@duke333/builder-ui 0.2.2 → 0.2.3

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.
package/dist/index.js CHANGED
@@ -420,11 +420,13 @@ function createBuilderClient({ transport, apiBasePath }) {
420
420
  return createBuilderApiClient(transport, { apiBasePath });
421
421
  }
422
422
  var BuilderContext = createContext(null);
423
+ var defaultComponents = {};
423
424
  function BuilderProvider({
424
425
  children,
425
426
  client: configuredClient,
426
427
  transport,
427
428
  apiBasePath,
429
+ components = defaultComponents,
428
430
  queryClient,
429
431
  onNotify
430
432
  }) {
@@ -446,8 +448,8 @@ function BuilderProvider({
446
448
  const internalQueryClient = useRef(null);
447
449
  if (!internalQueryClient.current) internalQueryClient.current = queryClient ?? new QueryClient();
448
450
  const value = useMemo(
449
- () => ({ client: internalClient, hooks, notify }),
450
- [hooks, internalClient, notify]
451
+ () => ({ client: internalClient, components, hooks, notify }),
452
+ [components, hooks, internalClient, notify]
451
453
  );
452
454
  return /* @__PURE__ */ jsx(QueryClientProvider, { client: internalQueryClient.current, children: /* @__PURE__ */ jsxs(BuilderContext.Provider, { value, children: [
453
455
  children,
@@ -827,7 +829,7 @@ function ReadyDataGrid({
827
829
  ] });
828
830
  }
829
831
  function readyColumns(columns) {
830
- return columns.map((column) => ({ ...column }));
832
+ return columns.filter((column) => !column.hidden).map((column) => ({ ...column }));
831
833
  }
832
834
 
833
835
  // src/ready/ReadySubform.tsx
@@ -884,6 +886,7 @@ function ReadySubform({ subform, parentEntry, rows, onRowsChange }) {
884
886
  key: "_actions",
885
887
  label: "\u04AE\u0439\u043B\u0434\u044D\u043B",
886
888
  sortable: false,
889
+ hidden: false,
887
890
  align: "right",
888
891
  render: (row) => /* @__PURE__ */ jsx5("button", { type: "button", className: "builder-link builder-link--danger", onClick: (event) => {
889
892
  event.stopPropagation();
@@ -948,7 +951,7 @@ function ReadySubform({ subform, parentEntry, rows, onRowsChange }) {
948
951
  /* @__PURE__ */ jsx5(ReadyFields, { formId: view.form.id, viewId: view.id, schema: view.form.schema }),
949
952
  /* @__PURE__ */ jsxs5("div", { className: "builder-actions", children: [
950
953
  /* @__PURE__ */ jsx5("button", { type: "button", className: "builder-button builder-button--ghost", onClick: close, children: "\u0411\u043E\u043B\u0438\u0445" }),
951
- /* @__PURE__ */ jsx5("button", { type: "submit", className: "builder-button builder-button--primary", children: "\u0425\u0430\u0434\u0433\u0430\u043B\u0430\u0445" })
954
+ /* @__PURE__ */ jsx5("button", { type: "submit", className: "builder-button builder-button--primary", children: editing ? "\u0428\u0438\u043D\u044D\u0447\u043B\u044D\u0445" : "\u041D\u044D\u043C\u044D\u0445" })
952
955
  ] })
953
956
  ] }) }) }) : null
954
957
  ] });
@@ -956,7 +959,7 @@ function ReadySubform({ subform, parentEntry, rows, onRowsChange }) {
956
959
 
957
960
  // src/ready/BuilderRuntimeComponents.tsx
958
961
  import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
959
- function BuilderForm({ formId }) {
962
+ function DefaultBuilderForm({ formId }) {
960
963
  const { hooks, notify } = useBuilderRuntime();
961
964
  const query = hooks.useRuntimeBuilderForm(formId);
962
965
  const save = hooks.useSaveRuntimeBuilderFormEntry(formId);
@@ -982,7 +985,7 @@ function BuilderForm({ formId }) {
982
985
  ] }) })
983
986
  ] });
984
987
  }
985
- function BuilderGrid({ listId }) {
988
+ function DefaultBuilderGrid({ listId }) {
986
989
  const { hooks } = useBuilderRuntime();
987
990
  const listQuery = hooks.useRuntimeBuilderList(listId);
988
991
  const state = useReadyTableState();
@@ -1049,7 +1052,7 @@ function BuilderEntryEditor({ view, editing, open, onClose }) {
1049
1052
  ] })
