@aiquants/daily-report 0.1.1
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/LICENSE +21 -0
- package/README.md +150 -0
- package/dist/client.d.mts +449 -0
- package/dist/client.d.ts +449 -0
- package/dist/client.js +7 -0
- package/dist/client.js.map +1 -0
- package/dist/client.mjs +7 -0
- package/dist/client.mjs.map +1 -0
- package/dist/index.d.mts +42 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2 -0
- package/dist/index.mjs.map +1 -0
- package/dist/logger-D3krZrNK.d.mts +29 -0
- package/dist/logger-D3krZrNK.d.ts +29 -0
- package/dist/server.d.mts +1515 -0
- package/dist/server.d.ts +1515 -0
- package/dist/server.js +10 -0
- package/dist/server.js.map +1 -0
- package/dist/server.mjs +10 -0
- package/dist/server.mjs.map +1 -0
- package/dist/sse-schema-CK7cUnEo.d.ts +1986 -0
- package/dist/sse-schema-yl5AaSsj.d.mts +1986 -0
- package/dist/types-CVhwLhSN.d.mts +76 -0
- package/dist/types-CVhwLhSN.d.ts +76 -0
- package/package.json +108 -0
- package/src/client/components/business-day-thumb-overlay.tsx +19 -0
- package/src/client/components/daily-report-comment-item.tsx +81 -0
- package/src/client/components/daily-report-comment-section.tsx +166 -0
- package/src/client/components/daily-report-detail-list.tsx +676 -0
- package/src/client/components/daily-report-edit-form.tsx +81 -0
- package/src/client/components/daily-report-list.tsx +1024 -0
- package/src/client/components/daily-report-page.tsx +147 -0
- package/src/client/components/daily-report-resolved-content.tsx +139 -0
- package/src/client/components/unread-indicator.tsx +13 -0
- package/src/client/config-context.tsx +129 -0
- package/src/client/contexts/daily-report-action-context.tsx +910 -0
- package/src/client/hooks/use-daily-report-comments.ts +73 -0
- package/src/client/hooks/use-daily-report-sse-connection.ts +86 -0
- package/src/client/hooks/use-daily-report.spec.ts +155 -0
- package/src/client/hooks/use-daily-report.ts +426 -0
- package/src/client/hooks/use-dynamic-viewport-height.ts +127 -0
- package/src/client/route-helpers.ts +76 -0
- package/src/client/ui/button.tsx +42 -0
- package/src/client/ui/cn.ts +14 -0
- package/src/client/ui/input.tsx +21 -0
- package/src/client/ui/label.tsx +16 -0
- package/src/client/ui/switch.tsx +19 -0
- package/src/client/ui/tabs.tsx +40 -0
- package/src/client/ui/textarea.tsx +19 -0
- package/src/client/utils/constants.ts +29 -0
- package/src/client.ts +21 -0
- package/src/index.ts +10 -0
- package/src/server/cache.ts +165 -0
- package/src/server/etag.ts +18 -0
- package/src/server/external-source.ts +60 -0
- package/src/server/handlers.ts +543 -0
- package/src/server/ports.ts +68 -0
- package/src/server/response.ts +37 -0
- package/src/server/schema.ts +266 -0
- package/src/server/service.spec.ts +97 -0
- package/src/server/service.ts +1308 -0
- package/src/server/sse-reader.spec.ts +55 -0
- package/src/server/sse-reader.ts +223 -0
- package/src/server.ts +83 -0
- package/src/shared/business-date.spec.ts +61 -0
- package/src/shared/business-date.ts +84 -0
- package/src/shared/comment-adapter.ts +78 -0
- package/src/shared/logger.ts +47 -0
- package/src/shared/sse-schema.ts +147 -0
- package/src/shared/text-utils.ts +57 -0
- package/src/shared/types.ts +76 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 AI Quants
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# @aiquants/daily-report
|
|
2
|
+
|
|
3
|
+
Reusable **daily-report** feature package: a virtual-scrolling report list/detail UI with optimistic updates and SSE real-time sync (React Router v7), plus a drizzle (**mssql**) server layer — all app-specific concerns (auth, user resolution, id obfuscation, redis, legacy tables, chrome) injected via DI ports.
|
|
4
|
+
|
|
5
|
+
Follows the `@aiquants/authz-*` DI layering — every app-specific concern (auth, user resolution, id obfuscation, redis, legacy tables) is injected via ports, so the package itself carries no application- or domain-specific knowledge. Packaged as one module with three entries:
|
|
6
|
+
|
|
7
|
+
| Entry | Contents | Environment |
|
|
8
|
+
| :--- | :--- | :--- |
|
|
9
|
+
| `@aiquants/daily-report` | Types, zod SSE schemas, business-date / text / comment utilities | isomorphic |
|
|
10
|
+
| `@aiquants/daily-report/client` | `DailyReportPage`, list/detail components, hooks, action context, route helpers | browser (React) |
|
|
11
|
+
| `@aiquants/daily-report/server` | `createDailyReportServer` (service + loaders/actions), `defineDailyReportSchema`, SSE fan-out reader, SQL result cache | node |
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
Monorepo (already a pnpm workspace package):
|
|
16
|
+
|
|
17
|
+
```jsonc
|
|
18
|
+
// consumer package.json
|
|
19
|
+
"dependencies": { "@aiquants/daily-report": "workspace:*" }
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
External projects:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pnpm add @aiquants/daily-report react react-dom react-router drizzle-orm zod
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
`react` / `react-dom` / `react-router` / `drizzle-orm` / `zod` are **peer dependencies**. Build / test: `pnpm run build` (tsup → dist) / `pnpm run test` (vitest).
|
|
29
|
+
|
|
30
|
+
### Tailwind CSS
|
|
31
|
+
|
|
32
|
+
Components carry Tailwind utility classes in JSX (no compiled CSS is shipped). Add the package source to your app's Tailwind scan targets:
|
|
33
|
+
|
|
34
|
+
```css
|
|
35
|
+
/* app tailwind.css (Tailwind v4) */
|
|
36
|
+
@source "../node_modules/@aiquants/daily-report/src/**/*.{ts,tsx}";
|
|
37
|
+
/* monorepo: @source "../../../../packages/daily-report/src/**/*.{ts,tsx}"; */
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Required database schema
|
|
41
|
+
|
|
42
|
+
Six tables: `DailyReportHub` (中核・出所横断), `DailyReportInternal` (アプリ内作成本文), `DailyReportComment`, `DailyReportLabel`, `DailyReportHub_Label`, `DailyReportUserStatus` (既読・スター)。
|
|
43
|
+
|
|
44
|
+
Existing apps can inject their own drizzle models (structural typing — see `DailyReportTables`). Greenfield projects can generate definitions:
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
import { defineDailyReportSchema } from "@aiquants/daily-report/server"
|
|
48
|
+
const tables = defineDailyReportSchema("dbo_app", { userTable: Users })
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
`DailyReportHub.source_id_num` is a computed column (`TRY_CAST(source_id AS BIGINT)`), used to join external legacy sources.
|
|
52
|
+
|
|
53
|
+
## Server wiring (DI)
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
// app/services/daily-report/config.server.ts
|
|
57
|
+
import { createDailyReportServer, type DailyReportDb, type DailyReportRedisProvider } from "@aiquants/daily-report/server"
|
|
58
|
+
|
|
59
|
+
export const dailyReportServer = createDailyReportServer({
|
|
60
|
+
db: db as unknown as DailyReportDb, // drizzle mssql handle
|
|
61
|
+
tables: { hub, internal, comment, label, hubLabel, userStatus },
|
|
62
|
+
userTable: Users, // { id, displayName }
|
|
63
|
+
resolveUserId: async (externalId) => {/* 外部 ID (Google sub 等) → 内部数値 ID */},
|
|
64
|
+
encodeUserId: (id) => encodeId(id), // 内部 ID の難読化 (例: sqids)
|
|
65
|
+
authenticate: authenticateInLoader, // (request, { failureRedirect }) => { user?, cookie? }
|
|
66
|
+
redis: redisProvider as unknown as DailyReportRedisProvider, // 省略可 (SSE/epoch 無効化)
|
|
67
|
+
externalSources: [ // 省略可: 別システムのレガシー日報テーブルの取り込み
|
|
68
|
+
{ sourceType: "legacy", table: LegacyReport, idColumn: LegacyReport.reportId, mapRow: mapLegacyRow },
|
|
69
|
+
],
|
|
70
|
+
draftLabelName: "draft", // 必須: 自 DB のドラフトラベル名 (パッケージは既定値を持たない)
|
|
71
|
+
})
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Route mounts (React Router v7, file convention は自由):
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
// daily_report._index/loader.server.ts
|
|
78
|
+
export const loader = async (args) => {
|
|
79
|
+
const r = await dailyReportServer.index.loader(args)
|
|
80
|
+
return data(r.data, { headers: r.headers })
|
|
81
|
+
}
|
|
82
|
+
// daily_report.api.$endpoint/route.tsx
|
|
83
|
+
export const loader = (args) => dailyReportServer.api.loader(args)
|
|
84
|
+
export const action = (args) => dailyReportServer.api.action(args)
|
|
85
|
+
// sse.daily_report.$endpoint/route.tsx
|
|
86
|
+
export const loader = (args) => dailyReportServer.sse.loader(args)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### DI ports
|
|
90
|
+
|
|
91
|
+
- `authenticate(request, { failureRedirect })` — セッション検証。`failureRedirect: string` のとき未認証は redirect を throw する実装にする。
|
|
92
|
+
- `resolveUserId(externalId)` — 外部 ID → 内部数値 ID (`null` = 未登録)。プロセス内キャッシュは `disableUserIdCache` で無効化可 (テスト用)。
|
|
93
|
+
- `encodeUserId(id)` — クライアントへ出す ID の難読化。既存 ID 空間を維持するためアプリ側実装を注入する。
|
|
94
|
+
- `redis` — `getClient()` (get/incr/xAdd/xRange/xRevRange) + `createClient()` (blocking xRead)。`node-redis` v5 クライアントが構造的に適合する。省略時: SSE publish はスキップ (warn)、epoch 無効。
|
|
95
|
+
- `externalSources[]` — `Hub.source_type` 一致時に `Hub.source_id_num = idColumn` で LEFT JOIN し `mapRow` で表示フィールドへ変換。
|
|
96
|
+
- `draftLabelName` — **必須**。ドラフト状態を表す自 DB のラベル名。サーバー側のクロスユーザー可視性フィルタ (他ユーザーの下書きを隠す) に使うため、パッケージはサイレントな既定値を持たない。
|
|
97
|
+
- 主要チューニング: `idsTtlMs` (180s) / `businessDateTtlMs` (300s) / `streamKey` / `streamMaxLen` / `loginRedirectPath`。
|
|
98
|
+
|
|
99
|
+
## Client wiring
|
|
100
|
+
|
|
101
|
+
```tsx
|
|
102
|
+
// daily_report._index/route.tsx
|
|
103
|
+
import { createDailyReportClientLoader, DailyReportPage, dailyReportShouldRevalidate } from "@aiquants/daily-report/client"
|
|
104
|
+
|
|
105
|
+
export const shouldRevalidate = dailyReportShouldRevalidate
|
|
106
|
+
export const clientLoader = createDailyReportClientLoader() // /daily_report/api/ids を defer 取得
|
|
107
|
+
|
|
108
|
+
export default function Route() {
|
|
109
|
+
const { user, userId, dailyReportIds } = useLoaderData<typeof clientLoader>()
|
|
110
|
+
return (
|
|
111
|
+
<YourAppLayout>
|
|
112
|
+
<DailyReportPage
|
|
113
|
+
user={user}
|
|
114
|
+
userId={userId}
|
|
115
|
+
dailyReportIds={dailyReportIds}
|
|
116
|
+
config={{
|
|
117
|
+
renderHeader: ({ title, annotation }) => <YourHeader title={title} annotation={annotation} />,
|
|
118
|
+
showDevControls: import.meta.env.DEV, // SSE 購読トグル等
|
|
119
|
+
draftLabelName: "draft", // ドラフト状態のラベル名 (自 DB に合わせる)
|
|
120
|
+
fieldLabels: { // 詳細/一覧カードの見出しラベル (下記参照。部分上書き可)
|
|
121
|
+
businessDate: "日付", content: "本文", comments: "コメント", /* ... 各キーを自アプリの言語・表記へ */
|
|
122
|
+
},
|
|
123
|
+
// apiBasePath: "/daily_report/api", ssePath: "/sse/daily_report/updates"
|
|
124
|
+
}}
|
|
125
|
+
/>
|
|
126
|
+
</YourAppLayout>
|
|
127
|
+
)
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
`DailyReportPage` はレイアウト非依存 (ヘッダーは `renderHeader` スロット、エラー境界・フッター制御はアプリ側)。細粒度に使う場合は `DailyReportActionProvider` / `DailyReportResolvedContent` / `useDailyReportDetail` 等を個別 import できる。
|
|
132
|
+
|
|
133
|
+
### フィールドラベル (`fieldLabels`)
|
|
134
|
+
|
|
135
|
+
詳細/一覧カードの見出し (`id` / `businessDate` / `author` / `visitTime` / `createdAt` / `updatedAt` / `updatedBy` / `category` / `categoryInfo` / `creationCategory` / `customer` / `subject` / `content` / `interviewers` / `comments` / `tabArticle` / `tabRelations` / `relationsEmpty`) はすべて DI。**パッケージは中立な英語 (`Business date` / `Customer` / `Content` 等) のみを既定で同梱**し、各見出しの言語・表記は消費アプリが `fieldLabels` で上書きする。これによりパッケージ本体は業務ドメイン固有の表記を持たない。部分指定した分だけ既定へ上書きされる (`DailyReportConfigProvider` が 1 段深くマージ)。
|
|
136
|
+
|
|
137
|
+
## Realtime architecture
|
|
138
|
+
|
|
139
|
+
1. 変更系サービスは `invalidate → epoch increment → SSE publish` の順で Redis Stream (`daily-report:sse-stream`) へ発行。
|
|
140
|
+
2. `DailyReportSseReader` が単一の blocking `xRead` ループで全 SSE 接続へ fan-out (接続ごとの Redis TCP を排除)。
|
|
141
|
+
3. `sse.loader` は `Last-Event-ID` / `lastEventId` による catch-up (`xRange`) と 5 秒 keep-alive を実装。`recipientRawUserId` はサーバー側でフィルタ後に除去される (内部 ID 漏洩防止)。
|
|
142
|
+
4. クライアントは `useDailyReportSseConnection` が指数バックオフ再接続し、アクションコンテキストが楽観的更新と SSE エコーを `clientTempId` で照合する。
|
|
143
|
+
|
|
144
|
+
## API surface (抜粋)
|
|
145
|
+
|
|
146
|
+
- server: `createDailyReportServer` / `createDailyReportService` / `createDailyReportHandlers` / `defineDailyReportSchema` / `DailyReportSseReader` / `SqlResultCache` / `transformJsonArray` / `jsonResponseWithETag` / `generateETag` / `isStreamIdLte`
|
|
147
|
+
- client: `DailyReportPage` / `DailyReportResolvedContent` / `DailyReportList` / `DailyReportDetailList` / `DailyReportActionProvider` / `useDailyReportActionContext` / `useDailyReportDetail` / `useDailyReportPrefetch` / `useDailyReportComments` / `useDailyReportSseConnection` / `DailyReportConfigProvider` / `createDailyReportClientLoader` / `dailyReportShouldRevalidate`
|
|
148
|
+
- shared: `DailyReportItem` / `DailyReportDetail` / `DailyReportUser` / `dailyReportSseMessageSchema` (8 種 discriminated union) / `normalizeBusinessDateKey` / `mergeComments`
|
|
149
|
+
|
|
150
|
+
MIT
|
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode, Context, RefObject } from 'react';
|
|
3
|
+
import { ScrollBarThumbOverlayRenderProps, ScrollPaneInertiaOptions, ScrollBarTapCircleOptions } from '@aiquants/virtualscroll';
|
|
4
|
+
import { U as UIComment, D as DailyReportSseMessage } from './sse-schema-yl5AaSsj.mjs';
|
|
5
|
+
import { D as DailyReportItem, a as DailyReportDetail, b as DailyReportUser } from './types-CVhwLhSN.mjs';
|
|
6
|
+
import { ShouldRevalidateFunction } from 'react-router';
|
|
7
|
+
import 'zod';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Tooltip bubble that anchors to the scrollbar thumb while interacting.
|
|
11
|
+
* スクロール操作中にスクロールバーのサムへ連動表示するツールチップのコンポーネント。
|
|
12
|
+
*/
|
|
13
|
+
declare const BusinessDayThumbOverlay: ({ orientation, thumbCenter, label, isDragging, isTapScrollActive, isWheelScrollActive }: ScrollBarThumbOverlayRenderProps & {
|
|
14
|
+
label: string;
|
|
15
|
+
isWheelScrollActive: boolean;
|
|
16
|
+
}) => react.JSX.Element | null;
|
|
17
|
+
|
|
18
|
+
type DailyReportCommentItemProps = {
|
|
19
|
+
comment: UIComment;
|
|
20
|
+
reportHubId: number;
|
|
21
|
+
businessDate: string;
|
|
22
|
+
onOptimisticDelete: (commentId: number) => void;
|
|
23
|
+
pendingDeleteId: number | string | null;
|
|
24
|
+
onPendingDeleteIdChange: (id: number | string | null) => void;
|
|
25
|
+
onTrashClick: (e: React.MouseEvent | React.TouchEvent, commentId: number | string) => void;
|
|
26
|
+
resolvedIdMap?: Map<number, number>;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Renders a single comment item with delete functionality.
|
|
30
|
+
* 削除機能付きの単一コメントアイテムを描画するコンポーネント。
|
|
31
|
+
*/
|
|
32
|
+
declare const DailyReportCommentItem: ({ comment, reportHubId: _reportHubId, businessDate: _businessDate, onOptimisticDelete, pendingDeleteId, onPendingDeleteIdChange, onTrashClick, resolvedIdMap }: DailyReportCommentItemProps) => react.JSX.Element;
|
|
33
|
+
|
|
34
|
+
type DailyReportCommentListProps = {
|
|
35
|
+
comments: UIComment[];
|
|
36
|
+
reportHubId: number;
|
|
37
|
+
businessDate: string;
|
|
38
|
+
onDeleteComment?: (commentId: number) => void;
|
|
39
|
+
pendingDeleteId: number | string | null;
|
|
40
|
+
onPendingDeleteIdChange: (id: number | string | null) => void;
|
|
41
|
+
resolvedIdMap?: Map<number, number>;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Renders a list of daily report comments.
|
|
45
|
+
* 日報コメントのリストを描画するコンポーネント。
|
|
46
|
+
*/
|
|
47
|
+
declare const DailyReportCommentList: ({ comments, reportHubId, businessDate, onDeleteComment, pendingDeleteId, onPendingDeleteIdChange, resolvedIdMap }: DailyReportCommentListProps) => react.JSX.Element | null;
|
|
48
|
+
type DailyReportCommentFormProps = {
|
|
49
|
+
reportHubId: number;
|
|
50
|
+
businessDate: string;
|
|
51
|
+
onAddComment?: (content: string) => Promise<void> | void;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Renders a form to add a new comment to a daily report.
|
|
55
|
+
* 日報に新しいコメントを追加するためのフォームを描画するコンポーネント。
|
|
56
|
+
*/
|
|
57
|
+
declare const DailyReportCommentForm: ({ reportHubId, businessDate, onAddComment }: DailyReportCommentFormProps) => react.JSX.Element;
|
|
58
|
+
|
|
59
|
+
type DailyReportDetailListProps = {
|
|
60
|
+
dailyReportItems: DailyReportItem[];
|
|
61
|
+
userId?: string | null;
|
|
62
|
+
selectedItemId?: number | null;
|
|
63
|
+
onSelectItem?: (id: number | null) => void;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Daily report detail cards rendered with dynamic height virtual scroll.
|
|
67
|
+
* 動的高さの仮想スクロールで日報詳細カードを描画するコンポーネント。
|
|
68
|
+
*/
|
|
69
|
+
declare const DailyReportDetailList: ({ dailyReportItems, userId, selectedItemId, onSelectItem }: DailyReportDetailListProps) => react.JSX.Element;
|
|
70
|
+
|
|
71
|
+
type DailyReportEditFormProps = {
|
|
72
|
+
report: DailyReportDetail;
|
|
73
|
+
onCancel?: () => void;
|
|
74
|
+
onPublishSuccess?: () => void;
|
|
75
|
+
};
|
|
76
|
+
declare const DailyReportEditForm: ({ report, onCancel, onPublishSuccess }: DailyReportEditFormProps) => react.JSX.Element;
|
|
77
|
+
|
|
78
|
+
type DailyReportListProps = {
|
|
79
|
+
dailyReportItems: DailyReportItem[];
|
|
80
|
+
initialSelectedBusinessDate?: string | null;
|
|
81
|
+
initialSelectedReportHubId?: number | null;
|
|
82
|
+
autoMarkRead?: boolean;
|
|
83
|
+
selectedReportHubId: number | null;
|
|
84
|
+
onSelectItem: (reportHubId: number | null) => void;
|
|
85
|
+
userId?: string | null;
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* Daily report list cards with key metadata and preview content via virtual scrolling.
|
|
89
|
+
* 主なメタデータと内容プレビューを仮想スクロール表示する日報リスト。
|
|
90
|
+
*/
|
|
91
|
+
declare const DailyReportList: ({ dailyReportItems, initialSelectedBusinessDate, initialSelectedReportHubId, autoMarkRead, selectedReportHubId, onSelectItem, userId }: DailyReportListProps) => react.JSX.Element;
|
|
92
|
+
|
|
93
|
+
/** ヘッダー描画スロットに渡される引数。 */
|
|
94
|
+
type DailyReportHeaderProps = {
|
|
95
|
+
title: string;
|
|
96
|
+
annotation?: ReactNode;
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* Display labels for the report detail/list fields, sections, and side-pane tabs.
|
|
100
|
+
* 日報の詳細/一覧カードのフィールド・セクション・タブ見出しの表示ラベル群。
|
|
101
|
+
*
|
|
102
|
+
* パッケージは中立な英語ラベルのみを既定として同梱し、ドメイン固有の表現 (言語・業務語彙) は
|
|
103
|
+
* 消費アプリが `fieldLabels` で注入する。これによりパッケージ本体が業務ドメイン知識を持たない。
|
|
104
|
+
*/
|
|
105
|
+
type DailyReportFieldLabels = {
|
|
106
|
+
id: string;
|
|
107
|
+
businessDate: string;
|
|
108
|
+
author: string;
|
|
109
|
+
visitTime: string;
|
|
110
|
+
createdAt: string;
|
|
111
|
+
updatedAt: string;
|
|
112
|
+
updatedBy: string;
|
|
113
|
+
category: string;
|
|
114
|
+
categoryInfo: string;
|
|
115
|
+
creationCategory: string;
|
|
116
|
+
customer: string;
|
|
117
|
+
subject: string;
|
|
118
|
+
content: string;
|
|
119
|
+
interviewers: string;
|
|
120
|
+
comments: string;
|
|
121
|
+
tabArticle: string;
|
|
122
|
+
tabRelations: string;
|
|
123
|
+
relationsEmpty: string;
|
|
124
|
+
};
|
|
125
|
+
/** クライアント層の設定一式。 */
|
|
126
|
+
type DailyReportClientConfig = {
|
|
127
|
+
/** 画面タイトル (ヘッダーへ渡す)。 */
|
|
128
|
+
title: string;
|
|
129
|
+
/** API ベースパス (例 `/daily_report/api`)。末尾スラッシュ無し。 */
|
|
130
|
+
apiBasePath: string;
|
|
131
|
+
/** SSE エンドポイントパス (例 `/sse/daily_report/updates`)。 */
|
|
132
|
+
ssePath: string;
|
|
133
|
+
/** 下書き状態を表すラベル名。UI の編集モード判定に使う。既定はプレースホルダーなので消費側で自アプリのラベル名へ上書きする。 */
|
|
134
|
+
draftLabelName: string;
|
|
135
|
+
/** 詳細/一覧カードのフィールド見出しラベル。既定は中立英語。アプリが自ドメインの表記を注入する。 */
|
|
136
|
+
fieldLabels: DailyReportFieldLabels;
|
|
137
|
+
/** ヘッダー描画スロット。アプリのヘッダーコンポーネントを差し込む。 */
|
|
138
|
+
renderHeader: (props: DailyReportHeaderProps) => ReactNode;
|
|
139
|
+
/** 開発向けコントロール (SSE 購読トグル等) を表示するか。 */
|
|
140
|
+
showDevControls: boolean;
|
|
141
|
+
};
|
|
142
|
+
/**
|
|
143
|
+
* Partial client-config override. `fieldLabels` may itself be partially overridden.
|
|
144
|
+
* クライアント設定の部分上書き型。`fieldLabels` も部分上書き可 (プロバイダーが深くマージする)。
|
|
145
|
+
*/
|
|
146
|
+
type DailyReportClientConfigInput = Partial<Omit<DailyReportClientConfig, "fieldLabels">> & {
|
|
147
|
+
fieldLabels?: Partial<DailyReportFieldLabels>;
|
|
148
|
+
};
|
|
149
|
+
/** 中立英語のフィールドラベル既定 (ドメイン非依存)。 */
|
|
150
|
+
declare const defaultDailyReportFieldLabels: DailyReportFieldLabels;
|
|
151
|
+
/** 既定設定 (消費側は必要なフィールドのみ部分上書きする)。 */
|
|
152
|
+
declare const defaultDailyReportClientConfig: DailyReportClientConfig;
|
|
153
|
+
/**
|
|
154
|
+
* Provides a partial override of the daily-report client configuration.
|
|
155
|
+
* 日報クライアント設定の部分上書きを提供するプロバイダー。
|
|
156
|
+
*/
|
|
157
|
+
declare const DailyReportConfigProvider: ({ config, children }: {
|
|
158
|
+
config?: DailyReportClientConfigInput;
|
|
159
|
+
children: ReactNode;
|
|
160
|
+
}) => react.JSX.Element;
|
|
161
|
+
/**
|
|
162
|
+
* Reads the daily-report client configuration (defaults when no provider).
|
|
163
|
+
* 日報クライアント設定を読む (プロバイダー未設置時は既定値)。
|
|
164
|
+
*/
|
|
165
|
+
declare const useDailyReportConfig: () => DailyReportClientConfig;
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Error display component for daily report data fetch failures.
|
|
169
|
+
* 日報データの取得失敗時に表示するエラーコンポーネント。
|
|
170
|
+
*/
|
|
171
|
+
declare const DailyReportLoadError: () => react.JSX.Element;
|
|
172
|
+
/**
|
|
173
|
+
* Suspense fallback while daily report identifiers resolve.
|
|
174
|
+
* 日報 ID 解決中のサスペンスフォールバック。
|
|
175
|
+
*/
|
|
176
|
+
declare const DailyReportLoading: () => react.JSX.Element;
|
|
177
|
+
type DailyReportPageProps = {
|
|
178
|
+
/** 表示中ユーザー (楽観的コメントの作者名等に使用)。 */
|
|
179
|
+
user?: DailyReportUser;
|
|
180
|
+
/** 難読化済みの内部ユーザー ID (未登録ユーザーは null)。 */
|
|
181
|
+
userId?: string | null;
|
|
182
|
+
/** clientLoader で defer した日報 ID 一覧 (Promise) または解決済み配列。 */
|
|
183
|
+
dailyReportIds?: Promise<DailyReportItem[]> | DailyReportItem[] | null;
|
|
184
|
+
/** クライアント設定の部分上書き (ヘッダー描画・パス・ラベル名・フィールドラベルなど)。 */
|
|
185
|
+
config?: DailyReportClientConfigInput;
|
|
186
|
+
};
|
|
187
|
+
/**
|
|
188
|
+
* Chrome-agnostic daily report page with client configuration provider.
|
|
189
|
+
* 設定プロバイダー込みの日報ページコンポーネント。
|
|
190
|
+
*/
|
|
191
|
+
declare const DailyReportPage: ({ config, ...rest }: DailyReportPageProps) => react.JSX.Element;
|
|
192
|
+
|
|
193
|
+
type DailyReportResolvedContentProps = {
|
|
194
|
+
dailyReportItems: DailyReportItem[];
|
|
195
|
+
userId?: string | null;
|
|
196
|
+
};
|
|
197
|
+
/**
|
|
198
|
+
* Displays fetched daily reports with layout and tabbed virtual scroll views.
|
|
199
|
+
* レイアウトとタブ付き仮想スクロールで取得済み日報を表示するコンポーネント。
|
|
200
|
+
*/
|
|
201
|
+
declare const DailyReportResolvedContent: ({ dailyReportItems: _initialItems, userId }: DailyReportResolvedContentProps) => react.JSX.Element;
|
|
202
|
+
|
|
203
|
+
type UnreadIndicatorProps = {
|
|
204
|
+
className?: string;
|
|
205
|
+
};
|
|
206
|
+
/**
|
|
207
|
+
* A simple blue dot indicator used to represent unread status.
|
|
208
|
+
* 未読状態を表すためのシンプルな青いドットインジケーター。
|
|
209
|
+
*/
|
|
210
|
+
declare const UnreadIndicator: ({ className }: UnreadIndicatorProps) => react.JSX.Element;
|
|
211
|
+
|
|
212
|
+
type DailyReportActionContextType = {
|
|
213
|
+
/** 表示中ユーザー (楽観的コメントの作者名等に使用)。 */
|
|
214
|
+
user?: DailyReportUser;
|
|
215
|
+
/** reportHubId -> Map<tempCommentId, content> (追加コメントの一時IDと内容) */
|
|
216
|
+
pendingAddCommentIds: React.MutableRefObject<Map<number, Map<number, string>>>;
|
|
217
|
+
/** reportHubId -> Set<tempCommentId> (削除された一時ID) */
|
|
218
|
+
pendingDeleteCommentIds: React.MutableRefObject<Map<number, Set<number>>>;
|
|
219
|
+
/** reportHubId -> boolean (スターの保留状態) */
|
|
220
|
+
pendingStarUpdates: React.MutableRefObject<Map<number, boolean>>;
|
|
221
|
+
/** reportHubId -> boolean (既読の保留状態) */
|
|
222
|
+
pendingReadUpdates: React.MutableRefObject<Map<number, boolean>>;
|
|
223
|
+
/** tempId -> realId (解決されたID) */
|
|
224
|
+
resolvedIdMap: React.MutableRefObject<Map<number, number>>;
|
|
225
|
+
/** 状態変更通知用バージョン */
|
|
226
|
+
version: number;
|
|
227
|
+
/** 日報リスト */
|
|
228
|
+
items: DailyReportItem[];
|
|
229
|
+
/** SSE購読が有効かどうか */
|
|
230
|
+
isSseEnabled: boolean;
|
|
231
|
+
/** SSE購読の有効/無効を切り替える */
|
|
232
|
+
toggleSse: () => void;
|
|
233
|
+
/**
|
|
234
|
+
* コメントを追加します。
|
|
235
|
+
* @param reportHubId 日報HubID
|
|
236
|
+
* @param content コメント内容
|
|
237
|
+
* @param businessDate 営業日
|
|
238
|
+
*/
|
|
239
|
+
addComment: (reportHubId: number, content: string, businessDate: string) => Promise<void>;
|
|
240
|
+
/**
|
|
241
|
+
* コメントを削除します。
|
|
242
|
+
* @param reportHubId 日報HubID
|
|
243
|
+
* @param commentId コメントID (一時IDまたは実ID)
|
|
244
|
+
* @param businessDate 営業日
|
|
245
|
+
*/
|
|
246
|
+
deleteComment: (reportHubId: number, commentId: number, businessDate: string) => Promise<void>;
|
|
247
|
+
/**
|
|
248
|
+
* スターの状態を切り替えます。
|
|
249
|
+
* @param reportHubId 日報HubID
|
|
250
|
+
* @param isStarred 新しいスター状態
|
|
251
|
+
* @param businessDate 営業日
|
|
252
|
+
*/
|
|
253
|
+
toggleStar: (reportHubId: number, isStarred: boolean, businessDate: string) => Promise<void>;
|
|
254
|
+
/**
|
|
255
|
+
* 既読の状態を切り替えます。
|
|
256
|
+
* @param reportHubId 日報HubID
|
|
257
|
+
* @param isRead 新しい既読状態
|
|
258
|
+
* @param businessDate 営業日
|
|
259
|
+
*/
|
|
260
|
+
toggleRead: (reportHubId: number, isRead: boolean, businessDate: string) => Promise<void>;
|
|
261
|
+
createReport: (businessDate: string) => Promise<number>;
|
|
262
|
+
updateReport: (reportHubId: number, data: {
|
|
263
|
+
title?: string;
|
|
264
|
+
content?: string;
|
|
265
|
+
}, businessDate: string) => Promise<void>;
|
|
266
|
+
publishReport: (reportHubId: number, businessDate: string) => Promise<void>;
|
|
267
|
+
deleteReport: (reportHubId: number, businessDate: string) => Promise<void>;
|
|
268
|
+
/** stale アイテムをリストから除去する安全弁 */
|
|
269
|
+
removeStaleItem: (reportHubId: number) => void;
|
|
270
|
+
};
|
|
271
|
+
declare global {
|
|
272
|
+
var __DailyReportActionContext: Context<DailyReportActionContextType | null> | undefined;
|
|
273
|
+
}
|
|
274
|
+
declare const useDailyReportActionContext: () => DailyReportActionContextType;
|
|
275
|
+
/**
|
|
276
|
+
* Provides a context for daily report actions including comments, stars, leads, and basic CRUD operations.
|
|
277
|
+
* Also manages optimistic UI updates and real-time synchronization via SSE.
|
|
278
|
+
* 日報のアクション(コメント追加・削除、スター、既読)を管理するプロバイダー。
|
|
279
|
+
* 楽観的UI更新とAPI通信の抽象化を提供します。
|
|
280
|
+
*/
|
|
281
|
+
declare const DailyReportActionProvider: ({ children, user, initialItems, userId }: {
|
|
282
|
+
children: ReactNode;
|
|
283
|
+
user?: DailyReportUser;
|
|
284
|
+
initialItems?: DailyReportItem[];
|
|
285
|
+
userId?: string | null;
|
|
286
|
+
}) => react.JSX.Element;
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Update the cache for a single report.
|
|
290
|
+
* 単一レポートのキャッシュを更新する。
|
|
291
|
+
*/
|
|
292
|
+
declare const writeCache: (r: DailyReportDetail, exp: number, sync?: boolean) => void;
|
|
293
|
+
/**
|
|
294
|
+
* Get a cached report by ID.
|
|
295
|
+
* ID でキャッシュされたレポートを取得する。
|
|
296
|
+
*/
|
|
297
|
+
declare const getCachedReport: (id: number, opts?: {
|
|
298
|
+
ignoreExpiry?: boolean;
|
|
299
|
+
}) => DailyReportDetail | null;
|
|
300
|
+
/**
|
|
301
|
+
* Update specific fields of a cached report.
|
|
302
|
+
* キャッシュされたレポートの特定のフィールドを更新する。
|
|
303
|
+
*/
|
|
304
|
+
declare const updateDailyReportCache: (id: number, u: Partial<DailyReportDetail>) => void;
|
|
305
|
+
/**
|
|
306
|
+
* Delete a report from the cache.
|
|
307
|
+
* キャッシュからレポートを削除する。
|
|
308
|
+
*/
|
|
309
|
+
declare const deleteDailyReportCache: (id: number, d: string) => void;
|
|
310
|
+
declare const acquireMutationLock: (id: number) => void;
|
|
311
|
+
declare const releaseMutationLock: (id: number) => void;
|
|
312
|
+
declare const registerRecentDeletion: (cId: number) => Map<number, number>;
|
|
313
|
+
/**
|
|
314
|
+
* Subscribe to cache-ready events for a specific report.
|
|
315
|
+
* Returns an unsubscribe function.
|
|
316
|
+
*
|
|
317
|
+
* 特定レポートのキャッシュ書き込みを監視する。
|
|
318
|
+
* 解除関数を返す。
|
|
319
|
+
*/
|
|
320
|
+
declare const subscribeCacheReady: (reportHubId: number, callback: () => void) => (() => void);
|
|
321
|
+
declare const applyDailyReportServerUpdates: (_reportHubIdd: number, report: DailyReportDetail) => void;
|
|
322
|
+
type DailyReportDetailResource = {
|
|
323
|
+
report: DailyReportDetail | null;
|
|
324
|
+
error: Error | null;
|
|
325
|
+
isLoading: boolean;
|
|
326
|
+
isRefetching: boolean;
|
|
327
|
+
};
|
|
328
|
+
/**
|
|
329
|
+
* Provides a fetcher-driven daily report detail reader with business-date aware caching.
|
|
330
|
+
* 営業日キャッシュ対応の日報詳細取得フック。
|
|
331
|
+
*/
|
|
332
|
+
declare const useDailyReportDetail: (reportHubId: number, businessDate: string | null) => DailyReportDetailResource;
|
|
333
|
+
/**
|
|
334
|
+
* Provides a business-date aware prefetch helper.
|
|
335
|
+
* 営業日キャッシュを活用した日報プリフェッチ補助フック。
|
|
336
|
+
*/
|
|
337
|
+
declare const useDailyReportPrefetch: () => (date: string | null) => void;
|
|
338
|
+
|
|
339
|
+
type User = {
|
|
340
|
+
displayName?: string;
|
|
341
|
+
name?: {
|
|
342
|
+
familyName?: string;
|
|
343
|
+
givenName?: string;
|
|
344
|
+
};
|
|
345
|
+
emails?: {
|
|
346
|
+
value: string;
|
|
347
|
+
}[];
|
|
348
|
+
};
|
|
349
|
+
/**
|
|
350
|
+
* Manages daily report comments, integrating server data with optimistic local updates.
|
|
351
|
+
* サーバーデータとローカルの楽観的更新を統合して日報コメントを管理するフック。
|
|
352
|
+
*/
|
|
353
|
+
declare const useDailyReportComments: (report: DailyReportDetail | null, user: User | null | undefined, userId?: string | null) => {
|
|
354
|
+
uiComments: UIComment[];
|
|
355
|
+
handleAddComment: (content: string) => Promise<void>;
|
|
356
|
+
handleDeleteComment: (cId: number) => Promise<void> | null;
|
|
357
|
+
pendingDeleteId: string | number | null;
|
|
358
|
+
setPendingDeleteId: react.Dispatch<react.SetStateAction<string | number | null>>;
|
|
359
|
+
resolvedIdMap: Map<number, number>;
|
|
360
|
+
};
|
|
361
|
+
|
|
362
|
+
type UseDailyReportSseConnectionOptions = {
|
|
363
|
+
isSseEnabled: boolean;
|
|
364
|
+
onMessage: (payload: Exclude<DailyReportSseMessage, {
|
|
365
|
+
type: "connected";
|
|
366
|
+
}>) => void;
|
|
367
|
+
};
|
|
368
|
+
/**
|
|
369
|
+
* Manages Daily Report SSE connection lifecycle with reconnect handling.
|
|
370
|
+
* Handles open, message parse/dispatch, error logging, retry, and cleanup.
|
|
371
|
+
*
|
|
372
|
+
* 日報 SSE 接続のライフサイクルを管理する Hook。
|
|
373
|
+
* 接続開始、メッセージ解析と配送、エラー時再接続、クリーンアップを管理します。
|
|
374
|
+
*/
|
|
375
|
+
declare const useDailyReportSseConnection: ({ isSseEnabled, onMessage }: UseDailyReportSseConnectionOptions) => void;
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* Shared hook for calculating viewport height of virtual scroll containers.
|
|
379
|
+
* 仮想スクロールコンテナのビューポート高さを計測する共通フック。
|
|
380
|
+
*/
|
|
381
|
+
|
|
382
|
+
type UseDynamicViewportHeightOptions = {
|
|
383
|
+
enableMutationObserver?: boolean;
|
|
384
|
+
bottomGap?: number;
|
|
385
|
+
minFallbackHeight?: number;
|
|
386
|
+
};
|
|
387
|
+
type UseDynamicViewportHeightResult = {
|
|
388
|
+
viewportHeight: number;
|
|
389
|
+
updateViewportHeight: () => void;
|
|
390
|
+
};
|
|
391
|
+
/**
|
|
392
|
+
* Computes and updates the viewport height for scroll containers while reacting to layout changes.
|
|
393
|
+
* レイアウト変化に追従しながらスクロールコンテナのビューポート高さを算出して更新する関数。
|
|
394
|
+
*/
|
|
395
|
+
declare const useDynamicViewportHeight: (containerRef: RefObject<HTMLDivElement | null>, options?: UseDynamicViewportHeightOptions) => UseDynamicViewportHeightResult;
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* React Router route helpers for the daily-report page (revalidation policy / client loader).
|
|
399
|
+
* 日報ページ向け React Router ルートヘルパー (再検証ポリシー / クライアントローダー)。
|
|
400
|
+
*/
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* Prevents loader revalidation when POP navigations keep identical URL state.
|
|
404
|
+
* URL 状態が同一の POP ナビゲーション時にローダー再検証を抑止。
|
|
405
|
+
*/
|
|
406
|
+
declare const dailyReportShouldRevalidate: ShouldRevalidateFunction;
|
|
407
|
+
/**
|
|
408
|
+
* Fetches the deferred daily report id list from the API endpoint.
|
|
409
|
+
* API エンドポイントから日報 ID 一覧を遅延取得する処理。
|
|
410
|
+
*/
|
|
411
|
+
declare const fetchDailyReportIds: (apiBasePath?: string) => Promise<DailyReportItem[]>;
|
|
412
|
+
/**
|
|
413
|
+
* Creates a React Router clientLoader that merges server data with deferred report ids.
|
|
414
|
+
* サーバーデータへ遅延日報 ID を合成する React Router clientLoader を生成する処理。
|
|
415
|
+
*
|
|
416
|
+
* 返す関数へ `hydrate = true as const` を付与済み (初期ハイドレーションでも実行される)。
|
|
417
|
+
*/
|
|
418
|
+
declare const createDailyReportClientLoader: <TServerData extends Record<string, unknown>>(options?: {
|
|
419
|
+
apiBasePath?: string;
|
|
420
|
+
}) => {
|
|
421
|
+
(args: {
|
|
422
|
+
serverLoader: () => Promise<unknown>;
|
|
423
|
+
}): Promise<TServerData & {
|
|
424
|
+
dailyReportIds: Promise<DailyReportItem[]>;
|
|
425
|
+
}>;
|
|
426
|
+
hydrate: true;
|
|
427
|
+
};
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* Shared constants for Daily Report data fetching parameters.
|
|
431
|
+
* 日報データ取得で利用する共通パラメーター。
|
|
432
|
+
*/
|
|
433
|
+
declare const DAILY_REPORT_FETCH_DEBOUNCE_MS = 180;
|
|
434
|
+
declare const DEFAULT_ITEM_HEIGHT = 160;
|
|
435
|
+
declare const ITEM_VERTICAL_PADDING = 6;
|
|
436
|
+
declare const ITEM_CONTAINER_HEIGHT: number;
|
|
437
|
+
declare const FAST_SCROLL_WHEEL_MULTIPLIER = 0.8;
|
|
438
|
+
declare const FAST_SCROLL_INERTIA_OPTIONS: ScrollPaneInertiaOptions;
|
|
439
|
+
declare const PREFETCH_LOOKAHEAD = 20;
|
|
440
|
+
declare const PREFETCH_MAX_DATES = 6;
|
|
441
|
+
declare const EMPTY_ITEM: DailyReportItem;
|
|
442
|
+
declare const EMPTY_DETAIL: DailyReportDetailResource;
|
|
443
|
+
declare const WHEEL_RESET_TIMEOUT_MS = 240;
|
|
444
|
+
declare const VIRTUAL_SCROLL_OVERSCAN_COUNT = 15;
|
|
445
|
+
declare const SCROLL_BAR_WIDTH = 8;
|
|
446
|
+
declare const MAX_PREVIEW_LINES = 3;
|
|
447
|
+
declare const TAP_SCROLL_CIRCLE_OPTIONS: ScrollBarTapCircleOptions;
|
|
448
|
+
|
|
449
|
+
export { BusinessDayThumbOverlay, DAILY_REPORT_FETCH_DEBOUNCE_MS, DEFAULT_ITEM_HEIGHT, DailyReportActionProvider, type DailyReportClientConfig, type DailyReportClientConfigInput, DailyReportCommentForm, DailyReportCommentItem, DailyReportCommentList, DailyReportConfigProvider, DailyReportDetailList, type DailyReportDetailResource, DailyReportEditForm, type DailyReportFieldLabels, type DailyReportHeaderProps, DailyReportList, DailyReportLoadError, DailyReportLoading, DailyReportPage, type DailyReportPageProps, 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, TAP_SCROLL_CIRCLE_OPTIONS, UnreadIndicator, VIRTUAL_SCROLL_OVERSCAN_COUNT, WHEEL_RESET_TIMEOUT_MS, acquireMutationLock, applyDailyReportServerUpdates, createDailyReportClientLoader, dailyReportShouldRevalidate, defaultDailyReportClientConfig, defaultDailyReportFieldLabels, deleteDailyReportCache, fetchDailyReportIds, getCachedReport, registerRecentDeletion, releaseMutationLock, subscribeCacheReady, updateDailyReportCache, useDailyReportActionContext, useDailyReportComments, useDailyReportConfig, useDailyReportDetail, useDailyReportPrefetch, useDailyReportSseConnection, useDynamicViewportHeight, writeCache };
|