@duke333/builder-ui 0.2.2 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -46,6 +46,10 @@ type BuilderEditorField<TFieldType extends string> = {
46
46
  required: boolean;
47
47
  hidden?: boolean;
48
48
  disabled?: boolean;
49
+ storage?: "s3" | "server";
50
+ contentKind?: "image" | "file";
51
+ multiple?: boolean;
52
+ maxBytes?: number;
49
53
  placeholder?: string;
50
54
  description?: string;
51
55
  options?: BuilderEditorSelectOption[];
@@ -89,6 +93,7 @@ type BuilderEditorColumn = {
89
93
  key: string;
90
94
  label: string;
91
95
  sortable: boolean;
96
+ hidden?: boolean;
92
97
  align: "left" | "right";
93
98
  };
94
99
  type BuilderFormEditorEntity<TFieldType extends string = string, TTriggerEvent extends string = string> = {
@@ -111,6 +116,7 @@ type BuilderListEditorEntity<TTriggerEvent extends string = string> = {
111
116
  source: BuilderEditorSource;
112
117
  schema: {
113
118
  columns: BuilderEditorColumn[];
119
+ orderBy?: BuilderListEditorOrderByValues | BuilderListEditorOrderByValues[];
114
120
  };
115
121
  triggers: BuilderEditorTrigger<TTriggerEvent>[];
116
122
  };
@@ -121,6 +127,10 @@ type BuilderFormEditorFieldValues<TFieldType extends string = string> = {
121
127
  required: boolean;
122
128
  hidden: boolean;
123
129
  disabled: boolean;
130
+ storage?: "s3" | "server";
131
+ contentKind?: "image" | "file";
132
+ multiple?: boolean;
133
+ maxMegabytes?: number;
124
134
  placeholder?: string;
125
135
  optionsText?: string;
126
136
  optionsMode: "static" | "table";
@@ -188,14 +198,20 @@ type BuilderListEditorColumnValues = {
188
198
  key: string;
189
199
  label: string;
190
200
  sortable: boolean;
201
+ hidden: boolean;
191
202
  align: "left" | "right";
192
203
  };
204
+ type BuilderListEditorOrderByValues = {
205
+ field: string;
206
+ direction: "asc" | "desc";
207
+ };
193
208
  type BuilderListEditorValues<TTriggerEvent extends string = string> = {
194
209
  title: string;
195
210
  description?: string;
196
211
  sourceType: "none" | "dbTable" | "apiEndpoint";
197
212
  sourceTable: string;
198
213
  apiBasePath?: string;
214
+ orderBy: BuilderListEditorOrderByValues[];
199
215
  columns: BuilderListEditorColumnValues[];
200
216
  triggers: BuilderEditorTriggerValues<TTriggerEvent>[];
201
217
  version: number;
@@ -253,6 +269,10 @@ declare function builderFormEditorInputFromValues<TFieldType extends string, TTr
253
269
  required: boolean;
254
270
  hidden: boolean;
255
271
  disabled: boolean;
272
+ storage: "s3" | "server" | undefined;
273
+ contentKind: "file" | "image" | undefined;
274
+ multiple: boolean | undefined;
275
+ maxBytes: number | undefined;
256
276
  placeholder: string;
257
277
  options: BuilderEditorSelectOption[] | undefined;
258
278
  optionsSource: {
@@ -312,6 +332,7 @@ declare function builderListEditorInputFromValues<TTriggerEvent extends string>(
312
332
  tableName?: undefined;
313
333
  } | null;
314
334
  schema: {
335
+ orderBy?: BuilderListEditorOrderByValues[] | undefined;
315
336
  columns: BuilderListEditorColumnValues[];
316
337
  };
317
338
  triggers: {
@@ -386,6 +407,7 @@ type BuilderListEditorBodyProps<TTriggerEvent extends string> = {
386
407
  listId?: string;
387
408
  form: UseFormReturn<BuilderListEditorValues<TTriggerEvent>>;
388
409
  columnArray: UseFieldArrayReturn<BuilderListEditorValues<TTriggerEvent>, "columns">;
410
+ orderByArray: UseFieldArrayReturn<BuilderListEditorValues<TTriggerEvent>, "orderBy">;
389
411
  triggerArray: UseFieldArrayReturn<BuilderListEditorValues<TTriggerEvent>, "triggers">;
390
412
  sourceType: BuilderListEditorValues<TTriggerEvent>["sourceType"];
391
413
  sourceTable: string;
@@ -451,7 +473,7 @@ type BuilderDefaultListEditorBodyOptions = {
451
473
  listTriggerEventOptions: BuilderDefaultOption[];
452
474
  };
453
475
  declare function createBuilderDefaultFormEditorBody<TFieldType extends string, TTriggerEvent extends string>(options: BuilderDefaultFormEditorBodyOptions): ({ formId, form, fieldArray, subformArray, triggerArray, fields, sourceType, sourceTable, tables, emptyField, emptyTrigger, isSaving, importFieldsFromTable, }: BuilderFormEditorBodyProps<TFieldType, TTriggerEvent>) => react.JSX.Element;
454
- declare function createBuilderDefaultListEditorBody<TTriggerEvent extends string>(options: BuilderDefaultListEditorBodyOptions): ({ listId, form, columnArray, triggerArray, sourceType, sourceTable, tables, emptyColumn, emptyTrigger, isSaving, importColumnsFromTable, }: BuilderListEditorBodyProps<TTriggerEvent>) => react.JSX.Element;
476
+ declare function createBuilderDefaultListEditorBody<TTriggerEvent extends string>(options: BuilderDefaultListEditorBodyOptions): ({ listId, form, columnArray, orderByArray, triggerArray, sourceType, sourceTable, tables, emptyColumn, emptyTrigger, isSaving, importColumnsFromTable, }: BuilderListEditorBodyProps<TTriggerEvent>) => react.JSX.Element;
455
477
 
456
478
  type BuilderDefaultEntity = {
457
479
  id: string;
@@ -595,4 +617,4 @@ declare function createBuilderAdminPages<C extends BuilderAdminPageContracts>({
595
617
  };
596
618
  };
597
619
 
598
- export { type BuilderViewEditorEntity as A, BUILDER_EDITOR_NONE_VALUE as B, type BuilderViewEditorValues as C, builderEditorOptionsToText as D, builderEditorSearchFieldsToText as E, builderEditorTextToOptions as F, builderEditorTextToSearchFields as G, builderFormEditorFieldsFromTable as H, builderFormEditorInputFromValues as I, builderFormEditorValuesFromEntity as J, builderListEditorColumnsFromTable as K, builderListEditorInputFromValues as L, builderListEditorValuesFromEntity as M, builderViewEditorInputFromValues as N, builderViewEditorValuesFromEntity as O, createBuilderAdminPages as P, createBuilderDefaultEntityManagerComponent as Q, createBuilderDefaultFormEditorBody as R, createBuilderDefaultListEditorBody as S, createBuilderFormEditorPageComponent as T, createBuilderListEditorPageComponent as U, getBuilderEditorTriggerRoute as V, type BuilderFormEditorLayoutGroupValues as W, type BuilderFormEditorSubformValues as X, builderFormEditorDefaultLayoutGroups as Y, builderFormEditorDefaultSpan as Z, type BuilderAdminPageContracts as a, type BuilderAdminPagesOptions as b, type BuilderAdminPagesRoutes as c, type BuilderDefaultEntity as d, type BuilderDefaultEntityListResult as e, type BuilderDefaultEntityManagerDependencies as f, type BuilderDefaultEntityManagerLabels as g, type BuilderDefaultEntityManagerState as h, type BuilderDefaultEntityMutation as i, type BuilderDefaultEntityQueryResult as j, type BuilderDefaultFormEditorBodyOptions as k, type BuilderDefaultListEditorBodyOptions as l, type BuilderDefaultOption as m, type BuilderEditorDbTable as n, type BuilderEditorSelectOption as o, type BuilderEditorTriggerValues as p, type BuilderFormEditorBodyProps as q, type BuilderFormEditorEntity as r, type BuilderFormEditorFieldValues as s, type BuilderFormEditorPageDependencies as t, type BuilderFormEditorValues as u, type BuilderListEditorBodyProps as v, type BuilderListEditorColumnValues as w, type BuilderListEditorEntity as x, type BuilderListEditorPageDependencies as y, type BuilderListEditorValues as z };
620
+ export { type BuilderListEditorValues as A, BUILDER_EDITOR_NONE_VALUE as B, type BuilderViewEditorEntity as C, type BuilderViewEditorValues as D, builderEditorOptionsToText as E, builderEditorSearchFieldsToText as F, builderEditorTextToOptions as G, builderEditorTextToSearchFields as H, builderFormEditorFieldsFromTable as I, builderFormEditorInputFromValues as J, builderFormEditorValuesFromEntity as K, builderListEditorColumnsFromTable as L, builderListEditorInputFromValues as M, builderListEditorValuesFromEntity as N, builderViewEditorInputFromValues as O, builderViewEditorValuesFromEntity as P, createBuilderAdminPages as Q, createBuilderDefaultEntityManagerComponent as R, createBuilderDefaultFormEditorBody as S, createBuilderDefaultListEditorBody as T, createBuilderFormEditorPageComponent as U, createBuilderListEditorPageComponent as V, getBuilderEditorTriggerRoute as W, type BuilderFormEditorLayoutGroupValues as X, type BuilderFormEditorSubformValues as Y, builderFormEditorDefaultLayoutGroups as Z, builderFormEditorDefaultSpan as _, type BuilderAdminPageContracts as a, type BuilderAdminPagesOptions as b, type BuilderAdminPagesRoutes as c, type BuilderDefaultEntity as d, type BuilderDefaultEntityListResult as e, type BuilderDefaultEntityManagerDependencies as f, type BuilderDefaultEntityManagerLabels as g, type BuilderDefaultEntityManagerState as h, type BuilderDefaultEntityMutation as i, type BuilderDefaultEntityQueryResult as j, type BuilderDefaultFormEditorBodyOptions as k, type BuilderDefaultListEditorBodyOptions as l, type BuilderDefaultOption as m, type BuilderEditorDbTable as n, type BuilderEditorSelectOption as o, type BuilderEditorTriggerValues as p, type BuilderFormEditorBodyProps as q, type BuilderFormEditorEntity as r, type BuilderFormEditorFieldValues as s, type BuilderFormEditorPageDependencies as t, type BuilderFormEditorValues as u, type BuilderListEditorBodyProps as v, type BuilderListEditorColumnValues as w, type BuilderListEditorEntity as x, type BuilderListEditorOrderByValues as y, type BuilderListEditorPageDependencies as z };
@@ -2,7 +2,7 @@ import * as react from 'react';
2
2
  import { ComponentType, ReactNode } from 'react';
3
3
  import { BuilderApiContracts } from './api/index.js';
4
4
  import { BuilderHooks } from './hooks/index.js';
5
- import { BuilderRuntimeFormSchemaLike, BuilderRuntimeFormValues, BuilderRuntimeEntryLike, BuilderRuntimeViewLike, BuilderRuntimePresentation, BuilderRuntimeEntryValues } from './runtime/index.js';
5
+ import { a as BuilderRuntimeFormSchemaLike, d as BuilderRuntimeFormValues, b as BuilderRuntimeEntryLike, e as BuilderRuntimeViewLike, B as BuilderRuntimePresentation, c as BuilderRuntimeEntryValues } from './runtimeUtils-CCtLyIf1.js';
6
6
 
7
7
  type DynamicFormContracts = BuilderApiContracts & {
8
8
  BuilderForm: {
@@ -1,5 +1,5 @@
1
- import { A as BuilderViewEditorEntity, C as BuilderViewEditorValues, W as BuilderFormEditorLayoutGroupValues, u as BuilderFormEditorValues, s as BuilderFormEditorFieldValues, X as BuilderFormEditorSubformValues } from '../BuilderAdminPages-C-jaMLOa.js';
2
- export { B as BUILDER_EDITOR_NONE_VALUE, a as BuilderAdminPageContracts, b as BuilderAdminPagesOptions, c as BuilderAdminPagesRoutes, d as BuilderDefaultEntity, e as BuilderDefaultEntityListResult, f as BuilderDefaultEntityManagerDependencies, g as BuilderDefaultEntityManagerLabels, h as BuilderDefaultEntityManagerState, i as BuilderDefaultEntityMutation, j as BuilderDefaultEntityQueryResult, k as BuilderDefaultFormEditorBodyOptions, l as BuilderDefaultListEditorBodyOptions, m as BuilderDefaultOption, n as BuilderEditorDbTable, o as BuilderEditorSelectOption, p as BuilderEditorTriggerValues, q as BuilderFormEditorBodyProps, r as BuilderFormEditorEntity, t as BuilderFormEditorPageDependencies, v as BuilderListEditorBodyProps, w as BuilderListEditorColumnValues, x as BuilderListEditorEntity, y as BuilderListEditorPageDependencies, z as BuilderListEditorValues, D as builderEditorOptionsToText, E as builderEditorSearchFieldsToText, F as builderEditorTextToOptions, G as builderEditorTextToSearchFields, Y as builderFormEditorDefaultLayoutGroups, Z as builderFormEditorDefaultSpan, H as builderFormEditorFieldsFromTable, I as builderFormEditorInputFromValues, J as builderFormEditorValuesFromEntity, K as builderListEditorColumnsFromTable, L as builderListEditorInputFromValues, M as builderListEditorValuesFromEntity, N as builderViewEditorInputFromValues, O as builderViewEditorValuesFromEntity, P as createBuilderAdminPages, Q as createBuilderDefaultEntityManagerComponent, R as createBuilderDefaultFormEditorBody, S as createBuilderDefaultListEditorBody, T as createBuilderFormEditorPageComponent, U as createBuilderListEditorPageComponent, V as getBuilderEditorTriggerRoute } from '../BuilderAdminPages-C-jaMLOa.js';
1
+ import { C as BuilderViewEditorEntity, D as BuilderViewEditorValues, X as BuilderFormEditorLayoutGroupValues, u as BuilderFormEditorValues, s as BuilderFormEditorFieldValues, Y as BuilderFormEditorSubformValues } from '../BuilderAdminPages-DwwdA8Dv.js';
2
+ export { B as BUILDER_EDITOR_NONE_VALUE, a as BuilderAdminPageContracts, b as BuilderAdminPagesOptions, c as BuilderAdminPagesRoutes, d as BuilderDefaultEntity, e as BuilderDefaultEntityListResult, f as BuilderDefaultEntityManagerDependencies, g as BuilderDefaultEntityManagerLabels, h as BuilderDefaultEntityManagerState, i as BuilderDefaultEntityMutation, j as BuilderDefaultEntityQueryResult, k as BuilderDefaultFormEditorBodyOptions, l as BuilderDefaultListEditorBodyOptions, m as BuilderDefaultOption, n as BuilderEditorDbTable, o as BuilderEditorSelectOption, p as BuilderEditorTriggerValues, q as BuilderFormEditorBodyProps, r as BuilderFormEditorEntity, t as BuilderFormEditorPageDependencies, v as BuilderListEditorBodyProps, w as BuilderListEditorColumnValues, x as BuilderListEditorEntity, y as BuilderListEditorOrderByValues, z as BuilderListEditorPageDependencies, A as BuilderListEditorValues, E as builderEditorOptionsToText, F as builderEditorSearchFieldsToText, G as builderEditorTextToOptions, H as builderEditorTextToSearchFields, Z as builderFormEditorDefaultLayoutGroups, _ as builderFormEditorDefaultSpan, I as builderFormEditorFieldsFromTable, J as builderFormEditorInputFromValues, K as builderFormEditorValuesFromEntity, L as builderListEditorColumnsFromTable, M as builderListEditorInputFromValues, N as builderListEditorValuesFromEntity, O as builderViewEditorInputFromValues, P as builderViewEditorValuesFromEntity, Q as createBuilderAdminPages, R as createBuilderDefaultEntityManagerComponent, S as createBuilderDefaultFormEditorBody, T as createBuilderDefaultListEditorBody, U as createBuilderFormEditorPageComponent, V as createBuilderListEditorPageComponent, W as getBuilderEditorTriggerRoute } from '../BuilderAdminPages-DwwdA8Dv.js';
3
3
  import * as react from 'react';
4
4
  import { ComponentType, ReactNode } from 'react';
5
5
  import { BuilderApiContracts } from '../api/index.js';
@@ -45,7 +45,7 @@ function clampLayoutSpan(span, columns) {
45
45
  return Math.max(1, Math.min(columns, Math.trunc(span)));
46
46
  }
47
47
  function builderFormEditorDefaultSpan(field) {
48
- if (field.type === "textarea" || field.type === "checkbox") return 12;
48
+ if (field.type === "textarea" || field.type === "richtext" || field.type === "checkbox") return 12;
49
49
  return 6;
50
50
  }
51
51
  function builderFormEditorDefaultLayoutGroups(fields, subforms = []) {
@@ -112,6 +112,10 @@ function builderFormEditorValuesFromEntity(form, emptyValues) {
112
112
  required: field.required,
113
113
  hidden: field.hidden ?? false,
114
114
  disabled: field.disabled ?? false,
115
+ storage: field.storage ?? "s3",
116
+ contentKind: field.contentKind ?? "image",
117
+ multiple: field.multiple ?? false,
118
+ maxMegabytes: field.maxBytes ? field.maxBytes / (1024 * 1024) : 10,
115
119
  placeholder: field.placeholder ?? "",
116
120
  optionsText: builderEditorOptionsToText(field.options),
117
121
  optionsMode: field.optionsSource?.type === "dbTable" ? "table" : "static",
@@ -154,16 +158,19 @@ function builderFormEditorValuesFromEntity(form, emptyValues) {
154
158
  function builderListEditorValuesFromEntity(list, emptyValues) {
155
159
  if (!list) return emptyValues;
156
160
  const source = list.source;
161
+ const orderBy = list.schema.orderBy ? Array.isArray(list.schema.orderBy) ? list.schema.orderBy : [list.schema.orderBy] : [];
157
162
  return {
158
163
  title: list.title,
159
164
  description: list.description ?? "",
160
165
  sourceType: source?.type ?? "none",
161
166
  sourceTable: source?.type === "dbTable" ? source.tableName : BUILDER_EDITOR_NONE_VALUE,
162
167
  apiBasePath: source?.type === "apiEndpoint" ? source.basePath : "",
168
+ orderBy,
163
169
  columns: list.schema.columns.map((column) => ({
164
170
  key: column.key,
165
171
  label: column.label,
166
172
  sortable: column.sortable,
173
+ hidden: column.hidden ?? false,
167
174
  align: column.align
168
175
  })),
169
176
  triggers: valuesFromTriggers(list.triggers),
@@ -191,6 +198,10 @@ function builderFormEditorFieldsFromTable(table) {
191
198
  required: !column.nullable,
192
199
  hidden: false,
193
200
  disabled: false,
201
+ storage: "s3",
202
+ contentKind: "image",
203
+ multiple: false,
204
+ maxMegabytes: 10,
194
205
  placeholder: column.label,
195
206
  optionsText: "",
196
207
  optionsMode: "static",
@@ -208,6 +219,7 @@ function builderListEditorColumnsFromTable(table) {
208
219
  key: column.name,
209
220
  label: column.label,
210
221
  sortable: column.sortable,
222
+ hidden: false,
211
223
  align: column.fieldType === "number" || column.fieldType === "money" ? "right" : "left"
212
224
  }));
213
225
  }
@@ -226,6 +238,10 @@ function builderFormEditorInputFromValues(values) {
226
238
  required: field.required,
227
239
  hidden: field.hidden,
228
240
  disabled: field.disabled,
241
+ storage: field.type === "file" ? field.storage : void 0,
242
+ contentKind: field.type === "file" ? field.contentKind : void 0,
243
+ multiple: field.type === "file" ? field.multiple : void 0,
244
+ maxBytes: field.type === "file" && typeof field.maxMegabytes === "number" && field.maxMegabytes > 0 ? Math.round(field.maxMegabytes * 1024 * 1024) : void 0,
229
245
  placeholder: field.placeholder?.trim() || field.label,
230
246
  options: field.type === "select" && field.optionsMode === "static" ? builderEditorTextToOptions(field.optionsText) : void 0,
231
247
  optionsSource: field.type === "select" && field.optionsMode === "table" && field.optionsTable !== BUILDER_EDITOR_NONE_VALUE && field.optionsValueField !== BUILDER_EDITOR_NONE_VALUE && field.optionsLabelField !== BUILDER_EDITOR_NONE_VALUE ? {
@@ -279,11 +295,19 @@ function builderFormEditorInputFromValues(values) {
279
295
  }
280
296
  function builderListEditorInputFromValues(values) {
281
297
  const source = values.sourceType === "dbTable" && values.sourceTable !== BUILDER_EDITOR_NONE_VALUE ? { type: "dbTable", tableName: values.sourceTable } : values.sourceType === "apiEndpoint" && values.apiBasePath ? { type: "apiEndpoint", basePath: values.apiBasePath } : null;
298
+ const orderBy = Array.from(
299
+ new Map(
300
+ values.orderBy.filter((rule) => rule.field && rule.field !== BUILDER_EDITOR_NONE_VALUE).map((rule) => [rule.field, rule])
301
+ ).values()
302
+ );
282
303
  return {
283
304
  title: values.title,
284
305
  description: values.description || null,
285
306
  source,
286
- schema: { columns: values.columns },
307
+ schema: {
308
+ columns: values.columns,
309
+ ...source && orderBy.length > 0 ? { orderBy } : {}
310
+ },
287
311
  triggers: values.triggers.map((trigger) => ({
288
312
  event: trigger.event,
289
313
  action: "callApi",
@@ -308,7 +332,7 @@ function builderViewEditorInputFromValues(values, parseTriggers) {
308
332
  }
309
333
 
310
334
  // src/admin/BuilderDefaultEditorBodies.tsx
311
- import { jsx, jsxs } from "react/jsx-runtime";
335
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
312
336
  var styles = {
313
337
  page: {
314
338
  display: "grid",
@@ -486,10 +510,18 @@ function createBuilderDefaultFormEditorBody(options) {
486
510
  ] }),
487
511
  sourceType === "dbTable" ? /* @__PURE__ */ jsxs("label", { style: styles.field, children: [
488
512
  /* @__PURE__ */ jsx("span", { style: styles.label, children: "Table" }),
489
- /* @__PURE__ */ jsxs("select", { style: styles.input, ...form.register("sourceTable"), children: [
490
- /* @__PURE__ */ jsx("option", { value: BUILDER_EDITOR_NONE_VALUE, children: "Select table" }),
491
- tables.map((table) => /* @__PURE__ */ jsx("option", { value: table.name, children: table.label ?? table.name }, table.name))
492
- ] })
513
+ /* @__PURE__ */ jsxs(
514
+ "select",
515
+ {
516
+ style: styles.input,
517
+ value: sourceTable,
518
+ ...form.register("sourceTable"),
519
+ children: [
520
+ /* @__PURE__ */ jsx("option", { value: BUILDER_EDITOR_NONE_VALUE, children: "Select table" }),
521
+ tables.map((table) => /* @__PURE__ */ jsx("option", { value: table.name, children: table.label ?? table.name }, table.name))
522
+ ]
523
+ }
524
+ )
493
525
  ] }) : null,
494
526
  sourceType === "apiEndpoint" ? /* @__PURE__ */ jsxs("label", { style: styles.field, children: [
495
527
  /* @__PURE__ */ jsx("span", { style: styles.label, children: "API base path" }),
@@ -563,6 +595,30 @@ function createBuilderDefaultFormEditorBody(options) {
563
595
  /* @__PURE__ */ jsx("input", { type: "checkbox", ...form.register(`fields.${index}.disabled`) }),
564
596
  "Disabled"
565
597
  ] }),
598
+ fields[index]?.type === "file" ? /* @__PURE__ */ jsxs(Fragment, { children: [
599
+ /* @__PURE__ */ jsxs("label", { style: styles.field, children: [
600
+ /* @__PURE__ */ jsx("span", { style: styles.label, children: "Storage" }),
601
+ /* @__PURE__ */ jsxs("select", { style: styles.input, ...form.register(`fields.${index}.storage`), children: [
602
+ /* @__PURE__ */ jsx("option", { value: "s3", children: "S3" }),
603
+ /* @__PURE__ */ jsx("option", { value: "server", children: "Server" })
604
+ ] })
605
+ ] }),
606
+ /* @__PURE__ */ jsxs("label", { style: styles.field, children: [
607
+ /* @__PURE__ */ jsx("span", { style: styles.label, children: "Content type" }),
608
+ /* @__PURE__ */ jsxs("select", { style: styles.input, ...form.register(`fields.${index}.contentKind`), children: [
609
+ /* @__PURE__ */ jsx("option", { value: "image", children: "Image" }),
610
+ /* @__PURE__ */ jsx("option", { value: "file", children: "File" })
611
+ ] })
612
+ ] }),
613
+ /* @__PURE__ */ jsxs("label", { style: styles.checkboxField, children: [
614
+ /* @__PURE__ */ jsx("input", { type: "checkbox", ...form.register(`fields.${index}.multiple`) }),
615
+ "Multiple"
616
+ ] }),
617
+ /* @__PURE__ */ jsxs("label", { style: styles.field, children: [
618
+ /* @__PURE__ */ jsx("span", { style: styles.label, children: "Max size (MB)" }),
619
+ /* @__PURE__ */ jsx("input", { type: "number", min: "1", max: "100", style: styles.input, ...form.register(`fields.${index}.maxMegabytes`, { valueAsNumber: true }) })
620
+ ] })
621
+ ] }) : null,
566
622
  /* @__PURE__ */ jsxs("label", { style: styles.field, children: [
567
623
  /* @__PURE__ */ jsx("span", { style: styles.label, children: "Placeholder" }),
568
624
  /* @__PURE__ */ jsx("input", { style: styles.input, ...form.register(`fields.${index}.placeholder`) })
@@ -747,6 +803,7 @@ function createBuilderDefaultListEditorBody(options) {
747
803
  listId,
748
804
  form,
749
805
  columnArray,
806
+ orderByArray,
750
807
  triggerArray,
751
808
  sourceType,
752
809
  sourceTable,
@@ -756,6 +813,8 @@ function createBuilderDefaultListEditorBody(options) {
756
813
  isSaving,
757
814
  importColumnsFromTable
758
815
  }) {
816
+ const selectedTable = tables.find((table) => table.name === sourceTable);
817
+ const orderByColumns = selectedTable?.columns.filter((column) => column.sortable) ?? [];
759
818
  return /* @__PURE__ */ jsxs("div", { style: styles.page, children: [
760
819
  /* @__PURE__ */ jsxs("div", { style: styles.header, children: [
761
820
  /* @__PURE__ */ jsxs("div", { children: [
@@ -788,10 +847,18 @@ function createBuilderDefaultListEditorBody(options) {
788
847
  ] }),
789
848
  sourceType === "dbTable" ? /* @__PURE__ */ jsxs("label", { style: styles.field, children: [
790
849
  /* @__PURE__ */ jsx("span", { style: styles.label, children: "Table" }),
791
- /* @__PURE__ */ jsxs("select", { style: styles.input, ...form.register("sourceTable"), children: [
792
- /* @__PURE__ */ jsx("option", { value: BUILDER_EDITOR_NONE_VALUE, children: "Select table" }),
793
- tables.map((table) => /* @__PURE__ */ jsx("option", { value: table.name, children: table.label ?? table.name }, table.name))
794
- ] })
850
+ /* @__PURE__ */ jsxs(
851
+ "select",
852
+ {
853
+ style: styles.input,
854
+ value: sourceTable,
855
+ ...form.register("sourceTable"),
856
+ children: [
857
+ /* @__PURE__ */ jsx("option", { value: BUILDER_EDITOR_NONE_VALUE, children: "Select table" }),
858
+ tables.map((table) => /* @__PURE__ */ jsx("option", { value: table.name, children: table.label ?? table.name }, table.name))
859
+ ]
860
+ }
861
+ )
795
862
  ] }) : null,
796
863
  sourceType === "apiEndpoint" ? /* @__PURE__ */ jsxs("label", { style: styles.field, children: [
797
864
  /* @__PURE__ */ jsx("span", { style: styles.label, children: "API base path" }),
@@ -809,6 +876,85 @@ function createBuilderDefaultListEditorBody(options) {
809
876
  ) }) : null
810
877
  ] })
811
878
  ] }),
879
+ /* @__PURE__ */ jsxs("section", { style: styles.section, children: [
880
+ /* @__PURE__ */ jsxs("div", { style: styles.sectionHeader, children: [
881
+ /* @__PURE__ */ jsxs("div", { children: [
882
+ /* @__PURE__ */ jsx("h2", { style: styles.sectionTitle, children: "Default ordering" }),
883
+ /* @__PURE__ */ jsx("p", { style: styles.description, children: "Rules are applied from top to bottom." })
884
+ ] }),
885
+ /* @__PURE__ */ jsx(
886
+ "button",
887
+ {
888
+ type: "button",
889
+ style: styles.button,
890
+ disabled: sourceType === "none" || orderByArray.fields.length >= 8,
891
+ onClick: () => orderByArray.append({
892
+ field: sourceType === "dbTable" ? orderByColumns[0]?.name ?? BUILDER_EDITOR_NONE_VALUE : "",
893
+ direction: "desc"
894
+ }),
895
+ children: "Add ordering"
896
+ }
897
+ )
898
+ ] }),
899
+ orderByArray.fields.length === 0 ? /* @__PURE__ */ jsx("div", { style: styles.grid, children: /* @__PURE__ */ jsx("p", { style: styles.description, children: "Automatic ordering is used." }) }) : null,
900
+ orderByArray.fields.map((rule, index) => /* @__PURE__ */ jsxs("div", { style: styles.row, children: [
901
+ sourceType === "dbTable" ? /* @__PURE__ */ jsxs("label", { style: styles.field, children: [
902
+ /* @__PURE__ */ jsx("span", { style: styles.label, children: "Order by field" }),
903
+ /* @__PURE__ */ jsxs("select", { style: styles.input, ...form.register(`orderBy.${index}.field`), children: [
904
+ /* @__PURE__ */ jsx("option", { value: BUILDER_EDITOR_NONE_VALUE, children: "Select field" }),
905
+ orderByColumns.map((column) => /* @__PURE__ */ jsx("option", { value: column.name, children: column.label }, column.name))
906
+ ] })
907
+ ] }) : /* @__PURE__ */ jsxs("label", { style: styles.field, children: [
908
+ /* @__PURE__ */ jsx("span", { style: styles.label, children: "Order by field" }),
909
+ /* @__PURE__ */ jsx(
910
+ "input",
911
+ {
912
+ style: styles.input,
913
+ placeholder: "createdAt",
914
+ ...form.register(`orderBy.${index}.field`)
915
+ }
916
+ )
917
+ ] }),
918
+ /* @__PURE__ */ jsxs("label", { style: styles.field, children: [
919
+ /* @__PURE__ */ jsx("span", { style: styles.label, children: "Direction" }),
920
+ /* @__PURE__ */ jsxs("select", { style: styles.input, ...form.register(`orderBy.${index}.direction`), children: [
921
+ /* @__PURE__ */ jsx("option", { value: "asc", children: "Ascending" }),
922
+ /* @__PURE__ */ jsx("option", { value: "desc", children: "Descending" })
923
+ ] })
924
+ ] }),
925
+ /* @__PURE__ */ jsxs("div", { style: styles.actions, children: [
926
+ /* @__PURE__ */ jsx(
927
+ "button",
928
+ {
929
+ type: "button",
930
+ style: styles.button,
931
+ disabled: index === 0,
932
+ onClick: () => orderByArray.move(index, index - 1),
933
+ children: "Move up"
934
+ }
935
+ ),
936
+ /* @__PURE__ */ jsx(
937
+ "button",
938
+ {
939
+ type: "button",
940
+ style: styles.button,
941
+ disabled: index === orderByArray.fields.length - 1,
942
+ onClick: () => orderByArray.move(index, index + 1),
943
+ children: "Move down"
944
+ }
945
+ ),
946
+ /* @__PURE__ */ jsx(
947
+ "button",
948
+ {
949
+ type: "button",
950
+ style: styles.button,
951
+ onClick: () => orderByArray.remove(index),
952
+ children: "Remove"
953
+ }
954
+ )
955
+ ] })
956
+ ] }, rule.id))
957
+ ] }),
812
958
  /* @__PURE__ */ jsxs("section", { style: styles.section, children: [
813
959
  /* @__PURE__ */ jsxs("div", { style: styles.sectionHeader, children: [
814
960
  /* @__PURE__ */ jsxs("div", { children: [
@@ -849,16 +995,10 @@ function createBuilderDefaultListEditorBody(options) {
849
995
  /* @__PURE__ */ jsx("input", { type: "checkbox", ...form.register(`columns.${index}.sortable`) }),
850
996
  "Sortable"
851
997
  ] }),
852
- /* @__PURE__ */ jsx(
853
- "button",
854
- {
855
- type: "button",
856
- style: styles.button,
857
- onClick: () => columnArray.remove(index),
858
- disabled: columnArray.fields.length <= 1,
859
- children: "Remove"
860
- }
861
- )
998
+ /* @__PURE__ */ jsxs("label", { style: styles.checkboxField, children: [
999
+ /* @__PURE__ */ jsx("input", { type: "checkbox", ...form.register(`columns.${index}.hidden`) }),
1000
+ "Hidden"
1001
+ ] })
862
1002
  ] }, column.id))
863
1003
  ] }),
864
1004
  /* @__PURE__ */ jsxs("section", { style: styles.section, children: [
@@ -1089,7 +1229,7 @@ function createBuilderDefaultEntityManagerComponent(deps) {
1089
1229
  // src/admin/BuilderDefaultViewEditorPage.tsx
1090
1230
  import { useEffect } from "react";
1091
1231
  import { useForm } from "react-hook-form";
1092
- import { Fragment, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
1232
+ import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
1093
1233
  var styles3 = {
1094
1234
  page: {
1095
1235
  display: "grid",
@@ -1276,7 +1416,7 @@ function createBuilderDefaultViewEditorPage(options) {
1276
1416
  (lists.data ?? []).map((item) => /* @__PURE__ */ jsx3("option", { value: item.id, children: item.title }, item.id))
1277
1417
  ] })
1278
1418
  ] }),
1279
- showPermissions ? /* @__PURE__ */ jsxs3(Fragment, { children: [
1419
+ showPermissions ? /* @__PURE__ */ jsxs3(Fragment2, { children: [
1280
1420
  /* @__PURE__ */ jsxs3("label", { style: styles3.field, children: [
1281
1421
  /* @__PURE__ */ jsx3("span", { style: styles3.label, children: "Read permission" }),
1282
1422
  /* @__PURE__ */ jsxs3("select", { style: styles3.input, ...form.register("permissionRead"), children: [
@@ -1387,6 +1527,7 @@ function createBuilderListEditorPageComponent(deps) {
1387
1527
  defaultValues: deps.emptyValues
1388
1528
  });
1389
1529
  const columnArray = useFieldArray({ control: form.control, name: "columns" });
1530
+ const orderByArray = useFieldArray({ control: form.control, name: "orderBy" });
1390
1531
  const triggerArray = useFieldArray({ control: form.control, name: "triggers" });
1391
1532
  const sourceType = useWatch({ control: form.control, name: "sourceType" });
1392
1533
  const sourceTable = useWatch({ control: form.control, name: "sourceTable" });
@@ -1420,6 +1561,7 @@ function createBuilderListEditorPageComponent(deps) {
1420
1561
  listId,
1421
1562
  form,
1422
1563
  columnArray,
1564
+ orderByArray,
1423
1565
  triggerArray,
1424
1566
  sourceType,
1425
1567
  sourceTable,
@@ -1438,6 +1580,7 @@ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
1438
1580
  var defaultFieldTypeOptions = [
1439
1581
  { value: "text", label: "Text" },
1440
1582
  { value: "textarea", label: "Textarea" },
1583
+ { value: "richtext", label: "Rich text" },
1441
1584
  { value: "number", label: "Number" },
1442
1585
  { value: "money", label: "Money" },
1443
1586
  { value: "select", label: "Select" },
@@ -1548,6 +1691,10 @@ function createBuilderAdminPages({
1548
1691
  required: true,
1549
1692
  hidden: false,
1550
1693
  disabled: false,
1694
+ storage: "s3",
1695
+ contentKind: "image",
1696
+ multiple: false,
1697
+ maxMegabytes: 10,
1551
1698
  placeholder: "",
1552
1699
  optionsText: "",
1553
1700
  optionsMode: "static",
@@ -1582,6 +1729,7 @@ function createBuilderAdminPages({
1582
1729
  key: "name",
1583
1730
  label: "Name",
1584
1731
  sortable: true,
1732
+ hidden: false,
1585
1733
  align: "left"
1586
1734
  };
1587
1735
  const emptyListValues = {
@@ -1590,6 +1738,7 @@ function createBuilderAdminPages({
1590
1738
  sourceType: "none",
1591
1739
  sourceTable: BUILDER_EDITOR_NONE_VALUE,
1592
1740
  apiBasePath: "",
1741
+ orderBy: [],
1593
1742
  columns: [emptyColumn],
1594
1743
  triggers: [],
1595
1744
  version: 0