Commit 6354c9d3ef385fd6b6d2ecf4af8cb70d9c6234f7
1 parent
8b9e0ab2
fix(web): add DynamicExtFields to all create pages
Showing
6 changed files
with
82 additions
and
11 deletions
distribution/src/main/kotlin/org/vibeerp/demo/DemoSeedRunner.kt
| @@ -186,7 +186,7 @@ class DemoSeedRunner( | @@ -186,7 +186,7 @@ class DemoSeedRunner( | ||
| 186 | val locations = listOf( | 186 | val locations = listOf( |
| 187 | DemoLocation("WH-RAW", "Raw Materials Warehouse", "WAREHOUSE"), | 187 | DemoLocation("WH-RAW", "Raw Materials Warehouse", "WAREHOUSE"), |
| 188 | DemoLocation("WH-FG", "Finished Goods Warehouse", "WAREHOUSE"), | 188 | DemoLocation("WH-FG", "Finished Goods Warehouse", "WAREHOUSE"), |
| 189 | - DemoLocation("WH-QUARANTINE", "Quarantine Area", "QUARANTINE"), | 189 | + DemoLocation("WH-STAGING", "Staging Area", "VIRTUAL"), |
| 190 | ) | 190 | ) |
| 191 | 191 | ||
| 192 | val sql = """ | 192 | val sql = """ |
| @@ -228,9 +228,9 @@ class DemoSeedRunner( | @@ -228,9 +228,9 @@ class DemoSeedRunner( | ||
| 228 | ) | 228 | ) |
| 229 | 229 | ||
| 230 | val balances = listOf( | 230 | val balances = listOf( |
| 231 | - DemoBalance("PAPER-A3-120G", "WH-RAW", BigDecimal("5000.0000")), | ||
| 232 | - DemoBalance("INK-CMYK-BLACK", "WH-RAW", BigDecimal("200.0000")), | ||
| 233 | - DemoBalance("BROCHURE-A4", "WH-FG", BigDecimal("500.0000")), | 231 | + DemoBalance("PAPER-A3-120G", "WH-RAW", BigDecimal("10000.0000")), |
| 232 | + DemoBalance("INK-CMYK-BLACK", "WH-RAW", BigDecimal("1000.0000")), | ||
| 233 | + DemoBalance("BROCHURE-A4", "WH-FG", BigDecimal("5000.0000")), | ||
| 234 | ) | 234 | ) |
| 235 | 235 | ||
| 236 | val balanceSql = """ | 236 | val balanceSql = """ |
| @@ -286,14 +286,13 @@ class DemoSeedRunner( | @@ -286,14 +286,13 @@ class DemoSeedRunner( | ||
| 286 | 286 | ||
| 287 | // --- SO-001: Acme Publishing, 2 lines --- | 287 | // --- SO-001: Acme Publishing, 2 lines --- |
| 288 | val so1Id = UUID.randomUUID() | 288 | val so1Id = UUID.randomUUID() |
| 289 | - val so1Total = BigDecimal("1000.0000") | ||
| 290 | - .add(BigDecimal("400.0000")) // 1000 * 0.50 + 5 * 80 | 289 | + val so1Total = BigDecimal("900.0000") // 1000 * 0.50 + 500 * 0.80 |
| 291 | insertSalesOrder(so1Id, "DEMO-SO-001", "CUST-ACME", orderDate, "USD", so1Total, now, principal) | 290 | insertSalesOrder(so1Id, "DEMO-SO-001", "CUST-ACME", orderDate, "USD", so1Total, now, principal) |
| 292 | 291 | ||
| 293 | insertSalesOrderLine(so1Id, 1, "BROCHURE-A4", | 292 | insertSalesOrderLine(so1Id, 1, "BROCHURE-A4", |
| 294 | BigDecimal("1000.0000"), BigDecimal("0.5000"), "USD", now, principal) | 293 | BigDecimal("1000.0000"), BigDecimal("0.5000"), "USD", now, principal) |
| 295 | - insertSalesOrderLine(so1Id, 2, "DESIGN-HOURLY", | ||
| 296 | - BigDecimal("5.0000"), BigDecimal("80.0000"), "USD", now, principal) | 294 | + insertSalesOrderLine(so1Id, 2, "BROCHURE-A4", |
| 295 | + BigDecimal("500.0000"), BigDecimal("0.8000"), "USD", now, principal) | ||
| 297 | 296 | ||
| 298 | // --- SO-002: Globex Print, 1 line --- | 297 | // --- SO-002: Globex Print, 1 line --- |
| 299 | val so2Id = UUID.randomUUID() | 298 | val so2Id = UUID.randomUUID() |
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'} |
web/src/pages/MetadataAdminPage.tsx
| @@ -145,6 +145,8 @@ export function MetadataAdminPage() { | @@ -145,6 +145,8 @@ export function MetadataAdminPage() { | ||
| 145 | const [cfPii, setCfPii] = useState(false) | 145 | const [cfPii, setCfPii] = useState(false) |
| 146 | const [cfLabelEn, setCfLabelEn] = useState('') | 146 | const [cfLabelEn, setCfLabelEn] = useState('') |
| 147 | const [cfLabelZh, setCfLabelZh] = useState('') | 147 | const [cfLabelZh, setCfLabelZh] = useState('') |
| 148 | + const [cfAllowedValues, setCfAllowedValues] = useState('') | ||
| 149 | + const [cfMaxLength, setCfMaxLength] = useState('') | ||
| 148 | const [cfSaving, setCfSaving] = useState(false) | 150 | const [cfSaving, setCfSaving] = useState(false) |
| 149 | 151 | ||
| 150 | // ── Loaders ─────────────────────────────────────────────────────── | 152 | // ── Loaders ─────────────────────────────────────────────────────── |
| @@ -192,6 +194,8 @@ export function MetadataAdminPage() { | @@ -192,6 +194,8 @@ export function MetadataAdminPage() { | ||
| 192 | setCfTargetEntity('') | 194 | setCfTargetEntity('') |
| 193 | setCfFieldKey('') | 195 | setCfFieldKey('') |
| 194 | setCfTypeKind('string') | 196 | setCfTypeKind('string') |
| 197 | + setCfAllowedValues('') | ||
| 198 | + setCfMaxLength('') | ||
| 195 | setCfRequired(false) | 199 | setCfRequired(false) |
| 196 | setCfPii(false) | 200 | setCfPii(false) |
| 197 | setCfLabelEn('') | 201 | setCfLabelEn('') |
| @@ -222,7 +226,11 @@ export function MetadataAdminPage() { | @@ -222,7 +226,11 @@ export function MetadataAdminPage() { | ||
| 222 | const body: Omit<CustomFieldDef, 'source'> = { | 226 | const body: Omit<CustomFieldDef, 'source'> = { |
| 223 | key: cfFieldKey, | 227 | key: cfFieldKey, |
| 224 | targetEntity: cfTargetEntity, | 228 | targetEntity: cfTargetEntity, |
| 225 | - type: { kind: cfTypeKind }, | 229 | + type: { |
| 230 | + kind: cfTypeKind, | ||
| 231 | + ...(cfTypeKind === 'enum' && cfAllowedValues ? { allowedValues: cfAllowedValues.split(',').map((v) => v.trim()).filter(Boolean) } : {}), | ||
| 232 | + ...(cfTypeKind === 'string' && cfMaxLength ? { maxLength: Number(cfMaxLength) } : {}), | ||
| 233 | + }, | ||
| 226 | required: cfRequired, | 234 | required: cfRequired, |
| 227 | pii: cfPii, | 235 | pii: cfPii, |
| 228 | labelTranslations: { | 236 | labelTranslations: { |
| @@ -613,6 +621,34 @@ export function MetadataAdminPage() { | @@ -613,6 +621,34 @@ export function MetadataAdminPage() { | ||
| 613 | ))} | 621 | ))} |
| 614 | </select> | 622 | </select> |
| 615 | </div> | 623 | </div> |
| 624 | + {cfTypeKind === 'enum' && ( | ||
| 625 | + <div> | ||
| 626 | + <label className="block text-xs font-medium text-slate-700"> | ||
| 627 | + Allowed values (comma-separated) | ||
| 628 | + </label> | ||
| 629 | + <input | ||
| 630 | + type="text" | ||
| 631 | + value={cfAllowedValues} | ||
| 632 | + onChange={(e) => setCfAllowedValues(e.target.value)} | ||
| 633 | + placeholder="LOW, NORMAL, HIGH, URGENT" | ||
| 634 | + className="mt-1 w-full rounded-md border border-slate-300 px-2 py-1.5 text-sm" | ||
| 635 | + /> | ||
| 636 | + </div> | ||
| 637 | + )} | ||
| 638 | + {cfTypeKind === 'string' && ( | ||
| 639 | + <div> | ||
| 640 | + <label className="block text-xs font-medium text-slate-700"> | ||
| 641 | + Max length | ||
| 642 | + </label> | ||
| 643 | + <input | ||
| 644 | + type="number" | ||
| 645 | + value={cfMaxLength} | ||
| 646 | + onChange={(e) => setCfMaxLength(e.target.value)} | ||
| 647 | + placeholder="255" | ||
| 648 | + className="mt-1 w-full rounded-md border border-slate-300 px-2 py-1.5 text-sm" | ||
| 649 | + /> | ||
| 650 | + </div> | ||
| 651 | + )} | ||
| 616 | <div className="flex items-end gap-4 pb-1"> | 652 | <div className="flex items-end gap-4 pb-1"> |
| 617 | <label className="flex items-center gap-1.5 text-sm text-slate-700"> | 653 | <label className="flex items-center gap-1.5 text-sm text-slate-700"> |
| 618 | <input | 654 | <input |