test: prove TechLog UI migration parity

This commit is contained in:
DongHyeonka
2026-08-16 02:48:26 +09:00
parent c5c8b9423c
commit 6c2780b7a7
176 changed files with 2393 additions and 616 deletions
@@ -3,6 +3,7 @@ import type { WorkingCopyInput } from "../../../contracts/studio/contract.ts";
import { ContentFormatError } from "../../../domain/content-format/parse-case-content.ts";
import { projectWorkingCopy } from "../../../domain/content-format/project-public-render-model.ts";
import { PublicRecordRenderer } from "../../shared/public-render/public-record-renderer.tsx";
import { useStudio } from "../use-studio.ts";
type CatalogEntry = components["schemas"]["CatalogEntry"];
@@ -24,6 +25,7 @@ function resolvePreviewEvidenceAsset(key: string) {
}
export function InstantPreview({ draft, catalog }: { draft: WorkingCopyInput; catalog: CatalogEntry[] }) {
const studio = useStudio();
let model: ReturnType<typeof projectWorkingCopy> | null = null;
let issues: string[] | null = null;
try {
@@ -45,7 +47,7 @@ export function InstantPreview({ draft, catalog }: { draft: WorkingCopyInput; ca
model={model!}
embedded
resolveEvidenceAsset={resolvePreviewEvidenceAsset}
resolvePublishedLabel={() => undefined}
resolvePublishedLabel={studio.resolvePublishedLabel}
/>
</div>
);
@@ -288,7 +288,7 @@ export function PublicPreviewScreen({ documentId }: { documentId: string }) {
model={previewDetail.preview.renderModel}
embedded
resolveEvidenceAsset={resolvePreviewEvidenceAsset}
resolvePublishedLabel={() => undefined}
resolvePublishedLabel={studio.resolvePublishedLabel}
/>
</div>
</>
@@ -1,5 +1,3 @@
/* eslint-disable react-hooks/set-state-in-effect -- a changed event or retry intentionally enters a fresh loading state. */
import { useEffect, useState } from "react";
import {
@@ -50,7 +48,8 @@ export function PublicationEventPreviewScreen({
publicationEventId: string;
classes?: PublicationFlowClasses;
}) {
const { gateway } = useStudio();
const studio = useStudio();
const { gateway } = studio;
const [retry, setRetry] = useState(0);
const [state, setState] = useState<
| { status: "LOADING" }
@@ -168,7 +167,7 @@ export function PublicationEventPreviewScreen({
model={renderModel}
embedded
resolveEvidenceAsset={resolveEvidenceAsset}
resolvePublishedLabel={() => undefined}
resolvePublishedLabel={studio.resolvePublishedLabel}
/>
</div>
</div>
@@ -1,4 +1,6 @@
export const defaultPublicationFlowClasses = {
import styles from "../../styles/publication-flow.module.css";
const publicationFlowClassContract = {
page: "studio-publication-page",
snapshotPage: "studio-snapshot-page",
heading: "studio-publication-heading",
@@ -35,4 +37,11 @@ export const defaultPublicationFlowClasses = {
snapshotDocument: "studio-publication-snapshot-document",
} as const;
export type PublicationFlowClasses = Record<keyof typeof defaultPublicationFlowClasses, string>;
export type PublicationFlowClasses = Record<
keyof typeof publicationFlowClassContract,
string
>;
export const defaultPublicationFlowClasses = Object.fromEntries(
Object.keys(publicationFlowClassContract).map((key) => [key, styles[key]]),
) as PublicationFlowClasses;
@@ -1,5 +1,3 @@
/* eslint-disable react-hooks/set-state-in-effect -- a changed history query intentionally enters a fresh loading state. */
import { useEffect, useRef, useState, type FormEvent } from "react";
import {
@@ -1,5 +1,3 @@
/* eslint-disable react-hooks/set-state-in-effect -- a changed document or retry intentionally enters a fresh loading state. */
import { useEffect, useMemo, useState } from "react";
import {
@@ -8,6 +8,7 @@ import {
import { isStudioGatewayError } from "../../application/ports/studio-gateway-error.ts";
import type { StudioGateway } from "../../application/ports/studio-gateway.ts";
import type { ResolvePublishedLabel } from "../../domain/public-render-content.ts";
import type {
WorkingCopy,
WorkingCopyInput,
@@ -24,6 +25,7 @@ import { useBeforeUnload } from "./components/use-before-unload.ts";
type StudioProviderProps = Readonly<{
children: ReactNode;
createGateway: () => StudioGateway;
resolvePublishedLabel?: ResolvePublishedLabel;
now?: () => Date;
navigate?: (href: string) => void;
}>;
@@ -41,9 +43,12 @@ function defaultNavigate(href: string): void {
window.dispatchEvent(new PopStateEvent("popstate"));
}
const missingPublishedLabel: ResolvePublishedLabel = () => undefined;
export function StudioProvider({
children,
createGateway,
resolvePublishedLabel = missingPublishedLabel,
now = () => new Date("2026-08-14T01:00:00.000Z"),
navigate = defaultNavigate,
}: StudioProviderProps) {
@@ -143,6 +148,7 @@ export function StudioProvider({
const value = useMemo<StudioContextValue>(
() => ({
gateway,
resolvePublishedLabel,
now,
editor,
requestAnnouncement,
@@ -161,6 +167,7 @@ export function StudioProvider({
navigateInternal,
now,
requestAnnouncement,
resolvePublishedLabel,
setEditorStatus,
updateEditorDraft,
],
@@ -47,6 +47,14 @@ export function StudioShell({ children }: StudioShellProps) {
() => application.features.get(TECH_LOG_FEATURE_ID).createStudioGateway(),
[application],
);
const resolvePublishedLabel = useCallback(
(path: string) =>
application.features
.get(TECH_LOG_FEATURE_ID)
.publicContent.listRecords()
.find((record) => record.path === path)?.publishedLabel,
[application],
);
useEffect(() => {
const resetPersistedSession = (event: PageTransitionEvent) => {
@@ -61,6 +69,7 @@ export function StudioShell({ children }: StudioShellProps) {
<StudioProvider
key={generation}
createGateway={createGateway}
resolvePublishedLabel={resolvePublishedLabel}
navigate={navigateInternal}
>
<StudioFrame>{children}</StudioFrame>
@@ -1,6 +1,7 @@
import { createContext, useContext, useMemo } from "react";
import type { StudioGateway } from "../../application/ports/studio-gateway.ts";
import type { ResolvePublishedLabel } from "../../domain/public-render-content.ts";
import type {
WorkingCopy,
WorkingCopyInput,
@@ -17,6 +18,7 @@ export type StudioEditorState = Readonly<{
export type StudioContextValue = Readonly<{
gateway: StudioGateway;
resolvePublishedLabel: ResolvePublishedLabel;
now(): Date;
editor: StudioEditorState | null;
requestAnnouncement: string;