Skip to content

Commit a15b89a

Browse files
xuyushun441-sysos-zhuangclaude
authored
feat(spec,showcase): allowCreate flag for inline lookup quick-create (#2128)
Exposes the opt-in inline quick-create the objectui record picker supports: when no match exists, the user creates a record from the typed text via an optimistic dataSource.create with the display field. Best for simple objects whose only required field is the display field. - spec: add `allowCreate` to FieldSchema (flows through Field.lookup via FieldInput); classify it live in the liveness ledger (objectui consumer). - showcase: enable it on showcase_category.parent (Category requires only `name`, so quick-create succeeds) to demonstrate the flow end-to-end. - test: assert allowCreate survives FieldSchema.parse. Pairs with objectui #1863 (renderer quick-create reads allowCreate || allow_create). Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent adac0f7 commit a15b89a

4 files changed

Lines changed: 8 additions & 1 deletion

File tree

examples/app-showcase/src/objects/category.object.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export const Category = ObjectSchema.create({
1515

1616
fields: {
1717
name: Field.text({ label: 'Name', required: true, searchable: true, maxLength: 120 }),
18-
parent: Field.lookup('showcase_category', { label: 'Parent Category' }),
18+
parent: Field.lookup('showcase_category', { label: 'Parent Category', allowCreate: true }),
1919
color: Field.color({ label: 'Color' }),
2020
sort_order: Field.number({ label: 'Sort Order', min: 0, defaultValue: 0 }),
2121
},

packages/spec/liveness/field.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,10 @@
179179
"status": "live",
180180
"note": "objectui LookupField — dependent/cascading lookup; restricts candidates by another field's value (reads dependsOn || depends_on)."
181181
},
182+
"allowCreate": {
183+
"status": "live",
184+
"note": "objectui LookupField — opt-in inline quick-create (dataSource.create from typed text) (reads allowCreate || allow_create)."
185+
},
182186
"maxRating": {
183187
"status": "dead",
184188
"evidence": "RatingField reads `max` (RatingField.tsx:13) — dead + redundant with max",

packages/spec/src/data/field.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,7 @@ describe('FieldSchema', () => {
309309
lookupPageSize: 20,
310310
lookupFilters: [{ field: 'status', operator: 'eq', value: 'active' }],
311311
dependsOn: ['region', { field: 'country', param: 'country_code' }],
312+
allowCreate: true,
312313
};
313314

314315
const result = FieldSchema.parse(lookupField);
@@ -318,6 +319,7 @@ describe('FieldSchema', () => {
318319
expect(result.lookupPageSize).toBe(20);
319320
expect(result.lookupFilters?.[0]).toEqual({ field: 'status', operator: 'eq', value: 'active' });
320321
expect(result.dependsOn).toHaveLength(2);
322+
expect(result.allowCreate).toBe(true);
321323
});
322324

323325
it('builds a lookup with picker config via Field.lookup', () => {

packages/spec/src/data/field.zod.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,7 @@ export const FieldSchema = lazySchema(() => z.object({
473473
field: z.string(),
474474
param: z.string().optional(),
475475
})])).optional().describe('Dependent lookup: restrict candidates by the value of other field(s) on the same record. String = same local/remote key; {field,param} when the remote filter key differs.'),
476+
allowCreate: z.boolean().optional().describe('Allow inline quick-create from the record picker: when no match exists the user can create a record from the typed text (optimistic dataSource.create with the display field). Best for simple objects whose only required field is the display field.'),
476477

477478
/** Calculation — CEL formula. Plain string accepted for back-compat; build emits canonical envelope. */
478479
expression: ExpressionInputSchema.optional().describe('Formula expression (CEL). e.g. F`record.amount * 0.1`'),

0 commit comments

Comments
 (0)