@nightkatana/kronosys-app 1.0.0-beta.2 → 1.0.0-beta.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/README.md +28 -1
  2. package/app/api/action/route.ts +39 -3
  3. package/app/api/action-logs/route.ts +24 -0
  4. package/app/api/backup/route.ts +1 -1
  5. package/app/api/restore/route.ts +145 -0
  6. package/app/changelog/page.tsx +71 -4
  7. package/app/globals.css +127 -0
  8. package/app/guide/page.tsx +61 -15
  9. package/app/implementation/page.tsx +700 -0
  10. package/app/layout.tsx +14 -3
  11. package/app/licenses/page.tsx +99 -37
  12. package/app/logs/page.tsx +258 -0
  13. package/app/manifest.ts +5 -5
  14. package/app/page.tsx +784 -229
  15. package/app/reporting/page.tsx +1266 -474
  16. package/app/settings/page.tsx +252 -18
  17. package/bin/kronosys.mjs +140 -15
  18. package/components/KronosysPayloadProvider.tsx +2 -0
  19. package/components/RouteTransition.tsx +18 -0
  20. package/components/dashboard/AppShellCommandCenterPlaceholder.tsx +17 -0
  21. package/components/dashboard/AppShellHeaderSessionMeta.tsx +210 -0
  22. package/components/dashboard/AppShellHeaderWallClock.tsx +54 -0
  23. package/components/dashboard/AppShellLiveSessionDrawer.tsx +154 -38
  24. package/components/dashboard/AppShellRouteNav.tsx +323 -48
  25. package/components/dashboard/DashboardPauseBackdrop.tsx +50 -0
  26. package/components/dashboard/DashboardSimpleModal.tsx +168 -25
  27. package/components/dashboard/DashboardTour.tsx +115 -29
  28. package/components/dashboard/GlobalPauseConfirmModal.tsx +183 -0
  29. package/components/dashboard/KronosysDatetimePopoverField.tsx +167 -122
  30. package/components/dashboard/KronosysTimePopoverField.tsx +54 -12
  31. package/components/dashboard/NewSessionScopeModal.tsx +211 -20
  32. package/components/dashboard/PlannedTaskBoundaryConflictWatcher.tsx +275 -0
  33. package/components/dashboard/ReportingTour.tsx +87 -21
  34. package/components/dashboard/SavedProjectPicker.tsx +16 -3
  35. package/components/dashboard/SelectedSessionSidebarBlock.tsx +512 -142
  36. package/components/dashboard/SessionListPanel.tsx +327 -44
  37. package/components/dashboard/SettingsTagsProjectsSection.tsx +1073 -264
  38. package/components/dashboard/SettingsTaskTemplatesSection.tsx +316 -0
  39. package/components/dashboard/SettingsTour.tsx +86 -21
  40. package/components/dashboard/TagPills.tsx +14 -1
  41. package/components/dashboard/TaskFocusPanel.tsx +1081 -478
  42. package/components/dashboard/TaskSessionLiveCard.tsx +650 -135
  43. package/components/dashboard/TaskTimelineGanttModal.tsx +601 -0
  44. package/components/dashboard/taskFieldStyles.ts +20 -4
  45. package/components/dashboard/useReportingInteractionState.ts +80 -0
  46. package/lib/appShellHeaderClasses.ts +13 -0
  47. package/lib/businessRulesMatrix.ts +210 -0
  48. package/lib/copyToClipboard.ts +43 -0
  49. package/lib/dashboardCopy.ts +494 -84
  50. package/lib/dashboardQuickSearch.ts +54 -2
  51. package/lib/dashboardTimeZone.ts +109 -0
  52. package/lib/formatAppShellWallClock.ts +66 -0
  53. package/lib/formatSessionNameTemplate.ts +141 -0
  54. package/lib/generatedUserChangelog.ts +177 -6
  55. package/lib/globalPausePreview.ts +292 -0
  56. package/lib/implementationNotes.ts +1188 -0
  57. package/lib/kronosysApi.ts +6 -0
  58. package/lib/kronosysDashboardModalGates.ts +24 -0
  59. package/lib/plannedBoundaryAttention.ts +9 -0
  60. package/lib/plannedBoundaryConflict.ts +23 -0
  61. package/lib/reportingAggregate.ts +517 -75
  62. package/lib/reportingMetricHelp.ts +8 -0
  63. package/lib/reportingStrings.ts +37 -3
  64. package/lib/sessionListMerge.ts +4 -0
  65. package/lib/sessionTaskSidebarStats.ts +182 -21
  66. package/lib/settingsCopy.ts +178 -4
  67. package/lib/taskParsing.ts +360 -103
  68. package/lib/taskTemplateDraft.ts +135 -0
  69. package/lib/taskTimelineGantt.ts +265 -0
  70. package/lib/temporalDisplayPlanned.ts +71 -0
  71. package/lib/userGuideCopy.ts +121 -47
  72. package/next.config.ts +7 -0
  73. package/package.json +12 -24
  74. package/server/actionDispatch.ts +1000 -77
  75. package/server/actionTaskSession.ts +337 -24
  76. package/server/db.ts +7 -15
  77. package/server/dbSchema.ts +24 -0
  78. package/server/defaultCfg.ts +5 -0
  79. package/server/gitlabTokenStore.ts +0 -12
  80. package/server/liveHistorySync.ts +53 -0
  81. package/server/mainTimerHydrate.ts +38 -2
  82. package/server/payloadStore.ts +33 -11
  83. package/server/sessionWallHydrate.ts +66 -3
  84. package/server/userActionLog.ts +126 -0
  85. package/sonar-project.properties +11 -0
  86. package/tsconfig.json +2 -1
  87. package/components/dashboard/IssuePickerModal.tsx +0 -168
  88. package/components/dashboard/ThemeToggle.test.tsx +0 -26
  89. package/lib/backupCsvExport.test.ts +0 -149
  90. package/lib/dashboardQuickSearchQuery.test.ts +0 -63
  91. package/lib/dataDir.test.ts +0 -87
  92. package/lib/formatIsoShort.test.ts +0 -46
  93. package/lib/kronoFocusRhythm.test.ts +0 -130
  94. package/lib/kronoFocusTimerUrgency.test.ts +0 -74
  95. package/lib/legacyKronoFocusStorageKeys.test.ts +0 -29
  96. package/lib/reportingAggregate.test.ts +0 -325
  97. package/lib/reportingNonFinalIndicators.test.ts +0 -157
  98. package/lib/reportingTagWeekBreakdown.test.ts +0 -141
  99. package/lib/reportingWeekLayout.test.ts +0 -239
  100. package/lib/sessionAssiduity.test.ts +0 -25
  101. package/lib/sessionEndWarnings.test.ts +0 -200
  102. package/lib/sessionListMerge.test.ts +0 -101
  103. package/lib/sessionTaskSidebarStats.test.ts +0 -24
  104. package/lib/taskParsing.test.ts +0 -153
  105. package/lib/usageProfile.test.ts +0 -84
  106. package/server/actionDispatch.test.ts +0 -723
  107. package/server/actionTaskSession.test.ts +0 -713
  108. package/server/kronoFocusHydrate.test.ts +0 -142
  109. package/server/kronoFocusMigrate.test.ts +0 -53
  110. package/server/mainTimerHydrate.test.ts +0 -65
  111. package/server/payloadStore.test.ts +0 -78
  112. package/server/sessionWallHydrate.test.ts +0 -46
