Mirror PE PeWorkspaceCreateView Workspace pattern. Drafter pick V2 workflow IsUserSelectable=true filter ApplicableType=Contract(3). Changes × 2 app: - Add useQuery fetch /api/approval-workflows-v2?applicableType=3 + filter client-side isUserSelectable=true (mirror PE Mig 25 pattern) - Add Select dropdown "Quy trình duyệt V2 (tùy chọn)" trong ContractHeaderForm (create mode panel 2) - Wire approvalWorkflowId vào CreateContractCommand POST body - Conditional UI: blank = V1 fallback auto pick (7 prod contract behavior giữ nguyên); user pick V2 → pin ApprovalWorkflowId Mig 32 schema - Hint khi 0 workflows V2 admin ghim → message rõ V1 fallback Verify: - npm run build × 2 app PASS 0 TS err (1.32MB fe-user, 1.40MB fe-admin) - Mirror 2 app §3.9: +44 LOC mỗi file = +88 LOC total byte-similar - API endpoint /api/approval-workflows-v2 existing (Mig 25 Plan AA S24) - BE CreateContractCommand.ApprovalWorkflowId field đã add Chunk E1 (em main commit prior) — FE wire safe - Backward compat: V1 contract path unchanged khi user bỏ trống dropdown Plan B chain (6 chunks): - A158898e8✅ Entity ApprovalWorkflowId + CurrentApprovalLevelOrder - A2a85e437✅ Mig 32 + Seed sample V2 Contract workflow - B138469d✅ Service ApproveV2 branch (PE pattern mirror) - C26c98d3✅ Mig 33 ContractLevelOpinions - B21f199b0✅ UPSERT LevelOpinion block (PE Mig 26 mirror) - D (this) ✅ FE Workspace V2 dropdown - E FE Section 5 V2 (em main + Implementer split E1+E2 sau) Pattern 16-bis 4-place mirror check: - Page file × 2 app: edited (insertion mirror byte-similar) - App.tsx Routes: N/A (enhance existing /contracts/new route) - menuKeys.ts: N/A (không thêm menu key mới) - Layout staticMap: N/A (route unchanged) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
React + TypeScript + Vite
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
Currently, two official plugins are available:
- @vitejs/plugin-react uses Oxc
- @vitejs/plugin-react-swc uses SWC
React Compiler
The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see this documentation.
Expanding the ESLint configuration
If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...
// Remove tseslint.configs.recommended and replace with this
tseslint.configs.recommendedTypeChecked,
// Alternatively, use this for stricter rules
tseslint.configs.strictTypeChecked,
// Optionally, add this for stylistic rules
tseslint.configs.stylisticTypeChecked,
// Other configs...
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])
You can also install eslint-plugin-react-x and eslint-plugin-react-dom for React-specific lint rules:
// eslint.config.js
import reactX from 'eslint-plugin-react-x'
import reactDom from 'eslint-plugin-react-dom'
export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...
// Enable lint rules for React
reactX.configs['recommended-typescript'],
// Enable lint rules for React DOM
reactDom.configs.recommended,
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])