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,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 '@/api/client' | @@ -4,6 +4,7 @@ import { catalog, partners, purchaseOrders } from '@/api/client' | ||
| 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 '@/api/client' | @@ -4,6 +4,7 @@ import { catalog, partners, salesOrders } from '@/api/client' | ||
| 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 '@/api/client' | @@ -4,6 +4,7 @@ import { catalog, inventory, production } from '@/api/client' | ||
| 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'} |