Repository: obsidian-tasks-group/obsidian-tasks
Pull request #2831 (2024-05-17 04:55:48)

refactor: extract `StatusEditor` component from Edit Task modal
# Description

- extract `StatusEditor` component from Edit Task modal

## Motivation and Context

- have reusable components
- simplify cluttered Edit Task modal code

## How has this been tested?

- unit tests
- manual test in demo vault (open the task modal, change status, apply it, verify the change in the task line)

## Types of changes

Internal changes:

- [x] **Refactor** (prefix: `refactor` - non-breaking change which only improves the design or structure of existing code, and making no changes to its external behaviour)

## Checklist

- [x] My code follows the code style of this project and passes `yarn run lint`.
- [x] My change has adequate [Unit Test coverage](https://publish.obsidian.md/tasks-contributing/Testing/About+Testing).

## Terms

<!--
By submitting this pull request, you must agree to follow our
[contributing guide](https://publish.obsidian.md/tasks-contributing) and
[Code of Conduct](https://github.com/obsidian-tasks-group/obsidian-tasks/blob/main/CODE_OF_CONDUCT.md).
Put an x in the boxes to confirm you agree.
-->

- [x] My contribution follows this project's [contributing guide](https://publish.obsidian.md/tasks-contributing)
- [x] I agree to follow this project's [Code of Conduct](https://github.com/obsidian-tasks-group/obsidian-tasks/blob/main/CODE_OF_CONDUCT.md)



Patch:
diff --git a/src/ui/EditTask.scss b/src/ui/EditTask.scss
index b020c5ff..9a9ca3ae 100644
--- a/src/ui/EditTask.scss
+++ b/src/ui/EditTask.scss
@@ -97,7 +97,7 @@
         }
     }
 
-    .tasks-modal-status-selector {
+    .status-editor-status-selector {
         grid-column: 2;
         width: 15em;
     }
@@ -163,7 +163,7 @@
             grid-column: 2;
         }
 
-        .tasks-modal-status-selector {
+        .status-editor-status-selector {
             grid-column: 1;
         }
     }
@@ -181,7 +181,7 @@
 
 @media (max-width: 399px) {
     .tasks-modal-dates-section {
-        .tasks-modal-status-selector {
+        .status-editor-status-selector {
             grid-column: 1;
             width: auto;
         }
diff --git a/src/ui/EditTask.svelte b/src/ui/EditTask.svelte
index 9fda5906..dd844170 100644
--- a/src/ui/EditTask.svelte
+++ b/src/ui/EditTask.svelte
@@ -14,6 +14,7 @@
     import type { EditableTask } from './EditableTask';
     import Dependency from './Dependency.svelte';
     import { labelContentWithAccessKey } from './EditTaskHelpers';
+    import StatusEditor from './StatusEditor.svelte';
 
     // These exported variables are passed in as props by TaskModal.onOpen():
     export let task: Task;
@@ -21,8 +22,6 @@
     export let statusOptions: Status[];
     export let allTasks: Task[];
 
-    let statusSymbol = task.status.symbol;
-
     const {
         // NEW_TASK_FIELD_EDIT_REQUIRED
         prioritySymbols,
@@ -139,27 +138,6 @@
         return updatedTask;
     }
 
-    const _onStatusChange = () => {
-        // Use statusSymbol to find the status to save to editableTask.status
-        const selectedStatus: Status | undefined = statusOptions.find((s) => s.symbol === statusSymbol);
-        if (selectedStatus) {
-            editableTask.status = selectedStatus;
-        } else {
-            console.log(`Error in EditTask: cannot find status with symbol ${statusSymbol}`);
-            return;
-        }
-
-        // Obtain a temporary task with the new status applied, to see what would
-        // happen to the done date:
-        const taskWithEditedStatusApplied = task.handleNewStatus(selectedStatus).pop();
-
-        if (taskWithEditedStatusApplied) {
-            // Update the doneDate field, in case changing the status changed the value:
-            editableTask.doneDate = taskWithEditedStatusApplied.done.formatAsDate();
-            editableTask.cancelledDate = taskWithEditedStatusApplied.cancelled.formatAsDate();
-        }
-    };
-
     $: accesskey = (key: string) => (withAccessKeys ? key : null);
     $: formIsValid =
         isDueDateValid &&
@@ -592,19 +570,7 @@ Availability of access keys:
         <!-- --------------------------------------------------------------------------- -->
         <!--  Status  -->
         <!-- --------------------------------------------------------------------------- -->
-        <label for="status">{@html labelContentWithAccessKey('Status', accesskey('u'))}</label>
-        <!-- svelte-ignore a11y-accesskey -->
-        <select
-            bind:value={statusSymbol}
-            on:change={_onStatusChange}
-            id="status-type"
-            class="tasks-modal-status-selector"
-            accesskey={accesskey('u')}
-        >
-            {#each statusOptions as status}
-                <option value={status.symbol}>{status.name} [{status.symbol}]</option>
-            {/each}
-        </select>
+        <StatusEditor {task} bind:editableTask {statusOptions} accesskey={accesskey('u')} />
 
         <!-- --------------------------------------------------------------------------- -->
         <!--  Created Date  -->
diff --git a/src/ui/StatusEditor.svelte b/src/ui/StatusEditor.svelte
new file mode 100644
index 00000000..e53d71db
--- /dev/null
+++ b/src/ui/StatusEditor.svelte
@@ -0,0 +1,48 @@
+<script lang="ts">
+    import type { Status } from '../Statuses/Status';
+    import type { Task } from '../Task/Task';
+    import type { EditableTask } from './EditableTask';
+    import { labelContentWithAccessKey } from './EditTaskHelpers';
+
+    export let task: Task;
+    export let editableTask: EditableTask;
+    export let statusOptions: Status[];
+    export let accesskey: string | null;
+
+    let statusSymbol = task.status.symbol;
+
+    const _onStatusChange = () => {
+        // Use statusSymbol to find the status to save to editableTask.status
+        const selectedStatus: Status | undefined = statusOptions.find((s) => s.symbol === statusSymbol);
+        if (selectedStatus) {
+            editableTask.status = selectedStatus;
+        } else {
+            console.log(`Error in EditTask: cannot find status with symbol ${statusSymbol}`);
+            return;
+        }
+
+        // Obtain a temporary task with the new status applied, to see what would
+        // happen to the done date:
+        const taskWithEditedStatusApplied = task.handleNewStatus(selectedStatus).pop();
+
+        if (taskWithEditedStatusApplied) {
+            // Update the doneDate field, in case changing the status changed the value:
+            editableTask.doneDate = taskWithEditedStatusApplied.done.formatAsDate();
+            editableTask.cancelledDate = taskWithEditedStatusApplied.cancelled.formatAsDate();
+        }
+    };
+</script>
+
+<label for="status">{@html labelContentWithAccessKey('Status', accesskey)}</label>
+<!-- svelte-ignore a11y-accesskey -->
+<select
+    bind:value={statusSymbol}
+    on:change={_onStatusChange}
+    id="status-type"
+    class="status-editor-status-selector"
+    {accesskey}
+>
+    {#each statusOptions as status}
+        <option value={status.symbol}>{status.name} [{status.symbol}]</option>
+    {/each}
+</select>


Test patch:
diff --git a/tests/ui/EditTask.test.Edit_Modal_HTML_snapshot_tests_should_match_snapshot.approved.html b/tests/ui/EditTask.test.Edit_Modal_HTML_snapshot_tests_should_match_snapshot.approved.html
index 0f4ae338..7333f8b2 100644
--- a/tests/ui/EditTask.test.Edit_Modal_HTML_snapshot_tests_should_match_snapshot.approved.html
+++ b/tests/ui/EditTask.test.Edit_Modal_HTML_snapshot_tests_should_match_snapshot.approved.html
@@ -205,7 +205,7 @@
         <span class="accesskey">u</span>
         s
       </label>
-      <select id="status-type" class="tasks-modal-status-selector" accesskey="u">
+      <select id="status-type" class="status-editor-status-selector" accesskey="u">
         <option value=" ">Todo [ ]</option>
         <option value="/">In Progress [/]</option>
         <option value="x">Done [x]</option>
diff --git a/tests/ui/EditTask.test.Edit_Modal_HTML_snapshot_tests_should_match_snapshot_-_without_access_keys.approved.html b/tests/ui/EditTask.test.Edit_Modal_HTML_snapshot_tests_should_match_snapshot_-_without_access_keys.approved.html
index 26a0de65..e35d282d 100644
--- a/tests/ui/EditTask.test.Edit_Modal_HTML_snapshot_tests_should_match_snapshot_-_without_access_keys.approved.html
+++ b/tests/ui/EditTask.test.Edit_Modal_HTML_snapshot_tests_should_match_snapshot_-_without_access_keys.approved.html
@@ -133,7 +133,7 @@
     <hr />
     <section class="tasks-modal-dates-section">
       <label for="status">Status</label>
-      <select id="status-type" class="tasks-modal-status-selector">
+      <select id="status-type" class="status-editor-status-selector">
         <option value=" ">Todo [ ]</option>
         <option value="/">In Progress [/]</option>
         <option value="x">Done [x]</option>