| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- using Inversion;
- using Spry;
- using Spry.Authentication;
- using Statum;
- using ClankerSaddle.Services;
- namespace ClankerSaddle {
- /** Sealed project id carried by the project actions. */
- public class ProjectActionPrivate : Object {
- public int64 project_id { get; set; }
- }
- /** Sealed link identity carried by {@link RemoveProjectLinkAction}. */
- public class ProjectLinkActionPrivate : Object {
- public int64 project_id { get; set; }
- public int64 link_id { get; set; }
- }
- /** Sealed note identity carried by {@link DeleteProjectNoteAction}. */
- public class ProjectNoteActionPrivate : Object {
- public int64 project_id { get; set; }
- public int64 note_id { get; set; }
- }
- /**
- * Creates a project from the projects form (name and git URL
- * required); default_branch falls back to 'main'.
- */
- public class CreateProjectAction : StatumAction {
- private ProjectService projects = inject<ProjectService>();
- private UserService users = inject<UserService>();
- public override async DirectiveBuilder handle() throws GLib.Error {
- var guard = yield SpryAuth.require_login(directives(), request, users);
- if (guard != null) {
- return (!)guard;
- }
- string name = Forms.field(request, "name");
- string git_url = Forms.field(request, "git_url");
- if (name.length == 0 || git_url.length == 0) {
- return directives().notify("error", "Name and git URL are required").navigate("/projects");
- }
- try {
- var project = yield projects.create_project(name, git_url,
- Forms.field(request, "default_branch"), Forms.field(request, "summary"));
- return directives().notify("success", @"Project '$(project.name)' created")
- .navigate(@"/projects/$(project.id)");
- } catch (Error e) {
- return directives().notify("error", @"Could not create the project: $(e.message)").navigate("/projects");
- }
- }
- }
- /**
- * Saves the editable fields of a project; the id comes from the sealed
- * {@link ProjectActionPrivate} blob (the hidden form field is a
- * fallback). An empty summary clears the stored one.
- */
- public class UpdateProjectAction : TypedStatumAction<ProjectActionPrivate> {
- private ProjectService projects = inject<ProjectService>();
- private UserService users = inject<UserService>();
- protected override Type private_type { get { return typeof(ProjectActionPrivate); } }
- public override async DirectiveBuilder handle() throws GLib.Error {
- var guard = yield SpryAuth.require_login(directives(), request, users);
- if (guard != null) {
- return (!)guard;
- }
- var ctx = request_private;
- int64 project_id = ctx != null ? ((!)ctx).project_id : Forms.integer(request, "project_id", 0);
- if (project_id <= 0) {
- return directives().navigate("/projects");
- }
- try {
- yield projects.update_project(project_id,
- Forms.optional(request, "name"), Forms.optional(request, "git_url"),
- Forms.optional(request, "default_branch"),
- request.form != null ? Forms.field(request, "summary") : null);
- return directives().notify("success", "Project saved")
- .navigate(@"/projects/$(project_id)");
- } catch (Error e) {
- return directives().notify("error", @"Could not save the project: $(e.message)")
- .navigate(@"/projects/$(project_id)");
- }
- }
- }
- /**
- * Links another project to this one; the parent id is sealed, the
- * target and relationship come from the form selects.
- */
- public class AddProjectLinkAction : TypedStatumAction<ProjectActionPrivate> {
- private ProjectService projects = inject<ProjectService>();
- private UserService users = inject<UserService>();
- protected override Type private_type { get { return typeof(ProjectActionPrivate); } }
- public override async DirectiveBuilder handle() throws GLib.Error {
- var guard = yield SpryAuth.require_login(directives(), request, users);
- if (guard != null) {
- return (!)guard;
- }
- var ctx = request_private;
- int64 project_id = ctx != null ? ((!)ctx).project_id : Forms.integer(request, "project_id", 0);
- int64 linked_id = Forms.integer(request, "linked_project_id", 0);
- string relationship = Forms.field(request, "relationship");
- if (project_id <= 0 || linked_id <= 0) {
- return directives().notify("error", "Pick a project to link").navigate(@"/projects/$(project_id)");
- }
- try {
- yield projects.add_link(project_id, linked_id, relationship);
- return directives().notify("success", "Link added").navigate(@"/projects/$(project_id)");
- } catch (Error e) {
- return directives().notify("error", @"Could not add the link: $(e.message)")
- .navigate(@"/projects/$(project_id)");
- }
- }
- }
- /** Removes a project link; both ids come from the sealed private blob. */
- public class RemoveProjectLinkAction : TypedStatumAction<ProjectLinkActionPrivate> {
- private ProjectService projects = inject<ProjectService>();
- private UserService users = inject<UserService>();
- protected override Type private_type { get { return typeof(ProjectLinkActionPrivate); } }
- public override async DirectiveBuilder handle() throws GLib.Error {
- var guard = yield SpryAuth.require_login(directives(), request, users);
- if (guard != null) {
- return (!)guard;
- }
- var ctx = request_private;
- if (ctx == null) {
- return directives().navigate("/projects");
- }
- try {
- yield projects.remove_link(((!)ctx).link_id);
- return directives().notify("success", "Link removed")
- .navigate(@"/projects/$(((!)ctx).project_id)");
- } catch (Error e) {
- return directives().notify("error", @"Could not remove the link: $(e.message)")
- .navigate(@"/projects/$(((!)ctx).project_id)");
- }
- }
- }
- /**
- * Deletes a project note; both ids come from the sealed private blob.
- * Notes are LLM-authored (`saddle note` via the callback endpoint) —
- * the web UI only curates them.
- */
- public class DeleteProjectNoteAction : TypedStatumAction<ProjectNoteActionPrivate> {
- private ProjectService projects = inject<ProjectService>();
- private UserService users = inject<UserService>();
- protected override Type private_type { get { return typeof(ProjectNoteActionPrivate); } }
- public override async DirectiveBuilder handle() throws GLib.Error {
- var guard = yield SpryAuth.require_login(directives(), request, users);
- if (guard != null) {
- return (!)guard;
- }
- var ctx = request_private;
- if (ctx == null) {
- return directives().navigate("/projects");
- }
- try {
- yield projects.delete_note(((!)ctx).note_id);
- return directives().notify("success", "Note deleted")
- .navigate(@"/projects/$(((!)ctx).project_id)");
- } catch (Error e) {
- return directives().notify("error", @"Could not delete the note: $(e.message)")
- .navigate(@"/projects/$(((!)ctx).project_id)");
- }
- }
- }
- }
|