mirror of
https://github.com/multica-ai/multica.git
synced 2026-08-02 18:13:27 +02:00
* 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>
50 lines
1.5 KiB
TypeScript
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;
|
|
}
|