Files
multica/packages/views/locales/en/projects.json
Bohan Jiang 47e3fdedd0 feat(projects): start_date / due_date UI + create-project footer aligned with create-issue (MUL-4388) (#5331)
* feat(projects): add start_date / due_date pickers to project create modal and sidebar

#5313 landed the backend start_date/due_date fields + types but deliberately
shipped no UI. Wire up the two editor surfaces users expect:

- ProjectStartDatePicker / ProjectDueDatePicker mirror the issue pickers (same
  calendar-day contract, clear idiom, shared @multica/core/issues/date helpers)
  but are typed to UpdateProjectRequest and scoped to the "projects" i18n
  namespace. One component serves both surfaces via a custom trigger.
- Create-project modal: two date pills; values flow into the create payload and
  the persisted draft (draft-store gains startDate/dueDate).
- Project sidebar (project-detail): two PropRows after Lead, wired to the update
  mutation, with clear support (send null).
- i18n: prop_start_date / prop_due_date / clear_date across en/zh-Hans/ja/ko,
  reusing the existing issue date wording.

Tests: picker display + clear behavior (real popover), and the create modal
renders both pills. typecheck + lint + i18n parity pass.

Part of #5227

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

* refactor(projects): align create-project footer with create-issue

Restructure the create-project modal footer to match the create-issue pattern
(per design feedback): the primary action moves out of the cramped single
justify-between row into its own border-t action strip, and the property pills
sit in a dedicated wrapping toolbar above it. Low-frequency fields (start/due
date) collapse into a ⋯ overflow via progressive disclosure — a pill only
renders inline once its date is set or the user opens it from the menu — so the
default toolbar stays a clean single row (Status · Priority · Lead · Repos · ⋯).

- Use the shared PillButton (../common/pill-button) instead of the modal-local
  copy, gaining the data-popup-open styling create-issue uses.
- ProjectStartDatePicker / ProjectDueDatePicker gain controlled open props so
  the overflow menu can reveal + open them (mirrors the issue pickers).
- i18n: create_project.set_start_date / set_due_date / more_options_aria across
  en / zh-Hans / ja / ko, reusing the create-issue wording.

Test updated to assert the dates are revealed from the overflow rather than
shown inline by default. typecheck / lint / i18n parity pass.

Part of #5227

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

* refactor(views): extract shared DateOnlyPicker base for date pills (Elon nit2)

The issue and project start/due-date pickers were near-complete copies of the
same Popover + Calendar + clear wiring, so they could drift in behaviour or
formatting. Extract that into one entity-agnostic DateOnlyPicker
(packages/views/common/date-only-picker.tsx); each of the four pills is now a
thin wrapper supplying only its field name (via onChange), icon, overdue flag,
and localized copy. -264 lines of duplication, single source of truth.

Behaviour is unchanged: the issue pickers keep their full API (trigger /
triggerRender / open / onOpenChange / align / defaultOpen — all still used by
board-card, issue-detail, create-issue) and the calendar-day contract stays in
@multica/core/issues/date. The en-US display format now lives in one place
rather than being duplicated per entity.

Full views test suite (1857 tests) + typecheck + lint pass.

Part of #5227

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

---------

Co-authored-by: J <j@multica.ai>
Co-authored-by: multica-agent <github@multica.ai>
2026-07-13 17:13:43 +08:00

152 lines
5.6 KiB
JSON

{
"page": {
"title": "Projects",
"new_project": "New project",
"empty": "No projects yet",
"create_first": "Create your first project",
"view_compact": "Compact",
"view_comfortable": "Comfortable",
"search_placeholder": "Search projects...",
"no_search_results": "No results match your search",
"view_table": "Table",
"view_cards": "Cards",
"row_menu": "Project actions",
"pin": "Pin to sidebar",
"unpin": "Unpin",
"delete": "Delete",
"no_matches": "No projects match",
"selected_one": "{{count}} selected",
"selected_other": "{{count}} selected",
"clear_selection": "Clear selection"
},
"table": {
"name": "Name",
"priority": "Priority",
"status": "Status",
"progress": "Progress",
"lead": "Lead",
"created": "Created",
"issues": "Issues"
},
"status": {
"planned": "Planned",
"in_progress": "In Progress",
"paused": "Paused",
"completed": "Completed",
"cancelled": "Cancelled"
},
"priority": {
"urgent": "Urgent",
"high": "High",
"medium": "Medium",
"low": "Low",
"none": "No priority"
},
"lead": {
"no_lead": "No lead",
"assign_placeholder": "Assign lead...",
"members_group": "Members",
"agents_group": "Agents",
"no_results": "No results"
},
"relative_date": {
"today": "Today",
"one_day_ago": "1d ago",
"days_ago": "{{count}}d ago",
"months_ago": "{{count}}mo ago"
},
"detail": {
"not_found": "Project not found",
"breadcrumb_fallback": "Projects",
"title_placeholder": "Project title",
"icon_tooltip": "Change icon",
"pin_tooltip": "Pin to sidebar",
"unpin_tooltip": "Unpin from sidebar",
"sidebar_tooltip": "Toggle sidebar",
"copy_link": "Copy link",
"delete_action": "Delete project",
"section_properties": "Properties",
"section_progress": "Progress",
"section_description": "Description",
"prop_start_date": "Start date",
"prop_due_date": "Due date",
"clear_date": "Clear date",
"description_placeholder": "Add description...",
"description_hint": "Shared with agents as context for every task in this project.",
"empty_issues_title": "No issues linked",
"empty_issues_hint": "Create a new issue or assign existing ones to this project.",
"empty_issues_new_button": "New Issue",
"no_issues_yet": "No issues yet",
"toast_link_copied": "Link copied",
"toast_project_deleted": "Project deleted",
"toast_move_issue_failed": "Failed to move issue"
},
"resources": {
"section_header": "Resources",
"empty": "No resources attached.",
"add_button": "Add resource",
"popover_title": "Attach a GitHub repo",
"repos_search_placeholder": "Search repositories...",
"repos_search_empty": "No repositories match your search.",
"attached_badge": "attached",
"remove_tooltip": "Remove",
"url_placeholder": "https://github.com/owner/repo or git@github.com:owner/repo.git",
"url_submit": "Add",
"toast_attached": "Repository attached",
"toast_attach_failed": "Failed to attach",
"toast_removed": "Resource removed",
"toast_remove_failed": "Failed to remove resource",
"add_local_directory_button": "Add local directory",
"local_daemon_offline_hint": "Start the local daemon to attach a directory on this machine.",
"local_daemon_already_attached_hint": "This machine already has a local directory attached. Remove it before adding another.",
"local_rename_tooltip": "Rename",
"local_rename_label": "Local directory label",
"local_no_daemon_tooltip": "Local daemon isn't reporting an ID yet — the agent can't open this directory.",
"local_other_machine_tooltip": "Only available on the machine that registered this directory.",
"chat_hint_prefix": "Agent will work in-place at",
"toast_local_attached": "Local directory attached",
"toast_local_renamed": "Renamed",
"toast_local_rename_failed": "Failed to rename",
"toast_local_pick_failed": "Failed to pick directory",
"toast_local_already_attached": "This directory is already attached to the project on this machine.",
"toast_local_daemon_already_attached": "This machine already has a local directory attached to this project. Remove it before adding another.",
"toast_local_daemon_not_running": "Local daemon isn't running.",
"local_validate_not_absolute": "Pick an absolute path.",
"local_validate_not_found": "Path doesn't exist.",
"local_validate_not_a_directory": "Path is not a directory.",
"local_validate_not_readable": "Directory is not readable.",
"local_validate_not_writable": "Directory is not writable.",
"local_validate_unsupported": "Local directories can only be picked on the desktop app."
},
"delete_dialog": {
"title": "Delete project",
"description": "This will delete the project. Issues will not be deleted but will be unlinked.",
"confirm": "Delete",
"cancel": "Cancel"
},
"picker": {
"no_project": "No project",
"remove": "Remove from project",
"empty": "No projects yet"
},
"chip": {
"fallback_label": "Project"
},
"toolbar": {
"result_count_title": "Matching projects / all projects",
"filter_label": "Filter",
"filter_active_count_one": "{{count}} filter",
"filter_active_count_other": "{{count}} filters",
"clear_filters": "Clear filters",
"section_status": "Status",
"section_priority": "Priority",
"section_lead": "Lead",
"display": "Display",
"sort_by": "Sort by",
"direction_asc": "Ascending",
"direction_desc": "Descending",
"section_columns": "Columns",
"view": "View"
}
}