2026-08-19 23:06:57 +07:00
|
|
|
import * as React from "react";
|
|
|
|
|
import {
|
|
|
|
|
Badge,
|
|
|
|
|
Button,
|
|
|
|
|
MessageBar,
|
|
|
|
|
MessageBarBody,
|
|
|
|
|
Spinner,
|
|
|
|
|
Text,
|
|
|
|
|
makeStyles,
|
|
|
|
|
tokens,
|
|
|
|
|
} from "@fluentui/react-components";
|
2026-09-08 14:01:13 +07:00
|
|
|
import {
|
|
|
|
|
ArrowDownload24Regular,
|
|
|
|
|
DocumentPdf24Regular,
|
|
|
|
|
History24Regular,
|
|
|
|
|
} from "@fluentui/react-icons";
|
2026-08-19 23:06:57 +07:00
|
|
|
import { VersionRecord } from "../../models/versionRecord";
|
|
|
|
|
|
|
|
|
|
interface VersionHistoryPanelProps {
|
|
|
|
|
versions: VersionRecord[];
|
|
|
|
|
loading: boolean;
|
|
|
|
|
error: string | null;
|
|
|
|
|
/** versionId ของ version ที่กำลังดาวน์โหลดอยู่ (แสดง spinner ที่ปุ่ม) */
|
|
|
|
|
downloadingVersionId: string | null;
|
2026-09-08 14:01:13 +07:00
|
|
|
downloadingPdfVersionId: string | null;
|
|
|
|
|
onDownloadPdf: (version: VersionRecord) => void;
|
2026-08-19 23:06:57 +07:00
|
|
|
onDownload: (version: VersionRecord) => void;
|
|
|
|
|
onRetry: () => void;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const useStyles = makeStyles({
|
|
|
|
|
root: {
|
|
|
|
|
display: "flex",
|
|
|
|
|
flexDirection: "column",
|
|
|
|
|
gap: tokens.spacingVerticalS,
|
|
|
|
|
},
|
|
|
|
|
header: {
|
|
|
|
|
display: "flex",
|
|
|
|
|
alignItems: "center",
|
|
|
|
|
gap: tokens.spacingHorizontalXS,
|
|
|
|
|
marginTop: tokens.spacingVerticalL,
|
|
|
|
|
marginBottom: tokens.spacingVerticalXXS,
|
|
|
|
|
},
|
|
|
|
|
item: {
|
|
|
|
|
display: "flex",
|
|
|
|
|
alignItems: "center",
|
|
|
|
|
justifyContent: "space-between",
|
|
|
|
|
gap: tokens.spacingHorizontalS,
|
|
|
|
|
padding: `${tokens.spacingVerticalXS} ${tokens.spacingHorizontalS}`,
|
|
|
|
|
borderRadius: tokens.borderRadiusMedium,
|
|
|
|
|
":hover": {
|
|
|
|
|
backgroundColor: tokens.colorNeutralBackground1Hover,
|
|
|
|
|
},
|
|
|
|
|
},
|
2026-09-08 14:01:13 +07:00
|
|
|
actions: { display: "flex", flexDirection: "column", flexShrink: 0 },
|
2026-08-19 23:06:57 +07:00
|
|
|
itemInfo: {
|
|
|
|
|
display: "flex",
|
|
|
|
|
flexDirection: "column",
|
|
|
|
|
minWidth: 0,
|
|
|
|
|
},
|
|
|
|
|
metaRow: {
|
|
|
|
|
color: tokens.colorNeutralForeground3,
|
|
|
|
|
fontSize: tokens.fontSizeBase200,
|
|
|
|
|
},
|
2026-08-20 22:05:49 +07:00
|
|
|
messageRow: {
|
|
|
|
|
color: tokens.colorNeutralForeground2,
|
|
|
|
|
fontSize: tokens.fontSizeBase200,
|
|
|
|
|
whiteSpace: "pre-wrap",
|
|
|
|
|
overflowWrap: "anywhere",
|
|
|
|
|
},
|
2026-08-19 23:06:57 +07:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
function formatTimestamp(iso: string): string {
|
|
|
|
|
const date = new Date(iso);
|
|
|
|
|
return Number.isNaN(date.getTime())
|
|
|
|
|
? iso
|
|
|
|
|
: date.toLocaleString(undefined, { dateStyle: "medium", timeStyle: "short" });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** FR-4 — แสดง version history (เลข version / เวลา / ผู้สร้าง) + ปุ่มดาวน์โหลด version นั้น */
|
|
|
|
|
export const VersionHistoryPanel: React.FC<VersionHistoryPanelProps> = ({
|
|
|
|
|
versions,
|
|
|
|
|
loading,
|
|
|
|
|
error,
|
|
|
|
|
downloadingVersionId,
|
2026-09-08 14:01:13 +07:00
|
|
|
downloadingPdfVersionId,
|
|
|
|
|
onDownloadPdf,
|
2026-08-19 23:06:57 +07:00
|
|
|
onDownload,
|
|
|
|
|
onRetry,
|
|
|
|
|
}) => {
|
|
|
|
|
const styles = useStyles();
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className={styles.root}>
|
|
|
|
|
<div className={styles.header}>
|
|
|
|
|
<History24Regular />
|
|
|
|
|
<Text weight="semibold">Version history</Text>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{loading ? <Spinner size="small" label="กำลังโหลด…" /> : null}
|
|
|
|
|
|
|
|
|
|
{error ? (
|
|
|
|
|
<MessageBar intent="error">
|
|
|
|
|
<MessageBarBody>
|
|
|
|
|
{error}{" "}
|
|
|
|
|
<Button size="small" appearance="subtle" onClick={onRetry}>
|
|
|
|
|
ลองใหม่
|
|
|
|
|
</Button>
|
|
|
|
|
</MessageBarBody>
|
|
|
|
|
</MessageBar>
|
|
|
|
|
) : null}
|
|
|
|
|
|
|
|
|
|
{!loading && !error && versions.length === 0 ? (
|
|
|
|
|
<Text size={200} style={{ color: tokens.colorNeutralForeground3 }}>
|
|
|
|
|
ยังไม่มี version ในระบบ
|
|
|
|
|
</Text>
|
|
|
|
|
) : null}
|
|
|
|
|
|
|
|
|
|
{versions.map((version) => (
|
|
|
|
|
<div className={styles.item} key={version.versionId}>
|
|
|
|
|
<div className={styles.itemInfo}>
|
|
|
|
|
<Badge appearance="filled" color="brand">
|
|
|
|
|
v{version.versionNumber}
|
|
|
|
|
</Badge>
|
|
|
|
|
<span className={styles.metaRow}>{formatTimestamp(version.createdAt)}</span>
|
|
|
|
|
<span className={styles.metaRow}>โดย {version.createdByUserId}</span>
|
2026-09-08 14:01:13 +07:00
|
|
|
{version.message ? <span className={styles.messageRow}>{version.message}</span> : null}
|
|
|
|
|
</div>
|
|
|
|
|
<div className={styles.actions}>
|
|
|
|
|
<Button
|
|
|
|
|
icon={<ArrowDownload24Regular />}
|
|
|
|
|
size="small"
|
|
|
|
|
appearance="subtle"
|
|
|
|
|
disabled={downloadingVersionId !== null || downloadingPdfVersionId !== null}
|
|
|
|
|
onClick={() => onDownload(version)}
|
|
|
|
|
>
|
|
|
|
|
{downloadingVersionId === version.versionId ? "กำลังดาวน์โหลด…" : "ดาวน์โหลด"}
|
|
|
|
|
</Button>
|
|
|
|
|
{version.hasPdf ? (
|
|
|
|
|
<Button
|
|
|
|
|
icon={<DocumentPdf24Regular />}
|
|
|
|
|
size="small"
|
|
|
|
|
appearance="subtle"
|
|
|
|
|
disabled={downloadingVersionId !== null || downloadingPdfVersionId !== null}
|
|
|
|
|
onClick={() => onDownloadPdf(version)}
|
|
|
|
|
>
|
|
|
|
|
{downloadingPdfVersionId === version.versionId ? "กำลังเปิด…" : "PDF"}
|
|
|
|
|
</Button>
|
2026-08-20 22:05:49 +07:00
|
|
|
) : null}
|
2026-08-19 23:06:57 +07:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default VersionHistoryPanel;
|