@@ -7,7 +7,14 @@ import { BookOpen, Search, X } from "lucide-react";
7
7
  import { useKronosysPayload } from "@/components/KronosysPayloadProvider";
8
8
  import { postKronosysAction } from "@/lib/kronosysApi";
9
9
  import { AppVersionStamp } from "@/components/dashboard/AppVersionStamp";
10
- import { appShellHeaderClassName, appShellHeaderToolRowClassName } from "@/lib/appShellHeaderClasses";
10
+ import {
11
+ appShellHeaderClassName,
12
+ appShellHeaderTitleMetaRowClassName,
13
+ appShellHeaderToolbarClassName,
14
+ } from "@/lib/appShellHeaderClasses";
15
+ import { AppShellCommandCenterPlaceholder } from "@/components/dashboard/AppShellCommandCenterPlaceholder";
16
+ import { AppShellHeaderSessionMeta } from "@/components/dashboard/AppShellHeaderSessionMeta";
17
+ import { AppShellHeaderWallClock } from "@/components/dashboard/AppShellHeaderWallClock";
11
18
  import { AppShellRouteNav } from "@/components/dashboard/AppShellRouteNav";
12
19
  import { UserGuideBodyText } from "@/components/dashboard/UserGuideBodyText";
13
20
  import { ThemeToggle } from "@/components/dashboard/ThemeToggle";
