From e9d5dbe6adb387a31afd13d3d9d16d225a29e18b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=B7=E7=94=B5=E8=8A=BD=E8=A1=A3?= Date: Mon, 5 Oct 2026 15:51:57 -0400 Subject: [PATCH] WIP components (as built) --- assignee_picker.go | 232 +++++++++++++++ assignee_picker_test.go | 154 ++++++++++ burndown_chart.go | 216 ++++++++++++++ burndown_chart_test.go | 145 ++++++++++ docs/components/361-kanban-board.md | 43 +++ docs/components/362-task-list.md | 44 +++ docs/components/363-task-item.md | 42 +++ docs/components/364-task-detail-panel.md | 43 +++ docs/components/365-subtask-list.md | 38 +++ docs/components/368-sprint-board.md | 44 +++ docs/components/369-burndown-chart.md | 46 +++ docs/components/370-priority-indicator.md | 36 +++ docs/components/371-status-select.md | 39 +++ docs/components/372-assignee-picker.md | 39 +++ docs/components/373-due-date-picker.md | 38 +++ docs/components/374-label-manager.md | 39 +++ docs/components/375-issue-card.md | 39 +++ docs/components/376-issue-id-badge.md | 38 +++ docs/components/377-milestone-progress.md | 36 +++ docs/components/378-workload-view.md | 36 +++ docs/components/379-time-tracker.md | 38 +++ docs/components/380-pomodoro-timer.md | 42 +++ docs_test.go | 3 + due_date_picker.go | 76 +++++ due_date_picker_test.go | 83 ++++++ example_projects_test.go | 242 ++++++++++++++++ examples/gallery/pages_projects.go | 81 +++++- examples/gallery/pages_projects_demos.go | 172 ++++++++++++ examples/gallery/pages_projects_fields.go | 61 ++++ .../gallery/pages_projects_fields_demos.go | 142 ++++++++++ examples/gallery/pages_projects_test.go | 97 +++++++ examples/gallery/pages_projects_time.go | 53 ++++ examples/gallery/pages_projects_time_demos.go | 83 ++++++ issue_card.go | 87 ++++++ issue_card_test.go | 88 ++++++ issue_id_badge.go | 73 +++++ issue_id_badge_test.go | 82 ++++++ kanban_board.go | 263 ++++++++++++++++++ kanban_board_test.go | 177 ++++++++++++ label_manager.go | 208 ++++++++++++++ label_manager_test.go | 102 +++++++ messages_projects.go | 120 ++++++++ milestone_progress.go | 72 +++++ milestone_progress_test.go | 55 ++++ pomodoro_timer.go | 212 ++++++++++++++ pomodoro_timer_test.go | 132 +++++++++ priority_indicator.go | 67 +++++ priority_indicator_test.go | 79 ++++++ projects.go | 146 ++++++++++ projects_test.go | 54 ++++ sprint_board.go | 111 ++++++++ sprint_board_test.go | 87 ++++++ status_select.go | 140 ++++++++++ status_select_test.go | 93 +++++++ subtask_list.go | 158 +++++++++++ subtask_list_test.go | 107 +++++++ task_detail_panel.go | 115 ++++++++ task_detail_panel_test.go | 147 ++++++++++ task_item.go | 99 +++++++ task_item_test.go | 102 +++++++ task_list.go | 215 ++++++++++++++ task_list_test.go | 147 ++++++++++ .../snapshots/darwin/assignee_picker-dark.png | Bin 0 -> 6877 bytes .../darwin/assignee_picker-light.png | Bin 0 -> 6807 bytes .../snapshots/darwin/burndown_chart-dark.png | Bin 0 -> 21277 bytes .../snapshots/darwin/burndown_chart-light.png | Bin 0 -> 20054 bytes .../snapshots/darwin/due_date_picker-dark.png | Bin 0 -> 8901 bytes .../darwin/due_date_picker-light.png | Bin 0 -> 8509 bytes testdata/snapshots/darwin/issue_card-dark.png | Bin 0 -> 15654 bytes .../snapshots/darwin/issue_card-light.png | Bin 0 -> 15376 bytes .../snapshots/darwin/issue_id_badge-dark.png | Bin 0 -> 2711 bytes .../snapshots/darwin/issue_id_badge-light.png | Bin 0 -> 2622 bytes .../snapshots/darwin/kanban_board-dark.png | Bin 0 -> 33928 bytes .../snapshots/darwin/kanban_board-light.png | Bin 0 -> 33231 bytes .../snapshots/darwin/label_manager-dark.png | Bin 0 -> 8212 bytes .../snapshots/darwin/label_manager-light.png | Bin 0 -> 8045 bytes .../darwin/milestone_progress-dark.png | Bin 0 -> 11715 bytes .../darwin/milestone_progress-light.png | Bin 0 -> 11540 bytes .../snapshots/darwin/pomodoro_timer-dark.png | Bin 0 -> 15913 bytes .../snapshots/darwin/pomodoro_timer-light.png | Bin 0 -> 15279 bytes .../darwin/priority_indicator-dark.png | Bin 0 -> 4457 bytes .../darwin/priority_indicator-light.png | Bin 0 -> 4303 bytes .../snapshots/darwin/sprint_board-dark.png | Bin 0 -> 50219 bytes .../snapshots/darwin/sprint_board-light.png | Bin 0 -> 48929 bytes .../snapshots/darwin/status_select-dark.png | Bin 0 -> 9323 bytes .../snapshots/darwin/status_select-light.png | Bin 0 -> 9056 bytes .../snapshots/darwin/subtask_list-dark.png | Bin 0 -> 10718 bytes .../snapshots/darwin/subtask_list-light.png | Bin 0 -> 10440 bytes .../darwin/task_detail_panel-dark.png | Bin 0 -> 47675 bytes .../darwin/task_detail_panel-light.png | Bin 0 -> 46322 bytes testdata/snapshots/darwin/task_item-dark.png | Bin 0 -> 23310 bytes testdata/snapshots/darwin/task_item-light.png | Bin 0 -> 22316 bytes testdata/snapshots/darwin/task_list-dark.png | Bin 0 -> 33319 bytes testdata/snapshots/darwin/task_list-light.png | Bin 0 -> 32088 bytes .../snapshots/darwin/time_tracker-dark.png | Bin 0 -> 4513 bytes .../snapshots/darwin/time_tracker-light.png | Bin 0 -> 4434 bytes .../snapshots/darwin/workload_view-dark.png | Bin 0 -> 17066 bytes .../snapshots/darwin/workload_view-light.png | Bin 0 -> 16450 bytes time_tracker.go | 131 +++++++++ time_tracker_test.go | 105 +++++++ workload_view.go | 126 +++++++++ workload_view_test.go | 79 ++++++ 102 files changed, 6538 insertions(+), 1 deletion(-) create mode 100644 assignee_picker.go create mode 100644 assignee_picker_test.go create mode 100644 burndown_chart.go create mode 100644 burndown_chart_test.go create mode 100644 docs/components/361-kanban-board.md create mode 100644 docs/components/362-task-list.md create mode 100644 docs/components/363-task-item.md create mode 100644 docs/components/364-task-detail-panel.md create mode 100644 docs/components/365-subtask-list.md create mode 100644 docs/components/368-sprint-board.md create mode 100644 docs/components/369-burndown-chart.md create mode 100644 docs/components/370-priority-indicator.md create mode 100644 docs/components/371-status-select.md create mode 100644 docs/components/372-assignee-picker.md create mode 100644 docs/components/373-due-date-picker.md create mode 100644 docs/components/374-label-manager.md create mode 100644 docs/components/375-issue-card.md create mode 100644 docs/components/376-issue-id-badge.md create mode 100644 docs/components/377-milestone-progress.md create mode 100644 docs/components/378-workload-view.md create mode 100644 docs/components/379-time-tracker.md create mode 100644 docs/components/380-pomodoro-timer.md create mode 100644 due_date_picker.go create mode 100644 due_date_picker_test.go create mode 100644 example_projects_test.go create mode 100644 examples/gallery/pages_projects_demos.go create mode 100644 examples/gallery/pages_projects_fields.go create mode 100644 examples/gallery/pages_projects_fields_demos.go create mode 100644 examples/gallery/pages_projects_test.go create mode 100644 examples/gallery/pages_projects_time.go create mode 100644 examples/gallery/pages_projects_time_demos.go create mode 100644 issue_card.go create mode 100644 issue_card_test.go create mode 100644 issue_id_badge.go create mode 100644 issue_id_badge_test.go create mode 100644 kanban_board.go create mode 100644 kanban_board_test.go create mode 100644 label_manager.go create mode 100644 label_manager_test.go create mode 100644 messages_projects.go create mode 100644 milestone_progress.go create mode 100644 milestone_progress_test.go create mode 100644 pomodoro_timer.go create mode 100644 pomodoro_timer_test.go create mode 100644 priority_indicator.go create mode 100644 priority_indicator_test.go create mode 100644 projects.go create mode 100644 projects_test.go create mode 100644 sprint_board.go create mode 100644 sprint_board_test.go create mode 100644 status_select.go create mode 100644 status_select_test.go create mode 100644 subtask_list.go create mode 100644 subtask_list_test.go create mode 100644 task_detail_panel.go create mode 100644 task_detail_panel_test.go create mode 100644 task_item.go create mode 100644 task_item_test.go create mode 100644 task_list.go create mode 100644 task_list_test.go create mode 100644 testdata/snapshots/darwin/assignee_picker-dark.png create mode 100644 testdata/snapshots/darwin/assignee_picker-light.png create mode 100644 testdata/snapshots/darwin/burndown_chart-dark.png create mode 100644 testdata/snapshots/darwin/burndown_chart-light.png create mode 100644 testdata/snapshots/darwin/due_date_picker-dark.png create mode 100644 testdata/snapshots/darwin/due_date_picker-light.png create mode 100644 testdata/snapshots/darwin/issue_card-dark.png create mode 100644 testdata/snapshots/darwin/issue_card-light.png create mode 100644 testdata/snapshots/darwin/issue_id_badge-dark.png create mode 100644 testdata/snapshots/darwin/issue_id_badge-light.png create mode 100644 testdata/snapshots/darwin/kanban_board-dark.png create mode 100644 testdata/snapshots/darwin/kanban_board-light.png create mode 100644 testdata/snapshots/darwin/label_manager-dark.png create mode 100644 testdata/snapshots/darwin/label_manager-light.png create mode 100644 testdata/snapshots/darwin/milestone_progress-dark.png create mode 100644 testdata/snapshots/darwin/milestone_progress-light.png create mode 100644 testdata/snapshots/darwin/pomodoro_timer-dark.png create mode 100644 testdata/snapshots/darwin/pomodoro_timer-light.png create mode 100644 testdata/snapshots/darwin/priority_indicator-dark.png create mode 100644 testdata/snapshots/darwin/priority_indicator-light.png create mode 100644 testdata/snapshots/darwin/sprint_board-dark.png create mode 100644 testdata/snapshots/darwin/sprint_board-light.png create mode 100644 testdata/snapshots/darwin/status_select-dark.png create mode 100644 testdata/snapshots/darwin/status_select-light.png create mode 100644 testdata/snapshots/darwin/subtask_list-dark.png create mode 100644 testdata/snapshots/darwin/subtask_list-light.png create mode 100644 testdata/snapshots/darwin/task_detail_panel-dark.png create mode 100644 testdata/snapshots/darwin/task_detail_panel-light.png create mode 100644 testdata/snapshots/darwin/task_item-dark.png create mode 100644 testdata/snapshots/darwin/task_item-light.png create mode 100644 testdata/snapshots/darwin/task_list-dark.png create mode 100644 testdata/snapshots/darwin/task_list-light.png create mode 100644 testdata/snapshots/darwin/time_tracker-dark.png create mode 100644 testdata/snapshots/darwin/time_tracker-light.png create mode 100644 testdata/snapshots/darwin/workload_view-dark.png create mode 100644 testdata/snapshots/darwin/workload_view-light.png create mode 100644 time_tracker.go create mode 100644 time_tracker_test.go create mode 100644 workload_view.go create mode 100644 workload_view_test.go diff --git a/assignee_picker.go b/assignee_picker.go new file mode 100644 index 0000000..0d9cc06 --- /dev/null +++ b/assignee_picker.go @@ -0,0 +1,232 @@ +package mujica + +import ( + "fmt" + "log/slog" + "slices" + "strings" + + "github.com/egoist/mygo/ui" + "mujicaui/internal" + "mujicaui/theme" +) + +// AssigneePickerOptions configure an AssigneePicker. +type AssigneePickerOptions struct { + // Max limits selections; zero allows any number. + Max int + Disabled bool + Label string + // Version changes when members or selection change in place. + Version int +} + +type assigneeState struct { + first *Member + n, version int + ready, open bool + query, filtered string + options, shown []SelectOption[string] + members map[string]Member + selected map[string]bool + selectedFirst *string + selectedN, count int + list ui.ListState + focus string +} + +// AssigneePicker searches and selects members, showing their avatars. +func AssigneePicker(c *ui.Context, ids *[]string, members []Member, opts AssigneePickerOptions) ChoiceResult { + if opts.Max < 0 { + panic("mujica: AssigneePicker Max must be non-negative") + } + d, k := Density(c), Tokens(c) + label := opts.Label + if label == "" { + label = msg(c, "assignee_picker.label") + } + row := ui.Row(c).Gap(d.Unit() * 2).AlignItems(ui.Center).Disabled(opts.Disabled) + st := ui.Local(row, "assignees", func() assigneeState { return assigneeState{} }) + var first *Member + var selectedFirst *string + if len(members) > 0 { + first = &members[0] + } + if len(*ids) > 0 { + selectedFirst = &(*ids)[0] + } + dataChanged := !st.ready || st.first != first || st.n != len(members) || st.version != opts.Version + if dataChanged { + st.first, st.n, st.version, st.ready = first, len(members), opts.Version, true + st.members = make(map[string]Member, len(members)) + st.options = make([]SelectOption[string], len(members)) + for i, m := range members { + if _, exists := st.members[m.ID]; exists || m.ID == "" { + panic("mujica: AssigneePicker needs unique non-empty IDs") + } + st.members[m.ID] = m + st.options[i] = SelectOption[string]{Value: m.ID, Label: m.Name} + } + st.shown = nil + } + before := *ids + var trigger *ui.Element + row.Children(func() { + if len(*ids) > 0 { + items := make([]AvatarItem, min(3, len(*ids))) + for i := range items { + items[i] = AvatarItem{Name: st.members[(*ids)[i]].Name} + } + AvatarGroup(c, items, AvatarGroupOptions{Max: 3, Size: 28}) + } + trigger = ui.ButtonBase(c).Disabled(row.IsDisabled()).Role(ui.RolePopUpButton).Label(label) + if trigger.IsDisabled() { + st.open = false + } + if !trigger.IsDisabled() && (trigger.Clicked() || !st.open && trigger.Shortcut(0, ui.KeyDown)) { + st.open, st.query = !st.open, "" + } + if len(*ids) > 0 && !trigger.IsDisabled() && trigger.Shortcut(0, ui.KeyBackspace) { + *ids = slices.Clone((*ids)[:len(*ids)-1]) + } + selectField(c, trigger, st.open, func() { + options := make([]SelectOption[string], min(2, len(*ids))) + for i := range options { + options[i] = SelectOption[string]{Value: (*ids)[i], Label: st.members[(*ids)[i]].Name} + } + multiSelectTags(c, ids, options, MultiSelectOptions{MaxTags: 2, Disabled: trigger.IsDisabled(), Placeholder: msg(c, "assignee_picker.placeholder")}) + }) + ui.PopoverBase(c, trigger, &st.open, func(panel *ui.Element) { + selectPanel(c, panel) + ww, wh := c.Size() + panel.MinWidth(min(ww-8, trigger.Bounds().W)).MaxWidth(max(1, ww-8)).MaxHeight(max(1, wh-8)) + ui.Scroll(c).MaxHeight(max(1, wh-24)).Children(func() { + search := selectSearch(c, &st.query, msg(c, "multi_select.search")) + q := strings.ToLower(strings.TrimSpace(st.query)) + if st.shown == nil || st.filtered != q { + st.shown = make([]SelectOption[string], 0) + for _, o := range st.options { + if strings.Contains(strings.ToLower(o.Label), q) { + st.shown = append(st.shown, o) + } + } + st.filtered = q + st.list.ScrollTo(0, ui.Start) + dataChanged = true + } + if dataChanged || st.selectedFirst != selectedFirst || st.selectedN != len(*ids) || st.selected == nil { + st.selected = make(map[string]bool, len(*ids)) + for _, id := range *ids { + if _, ok := st.members[id]; !ok { + panic("mujica: AssigneePicker selection contains an unknown ID") + } + if st.selected[id] { + panic("mujica: AssigneePicker selection contains duplicate IDs") + } + st.selected[id] = true + } + st.selectedFirst, st.selectedN, st.count = selectedFirst, len(*ids), 0 + for _, o := range st.shown { + if st.selected[o.Value] { + st.count++ + } + } + } + if len(st.shown) == 0 { + selectNote(c, msg(c, "multi_select.no_results")) + return + } + on, full := st.count == len(st.shown), opts.Max > 0 && len(*ids) >= opts.Max + mark := internal.Unchecked + if on { + mark = internal.Checked + } else if st.count > 0 { + mark = internal.Mixed + } + var all *ui.Element + ui.Row(c).MinHeight(d.ControlHeight()).Children(func() { all = multiSelectCheck(c, k, &on, mark, msg(c, "multi_select.all"), full && st.count == 0) }) + if search.Shortcut(0, ui.KeyDown) { + all.Focus() + } + if all.Changed() && !all.IsDisabled() { + *ids = multiSelectAll(*ids, st.shown, on, opts.Max) + } + if all.Shortcut(0, ui.KeyDown) && !all.IsDisabled() { + for i, o := range st.shown { + if full && !st.selected[o.Value] { + continue + } + st.focus = o.Value + st.list.ScrollIntoView(i) + c.Invalidate() + break + } + } + st.list.Key = func(i int) any { return st.shown[i].Value } + ui.List(c, &st.list, len(st.shown), func(i int) { + o := st.shown[i] + selected := st.selected[o.Value] + state := internal.Unchecked + if selected { + state = internal.Checked + } + var cb *ui.Element + ui.Row(c).MinHeight(d.ControlHeight()).Children(func() { cb = multiSelectCheck(c, k, &selected, state, o.Label, full && !selected) }) + if st.focus == o.Value && !cb.IsDisabled() { + cb.Focus() + st.focus = "" + } + if cb.Changed() && !cb.IsDisabled() { + *ids = multiSelectSet(*ids, o.Value, selected) + } + if cb.IsDisabled() { + return + } + to := i + switch { + case cb.Shortcut(0, ui.KeyDown): + to = assigneeNext(st, i, 1, full) + case cb.Shortcut(0, ui.KeyUp): + to = assigneeNext(st, i, -1, full) + case cb.Shortcut(0, ui.KeyHome): + to = assigneeNext(st, -1, 1, full) + case cb.Shortcut(0, ui.KeyEnd): + to = assigneeNext(st, len(st.shown), -1, full) + } + if to != i { + st.focus = st.shown[to].Value + st.list.ScrollIntoView(to) + c.Invalidate() + } + }).Height(min(240, min(float32(len(st.shown))*d.ControlHeight(), max(d.ControlHeight(), wh-140)))).Padding(4) + if opts.Max > 0 { + ui.Text(c, fmt.Sprintf(msg(c, "multi_select.limit"), len(*ids), opts.Max)).FontSize(FontSize(c, theme.CaptionSize)).TextColor(k.TextMuted) + } + }) + }) + }) + changed := !slices.Equal(before, *ids) + if dataChanged && !st.open { + for _, id := range *ids { + if _, ok := st.members[id]; !ok { + panic("mujica: AssigneePicker selection contains an unknown ID") + } + } + } + if changed { + st.selected = nil + slog.Debug("mujica: assignee_picker change", "count", len(*ids)) + c.Invalidate() + } + return ChoiceResult{Element: row, changed: changed} +} + +// assigneeNext skips choices disabled by the selection limit. +func assigneeNext(st *assigneeState, from, direction int, full bool) int { + for i := from + direction; i >= 0 && i < len(st.shown); i += direction { + if !full || st.selected[st.shown[i].Value] { + return i + } + } + return from +} diff --git a/assignee_picker_test.go b/assignee_picker_test.go new file mode 100644 index 0000000..6e7b8fc --- /dev/null +++ b/assignee_picker_test.go @@ -0,0 +1,154 @@ +package mujica + +import ( + "fmt" + "slices" + "testing" + + "github.com/egoist/mygo/ui" + "mujicaui/theme" +) + +func assigneeTester(ids *[]string, opts *AssigneePickerOptions, n *int) *ui.Tester { + return ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + ui.Column(c).Padding(16).Children(func() { + if AssigneePicker(c, ids, projMembers, *opts).Changed() { + *n++ + } + }) + }, 520, 520) +} + +func TestAssigneePickerSearchAndAvatars(t *testing.T) { + ids, n := []string{"saki"}, 0 + tt := assigneeTester(&ids, &AssigneePickerOptions{}, &n) + if !tt.HasText("Sakiko Togawa") { + t.Fatalf("avatar label missing: %v", tt.Texts()) + } + _ = tt.Click("Assignees") + tt.Type("mutsu") + if tt.HasText("Uika Misumi") { + t.Fatalf("search should filter: %v", tt.Texts()) + } + tt.Key(0, ui.KeyDown) + tt.Key(0, ui.KeyEnter) + if !slices.Contains(ids, "mutsu") || n == 0 { + t.Fatalf("ids %v", ids) + } +} + +func TestAssigneePickerMaxDisabledInvalid(t *testing.T) { + ids, n := []string{"saki"}, 0 + tt := assigneeTester(&ids, &AssigneePickerOptions{Disabled: true}, &n) + _ = tt.Click("Assignees") + tt.Type("mutsu") + tt.Key(0, ui.KeyEnter) + if len(ids) != 1 || n != 0 { + t.Fatal("disabled picker changed") + } + defer func() { + if recover() == nil { + t.Fatal("expected panic for an unknown member") + } + }() + bad := []string{"ghost"} + assigneeTester(&bad, &AssigneePickerOptions{}, &n) +} + +func TestAssigneePickerSnapshot(t *testing.T) { + ids := []string{"saki", "mutsu", "uika", "nyamu"} + snapshot(t, "assignee_picker", 560, 80, func(c *ui.Context) { + ui.Column(c).Padding(16).Children(func() { AssigneePicker(c, &ids, projMembers, AssigneePickerOptions{}) }) + }) +} + +func TestAssigneePickerAncestorDisableCloses(t *testing.T) { + ids, disabled := []string{}, false + tt := ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + ui.Column(c).Disabled(disabled).Children(func() { AssigneePicker(c, &ids, projMembers, AssigneePickerOptions{}) }) + }, 500, 520) + if err := tt.Click("Assignees"); err != nil { + t.Fatal(err) + } + disabled = true + tt.Frame() + if tt.HasText("Select all") { + t.Fatal("ancestor-disabled popup remains visible") + } + if err := tt.Click("Sakiko Togawa"); err == nil && len(ids) != 0 { + t.Fatal("disabled popup selected a member") + } +} + +func TestAssigneePickerLargeData(t *testing.T) { + members := make([]Member, 100000) + for i := range members { + members[i] = Member{ID: fmt.Sprint(i), Name: fmt.Sprintf("Member %d", i)} + } + var ids []string + tt := ui.NewTester(func(c *ui.Context) { Use(c, Settings{}); AssigneePicker(c, &ids, members, AssigneePickerOptions{}) }, 500, 520) + if err := tt.Click("Assignees"); err != nil { + t.Fatal(err) + } + if built := len(tt.Texts()); built > 200 { + t.Fatalf("built %d labels", built) + } + tt.Type("Member 99999") + tt.Key(0, ui.KeyDown) + tt.Key(0, ui.KeyEnter) + if !slices.Equal(ids, []string{"99999"}) { + t.Fatalf("selected %v", ids) + } +} + +func TestAssigneePickerFullKeyboardSkipsDisabled(t *testing.T) { + ids, changes := []string{"mutsu"}, 0 + tt := assigneeTester(&ids, &AssigneePickerOptions{Max: 1}, &changes) + if err := tt.Click("Assignees"); err != nil { + t.Fatal(err) + } + tt.Key(0, ui.KeyDown) + tt.Key(0, ui.KeyDown) + tt.Key(0, ui.KeyDown) + tt.Key(0, ui.KeyEnter) + if len(ids) != 0 || changes != 1 { + t.Fatalf("selected = %v, changes = %d", ids, changes) + } +} + +func TestAssigneePickerVersionRefreshAndBulkClear(t *testing.T) { + ids, changes := []string{"saki"}, 0 + opts := &AssigneePickerOptions{} + tt := assigneeTester(&ids, opts, &changes) + if err := tt.Click("Assignees"); err != nil { + t.Fatal(err) + } + ids[0], opts.Version = "mutsu", 1 + tt.Frame() + tt.Type("Mutsumi") + if err := tt.Click("Select all"); err != nil { + t.Fatal(err) + } + if len(ids) != 0 || changes != 1 { + t.Fatalf("selected = %v, changes = %d", ids, changes) + } +} + +func TestAssigneePickerCompactHitAreas(t *testing.T) { + var ids []string + tt := ui.NewTester(func(c *ui.Context) { + Use(c, Settings{Density: theme.Compact}) + ui.Column(c).Padding(16).Children(func() { AssigneePicker(c, &ids, []Member{{ID: "only", Name: "Only Member"}}, AssigneePickerOptions{}) }) + }, 500, 520) + if err := tt.Click("Assignees"); err != nil { + t.Fatal(err) + } + for _, label := range []string{"Select all", "Only Member"} { + r, ok := tt.Find(label) + if !ok || r.H < 28 { + t.Fatalf("%s hit height = %g", label, r.H) + } + } +} diff --git a/burndown_chart.go b/burndown_chart.go new file mode 100644 index 0000000..75a81e0 --- /dev/null +++ b/burndown_chart.go @@ -0,0 +1,216 @@ +package mujica + +import ( + "fmt" + "math" + "slices" + "strconv" + "strings" + + "github.com/egoist/mygo/ui" + + "mujicaui/internal" + "mujicaui/theme" +) + +// BurndownChartOptions configure a BurndownChart. +type BurndownChartOptions struct { + Frame ChartFrame + // Start and End are the sprint's first and last days. + Start, End Date + // Total starts the ideal line, which reaches zero. + Total float64 + // Format writes amounts; nil uses up to two decimals. + Format func(v float64) string + // Version changes when remaining work changes in place. + Version int +} + +// BurndownChart compares remaining work with the ideal line. +func BurndownChart(c *ui.Context, remaining []float64, opts BurndownChartOptions) ChartResult { + datetimeCheckDate("BurndownChart Start", opts.Start) + datetimeCheckDate("BurndownChart End", opts.End) + if opts.Start.IsZero() || opts.End.Compare(opts.Start) <= 0 || !(opts.Total > 0) || math.IsInf(opts.Total, 0) { + panic(fmt.Sprintf("mujica: BurndownChart needs Start < End and a positive Total, got %v..%v %v", opts.Start, opts.End, opts.Total)) + } + days := int((opts.End.civil().Unix()-opts.Start.civil().Unix())/86400) + 1 + if len(remaining) > days { + panic(fmt.Sprintf("mujica: BurndownChart has %d values for %d days", len(remaining), days)) + } + format := opts.Format + if format == nil { + format = func(v float64) string { + return strings.TrimRight(strings.TrimRight(strconv.FormatFloat(v, 'f', 2, 64), "0"), ".") + } + } + ch := newChart(c, opts.Frame) + summary := chartMemo(ch, "burndown-domain", struct { + data string + total float64 + version int + }{chartID(remaining), opts.Total, opts.Version}, func() float64 { + hi := opts.Total + for _, v := range remaining { + if v < 0 || math.IsInf(v, 0) { + panic("mujica: BurndownChart amounts must be non-negative and finite or NaN") + } + if !math.IsNaN(v) { + hi = max(hi, v) + } + } + return hi + }) + cache := ui.Local(ch.res.Element, "burndown-samples", func() burndownCache { return burndownCache{} }) + k := Tokens(c) + pal := internal.Palette(k) + size := FontSize(c, theme.CaptionSize) + ideal := func(i int) float64 { return opts.Total * (1 - float64(i)/float64(days-1)) } + actual := func(i int) float64 { + if i < len(remaining) { + return remaining[i] + } + return math.NaN() + } + lo, top, step := internal.Nice(0, summary, 4) + ticks := internal.Ticks(lo, top, step) + keys := []chartKey{{Name: msg(c, "burndown_chart.actual"), Color: pal[0], Shape: 0}, {Name: msg(c, "burndown_chart.ideal"), Color: pal[5], Shape: 1}} + geom := func(r ui.Rect) (ui.Rect, internal.Linear, internal.Linear) { + plot := chartInset(r, 48, 26) + return plot, internal.Linear{D0: 0, D1: float64(days - 1), R0: float64(plot.X), R1: float64(plot.X + plot.W)}, + internal.Linear{D0: lo, D1: top, R0: float64(plot.Y + plot.H), R1: float64(plot.Y)} + } + n := days + if len(remaining) == 0 { + n = 0 + } + spec := chartSpec{n: n, keys: keys, toggle: true} + spec.pick = func(r ui.Rect, x, y float32) int { + plot, xs, _ := geom(r) + if x < plot.X-8 || x > plot.X+plot.W+8 { + return -1 + } + return max(0, min(days-1, int(math.Round(xs.Invert(x))))) + } + spec.readout = func(i int) string { + day := opts.Start.AddDays(i) + parts := datetimeMonthName(c, day.Month) + " " + strconv.Itoa(day.Day) + if v := actual(i); !math.IsNaN(v) && !ch.hidden(keys[0].Name) { + parts += " · " + keys[0].Name + " " + format(v) + } + if !ch.hidden(keys[1].Name) { + parts += " · " + keys[1].Name + " " + format(math.Round(ideal(i)*100)/100) + } + return parts + } + spec.draw = func(p *ui.Painter, r ui.Rect, active int) { + plot, xs, ys := geom(r) + internal.AxisY(p, plot, ys, ticks, func(v float64) string { return internal.FormatTick(v, step) }, size, k) + var tx []float32 + var tl []string + stride := max(1, int(math.Ceil(float64(days)/max(float64(plot.W)/70, 1)))) + for i := 0; i < days; i += stride { + tx = append(tx, xs.Map(float64(i))) + tl = append(tl, strconv.Itoa(opts.Start.AddDays(i).Day)) + } + internal.AxisX(p, plot, tx, tl, size, k) + pt := func(i int, v float64) (float32, float32) { + return internal.Snap(p, xs.Map(float64(i))), internal.Snap(p, ys.Map(v)) + } + if !ch.hidden(keys[1].Name) { + x0, y0 := pt(0, ideal(0)) + x1, y1 := pt(days-1, 0) + burndownDashed(p, x0, y0, x1, y1, keys[1].Color) + } + if !ch.hidden(keys[0].Name) { + var line ui.Path + open := false + width := max(1, int(plot.W*p.Scale())) + data := chartID(remaining) + if cache.data != data || cache.version != opts.Version || cache.days != days || cache.width != width { + cache.data, cache.version, cache.days, cache.width = data, opts.Version, days, width + cache.points = burndownSamples(remaining, days, width) + } + lastRun := -1 + for _, point := range cache.points { + x, y := pt(point.index, remaining[point.index]) + if open && lastRun == point.run { + line.LineTo(x, y) + } else { + line.MoveTo(x, y) + open = true + } + lastRun = point.run + internal.Marker(p, 0, x, y, 7, keys[0].Color) + } + p.StrokePath(&line, 2, keys[0].Color) + } + if active >= 0 { + ax, _ := pt(active, 0) + p.Line(ax, plot.Y, ax, plot.Y+plot.H, 1, k.TextMuted) + } + } + res, _ := ch.build(spec) + return res +} + +// burndownDashed draws the ideal line with a distinct pattern. +func burndownDashed(p *ui.Painter, x0, y0, x1, y1 float32, col ui.Color) { + l := float32(math.Hypot(float64(x1-x0), float64(y1-y0))) + var path ui.Path + for t := float32(0); t < l; t += 10 { + e := min(t+6, l) + path.MoveTo(internal.Snap(p, x0+(x1-x0)*t/l), internal.Snap(p, y0+(y1-y0)*t/l)) + path.LineTo(internal.Snap(p, x0+(x1-x0)*e/l), internal.Snap(p, y0+(y1-y0)*e/l)) + } + p.StrokePath(&path, 1.5, col) +} + +type burndownPoint struct{ index, run int } +type burndownCache struct { + data string + version, days, width int + points []burndownPoint +} + +// burndownSamples keeps four finite points per device pixel. +func burndownSamples(values []float64, days, width int) []burndownPoint { + var out []burndownPoint + run := 0 + for i := 0; i < len(values); { + bucket := i * width / max(days-1, 1) + var first, low, high, last burndownPoint + count := 0 + for i < len(values) && i*width/max(days-1, 1) == bucket { + v := values[i] + if math.IsNaN(v) { + run++ + i++ + continue + } + point := burndownPoint{index: i, run: run} + if count == 0 { + first, low, high = point, point, point + } + if v < values[low.index] { + low = point + } + if v > values[high.index] { + high = point + } + last = point + count++ + i++ + } + if count == 0 { + continue + } + points := []burndownPoint{first, low, high, last} + slices.SortFunc(points, func(a, b burndownPoint) int { return a.index - b.index }) + for j, point := range points { + if j == 0 || points[j-1].index != point.index { + out = append(out, point) + } + } + } + return out +} diff --git a/burndown_chart_test.go b/burndown_chart_test.go new file mode 100644 index 0000000..f9c00b8 --- /dev/null +++ b/burndown_chart_test.go @@ -0,0 +1,145 @@ +package mujica + +import ( + "math" + "testing" + + "github.com/egoist/mygo/ui" +) + +var burndownRemaining = []float64{40, 38, 35, 35, 30, 26, math.NaN(), 20, 19} + +func burndownTester(remaining []float64, opts BurndownChartOptions, points *[]int) *ui.Tester { + opts.Frame.Label = "Sprint 12 burndown" + opts.Start, opts.End = oct(1), oct(14) + if opts.Total == 0 { + opts.Total = 40 + } + return ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + ui.Column(c).Padding(16).Width(600).Children(func() { + if r := BurndownChart(c, remaining, opts); r.Changed() { + *points = append(*points, r.Point) + } + }) + }, 640, 400) +} + +func TestBurndownChartReadoutAndKeys(t *testing.T) { + var points []int + tt := burndownTester(burndownRemaining, BurndownChartOptions{}, &points) + if !tt.HasText("Remaining") || !tt.HasText("Ideal") { + t.Fatalf("legend %v", tt.Texts()) + } + tt.Key(0, ui.KeyTab) + tt.Key(0, ui.KeyTab) + tt.Key(0, ui.KeyTab) + tt.Key(0, ui.KeyRight) + tt.Key(0, ui.KeyRight) + tt.Key(0, ui.KeyRight) + if !tt.HasText("October 3 · Remaining 35 · Ideal 33.85") { + t.Fatalf("readout %v", tt.Texts()) + } + if a := tt.Announcements(); len(a) == 0 || a[len(a)-1] != "October 3 · Remaining 35 · Ideal 33.85" { + t.Fatalf("announce %q", a) + } + tt.Key(0, ui.KeyEnd) + if !tt.HasText("October 14 · Ideal 0") { + t.Fatalf("future day shows only the ideal: %v", tt.Texts()) + } + _ = tt.Click("Ideal") + tt.Key(0, ui.KeyTab) + tt.Key(0, ui.KeyHome) + if !tt.HasText("October 1 · Remaining 40") || tt.HasText("Ideal 40") { + t.Fatal("hidden series in readout") + } +} + +func TestBurndownChartEmptyAndInvalid(t *testing.T) { + var points []int + tt := burndownTester(nil, BurndownChartOptions{Frame: ChartFrame{Status: DataLoading}}, &points) + if !tt.HasText("Loading") || tt.HasText("October") { + t.Fatalf("loading state %v", tt.Texts()) + } + for _, bad := range []BurndownChartOptions{{Total: -1}} { + func() { + defer func() { + if recover() == nil { + t.Error("expected panic") + } + }() + burndownTester(nil, bad, &points) + }() + } + defer func() { + if recover() == nil { + t.Fatal("expected panic for too many days") + } + }() + burndownTester(make([]float64, 20), BurndownChartOptions{}, &points) +} + +func TestBurndownChartSnapshot(t *testing.T) { + snapshot(t, "burndown_chart", 620, 340, func(c *ui.Context) { + ui.Column(c).Padding(16).Children(func() { + BurndownChart(c, burndownRemaining, BurndownChartOptions{Frame: ChartFrame{Label: "Burndown"}, Start: oct(1), End: oct(14), Total: 40}) + }) + }) +} + +func TestBurndownChartInvalidAmounts(t *testing.T) { + for _, values := range [][]float64{{-1}, {math.Inf(1)}} { + t.Run("amount", func(t *testing.T) { + defer func() { + if recover() == nil { + t.Fatal("expected invalid amount panic") + } + }() + var points []int + burndownTester(values, BurndownChartOptions{}, &points) + }) + } +} + +func TestBurndownChartEmptyFailedDisabled(t *testing.T) { + var points []int + tt := burndownTester(nil, BurndownChartOptions{}, &points) + if !tt.HasText("No data") { + t.Fatal("missing empty state") + } + tt = burndownTester(nil, BurndownChartOptions{Frame: ChartFrame{Status: DataFailed, Error: "Unavailable"}}, &points) + if !tt.HasText("Unavailable") { + t.Fatal("missing error state") + } + tt = ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + ui.Column(c).Disabled(true).Children(func() { + r := BurndownChart(c, burndownRemaining, BurndownChartOptions{Frame: ChartFrame{Label: "Burndown"}, Start: oct(1), End: oct(14), Total: 40}) + if _, ok := r.Toggled(); ok { + t.Fatal("disabled legend toggled") + } + }) + }, 600, 340) + _ = tt.Click("Ideal") + tt.Key(0, ui.KeyTab) + tt.Key(0, ui.KeyRight) + if len(tt.Announcements()) != 0 { + t.Fatal("disabled chart announced a point") + } +} + +func TestBurndownChartLargeData(t *testing.T) { + values := make([]float64, 100000) + for i := range values { + values[i] = float64(100000 - i) + } + opts := BurndownChartOptions{Frame: ChartFrame{Label: "Large burndown"}, Start: Date{Year: 1900, Month: 1, Day: 1}, End: Date{Year: 1900, Month: 1, Day: 1}.AddDays(99999), Total: 100000} + ui.NewTester(func(c *ui.Context) { Use(c, Settings{}); BurndownChart(c, values, opts) }, 640, 360) + points := burndownSamples(values, 100000, 600) + if len(points) > 2404 { + t.Fatalf("built %d points", len(points)) + } + if points[0].index != 0 || points[len(points)-1].index != 99999 { + t.Fatal("downsampling lost endpoints") + } +} diff --git a/docs/components/361-kanban-board.md b/docs/components/361-kanban-board.md new file mode 100644 index 0000000..ab3fd4e --- /dev/null +++ b/docs/components/361-kanban-board.md @@ -0,0 +1,43 @@ +# 361 KanbanBoard · 任务看板 + +## 用途 + +任务看板用于项目管理界面。 + +## 最小示例 + +```go +statuses := []mujica.WorkflowStatus{{ID: "todo", Name: "To do", Group: mujica.StatusUnstarted}, {ID: "done", Name: "Done", Group: mujica.StatusCompleted}} +tasks := []mujica.Task{{ID: "ENG-1", Title: "Plan the release", Status: "todo"}} +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + r := mujica.KanbanBoard(c, &tasks, mujica.KanbanBoardOptions{Columns: []mujica.KanbanColumn{{Status: "todo"}, {Status: "done", WIP: 2}}, Statuses: statuses}) + if move, ok := r.Moved(); ok { + log.Println("move", move.ID, move.To, move.Index) + } + if id, ok := r.Opened(); ok { + log.Println("open", id) + } +} +ui.Render(view, 1000, 700, 1) +``` + +## 参数 + +`tasks *[]Task` 为受控数据。`Columns` 至少一列;`Statuses` 提供其状态;`Members`、`Labels` 解析关联 ID。`Version` 标识原地数据更改;`Disabled` 禁用移动与打开;`Label` 为无障碍名称。 + +## 状态 + +业务状态由调用方持有;主题、密度与文本缩放遵循窗口设置。交互控件提供焦点、悬停和禁用状态;展示组件保留语义名称。 + +## 事件 + +`Moved()` 返回已应用的 `KanbanMove{ID, From, To, Index}`;`Opened()` 返回卡片 ID。 + +## 键盘操作 + +Tab 聚焦卡片;Enter/Space 打开;Alt+左右跨列;Alt+上下排序;可拖放到卡片之前或列末。 + +## 限制 + +修改原切片任务时递增 `Version`。列按 `Columns` 顺序排列;`WIP=0` 表示自由容量。网络与持久化由调用方处理。 diff --git a/docs/components/362-task-list.md b/docs/components/362-task-list.md new file mode 100644 index 0000000..b707d4f --- /dev/null +++ b/docs/components/362-task-list.md @@ -0,0 +1,44 @@ +# 362 TaskList · 任务列表 + +## 用途 + +任务列表用于项目管理界面。 + +## 最小示例 + +```go +statuses := []mujica.WorkflowStatus{{ID: "todo", Name: "To do", Group: mujica.StatusUnstarted}, {ID: "done", Name: "Done", Group: mujica.StatusCompleted}} +tasks := []mujica.Task{{ID: "ENG-1", Title: "Plan the release", Status: "todo"}} +filter := mujica.TaskShowAll +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + r := mujica.TaskList(c, tasks, &filter, mujica.TaskListOptions{GroupBy: mujica.TaskGroupStatus, Statuses: statuses}) + if id, ok := r.Changed(); ok { + log.Println("edit", id) + } + if id, ok := r.Opened(); ok { + log.Println("open", id) + } +} +ui.Render(view, 1000, 700, 1) +``` + +## 参数 + +`tasks []Task`、`filter *TaskFilter`;`GroupBy` 为无分组、状态或优先级。按状态分组必传 `Statuses`。`Members` 解析负责人;`Today` 为逾期基准;`Version`、`Disabled`、`Label` 控制数据刷新与交互。 + +## 状态 + +业务状态由调用方持有;主题、密度与文本缩放遵循窗口设置。交互控件提供焦点、悬停和禁用状态;展示组件保留语义名称。 + +## 事件 + +`Changed()` 返回编辑任务 ID;`Opened()` 返回打开任务 ID。筛选值直接写入 `filter`。 + +## 键盘操作 + +Tab 在筛选器和任务控件间移动;空格切换完成;Enter 打开;F2 编辑标题。 + +## 限制 + +可见行虚拟化;外部原地数据修改递增 `Version`。列表需父容器提供有限高度。 diff --git a/docs/components/363-task-item.md b/docs/components/363-task-item.md new file mode 100644 index 0000000..3c7b7ba --- /dev/null +++ b/docs/components/363-task-item.md @@ -0,0 +1,42 @@ +# 363 TaskItem · 任务行 + +## 用途 + +任务行用于项目管理界面。 + +## 最小示例 + +```go +task := mujica.Task{ID: "ENG-1", Title: "Plan the release", Status: "todo", Priority: mujica.PriorityHigh} +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + r := mujica.TaskItem(c, &task, mujica.TaskItemOptions{}) + if id, ok := r.Changed(); ok { + log.Println("edit", id) + } + if id, ok := r.Opened(); ok { + log.Println("open", id) + } +} +ui.Render(view, 1000, 700, 1) +``` + +## 参数 + +`task *Task` 保存标题、完成、优先级、日期、负责人;`Members` 解析负责人;`Today` 默认当前日期;`Disabled` 禁用输入。 + +## 状态 + +业务状态由调用方持有;主题、密度与文本缩放遵循窗口设置。交互控件提供焦点、悬停和禁用状态;展示组件保留语义名称。 + +## 事件 + +`Changed()` 返回完成或标题编辑的任务 ID;`Opened()` 返回打开任务 ID。 + +## 键盘操作 + +Tab 在复选框和标题间移动;空格切换完成;Enter 打开;F2 或双击开始编辑;Enter 保存;Escape 取消。 + +## 限制 + +任务标题保存时去除首尾空白;空标题保留编辑态。业务字段来自调用方。 diff --git a/docs/components/364-task-detail-panel.md b/docs/components/364-task-detail-panel.md new file mode 100644 index 0000000..0736810 --- /dev/null +++ b/docs/components/364-task-detail-panel.md @@ -0,0 +1,43 @@ +# 364 TaskDetailPanel · 任务详情侧栏 + +## 用途 + +任务详情侧栏用于项目管理界面。 + +## 最小示例 + +```go +statuses := []mujica.WorkflowStatus{{ID: "todo", Name: "To do", Group: mujica.StatusUnstarted}, {ID: "done", Name: "Done", Group: mujica.StatusCompleted}} +task := mujica.Task{ID: "ENG-1", Title: "Plan the release", Status: "todo", Priority: mujica.PriorityHigh} +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + r := mujica.TaskDetailPanel(c, &task, mujica.TaskDetailPanelOptions{Statuses: statuses, Activity: func() { ui.Text(c, "Release planned") }}) + if r.Changed() { + log.Println("task edited", task.ID) + } + if r.Closed() { + log.Println("close", task.ID) + } +} +ui.Render(view, 1000, 700, 1) +``` + +## 参数 + +`task *Task` 为受控任务;`Statuses`、`Members`、`Labels` 为关联数据;`Activity func()` 构建活动记录;`Today`、`Disabled` 控制日期与交互;`Version` 用于外部原地修改任务、成员或子任务。 + +## 状态 + +业务状态由调用方持有;主题、密度与文本缩放遵循窗口设置。交互控件提供焦点、悬停和禁用状态;展示组件保留语义名称。 + +## 事件 + +`Changed()` 表示字段更改;`Closed()` 表示关闭按钮或 Escape。由调用方控制侧栏显隐。 + +## 键盘操作 + +Tab 在字段间移动;选择框使用方向键和 Enter;Escape 返回关闭事件;子任务 Enter 新增。 + +## 限制 + +组件是可嵌入的侧栏内容;容器负责布局与滚动。活动记录通过 `Activity` 插槽构建;外部原地更改后递增 `Version`。 diff --git a/docs/components/365-subtask-list.md b/docs/components/365-subtask-list.md new file mode 100644 index 0000000..c6e656c --- /dev/null +++ b/docs/components/365-subtask-list.md @@ -0,0 +1,38 @@ +# 365 SubtaskList · 子任务列表 + +## 用途 + +子任务列表用于项目管理界面。 + +## 最小示例 + +```go +subtasks := []mujica.Subtask{{ID: "one", Title: "Review", Done: true}, {ID: "two", Title: "Ship"}} +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + if mujica.SubtaskList(c, &subtasks, mujica.SubtaskListOptions{}).Changed() { + log.Println("subtasks changed", len(subtasks)) + } +} +ui.Render(view, 1000, 700, 1) +``` + +## 参数 + +`subs *[]Subtask` 保存子任务;`Disabled` 禁用所有操作;`Label` 为进度与列表名称;`Version` 用于外部原地修改。 + +## 状态 + +业务状态由调用方持有;主题、密度与文本缩放遵循窗口设置。交互控件提供焦点、悬停和禁用状态;展示组件保留语义名称。 + +## 事件 + +`Changed()` 表示勾选、新增、删除或排序;变更已写入切片。 + +## 键盘操作 + +Tab 移动;Space 切换完成;新增输入框 Enter 提交;Alt+上下排序;拖动握柄排序。 + +## 限制 + +新增 ID 按 `sub-N` 生成;原有 ID 必须唯一且非空。空白新增内容保留输入。列表虚拟化,最多显示八行高度。 diff --git a/docs/components/368-sprint-board.md b/docs/components/368-sprint-board.md new file mode 100644 index 0000000..b3ca3aa --- /dev/null +++ b/docs/components/368-sprint-board.md @@ -0,0 +1,44 @@ +# 368 SprintBoard · 迭代看板 + +## 用途 + +迭代看板用于项目管理界面。 + +## 最小示例 + +```go +statuses := []mujica.WorkflowStatus{{ID: "todo", Name: "To do", Group: mujica.StatusUnstarted}, {ID: "done", Name: "Done", Group: mujica.StatusCompleted}} +tasks := []mujica.Task{{ID: "ENG-1", Title: "Plan the release", Status: "todo"}} +sprint := mujica.Sprint{Name: "Release sprint", Goal: "Ship", Start: mujica.Date{Year: 2026, Month: 10, Day: 1}, End: mujica.Date{Year: 2026, Month: 10, Day: 14}} +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + r := mujica.SprintBoard(c, sprint, &tasks, mujica.SprintBoardOptions{Board: mujica.KanbanBoardOptions{Columns: []mujica.KanbanColumn{{Status: "todo"}, {Status: "done", WIP: 2}}, Statuses: statuses}}) + if move, ok := r.Moved(); ok { + log.Println("move", move.ID, move.To) + } + if id, ok := r.Opened(); ok { + log.Println("open", id) + } +} +ui.Render(view, 1000, 700, 1) +``` + +## 参数 + +`Sprint{Name, Goal, Start, End}`;日期必填且顺序有效。`Board` 为看板参数;`Today` 默认当前日期。 + +## 状态 + +业务状态由调用方持有;主题、密度与文本缩放遵循窗口设置。交互控件提供焦点、悬停和禁用状态;展示组件保留语义名称。 + +## 事件 + +与 `KanbanBoard` 相同;移动更新受控任务并刷新完成数。 + +## 键盘操作 + +看板卡片支持 Tab、Enter/Space、Alt+方向键与拖放。 + +## 限制 + +完成度按工作流状态统计,取消状态排除。日期为包含首尾的区间;外部原地修改递增 `Board.Version`。 diff --git a/docs/components/369-burndown-chart.md b/docs/components/369-burndown-chart.md new file mode 100644 index 0000000..241a4dd --- /dev/null +++ b/docs/components/369-burndown-chart.md @@ -0,0 +1,46 @@ +# 369 BurndownChart · 燃尽图 + +## 用途 + +燃尽图用于项目管理界面。 + +## 最小示例 + +```go +remaining := []float64{40, 32, 25, 18} +opts := mujica.BurndownChartOptions{Frame: mujica.ChartFrame{Label: "Release burndown"}, Start: mujica.Date{Year: 2026, Month: 10, Day: 1}, End: mujica.Date{Year: 2026, Month: 10, Day: 14}, Total: 40} +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + r := mujica.BurndownChart(c, remaining, opts) + if r.Changed() { + log.Println("point", r.Point) + } + if name, ok := r.Toggled(); ok { + log.Println("series", name) + } + if r.Retried() { + log.Println("retry") + } +} +ui.Render(view, 1000, 700, 1) +``` + +## 参数 + +`Frame` 提供必填 `Label`、默认 240 DIP `Height`、`Status/Error/Empty`;`Start < End`,`Total > 0`;`Format` 自定义读数;`Version` 刷新原地修改。 + +## 状态 + +业务状态由调用方持有;主题、密度与文本缩放遵循窗口设置。交互控件提供焦点、悬停和禁用状态;展示组件保留语义名称。 + +## 事件 + +`Changed()` 与 `Point` 返回活跃日期索引;`Toggled()` 返回图例名称;`Retried()` 请求重试。 + +## 键盘操作 + +Tab 聚焦图例与图表;Space 切换图例;方向键逐日读取;Home/End 首尾;Escape 清除读数。 + +## 限制 + +实际值以 `NaN` 表示缺失;数组从 Start 连续对应日期。数据加载与失败由调用方提供;数值须有限且非负。 diff --git a/docs/components/370-priority-indicator.md b/docs/components/370-priority-indicator.md new file mode 100644 index 0000000..76fe81e --- /dev/null +++ b/docs/components/370-priority-indicator.md @@ -0,0 +1,36 @@ +# 370 PriorityIndicator · 优先级指示 + +## 用途 + +优先级指示用于项目管理界面。 + +## 最小示例 + +```go +priority := mujica.PriorityHigh +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + mujica.PriorityIndicator(c, priority, mujica.PriorityIndicatorOptions{}) +} +ui.Render(view, 1000, 700, 1) +``` + +## 参数 + +`p Priority` 决定等级;`IconOnly` 默认 false,开启后保留无障碍名称。 + +## 状态 + +业务状态由调用方持有;主题、密度与文本缩放遵循窗口设置。交互控件提供焦点、悬停和禁用状态;展示组件保留语义名称。 + +## 事件 + +静态展示。 + +## 键盘操作 + +静态展示,通过无障碍名称读取完整等级。 + +## 限制 + +等级仅接受 None、Low、Medium、High、Urgent。 diff --git a/docs/components/371-status-select.md b/docs/components/371-status-select.md new file mode 100644 index 0000000..e8b5603 --- /dev/null +++ b/docs/components/371-status-select.md @@ -0,0 +1,39 @@ +# 371 StatusSelect · 状态选择 + +## 用途 + +状态选择用于项目管理界面。 + +## 最小示例 + +```go +statuses := []mujica.WorkflowStatus{{ID: "todo", Name: "To do", Group: mujica.StatusUnstarted}, {ID: "done", Name: "Done", Group: mujica.StatusCompleted}} +value := "todo" +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + if mujica.StatusSelect(c, &value, statuses, mujica.StatusSelectOptions{}).Changed() { + log.Println("status", value) + } +} +ui.Render(view, 1000, 700, 1) +``` + +## 参数 + +`value *string`、`statuses []WorkflowStatus`;状态 `Group` 为 Backlog、Unstarted、Started、Completed、Canceled;`Disabled` 和 `Label` 控制交互与名称。 + +## 状态 + +业务状态由调用方持有;主题、密度与文本缩放遵循窗口设置。交互控件提供焦点、悬停和禁用状态;展示组件保留语义名称。 + +## 事件 + +`Changed()` 表示受控状态 ID 更改。 + +## 键盘操作 + +Enter/Space 或上下键打开;上下、Home/End 定位;Enter 确认;Escape 关闭。 + +## 限制 + +状态 ID 唯一且非空;当前值须属于状态列表。状态按五个工作流阶段分组。 diff --git a/docs/components/372-assignee-picker.md b/docs/components/372-assignee-picker.md new file mode 100644 index 0000000..4fa99db --- /dev/null +++ b/docs/components/372-assignee-picker.md @@ -0,0 +1,39 @@ +# 372 AssigneePicker · 负责人选择 + +## 用途 + +负责人选择用于项目管理界面。 + +## 最小示例 + +```go +members := []mujica.Member{{ID: "ann", Name: "Ann"}, {ID: "ben", Name: "Ben"}} +ids := []string{"ann"} +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + if mujica.AssigneePicker(c, &ids, members, mujica.AssigneePickerOptions{Max: 2}).Changed() { + log.Println("assignees", ids) + } +} +ui.Render(view, 1000, 700, 1) +``` + +## 参数 + +`ids *[]string`、`members []Member`;`Max=0` 表示自由数量;`Disabled`、`Label` 控制交互与名称;`Version` 用于外部原地修改。 + +## 状态 + +业务状态由调用方持有;主题、密度与文本缩放遵循窗口设置。交互控件提供焦点、悬停和禁用状态;展示组件保留语义名称。 + +## 事件 + +`Changed()` 表示受控成员 ID 列表更改。 + +## 键盘操作 + +Enter/Space 打开;输入搜索;下键进入选项;Space/Enter 勾选;Backspace 移除最后一项;Escape 关闭。 + +## 限制 + +成员 ID 唯一且非空;所有已选 ID 必须存在。头像使用姓名回退;网络成员查询由调用方提供。搜索结果按可见行虚拟化。 diff --git a/docs/components/373-due-date-picker.md b/docs/components/373-due-date-picker.md new file mode 100644 index 0000000..10e8c4b --- /dev/null +++ b/docs/components/373-due-date-picker.md @@ -0,0 +1,38 @@ +# 373 DueDatePicker · 截止日期选择 + +## 用途 + +截止日期选择用于项目管理界面。 + +## 最小示例 + +```go +var due mujica.Date +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + if mujica.DueDatePicker(c, &due, mujica.DueDatePickerOptions{}).Changed() { + log.Println("due", due) + } +} +ui.Render(view, 1000, 700, 1) +``` + +## 参数 + +`value *Date`;`Today` 默认当前日期;`WeekStart` 默认本地周起始;`Done`、`Disabled`、`Label` 控制展示与交互。 + +## 状态 + +业务状态由调用方持有;主题、密度与文本缩放遵循窗口设置。交互控件提供焦点、悬停和禁用状态;展示组件保留语义名称。 + +## 事件 + +`Changed()` 表示日期更改;返回 `Input` 为日期编辑器。 + +## 键盘操作 + +Tab 到快捷项、日期输入与日历按钮;Enter 选择;日历方向键移动;Escape 关闭。 + +## 限制 + +零日期表示清空;Next week 选择下一个周起始日。`Done` 让已完成任务显示普通日期。 diff --git a/docs/components/374-label-manager.md b/docs/components/374-label-manager.md new file mode 100644 index 0000000..5a188f0 --- /dev/null +++ b/docs/components/374-label-manager.md @@ -0,0 +1,39 @@ +# 374 LabelManager · 标签管理 + +## 用途 + +标签管理用于项目管理界面。 + +## 最小示例 + +```go +labels := []mujica.TaskLabel{{ID: "ui", Name: "UI", Color: mujica.EventInfo}} +selected := []string{} +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + if mujica.LabelManager(c, &labels, &selected, mujica.LabelManagerOptions{}).Changed() { + log.Println("labels changed", len(labels), selected) + } +} +ui.Render(view, 1000, 700, 1) +``` + +## 参数 + +`labels *[]TaskLabel`、`selected *[]string`;ID 非空唯一;`Color` 为六种 EventColor;`Disabled`、`Label` 控制交互与名称;`Version` 用于外部原地修改。 + +## 状态 + +业务状态由调用方持有;主题、密度与文本缩放遵循窗口设置。交互控件提供焦点、悬停和禁用状态;展示组件保留语义名称。 + +## 事件 + +`Changed()` 表示选择、创建、重命名、颜色或删除变更。删除同步移除已选 ID。 + +## 键盘操作 + +Tab 移动;Space 勾选;新增输入 Enter 创建;编辑颜色按钮打开编辑;Enter 保存名称;Escape 结束编辑。 + +## 限制 + +名称去除首尾空白并按大小写折叠检测重复;颜色选中立即提交。列表虚拟化,最多显示八行高度。 diff --git a/docs/components/375-issue-card.md b/docs/components/375-issue-card.md new file mode 100644 index 0000000..ffa2eed --- /dev/null +++ b/docs/components/375-issue-card.md @@ -0,0 +1,39 @@ +# 375 IssueCard · 任务卡片 + +## 用途 + +任务卡片用于项目管理界面。 + +## 最小示例 + +```go +statuses := []mujica.WorkflowStatus{{ID: "todo", Name: "To do", Group: mujica.StatusUnstarted}, {ID: "done", Name: "Done", Group: mujica.StatusCompleted}} +task := mujica.Task{ID: "ENG-1", Title: "Plan the release", Status: "todo", Priority: mujica.PriorityHigh} +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + if mujica.IssueCard(c, task, mujica.IssueCardOptions{Statuses: statuses}).Clicked() { + log.Println("open", task.ID) + } +} +ui.Render(view, 1000, 700, 1) +``` + +## 参数 + +`task Task`;`Statuses` 解析状态;`Members`、`Labels` 解析关联数据;`Selected` 显示选中底色与边标;`Disabled` 禁用激活。 + +## 状态 + +业务状态由调用方持有;主题、密度与文本缩放遵循窗口设置。交互控件提供焦点、悬停和禁用状态;展示组件保留语义名称。 + +## 事件 + +返回 `Element.Clicked()` 为卡片激活。 + +## 键盘操作 + +Tab 聚焦;Enter/Space 激活。 + +## 限制 + +长标题最多两行;头像组折叠到三个;字段与关联数据由调用方提供。 diff --git a/docs/components/376-issue-id-badge.md b/docs/components/376-issue-id-badge.md new file mode 100644 index 0000000..b966df7 --- /dev/null +++ b/docs/components/376-issue-id-badge.md @@ -0,0 +1,38 @@ +# 376 IssueIdBadge · 任务编号 + +## 用途 + +任务编号用于项目管理界面。 + +## 最小示例 + +```go +id := "ENG-123" +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + if mujica.IssueIdBadge(c, id, mujica.IssueIdBadgeOptions{Copyable: true}).Changed() { + log.Println("copied", id) + } +} +ui.Render(view, 1000, 700, 1) +``` + +## 参数 + +`id string`;`Copyable` 默认 false;`Disabled` 禁用复制。 + +## 状态 + +业务状态由调用方持有;主题、密度与文本缩放遵循窗口设置。交互控件提供焦点、悬停和禁用状态;展示组件保留语义名称。 + +## 事件 + +`Changed()` 表示复制,剪贴板由组件写入;同时朗读复制结果。 + +## 键盘操作 + +Copyable 开启时 Tab 聚焦,Enter/Space 复制。 + +## 限制 + +编号匹配大写项目名、连字符、正整数,例如 ENG-123。复制提示保持 1500 ms。 diff --git a/docs/components/377-milestone-progress.md b/docs/components/377-milestone-progress.md new file mode 100644 index 0000000..1f454c9 --- /dev/null +++ b/docs/components/377-milestone-progress.md @@ -0,0 +1,36 @@ +# 377 MilestoneProgress · 里程碑进度 + +## 用途 + +里程碑进度用于项目管理界面。 + +## 最小示例 + +```go +milestone := mujica.Milestone{Title: "Release", Due: mujica.Date{Year: 2026, Month: 10, Day: 14}, Done: 3, Total: 8} +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + mujica.MilestoneProgress(c, milestone, mujica.MilestoneProgressOptions{}) +} +ui.Render(view, 1000, 700, 1) +``` + +## 参数 + +`Milestone{Title, Due, Done, Total}`;`Today` 默认当前日期;零 Due 表示无日期。 + +## 状态 + +业务状态由调用方持有;主题、密度与文本缩放遵循窗口设置。交互控件提供焦点、悬停和禁用状态;展示组件保留语义名称。 + +## 事件 + +静态展示。 + +## 键盘操作 + +静态展示,进度条通过无障碍名称与百分比读取。 + +## 限制 + +要求 0 ≤ Done ≤ Total;零总量显示 0%;完成后显示达成标记。 diff --git a/docs/components/378-workload-view.md b/docs/components/378-workload-view.md new file mode 100644 index 0000000..0ae8335 --- /dev/null +++ b/docs/components/378-workload-view.md @@ -0,0 +1,36 @@ +# 378 WorkloadView · 成员负载 + +## 用途 + +成员负载用于项目管理界面。 + +## 最小示例 + +```go +loads := []mujica.Workload{{Member: mujica.Member{ID: "ann", Name: "Ann"}, Assigned: 46, Capacity: 40}} +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + mujica.WorkloadView(c, loads, mujica.WorkloadViewOptions{}) +} +ui.Render(view, 1000, 700, 1) +``` + +## 参数 + +`loads []Workload`;`Unit` 默认小时;`Label` 为列表名称;`Version` 刷新原地数据更改。 + +## 状态 + +业务状态由调用方持有;主题、密度与文本缩放遵循窗口设置。交互控件提供焦点、悬停和禁用状态;展示组件保留语义名称。 + +## 事件 + +静态展示。 + +## 键盘操作 + +静态行通过无障碍名称读取负载与超出量;滚动查看更多成员。 + +## 限制 + +成员 ID 唯一;Assigned 有限非负,Capacity 有限正数。可见行虚拟化;父容器需提供有限高度;原地修改递增 Version。 diff --git a/docs/components/379-time-tracker.md b/docs/components/379-time-tracker.md new file mode 100644 index 0000000..ccc53b9 --- /dev/null +++ b/docs/components/379-time-tracker.md @@ -0,0 +1,38 @@ +# 379 TimeTracker · 工时计时 + +## 用途 + +工时计时用于项目管理界面。 + +## 最小示例 + +```go +var state mujica.TimeTrackerState +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + if mujica.TimeTracker(c, &state, mujica.TimeTrackerOptions{}).Changed() { + log.Println("tracked", state.Total(c.Now())) + } +} +ui.Render(view, 1000, 700, 1) +``` + +## 参数 + +`state *TimeTrackerState`;`Now` 固定时钟供测试;`Disabled` 禁用操作;`Label` 为读数名称。 + +## 状态 + +业务状态由调用方持有;主题、密度与文本缩放遵循窗口设置。交互控件提供焦点、悬停和禁用状态;展示组件保留语义名称。 + +## 事件 + +`Changed()` 表示开始、停止或手动修正;`Entries` 和 `Adjust` 由调用方持有。 + +## 键盘操作 + +Tab 移动;Enter/Space 开始停止;停止后打开修正,编辑时长,Apply 提交。 + +## 限制 + +只有最后一项可处于运行态;时段按顺序且互不重叠;累计时长非负。隐藏时保留计时状态。 diff --git a/docs/components/380-pomodoro-timer.md b/docs/components/380-pomodoro-timer.md new file mode 100644 index 0000000..5ab2793 --- /dev/null +++ b/docs/components/380-pomodoro-timer.md @@ -0,0 +1,42 @@ +# 380 PomodoroTimer · 番茄钟 + +## 用途 + +番茄钟用于项目管理界面。 + +## 最小示例 + +```go +var state mujica.PomodoroState +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + r := mujica.PomodoroTimer(c, &state, mujica.PomodoroTimerOptions{Focus: 25 * time.Minute}) + if r.Changed() { + log.Println("timer", state.Phase(), state.Running()) + } + if phase, ok := r.Finished(); ok { + log.Println("finished", phase) + } +} +ui.Render(view, 1000, 700, 1) +``` + +## 参数 + +`state *PomodoroState`;`Focus/Break/LongBreak` 默认 25/5/15 分钟;`LongEvery` 默认 4;`Now` 固定时钟;`Disabled`、`Label` 控制交互与名称。 + +## 状态 + +业务状态由调用方持有;主题、密度与文本缩放遵循窗口设置。交互控件提供焦点、悬停和禁用状态;展示组件保留语义名称。 + +## 事件 + +`Changed()` 返回操作事件;`Finished()` 返回自然完成的阶段,调用方可播放提示。 + +## 键盘操作 + +Tab 移动;Enter/Space 开始、暂停、跳过与重置。 + +## 限制 + +时长为整秒;自然完成后等待用户启动下一阶段。隐藏组件停止请求帧,恢复显示时读取经过时间。 diff --git a/docs_test.go b/docs_test.go index f7f1d22..c7e169a 100644 --- a/docs_test.go +++ b/docs_test.go @@ -83,6 +83,9 @@ func TestDocSnippetsAreCompiledExamples(t *testing.T) { // TestDocsMatchGalleryPages wants exactly one doc and one gallery page per component ID. func TestDocsMatchGalleryPages(t *testing.T) { + if n := len(readGlob(t, "docs/components/*.md")); n != 318 { + t.Fatalf("component docs = %d, want 318", n) + } pages := map[string]int{} for _, src := range readGlob(t, "examples/gallery/pages_*.go") { for _, m := range docsPageID.FindAllStringSubmatch(src, -1) { diff --git a/due_date_picker.go b/due_date_picker.go new file mode 100644 index 0000000..ed75472 --- /dev/null +++ b/due_date_picker.go @@ -0,0 +1,76 @@ +package mujica + +import ( + "log/slog" + + "github.com/egoist/mygo/ui" + + "mujicaui/icons" + "mujicaui/theme" +) + +// DueDatePickerOptions configure a DueDatePicker. +type DueDatePickerOptions struct { + // Done stops a past date from showing as overdue. + Done bool + WeekStart WeekStart + // Today anchors shortcuts and overdue marks; zero uses today. + Today Date + Disabled bool + Label string +} + +// DueDatePicker combines date shortcuts, a calendar and overdue marks. +func DueDatePicker(c *ui.Context, value *Date, opts DueDatePickerOptions) DateTimeResult { + datetimeCheckDate("DueDatePicker value", *value) + k := Tokens(c) + d := Density(c) + today := datetimeToday(c, opts.Today) + first := calendarFirstWeekday(c, opts.WeekStart) + nextWeek := today.AddDays(7 - (int(today.Weekday())-int(first)+7)%7) + label := opts.Label + if label == "" { + label = msg(c, "due_date_picker.label") + } + old := *value + col := ui.Column(c).Gap(d.Unit() * 2).Role(ui.RoleGroup).Label(label).Disabled(opts.Disabled) + var r DateTimeResult + col.Children(func() { + ui.Row(c).Gap(d.Unit()).Wrap().Children(func() { + for _, q := range []struct { + key string + day Date + }{{"due_date_picker.today", today}, {"due_date_picker.tomorrow", today.AddDays(1)}, {"due_date_picker.next_week", nextWeek}} { + variant := Secondary + text := msg(c, q.key) + if *value == q.day { + variant = Outline + text = "✓ " + text + } + b := Button(c, text, ButtonOptions{Variant: variant}).Label(msg(c, q.key)) + if *value == q.day { + b.Background(k.Selection).TextColor(k.Text) + } + if b.Clicked() && !b.IsDisabled() { + *value = q.day + } + } + }) + r = DatePicker(c, value, DatePickerOptions{Label: label, WeekStart: opts.WeekStart, Today: today, Clearable: true, Disabled: col.IsDisabled()}) + if text, late := projectDueText(c, *value, today, opts.Done); text != "" { + fg, icon := k.TextMuted, "calendar" + if late { + fg, icon = k.Danger, "triangle-alert" + } + ui.Row(c).Gap(d.Unit()).AlignItems(ui.Center).TextColor(fg).Role(ui.RoleStatus).Children(func() { + ui.Icon(c, icons.Must(icon)).Size(14, 14) + ui.Text(c, text).FontSize(FontSize(c, theme.CaptionSize)) + }) + } + }) + changed := *value != old + if changed { + slog.Debug("mujica: due_date_picker change", "from", old, "to", *value) + } + return DateTimeResult{Element: col, Input: r.Input, changed: changed} +} diff --git a/due_date_picker_test.go b/due_date_picker_test.go new file mode 100644 index 0000000..d2eb2a2 --- /dev/null +++ b/due_date_picker_test.go @@ -0,0 +1,83 @@ +package mujica + +import ( + "testing" + + "github.com/egoist/mygo/ui" +) + +func dueTester(v *Date, opts *DueDatePickerOptions, n *int) *ui.Tester { + return ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + o := *opts + o.Today = calendarToday + ui.Column(c).Padding(16).Children(func() { + if DueDatePicker(c, v, o).Changed() { + *n++ + } + }) + }, 480, 520) +} + +func TestDueDatePickerShortcuts(t *testing.T) { + v, n := Date{}, 0 + tt := dueTester(&v, &DueDatePickerOptions{}, &n) + _ = tt.Click("Tomorrow") + if v != oct(6) || n != 1 || !tt.HasText("Due tomorrow") { + t.Fatalf("tomorrow %v", v) + } + _ = tt.Click("Next week") + if v != oct(11) { + t.Fatalf("next week (Sunday start) %v", v) + } + _ = tt.Click("Today") + if v != oct(5) || !tt.HasText("Due today") { + t.Fatalf("today %v", v) + } + _ = tt.Click("Open calendar") + _ = tt.Click(datetimeTestLabel(oct(20))) + if v != oct(20) || n != 4 { + t.Fatalf("calendar pick %v (%d)", v, n) + } +} + +func TestDueDatePickerOverdueAndDone(t *testing.T) { + v, n := oct(2), 0 + opts := &DueDatePickerOptions{} + tt := dueTester(&v, opts, &n) + if !tt.HasText("Overdue by 3 days") { + t.Fatalf("overdue missing: %v", tt.Texts()) + } + opts.Done = true + tt.Frame() + if tt.HasText("Overdue") { + t.Fatal("a done task is not overdue") + } + opts.Disabled = true + tt.Frame() + _ = tt.Click("Today") + if v != oct(2) || n != 0 { + t.Fatal("disabled picker changed") + } +} + +func TestDueDatePickerSnapshot(t *testing.T) { + v := oct(2) + snapshot(t, "due_date_picker", 360, 140, func(c *ui.Context) { + ui.Column(c).Padding(16).Children(func() { DueDatePicker(c, &v, DueDatePickerOptions{Today: calendarToday}) }) + }) +} + +func TestDueDatePickerSelectedShortcutMark(t *testing.T) { + v, n := oct(5), 0 + tt := dueTester(&v, &DueDatePickerOptions{}, &n) + if !tt.HasText("✓ Today") { + t.Fatal("selected shortcut needs a non-color mark") + } + tt.Key(0, ui.KeyTab) + tt.Key(0, ui.KeyTab) + tt.Key(0, ui.KeyEnter) + if v != oct(6) || n != 1 { + t.Fatalf("keyboard shortcut date %v, changes %d", v, n) + } +} diff --git a/example_projects_test.go b/example_projects_test.go new file mode 100644 index 0000000..93d95d8 --- /dev/null +++ b/example_projects_test.go @@ -0,0 +1,242 @@ +package mujica_test + +import ( + "github.com/egoist/mygo/ui" + "log" + mujica "mujicaui" + "time" +) + +func ExampleKanbanBoard() { + statuses := []mujica.WorkflowStatus{{ID: "todo", Name: "To do", Group: mujica.StatusUnstarted}, {ID: "done", Name: "Done", Group: mujica.StatusCompleted}} + tasks := []mujica.Task{{ID: "ENG-1", Title: "Plan the release", Status: "todo"}} + view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + r := mujica.KanbanBoard(c, &tasks, mujica.KanbanBoardOptions{Columns: []mujica.KanbanColumn{{Status: "todo"}, {Status: "done", WIP: 2}}, Statuses: statuses}) + if move, ok := r.Moved(); ok { + log.Println("move", move.ID, move.To, move.Index) + } + if id, ok := r.Opened(); ok { + log.Println("open", id) + } + } + ui.Render(view, 1000, 700, 1) +} + +func ExampleTaskList() { + statuses := []mujica.WorkflowStatus{{ID: "todo", Name: "To do", Group: mujica.StatusUnstarted}, {ID: "done", Name: "Done", Group: mujica.StatusCompleted}} + tasks := []mujica.Task{{ID: "ENG-1", Title: "Plan the release", Status: "todo"}} + filter := mujica.TaskShowAll + view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + r := mujica.TaskList(c, tasks, &filter, mujica.TaskListOptions{GroupBy: mujica.TaskGroupStatus, Statuses: statuses}) + if id, ok := r.Changed(); ok { + log.Println("edit", id) + } + if id, ok := r.Opened(); ok { + log.Println("open", id) + } + } + ui.Render(view, 1000, 700, 1) +} + +func ExampleTaskItem() { + task := mujica.Task{ID: "ENG-1", Title: "Plan the release", Status: "todo", Priority: mujica.PriorityHigh} + view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + r := mujica.TaskItem(c, &task, mujica.TaskItemOptions{}) + if id, ok := r.Changed(); ok { + log.Println("edit", id) + } + if id, ok := r.Opened(); ok { + log.Println("open", id) + } + } + ui.Render(view, 1000, 700, 1) +} + +func ExampleTaskDetailPanel() { + statuses := []mujica.WorkflowStatus{{ID: "todo", Name: "To do", Group: mujica.StatusUnstarted}, {ID: "done", Name: "Done", Group: mujica.StatusCompleted}} + task := mujica.Task{ID: "ENG-1", Title: "Plan the release", Status: "todo", Priority: mujica.PriorityHigh} + view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + r := mujica.TaskDetailPanel(c, &task, mujica.TaskDetailPanelOptions{Statuses: statuses, Activity: func() { ui.Text(c, "Release planned") }}) + if r.Changed() { + log.Println("task edited", task.ID) + } + if r.Closed() { + log.Println("close", task.ID) + } + } + ui.Render(view, 1000, 700, 1) +} + +func ExampleSubtaskList() { + subtasks := []mujica.Subtask{{ID: "one", Title: "Review", Done: true}, {ID: "two", Title: "Ship"}} + view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + if mujica.SubtaskList(c, &subtasks, mujica.SubtaskListOptions{}).Changed() { + log.Println("subtasks changed", len(subtasks)) + } + } + ui.Render(view, 1000, 700, 1) +} + +func ExampleSprintBoard() { + statuses := []mujica.WorkflowStatus{{ID: "todo", Name: "To do", Group: mujica.StatusUnstarted}, {ID: "done", Name: "Done", Group: mujica.StatusCompleted}} + tasks := []mujica.Task{{ID: "ENG-1", Title: "Plan the release", Status: "todo"}} + sprint := mujica.Sprint{Name: "Release sprint", Goal: "Ship", Start: mujica.Date{Year: 2026, Month: 10, Day: 1}, End: mujica.Date{Year: 2026, Month: 10, Day: 14}} + view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + r := mujica.SprintBoard(c, sprint, &tasks, mujica.SprintBoardOptions{Board: mujica.KanbanBoardOptions{Columns: []mujica.KanbanColumn{{Status: "todo"}, {Status: "done", WIP: 2}}, Statuses: statuses}}) + if move, ok := r.Moved(); ok { + log.Println("move", move.ID, move.To) + } + if id, ok := r.Opened(); ok { + log.Println("open", id) + } + } + ui.Render(view, 1000, 700, 1) +} + +func ExampleBurndownChart() { + remaining := []float64{40, 32, 25, 18} + opts := mujica.BurndownChartOptions{Frame: mujica.ChartFrame{Label: "Release burndown"}, Start: mujica.Date{Year: 2026, Month: 10, Day: 1}, End: mujica.Date{Year: 2026, Month: 10, Day: 14}, Total: 40} + view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + r := mujica.BurndownChart(c, remaining, opts) + if r.Changed() { + log.Println("point", r.Point) + } + if name, ok := r.Toggled(); ok { + log.Println("series", name) + } + if r.Retried() { + log.Println("retry") + } + } + ui.Render(view, 1000, 700, 1) +} + +func ExamplePriorityIndicator() { + priority := mujica.PriorityHigh + view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + mujica.PriorityIndicator(c, priority, mujica.PriorityIndicatorOptions{}) + } + ui.Render(view, 1000, 700, 1) +} + +func ExampleStatusSelect() { + statuses := []mujica.WorkflowStatus{{ID: "todo", Name: "To do", Group: mujica.StatusUnstarted}, {ID: "done", Name: "Done", Group: mujica.StatusCompleted}} + value := "todo" + view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + if mujica.StatusSelect(c, &value, statuses, mujica.StatusSelectOptions{}).Changed() { + log.Println("status", value) + } + } + ui.Render(view, 1000, 700, 1) +} + +func ExampleAssigneePicker() { + members := []mujica.Member{{ID: "ann", Name: "Ann"}, {ID: "ben", Name: "Ben"}} + ids := []string{"ann"} + view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + if mujica.AssigneePicker(c, &ids, members, mujica.AssigneePickerOptions{Max: 2}).Changed() { + log.Println("assignees", ids) + } + } + ui.Render(view, 1000, 700, 1) +} + +func ExampleDueDatePicker() { + var due mujica.Date + view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + if mujica.DueDatePicker(c, &due, mujica.DueDatePickerOptions{}).Changed() { + log.Println("due", due) + } + } + ui.Render(view, 1000, 700, 1) +} + +func ExampleLabelManager() { + labels := []mujica.TaskLabel{{ID: "ui", Name: "UI", Color: mujica.EventInfo}} + selected := []string{} + view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + if mujica.LabelManager(c, &labels, &selected, mujica.LabelManagerOptions{}).Changed() { + log.Println("labels changed", len(labels), selected) + } + } + ui.Render(view, 1000, 700, 1) +} + +func ExampleIssueCard() { + statuses := []mujica.WorkflowStatus{{ID: "todo", Name: "To do", Group: mujica.StatusUnstarted}, {ID: "done", Name: "Done", Group: mujica.StatusCompleted}} + task := mujica.Task{ID: "ENG-1", Title: "Plan the release", Status: "todo", Priority: mujica.PriorityHigh} + view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + if mujica.IssueCard(c, task, mujica.IssueCardOptions{Statuses: statuses}).Clicked() { + log.Println("open", task.ID) + } + } + ui.Render(view, 1000, 700, 1) +} + +func ExampleIssueIdBadge() { + id := "ENG-123" + view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + if mujica.IssueIdBadge(c, id, mujica.IssueIdBadgeOptions{Copyable: true}).Changed() { + log.Println("copied", id) + } + } + ui.Render(view, 1000, 700, 1) +} + +func ExampleMilestoneProgress() { + milestone := mujica.Milestone{Title: "Release", Due: mujica.Date{Year: 2026, Month: 10, Day: 14}, Done: 3, Total: 8} + view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + mujica.MilestoneProgress(c, milestone, mujica.MilestoneProgressOptions{}) + } + ui.Render(view, 1000, 700, 1) +} + +func ExampleWorkloadView() { + loads := []mujica.Workload{{Member: mujica.Member{ID: "ann", Name: "Ann"}, Assigned: 46, Capacity: 40}} + view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + mujica.WorkloadView(c, loads, mujica.WorkloadViewOptions{}) + } + ui.Render(view, 1000, 700, 1) +} + +func ExampleTimeTracker() { + var state mujica.TimeTrackerState + view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + if mujica.TimeTracker(c, &state, mujica.TimeTrackerOptions{}).Changed() { + log.Println("tracked", state.Total(c.Now())) + } + } + ui.Render(view, 1000, 700, 1) +} + +func ExamplePomodoroTimer() { + var state mujica.PomodoroState + view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + r := mujica.PomodoroTimer(c, &state, mujica.PomodoroTimerOptions{Focus: 25 * time.Minute}) + if r.Changed() { + log.Println("timer", state.Phase(), state.Running()) + } + if phase, ok := r.Finished(); ok { + log.Println("finished", phase) + } + } + ui.Render(view, 1000, 700, 1) +} diff --git a/examples/gallery/pages_projects.go b/examples/gallery/pages_projects.go index 386b9c2..bdbae6a 100644 --- a/examples/gallery/pages_projects.go +++ b/examples/gallery/pages_projects.go @@ -1,3 +1,82 @@ package main -var projectsPages = []page{} +const projectsCategory = "Projects" + +var projectsPages = append(append(projectsTaskPages, projectsFieldPages...), projectsTimePages...) + +var projectsTaskPages = []page{ + {ID: "361", Name: "KanbanBoard", ZhName: "任务看板", Category: projectsCategory, Demo: projectsDemoKanbanBoard, Keys: "Tab 聚焦卡片;Enter/Space 打开;Alt+左右跨列;Alt+上下排序;可拖放到卡片之前或列末。", Code: `statuses := []mujica.WorkflowStatus{{ID: "todo", Name: "To do", Group: mujica.StatusUnstarted}, {ID: "done", Name: "Done", Group: mujica.StatusCompleted}} +tasks := []mujica.Task{{ID: "ENG-1", Title: "Plan the release", Status: "todo"}} +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + r := mujica.KanbanBoard(c, &tasks, mujica.KanbanBoardOptions{Columns: []mujica.KanbanColumn{{Status: "todo"}, {Status: "done", WIP: 2}}, Statuses: statuses}) + if move, ok := r.Moved(); ok { + log.Println("move", move.ID, move.To, move.Index) + } + if id, ok := r.Opened(); ok { + log.Println("open", id) + } +} +ui.Render(view, 1000, 700, 1)`}, + {ID: "362", Name: "TaskList", ZhName: "任务列表", Category: projectsCategory, Demo: projectsDemoTaskList, Keys: "Tab 在筛选器和任务控件间移动;空格切换完成;Enter 打开;F2 编辑标题。", Code: `statuses := []mujica.WorkflowStatus{{ID: "todo", Name: "To do", Group: mujica.StatusUnstarted}, {ID: "done", Name: "Done", Group: mujica.StatusCompleted}} +tasks := []mujica.Task{{ID: "ENG-1", Title: "Plan the release", Status: "todo"}} +filter := mujica.TaskShowAll +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + r := mujica.TaskList(c, tasks, &filter, mujica.TaskListOptions{GroupBy: mujica.TaskGroupStatus, Statuses: statuses}) + if id, ok := r.Changed(); ok { + log.Println("edit", id) + } + if id, ok := r.Opened(); ok { + log.Println("open", id) + } +} +ui.Render(view, 1000, 700, 1)`}, + {ID: "363", Name: "TaskItem", ZhName: "任务行", Category: projectsCategory, Demo: projectsDemoTaskItem, Keys: "Tab 在复选框和标题间移动;空格切换完成;Enter 打开;F2 或双击开始编辑;Enter 保存;Escape 取消。", Code: `task := mujica.Task{ID: "ENG-1", Title: "Plan the release", Status: "todo", Priority: mujica.PriorityHigh} +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + r := mujica.TaskItem(c, &task, mujica.TaskItemOptions{}) + if id, ok := r.Changed(); ok { + log.Println("edit", id) + } + if id, ok := r.Opened(); ok { + log.Println("open", id) + } +} +ui.Render(view, 1000, 700, 1)`}, + {ID: "364", Name: "TaskDetailPanel", ZhName: "任务详情侧栏", Category: projectsCategory, Demo: projectsDemoTaskDetailPanel, Keys: "Tab 在字段间移动;选择框使用方向键和 Enter;Escape 返回关闭事件;子任务 Enter 新增。", Code: `statuses := []mujica.WorkflowStatus{{ID: "todo", Name: "To do", Group: mujica.StatusUnstarted}, {ID: "done", Name: "Done", Group: mujica.StatusCompleted}} +task := mujica.Task{ID: "ENG-1", Title: "Plan the release", Status: "todo", Priority: mujica.PriorityHigh} +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + r := mujica.TaskDetailPanel(c, &task, mujica.TaskDetailPanelOptions{Statuses: statuses, Activity: func() { ui.Text(c, "Release planned") }}) + if r.Changed() { + log.Println("task edited", task.ID) + } + if r.Closed() { + log.Println("close", task.ID) + } +} +ui.Render(view, 1000, 700, 1)`}, + {ID: "365", Name: "SubtaskList", ZhName: "子任务列表", Category: projectsCategory, Demo: projectsDemoSubtaskList, Keys: "Tab 移动;Space 切换完成;新增输入框 Enter 提交;Alt+上下排序;拖动握柄排序。", Code: `subtasks := []mujica.Subtask{{ID: "one", Title: "Review", Done: true}, {ID: "two", Title: "Ship"}} +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + if mujica.SubtaskList(c, &subtasks, mujica.SubtaskListOptions{}).Changed() { + log.Println("subtasks changed", len(subtasks)) + } +} +ui.Render(view, 1000, 700, 1)`}, + {ID: "368", Name: "SprintBoard", ZhName: "迭代看板", Category: projectsCategory, Demo: projectsDemoSprintBoard, Keys: "看板卡片支持 Tab、Enter/Space、Alt+方向键与拖放。", Code: `statuses := []mujica.WorkflowStatus{{ID: "todo", Name: "To do", Group: mujica.StatusUnstarted}, {ID: "done", Name: "Done", Group: mujica.StatusCompleted}} +tasks := []mujica.Task{{ID: "ENG-1", Title: "Plan the release", Status: "todo"}} +sprint := mujica.Sprint{Name: "Release sprint", Goal: "Ship", Start: mujica.Date{Year: 2026, Month: 10, Day: 1}, End: mujica.Date{Year: 2026, Month: 10, Day: 14}} +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + r := mujica.SprintBoard(c, sprint, &tasks, mujica.SprintBoardOptions{Board: mujica.KanbanBoardOptions{Columns: []mujica.KanbanColumn{{Status: "todo"}, {Status: "done", WIP: 2}}, Statuses: statuses}}) + if move, ok := r.Moved(); ok { + log.Println("move", move.ID, move.To) + } + if id, ok := r.Opened(); ok { + log.Println("open", id) + } +} +ui.Render(view, 1000, 700, 1)`}, +} diff --git a/examples/gallery/pages_projects_demos.go b/examples/gallery/pages_projects_demos.go new file mode 100644 index 0000000..357e967 --- /dev/null +++ b/examples/gallery/pages_projects_demos.go @@ -0,0 +1,172 @@ +package main + +import ( + "fmt" + "slices" + + "github.com/egoist/mygo/ui" + mujica "mujicaui" +) + +var projectsStatuses = []mujica.WorkflowStatus{ + {ID: "todo", Name: "To do", Group: mujica.StatusUnstarted}, + {ID: "doing", Name: "In progress", Group: mujica.StatusStarted}, + {ID: "done", Name: "Done", Group: mujica.StatusCompleted}, +} +var projectsMembers = []mujica.Member{{ID: "ann", Name: "Ann"}, {ID: "ben", Name: "Ben"}, {ID: "cy", Name: "Cy"}} +var projectsLabels = []mujica.TaskLabel{{ID: "ui", Name: "UI", Color: mujica.EventInfo}, {ID: "release", Name: "Release", Color: mujica.EventSuccess}} + +func projectsCheck(c *ui.Context, log func(string), value *bool, label string) { + if mujica.Checkbox(c, value, label, mujica.CheckboxOptions{}).Changed() { + log(fmt.Sprintf("%s = %v", label, *value)) + } +} + +func projectsChoice[T comparable](c *ui.Context, log func(string), value *T, options []mujica.SelectOption[T], label string) { + if mujica.Select(c, value, options, mujica.SelectOptions{Label: label}).Changed() { + log(fmt.Sprintf("%s = %v", label, *value)) + } +} + +type projectsTaskState struct { + tasks []mujica.Task + disabled bool + version int + group mujica.TaskGrouping + filter mujica.TaskFilter + wip float64 + closed bool +} + +func projectsTasks(c *ui.Context, key string) *projectsTaskState { + return *ui.Local(c.Root(), key, func() *projectsTaskState { + return &projectsTaskState{wip: 2, tasks: []mujica.Task{ + {ID: "ENG-1", Title: "Plan the release", Status: "todo", Priority: mujica.PriorityHigh, Due: mujica.Date{Year: 2026, Month: 10, Day: 3}, Assignees: []string{"ann"}, Labels: []string{"ui"}, Subtasks: []mujica.Subtask{{ID: "one", Title: "Review", Done: true}, {ID: "two", Title: "Ship"}}}, + {ID: "ENG-2", Title: "Check keyboard paths", Status: "doing", Priority: mujica.PriorityUrgent, Assignees: []string{"ben"}, Labels: []string{"release"}}, + {ID: "ENG-3", Title: "Publish docs", Status: "done", Done: true, Priority: mujica.PriorityLow}, + }} + }) +} + +func projectsBoardOptions(s *projectsTaskState) mujica.KanbanBoardOptions { + return mujica.KanbanBoardOptions{Columns: []mujica.KanbanColumn{{Status: "todo"}, {Status: "doing", WIP: int(s.wip)}, {Status: "done"}}, Statuses: projectsStatuses, Members: projectsMembers, Labels: projectsLabels, Version: s.version, Disabled: s.disabled} +} + +func projectsLogBoard(s *projectsTaskState, r mujica.KanbanResult, log func(string)) { + if move, ok := r.Moved(); ok { + s.version++ + log(fmt.Sprintf("move %s: %s -> %s at %d", move.ID, move.From, move.To, move.Index)) + } + if id, ok := r.Opened(); ok { + log("open " + id) + } +} + +func projectsDemoKanbanBoard(c *ui.Context, log func(string)) { + s := projectsTasks(c, "361") + projectsCheck(c, log, &s.disabled, "Disabled") + if mujica.NumberInput(c, &s.wip, mujica.NumberInputOptions{Min: 0, Max: 10, Step: 1, Label: "WIP limit"}).Changed() { + log(fmt.Sprintf("WIP = %g", s.wip)) + } + ui.ScrollHorizontal(c).Height(420).FillWidth().Children(func() { + ui.Box(c).Width(880).Height(420).Children(func() { projectsLogBoard(s, mujica.KanbanBoard(c, &s.tasks, projectsBoardOptions(s)), log) }) + }) +} + +func projectsDemoTaskList(c *ui.Context, log func(string)) { + s := projectsTasks(c, "362") + projectsCheck(c, log, &s.disabled, "Disabled") + projectsChoice(c, log, &s.group, []mujica.SelectOption[mujica.TaskGrouping]{{Value: mujica.TaskGroupNone, Label: "Ungrouped"}, {Value: mujica.TaskGroupStatus, Label: "By status"}, {Value: mujica.TaskGroupPriority, Label: "By priority"}}, "Grouping") + ui.Box(c).Height(360).FillWidth().Children(func() { + before := s.filter + r := mujica.TaskList(c, s.tasks, &s.filter, mujica.TaskListOptions{Statuses: projectsStatuses, Members: projectsMembers, GroupBy: s.group, Version: s.version, Disabled: s.disabled}) + if s.filter != before { + log(fmt.Sprintf("filter = %d", s.filter)) + } + if id, ok := r.Changed(); ok { + s.version++ + log("edit " + id) + } + if id, ok := r.Opened(); ok { + log("open " + id) + } + }) +} + +func projectsDemoTaskItem(c *ui.Context, log func(string)) { + s := projectsTasks(c, "363") + projectsCheck(c, log, &s.disabled, "Disabled") + projectsChoice(c, log, &s.tasks[0].Priority, []mujica.SelectOption[mujica.Priority]{{Value: mujica.PriorityLow, Label: "Low"}, {Value: mujica.PriorityHigh, Label: "High"}, {Value: mujica.PriorityUrgent, Label: "Urgent"}}, "Priority") + r := mujica.TaskItem(c, &s.tasks[0], mujica.TaskItemOptions{Members: projectsMembers, Disabled: s.disabled}) + if id, ok := r.Changed(); ok { + log("edit " + id) + } + if id, ok := r.Opened(); ok { + log("open " + id) + } +} + +func projectsDemoTaskDetailPanel(c *ui.Context, log func(string)) { + s := projectsTasks(c, "364") + projectsCheck(c, log, &s.disabled, "Disabled") + if s.closed { + if mujica.Button(c, "Open details", mujica.ButtonOptions{}).Clicked() { + s.closed = false + log("open details") + } + return + } + ui.Scroll(c).Height(620).FillWidth().Children(func() { + ui.Box(c).MaxWidth(500).FillWidth().Children(func() { + r := mujica.TaskDetailPanel(c, &s.tasks[0], mujica.TaskDetailPanelOptions{Statuses: projectsStatuses, Members: projectsMembers, Labels: projectsLabels, Disabled: s.disabled, Activity: func() { ui.Text(c, "Ann created this task") }}) + if r.Changed() { + log("task fields changed") + } + if r.Closed() { + s.closed = true + log("close details") + } + }) + }) +} + +func projectsDemoSubtaskList(c *ui.Context, log func(string)) { + s := projectsTasks(c, "365") + projectsCheck(c, log, &s.disabled, "Disabled") + if mujica.Button(c, "Clear subtasks", mujica.ButtonOptions{Disabled: s.disabled}).Clicked() { + s.tasks[0].Subtasks = nil + log("clear subtasks") + } + if mujica.SubtaskList(c, &s.tasks[0].Subtasks, mujica.SubtaskListOptions{Disabled: s.disabled}).Changed() { + log("subtasks changed") + } +} + +func projectsDemoSprintBoard(c *ui.Context, log func(string)) { + s := projectsTasks(c, "368") + projectsCheck(c, log, &s.disabled, "Disabled") + sprint := mujica.Sprint{Name: "Release sprint", Goal: "Ship the first release", Start: mujica.Date{Year: 2026, Month: 10, Day: 1}, End: mujica.Date{Year: 2026, Month: 10, Day: 14}} + ui.ScrollHorizontal(c).Height(540).FillWidth().Children(func() { + ui.Box(c).Width(880).Height(540).Children(func() { + projectsLogBoard(s, mujica.SprintBoard(c, sprint, &s.tasks, mujica.SprintBoardOptions{Board: projectsBoardOptions(s)}), log) + }) + }) +} + +func projectsDemoLabelManager(c *ui.Context, log func(string)) { + s := *ui.Local(c.Root(), "374", func() *struct { + labels []mujica.TaskLabel + selected []string + disabled bool + } { + return &struct { + labels []mujica.TaskLabel + selected []string + disabled bool + }{labels: slices.Clone(projectsLabels)} + }) + projectsCheck(c, log, &s.disabled, "Disabled") + if mujica.LabelManager(c, &s.labels, &s.selected, mujica.LabelManagerOptions{Disabled: s.disabled}).Changed() { + log(fmt.Sprintf("labels changed: %d, selected %v", len(s.labels), s.selected)) + } +} diff --git a/examples/gallery/pages_projects_fields.go b/examples/gallery/pages_projects_fields.go new file mode 100644 index 0000000..8c2e889 --- /dev/null +++ b/examples/gallery/pages_projects_fields.go @@ -0,0 +1,61 @@ +package main + +var projectsFieldPages = []page{ + {ID: "369", Name: "BurndownChart", ZhName: "燃尽图", Category: projectsCategory, Demo: projectsDemoBurndownChart, Keys: "Tab 聚焦图例与图表;Space 切换图例;方向键逐日读取;Home/End 首尾;Escape 清除读数。", Code: `remaining := []float64{40, 32, 25, 18} +opts := mujica.BurndownChartOptions{Frame: mujica.ChartFrame{Label: "Release burndown"}, Start: mujica.Date{Year: 2026, Month: 10, Day: 1}, End: mujica.Date{Year: 2026, Month: 10, Day: 14}, Total: 40} +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + r := mujica.BurndownChart(c, remaining, opts) + if r.Changed() { + log.Println("point", r.Point) + } + if name, ok := r.Toggled(); ok { + log.Println("series", name) + } + if r.Retried() { + log.Println("retry") + } +} +ui.Render(view, 1000, 700, 1)`}, + {ID: "370", Name: "PriorityIndicator", ZhName: "优先级指示", Category: projectsCategory, Demo: projectsDemoPriorityIndicator, Keys: "静态展示,通过无障碍名称读取完整等级。", Code: `priority := mujica.PriorityHigh +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + mujica.PriorityIndicator(c, priority, mujica.PriorityIndicatorOptions{}) +} +ui.Render(view, 1000, 700, 1)`}, + {ID: "371", Name: "StatusSelect", ZhName: "状态选择", Category: projectsCategory, Demo: projectsDemoStatusSelect, Keys: "Enter/Space 或上下键打开;上下、Home/End 定位;Enter 确认;Escape 关闭。", Code: `statuses := []mujica.WorkflowStatus{{ID: "todo", Name: "To do", Group: mujica.StatusUnstarted}, {ID: "done", Name: "Done", Group: mujica.StatusCompleted}} +value := "todo" +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + if mujica.StatusSelect(c, &value, statuses, mujica.StatusSelectOptions{}).Changed() { + log.Println("status", value) + } +} +ui.Render(view, 1000, 700, 1)`}, + {ID: "372", Name: "AssigneePicker", ZhName: "负责人选择", Category: projectsCategory, Demo: projectsDemoAssigneePicker, Keys: "Enter/Space 打开;输入搜索;下键进入选项;Space/Enter 勾选;Backspace 移除最后一项;Escape 关闭。", Code: `members := []mujica.Member{{ID: "ann", Name: "Ann"}, {ID: "ben", Name: "Ben"}} +ids := []string{"ann"} +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + if mujica.AssigneePicker(c, &ids, members, mujica.AssigneePickerOptions{Max: 2}).Changed() { + log.Println("assignees", ids) + } +} +ui.Render(view, 1000, 700, 1)`}, + {ID: "373", Name: "DueDatePicker", ZhName: "截止日期选择", Category: projectsCategory, Demo: projectsDemoDueDatePicker, Keys: "Tab 到快捷项、日期输入与日历按钮;Enter 选择;日历方向键移动;Escape 关闭。", Code: `var due mujica.Date +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + if mujica.DueDatePicker(c, &due, mujica.DueDatePickerOptions{}).Changed() { + log.Println("due", due) + } +} +ui.Render(view, 1000, 700, 1)`}, + {ID: "374", Name: "LabelManager", ZhName: "标签管理", Category: projectsCategory, Demo: projectsDemoLabelManager, Keys: "Tab 移动;Space 勾选;新增输入 Enter 创建;编辑颜色按钮打开编辑;Enter 保存名称;Escape 结束编辑。", Code: `labels := []mujica.TaskLabel{{ID: "ui", Name: "UI", Color: mujica.EventInfo}} +selected := []string{} +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + if mujica.LabelManager(c, &labels, &selected, mujica.LabelManagerOptions{}).Changed() { + log.Println("labels changed", len(labels), selected) + } +} +ui.Render(view, 1000, 700, 1)`}, +} diff --git a/examples/gallery/pages_projects_fields_demos.go b/examples/gallery/pages_projects_fields_demos.go new file mode 100644 index 0000000..0351b5b --- /dev/null +++ b/examples/gallery/pages_projects_fields_demos.go @@ -0,0 +1,142 @@ +package main + +import ( + "fmt" + "github.com/egoist/mygo/ui" + "math" + mujica "mujicaui" +) + +func projectsDemoBurndownChart(c *ui.Context, log func(string)) { + s := ui.Local(c.Root(), "369", func() struct { + disabled bool + status mujica.DataStatus + total float64 + values []float64 + } { + return struct { + disabled bool + status mujica.DataStatus + total float64 + values []float64 + }{total: 40, values: []float64{40, 38, 32, 34, 26, math.NaN(), 20, 18}} + }) + projectsCheck(c, log, &s.disabled, "Disabled") + projectsChoice(c, log, &s.status, []mujica.SelectOption[mujica.DataStatus]{{Value: mujica.DataReady, Label: "Ready"}, {Value: mujica.DataLoading, Label: "Loading"}, {Value: mujica.DataFailed, Label: "Error"}}, "Data state") + if mujica.NumberInput(c, &s.total, mujica.NumberInputOptions{Min: 1, Max: 100, Step: 1, Label: "Total work"}).Changed() { + log(fmt.Sprintf("total = %g", s.total)) + } + ui.Box(c).Disabled(s.disabled).FillWidth().Children(func() { + r := mujica.BurndownChart(c, s.values, mujica.BurndownChartOptions{Frame: mujica.ChartFrame{Label: "Release burndown", Status: s.status, Error: "Data unavailable"}, Start: mujica.Date{Year: 2026, Month: 10, Day: 1}, End: mujica.Date{Year: 2026, Month: 10, Day: 14}, Total: s.total}) + if r.Changed() { + log(fmt.Sprintf("point = %d", r.Point)) + } + if name, ok := r.Toggled(); ok { + log("toggle " + name) + } + if r.Retried() { + s.status = mujica.DataReady + log("retry") + } + }) +} + +func projectsDemoPriorityIndicator(c *ui.Context, log func(string)) { + s := ui.Local(c.Root(), "370", func() struct { + priority mujica.Priority + iconOnly bool + } { + return struct { + priority mujica.Priority + iconOnly bool + }{priority: mujica.PriorityHigh} + }) + projectsCheck(c, log, &s.iconOnly, "Icon only") + projectsChoice(c, log, &s.priority, []mujica.SelectOption[mujica.Priority]{{Value: mujica.PriorityNone, Label: "None"}, {Value: mujica.PriorityLow, Label: "Low"}, {Value: mujica.PriorityMedium, Label: "Medium"}, {Value: mujica.PriorityHigh, Label: "High"}, {Value: mujica.PriorityUrgent, Label: "Urgent"}}, "Priority") + mujica.PriorityIndicator(c, s.priority, mujica.PriorityIndicatorOptions{IconOnly: s.iconOnly}) +} + +func projectsDemoStatusSelect(c *ui.Context, log func(string)) { + s := ui.Local(c.Root(), "371", func() struct { + value string + disabled bool + } { + return struct { + value string + disabled bool + }{value: "todo"} + }) + projectsCheck(c, log, &s.disabled, "Disabled") + if mujica.StatusSelect(c, &s.value, projectsStatuses, mujica.StatusSelectOptions{Disabled: s.disabled}).Changed() { + log("status " + s.value) + } +} + +func projectsDemoAssigneePicker(c *ui.Context, log func(string)) { + s := ui.Local(c.Root(), "372", func() struct { + ids []string + disabled bool + max float64 + } { + return struct { + ids []string + disabled bool + max float64 + }{ids: []string{"ann"}, max: 2} + }) + projectsCheck(c, log, &s.disabled, "Disabled") + if mujica.NumberInput(c, &s.max, mujica.NumberInputOptions{Min: 0, Max: 3, Step: 1, Label: "Selection limit"}).Changed() { + log(fmt.Sprintf("limit = %g", s.max)) + } + if mujica.AssigneePicker(c, &s.ids, projectsMembers, mujica.AssigneePickerOptions{Max: int(s.max), Disabled: s.disabled}).Changed() { + log(fmt.Sprintf("assignees %v", s.ids)) + } +} + +func projectsDemoDueDatePicker(c *ui.Context, log func(string)) { + s := ui.Local(c.Root(), "373", func() struct { + due mujica.Date + disabled, done bool + } { + return struct { + due mujica.Date + disabled, done bool + }{due: mujica.Date{Year: 2026, Month: 10, Day: 3}} + }) + projectsCheck(c, log, &s.disabled, "Disabled") + projectsCheck(c, log, &s.done, "Completed") + if mujica.DueDatePicker(c, &s.due, mujica.DueDatePickerOptions{Done: s.done, Disabled: s.disabled}).Changed() { + log(fmt.Sprintf("due %v", s.due)) + } +} + +func projectsDemoIssueCard(c *ui.Context, log func(string)) { + s := projectsTasks(c, "375") + selected := ui.Local(c.Root(), "375-selected", func() bool { return false }) + projectsCheck(c, log, &s.disabled, "Disabled") + projectsCheck(c, log, selected, "Selected") + ui.Box(c).Width(300).Children(func() { + if mujica.IssueCard(c, s.tasks[0], mujica.IssueCardOptions{Statuses: projectsStatuses, Members: projectsMembers, Labels: projectsLabels, Selected: *selected, Disabled: s.disabled}).Clicked() { + *selected = !*selected + log("open " + s.tasks[0].ID) + } + }) +} + +func projectsDemoIssueIdBadge(c *ui.Context, log func(string)) { + s := ui.Local(c.Root(), "376", func() struct { + disabled, copyable bool + id string + } { + return struct { + disabled, copyable bool + id string + }{copyable: true, id: "ENG-123"} + }) + projectsCheck(c, log, &s.disabled, "Disabled") + projectsCheck(c, log, &s.copyable, "Copyable") + projectsChoice(c, log, &s.id, []mujica.SelectOption[string]{{Value: "ENG-123", Label: "ENG-123"}, {Value: "OPS-7", Label: "OPS-7"}}, "Issue key") + if mujica.IssueIdBadge(c, s.id, mujica.IssueIdBadgeOptions{Copyable: s.copyable, Disabled: s.disabled}).Changed() { + log("copied " + s.id) + } +} diff --git a/examples/gallery/pages_projects_test.go b/examples/gallery/pages_projects_test.go new file mode 100644 index 0000000..8f022b5 --- /dev/null +++ b/examples/gallery/pages_projects_test.go @@ -0,0 +1,97 @@ +package main + +import ( + "strings" + "testing" + + "github.com/egoist/mygo/ui" + mujica "mujicaui" +) + +func projectsGalleryTester(t *testing.T, id string) (*ui.Tester, *[]string) { + t.Helper() + var events []string + for _, p := range projectsPages { + if p.ID == id { + tt := ui.NewTester(func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + ui.Column(c).Fill().Gap(12).Padding(16).Children(func() { p.Demo(c, func(s string) { events = append(events, s) }) }) + }, 1200, 1000) + tt.SetPreferences(ui.Preferences{ReduceMotion: true, TextScale: 1}) + return tt, &events + } + } + t.Fatal("unknown project page " + id) + return nil, nil +} + +func TestProjectsGalleryCatalog(t *testing.T) { + if len(projectsPages) != 18 { + t.Fatalf("pages = %d", len(projectsPages)) + } + seen := map[string]bool{} + for _, p := range projectsPages { + if p.Category != "Projects" || p.Keys == "" || p.Code == "" || seen[p.ID] { + t.Fatalf("invalid page %s", p.ID) + } + seen[p.ID] = true + projectsGalleryTester(t, p.ID) + } + if seen["366"] || seen["367"] { + t.Fatal("dropped components have gallery pages") + } +} + +func TestProjectsGalleryEvents(t *testing.T) { + for _, tc := range []struct{ id, action, event string }{ + {"361", "ENG-1 Plan the release", "open ENG-1"}, + {"362", "Done 1", "filter = 2"}, + {"363", "Plan the release", "open ENG-1"}, + {"364", "Close details", "close details"}, + {"365", "Clear subtasks", "clear subtasks"}, + {"368", "ENG-1 Plan the release", "open ENG-1"}, + {"369", "Ideal", "toggle Ideal"}, + {"370", "Icon only", "Icon only = true"}, + {"371", "Status", ""}, + {"372", "Disabled", "Disabled = true"}, + {"373", "Today", "due "}, + {"374", "UI", "labels changed:"}, + {"375", "ENG-1 Plan the release", "open ENG-1"}, + {"376", "Copy ENG-123", "copied ENG-123"}, + {"377", "Completed tasks", ""}, + {"378", "Ben assigned hours", ""}, + {"379", "Start", "tracked "}, + {"380", "Start", "timer phase = 0, running = true"}, + } { + t.Run(tc.id, func(t *testing.T) { + tt, events := projectsGalleryTester(t, tc.id) + if err := tt.Click(tc.action); err != nil { + t.Fatal(err) + } + switch tc.id { + case "371": + tt.Key(0, ui.KeyEnd) + tt.Key(0, ui.KeyEnter) + tc.event = "status done" + case "377", "378": + tt.Command("selectAll") + tt.Type("5") + tt.Key(0, ui.KeyEnter) + if tc.id == "377" { + tc.event = "completed = 5" + } else { + tc.event = "assigned = 5" + } + } + found := false + for _, e := range *events { + if strings.HasPrefix(e, tc.event) { + found = true + } + } + if !found { + t.Fatalf("event %q missing in %v", tc.event, *events) + } + }) + } +} diff --git a/examples/gallery/pages_projects_time.go b/examples/gallery/pages_projects_time.go new file mode 100644 index 0000000..447455b --- /dev/null +++ b/examples/gallery/pages_projects_time.go @@ -0,0 +1,53 @@ +package main + +var projectsTimePages = []page{ + {ID: "375", Name: "IssueCard", ZhName: "任务卡片", Category: projectsCategory, Demo: projectsDemoIssueCard, Keys: "Tab 聚焦;Enter/Space 激活。", Code: `statuses := []mujica.WorkflowStatus{{ID: "todo", Name: "To do", Group: mujica.StatusUnstarted}, {ID: "done", Name: "Done", Group: mujica.StatusCompleted}} +task := mujica.Task{ID: "ENG-1", Title: "Plan the release", Status: "todo", Priority: mujica.PriorityHigh} +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + if mujica.IssueCard(c, task, mujica.IssueCardOptions{Statuses: statuses}).Clicked() { + log.Println("open", task.ID) + } +} +ui.Render(view, 1000, 700, 1)`}, + {ID: "376", Name: "IssueIdBadge", ZhName: "任务编号", Category: projectsCategory, Demo: projectsDemoIssueIdBadge, Keys: "Copyable 开启时 Tab 聚焦,Enter/Space 复制。", Code: `id := "ENG-123" +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + if mujica.IssueIdBadge(c, id, mujica.IssueIdBadgeOptions{Copyable: true}).Changed() { + log.Println("copied", id) + } +} +ui.Render(view, 1000, 700, 1)`}, + {ID: "377", Name: "MilestoneProgress", ZhName: "里程碑进度", Category: projectsCategory, Demo: projectsDemoMilestoneProgress, Keys: "静态展示,进度条通过无障碍名称与百分比读取。", Code: `milestone := mujica.Milestone{Title: "Release", Due: mujica.Date{Year: 2026, Month: 10, Day: 14}, Done: 3, Total: 8} +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + mujica.MilestoneProgress(c, milestone, mujica.MilestoneProgressOptions{}) +} +ui.Render(view, 1000, 700, 1)`}, + {ID: "378", Name: "WorkloadView", ZhName: "成员负载", Category: projectsCategory, Demo: projectsDemoWorkloadView, Keys: "静态行通过无障碍名称读取负载与超出量;滚动查看更多成员。", Code: `loads := []mujica.Workload{{Member: mujica.Member{ID: "ann", Name: "Ann"}, Assigned: 46, Capacity: 40}} +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + mujica.WorkloadView(c, loads, mujica.WorkloadViewOptions{}) +} +ui.Render(view, 1000, 700, 1)`}, + {ID: "379", Name: "TimeTracker", ZhName: "工时计时", Category: projectsCategory, Demo: projectsDemoTimeTracker, Keys: "Tab 移动;Enter/Space 开始停止;停止后打开修正,编辑时长,Apply 提交。", Code: `var state mujica.TimeTrackerState +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + if mujica.TimeTracker(c, &state, mujica.TimeTrackerOptions{}).Changed() { + log.Println("tracked", state.Total(c.Now())) + } +} +ui.Render(view, 1000, 700, 1)`}, + {ID: "380", Name: "PomodoroTimer", ZhName: "番茄钟", Category: projectsCategory, Demo: projectsDemoPomodoroTimer, Keys: "Tab 移动;Enter/Space 开始、暂停、跳过与重置。", Code: `var state mujica.PomodoroState +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + r := mujica.PomodoroTimer(c, &state, mujica.PomodoroTimerOptions{Focus: 25 * time.Minute}) + if r.Changed() { + log.Println("timer", state.Phase(), state.Running()) + } + if phase, ok := r.Finished(); ok { + log.Println("finished", phase) + } +} +ui.Render(view, 1000, 700, 1)`}, +} diff --git a/examples/gallery/pages_projects_time_demos.go b/examples/gallery/pages_projects_time_demos.go new file mode 100644 index 0000000..803394a --- /dev/null +++ b/examples/gallery/pages_projects_time_demos.go @@ -0,0 +1,83 @@ +package main + +import ( + "fmt" + "github.com/egoist/mygo/ui" + mujica "mujicaui" + "time" +) + +func projectsDemoMilestoneProgress(c *ui.Context, log func(string)) { + done := ui.Local(c.Root(), "377", func() float64 { return 3 }) + if mujica.NumberInput(c, done, mujica.NumberInputOptions{Min: 0, Max: 8, Step: 1, Label: "Completed tasks"}).Changed() { + log(fmt.Sprintf("completed = %g", *done)) + } + mujica.MilestoneProgress(c, mujica.Milestone{Title: "Release", Due: mujica.Date{Year: 2026, Month: 10, Day: 14}, Done: int(*done), Total: 8}, mujica.MilestoneProgressOptions{}) +} + +func projectsDemoWorkloadView(c *ui.Context, log func(string)) { + s := ui.Local(c.Root(), "378", func() struct { + assigned float64 + loads []mujica.Workload + version int + } { + return struct { + assigned float64 + loads []mujica.Workload + version int + }{assigned: 46, loads: []mujica.Workload{{Member: projectsMembers[0], Assigned: 32, Capacity: 40}, {Member: projectsMembers[1], Assigned: 46, Capacity: 40}, {Member: projectsMembers[2], Assigned: 12, Capacity: 20}}} + }) + if mujica.NumberInput(c, &s.assigned, mujica.NumberInputOptions{Min: 0, Max: 80, Step: 1, Label: "Ben assigned hours"}).Changed() { + s.loads[1].Assigned = s.assigned + s.version++ + log(fmt.Sprintf("assigned = %g", s.assigned)) + } + ui.Box(c).Height(240).FillWidth().Children(func() { mujica.WorkloadView(c, s.loads, mujica.WorkloadViewOptions{Version: s.version}) }) +} + +func projectsDemoTimeTracker(c *ui.Context, log func(string)) { + s := ui.Local(c.Root(), "379", func() struct { + timer mujica.TimeTrackerState + disabled bool + } { + return struct { + timer mujica.TimeTrackerState + disabled bool + }{} + }) + projectsCheck(c, log, &s.disabled, "Disabled") + ui.ScrollHorizontal(c).Height(120).FillWidth().Children(func() { + if mujica.TimeTracker(c, &s.timer, mujica.TimeTrackerOptions{Disabled: s.disabled}).Changed() { + log("tracked " + s.timer.Total(c.Now()).String()) + } + }) +} + +func projectsDemoPomodoroTimer(c *ui.Context, log func(string)) { + s := ui.Local(c.Root(), "380", func() struct { + timer mujica.PomodoroState + disabled, hidden bool + seconds float64 + } { + return struct { + timer mujica.PomodoroState + disabled, hidden bool + seconds float64 + }{seconds: 10} + }) + projectsCheck(c, log, &s.disabled, "Disabled") + projectsCheck(c, log, &s.hidden, "Hidden") + if mujica.NumberInput(c, &s.seconds, mujica.NumberInputOptions{Min: 1, Max: 1500, Step: 1, Label: "Focus seconds", Disabled: s.timer.Running()}).Changed() { + log(fmt.Sprintf("focus = %g seconds", s.seconds)) + } + if s.hidden { + return + } + r := mujica.PomodoroTimer(c, &s.timer, mujica.PomodoroTimerOptions{Focus: time.Duration(s.seconds) * time.Second, Break: 5 * time.Second, LongBreak: 10 * time.Second, LongEvery: 2, Disabled: s.disabled}) + if r.Changed() { + log(fmt.Sprintf("timer phase = %d, running = %v", s.timer.Phase(), s.timer.Running())) + } + if phase, ok := r.Finished(); ok { + log(fmt.Sprintf("finished phase %d", phase)) + } +} diff --git a/issue_card.go b/issue_card.go new file mode 100644 index 0000000..26a9d1f --- /dev/null +++ b/issue_card.go @@ -0,0 +1,87 @@ +package mujica + +import ( + "fmt" + "github.com/egoist/mygo/ui" + "log/slog" + + "mujicaui/internal" + "mujicaui/theme" +) + +// IssueCardOptions configure an IssueCard. +type IssueCardOptions struct { + Statuses []WorkflowStatus + Members []Member + Labels []TaskLabel + Selected bool + Disabled bool +} + +// IssueCard displays task fields in a selectable card. +func IssueCard(c *ui.Context, task Task, opts IssueCardOptions) *ui.Element { + projectCheckPriority(task.Priority) + st := projectStatus(opts.Statuses, task.Status) + k := Tokens(c) + d := Density(c) + small := FontSize(c, theme.CaptionSize) + b := ui.ButtonBase(c).Column().AlignItems(ui.Stretch).Justify(ui.Start).Padding(d.Unit()*3).Gap(d.Unit()*2). + Radius(theme.CardRadius).Border(theme.BorderWidth, k.Border).Background(k.Surface). + Label(task.ID + " " + task.Title).Description(fmt.Sprintf(msg(c, "issue_card.description"), st.Name, PriorityName(c, task.Priority))).Disabled(opts.Disabled) + internal.Ring(b, k.Focus, theme.CardRadius) + switch { + case opts.Selected: + b.Background(k.Selection) + case b.Hovered(): + b.Background(k.SurfaceHover).Border(theme.BorderWidth, k.ControlBorder) + } + selected := opts.Selected + b.Transition(colorFade).Draw(func(p *ui.Painter, r ui.Rect) { + if selected { + datetimeSelectedMark(p, r, k.AccentText) + } + }) + b.Children(func() { + ui.Row(c).Gap(d.Unit() * 2).AlignItems(ui.Center).Children(func() { + statusGlyphBox(c, st.Group) + ui.Text(c, task.ID).Font(theme.MonoFont).FontSize(small).TextColor(k.TextMuted).Grow(1) + PriorityIndicator(c, task.Priority, PriorityIndicatorOptions{IconOnly: true}) + }) + t := ui.Text(c, task.Title).TextColor(k.Text).MaxLines(2).Ellipsis("…") + if st.Group == StatusCanceled { + t.Strikethrough().TextColor(k.TextMuted) + } + if len(task.Labels) == 0 && len(task.Assignees) == 0 { + return + } + ui.Row(c).Gap(d.Unit()).AlignItems(ui.Center).Wrap().Children(func() { + for _, id := range task.Labels { + issueLabelChip(c, projectLabel(opts.Labels, id)) + } + ui.Spacer(c) + if len(task.Assignees) > 0 { + items := make([]AvatarItem, len(task.Assignees)) + for i, id := range task.Assignees { + items[i] = AvatarItem{Name: projectMember(opts.Members, id).Name} + } + AvatarGroup(c, items, AvatarGroupOptions{Max: 3, Size: 22}) + } + }) + }) + if b.Clicked() && !b.IsDisabled() { + slog.Debug("mujica: issue_card open", "id", task.ID) + } + return b +} + +// issueLabelChip displays a label with its color dot. +func issueLabelChip(c *ui.Context, l TaskLabel) { + k := Tokens(c) + d := Density(c) + col := eventColor(k, l.Color) + ui.Row(c).Gap(d.Unit()).AlignItems(ui.Center).Padding(1, d.Unit()*1.5).Radius(theme.ControlRadius). + Border(theme.BorderWidth, k.Border).Children(func() { + ui.Box(c).Size(8, 8).Radius(4).Background(col) + ui.Text(c, l.Name).FontSize(FontSize(c, theme.CaptionSize)).TextColor(k.Text).SingleLine() + }) +} diff --git a/issue_card_test.go b/issue_card_test.go new file mode 100644 index 0000000..91e91ca --- /dev/null +++ b/issue_card_test.go @@ -0,0 +1,88 @@ +package mujica + +import ( + "testing" + + "github.com/egoist/mygo/ui" + "mujicaui/theme" +) + +func issueCardTester(task Task, opts IssueCardOptions, n *int) *ui.Tester { + opts.Statuses, opts.Members, opts.Labels = projStatuses, projMembers, projLabels + return ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + ui.Column(c).Padding(16).Width(300).Children(func() { + if IssueCard(c, task, opts).Clicked() { + *n++ + } + }) + }, 360, 260) +} + +func TestIssueCardShowsFieldsAndActivates(t *testing.T) { + n := 0 + tt := issueCardTester(projTasks()[1], IssueCardOptions{}, &n) + for _, s := range []string{"AVE-2", "Tune the organ", "Bug", "Urgent", "Mutsumi Wakaba", "Uika Misumi"} { + if !tt.HasText(s) { + t.Fatalf("missing %q in %v", s, tt.Texts()) + } + } + _ = tt.Click("AVE-2 Tune the organ") + tt.Key(0, ui.KeyTab) + tt.Key(0, ui.KeyEnter) + if n != 2 { + t.Fatalf("activations %d", n) + } +} + +func TestIssueCardDisabledAndInvalid(t *testing.T) { + n := 0 + tt := issueCardTester(projTasks()[0], IssueCardOptions{Disabled: true}, &n) + _ = tt.Click("AVE-1 Write the overture") + if n != 0 { + t.Fatal("disabled card clicked") + } + defer func() { + if recover() == nil { + t.Fatal("expected panic for an unknown status") + } + }() + bad := projTasks()[0] + bad.Status = "lost" + issueCardTester(bad, IssueCardOptions{}, &n) +} + +func TestIssueCardSnapshot(t *testing.T) { + tasks := projTasks() + snapshot(t, "issue_card", 640, 200, func(c *ui.Context) { + ui.Row(c).Padding(16).Gap(12).AlignItems(ui.Start).Children(func() { + for i, task := range tasks[:3] { + ui.Box(c).Width(190).Children(func() { + IssueCard(c, task, IssueCardOptions{Statuses: projStatuses, Members: projMembers, Labels: projLabels, Selected: i == 1}) + }) + } + }) + }) +} + +func TestIssueCardFocusRing(t *testing.T) { + n := 0 + tt := issueCardTester(projTasks()[0], IssueCardOptions{}, &n) + tt.SetPreferences(ui.Preferences{ReduceMotion: true, TextScale: 1}) + tt.Key(0, ui.KeyTab) + r, ok := tt.Find("AVE-1 Write the overture") + if !ok { + t.Fatal("card missing") + } + img, found := tt.Image(), false + for x := int(r.X) - 5; x < int(r.X)-1; x++ { + for y := int(r.Y) + 8; y < int(r.Y+r.H)-8; y++ { + if datetimeNear(img.RGBAAt(x, y), theme.Light().Focus) { + found = true + } + } + } + if !found { + t.Fatal("card keyboard focus has no outer ring") + } +} diff --git a/issue_id_badge.go b/issue_id_badge.go new file mode 100644 index 0000000..9261c26 --- /dev/null +++ b/issue_id_badge.go @@ -0,0 +1,73 @@ +package mujica + +import ( + "fmt" + "log/slog" + "regexp" + "time" + + "github.com/egoist/mygo/ui" + + "mujicaui/icons" + "mujicaui/internal" + "mujicaui/theme" +) + +var issueIDPattern = regexp.MustCompile(`^[A-Z][A-Z0-9]*-[1-9][0-9]*$`) + +// IssueIdBadgeOptions configure an IssueIdBadge. +type IssueIdBadgeOptions struct { + // Copyable makes a click or Enter copy the key. + Copyable bool + Disabled bool +} + +// issueCopiedFor is how long "Copied" shows after a copy. +const issueCopiedFor = 1500 * time.Millisecond + +// IssueIdBadge displays a monospace issue key with optional copying. +func IssueIdBadge(c *ui.Context, id string, opts IssueIdBadgeOptions) ChoiceResult { + if !issueIDPattern.MatchString(id) { + panic(fmt.Sprintf("mujica: IssueIdBadge %q is not a key like ENG-123", id)) + } + k := Tokens(c) + d := Density(c) + small := FontSize(c, theme.CaptionSize) + if !opts.Copyable { + e := ui.Row(c).Padding(d.Unit()/2, d.Unit()*1.5).Radius(theme.ControlRadius).Background(k.Background). + Border(theme.BorderWidth, k.Border).Shrink(0).Label(id) + e.Children(func() { ui.Text(c, id).Font(theme.MonoFont).FontSize(small).TextColor(k.TextMuted).SingleLine() }) + return ChoiceResult{Element: e} + } + b := ui.ButtonBase(c).MinHeight(theme.MinHitSize).Gap(d.Unit()).PaddingX(d.Unit()*1.5).Radius(theme.ControlRadius). + Background(k.Background).Border(theme.BorderWidth, k.Border).Disabled(opts.Disabled) + internal.Ring(b, k.Focus, theme.ControlRadius) + copied := ui.Local(b, "issue-copied", func() time.Time { return time.Time{} }) + changed := false + if b.Clicked() && !b.IsDisabled() { + c.WriteClipboard(id) + c.Announce(fmt.Sprintf(msg(c, "issue_id_badge.copied_label"), id)) + *copied, changed = c.Now(), true + slog.Debug("mujica: issue_id_badge copy", "id", id) + } + showing := !copied.IsZero() && c.Now().Sub(*copied) < issueCopiedFor + if showing { + c.After(issueCopiedFor - c.Now().Sub(*copied)) + } + b.Label(fmt.Sprintf(msg(c, "issue_id_badge.copy"), id)) + if b.Hovered() { + b.Background(k.SurfaceHover) + } + b.Transition(colorFade).Children(func() { + ui.Text(c, id).Font(theme.MonoFont).FontSize(small).TextColor(k.Text).SingleLine() + icon, col := "copy", k.TextMuted + if showing { + icon, col = "check", k.Success + } + ui.Icon(c, icons.Must(icon)).Size(12, 12).TextColor(col) + if showing { + ui.Text(c, msg(c, "issue_id_badge.copied")).FontSize(small).TextColor(k.Success) + } + }) + return ChoiceResult{Element: b, changed: changed} +} diff --git a/issue_id_badge_test.go b/issue_id_badge_test.go new file mode 100644 index 0000000..b63cf08 --- /dev/null +++ b/issue_id_badge_test.go @@ -0,0 +1,82 @@ +package mujica + +import ( + "testing" + "time" + + "github.com/egoist/mygo/ui" +) + +func TestIssueIdBadgeCopy(t *testing.T) { + n, disabled := 0, false + tt := ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + ui.Column(c).Children(func() { + if IssueIdBadge(c, "ENG-123", IssueIdBadgeOptions{Copyable: true, Disabled: disabled}).Changed() { + n++ + } + IssueIdBadge(c, "OPS-7", IssueIdBadgeOptions{}) + }) + }, 300, 120) + _ = tt.Click("Copy ENG-123") + if tt.Clipboard() != "ENG-123" || n != 1 || !tt.HasText("Copied") { + t.Fatalf("copy %q %d %v", tt.Clipboard(), n, tt.Texts()) + } + if a := tt.Announcements(); len(a) != 1 || a[0] != "ENG-123 copied" { + t.Fatalf("announce %q", a) + } + tt.SetClipboard("") + tt.Key(0, ui.KeyTab) + tt.Key(0, ui.KeyEnter) + if tt.Clipboard() != "ENG-123" || n != 2 { + t.Fatal("Enter should copy") + } + if !tt.HasText("OPS-7") || tt.HasText("Copy OPS-7") { + t.Fatal("plain badge should not be a button") + } + disabled = true + tt.SetClipboard("") + tt.Frame() + _ = tt.Click("Copy ENG-123") + if tt.Clipboard() != "" || n != 2 { + t.Fatal("disabled badge copied") + } +} + +func TestIssueIdBadgeCopiedFades(t *testing.T) { + tt := ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + IssueIdBadge(c, "ENG-1", IssueIdBadgeOptions{Copyable: true}) + }, 300, 120) + _ = tt.Click("Copy ENG-1") + if !tt.HasText("Copied") { + t.Fatal("no Copied note") + } + time.Sleep(issueCopiedFor + 50*time.Millisecond) + tt.Frame() + if tt.HasText("Copied") { + t.Fatal("Copied should go away") + } +} + +func TestIssueIdBadgeInvalid(t *testing.T) { + for _, id := range []string{"eng-1", "ENG-0", "ENG123", ""} { + func() { + defer func() { + if recover() == nil { + t.Errorf("%q: expected panic", id) + } + }() + ui.NewTester(func(c *ui.Context) { Use(c, Settings{}); IssueIdBadge(c, id, IssueIdBadgeOptions{}) }, 10, 10) + }() + } +} + +func TestIssueIdBadgeSnapshot(t *testing.T) { + snapshot(t, "issue_id_badge", 300, 60, func(c *ui.Context) { + ui.Row(c).Padding(16).Gap(12).AlignItems(ui.Center).Children(func() { + IssueIdBadge(c, "ENG-123", IssueIdBadgeOptions{Copyable: true}) + IssueIdBadge(c, "OPS-7", IssueIdBadgeOptions{}) + }) + }) +} diff --git a/kanban_board.go b/kanban_board.go new file mode 100644 index 0000000..86ed718 --- /dev/null +++ b/kanban_board.go @@ -0,0 +1,263 @@ +package mujica + +import ( + "fmt" + "log/slog" + "slices" + + "github.com/egoist/mygo/ui" + + "mujicaui/icons" + "mujicaui/theme" +) + +// KanbanColumn is one column, holding the tasks in Status. +type KanbanColumn struct { + Status string + // WIP limits card count; zero allows any count. + WIP int +} + +// KanbanBoardOptions configure a KanbanBoard. +type KanbanBoardOptions struct { + Columns []KanbanColumn + Statuses []WorkflowStatus + Members []Member + Labels []TaskLabel + // Version must change when tasks change in place. + Version int + Disabled bool + Label string +} + +// KanbanMove identifies a moved card and its destination. +type KanbanMove struct { + ID, From, To string + Index int +} + +// KanbanResult is the board and what the user did. +type KanbanResult struct { + Element *ui.Element + move *KanbanMove + opened string +} + +// Moved returns this frame's applied card move. +func (r KanbanResult) Moved() (KanbanMove, bool) { + if r.move == nil { + return KanbanMove{}, false + } + return *r.move, true +} + +// Opened returns the card the user activated. +func (r KanbanResult) Opened() (string, bool) { return r.opened, r.opened != "" } + +// kanbanDrag is the ID of a card being dragged. +type kanbanDrag string + +// kanbanState caches column indexes and pending focus. +type kanbanState struct { + first *Task + n, ver int + rev, at int + cols [][]int + columns []KanbanColumn + focus string + problem string + // problemAt is the column the problem belongs to. + problemAt string + lists []*ui.ListState +} + +// KanbanBoard supports status columns, WIP limits and card moves. +func KanbanBoard(c *ui.Context, tasks *[]Task, opts KanbanBoardOptions) KanbanResult { + if len(opts.Columns) == 0 { + panic("mujica: KanbanBoard needs Columns") + } + for i, col := range opts.Columns { + projectStatus(opts.Statuses, col.Status) + if col.WIP < 0 || slices.ContainsFunc(opts.Columns[:i], func(o KanbanColumn) bool { return o.Status == col.Status }) { + panic(fmt.Sprintf("mujica: KanbanBoard column %q repeats or has a negative WIP", col.Status)) + } + } + d := Density(c) + label := opts.Label + if label == "" { + label = msg(c, "kanban_board.label") + } + r := KanbanResult{} + board := ui.Row(c).Gap(d.Unit() * 3).AlignItems(ui.Stretch).Grow(1).MinHeight(0).Role(ui.RoleGroup).Label(label).Disabled(opts.Disabled) + r.Element = board + st := *ui.Local(board, "kanban", func() *kanbanState { return &kanbanState{} }) + cols := kanbanColumns(st, *tasks, opts) + apply := func(id, to, before, how string) { + from := slices.IndexFunc(*tasks, func(t Task) bool { return t.ID == id }) + ci := slices.IndexFunc(opts.Columns, func(c KanbanColumn) bool { return c.Status == to }) + if from < 0 || ci < 0 { + return + } + t := (*tasks)[from] + if wip := opts.Columns[ci].WIP; wip > 0 && t.Status != to && len(cols[ci]) >= wip { + st.problem, st.problemAt = fmt.Sprintf(msg(c, "kanban_board.full"), projectStatus(opts.Statuses, to).Name, wip), to + slog.Debug("mujica: kanban_board wip refused", "id", id, "to", to) + return + } + var dest []string + for _, i := range cols[ci] { + if i != from { + dest = append(dest, (*tasks)[i].ID) + } + } + rest := slices.Delete(*tasks, from, from+1) + pos := func(id string) int { return slices.IndexFunc(rest, func(x Task) bool { return x.ID == id }) } + index, at := len(dest), len(rest) + switch { + case before != "": + index, at = slices.Index(dest, before), pos(before) + case len(dest) > 0: + at = pos(dest[len(dest)-1]) + 1 + } + from0 := t.Status + t.Status = to + *tasks = slices.Insert(rest, at, t) + st.rev++ + st.focus, st.problem = id, "" + st.lists[ci].ScrollIntoView(index) + r.move = &KanbanMove{ID: id, From: from0, To: to, Index: index} + slog.Debug("mujica: kanban_board move", "id", id, "from", from0, "to", to, "index", index, "by", how) + } + // Apply moves after building all rows. + var pending func() + move := func(id, to, before, how string) { + if !board.IsDisabled() && id != before && pending == nil { + pending = func() { apply(id, to, before, how) } + } + } + board.Children(func() { + for ci, col := range opts.Columns { + kanbanColumn(c, st, ci, col, func(i int) []int { return cols[i] }, *tasks, opts, &r, move) + } + }) + if pending != nil { + pending() + c.Invalidate() + } + return r +} + +// kanbanColumns returns each column's task indexes, rebuilt when tasks change. +func kanbanColumns(st *kanbanState, tasks []Task, opts KanbanBoardOptions) [][]int { + var first *Task + if len(tasks) > 0 { + first = &tasks[0] + } + if st.cols != nil && st.first == first && st.n == len(tasks) && st.ver == opts.Version && st.at == st.rev && slices.Equal(st.columns, opts.Columns) { + return st.cols + } + st.first, st.n, st.ver, st.at = first, len(tasks), opts.Version, st.rev + st.columns = slices.Clone(opts.Columns) + st.cols = make([][]int, len(opts.Columns)) + for i, t := range tasks { + ci := slices.IndexFunc(opts.Columns, func(c KanbanColumn) bool { return c.Status == t.Status }) + if ci < 0 { + projectStatus(opts.Statuses, t.Status) + continue + } + st.cols[ci] = append(st.cols[ci], i) + } + for len(st.lists) < len(opts.Columns) { + st.lists = append(st.lists, &ui.ListState{}) + } + return st.cols +} + +// kanbanColumn draws a header, WIP count and virtual cards. +func kanbanColumn(c *ui.Context, st *kanbanState, ci int, col KanbanColumn, colsOf func(int) []int, tasks []Task, opts KanbanBoardOptions, + r *KanbanResult, move func(id, to, before, how string)) { + k := Tokens(c) + d := Density(c) + idx := colsOf(ci) + status := projectStatus(opts.Statuses, col.Status) + over := col.WIP > 0 && len(idx) > col.WIP + full := col.WIP > 0 && len(idx) >= col.WIP + box := ui.Column(c).Key(col.Status).Width(d.ControlHeight()*7.5).Shrink(0).Gap(d.Unit()*2).Padding(d.Unit()*2). + Radius(theme.CardRadius).Background(k.Background).Border(theme.BorderWidth, k.Border).Role(ui.RoleGroup).Label(status.Name) + if id, ok := ui.Drop[kanbanDrag](box); ok && !box.IsDisabled() { + move(string(id), col.Status, "", "drag") + } + if _, ok := ui.DragOver[kanbanDrag](box); ok { + box.Border(theme.BorderWidth, k.AccentText) + } + box.Children(func() { + ui.Row(c).Gap(d.Unit() * 2).AlignItems(ui.Center).MinHeight(theme.MinHitSize).Children(func() { + statusGlyphBox(c, status.Group) + ui.Text(c, status.Name).Font(theme.SerifFont).TextColor(k.Text).Grow(1).SingleLine() + count := fmt.Sprint(len(idx)) + if col.WIP > 0 { + count = fmt.Sprintf("%d / %d", len(idx), col.WIP) + } + fg := k.TextMuted + if over { + fg = k.Danger + ui.Icon(c, icons.Must("triangle-alert")).Size(14, 14).TextColor(fg) + } + wip := ui.Text(c, count).FontSize(FontSize(c, theme.CaptionSize)).TextColor(fg).FontFeatures("tnum") + if col.WIP > 0 { + wip.Label(fmt.Sprintf(msg(c, "kanban_board.wip"), len(idx), col.WIP)) + } + }) + if over { + ui.Text(c, fmt.Sprintf(msg(c, "kanban_board.over"), len(idx)-col.WIP)).FontSize(FontSize(c, theme.CaptionSize)).TextColor(k.Danger).Role(ui.RoleStatus) + } else if full && st.problem != "" && st.problemAt == col.Status { + ui.Text(c, st.problem).FontSize(FontSize(c, theme.CaptionSize)).TextColor(k.Danger).Role(ui.RoleStatus) + } + ls := st.lists[ci] + ls.Key = func(i int) any { return tasks[idx[i]].ID } + at := func(cidx []int, i int) string { + if i < 0 || i >= len(cidx) { + return "" + } + return tasks[cidx[i]].ID + } + ui.List(c, ls, len(idx), func(i int) { + t := tasks[idx[i]] + cell := ui.Box(c).PaddingY(d.Unit()) + if id, ok := ui.Drop[kanbanDrag](cell); ok && !cell.IsDisabled() { + move(string(id), col.Status, t.ID, "drag") + } + if _, ok := ui.DragOver[kanbanDrag](cell); ok { + cell.DrawOver(func(p *ui.Painter, rr ui.Rect) { p.Fill(ui.Rect{X: rr.X, Y: rr.Y, W: rr.W, H: 2}, k.AccentText, 1) }) + } + cell.Children(func() { + card := IssueCard(c, t, IssueCardOptions{Statuses: opts.Statuses, Members: opts.Members, Labels: opts.Labels}) + if card.IsDisabled() { + return + } + card.Drag(kanbanDrag(t.ID)) + if st.focus == t.ID { + card.Focus() + st.focus = "" + } + if card.Clicked() { + r.opened = t.ID + } + switch { + case card.Shortcut(ui.Alt, ui.KeyUp) && i > 0: + move(t.ID, col.Status, at(idx, i-1), "keys") + case card.Shortcut(ui.Alt, ui.KeyDown) && i < len(idx)-1: + move(t.ID, col.Status, at(idx, i+2), "keys") + case card.Shortcut(ui.Alt, ui.KeyLeft) && ci > 0: + move(t.ID, opts.Columns[ci-1].Status, at(colsOf(ci-1), i), "keys") + case card.Shortcut(ui.Alt, ui.KeyRight) && ci < len(opts.Columns)-1: + move(t.ID, opts.Columns[ci+1].Status, at(colsOf(ci+1), i), "keys") + } + }) + }).Grow(1).MinHeight(d.ControlHeight() * 3).Children(func() { + if len(idx) == 0 { + ui.Text(c, msg(c, "kanban_board.empty")).FontSize(FontSize(c, theme.CaptionSize)).TextColor(k.TextMuted).Padding(d.Unit() * 2) + } + }) + }) +} diff --git a/kanban_board_test.go b/kanban_board_test.go new file mode 100644 index 0000000..f662109 --- /dev/null +++ b/kanban_board_test.go @@ -0,0 +1,177 @@ +package mujica + +import ( + "fmt" + "strings" + "testing" + + "github.com/egoist/mygo/ui" +) + +var kanbanColumns3 = []KanbanColumn{{Status: "todo"}, {Status: "doing", WIP: 3}, {Status: "review"}, {Status: "done"}} + +type kanbanProbe struct { + tasks []Task + cols []KanbanColumn + disabled bool + moves []KanbanMove + opened []string +} + +func (p *kanbanProbe) tester() *ui.Tester { + if p.cols == nil { + p.cols = kanbanColumns3 + } + return ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + ui.Column(c).Height(560).Padding(8).Children(func() { + r := KanbanBoard(c, &p.tasks, KanbanBoardOptions{Columns: p.cols, Statuses: projStatuses, Members: projMembers, + Labels: projLabels, Disabled: p.disabled}) + if m, ok := r.Moved(); ok { + p.moves = append(p.moves, m) + } + if id, ok := r.Opened(); ok { + p.opened = append(p.opened, id) + } + }) + }, 1240, 600) +} + +// kanbanOrder lists IDs per status in slice order. +func kanbanOrder(tasks []Task, status string) string { + var out []string + for _, t := range tasks { + if t.Status == status { + out = append(out, t.ID) + } + } + return strings.Join(out, ",") +} + +func TestKanbanBoardDragAcrossAndWithin(t *testing.T) { + p := &kanbanProbe{tasks: projTasks()} + tt := p.tester() + src, _ := tt.Find("AVE-1 Write the overture") + dst, _ := tt.Find("AVE-4 Rehearse act two") + calDrag(tt, src.X+20, src.Y+20, dst.X+20, dst.Y+10) + if kanbanOrder(p.tasks, "review") != "AVE-1,AVE-4" || kanbanOrder(p.tasks, "todo") != "" || len(p.moves) != 1 || + p.moves[0] != (KanbanMove{ID: "AVE-1", From: "todo", To: "review", Index: 0}) { + t.Fatalf("drag onto a card: %v %+v", kanbanOrder(p.tasks, "review"), p.moves) + } + src, _ = tt.Find("AVE-2 Tune the organ") + col, _ := tt.Find("In Progress") + calDrag(tt, src.X+20, src.Y+20, col.X+20, col.Y+400) + if kanbanOrder(p.tasks, "doing") != "AVE-3,AVE-2" { + t.Fatalf("drag to the column end: %v", kanbanOrder(p.tasks, "doing")) + } +} + +func TestKanbanBoardKeyboardMoves(t *testing.T) { + p := &kanbanProbe{tasks: projTasks()} + tt := p.tester() + _ = tt.Click("AVE-2 Tune the organ") + tt.Key(ui.Alt, ui.KeyDown) + if kanbanOrder(p.tasks, "doing") != "AVE-3,AVE-2" || !tt.Focused("AVE-2 Tune the organ") { + t.Fatalf("Alt+Down %v", kanbanOrder(p.tasks, "doing")) + } + tt.Key(ui.Alt, ui.KeyRight) + if kanbanOrder(p.tasks, "review") != "AVE-4,AVE-2" || !tt.Focused("AVE-2 Tune the organ") { + t.Fatalf("Alt+Right %v", kanbanOrder(p.tasks, "review")) + } + tt.Key(ui.Alt, ui.KeyUp) + if kanbanOrder(p.tasks, "review") != "AVE-2,AVE-4" { + t.Fatalf("Alt+Up %v", kanbanOrder(p.tasks, "review")) + } + tt.Key(0, ui.KeyEnter) + if len(p.opened) != 2 || p.opened[1] != "AVE-2" { + t.Fatalf("opened %v", p.opened) + } +} + +func TestKanbanBoardWIPLimit(t *testing.T) { + p := &kanbanProbe{tasks: projTasks(), cols: []KanbanColumn{{Status: "todo"}, {Status: "doing", WIP: 2}, {Status: "review"}, {Status: "done"}}} + tt := p.tester() + if !tt.HasText("2 of 2 cards") { + t.Fatalf("WIP count %v", tt.Texts()) + } + _ = tt.Click("AVE-1 Write the overture") + tt.Key(ui.Alt, ui.KeyRight) + if kanbanOrder(p.tasks, "todo") != "AVE-1" || !tt.HasText("In Progress is at its limit of 2 cards.") { + t.Fatalf("WIP not enforced: %v", tt.Texts()) + } + p.cols[1].WIP = 1 + tt.Frame() + if !tt.HasText("1 over the limit") { + t.Fatal("over-limit warning missing") + } +} + +func TestKanbanBoardDisabledAndInvalid(t *testing.T) { + p := &kanbanProbe{tasks: projTasks(), disabled: true} + tt := p.tester() + src, _ := tt.Find("AVE-1 Write the overture") + dst, _ := tt.Find("AVE-4 Rehearse act two") + calDrag(tt, src.X+20, src.Y+20, dst.X+20, dst.Y+10) + _ = tt.Click("AVE-1 Write the overture") + tt.Key(ui.Alt, ui.KeyRight) + if len(p.moves) != 0 || len(p.opened) != 0 || kanbanOrder(p.tasks, "todo") != "AVE-1" { + t.Fatal("disabled board changed") + } + defer func() { + if recover() == nil { + t.Fatal("expected panic for a repeated column") + } + }() + q := &kanbanProbe{tasks: projTasks(), cols: []KanbanColumn{{Status: "todo"}, {Status: "todo"}}} + q.tester() +} + +func TestKanbanBoardLargeData(t *testing.T) { + p := &kanbanProbe{} + for i := range 100000 { + p.tasks = append(p.tasks, Task{ID: fmt.Sprintf("BIG-%d", i+1), Title: "Card", Status: kanbanColumns3[i%4].Status}) + } + p.cols = []KanbanColumn{{Status: "todo"}, {Status: "doing"}, {Status: "review"}, {Status: "done"}} + tt := p.tester() + if n := len(tt.Texts()); n > 600 { + t.Fatalf("built %d labels", n) + } +} + +func TestKanbanBoardSnapshot(t *testing.T) { + tasks := projTasks() + snapshot(t, "kanban_board", 1240, 460, func(c *ui.Context) { + ui.Column(c).Height(460).Padding(16).Children(func() { + KanbanBoard(c, &tasks, KanbanBoardOptions{Columns: kanbanColumns3, Statuses: projStatuses, Members: projMembers, Labels: projLabels}) + }) + }) +} + +func TestKanbanBoardColumnChanges(t *testing.T) { + p := &kanbanProbe{tasks: projTasks(), cols: []KanbanColumn{{Status: "todo"}, {Status: "doing"}}} + tt := p.tester() + p.cols = []KanbanColumn{{Status: "done"}, {Status: "review"}, {Status: "doing"}} + tt.Frame() + if !tt.HasText("AVE-5 Book the hall") || !tt.HasText("AVE-4 Rehearse act two") { + t.Fatal("columns retain old indexes") + } +} + +func TestKanbanBoardForeignDrop(t *testing.T) { + left := []Task{{ID: "A-1", Title: "First", Status: "todo"}} + right := []Task{{ID: "B-1", Title: "Second", Status: "todo"}} + opts := KanbanBoardOptions{Columns: []KanbanColumn{{Status: "todo"}}, Statuses: projStatuses} + tt := ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + ui.Row(c).Height(400).Children(func() { + ui.Box(c).Key("left").Width(300).Height(400).Children(func() { KanbanBoard(c, &left, opts) }) + ui.Box(c).Key("right").Width(300).Height(400).Children(func() { KanbanBoard(c, &right, opts) }) + }) + }, 640, 420) + src, _ := tt.Find("A-1 First") + dst, _ := tt.Find("B-1 Second") + calDrag(tt, src.X+20, src.Y+20, dst.X+20, dst.Y+10) + if len(left) != 1 || left[0].ID != "A-1" || len(right) != 1 || right[0].ID != "B-1" { + t.Fatal("foreign drop changed another board") + } +} diff --git a/label_manager.go b/label_manager.go new file mode 100644 index 0000000..455a570 --- /dev/null +++ b/label_manager.go @@ -0,0 +1,208 @@ +package mujica + +import ( + "fmt" + "log/slog" + "slices" + "strings" + + "github.com/egoist/mygo/ui" + + "mujicaui/icons" + "mujicaui/internal" + "mujicaui/theme" +) + +// LabelManagerOptions configure a LabelManager. +type LabelManagerOptions struct { + Disabled bool + Label string + // Version changes when labels or selection change in place. + Version int +} + +// labelManagerState is the label being edited and the new-label draft. +type labelManagerState struct { + editing string + name string + draft string + problem string +} + +// LabelManager edits labels and stores chosen IDs in selected. +func LabelManager(c *ui.Context, labels *[]TaskLabel, selected *[]string, opts LabelManagerOptions) ChoiceResult { + k := Tokens(c) + d := Density(c) + label := opts.Label + if label == "" { + label = msg(c, "label_manager.label") + } + changed := false + col := ui.Column(c).Gap(d.Unit() * 2).Role(ui.RoleGroup).Label(label).Disabled(opts.Disabled) + st := ui.Local(col, "label-manager", func() *labelManagerState { return &labelManagerState{} }) + s := *st + cache := ui.Local(col, "label-data", func() labelDataCache { return labelDataCache{} }) + var first *TaskLabel + var selectedFirst *string + if len(*labels) > 0 { + first = &(*labels)[0] + } + if len(*selected) > 0 { + selectedFirst = &(*selected)[0] + } + if !cache.ready || cache.first != first || cache.n != len(*labels) || cache.selectedFirst != selectedFirst || cache.selectedN != len(*selected) || cache.version != opts.Version { + *cache = labelDataCache{first: first, n: len(*labels), selectedFirst: selectedFirst, selectedN: len(*selected), version: opts.Version, ready: true, selected: map[string]bool{}} + known := map[string]bool{} + for _, l := range *labels { + eventColor(k, l.Color) + if l.ID == "" || known[l.ID] { + panic("mujica: LabelManager needs unique non-empty IDs") + } + known[l.ID] = true + } + for _, id := range *selected { + if !known[id] { + panic("mujica: LabelManager selection contains an unknown ID") + } + cache.selected[id] = true + } + } + state := ui.Local(col, "label-rows", func() ui.ListState { return ui.ListState{} }) + state.Key = func(i int) any { return (*labels)[i].ID } + + live := func() bool { return !col.IsDisabled() } + taken := func(name, except string) bool { + return slices.ContainsFunc(*labels, func(l TaskLabel) bool { return l.ID != except && strings.EqualFold(l.Name, name) }) + } + col.Children(func() { + removed := -1 + ui.List(c, state, len(*labels), func(i int) { + l := &(*labels)[i] + ui.Row(c).Key(l.ID).MinHeight(d.ControlHeight()).Gap(d.Unit() * 2).AlignItems(ui.Center).Children(func() { + on := cache.selected[l.ID] + box := ui.CheckboxBase(c, &on).Size(theme.MinHitSize, theme.MinHitSize).Center().Label(l.Name) + internal.Ring(box, k.Focus, theme.ControlRadius) + if box.Draw(func(p *ui.Painter, r ui.Rect) { labelSwatch(p, r, eventColor(k, l.Color), on, k) }).Changed() && live() { + if on { + *selected = append(*selected, l.ID) + } else { + *selected = slices.DeleteFunc(*selected, func(id string) bool { return id == l.ID }) + } + changed = true + slog.Debug("mujica: label_manager select", "id", l.ID, "selected", on) + } + if s.editing == l.ID && live() { + labelEditRow(c, s, l, taken, &changed) + return + } + ui.Text(c, l.Name).Grow(1).TextColor(k.Text).SingleLine().Ellipsis("…") + if b := iconAction(c, icons.Must("palette"), fmt.Sprintf(msg(c, "label_manager.edit"), l.Name)); b.Clicked() && live() { + s.editing, s.name, s.problem = l.ID, l.Name, "" + } + if b := iconAction(c, icons.Must("trash-2"), fmt.Sprintf(msg(c, "label_manager.delete"), l.Name)); b.Clicked() && live() { + removed = i + } + }) + }).Height(min(float32(len(*labels)), 8) * d.ControlHeight()) + if removed >= 0 { + id := (*labels)[removed].ID + slog.Debug("mujica: label_manager delete", "id", id) + *labels = slices.Delete(*labels, removed, removed+1) + *selected = slices.DeleteFunc(*selected, func(x string) bool { return x == id }) + changed = true + } + if len(*labels) == 0 { + ui.Text(c, msg(c, "label_manager.empty")).TextColor(k.TextMuted) + } + in := TextInput(c, &s.draft, TextInputOptions{Placeholder: msg(c, "label_manager.new"), Label: msg(c, "label_manager.new"), + Disabled: opts.Disabled, Error: s.problem}) + if in.Submitted() && live() { + name := strings.TrimSpace(s.draft) + switch { + case name == "": + case taken(name, ""): + s.problem = fmt.Sprintf(msg(c, "label_manager.taken"), name) + default: + l := TaskLabel{ID: labelNewID(*labels), Name: name, Color: EventColor(len(*labels) % 6)} + *labels = append(*labels, l) + s.draft, s.problem, changed = "", "", true + slog.Debug("mujica: label_manager create", "id", l.ID) + } + } + }) + if changed { + cache.ready = false + c.Invalidate() + } + return ChoiceResult{Element: col, changed: changed} +} + +// labelEditRow renames a label and picks its color. +func labelEditRow(c *ui.Context, s *labelManagerState, l *TaskLabel, taken func(string, string) bool, changed *bool) { + k := Tokens(c) + d := Density(c) + ui.Column(c).Grow(1).Gap(d.Unit()).Children(func() { + in := TextInput(c, &s.name, TextInputOptions{Label: msg(c, "label_manager.name"), Error: s.problem}) + in.Input.AutoFocus() + ui.Row(c).Gap(d.Unit()).Role(ui.RoleRadioGroup).Label(msg(c, "label_manager.color")).Children(func() { + for i := range 6 { + col := EventColor(i) + sel := l.Color + b := ui.RadioBase(c, &sel, col).Size(theme.MinHitSize, theme.MinHitSize).Label(msg(c, labelColorKeys[i])) + internal.Ring(b, k.Focus, theme.ControlRadius) + on := l.Color == col + b.Draw(func(p *ui.Painter, r ui.Rect) { labelSwatch(p, r, eventColor(k, col), on, k) }) + if b.Changed() && !b.IsDisabled() { + l.Color, *changed = col, true + slog.Debug("mujica: label_manager color", "id", l.ID, "color", col) + } + } + }) + done := in.Submitted() || in.Input.Shortcut(0, ui.KeyEscape) + if in.Submitted() { + name := strings.TrimSpace(s.name) + switch { + case name == "": + done = false + case taken(name, l.ID): + s.problem, done = fmt.Sprintf(msg(c, "label_manager.taken"), name), false + case name != l.Name: + l.Name, *changed = name, true + slog.Debug("mujica: label_manager rename", "id", l.ID) + } + } + if done { + s.editing, s.problem = "", "" + } + }) +} + +var labelColorKeys = [...]string{"label_manager.accent", "label_manager.info", "label_manager.success", "label_manager.warning", + "label_manager.danger", "label_manager.neutral"} + +// labelSwatch draws a color dot with a selection check. +func labelSwatch(p *ui.Painter, r ui.Rect, col ui.Color, on bool, k theme.Tokens) { + box := ui.Rect{X: r.X + r.W/2 - 8, Y: r.Y + r.H/2 - 8, W: 16, H: 16} + p.Fill(box, col, 8) + if on { + internal.Mark(p, ui.Rect{X: box.X + 2, Y: box.Y + 2, W: 12, H: 12}, "check", k.Surface) + } +} + +// labelNewID returns an ID no label uses. +func labelNewID(labels []TaskLabel) string { + for n := len(labels) + 1; ; n++ { + id := fmt.Sprintf("label-%d", n) + if !slices.ContainsFunc(labels, func(l TaskLabel) bool { return l.ID == id }) { + return id + } + } +} + +type labelDataCache struct { + first *TaskLabel + selectedFirst *string + n, selectedN, version int + ready bool + selected map[string]bool +} diff --git a/label_manager_test.go b/label_manager_test.go new file mode 100644 index 0000000..8b1ff3c --- /dev/null +++ b/label_manager_test.go @@ -0,0 +1,102 @@ +package mujica + +import ( + "fmt" + "slices" + "testing" + + "github.com/egoist/mygo/ui" +) + +func labelTester(labels *[]TaskLabel, sel *[]string, opts *LabelManagerOptions, n *int) *ui.Tester { + return ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + ui.Column(c).Padding(16).Children(func() { + if LabelManager(c, labels, sel, *opts).Changed() { + *n++ + } + }) + }, 480, 480) +} + +func TestLabelManagerSelectCreateDelete(t *testing.T) { + labels, sel, n := slices.Clone(projLabels), []string{}, 0 + tt := labelTester(&labels, &sel, &LabelManagerOptions{}, &n) + _ = tt.Click("UI") + if !slices.Equal(sel, []string{"ui"}) { + t.Fatalf("select %v", sel) + } + _ = tt.Click("New label") + tt.Type("Docs") + tt.Key(0, ui.KeyEnter) + if len(labels) != 3 || !tt.HasText(`A label named "Docs" exists.`) { + t.Fatalf("duplicate accepted: %v", labels) + } + tt.Command("selectAll") + tt.Type("Performance") + tt.Key(0, ui.KeyEnter) + if len(labels) != 4 || labels[3].Name != "Performance" || labels[3].ID != "label-4" { + t.Fatalf("create %+v", labels) + } + _ = tt.Click("Delete UI") + if len(labels) != 3 || len(sel) != 0 || n != 3 { + t.Fatalf("delete left %+v sel %v (%d)", labels, sel, n) + } +} + +func TestLabelManagerRenameAndColor(t *testing.T) { + labels, sel, n := slices.Clone(projLabels), []string{}, 0 + tt := labelTester(&labels, &sel, &LabelManagerOptions{}, &n) + _ = tt.Click("Edit Bug") + _ = tt.Click("Green") + _ = tt.Click("Label name") + tt.Command("selectAll") + tt.Type("UI") + tt.Key(0, ui.KeyEnter) + if labels[0].Color != EventSuccess || labels[0].Name != "Bug" || !tt.HasText(`A label named "UI" exists.`) { + t.Fatalf("color/duplicate %+v", labels[0]) + } + tt.Command("selectAll") + tt.Type("Defect") + tt.Key(0, ui.KeyEnter) + if labels[0].Name != "Defect" || tt.HasText("Label name") { + t.Fatalf("rename %+v", labels[0]) + } +} + +func TestLabelManagerDisabledAndInvalid(t *testing.T) { + labels, sel, n := slices.Clone(projLabels), []string{}, 0 + tt := labelTester(&labels, &sel, &LabelManagerOptions{Disabled: true}, &n) + _ = tt.Click("UI") + _ = tt.Click("Delete Bug") + _ = tt.Click("Edit Bug") + if n != 0 || len(labels) != 3 || len(sel) != 0 || tt.HasText("Label name") { + t.Fatal("disabled manager changed") + } + defer func() { + if recover() == nil { + t.Fatal("expected panic for an unknown selected label") + } + }() + bad := []string{"ghost"} + labelTester(&labels, &bad, &LabelManagerOptions{}, &n) +} + +func TestLabelManagerSnapshot(t *testing.T) { + labels, sel := slices.Clone(projLabels), []string{"bug"} + snapshot(t, "label_manager", 400, 220, func(c *ui.Context) { + ui.Column(c).Padding(16).Children(func() { LabelManager(c, &labels, &sel, LabelManagerOptions{}) }) + }) +} + +func TestLabelManagerLargeData(t *testing.T) { + labels := make([]TaskLabel, 100000) + for i := range labels { + labels[i] = TaskLabel{ID: fmt.Sprint(i), Name: "Tag"} + } + selected, n := []string{}, 0 + tt := labelTester(&labels, &selected, &LabelManagerOptions{}, &n) + if built := len(tt.Texts()); built > 200 { + t.Fatalf("built %d labels", built) + } +} diff --git a/messages_projects.go b/messages_projects.go new file mode 100644 index 0000000..11adf92 --- /dev/null +++ b/messages_projects.go @@ -0,0 +1,120 @@ +package mujica + +func init() { + addMessages(map[string][2]string{ + "projects.overdue": {"Overdue by %d days", "逾期 %d 天"}, + "projects.overdue_one": {"Overdue by %d day", "逾期 %d 天"}, + "projects.due_today": {"Due today", "今天到期"}, + "projects.due_tomorrow": {"Due tomorrow", "明天到期"}, + "projects.due": {"Due %s %d", "%s%d日到期"}, + + "priority_indicator.none": {"No priority", "无优先级"}, + "priority_indicator.low": {"Low", "低"}, + "priority_indicator.medium": {"Medium", "中"}, + "priority_indicator.high": {"High", "高"}, + "priority_indicator.urgent": {"Urgent", "紧急"}, + + "issue_card.description": {"%s, %s", "%s,%s"}, + + "issue_id_badge.copy": {"Copy %s", "复制 %s"}, + "issue_id_badge.copied": {"Copied", "已复制"}, + "issue_id_badge.copied_label": {"%s copied", "已复制 %s"}, + + "status_select.label": {"Status", "状态"}, + "status_select.backlog": {"Backlog", "待规划"}, + "status_select.unstarted": {"To do", "未开始"}, + "status_select.started": {"In progress", "进行中"}, + "status_select.completed": {"Done", "已完成"}, + "status_select.canceled": {"Canceled", "已取消"}, + + "assignee_picker.label": {"Assignees", "负责人"}, + "assignee_picker.placeholder": {"Unassigned", "未分配"}, + + "due_date_picker.label": {"Due date", "截止日期"}, + "due_date_picker.today": {"Today", "今天"}, + "due_date_picker.tomorrow": {"Tomorrow", "明天"}, + "due_date_picker.next_week": {"Next week", "下周"}, + + "task_item.rename": {"Task title", "任务标题"}, + + "subtask_list.label": {"Subtasks", "子任务"}, + "subtask_list.progress": {"%d of %d done", "已完成 %d / %d"}, + "subtask_list.drag": {"Drag %s", "拖动 %s"}, + "subtask_list.remove": {"Remove %s", "删除 %s"}, + "subtask_list.add": {"Add a subtask", "添加子任务"}, + + "label_manager.label": {"Labels", "标签"}, + "label_manager.edit": {"Edit %s", "编辑 %s"}, + "label_manager.delete": {"Delete %s", "删除 %s"}, + "label_manager.empty": {"No labels yet.", "暂无标签。"}, + "label_manager.new": {"New label", "新建标签"}, + "label_manager.name": {"Label name", "标签名称"}, + "label_manager.color": {"Color", "颜色"}, + "label_manager.taken": {"A label named %q exists.", "已有名为 %q 的标签。"}, + "label_manager.accent": {"Crimson", "酒红"}, + "label_manager.info": {"Blue", "蓝"}, + "label_manager.success": {"Green", "绿"}, + "label_manager.warning": {"Amber", "琥珀"}, + "label_manager.danger": {"Red", "红"}, + "label_manager.neutral": {"Gray", "灰"}, + + "task_list.label": {"Tasks", "任务"}, + "task_list.filter": {"Show", "显示"}, + "task_list.all": {"All %d", "全部 %d"}, + "task_list.open": {"Open %d", "未完成 %d"}, + "task_list.done": {"Done %d", "已完成 %d"}, + "task_list.empty": {"No tasks here.", "这里没有任务。"}, + + "task_detail_panel.close": {"Close details", "关闭详情"}, + "task_detail_panel.title": {"Title", "标题"}, + "task_detail_panel.status": {"Status", "状态"}, + "task_detail_panel.priority": {"Priority", "优先级"}, + "task_detail_panel.activity": {"Activity", "活动记录"}, + + "kanban_board.label": {"Board", "看板"}, + "kanban_board.full": {"%s is at its limit of %d cards.", "%s 已达 %d 张卡片的上限。"}, + "kanban_board.wip": {"%d of %d cards", "%d / %d 张卡片"}, + "kanban_board.over": {"%d over the limit", "超出上限 %d 张"}, + "kanban_board.empty": {"No cards", "暂无卡片"}, + + "sprint_board.time": {"Time", "时间"}, + "sprint_board.done": {"%d of %d done", "已完成 %d / %d"}, + "sprint_board.progress": {"Sprint progress", "迭代进度"}, + "sprint_board.starts_in": {"Starts in %d days", "%d 天后开始"}, + "sprint_board.starts_in_one": {"Starts in %d day", "%d 天后开始"}, + "sprint_board.ended": {"Ended", "已结束"}, + "sprint_board.left": {"%d days left", "剩余 %d 天"}, + "sprint_board.left_one": {"%d day left", "剩余 %d 天"}, + + "milestone_progress.count": {"%d of %d tasks done", "已完成 %d / %d 个任务"}, + "milestone_progress.reached": {"Reached", "已达成"}, + + "workload_view.label": {"Workload", "工作负载"}, + "workload_view.hours": {"h", "小时"}, + "workload_view.over": {"over by %s %s", "超出 %s %s"}, + "workload_view.overloaded": {"%d people are over capacity", "%d 人超出负荷"}, + "workload_view.overloaded_one": {"%d person is over capacity", "%d 人超出负荷"}, + + "time_tracker.label": {"Time tracked", "已记录时间"}, + "time_tracker.start": {"Start", "开始"}, + "time_tracker.stop": {"Stop", "停止"}, + "time_tracker.running": {"Tracking…", "计时中…"}, + "time_tracker.correct": {"Correct the total", "修正总时长"}, + "time_tracker.apply": {"Apply", "应用"}, + + "pomodoro_timer.label": {"Pomodoro timer", "番茄钟"}, + "pomodoro_timer.focus": {"Focus", "专注"}, + "pomodoro_timer.break": {"Short break", "短休息"}, + "pomodoro_timer.long_break": {"Long break", "长休息"}, + "pomodoro_timer.done": {"%s finished.", "%s结束。"}, + "pomodoro_timer.left": {"%s, %s left", "%s,剩余 %s"}, + "pomodoro_timer.sessions": {"%d of %d sessions before a long break", "距长休息:%d / %d 轮"}, + "pomodoro_timer.start": {"Start", "开始"}, + "pomodoro_timer.pause": {"Pause", "暂停"}, + "pomodoro_timer.skip": {"Skip", "跳过"}, + "pomodoro_timer.reset": {"Reset", "重置"}, + + "burndown_chart.actual": {"Remaining", "剩余"}, + "burndown_chart.ideal": {"Ideal", "理想"}, + }) +} diff --git a/milestone_progress.go b/milestone_progress.go new file mode 100644 index 0000000..42bc9f1 --- /dev/null +++ b/milestone_progress.go @@ -0,0 +1,72 @@ +package mujica + +import ( + "fmt" + + "github.com/egoist/mygo/ui" + + "mujicaui/icons" + "mujicaui/internal" + "mujicaui/theme" +) + +// Milestone holds a goal, due date and completion counts. +type Milestone struct { + Title string + Due Date + Done, Total int +} + +// MilestoneProgressOptions configure a MilestoneProgress. +type MilestoneProgressOptions struct { + // Today anchors the date note; zero uses the system clock. + Today Date +} + +// MilestoneProgress shows completion counts, progress and due dates. +func MilestoneProgress(c *ui.Context, m Milestone, opts MilestoneProgressOptions) *ui.Element { + datetimeCheckDate("MilestoneProgress Due", m.Due) + if m.Total < 0 || m.Done < 0 || m.Done > m.Total { + panic(fmt.Sprintf("mujica: MilestoneProgress %d of %d is not valid", m.Done, m.Total)) + } + k := Tokens(c) + d := Density(c) + today := datetimeToday(c, opts.Today) + frac := 0.0 + if m.Total > 0 { + frac = float64(m.Done) / float64(m.Total) + } + reached := m.Total > 0 && m.Done == m.Total + pct := fmt.Sprintf("%d%%", int(frac*100)) + col := ui.Column(c).Gap(d.Unit()*2).Padding(d.Unit()*3).Radius(theme.CardRadius).Border(theme.BorderWidth, k.Border). + Background(k.Surface).Role(ui.RoleGroup).Label(m.Title).Description(pct) + col.Children(func() { + ui.Row(c).Gap(d.Unit() * 2).AlignItems(ui.Center).Children(func() { + ui.Box(c).Size(12, 12).Shrink(0).Draw(func(p *ui.Painter, r ui.Rect) { + p.FillPath(internal.Diamond(r.X+r.W/2, r.Y+r.H/2, r.W), k.Ornament) + }) + ui.Text(c, m.Title).Font(theme.SerifFont).TextColor(k.Text).Grow(1).SingleLine().Ellipsis("…") + ui.Text(c, pct).TextColor(k.AccentText).FontFeatures("tnum") + }) + projectBar(c, frac, m.Title) + ui.Row(c).Gap(d.Unit() * 2).AlignItems(ui.Center).Children(func() { + ui.Text(c, fmt.Sprintf(msg(c, "milestone_progress.count"), m.Done, m.Total)).FontSize(FontSize(c, theme.CaptionSize)). + TextColor(k.TextMuted).Grow(1).FontFeatures("tnum") + text, late := projectDueText(c, m.Due, today, reached) + fg, icon := k.TextMuted, "calendar" + switch { + case reached: + text, fg, icon = msg(c, "milestone_progress.reached"), k.Success, "circle-check" + case late: + fg, icon = k.Danger, "triangle-alert" + } + if text != "" { + ui.Row(c).Gap(d.Unit()).AlignItems(ui.Center).TextColor(fg).Role(ui.RoleStatus).Children(func() { + ui.Icon(c, icons.Must(icon)).Size(14, 14) + ui.Text(c, text).FontSize(FontSize(c, theme.CaptionSize)) + }) + } + }) + }) + return col +} diff --git a/milestone_progress_test.go b/milestone_progress_test.go new file mode 100644 index 0000000..70466bd --- /dev/null +++ b/milestone_progress_test.go @@ -0,0 +1,55 @@ +package mujica + +import ( + "testing" + + "github.com/egoist/mygo/ui" +) + +func milestoneTester(m Milestone) *ui.Tester { + return ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + ui.Box(c).Width(360).Children(func() { MilestoneProgress(c, m, MilestoneProgressOptions{Today: calendarToday}) }) + }, 400, 200) +} + +func TestMilestoneProgressStates(t *testing.T) { + for _, c := range []struct { + m Milestone + want []string + }{ + {Milestone{Title: "Act one", Due: oct(12), Done: 3, Total: 8}, []string{"37%", "3 of 8 tasks done", "Due October 12"}}, + {Milestone{Title: "Act two", Due: oct(1), Done: 5, Total: 8}, []string{"62%", "Overdue by 4 days"}}, + {Milestone{Title: "Premiere", Due: oct(1), Done: 4, Total: 4}, []string{"100%", "Reached"}}, + {Milestone{Title: "Encore", Total: 0}, []string{"0%", "0 of 0 tasks done"}}, + } { + tt := milestoneTester(c.m) + for _, s := range c.want { + if !tt.HasText(s) { + t.Errorf("%s: missing %q in %v", c.m.Title, s, tt.Texts()) + } + } + } + if tt := milestoneTester(Milestone{Title: "Premiere", Due: oct(1), Done: 4, Total: 4}); tt.HasText("Overdue") { + t.Error("a reached milestone is not overdue") + } +} + +func TestMilestoneProgressInvalid(t *testing.T) { + defer func() { + if recover() == nil { + t.Fatal("expected panic") + } + }() + milestoneTester(Milestone{Title: "x", Done: 5, Total: 3}) +} + +func TestMilestoneProgressSnapshot(t *testing.T) { + snapshot(t, "milestone_progress", 760, 140, func(c *ui.Context) { + ui.Row(c).Padding(16).Gap(16).Children(func() { + for _, m := range []Milestone{{Title: "Act one", Due: oct(12), Done: 3, Total: 8}, {Title: "Act two", Due: oct(1), Done: 5, Total: 8}} { + ui.Box(c).Width(350).Children(func() { MilestoneProgress(c, m, MilestoneProgressOptions{Today: calendarToday}) }) + } + }) + }) +} diff --git a/pomodoro_timer.go b/pomodoro_timer.go new file mode 100644 index 0000000..21b1731 --- /dev/null +++ b/pomodoro_timer.go @@ -0,0 +1,212 @@ +package mujica + +import ( + "fmt" + "log/slog" + "math" + "time" + + "github.com/egoist/mygo/ui" + + "mujicaui/icons" + "mujicaui/internal" + "mujicaui/theme" +) + +// PomodoroPhase is the part of the cycle running. +type PomodoroPhase int + +const ( + PomodoroFocus PomodoroPhase = iota + PomodoroBreak + PomodoroLongBreak +) + +// PomodoroState holds the cycle, sessions and running clock. +type PomodoroState struct { + phase PomodoroPhase + focused int + running bool + since time.Time + spent time.Duration +} + +// Phase returns the current phase. +func (s *PomodoroState) Phase() PomodoroPhase { return s.phase } + +// Sessions returns how many focus sessions finished. +func (s *PomodoroState) Sessions() int { return s.focused } + +// Running reports whether the clock runs. +func (s *PomodoroState) Running() bool { return s.running } + +func (s *PomodoroState) elapsed(now time.Time) time.Duration { + if s.running { + return s.spent + now.Sub(s.since) + } + return s.spent +} + +// PomodoroTimerOptions configure a PomodoroTimer. +type PomodoroTimerOptions struct { + // Focus/Break/LongBreak default to 25/5/15 minutes. + Focus, Break, LongBreak time.Duration + // LongEvery counts sessions per long break; zero means four. + LongEvery int + // Now fixes the clock; zero uses the system clock. + Now time.Time + Disabled bool + Label string +} + +// PomodoroResult is the timer and what changed this frame. +type PomodoroResult struct { + Element *ui.Element + changed bool + finished PomodoroPhase + done bool +} + +// Changed reports a start, pause, skip or reset. +func (r PomodoroResult) Changed() bool { return r.changed } + +// Finished returns the phase that ran out this frame. +func (r PomodoroResult) Finished() (PomodoroPhase, bool) { return r.finished, r.done } + +// PomodoroTimer cycles focus and breaks with pause, skip and reset. +func PomodoroTimer(c *ui.Context, s *PomodoroState, opts PomodoroTimerOptions) PomodoroResult { + lengths := [3]time.Duration{opts.Focus, opts.Break, opts.LongBreak} + for i, def := range []time.Duration{25 * time.Minute, 5 * time.Minute, 15 * time.Minute} { + if lengths[i] < 0 || lengths[i]%time.Second != 0 { + panic(fmt.Sprintf("mujica: PomodoroTimer length %v is negative or finer than a second", lengths[i])) + } + if lengths[i] == 0 { + lengths[i] = def + } + } + every := opts.LongEvery + if every < 0 { + panic("mujica: PomodoroTimer LongEvery is negative") + } + if every == 0 { + every = 4 + } + now := opts.Now + live := now.IsZero() + if live { + now = c.Now() + } + k := Tokens(c) + d := Density(c) + label := opts.Label + if label == "" { + label = msg(c, "pomodoro_timer.label") + } + r := PomodoroResult{} + next := func() { + if s.phase == PomodoroFocus { + s.focused++ + s.phase = PomodoroBreak + if s.focused%every == 0 { + s.phase = PomodoroLongBreak + } + } else { + s.phase = PomodoroFocus + } + s.running, s.spent = false, 0 + } + if s.running && s.elapsed(now) >= lengths[s.phase] { + r.finished, r.done = s.phase, true + c.Announce(fmt.Sprintf(msg(c, "pomodoro_timer.done"), msg(c, pomodoroKeys[s.phase]))) + slog.Debug("mujica: pomodoro_timer finished", "phase", s.phase) + next() + } + col := ui.Column(c).Gap(d.Unit() * 3).AlignItems(ui.Center).Role(ui.RoleGroup).Label(label).Disabled(opts.Disabled) + r.Element = col + act := func(what string, fn func()) { + if col.IsDisabled() { + return + } + fn() + r.changed = true + slog.Debug("mujica: pomodoro_timer "+what, "phase", s.phase) + } + left := lengths[s.phase] - s.elapsed(now) + secs := int(math.Ceil(left.Seconds())) + frac := 1 - float32(secs)/float32(lengths[s.phase]/time.Second) + col.Children(func() { + phase := msg(c, pomodoroKeys[s.phase]) + text := fmt.Sprintf("%02d:%02d", secs/60, secs%60) + ring := ui.Box(c).Size(160, 160).Center().Role(ui.RoleStatus).Label(fmt.Sprintf(msg(c, "pomodoro_timer.left"), phase, CountdownText(c, time.Duration(secs)*time.Second, CountdownWords))) + tone := k.AccentText + if s.phase != PomodoroFocus { + tone = k.Success + } + ring.Draw(func(p *ui.Painter, rr ui.Rect) { + cx, cy := internal.Snap(p, rr.X+rr.W/2), internal.Snap(p, rr.Y+rr.H/2) + p.FillPath(pomodoroSector(p, cx, cy, 70, 76, 2*math.Pi), k.Border) + if frac > 0 && !c.Preferences().ReduceMotion { + p.FillPath(pomodoroSector(p, cx, cy, 70, 76, 2*math.Pi*float64(frac)), tone) + } + }) + ring.Children(func() { + ui.Column(c).AlignItems(ui.Center).Gap(2).Children(func() { + ui.Text(c, text).Font(theme.MonoFont).FontSize(FontSize(c, theme.H1Size)).TextColor(k.Text).FontFeatures("tnum") + ui.Text(c, phase).FontSize(FontSize(c, theme.CaptionSize)).TextColor(tone) + }) + }) + ui.Text(c, fmt.Sprintf(msg(c, "pomodoro_timer.sessions"), s.focused%every, every)).FontSize(FontSize(c, theme.CaptionSize)).TextColor(k.TextMuted) + ui.Row(c).Gap(d.Unit() * 2).Children(func() { + key, icon, variant := "pomodoro_timer.start", "play", Primary + if s.running { + key, icon, variant = "pomodoro_timer.pause", "pause", Secondary + } + if Button(c, msg(c, key), ButtonOptions{Variant: variant, Icon: icons.Must(icon)}).Clicked() { + act("toggle", func() { + if s.running { + s.spent, s.running = s.elapsed(now), false + } else { + s.since, s.running = now, true + } + }) + } + if Button(c, msg(c, "pomodoro_timer.skip"), ButtonOptions{Variant: Secondary}).Clicked() { + act("skip", next) + } + if Button(c, msg(c, "pomodoro_timer.reset"), ButtonOptions{Variant: Ghost, Icon: icons.Must("rotate-ccw")}).Clicked() { + act("reset", func() { *s = PomodoroState{} }) + } + }) + }) + if s.running && live { + delay := left % time.Second + if delay == 0 { + delay = time.Second + } + c.After(delay) + } + return r +} + +var pomodoroKeys = [...]string{"pomodoro_timer.focus", "pomodoro_timer.break", "pomodoro_timer.long_break"} + +// pomodoroSector snaps every changing vertex to the cache grid. +func pomodoroSector(p *ui.Painter, cx, cy, inner, outer float32, end float64) *ui.Path { + var path ui.Path + n := max(2, int(math.Ceil(end/(math.Pi/48)))) + for i := 0; i <= n; i++ { + x, y := internal.Polar(cx, cy, outer, end*float64(i)/float64(n)) + x, y = internal.Snap(p, x), internal.Snap(p, y) + if i == 0 { + path.MoveTo(x, y) + } else { + path.LineTo(x, y) + } + } + for i := n; i >= 0; i-- { + x, y := internal.Polar(cx, cy, inner, end*float64(i)/float64(n)) + path.LineTo(internal.Snap(p, x), internal.Snap(p, y)) + } + path.Close() + return &path +} diff --git a/pomodoro_timer_test.go b/pomodoro_timer_test.go new file mode 100644 index 0000000..2c95216 --- /dev/null +++ b/pomodoro_timer_test.go @@ -0,0 +1,132 @@ +package mujica + +import ( + "testing" + "time" + + "github.com/egoist/mygo/ui" +) + +type pomodoroProbe struct { + s PomodoroState + now time.Time + opts PomodoroTimerOptions + finished []PomodoroPhase + changes int +} + +func (p *pomodoroProbe) tester() *ui.Tester { + p.now = time.Date(2026, time.October, 5, 9, 0, 0, 0, time.UTC) + return ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + o := p.opts + o.Now = p.now + r := PomodoroTimer(c, &p.s, o) + if ph, ok := r.Finished(); ok { + p.finished = append(p.finished, ph) + } + if r.Changed() { + p.changes++ + } + }, 400, 400) +} + +func TestPomodoroTimerCycle(t *testing.T) { + p := &pomodoroProbe{opts: PomodoroTimerOptions{Focus: 2 * time.Second, Break: time.Second, LongBreak: 3 * time.Second, LongEvery: 2}} + tt := p.tester() + if !tt.HasText("Focus, 2 s left") { + t.Fatalf("start %v", tt.Texts()) + } + _ = tt.Click("Start") + p.now = p.now.Add(900 * time.Millisecond) + tt.Frame() + if !tt.HasText("Focus, 2 s left") { + t.Fatal("seconds round up") + } + _ = tt.Click("Pause") + p.now = p.now.Add(time.Hour) + tt.Frame() + if !tt.HasText("Focus, 2 s left") || p.s.Running() { + t.Fatal("pause should hold the clock") + } + _ = tt.Click("Start") + p.now = p.now.Add(1100 * time.Millisecond) + tt.Frame() + if len(p.finished) != 1 || p.finished[0] != PomodoroFocus || p.s.Phase() != PomodoroBreak || p.s.Running() || p.s.Sessions() != 1 { + t.Fatalf("focus end: %v %v", p.finished, p.s.Phase()) + } + if a := tt.Announcements(); len(a) == 0 || a[len(a)-1] != "Focus finished." { + t.Fatalf("announce %q", a) + } + _ = tt.Click("Skip") + _ = tt.Click("Skip") + if p.s.Phase() != PomodoroLongBreak || p.s.Sessions() != 2 { + t.Fatalf("second focus should earn a long break: %v", p.s.Phase()) + } + _ = tt.Click("Reset") + if p.s.Phase() != PomodoroFocus || p.s.Sessions() != 0 || p.changes != 6 { + t.Fatalf("reset %v (%d)", p.s.Phase(), p.changes) + } +} + +func TestPomodoroTimerKeyboardDisabledInvalid(t *testing.T) { + p := &pomodoroProbe{opts: PomodoroTimerOptions{Disabled: true}} + tt := p.tester() + _ = tt.Click("Start") + tt.Key(0, ui.KeyTab) + tt.Key(0, ui.KeyEnter) + if p.s.Running() || p.changes != 0 || !tt.HasText("Focus, 25 min left") { + t.Fatal("disabled timer started") + } + q := &pomodoroProbe{} + tt = q.tester() + tt.Key(0, ui.KeyTab) + tt.Key(0, ui.KeyEnter) + if !q.s.Running() { + t.Fatal("Enter should start") + } + defer func() { + if recover() == nil { + t.Fatal("expected panic") + } + }() + bad := &pomodoroProbe{opts: PomodoroTimerOptions{Focus: 1500 * time.Millisecond}} + bad.tester() +} + +func TestPomodoroTimerSnapshot(t *testing.T) { + now := time.Date(2026, time.October, 5, 9, 0, 0, 0, time.UTC) + s := PomodoroState{spent: 10 * time.Minute} + snapshot(t, "pomodoro_timer", 360, 300, func(c *ui.Context) { + ui.Column(c).Padding(16).Children(func() { PomodoroTimer(c, &s, PomodoroTimerOptions{Now: now}) }) + }) +} + +func TestPomodoroTimerIdleAndHidden(t *testing.T) { + s, shown, builds := PomodoroState{}, true, 0 + tt := ui.NewTester(func(c *ui.Context) { + builds++ + Use(c, Settings{}) + if shown { + PomodoroTimer(c, &s, PomodoroTimerOptions{}) + } + }, 400, 400) + if builds > 2 { + t.Fatalf("idle built %d frames", builds) + } + if err := tt.Click("Start"); err != nil { + t.Fatal(err) + } + shown = false + tt.Frame() + before := builds + time.Sleep(1100 * time.Millisecond) + if builds != before || !s.Running() { + t.Fatalf("hidden timer: builds %d, running %v", builds, s.Running()) + } + shown = true + tt.Frame() + if !tt.HasText("Pause") { + t.Fatal("visible timer did not retain its clock") + } +} diff --git a/priority_indicator.go b/priority_indicator.go new file mode 100644 index 0000000..e0e3623 --- /dev/null +++ b/priority_indicator.go @@ -0,0 +1,67 @@ +package mujica + +import ( + "github.com/egoist/mygo/ui" + + "mujicaui/theme" +) + +// PriorityIndicatorOptions configure a PriorityIndicator. +type PriorityIndicatorOptions struct { + // IconOnly hides the text; the name stays in the label. + IconOnly bool +} + +var priorityKeys = [...]string{"priority_indicator.none", "priority_indicator.low", "priority_indicator.medium", + "priority_indicator.high", "priority_indicator.urgent"} + +// PriorityName is a priority's localized name. +func PriorityName(c *ui.Context, p Priority) string { + projectCheckPriority(p) + return msg(c, priorityKeys[p]) +} + +// PriorityIndicator displays urgency with shapes and localized text. +func PriorityIndicator(c *ui.Context, p Priority, opts PriorityIndicatorOptions) *ui.Element { + name := PriorityName(c, p) + k := Tokens(c) + d := Density(c) + col := k.TextMuted + switch p { + case PriorityUrgent: + col = k.Danger + case PriorityHigh: + col = k.Warning + } + row := ui.Row(c).Gap(d.Unit()).AlignItems(ui.Center).Shrink(0).Role(ui.RoleImage).Label(name) + row.Children(func() { + ui.Box(c).Size(14, 14).Shrink(0).Draw(func(pp *ui.Painter, r ui.Rect) { priorityGlyph(pp, r, p, col, k.Surface, k.Border) }) + if !opts.IconOnly { + ui.Text(c, name).FontSize(FontSize(c, theme.CaptionSize)).TextColor(col).SingleLine() + } + }) + return row +} + +// priorityGlyph draws level bars, urgency marks or empty dashes. +func priorityGlyph(p *ui.Painter, r ui.Rect, pr Priority, col, bg, faint ui.Color) { + switch pr { + case PriorityUrgent: + p.Fill(r, col, 2) + p.Fill(ui.Rect{X: r.X + r.W/2 - 1, Y: r.Y + 3, W: 2, H: r.H - 8}, bg, 0) + p.Fill(ui.Rect{X: r.X + r.W/2 - 1, Y: r.Y + r.H - 4, W: 2, H: 2}, bg, 0) + case PriorityNone: + for i := range 3 { + p.Fill(ui.Rect{X: r.X + 1 + float32(i)*4.5, Y: r.Y + r.H/2 - 1, W: 3, H: 2}, col, 0) + } + default: + for i := range 3 { + h := r.H * float32(i+1) / 3 + c := faint + if i < int(pr) { + c = col + } + p.Fill(ui.Rect{X: r.X + 1 + float32(i)*4.5, Y: r.Y + r.H - h, W: 3, H: h}, c, 1) + } + } +} diff --git a/priority_indicator_test.go b/priority_indicator_test.go new file mode 100644 index 0000000..ea7360a --- /dev/null +++ b/priority_indicator_test.go @@ -0,0 +1,79 @@ +package mujica + +import ( + "testing" + + "github.com/egoist/mygo/ui" + + "mujicaui/theme" +) + +func TestPriorityIndicatorNamesAndShapes(t *testing.T) { + tt := ui.NewTester(func(c *ui.Context) { + Use(c, Settings{Mode: Light, Locale: ZhCN}) + ui.Column(c).Children(func() { + for p := PriorityNone; p <= PriorityUrgent; p++ { + PriorityIndicator(c, p, PriorityIndicatorOptions{}) + } + PriorityIndicator(c, PriorityHigh, PriorityIndicatorOptions{IconOnly: true}) + }) + }, 200, 200) + tt.SetPreferences(ui.Preferences{ReduceMotion: true, TextScale: 1}) + for _, s := range []string{"无优先级", "低", "中", "高", "紧急"} { + if !tt.HasText(s) { + t.Fatalf("missing %q: %v", s, tt.Texts()) + } + } +} + +func TestPriorityIndicatorBarsShowLevel(t *testing.T) { + tt := ui.NewTester(func(c *ui.Context) { + Use(c, Settings{Mode: Light}) + ui.Column(c).Children(func() { + for p := PriorityLow; p <= PriorityHigh; p++ { + ui.Box(c).Height(20).Children(func() { PriorityIndicator(c, p, PriorityIndicatorOptions{IconOnly: true}) }) + } + }) + }, 100, 100) + tt.SetPreferences(ui.Preferences{ReduceMotion: true, TextScale: 1}) + if !tt.HasText("Medium") { + t.Fatal("icon-only indicator lost its name") + } + img := tt.Image() + k := theme.Light() + for i, want := range []struct { + n int + col ui.Color + }{{1, k.TextMuted}, {2, k.TextMuted}, {3, k.Warning}} { + runs, on := 0, false + for x := 0; x < 16; x++ { + hit := datetimeNear(img.RGBAAt(x, i*20+13), want.col) + if hit && !on { + runs++ + } + on = hit + } + if runs != want.n { + t.Errorf("priority %d: %d filled bars, want %d", i+1, runs, want.n) + } + } +} + +func TestPriorityIndicatorInvalid(t *testing.T) { + defer func() { + if recover() == nil { + t.Fatal("expected panic") + } + }() + ui.NewTester(func(c *ui.Context) { Use(c, Settings{}); PriorityIndicator(c, 9, PriorityIndicatorOptions{}) }, 10, 10) +} + +func TestPriorityIndicatorSnapshot(t *testing.T) { + snapshot(t, "priority_indicator", 520, 60, func(c *ui.Context) { + ui.Row(c).Padding(16).Gap(16).Children(func() { + for p := PriorityNone; p <= PriorityUrgent; p++ { + PriorityIndicator(c, p, PriorityIndicatorOptions{}) + } + }) + }) +} diff --git a/projects.go b/projects.go new file mode 100644 index 0000000..44cc3ea --- /dev/null +++ b/projects.go @@ -0,0 +1,146 @@ +package mujica + +import ( + "fmt" + "slices" + + "github.com/egoist/mygo/ui" +) + +// Priority describes urgency; zero means no priority. +type Priority int + +const ( + PriorityNone Priority = iota + PriorityLow + PriorityMedium + PriorityHigh + PriorityUrgent +) + +// Member is a person tasks can be assigned to. +type Member struct { + ID string + Name string +} + +// TaskLabel is a colored tag tasks carry. +type TaskLabel struct { + ID string + Name string + Color EventColor +} + +// Subtask is one checklist step of a task. +type Subtask struct { + ID string + Title string + Done bool +} + +// Task is one unit of project work. +type Task struct { + // ID is the issue key, as ENG-123. + ID string + Title string + Done bool + Priority Priority + Due Date + Status string + Assignees []string + Labels []string + Subtasks []Subtask +} + +// StatusGroup is the workflow stage a status belongs to. +type StatusGroup int + +const ( + StatusBacklog StatusGroup = iota + StatusUnstarted + StatusStarted + StatusCompleted + StatusCanceled +) + +// WorkflowStatus is one workflow state. +type WorkflowStatus struct { + ID string + Name string + Group StatusGroup +} + +// ProjectResult exposes the element and task events. +type ProjectResult struct { + Element *ui.Element + changed string + opened string +} + +// Changed returns the edited task ID. +func (r ProjectResult) Changed() (string, bool) { return r.changed, r.changed != "" } + +// Opened returns the activated task ID. +func (r ProjectResult) Opened() (string, bool) { return r.opened, r.opened != "" } + +// projectCheckPriority panics on an unknown priority. +func projectCheckPriority(p Priority) { + if p < PriorityNone || p > PriorityUrgent { + panic(fmt.Sprintf("mujica: Priority %d out of range", p)) + } +} + +// projectMember resolves a member ID or panics. +func projectMember(members []Member, id string) Member { + i := slices.IndexFunc(members, func(m Member) bool { return m.ID == id }) + if i < 0 { + panic(fmt.Sprintf("mujica: unknown member %q", id)) + } + return members[i] +} + +// projectLabel resolves a label ID or panics. +func projectLabel(labels []TaskLabel, id string) TaskLabel { + i := slices.IndexFunc(labels, func(l TaskLabel) bool { return l.ID == id }) + if i < 0 { + panic(fmt.Sprintf("mujica: unknown label %q", id)) + } + return labels[i] +} + +// projectStatus resolves a status ID or panics. +func projectStatus(statuses []WorkflowStatus, id string) WorkflowStatus { + i := slices.IndexFunc(statuses, func(s WorkflowStatus) bool { return s.ID == id }) + if i < 0 { + panic(fmt.Sprintf("mujica: unknown status %q", id)) + } + return statuses[i] +} + +// projectDueText formats a date relative to today. +func projectDueText(c *ui.Context, due, today Date, done bool) (string, bool) { + datetimeCheckDate("project due", due) + if due.IsZero() { + return "", false + } + days := int(due.civil().Sub(today.civil()).Hours() / 24) + switch { + case days < 0 && !done: + return calendarCount(c, "projects.overdue", -days), true + case days == 0: + return msg(c, "projects.due_today"), false + case days == 1: + return msg(c, "projects.due_tomorrow"), false + } + return fmt.Sprintf(msg(c, "projects.due"), datetimeMonthName(c, due.Month), due.Day), false +} + +// projectBar draws a named completion bar. +func projectBar(c *ui.Context, frac float64, label string) *ui.Element { + k := Tokens(c) + return ui.Box(c).Height(6).FillWidth().Role(ui.RoleProgress).Label(label).Description(fmt.Sprintf("%d%%", int(frac*100))). + Draw(func(p *ui.Painter, r ui.Rect) { + p.Fill(r, k.Border, 3) + p.Fill(ui.Rect{X: r.X, Y: r.Y, W: r.W * float32(frac), H: r.H}, k.AccentText, 3) + }) +} diff --git a/projects_test.go b/projects_test.go new file mode 100644 index 0000000..6b6cd6a --- /dev/null +++ b/projects_test.go @@ -0,0 +1,54 @@ +package mujica + +import ( + "testing" + + "github.com/egoist/mygo/ui" +) + +var projStatuses = []WorkflowStatus{ + {ID: "backlog", Name: "Backlog", Group: StatusBacklog}, + {ID: "todo", Name: "Todo", Group: StatusUnstarted}, + {ID: "doing", Name: "In Progress", Group: StatusStarted}, + {ID: "review", Name: "In Review", Group: StatusStarted}, + {ID: "done", Name: "Done", Group: StatusCompleted}, + {ID: "dropped", Name: "Dropped", Group: StatusCanceled}, +} + +var projMembers = []Member{{ID: "saki", Name: "Sakiko Togawa"}, {ID: "mutsu", Name: "Mutsumi Wakaba"}, + {ID: "uika", Name: "Uika Misumi"}, {ID: "nyamu", Name: "Nyamu Yuutenji"}, {ID: "umiri", Name: "Umiri Yahata"}} + +var projLabels = []TaskLabel{{ID: "bug", Name: "Bug", Color: EventDanger}, {ID: "ui", Name: "UI", Color: EventInfo}, + {ID: "docs", Name: "Docs", Color: EventSuccess}} + +// projTasks returns fresh tasks for one test. +func projTasks() []Task { + return []Task{ + {ID: "AVE-1", Title: "Write the overture", Status: "todo", Priority: PriorityHigh, Due: oct(7), Assignees: []string{"saki"}, Labels: []string{"docs"}}, + {ID: "AVE-2", Title: "Tune the organ", Status: "doing", Priority: PriorityUrgent, Due: oct(3), Assignees: []string{"mutsu", "uika"}, Labels: []string{"bug"}}, + {ID: "AVE-3", Title: "Masks for the ball", Status: "doing", Priority: PriorityMedium, Assignees: []string{"nyamu"}}, + {ID: "AVE-4", Title: "Rehearse act two", Status: "review", Priority: PriorityLow, Due: oct(12)}, + {ID: "AVE-5", Title: "Book the hall", Status: "done", Done: true, Priority: PriorityNone, Due: oct(1), Labels: []string{"ui"}}, + } +} + +func TestProjectDueText(t *testing.T) { + var got []string + var late []bool + ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + for _, c2 := range []struct { + due Date + done bool + }{{oct(2), false}, {oct(4), false}, {oct(5), false}, {oct(6), false}, {oct(14), false}, {oct(1), true}} { + s, l := projectDueText(c, c2.due, calendarToday, c2.done) + got, late = append(got, s), append(late, l) + } + }, 10, 10) + want := []string{"Overdue by 3 days", "Overdue by 1 day", "Due today", "Due tomorrow", "Due October 14", "Due October 1"} + for i := range want { + if got[i] != want[i] || late[i] != (i < 2) { + t.Fatalf("%d: %q %v", i, got[i], late[i]) + } + } +} diff --git a/sprint_board.go b/sprint_board.go new file mode 100644 index 0000000..5bb76ed --- /dev/null +++ b/sprint_board.go @@ -0,0 +1,111 @@ +package mujica + +import ( + "fmt" + "slices" + + "github.com/egoist/mygo/ui" + + "mujicaui/internal" + "mujicaui/theme" +) + +// Sprint is one iteration: its name, goal and inclusive dates. +type Sprint struct { + Name string + Goal string + Start, End Date +} + +// SprintBoardOptions configure a SprintBoard. +type SprintBoardOptions struct { + Board KanbanBoardOptions + // Today counts the days left; zero uses the system clock. + Today Date +} + +// SprintBoard combines iteration information, completion and a task board. +func SprintBoard(c *ui.Context, sprint Sprint, tasks *[]Task, opts SprintBoardOptions) KanbanResult { + datetimeCheckDate("SprintBoard Start", sprint.Start) + datetimeCheckDate("SprintBoard End", sprint.End) + if sprint.Start.IsZero() || sprint.End.Compare(sprint.Start) < 0 { + panic(fmt.Sprintf("mujica: SprintBoard dates %v..%v are not a span", sprint.Start, sprint.End)) + } + k := Tokens(c) + d := Density(c) + today := datetimeToday(c, opts.Today) + var r KanbanResult + col := ui.Column(c).Gap(d.Unit() * 4).Grow(1).MinHeight(0).Role(ui.RoleGroup).Label(sprint.Name) + cache := ui.Local(col, "sprint-counts", func() sprintCache { return sprintCache{} }) + var first *Task + if len(*tasks) > 0 { + first = &(*tasks)[0] + } + if !cache.ready || cache.first != first || cache.n != len(*tasks) || cache.version != opts.Board.Version || !slices.Equal(cache.statuses, opts.Board.Statuses) { + *cache = sprintCache{first: first, n: len(*tasks), version: opts.Board.Version, statuses: slices.Clone(opts.Board.Statuses), ready: true} + for _, t := range *tasks { + if g := projectStatus(opts.Board.Statuses, t.Status).Group; g != StatusCanceled { + cache.total++ + if g == StatusCompleted { + cache.done++ + } + } + } + } + done, total := cache.done, cache.total + col.Children(func() { + ui.Row(c).Gap(d.Unit() * 6).AlignItems(ui.Center).Wrap().Children(func() { + ui.Column(c).Gap(d.Unit()).Grow(1).Children(func() { + ui.Text(c, sprint.Name).Font(theme.SerifFont).FontSize(FontSize(c, theme.H2Size)).TextColor(k.Text) + if sprint.Goal != "" { + ui.Text(c, sprint.Goal).TextColor(k.TextMuted) + } + ui.Text(c, weekViewTitle(c, sprint.Start, sprint.End)).FontSize(FontSize(c, theme.CaptionSize)).TextColor(k.TextMuted) + }) + sprintStat(c, sprintDaysLeft(c, sprint, today), msg(c, "sprint_board.time")) + frac := 0.0 + if total > 0 { + frac = float64(done) / float64(total) + } + ui.Column(c).Width(d.ControlHeight() * 5).Gap(d.Unit()).Children(func() { + ui.Text(c, fmt.Sprintf(msg(c, "sprint_board.done"), done, total)).TextColor(k.Text).FontFeatures("tnum") + Progress(c, frac, ProgressOptions{Label: msg(c, "sprint_board.progress")}) + }) + }) + ui.Box(c).Height(12).FillWidth().Draw(func(p *ui.Painter, rr ui.Rect) { internal.RuleDiamond(p, rr, 8, 6, k.Ornament) }) + r = KanbanBoard(c, tasks, opts.Board) + }) + if _, moved := r.Moved(); moved { + cache.ready = false + c.Invalidate() + } + r.Element = col + return r +} + +// sprintDaysLeft formats remaining time relative to the iteration. +func sprintDaysLeft(c *ui.Context, s Sprint, today Date) string { + switch { + case today.Compare(s.Start) < 0: + return calendarCount(c, "sprint_board.starts_in", int(s.Start.civil().Sub(today.civil()).Hours()/24)) + case today.Compare(s.End) > 0: + return msg(c, "sprint_board.ended") + } + return calendarCount(c, "sprint_board.left", int(s.End.civil().Sub(today.civil()).Hours()/24)+1) +} + +// sprintStat is a figure above its caption. +func sprintStat(c *ui.Context, value, caption string) { + k := Tokens(c) + ui.Column(c).Gap(2).Role(ui.RoleStatus).Label(caption + ": " + value).Children(func() { + ui.Text(c, value).Font(theme.SerifFont).FontSize(FontSize(c, theme.H3Size)).TextColor(k.AccentText) + ui.Text(c, caption).FontSize(FontSize(c, theme.CaptionSize)).TextColor(k.TextMuted) + }) +} + +type sprintCache struct { + first *Task + n, version, done, total int + statuses []WorkflowStatus + ready bool +} diff --git a/sprint_board_test.go b/sprint_board_test.go new file mode 100644 index 0000000..e9c3c49 --- /dev/null +++ b/sprint_board_test.go @@ -0,0 +1,87 @@ +package mujica + +import ( + "fmt" + "testing" + + "github.com/egoist/mygo/ui" +) + +var projSprint = Sprint{Name: "Sprint 12", Goal: "Ready the masquerade", Start: oct(1), End: oct(14)} + +func sprintTester(sprint Sprint, tasks *[]Task, today Date, disabled bool, moves *int) *ui.Tester { + return ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + ui.Column(c).Height(640).Padding(8).Children(func() { + r := SprintBoard(c, sprint, tasks, SprintBoardOptions{Today: today, Board: KanbanBoardOptions{Columns: kanbanColumns3, + Statuses: projStatuses, Members: projMembers, Labels: projLabels, Disabled: disabled}}) + if _, ok := r.Moved(); ok { + *moves++ + } + }) + }, 1240, 660) +} + +func TestSprintBoardHeaderAndMoves(t *testing.T) { + tasks, n := projTasks(), 0 + tt := sprintTester(projSprint, &tasks, calendarToday, false, &n) + for _, s := range []string{"Sprint 12", "Ready the masquerade", "October 1 – October 14, 2026", "10 days left", "1 of 5 done"} { + if !tt.HasText(s) { + t.Fatalf("missing %q in %v", s, tt.Texts()) + } + } + _ = tt.Click("AVE-4 Rehearse act two") + tt.Key(ui.Alt, ui.KeyRight) + if n != 1 || !tt.HasText("2 of 5 done") { + t.Fatal("moving to Done should count") + } +} + +func TestSprintBoardDaysAndDisabled(t *testing.T) { + tasks, n := projTasks(), 0 + for _, c := range []struct { + today Date + want string + }{{Date{2026, 9, 30}, "Starts in 1 day"}, {oct(14), "1 day left"}, {oct(15), "Ended"}} { + if tt := sprintTester(projSprint, &tasks, c.today, false, &n); !tt.HasText(c.want) { + t.Errorf("%v: want %q", c.today, c.want) + } + } + tt := sprintTester(projSprint, &tasks, calendarToday, true, &n) + _ = tt.Click("AVE-4 Rehearse act two") + tt.Key(ui.Alt, ui.KeyRight) + if n != 0 { + t.Fatal("disabled board moved") + } + defer func() { + if recover() == nil { + t.Fatal("expected panic for an inverted sprint") + } + }() + sprintTester(Sprint{Name: "x", Start: oct(5), End: oct(1)}, &tasks, calendarToday, false, &n) +} + +func TestSprintBoardSnapshot(t *testing.T) { + tasks := projTasks() + snapshot(t, "sprint_board", 1240, 560, func(c *ui.Context) { + ui.Column(c).Height(560).Padding(16).Children(func() { + SprintBoard(c, projSprint, &tasks, SprintBoardOptions{Today: calendarToday, Board: KanbanBoardOptions{Columns: kanbanColumns3, + Statuses: projStatuses, Members: projMembers, Labels: projLabels}}) + }) + }) +} + +func TestSprintBoardLargeData(t *testing.T) { + tasks := make([]Task, 100000) + for i := range tasks { + tasks[i] = Task{ID: fmt.Sprintf("BIG-%d", i+1), Title: "Task", Status: "todo"} + } + moves := 0 + tt := sprintTester(projSprint, &tasks, calendarToday, false, &moves) + if built := len(tt.Texts()); built > 600 { + t.Fatalf("built %d labels", built) + } + if !tt.HasText("0 of 100000 done") { + t.Fatal("incorrect sprint summary") + } +} diff --git a/status_select.go b/status_select.go new file mode 100644 index 0000000..d4aa7fc --- /dev/null +++ b/status_select.go @@ -0,0 +1,140 @@ +package mujica + +import ( + "fmt" + "log/slog" + "math" + + "github.com/egoist/mygo/ui" + + "mujicaui/internal" + "mujicaui/theme" +) + +// StatusSelectOptions configure a StatusSelect. +type StatusSelectOptions struct { + Disabled bool + Label string +} + +var statusGroupKeys = [...]string{"status_select.backlog", "status_select.unstarted", "status_select.started", + "status_select.completed", "status_select.canceled"} + +// StatusSelect chooses a status grouped by workflow stage. +func StatusSelect(c *ui.Context, value *string, statuses []WorkflowStatus, opts StatusSelectOptions) ChoiceResult { + if len(statuses) == 0 { + panic("mujica: StatusSelect needs statuses") + } + for i, s := range statuses { + if s.Group < StatusBacklog || s.Group > StatusCanceled || s.ID == "" { + panic(fmt.Sprintf("mujica: StatusSelect status %+v is not valid", s)) + } + for _, o := range statuses[:i] { + if o.ID == s.ID { + panic(fmt.Sprintf("mujica: StatusSelect status %q repeats", s.ID)) + } + } + } + cur := projectStatus(statuses, *value) + k := Tokens(c) + old := *value + pick := old + var s *ui.SelectParts[string] + root := ui.Row(c).Shrink(0).Disabled(opts.Disabled) + epoch := ui.Local(root, "status-epoch", func() struct { + disabled bool + generation int + } { + return struct { + disabled bool + generation int + }{} + }) + if disabled := root.IsDisabled(); disabled != epoch.disabled { + epoch.disabled = disabled + epoch.generation++ + } + root.Children(func() { + ui.Row(c).Key(epoch.generation).Children(func() { s = ui.SelectBase(c, &pick) }) + }) + tr := s.Trigger + label := opts.Label + if label == "" { + label = msg(c, "status_select.label") + } + tr.Label(label).Description(cur.Name) + selectField(c, tr, s.Open(), func() { + statusGlyphBox(c, cur.Group) + ui.Text(c, cur.Name).SingleLine().Grow(1).Shrink(1).TextColor(k.Text) + }) + if !tr.IsDisabled() { + s.Popup(func(panel *ui.Element) { + selectPanel(c, panel) + _, wh := c.Size() + ui.Scroll(c).MaxHeight(min(320, wh/2)).Children(func() { + for g := StatusBacklog; g <= StatusCanceled; g++ { + first := true + for _, st := range statuses { + if st.Group != g { + continue + } + if first { + ui.Text(c, msg(c, statusGroupKeys[g])).FontSize(FontSize(c, theme.CaptionSize)).TextColor(k.TextMuted). + Padding(Density(c).Unit(), Density(c).Unit()*2).Role(ui.RoleColumnHeader) + first = false + } + it := s.Item(st.ID) + selectRow(c, it, it.Highlighted(), st.ID == *value, "") + it.Label(st.Name).Children(func() { + statusGlyphBox(c, st.Group) + ui.Text(c, st.Name).SingleLine() + }) + } + } + }) + }) + } + if pick != *value && !tr.IsDisabled() { + *value = pick + } + changed := *value != old + if changed { + slog.Debug("mujica: status_select change", "from", old, "to", *value) + } + return ChoiceResult{Element: tr, changed: changed} +} + +// statusGlyphBox reserves 14 DIPs for a status glyph. +func statusGlyphBox(c *ui.Context, g StatusGroup) { + k := Tokens(c) + ui.Box(c).Size(14, 14).Shrink(0).Draw(func(p *ui.Painter, r ui.Rect) { statusGlyph(p, r, g, k) }) +} + +// statusGlyph draws a distinct shape for each workflow stage. +func statusGlyph(p *ui.Painter, r ui.Rect, g StatusGroup, k theme.Tokens) { + cx, cy, rad := r.X+r.W/2, r.Y+r.H/2, r.W/2-1 + ring := func(col ui.Color) { + var path ui.Path + internal.Arc(&path, cx, cy, rad, 0, 2*math.Pi, true) + p.StrokePath(&path, 1.5, col) + } + switch g { + case StatusBacklog: + for i := 0; i < 8; i += 2 { + var path ui.Path + internal.Arc(&path, cx, cy, rad, float64(i)*math.Pi/4, float64(i+1)*math.Pi/4, true) + p.StrokePath(&path, 1.5, k.TextMuted) + } + case StatusUnstarted: + ring(k.TextMuted) + case StatusStarted: + ring(k.Warning) + p.FillPath(internal.Sector(cx, cy, 0, rad-2, 0, math.Pi), k.Warning) + case StatusCompleted: + p.FillPath(internal.Sector(cx, cy, 0, rad+1, 0, 2*math.Pi), k.Success) + internal.Mark(p, ui.Rect{X: r.X + 3, Y: r.Y + 3, W: r.W - 6, H: r.H - 6}, "check", k.Surface) + case StatusCanceled: + p.FillPath(internal.Sector(cx, cy, 0, rad+1, 0, 2*math.Pi), k.TextMuted) + internal.Mark(p, ui.Rect{X: r.X + 3, Y: r.Y + 3, W: r.W - 6, H: r.H - 6}, "x", k.Surface) + } +} diff --git a/status_select_test.go b/status_select_test.go new file mode 100644 index 0000000..90e273f --- /dev/null +++ b/status_select_test.go @@ -0,0 +1,93 @@ +package mujica + +import ( + "testing" + + "github.com/egoist/mygo/ui" +) + +func statusTester(v *string, opts *StatusSelectOptions, n *int) *ui.Tester { + return ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + ui.Column(c).Padding(16).Children(func() { + if StatusSelect(c, v, projStatuses, *opts).Changed() { + *n++ + } + }) + }, 400, 520) +} + +func TestStatusSelectGroupsAndPick(t *testing.T) { + v, n := "todo", 0 + tt := statusTester(&v, &StatusSelectOptions{}, &n) + _ = tt.Click("Status") + for _, g := range []string{"Backlog", "To do", "In progress", "Done", "Canceled"} { + if !tt.HasText(g) { + t.Fatalf("group %q missing: %v", g, tt.Texts()) + } + } + _ = tt.Click("In Review") + if v != "review" || n != 1 { + t.Fatalf("picked %q", v) + } + tt.Key(0, ui.KeyDown) + tt.Key(0, ui.KeyDown) + tt.Key(0, ui.KeyEnter) + if v != "done" || n != 2 { + t.Fatalf("keyboard picked %q", v) + } +} + +func TestStatusSelectDisabledAndInvalid(t *testing.T) { + v, n := "todo", 0 + opts := &StatusSelectOptions{Disabled: true} + tt := statusTester(&v, opts, &n) + _ = tt.Click("Status") + tt.Key(0, ui.KeyDown) + if tt.HasText("In Review") || v != "todo" || n != 0 { + t.Fatal("disabled select opened") + } + for _, bad := range []string{"nope", ""} { + func() { + defer func() { + if recover() == nil { + t.Errorf("%q: expected panic", bad) + } + }() + w := bad + statusTester(&w, &StatusSelectOptions{}, &n) + }() + } +} + +func TestStatusSelectSnapshot(t *testing.T) { + values := []string{"backlog", "todo", "doing", "done", "dropped"} + snapshot(t, "status_select", 440, 176, func(c *ui.Context) { + ui.Row(c).Padding(16).Gap(8).Wrap().Children(func() { + for i := range values { + StatusSelect(c, &values[i], projStatuses, StatusSelectOptions{}) + } + }) + }) +} + +func TestStatusSelectAncestorDisableCloses(t *testing.T) { + value, disabled := "todo", false + tt := ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + ui.Column(c).Disabled(disabled).Children(func() { StatusSelect(c, &value, projStatuses, StatusSelectOptions{}) }) + }, 400, 520) + if err := tt.Click("Status"); err != nil { + t.Fatal(err) + } + disabled = true + tt.Frame() + if tt.HasText("In Review") { + t.Fatal("ancestor-disabled popup remains visible") + } + disabled = false + tt.Frame() + if tt.HasText("In Review") { + t.Fatal("popup reopens after enabling") + } +} diff --git a/subtask_list.go b/subtask_list.go new file mode 100644 index 0000000..1095476 --- /dev/null +++ b/subtask_list.go @@ -0,0 +1,158 @@ +package mujica + +import ( + "fmt" + "log/slog" + "slices" + "strings" + + "github.com/egoist/mygo/ui" + + "mujicaui/icons" + "mujicaui/theme" +) + +// SubtaskListOptions configure a SubtaskList. +type SubtaskListOptions struct { + Disabled bool + Label string + // Version changes when subtasks change in place. + Version int +} + +// subtaskDrag is the ID of a subtask being dragged. +type subtaskDrag string + +// SubtaskList edits and reorders subtasks with completion progress. +func SubtaskList(c *ui.Context, subs *[]Subtask, opts SubtaskListOptions) ChoiceResult { + k := Tokens(c) + d := Density(c) + label := opts.Label + if label == "" { + label = msg(c, "subtask_list.label") + } + changed := false + col := ui.Column(c).Gap(d.Unit() * 2).Role(ui.RoleGroup).Label(label).Disabled(opts.Disabled) + draft := ui.Local(col, "subtask-draft", func() string { return "" }) + cache := ui.Local(col, "subtask-summary", func() subtaskCache { return subtaskCache{} }) + var first *Subtask + if len(*subs) > 0 { + first = &(*subs)[0] + } + if !cache.ready || cache.first != first || cache.n != len(*subs) || cache.version != opts.Version { + *cache = subtaskCache{first: first, n: len(*subs), version: opts.Version, ready: true} + seen := map[string]bool{} + for _, s := range *subs { + if s.ID == "" || seen[s.ID] { + panic(fmt.Sprintf("mujica: SubtaskList subtask %q is empty or repeated", s.ID)) + } + seen[s.ID] = true + if s.Done { + cache.done++ + } + } + + } + state := ui.Local(col, "subtask-rows", func() ui.ListState { return ui.ListState{} }) + state.Key = func(i int) any { return (*subs)[i].ID } + var pending func() + + move := func(from, to int, how string) { + if col.IsDisabled() || to < 0 || to >= len(*subs) || from == to { + return + } + + if pending == nil { + pending = func() { + step := (*subs)[from] + *subs = slices.Insert(slices.Delete(*subs, from, from+1), to, step) + changed = true + state.ScrollIntoView(to) + slog.Debug("mujica: subtask_list move", "id", step.ID, "to", to, "by", how) + } + } + } + col.Children(func() { + done := cache.done + ui.Row(c).Gap(d.Unit() * 2).AlignItems(ui.Center).Children(func() { + frac := 0.0 + if len(*subs) > 0 { + frac = float64(done) / float64(len(*subs)) + } + ui.Box(c).Grow(1).Children(func() { projectBar(c, frac, label) }) + ui.Text(c, fmt.Sprintf(msg(c, "subtask_list.progress"), done, len(*subs))).FontSize(FontSize(c, theme.CaptionSize)). + TextColor(k.TextMuted).FontFeatures("tnum") + }) + removed := -1 + ui.List(c, state, len(*subs), func(i int) { + s := &(*subs)[i] + row := ui.Row(c).Key(s.ID).MinHeight(d.ControlHeight()).Gap(d.Unit() * 2).AlignItems(ui.Center).Role(ui.RoleListItem) + if id, ok := ui.Drop[subtaskDrag](row); ok { + if from := slices.IndexFunc(*subs, func(o Subtask) bool { return o.ID == string(id) }); from >= 0 { + move(from, i, "drag") + } + } + if _, over := ui.DragOver[subtaskDrag](row); over { + row.Background(k.Selection) + } + row.Children(func() { + grip := ui.Box(c).Size(theme.MinHitSize, theme.MinHitSize).Center().Cursor(ui.CursorGrab).Label(fmt.Sprintf(msg(c, "subtask_list.drag"), s.Title)) + if !grip.IsDisabled() { + grip.Drag(subtaskDrag(s.ID)) + } + grip.Children(func() { ui.Icon(c, icons.Must("grip-vertical")).Size(14, 14).TextColor(k.TextMuted) }) + v := s.Done + cb := Checkbox(c, &v, s.Title, CheckboxOptions{Disabled: opts.Disabled}) + if cb.Changed() && !cb.IsDisabled() { + s.Done, changed = v, true + } + if !cb.IsDisabled() { + if cb.Shortcut(ui.Alt, ui.KeyUp) { + move(i, i-1, "keys") + } + if cb.Shortcut(ui.Alt, ui.KeyDown) { + move(i, i+1, "keys") + } + } + ui.Spacer(c) + if b := iconAction(c, icons.Must("x"), fmt.Sprintf(msg(c, "subtask_list.remove"), s.Title)); b.Clicked() && !b.IsDisabled() { + removed = i + } + }) + }).Height(min(float32(len(*subs)), 8) * d.ControlHeight()) + if removed >= 0 && !col.IsDisabled() { + slog.Debug("mujica: subtask_list remove", "id", (*subs)[removed].ID) + *subs, changed = slices.Delete(*subs, removed, removed+1), true + } + in := TextInput(c, draft, TextInputOptions{Placeholder: msg(c, "subtask_list.add"), Label: msg(c, "subtask_list.add"), Disabled: opts.Disabled}) + if in.Submitted() && strings.TrimSpace(*draft) != "" && !col.IsDisabled() { + *subs = append(*subs, Subtask{ID: subtaskNewID(*subs), Title: strings.TrimSpace(*draft)}) + *draft, changed = "", true + slog.Debug("mujica: subtask_list add") + } + }) + if pending != nil { + pending() + } + if changed { + cache.ready = false + c.Invalidate() + } + return ChoiceResult{Element: col, changed: changed} +} + +// subtaskNewID returns an ID no subtask uses. +func subtaskNewID(subs []Subtask) string { + for n := len(subs) + 1; ; n++ { + id := fmt.Sprintf("sub-%d", n) + if !slices.ContainsFunc(subs, func(s Subtask) bool { return s.ID == id }) { + return id + } + } +} + +type subtaskCache struct { + first *Subtask + n, version, done int + ready bool +} diff --git a/subtask_list_test.go b/subtask_list_test.go new file mode 100644 index 0000000..8cf92ea --- /dev/null +++ b/subtask_list_test.go @@ -0,0 +1,107 @@ +package mujica + +import ( + "fmt" + "testing" + + "github.com/egoist/mygo/ui" +) + +func subtaskSample() []Subtask { + return []Subtask{{ID: "a", Title: "Sketch", Done: true}, {ID: "b", Title: "Score"}, {ID: "c", Title: "Rehearse"}} +} + +func subtaskTester(subs *[]Subtask, opts *SubtaskListOptions, n *int) *ui.Tester { + return ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + ui.Column(c).Padding(16).Children(func() { + if SubtaskList(c, subs, *opts).Changed() { + *n++ + } + }) + }, 480, 480) +} + +func subtaskTitles(s []Subtask) string { + out := "" + for _, x := range s { + out += x.ID + } + return out +} + +func TestSubtaskListProgressCheckAdd(t *testing.T) { + subs, n := subtaskSample(), 0 + tt := subtaskTester(&subs, &SubtaskListOptions{}, &n) + if !tt.HasText("1 of 3 done") { + t.Fatalf("progress %v", tt.Texts()) + } + _ = tt.Click("Score") + if !subs[1].Done || !tt.HasText("2 of 3 done") { + t.Fatal("check") + } + _ = tt.Click("Add a subtask") + tt.Type("Bow") + tt.Key(0, ui.KeyEnter) + if len(subs) != 4 || subs[3].Title != "Bow" || subs[3].ID != "sub-4" || !tt.HasText("2 of 4 done") { + t.Fatalf("add %+v", subs) + } + _ = tt.Click("Remove Sketch") + if subtaskTitles(subs) != "bcsub-4" || n != 3 { + t.Fatalf("remove %v (%d)", subtaskTitles(subs), n) + } +} + +func TestSubtaskListReorder(t *testing.T) { + subs, n := subtaskSample(), 0 + tt := subtaskTester(&subs, &SubtaskListOptions{}, &n) + _ = tt.Click("Rehearse") + tt.Key(ui.Alt, ui.KeyUp) + if subtaskTitles(subs) != "acb" { + t.Fatalf("Alt+Up %v", subtaskTitles(subs)) + } + g, _ := tt.Find("Drag Sketch") + target, _ := tt.Find("Drag Score") + calDrag(tt, g.X+g.W/2, g.Y+g.H/2, target.X+40, target.Y+target.H/2) + if subtaskTitles(subs) != "cba" { + t.Fatalf("drag %v", subtaskTitles(subs)) + } +} + +func TestSubtaskListDisabledAndInvalid(t *testing.T) { + subs, n := subtaskSample(), 0 + tt := subtaskTester(&subs, &SubtaskListOptions{Disabled: true}, &n) + _ = tt.Click("Score") + _ = tt.Click("Remove Sketch") + g, _ := tt.Find("Drag Sketch") + calDrag(tt, g.X+g.W/2, g.Y+g.H/2, g.X+g.W/2, g.Y+120) + if n != 0 || subtaskTitles(subs) != "abc" || subs[1].Done { + t.Fatal("disabled list changed") + } + defer func() { + if recover() == nil { + t.Fatal("expected panic for repeated IDs") + } + }() + bad := []Subtask{{ID: "x"}, {ID: "x"}} + subtaskTester(&bad, &SubtaskListOptions{}, &n) +} + +func TestSubtaskListSnapshot(t *testing.T) { + subs := subtaskSample() + snapshot(t, "subtask_list", 440, 240, func(c *ui.Context) { + ui.Column(c).Padding(16).Children(func() { SubtaskList(c, &subs, SubtaskListOptions{}) }) + }) +} + +func TestSubtaskListLargeData(t *testing.T) { + subs := make([]Subtask, 100000) + for i := range subs { + subs[i] = Subtask{ID: fmt.Sprint(i), Title: "Step"} + } + n := 0 + tt := subtaskTester(&subs, &SubtaskListOptions{}, &n) + if built := len(tt.Texts()); built > 200 { + t.Fatalf("built %d labels", built) + } +} diff --git a/task_detail_panel.go b/task_detail_panel.go new file mode 100644 index 0000000..60935fb --- /dev/null +++ b/task_detail_panel.go @@ -0,0 +1,115 @@ +package mujica + +import ( + "log/slog" + "slices" + + "github.com/egoist/mygo/ui" + + "mujicaui/icons" + "mujicaui/internal" + "mujicaui/theme" +) + +// TaskDetailPanelOptions configure a TaskDetailPanel. +type TaskDetailPanelOptions struct { + Statuses []WorkflowStatus + Members []Member + Labels []TaskLabel + // Activity builds the caller's activity log below the fields. + Activity func() + // Today anchors the due date; zero uses the system clock. + Today Date + Disabled bool + // Version changes when task or related data change in place. + Version int +} + +// TaskDetailResult exposes the panel, edits and close events. +type TaskDetailResult struct { + Element *ui.Element + changed bool + closed bool +} + +// Changed reports a field edit this frame. +func (r TaskDetailResult) Changed() bool { return r.changed } + +// Closed reports a click on Close or Escape. +func (r TaskDetailResult) Closed() bool { return r.closed } + +// TaskDetailPanel edits task fields and hosts an activity slot. +func TaskDetailPanel(c *ui.Context, task *Task, opts TaskDetailPanelOptions) TaskDetailResult { + projectStatus(opts.Statuses, task.Status) + k := Tokens(c) + d := Density(c) + r := TaskDetailResult{} + panel := ui.Column(c).Gap(d.Unit()*4).Padding(d.Unit()*4).Background(k.Surface).Border(theme.BorderWidth, k.Border). + Radius(theme.CardRadius).Role(ui.RoleGroup).Label(task.ID + " " + task.Title).Disabled(opts.Disabled) + r.Element = panel + opts.Disabled = panel.IsDisabled() + if opts.Disabled { + copied := *task + copied.Assignees, copied.Labels, copied.Subtasks = slices.Clone(task.Assignees), slices.Clone(task.Labels), slices.Clone(task.Subtasks) + task = &copied + } + panel.Children(func() { + ui.Row(c).Gap(d.Unit() * 2).AlignItems(ui.Center).Children(func() { + IssueIdBadge(c, task.ID, IssueIdBadgeOptions{Copyable: true, Disabled: opts.Disabled}) + ui.Spacer(c) + if b := iconAction(c, icons.Must("x"), msg(c, "task_detail_panel.close")); b.Clicked() && !b.IsDisabled() { + r.closed = true + } + }) + title := TextInput(c, &task.Title, TextInputOptions{Label: msg(c, "task_detail_panel.title"), Disabled: opts.Disabled}) + title.Input.Font(theme.SerifFont) + r.changed = title.Changed() + taskField(c, msg(c, "task_detail_panel.status"), func() { + r.changed = StatusSelect(c, &task.Status, opts.Statuses, StatusSelectOptions{Disabled: opts.Disabled}).Changed() || r.changed + }) + taskField(c, msg(c, "task_detail_panel.priority"), func() { + prios := make([]SelectOption[Priority], 0, 5) + for p := PriorityUrgent; p >= PriorityNone; p-- { + prios = append(prios, SelectOption[Priority]{Value: p, Label: PriorityName(c, p)}) + } + r.changed = Select(c, &task.Priority, prios, SelectOptions{Label: msg(c, "task_detail_panel.priority"), Disabled: opts.Disabled}).Changed() || r.changed + }) + taskField(c, msg(c, "assignee_picker.label"), func() { + r.changed = AssigneePicker(c, &task.Assignees, opts.Members, AssigneePickerOptions{Disabled: opts.Disabled, Version: opts.Version}).Changed() || r.changed + }) + taskField(c, msg(c, "due_date_picker.label"), func() { + r.changed = DueDatePicker(c, &task.Due, DueDatePickerOptions{Done: task.Done, Today: opts.Today, Disabled: opts.Disabled}).Changed() || r.changed + }) + taskField(c, msg(c, "label_manager.label"), func() { + options := make([]SelectOption[string], len(opts.Labels)) + for i, l := range opts.Labels { + options[i] = SelectOption[string]{Value: l.ID, Label: l.Name} + } + r.changed = MultiSelect(c, &task.Labels, options, MultiSelectOptions{Label: msg(c, "label_manager.label"), Disabled: opts.Disabled}).Changed() || r.changed + }) + r.changed = SubtaskList(c, &task.Subtasks, SubtaskListOptions{Disabled: opts.Disabled, Version: opts.Version}).Changed() || r.changed + if opts.Activity != nil { + ui.Box(c).Height(16).FillWidth().Draw(func(p *ui.Painter, rr ui.Rect) { internal.RuleDiamond(p, rr, 8, 6, k.Ornament) }) + ui.Text(c, msg(c, "task_detail_panel.activity")).Font(theme.SerifFont).TextColor(k.Text) + opts.Activity() + } + }) + if !panel.IsDisabled() && panel.FocusWithin() && c.Shortcut(0, ui.KeyEscape) { + r.closed = true + } + if r.changed { + slog.Debug("mujica: task_detail_panel change", "id", task.ID) + } + if r.closed { + slog.Debug("mujica: task_detail_panel close", "id", task.ID) + } + return r +} + +// taskField puts a caption above a control. +func taskField(c *ui.Context, label string, control func()) { + ui.Column(c).Gap(Density(c).Unit()).Children(func() { + ui.Text(c, label).FontSize(FontSize(c, theme.CaptionSize)).TextColor(Tokens(c).TextMuted) + control() + }) +} diff --git a/task_detail_panel_test.go b/task_detail_panel_test.go new file mode 100644 index 0000000..9ac7d55 --- /dev/null +++ b/task_detail_panel_test.go @@ -0,0 +1,147 @@ +package mujica + +import ( + "fmt" + "testing" + + "github.com/egoist/mygo/ui" +) + +type detailProbe struct { + task Task + disabled bool + version int + changes, closes int + activityRendered bool +} + +func (p *detailProbe) tester() *ui.Tester { + return ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + ui.Scroll(c).Fill().Children(func() { + ui.Box(c).Width(420).Children(func() { + r := TaskDetailPanel(c, &p.task, TaskDetailPanelOptions{Statuses: projStatuses, Members: projMembers, Labels: projLabels, + Today: calendarToday, Disabled: p.disabled, Version: p.version, Activity: func() { + p.activityRendered = true + ui.Text(c, "Sakiko opened this task") + }}) + if r.Changed() { + p.changes++ + } + if r.Closed() { + p.closes++ + } + }) + }) + }, 640, 1200) +} + +func TestTaskDetailPanelEditsFields(t *testing.T) { + p := &detailProbe{task: projTasks()[0]} + tt := p.tester() + if !tt.HasText("Sakiko opened this task") || !tt.HasText("Activity") { + t.Fatal("activity slot missing") + } + _ = tt.Click("Todo") + _ = tt.Click("In Review") + _ = tt.Click("Tomorrow") + _ = tt.Click("Add a subtask") + tt.Type("Copy parts") + tt.Key(0, ui.KeyEnter) + if p.task.Status != "review" || p.task.Due != oct(6) || len(p.task.Subtasks) != 1 || p.changes != 3 { + t.Fatalf("edited %+v (%d changes)", p.task, p.changes) + } + _ = tt.Click("Title") + tt.Command("selectAll") + tt.Type("Write the requiem") + if p.task.Title != "Write the requiem" { + t.Fatalf("title %q", p.task.Title) + } + _ = tt.Click("Close details") + if p.closes != 1 { + t.Fatal("close not reported") + } +} + +func TestTaskDetailPanelDisabled(t *testing.T) { + p := &detailProbe{task: projTasks()[0], disabled: true} + tt := p.tester() + _ = tt.Click("Tomorrow") + _ = tt.Click("Title") + tt.Type("x") + _ = tt.Click("Close details") + if p.changes != 0 || p.closes != 0 || p.task.Title != "Write the overture" { + t.Fatalf("disabled panel changed %+v", p.task) + } +} + +func TestTaskDetailPanelSnapshot(t *testing.T) { + task := projTasks()[1] + task.Subtasks = []Subtask{{ID: "s1", Title: "Replace the pipes", Done: true}, {ID: "s2", Title: "Tune by ear"}} + snapshot(t, "task_detail_panel", 460, 900, func(c *ui.Context) { + ui.Box(c).Width(420).Margin(16).Children(func() { + TaskDetailPanel(c, &task, TaskDetailPanelOptions{Statuses: projStatuses, Members: projMembers, Labels: projLabels, + Today: calendarToday, Activity: func() { ui.Text(c, "Mutsumi moved this to In Progress") }}) + }) + }) +} + +func TestTaskDetailPanelAncestorDisableClosesLabels(t *testing.T) { + task, disabled := projTasks()[0], false + tt := ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + ui.Column(c).Disabled(disabled).Children(func() { + TaskDetailPanel(c, &task, TaskDetailPanelOptions{Statuses: projStatuses, Members: projMembers, Labels: projLabels}) + }) + }, 600, 1000) + if err := tt.Click("Docs"); err != nil { + t.Fatal(err) + } + if !tt.HasText("Select all") { + t.Fatal("labels popup did not open") + } + disabled = true + tt.Frame() + if tt.HasText("Select all") { + t.Fatal("disabled panel retained its labels popup") + } + if taskSnapshot(task) != taskSnapshot(projTasks()[0]) { + t.Fatal("disabled panel changed task fields") + } +} + +func TestTaskDetailPanelEscapeClosesPopupFirst(t *testing.T) { + p := &detailProbe{task: projTasks()[0]} + tt := p.tester() + if err := tt.Click("Todo"); err != nil { + t.Fatal(err) + } + if !tt.HasText("In Review") { + t.Fatal("status popup did not open") + } + tt.Key(0, ui.KeyEscape) + if p.closes != 0 || tt.HasText("In Review") { + t.Fatalf("popup escape closes = %d, popup visible = %v", p.closes, tt.HasText("In Review")) + } + tt.Key(0, ui.KeyEscape) + if p.closes != 1 { + t.Fatalf("panel escape closes = %d", p.closes) + } +} + +// taskSnapshot compares editable task fields. +func taskSnapshot(t Task) string { + return fmt.Sprintf("%q|%q|%d|%v|%q|%q|%v", t.Title, t.Status, t.Priority, t.Due, t.Assignees, t.Labels, t.Subtasks) +} + +func TestTaskDetailPanelVersionUpdatesSubtasks(t *testing.T) { + p := &detailProbe{task: projTasks()[0]} + p.task.Subtasks = []Subtask{{ID: "one", Title: "One"}} + tt := p.tester() + p.task.Subtasks[0].Done = true + p.version++ + tt.Frame() + if !tt.HasText("1 of 1 done") || p.changes != 0 { + t.Fatalf("external update: changes %d, labels %v", p.changes, tt.Texts()) + } +} diff --git a/task_item.go b/task_item.go new file mode 100644 index 0000000..bd54a54 --- /dev/null +++ b/task_item.go @@ -0,0 +1,99 @@ +package mujica + +import ( + "log/slog" + "strings" + + "github.com/egoist/mygo/ui" + + "mujicaui/internal" + "mujicaui/theme" +) + +// TaskItemOptions configure a TaskItem. +type TaskItemOptions struct { + Members []Member + // Today anchors the overdue mark; zero uses the system clock. + Today Date + Disabled bool +} + +// taskItemEdit is a title being edited inline. +type taskItemEdit struct { + on bool + draft string +} + +// TaskItem displays task fields with completion and inline editing. +func TaskItem(c *ui.Context, task *Task, opts TaskItemOptions) ProjectResult { + projectCheckPriority(task.Priority) + for _, id := range task.Assignees { + projectMember(opts.Members, id) + } + k := Tokens(c) + d := Density(c) + today := datetimeToday(c, opts.Today) + r := ProjectResult{} + row := ui.Row(c).MinHeight(d.ControlHeight()).Gap(d.Unit() * 3).AlignItems(ui.Center).PaddingX(d.Unit() * 2). + Role(ui.RoleListItem).Label(task.Title).Disabled(opts.Disabled) + r.Element = row + edit := ui.Local(row, "task-item-edit", func() taskItemEdit { return taskItemEdit{} }) + if row.Hovered() { + row.Background(k.SurfaceHover) + } + row.Children(func() { + done := task.Done + if Checkbox(c, &done, "", CheckboxOptions{Disabled: opts.Disabled}).Label(task.Title).Changed() && !row.IsDisabled() { + task.Done, r.changed = done, task.ID + slog.Debug("mujica: task_item done", "id", task.ID, "done", done) + } + if edit.on && !row.IsDisabled() { + in := TextInput(c, &edit.draft, TextInputOptions{Label: msg(c, "task_item.rename")}) + in.Element.Grow(1) + in.Input.AutoFocus() + switch { + case in.Submitted() && strings.TrimSpace(edit.draft) != "": + if t := strings.TrimSpace(edit.draft); t != task.Title { + task.Title, r.changed = t, task.ID + slog.Debug("mujica: task_item rename", "id", task.ID) + } + edit.on = false + case in.Input.Shortcut(0, ui.KeyEscape): + edit.on = false + } + return + } + edit.on = false + title := ui.ButtonBase(c).Grow(1).Shrink(1).Justify(ui.Start).MinHeight(theme.MinHitSize).Radius(theme.ControlRadius).Label(task.Title) + internal.Ring(title, k.Focus, theme.ControlRadius) + title.Children(func() { + t := ui.Text(c, task.Title).SingleLine().Ellipsis("…").TextColor(k.Text) + if task.Done { + t.Strikethrough().TextColor(k.TextMuted) + } + }) + if !title.IsDisabled() { + if title.DoubleClicked() || title.Shortcut(0, ui.KeyF2) { + *edit = taskItemEdit{on: true, draft: task.Title} + } else if title.Clicked() { + r.opened = task.ID + } + } + PriorityIndicator(c, task.Priority, PriorityIndicatorOptions{IconOnly: true}) + if text, late := projectDueText(c, task.Due, today, task.Done); text != "" { + fg := k.TextMuted + if late { + fg = k.Danger + } + ui.Text(c, text).FontSize(FontSize(c, theme.CaptionSize)).TextColor(fg).SingleLine().Shrink(0) + } + if len(task.Assignees) > 0 { + items := make([]AvatarItem, len(task.Assignees)) + for i, id := range task.Assignees { + items[i] = AvatarItem{Name: projectMember(opts.Members, id).Name} + } + AvatarGroup(c, items, AvatarGroupOptions{Max: 2, Size: 24}) + } + }) + return r +} diff --git a/task_item_test.go b/task_item_test.go new file mode 100644 index 0000000..3ac3266 --- /dev/null +++ b/task_item_test.go @@ -0,0 +1,102 @@ +package mujica + +import ( + "testing" + + "github.com/egoist/mygo/ui" +) + +type taskItemProbe struct { + task Task + disabled bool + changes, openeds []string +} + +func (p *taskItemProbe) tester() *ui.Tester { + return ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + ui.Column(c).Padding(8).Children(func() { + r := TaskItem(c, &p.task, TaskItemOptions{Members: projMembers, Today: calendarToday, Disabled: p.disabled}) + if id, ok := r.Changed(); ok { + p.changes = append(p.changes, id) + } + if id, ok := r.Opened(); ok { + p.openeds = append(p.openeds, id) + } + }) + }, 600, 120) +} + +func TestTaskItemFieldsAndCheck(t *testing.T) { + p := &taskItemProbe{task: projTasks()[1]} + tt := p.tester() + for _, s := range []string{"Tune the organ", "Urgent", "Overdue by 2 days", "Mutsumi Wakaba"} { + if !tt.HasText(s) { + t.Fatalf("missing %q in %v", s, tt.Texts()) + } + } + tt.Key(0, ui.KeyTab) + tt.Key(0, ui.KeySpace) + if !p.task.Done || len(p.changes) != 1 || tt.HasText("Overdue") { + t.Fatalf("check: %+v", p.task) + } + tt.Key(0, ui.KeyTab) + tt.Key(0, ui.KeyEnter) + if len(p.openeds) != 1 || p.openeds[0] != "AVE-2" { + t.Fatalf("opened %v", p.openeds) + } +} + +func TestTaskItemInlineRename(t *testing.T) { + p := &taskItemProbe{task: projTasks()[0]} + tt := p.tester() + tt.Key(0, ui.KeyTab) + tt.Key(0, ui.KeyTab) + tt.Key(0, ui.KeyF2) + tt.Command("selectAll") + tt.Type("Write the finale") + tt.Key(0, ui.KeyEnter) + if p.task.Title != "Write the finale" || len(p.changes) != 1 || !tt.HasText("Write the finale") { + t.Fatalf("rename %q", p.task.Title) + } + tt.Key(0, ui.KeyTab) + tt.Key(0, ui.KeyTab) + tt.Key(0, ui.KeyF2) + tt.Type(" draft") + tt.Key(0, ui.KeyEscape) + if p.task.Title != "Write the finale" || !tt.HasText("Write the finale") { + t.Fatalf("Escape kept %q", p.task.Title) + } + tt.Key(0, ui.KeyTab) + tt.Key(0, ui.KeyTab) + tt.Key(0, ui.KeyF2) + tt.Command("selectAll") + tt.Type(" ") + tt.Key(0, ui.KeyEnter) + if p.task.Title != "Write the finale" { + t.Fatal("an empty title was saved") + } +} + +func TestTaskItemDisabled(t *testing.T) { + p := &taskItemProbe{task: projTasks()[0], disabled: true} + tt := p.tester() + _ = tt.Click("Write the overture") + tt.Key(0, ui.KeyTab) + tt.Key(0, ui.KeySpace) + tt.Key(0, ui.KeyF2) + if p.task.Done || len(p.changes)+len(p.openeds) != 0 { + t.Fatal("disabled item reacted") + } +} + +func TestTaskItemSnapshot(t *testing.T) { + tasks := projTasks() + snapshot(t, "task_item", 560, 220, func(c *ui.Context) { + ui.Column(c).Padding(8).Children(func() { + for i := range tasks { + TaskItem(c, &tasks[i], TaskItemOptions{Members: projMembers, Today: calendarToday}) + } + }) + }) +} diff --git a/task_list.go b/task_list.go new file mode 100644 index 0000000..ea533c2 --- /dev/null +++ b/task_list.go @@ -0,0 +1,215 @@ +package mujica + +import ( + "fmt" + "log/slog" + "slices" + + "github.com/egoist/mygo/ui" + + "mujicaui/internal" + "mujicaui/theme" +) + +// TaskGrouping chooses the sections of a TaskList. +type TaskGrouping int + +const ( + TaskGroupNone TaskGrouping = iota + TaskGroupStatus + TaskGroupPriority +) + +// TaskFilter shows all, open or done tasks. +type TaskFilter int + +const ( + TaskShowAll TaskFilter = iota + TaskShowOpen + TaskShowDone +) + +// TaskListOptions configure a TaskList. +type TaskListOptions struct { + GroupBy TaskGrouping + // Statuses order the status groups; required with TaskGroupStatus. + Statuses []WorkflowStatus + Members []Member + // Version must change when tasks change in place. + Version int + // Today anchors overdue marks; zero uses the system clock. + Today Date + Disabled bool + Label string +} + +// taskRow identifies a heading or task. +type taskRow struct { + head string + task int +} + +// taskListCache keeps rows until the data, grouping or filter change. +type taskListCache struct { + first *Task + n, ver int + group TaskGrouping + filter TaskFilter + rows []taskRow + counted [3]int + statuses []WorkflowStatus + locale Locale +} + +// TaskList groups and filters tasks, virtualizing visible rows. +func TaskList(c *ui.Context, tasks []Task, filter *TaskFilter, opts TaskListOptions) ProjectResult { + if opts.GroupBy < TaskGroupNone || opts.GroupBy > TaskGroupPriority || *filter < TaskShowAll || *filter > TaskShowDone { + panic(fmt.Sprintf("mujica: TaskList grouping %d or filter %d out of range", opts.GroupBy, *filter)) + } + if opts.GroupBy == TaskGroupStatus && len(opts.Statuses) == 0 { + panic("mujica: TaskList grouping by status needs Statuses") + } + k := Tokens(c) + d := Density(c) + label := opts.Label + if label == "" { + label = msg(c, "task_list.label") + } + r := ProjectResult{} + root := ui.Column(c).Grow(1).MinHeight(0).Gap(d.Unit() * 2).Role(ui.RoleGroup).Label(label).Disabled(opts.Disabled) + r.Element = root + cache := ui.Local(root, "task-list", func() *taskListCache { return &taskListCache{} }) + var first *Task + if len(tasks) > 0 { + first = &tasks[0] + } + if x := *cache; x.rows == nil || x.first != first || x.n != len(tasks) || x.ver != opts.Version || x.group != opts.GroupBy || x.filter != *filter || !slices.Equal(x.statuses, opts.Statuses) || x.locale != current(c).locale { + *cache = &taskListCache{first: first, n: len(tasks), ver: opts.Version, group: opts.GroupBy, filter: *filter, statuses: slices.Clone(opts.Statuses), locale: current(c).locale} + (*cache).rows, (*cache).counted = taskListRows(c, tasks, opts, *filter) + } + rows := (*cache).rows + state := ui.Local(root, "task-list-state", func() *ui.ListState { return &ui.ListState{} }) + st := *state + st.Key = func(i int) any { + if rows[i].task < 0 { + return "head:" + rows[i].head + } + return tasks[rows[i].task].ID + } + st.Header = func(i int) bool { return rows[i].task < 0 } + root.Children(func() { + counts := (*cache).counted + sel := int(*filter) + taskListFilter(c, &sel, []string{ + fmt.Sprintf(msg(c, "task_list.all"), counts[0]), + fmt.Sprintf(msg(c, "task_list.open"), counts[1]), + fmt.Sprintf(msg(c, "task_list.done"), counts[2]), + }) + if sel != int(*filter) && !root.IsDisabled() { + *filter = TaskFilter(sel) + slog.Debug("mujica: task_list filter", "filter", *filter) + } + list := ui.List(c, st, len(rows), func(i int) { + row := rows[i] + if row.task < 0 { + h := ui.Row(c).MinHeight(d.ControlHeight()).AlignItems(ui.Center).PaddingX(d.Unit() * 2).Background(k.Background).Role(ui.RoleColumnHeader) + h.Children(func() { ui.Text(c, row.head).Font(theme.SerifFont).TextColor(k.Text) }) + h.DrawOver(func(p *ui.Painter, rr ui.Rect) { internal.Rule(p, rr.X, rr.X+rr.W, rr.Y+rr.H-1, k.Ornament) }) + return + } + ir := TaskItem(c, &tasks[row.task], TaskItemOptions{Members: opts.Members, Today: opts.Today, Disabled: opts.Disabled}) + if id, ok := ir.Changed(); ok { + r.changed = id + (*cache).rows = nil + c.Invalidate() + } + if id, ok := ir.Opened(); ok { + r.opened = id + } + }).Grow(1).MinHeight(d.ControlHeight() * 4) + list.Children(func() { + if len(rows) == 0 { + ui.Text(c, msg(c, "task_list.empty")).TextColor(k.TextMuted).Padding(d.Unit() * 3) + } + }) + }) + return r +} + +// taskListRows computes groups and completion counts. +func taskListRows(c *ui.Context, tasks []Task, opts TaskListOptions, filter TaskFilter) ([]taskRow, [3]int) { + var counts [3]int + keep := make([]int, 0, len(tasks)) + for i, t := range tasks { + counts[0]++ + if t.Done { + counts[2]++ + } else { + counts[1]++ + } + if filter == TaskShowAll || (filter == TaskShowDone) == t.Done { + keep = append(keep, i) + } + } + rows := make([]taskRow, 0, len(keep)+8) + switch opts.GroupBy { + case TaskGroupNone: + for _, i := range keep { + rows = append(rows, taskRow{task: i}) + } + case TaskGroupStatus: + for _, s := range opts.Statuses { + rows = taskListSection(rows, s.Name, keep, func(i int) bool { return tasks[i].Status == s.ID }) + } + for _, i := range keep { + projectStatus(opts.Statuses, tasks[i].Status) + } + case TaskGroupPriority: + for p := PriorityUrgent; p >= PriorityNone; p-- { + rows = taskListSection(rows, PriorityName(c, p), keep, func(i int) bool { return tasks[i].Priority == p }) + } + } + return slices.Clip(rows), counts +} + +// taskListSection appends a heading and its tasks when any match. +func taskListSection(rows []taskRow, head string, keep []int, in func(int) bool) []taskRow { + start := len(rows) + for _, i := range keep { + if in(i) { + if len(rows) == start { + rows = append(rows, taskRow{head: head, task: -1}) + } + rows = append(rows, taskRow{task: i}) + } + } + return rows +} + +// taskListFilter marks the selected completion filter with an inset. +func taskListFilter(c *ui.Context, value *int, labels []string) { + k, d := Tokens(c), Density(c) + parts := ui.SegmentedBase(c, value, len(labels)) + parts.Track.MinHeight(max(d.ControlHeight(), theme.MinHitSize+4)).AlignItems(ui.Stretch).Padding(2).Gap(2).Radius(theme.ControlRadius+2). + Background(k.Background).Border(theme.BorderWidth, k.ControlBorder).Label(msg(c, "task_list.filter")) + parts.Track.Children(func() { + for i, label := range labels { + selected := i == *value + seg := parts.Segment(i).MinWidth(theme.MinHitSize).MinHeight(theme.MinHitSize).PaddingX(d.Unit() * 3).Radius(theme.ControlRadius).Label(label) + fg := k.TextMuted + if selected { + fg = k.AccentText + seg.Background(k.Selection).FontWeight(600) + seg.Draw(func(p *ui.Painter, r ui.Rect) { + p.Stroke(ui.Rect{X: r.X + 2, Y: r.Y + 2, W: r.W - 4, H: r.H - 4}, k.AccentText, theme.ControlRadius, 1) + }) + } else if seg.Hovered() { + fg = k.Text + seg.Background(k.SurfaceHover) + } + internal.Ease(seg, Motion(c, theme.StateDuration), fg) + internal.Ring(seg, k.Focus, theme.ControlRadius) + seg.Children(func() { ui.Text(c, label).SingleLine() }) + } + }) +} diff --git a/task_list_test.go b/task_list_test.go new file mode 100644 index 0000000..fa72dd4 --- /dev/null +++ b/task_list_test.go @@ -0,0 +1,147 @@ +package mujica + +import ( + "fmt" + "testing" + + "github.com/egoist/mygo/ui" + "mujicaui/theme" +) + +type taskListProbe struct { + tasks []Task + filter TaskFilter + opts TaskListOptions + changed, opens []string +} + +func (p *taskListProbe) tester() *ui.Tester { + p.opts.Members, p.opts.Statuses, p.opts.Today = projMembers, projStatuses, calendarToday + return ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + ui.Column(c).Height(560).Padding(8).Children(func() { + r := TaskList(c, p.tasks, &p.filter, p.opts) + if id, ok := r.Changed(); ok { + p.changed = append(p.changed, id) + } + if id, ok := r.Opened(); ok { + p.opens = append(p.opens, id) + } + }) + }, 640, 580) +} + +func textIndex(texts []string, s string) int { + for i, x := range texts { + if x == s { + return i + } + } + return -1 +} + +func TestTaskListGroupsAndFilter(t *testing.T) { + p := &taskListProbe{tasks: projTasks(), opts: TaskListOptions{GroupBy: TaskGroupStatus}} + tt := p.tester() + tx := tt.Texts() + todo, doing, review, done := textIndex(tx, "Todo"), textIndex(tx, "In Progress"), textIndex(tx, "In Review"), textIndex(tx, "Done") + if !(todo >= 0 && todo < doing && doing < review && review < done) || textIndex(tx, "Backlog") >= 0 { + t.Fatalf("groups %d %d %d %d in %v", todo, doing, review, done, tx) + } + _ = tt.Click("Open 4") + if p.filter != TaskShowOpen || tt.HasText("Book the hall") || !tt.HasText("Tune the organ") { + t.Fatalf("open filter %v", tt.Texts()) + } + _ = tt.Click("Done 1") + if tt.HasText("Tune the organ") || !tt.HasText("Book the hall") { + t.Fatal("done filter") + } + _ = tt.Click("Book the hall") + if len(p.opens) != 1 || p.opens[0] != "AVE-5" { + t.Fatalf("opened %v", p.opens) + } +} + +func TestTaskListPriorityGroupsAndEdit(t *testing.T) { + p := &taskListProbe{tasks: projTasks(), opts: TaskListOptions{GroupBy: TaskGroupPriority}} + tt := p.tester() + tx := tt.Texts() + if u, h := textIndex(tx, "Urgent"), textIndex(tx, "High"); u < 0 || u > h { + t.Fatalf("priority order %v", tx) + } + tt.Key(0, ui.KeyTab) + tt.Key(0, ui.KeyTab) + tt.Key(0, ui.KeySpace) + if len(p.changed) != 1 || !p.tasks[1].Done { + t.Fatalf("keyboard check %v %+v", p.changed, p.tasks[1]) + } +} + +func TestTaskListDisabledEmptyInvalid(t *testing.T) { + p := &taskListProbe{tasks: projTasks(), opts: TaskListOptions{Disabled: true}} + tt := p.tester() + _ = tt.Click("Done 1") + _ = tt.Click("Write the overture") + if p.filter != TaskShowAll || len(p.opens) != 0 { + t.Fatal("disabled list reacted") + } + q := &taskListProbe{} + if tt := q.tester(); !tt.HasText("No tasks here.") { + t.Fatal("no empty state") + } + defer func() { + if recover() == nil { + t.Fatal("expected panic") + } + }() + bad := &taskListProbe{filter: 7} + bad.tester() +} + +func TestTaskListLargeData(t *testing.T) { + p := &taskListProbe{opts: TaskListOptions{GroupBy: TaskGroupPriority}} + for i := range 100000 { + p.tasks = append(p.tasks, Task{ID: fmt.Sprintf("BIG-%d", i+1), Title: "Task", Status: "todo", Priority: Priority(i % 5)}) + } + tt := p.tester() + if n := len(tt.Texts()); n > 200 { + t.Fatalf("built %d labels", n) + } +} + +func TestTaskListSnapshot(t *testing.T) { + tasks := projTasks() + filter := TaskShowAll + snapshot(t, "task_list", 600, 420, func(c *ui.Context) { + ui.Column(c).Height(420).Padding(8).Children(func() { + TaskList(c, tasks, &filter, TaskListOptions{GroupBy: TaskGroupStatus, Statuses: projStatuses, Members: projMembers, Today: calendarToday}) + }) + }) +} + +func TestTaskListCompletionRefreshesCounts(t *testing.T) { + p := &taskListProbe{tasks: projTasks()} + tt := p.tester() + tt.Key(0, ui.KeyTab) + tt.Key(0, ui.KeyTab) + tt.Key(0, ui.KeySpace) + if !tt.HasText("Open 3") || !tt.HasText("Done 2") { + t.Fatal("completion left cached filter counts") + } +} + +func TestTaskListFilterHitAreas(t *testing.T) { + for _, density := range []theme.Density{theme.Compact, theme.Default, theme.Comfortable} { + tasks, filter := projTasks(), TaskShowAll + tt := ui.NewTester(func(c *ui.Context) { + Use(c, Settings{Density: density}) + ui.Box(c).Height(300).Children(func() { TaskList(c, tasks, &filter, TaskListOptions{Members: projMembers}) }) + }, 600, 320) + for _, label := range []string{"All 5", "Open 4", "Done 1"} { + r, ok := tt.Find(label) + if !ok || r.W < 28 || r.H < 28 { + t.Fatalf("density %v, %s: bounds %v", density, label, r) + } + } + } +} diff --git a/testdata/snapshots/darwin/assignee_picker-dark.png b/testdata/snapshots/darwin/assignee_picker-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..5bbb7ddcde28b66353d2b08a23645b4dd845501f GIT binary patch literal 6877 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 Ls?t@GA4C2Jb3h9a literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/assignee_picker-light.png b/testdata/snapshots/darwin/assignee_picker-light.png new file mode 100644 index 0000000000000000000000000000000000000000..8c19a1d2d64fe32d17cc125e4736f5896f27b1d7 GIT binary patch literal 6807 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 CI5=Sd literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/burndown_chart-light.png b/testdata/snapshots/darwin/burndown_chart-light.png new file mode 100644 index 0000000000000000000000000000000000000000..7a5d584d712ab6726d5b42b6700ec41d7cd6a1f7 GIT binary patch literal 20054 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 literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/due_date_picker-light.png b/testdata/snapshots/darwin/due_date_picker-light.png new file mode 100644 index 0000000000000000000000000000000000000000..12ee9e002421865a9b4bc307517053dfcc8c4e4e GIT binary patch literal 8509 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 O(B!0*rK%-NL;nY?kR2NU literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/issue_card-dark.png b/testdata/snapshots/darwin/issue_card-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..f741efcf1774b922b119fbbe2866921eecee646d GIT binary patch literal 15654 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 PKLZqGRb}cvnTP)`GW(9R literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/issue_card-light.png b/testdata/snapshots/darwin/issue_card-light.png new file mode 100644 index 0000000000000000000000000000000000000000..aaf9d4e9d391c4c180862d524c48a250219237c2 GIT binary patch literal 15376 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 Ezw9vd?EnA( literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/issue_id_badge-light.png b/testdata/snapshots/darwin/issue_id_badge-light.png new file mode 100644 index 0000000000000000000000000000000000000000..00a3420bf3a511db51185f584ade8b6a622c4342 GIT binary patch literal 2622 zcmcIm_dnZ<8V*PKqKIo&tQd`=#%+wEDKUfUQA({kRx7oG3NhQLgNl*btD%%0yJp3x za>TKB%^Z7+w6R*PO=LfC(85{y#v?xui_M z+opT{5Nk|!Mv-UEpS5}l&m>J)iTxopYn=Xd0TH+7$vwdbkEwFf$&s1bLAX-gDfRUxc=oPgSRg_;-%5 z5SUXtewPG9K`<5=oCh|s6%-tNSXs%>O->NM9f`Co)rM;{$)(HdY)h3Jj) z^q)x=O9yn0oSppuCY;qx#u*y1R7b`3vgw@}@1u#6@?wKxF!Iv5qMX8YeLywa{ITsu z^OXQcZKXToj}wN3g@`g&1o#dk558kzR(p%>t^0an;!v|OOn>8bEDJbC77s5HI*Z(A zY<2iRpbij%Dt7llWY;cQ|AppA5U#{RzH+|pG4)-#8O#u$kFX-UZ3qQ)B(7t8=oU_l zmAg$pYrGF}G_LoJk3!Vr4k3s{faiy#kKTov#LS9>Jov{R5A4H-B*&_g>2kMMHo2O9 z=pj0hQ%Ghxq(1TEZ$Y`4HVb9j$>jQNqsfvqGu3fdayZ#E!L06mU4HD4(PDSZa#>cH zad7gGVE(Ny$DaQX`k<%zB0Uq)F3g~(EFo~)X{cP2w|(#$7g9QR;z7jM8B-Q zxxVxR>#(lYlRvlQ;@tKmYc$#`Dk^4ODU*Y1wC~(YvM+4H+k^0}{_8Kx!x4T);T4~$ zG}BWx9rQcxko~K$!P)aQrHu6ZY~o>Ui+&7BcMIM8>dN`^U&O@3o_Nuu@$(C@5X3|D zlHs?to#j)Pb*Y;#7%xWd2n+L58di*qjP1dK8d2n# zB`0rnhfVp*oII@|$Kr;Tn3lXASM~*bMn=Z6EC~Odrw`RFW>Wz&G(+l2D!== zFu~xqFaw~^{cdFY658FU!O5x*K{I&A0ryaFmGLy=Kd zTmPeZPUGG+>jFf<-h`dKR;!l6Du>RDQiJK>Zz?8fj048VR!}zXhCWi?2unDiAAU58 zL{Xi;Elv$h;odZ%L?z+IKp;VgKRjX7Zxm?)LC_)^r zkZ!T964p7;NabsOI`7w^@KO7U$S@(dF$f_ZtQ?DM2^*Z6h>d4vl4vL|S=%y>nm?lKU=~dQB_qHW!(_r9JO98DfyxwURw4(eJyEyszkbsuID0H z$u4hxhOPzoTO8;ceUH@dZAbzWKc+Ob#Jr8uPVD(>=w?9EQKW7(rE#Z+C(bRYbs@2+ z%wx-|EkY-4eXv`#d+C8tWP}09+GqY`XxOlaiKNX-$NtBUZGbdlr~ z(~`Q78o!;QxMPU|?Lb10>m}ApPi2UN^Np;Oyw{_iro)-yw=wgR3+XZ_!Q5C46}aHe zY0VktCb17Lhyx*S#EpPl?j}9%y^|%DnHn&nqU*Ui5~B3V5eZyk`JI{Bz&Lr$?){8w z)NQ(1U9HPXu^^}x8g+86%+(daz|6s57$y|z*l=@aJ_^k+g zM4p>$`qcI5va{0U6WT(X#?{wtojVF&lJW%;g+%NJD|4;}6HOGC{WWyPJfi0t&Vq0O!vFj!C)4Gp`nD%x%xy&AoT&GYP>c7>zL4uNyNmaYO&Y3lS3G( zzLr!gSqSAyhOk7Aubg&@HfOt7NUr$# zSQk3Wic*cl)L|y%)lg|mmP;0&@($jVd*&!19CQ%gEmukv?V9c_`kzpN&b z{Lsn1vT=XZ?JbG+-~poqB8}(gD6x1;lba;}Jf02<{i~zK+zfqRUVvIa%_XOnqC<=G zdN&UH?v`e<@mOdI=N)($rmY^h=+n!Tdsb$ae3PXB*OyrH%wMAt+*6L2zblan48aB$ zKFS)S_|3x>3`}@2;V&E=0CNihxWG0xV~_uuI*RpcdFfV%;y3C$!*PRuSAM|1R=ELi z+<0`-H`{Nu{zXh=Tf(z^YA9-t&gy|(g^nlm^MUZsxsWRxw-RsEh%2ar2f8zqqvJTa z4=(Co0Nd=wt*rR$-1t%Rft^RUtc^)p9Fvx11n!Y-xeEdp@!>x_{>N}j|D=!!G|QU0 VdOzRS<02P=P=*!;Rmk6-{R0P5#D4$) literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/kanban_board-dark.png b/testdata/snapshots/darwin/kanban_board-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..a9126e716f0240fba13f7c44bbc43ea339f6bb3b GIT binary patch literal 33928 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/P-?ZF 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 literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/label_manager-light.png b/testdata/snapshots/darwin/label_manager-light.png new file mode 100644 index 0000000000000000000000000000000000000000..288e4372f6eed1f838758e74502fd908f19040e1 GIT binary patch literal 8045 zcmdUUXEdB&`|hOZZAcKEBt#jJ1fzy1A$kqN=)KqIWfBHK7$T#WkRW>RoycHx(MRvS zj5^x!JMTJco%89O^`3XF|N4K~dp{rc-q-W&dtdkcTvxcdsyrDnJuv_PAX9iJs|f(y ziMbtP2=CsuLoZB(0RR>O1z9O=@6_!Xn0nkP6T!Z-^cyP9L||*sLu%68utpF zKUS7eCKPXY>d(bFo9O4l)i^hIc@Q8m=gfTVH*@N9=+EMPGh9Fv#M*VrW-xUJ0w6KD z1Nw+p3ZQAd``_!KFz;@pyx8{7hH@Qfwt#@Zob%RG_!1o>D{;bE$(Pg$U%Is0w;Unq zcoAw8oH^e5;)^=x!;5ecMsg+#5t_)iKgJ-vG}51^K{e-W*cl9FomFh1^tfa*%23q9 zQ$tB=WAGk-Q4}2IMG+lE9F903JjxZkFO>r(?Jy{*H8RpE9^bT$>ZR#7Dzodvk!=|o z8rnvsK|t|Zbh#h&nRtPcu$JYH?(O8xeq!`QcEfpI){ojCnm?U(zTf+~Ud`e)=$;HzBu_D(D^}>WayWm zXwma?mqX0=I(SU&)>#3hJKn=>C=VM zwINX{^`oF5<&+ns?k5!$^i@_j(2L-p;B7%oJtGCe*b?OF%#N5lj+E;`?K9x>c#;p5{Ui8j4q-9N@=3qrBSSZc!i zzG;CbCLhOA=fA2$v;B{nM{O<>~yTt&X=aSQ03It>#RYnOYJX|ee~*-pOX-iZw{Rfz7lcUCfuP?QyWC=HMH6G|lUf!LKjt;9x%W0+X_r~KBR={D5zn}efL3C%rkd62?8Uc2? zZp%qL+fKa{iX+cxaS2Z+mCErUZNhKTVJQOz0Uw`G!_E%E4y)YcjkkGrhfamZ3>IP+ zNISkX$@eSj3l@z@6?hCz<=bWpf;;X)PM$q-cs;ZjBC%kKu*)tg{!z8Zq1ODecYknj zu*vVV#Ha{ouW=BcNM`UnfsT21ef?Du^OtMsp-CTWmqEJ+SL-F$I+vpbV#en~4B;6W z4G`$`;2aF`zd%X9dt>s(&;DWsgSNu{)|K>^nDZ30w%9T2JLvA|wbK+7%u6nRRUsGI zf5NlS73D&naB=A@=|U)&sbl_3O~RP-uvvYX(r>koWU6LQQ1q3Qudgq9A-s10I7c_<8b#ie7YX0MR$+MESe>$sr}BbiHT;808fB zjt7OhY&9q;9C*L1XsOBPTrz|^%_;-La~doH(4P02>v#1x!`J6>6SkECw0Te#w>z%( z9we0Lt8RzSmR_I#svT}I4w!8INFT6hTDfF5^aG+JhQH zS-6Rq3XtV;NeOY*IV}hU%i&rk*AFfnpH^C4mGAJ~lnzfTOl{Va#HOsz*Y2O~Uh_QJ z7>fH@Qj%esn3-v+tE)>(n-CulHdC`+V=_a?QnjzR@mbxRud8VhvYjWCJc^RTIo?mY zUT_h%A1~=ccSCPEY+VKdkHJLN1;@7;`gt7~_82qE>bl%)RKRclc#40Ib%;i8}b_OE-sdvNV!NYBt+6EobB%BN}dM? zJf|c)+iP~;AE!&|sh6XmXxo`Cl3sA|<+z_j8Cw)TJDH++XZ2ir|nKIfP2h157px^cGp?!?_ZfAPIL^B?gS-c!T=4yjOLqe ztgjzeU@$q$1K%?#< zpi)*4A<4hfS(TO=!2S89^97j{9j(nH%c|BGLfP&F8Yu<;bf^V^+cU`T04_g#q0OB4 znVp`7Ek7~oIO~OqBr}+&7oc+{Vk+S-NqaYgjDXfU zas5@ak*Xlaa}HO-MNFN$ZNFY;Gn{vyeVMeNz-vD)G9O*VEAa9T`i0kS#L4bQ%e5RN z$pT22q~EQ%A~ZCVSd#az?T5l36%{q)Ir>rPM)OF~xxQ9lUZd*!8uK;saBb-@l8?=L zb0aeqH&s_BZuvWoJGs#r!$MmfkK5N{==eK &t#YF@|J@w5-xPn&=;P_3Y)S`mux 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 WLxlGpC&=M!fV8-RShdLap#K97>2_oQ literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/milestone_progress-light.png b/testdata/snapshots/darwin/milestone_progress-light.png new file mode 100644 index 0000000000000000000000000000000000000000..748bfc8e9386d2e2c838a953358ca4223a8d8a12 GIT binary patch literal 11540 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 literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/pomodoro_timer-dark.png b/testdata/snapshots/darwin/pomodoro_timer-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..7143060055b86d60fb1599f472556f21f30a43e0 GIT binary patch literal 15913 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 literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/priority_indicator-dark.png b/testdata/snapshots/darwin/priority_indicator-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..3e373d687756f8d24f4fd8c9a3e75ea9b8b14d5d GIT binary patch literal 4457 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⪼j}3k8zEZ_RV~m0G=W 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 F`G0)I$s_;( literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/sprint_board-dark.png b/testdata/snapshots/darwin/sprint_board-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..6f2eb6d30f32ee3b0b5b9e3c16caefa55d37bd39 GIT binary patch literal 50219 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 AH~;_u literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/sprint_board-light.png b/testdata/snapshots/darwin/sprint_board-light.png new file mode 100644 index 0000000000000000000000000000000000000000..d99315ef08847a90a1b32ad590945fab0670daa0 GIT binary patch literal 48929 zcmeFZWl*HcmM%;Sjk~)`P7-OiNc*4(h)iu_mNq@Z^>NMLz*;-qP*z6(tj1QM5HDD-ESo@n+fX>hie zo@~&#ieRbDsDuEZ~2n_{N4?*yn6+HX3?tn+i1w3}irF4?Al3f?0iS`I!a@iEz1JbI&xor~T2< z6cRjqO+BwkqqYmr3$!o8N2Px!v4Iv|UZKFqI>_RemqMp(MPHRK+gw$}`!cS#(Jbko zPF#6;pIlws{1(^!BC}Q_oq1m7wpIn@atvIa*>s$iHos;raH-W=VfF&|jv!M} zgZc}veE0K+HIzQ1oRri`N2w4ox~j(f>EhEs(YT+DrRAtWdx9RMF!IMg)q~Dg_?5<$ zPxnFQWsSinHmqvhqLRyX#Hdy_DKxx)D=zN4hgLd(JW-05hfPjSgKNU`)<)FXc_z_` z#hW}q0m$%{znR!2AnNECfS0F#-*OR&h%l(7pf)cD{j_;=T-j{58WR>rHLj}LvG7b3 zJ!e+G|8j{1xc*>ZP`~)R8M;r0S=FfKQ(EhBmWYG&=@YogbIw+f@6UsR4goXs=Fl)O zR?pWtfTU~z>!X=aQp(}&Eh7q4X0K;qFrL#6N(#uud|o5~N%0r%COcm=XDu4a=P^-~ zK#%N5g81||c!EBU4KmT=1OyqQse+@~f)b?hHOpVvu<~26$NMc9#GRNkB0;)Qdq)3~ z_4bzEnw$F*FY>YK)yv6Om*_C%1T?2qde=LqoN*mx^ zZw~w6zHq~;kH;Fm_Z!t3dv=VUoh1z1(#Z1)C+Wt9wKjMPz~&!ya!T3X`#AKxXxlXx z)puV}F~+Sx4Fv+1=qma0fE5_tpfWl~?V=uW%=oe_=3|H*@(*>VTefTVV~^nSKE7E! zFNt|R{jqFgsE8OE*sij^6n=bq>b3p7taL4Ld7%*SeywYWBq_LW)OVsxg0mMwq$VlL!_1KH5 z?xqg9tHu1I<=7#EG1k_{$@N%$v{QU9u*rq3ljqBR2UoW-?Hm(X-N@CFPwVqg z7*vaUzouLc-MSl^b=G?^f1wbZ5-2tMu~9g_b?I5Tcs+p1dL?3T;Kd_@muoD&Y))c( zd#T_b2*UyRSXj%yeh-gxug(%g5AgZ`bF=Jo2hEw695B}m#>-}99i)N;vkCe@MMUp zLaN`X{XltYec|wM()3n35|wDn5nNXNFIEJn$0Z-)=YEz4yblPZ$qTDP#{v)|i;GA) ziaNec$~pE@m-rZ1TfX>o@j0HIXL{M~`0o#Mc02h(;r{yeiS7G41Ph_e^PY#iTk>m<3A~ZF@ZoPJHE7w6D_Qq!(YuZua zz(?yYHkjfj8fxl{?l0-h=lAJ`IhdF!35G_&dv`jn3K`EAZ;-NDP2TjWI;HwU+@H4= zE~Y_FSYA&tIV|)voOjt~&nZFtXjH*aF-YN&3doVXf+HwV7Mv`3J(QqZf~P6gDi^M+ ztEchxGQoZK!eMk+plZA9uu!u&P4b!GS8{5uyoQ~Nj*M*h59hP!S&VsoXfk zU}x$AQ4(<0uR9Kc2;{n^CO-EsPvz?v=BBH!$ya#hUYOTp~3{g@qsOa34 zGD`rDjhV@LZ)emp-MVW{a^jVy zH3&w=6=e8gwon{iJYlnfe7t>n^OCaK+p)rpZ|+!uE6{yrH5aXv?@b8_X=b{v+v0w6 zrUz7QG-fL>H-Y;YkT3CSI^0COb~?H%5kpQI1Rw>avtp$%K6wvZOF@$;#QqfiiNej@ z`uf_{2Zv2mBc%074Qx2q@qs1nu9%pK(t`T+3N74%3a_Q!G3UcNdkuCrTpXN)*!N^h z2+`DuOnH!yViGag85qo2@MNDu*x6u9RLhF@zp#i)5+f(bU2h135{oA-*_L*Ox7lZF zli2HqP`W?ZuS>)Xw&VV4dbMS*E)v{|+nfNM&?OsUg?mPvU)eUkPg;0TwcZ87iPk=uF%l@PQL(TWJdAv zPgEJuN!W~9ibujQQ~3rQyziNiOtBZ2m+Kby#QI}Z#T%*};YdVE3lE=;Cy~8_nSTTjz z+49tvM5@Uq`?uWOE`O0iN3IDUzq{N>^j`OlB{-}q>gr#^eXL-^A|krdrPw)Mdd!|X zTUm))S$*;d#g&nXjC|vk(tr1-(a+(u+GF>r3{s%Qpa;ni?Q1r!NxjxslyeWh_Q49P zRpyBacuypuI2AV?pTU#F`Z3!va&~{z*dW6SX_tc`_F7}-iZRA6azKD4p{FlWoyxd5 zOez^lH$el_H59UtY~J-+D~1q5ZQG(*bwVns=N58Jot!++JOIt?n7FrSnD}0K--st? zQPF^>XCDgTz(7bnX%R3DJKil2#qTzcuQCCHUz@yU?C?`>qPA|S>acqpu zcXhhgLSIHy+uVGlw3CI!%k_N_gNlAE&M04yOhW4 z)I-)h8KUIRz=P330|~K-ooff}HrY;uo7>ZNqIncqu<_NH*E&&AaWLel%pWlk?oa}W-_?Xuu_VZgRN?-V=muj)a4 ziWO*f1lAN~pFF^QSEQbp=!7FgkAG*RXObgOy_kW;>R0-N+`OoiJ3`yHtG@JXhmx0X zT-`9L0R;B9wedjbK0hHP8}4k0$m;+89yZQFHGyS|o|M|X)4~;h=K^5&Ey!t(jZLND zS6AufWM>!GTZIsB;Kf!7Qar0|yEm%KjF@<=RMT#B$Y?YC<;RqbtFr#oJpZfh$W z7#jLDF%dGg*D_&{fD}I-lPS$7$)N)SjV;A7OHTCyv}q!9pK1a3Q%XuodK&iKf#K3^ zE-u?_vTt?Gug`|LDnqn?;tfJE-}d{UtIKnJG_~P=Nm4dpmAwTZQpJ8IRU<|lA2jOq zyQiX;?bFLWmBFYfy`f-#qUhRZqL>?lZbKbG4J<~+J6er8`@J2zrIwJB6MU*ceJH=@ z#fgcz@k#@;fyT(xDJ);+)DzY1?bAlZEl&ne2=LdTh_=m!HI-wsax0%|nM-rwytNL#5Y(O>3tF zHVA5hVIm%<*s~hr`B;6qFO(q}2zdw?e66xYIKN}qeYBBt4Ezp$4b#JTE!bR9L>dpo z;E1&xSG|c|?N9DqSf%>jM2qD9GGY-mmydzYnKO**>^yyRp+##t&BEcC9~xq!aon5G zgHjbN2s)py(k1BL8Lc*DNso-&o;bxD8cv<)G z428WSu;kg3fdWqcsY1wYp~dNm&DFVCg2pNMB{}WFqV+lp0(2HfbBoQ4 z&7mHio*ti`=H@xEad8z(XSnNolMGG1eDAg%6i=58F=WA%NyU$`dn;Od3`MSMtexUp z{q^h1U6mX*r8Q<`G(5r($rr%eo_Iq+106rVjw#^ojF;TX?)EFu#~kL4?Mdu^I4js^ z*PQsfGQ75hP^+)Gs}!$qE%i#m*&`DLbPOJ9=)UyhO9;lAbKfymtg2*daM|8j*?!=6 zRHbF9yUpEIiHexbb<4)l3qJuX%T+)MzIjm-V zH6f_4I!;w)4+H4Yu{2Y&3Lfo55i&F; zu57oh_aZ|sD^N$!B31qZ^S9X@shN9sVw$1!`OPtzsYNwv_t|;1S`$!?%h=LXDPbF9$LSLDw^r@6txS|>T?Fa z5x-s4@*c_-=_8>PRW)hs6clq_VK_o^8|;VS1t`#>MSdZ zEPrt1Pgy$3&i$z5sI4dM4I(t(MTH8zM6h8ovMxc?^2ryu?i|mtjse__ zLF|#yHgtA`ip91Lt?xB9qII)dBl)>uAznGYp+J(silawSV=MimsXxO4z!{H(I7*f( ztQT1#N)1COt%8aq8nZYFZ@%F++cJbAlGULwI0s?)iMxa{pWB>Q`_`lZ_Xq zpKiaNXz4vST>do9z!arSSwK9DM83=*81uWmRNAWqqhejav#WVB?&4U${KzU%#Z`nX z)g5Ok#8WmU=ExKt21eD)C;Aty-G~3)s(&`quN8&8p^2Dgeal_VP)os0!xa8PI%k-9 zt0ocgP%$X3s@A_ncwv@MzEshf%R9J5n8|Wf<5vFzETg{HSAqJ|!^gm)7^&5oH@hhc z+&}^Mwzh$ak|q+1tAsZ5l{^{F%f#uCy7TATa|55fabo+Uk104x_bTfvfL+0N8|R3P z#t?roijR-`5fdhwH)QfazlRMJ98pHNFju6(>!C3Y2bqh;kxgF zkXQA)G8L(C8*4nW5uD@knc2@$?GHPTdJ~%Vrtk!a25X8+wnp~+MrSixgPhZiX)con z32x4a?e>hY$;v5N^G#;E)K*fMM>PX}Iq#Lz-|VWTNqRGWX5Sw)Xg~dhmYRFJz#Z}gBLk? zs0@g7@G5oAI3<=B^9`4!L(oK7y{!N>@pY@kp|-22&Px`8#`I2bc(hl%D6}8j8~}k}K6LxF z0d1E3_LlIZoj6F^TBDNFYjPM2=u%90-UpA5wy(-D!&7L87@4C<#w;{hX8b=WzL++I zXU*o;nDXs%=c(dWHcxJRA2%Qkx=ds=w-bzDk35tefXWF*%)TJuzQDVBJIR7kP1IN# zv{y$(ovR@~AqI}ngsB0(D<3OEmVeN$)b8i8b3xB4<%!8EbNPUQ&Z%2Ar`?EwrK&B2 z*&jg+`wm^0c!*S|CjnUm^)icdQx4^Qfbmn-v_NQDD4C`0ifv%QfUXFPW17Wc$Aw%N9Lqi#c&+f_ri%^)0XkzqJD#SKOXU`UruHIBll zKRvRls+wkIC*4ktgS9tHDl&&U5C73_jMD*Nky=@yv_Z$FRdD@T-I30a-cj12ojN`> zWw>FR5iiBFe3aq5C{9iz)@%Bo(dU0_4>%kR;(^waQ(MKH`3dx5K#LD}qPOB-B*NcA zeEXp0lxxMHIv!lss>qI2wkI;HTap3ykIXZJ600+!eEInMt;=dDbXc#TtgLFP7R9f* z8zNq9iqz^K`y;+OxXKu2H**OLB``MT2|@oE4t{k1AW$r24Oi*NIOZfp?v z4&vaGvJ(kA*57}v`&gaj0QdGV^-Yr-8wF5mMavW2bXcuOMa0ZWit%0m&gI`i&eGvD9y+g~h5=q(Tz4~R*x ze@cYi@nuu`?Hi6vYNfRm>IN26e=wY27MBO1Ur{<9jG&LZt<=vK2Bp)Pb}V%An!N}%XA9t5X&1j+ z?6wE0QV!-=?)43yQ{G2kT|4*V{Rn&Qk1m-CBMs7B)fD{vA6g7@)lF)xVG6_>`1g<50CKjyr$FW2ooP> z8YtkQ{FU#_Mxc3UWa@cZK@^FQ$KhJCAi2<^nz&R|+F4e2VD(A4)aGOXbUa`AecBQ_ zHzA=;uRT99r<;lCR}K!#O}&^C%*TKMaXu5Kyz`l`qoc#J6b9Q9n<%*`1$+S|9TjUc zJ9Pt%oXj*`b!D?3EWZi2`OQ|agA~op_fLpk2qHlNJ0HMb8%PLMKXj%P+&%h})`Xn#Vc3N|{w?W7;4U+gx+ z+QVYd>H@fgO<$Q$`gJ~8J2}-SH>w?UDB6Z_h)5dq@h5*}&lOz}CXI)^gu{j(sNk+I z(^oGnE^u>kX>Do!IEe_Z^rio;>~{7hr)pk(o+SXH7AWOiht+?6T z&ed)p3*KMohf(b_)nj|Cqee_Y=9zGe5b;;Svx@PVf%B8`JH)>rEE)hHZEZt*yB&k% z=g&f-f;>7tPEW5LA6tMXscp$GD>FOR@YtkdmC1HBq&qN(2F4`orm#3bEM-d3DZ045| zVdEZbCmLH>p%xUFXzJ)x>DCt1)g7I*%Ba$~>_+sLEyfOJA;2Nv2&~k$wwmsi`7z@} zCDW$N%(7?lxpb+}=ylumgAr;yXSerNcD_O%k;p2)%*m#het4odC=CT;{6BjCyp*6E zI%t?kPQE4Mi=E-w;py;D{$Gr5~Fe)~&3q6*72An~FGC`KKq=CdQ}bjGtkHw`M>p1C#?!m}8|CC9<-T zY#i)_hdc?u!Oqud7bHfcb(k)XR*x0FsxE=s&3H-jXK?`mdMogjvZduuf!ddkpKZ|g z1SguCYG1#MKw+w5sxg)`WOeWCZnJN`z(9IH3T8h2>=_9#?R&K4@mr^ARcP_h6(#F^ z7t+7~*QESgv*A3a4k?Gti`l+^R(oDn=80ei$7eP+&B&!rF*|Sv=la2kLn9EKwR{DY zQ7OO<+(-3biisAzdR_5&N3H*wo(9KFykLXUvDmmCFe#eo4rK4V? z^+Dd-Z$ezoUsFpA{{fs4IE%q1If0SGt?D%!8yg-UmXL7{VQ3}looxs6 z`6{gxN2>gMQB<$5oROyAFJ}k0C$_d;mn4PMMeC5KeUajEHZblupHMcSMb>>&JfjZ3)Z(pZ%ac@a*1X>E4o1fh`+owT?)#qkp*Fj zJ-4B$f#Ge?kuotH8Qe==U(fx^+si{!L+`Nd(Ns?4geViMbvsDa65hD{1}bp2p9e^S z=ql-r?*>UJ2=xgUk?PFHGK7hdVXxpSZ7Sg55q_uF`q^dMNi`=%$wsa4t^Vd5z~ScDT&i5VJ3XWSY>iabHW;Ptw91BV+UhKeZI}3%`(bh zip0{^5+MVBhizrpvL*3K(tMT<>5RXoz8MZkBuw9zL)S8iNpKaY@^x?Uf== zC?lS(V@z3GSOPCW?8i?mzjbD5Oc>+T>H{aHUw&kNu*b*z5AyG6UAsuRKS}V}_mz~D z^;o=zFP=iA(FE5>BI5FsGJkH1GJHfeGcIq4wtklf~q@ZkmTJWxgdaEK`@IC*zXf2gN zk{UWzDi7B}nJ%@+(ENOHF^U?LmacA@A~l$75bf?6TWgS_h#Y7+9C{gd@bT%ode^^A zWVLS(L}#;jAk z26O|;u7%2$=ZDlL%Z5!IuxlIV1pn+8IBsr4CrA9-#k|(_6TYv9myKX-pM6mEQbj6M zq)wPP3#5kzj2FAaeeQlhVR0yNklH!Hwk3=!|k_Mu~|_xgm7Exj#G_srs=RG~7?$Q%7hJ1mur9tw%`!_z1@ zR`ueCq}Rx4>Q#(HNYCym%(mBi0SawZUi<2t#_7l4F5wE4OEu}vT2HtktR}@tT?G#q zv-LY1sA>o9QA9RJd#?!hF&rXM(NNLQPX#O=&y7NlQjJ`Eq99O?R?GB;Hmvw7MczNlz zdCM`JR|NobH11!Ye4%qw)!4_!=@D;TJ43PA%3M;rl9H0b`w7aXgjWKJ*>J~uGOxD8 zAbkm*_D@W5l9J}u80OTgTrkl2$WX&$Vq7u!28kF31ijOaw^_@|%a414Y42(Ed!-&Y zJ-+;K7wo=67SYqwLqL$DOYxVbJU)o~2&Di6lTL%o7CHeF+wD5q-`{Fah7DRD4J+$3 z__gyra$V0`{d&wJh;=YiWr)7-R+*+U9zc4Sx*dIFA;QZzB9%O7o zpxj#AT9-F9`+;_ZZUau$3($@w*2!PTQg5Q19+>zc5OiAPDfQxdu7JD!lMylHbt`pr zH)~3sk%$q@Ur2MQJ?))u18u-|1moMatPD@pkAysR^g+&BEtgC<@r$Iez=ZGEUQPGH zZ^#rpV)P=)!ZLve8^kAybJO+1wc*adKRN!(19{>IY-=#X83T9;xgba#E`yF9{l~Ovq_)J%?xOheLtuc6i35jrr&qJBX zu|Q?Ak#@I;b+c%Exwlua(o>7TZEK}3+_z6)v~qi}+l~5m2mDhigPx+s{8!>fO`&hq zDJgSF!)V*v_LbT%yCq6?v$KsamD9Mj@SUA2Zr=5Nqbbl$rNgDu>u(838SclZIgDup zZSEK5Ib&H@4!fgAU^>#6Eau^13LY-Vnew`0QTi`)JNc%Rr%>(5jh@IQxZWI(QzQ2o zK7E9gBu}`Pxp)kDj7+630$G|;n3Cy=L*EC0L&!{PkvfMun5Zf?mVmj)UL%kn3u2Xj z)n2bX`HG2Z$DYJ}*%})MFBv`c_lU<))JoSB_GCggqeta5kT`J|ciX7*wtjuPIdut%S- z{MmRgX047p?;Je^)9fj~=`=bji}UT=na379k>G8z?HNN#_h#Ay&NRp}+?95}ajA(> zcsoA#OP@wAHCbN8G#)p7f$~eMy*po?Fv6+P{Dg9xLd5TSJ9Bv6STZA(_f)I*Q#j}$NnLf%TgiUANkfZ_ExLJA7aLtI>1mWRupGkA7WIj4Nfq&tj@ z`)tCA)Eu`+qDo&TlH202JCJ`Ok$?yT?B%Fu@*4KSsfBrRCtsBxX-Nc+hS73Si})Pf z;oY7uN3Y<3nP%004?Z%arlE!w4(Jx@hPoq^h0ES!ohaUSPEk*>VYT6RJx#TSaytJr zdioi)wY4oR*AjfYV?EPIQuD4mK-;|)p@$8gnw_0>LqNbrwYBXzI?{%NW2NlEqGPAO zBC_T*f60)fOa$*gcXbi2-JKquBq?81n$y^>G<3>Q^P$(vkfWl6ldA=sK|lwS@?;h1 zzc76M{B%)_XJ|-5RhV$+cQc!4~&ubeH z2NSueur8EZOPZqUqBFQ}M8(M=sz+KuQ_o35O z5>X&KmqqAVBv%o9{%ii6rB!#0Q0d;5oA4L_6GbF;=+@&6Z9WDRDJF{B&j39qqLeGvI;~|+Xd&$D-_H;DOFOrX>HUU zjU2_af`gO$pZl+H;6r37+i$lUN$ujRy6k@RLEL;kBaT+aQ^JkrD8cH$up*1#ghvPm zTsGHy6)@P?JX2OvQ_)v?c$k7bnl=#fD;PRAOPd!fo;L7`sdPq5)(<5qV*f5#PwkcjVV}*Rrr|8LtvVyE3WX-V(7sz%%{Wh)2Rl40Tl;t*fy9EOZU{mqcC;GH^V|zO>t1)Wghp{mqE@UB2u8wnhDn^~di&rXfRn!y{sNlw5jjIF4N&3Eq}KE5BqJd&2&` zv~lKTdNH4TJE_#At8R(L=A82{B<(=;1Ic&2_MnCq8lC) zN67>bk0K_H{x=DbIX{^v6nG-aLvArHX3e1O1j>k<({0$xW5=p&{jXU9n$`>-g|}t1 zx!AX7qEuMr$N#s)m5==R2Bu)L&-ArRvZc^*4e!Ac_4d!3-v}_785~qR6#iBI7jU7y zo1Pw!pTeI5DSxr60+dk1#LzL6{#ybBDi7oE(K9`mkII6h2;w?H?3Ei&KDRo2k3C;Q zXKjpKsV#-|1z`BMA~73=3)SF!pY%*(p=#2sb@)3TTj})s+$MH#tSI_C#?d?WEPlch z*LL~x{CX;1UdsGo6E@JIZH0RIFq?P0>7wxX_i?j)xMl|~eB8zmQ?0gdQPeDXLt&(3 z5&tdmc+ZkYH%iFuUeH>*Xu;&^=^;J{*x%cKe0-cb?zObCfJH=1k)&`o2pFXnktsn`?wC0=t+GO}*FxTCD!5=uG=+ZKxcJ*9#LaP;Gvpt9x zIfp?|%~#cNcyikH%W?C1cske~6VskSUP>nZJcSiAWbMymb$sm|Y3-`WxH~^@u!Fr` z-V^E~30wT0Nj0B_WU6uyFr5ctA)||64OEaG(ah~ujrg2B>_d}mNo@u61dR6s+c8#A zOADHdoAWwEK!wQR0Gvgfc%}Hu)k|xFc`$rZ8TEXPU+_4}E4}?ZbgY3$>r~929X1n! zo6n?GrDx4^yo)+YqdWvC&D9Wd&gr(YUJg%6-!fT%V;9rgtaYqh`0}giZRMvL5 z_y3H@Y4^>>=kTz6RJKfV1}uMGRmUZTZFS!?3L+=1CZ2q8#XZ7hvywBD-}CQ;I#}XI zR=||WFVtm7Js*vYictNm78I9Klv3a!m8Xb8LjJJ36ZnJ#j;&y5EOrC=Ssf@z0J!wK zR}VDF(&#i+71p{n?!tXZ(Cw=N_CGt)>&-kpwqYjR16Z>+_%al}egcCiTQNa@T-uX8 zasuN1ChEQyUafm%MAJAsHW!YZm`Mno=BO3a%OtyaTlek9x4h;Ea-{^u?)#|`O%>Bp z!%agNC)AXEdN+@Rj4(Nh$3`g|wfDKD6JdT{f&H?Y@m-C#KWKBHXddnntaJ>$*uLi+t|*8ou}b;bEA? z1Z-$z$HLQyakI!YRPbsTO|mP{XS9eO@3n37N;Ypg6bKf_J31j!q&xuGKQ^1GfwKevtqkI`M zkf)sTi*LM-uhXYtNLbCrC1s__gG@}!lk6BxwVE3HJwCtoyNe9vQAC0RMq(-@nn(|6 zPskz%Ckt@AlhgBX>@!2Ems^KQ{v34RYwW!}{r`kHIon z40_$Jt2Y5e-n>^><8JhA#gCee?sZ%Y0#*5)fmN-6rdkgS9*SS%$~Q{qk6u3dPQV4- zKXR}0g3U~_bDQtm5U34~c+%PtKMXcj+O?hbX41!2WNS6OD=syM=MvoBUKu*5|5gqx zJU}RTAY>)zUZzih;B~td=DZIdK1}b*+@3KM zmA=Jn-*fxi-@z>T!TBMa3eu>Wd5@rfWr#G3PzcxQ_(8Sx!2wANo+k<~63b+bs}4Jh zj7+~pkEw13n}t2-5S=NlbqJjZwN4BnCej}gmXuykVf1sc48JW@7*ooKAo;mMXAM>8 z_QS|5ZO;06W}6h8F8IW|sha5}Fz!Z7eSWlRr@4>r=wf0&i#2u|?>BcH!BIyZwHf2c zEyDdCPmEP}I_tCR{iXq7N)CepVH&^Nt8;O4@!gJsycOHU)UsJKq(oqNF%I}P5cQHx z(+tDn7-9X@h=f}TO50GYu;A<4DPpyF3e5LO5`J9F7}Vp#=ztV z`8U)FV*6u@_6_5O@QQhA z2p^Q8k@v+59(vgv3wm!=z_N?3i_Xm_T|`cF~pedJ@k)P=M<^g z*tlk1=WjcnJNgpc3HfhsJt?Hx-1gU|Rtj;W2eQt6AMY)5niZ6i_H@P(vO{+03s}#* z@ACR1tL6*{4v6ARTdzFKM{{(V?ACD&KJYDbRZ&#c4lRI#^$eQ#OP8s~s6ang`CL_5 zNd>i_n!azDx56-CeZTkCb$HYmynS`^lZ)GB1)xpeg*qfxzBPou?dx|y?dUbogtY}NiaApa-6 z`2>gvALC>07g6Dy=JOHzs;KB_Q@?mUZFQa-fvF47p^K>?UHfgQbt9HFhFGnMW`rB2 z-?q+0vDh2qHva3{=71o_nq7x&qZSgrK-`i``kKSod7|bTKCES<_I|1ZPE%upsW$8E zAWGqscR4qWgbG|j7K3^JB#nBtp5FC%-jc!WK#*n?uiJ8!?M0JoUv<~YuF*~ZeQ7|= z6)$h38#4IUOzE)~%s(InO+rqO@*(gov-c1UHL^cs9dTKp z`OsN~omML0@ijRdhlogHz7aNnICfY&%N5q%s8*94l^GWeNHr@Mkq01+N2*S_9jfEQ z#da~_PJr5DlIOzDc3i#!)9{B3z4g^b$D5HIe=XE-fQeRiORHOmBnkLJujQMl1;Fxe zWxpLot`a1N@l8cwT73*X3a82fO#8znLv<2It(efDR_=ZSyzGBo(>bw zgL6y&Ec>uvn5g%Oyn7rqanXdOcwhbR%eMqfPlqK`^Yz+?TGIW!Os{GB9wB+XVg6nd zM2`?rqJ|aArA80VQ~dKm?<*{19voiYAJz*(u0#ItS1kH3f$4wd!!;T53(}LT4H`4N z&^tCswqja4>;(wT0ALVI8o6v-4164=sWjzxmV{kQl2JP;I_2*jIRjrmXezwn0ff>2 zZ__t=fC~KQkV~w;yLf$&jV#AJW-J)XA6ZBJmvU(Siw&BE*=X4~^XNwYLzljQmK`;L zcg^#T=qM=Mfb498k&AtuqTDUk{uu!zyQuHrmzXGif)|PFlYgyDkC25iPPZ zl-V#V0DB&;QuINHc*Akq^n>G_JAW4AuEezNzm=8l>^*gFW$NI+)FM#ik0MIMRsSf_ z&JJMBn1Kg+B(eu|qTGnj;3@r?aIWUeBPAt;Qa}tKrT$AfkZ0KD{}8uvwmaYpkGL>4 zbPp5H2N=}AtrvyQ(z+(WwM!qMF^$$#iDX}}6h0RwDNC0!{;lo)-(CLy{}wn96mrJB z_}O^cwOTcK>wZJ1q{c2VaeB?dN?Pn8KsR{ftu;4&ubIfM^-rCStvVc^SPg3M7<`BS zCXslLin@q7xZu5*=7iS7%pPHkWeC4wh&MF!GrBgg2J3pqkQY8a>a(b5ZK-~S%4hyC zNo%A%7gm;uQBrzS&~FLmGkQFjS4ZZl*H z{SRCJ&gJ)^6L!S7|I$7*c2hSwAytjA%Tdc`N8IkrA`Qy_tOs0YQt2O6jnvVN{-xFR z|CPG_PZ}XWiJ>J*ufmfcHrsM; zcc))J76<$+{c@aBiII$PDLbj9t$lck7gizoy75w%edf2r+?#o>m5l)JwX`$+DhuU3 z{cb(>G<8IvD$yLix5H$@Qts;N&MqqE<>ILtGg2&@c?@T=lDB!4Y<_D5&4U`|FVLpK}R*u`q#h#rZb|r)(|gc-4d~KNnb%j=;5i`lFIJacCu-tB0kf z{QjrWn;Ui@uy%1V_`KWtasH$Ph8TAVC$q->QBjaG$cUXwPh~OrVnIcaG82VMAHj!^6WRalX~% z(}y<~15KFVQR#KBku{HR>@J;t&mTnsxZ=p`QuEbSKbCJy`hSD}nMVzaj;{M`D^{t# zO!TUXUjnU(wLxt~pqWl8Y8nv%nOyS`CCmodBoLPQ3Oozi6NmN}kBsmXsGjWYJm=o$ z@X7A*n7qpt!x3X(@GUAV+g<$~rAr}h*;>ALVhJD^CR>8+7Fe4+PtjtkGg*6?Z-8M6@G$Jc44O@j0Yz^4N zRcaBx=AREEg${@b)@E$D;t~Fjm7hKn(IWs^jP|*;(L&Zt*!57hoA0=ftnh7x6Kv!Zy0*ZB>OUE zC(Pftc*NXD_rA5l>=h}b12YU<@x$Ae{3OmKXJ+?OjeKE$`F;ANGMV{E0P*FjbGP-o zG4p&NJ-r;C+Y>&Yv#ur-Zi9j;QDZSw@WBsQ&~Mt!4nYWPAdYcYGjvvuRj2KVrmYMd z8p^(cU=^xIEJN$fl@1KT5-$#LTwvRe@=Cbqz0|vRM9*Fre&Bs5p8W;PZdgz=7zahpOWxTon+{n(|V7$w?dzg zxMwn#j+O|#+)ggmM3X4MoBc)<_N8>y`24PHu7mYsQ0bF7f_Dq2o4fmkB?W2jWGJ)` zM)~0)l;cd#G2>>b$!cNVo3%0*@B}pG7WY|_sLzAyOq@SguKgWVR3BH*SRLD0wZ-(f z7;uw)v792`MN^Upaxpl#)$3y~ToVLP2bjc`)+h1RJHT2WJ5NF8wr7bVh^f zRl;_sdM5%sd}aeAk?K!|srERWb`A3au~iI@Amif5h@8!fsooI8)h?gbtq(;CeSZY%iVpyocV=Gpt`6p&8+bw5`(Z z2zU@62G#Wu~UesvX@DZ*r%+&b|zBV<*V2q{)2kBGAi|aqL3fV|b9ooy^L(R^1e@{+| z|4fdL=-vGzpx>y!pW-w1(D9Lc2d0bh4NY-!Rm>&|v*9L)OdNi2`vUAUvx*wyL*GM! z#Mn6-J3MbZf4+yiyD9hbs+okup&LR-)~T`ZUs2?S_|bB)O*2Yco6xM9q9H#Aj9R^r z)l*rutU%*Q))1A+KafIEzw8%B3n1>NC%e}x zaqq*49dV{R)U9cls;sJns?0BEHhV&*4sT*os^mUC0Df^dwzmuV$XqQS+05FlTF?wT|SesxoJIZe4-{+_IwHpW^?Rkh{VVkms& zc{4W4b015{2do}G?nq8?bE=Dn_5lQu8qRZcgrhi$DpHV0PM!-7FX{9JqlEBg%(zeK z-gfiwbZS`*42@~2w1;lNsW*>z!OUD=3G`tbBr;4m%a?peyf7;Q+4=%|G#v5L>>AW;DDjKCh<6z3*J`kv8 zsBf-MQB#zev+0YtnYYd;I*KGQQ5>Zw&%-NU+2b{XF1+(w_n9BhCm=@it9&pY-{Q&y&VfOUwY`ftjOV%*?U=(&XjKQN1>>qC14~5}&x({$fQm(6_q8wQ2)l%;ixi5HEeMK`>uf zTYU5SD<=*6{e90f$9p^CDfv$u&i8f(@<%Oc>9WPR(Fs2(G9;j<%|4=HaO-u7aAqqg z;T7amTAFfj((RP*SK1I8EHpH*)6kR=@{W=uN&F3Chl z89~4NnvKYU6&@RH#)Rc0v-cGd%%#C)+TB9bL=+In2Vn<`Ry9(?QZ%JBe6XG6=28>x zH(mHpB&0^K-uKPr)%z`=1AK664zIakLStiNlB&KOFEn~LJ#OdXjM4~{J2K`9`_CB_ z6}K}aT1G}ro}Pv6FVHmXO`VskYKDSSLc|o=W>v?=_J&7df0$XS=qdJnWwPxn0$5R6KGRiq51liz?D{t4 zA}KM_;8(Lh!BmOey$l;U#eQX#9t<)sAP|ct7)aqgH>b8VgmXk%S2Ta@djIz2$@mSQ zC|-gNqpYO`oi_9f|0fOj%bss(8*=Am5<<|BslIAy^!2HJhlYO)x;ilS`a9IkM+OIP z&=UZ$VPRwS38BsR>E?r~>h9zB>uNFZ{DOjl{CrER<4bqmXf?6CWWXQQb7YSY`1=0* zy12Y_>EZgW&$Ti-dd!_yuQ!kng5_XveAGATa?qp#E?%P78=PjCwqD%o{tW{R)OfnM z=P{WmLJ|Cq&Y*NdE}GbqdP!&&Lq!$EyW`YeQK8GEH%kkN1WBBTPDd}BTe)G(qIn6^ zWP_<`G=Vh9V-GCC-$0XK~JP zvdwXxR0y@HCqhCB;^3q?Q^ZvH=uvXCd_@-xtOQ_6q@<2Sg;Ar`<}a`2=Jn@ekJ%X^ z2sXfD?feItywL}mWHLF}IeFZg25hsp`F~VF9S}1p7s>YFCFJIgdXcX#(=1xYsVTvN z6x5V<>_2<^wUw5#sHK=iMC2(5JfQ-V+PZYV!2y4yn`Ex0$)$j_W?jO0fWC$yLd3Q; zZbRmC6&m;j>*S~M1S@$umB!7zt>5X*XEyHF==DNJO6u!7LIoTCg{a&ay&PQ}DZd8r zAr_@3r)J?Joe}tRB6w~D=t(qN;n9fw1R!h?6;%~caWS4MXAGWdO-;QLJ~7-j)VNzJ zX;ocSRoUb(L|Ef2ydF1Xf!zo6hFw3*l~nTG2^SALFS~eL@p;h?{yGALf=cHy@lI{m zW$yT$y|40NNN`)j5b*F2i;5+t7P9f&NG%?!bAW=%%9;-J_a_eJhjVY&xFQXHV|EI# z?Th5@?)8FP@?i$i9(Iqyv@RBithS`f6?LWBSuCqNcGE-%<;1n?4!C z#xYS*qrs8H2i{Tr{ifWRO{wW6hj=9Zaf2IO@qLE7d<-wX{w?+OYg9y z)4Z{-!LWbF)wGJqt&At5=ZCAHS^;yYy15iO6$6oIZ^yVdX+3*kYz9{;xjAsttuq}q z0>r7QsmdA}GDS0GWmZOpsKdjMWqZv!mDTj1U&F(6=a-3HGafi?Ws#lpHgKn!OY1(q zc!&eN?spNpccnB^x3>r+1m*0;NK^C67~cGg?pZY<-}{djs(5&KY7*Xp%-6140cJEl zE{7PJn4TU^raY3h$l6q+mLk1 zAj!6)DfeV+1~Q;rUh)}ScNEmkOm`+kN)RAJ;)fd9+S1X}`yAE((V0Pg6XdibH+sj1 zhGbccf7|fmG+IEJT3=;K$R#`4eec<{UpA_DD&{JvpH2!&YAJLoxa2(@FlKUlYpqM_ z$L)7^awAn9NB)iuVv-mu}2M{wkYZ2=p{~gf3|b8QB(}SgEnG9Y$Sc zW##x3!kofV6laD9HSghy2V+2*s;VMHtC@CLPc7CgzxnT%mRd3D!OqPptTZ?sL!BOc zdG@4Z26Rg9D?VgH#tsXtc4!dlktSj^Z zM7M%QC9l|n6XtkrTD#y+YGZTS*Eex>4d>$A?{)g#(a^vLNKd=r{ElbDg#}Ku6yBMI z^zwW*sp^T%p7KndPmN7(Nt05vv{sV{FkqlvbXD_}lM`ZqK2BQ^o2>N zd;7_I*Cc4DsmHu@ntfj_!TpK04)+T_1J+DQcnLu5tLdxy*?M5l7|m$8hAheffzoi& zrq7F37#h&Iiu8n~1Jy(#!=qXfy+h@S0A?WOHtDm^6koku6jK-yQrIHKS|q<9FCo*B z^4)=v-Y7F2F0${40DQxnRqVo3Ln@;C>*v?61GqMorAtlc_R?0`wtD_0LwLf0B_#fV zjY?`b=*ZZ|4GVySa&cLSPGoCMw@3MH2f{Sy%aw^@+;4R>EaIv z?eA`n$1_&JQ+Dt28rT_i5#eB>TOCLhb#><&Vx6$R%741M;g^*Er1c)+wWJcFD=lK; z(0La`y_kt5Wl^v%mwCMT+uq3ym(v%|^`5`oeQI#iK4@hFZk?M|lMx4J?s5EV4IeR7 zSyfk>g8CN%?w=3@Lg${4duUXcGSw6XQV5QS&x+cO)C$+y5GQAeQ+#B|kPi0FGjns7 z7Z0ftM9wZ#ncu6@`KTZoZw7r4gH41kTPOe_snG{V_kOUl#VS!!CMJWpiXhuTh`)iyT1B;&`uhxKFUDwYUZNq^&Ku|)Salw%(@; z*qB#5fwRdP;Z615Q%0h}BjWgKpTpLwwlZZjSLY)k1ELB;esC^LPfr_(S>4(T5@n;O zZQxiVxMTTwFnX33+jryIA#QfX6oS>95la?zS(sZpPS%L>bjwiG0m4UoAGcfwjl`em zL}vS8@ak{`;_;-Is_cM|Q9TTv@Z`)Ys_=}MNJL7i)DN4wQT3i$Kp|KNoklGf@n`Cx z`~vQ^EMTod^?f*yq(4IIOGR})HBDC#8#HS8NZ0a`w`u=5zC-AzVBnqR;;+~+AtEH0 zo}H1%!kr|q9D{{W`1oDN<}vyTxUME=2Zy+N=6c5QR_-=;twbV-yhFZR7@T@APAplb zw6APFJLUnTxrAOKXn=%i(D;F?{R5ZOTjcu(p=VfG+u{t7TcUqpM7({z5W@yjq2&VV z?++yO@r0-Q>kHz4E`1@=XHvR|1a(2TGlH|3PXfjIh=B9=#D^|W2n|+|N+bs<`2X|C zR5zW-d$teHq9i`_FD5C*QTiZQXl84Tr#E?unjE%**)TyCJ0@MGEWh1Fdi}&6NTd&n z|9Ahd6!5VO8{Z@{nU|9eduJ`kY(b@3TjFk93kqjaRF-g2!WXhTD zy^u4Zw3f?Io!L_Qq{d%ZDUQ_U0Se}DHe7IcdS9rjPoWCvC$9Nm_PsYaWhI{2_MNh> zJMB?dcfxGJ!{k`PPzDSdKx%NG*Db*!kDg2A4-pZ7tB{=Cvi~_G=CxXcl<6lvS_Ndz zR6C`So@Q`#=({(=*aoEkq4>{XNO27kDbpB9G)I972nhh3#i`INe}jjCi-6^V6u(h@ zK_h}i`taZA-zjX^-0Ye}3#0*uPv`52N$ti6%Sd=Pd3ge^j*f;1(6w2$RbsOxdi0vu z-c-zyw2#_| z47(=$`O2aG5<2k%XSDt;`ZUAo0GDl+{w;zrU)xmZU1LVT3+7eRks1Oreb)P~-BZ@#da4HlWlA|MYBZRhi4J9mJY7XfP^|kynW^6B+{v!&P@1Gf8l*%=f22F{PMM)w=(87yd zP^Y8{X!uS&H?S3@o@8?rBt+KM*1{>}kQF_bZ&4j;I%(Cb50N0FOSD84U57W{l%<;K z(|519kZ-Y^O9q~^GR=zc_>+D#IL~n|I$Mocb6D|k^YUI^tV|L39w}|Dm-TU{>==K;lvYxWdJ&6QJf{;Tm>iI9EV@AcmG zmyu}DZk+5)vB4#&0(_M`C_tOLI|;S! zm9jmWwG3wXoliRi;U87UiYxd}|2lw|5P5XTp+4l)G|GR-K^_qoS5H-GGNAB z+LAhHLhJ)VXOx*+UzM?RGrdtXF}5@Q`>5=0s2H7lT}(Q>XOElf`BPeU_7@@zLcE*K zg5c;carDFA*Lo=>Ca$lWLL>UKKXQc}(dJ7@3i=dSk774gU^-JCTTw^T9W`V*}r+q8y<T$JS+y6ECt83mG9 zD;R6zq9L^F&vW1S=r!6;5e0{M^D*sS>PF6#?-j~bd?%Iaa^>6XElDr2s6f^HRLhge zkI_e%$0!cJIk%enV0o5btW@H7Z=b!t+dxC~g(2DYZ61T<>hhXBUG|o};Vg@Qer&7^ z9DLDvc(}P|dzY87syT9>77cbOT|TSF=j^EU`FX=g9f>WFZO%4f#F(5B)@b5AirrfN z-QfJhD6RGBv#%{RZvk|{ER<*#4dmg>JU5nFP8ec_a3VE@6L&awp>k7D%jaJM>(OWu-UZ^W8JF)b;^%ADI&8rlwsv*Fx%RCY>{9V5GrVY3)hF!i_3uM~Uj zoBG}(uQzTJToS0$J69H^C8b&HluIKcBlb^hBg;Fe6qDpgJJX)@4rh|6>OHfv5l_~B zHPI$ek3GUkg^lx#-_to0_0ssv-rCbjOMmNnaqN0arF@O0x(hRmEiO7o-nFUG$WY~{ z$AGipR`szteSN;~VtA~*9nXYA*nfNDCZGNVExHp}rQP1erHz9o;w3_L zgK_JJElh?oMFH88dgkK7T|O67wtep65@Vf~_TG9mx1K;=#rO#Zp}+_zd=ML-UfQUb z(MW}MD>jTXR)CJy)t?&7G{*b0CT@*du2X!WK~tYj{NUlhf$6=A0%}XCC?(dRjg4$1 z6tYC07s2`HW50Jd87AEiEgi0>^p5il>EL1fkwm4@k$f&&#->kNW?cv`ZL z()yD7xByeyT#)L?z1Kf|pfrvrQ2TmX9Bs0Hs8J=d^(|i%_d!~Rtu@KlsV5nr?tJc= z7mC?L779;vj37bTtKv|7I2+$CTk1F#4-a?ky6!;sqXpY+YP8wRe0kw@+zPGVz_`FT zy9iD4A@=zcGpAYrMd2qA8@hDey$6jrNZF{hL8kmeB_pGeF>U2-7d}5KpAX>vbCv~( z#bLQ55fQ~j>LMu}EeQf)#f7C$n}JSNrKQi`rZ=>q&o}dHiOkv-+knrR<9>S$M`PKwt(SIsQ|!do zyKu>&;7>?N7gh4r8@o-pN7wF`rpM?I%AeV9MZfpL|;X*i>@+=MB9~!DoSaO3N zDJ(QFCHarWc63NI%p~L4{}hnfk{pVtPQcw>@%59uCq`s&RWORsH0wOiGvp>BJsTDp z4Z3{Js(6B!(--~mTDl&lPD6*@-f(>UQ$ZGNT_BRpjMgS0W6i^`CXllVnz##Jz(GNO zyh)n>JphS?U9ZV{7nb{zAOl5+W?IQc6aA@1-<=Vk+0Ii~Z)&iMkNO3wQ1kM+ME;O@ zaod9#De+F;==xetdZRZBH&&H^$KbI%c+SGtGiY?^j;GuBLQ1K`#R>V7eQ|(6WA9Fc z%L&DeSk#N8CAZSF(QPcL=EC+vhcS5!!kiq+Ng`c@VB(R>@J&P~QEAk!Z zs=nWBE!Nmc2P&k=lZhDhtz69th|u5Y$YVO0eCL;K?(7q-vQsQh^5_e8#T9IDr~yuX zDkvNvDN?x=h0(+qKpI%C_2{-yb2|Ru_BFByT$^W)W-u|bfXGU}T;&y+7#rS&6Mtni z{uWU5GMDwWbKf=f7P=Z7jUE=`^e5*|)^55eBg zEwPg;;s^N5a#`Qof0FRH8B-^D9j~w8qQS!A{}56{zTJtSf^2Ei+1ED9hp`Y!i=+6@ zVQ6kTD55x0P2}Go{#YTKW;6dS&4>R#CeIWl_>|uw&vi9LC3{qM5TrFNRl0h$s-Ow7 z2(f`QI2BDT3`4PkeG>x}ICuawjh2I;gJ6UfXEhyz3Y|v0r~)K)Ei{!OvcgZAXQeyx z7I~IYG$9tqO|6csjRC^cL{`>N-VL6O_Ec6>bCDe6U@J0JX86cL_|E3%Uz1h_2ZciMoG-rJ zt?}@*x%9OExE}f#lS@ce1et*-ltL8uskgWH;3-<4gd||il^YYiW4U$-*=K*7oE2z^ zq({uC;`;jffGxJsFn-UZLP5o<($cqU6XgBj{S8L_x1q0-z-Jz3gkWfVGvm`Io&L49t|zT&;&kqk5($xX2C=YhnVn8!0VN#`SUUcKy+b^RxNpmP$!z0Ia?x zt7?4T%?;&e&6^cFx6!fh=1SPw9ClSzm{gBYM~EPWjmc_*zz&M!8uzIPph3;`*DW?u z&d$z+JADf&BC&5;#>aVRY2J=*L2z^v*~e9Q-aUNH*JRgp@ANrf=Ddktfy*iqy_| zk9+&$y1f|}KZj`;7&PlV^S&2$ZsMU55^kKG*;3wc>wY<2v z+A|s-^lN_J^Vae%lJFB=40M-4gZ1SRyK7C&CBfPHf$t&^_@<+SPfpfbq7qS7mY1Io z*@ph@+l=6dI$c9!&G6tLZ}mG9=x0rh#dYDS-Fnig{Zb{juu1H_|Kg&%GiwJKIiLN; zA-nI3A1~jUSS-QmPCY9ttG1qAj0D+w2X5$_cuAFh*VO!!_YIXzQTl#w_{OR8hNAvP zwMU|`iwgqiXJO&p-RTdYtBZ?2r?Q&aBUBX>eBj~Pl=*BSQpoJ&Llh8&an%=)Eeci? zc%rsU*PxY=kbvQG%qf`Q_wx({!eoS$k56%ObUipYShYM~oto-aW6Q2T#|6feh{&o& z^W?1WabduIFs|R?{Pc8yj1#xVR#a_mLQzqASXkIdj4nV7S6Ukm8!f-f-^u0W8T}z* zBJJ^=`CJ!AQy(mAwVxyXZlvG;KpcGiPE+W0SzMh+!6Iw6| zjT&|5`*?bQ?8hyvE-TwmP(aT6(l5B-qox+grQapV#npORW`~4H7+DD>Ba4~AjZH-< zurxc0WdlLbrXwp0_?@nIm5G#^dV3q1n3(i7c!gj(^WK)SdroyNA`})bDTItloEC#C03e5z@eDpRd$rH@|W^ zjG6fekAUFn(Fz7KHW{!3n(Stub`F~+g)#U-+KVhLJ)M*^@9t#D#L5f-G&wiNqW3j5 z?P+n)oB&vMx2&1)Wdwb3adAL;&}=*$Q)v$mHZqCrS!6`B-8K ziU_B6@Z-0T3mg;>C`^rZ3kXgm=pfNZ4A0X$YHDg#Wo7(gbF$ev zGr4pQa)Ebjr37OWlQ5C3nG78t2r)~o)`$p4Ez74;)y7m!t_@!vgRS24yHmcwI=bAI zK<}0pNA{PLvdwRS0JX=oIsPPpaAcv1*qBmfKDnKnO~4BEFv$NPigeN%wA~^d6%_5Q zs;8!=y+Xre%l)ezJZa)6%F0HBg$*V~jW(UH(^6AQNlPCePgR8kH8i;a{!Y`_Z1tpG zrNmDOoQ!(y#x)wi;F8ZWc0ja0VVuxwr^0hjp~hr2ExtJul0|<+Z2S2$PK1Pz?`XpI z!_V^at<#kz^Lss5SiN%HwuEaGXc*)Mm->V=fiL4x5D*i<0HL9gla})Qb9B^us6$0g zzk7BTeCwxp0o+SPO-sVyT>Od4TL<61(4n$3T_UvC%cOiN5mP2`n-Xz8grY;MV~G@czC9u5tU7P2}!43ofP zUGL#8FIWD-i`WPa-Kf^9IZ~T#xVnPPBLAYJgIC0+)9Kw%TKXh)@p#_(jIqW`@Ddcx zNa9-%o!$KNA5DE~Vmd4ahg>M9*v#1Yd#7(+l{^$kq4-EhNa+5Y5|fwF-gz~`6%z6{ zQDUgJ_L5tWl$2ydL1m&p1tEk}=;9-(KkEah-)xP%` zx;Q(-MurioVStE8NTOuKlTuQY6%}J*rLC>at!->rIhcU}NkB0&>g}yYV9@SVk(2~m zB66sHhYLLB!d`@8IWQ+ig0H0eosdl?f+NQbW3(bD8kBt}QQuTYP71t|17u)ekRMNv zU|7W_7W)>$I?#M?_FaPx<8Ha9=UGmsJSJvuwnX`djH#R)Lo4|gj5GX%IEC}LufMRA z7MHcWJlfpc+;ADI%S+3JdILz2WMr)c<3A#!$sHM{PH^q>yX}v!^# zUmxMreNE2kiSdE+T@#?bk>+`DFF##6geUG&T+@L)6!`ZU4h=>LxSptp z1cg*z2>3iOEBpvZDq4TdJx-7ide{QMk9vY;?G8zW%ntM-n;+kNcIPY7<9gy^V&+r7 z)d>la$;!em!^Kw0-NnWO@&_EWH zSV}zhM2lZTPI)=r3^In)aDuZh16o7yU`P z*RE?#P(9#_*hiG`oob)R^fEI*$S&30e!zr|`3Whr2I#VPcXtKSn3|gOm1Sj3^%}0% zrb!<~eH2XiUki;UTXfaLtB$cW zK$lzc`;|U`D3;568JOKngfz%R?8xa|{*}pjWO#T8K(6YiyJG=8J>95RMNq5UcHaNI z7I6)rOO*jU(L8mZ#I&@eq$6AH&bvcDDMv;`xOuowq+88TP7XH2WUS`TipSQ~IX+>i zGr+^&czXV*WM~8MJ0G@VDWx%1n$K^J79c=QPBRhlF|$;oEZ;S6`SI8><)^ zqNtm7i^Dw{A~QvXB+2=>gf?D&ovcquNSK|P;(pkUhZ>@8X?Yx%J2UDJBknqyO{wa7 z^DJtUHa}pOj@;c?Dd+O+)fW=NdnC}6kzwO|l~h!809p*t!VYkd1|@3kb4mh!&l(NL zF{h5^5ZHO#VKTV@LcXElCYF##Ra5i!NYw#IRcPEI2~I7o1q-sjzxS$=-pD{`{lG*?8^wrjIy2ZT zwoFakDNLw#*(oDL<;_-d6{fVi)f(`(iV={guP`aFmL7J=tz)4;^cH%kDK_3zDmDLcQS&Ry{zf*;p4eFySf4cCX2`K zV@qP9mAlnKrHV?%9Tj=B2n9aZ6X_K$Fdt%&9h=gW5}SHxC@Bd8Cw)DVA{2-IT)Dmy zz#v2vFv%GlCX$;t!{Oys1Wce{V3@u@PP?IhIndpqrUFw|7j#Gq4IN2k-5<~HA|oL& zG_*7ZU@F6Esn8Itj!nS81S#bpi_0c5c-&m2X}vg}uh6B-tSl?_5bo~<=xMl@`%K!p zt@+j?#F*JKDx_!DcWcaM_HGdowd0^jc!vg+R5N3E?>mb^C5sN>wEzon2;gskUAVQi zC~!ea!wtCBUtaAxDHq9g|1|+?9F45ZGLw_*+$O--*;PF}xH7JKl>z2Une|szPM!sU z(E`3j{zPo5n0Zwnwpjmg=aO9-pru9HgYp4nd+4Qe#_`1pRro}Qclq79$NmCmh; ze`;xoda&YytgIiP>At|#-M$izM#{^|Rsaj4ag#&~+0Teoz zG1+>6TG|(OIHLKssl@L0eZI1X9@2OT@FyriF}Oz-WZpM{9-oYK$Zgjp`N?$?DC+gIaRw+dmMni5ozTB7&(^Pf%p_7`g) z!5lp_wprTpoXhTU>1Bgm+8sN0oIkut@o$9>IcIM~#Om?NILwnAlGGh``8$7-0~am{ z+X)D6M}%)?X3irAK2_GQKc6j^i3}65T%NwRtvtJ}vHuT1nwx2)in6PR+bxsjgcZ54jJKlwTHc@YKry>Jh-vw`5%B-TAy(bOuhGH?}`VGETAPh8anFs)@GT z`DV=7R9UUB^DkVTsVd={sC{F+3f=7~t(jTXma4MpCBr%mjW%ULv_sy=jSxYypeo#b z8tpT;wo?kZ>6g38*Y0OAQAwnrH38PBn?hN%qOLx!0%V~uUO0~&15Qu+OQbbVYdg;I<*6<%>AK`!l?1{e> zZ_R7CTTAch^k`Zy-;>Xo_3*4xonEu^>!o3%VGH-zE(J1EXTLu@nBH-83F>0Tm!CWx=g}q*ph4A%gw&{KI|snidtiZ(Q@Oka1w_D$54?Qg=8B~ z5YqIq4k-6^1FTvc`;4H#@veDaZz7vC*<`4^?K;^!`9QLEZDQftj9A1oQ5xHvH9zG- zkFN}^D725O2B@$@{SaBWWJ1aU_TMbUEwhk4&y1|2T{5}=7aqqbdrVY2^gB;~m-{|i zFQtA>X%@L%+0iBp^om=K-1_G`%nox@n_SsY4zT};Zgj&<{DkSXK`=j?T-kNUw?r27 zCFcuBG2ZHDuH&^99Qv!|Ll(t7yDltwMEqc+lN)-+5e7Oxz~2;m+`O*3!#b zG_r{sJUM1r94)SFSoMnpxa6Qswi&AHudvt*WInRTbxfCYyNZsNz;=)M=Zc0d_Mf!J z52=;$CDhNI0wT7t7L%|c?Kq3LzRrzY|^jfGlR z35<>o(bH8TYk49QaJ1If%QOpb`1yHz9?=C&hNF5+6z0PiET+L}I~iCpSdYCHHSU4? z#|FH>gi-_wmdzYDD9wvQe?l{i4;AxT`8hX5SNkJc_)bJb0g`HqnF_p!ISoB9?ThSB zin26NV8HJ(&PG3%%F?VVynfsfI1}^+dgvaMybu^&cP+Z_ZF)C<(MEr#Au zw}QmH*qPz;RK#r8Gq8DIDwjZ1zfI8n6S0bi3MoJ!CaOVtx|$Y+V|i5{D_eu`Ok`kj zy|O3A@Ne11-=6A9L$uyL=4^}lF;=ztBh_B#;tlMcEMa3{XzA)YJsjJmFg~Al`Vfi@ zPzAewI}SL`a&c`CNZoseqUw`~B=%XBI%)GaelAs`bX5(2ie>#- z-}#b}u$0EDk$2A9uk_RtU1)GT(h;x8?Hmd@-T;V#93Eb-wU}x1;$J6c3n0mmLOv=q zRn;XGqWbEL7P9STJLkf&(Jhg|dN~4DUKFZs|JBDK)lMX=^|GMvfVHD@H)JpO2aNxoS*N!-Y&{K<=|w>NY&}6iiQ5? zqT1fHvoRtkl0;M}YJZos<&o#gZpd=x#T@c#Y@rsrk8MEumG z3GT3irq50OSg@9#3OYNxxcsuMO_BsTODY|=SZW3fVDqsGQSIk-_zinjQ4%`yp6mPG zL%qS~thMo{J>A^o_ZA7P-S;I8&77@Tp!S1AKYt^^;%q$l#VNk-dA`?23!O8w#3jzs z_~*03^;R+|w)SVZA{#4#8?pHc>AtAmih~h531pk1!b-VQplm?PtPjl3tM6cjo1A&P zKX&IdXf8LpDyM87@SN{=HtCW%II*yU`Ty!B30eAZh70-clyOr7mLiNvdNq;GP?5nS zzTXTM>&+6YbZG^lGX?akfyQTK)P8Bo)IPR6UiZGX2~zO&H89=VBbUZFeOQ@)3h6JG zJtqlT_q9@%iMl#)(~phup`o>kWWxHj+3nKBZPuh6|>JUL2T2)Kl6(73uQL3C2@wa-0VF50J2@A-*WWt%u|hsX zhhHMVT|!^rvXjSSL=MaCro3xlv2lc;Fqg0P49!ACu+1Zgu%Rf?U{sfa#Bp!yMQf5oP z`@!jD#3Buk`*!6AG5#)8D+9pfWcE58wm%wReRBc{hxu*SJfE-2k2ilfEDb4iY7-zA z9d+{4Ax)49!q_=Gw&8TaWFWZc#y#q-2K(q{y&MuKNS{l{m~UQkc0pJ!5>ARaxfSM`}mw&xFroObHr& zyZ2?MFa#a~*7$@QOh9dA&!R&8yTnsr1LOG`&38%KYd?(Nuix}}jw%(6@rNBY(~)R( z_=%dW?)BxfhdSJ;-^XsP^z<7lflgB?JRw~a9UTFB&pMI+29CBF7Quv#kVip&k?oY2 zYK)bGiNj7_a+hKSKN6FcVSdDtl=af4Zck*kc`{4(y(JO8!nQpc$+F5O$@3bj^+#05 z#ZGtyd&3n-z<}3G85IP=q9daTR3Fb~qvw}lFyUKUvbZ#$-ItS5`3QH)hb2JluriOo zyPJ#=Sx|gHnC;W(_YwrS8UTJBf775Dh~6NVhXJBVL(eU*wDUgmHvY|@b&C?#?G?!5 zd=Bu{fg6^KIl_Q4rM@^V%`^T;cNoJEZ&-jMe3l* zTh+laPa=Uw~$mljUagj*mNeZ@ysbmqr0=2@EtOA_;0<2w%0>*@|5iu-N-rezX55 zNh3L$E@0LdQ6NP6pY(qG;G~unF)Kda(#$ai_dK1!^8HOsP4)F^N$Lc=?#0ayM{kS* zg3#n-{U$b^ZfEV9f`VY$O{ZZoF#uQ|AcWS3AGTMy4oSrjCl=$Drlx9~)bF-Z)Lxzz zMwGLBOpj)VK0F5F4frFwAd*HPld<4pBU?>c^hL=)=V|(BnQ`E_93k#TnK5N-fXB6- zCC|E4L7#Ro;WR}3IK`HN<|ZkhbFg|M*kEB@^2>d_q=(Kylns?Cu(Y&XfA0f}5mr=0 z9&6IRJAH01EnOZNIX>>$&}v||TR*|Xq|>eQ>>&B|e&9!ln)Olia}?Cj+1?4kz%1bPOT zuz5rr8dt0SzQq9gh+im@=apo3jggVS@RG%vH;>ny)9wQ8cZNq*vmy=}8j|NKzfDS2 z3)bP`;S|Pq8*yj(uc*T>3devRk;(m5-= zx#L^96&`u54ge5atzy=)0Yy?iJS_#ItNEbdgJpvj#j!3M#Ah)301}BbgLsM2qnpzt zk(X~!XCZPM3@CN*v=kD{qT?Iq>aw=Bw)!US|K_2 zzAq)Ap`j@$MHi4%zhTe~nC*47@OvTzWg%2h|B2@M^-iB@$%iy>*~u`AQQtC|mCqmI z59h*yxm=eed?hX`v72Q&zF1<_QS{n*Fx!yEm8WvH)IpzeRumcuB(GZpGAdEAu;eyB zXnC*p_6AXFH`z{%u7b2-@C<3Yd#HpKa=_RTA^?>RlPqM@N6JjV(h(~};3piw4HJk? zA-??VNg%RF*y6+-(u8G>vkPgREnE6u*1G4`x8C9&jcDBbrsBj(%zEEOYB)a9d z_wO{ltv`{`uZ)EoMUe96@jf?*DUrm~Ri7yZ#g#TJtr{Rj@}AwhW=!SJ9IlLIDDLf! zwMyI6xk8O{3plbHU==DnY@ma0eh#oFkV0Pbn$;DT1%bX+6WuGat+(5rOgpXS>0Jm%A!X ze6RTHd^FzI>~9v*)-Yrr>wkX8)DmF;Cc?C0WI4;%_hW@z*_87kd*(96@!<=kpdwmN zm}cq?Ob9w@P&}Hj5{Y;Q=O<)#fBTSHdjcio$~?dv`TL1QCEFPylHc?8V1XZ?4(WrL zwq}{6%Uyb|oJA(Hc|`_~a|tQ0Lp9AL6#Mr>4_&|CtKB%;WFZvMzHKk|GfOJWcD`@d z2qH}jl$02KA~8|mgr1d|8M?@9b0j6h;Ggn#tc1@cg3UDxC}!SI-8Z^qL)>A3;+Z+4a z$~X?gUFgWj$R4RJq=En2*0T`{5B%Q$`@K&HfYTa%54CmYY{z{Iuyz06BkiXA0?eV6 z+fk^wh-LokOP}75Y?jY1ZqTYkq{gfLtd|+|{QnEY-vN)HbB)g0X=guee1el-oi3gF zi&pJ$`ufFkzU*>RsVqqX&B*PZ>%9#}dIiVAX=r6B@5BXfUj05c zu}sg~<(uiVeVeXb0wDPP|U~ zw)ZQn;zJn8?{#EnPq1eCEtB0#>8Cox_~MCEe>Ql8$`JM*>I96WSnBj=Uh*1##mj0> z=)}e6#4_35WA8~hB}(NxClU>3W>f0TCd(|aWo|K|9gMayUA|wl|63QMiOO52gTT)d zWvEDRr=8@uVxS1MZXMW#h&>|D=gsdBy_50MQ=Kj?)X``P_EH8W44DK0FMw1Hs15&# zr~c@ug+0CFXQJ2-PD>4Z(YC&KCLO5IgGceAV1@C~m{vQP9>;hsV{C)iXmWk|J74>9 zes7EP$vS@T&v(2&W__32d}G*NpoSZfiRy+P8|NhYAN6(*N0eC-|WhWwpb)-Zg877fV_X z7wZq~wYw9AM?07Lj!ypNW!rv!rD``Ah-_Ne_Gb3Fh%}On{7+{8R_18L0-M@eM4+%l z^R6-^Yx7y>9pnl)feB2el7iU?q!K^rR@*@ok%!^Lhn?~lLuak*)l2I}&9 zU35|Gn_6^+z4j^;2C_DolsR6b0)2=2e_}^ij66iRZrd?v0r+PBEA~e+u z2vT4Dz}fGy8W?-TsmCIBQz)@(tgEhfH2bK&9JA=DkvC8}<+e0t;`iV=d-#RRrDWEs zWcICoAigD<3v2kQ8F8hSRz4}(2U}nr1WoP=)8XYx`6A! zyka%a5_SE}ap%fF3SbrsOVcDv?#+NKVPv7_jBGyV8+E?q7m!xtI(Lkmu^FriH{9A8 z*TKyddem;b{IeR}4`|3Ew&*!S24w0j)9&nDiXk{3b$RfJdSOb}ZIj0LPC;NW1nyW9 z5A_Lb&L5u*x#CjAt6NBZ_Uy(*D1A3W_l3LfTT$mtJJmWZ$1ATnchNl2$cwU&zq()t zxN&>Q#AzHid3Q#b-;taV^d0I~lt3t-3ChtQc5+Kwbbg_xre-QQGTV76Ixb+y)s>ZU zTBolr4JC)BeKKq}!Zp<+-|W@gi3verLdteK$VXsmPbd}g`WKIvSKRO`yWTS+1?8sg z?oVGC1i3JyH)~VqM_$G8_yH?9qF6x7P#bkRS;QE1`)^T9k7W@A)p1kP3!17xyF9f* zapv=Sa`hQdgPvhq+gxMWM!KACOg3w*Zl`78Qg{3*Dkkb*>cNB-sgmKnPENl?-tjO} zw0vFHCUEQH_*#arB#I&0cF5T;{wwBwkKZ%T**(Y`GY1pU`58mjqe#lOjPnmGD=X0o z(xQDcGuAGbn3#w&J|%Wgrjd(eIb!Lz9$-E9L;IX zzCAs{M}ePGDZBZj_%Ja0!XL4kPHl)XrbvntHRWGm*VwW?=r_Wg3gog%d?FnDC|Zg$ zwkD)~v#I@#wt2mngj_Jlz#x7a<6OItm?-ChICExOA=5aV&-cuke82-QW=24`?`!&nB|PZ&VL-QXUf`X zn8rBN=vq>7B3dTvJdS+z_sF#J2A%sBOQk`>!(R6O{(Ck@dbu3A(FnvCXNqzqT~t01 zz14=7PAkXcZ2L`~6y-~$`8U2uto~P*5p7=Sq{EW!w|omVmzsX5-{gD|MhT0w(7hi) z19DK>7O-M>mSP(A@?!7bgODhdMF3z%U&r^wGyI#vWd`_N~-qY)Wr z^ls}K0zW%TF*%pp&goufCP3}z;E~KfyG#@I1*0nPDJjQUA}yiSl6XuL`TRlb86t4n zIco@rKQKA#`j4moh!>0a~?$o7E5sE3~?n)c#u+SlSI{4 z?0N^t!-L_kyn|npeD$3FKhezpR9OCh$c4WYwoow{u^3-lYYKzGte0w&li}wgz)Z1f zCO&2*!+go^_7$_vHSjm(yABEjn?U?Wk)tZ~YWCXx^tT!^B|T7G9Ui)F0;w85ADz{k zFFXZadmk8bO`zeKX<75mQrm!WGUPH=$qn9nb4!c9Ax{VK9%r&!KGEeRvm~OOsxHz-W>sZCX;dnLz zK*7?$y}UCrT;h?eurHyVaOL_0`tuxVfxwEWG$}O+R?yBWG0BW+x3P}mOV0ORbc|zJ z(QDIBe>XRyFh`sS2{-R`chMH&gz9c&!q$9h%m~Gs{JU~pkrq*5phf`tK~+^wWmp-am*}klHXn!;izh(Nk9$ zpvN7UX?0288OTorjNH9XXMl8hM;DS$-#4L4Pz&X|%|{x+LmBq)zFC>eu+a(flkx^= ztT>Iqs~Y zvl;Ly9w#lV01w*qa196y;Gyew8P$}rdP0PmPn^lx*vgy?*~LcbjSP(f+FT#+;iKXT z;Tk&EG|3)C%RWxsRq=_j3mKZ=Pd!K6Y*2yg85?h%I5)I>mFomTy{N4>Z&PV3~qQA7xZ?ba`RVK;H;YlgSCgxWt&k>S( zd^I#RdshzI3b?krFIXoh8{)25>(9)&?*~t&i%V}g1tMJBy5{Oy+8HCt6;8B0q_=1uDXtL{8nwKVp-1+9GmAOM z7ijn_lKMR^K#sfEhas`6sH{xCn6>;?RW~Z67IxtJ{$Mqbe~D-%?;jM@Wfxgm$`y3* zjw3wy$gn~2Rea(qd$_>X1yZ52y0R&+=Vft5v@gJGx~T+)K6P;WK*;%Sm(N z^`k@qUrIY$v6jaym}=?3rt!V%Erkt#T{_h>5$;0bSUQFtLBW|EN}^L5kRlxw>0eH# z$wA5*8gCO87SI59a}QV7%#@V(^W03LHvXfky*5O&_AFUgi2>%0t8;@du67QX)zZ`? zKUU9SG)v1y*MNqtNpD*Sg@|p87gC#+88IPYU3N6e+B%&wo0+xl)1gB1O(i&iCwD?U zpgZx(pjy}Q0r!GlPwLrui>EVJ;sy%_U?lC`&SH_`+Pg@5fs_XiEL3uPyUs==wA&Ef zFb=v+HcCoLZc$$gI9RFMI?EaUvY}T~`|-3;#q+E$Zd?;GO$~jG%Zz9dZXOT(5gB|7^sD@nsu4%RpZrXK=V%i}E#ild zM7ByQDD_~gY0175Gaio&G88WzgYAQ%}I>{o4-tYc1ejS{F6FY*DQQ|M>xtdS0fP8@c)T-)q-wE{RfPq9~y1ozhwzfRn zr(W)3g5;Q)OTxkeL)5nhW(XjCZ-RO6;-jqC8}&`q%tgJugBIqeSXfw?rCgmrYE zAjWu}nHiTf%TZe^b*oU9N_lB%$^M1P*4-c99Pz#*G1Q#l&~~NW)#;vY85Wus;g~}H zL9c@F$4Ccwvp#4)VtIY8C&B`kdMG0?n+pTuFnuC+M+{&2fY5&YRWnA2ZHgY^ME-ntb&Qsqc0RUJrrT&VQ zg0=o4+=w?qZBspb7b_h)xtMONk~5chc4&O%TAXP*?rfrNImrRw={SDW72A?+w~Z9hwkIv;uy$cvx@Me(R6v1|TsFBc%spi9_G z^wI4$m0W^rn)9x6r4{CL%^FnUN{mH{PWe7X+MDd(Kn;GuYr&)0mRv>gF77eq&o+{2 zh0CkiHPv&GSl;g^4?LhMYpSz%?=c5PxjxQc6hU{}EClniYyM(uTJ|!_N2aXys@WY{ z7uwU-WZy>-!$<*}!L^K6&64&-R<<|f2CeDRdky4D-e~0AZ4q#@JpaO#KQ_^Co&b)K zDUM4JF+e$f2PTnN_x=#YYWJMUvnc$c1K5JJV6bIyAum9P{l1YP5wjSl=ydwQVMj-D z4T*Tw%3>Tetw@IhH6E`RTSGfxUj*d zeQ8yk}_<7m2HFDJHH_Yh9+0a#2c| z05jk`O%1K7pl{#XssloARqlJbzrQ^FEK)hviE`8DkoU)3nfn6BN}8HCI)`Y+ruQ@K zNN>h}zNc=6;R$BRLjmHAY3pb3Xs+|Yd)vRO(dro$5{z`7uTzPQ>#@0dOw{H60-X7U zAu?wW$-CR-rdH3^(c&I!L9U;&6XQ!m4_e15APKCUVk90v~!#9}xc zF~Ph247w|CmS^ODPzdG}LdgUN;uU|EA$#E4yxW`QznUK52$$J?zlcSxzy0v(e?;*UKPAWX4LFf(8jhgHjZVwh5M)kXDnpd zTRvlQtD&#S#3~;Z>lCZ7U11J+4)&;zr2{eEJGeOvD7Hf zRo$Sj1IoHJg{g9Q!tBn0N8(^%bcILD{`P&J0Ep2R1?UFpaDH9 z0vh~z*q+W!64=WiQ9{o>H_>kcNT>#9?Y2gT&Jz>_;TTn-YJ zlGEHIlRQU1-}&8j8nlu`8=ukKD&B#y5n#HNgJkY-2Zzv>h_%st1sJ#`4GnDmxE(ht zYq{o64D`}gfR#&A?A?V%3bT>ZM-oS&r6s~PMRl8yQtRb|)}!k4jW`$<5#qD#NA|sC zCH&9Of?M=a$yq2>=4cxNPWWK8^YH~yDN%y}qbprvs8$iyhdIpiwuXSzRI7Gpa%B}z zVR{tv1puGB!Bo*pke9cm*VpS+cpBhnC-W`VXf7S&o0iQ)7#qAhlJN04WFa&gYhCs$ z$~MOS7NBvb=S6Yi74pjSm53W>^M5}=lyd%P8?^G4C_}7$;+!>8ylNsHYB0Z^UsL7N zUY*;$Z`KHis|LqG&|{YLO$qJ6m)akjw0q<#Hi1Gay`pmo+@5G6)! z=9$~!zwU6Rvo$Q?2ah>t z@)Be(`IVHT0oN0@xSwq*4TLR?w0aRt4Gk4sVFb}rGcm#9d@C@J=AeILHf3XvR~@U= zzT;mS5Glws zDK&G22$XskKkpPYVK47y`(-=)-ObZq4Vka(BEDVr`%j694qG@K%Q8F5w?7Yu`)NqucoFxD9RHPC|E`joiJ?DwVXWf82_m~r z*&L5td-Kxz{QqkY)c=$RKe3)4sjmIE_5XD(AVJZu;B7gu*_B@0?IlbuG*8WWJPA7g?>e&oVfv!aedt4~4R!GY$T@M)Z&(>$ zz$ylFM`o3L=1%uNJIkAYIQ|aX_%qFCAdN3S64M#@>97KgL#WDZ53@QBQSY#@4lNej z+f!hXBK)jwNTBg zo)o4@I%a>p4Y5;Z`B>mocc4-=J%{}I-t==M1E?(am4>9}GrfC>UyTRZtA}8RFCU|h z*EonEeaxD^1tqZ`ycq%Bna}K9IwyNc;1@+qBdVw)diL--wyj9eEmp( literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/status_select-dark.png b/testdata/snapshots/darwin/status_select-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..ab531db3dd1a29eaf5ce098aa254ce999f8d4a07 GIT binary patch literal 9323 zcmc(FWl&sCvpyO$xCRZuU4ky21;Ped+#v+n0KwgYJ1i0;xCL1>xC99vbaB@ZSlm6x ze}C`&a_j%)zHim7x?iTI&pFf6Gt=GAGhHVNtfurF_XREr3d(ckw?Iu46x3#9|2sAs zvOSAEkU~LW7E}hxX?tZIWZ~$O&QT1&nO`O{SDg@#+Sik&Y%71uPn2QnGN|uQ&KBt^ROpVQ$u*WSMiyXN^6*ObhOzugQaS4|&x({KqSQXQ zk6%M93*nt?$#gCQu5&gbV>hzKtMP6MYG$(rfw7CoQGs^ez zImpp(@{tfY?6J%ALhxqu0qYHMvLg<=P7coB%>x7FPw4RG=Pp-N zyN%;>1D=DTd;RNQSiMy;e-GB@eC+8zRDx!IFtoL@;h=v#PK3EGM2< zF@sVXUj|t>HHT&xJPx*OKk6G?Wo&J>-!1haKEOL=J4rUv&F2Q9N3C8zFmInniU<`tgYl7v{c%^yZW5yK_Bkzklg(+;$}3rYviBFD|!| zTD)(=0z#F<=dT~EZz;F7$S0C+TDgK`f3BUrkyZcV@Gh;g#Ia=H+<^PTaPdr|f8|(T z4j&H>jYRLl*{jp!-SgwM03x#H{(6X~vPyxrp}2h+Tl~QA$cXuvoufo<))2zZ2l|2l zDRytR=P@u-8HJM7Hs*&y@jHphqW$&91&a3m4RXO?%(|8 zX3JuDK{PHbDCqOLwagcK6C3c^ZN^g5ZRW+!-PWY=DUR~U7HnsBX1=j{=9H9pf1h40 zyECCyV4Y@84!x=v^7ZQAaesp}voRFRrJclEZFVi}s`;1f(0%dxqQBladJDA32xcb9;ifz7gg@y2nX=fQBQ!rC)p6iF{|Mv{+vU|}}+*YRYL>wFY; zE2VcyshE^hPxo^D7zyjvmS#p03K2EA==_W_w}>2Awi~Pk*zpUP~k= zCs{)*=xEnV99H!4q^20fXoslE;7w!rE+Uzg`Cay3A&o7@&(qsXO%?6!KDO0lVoDW` z3013B`XUIwH#HDtigcXo4Ejev1zRBd?bi~hf%5rIZr`_Dgj4+*W<6I0p91Y^3AWaw zad!^^Pjz*Nqg%G)50NQc6tPrCpllo`N$zgPLkcOW?9sLA0zxo{P>f;P+}dh!6=r*- z%NS)=@j5oVFtq2-$GZ8fg&_3-ET(N2cXZW)Axn&ierqsG?ywLF*p!!t zvvsMdn*8t!0iD;Z?siKHCLu%WDo;zvkewYK5BCVwyFYHzb3y{UAfxV%F`9IP!>d!b zrArmSu7(=*@x=R6{)c!|AT?R7(n_#cN^IO(uC%>mjKbISs~tzjLT%1X(l7XcJ@lX7 zqAc*A16qGPf6YIhHhcNl-BSpGXV8*0Ul|{G>rpBh8SQuOvsR-9G7tVL6~l9_gK72i z7~S12UK*w6qAZAeBXf`tL}lG+9%-NI6}^#(2`P2(4~E!fL#5-$b3zn6b`Yw7l9M|sZ~ zq}_JS9RG8)ob(Aqe6j@oajrRW?y19hUzgZbY8p^7 zi^+26JCnyD$SQrIje){!{I+=5J%f^i&DZV8smsrH!$(KQT}|!rF(iL*&_(ZXFs6{{%AqPOXET4w1@PP><_z$S2D*X ztwnN69{anyt@v(K>mSq7%)B_ZY~zpmQJfA9w}*6S{1IwqZB9@X)*ns+mrFBiLUW4k zF-$o~>7U3}?}Tcj3W#I%Xe$3u z4^hRj8;Hj185u2INCHgy0_B}er{Ff3hBYp4EVYfRO{EsNbw59jex2{kIPiS`{(b$i zELa2!RHVrfrJUT$+_=<96eiywTj9CmsE`jXr6l>csD2{{I0+Y1j_4ms=MN^qkmDpf zoE3V49INDIG`EU9vSI{%pD_d*5{o7);N)?4l~rnJldt-1!#Ky+PGeW`=OY2QquV<3y@;L%tU?10PI7<=vnr|d&-Yjo0 zofh87BgAtTEwljcm@4{hz z%R5h&{!MekpQyBIWXZ7g?_ameom0gK(cLvxQkfyjZL8j5?bMV_EtF)Gp*ieidS1G2 zd8|#ThMP8CKhw1F?_%aqDugU!gU{XNHdg#63)^7Q((HD7fUnUJn6Ilts3on==>>B8 z{di;zGLum23d*cNp$X|6e=k;}u=Br+?J&r=9uLcps{Nq=WOKlkZAR^aBygho?KD2>}B zh7_(jjvyU?QU_fp$mh?~c<)3o1oYq}bPTsuvdDOS(*>1>!54_-uP+!O3-v0RkD$TRaojnn6Ffsuqd1-0ez3uIG?+_MHd!p7pmBAGp zO!-XJtlr%hs2t_Bnq~93t>Xr}l-S$X#oIK;>lo%`nzNc?+%^~Na(xYx`dwA2#IomU zTQ4B&e0|+za|n9ZNg-)*x_ryU#6(D4qaQ;tl0`ulNf?}=RlO|qY^~5z*AdNHVWU^e zz-bX9{u=u$xx3FXP`Y}!Ka$xGSTb8-IN4a)pl!IZzp1Q|ynbJ#YQDi~?>`aC=6E;s z>xNBKkF3S>{KrF^Q1uqAG+7Ssh>OeK>O%fz=+6Wtt0V6MEBpiu^>Ejr2`h1>(&b)a>`0Lk*8q(+~j?F9|kER-%f#qz(Qb}6*R7-Pj*1osJ zK&*b-M~X~)vh$LkHNI&)=4PJ9v(zu^f0y5)W8L)ko8FvPpLa;-*y-_2q)e-`n5oKm zNLU;H#D0`@7tPK8Q!^zns5f6)#Bl#EiEl_n~KFSVpGJ-UmTtZFc8282j8iV(u!O>92)5% zPie!h$z{T4D@Wjl-l`5u0TvA5?g)6=a30t(BRuv$mg>Z}ufDIZuV=*W-D-WNT9g+1 zH3xHQ06(WCw4n58MZ))TD@W`S(RvBkNqq#^PlZ?Cgsirwy0=5(9h3^x>{nZ{Ub<~X zJFP4h-IPT#4{~TBqWTDlK0puQ z(AF7V)ZmCp`s}yWXH#jklzBOORP{w^@45Q&J@tH&1hjey=@p28Q_>|0EiFvN zFPTYTv&HdH;&Fn(5rXuGB2W=-I!6w@*#>9zdxv)sRd@0WRSWxv%I_C7@X2Ol|Xy zZ|aofw9wdJ+<5%5}F_A7sPz>g`Uf{p}Z8)1(dZn^RL>k&xSN3#5RAtCy%~<~q<65}B1> z)Gef>=!|3~`(Vy4S6mq>2s4OU*BNjZv=t<6u(l@$Y=1I07m(jsiUSA<*52MfKHRs3 zRf6Ehcc(fK2E8Dl>1uJ^8L(no+V?*;b%S&OKU3Kc1yM`Ft@ab zzY2A!T65dq`qr?!OBZT6|K6n~_>oe6#6t1u(dcg7oJ0OC_h+Zg@VAa7UyVxsSzjj8 zm#>#uI1J6U6dhJBMf^%_$E68~2@Tg5kHGUCr)lLjn2D&1i)RgQl1xYs!vZ?*tF>1=arS&9^TQBDG+094D1ifPW7w^tA2IA z8!>Qo9fR7J`?pC|RC4=X>@4!%>X#jpvsU*WQP*%R=bN@tbj++J3VJJk!dVRXLS+0K7Sjp~fzE%5%U|Gd>b#n>xoYMZg7dN8`R!qdER|Lqoc>X^uoCo^|KOtG zJh<_SjSUkTC3Bsrsa&hioy2?^vB!RO5C)fi@LEcBBq4dax;&*7^pXYs$^Q-T>=CJC zCaOUeGFpr`#$lU15k*LHY_4f&8dQx@Ryb7af+Pm5^kOA%ibxIsQy*ViAjYnyg3-jS zt&fc7Oxv@PK`ve0j_lEsGZ#0mmnoh?oq2g5XGb__p$jX%*KAl&XQv%8bIr)d0C-S_ z2@fX7nkmVgMgA?ilIrWC&_wOYkU}-O_=s<$=9R`S12ocv^GpT7$1`MnhHT0&83=F0{A{Skl4YUfggr3S9%HNduoe^h_ z^7?Bxp6&A|mcqU$v%)(^7Ymi=ejq=4lDHe<)tBgOcfOsoSdA(Q)ylD=x$zb_NFq zCXA@3T=r6 z(9oh8Z@RH?6<#uP{%QDP>`+$DB*E|T<@or1qlN9-v}Yt8ey=vxf?z5HDn`YUP_qbv zER%n+Cu;o94?5an&sr$6;&Gotu~Tqsyr^O#7>p#14ZV+W7|=noHeq1JP*6Nsnu(q5 z#tWiZdi)-*=#_$jSd8SrNzHt}qY5zl`Wt0-8{Nr^M*BCLqt=N(qwG+SFZc3$BWYea zc=X0WgP;?cP;=^_vA8k&nrs>{8b}t09hD^yse|O-6&5?z-P;Kg!D26M-QFhjt{jpx z**e%%mce)=Oed?fT}n{?rL>6r4K+OlXH1Oy_a?-PUvDJm-$;7hH~*R*`J~{@GKc?P z)9T__dFg*F;C_tabMyG#q@LVIssYyp6+K>Y*FNi+>EHJ}ZgkCUyFWR<{2UPUX}HtF ztabTU1M0t~*gBWxAi=eAu90fH$}y)hFg^$iAC`*k>Rf3CF}rO;cZO#6|6U=Aj#l8p zZ6j2Y^M|8R)er>jf30?iGSo$W`r~<|QIReU{xe8WV5EdLXSg|rTK{u0+Ji$jVBFXk zpx5Lgl%1=3@g8mhg%b3Hpj)g$)s#~KV)Fq_hce5ENa>i!?_e65OcDk0xpBI}o*p-e z71-Io?6YEcLrucGQP#g=)p$IbMJJOI=>a*&mEnT^4V4dOmU^==Tg+Wu%3AQ7G`ix! zd(GY?lQ}mtHB}YA&hxtXEZR1z7rtcoD>n3-Ts3}{jHlu+M`rs&P*{P>${i0Oy_Gjd7+l9We6Zrl6JV%SoxPz<^YJ)Y>2?!TO46r*j*JzDOrns)Iy!p>XMnfipl41$)T9f!zQ{e+ zcdGwtSGcnlm;IsxlRPx{xeF4eFK1JH3Ek01{zdmq9a`yOv8ebB!APgGWRCNKM!fpV;=6u%+$6lAlsUd|DN~ zAh7LmA0D|gzQIsL(#d>F8>d)j0SV8ozNRcswSAot5)s|j7Cr*{+U?JW$H5ZqBE9B( z2M_@E8V+)%r}(a)z9#+0^B1tdS6Z-gJ4U9cUThZPY;jkQAio;ZYV{y`a*J%>P;!iw^gS?c{ma>0k6DAwow zGma0R?}y-`D$sOx5(ze5eYfJXtZX_*_?TmHfB(UJx`53j1{T)e*U+j0T6KPMm`O6{H96*fWg`rFugQ*a67uY2?!DQTvLKXd$+gQJ%_W z@^)MZWOEs+xnM3)pxH;=ZVI1-X_tXoHck@nEl3LsziB=VmA%;f-mago2{RCYXP4t) zUkGO_AR{bSlZtO*|M_j$Ku?d-4c5&w<@@K)Li{#9ZBheyd71R)l1A+9aSE^L!Hpj zw^60re(k%F^@f$F3`_t(j$--77*iZa;-AyjCyA>B9+MZ(;i-@+*U{;j8ULvEkZj%Z zAMWJ~(<&?EAwdIm{ulSWRkk)7NI!h2Y;3-GJ@@RN{BeNA9s^B_WuP2X^Q&`R-d^Ks z;gs4r;Fd7$rjr6NDTNJ^6xVYBcuiV4{XQ-b5zovD$3|1_9v^F&1*AtZy)v_)`GIil zQJO~rc7tI)n244PyygV+jf($Ko?GqN)5isTZGGVwRoe0BV!zTCd6Kx~`AyXHha4~n zwF4b1diwfkZq5vf%|N{_b0FV-dRAl6-SV`Ih7JsVOEgHb&s2e#sfF|&f zJ-A=O#M07vdoM;u;b!Fc`bH0nVI{Bkgo{V>gA*Cq<7>O^WOqB=Z$*g6z9Z+UN2jXo z?#q2u46`XTO1KQqaZUFT6wi^s@G>tg+E!s`7*A zqlJ~B545gss;%X8&T%<9v*!EB!0*uX8oN1e^>^^oQ)-FbN}OdWBJ9vGr2sjb&wJYe z^yaS-N$uXD8YMHg1m}1BHaX4>w<&hsSZA)CGJgFRWisui5Pm8*3A(>!oplhqw9jV> zlUS~l58nBTh2jQ=9iMK~mhE?dgEj$A=9~SBZf>Pl-;UnFe+dgu#nGsWW@cz5ZAoMw zxf#qP#p{u1xL@8{4R_wjN&~DCv&_Hl?VaaV=)VDylS5?89!9&btvCiAaGD|NQ23S`|tUsR?(bR}j-b4VuD*qlS{m!^zO zuvS{8tQ+0;Q>!u1N-!33L*;|iO7zN)ov(KY*g9Sj!;V)FFIwL)lay)Op8JF6YuTOe z)xCb&lakNiV}R-NvNP$}0TZG43!@yto+|CKX4`6qnblRkUW=W$e9`dL zS+R>p;ZVa$(@yjK-CEA7jkLG$Uk#h5^fvO0M3HP^VQ*j)A3YDf&j>LI)py@VxE?q` z>Bee$#683Y2oUodw16y&h;z!d4ch++grBPOrgtyZeL0EE8@l*o)vAwo@sSW-i8~}x zG^BOVPxrDyGPa9<1YF~rsd;&zRRbm2XRoxRvodfux%kST7%21pr|YYj4~YsTb4?sN zRx|F#=sB1Db*s8h6{5IE=GTydxWC6A_BCf*P<&{(bQO0|uweqyPW_ literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/status_select-light.png b/testdata/snapshots/darwin/status_select-light.png new file mode 100644 index 0000000000000000000000000000000000000000..2ecbe66d9c6adbe9449d864e9a9588d2545b984b GIT binary patch literal 9056 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 literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/subtask_list-dark.png b/testdata/snapshots/darwin/subtask_list-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..a4b362909754d0b10747eb2428b550d20bae7f1d GIT binary patch literal 10718 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 literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/subtask_list-light.png b/testdata/snapshots/darwin/subtask_list-light.png new file mode 100644 index 0000000000000000000000000000000000000000..965661a496eaeffb444ffa92fb83d150eb780d28 GIT binary patch literal 10440 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 literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/task_detail_panel-dark.png b/testdata/snapshots/darwin/task_detail_panel-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..6a1f39d3f3b9b36a7ba7b1673deeaabb6b7fbe6b GIT binary patch literal 47675 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 V7TxLC4f;I|a#G5YWso=i{|kYQLwEoH literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/task_detail_panel-light.png b/testdata/snapshots/darwin/task_detail_panel-light.png new file mode 100644 index 0000000000000000000000000000000000000000..0f692bd82492ba725de2a430198d2c6a713fd828 GIT binary patch literal 46322 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 literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/task_item-dark.png b/testdata/snapshots/darwin/task_item-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..af2dd0f96a4ad2f3611d3931a91daccf9d9ac8f5 GIT binary patch literal 23310 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 CU}_Qo literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/task_list-dark.png b/testdata/snapshots/darwin/task_list-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..396cacd0dce210f7bbcdcb04748f63ade1aa1f56 GIT binary patch literal 33319 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 z zeeHrF5U#Sbol&SGzY-CZsLfuKPyR|nII*Ilsu9BXB28^&X=PL~lY0vq>8eDE4)lyA zkIYsjj^D$XZqU1Futtzx;gz)f_Hy!J5BC#^oFjUE>`t%-3s;I5cIU$kFduE9bZ#t| z)sv;$US6qc7CXN(&MIs547uTf@mA5fEAfxP^7(NS1pKzNvctO4J|(RTZ}He!O$rau zV2fV5jC2ZNzuS*Ios`d0HsFqU30Vxrxfw4<28sze{N&k6;X(hPZ(OAkyZxz{gf=t@ z0=Hh5W{H}d86r=VCkLFcIvBAs{p)p&}CTTy1gC5DRC-w_>G zT`XQCHktC}+d#I(_LFN2_9Ok0e&%WX{OlB)OtX~}^rf4Vt%utSv-F`MjrRzn0#Wso zJt+`Olw?KL)8%|wYSQn0z83=Q8MvivQjln+WS=81VMR`=|3|ZizKCFT52L z&^dJlX-3mK#ex&IFr$76^bvGxR#k~wo#wjZ+*joUq3yCvi6`9;cSx_(jiqmu>UDZ5kLcS_|p+WKvP#3Iz z-r>4Q)+pSs}xzFR6*d0wG6SoyUMx|I7k*S?zz~w7_yL}G;(S+Cf zeL~mAW_xhc6J0T<b36)swewf?U!?f*VYR1;Kk b@xlhCqwXwy8H{kfa6wV-g=~@Z+kpQIFJf>p literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/task_list-light.png b/testdata/snapshots/darwin/task_list-light.png new file mode 100644 index 0000000000000000000000000000000000000000..7d4ab516a2725f19f8a438e203d9d5101b38e445 GIT binary patch literal 32088 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 o1D))(#j-S)oP^C7Ur(rJGra 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 literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/workload_view-light.png b/testdata/snapshots/darwin/workload_view-light.png new file mode 100644 index 0000000000000000000000000000000000000000..1ac3ffbc9653ca8e67e228ab036860c793ee9cfb GIT binary patch literal 16450 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 JR0$dQ|35o|BHaK0 literal 0 HcmV?d00001 diff --git a/time_tracker.go b/time_tracker.go new file mode 100644 index 0000000..b3baa35 --- /dev/null +++ b/time_tracker.go @@ -0,0 +1,131 @@ +package mujica + +import ( + "log/slog" + "time" + + "github.com/egoist/mygo/ui" + + "mujicaui/icons" + "mujicaui/theme" +) + +// TimeEntry records a span; zero End means running. +type TimeEntry struct { + Start, End time.Time +} + +// TimeTrackerState holds the caller's tracked spans and manual correction. +type TimeTrackerState struct { + Entries []TimeEntry + // Adjust is added to the tracked spans by manual correction. + Adjust time.Duration +} + +// Running reports whether the last entry is still open. +func (s *TimeTrackerState) Running() bool { + return len(s.Entries) > 0 && s.Entries[len(s.Entries)-1].End.IsZero() +} + +// Total returns the tracked time at now, including the correction. +func (s *TimeTrackerState) Total(now time.Time) time.Duration { + t := s.Adjust + for _, e := range s.Entries { + end := e.End + if end.IsZero() { + end = now + } + t += end.Sub(e.Start) + } + return t +} + +// TimeTrackerOptions configure a TimeTracker. +type TimeTrackerOptions struct { + // Now fixes the clock; zero uses the system clock. + Now time.Time + Disabled bool + Label string +} + +// TimeTracker records spans and supports manual total corrections. +func TimeTracker(c *ui.Context, s *TimeTrackerState, opts TimeTrackerOptions) ChoiceResult { + now := opts.Now + live := now.IsZero() + if live { + now = c.Now() + } + for i, e := range s.Entries { + if e.Start.IsZero() || e.Start.After(now) || !e.End.IsZero() && (e.End.Before(e.Start) || e.End.After(now)) || e.End.IsZero() && i != len(s.Entries)-1 || i > 0 && e.Start.Before(s.Entries[i-1].End) { + panic("mujica: TimeTracker entries must be ordered spans with only the last open") + } + } + if s.Total(now) < 0 { + panic("mujica: TimeTracker total must be non-negative") + } + k := Tokens(c) + d := Density(c) + label := opts.Label + if label == "" { + label = msg(c, "time_tracker.label") + } + changed := false + row := ui.Row(c).Gap(d.Unit() * 3).AlignItems(ui.Center).Role(ui.RoleGroup).Label(label).Disabled(opts.Disabled) + editing := ui.Local(row, "time-tracker-edit", func() bool { return false }) + draft := ui.Local(row, "time-tracker-draft", func() time.Duration { return 0 }) + act := func(what string, fn func()) { + if row.IsDisabled() { + return + } + fn() + changed = true + slog.Debug("mujica: time_tracker "+what, "total", s.Total(now)) + } + row.Children(func() { + total := s.Total(now) + running := s.Running() + icon, key, variant := "play", "time_tracker.start", Secondary + if running { + icon, key, variant = "pause", "time_tracker.stop", Primary + } + if Button(c, msg(c, key), ButtonOptions{Variant: variant, Icon: icons.Must(icon)}).Clicked() { + act(key[len("time_tracker."):], func() { + if running { + s.Entries[len(s.Entries)-1].End = now + } else { + s.Entries = append(s.Entries, TimeEntry{Start: now}) + } + }) + } + if *editing && !row.IsDisabled() { + DurationPicker(c, draft, DurationPickerOptions{Seconds: true, Label: msg(c, "time_tracker.correct")}) + if Button(c, msg(c, "time_tracker.apply"), ButtonOptions{}).Clicked() { + act("correct", func() { s.Adjust += *draft - total }) + *editing = false + } + if Button(c, msg(c, "calendar.cancel"), ButtonOptions{Variant: Ghost}).Clicked() { + *editing = false + } + return + } + *editing = false + fg := k.Text + if running { + fg = k.AccentText + } + ui.Text(c, StopwatchText(total)).Font(theme.MonoFont).FontSize(FontSize(c, theme.H3Size)).TextColor(fg).FontFeatures("tnum"). + Label(label + ", " + DurationText(c, total.Truncate(time.Second))) + if running { + ui.Text(c, msg(c, "time_tracker.running")).FontSize(FontSize(c, theme.CaptionSize)).TextColor(k.AccentText) + } + ui.Box(c).Disabled(running).Children(func() { + if b := iconAction(c, icons.Must("pencil"), msg(c, "time_tracker.correct")); b.Clicked() && !b.IsDisabled() { + *editing, *draft = true, total.Truncate(time.Second) + } + }) + }) + if s.Running() && live { + c.After(100*time.Millisecond - s.Total(now)%(100*time.Millisecond)) + } + return ChoiceResult{Element: row, changed: changed} +} diff --git a/time_tracker_test.go b/time_tracker_test.go new file mode 100644 index 0000000..8da2e5d --- /dev/null +++ b/time_tracker_test.go @@ -0,0 +1,105 @@ +package mujica + +import ( + "testing" + "time" + + "github.com/egoist/mygo/ui" +) + +func TestTimeTrackerStartStopCorrect(t *testing.T) { + var s TimeTrackerState + now := time.Date(2026, time.October, 5, 9, 0, 0, 0, time.UTC) + n, disabled := 0, false + tt := ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + if TimeTracker(c, &s, TimeTrackerOptions{Now: now, Disabled: disabled}).Changed() { + n++ + } + }, 900, 160) + _ = tt.Click("Start") + now = now.Add(25*time.Minute + 30*time.Second) + tt.Frame() + if !s.Running() || !tt.HasText("Time tracked, 25 min 30 s") || !tt.HasText("Tracking…") { + t.Fatalf("running %v", tt.Texts()) + } + _ = tt.Click("Correct the total") + if tt.HasText("Apply") { + t.Fatal("correction must wait until tracking stops") + } + _ = tt.Click("Stop") + now = now.Add(time.Hour) + _ = tt.Click("Start") + now = now.Add(4*time.Minute + 30*time.Second) + _ = tt.Click("Stop") + if s.Total(now) != 30*time.Minute || len(s.Entries) != 2 || n != 4 { + t.Fatalf("total %v entries %d changes %d", s.Total(now), len(s.Entries), n) + } + _ = tt.Click("Correct the total") + _ = tt.Click("Minutes") + tt.Command("selectAll") + tt.Type("45") + tt.Key(0, ui.KeyEnter) + _ = tt.Click("Apply") + if s.Total(now) != 45*time.Minute || s.Adjust != 15*time.Minute || !tt.HasText("Time tracked, 45 min") { + t.Fatalf("corrected to %v (adjust %v)", s.Total(now), s.Adjust) + } + disabled = true + tt.Frame() + _ = tt.Click("Start") + if s.Running() { + t.Fatal("disabled tracker started") + } +} + +func TestTimeTrackerInvalid(t *testing.T) { + defer func() { + if recover() == nil { + t.Fatal("expected panic for two open entries") + } + }() + now := time.Now() + s := TimeTrackerState{Entries: []TimeEntry{{Start: now}, {Start: now}}} + ui.NewTester(func(c *ui.Context) { Use(c, Settings{}); TimeTracker(c, &s, TimeTrackerOptions{Now: now}) }, 10, 10) +} + +func TestTimeTrackerSnapshot(t *testing.T) { + now := time.Date(2026, time.October, 5, 9, 0, 0, 0, time.UTC) + s := TimeTrackerState{Entries: []TimeEntry{{Start: now.Add(-time.Hour), End: now.Add(-30 * time.Minute)}, {Start: now.Add(-12 * time.Minute)}}} + snapshot(t, "time_tracker", 460, 80, func(c *ui.Context) { + ui.Column(c).Padding(16).Children(func() { TimeTracker(c, &s, TimeTrackerOptions{Now: now}) }) + }) +} + +func TestTimeTrackerRejectsInvalidSpans(t *testing.T) { + now := time.Date(2026, time.October, 5, 9, 0, 0, 0, time.UTC) + for _, state := range []TimeTrackerState{ + {Entries: []TimeEntry{{Start: now, End: now.Add(time.Hour)}, {Start: now.Add(time.Minute), End: now.Add(2 * time.Hour)}}}, + {Entries: []TimeEntry{{Start: now.Add(time.Hour)}}}, + {Adjust: -time.Second}, + } { + t.Run("span", func(t *testing.T) { + defer func() { + if recover() == nil { + t.Fatal("expected invalid span panic") + } + }() + ui.NewTester(func(c *ui.Context) { Use(c, Settings{}); TimeTracker(c, &state, TimeTrackerOptions{Now: now}) }, 600, 200) + }) + } +} + +func TestTimeTrackerCorrectionRemovesFractionalRemainder(t *testing.T) { + now := time.Date(2026, time.October, 5, 9, 0, 0, 0, time.UTC) + s := TimeTrackerState{Entries: []TimeEntry{{Start: now.Add(-30500 * time.Millisecond), End: now}}} + tt := ui.NewTester(func(c *ui.Context) { Use(c, Settings{}); TimeTracker(c, &s, TimeTrackerOptions{Now: now}) }, 900, 180) + if err := tt.Click("Correct the total"); err != nil { + t.Fatal(err) + } + if err := tt.Click("Apply"); err != nil { + t.Fatal(err) + } + if s.Total(now) != 30*time.Second { + t.Fatalf("total = %v", s.Total(now)) + } +} diff --git a/workload_view.go b/workload_view.go new file mode 100644 index 0000000..ba44ac6 --- /dev/null +++ b/workload_view.go @@ -0,0 +1,126 @@ +package mujica + +import ( + "fmt" + "math" + "strconv" + + "github.com/egoist/mygo/ui" + + "mujicaui/icons" + "mujicaui/theme" +) + +// Workload is one member's assigned and available hours. +type Workload struct { + Member Member + Assigned float64 + Capacity float64 +} + +// WorkloadViewOptions configure a WorkloadView. +type WorkloadViewOptions struct { + // Unit labels the amounts; empty uses hours. + Unit string + Label string + // Version changes when loads change in place. + Version int +} + +// WorkloadView virtualizes member loads with capacity and overload marks. +func WorkloadView(c *ui.Context, loads []Workload, opts WorkloadViewOptions) *ui.Element { + k := Tokens(c) + d := Density(c) + unit := opts.Unit + if unit == "" { + unit = msg(c, "workload_view.hours") + } + label := opts.Label + if label == "" { + label = msg(c, "workload_view.label") + } + root := ui.Column(c).Grow(1).MinHeight(0).Role(ui.RoleList).Label(label) + cache := ui.Local(root, "workload-summary", func() workloadCache { return workloadCache{} }) + var first *Workload + if len(loads) > 0 { + first = &loads[0] + } + if !cache.ready || cache.first != first || cache.n != len(loads) || cache.version != opts.Version { + *cache = workloadSummary(loads) + cache.first, cache.n, cache.version, cache.ready = first, len(loads), opts.Version, true + } + top := cache.top + state := ui.Local(root, "workload-list", func() *ui.ListState { return &ui.ListState{} }) + st := *state + st.Key = func(i int) any { return loads[i].Member.ID } + num := func(v float64) string { return strconv.FormatFloat(v, 'f', -1, 64) } + root.Children(func() { + over := cache.over + if over > 0 { + ui.Row(c).Gap(d.Unit()).AlignItems(ui.Center).TextColor(k.Danger).Role(ui.RoleStatus).Padding(d.Unit()).Children(func() { + ui.Icon(c, icons.Must("triangle-alert")).Size(14, 14) + ui.Text(c, calendarCount(c, "workload_view.overloaded", over)).FontSize(FontSize(c, theme.CaptionSize)) + }) + } + ui.List(c, st, len(loads), func(i int) { + l := loads[i] + hot := l.Assigned > l.Capacity + text := fmt.Sprintf("%s / %s %s", num(l.Assigned), num(l.Capacity), unit) + note := "" + if hot { + note = fmt.Sprintf(msg(c, "workload_view.over"), num(l.Assigned-l.Capacity), unit) + } + ui.Row(c).MinHeight(d.ControlHeight()).Gap(d.Unit() * 3).AlignItems(ui.Center).PaddingX(d.Unit()).Role(ui.RoleListItem). + Label(l.Member.Name + ", " + text + " " + note).Children(func() { + Avatar(c, l.Member.Name, AvatarOptions{Size: 24}) + ui.Text(c, l.Member.Name).Width(d.ControlHeight() * 4).Shrink(0).SingleLine().Ellipsis("…").TextColor(k.Text) + ui.Box(c).Grow(1).Height(10).Draw(func(p *ui.Painter, r ui.Rect) { workloadBar(p, r, l, top, k.Border, k.AccentText, k.Danger, k.Text) }) + fg := k.TextMuted + if hot { + fg = k.Danger + ui.Icon(c, icons.Must("triangle-alert")).Size(14, 14).TextColor(fg) + } + ui.Text(c, text).Width(d.ControlHeight() * 3).Shrink(0).FontSize(FontSize(c, theme.CaptionSize)).TextColor(fg).FontFeatures("tnum").TextAlign(ui.End) + }) + }).Grow(1).MinHeight(d.ControlHeight() * 3) + }) + return root +} + +// workloadBar draws assigned work, overload hatching and capacity marks. +func workloadBar(p *ui.Painter, r ui.Rect, l Workload, top float64, track, fill, hot, tick ui.Color) { + x := func(v float64) float32 { return r.X + r.W*float32(v/top) } + p.Fill(r, track, 3) + p.Fill(ui.Rect{X: r.X, Y: r.Y, W: x(min(l.Assigned, l.Capacity)) - r.X, H: r.H}, fill, 3) + if l.Assigned > l.Capacity { + p.Fill(ui.Rect{X: x(l.Capacity), Y: r.Y, W: x(l.Assigned) - x(l.Capacity), H: r.H}, hot, 0) + for sx := x(l.Capacity) + 2; sx < x(l.Assigned); sx += 5 { + p.Line(sx, r.Y+r.H, sx+3, r.Y, 1, track) + } + } + cx := x(l.Capacity) + p.Line(cx, r.Y-3, cx, r.Y+r.H+3, 2, tick) +} + +type workloadCache struct { + first *Workload + n, version, over int + top float64 + ready bool +} + +func workloadSummary(loads []Workload) workloadCache { + out := workloadCache{} + seen := map[string]bool{} + for _, l := range loads { + if l.Member.ID == "" || seen[l.Member.ID] || l.Assigned < 0 || l.Capacity <= 0 || math.IsNaN(l.Assigned) || math.IsNaN(l.Capacity) || math.IsInf(l.Assigned, 0) || math.IsInf(l.Capacity, 0) { + panic("mujica: WorkloadView needs unique member IDs and finite non-negative loads with positive capacity") + } + seen[l.Member.ID] = true + out.top = max(out.top, l.Assigned, l.Capacity) + if l.Assigned > l.Capacity { + out.over++ + } + } + return out +} diff --git a/workload_view_test.go b/workload_view_test.go new file mode 100644 index 0000000..7b22374 --- /dev/null +++ b/workload_view_test.go @@ -0,0 +1,79 @@ +package mujica + +import ( + "fmt" + "math" + "testing" + + "github.com/egoist/mygo/ui" + + "mujicaui/theme" +) + +func workloadSample() []Workload { + return []Workload{{Member: projMembers[0], Assigned: 32, Capacity: 40}, {Member: projMembers[1], Assigned: 46.5, Capacity: 40}, + {Member: projMembers[2], Assigned: 12, Capacity: 20}} +} + +func workloadTester(loads []Workload, opts WorkloadViewOptions) *ui.Tester { + return ui.NewTester(func(c *ui.Context) { + Use(c, Settings{Mode: Light}) + ui.Column(c).Height(300).Width(600).Children(func() { WorkloadView(c, loads, opts) }) + }, 600, 300) +} + +func TestWorkloadViewOverload(t *testing.T) { + tt := workloadTester(workloadSample(), WorkloadViewOptions{}) + for _, s := range []string{"1 person is over capacity", "46.5 / 40 h", "Mutsumi Wakaba, 46.5 / 40 h over by 6.5 h", "Sakiko Togawa, 32 / 40 h "} { + if !tt.HasText(s) { + t.Fatalf("missing %q in %v", s, tt.Texts()) + } + } + tt.SetPreferences(ui.Preferences{ReduceMotion: true, TextScale: 1}) + r, _ := tt.Find("Mutsumi Wakaba, 46.5 / 40 h over by 6.5 h") + img := tt.Image() + found := false + for x := int(r.X); x < int(r.X+r.W); x++ { + if datetimeNear(img.RGBAAt(x, int(r.Y+r.H/2)), theme.Light().Danger) { + found = true + } + } + if !found { + t.Fatal("overload is not drawn in Danger") + } + if tt := workloadTester(workloadSample()[:1], WorkloadViewOptions{Unit: "pts"}); !tt.HasText("32 / 40 pts") || tt.HasText("over capacity") { + t.Fatal("custom unit or false alarm") + } +} + +func TestWorkloadViewLargeAndInvalid(t *testing.T) { + var loads []Workload + for i := range 100000 { + loads = append(loads, Workload{Member: Member{ID: fmt.Sprint(i), Name: "M"}, Assigned: float64(i % 50), Capacity: 40}) + } + if n := len(workloadTester(loads, WorkloadViewOptions{}).Texts()); n > 200 { + t.Fatalf("built %d labels", n) + } + defer func() { + if recover() == nil { + t.Fatal("expected panic for zero capacity") + } + }() + workloadTester([]Workload{{Member: projMembers[0], Capacity: 0}}, WorkloadViewOptions{}) +} + +func TestWorkloadViewSnapshot(t *testing.T) { + loads := workloadSample() + snapshot(t, "workload_view", 600, 200, func(c *ui.Context) { + ui.Column(c).Height(200).Padding(16).Children(func() { WorkloadView(c, loads, WorkloadViewOptions{}) }) + }) +} + +func TestWorkloadViewRejectsInfinite(t *testing.T) { + defer func() { + if recover() == nil { + t.Fatal("expected infinite load panic") + } + }() + workloadTester([]Workload{{Member: projMembers[0], Assigned: math.Inf(1), Capacity: 40}}, WorkloadViewOptions{}) +}