mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-03-09 16:07:49 +00:00
refactor(prd-editor): modularize PRD editor with typed feature modules
Break the legacy PRDEditor.jsx monolith into a feature-based TypeScript architecture under src/components/prd-editor while keeping behavior parity and readability. Key changes: - Replace PRDEditor.jsx with a typed orchestrator component and a compatibility export bridge at src/components/PRDEditor.tsx. - Split responsibilities into dedicated hooks: document loading/init, existing PRD registry fetching, save workflow with overwrite detection, and keyboard shortcuts. - Split UI into focused view components: header, editor/preview body, footer stats, loading state, generate-tasks modal, and overwrite-confirm modal. - Move filename concerns into utility helpers (sanitize, extension handling, default naming) and centralize template/constants. - Keep component-local state close to the UI that owns it (workspace controls/modal toggles), while shared workflow state remains in the feature container. - Reuse the existing MarkdownPreview component for safer markdown rendering instead of ad-hoc HTML conversion. - Update TaskMasterPanel integration to consume typed PRDEditor directly (remove any-cast) and pass isExisting metadata for correct overwrite behavior. - Keep all new/changed files below 300 lines and add targeted comments where behavior needs clarification. Validation: - npm run typecheck - npm run build
This commit is contained in:
50
src/components/prd-editor/hooks/usePrdRegistry.ts
Normal file
50
src/components/prd-editor/hooks/usePrdRegistry.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { api } from '../../../utils/api';
|
||||
import type { ExistingPrdFile, PrdListResponse } from '../types';
|
||||
|
||||
type UsePrdRegistryArgs = {
|
||||
projectName?: string;
|
||||
};
|
||||
|
||||
type UsePrdRegistryResult = {
|
||||
existingPrds: ExistingPrdFile[];
|
||||
refreshExistingPrds: () => Promise<void>;
|
||||
};
|
||||
|
||||
function getPrdFiles(data: PrdListResponse): ExistingPrdFile[] {
|
||||
return data.prdFiles || data.prds || [];
|
||||
}
|
||||
|
||||
export function usePrdRegistry({ projectName }: UsePrdRegistryArgs): UsePrdRegistryResult {
|
||||
const [existingPrds, setExistingPrds] = useState<ExistingPrdFile[]>([]);
|
||||
|
||||
const refreshExistingPrds = useCallback(async () => {
|
||||
if (!projectName) {
|
||||
setExistingPrds([]);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await api.get(`/taskmaster/prd/${encodeURIComponent(projectName)}`);
|
||||
if (!response.ok) {
|
||||
setExistingPrds([]);
|
||||
return;
|
||||
}
|
||||
|
||||
const data = (await response.json()) as PrdListResponse;
|
||||
setExistingPrds(getPrdFiles(data));
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch existing PRDs:', error);
|
||||
setExistingPrds([]);
|
||||
}
|
||||
}, [projectName]);
|
||||
|
||||
useEffect(() => {
|
||||
void refreshExistingPrds();
|
||||
}, [refreshExistingPrds]);
|
||||
|
||||
return {
|
||||
existingPrds,
|
||||
refreshExistingPrds,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user