@luomus/laji-form 15.1.60 → 15.1.62

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.
@@ -18,6 +18,7 @@ import IdService from "../services/id-service";
18
18
  import RootInstanceService from "../services/root-instance-service";
19
19
  import SingletonMapService from "../services/singleton-map-service";
20
20
  import { FieldProps, HasMaybeChildren, Lang } from "../types";
21
+ import MultiActiveArrayService from "../services/multi-active-array-service";
21
22
  export interface LajiFormProps extends HasMaybeChildren {
22
23
  apiClient?: ApiClientImplementation;
23
24
  lang?: Lang;
@@ -114,6 +115,7 @@ export interface FormContext {
114
115
  ids: IdService;
115
116
  rootInstance: RootInstanceService;
116
117
  singletonMap: SingletonMapService;
118
+ multiActiveArray: MultiActiveArrayService;
117
119
  };
118
120
  }
119
121
  export declare type NotifyMessager = (msg: string) => void;
@@ -212,9 +214,13 @@ export default class LajiForm extends React.Component<LajiFormProps, LajiFormSta
212
214
  };
213
215
  pushBlockingLoader: () => void;
214
216
  popBlockingLoader: () => void;
217
+ focusField: (fieldName: string) => void;
218
+ openAllMultiActiveArrays: () => void;
219
+ closeAllMultiActiveArrays: () => void;
215
220
  getSettings(global?: boolean): {};
216
221
  onSettingsChange: (settings: Settings, global?: boolean) => void;
217
222
  addEventListener: (target: typeof document | typeof window, name: string, fn: (e: Event) => void) => void;
218
223
  setTimeout: (fn: () => void, time?: number) => number;
219
224
  destroy: () => void;
225
+ getSchemaValidationErrors: (formData: any) => any;
220
226
  }
@@ -36,7 +36,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  const React = __importStar(require("react"));
37
37
  const react_dom_1 = require("react-dom");
38
38
  const PropTypes = __importStar(require("prop-types"));
39
- const validation_1 = __importDefault(require("../validation"));
39
+ const validation_1 = __importStar(require("../validation"));
40
40
  const validation_2 = require("../validation");
41
41
  const components_1 = require("./components");
42
42
  const utils_1 = require("../utils");
@@ -59,6 +59,7 @@ const dom_id_service_1 = __importDefault(require("../services/dom-id-service"));
59
59
  const id_service_1 = __importDefault(require("../services/id-service"));
60
60
  const root_instance_service_1 = __importDefault(require("../services/root-instance-service"));
61
61
  const singleton_map_service_1 = __importDefault(require("../services/singleton-map-service"));
