Files
multica/packages/views/issues/utils/sort.ts
Bohan Jiang 3645bdb5b6 feat(issues): add start_date field with progressive disclosure (MUL-2274) (#2696)
* feat(issues): add start_date field with progressive disclosure (MUL-2274)

Mirrors the existing due_date implementation end-to-end so an issue can
express a planned start in addition to a deadline. Surfaces start_date as
an optional sidebar property alongside priority / due_date / labels (added
in MUL-2275), with consistent picker, board/list/sort, activity, and inbox
plumbing.

Backs the Project Gantt work (parent MUL-1881) and keeps the
progressive-disclosure attribute experience consistent.

- DB: migration 091 adds issue.start_date TIMESTAMPTZ.
- sqlc: ListIssues / CreateIssue / UpdateIssue / CreateIssueWithOrigin /
  ListOpenIssues read & write start_date.
- Backend: IssueResponse + create/update/batch-update handlers parse and
  emit start_date with RFC3339 validation; new start_date_changed activity
  event + subscriber notification (with prev_start_date in event payload).
- CLI: --start-date flag on `multica issue create` / `issue update`.
- Frontend: StartDatePicker component, start_date wired into Issue type,
  Zod schema, draft / view stores, sort util, header sort + card-property
  options, list-row / board-card display, create-issue modal, and the
  issue-detail progressive-disclosure "+ Add property" surface (visibility
  rule, picker row, add-property menu icon + label).
- i18n: en + zh-Hans for sort_start_date / card_start_date /
  prop_start_date / activity start_date_set / start_date_removed /
  picker start_date.trigger_label / clear_action / inbox labels.
- Tests: new TestNotification_StartDateChanged; existing Issue / draft /
  modal fixtures extended with start_date.

Co-authored-by: multica-agent <github@multica.ai>

* feat(issues): align start_date with due_date in actions menu and CLI table

- Add Start Date submenu (today / tomorrow / next week / clear) in
  actions menu, mirroring Due Date — parity with the Due Date quick
  setters in list/board context and 3-dot menus.
- Add corresponding en / zh-Hans i18n keys
  (actions.start_date / start_today / start_tomorrow / start_next_week
  / start_clear).
- CLI human table for `multica issue list` and `multica issue get`
  now shows a START DATE column next to DUE DATE; --full-id variant
  too.

Co-authored-by: multica-agent <github@multica.ai>

---------

Co-authored-by: multica-agent <github@multica.ai>
2026-05-17 15:01:38 +08:00

50 lines
1.5 KiB
TypeScript

import type { Issue } from "@multica/core/types";
import { PRIORITY_ORDER } from "@multica/core/issues/config";
import type { SortField, SortDirection } from "@multica/core/issues/stores/view-store";
const PRIORITY_RANK: Record<string, number> = Object.fromEntries(
PRIORITY_ORDER.map((p, i) => [p, i])
);
export function sortIssues(
issues: Issue[],
field: SortField,
direction: SortDirection
): Issue[] {
const sorted = [...issues].sort((a, b) => {
switch (field) {
case "priority":
return (
(PRIORITY_RANK[a.priority] ?? 99) -
(PRIORITY_RANK[b.priority] ?? 99)
);
case "start_date": {
if (!a.start_date && !b.start_date) return 0;
if (!a.start_date) return 1;
if (!b.start_date) return -1;
return (
new Date(a.start_date).getTime() - new Date(b.start_date).getTime()
);
}
case "due_date": {
if (!a.due_date && !b.due_date) return 0;
if (!a.due_date) return 1;
if (!b.due_date) return -1;
return (
new Date(a.due_date).getTime() - new Date(b.due_date).getTime()
);
}
case "created_at":
return (
new Date(a.created_at).getTime() - new Date(b.created_at).getTime()
);
case "title":
return a.title.localeCompare(b.title);
case "position":
default:
return a.position - b.position;
}
});
return direction === "desc" ? sorted.reverse() : sorted;
}