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