@aiquants/daily-report 0.20.1 → 0.21.0
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.
- package/README.md +229 -8
- package/dist/client.d.mts +192 -35
- package/dist/client.d.ts +192 -35
- package/dist/client.js +5 -5
- package/dist/client.mjs +5 -5
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/dist/server.js +1 -1
- package/dist/server.mjs +1 -1
- package/dist/{sse-schema-ChSFm-4q.d.mts → sse-schema-DCxpdETM.d.mts} +131 -131
- package/dist/{sse-schema-BdUGThiz.d.ts → sse-schema-DoQw8_om.d.ts} +131 -131
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -213,9 +213,10 @@ export default function Route() {
|
|
|
213
213
|
config={{
|
|
214
214
|
renderHeader: ({ title, annotation }) => <YourHeader title={title} annotation={annotation} />,
|
|
215
215
|
showDevControls: import.meta.env.DEV, // Toggle SSE subscriptions, etc.
|
|
216
|
-
draftLabelName: "Draft", // Label name for draft states (matches target DB)
|
|
217
|
-
|
|
218
|
-
|
|
216
|
+
draftLabelName: "Draft", // Label name for draft states (matches target DB; not tied to locale)
|
|
217
|
+
locale: "en", // UI chrome language: "en" (default) | "ja"
|
|
218
|
+
labels: { // Optional per-key overrides over the catalog of `locale`
|
|
219
|
+
title: "Field Reports", content: "Body",
|
|
219
220
|
},
|
|
220
221
|
onError: (info) => yourToast(info.message), // Optional: route mutation failures to your own toast
|
|
221
222
|
// apiBasePath: "/daily_report/api", ssePath: "/sse/daily_report/updates"
|
|
@@ -236,10 +237,230 @@ If your app overrides `config.apiBasePath`, pass the same value to `createDailyR
|
|
|
236
237
|
`DailyReportPage` subscribes via `useDailyReportIdsStream`, rendering the list as soon as the first chunk arrives (on cache misses the server races a fast `TOP 200` first page against the cached full query, so first paint does not wait for the full id scan).
|
|
237
238
|
There is no `dailyReportIds` prop and no deferred `/ids` JSON fetch (the old `ids` endpoint was removed).
|
|
238
239
|
|
|
239
|
-
###
|
|
240
|
+
### Localization (`locale` / `labels`)
|
|
240
241
|
|
|
241
|
-
|
|
242
|
-
|
|
242
|
+
Every string the package renders on its own comes from one built-in catalog per **UI chrome
|
|
243
|
+
locale**: English (`"en"`, the default) and Japanese (`"ja"`). Pick the language with
|
|
244
|
+
`config.locale` and override single keys with `config.labels`, which are laid over the catalog of
|
|
245
|
+
`locale`:
|
|
246
|
+
|
|
247
|
+
```tsx
|
|
248
|
+
<DailyReportPage
|
|
249
|
+
config={{
|
|
250
|
+
locale: "ja",
|
|
251
|
+
labels: { content: "商談内容", comments: "コメント一覧", tabArticle: "記事" },
|
|
252
|
+
}}
|
|
253
|
+
/>
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
- **One surface for all wording.** The catalog covers the 7 engine chrome keys of
|
|
257
|
+
`@aiquants/virtualscroll` plus 81 own keys: field headings, the page title (`title`, passed to
|
|
258
|
+
`renderHeader` and used as the accessible name of both lists), tabs, buttons, placeholders,
|
|
259
|
+
`confirm()` / `alert()` texts, stream badges, the load-error screen and the mutation-failure
|
|
260
|
+
message. The engine part of each catalog is `VIRTUAL_SCROLL_LABEL_CATALOGS[locale]`, reused by
|
|
261
|
+
value, so the scroll arrows and the "No items" text always speak the same language as the rest.
|
|
262
|
+
- **Forwarded to every embedded `VirtualScroll`.** Both the List and the DetailList pass `locale`
|
|
263
|
+
and the 7 engine keys of the resolved labels to their `VirtualScroll`. The engine label object keeps
|
|
264
|
+
its identity while its values are unchanged, so rebuilding `config.labels` on every render does not
|
|
265
|
+
re-render the memoized list subtree.
|
|
266
|
+
- **Formatter keys.** Nine keys take arguments and are functions: `totalCount(count)`,
|
|
267
|
+
`debounce(milliseconds)`, `streamProgressCount(loaded)`, `streamProgressRatio(loaded, total, percent)`,
|
|
268
|
+
`streamRetrying(loaded)`, `reportLoadFailed(reportHubId)`, `reportSummaryLoadFailed(reportHubId)`,
|
|
269
|
+
`interviewerWithAffiliation(name, affiliation)` and `operationFailed(operation)` (`operation` is a
|
|
270
|
+
`DailyReportOperation`: `create` / `update` / `publish` / `delete` / `addComment` / `deleteComment` /
|
|
271
|
+
`toggleStar` / `toggleRead`). An override of such a key must be a function too.
|
|
272
|
+
- **Digit grouping follows the UI locale, not the runtime.** The built-in formatters group numbers with
|
|
273
|
+
the BCP 47 tag bound to their locale (`en` → `"en-US"`, `ja` → `"ja-JP"`); a host override receives
|
|
274
|
+
the raw number and formats it itself.
|
|
275
|
+
- **Fail-fast**: an unsupported `locale` (`"EN"`, `"ja-JP"`, `"fr"`, `""`, `null`, ...) throws a
|
|
276
|
+
`RangeError` at render. So do an unknown `labels` key (including the removed `fieldLabels`
|
|
277
|
+
container), a string key whose value is not a string with non-whitespace content, and a formatter
|
|
278
|
+
key whose value is not a function. An `undefined` value keeps the catalog value.
|
|
279
|
+
- **`config` has a closed key set**: `apiBasePath`, `ssePath`, `draftLabelName`, `locale`, `labels`,
|
|
280
|
+
`sourceTypeConfigs`, `renderHeader`, `showDevControls`, `onError`. The removed keys throw a
|
|
281
|
+
`RangeError` that names the replacement — `config.fieldLabels was removed in 0.21.0; use
|
|
282
|
+
config.labels (the same 21 keys)` and `config.title was removed in 0.21.0; use config.labels.title`
|
|
283
|
+
— even when their value is `undefined`. Any other unknown key throws a `RangeError` listing the
|
|
284
|
+
accepted keys. This runs at render because a config built outside a typed object literal (a
|
|
285
|
+
`useMemo` result, a variable) skips TypeScript's excess-property check.
|
|
286
|
+
- **`defaultDailyReportClientConfig` is spreadable input.** Its type `DailyReportClientConfigDefaults`
|
|
287
|
+
holds only the locale-independent defaults (`apiBasePath`, `ssePath`, `draftLabelName`,
|
|
288
|
+
`renderHeader`, `showDevControls`) and it is frozen. It carries no `locale`, `labels` or
|
|
289
|
+
`sourceTypeConfigs`, so `{ ...defaultDailyReportClientConfig, locale: "ja" }` renders Japanese. The
|
|
290
|
+
resolved configuration from `useDailyReportConfig()` is output only: spreading it into `config`
|
|
291
|
+
would pin its labels as overrides.
|
|
292
|
+
- **Unknown authors**: a comment whose author name is unknown — a legacy comment without a name, a
|
|
293
|
+
relational comment with an empty `userName`, the pending comment of a viewing user without any name
|
|
294
|
+
or email — shows `labels.unknownUser`. The server never sends a fixed fallback name (an author
|
|
295
|
+
without a display name is sent as `""`).
|
|
296
|
+
- **`labels` must be a plain object** (prototype `Object.prototype` or `null`); arrays, class
|
|
297
|
+
instances and objects created with `Object.create(proto)` throw a `RangeError`. Only own properties
|
|
298
|
+
are read, so a label key inherited from a polluted `Object.prototype` is never applied. Error
|
|
299
|
+
messages describe the rejected value without throwing (a string as JSON, `null`, otherwise only its
|
|
300
|
+
`typeof` tag).
|
|
301
|
+
- **No language negotiation**: the package never reads `navigator.language`; map it to a supported
|
|
302
|
+
value yourself. No `lang` attribute is stamped either — the document language belongs to the host.
|
|
303
|
+
- **Not tied to `locale`**: `draftLabelName` (a label name stored in the database) and
|
|
304
|
+
`sourceTypeConfigs` (host data). Only the built-in default badge map used when `sourceTypeConfigs`
|
|
305
|
+
is omitted takes its `Internal` label from `labels.sourceInternal`.
|
|
306
|
+
- **Host notifications**: `config.onError` receives `DailyReportErrorInfo` with the stable
|
|
307
|
+
`operation` key and `message` = `labels.operationFailed(operation)` in the chosen locale.
|
|
308
|
+
- **`locale` is the only language axis.** This package has no BCP 47 `formatLocale` option: digit
|
|
309
|
+
grouping follows `locale` (`en` → `"en-US"`, `ja` → `"ja-JP"`) and dates stay in ISO form. Packages
|
|
310
|
+
that do format dates (for example `@aiquants/period-slider`) name that separate axis `formatLocale`.
|
|
311
|
+
|
|
312
|
+
Exported API (`@aiquants/daily-report/client`): `DAILY_REPORT_LABEL_KEYS` (all 88 keys, engine keys
|
|
313
|
+
first), `DAILY_REPORT_LABEL_CATALOGS` (the frozen catalogs), `resolveDailyReportLabels(locale, labels)`
|
|
314
|
+
(the effective frozen labels — the catalog object itself when `labels` is `undefined`), the resolved
|
|
315
|
+
`locale` / `labels` on `useDailyReportConfig()`, and the types `DailyReportLocale` (= `VirtualScrollLocale`),
|
|
316
|
+
`DailyReportLabels`, `DailyReportLabelOverrides` and `DailyReportOperation`.
|
|
317
|
+
|
|
318
|
+
| Key | Where it appears | `en` | `ja` |
|
|
319
|
+
| --- | --- | --- | --- |
|
|
320
|
+
| `scrollUp` | engine: vertical ScrollBar up arrow (`aria-label`) | Scroll up | 上へスクロール |
|
|
321
|
+
| `scrollDown` | engine: vertical ScrollBar down arrow (`aria-label`) | Scroll down | 下へスクロール |
|
|
322
|
+
| `scrollLeft` | engine: horizontal arrow (not rendered by this package) | Scroll left | 左へスクロール |
|
|
323
|
+
| `scrollRight` | engine: horizontal arrow (not rendered by this package) | Scroll right | 右へスクロール |
|
|
324
|
+
| `scrollToTop` | engine: top pill (not enabled by this package) | Top | 先頭へ |
|
|
325
|
+
| `scrollToBottom` | engine: bottom pill (not enabled by this package) | Bottom | 末尾へ |
|
|
326
|
+
| `noItems` | engine: empty list text | No items | 項目がありません |
|
|
327
|
+
| `id` | DetailList card: id chip | ID | ID |
|
|
328
|
+
| `businessDate` | business date heading | Business date | 営業日 |
|
|
329
|
+
| `author` | author heading | Author | 作成者 |
|
|
330
|
+
| `visitTime` | visit time heading | Visit time | 訪問時間 |
|
|
331
|
+
| `createdAt` | created-at heading | Created at | 作成日時 |
|
|
332
|
+
| `updatedAt` | updated-at heading | Updated at | 更新日時 |
|
|
333
|
+
| `updatedBy` | updated-by heading | Updated by | 更新者 |
|
|
334
|
+
| `category` | category chip / `category: value` prefix | Category | 区分 |
|
|
335
|
+
| `categoryInfo` | metadata panel: category block heading | Category | 区分情報 |
|
|
336
|
+
| `creationCategory` | `creationCategory: value` prefix | Creation category | 作成区分 |
|
|
337
|
+
| `customer` | customer heading | Customer | 顧客 |
|
|
338
|
+
| `subject` | subject heading | Subject | 件名 |
|
|
339
|
+
| `content` | content heading | Content | 内容 |
|
|
340
|
+
| `interviewers` | interviewer list heading | Attendees | 面談者 |
|
|
341
|
+
| `comments` | comment section heading | Comments | コメント |
|
|
342
|
+
| `attachments` | attachment section heading, attachment marker name | Attachments | 添付ファイル |
|
|
343
|
+
| `attachmentMissing` | note on a missing attachment | File is missing | 実体が見つかりません |
|
|
344
|
+
| `attachmentDownload` | attachment download link | Download | ダウンロード |
|
|
345
|
+
| `tabArticle` | side pane tab | Overview | 概要 |
|
|
346
|
+
| `tabRelations` | side pane tab | Related | 関連 |
|
|
347
|
+
| `relationsEmpty` | side pane related tab body | No related view configured yet. | 関連ビューはまだ構成されていません。 |
|
|
348
|
+
| `title` | `renderHeader({ title })`, both lists' `aria-label` | Daily Reports | 日報 |
|
|
349
|
+
| `tabList` | top-level tab | 📄 List | 📄 一覧 |
|
|
350
|
+
| `tabTree` | top-level tab | 🌳 Tree | 🌳 ツリー |
|
|
351
|
+
| `tabDetailList` | top-level tab | 📋 DetailList | 📋 詳細一覧 |
|
|
352
|
+
| `treeComingSoon` | tree tab body | The tree view is coming soon | ツリーは現在準備中です |
|
|
353
|
+
| `totalCountLoading` | header annotation while loading | Total: loading... | 総件数: 読み込み中... |
|
|
354
|
+
| `createReport` | create button | New report | 日報作成 |
|
|
355
|
+
| `createReportTitle` | create button tooltip | Create a daily report | 日報を作成 |
|
|
356
|
+
| `devControls` | dev toolbox tooltip (`showDevControls`) | Development-only controls | 開発環境限定コントロール |
|
|
357
|
+
| `devSseToggle` | dev toolbox: SSE switch tooltip | Toggle SSE real-time sync | SSE リアルタイム同期切替 |
|
|
358
|
+
| `devReload` | dev toolbox: reload tooltip | Reload data | データ再取得 (リロード) |
|
|
359
|
+
| `devClearCache` | dev toolbox: clear-cache tooltip | Clear the cache and reload | キャッシュ破棄 & 再取得 |
|
|
360
|
+
| `autoRead` | auto-read switch label | Auto-read | 自動既読 |
|
|
361
|
+
| `autoReadTitle` | auto-read switch tooltip | Mark reports as read automatically while viewing them | 日報閲覧時の自動既読処理切替 |
|
|
362
|
+
| `loadErrorBadge` | header annotation on load failure | Error | エラー |
|
|
363
|
+
| `loadError` | load-failure screen | Failed to load the daily reports. | 日報データの読み込みに失敗しました。 |
|
|
364
|
+
| `reload` | load-failure screen button | Reload | 再読み込み |
|
|
365
|
+
| `loadingIds` | loading screen | Loading report IDs... | 日報 ID を読み込み中です... |
|
|
366
|
+
| `streamFailed` | stream badge (failed) | Failed to load | 読み込みに失敗しました |
|
|
367
|
+
| `streamRetry` | stream badge retry button | Retry | 再試行 |
|
|
368
|
+
| `streamRevalidating` | stream badge (revalidating) | Refreshing | 最新化中 |
|
|
369
|
+
| `listEmpty` | package empty state under an empty list | No data | データがありません |
|
|
370
|
+
| `selectPrompt` | side pane without a selection | Select a report from the list on the left. | 左側の一覧から日報を選択してください。 |
|
|
371
|
+
| `loading` | side pane loading (edit mode) | Loading... | 読み込み中... |
|
|
372
|
+
| `reportNotFound` | list card of a vanished report | Report not found | 日報が見つかりません |
|
|
373
|
+
| `contentEmpty` | side pane: report without content | No content has been entered. | 内容は登録されていません。 |
|
|
374
|
+
| `contentEmptyPreview` | list card preview: report without content | No content has been entered | 内容は登録されていません |
|
|
375
|
+
| `confirmDelete` | `confirm()` before deleting a report | Are you sure you want to delete this report? | 本当に削除しますか? |
|
|
376
|
+
| `deleteFailed` | `alert()` after a failed delete | Failed to delete the report | 削除に失敗しました |
|
|
377
|
+
| `starAdd` | star toggle (unstarred) | Add star | スターを付ける |
|
|
378
|
+
| `starRemove` | star toggle (starred) | Remove star | スターを外す |
|
|
379
|
+
| `markRead` | read toggle (unread) | Mark as read | 既読にする |
|
|
380
|
+
| `markUnread` | read toggle (read) | Mark as unread | 未読にする |
|
|
381
|
+
| `deleteReport` | report delete button | Delete | 削除する |
|
|
382
|
+
| `resizeHandle` | list / detail resize handle `aria-label` | Resize the border between the report list and the detail pane | 日報一覧と詳細ペインの境界のサイズ変更ハンドル |
|
|
383
|
+
| `overlayBackdrop` | mobile overlay backdrop `aria-label` | Tap the background to close | 背景をタップして閉じる |
|
|
384
|
+
| `overlayDialog` | mobile detail dialog `aria-label` | Report details | 日報詳細 |
|
|
385
|
+
| `close` | mobile overlay close button, error banner close `aria-label` | Close | 閉じる |
|
|
386
|
+
| `formTitle` | edit form | Title | タイトル |
|
|
387
|
+
| `formTitlePlaceholder` | edit form | Enter the report title | 日報のタイトルを入力 |
|
|
388
|
+
| `formContent` | edit form | Content | 内容 |
|
|
389
|
+
| `formContentPlaceholder` | edit form | Enter the report content | 日報の内容を入力 |
|
|
390
|
+
| `formCancel` | edit form | Cancel | キャンセル |
|
|
391
|
+
| `formSave` | edit form | Save | 保存 |
|
|
392
|
+
| `formPublish` | edit form | Publish | 公開 |
|
|
393
|
+
| `commentPlaceholder` | comment form | Add a comment... | コメントを追加... |
|
|
394
|
+
| `commentSend` | comment form | Send | 送信 |
|
|
395
|
+
| `commentDelete` | comment trash button (`aria-label` / tooltip) | Delete comment | 削除 |
|
|
396
|
+
| `commentDeleteConfirm` | comment delete confirmation | Delete | 削除する |
|
|
397
|
+
| `unknownUser` | author name when none is known (legacy / relational comment without a name, optimistic data of a user without a name) | Unknown | 不明なユーザー |
|
|
398
|
+
| `sourceInternal` | built-in `Internal` badge (only when `sourceTypeConfigs` is omitted) | Original | オリジナル |
|
|
399
|
+
| `totalCount` | header annotation | `(1234)` → Total: 1,234 | `(1234)` → 総件数: 1,234 件 |
|
|
400
|
+
| `debounce` | header annotation | `(300)` → Debounce: 300 ms | `(300)` → デバウンス: 300 ms |
|
|
401
|
+
| `streamProgressCount` | stream badge before the total is known | `(1234)` → Loading 1,234 | `(1234)` → 読み込み中 1,234 件 |
|
|
402
|
+
| `streamProgressRatio` | stream badge once the total is known | `(1234, 5000, 25)` → Loading 1,234 / 5,000 (25%) | `(1234, 5000, 25)` → 読み込み中 1,234 / 5,000 (25%) |
|
|
403
|
+
| `streamRetrying` | stream badge (reconnecting) | `(1234)` → Reconnecting... (1,234 received) | `(1234)` → 再接続中... (1,234 件受信済) |
|
|
404
|
+
| `reportLoadFailed` | detail load failure (side pane, DetailList card) | `(12345)` → Failed to load report 12,345. | `(12345)` → 日報 12,345 の読み込みに失敗しました。 |
|
|
405
|
+
| `reportSummaryLoadFailed` | list card load failure | `(12345)` → Failed to load the summary of report 12,345. | `(12345)` → 日報 12,345 の概要読み込みに失敗しました。 |
|
|
406
|
+
| `interviewerWithAffiliation` | interviewer chip | `("Sato", "Acme")` → Sato (Acme) | `("佐藤", "三和")` → 佐藤 (三和) |
|
|
407
|
+
| `operationFailed` | error banner / `DailyReportErrorInfo.message` | `("update")` → Failed to save the report. Please try again later. | `("update")` → 日報の保存に失敗しました。時間をおいて再度お試しください。 |
|
|
408
|
+
|
|
409
|
+
#### Migrating from 0.20.x (breaking changes in 0.21.0)
|
|
410
|
+
|
|
411
|
+
0.21.0 is a clean cut-over: there are no aliases for the removed names. It needs the peer
|
|
412
|
+
`@aiquants/virtualscroll` 3.7.0 or later (the engine label catalog it reuses).
|
|
413
|
+
|
|
414
|
+
1. **The default UI language is English.** The Japanese wording that used to be hard-coded in the
|
|
415
|
+
components (buttons, placeholders, confirmation dialogs, status badges, loading / error screens,
|
|
416
|
+
the failure banner) now renders in English when `locale` is omitted. A host that relies on the
|
|
417
|
+
Japanese chrome must opt in with `config.locale: "ja"`. The ja catalog keeps the former Japanese
|
|
418
|
+
wording except four values aligned with the shared `@aiquants` vocabulary: `treeComingSoon`
|
|
419
|
+
(`ツリーは現在準備中です`), `resizeHandle` (`日報一覧と詳細ペインの境界のサイズ変更ハンドル`),
|
|
420
|
+
`unknownUser` (`不明なユーザー`, formerly `"Unknown"` / `不明`) and `interviewerWithAffiliation`
|
|
421
|
+
(half-width parentheses: `佐藤 (三和)`).
|
|
422
|
+
2. **`config.fieldLabels` → `config.labels`** (the same 21 keys). The type `DailyReportFieldLabels`
|
|
423
|
+
and the value `defaultDailyReportFieldLabels` are removed; use `DailyReportLabels` /
|
|
424
|
+
`DAILY_REPORT_LABEL_CATALOGS[locale]`. A leftover `fieldLabels` key throws a `RangeError` at
|
|
425
|
+
render, even inside a `useMemo` config that TypeScript does not flag.
|
|
426
|
+
3. **`config.title` → `config.labels.title`** (en `"Daily Reports"`, ja `"日報"`). It is still what
|
|
427
|
+
`renderHeader({ title })` receives and the accessible name of both lists. A leftover `title` key
|
|
428
|
+
throws a `RangeError` at render.
|
|
429
|
+
4. **Adding only `locale: "ja"` replaces your vocabulary with the catalog's.** The ja catalog carries
|
|
430
|
+
neutral headings (`顧客`, `内容`, `コメント`, `概要`, `関連`, ...). Move the domain wording you used to
|
|
431
|
+
pass in `fieldLabels` into `labels` in the same change, e.g.
|
|
432
|
+
`{ locale: "ja", labels: { customer: "顧客・面談先", content: "商談内容", comments: "コメント一覧", tabArticle: "記事", tabRelations: "相関" } }`.
|
|
433
|
+
5. **`locale: "ja"` also translates what used to stay English**: the top-level tabs (`📄 一覧` /
|
|
434
|
+
`🌳 ツリー` / `📋 詳細一覧`), the page title (`日報`), the load-error badge (`エラー`), the side-pane
|
|
435
|
+
tabs (`概要` / `関連`), the scroll arrows (`上へスクロール` / `下へスクロール`) and the empty state
|
|
436
|
+
(`項目がありません`). Keep the English form through `labels`, e.g.
|
|
437
|
+
`labels: { tabList: "📄 List", tabDetailList: "📋 DetailList" }`.
|
|
438
|
+
6. **Resolved config shape**: `DailyReportClientConfig` (the value of `useDailyReportConfig()`) loses
|
|
439
|
+
`title` / `fieldLabels`, gains the resolved `locale` / `labels`, and `sourceTypeConfigs` is always
|
|
440
|
+
present (the built-in default when omitted).
|
|
441
|
+
7. **`defaultDailyReportClientConfig`** is now the frozen, locale-independent input
|
|
442
|
+
`DailyReportClientConfigDefaults` (`apiBasePath`, `ssePath`, `draftLabelName`, `renderHeader`,
|
|
443
|
+
`showDevControls`). It no longer has `title`, `fieldLabels` or `sourceTypeConfigs`; read resolved
|
|
444
|
+
values through `useDailyReportConfig()`.
|
|
445
|
+
8. **Built-in `Internal` badge**: when `sourceTypeConfigs` is omitted, its label is
|
|
446
|
+
`labels.sourceInternal` — en `"Original"` (formerly always `オリジナル`), ja `"オリジナル"`.
|
|
447
|
+
9. **`DailyReportErrorInfo`**: `operation` is narrowed from `string` to `DailyReportOperation`, and
|
|
448
|
+
`message` is `labels.operationFailed(operation)` in the chosen locale (English by default).
|
|
449
|
+
10. **`mergeComments(legacyComments, modernComments, currentUserId, unknownAuthorName)`** (root
|
|
450
|
+
export): the fourth argument is new and required, `currentUserId` is no longer optional (pass
|
|
451
|
+
`undefined` to keep the server's `isMine`), and a blank or non-string `unknownAuthorName` throws a
|
|
452
|
+
`RangeError`. A comment without an author name (legacy `name` or relational `userName` that is
|
|
453
|
+
empty, `null` or missing) gets `unknownAuthorName`; the client passes `labels.unknownUser`.
|
|
454
|
+
11. **Server `addComment`**: the SSE `comment-add` payload sends `userName: ""` (formerly `"Unknown"`)
|
|
455
|
+
for an author without a display name, like the read paths; the client renders
|
|
456
|
+
`labels.unknownUser`. Comments with an empty author name show `labels.unknownUser` instead of `-`.
|
|
457
|
+
12. **List side-pane load error** renders `labels.reportLoadFailed(reportHubId)` instead of the
|
|
458
|
+
exception message (the same text as the DetailList).
|
|
459
|
+
13. **Explicit `undefined`** for `apiBasePath` / `ssePath` / `draftLabelName` / `showDevControls` /
|
|
460
|
+
`renderHeader` now resolves to the default (it used to override the default with `undefined`).
|
|
461
|
+
|
|
462
|
+
Unchanged: `draftLabelName` (label data stored in the database) does not follow `locale`, and dates
|
|
463
|
+
keep their ISO form.
|
|
243
464
|
|
|
244
465
|
### External Source Badge Configuration (`sourceTypeConfigs`)
|
|
245
466
|
|
|
@@ -310,7 +531,7 @@ export default defineConfig({
|
|
|
310
531
|
## API Surface (Summary)
|
|
311
532
|
|
|
312
533
|
- **server**: `createDailyReportServer` / `createDailyReportService` / `createDailyReportHandlers` / `defineDailyReportSchema` / `DailyReportSseReader` / `SqlResultCache` / `transformJsonArray` / `jsonResponseWithETag` / `generateETag` / `isStreamIdLte`
|
|
313
|
-
- **client**: `DailyReportPage` / `DailyReportResolvedContent` / `DailyReportList` / `DailyReportDetailList` / `DailyReportActionProvider` / `useDailyReportActionContext` / `useDailyReportDetail` / `useDailyReportPrefetch` / `useDailyReportComments` / `useDailyReportSseConnection` / `useDailyReportIdsStream` / `DailyReportIdsStreamStatus` / `DailyReportIdsStreamClient` / `DailyReportConfigProvider` / `createDailyReportClientLoader` / `dailyReportShouldRevalidate`
|
|
314
|
-
- **shared**: `DailyReportItem` / `DailyReportDetail` / `DailyReportUser` / `dailyReportSseMessageSchema` (8 discriminated union types) / `normalizeBusinessDateKey` / `mergeComments`
|
|
534
|
+
- **client**: `DailyReportPage` / `DailyReportResolvedContent` / `DailyReportList` / `DailyReportDetailList` / `DailyReportActionProvider` / `useDailyReportActionContext` / `useDailyReportDetail` / `useDailyReportPrefetch` / `useDailyReportComments` / `useDailyReportSseConnection` / `useDailyReportIdsStream` / `DailyReportIdsStreamStatus` / `DailyReportIdsStreamClient` / `DailyReportConfigProvider` / `useDailyReportConfig` / `defaultDailyReportClientConfig` / `resolveDailyReportLabels` / `DAILY_REPORT_LABEL_CATALOGS` / `DAILY_REPORT_LABEL_KEYS` / `createDailyReportClientLoader` / `dailyReportShouldRevalidate`
|
|
535
|
+
- **shared**: `DailyReportItem` / `DailyReportDetail` / `DailyReportUser` / `dailyReportSseMessageSchema` (8 discriminated union types) / `normalizeBusinessDateKey` / `mergeComments(legacyComments, modernComments, currentUserId, unknownAuthorName)`
|
|
315
536
|
|
|
316
537
|
MIT
|
package/dist/client.d.mts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as react from "react";
|
|
2
2
|
import { RefObject, ReactNode, Context } from "react";
|
|
3
|
-
import { ScrollBarThumbOverlayRenderProps, ScrollPaneInertiaOptions, ScrollBarTapCircleOptions } from "@aiquants/virtualscroll";
|
|
3
|
+
import { ScrollBarThumbOverlayRenderProps, VirtualScrollLocale, VirtualScrollLabels, ScrollPaneInertiaOptions, ScrollBarTapCircleOptions } from "@aiquants/virtualscroll";
|
|
4
4
|
import { D as DailyReportAttachmentSummary, a as DailyReportItem, b as DailyReportDetail, c as DailyReportUser } from "./types-CqgYQgbH.mjs";
|
|
5
|
-
import { U as UIComment, D as DailyReportSseMessage } from "./sse-schema-
|
|
5
|
+
import { U as UIComment, D as DailyReportSseMessage } from "./sse-schema-DCxpdETM.mjs";
|
|
6
6
|
import { ShouldRevalidateFunction } from "react-router";
|
|
7
7
|
import "zod";
|
|
8
8
|
declare const BusinessDayThumbOverlay: ({ orientation, thumbCenter, label, isDragging, isTapScrollActive, isWheelScrollActive }: ScrollBarThumbOverlayRenderProps & {
|
|
@@ -78,35 +78,192 @@ type DailyReportListProps = {
|
|
|
78
78
|
scrollOffsetRef?: RefObject<number>;
|
|
79
79
|
};
|
|
80
80
|
declare const DailyReportList: ({ dailyReportItems, autoMarkRead, selectedReportHubId, onSelectItem, userId, scrollOffsetRef }: DailyReportListProps) => react.JSX.Element;
|
|
81
|
+
type DailyReportLocale = VirtualScrollLocale;
|
|
82
|
+
type DailyReportOperation = "create" | "update" | "publish" | "delete" | "addComment" | "deleteComment" | "toggleStar" | "toggleRead";
|
|
83
|
+
type DailyReportLabels = VirtualScrollLabels & {
|
|
84
|
+
readonly id: string;
|
|
85
|
+
readonly businessDate: string;
|
|
86
|
+
readonly author: string;
|
|
87
|
+
readonly visitTime: string;
|
|
88
|
+
readonly createdAt: string;
|
|
89
|
+
readonly updatedAt: string;
|
|
90
|
+
readonly updatedBy: string;
|
|
91
|
+
readonly category: string;
|
|
92
|
+
readonly categoryInfo: string;
|
|
93
|
+
readonly creationCategory: string;
|
|
94
|
+
readonly customer: string;
|
|
95
|
+
readonly subject: string;
|
|
96
|
+
readonly content: string;
|
|
97
|
+
readonly interviewers: string;
|
|
98
|
+
readonly comments: string;
|
|
99
|
+
readonly attachments: string;
|
|
100
|
+
readonly attachmentMissing: string;
|
|
101
|
+
readonly attachmentDownload: string;
|
|
102
|
+
readonly tabArticle: string;
|
|
103
|
+
readonly tabRelations: string;
|
|
104
|
+
readonly relationsEmpty: string;
|
|
105
|
+
readonly title: string;
|
|
106
|
+
readonly tabList: string;
|
|
107
|
+
readonly tabTree: string;
|
|
108
|
+
readonly tabDetailList: string;
|
|
109
|
+
readonly treeComingSoon: string;
|
|
110
|
+
readonly totalCountLoading: string;
|
|
111
|
+
readonly createReport: string;
|
|
112
|
+
readonly createReportTitle: string;
|
|
113
|
+
readonly devControls: string;
|
|
114
|
+
readonly devSseToggle: string;
|
|
115
|
+
readonly devReload: string;
|
|
116
|
+
readonly devClearCache: string;
|
|
117
|
+
readonly autoRead: string;
|
|
118
|
+
readonly autoReadTitle: string;
|
|
119
|
+
readonly loadErrorBadge: string;
|
|
120
|
+
readonly loadError: string;
|
|
121
|
+
readonly reload: string;
|
|
122
|
+
readonly loadingIds: string;
|
|
123
|
+
readonly streamFailed: string;
|
|
124
|
+
readonly streamRetry: string;
|
|
125
|
+
readonly streamRevalidating: string;
|
|
126
|
+
readonly listEmpty: string;
|
|
127
|
+
readonly selectPrompt: string;
|
|
128
|
+
readonly loading: string;
|
|
129
|
+
readonly reportNotFound: string;
|
|
130
|
+
readonly contentEmpty: string;
|
|
131
|
+
readonly contentEmptyPreview: string;
|
|
132
|
+
readonly confirmDelete: string;
|
|
133
|
+
readonly deleteFailed: string;
|
|
134
|
+
readonly starAdd: string;
|
|
135
|
+
readonly starRemove: string;
|
|
136
|
+
readonly markRead: string;
|
|
137
|
+
readonly markUnread: string;
|
|
138
|
+
readonly deleteReport: string;
|
|
139
|
+
readonly resizeHandle: string;
|
|
140
|
+
readonly overlayBackdrop: string;
|
|
141
|
+
readonly overlayDialog: string;
|
|
142
|
+
readonly close: string;
|
|
143
|
+
readonly formTitle: string;
|
|
144
|
+
readonly formTitlePlaceholder: string;
|
|
145
|
+
readonly formContent: string;
|
|
146
|
+
readonly formContentPlaceholder: string;
|
|
147
|
+
readonly formCancel: string;
|
|
148
|
+
readonly formSave: string;
|
|
149
|
+
readonly formPublish: string;
|
|
150
|
+
readonly commentPlaceholder: string;
|
|
151
|
+
readonly commentSend: string;
|
|
152
|
+
readonly commentDelete: string;
|
|
153
|
+
readonly commentDeleteConfirm: string;
|
|
154
|
+
readonly unknownUser: string;
|
|
155
|
+
readonly sourceInternal: string;
|
|
156
|
+
readonly totalCount: (count: number) => string;
|
|
157
|
+
readonly debounce: (milliseconds: number) => string;
|
|
158
|
+
readonly streamProgressCount: (loaded: number) => string;
|
|
159
|
+
readonly streamProgressRatio: (loaded: number, total: number, percent: number) => string;
|
|
160
|
+
readonly streamRetrying: (loaded: number) => string;
|
|
161
|
+
readonly reportLoadFailed: (reportHubId: number) => string;
|
|
162
|
+
readonly reportSummaryLoadFailed: (reportHubId: number) => string;
|
|
163
|
+
readonly interviewerWithAffiliation: (name: string, affiliation: string) => string;
|
|
164
|
+
readonly operationFailed: (operation: DailyReportOperation) => string;
|
|
165
|
+
};
|
|
166
|
+
type DailyReportLabelOverrides = {
|
|
167
|
+
readonly [K in keyof DailyReportLabels]?: DailyReportLabels[K];
|
|
168
|
+
};
|
|
169
|
+
declare const DAILY_REPORT_LABEL_KEYS: readonly [
|
|
170
|
+
"scrollUp",
|
|
171
|
+
"scrollDown",
|
|
172
|
+
"scrollLeft",
|
|
173
|
+
"scrollRight",
|
|
174
|
+
"scrollToTop",
|
|
175
|
+
"scrollToBottom",
|
|
176
|
+
"noItems",
|
|
177
|
+
"id",
|
|
178
|
+
"businessDate",
|
|
179
|
+
"author",
|
|
180
|
+
"visitTime",
|
|
181
|
+
"createdAt",
|
|
182
|
+
"updatedAt",
|
|
183
|
+
"updatedBy",
|
|
184
|
+
"category",
|
|
185
|
+
"categoryInfo",
|
|
186
|
+
"creationCategory",
|
|
187
|
+
"customer",
|
|
188
|
+
"subject",
|
|
189
|
+
"content",
|
|
190
|
+
"interviewers",
|
|
191
|
+
"comments",
|
|
192
|
+
"attachments",
|
|
193
|
+
"attachmentMissing",
|
|
194
|
+
"attachmentDownload",
|
|
195
|
+
"tabArticle",
|
|
196
|
+
"tabRelations",
|
|
197
|
+
"relationsEmpty",
|
|
198
|
+
"title",
|
|
199
|
+
"tabList",
|
|
200
|
+
"tabTree",
|
|
201
|
+
"tabDetailList",
|
|
202
|
+
"treeComingSoon",
|
|
203
|
+
"totalCountLoading",
|
|
204
|
+
"createReport",
|
|
205
|
+
"createReportTitle",
|
|
206
|
+
"devControls",
|
|
207
|
+
"devSseToggle",
|
|
208
|
+
"devReload",
|
|
209
|
+
"devClearCache",
|
|
210
|
+
"autoRead",
|
|
211
|
+
"autoReadTitle",
|
|
212
|
+
"loadErrorBadge",
|
|
213
|
+
"loadError",
|
|
214
|
+
"reload",
|
|
215
|
+
"loadingIds",
|
|
216
|
+
"streamFailed",
|
|
217
|
+
"streamRetry",
|
|
218
|
+
"streamRevalidating",
|
|
219
|
+
"listEmpty",
|
|
220
|
+
"selectPrompt",
|
|
221
|
+
"loading",
|
|
222
|
+
"reportNotFound",
|
|
223
|
+
"contentEmpty",
|
|
224
|
+
"contentEmptyPreview",
|
|
225
|
+
"confirmDelete",
|
|
226
|
+
"deleteFailed",
|
|
227
|
+
"starAdd",
|
|
228
|
+
"starRemove",
|
|
229
|
+
"markRead",
|
|
230
|
+
"markUnread",
|
|
231
|
+
"deleteReport",
|
|
232
|
+
"resizeHandle",
|
|
233
|
+
"overlayBackdrop",
|
|
234
|
+
"overlayDialog",
|
|
235
|
+
"close",
|
|
236
|
+
"formTitle",
|
|
237
|
+
"formTitlePlaceholder",
|
|
238
|
+
"formContent",
|
|
239
|
+
"formContentPlaceholder",
|
|
240
|
+
"formCancel",
|
|
241
|
+
"formSave",
|
|
242
|
+
"formPublish",
|
|
243
|
+
"commentPlaceholder",
|
|
244
|
+
"commentSend",
|
|
245
|
+
"commentDelete",
|
|
246
|
+
"commentDeleteConfirm",
|
|
247
|
+
"unknownUser",
|
|
248
|
+
"sourceInternal",
|
|
249
|
+
"totalCount",
|
|
250
|
+
"debounce",
|
|
251
|
+
"streamProgressCount",
|
|
252
|
+
"streamProgressRatio",
|
|
253
|
+
"streamRetrying",
|
|
254
|
+
"reportLoadFailed",
|
|
255
|
+
"reportSummaryLoadFailed",
|
|
256
|
+
"interviewerWithAffiliation",
|
|
257
|
+
"operationFailed"
|
|
258
|
+
];
|
|
259
|
+
declare const DAILY_REPORT_LABEL_CATALOGS: Readonly<Record<DailyReportLocale, DailyReportLabels>>;
|
|
260
|
+
declare const resolveDailyReportLabels: (locale: DailyReportLocale | undefined, overrides: DailyReportLabelOverrides | undefined) => DailyReportLabels;
|
|
81
261
|
type DailyReportHeaderProps = {
|
|
82
262
|
title: string;
|
|
83
263
|
annotation?: ReactNode;
|
|
84
264
|
};
|
|
85
|
-
type DailyReportFieldLabels = {
|
|
86
|
-
id: string;
|
|
87
|
-
businessDate: string;
|
|
88
|
-
author: string;
|
|
89
|
-
visitTime: string;
|
|
90
|
-
createdAt: string;
|
|
91
|
-
updatedAt: string;
|
|
92
|
-
updatedBy: string;
|
|
93
|
-
category: string;
|
|
94
|
-
categoryInfo: string;
|
|
95
|
-
creationCategory: string;
|
|
96
|
-
customer: string;
|
|
97
|
-
subject: string;
|
|
98
|
-
content: string;
|
|
99
|
-
interviewers: string;
|
|
100
|
-
comments: string;
|
|
101
|
-
attachments: string;
|
|
102
|
-
attachmentMissing: string;
|
|
103
|
-
attachmentDownload: string;
|
|
104
|
-
tabArticle: string;
|
|
105
|
-
tabRelations: string;
|
|
106
|
-
relationsEmpty: string;
|
|
107
|
-
};
|
|
108
265
|
type DailyReportErrorInfo = {
|
|
109
|
-
operation:
|
|
266
|
+
operation: DailyReportOperation;
|
|
110
267
|
message: string;
|
|
111
268
|
cause?: unknown;
|
|
112
269
|
};
|
|
@@ -116,22 +273,22 @@ type SourceTypeConfig = {
|
|
|
116
273
|
allowComment?: boolean;
|
|
117
274
|
};
|
|
118
275
|
type DailyReportClientConfig = {
|
|
119
|
-
title: string;
|
|
120
276
|
apiBasePath: string;
|
|
121
277
|
ssePath: string;
|
|
122
278
|
draftLabelName: string;
|
|
123
|
-
|
|
124
|
-
|
|
279
|
+
locale: DailyReportLocale;
|
|
280
|
+
labels: DailyReportLabels;
|
|
281
|
+
sourceTypeConfigs: Record<string, SourceTypeConfig>;
|
|
125
282
|
renderHeader: (props: DailyReportHeaderProps) => ReactNode;
|
|
126
283
|
showDevControls: boolean;
|
|
127
284
|
onError?: (info: DailyReportErrorInfo) => void;
|
|
128
285
|
};
|
|
129
|
-
type DailyReportClientConfigInput = Partial<Omit<DailyReportClientConfig, "
|
|
130
|
-
|
|
131
|
-
|
|
286
|
+
type DailyReportClientConfigInput = Partial<Omit<DailyReportClientConfig, "locale" | "labels">> & {
|
|
287
|
+
locale?: DailyReportLocale;
|
|
288
|
+
labels?: DailyReportLabelOverrides;
|
|
132
289
|
};
|
|
133
|
-
|
|
134
|
-
declare const defaultDailyReportClientConfig:
|
|
290
|
+
type DailyReportClientConfigDefaults = Readonly<Pick<DailyReportClientConfig, "apiBasePath" | "ssePath" | "draftLabelName" | "renderHeader" | "showDevControls">>;
|
|
291
|
+
declare const defaultDailyReportClientConfig: DailyReportClientConfigDefaults;
|
|
135
292
|
declare const DailyReportConfigProvider: ({ config, children }: {
|
|
136
293
|
config?: DailyReportClientConfigInput;
|
|
137
294
|
children: ReactNode;
|
|
@@ -400,4 +557,4 @@ declare const CONTENT_DRAG_POINTER_INPUTS: readonly [
|
|
|
400
557
|
"pen",
|
|
401
558
|
"touch"
|
|
402
559
|
];
|
|
403
|
-
export { BusinessDayThumbOverlay, CONTENT_DRAG_POINTER_INPUTS, DAILY_REPORT_FETCH_DEBOUNCE_MS, DEFAULT_ITEM_HEIGHT, type DailyReportActionContextType, DailyReportActionProvider, DailyReportAttachmentIndicator, DailyReportAttachmentList, DailyReportCache, type DailyReportClientConfig, type DailyReportClientConfigInput, DailyReportCommentForm, DailyReportCommentList, DailyReportConfigProvider, DailyReportDetailList, type DailyReportDetailListScrollRestore, type DailyReportDetailResource, DailyReportEditForm, type DailyReportErrorInfo, DailyReportErrorProvider, type
|
|
560
|
+
export { BusinessDayThumbOverlay, CONTENT_DRAG_POINTER_INPUTS, DAILY_REPORT_FETCH_DEBOUNCE_MS, DAILY_REPORT_LABEL_CATALOGS, DAILY_REPORT_LABEL_KEYS, DEFAULT_ITEM_HEIGHT, type DailyReportActionContextType, DailyReportActionProvider, DailyReportAttachmentIndicator, DailyReportAttachmentList, DailyReportCache, type DailyReportClientConfig, type DailyReportClientConfigDefaults, type DailyReportClientConfigInput, DailyReportCommentForm, DailyReportCommentList, DailyReportConfigProvider, DailyReportDetailList, type DailyReportDetailListScrollRestore, type DailyReportDetailResource, DailyReportEditForm, type DailyReportErrorInfo, DailyReportErrorProvider, type DailyReportHeaderProps, DailyReportIdsStreamClient, type DailyReportIdsStreamClientOptions, type DailyReportIdsStreamPhase, type DailyReportIdsStreamState, DailyReportIdsStreamStatus, type DailyReportLabelOverrides, type DailyReportLabels, DailyReportList, DailyReportLoadError, DailyReportLoading, type DailyReportLocale, type DailyReportOperation, DailyReportPage, type DailyReportPageProps, DailyReportPostedComment, DailyReportResolvedContent, EMPTY_DETAIL, EMPTY_ITEM, FAST_SCROLL_INERTIA_OPTIONS, FAST_SCROLL_WHEEL_MULTIPLIER, ITEM_CONTAINER_HEIGHT, ITEM_VERTICAL_PADDING, MAX_PREVIEW_LINES, PREFETCH_LOOKAHEAD, PREFETCH_MAX_DATES, SCROLL_BAR_WIDTH, SSE_INITIAL_CONNECT_DEFER_MS, type SourceTypeConfig, TAP_SCROLL_CIRCLE_OPTIONS, UnreadIndicator, VIRTUAL_SCROLL_OVERSCAN_COUNT, WHEEL_RESET_TIMEOUT_MS, acquireMutationLock, applyBroadcastReportUpdate, applyDailyReportServerUpdates, bootstrapDailyReportIdsStreamSession, clearDailyReportCache, createDailyReportClientLoader, dailyReportShouldRevalidate, defaultDailyReportClientConfig, deleteDailyReportCache, ensureDailyReportIdsStreamSession, getCachedReport, getDailyReportIdsStreamSessionUserKey, primeDailyReportIdsStreamSession, refreshDailyReportIdsStream, registerRecentDeletion, releaseMutationLock, reloadDocument, removeDailyReportIdsStreamItem, resetDailyReportIdsStreamSessionForTesting, resolveDailyReportLabels, resolveSourceTypeConfig, retryDailyReportIdsStream, subscribeCacheReady, updateDailyReportCache, upsertDailyReportIdsStreamItem, useAnimatedNumber, useDailyReportActionContext, useDailyReportComments, useDailyReportConfig, useDailyReportDetail, useDailyReportErrorSurface, useDailyReportIdsStream, useDailyReportPrefetch, useDailyReportSseConnection, useDynamicViewportHeight, writeCache };
|