62
+ const multi_active_array_service_1 = __importDefault(require("../services/multi-active-array-service"));
62
63
  const fields = importLocalComponents("fields", [
63
64
  "SchemaField",
64
65
  { "ArraySchemaField": "SchemaField" },
@@ -128,6 +129,7 @@ const fields = importLocalComponents("fields", [
128
129
  "PdfArrayField",
129
130
  "AsArrayField",
130
131
  "CondensedObjectField",
132
+ "MultiActiveArrayField",
131
133
  { "InputTransformerField": "ConditionalOnChangeField" },
132
134
  { "ConditionalField": "ConditionalUiSchemaField" },
133
135
  { "UnitRapidField": "UnitShorthandField" },
@@ -303,7 +305,7 @@ class LajiForm extends React.Component {
303
305
  liveValidations = {};
304
306
  }
305
307
  const schemaErrors = nonlive || onlySchema
306
- ? validator_ajv6_1.default.validateFormData(removeUndefinedFromArrays(formData), this.props.schema, undefined, ((e) => validation_2.transformErrors(this.state.formContext.translations, e))).errorSchema
308
+ ? this.getSchemaValidationErrors(formData)
307
309
  : {};
308
310
  block && this.memoizedFormContext.services.blocker.push();
309
311
  return new Promise(resolve => Promise.all([validation_1.default(validations, formData), validation_1.default(liveValidations, formData)]).then(([_validations, _liveValidations]) => {
@@ -444,6 +446,16 @@ class LajiForm extends React.Component {
444
446
  this.popBlockingLoader = () => {
445
447
  this.memoizedFormContext.services.blocker.pop();
446
448
  };
449
+ this.focusField = (fieldName) => {
450
+ const id = utils_1.JSONPointerToId(fieldName);
451
+ this.memoizedFormContext.services.focus.focus("root_" + id);
452
+ };
453
+ this.openAllMultiActiveArrays = () => {
454
+ this.memoizedFormContext.services.multiActiveArray.openAll();
455
+ };
456
+ this.closeAllMultiActiveArrays = () => {
457
+ this.memoizedFormContext.services.multiActiveArray.closeAll();
458
+ };
447
459
  this.onSettingsChange = (settings, global = false) => {
448
460
  if (this.props.onSettingsChange)
449
461
  this.props.onSettingsChange(settings, global);
@@ -468,6 +480,10 @@ class LajiForm extends React.Component {
468
480
  });
469
481
  this.eventListeners = [];
470
482
  };
483
+ this.getSchemaValidationErrors = (formData) => {
484
+ const errors = validator_ajv6_1.default.validateFormData(removeUndefinedFromArrays(formData), this.props.schema, undefined, ((e) => validation_2.transformErrors(this.state.formContext.translations, e))).errors;
485
+ return validation_1.toErrorSchema(errors);
486
+ };
471
487
  if (props.apiClient) {
472
488
  this.apiClient = new ApiClient_1.default(props.apiClient, props.lang, this.translations);
473
489
  }
@@ -535,6 +551,7 @@ class LajiForm extends React.Component {
535
551
  this.memoizedFormContext.services.ids = new id_service_1.default(props.schema, props.formData);
536
552
  this.memoizedFormContext.services.rootInstance = new root_instance_service_1.default(props.schema, props.formData, (formData) => this.onChange({ formData }), this.validate, () => this.validateAndSubmit(false));
537
553
  this.memoizedFormContext.services.singletonMap = new singleton_map_service_1.default();
554
+ this.memoizedFormContext.services.multiActiveArray = new multi_active_array_service_1.default();
538
555
  }
539
556
  return this.memoizedFormContext;
540
557
  }
@@ -156,7 +156,7 @@ class CondensedObjectField extends React.Component {
156
156
  React.createElement(SchemaField, Object.assign({}, this.props, props, { key: idx, onChange: this.onFieldChange(idx) }))),
157
157
  React.createElement("div", { className: "laji-form-field-template-buttons" },
158
158
  React.createElement(components_1.DeleteButton, { id: props.idSchema.$id, onClick: this.onFieldDelete(idx), translations: translations })))),
159
- React.createElement(SelectWidget_1.default, { key: childProps.length, options: { enumOptions: selectableFieldEnums, placeholder: addFieldPlaceholder }, onChange: this.onSelectFieldChange, includeEmpty: true, schema: {}, id: `${idSchema.$id}_field_select`, formContext: this.props.formContext })));
159
+ React.createElement(SelectWidget_1.default, { key: childProps.length, options: { enumOptions: selectableFieldEnums, placeholder: addFieldPlaceholder }, onChange: this.onSelectFieldChange, includeEmpty: true, schema: {}, id: `${idSchema.$id}_field_select`, formContext: this.props.formContext, disabled: this.props.disabled, readonly: this.props.readonly })));
160
160
  }
161
161
  }
162
162
  exports.default = CondensedObjectField;
