sera-components 1.5.0 → 1.6.0

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.
@@ -1,22 +1,23 @@
1
1
  import { Trie } from '../utils';
2
- import { NavigateFunction, Permission, NoArgsRoute } from '../types';
2
+ import { NavigateFunction, Permission, NoArgsRoute, NoURLArgsRoute } from '../types';
3
3
  type MenuKey = string;
4
- export interface MenuRoute<R> {
5
- path: NoArgsRoute;
4
+ export interface MenuRoute<Q, R> {
5
+ path: NoURLArgsRoute<Q> | NoArgsRoute;
6
6
  role: R;
7
+ defaultPathArgs?: Q;
7
8
  }
8
9
  export interface SeraMenuItem<R> {
9
10
  key: MenuKey;
10
11
  label: React.ReactElement | string;
11
12
  icon?: React.ReactElement;
12
- route?: MenuRoute<R>;
13
+ route?: MenuRoute<any, R>;
13
14
  children?: SeraMenuItem<R>[];
14
15
  }
15
- export declare function buildMenuItemIndex<R>(items: SeraMenuItem<R>[]): {
16
+ export declare function buildMenuItemIndex<Q, R>(items: SeraMenuItem<R>[]): {
16
17
  key2item: Record<MenuKey, SeraMenuItem<R>>;
17
18
  key2fullpath: Record<MenuKey, MenuKey[]>;
18
19
  key2route: {
19
- [key: MenuKey]: MenuRoute<R>;
20
+ [key: MenuKey]: MenuRoute<Q, R>;
20
21
  };
21
22
  };
22
23
  export declare function filterAllowedItems<R>(items: SeraMenuItem<R>[], checkPermission: (role: R) => Permission): SeraMenuItem<R>[];
@@ -1,4 +1,4 @@
1
- import { DataProperty, DB, DraftEmbeddedRecord, DraftRecord, EmbeddedSchema, GenericEmbeddedRecord, GenericRecord, ObjectProperty, Schema, SchemaType } from 'sera-db';
1
+ import { DataProperty, DB, DraftEmbeddedRecord, DraftRecord, EmbeddedSchema, GenericEmbeddedRecord, GenericRecord, ObjectProperty, PropertyNames, Schema, SchemaType } from 'sera-db';
2
2
  import { DisplayInterface } from '../data/display';
3
3
  type DOP = DataProperty | ObjectProperty;
4
4
  /**
@@ -43,10 +43,10 @@ export declare function makeTableColumnFromNestedProperty<R>(db: DB, property: D
43
43
  nestedKey?: string;
44
44
  component?: React.ComponentType<DisplayInterface<any>>;
45
45
  }): SeraColumn<R>;
46
- export declare function makeTableColumns<ID extends string | number, R extends GenericRecord<ID, DR>, DR extends DraftRecord<ID>, PF extends keyof R, F extends keyof DR, ST extends SchemaType<ID, R, DR, PF, F>, OR>(db: DB, schema: Schema<ID, R, DR, PF, F, ST> | EmbeddedSchema<R, DR, PF, F>, selectedColumns: (PF | SeraColumn<OR>)[], options?: {
46
+ export declare function makeTableColumns<ID extends string | number, R extends GenericRecord<ID, DR>, DR extends DraftRecord<ID>, PF extends PropertyNames<R>, F extends PropertyNames<DR>, ST extends SchemaType<ID, R, DR, PF, F>, OR>(db: DB, schema: Schema<ID, R, DR, PF, F, ST> | EmbeddedSchema<R, DR, PF, F>, selectedColumns: (PF | SeraColumn<OR>)[], options?: {
47
47
  nestedKey?: string;
48
48
  }): SeraColumn<OR>[];
49
- export declare function makeEmbeddedTableColumns<R extends GenericEmbeddedRecord<DR>, DR extends DraftEmbeddedRecord, PF extends keyof R, F extends keyof DR, OR>(db: DB, schema: EmbeddedSchema<R, DR, PF, F>, selectedColumns?: (PF | SeraColumn<OR>)[], options?: {
49
+ export declare function makeEmbeddedTableColumns<R extends GenericEmbeddedRecord<DR>, DR extends DraftEmbeddedRecord, PF extends PropertyNames<R>, F extends PropertyNames<DR>, OR>(db: DB, schema: EmbeddedSchema<R, DR, PF, F>, selectedColumns?: (PF | SeraColumn<OR>)[], options?: {
50
50
  nestedKey?: string;
51
51
  }): SeraColumn<OR>[];
52
52
  export declare function isSeraColumn<R>(column: SeraColumn<R> | any): column is SeraColumn<R>;
package/dist/types.d.ts CHANGED
@@ -26,6 +26,18 @@ export interface NoArgsRoute {
26
26
  open: (navigate: NavigateFunction) => void;
27
27
  };
28
28
  getURL(): string;
29
+ pathDef: string;
30
+ }
31
+ export interface NoURLArgsRoute<Q> {
32
+ path({ queryArgs }: {
33
+ queryArgs: Q;
34
+ }): {
35
+ open: (navigate: NavigateFunction) => void;
36
+ };
37
+ getURL({ queryArgs }: {
38
+ queryArgs: Q;
39
+ }): string;
40
+ pathDef: string;
29
41
  }
30
42
  export interface EntityRoute {
31
43
  path({ urlArgs }: {
@@ -1,2 +1,3 @@
1
1
  export * from './utils';
2
2
  export * from './trie';
3
+ export * from './propertyUtils';
@@ -0,0 +1,33 @@
1
+ import { DataProperty, ObjectProperty, NestedProperty } from 'sera-db';
2
+ /**
3
+ * Gets the value of a property (regular or nested) from a record.
4
+ *
5
+ * @param record - The record to extract the value from
6
+ * @param property - The property (DataProperty, ObjectProperty, or NestedProperty)
7
+ * @returns The value of the property
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * const value = getPropertyValue(supplier, paymentPolicyProp);
12
+ * const nestedValue = getPropertyValue(supplier, new NestedProperty(supplier.paymentPolicy, paymentPolicy.type));
13
+ * ```
14
+ */
15
+ export declare function getPropertyValue(record: any, property: DataProperty | ObjectProperty | NestedProperty): any;
16
+ /**
17
+ * Sets the value of a property (regular or nested) in a record.
18
+ *
19
+ * For regular properties, calls the updateFuncName method.
20
+ * For nested properties, uses the setValue method which handles
21
+ * creating intermediate objects as needed.
22
+ *
23
+ * @param record - The record to set the value in (must be a draft record)
24
+ * @param property - The property (DataProperty, ObjectProperty, or NestedProperty)
25
+ * @param value - The new value to set
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * setPropertyValue(draftSupplier, paymentPolicyProp, newPolicy);
30
+ * setPropertyValue(draftSupplier, new NestedProperty(supplier.paymentPolicy, paymentPolicy.type), PaymentPolicyType.PaymentBeforeService);
31
+ * ```
32
+ */
33
+ export declare function setPropertyValue(record: any, property: DataProperty | ObjectProperty | NestedProperty, value: any): void;
@@ -1,18 +1,21 @@
1
- import { DataProperty, DraftRecord, GenericRecord, ObjectProperty, Schema, SchemaType, Table } from 'sera-db';
1
+ import { DraftRecord, GenericRecord, Schema, SchemaType, Table, NestedProperty, PropertyNames } from 'sera-db';
2
2
  import { MantineSpacing } from '@mantine/core';
3
3
  import { DisplayInterface } from '../data/display';
4
4
  interface FieldArgs<R> {
5
5
  display?: React.ComponentType<DisplayInterface<any>>;
6
6
  visible?: (record: R) => boolean;
7
7
  }
8
- export interface FieldGroup<ID extends string | number, R extends GenericRecord<ID, DR>, DR extends DraftRecord<ID>, PF extends keyof R, F extends keyof DR, ST extends SchemaType<ID, R, DR, PF, F>> {
8
+ export interface FieldGroup<ID extends string | number, R extends GenericRecord<ID, DR>, DR extends DraftRecord<ID>, PF extends PropertyNames<R>, F extends PropertyNames<DR>, ST extends SchemaType<ID, R, DR, PF, F>> {
9
9
  name?: string;
10
10
  fields: (ST["allProperties"] | {
11
11
  prop: ST["allProperties"];
12
12
  args?: FieldArgs<R>;
13
+ } | NestedProperty | {
14
+ prop: NestedProperty;
15
+ args?: FieldArgs<R>;
13
16
  } | ((store: Table<ID, R, DR>, record: R) => React.ReactNode))[][];
14
17
  }
15
- export interface SeraViewProps<ID extends string | number, R extends GenericRecord<ID, DR>, DR extends DraftRecord<ID>, PF extends keyof R, F extends keyof DR, ST extends SchemaType<ID, R, DR, PF, F>> {
18
+ export interface SeraViewProps<ID extends string | number, R extends GenericRecord<ID, DR>, DR extends DraftRecord<ID>, PF extends PropertyNames<R>, F extends PropertyNames<DR>, ST extends SchemaType<ID, R, DR, PF, F>> {
16
19
  schema: Schema<ID, R, DR, PF, F, ST>;
17
20
  store: Table<ID, R, DR>;
18
21
  fieldGroups: FieldGroup<ID, R, DR, PF, F, ST>[];
@@ -20,32 +23,7 @@ export interface SeraViewProps<ID extends string | number, R extends GenericReco
20
23
  styles?: React.CSSProperties;
21
24
  className?: string;
22
25
  }
23
- export declare const SeraView: <ID extends string | number, R extends GenericRecord<ID, DR>, DR extends DraftRecord<ID>, PF extends keyof R, F extends keyof DR, ST extends SchemaType<ID, R, DR, PF, F>>(props: SeraViewProps<ID, R, DR, PF, F, ST>) => import("react/jsx-runtime").JSX.Element;
24
- /**
25
- * Creates a nested field renderer function for displaying nested record properties.
26
- *
27
- * This function determines the appropriate display component based on the property type
28
- * (data property or object property) and cardinality, then returns a function that renders
29
- * the property value within a ViewNestedPropertyItem component.
30
- *
31
- * @template ID - The type of the record identifier (string or number)
32
- * @template R - The generic record type extending GenericRecord
33
- * @template DR - The draft record type extending DraftRecord
34
- *
35
- * @param props - Array of properties defining the nested path to the field
36
- * @param display - Optional custom display component for rendering the field value
37
- *
38
- * @returns A function that takes a store and record, returning a React node to display the nested field
39
- *
40
- * @throws {Error} When no display component is found for the specified datatype
41
- *
42
- * @example
43
- * ```tsx
44
- * const renderField = makeNestedField([userProperty, nameProperty]);
45
- * const node = renderField(store, record);
46
- * ```
47
- */
48
- export declare function makeNestedField<ID extends string | number, R extends GenericRecord<ID, DR>, DR extends DraftRecord<ID>>(props: (DataProperty | ObjectProperty)[], args?: FieldArgs<R>): (store: Table<ID, R, DR>, record: R) => React.ReactNode;
26
+ export declare const SeraView: <ID extends string | number, R extends GenericRecord<ID, DR>, DR extends DraftRecord<ID>, PF extends PropertyNames<R>, F extends PropertyNames<DR>, ST extends SchemaType<ID, R, DR, PF, F>>(props: SeraViewProps<ID, R, DR, PF, F, ST>) => import("react/jsx-runtime").JSX.Element;
49
27
  /**
50
28
  * Groups multiple fields together in a row layout using SimpleGrid.
51
29
  *
@@ -66,9 +44,12 @@ export declare function makeNestedField<ID extends string | number, R extends Ge
66
44
  * const node = groupedFields(store, record);
67
45
  * ```
68
46
  */
69
- export declare function groupFields<ID extends string | number, R extends GenericRecord<ID, DR>, DR extends DraftRecord<ID>, PF extends keyof R, F extends keyof DR, ST extends SchemaType<ID, R, DR, PF, F>>(schema: Schema<ID, R, DR, PF, F, ST>, fields: (ST["allProperties"] | {
47
+ export declare function groupFields<ID extends string | number, R extends GenericRecord<ID, DR>, DR extends DraftRecord<ID>, PF extends PropertyNames<R>, F extends PropertyNames<DR>, ST extends SchemaType<ID, R, DR, PF, F>>(schema: Schema<ID, R, DR, PF, F, ST>, fields: (ST["allProperties"] | {
70
48
  prop: ST["allProperties"];
71
49
  args?: FieldArgs<R>;
50
+ } | NestedProperty | {
51
+ prop: NestedProperty;
52
+ args?: FieldArgs<R>;
72
53
  } | ((store: Table<ID, R, DR>, record: R) => React.ReactNode))[], args?: {
73
54
  visible?: (record: R) => boolean;
74
55
  flexGrow?: boolean;
@@ -1,9 +1,9 @@
1
- import { DataProperty, DraftRecord, GenericRecord, ObjectProperty, Table } from 'sera-db';
1
+ import { DataProperty, DraftRecord, GenericRecord, ObjectProperty, Table, NestedProperty } from 'sera-db';
2
2
  import { DisplayInterface } from '../data';
3
3
  export interface ViewItemProps<ID extends string | number, R extends GenericRecord<ID, DR>, DR extends DraftRecord<ID>> {
4
4
  store: Table<ID, R, DR>;
5
5
  record: R;
6
- property: DataProperty | ObjectProperty;
6
+ property: DataProperty | ObjectProperty | NestedProperty;
7
7
  visible?: (record: R) => boolean;
8
8
  DisplayComponent: React.ComponentType<DisplayInterface<any>>;
9
9
  }
@@ -1,6 +1,6 @@
1
- import { DraftRecord, GenericRecord, Schema, SchemaType, Table } from 'sera-db';
1
+ import { DraftRecord, GenericRecord, PropertyNames, Schema, SchemaType, Table } from 'sera-db';
2
2
  import { FieldGroup } from './View';
3
- export interface SeraViewTabProps<ID extends string | number, R extends GenericRecord<ID, DR>, DR extends DraftRecord<ID>, PF extends keyof R, F extends keyof DR, ST extends SchemaType<ID, R, DR, PF, F>> {
3
+ export interface SeraViewTabProps<ID extends string | number, R extends GenericRecord<ID, DR>, DR extends DraftRecord<ID>, PF extends PropertyNames<R>, F extends PropertyNames<DR>, ST extends SchemaType<ID, R, DR, PF, F>> {
4
4
  schema: Schema<ID, R, DR, PF, F, ST>;
5
5
  store: Table<ID, R, DR>;
6
6
  fieldTabs: {
@@ -11,4 +11,4 @@ export interface SeraViewTabProps<ID extends string | number, R extends GenericR
11
11
  tabStyles?: React.CSSProperties;
12
12
  tabClassName?: string;
13
13
  }
14
- export declare const SeraViewTab: <ID extends string | number, R extends GenericRecord<ID, DR>, DR extends DraftRecord<ID>, PF extends keyof R, F extends keyof DR, ST extends SchemaType<ID, R, DR, PF, F>>(props: SeraViewTabProps<ID, R, DR, PF, F, ST>) => import("react/jsx-runtime").JSX.Element;
14
+ export declare const SeraViewTab: <ID extends string | number, R extends GenericRecord<ID, DR>, DR extends DraftRecord<ID>, PF extends PropertyNames<R>, F extends PropertyNames<DR>, ST extends SchemaType<ID, R, DR, PF, F>>(props: SeraViewTabProps<ID, R, DR, PF, F, ST>) => import("react/jsx-runtime").JSX.Element;
@@ -1,2 +1,2 @@
1
- export { SeraView, makeNestedField, groupFields } from './View';
1
+ export { SeraView, groupFields } from './View';
2
2
  export { SeraViewTab } from './ViewTab';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "sera-components",
3
3
  "private": false,
4
- "version": "1.5.0",
4
+ "version": "1.6.0",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "dist"
@@ -19,13 +19,14 @@
19
19
  "dev": "vite",
20
20
  "clean": "rimraf dist",
21
21
  "build": "tsc -b tsconfig.build.json && vite build",
22
+ "typecheck": "tsc --noEmit",
22
23
  "preview": "vite preview",
23
24
  "test": "vitest",
24
25
  "prepublishOnly": "npm run clean && npm run build"
25
26
  },
26
27
  "devDependencies": {
27
- "@types/react": "^19.0.12",
28
- "@types/react-dom": "^19.0.4",
28
+ "@types/react": "^19.2.7",
29
+ "@types/react-dom": "^19.2.3",
29
30
  "@types/throttle-debounce": "^5.0.2",
30
31
  "rimraf": "^6.0.1",
31
32
  "typescript": "~5.7.2",
@@ -35,17 +36,17 @@
35
36
  },
36
37
  "peerDependencies": {
37
38
  "@mantine/core": "^8.1.0",
38
- "@mantine/form": "^8.1.0",
39
39
  "@mantine/dates": "^8.3.1",
40
+ "@mantine/form": "^8.1.0",
40
41
  "@tabler/icons-react": "^3.31.0",
41
42
  "@tanstack/react-table": "^8.21.3",
43
+ "dayjs": "^1.11.18",
42
44
  "mobx-react-lite": "^4.1.0",
43
- "react": "^19.0.0",
44
- "react-dom": "^19.0.0",
45
+ "react": "^19.2.3",
46
+ "react-dom": "^19.2.3",
45
47
  "react-imask": "^7.6.1",
46
48
  "react-router": "^7.7.1",
47
- "sera-db": "^1.12.7",
48
- "throttle-debounce": "^5.0.2",
49
- "dayjs": "^1.11.18"
49
+ "sera-db": "^1.13.0",
50
+ "throttle-debounce": "^5.0.2"
50
51
  }
51
52
  }
@@ -1,38 +0,0 @@
1
- import { DataProperty, DraftRecord, GenericRecord, ObjectProperty, validators, Table } from 'sera-db';
2
- import { InputInterface } from '../data';
3
- import { FormItemLayout } from './FormItem';
4
- export interface FormNestedPropertyItemProps<ID extends string | number, R extends GenericRecord<ID, DR>, DR extends DraftRecord<ID>> {
5
- store: Table<ID, R, DR>;
6
- record: DR | R;
7
- properties: (DataProperty | ObjectProperty)[];
8
- InputComponent: React.ComponentType<InputInterface<any>>;
9
- validator: validators.ValueValidator;
10
- layout?: FormItemLayout;
11
- freeze?: boolean;
12
- }
13
- /**
14
- * A component that renders a nested property input for forms.
15
- *
16
- * This component traverses through a chain of properties to create input fields
17
- * for deeply nested property values in a record. It handles embedded objects
18
- * by creating nested form structures.
19
- *
20
- * @template ID - The type of the record identifier (string or number)
21
- * @template R - The type of the generic record extending GenericRecord
22
- * @template DR - The type of the draft record extending DraftRecord
23
- *
24
- * @param props - The component properties
25
- * @param props.store - The table store containing the record data
26
- * @param props.record - The draft record being edited
27
- * @param props.properties - Array of properties defining the path to the nested value
28
- * @param props.InputComponent - React component used to render the field input
29
- *
30
- * @returns A JSX element with input fields for the nested property
31
- */
32
- export declare const FormNestedPropertyItem: (<ID extends string | number, R extends GenericRecord<ID, DR>, DR extends DraftRecord<ID>>({ store, record, properties, layout, InputComponent, validator, freeze, }: FormNestedPropertyItemProps<ID, R, DR>) => import("react/jsx-runtime").JSX.Element) & {
33
- displayName: string;
34
- };
35
- export declare function makeFieldForm<ID extends string | number, R extends GenericRecord<ID, DR>, DR extends DraftRecord<ID>>(props: (DataProperty | ObjectProperty)[], validators: validators.ValueValidator, args?: {
36
- input?: React.ComponentType<InputInterface<any>>;
37
- freeze?: boolean;
38
- }): (store: Table<ID, R, DR>, record: DR) => React.ReactNode;
@@ -1,43 +0,0 @@
1
- import { DataProperty, DraftRecord, GenericRecord, ObjectProperty, Table } from 'sera-db';
2
- import { DisplayInterface } from '../data';
3
- export interface ViewNestedPropertyItemProps<ID extends string | number, R extends GenericRecord<ID, DR>, DR extends DraftRecord<ID>> {
4
- store: Table<ID, R, DR>;
5
- record: R;
6
- properties: (DataProperty | ObjectProperty)[];
7
- DisplayComponent: React.ComponentType<DisplayInterface<any>>;
8
- visible?: (record: R) => boolean;
9
- }
10
- /**
11
- * A component that renders a nested property item.
12
- *
13
- * This component traverses through a chain of properties to display a deeply nested
14
- * property value from a record. It shows the last property label and renders the value
15
- * using the provided DisplayComponent.
16
- *
17
- * @template ID - The type of the record identifier (string or number)
18
- * @template R - The type of the generic record extending GenericRecord
19
- * @template DR - The type of the draft record extending DraftRecord
20
- * @template PF - The property field type constrained to keys of R
21
- * @template F - The field type constrained to keys of DR
22
- *
23
- * @param props - The component properties
24
- * @param props.store - The table store containing the record data
25
- * @param props.record - The record being viewed
26
- * @param props.properties - Array of properties defining the path to the nested value
27
- * @param props.DisplayComponent - React component used to render the field value
28
- *
29
- * @returns A JSX element displaying the nested property with its label and value
30
- *
31
- * @example
32
- * ```tsx
33
- * <ViewNestedPropertyItem
34
- * store={userStore}
35
- * record={user}
36
- * properties={[addressProperty, streetProperty]}
37
- * DisplayComponent={TextDisplay}
38
- * />
39
- * ```
40
- */
41
- export declare const ViewNestedPropertyItem: (<ID extends string | number, R extends GenericRecord<ID, DR>, DR extends DraftRecord<ID>>({ store, record, properties, DisplayComponent, visible, }: ViewNestedPropertyItemProps<ID, R, DR>) => import("react/jsx-runtime").JSX.Element) & {
42
- displayName: string;
43
- };