mirror of
https://github.com/bknd-io/bknd/
synced 2026-08-02 16:16:02 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7d89fe4894 |
@@ -18,6 +18,7 @@ export const entityConfigSchema = s
|
||||
sort_field: s.string({ default: config.data.default_primary_field }),
|
||||
sort_dir: s.string({ enum: ["asc", "desc"], default: "asc" }),
|
||||
primary_format: s.string({ enum: primaryFieldTypes }),
|
||||
fields_order: s.array(s.string()).optional(),
|
||||
},
|
||||
{ default: {} },
|
||||
)
|
||||
@@ -137,7 +138,9 @@ export class Entity<
|
||||
}
|
||||
|
||||
getFillableFields(context?: TActionContext, include_virtual?: boolean): Field[] {
|
||||
return this.getFields(include_virtual).filter((field) => field.isFillable(context));
|
||||
return this.getFields({ virtual: include_virtual }).filter((field) =>
|
||||
field.isFillable(context),
|
||||
);
|
||||
}
|
||||
|
||||
getRequiredFields(): Field[] {
|
||||
@@ -189,9 +192,24 @@ export class Entity<
|
||||
return this.fields.findIndex((field) => field.name === name) !== -1;
|
||||
}
|
||||
|
||||
getFields(include_virtual: boolean = false): Field[] {
|
||||
if (include_virtual) return this.fields;
|
||||
return this.fields.filter((f) => !f.isVirtual());
|
||||
getFields(opts?: { virtual?: boolean; sorted?: boolean }): Field[] {
|
||||
const fields = [...this.fields];
|
||||
const sort = opts?.sorted !== false;
|
||||
const fields_order = this.config.fields_order;
|
||||
if (fields_order && fields_order.length > 0 && sort) {
|
||||
if (fields_order.length !== this.fields.length) {
|
||||
$console.warn("Fields order must contain all fields");
|
||||
} else {
|
||||
// sort fields by order
|
||||
fields.sort((a, b) => {
|
||||
const a_index = fields_order.indexOf(a.name);
|
||||
const b_index = fields_order.indexOf(b.name);
|
||||
return a_index - b_index;
|
||||
});
|
||||
}
|
||||
}
|
||||
if (opts?.virtual) return fields;
|
||||
return fields.filter((f) => !f.isVirtual());
|
||||
}
|
||||
|
||||
addField(field: Field) {
|
||||
@@ -275,7 +293,7 @@ export class Entity<
|
||||
fields = this.getFillableFields(options.context);
|
||||
break;
|
||||
default:
|
||||
fields = this.getFields(true);
|
||||
fields = this.getFields({ virtual: true });
|
||||
}
|
||||
|
||||
const _fields = Object.fromEntries(fields.map((field) => [field.name, field]));
|
||||
@@ -309,7 +327,12 @@ export class Entity<
|
||||
toJSON() {
|
||||
return {
|
||||
type: this.type,
|
||||
fields: Object.fromEntries(this.fields.map((field) => [field.name, field.toJSON()])),
|
||||
fields: Object.fromEntries(
|
||||
this.getFields({ virtual: true, sorted: true }).map((field) => [
|
||||
field.name,
|
||||
field.toJSON(),
|
||||
]),
|
||||
),
|
||||
config: this.config,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ export class SchemaManager {
|
||||
}
|
||||
|
||||
getIntrospectionFromEntity(entity: Entity): IntrospectedTable {
|
||||
const fields = entity.getFields(false);
|
||||
const fields = entity.getFields({ virtual: false, sorted: true });
|
||||
const indices = this.em.getIndicesOf(entity);
|
||||
|
||||
// this is intentionally setting values to defaults, like "nullable" and "default"
|
||||
|
||||
@@ -120,17 +120,20 @@ function entityFieldActions(bkndActions: TSchemaActions, entityName: string) {
|
||||
return await bkndActions.add("data", `entities.${entityName}.fields.${name}`, validated);
|
||||
},
|
||||
patch: () => null,
|
||||
set: async (fields: TAppDataEntityFields) => {
|
||||
set: async (fields: TAppDataEntityFields, order?: string[]) => {
|
||||
try {
|
||||
const validated = parse(entityFields, fields, {
|
||||
skipMark: true,
|
||||
forceParse: true,
|
||||
});
|
||||
const res = await bkndActions.overwrite(
|
||||
"data",
|
||||
`entities.${entityName}.fields`,
|
||||
validated,
|
||||
);
|
||||
await bkndActions.overwrite("data", `entities.${entityName}.fields`, validated);
|
||||
if (order) {
|
||||
await bkndActions.overwrite(
|
||||
"data",
|
||||
`entities.${entityName}.config.fields_order`,
|
||||
order,
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("error", e);
|
||||
if (e instanceof InvalidSchemaError) {
|
||||
|
||||
@@ -155,18 +155,25 @@ const Fields = ({ entity }: { entity: Entity }) => {
|
||||
const { readonly } = useBknd();
|
||||
const [res, setRes] = useState<any>();
|
||||
const ref = useRef<EntityFieldsFormRef>(null);
|
||||
|
||||
// @todo: the return of toJSON from Fields doesn't match "type" enum
|
||||
const initialFields = Object.fromEntries(entity.fields.map((f) => [f.name, f.toJSON()])) as any;
|
||||
|
||||
async function handleUpdate() {
|
||||
if (submitting) return;
|
||||
setSubmitting(true);
|
||||
const fields = ref.current?.getData()!;
|
||||
|
||||
await actions.entity.patch(entity.name).fields.set(fields);
|
||||
|
||||
// check if field order has changed
|
||||
if (Object.keys(initialFields).join(",") !== Object.keys(fields).join(",")) {
|
||||
await actions.entity.patch(entity.name).fields.set(fields, Object.keys(fields));
|
||||
}
|
||||
setSubmitting(false);
|
||||
setUpdates((u) => u + 1);
|
||||
}
|
||||
|
||||
// @todo: the return of toJSON from Fields doesn't match "type" enum
|
||||
const initialFields = Object.fromEntries(entity.fields.map((f) => [f.name, f.toJSON()])) as any;
|
||||
|
||||
return (
|
||||
<AppShell.RouteAwareSectionHeaderAccordionItem
|
||||
identifier="fields"
|
||||
|
||||
Reference in New Issue
Block a user