@@ -0,0 +1,45 @@
1
+ import * as React from "react";
2
+ import { FieldProps, JSONSchemaObject } from "src/types";
3
+ import * as PropTypes from "prop-types";
4
+ interface State {
5
+ activeIdx: number[];
6
+ }
7
+ export default class MultiActiveArrayField extends React.Component<FieldProps<JSONSchemaObject>, State> {
8
+ static contextType: React.Context<import("../../ReactContext").ContextProps>;
9
+ static propTypes: {
10
+ uiSchema: PropTypes.Requireable<PropTypes.InferProps<{
11
+ "ui:options": PropTypes.Requireable<PropTypes.InferProps<{
12
+ renderer: PropTypes.Requireable<string>;
13
+ activeIdx: PropTypes.Requireable<(number | null | undefined)[]>;
14
+ }>>;
15
+ }>>;
16
+ schema: PropTypes.Validator<PropTypes.InferProps<{
17
+ type: PropTypes.Requireable<string>;
18
+ }>>;
19
+ formData: PropTypes.Requireable<any[]>;
20
+ };
21
+ deleteButtonRefs: {};
22
+ deleteButtonRefSetters: {};
23
+ constructor(props: FieldProps<JSONSchemaObject>);
24
+ getInitialActiveIdx: (props: FieldProps<JSONSchemaObject>) => number[];
25
+ getStateFromProps(props: FieldProps<JSONSchemaObject>): State | null;
26
+ render(): JSX.Element;
27
+ onActiveChange: (idx: number, prop?: string | undefined, callback?: (() => void) | undefined) => void;
28
+ onDelete: (item: any) => (e: any) => void;
29
+ buttonDefinitions: {
30
+ add: {
31
+ callback: () => void;
32
+ };
33
+ addPredefined: {
34
+ callback: () => void;
35
+ };
36
+ copy: {
37
+ fn: () => (...params: any[]) => void;
38
+ callback: () => void;
39
+ rules: {
40
+ minLength: number;
41
+ };
42
+ };
43
+ };
44
+ }
45
+ export {};
@@ -0,0 +1,152 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
15
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
16
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
17
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
18
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
19
+ };
20
+ var __importStar = (this && this.__importStar) || function (mod) {
21
+ if (mod && mod.__esModule) return mod;
22
+ var result = {};
23
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
24
+ __setModuleDefault(result, mod);
25
+ return result;
26
+ };
27
+ var __importDefault = (this && this.__importDefault) || function (mod) {
28
+ return (mod && mod.__esModule) ? mod : { "default": mod };
29
+ };
30
+ Object.defineProperty(exports, "__esModule", { value: true });
31
+ const BaseComponent_1 = __importDefault(require("../BaseComponent"));
32
+ const React = __importStar(require("react"));
33
+ const ReactContext_1 = __importDefault(require("../../ReactContext"));
34
+ const PropTypes = __importStar(require("prop-types"));
35
+ const utils_1 = require("../../utils");
36
+ const deepmerge_1 = __importDefault(require("deepmerge"));
37
+ const ArrayFieldTemplate_1 = require("../templates/ArrayFieldTemplate");
38
+ const ArrayField_1 = require("./ArrayField");
39
+ const SingleActiveArrayField_1 = require("./SingleActiveArrayField");
40
+ let MultiActiveArrayField = class MultiActiveArrayField extends React.Component {
41
+ constructor(props) {
42
+ super(props);
43
+ // these are required by the AccordionArrayFieldTemplate
44
+ this.deleteButtonRefs = {};
45
+ this.deleteButtonRefSetters = {};
46
+ this.getInitialActiveIdx = (props) => {
47
+ const { formData } = props;
48
+ const formDataLength = (formData || []).length;
49
+ return [...Array(formDataLength).keys()];
50
+ };
51
+ this.onActiveChange = (idx, prop, callback) => {
52
+ let newActiveIdx;
53
+ if (this.state.activeIdx.includes(idx)) {
54
+ newActiveIdx = this.state.activeIdx.filter(i => i !== idx);
55
+ }
56
+ else {
57
+ newActiveIdx = [...this.state.activeIdx, idx];
58
+ }
59
+ this.setState({ activeIdx: newActiveIdx }, callback);
60
+ };
61
+ this.onDelete = (item) => (e) => {
62
+ const idx = item.index;
63
+ const newActiveIdx = this.state.activeIdx.filter(i => i !== idx).map(i => i > idx ? i - 1 : i);
64
+ this.setState({ activeIdx: newActiveIdx });
65
+ item.onDropIndexClick(item.index)(e);
66
+ };
67
+ this.buttonDefinitions = {
68
+ add: {
69
+ callback: () => this.onActiveChange((this.props.formData || []).length)
70
+ },
71
+ addPredefined: {
72
+ callback: () => this.onActiveChange((this.props.formData || []).length)
73
+ },
74
+ copy: {
75
+ fn: () => (...params) => {
76
+ const { formData = [] } = this.props;
77
+ const idx = this.state.activeIdx.length > 0 ?
78
+ this.state.activeIdx[this.state.activeIdx.length - 1] :
79
+ formData.length - 1;
80
+ ArrayFieldTemplate_1.beforeAdd(this.props, idx + 1);
81
+ this.props.onChange([
82
+ ...formData.slice(0, idx + 1),
83
+ ArrayField_1.copyItemFunction(this, formData[idx])(...params),
84
+ ...formData.slice(idx + 1)
85
+ ]);
86
+ },
87
+ callback: () => {
88
+ const idx = this.state.activeIdx !== undefined ?
89
+ this.state.activeIdx[this.state.activeIdx.length - 1] :
90
+ (this.props.formData || []).length - 1;
91
+ this.onActiveChange(idx + 1);
92
+ },
93
+ rules: {
94
+ minLength: 1
95
+ }
96
+ }
97
+ };
98
+ this.deleteButtonRefs = {};
99
+ this.deleteButtonRefSetters = {};
100
+ this.state = Object.assign({ activeIdx: this.getInitialActiveIdx(props) }, this.getStateFromProps(props));
101
+ }
102
+ getStateFromProps(props) {
103
+ let activeIdx;
104
+ const options = utils_1.getUiOptions(props.uiSchema);
105
+ if ("activeIdx" in options) {
106
+ activeIdx = options.activeIdx;
107
+ }
108
+ else if ((props.formData || []).length > 0 && (this.props.formData || []).length === 0) {
109
+ activeIdx = [...Array((props.formData || []).length).keys()];
110
+ }
111
+ if (!activeIdx && this.props && props.idSchema.$id !== this.props.idSchema.$id) {
112
+ activeIdx = this.getInitialActiveIdx(props);
113
+ }
114
+ return activeIdx ? { activeIdx } : null;
115
+ }
116
+ render() {
117
+ const { renderer = "accordion" } = utils_1.getUiOptions(this.props.uiSchema);
118
+ let ArrayFieldTemplate = undefined;
119
+ switch (renderer) {
120
+ case "accordion":
121
+ ArrayFieldTemplate = SingleActiveArrayField_1.AccordionArrayFieldTemplate;
122
+ break;
123
+ default:
124
+ throw new Error(`Unknown renderer '${renderer}' for MultiActiveArrayField`);
125
+ }
126
+ const formContext = Object.assign(Object.assign({}, this.props.formContext), { this: this, activeIdx: this.state.activeIdx });
127
+ const { registry: { fields: { ArrayField } } } = this.props;
128
+ const { buttons = [], buttonDefinitions } = utils_1.getUiOptions(this.props.uiSchema);
129
+ let uiSchema = Object.assign(Object.assign({}, this.props.uiSchema), { "ui:field": undefined, "ui:classNames": undefined, "ui:options": Object.assign(Object.assign({}, utils_1.getUiOptions(this.props.uiSchema)), { buttons, buttonDefinitions: buttonDefinitions
130
+ ? deepmerge_1.default(this.buttonDefinitions, buttonDefinitions)
131
+ : this.buttonDefinitions }) });
132
+ uiSchema["ui:ArrayFieldTemplate"] = ArrayFieldTemplate;
133
+ return (React.createElement(ArrayField, Object.assign({}, this.props, { formContext: formContext, registry: Object.assign(Object.assign({}, this.props.registry), { formContext }), schema: this.props.schema, uiSchema: uiSchema, idSchema: this.props.idSchema, errorSchema: this.props.errorSchema, onChange: this.props.onChange, onBlur: this.props.onBlur, onFocus: this.props.onFocus, disabled: this.props.disabled, readonly: this.props.readonly, name: this.props.name })));
134
+ }
135
+ };
136
+ MultiActiveArrayField.contextType = ReactContext_1.default;
137
+ MultiActiveArrayField.propTypes = {
138
+ uiSchema: PropTypes.shape({
139
+ "ui:options": PropTypes.shape({
140
+ renderer: PropTypes.oneOf(["accordion"]),
141
+ activeIdx: PropTypes.arrayOf(PropTypes.number)
142
+ })
143
+ }),
144
+ schema: PropTypes.shape({
145
+ type: PropTypes.oneOf(["array"])
146
+ }).isRequired,
147
+ formData: PropTypes.array
148
+ };
149
+ MultiActiveArrayField = __decorate([
150
+ BaseComponent_1.default
151
+ ], MultiActiveArrayField);
152
+ exports.default = MultiActiveArrayField;
@@ -77,7 +77,7 @@ class _SchemaField extends React.Component {
77
77
  return Object.assign(Object.assign({}, _props), { uiSchema: Object.assign(Object.assign({}, _props.uiSchema), { "ui:functions": restUiFns }) });
78
78
  }
