Loggest thine Stuff
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

117 lines
3.4 KiB

  1. <script lang="ts">
  2. import { goto } from "$app/navigation";
  3. import { getStores } from "$app/stores";
  4. import { sl3 } from "$lib/clients/sl3";
  5. import Modal from "$lib/components/common/Modal.svelte";
  6. import ModalBody from "$lib/components/common/ModalBody.svelte";
  7. import { getModalContext } from "$lib/components/contexts/ModalContext.svelte";
  8. import { getProjectContext } from "$lib/components/contexts/ProjectContext.svelte";
  9. import { getProjectListContext } from "$lib/components/contexts/ProjectListContext.svelte";
  10. import { getScopeContext } from "$lib/components/contexts/ScopeContext.svelte";
  11. import StatusSelect from "$lib/components/controls/StatusSelect.svelte";
  12. import type Project from "$lib/models/project";
  13. import type { ProjectEntry, ProjectInput, Requirement, RequirementInput } from "$lib/models/project";
  14. import Status from "$lib/models/status";
  15. import { projectPrettyId, scopePrettyId } from "$lib/utils/prettyIds";
  16. const {currentModal, closeModal} = getModalContext();
  17. const {scope} = getScopeContext();
  18. const {reloadProject} = getProjectContext();
  19. const {reloadProjectList} = getProjectListContext();
  20. const {page} = getStores();
  21. let project: ProjectInput
  22. let projectId: number
  23. let oldStats: RequirementInput["stats"]
  24. let error: string
  25. let loading: boolean
  26. let show: boolean
  27. let op: "Create" | "Edit" | "Delete"
  28. $: switch ($currentModal.name) {
  29. case "project.create":
  30. initCreate();
  31. op = "Create";
  32. break;
  33. case "project.edit":
  34. initEdit($currentModal.project);
  35. op = "Edit";
  36. break;
  37. default:
  38. loading = false;
  39. error = null;
  40. show = false;
  41. }
  42. function initCreate() {
  43. project = {
  44. name: "",
  45. description: "",
  46. status: Status.Available,
  47. createdTime: void(0),
  48. }
  49. show = true;
  50. }
  51. function initEdit(current: Project) {
  52. project = {
  53. name: current.name,
  54. description: current.description,
  55. status: current.status,
  56. }
  57. projectId = current.id;
  58. show = true;
  59. }
  60. async function submit() {
  61. error = null;
  62. loading = true;
  63. try {
  64. switch (op) {
  65. case "Create":
  66. const newProject = await sl3(fetch, $page.stuff.idToken).createProject($scope.id, project);
  67. projectId = newProject.id
  68. break;
  69. case "Edit":
  70. await sl3(fetch, $page.stuff.idToken).updateProject($scope.id, projectId, project);
  71. break;
  72. }
  73. // Wait for project to reload
  74. await reloadProject();
  75. await reloadProjectList();
  76. goto(`/${scopePrettyId($scope)}/projects/${projectPrettyId({id: projectId, name: project.name})}`, {replaceState: op === "Edit"})
  77. closeModal();
  78. } catch(err) {
  79. if (err.statusCode != null) {
  80. error = err.statusMessage;
  81. } else {
  82. error = err
  83. }
  84. } finally {
  85. loading = false;
  86. }
  87. }
  88. </script>
  89. <form on:submit|preventDefault={submit}>
  90. <Modal show={show} closable verb={op} noun="Project" disabled={loading} error={error}>
  91. <ModalBody>
  92. <label for="name">Name</label>
  93. <input name="name" type="text" bind:value={project.name} />
  94. <label for="description">Description</label>
  95. <textarea name="description" bind:value={project.description} />
  96. <label for="stats">Status</label>
  97. <StatusSelect bind:status={project.status} />
  98. </ModalBody>
  99. </Modal>
  100. </form>