@@ -21,7 +28,10 @@ import { sectionSearchHaystack, userGuideBundle } from "@/lib/userGuideCopy";
21
28
 
22
29
  type LiveShape = { language?: string };
23
30
 
24
- function filterSections(query: string, sections: ReturnType<typeof userGuideBundle>["sections"]): number[] {
31
+ function filterSections(
32
+ query: string,
33
+ sections: ReturnType<typeof userGuideBundle>["sections"],
34
+ ): number[] {
25
35
  const q = query.trim().toLowerCase();
26
36
  if (q.length === 0) {
27
37
  return sections.map((_, i) => i);
@@ -44,14 +54,21 @@ function GuideContent() {
44
54
  const nav = useMemo(() => reportingNav(lang), [lang]);
45
55
  const dt = dashboardStrings(lang);
46
56
  const bundle = useMemo(() => userGuideBundle(lang), [lang]);
47
- const visible = useMemo(() => filterSections(q, bundle.sections), [q, bundle.sections]);
57
+ const visible = useMemo(
58
+ () => filterSections(q, bundle.sections),
59
+ [q, bundle.sections],
60
+ );
48
61
 
49
62
  const postLang = async (next: Lang) => {
50
63
  await postKronosysAction({ type: "setLanguage", lang: next });
51
64
  await refresh();
52
65
  };
53
66
 
54
- const bulletList = (lines: string[], idPrefix: string, listType: "ul" | "ol" = "ul"): ReactNode => {
67
+ const bulletList = (
68
+ lines: string[],
69
+ idPrefix: string,
70
+ listType: "ul" | "ol" = "ul",
71
+ ): ReactNode => {
55
72
  const listClass =
56
73
  listType === "ol"
57
74
  ? "mt-2 list-inside list-decimal space-y-1.5 pl-0.5 text-sm leading-relaxed text-zinc-600 dark:text-zinc-300"
@@ -71,7 +88,7 @@ function GuideContent() {
71
88
  return (
72
89
  <div className="min-h-screen bg-zinc-100 text-zinc-900 dark:bg-zinc-900 dark:text-zinc-100">
73
90
  <header className={appShellHeaderClassName}>
74
- <div className={appShellHeaderToolRowClassName}>
91
+ <div className={appShellHeaderTitleMetaRowClassName}>
75
92
  <div className="flex min-w-0 flex-col gap-1">
76
93
  <div className="flex min-w-0 flex-wrap items-baseline gap-x-2 gap-y-0.5">
77
94
  <Link
@@ -83,8 +100,13 @@ function GuideContent() {
83
100
  <span className="text-zinc-400 dark:text-zinc-600" aria-hidden>
84
101
  /
85
102
  </span>
86
- <span className="text-lg font-medium text-zinc-700 dark:text-zinc-300">{bundle.pageTitle}</span>
87
- <span className="inline-flex items-center text-violet-500 dark:text-violet-400" aria-hidden>
103
+ <span className="text-lg font-medium text-zinc-700 dark:text-zinc-300">
104
+ {bundle.pageTitle}
105
+ </span>
106
+ <span
107
+ className="inline-flex items-center text-violet-500 dark:text-violet-400"
108
+ aria-hidden
109
+ >
88
110
  <BookOpen className="size-5" strokeWidth={2} />
89
111
  </span>
90
112
  </div>
@@ -96,12 +118,18 @@ function GuideContent() {
96
118
  <AppVersionStamp ariaLabelTemplate={dt.appVersionAriaLabel} />
97
119
  </p>
98
120
  </div>
99
- <div className="flex flex-wrap items-center gap-1.5">
121
+ <AppShellHeaderSessionMeta payload={payload} dt={dt} />
122
+ </div>
123
+ <div className="flex w-full justify-end">
124
+ <div className={appShellHeaderToolbarClassName}>
125
+ <AppShellHeaderWallClock lang={lang} dt={dt} />
126
+ <AppShellCommandCenterPlaceholder />
100
127
  <AppShellRouteNav
101
128
  current="guide"
102
129
  labels={nav}
103
130
  navAriaLabel={dt.appShellRouteNavAria}
104
131
  dashboardSessionId={dashboardSessionNavId}
132
+ reserveGlobalPauseSlot
105
133
  />
106
134
  <ThemeToggle lang={lang} />
107
135
  <PageRefreshButton
@@ -121,7 +149,9 @@ function GuideContent() {
121
149
  labelEn="English"
122
150
  labelFr="Français"
123
151
  menuHeading={lang === "fr" ? "Langue" : "Language"}
124
- triggerAriaLabel={lang === "fr" ? "Langue de l’interface" : "Interface language"}
152
+ triggerAriaLabel={
153
+ lang === "fr" ? "Langue de l’interface" : "Interface language"
154
+ }
125
155
  onSelect={(next) => void postLang(next)}
126
156
  />
127
157
  </div>
@@ -133,9 +163,14 @@ function GuideContent() {
133
163
  data-user-guide-scrolled=""
134
164
  >
135
165
  <p className="max-w-3xl text-sm leading-relaxed text-zinc-600 dark:text-zinc-400">
136
- <UserGuideBodyText line={bundle.pageSubtitle} sessionId={dashboardSessionNavId} />
166
+ <UserGuideBodyText
167
+ line={bundle.pageSubtitle}
168
+ sessionId={dashboardSessionNavId}
169
+ />
170
+ </p>
171
+ <p className="mt-2 text-xs text-zinc-500 dark:text-zinc-500">
172
+ {bundle.lastUpdated}
137
173
  </p>
138
- <p className="mt-2 text-xs text-zinc-500 dark:text-zinc-500">{bundle.lastUpdated}</p>
139
174
 
140
175
  <form
141
176
  onSubmit={(e) => e.preventDefault()}
@@ -179,7 +214,10 @@ function GuideContent() {
179
214
  </form>
180
215
 
181
216
  {visible.length === 0 && q.trim() ? (
182
- <output className="mt-8 block text-sm text-zinc-500 dark:text-zinc-400" aria-live="polite">
217
+ <output
218
+ className="mt-8 block text-sm text-zinc-500 dark:text-zinc-400"
219
+ aria-live="polite"
220
+ >
183
221
  {bundle.searchNoResults}
184
222
  </output>
185
223
  ) : null}
@@ -230,8 +268,14 @@ function GuideContent() {
230
268
  </h2>
231
269
  <div className="mt-3 space-y-3 text-sm leading-relaxed text-zinc-600 dark:text-zinc-300">
232
270
  {s.paragraphs.map((p, pIdx) => (
233
- <p key={`${s.id}-p${pIdx}`} className="[&:not(:first-of-type)]:pt-0.5">
234
- <UserGuideBodyText line={p} sessionId={dashboardSessionNavId} />
271
+ <p
272
+ key={`${s.id}-p${pIdx}`}
273
+ className="[&:not(:first-of-type)]:pt-0.5"
274
+ >
275
+ <UserGuideBodyText
276
+ line={p}
277
+ sessionId={dashboardSessionNavId}
278
+ />
235
279
  </p>
236
280
  ))}
237
281
  {s.steps && s.steps.length > 0 ? (
@@ -251,7 +295,9 @@ function GuideContent() {
251
295
  </div>
252
296
  ) : null}
253
297
  </div>
254
- {s.bullets && s.bullets.length > 0 ? bulletList(s.bullets, s.id) : null}
298
+ {s.bullets && s.bullets.length > 0
299
+ ? bulletList(s.bullets, s.id)
300
+ : null}
255
301
  </article>
256
302
  );
257
303
  })}