79
79
  render() {
80
- var _a;
80
+ var _a, _b;
81
81
  const props = this.applyFunction(this.props);
82
82
  let { schema, uiSchema = {}, formContext, registry } = props, _props = __rest(props, ["schema", "uiSchema", "formContext", "registry"]); // eslint-disable-line @typescript-eslint/no-unused-vars
83
83
  const { formContext: _formContext } = registry;
@@ -105,6 +105,11 @@ class _SchemaField extends React.Component {
105
105
  registry = Object.assign(Object.assign({}, registry), { formContext: Object.assign(Object.assign({}, _formContext), { formDataTransformers: filtered }) });
106
106
  }
107
107
  }
108
+ const idPointer = props.idSchema.$id ? utils_1.idSchemaIdToJSONPointer(props.idSchema.$id) : undefined;
109
+ if (idPointer && ((_b = _formContext.uiSchemaContext.additionalClassNames) === null || _b === void 0 ? void 0 : _b[idPointer])) {
110
+ const additionalClassNames = _formContext.uiSchemaContext.additionalClassNames[idPointer];
111
+ uiSchema = Object.assign(Object.assign({}, uiSchema), { "ui:classNames": utils_1.classNames(uiSchema["ui:classNames"], additionalClassNames) });
112
+ }
108
113
  const { SchemaField } = core_1.getDefaultRegistry().fields;
