@aiquants/daily-report 0.1.1 → 0.3.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.
@@ -13,6 +13,7 @@ import { useDailyReportActionContext } from "../contexts/daily-report-action-con
13
13
  import { useDailyReportDetail } from "../hooks/use-daily-report"
14
14
  import { useDailyReportComments } from "../hooks/use-daily-report-comments"
15
15
  import { useDynamicViewportHeight } from "../hooks/use-dynamic-viewport-height"
16
+ import { cn } from "../ui/cn"
16
17
  import { Tabs, TabsContent, TabsList, TabsTrigger } from "../ui/tabs"
17
18
  import {
18
19
  DEFAULT_ITEM_HEIGHT,
@@ -504,7 +505,7 @@ const DailyReportSidePane = ({
504
505
  }) => {
505
506
  const [activeTab, setActiveTab] = useState<DailyReportSidePaneTab>("article")
506
507
  const [isEditing, setIsEditing] = useState(false)
507
- const { draftLabelName, fieldLabels } = useDailyReportConfig()
508
+ const { draftLabelName, fieldLabels, sourceTypeConfigs } = useDailyReportConfig()
508
509
  const { report, error, isLoading } = useDailyReportDetail(selectedItem?.reportHubId ?? -1, selectedItem?.businessDate ?? null)
509
510
 
510
511
  const scrollContainerRef = useRef<HTMLDivElement>(null)
@@ -570,6 +571,11 @@ const DailyReportSidePane = ({
570
571
  <div className="flex min-h-4 items-center gap-1 text-slate-500 text-xs dark:text-slate-300">
571
572
  <span>{fieldLabels.author}:</span>
572
573
  {showHeaderSkeleton ? <div className="h-3 w-24 animate-pulse rounded bg-slate-200 dark:bg-slate-700" /> : <span>{headerCreator}</span>}
574
+ {(() => {
575
+ const sourceType = report?.sourceType
576
+ const sourceConfig = sourceType ? sourceTypeConfigs?.[sourceType] : undefined
577
+ return sourceConfig ? <span className={cn("ml-2 inline-flex shrink-0 items-center rounded px-2 py-0.5 font-semibold text-[10px] tracking-wide", sourceConfig.badgeClassName)}>{sourceConfig.label}</span> : null
578
+ })()}
573
579
  </div>
574
580
  </div>
575
581
  <Tabs value={activeTab} onValueChange={(v) => setActiveTab(v as DailyReportSidePaneTab)} className="flex min-h-0 flex-1 flex-col">
@@ -904,6 +910,7 @@ const extractPreviewLines = (content: string | null): string[] => {
904
910
  const ListReportItem = ({ item, isActive, onSelect }: { item: DailyReportItem; isActive: boolean; onSelect: (id: number) => void }) => {
905
911
  const { report, error, isLoading, isRefetching } = useDailyReportDetail(item.reportHubId, item.businessDate)
906
912
  const { toggleStar, toggleRead, removeStaleItem } = useDailyReportActionContext()
913
+ const { sourceTypeConfigs } = useDailyReportConfig()
907
914
 
908
915
  // フェッチが一度でも試行されたかを追跡する ref
909
916
  const hasEverFetched = useRef(false)
@@ -989,6 +996,11 @@ const ListReportItem = ({ item, isActive, onSelect }: { item: DailyReportItem; i
989
996
  <span className="truncate font-medium text-slate-900 dark:text-slate-100">{creator}</span>
990
997
  </span>
991
998
  <div className="ml-auto flex items-center gap-1.5">
999
+ {(() => {
1000
+ const sourceType = report?.sourceType
1001
+ const sourceConfig = sourceType ? sourceTypeConfigs?.[sourceType] : undefined
1002
+ return sourceConfig ? <span className={cn("inline-flex shrink-0 items-center rounded px-2 py-0.5 font-semibold text-[10px] tracking-wide", sourceConfig.badgeClassName)}>{sourceConfig.label}</span> : null
1003
+ })()}
992
1004
  <button
993
1005
  type="button"
994
1006
  title={report.isStarred ? "スターを外す" : "スターを付ける"}
@@ -38,6 +38,11 @@ export type DailyReportFieldLabels = {
38
38
  relationsEmpty: string
39
39
  }
40
40
 
41
+ export type SourceTypeConfig = {
42
+ label: string
43
+ badgeClassName?: string
44
+ }
45
+
41
46
  /** クライアント層の設定一式。 */
42
47
  export type DailyReportClientConfig = {
43
48
  /** 画面タイトル (ヘッダーへ渡す)。 */
@@ -50,6 +55,8 @@ export type DailyReportClientConfig = {
50
55
  draftLabelName: string
51
56
  /** 詳細/一覧カードのフィールド見出しラベル。既定は中立英語。アプリが自ドメインの表記を注入する。 */
52
57
  fieldLabels: DailyReportFieldLabels
58
+ /** 外部ソース区分ごとのバッジ表示設定。 */
59
+ sourceTypeConfigs?: Record<string, SourceTypeConfig>
53
60
  /** ヘッダー描画スロット。アプリのヘッダーコンポーネントを差し込む。 */
54
61
  renderHeader: (props: DailyReportHeaderProps) => ReactNode
55
62
  /** 開発向けコントロール (SSE 購読トグル等) を表示するか。 */
@@ -62,6 +69,7 @@ export type DailyReportClientConfig = {
62
69
  */
63
70
  export type DailyReportClientConfigInput = Partial<Omit<DailyReportClientConfig, "fieldLabels">> & {
64
71
  fieldLabels?: Partial<DailyReportFieldLabels>
72
+ sourceTypeConfigs?: Record<string, SourceTypeConfig>
65
73
  }
66
74
 
67
75
  /** 中立英語のフィールドラベル既定 (ドメイン非依存)。 */
@@ -94,6 +102,7 @@ export const defaultDailyReportClientConfig: DailyReportClientConfig = {
94
102
  // 中立プレースホルダー。実運用のラベル名 (アプリ固有) は Provider / config prop で上書きする。
95
103
  draftLabelName: "draft",
96
104
  fieldLabels: defaultDailyReportFieldLabels,
105
+ sourceTypeConfigs: {},
97
106
  renderHeader: ({ title, annotation }) => (
98
107
  <header className="flex flex-wrap items-baseline justify-between gap-2 px-2 py-1">
99
108
  <span className="text-nowrap text-slate-700 text-sm dark:text-slate-200">{title}</span>
@@ -703,6 +703,7 @@ export const DailyReportActionProvider = ({ children, user, initialItems = [], u
703
703
  createdAt: now,
704
704
  author: getUserDisplayName(user),
705
705
  userId: user?.id ?? "unknown",
706
+ sourceType: "Internal",
706
707
  employeeName: getUserDisplayName(user),
707
708
  updatedBy: getUserDisplayName(user),
708
709
  updatedAt: now,
@@ -326,6 +326,7 @@ export function createDailyReportService(config: DailyReportServiceConfig) {
326
326
  date: formatDateValue(hub.businessDate, "YYYY-MM-DD"),
327
327
  author: row.creatorName ?? maskAuditActor(hub.createdBy) ?? "",
328
328
  userId: hub.userId ? encodeUserId(hub.userId) : "",
329
+ sourceType: hub.sourceType ?? "Internal",
329
330
  createdAt: formatDateValue(hub.createdAt, "YYYY-MM-DD HH:mm:ss"),
330
331
  updatedAt: formatDateValue(hub.updatedAt, "YYYY-MM-DD HH:mm:ss"),
331
332
  updatedBy: maskAuditActor(hub.updatedBy),
@@ -1034,6 +1035,7 @@ export function createDailyReportService(config: DailyReportServiceConfig) {
1034
1035
  createdAt: formatDateValue(hub.createdAt, "YYYY-MM-DD HH:mm:ss"),
1035
1036
  author: userName,
1036
1037
  userId: encodeUserId(userId),
1038
+ sourceType: "Internal",
1037
1039
  employeeName: userName,
1038
1040
  // 監査列と同様、クライアント公開時は生内部 ID を難読化する (mapHubRecord と整合)
1039
1041
  updatedBy: encodeUserId(userId),
@@ -39,6 +39,7 @@ export const dailyReportDetailSchema = z.object({
39
39
  createdAt: z.string().nullable(),
40
40
  author: z.string(),
41
41
  userId: z.string(),
42
+ sourceType: z.string().nullable(),
42
43
  employeeName: z.string().nullable(),
43
44
  updatedBy: z.string().nullable(),
44
45
  updatedAt: z.string().nullable(),
@@ -46,6 +46,7 @@ export type DailyReportDetail = {
46
46
  createdAt: string | null
47
47
  author: string
48
48
  userId: string
49
+ sourceType: string | null
49
50
  employeeName: string | null
50
51
  updatedBy: string | null
51
52
  updatedAt: string | null