swoop-common 1.0.13 → 1.0.15

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.
Files changed (82) hide show
  1. package/README.md +1 -1
  2. package/package.json +1 -1
  3. package/dist/api/consts.d.ts +0 -1
  4. package/dist/api/consts.js +0 -2
  5. package/dist/components/SchemaValidator.d.ts +0 -3
  6. package/dist/components/SchemaValidator.js +0 -6
  7. package/dist/components/StyledFormView.d.ts +0 -34
  8. package/dist/components/StyledFormView.js +0 -12
  9. package/dist/default_registration/fields_base.d.ts +0 -1
  10. package/dist/default_registration/fields_base.js +0 -129
  11. package/dist/hooks/errors.d.ts +0 -6
  12. package/dist/hooks/errors.js +0 -17
  13. package/dist/index.d.ts +0 -10
  14. package/dist/index.js +0 -9
  15. package/dist/prebuild/generated/import_generated.d.ts +0 -15
  16. package/dist/prebuild/generated/import_generated.js +0 -18
  17. package/dist/prebuild/import.d.ts +0 -1
  18. package/dist/prebuild/import.js +0 -32
  19. package/dist/registry/components.d.ts +0 -13
  20. package/dist/registry/components.js +0 -49
  21. package/dist/registry/fields.d.ts +0 -10
  22. package/dist/registry/fields.js +0 -19
  23. package/dist/registry/types.d.ts +0 -5
  24. package/dist/registry/types.js +0 -5
  25. package/dist/renderers/Address.d.ts +0 -1
  26. package/dist/renderers/Address.js +0 -67
  27. package/dist/renderers/ComponentPicker.d.ts +0 -19
  28. package/dist/renderers/ComponentPicker.js +0 -68
  29. package/dist/renderers/Debug.d.ts +0 -1
  30. package/dist/renderers/Debug.js +0 -13
  31. package/dist/renderers/Example.d.ts +0 -1
  32. package/dist/renderers/Example.js +0 -31
  33. package/dist/renderers/Image/ImageForm.d.ts +0 -10
  34. package/dist/renderers/Image/ImageForm.js +0 -78
  35. package/dist/renderers/Image/ImagePresentation.d.ts +0 -6
  36. package/dist/renderers/Image/ImagePresentation.js +0 -62
  37. package/dist/renderers/StagedText.d.ts +0 -1
  38. package/dist/renderers/StagedText.js +0 -20
  39. package/dist/renderers/TemplatePicker.d.ts +0 -1
  40. package/dist/renderers/TemplatePicker.js +0 -55
  41. package/dist/renderers/address/AddressForm.d.ts +0 -1
  42. package/dist/renderers/address/AddressForm.js +0 -46
  43. package/dist/renderers/address/AddressPresentation.d.ts +0 -1
  44. package/dist/renderers/address/AddressPresentation.js +0 -34
  45. package/dist/renderers/textfield/MultilineForm.d.ts +0 -1
  46. package/dist/renderers/textfield/MultilineForm.js +0 -21
  47. package/dist/renderers/textfield/MultilinePresentation.d.ts +0 -1
  48. package/dist/renderers/textfield/MultilinePresentation.js +0 -13
  49. package/dist/schema/formBuilders/formBuilderJsonSchema.d.ts +0 -11
  50. package/dist/schema/formBuilders/formBuilderJsonSchema.js +0 -178
  51. package/dist/schema/formBuilders/formBuilderUiSchema.d.ts +0 -2
  52. package/dist/schema/formBuilders/formBuilderUiSchema.js +0 -208
  53. package/dist/schema/formSchemaTypes.d.ts +0 -15
  54. package/dist/schema/formSchemaTypes.js +0 -6
  55. package/dist/schema/generate/formSchemaGenerate.d.ts +0 -3
  56. package/dist/schema/generate/formSchemaGenerate.js +0 -19
  57. package/dist/schema/generate/jsonSchemaGenerate.d.ts +0 -3
  58. package/dist/schema/generate/jsonSchemaGenerate.js +0 -150
  59. package/dist/schema/generate/jsonSchemaGeneratewip.d.ts +0 -4
  60. package/dist/schema/generate/jsonSchemaGeneratewip.js +0 -59
  61. package/dist/schema/generate/uiSchemaGenerate.d.ts +0 -3
  62. package/dist/schema/generate/uiSchemaGenerate.js +0 -33
  63. package/dist/schema/schema.d.ts +0 -48
  64. package/dist/schema/schema.js +0 -1
  65. package/dist/schema/template/constraint.d.ts +0 -17
  66. package/dist/schema/template/constraint.js +0 -119
  67. package/dist/schema/template/type.d.ts +0 -94
  68. package/dist/schema/template/type.js +0 -1
  69. package/dist/schema/util.d.ts +0 -1
  70. package/dist/schema/util.js +0 -22
  71. package/dist/test.d.ts +0 -6
  72. package/dist/test.js +0 -5
  73. package/dist/types/address.d.ts +0 -10
  74. package/dist/types/address.js +0 -1
  75. package/dist/types/jsonSchema.d.ts +0 -4
  76. package/dist/types/jsonSchema.js +0 -1
  77. package/dist/types/util.d.ts +0 -1
  78. package/dist/types/util.js +0 -1
  79. package/dist/util/xtype.d.ts +0 -3
  80. package/dist/util/xtype.js +0 -18
  81. package/dist/validation/schemaValidator.d.ts +0 -4
  82. package/dist/validation/schemaValidator.js +0 -6
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Custom Form Library
1
+ # Swoop Template Library
2
2
 