109
114
  return React.createElement(SchemaField, Object.assign({}, _props, { registry: registry, schema: schema, uiSchema: uiSchema }));
110
115
  }
@@ -26,7 +26,6 @@ export default class SingleActiveArrayField extends React.Component<any, any, an
26
26
  localContextKey: any;
27
27
  localContext: any;
28
28
  updateRenderingMode: (normalRendering: any, callback: any) => void;
29
- getPopupDataPromise: (idx: any, props: any, itemFormData: any) => Promise<any>;
30
29
  onActiveChange: (idx: any, prop: any, callback: any) => void;
31
30
  onDelete: (item: any) => (e: any) => void;
32
31
  buttonDefinitions: {
@@ -45,5 +44,14 @@ export default class SingleActiveArrayField extends React.Component<any, any, an
45
44
  };
46
45
  };
47
46
  }
47
+ export class AccordionArrayFieldTemplate extends React.Component<any, any, any> {
48
+ static contextType: React.Context<import("../../ReactContext").ContextProps>;
49
+ constructor(props: any);
50
+ constructor(props: any, context: any);
51
+ setHeaderRef: (elem: any) => void;
52
+ headerRef: any;
53
+ onSelect: (key: any) => void;
54
+ setDeleteButtonRef: (idx: any) => (elem: any) => void;
55
+ }
48
56
  import * as React from "react";
49
57
  import * as PropTypes from "prop-types";