Commit 02ac41c1176721740c0fa77bd26b2fc89eb67d42

Authored by zichun
1 parent dae22ca4

fix(web): add DynamicExtFields to all create pages

web/src/pages/CreateLocationPage.tsx
@@ -3,6 +3,7 @@ import { useNavigate } from 'react-router-dom' @@ -3,6 +3,7 @@ import { useNavigate } from 'react-router-dom'
3 import { inventory } from '@/api/client' 3 import { inventory } from '@/api/client'
4 import { PageHeader } from '@/components/PageHeader' 4 import { PageHeader } from '@/components/PageHeader'
5 import { ErrorBox } from '@/components/ErrorBox' 5 import { ErrorBox } from '@/components/ErrorBox'
  6 +import { DynamicExtFields } from '@/components/DynamicExtFields'
6 7
7 const LOCATION_TYPES = ['WAREHOUSE', 'BIN', 'VIRTUAL'] as const 8 const LOCATION_TYPES = ['WAREHOUSE', 'BIN', 'VIRTUAL'] as const
8 9
@@ -11,6 +12,7 @@ export function CreateLocationPage() { @@ -11,6 +12,7 @@ export function CreateLocationPage() {
11 const [code, setCode] = useState('') 12 const [code, setCode] = useState('')
12 const [name, setName] = useState('') 13 const [name, setName] = useState('')
13 const [type, setType] = useState<string>('WAREHOUSE') 14 const [type, setType] = useState<string>('WAREHOUSE')
  15 + const [ext, setExt] = useState<Record<string, unknown>>({})
14 const [submitting, setSubmitting] = useState(false) 16 const [submitting, setSubmitting] = useState(false)
15 const [error, setError] = useState<Error | null>(null) 17 const [error, setError] = useState<Error | null>(null)
16 18
@@ -19,7 +21,8 @@ export function CreateLocationPage() { @@ -19,7 +21,8 @@ export function CreateLocationPage() {
19 setError(null) 21 setError(null)
20 setSubmitting(true) 22 setSubmitting(true)
21 try { 23 try {
22 - await inventory.createLocation({ code, name, type }) 24 + const extPayload = Object.keys(ext).length > 0 ? ext : undefined
  25 + await inventory.createLocation({ code, name, type, ...(extPayload ? { ext: extPayload } : {}) })
23 navigate('/locations') 26 navigate('/locations')
24 } catch (err: unknown) { 27 } catch (err: unknown) {
25 setError(err instanceof Error ? err : new Error(String(err))) 28 setError(err instanceof Error ? err : new Error(String(err)))
@@ -53,6 +56,11 @@ export function CreateLocationPage() { @@ -53,6 +56,11 @@ export function CreateLocationPage() {
53 {LOCATION_TYPES.map((t) => <option key={t} value={t}>{t}</option>)} 56 {LOCATION_TYPES.map((t) => <option key={t} value={t}>{t}</option>)}
54 </select> 57 </select>
55 </div> 58 </div>
  59 + <DynamicExtFields
  60 + entityName="Location"
  61 + values={ext}
  62 + onChange={(k, v) => setExt((prev) => ({ ...prev, [k]: v }))}
  63 + />
56 {error && <ErrorBox error={error} />} 64 {error && <ErrorBox error={error} />}
57 <button type="submit" className="btn-primary" disabled={submitting}> 65 <button type="submit" className="btn-primary" disabled={submitting}>
58 {submitting ? 'Creating...' : 'Create Location'} 66 {submitting ? 'Creating...' : 'Create Location'}
web/src/pages/CreatePurchaseOrderPage.tsx
@@ -4,6 +4,7 @@ import { catalog, partners, purchaseOrders } from &#39;@/api/client&#39; @@ -4,6 +4,7 @@ import { catalog, partners, purchaseOrders } from &#39;@/api/client&#39;
4 import type { Item, Partner } from '@/types/api' 4 import type { Item, Partner } from '@/types/api'
5 import { PageHeader } from '@/components/PageHeader' 5 import { PageHeader } from '@/components/PageHeader'
6 import { ErrorBox } from '@/components/ErrorBox' 6 import { ErrorBox } from '@/components/ErrorBox'
  7 +import { DynamicExtFields } from '@/components/DynamicExtFields'
7 8
8 interface LineInput { 9 interface LineInput {
9 itemCode: string 10 itemCode: string
@@ -20,6 +21,7 @@ export function CreatePurchaseOrderPage() { @@ -20,6 +21,7 @@ export function CreatePurchaseOrderPage() {
20 const [lines, setLines] = useState<LineInput[]>([{ itemCode: '', quantity: '', unitPrice: '' }]) 21 const [lines, setLines] = useState<LineInput[]>([{ itemCode: '', quantity: '', unitPrice: '' }])
21 const [items, setItems] = useState<Item[]>([]) 22 const [items, setItems] = useState<Item[]>([])
22 const [supplierList, setSupplierList] = useState<Partner[]>([]) 23 const [supplierList, setSupplierList] = useState<Partner[]>([])
  24 + const [ext, setExt] = useState<Record<string, unknown>>({})
23 const [submitting, setSubmitting] = useState(false) 25 const [submitting, setSubmitting] = useState(false)
24 const [error, setError] = useState<Error | null>(null) 26 const [error, setError] = useState<Error | null>(null)
25 27
@@ -51,6 +53,7 @@ export function CreatePurchaseOrderPage() { @@ -51,6 +53,7 @@ export function CreatePurchaseOrderPage() {
51 setError(null) 53 setError(null)
52 setSubmitting(true) 54 setSubmitting(true)
53 try { 55 try {
  56 + const extPayload = Object.keys(ext).length > 0 ? ext : undefined
54 const created = await purchaseOrders.create({ 57 const created = await purchaseOrders.create({
55 code, partnerCode, currencyCode, 58 code, partnerCode, currencyCode,
56 orderDate: new Date().toISOString().slice(0, 10), 59 orderDate: new Date().toISOString().slice(0, 10),
@@ -62,6 +65,7 @@ export function CreatePurchaseOrderPage() { @@ -62,6 +65,7 @@ export function CreatePurchaseOrderPage() {
62 unitPrice: Number(l.unitPrice), 65 unitPrice: Number(l.unitPrice),
63 currencyCode, 66 currencyCode,
64 })), 67 })),
  68 + ...(extPayload ? { ext: extPayload } : {}),
65 }) 69 })
66 navigate(`/purchase-orders/${created.id}`) 70 navigate(`/purchase-orders/${created.id}`)
67 } catch (err: unknown) { 71 } catch (err: unknown) {
@@ -128,6 +132,11 @@ export function CreatePurchaseOrderPage() { @@ -128,6 +132,11 @@ export function CreatePurchaseOrderPage() {
128 </div> 132 </div>
129 </div> 133 </div>
130 134
  135 + <DynamicExtFields
  136 + entityName="PurchaseOrder"
  137 + values={ext}
  138 + onChange={(k, v) => setExt((prev) => ({ ...prev, [k]: v }))}
  139 + />
131 {error && <ErrorBox error={error} />} 140 {error && <ErrorBox error={error} />}
132 <button type="submit" className="btn-primary" disabled={submitting}> 141 <button type="submit" className="btn-primary" disabled={submitting}>
133 {submitting ? 'Creating...' : 'Create Purchase Order'} 142 {submitting ? 'Creating...' : 'Create Purchase Order'}
web/src/pages/CreateSalesOrderPage.tsx
@@ -4,6 +4,7 @@ import { catalog, partners, salesOrders } from &#39;@/api/client&#39; @@ -4,6 +4,7 @@ import { catalog, partners, salesOrders } from &#39;@/api/client&#39;
4 import type { Item, Partner } from '@/types/api' 4 import type { Item, Partner } from '@/types/api'
5 import { PageHeader } from '@/components/PageHeader' 5 import { PageHeader } from '@/components/PageHeader'
6 import { ErrorBox } from '@/components/ErrorBox' 6 import { ErrorBox } from '@/components/ErrorBox'
  7 +import { DynamicExtFields } from '@/components/DynamicExtFields'
7 8
8 interface LineInput { 9 interface LineInput {
9 itemCode: string 10 itemCode: string
@@ -21,6 +22,7 @@ export function CreateSalesOrderPage() { @@ -21,6 +22,7 @@ export function CreateSalesOrderPage() {
21 ]) 22 ])
22 const [items, setItems] = useState<Item[]>([]) 23 const [items, setItems] = useState<Item[]>([])
23 const [partnerList, setPartnerList] = useState<Partner[]>([]) 24 const [partnerList, setPartnerList] = useState<Partner[]>([])
  25 + const [ext, setExt] = useState<Record<string, unknown>>({})
24 const [submitting, setSubmitting] = useState(false) 26 const [submitting, setSubmitting] = useState(false)
25 const [error, setError] = useState<Error | null>(null) 27 const [error, setError] = useState<Error | null>(null)
26 28
@@ -52,6 +54,7 @@ export function CreateSalesOrderPage() { @@ -52,6 +54,7 @@ export function CreateSalesOrderPage() {
52 setError(null) 54 setError(null)
53 setSubmitting(true) 55 setSubmitting(true)
54 try { 56 try {
  57 + const extPayload = Object.keys(ext).length > 0 ? ext : undefined
55 const created = await salesOrders.create({ 58 const created = await salesOrders.create({
56 code, 59 code,
57 partnerCode, 60 partnerCode,
@@ -64,7 +67,8 @@ export function CreateSalesOrderPage() { @@ -64,7 +67,8 @@ export function CreateSalesOrderPage() {
64 unitPrice: Number(l.unitPrice), 67 unitPrice: Number(l.unitPrice),
65 currencyCode, 68 currencyCode,
66 })), 69 })),
67 - }) 70 + ...(extPayload ? { ext: extPayload } : {}),
  71 + } as Parameters<typeof salesOrders.create>[0])
68 navigate(`/sales-orders/${created.id}`) 72 navigate(`/sales-orders/${created.id}`)
69 } catch (err: unknown) { 73 } catch (err: unknown) {
70 setError(err instanceof Error ? err : new Error(String(err))) 74 setError(err instanceof Error ? err : new Error(String(err)))
@@ -177,6 +181,12 @@ export function CreateSalesOrderPage() { @@ -177,6 +181,12 @@ export function CreateSalesOrderPage() {
177 </div> 181 </div>
178 </div> 182 </div>
179 183
  184 + <DynamicExtFields
  185 + entityName="SalesOrder"
  186 + values={ext}
  187 + onChange={(k, v) => setExt((prev) => ({ ...prev, [k]: v }))}
  188 + />
  189 +
180 {error && <ErrorBox error={error} />} 190 {error && <ErrorBox error={error} />}
181 191
182 <div className="flex items-center gap-3 pt-2"> 192 <div className="flex items-center gap-3 pt-2">
web/src/pages/CreateWorkOrderPage.tsx
@@ -4,6 +4,7 @@ import { catalog, inventory, production } from &#39;@/api/client&#39; @@ -4,6 +4,7 @@ import { catalog, inventory, production } from &#39;@/api/client&#39;
4 import type { Item, Location } from '@/types/api' 4 import type { Item, Location } from '@/types/api'
5 import { PageHeader } from '@/components/PageHeader' 5 import { PageHeader } from '@/components/PageHeader'
6 import { ErrorBox } from '@/components/ErrorBox' 6 import { ErrorBox } from '@/components/ErrorBox'
  7 +import { DynamicExtFields } from '@/components/DynamicExtFields'
7 8
8 interface BomLine { itemCode: string; quantityPerUnit: string; sourceLocationCode: string } 9 interface BomLine { itemCode: string; quantityPerUnit: string; sourceLocationCode: string }
9 interface OpLine { operationCode: string; workCenter: string; standardMinutes: string } 10 interface OpLine { operationCode: string; workCenter: string; standardMinutes: string }
@@ -18,6 +19,7 @@ export function CreateWorkOrderPage() { @@ -18,6 +19,7 @@ export function CreateWorkOrderPage() {
18 const [ops, setOps] = useState<OpLine[]>([]) 19 const [ops, setOps] = useState<OpLine[]>([])
19 const [items, setItems] = useState<Item[]>([]) 20 const [items, setItems] = useState<Item[]>([])
20 const [locations, setLocations] = useState<Location[]>([]) 21 const [locations, setLocations] = useState<Location[]>([])
  22 + const [ext, setExt] = useState<Record<string, unknown>>({})
21 const [submitting, setSubmitting] = useState(false) 23 const [submitting, setSubmitting] = useState(false)
22 const [error, setError] = useState<Error | null>(null) 24 const [error, setError] = useState<Error | null>(null)
23 25
@@ -47,6 +49,7 @@ export function CreateWorkOrderPage() { @@ -47,6 +49,7 @@ export function CreateWorkOrderPage() {
47 setError(null) 49 setError(null)
48 setSubmitting(true) 50 setSubmitting(true)
49 try { 51 try {
  52 + const extPayload = Object.keys(ext).length > 0 ? ext : undefined
50 const created = await production.createWorkOrder({ 53 const created = await production.createWorkOrder({
51 code, outputItemCode, 54 code, outputItemCode,
52 outputQuantity: Number(outputQuantity), 55 outputQuantity: Number(outputQuantity),
@@ -61,6 +64,7 @@ export function CreateWorkOrderPage() { @@ -61,6 +64,7 @@ export function CreateWorkOrderPage() {
61 workCenter: o.workCenter, 64 workCenter: o.workCenter,
62 standardMinutes: Number(o.standardMinutes), 65 standardMinutes: Number(o.standardMinutes),
63 })), 66 })),
  67 + ...(extPayload ? { ext: extPayload } : {}),
64 }) 68 })
65 navigate(`/work-orders/${created.id}`) 69 navigate(`/work-orders/${created.id}`)
66 } catch (err: unknown) { 70 } catch (err: unknown) {
@@ -160,6 +164,11 @@ export function CreateWorkOrderPage() { @@ -160,6 +164,11 @@ export function CreateWorkOrderPage() {
160 </div> 164 </div>
161 </div> 165 </div>
162 166
  167 + <DynamicExtFields
  168 + entityName="WorkOrder"
  169 + values={ext}
  170 + onChange={(k, v) => setExt((prev) => ({ ...prev, [k]: v }))}
  171 + />
163 {error && <ErrorBox error={error} />} 172 {error && <ErrorBox error={error} />}
164 <button type="submit" className="btn-primary" disabled={submitting}> 173 <button type="submit" className="btn-primary" disabled={submitting}>
165 {submitting ? 'Creating...' : 'Create Work Order'} 174 {submitting ? 'Creating...' : 'Create Work Order'}