3
3
  This library is used for rendering **Swoop itinerary templates**. It provides tools for defining **custom field types**, registering **custom components**, and rendering templates from a **MasterSchema**. It supports both input mode (for creating templates) and presentation mode (for rendering them for end users). The schema system is stage-aware, enabling precise control over what data is editable or displayed at which stage.
4
4
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "swoop-common",
3
- "version": "1.0.13",
3
+ "version": "1.0.15",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [
@@ -1 +0,0 @@
1
- export declare const BASE_API_URL = "https://data-api-dev.swoop-adventures.com";
@@ -1,2 +0,0 @@
1
- // temp
2
- export const BASE_API_URL = "https://data-api-dev.swoop-adventures.com";
@@ -1,3 +0,0 @@
1
- import React from 'react';
2
- declare const ErrorRenderer: () => React.JSX.Element;
3
- export default ErrorRenderer;
@@ -1,6 +0,0 @@
1
- import React from 'react';
2
- import { Typography } from '@mui/material';
3
- const ErrorRenderer = () => {
4
- return (React.createElement(Typography, { variant: 'h3' }, "Error loading"));
5
- };
6
- export default ErrorRenderer;
@@ -1,34 +0,0 @@
1
- import React from 'react';
2
- import "../prebuild/generated/import_generated";
3
- import { ComponentPool } from '../registry/types';
4
- import { FormSchema, Stage } from '../schema/formSchemaTypes';
5
- interface Props {
6
- /**
7
- * This should only be used for the initial values, as this is not truly a controlled component.
8
- * Frequent updates of this can cause significant perfomance dips.
9
- */
10
- initialData: any;
11
- schema: FormSchema;
12
- /**
13
- * This should not be fed back into the form.
14
- * Instead store it as a ref.
15
- */
16
- onChange?: (value: any) => void;
17
- /**
18
- * Dictates which mode the form will display in.
19
- * Each mode has a different pool of renderers.
20
- */
21
- pool: ComponentPool;
22
- /**
23
- * Whether this form should be readonly.
24
- * Has little to no effect if using the presentation pool of components
25
- */
26
- readonly?: boolean;
27
- /**
28
- * Whether to also include mui default renderers
29
- */
30
- useMui?: boolean;
31
- stage: Stage;
32
- }
33
- export declare const StyledFormView: React.FC<Props>;
34
- export {};
@@ -1,12 +0,0 @@
1
- import { JsonForms } from '@jsonforms/react';
2
- import React from 'react';
3
- import { materialCells, materialRenderers } from '@jsonforms/material-renderers';
4
- import "../prebuild/generated/import_generated";
5
- import { getComponents } from '../registry/components';
6
- import { generateJsonSchema } from '../schema/generate/jsonSchemaGeneratewip';
7
- import { generateUiSchema } from '../schema/generate/uiSchemaGenerate';
8
- export const StyledFormView = ({ initialData, schema, onChange, stage, pool, readonly, useMui }) => {
9
- const json = generateJsonSchema(schema, stage);
10
- const ui = generateUiSchema(schema, stage);
11
- return (React.createElement(JsonForms, { onChange: onChange, data: initialData, schema: json, uischema: ui, renderers: [...(useMui ? materialRenderers : []), ...getComponents(pool)], readonly: readonly, cells: materialCells }));
12
- };
@@ -1 +0,0 @@
1
- export {};
@@ -1,129 +0,0 @@
1
- import { registerType } from "../registry/fields";
2
- registerType("string", "Text", { type: "string" }, {
3
- type: "object",
4
- title: "Text Options",
5
- properties: {
6
- minLength: { type: "integer", minimum: 0 },
7
- maxLength: { type: "integer", minimum: 1 },
8
- pattern: { type: "string" },
9
- format: {
10
- type: "string",
11
- enum: ["", "email", "uri", "date-time", "date", "time"],
12
- },
13
- },
14
- }, false);
15
- registerType("number", "Number", { type: "number" }, {
16
- type: "object",
17
- properties: {
18
- minimum: { type: "number" },
19
- maximum: { type: "number" },
20
- multipleOf: { type: "number", exclusiveMinimum: 0 },
21
- },
22
- }, false);
23
- registerType("integer", "Integer", { type: "integer" }, {
24
- type: "object",
25
- properties: {
26
- minimum: { type: "number" },
27
- maximum: { type: "number" },
28
- multipleOf: { type: "number", exclusiveMinimum: 0 },
29
- },
30
- }, false);
31
- registerType("boolean", "Checkbox", { type: "boolean" }, {}, false);
32
- registerType("enum", "Dropdown", { type: "array" }, {
33
- type: "object",
34
- title: "Dropdown Options",
35
- properties: {
36
- enumValues: {
37
- title: "Dropdown Values",
38
- type: "array",
39
- items: { type: "string" },
40
- },
41
- },
42
- }, true);
43
- registerType("array", "List", { type: "array" }, {
44
- type: "object",
45
- title: "List Options",
46
- properties: {
47
- minItems: { type: "integer", minimum: 0 },
48
- maxItems: { type: "integer", minimum: 1 },
49
- uniqueItems: { type: "boolean", default: false },
50
- itemDefinition: { $ref: "#/$defs/arrayItemDefinition" },
51
- },
52
- }, true);
53
- registerType("object", "Group", { type: "object" }, {
54
- type: "object",
55
- title: "Group",
56
- properties: {
57
- properties: {
58
- type: "array",
59
- title: "Group Fields",
60
- items: { $ref: "#/$defs/fieldDefinition" },
61
- },
62
- },
63
- }, true);
64
- registerType("stagedText", "Staged Text", {}, {}, false);
65
- registerType("liveData", "Live Data", {}, {}, false);
66
- registerType("component", "Component Reference", {}, {
67
- "x-type": "componentOptions",
68
- type: "object",
69
- title: "Component Options",
70
- properties: {
71
- templateIds: {
72
- type: "array",
73
- title: "Select Templates",
74
- items: {
75
- type: "string",
76
- },
77
- },
78
- },
79
- }, false);
80
- registerType("example", "Example Field", { type: "string" }, {
81
- type: "object",
82
- title: "Example Options",
83
- properties: {
84
- exampleTextInput: { type: "string" },
85
- },
86
- }, false);
87
- registerType("address", "Address", {
88
- title: "your address",
89
- description: "your address",
90
- type: "object",
91
- properties: {
92
- line1: {
93
- type: "string",
94
- title: "Address Line 1"
95
- },
96
- line2: {
97
- type: "string",
98
- title: "Address Line 2"
99
- },
100
- city: {
101
- type: "string",
102
- title: "City"
103
- },
104
- county: {
105
- type: "string",
106
- title: "County"
107
- },
108
- postcode: {
109
- type: "string",
110
- title: "Postcode",
111
- pattern: "^[A-Z]{1,2}[0-9][0-9A-Z]? ?[0-9][A-Z]{2}$"
112
- },
113
- number: {
114
- type: "number",
115
- title: "Number"
116
- }
117
- },
118
- required: ["line1", "city", "postcode"]
119
- }, {}, false);
120
- registerType("subset", "Subset", {
121
- title: "your address",
122
- description: "your address",
123
- type: "array",
124
- items: {
125
- type: "string"
126
- }
127
- }, {}, false);
128
- registerType("image", "Image", { type: "string" }, {}, false);
129
- registerType("multiline", "Multiline", { type: "string" }, {}, false);
@@ -1,6 +0,0 @@
1
- /**
2
- * Returns a function which can be used to retrieve errors.
3
- * For objects field is the field name.
4
- * For primitives field is the x-type.
5
- */
6
- export declare const useLocalErrors: (path: string) => (field: string) => import("ajv").ErrorObject<string, Record<string, any>, unknown> | undefined;
@@ -1,17 +0,0 @@
1
- import { useJsonForms } from "@jsonforms/react";
2
- import React from "react";
3
- /**
4
- * Returns a function which can be used to retrieve errors.
5
- * For objects field is the field name.
6
- * For primitives field is the x-type.
7
- */
8
- export const useLocalErrors = (path) => {
9
- const { core } = useJsonForms();
10
- console.log(core);
11
- // Filters out errors for the current scope
12
- const local = React.useMemo(() => {
13
- var _a;
14
- return ((_a = core === null || core === void 0 ? void 0 : core.errors) === null || _a === void 0 ? void 0 : _a.filter(e => e.instancePath.startsWith("/" + path.replace(/\./g, "/")))) || [];
15
- }, [core === null || core === void 0 ? void 0 : core.errors, path]);
16
- return React.useCallback((field) => local.find(e => e.instancePath.endsWith("/" + field)), [local]);
17
- };
package/dist/index.d.ts DELETED
@@ -1,10 +0,0 @@
1
- export { getComponents } from "./registry/components";
2
- export { JSONSchemaObject } from "./schema/schema";
3
- export { generateUiSchema } from "./schema/generate/uiSchemaGenerate";
4
- export { generateJsonSchema } from "./schema/generate/jsonSchemaGeneratewip";
5
- export * from "./test";
6
- export * from "./components/StyledFormView";
7
- export * from "./registry/types";
8
- export { FormSchema, Stage } from "./schema/formSchemaTypes";
9
- export { FORM_BUILDER_JSON_SCHEMA } from "./schema/formBuilders/formBuilderJsonSchema";
10
- export { FORM_BUILDER_UI_SCHEMA } from "./schema/formBuilders/formBuilderUiSchema";
package/dist/index.js DELETED
@@ -1,9 +0,0 @@
1
- export { getComponents } from "./registry/components";
2
- export { generateUiSchema } from "./schema/generate/uiSchemaGenerate";
3
- export { generateJsonSchema } from "./schema/generate/jsonSchemaGeneratewip";
4
- export * from "./test";
5
- export * from "./components/StyledFormView";
6
- export * from "./registry/types";
7
- export { Stage } from "./schema/formSchemaTypes";
8
- export { FORM_BUILDER_JSON_SCHEMA } from "./schema/formBuilders/formBuilderJsonSchema";
9
- export { FORM_BUILDER_UI_SCHEMA } from "./schema/formBuilders/formBuilderUiSchema";
@@ -1,15 +0,0 @@
1
- import "../../default_registration/fields_base";
2
- import "../../renderers/address/AddressForm";
3
- import "../../renderers/address/AddressPresentation";
4
- import "../../renderers/Address";
5
- import "../../renderers/ComponentPicker";
6
- import "../../renderers/Debug";
7
- import "../../renderers/Example";
8
- import "../../renderers/Image/ImageForm";
9
- import "../../renderers/Image/ImagePresentation";
10
- import "../../renderers/StagedText";
11
- import "../../renderers/TemplatePicker";
12
- import "../../renderers/textfield/MultilineForm";
13
- import "../../renderers/textfield/MultilinePresentation";
14
- import "../../schema/formBuilders/formBuilderJsonSchema";
15
- import "../../schema/formBuilders/formBuilderUiSchema";
@@ -1,18 +0,0 @@
1
- // Base field types
2
- import "../../default_registration/fields_base";
3
- // Custom component renderers
4
- import "../../renderers/address/AddressForm";
5
- import "../../renderers/address/AddressPresentation";
6
- import "../../renderers/Address";
7
- import "../../renderers/ComponentPicker";
8
- import "../../renderers/Debug";
9
- import "../../renderers/Example";
10
- import "../../renderers/Image/ImageForm";
11
- import "../../renderers/Image/ImagePresentation";
12
- import "../../renderers/StagedText";
13
- import "../../renderers/TemplatePicker";
14
- import "../../renderers/textfield/MultilineForm";
15
- import "../../renderers/textfield/MultilinePresentation";
16
- // Build template from schema last
17
- import "../../schema/formBuilders/formBuilderJsonSchema";
18
- import "../../schema/formBuilders/formBuilderUiSchema";
@@ -1 +0,0 @@
1
- export declare function getFilesRec(dir: string): string[];
@@ -1,32 +0,0 @@
1
- import fs from "fs";
2
- import path from "path";
3
- // Using codegen here as it reduces the number of files required to edit to add a new component.
4
- // It also ensures import order, which is important as types must be registered before any form schema is generated (this is generated at load, once)
5
- export function getFilesRec(dir) {
6
- const entries = fs.readdirSync(dir, { withFileTypes: true });
7
- return entries.flatMap((entry) => {
8
- const fullPath = path.join(dir, entry.name);
9
- if (entry.isDirectory())
10
- return getFilesRec(fullPath);
11
- else
12
- return fullPath;
13
- });
14
- }
15
- const getImports = (base) => {
16
- const files = getFilesRec(base).filter(f => f.endsWith(".tsx"));
17
- const renderers = files.map((file) => {
18
- const relativePath = path.relative(base, file);
19
- const noExt = relativePath.replace(/\.[^/.]+$/, '');
20
- const normalized = noExt.split(path.sep).join('/');
21
- return `import "../../renderers/${normalized}"`;
22
- });
23
- const templateFormSchemas = [`import "../../schema/formBuilders/formBuilderJsonSchema"`, `import "../../schema/formBuilders/formBuilderUiSchema"`];
24
- const baseFieldTypes = `import "../../default_registration/fields_base"`;
25
- return [
26
- "// Base field types", baseFieldTypes, "",
27
- "// Custom component renderers",
28
- ...renderers, "",
29
- "// Build template from schema last", ...templateFormSchemas
30
- ];
31
- };
32
- fs.writeFileSync("./src/prebuild/generated/import_generated.ts", getImports("./src/renderers").join("\n"));
@@ -1,13 +0,0 @@
1
- import { ControlProps, OwnPropsOfControl, RankedTester } from "@jsonforms/core";
2
- import { ComponentType } from "react";
3
- import { ComponentPool } from "./types";
4
- export interface CustomTypeData extends CustomTypeComponent {
5
- }
6
- interface CustomTypeComponent {
7
- tester: RankedTester;
8
- renderer: ComponentType<OwnPropsOfControl>;
9
- }
10
- export declare const registerComponent: (xType: string, Renderer: ComponentType<ControlProps>, mode: ComponentPool, overrideTester?: RankedTester) => void;
11
- export declare const getComponents: (mode: ComponentPool) => Readonly<Array<CustomTypeComponent>>;
12
- export declare const getComponent: (mode: ComponentPool, xType: string) => CustomTypeComponent | undefined;
13
- export {};
@@ -1,49 +0,0 @@
1
- import { withJsonFormsControlProps } from "@jsonforms/react";
2
- import { isXType } from "../util/xtype";
3
- import { ComponentPool } from "./types";
4
- import React from "react";
5
- // Stored seperately to avoid more expensive lookups
6
- const componentRegistry = {
7
- [ComponentPool.FORM]: new Map(),
8
- [ComponentPool.PRESENTATION]: new Map()
9
- };
10
- export const registerComponent = (xType, Renderer, mode, overrideTester) => {
11
- if (overrideTester) {
12
- componentRegistry[mode].set(xType, {
13
- tester: overrideTester,
14
- renderer: withJsonFormsControlProps(Renderer)
15
- });
16
- return;
17
- }
18
- if (componentRegistry[mode].has(xType)) {
19
- console.error("Tried to register duplicate component name:", xType);
20
- return;
21
- }
22
- // Wrap the component in a visibility checker
23
- const wrapped = (props) => {
24
- if (!props.visible)
25
- return null;
26
- return React.createElement(Renderer, Object.assign({}, props));
27
- };
28
- componentRegistry[mode].set(xType, {
29
- tester: isXType(xType),
30
- renderer: withJsonFormsControlProps(wrapped)
31
- });
32
- };
33
- export const getComponents = (mode) => {
34
- const list = [...componentRegistry[mode].values()];
35
- return (list.map(c => ({ renderer: c.renderer, tester: c.tester })));
36
- };
37
- export const getComponent = (mode, xType) => {
38
- const comp = componentRegistry[mode].get(xType);
39
- if (!comp)
40
- return undefined;
41
- return ({ tester: comp.tester, renderer: comp.renderer });
42
- };
43
- /*
44
- export const genComponentSchema = (mode: ComponentPool, xType: string): ComponentDataSchema | undefined =>
45
- {
46
- const comp = componentRegistry[mode].get(xType)
47
- if (!comp) return undefined;
48
- return structuredClone(comp.schema);
49
- }*/
@@ -1,10 +0,0 @@
1
- import { JsonSchema } from "@jsonforms/core";
2
- import { TemplateField } from "../schema/formBuilders/formBuilderJsonSchema";
3
- import { JsonSchemaWithXType } from "../types/jsonSchema";
4
- /**
5
- * If type is not a default json schema type, it is treated as x-type.
6
- * E.g. "number" will define the default number field, whereas "address" will define a custom field
7
- */
8
- export declare const registerType: (name: string, title: string, schema: JsonSchema, options: JsonSchemaWithXType, optionsRequired: boolean) => void;
9
- export declare const getAllTypes: () => Array<TemplateField>;
10
- export declare const getType: (xType: string) => TemplateField | undefined;
@@ -1,19 +0,0 @@
1
- const typeRegistry = new Map();
2
- /**
3
- * If type is not a default json schema type, it is treated as x-type.
4
- * E.g. "number" will define the default number field, whereas "address" will define a custom field
5
- */
6
- export const registerType = (name, title, schema, options, optionsRequired) => {
7
- if (typeRegistry.has(name)) {
8
- console.error("Tried to register duplicate name:", name);
9
- return;
10
- }
11
- const withXType = Object.assign({ "x-type": name }, schema);
12
- typeRegistry.set(name, { name, title, options, optionsRequired, schema: withXType });
13
- };
14
- export const getAllTypes = () => {
15
- return structuredClone([...typeRegistry.values()]);
16
- };
17
- export const getType = (xType) => {
18
- return structuredClone(typeRegistry.get(xType));
19
- };
@@ -1,5 +0,0 @@
1
- export declare enum ComponentPool {
2
- PRESENTATION = 0,
3
- FORM = 1
4
- }
5
- export type ComponentDataSchema = object;
@@ -1,5 +0,0 @@
1
- export var ComponentPool;
2
- (function (ComponentPool) {
3
- ComponentPool[ComponentPool["PRESENTATION"] = 0] = "PRESENTATION";
4
- ComponentPool[ComponentPool["FORM"] = 1] = "FORM";
5
- })(ComponentPool || (ComponentPool = {}));
@@ -1 +0,0 @@
1
- export {};
@@ -1,67 +0,0 @@
1
- 'use client';
2
- import React, { useEffect, useMemo, useState } from 'react';
3
- import { Paper, Typography, TextField, Grid, Divider } from '@mui/material';
4
- import { registerComponent } from '../registry/components';
5
- import { ComponentPool } from '../registry/types';
6
- const FormAddress = ({ data, onChange, enabled, label, postcodePattern }) => {
7
- var _a;
8
- const [postcodeInvalid, setPostcodeInvalid] = useState(false);
9
- const [postcodeHelperText, setPostcodeHelperText] = useState('');
10
- const validatePostcode = (value) => {
11
- if (!value)
12
- return true;
13
- const regex = new RegExp(postcodePattern || '^[A-Z]{1,2}[0-9][0-9A-Z]? ?[0-9][A-Z]{2}$', 'i');
14
- return regex.test(value);
15
- };
16
- const handlePostcodeChange = (value) => {
17
- const valid = validatePostcode(value);
18
- setPostcodeInvalid(!valid);
19
- setPostcodeHelperText(valid ? '' : 'Please enter a valid postcode (e.g., SW1A 1AA)');
20
- onChange('postcode', value);
21
- };
22
- const hasAddress = useMemo(() => !!(data.line1 || data.line2 || data.city || data.county || data.postcode), [data]);
23
- useEffect(() => {
24
- if (hasAddress) {
25
- console.log('Address updated:', data);
26
- }
27
- }, [hasAddress, data]);
28
- return (React.createElement(Paper, { sx: { display: 'flex', flexDirection: 'column', gap: 2, p: 2, mb: 1 }, component: "form", noValidate: true, autoComplete: "off" },
29
- React.createElement(Typography, { variant: "h6" }, label),
30
- React.createElement(Grid, { container: true, spacing: 2 },
31
- React.createElement(Grid, { item: true, xs: 12 },
32
- React.createElement(TextField, { fullWidth: true, label: "Address Line 1", value: data.line1 || '', onChange: (e) => onChange('line1', e.target.value), disabled: !enabled, required: true })),
33
- React.createElement(Grid, { item: true, xs: 12 },
34
- React.createElement(TextField, { fullWidth: true, label: "Address Line 2", value: data.line2 || '', onChange: (e) => onChange('line2', e.target.value), disabled: !enabled })),
35
- React.createElement(Grid, { item: true, xs: 12, sm: 6 },
36
- React.createElement(TextField, { fullWidth: true, label: "City", value: data.city || '', onChange: (e) => onChange('city', e.target.value), disabled: !enabled, required: true })),
37
- React.createElement(Grid, { item: true, xs: 12, sm: 6 },
38
- React.createElement(TextField, { fullWidth: true, label: "County", value: data.county || '', onChange: (e) => onChange('county', e.target.value), disabled: !enabled })),
39
- React.createElement(Grid, { item: true, xs: 12, sm: 6 },
40
- React.createElement(TextField, { fullWidth: true, label: "Postcode", value: data.postcode || '', onChange: (e) => handlePostcodeChange(e.target.value), error: postcodeInvalid, helperText: postcodeHelperText, disabled: !enabled, required: true })),
41
- React.createElement(Grid, { item: true, xs: 12, sm: 6 },
42
- React.createElement(TextField, { fullWidth: true, label: "Number", type: "number", value: (_a = data.number) !== null && _a !== void 0 ? _a : '', onChange: (e) => onChange('number', e.target.value === '' ? '' : Number(e.target.value)), disabled: !enabled }))),
43
- React.createElement(Divider, null),
44
- React.createElement(Typography, { variant: "subtitle1" }, "Location Preview"),
45
- React.createElement("div", { style: {
46
- height: '250px',
47
- display: 'flex',
48
- alignItems: 'center',
49
- justifyContent: 'center',
50
- border: '1px solid #ccc',
51
- borderRadius: '8px',
52
- fontSize: '0.9rem',
53
- color: '#777'
54
- } }, "[Map Placeholder]")));
55
- };
56
- const FormRendererAddress = ({ data, handleChange, path, enabled, label, schema }) => {
57
- var _a, _b;
58
- const safeData = data || {
59
- line1: '', line2: '', city: '', county: '', postcode: '', number: undefined
60
- };
61
- const postcodePattern = ((_b = (_a = schema === null || schema === void 0 ? void 0 : schema.properties) === null || _a === void 0 ? void 0 : _a.postcode) === null || _b === void 0 ? void 0 : _b.pattern) || undefined;
62
- const handleFieldChange = (key, value) => {
63
- handleChange(`${path}.${key}`, value);
64
- };
65
- return (React.createElement(FormAddress, { data: safeData, onChange: handleFieldChange, enabled: enabled, label: label, postcodePattern: postcodePattern }));
66
- };
67
- registerComponent("address", FormRendererAddress, ComponentPool.FORM);
@@ -1,19 +0,0 @@
1
- interface Component {
2
- id: string;
3
- name: string;
4
- templateId: string;
5
- revisionGroupId: string;
6
- revision: number;
7
- [key: string]: any;
8
- }
9
- export declare const fetchComponents: () => Promise<{
10
- data: {
11
- revisions: Component[];
12
- id: string;
13
- name: string;
14
- templateId: string;
15
- revisionGroupId: string;
16
- revision: number;
17
- }[];
18
- }>;
19
- export {};
@@ -1,68 +0,0 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- import React, { useEffect, useMemo, useState } from 'react';
11
- import { Paper, Typography, Box, TextField, Autocomplete } from '@mui/material';
12
- import { useLocalErrors } from '../hooks/errors';
13
- import { ComponentPool } from '../registry/types';
14
- import { registerComponent } from '../registry/components';
15
- import { BASE_API_URL } from '../api/consts';
16
- const FormComponentPicker = ({ components, selectedComponent, onChange, templateIds, getError, label, enabled }) => {
17
- const selected = components.find(c => c.id === selectedComponent) || null;
18
- return (React.createElement(Paper, { component: "form", sx: { display: 'flex', flexDirection: 'column', gap: 1, p: 2, mb: 1 }, noValidate: true, autoComplete: "off" },
19
- React.createElement(Typography, { variant: 'h6' }, label),
20
- React.createElement(Autocomplete, { options: components, getOptionLabel: (option) => option.name, value: selected, onChange: (_, newValue) => onChange(newValue ? newValue.id : null), renderInput: (params) => (React.createElement(TextField, Object.assign({}, params, { variant: "outlined", placeholder: "Search and select a component", disabled: !enabled }))), renderOption: (props, option) => (React.createElement("li", Object.assign({}, props),
21
- React.createElement(Box, null,
22
- React.createElement(Typography, { variant: "body1" }, option.name),
23
- React.createElement(Typography, { variant: "caption", color: "text.secondary" },
24
- "Version: v",
25
- option.revision)))), isOptionEqualToValue: (option, value) => option.id === value.id })));
26
- };
27
- const FormRendererComponentPicker = ({ data, handleChange, path, label, enabled, schema }) => {
28
- const [components, setComponents] = useState([]);
29
- const getError = useLocalErrors(path);
30
- const templateIds = useMemo(() =>
31
- // @ts-ignore
32
- schema['x-templateIds'] || [], [schema]);
33
- useEffect(() => {
34
- const load = () => __awaiter(void 0, void 0, void 0, function* () {
35
- try {
36
- const fetched = yield fetchComponents();
37
- let filtered = fetched.data;
38
- if (templateIds.length > 0) {
39
- filtered = filtered.filter(c => templateIds.includes(c.templateId));
40
- }
41
- setComponents(filtered);
42
- }
43
- catch (err) {
44
- console.error('Error loading components:', err);
45
- }
46
- });
47
- load();
48
- }, [templateIds]);
49
- return (React.createElement(FormComponentPicker, { components: components, selectedComponent: data || null, onChange: (id) => handleChange(path, id), templateIds: templateIds, getError: getError, label: label, enabled: enabled }));
50
- };
51
- registerComponent("component", FormRendererComponentPicker, ComponentPool.FORM);
52
- export const fetchComponents = () => __awaiter(void 0, void 0, void 0, function* () {
53
- const response = yield fetch(`${BASE_API_URL}/core-data-service/v1/components?limit=200`);
54
- const data = yield response.json();
55
- const componentsByGroup = new Map();
56
- (data.data || []).forEach((component) => {
57
- const groupId = component.revisionGroupId;
58
- if (!componentsByGroup.has(groupId)) {
59
- componentsByGroup.set(groupId, []);
60
- }
61
- componentsByGroup.get(groupId).push(component);
62
- });
63
- const latestComponents = Array.from(componentsByGroup.values()).map((components) => {
64
- const sortedComponents = components.sort((a, b) => b.revision - a.revision);
65
- return Object.assign(Object.assign({}, sortedComponents[0]), { revisions: sortedComponents });
66
- });
67
- return { data: latestComponents };
68
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,13 +0,0 @@
1
- import React from 'react';
2
- import { Paper, TextField, Typography } from '@mui/material';
3
- const FormDebug = ({ path, label }) => {
4
- return (React.createElement(Paper, { component: "form", sx: { display: 'flex', flexDirection: 'column', gap: 1, p: 2, background: "#CBC3E3", mb: 1 }, noValidate: true, autoComplete: "off" },
5
- React.createElement(Typography, { variant: 'h6' }, label),
6
- React.createElement(TextField, { label: "Path", value: path })));
7
- };
8
- const FormRendererDebug = ({ path, label }) => {
9
- return React.createElement(FormDebug, { label: label, path: path });
10
- };
11
- // Will render any components if they do not have a renderer, for testing
12
- //registerComponent("", FormRendererDebug, ComponentPool.FORM, () => 1)
13
- //registerComponent("", FormRendererDebug, ComponentPool.PRESENTATION, () => 1)
@@ -1 +0,0 @@
1
- export {};