1050
1053
  ] }) }) : /* @__PURE__ */ jsx6(ReadyErrorState, { title: "Form \u0445\u043E\u043B\u0431\u043E\u043E\u0433\u04AF\u0439", description: "\u042D\u043D\u044D view-\u0434 form \u0442\u043E\u0445\u0438\u0440\u0443\u0443\u043B\u0430\u0430\u0433\u04AF\u0439 \u0431\u0430\u0439\u043D\u0430." }) });
1051
1054
  }
1052
- function BuilderView({ viewId }) {
1055
+ function DefaultBuilderView({ viewId }) {
1053
1056
  const { hooks, notify } = useBuilderRuntime();
1054
1057
  const [editing, setEditing] = useState5(null);
1055
1058
  const [editorOpen, setEditorOpen] = useState5(false);
@@ -1066,6 +1069,7 @@ function BuilderView({ viewId }) {
1066
1069
  key: "_actions",
1067
1070
  label: "\u04AE\u0439\u043B\u0434\u044D\u043B",
1068
1071
  sortable: false,
1072
+ hidden: false,
1069
1073
  align: "right",
1070
1074
  render: (entry) => /* @__PURE__ */ jsxs6("div", { className: "builder-row-actions", "data-builder-row-action": true, children: [
1071
1075
  /* @__PURE__ */ jsx6("button", { type: "button", className: "builder-button builder-button--ghost", onClick: (event) => {
@@ -1124,6 +1128,21 @@ function BuilderView({ viewId }) {
1124
1128
  )
1125
1129
  ] });
1126
1130
  }
1131
+ function BuilderForm(props) {
1132
+ const { components } = useBuilderRuntime();
1133
+ const Component = components.Form;
1134
+ return Component ? /* @__PURE__ */ jsx6(Component, { ...props }) : /* @__PURE__ */ jsx6(DefaultBuilderForm, { ...props });
1135
+ }
1136
+ function BuilderGrid(props) {
1137
+ const { components } = useBuilderRuntime();
1138
+ const Component = components.Grid;
1139
+ return Component ? /* @__PURE__ */ jsx6(Component, { ...props }) : /* @__PURE__ */ jsx6(DefaultBuilderGrid, { ...props });
1140
+ }
1141
+ function BuilderView(props) {
1142
+ const { components } = useBuilderRuntime();
1143
+ const Component = components.View;
1144
+ return Component ? /* @__PURE__ */ jsx6(Component, { ...props }) : /* @__PURE__ */ jsx6(DefaultBuilderView, { ...props });
1145
+ }
1127
1146
 
1128
1147
  // src/admin/editorState.ts
1129
1148
  var BUILDER_EDITOR_NONE_VALUE = "__none";
@@ -1279,16 +1298,19 @@ function builderFormEditorValuesFromEntity(form, emptyValues) {
1279
1298
  function builderListEditorValuesFromEntity(list, emptyValues) {
1280
1299
  if (!list) return emptyValues;
1281
1300
  const source = list.source;
1301
+ const orderBy = list.schema.orderBy ? Array.isArray(list.schema.orderBy) ? list.schema.orderBy : [list.schema.orderBy] : [];
1282
1302
  return {
1283
1303
  title: list.title,
1284
1304
  description: list.description ?? "",
1285
1305
  sourceType: source?.type ?? "none",
1286
1306
  sourceTable: source?.type === "dbTable" ? source.tableName : BUILDER_EDITOR_NONE_VALUE,
1287
1307
  apiBasePath: source?.type === "apiEndpoint" ? source.basePath : "",
1308
+ orderBy,
1288
1309
  columns: list.schema.columns.map((column) => ({
1289
1310
  key: column.key,
1290
1311
  label: column.label,
1291
1312
  sortable: column.sortable,
1313
+ hidden: column.hidden ?? false,
1292
1314
  align: column.align
1293
1315
  })),
1294
1316
  triggers: valuesFromTriggers(list.triggers),
@@ -1333,6 +1355,7 @@ function builderListEditorColumnsFromTable(table) {
1333
1355
  key: column.name,
1334
1356
  label: column.label,
1335
1357
  sortable: column.sortable,
1358
+ hidden: false,
1336
1359
  align: column.fieldType === "number" || column.fieldType === "money" ? "right" : "left"
1337
1360
  }));
1338
1361
  }
@@ -1404,11 +1427,19 @@ function builderFormEditorInputFromValues(values) {
1404
1427
  }
1405
1428
  function builderListEditorInputFromValues(values) {
1406
1429
  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;
1430
+ const orderBy = Array.from(
1431
+ new Map(
1432
+ values.orderBy.filter((rule) => rule.field && rule.field !== BUILDER_EDITOR_NONE_VALUE).map((rule) => [rule.field, rule])
1433
+ ).values()
1434
+ );
1407
1435
  return {
1408
1436
  title: values.title,
1409
1437
  description: values.description || null,
1410
1438
  source,
1411
- schema: { columns: values.columns },
1439
+ schema: {
1440
+ columns: values.columns,
1441
+ ...source && orderBy.length > 0 ? { orderBy } : {}
1442
+ },
1412
1443
  triggers: values.triggers.map((trigger) => ({
1413
1444
  event: trigger.event,
1414
1445
  action: "callApi",
@@ -1611,10 +1642,18 @@ function createBuilderDefaultFormEditorBody(options) {
1611
1642
  ] }),
1612
1643
  sourceType === "dbTable" ? /* @__PURE__ */ jsxs7("label", { style: styles.field, children: [
1613
1644
  /* @__PURE__ */ jsx7("span", { style: styles.label, children: "Table" }),
1614
- /* @__PURE__ */ jsxs7("select", { style: styles.input, ...form.register("sourceTable"), children: [
1615
- /* @__PURE__ */ jsx7("option", { value: BUILDER_EDITOR_NONE_VALUE, children: "Select table" }),
1616
- tables.map((table) => /* @__PURE__ */ jsx7("option", { value: table.name, children: table.label ?? table.name }, table.name))
1617
- ] })
1645
+ /* @__PURE__ */ jsxs7(
1646
+ "select",
1647
+ {
1648
+ style: styles.input,
1649
+ value: sourceTable,
1650
+ ...form.register("sourceTable"),
1651
+ children: [
1652
+ /* @__PURE__ */ jsx7("option", { value: BUILDER_EDITOR_NONE_VALUE, children: "Select table" }),
1653
+ tables.map((table) => /* @__PURE__ */ jsx7("option", { value: table.name, children: table.label ?? table.name }, table.name))
1654
+ ]
1655
+ }
1656
+ )
1618
1657
  ] }) : null,
1619
1658
  sourceType === "apiEndpoint" ? /* @__PURE__ */ jsxs7("label", { style: styles.field, children: [
1620
1659
  /* @__PURE__ */ jsx7("span", { style: styles.label, children: "API base path" }),
@@ -1872,6 +1911,7 @@ function createBuilderDefaultListEditorBody(options) {
1872
1911
  listId,
1873
1912
  form,
1874
1913
  columnArray,
1914
+ orderByArray,
1875
1915
  triggerArray,
1876
1916
  sourceType,
1877
1917
  sourceTable,
@@ -1881,6 +1921,8 @@ function createBuilderDefaultListEditorBody(options) {
1881
1921
  isSaving,
1882
1922
  importColumnsFromTable
1883
1923
  }) {
1924
+ const selectedTable = tables.find((table) => table.name === sourceTable);
1925
+ const orderByColumns = selectedTable?.columns.filter((column) => column.sortable) ?? [];
1884
1926
  return /* @__PURE__ */ jsxs7("div", { style: styles.page, children: [
1885
1927
  /* @__PURE__ */ jsxs7("div", { style: styles.header, children: [
1886
1928
  /* @__PURE__ */ jsxs7("div", { children: [
@@ -1913,10 +1955,18 @@ function createBuilderDefaultListEditorBody(options) {
1913
1955
  ] }),
1914
1956
  sourceType === "dbTable" ? /* @__PURE__ */ jsxs7("label", { style: styles.field, children: [
1915
1957
  /* @__PURE__ */ jsx7("span", { style: styles.label, children: "Table" }),
1916
- /* @__PURE__ */ jsxs7("select", { style: styles.input, ...form.register("sourceTable"), children: [
1917
- /* @__PURE__ */ jsx7("option", { value: BUILDER_EDITOR_NONE_VALUE, children: "Select table" }),
1918
- tables.map((table) => /* @__PURE__ */ jsx7("option", { value: table.name, children: table.label ?? table.name }, table.name))
1919
- ] })
1958
+ /* @__PURE__ */ jsxs7(
1959
+ "select",
1960
+ {
1961
+ style: styles.input,
1962
+ value: sourceTable,
1963
+ ...form.register("sourceTable"),
1964
+ children: [
1965
+ /* @__PURE__ */ jsx7("option", { value: BUILDER_EDITOR_NONE_VALUE, children: "Select table" }),
1966
+ tables.map((table) => /* @__PURE__ */ jsx7("option", { value: table.name, children: table.label ?? table.name }, table.name))
1967
+ ]
1968
+ }
1969
+ )
1920
1970
  ] }) : null,
1921
1971
  sourceType === "apiEndpoint" ? /* @__PURE__ */ jsxs7("label", { style: styles.field, children: [
1922
1972
  /* @__PURE__ */ jsx7("span", { style: styles.label, children: "API base path" }),
@@ -1934,6 +1984,85 @@ function createBuilderDefaultListEditorBody(options) {
1934
1984
  ) }) : null
1935
1985
  ] })
1936
1986
  ] }),
1987
+ /* @__PURE__ */ jsxs7("section", { style: styles.section, children: [
1988
+ /* @__PURE__ */ jsxs7("div", { style: styles.sectionHeader, children: [
1989
+ /* @__PURE__ */ jsxs7("div", { children: [
1990
+ /* @__PURE__ */ jsx7("h2", { style: styles.sectionTitle, children: "Default ordering" }),
1991
+ /* @__PURE__ */ jsx7("p", { style: styles.description, children: "Rules are applied from top to bottom." })
1992
+ ] }),
1993
+ /* @__PURE__ */ jsx7(
1994
+ "button",
1995
+ {
1996
+ type: "button",
1997
+ style: styles.button,
1998
+ disabled: sourceType === "none" || orderByArray.fields.length >= 8,
1999
+ onClick: () => orderByArray.append({
2000
+ field: sourceType === "dbTable" ? orderByColumns[0]?.name ?? BUILDER_EDITOR_NONE_VALUE : "",
2001
+ direction: "desc"
2002
+ }),
2003
+ children: "Add ordering"
2004
+ }
2005
+ )
2006
+ ] }),
2007
+ orderByArray.fields.length === 0 ? /* @__PURE__ */ jsx7("div", { style: styles.grid, children: /* @__PURE__ */ jsx7("p", { style: styles.description, children: "Automatic ordering is used." }) }) : null,
2008
+ orderByArray.fields.map((rule, index) => /* @__PURE__ */ jsxs7("div", { style: styles.row, children: [
2009
+ sourceType === "dbTable" ? /* @__PURE__ */ jsxs7("label", { style: styles.field, children: [
2010
+ /* @__PURE__ */ jsx7("span", { style: styles.label, children: "Order by field" }),
2011
+ /* @__PURE__ */ jsxs7("select", { style: styles.input, ...form.register(`orderBy.${index}.field`), children: [
2012
+ /* @__PURE__ */ jsx7("option", { value: BUILDER_EDITOR_NONE_VALUE, children: "Select field" }),
2013
+ orderByColumns.map((column) => /* @__PURE__ */ jsx7("option", { value: column.name, children: column.label }, column.name))
2014
+ ] })
2015
+ ] }) : /* @__PURE__ */ jsxs7("label", { style: styles.field, children: [
2016
+ /* @__PURE__ */ jsx7("span", { style: styles.label, children: "Order by field" }),
2017
+ /* @__PURE__ */ jsx7(
2018
+ "input",
2019
+ {
2020
+ style: styles.input,
2021
+ placeholder: "createdAt",
2022
+ ...form.register(`orderBy.${index}.field`)
2023
+ }
2024
+ )
2025
+ ] }),
2026
+ /* @__PURE__ */ jsxs7("label", { style: styles.field, children: [
2027
+ /* @__PURE__ */ jsx7("span", { style: styles.label, children: "Direction" }),
2028
+ /* @__PURE__ */ jsxs7("select", { style: styles.input, ...form.register(`orderBy.${index}.direction`), children: [
2029
+ /* @__PURE__ */ jsx7("option", { value: "asc", children: "Ascending" }),
2030
+ /* @__PURE__ */ jsx7("option", { value: "desc", children: "Descending" })
2031
+ ] })
2032
+ ] }),
2033
+ /* @__PURE__ */ jsxs7("div", { style: styles.actions, children: [
2034
+ /* @__PURE__ */ jsx7(
2035
+ "button",
2036
+ {
2037
+ type: "button",
2038
+ style: styles.button,
2039
+ disabled: index === 0,
2040
+ onClick: () => orderByArray.move(index, index - 1),
2041
+ children: "Move up"
2042
+ }
2043
+ ),
2044
+ /* @__PURE__ */ jsx7(
2045
+ "button",
2046
+ {
2047
+ type: "button",
2048
+ style: styles.button,
2049
+ disabled: index === orderByArray.fields.length - 1,
2050
+ onClick: () => orderByArray.move(index, index + 1),
2051
+ children: "Move down"
2052
+ }
2053
+ ),
2054
+ /* @__PURE__ */ jsx7(
2055
+ "button",
2056
+ {
2057
+ type: "button",
2058
+ style: styles.button,
2059
+ onClick: () => orderByArray.remove(index),
2060
+ children: "Remove"
2061
+ }
2062
+ )
2063
+ ] })
2064
+ ] }, rule.id))
2065
+ ] }),
1937
2066
  /* @__PURE__ */ jsxs7("section", { style: styles.section, children: [
1938
2067
  /* @__PURE__ */ jsxs7("div", { style: styles.sectionHeader, children: [
1939
2068
  /* @__PURE__ */ jsxs7("div", { children: [
@@ -1974,16 +2103,10 @@ function createBuilderDefaultListEditorBody(options) {
1974
2103
  /* @__PURE__ */ jsx7("input", { type: "checkbox", ...form.register(`columns.${index}.sortable`) }),
1975
2104
  "Sortable"
1976
2105
  ] }),
1977
- /* @__PURE__ */ jsx7(
1978
- "button",
1979
- {
1980
- type: "button",
1981
- style: styles.button,
1982
- onClick: () => columnArray.remove(index),
1983
- disabled: columnArray.fields.length <= 1,
1984
- children: "Remove"
1985
- }
1986
- )
2106
+ /* @__PURE__ */ jsxs7("label", { style: styles.checkboxField, children: [
2107
+ /* @__PURE__ */ jsx7("input", { type: "checkbox", ...form.register(`columns.${index}.hidden`) }),
2108
+ "Hidden"
2109
+ ] })
1987
2110
  ] }, column.id))
1988
2111
  ] }),
1989
2112
  /* @__PURE__ */ jsxs7("section", { style: styles.section, children: [
@@ -2512,6 +2635,7 @@ function createBuilderListEditorPageComponent(deps) {
2512
2635
  defaultValues: deps.emptyValues
2513
2636
  });
2514
2637
  const columnArray = useFieldArray({ control: form.control, name: "columns" });
2638
+ const orderByArray = useFieldArray({ control: form.control, name: "orderBy" });
2515
2639
  const triggerArray = useFieldArray({ control: form.control, name: "triggers" });
2516
2640
  const sourceType = useWatch2({ control: form.control, name: "sourceType" });
2517
2641
  const sourceTable = useWatch2({ control: form.control, name: "sourceTable" });
@@ -2545,6 +2669,7 @@ function createBuilderListEditorPageComponent(deps) {
2545
2669
  listId,
2546
2670
  form,
2547
2671
  columnArray,
2672
+ orderByArray,
2548
2673
  triggerArray,
2549
2674
  sourceType,
2550
2675
  sourceTable,
@@ -2707,6 +2832,7 @@ function createBuilderAdminPages({
2707
2832
  key: "name",
2708
2833
  label: "Name",
2709
2834
  sortable: true,
2835
+ hidden: false,
2710
2836
  align: "left"
2711
2837
  };
2712
2838
  const emptyListValues = {
@@ -2715,6 +2841,7 @@ function createBuilderAdminPages({
2715
2841
  sourceType: "none",
2716
2842
  sourceTable: BUILDER_EDITOR_NONE_VALUE,
2717
2843
  apiBasePath: "",
2844
+ orderBy: [],
2718
2845
  columns: [emptyColumn],
2719
2846
  triggers: [],
2720
2847
  version: 0