Skip to content

Commit a897bd5

Browse files
committed
feat: enhance UI view generation with intelligent column selection and improved form layout
1 parent 4efa9c1 commit a897bd5

1 file changed

Lines changed: 61 additions & 20 deletions

File tree

packages/objectql/src/protocol.ts

Lines changed: 61 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -77,31 +77,72 @@ export class ObjectStackProtocolImplementation implements ObjectStackProtocol {
7777
const schema = SchemaRegistry.getObject(request.object);
7878
if (!schema) throw new Error(`Object ${request.object} not found`);
7979

80-
let view: any;
80+
const fields = schema.fields || {};
81+
const fieldKeys = Object.keys(fields);
82+
8183
if (request.type === 'list') {
82-
view = {
83-
type: 'list',
84-
object: request.object,
85-
columns: Object.keys(schema.fields || {}).slice(0, 5).map(f => ({
86-
field: f,
87-
label: schema.fields[f].label || f
88-
}))
84+
// Intelligent Column Selection
85+
// 1. Always include 'name' or name-like fields
86+
// 2. Limit to 6 columns by default
87+
const priorityFields = ['name', 'title', 'label', 'subject', 'email', 'status', 'type', 'category', 'created_at'];
88+
89+
let columns = fieldKeys.filter(k => priorityFields.includes(k));
90+
91+
// If few priority fields, add others until 5
92+
if (columns.length < 5) {
93+
const remaining = fieldKeys.filter(k => !columns.includes(k) && k !== 'id' && !fields[k].hidden);
94+
columns = [...columns, ...remaining.slice(0, 5 - columns.length)];
95+
}
96+
97+
// Sort columns by priority then alphabet or schema order
98+
// For now, just keep them roughly in order they appear in schema or priority list
99+
100+
return {
101+
list: {
102+
type: 'grid' as const,
103+
object: request.object,
104+
label: schema.label || schema.name,
105+
columns: columns.map(f => ({
106+
field: f,
107+
label: fields[f]?.label || f,
108+
sortable: true
109+
})),
110+
sort: fields['created_at'] ? ([{ field: 'created_at', order: 'desc' }] as any) : undefined,
111+
searchableFields: columns.slice(0, 3) // Make first few textual columns searchable
112+
}
89113
};
90114
} else {
91-
view = {
92-
type: 'form',
93-
object: request.object,
94-
sections: [
95-
{
96-
label: 'General',
97-
fields: Object.keys(schema.fields || {}).map(f => ({
98-
field: f
99-
}))
100-
}
101-
]
115+
// Form View Generation
116+
// Simple single-section layout for now
117+
const formFields = fieldKeys
118+
.filter(k => k !== 'id' && k !== 'created_at' && k !== 'modified_at' && !fields[k].hidden)
119+
.map(f => ({
120+
field: f,
121+
label: fields[f]?.label,
122+
required: fields[f]?.required,
123+
readonly: fields[f]?.readonly,
124+
type: fields[f]?.type,
125+
// Default to 2 columns for most, 1 for textareas
126+
colSpan: (fields[f]?.type === 'textarea' || fields[f]?.type === 'html') ? 2 : 1
127+
}));
128+
129+
return {
130+
form: {
131+
type: 'simple' as const,
132+
object: request.object,
133+
label: `Edit ${schema.label || schema.name}`,
134+
sections: [
135+
{
136+
label: 'General Information',
137+
columns: 2 as const,
138+
collapsible: false,
139+
collapsed: false,
140+
fields: formFields
141+
}
142+
]
143+
}
102144
};
103145
}
104-
return view;
105146
}
106147

107148
async findData(request: { object: string, query?: any }) {

0 commit comments

Comments
 (0)