| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- using Invercargill;
- using Invercargill.DataStructures;
- using Spry;
- using Spry.Authentication;
- using Statum;
- using ClankerSaddle.Data;
- using ClankerSaddle.Services;
- namespace ClankerSaddle {
- /** A stack row on the stacks page, with its member names. */
- public class StackRowView : Object {
- public int64 id { get; set; }
- public string name { get; set; default = ""; }
- public string summary { get; set; default = ""; }
- public string created_display { get; set; default = ""; }
- public int64 member_count { get; set; }
- }
- /** Public data of the `stacks` slot. */
- public class StacksPublic : Object {
- public Statum.Model.ActionDto create { get; set; }
- }
- /**
- * Entrypoint for /stacks (goal 8 task 2 B): every stack with its
- * member count and a link to its page, plus the create form. A
- * stack is a named bundle of reference projects applied one-click
- * to a project's or a goal's link set.
- */
- public class StacksEntrypoint : StatumEntrypoint {
- private StackService stack_service = Inversion.inject<StackService>();
- private ProjectService project_service = Inversion.inject<ProjectService>();
- private UserService users = Inversion.inject<UserService>();
- public override async DirectiveBuilder handle() throws GLib.Error {
- var guard = yield SpryAuth.require_login(directives(), request, users);
- if (guard != null) {
- return (!)guard;
- }
- var rows = new Vector<StackRowView>();
- foreach (var stack in yield stack_service.list_stacks()) {
- rows.add(new StackRowView() {
- id = stack.id,
- name = stack.name,
- summary = stack.summary ?? "",
- created_display = format_stamp(stack.created_at),
- member_count = (yield stack_service.list_members(stack.id)).length
- });
- }
- var pub = new StacksPublic();
- pub.create = action_registry.author<CreateStackAction>();
- var props = (PropertyDictionary) GObjectMapping.to_properties(pub);
- props["stacks"] = StateJson.list<StackRowView>(rows.to_immutable_buffer());
- var slot = state_service.new_slot(Scope.PAGE, new State() {
- type_name = "stacks",
- public_data = props,
- private_data = new PropertyDictionary()
- });
- return directives().set(slot);
- }
- }
- /** A member project of a stack, with its remove action. */
- public class StackMemberView : Object {
- public int64 member_id { get; set; }
- public int64 project_id { get; set; }
- public string name { get; set; default = ""; }
- public string git_url { get; set; default = ""; }
- public string relationship { get; set; default = ""; }
- public Statum.Model.ActionDto? remove { get; set; }
- }
- /** A project option in the member-add select. */
- public class StackProjectOptionView : Object {
- public int64 id { get; set; }
- public string name { get; set; default = ""; }
- }
- /** Public data of the `stack` slot. */
- public class StackDetailPublic : Object {
- public bool exists { get; set; }
- public int64 id { get; set; }
- public string name { get; set; default = ""; }
- public string summary { get; set; default = ""; }
- public string created_display { get; set; default = ""; }
- public Statum.Model.ActionDto? update { get; set; }
- public Statum.Model.ActionDto? add_member { get; set; }
- public Statum.Model.ActionDto? delete { get; set; }
- }
- /**
- * Entrypoint for /stacks/{stack_id}: the stack's editable card,
- * its member projects with relationship badges and remove actions,
- * and the add-member form (every project, relationship select).
- */
- public class StackDetailEntrypoint : StatumEntrypoint {
- private StackService stack_service = Inversion.inject<StackService>();
- private ProjectService project_service = Inversion.inject<ProjectService>();
- private UserService users = Inversion.inject<UserService>();
- public override async DirectiveBuilder handle() throws GLib.Error {
- var guard = yield SpryAuth.require_login(directives(), request, users);
- if (guard != null) {
- return (!)guard;
- }
- int64 stack_id = int64.parse(request.route("stack_id") ?? "0");
- var stack = yield stack_service.get_stack(stack_id);
- if (stack == null) {
- return directives().set_typed<StackDetailPublic>("stack", Scope.PAGE,
- new StackDetailPublic() { exists = false });
- }
- var sealed = new StackActionPrivate() { stack_id = stack_id };
- var pub = new StackDetailPublic() {
- exists = true,
- id = ((!)stack).id,
- name = ((!)stack).name,
- summary = ((!)stack).summary ?? "",
- created_display = format_stamp(((!)stack).created_at),
- update = action_registry.author_private<UpdateStackAction, StackActionPrivate>(sealed),
- add_member = action_registry.author_private<AddStackMemberAction, StackActionPrivate>(sealed),
- delete = action_registry.author_private<DeleteStackAction, StackActionPrivate>(sealed)
- };
- var members = new Vector<StackMemberView>();
- foreach (var member in yield stack_service.list_members(stack_id)) {
- var project = yield project_service.get_project(member.project_id);
- if (project == null) {
- continue;
- }
- members.add(new StackMemberView() {
- member_id = member.id,
- project_id = member.project_id,
- name = ((!)project).name,
- git_url = ((!)project).git_url,
- relationship = member.relationship,
- remove = action_registry.author_private<RemoveStackMemberAction, StackMemberActionPrivate>(
- new StackMemberActionPrivate() { stack_id = stack_id, member_id = member.id })
- });
- }
- var options = new Vector<StackProjectOptionView>();
- foreach (var project in yield project_service.list_projects()) {
- options.add(new StackProjectOptionView() {
- id = project.id,
- name = project.name
- });
- }
- var props = (PropertyDictionary) GObjectMapping.to_properties(pub);
- props["members"] = StateJson.list<StackMemberView>(members.to_immutable_buffer());
- props["options"] = StateJson.list<StackProjectOptionView>(options.to_immutable_buffer());
- var slot = state_service.new_slot(Scope.PAGE, new State() {
- type_name = "stack",
- public_data = props,
- private_data = new PropertyDictionary()
- });
- return directives().set(slot);
- }
- }
- }
|