@bpmn-io/form-js-viewer 0.10.0-alpha.3 → 0.10.1
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/LICENSE +22 -22
- package/README.md +165 -164
- package/dist/assets/flatpickr/light.css +809 -0
- package/dist/assets/form-js.css +611 -498
- package/dist/index.cjs +1493 -369
- package/dist/index.cjs.map +1 -1
- package/dist/index.es.js +1475 -372
- package/dist/index.es.js.map +1 -1
- package/dist/types/Form.d.ts +144 -144
- package/dist/types/core/ConditionChecker.d.ts +57 -57
- package/dist/types/core/EventBus.d.ts +1 -1
- package/dist/types/core/FormFieldRegistry.d.ts +17 -17
- package/dist/types/core/Validator.d.ts +7 -7
- package/dist/types/core/index.d.ts +18 -18
- package/dist/types/import/Importer.d.ts +43 -43
- package/dist/types/import/index.d.ts +5 -5
- package/dist/types/index.d.ts +18 -18
- package/dist/types/render/FormFields.d.ts +5 -5
- package/dist/types/render/Renderer.d.ts +23 -23
- package/dist/types/render/components/Description.d.ts +1 -1
- package/dist/types/render/components/Errors.d.ts +1 -1
- package/dist/types/render/components/FormComponent.d.ts +1 -1
- package/dist/types/render/components/FormField.d.ts +1 -1
- package/dist/types/render/components/Label.d.ts +1 -1
- package/dist/types/render/components/PoweredBy.d.ts +1 -1
- package/dist/types/render/components/Sanitizer.d.ts +8 -8
- package/dist/types/render/components/Util.d.ts +17 -19
- package/dist/types/render/components/form-fields/Button.d.ts +11 -11
- package/dist/types/render/components/form-fields/Checkbox.d.ts +13 -13
- package/dist/types/render/components/form-fields/Checklist.d.ts +12 -12
- package/dist/types/render/components/form-fields/Datetime.d.ts +11 -0
- package/dist/types/render/components/form-fields/Default.d.ts +9 -9
- package/dist/types/render/components/form-fields/Image.d.ts +8 -8
- package/dist/types/render/components/form-fields/Number.d.ts +14 -14
- package/dist/types/render/components/form-fields/Radio.d.ts +12 -12
- package/dist/types/render/components/form-fields/Select.d.ts +12 -12
- package/dist/types/render/components/form-fields/Taglist.d.ts +12 -12
- package/dist/types/render/components/form-fields/Text.d.ts +10 -10
- package/dist/types/render/components/form-fields/Textarea.d.ts +13 -13
- package/dist/types/render/components/form-fields/Textfield.d.ts +13 -13
- package/dist/types/render/components/form-fields/parts/Datepicker.d.ts +1 -0
- package/dist/types/render/components/form-fields/parts/DropdownList.d.ts +1 -1
- package/dist/types/render/components/form-fields/parts/InputAdorner.d.ts +1 -0
- package/dist/types/render/components/form-fields/parts/Timepicker.d.ts +1 -0
- package/dist/types/render/components/icons/index.d.ts +16 -0
- package/dist/types/render/components/index.d.ts +17 -15
- package/dist/types/render/components/util/dateTimeUtil.d.ts +12 -0
- package/dist/types/render/components/util/numberFieldUtil.d.ts +4 -4
- package/dist/types/render/components/util/sanitizerUtil.d.ts +3 -0
- package/dist/types/render/context/FormContext.d.ts +12 -12
- package/dist/types/render/context/FormRenderContext.d.ts +6 -6
- package/dist/types/render/context/index.d.ts +2 -2
- package/dist/types/render/hooks/useCondition.d.ts +9 -9
- package/dist/types/render/hooks/useEvaluation.d.ts +6 -6
- package/dist/types/render/hooks/useExpressionValue.d.ts +5 -5
- package/dist/types/render/hooks/useKeyDownAction.d.ts +1 -1
- package/dist/types/render/hooks/useService.d.ts +1 -1
- package/dist/types/render/hooks/useValuesAsync.d.ts +28 -28
- package/dist/types/render/index.d.ts +11 -11
- package/dist/types/src/types.d.ts +35 -35
- package/dist/types/util/constants/DatetimeConstants.d.ts +24 -0
- package/dist/types/util/constants/ValuesSourceConstants.d.ts +15 -0
- package/dist/types/util/constants/index.d.ts +2 -0
- package/dist/types/util/feel.d.ts +15 -14
- package/dist/types/util/form.d.ts +6 -6
- package/dist/types/util/index.d.ts +25 -24
- package/dist/types/util/injector.d.ts +2 -2
- package/package.json +4 -2
package/dist/index.cjs
CHANGED
|
@@ -12,6 +12,7 @@ var jsxRuntime = require('preact/jsx-runtime');
|
|
|
12
12
|
var hooks = require('preact/hooks');
|
|
13
13
|
var preact = require('preact');
|
|
14
14
|
var React = require('preact/compat');
|
|
15
|
+
var flatpickr = require('flatpickr');
|
|
15
16
|
var Markup = require('preact-markup');
|
|
16
17
|
var didi = require('didi');
|
|
17
18
|
|
|
@@ -22,11 +23,12 @@ var Big__default = /*#__PURE__*/_interopDefaultLegacy(Big);
|
|
|
22
23
|
var snarkdown__default = /*#__PURE__*/_interopDefaultLegacy(snarkdown);
|
|
23
24
|
var classNames__default = /*#__PURE__*/_interopDefaultLegacy(classNames);
|
|
24
25
|
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
|
|
26
|
+
var flatpickr__default = /*#__PURE__*/_interopDefaultLegacy(flatpickr);
|
|
25
27
|
var Markup__default = /*#__PURE__*/_interopDefaultLegacy(Markup);
|
|
26
28
|
|
|
27
|
-
/**
|
|
28
|
-
* @typedef {object} Condition
|
|
29
|
-
* @property {string} [hide]
|
|
29
|
+
/**
|
|
30
|
+
* @typedef {object} Condition
|
|
31
|
+
* @property {string} [hide]
|
|
30
32
|
*/
|
|
31
33
|
|
|
32
34
|
class ConditionChecker {
|
|
@@ -35,11 +37,11 @@ class ConditionChecker {
|
|
|
35
37
|
this._eventBus = eventBus;
|
|
36
38
|
}
|
|
37
39
|
|
|
38
|
-
/**
|
|
39
|
-
* For given data, remove properties based on condition.
|
|
40
|
-
*
|
|
41
|
-
* @param {Object<string, any>} properties
|
|
42
|
-
* @param {Object<string, any>} data
|
|
40
|
+
/**
|
|
41
|
+
* For given data, remove properties based on condition.
|
|
42
|
+
*
|
|
43
|
+
* @param {Object<string, any>} properties
|
|
44
|
+
* @param {Object<string, any>} data
|
|
43
45
|
*/
|
|
44
46
|
applyConditions(properties, data = {}) {
|
|
45
47
|
const conditions = this._getConditions();
|
|
@@ -58,13 +60,13 @@ class ConditionChecker {
|
|
|
58
60
|
return newProperties;
|
|
59
61
|
}
|
|
60
62
|
|
|
61
|
-
/**
|
|
62
|
-
* Check if given condition is met. Returns null for invalid/missing conditions.
|
|
63
|
-
*
|
|
64
|
-
* @param {string} condition
|
|
65
|
-
* @param {import('../types').Data} [data]
|
|
66
|
-
*
|
|
67
|
-
* @returns {boolean|null}
|
|
63
|
+
/**
|
|
64
|
+
* Check if given condition is met. Returns null for invalid/missing conditions.
|
|
65
|
+
*
|
|
66
|
+
* @param {string} condition
|
|
67
|
+
* @param {import('../types').Data} [data]
|
|
68
|
+
*
|
|
69
|
+
* @returns {boolean|null}
|
|
68
70
|
*/
|
|
69
71
|
check(condition, data = {}) {
|
|
70
72
|
if (!condition) {
|
|
@@ -85,12 +87,12 @@ class ConditionChecker {
|
|
|
85
87
|
}
|
|
86
88
|
}
|
|
87
89
|
|
|
88
|
-
/**
|
|
89
|
-
* Check if hide condition is met.
|
|
90
|
-
*
|
|
91
|
-
* @param {Condition} condition
|
|
92
|
-
* @param {Object<string, any>} data
|
|
93
|
-
* @returns {boolean}
|
|
90
|
+
/**
|
|
91
|
+
* Check if hide condition is met.
|
|
92
|
+
*
|
|
93
|
+
* @param {Condition} condition
|
|
94
|
+
* @param {Object<string, any>} data
|
|
95
|
+
* @returns {boolean}
|
|
94
96
|
*/
|
|
95
97
|
_checkHideCondition(condition, data) {
|
|
96
98
|
if (!condition.hide) {
|
|
@@ -100,13 +102,13 @@ class ConditionChecker {
|
|
|
100
102
|
return result === true;
|
|
101
103
|
}
|
|
102
104
|
|
|
103
|
-
/**
|
|
104
|
-
* Evaluate an expression.
|
|
105
|
-
*
|
|
106
|
-
* @param {string} expression
|
|
107
|
-
* @param {import('../types').Data} [data]
|
|
108
|
-
*
|
|
109
|
-
* @returns {any}
|
|
105
|
+
/**
|
|
106
|
+
* Evaluate an expression.
|
|
107
|
+
*
|
|
108
|
+
* @param {string} expression
|
|
109
|
+
* @param {import('../types').Data} [data]
|
|
110
|
+
*
|
|
111
|
+
* @returns {any}
|
|
110
112
|
*/
|
|
111
113
|
evaluate(expression, data = {}) {
|
|
112
114
|
if (!expression) {
|
|
@@ -715,11 +717,11 @@ class FormFieldRegistry {
|
|
|
715
717
|
}
|
|
716
718
|
FormFieldRegistry.$inject = ['eventBus'];
|
|
717
719
|
|
|
718
|
-
/**
|
|
719
|
-
* Retrieve variable names from given FEEL unary test.
|
|
720
|
-
*
|
|
721
|
-
* @param {string} unaryTest
|
|
722
|
-
* @returns {string[]}
|
|
720
|
+
/**
|
|
721
|
+
* Retrieve variable names from given FEEL unary test.
|
|
722
|
+
*
|
|
723
|
+
* @param {string} unaryTest
|
|
724
|
+
* @returns {string[]}
|
|
723
725
|
*/
|
|
724
726
|
function getVariableNames(unaryTest) {
|
|
725
727
|
const tree = feelin.parseUnaryTests(unaryTest);
|
|
@@ -734,11 +736,11 @@ function getVariableNames(unaryTest) {
|
|
|
734
736
|
return Array.from(variables);
|
|
735
737
|
}
|
|
736
738
|
|
|
737
|
-
/**
|
|
738
|
-
* Retrieve variable names from given FEEL expression.
|
|
739
|
-
*
|
|
740
|
-
* @param {string} expression
|
|
741
|
-
* @returns {string[]}
|
|
739
|
+
/**
|
|
740
|
+
* Retrieve variable names from given FEEL expression.
|
|
741
|
+
*
|
|
742
|
+
* @param {string} expression
|
|
743
|
+
* @returns {string[]}
|
|
742
744
|
*/
|
|
743
745
|
function getExpressionVariableNames(expression) {
|
|
744
746
|
const tree = feelin.parseExpressions(expression);
|
|
@@ -752,6 +754,71 @@ function getExpressionVariableNames(expression) {
|
|
|
752
754
|
} while (cursor.next());
|
|
753
755
|
return Array.from(variables);
|
|
754
756
|
}
|
|
757
|
+
function isExpression$2(value) {
|
|
758
|
+
return minDash.isString(value) && value.startsWith('=');
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
// config ///////////////////
|
|
762
|
+
|
|
763
|
+
const MINUTES_IN_DAY = 60 * 24;
|
|
764
|
+
const DATETIME_SUBTYPES = {
|
|
765
|
+
DATE: 'date',
|
|
766
|
+
TIME: 'time',
|
|
767
|
+
DATETIME: 'datetime'
|
|
768
|
+
};
|
|
769
|
+
const TIME_SERIALISING_FORMATS = {
|
|
770
|
+
UTC_OFFSET: 'utc_offset',
|
|
771
|
+
UTC_NORMALIZED: 'utc_normalized',
|
|
772
|
+
NO_TIMEZONE: 'no_timezone'
|
|
773
|
+
};
|
|
774
|
+
const DATETIME_SUBTYPES_LABELS = {
|
|
775
|
+
[DATETIME_SUBTYPES.DATE]: 'Date',
|
|
776
|
+
[DATETIME_SUBTYPES.TIME]: 'Time',
|
|
777
|
+
[DATETIME_SUBTYPES.DATETIME]: 'Date & Time'
|
|
778
|
+
};
|
|
779
|
+
const TIME_SERIALISINGFORMAT_LABELS = {
|
|
780
|
+
[TIME_SERIALISING_FORMATS.UTC_OFFSET]: 'UTC offset',
|
|
781
|
+
[TIME_SERIALISING_FORMATS.UTC_NORMALIZED]: 'UTC normalized',
|
|
782
|
+
[TIME_SERIALISING_FORMATS.NO_TIMEZONE]: 'No timezone'
|
|
783
|
+
};
|
|
784
|
+
const DATETIME_SUBTYPE_PATH = ['subtype'];
|
|
785
|
+
const DATE_LABEL_PATH = ['dateLabel'];
|
|
786
|
+
const DATE_DISALLOW_PAST_PATH = ['disallowPassedDates'];
|
|
787
|
+
const TIME_LABEL_PATH = ['timeLabel'];
|
|
788
|
+
const TIME_USE24H_PATH = ['use24h'];
|
|
789
|
+
const TIME_INTERVAL_PATH = ['timeInterval'];
|
|
790
|
+
const TIME_SERIALISING_FORMAT_PATH = ['timeSerializingFormat'];
|
|
791
|
+
|
|
792
|
+
// config ///////////////////
|
|
793
|
+
|
|
794
|
+
const VALUES_SOURCES = {
|
|
795
|
+
STATIC: 'static',
|
|
796
|
+
INPUT: 'input'
|
|
797
|
+
};
|
|
798
|
+
const VALUES_SOURCE_DEFAULT = VALUES_SOURCES.STATIC;
|
|
799
|
+
const VALUES_SOURCES_LABELS = {
|
|
800
|
+
[VALUES_SOURCES.STATIC]: 'Static',
|
|
801
|
+
[VALUES_SOURCES.INPUT]: 'Input data'
|
|
802
|
+
};
|
|
803
|
+
const VALUES_SOURCES_PATHS = {
|
|
804
|
+
[VALUES_SOURCES.STATIC]: ['values'],
|
|
805
|
+
[VALUES_SOURCES.INPUT]: ['valuesKey']
|
|
806
|
+
};
|
|
807
|
+
const VALUES_SOURCES_DEFAULTS = {
|
|
808
|
+
[VALUES_SOURCES.STATIC]: [],
|
|
809
|
+
[VALUES_SOURCES.INPUT]: ''
|
|
810
|
+
};
|
|
811
|
+
|
|
812
|
+
// helpers ///////////////////
|
|
813
|
+
|
|
814
|
+
function getValuesSource(field) {
|
|
815
|
+
for (const source of Object.values(VALUES_SOURCES)) {
|
|
816
|
+
if (minDash.get(field, VALUES_SOURCES_PATHS[source]) !== undefined) {
|
|
817
|
+
return source;
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
return VALUES_SOURCE_DEFAULT;
|
|
821
|
+
}
|
|
755
822
|
|
|
756
823
|
function createInjector(bootstrapModules) {
|
|
757
824
|
const injector = new didi.Injector(bootstrapModules);
|
|
@@ -759,10 +826,10 @@ function createInjector(bootstrapModules) {
|
|
|
759
826
|
return injector;
|
|
760
827
|
}
|
|
761
828
|
|
|
762
|
-
/**
|
|
763
|
-
* @param {string?} prefix
|
|
764
|
-
*
|
|
765
|
-
* @returns Element
|
|
829
|
+
/**
|
|
830
|
+
* @param {string?} prefix
|
|
831
|
+
*
|
|
832
|
+
* @returns Element
|
|
766
833
|
*/
|
|
767
834
|
function createFormContainer(prefix = 'fjs') {
|
|
768
835
|
const container = document.createElement('div');
|
|
@@ -770,7 +837,7 @@ function createFormContainer(prefix = 'fjs') {
|
|
|
770
837
|
return container;
|
|
771
838
|
}
|
|
772
839
|
|
|
773
|
-
const EXPRESSION_PROPERTIES = ['alt', 'source'];
|
|
840
|
+
const EXPRESSION_PROPERTIES = ['alt', 'source', 'text'];
|
|
774
841
|
function findErrors(errors, path) {
|
|
775
842
|
return errors[pathStringify(path)];
|
|
776
843
|
}
|
|
@@ -807,22 +874,22 @@ function generateIdForType(type) {
|
|
|
807
874
|
return `${type}${generateIndexForType(type)}`;
|
|
808
875
|
}
|
|
809
876
|
|
|
810
|
-
/**
|
|
811
|
-
* @template T
|
|
812
|
-
* @param {T} data
|
|
813
|
-
* @param {(this: any, key: string, value: any) => any} [replacer]
|
|
814
|
-
* @return {T}
|
|
877
|
+
/**
|
|
878
|
+
* @template T
|
|
879
|
+
* @param {T} data
|
|
880
|
+
* @param {(this: any, key: string, value: any) => any} [replacer]
|
|
881
|
+
* @return {T}
|
|
815
882
|
*/
|
|
816
883
|
function clone(data, replacer) {
|
|
817
884
|
return JSON.parse(JSON.stringify(data, replacer));
|
|
818
885
|
}
|
|
819
886
|
|
|
820
|
-
/**
|
|
821
|
-
* Parse the schema for input variables a form might make use of
|
|
822
|
-
*
|
|
823
|
-
* @param {any} schema
|
|
824
|
-
*
|
|
825
|
-
* @return {string[]}
|
|
887
|
+
/**
|
|
888
|
+
* Parse the schema for input variables a form might make use of
|
|
889
|
+
*
|
|
890
|
+
* @param {any} schema
|
|
891
|
+
*
|
|
892
|
+
* @return {string[]}
|
|
826
893
|
*/
|
|
827
894
|
function getSchemaVariables(schema) {
|
|
828
895
|
if (!schema.components) {
|
|
@@ -835,7 +902,7 @@ function getSchemaVariables(schema) {
|
|
|
835
902
|
type,
|
|
836
903
|
conditional
|
|
837
904
|
} = component;
|
|
838
|
-
if (['
|
|
905
|
+
if (['button'].includes(type)) {
|
|
839
906
|
return variables;
|
|
840
907
|
}
|
|
841
908
|
if (key) {
|
|
@@ -871,25 +938,25 @@ function isExpression$1(value) {
|
|
|
871
938
|
}
|
|
872
939
|
|
|
873
940
|
class Importer {
|
|
874
|
-
/**
|
|
875
|
-
* @constructor
|
|
876
|
-
* @param { import('../core').FormFieldRegistry } formFieldRegistry
|
|
877
|
-
* @param { import('../render/FormFields').default } formFields
|
|
941
|
+
/**
|
|
942
|
+
* @constructor
|
|
943
|
+
* @param { import('../core').FormFieldRegistry } formFieldRegistry
|
|
944
|
+
* @param { import('../render/FormFields').default } formFields
|
|
878
945
|
*/
|
|
879
946
|
constructor(formFieldRegistry, formFields) {
|
|
880
947
|
this._formFieldRegistry = formFieldRegistry;
|
|
881
948
|
this._formFields = formFields;
|
|
882
949
|
}
|
|
883
950
|
|
|
884
|
-
/**
|
|
885
|
-
* Import schema adding `id`, `_parent` and `_path`
|
|
886
|
-
* information to each field and adding it to the
|
|
887
|
-
* form field registry.
|
|
888
|
-
*
|
|
889
|
-
* @param {any} schema
|
|
890
|
-
* @param {any} [data]
|
|
891
|
-
*
|
|
892
|
-
* @return { { warnings: Array<any>, schema: any, data: any } }
|
|
951
|
+
/**
|
|
952
|
+
* Import schema adding `id`, `_parent` and `_path`
|
|
953
|
+
* information to each field and adding it to the
|
|
954
|
+
* form field registry.
|
|
955
|
+
*
|
|
956
|
+
* @param {any} schema
|
|
957
|
+
* @param {any} [data]
|
|
958
|
+
*
|
|
959
|
+
* @return { { warnings: Array<any>, schema: any, data: any } }
|
|
893
960
|
*/
|
|
894
961
|
importSchema(schema, data = {}) {
|
|
895
962
|
// TODO: Add warnings - https://github.com/bpmn-io/form-js/issues/289
|
|
@@ -908,11 +975,11 @@ class Importer {
|
|
|
908
975
|
}
|
|
909
976
|
}
|
|
910
977
|
|
|
911
|
-
/**
|
|
912
|
-
* @param {any} formField
|
|
913
|
-
* @param {string} [parentId]
|
|
914
|
-
*
|
|
915
|
-
* @return {any} importedField
|
|
978
|
+
/**
|
|
979
|
+
* @param {any} formField
|
|
980
|
+
* @param {string} [parentId]
|
|
981
|
+
*
|
|
982
|
+
* @return {any} importedField
|
|
916
983
|
*/
|
|
917
984
|
importFormField(formField, parentId) {
|
|
918
985
|
const {
|
|
@@ -963,10 +1030,10 @@ class Importer {
|
|
|
963
1030
|
});
|
|
964
1031
|
}
|
|
965
1032
|
|
|
966
|
-
/**
|
|
967
|
-
* @param {Object} data
|
|
968
|
-
*
|
|
969
|
-
* @return {Object} initializedData
|
|
1033
|
+
/**
|
|
1034
|
+
* @param {Object} data
|
|
1035
|
+
*
|
|
1036
|
+
* @return {Object} initializedData
|
|
970
1037
|
*/
|
|
971
1038
|
initializeFieldValues(data) {
|
|
972
1039
|
return this._formFieldRegistry.getAll().reduce((initializedData, formField) => {
|
|
@@ -1008,7 +1075,7 @@ var importModule = {
|
|
|
1008
1075
|
|
|
1009
1076
|
const NODE_TYPE_TEXT = 3,
|
|
1010
1077
|
NODE_TYPE_ELEMENT = 1;
|
|
1011
|
-
const ALLOWED_NODES = ['h1', 'h2', 'h3', 'h4', 'h5', 'span', 'em', 'a', 'p', 'div', 'ul', 'ol', 'li', 'hr', 'blockquote', 'img', 'pre', 'code', 'br', 'strong'];
|
|
1078
|
+
const ALLOWED_NODES = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'span', 'em', 'a', 'p', 'div', 'ul', 'ol', 'li', 'hr', 'blockquote', 'img', 'pre', 'code', 'br', 'strong'];
|
|
1012
1079
|
const ALLOWED_ATTRIBUTES = ['align', 'alt', 'class', 'href', 'id', 'name', 'rel', 'target', 'src'];
|
|
1013
1080
|
const ALLOWED_URI_PATTERN = /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i; // eslint-disable-line no-useless-escape
|
|
1014
1081
|
const ALLOWED_IMAGE_SRC_PATTERN = /^(https?|data):.*/i; // eslint-disable-line no-useless-escape
|
|
@@ -1016,11 +1083,11 @@ const ATTR_WHITESPACE_PATTERN = /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u
|
|
|
1016
1083
|
|
|
1017
1084
|
const FORM_ELEMENT = document.createElement('form');
|
|
1018
1085
|
|
|
1019
|
-
/**
|
|
1020
|
-
* Sanitize a HTML string and return the cleaned, safe version.
|
|
1021
|
-
*
|
|
1022
|
-
* @param {string} html
|
|
1023
|
-
* @return {string}
|
|
1086
|
+
/**
|
|
1087
|
+
* Sanitize a HTML string and return the cleaned, safe version.
|
|
1088
|
+
*
|
|
1089
|
+
* @param {string} html
|
|
1090
|
+
* @return {string}
|
|
1024
1091
|
*/
|
|
1025
1092
|
function sanitizeHTML(html) {
|
|
1026
1093
|
const doc = new DOMParser().parseFromString(`<!DOCTYPE html>\n<html><body><div>${html}`, 'text/html');
|
|
@@ -1040,15 +1107,15 @@ function sanitizeImageSource(src) {
|
|
|
1040
1107
|
return valid ? src : '';
|
|
1041
1108
|
}
|
|
1042
1109
|
|
|
1043
|
-
/**
|
|
1044
|
-
* Recursively sanitize a HTML node, potentially
|
|
1045
|
-
* removing it, its children or attributes.
|
|
1046
|
-
*
|
|
1047
|
-
* Inspired by https://github.com/developit/snarkdown/issues/70
|
|
1048
|
-
* and https://github.com/cure53/DOMPurify. Simplified
|
|
1049
|
-
* for our use-case.
|
|
1050
|
-
*
|
|
1051
|
-
* @param {Element} node
|
|
1110
|
+
/**
|
|
1111
|
+
* Recursively sanitize a HTML node, potentially
|
|
1112
|
+
* removing it, its children or attributes.
|
|
1113
|
+
*
|
|
1114
|
+
* Inspired by https://github.com/developit/snarkdown/issues/70
|
|
1115
|
+
* and https://github.com/cure53/DOMPurify. Simplified
|
|
1116
|
+
* for our use-case.
|
|
1117
|
+
*
|
|
1118
|
+
* @param {Element} node
|
|
1052
1119
|
*/
|
|
1053
1120
|
function sanitizeNode(node) {
|
|
1054
1121
|
// allow text nodes
|
|
@@ -1092,13 +1159,13 @@ function sanitizeNode(node) {
|
|
|
1092
1159
|
}
|
|
1093
1160
|
}
|
|
1094
1161
|
|
|
1095
|
-
/**
|
|
1096
|
-
* Validates attributes for validity.
|
|
1097
|
-
*
|
|
1098
|
-
* @param {string} lcTag
|
|
1099
|
-
* @param {string} lcName
|
|
1100
|
-
* @param {string} value
|
|
1101
|
-
* @return {boolean}
|
|
1162
|
+
/**
|
|
1163
|
+
* Validates attributes for validity.
|
|
1164
|
+
*
|
|
1165
|
+
* @param {string} lcTag
|
|
1166
|
+
* @param {string} lcName
|
|
1167
|
+
* @param {string} value
|
|
1168
|
+
* @return {boolean}
|
|
1102
1169
|
*/
|
|
1103
1170
|
function isValidAttribute(lcTag, lcName, value) {
|
|
1104
1171
|
// disallow most attributes based on whitelist
|
|
@@ -1140,7 +1207,7 @@ function prefixId(id, formId) {
|
|
|
1140
1207
|
return `fjs-form-${id}`;
|
|
1141
1208
|
}
|
|
1142
1209
|
function markdownToHTML(markdown) {
|
|
1143
|
-
const htmls = markdown.split(/(?:\r?\n){2,}/).map(line => /^((\d+.)|[><\s#-*])/.test(line) ? snarkdown__default['default'](line) : `<p>${snarkdown__default['default'](line)}</p>`);
|
|
1210
|
+
const htmls = markdown.toString().split(/(?:\r?\n){2,}/).map(line => /^((\d+.)|[><\s#-*])/.test(line) ? snarkdown__default['default'](line) : `<p>${snarkdown__default['default'](line)}</p>`);
|
|
1144
1211
|
return htmls.join('\n\n');
|
|
1145
1212
|
}
|
|
1146
1213
|
|
|
@@ -1150,58 +1217,20 @@ function safeMarkdown(markdown) {
|
|
|
1150
1217
|
return sanitizeHTML(html);
|
|
1151
1218
|
}
|
|
1152
1219
|
|
|
1153
|
-
/**
|
|
1154
|
-
* Sanitizes an image source to ensure we only allow for data URI and links
|
|
1155
|
-
* that start with http(s).
|
|
1156
|
-
*
|
|
1157
|
-
* Note: Most browsers anyway do not support script execution in <img> elements.
|
|
1158
|
-
*
|
|
1159
|
-
* @param {string} src
|
|
1160
|
-
* @returns {string}
|
|
1220
|
+
/**
|
|
1221
|
+
* Sanitizes an image source to ensure we only allow for data URI and links
|
|
1222
|
+
* that start with http(s).
|
|
1223
|
+
*
|
|
1224
|
+
* Note: Most browsers anyway do not support script execution in <img> elements.
|
|
1225
|
+
*
|
|
1226
|
+
* @param {string} src
|
|
1227
|
+
* @returns {string}
|
|
1161
1228
|
*/
|
|
1162
1229
|
function safeImageSource(src) {
|
|
1163
1230
|
return sanitizeImageSource(src);
|
|
1164
1231
|
}
|
|
1165
|
-
function sanitizeSingleSelectValue(options) {
|
|
1166
|
-
const {
|
|
1167
|
-
formField,
|
|
1168
|
-
data,
|
|
1169
|
-
value
|
|
1170
|
-
} = options;
|
|
1171
|
-
const {
|
|
1172
|
-
valuesKey,
|
|
1173
|
-
values
|
|
1174
|
-
} = formField;
|
|
1175
|
-
try {
|
|
1176
|
-
const validValues = (valuesKey ? minDash.get(data, [valuesKey]) : values).map(v => v.value) || [];
|
|
1177
|
-
return validValues.includes(value) ? value : null;
|
|
1178
|
-
} catch (error) {
|
|
1179
|
-
// use default value in case of formatting error
|
|
1180
|
-
// TODO(@Skaiir): log a warning when this happens - https://github.com/bpmn-io/form-js/issues/289
|
|
1181
|
-
return null;
|
|
1182
|
-
}
|
|
1183
|
-
}
|
|
1184
|
-
function sanitizeMultiSelectValue(options) {
|
|
1185
|
-
const {
|
|
1186
|
-
formField,
|
|
1187
|
-
data,
|
|
1188
|
-
value
|
|
1189
|
-
} = options;
|
|
1190
|
-
const {
|
|
1191
|
-
valuesKey,
|
|
1192
|
-
values
|
|
1193
|
-
} = formField;
|
|
1194
|
-
try {
|
|
1195
|
-
const validValues = (valuesKey ? minDash.get(data, [valuesKey]) : values).map(v => v.value) || [];
|
|
1196
|
-
return value.filter(v => validValues.includes(v));
|
|
1197
|
-
} catch (error) {
|
|
1198
|
-
// use default value in case of formatting error
|
|
1199
|
-
// TODO(@Skaiir): log a warning when this happens - https://github.com/bpmn-io/form-js/issues/289
|
|
1200
|
-
return [];
|
|
1201
|
-
}
|
|
1202
|
-
}
|
|
1203
1232
|
|
|
1204
|
-
const type$
|
|
1233
|
+
const type$b = 'button';
|
|
1205
1234
|
function Button(props) {
|
|
1206
1235
|
const {
|
|
1207
1236
|
disabled,
|
|
@@ -1211,7 +1240,7 @@ function Button(props) {
|
|
|
1211
1240
|
action = 'submit'
|
|
1212
1241
|
} = field;
|
|
1213
1242
|
return jsxRuntime.jsx("div", {
|
|
1214
|
-
class: formFieldClasses(type$
|
|
1243
|
+
class: formFieldClasses(type$b),
|
|
1215
1244
|
children: jsxRuntime.jsx("button", {
|
|
1216
1245
|
class: "fjs-button",
|
|
1217
1246
|
type: action,
|
|
@@ -1226,7 +1255,7 @@ Button.create = function (options = {}) {
|
|
|
1226
1255
|
...options
|
|
1227
1256
|
};
|
|
1228
1257
|
};
|
|
1229
|
-
Button.type = type$
|
|
1258
|
+
Button.type = type$b;
|
|
1230
1259
|
Button.label = 'Button';
|
|
1231
1260
|
Button.keyed = true;
|
|
1232
1261
|
|
|
@@ -1242,11 +1271,11 @@ const FormRenderContext = preact.createContext({
|
|
|
1242
1271
|
}
|
|
1243
1272
|
});
|
|
1244
1273
|
|
|
1245
|
-
/**
|
|
1246
|
-
* @param {string} type
|
|
1247
|
-
* @param {boolean} [strict]
|
|
1248
|
-
*
|
|
1249
|
-
* @returns {any}
|
|
1274
|
+
/**
|
|
1275
|
+
* @param {string} type
|
|
1276
|
+
* @param {boolean} [strict]
|
|
1277
|
+
*
|
|
1278
|
+
* @returns {any}
|
|
1250
1279
|
*/
|
|
1251
1280
|
function getService(type, strict) {}
|
|
1252
1281
|
const FormContext = preact.createContext({
|
|
@@ -1290,11 +1319,14 @@ function Label(props) {
|
|
|
1290
1319
|
const {
|
|
1291
1320
|
id,
|
|
1292
1321
|
label,
|
|
1322
|
+
collapseOnEmpty = true,
|
|
1293
1323
|
required = false
|
|
1294
1324
|
} = props;
|
|
1295
1325
|
return jsxRuntime.jsxs("label", {
|
|
1296
1326
|
for: id,
|
|
1297
|
-
class: classNames__default['default']('fjs-form-field-label',
|
|
1327
|
+
class: classNames__default['default']('fjs-form-field-label', {
|
|
1328
|
+
'fjs-incollapsible-label': !collapseOnEmpty
|
|
1329
|
+
}, props['class']),
|
|
1298
1330
|
children: [props.children, label || '', required && jsxRuntime.jsx("span", {
|
|
1299
1331
|
class: "fjs-asterix",
|
|
1300
1332
|
children: "*"
|
|
@@ -1302,7 +1334,7 @@ function Label(props) {
|
|
|
1302
1334
|
});
|
|
1303
1335
|
}
|
|
1304
1336
|
|
|
1305
|
-
const type$
|
|
1337
|
+
const type$a = 'checkbox';
|
|
1306
1338
|
function Checkbox(props) {
|
|
1307
1339
|
const {
|
|
1308
1340
|
disabled,
|
|
@@ -1327,7 +1359,7 @@ function Checkbox(props) {
|
|
|
1327
1359
|
formId
|
|
1328
1360
|
} = hooks.useContext(FormContext);
|
|
1329
1361
|
return jsxRuntime.jsxs("div", {
|
|
1330
|
-
class: classNames__default['default'](formFieldClasses(type$
|
|
1362
|
+
class: classNames__default['default'](formFieldClasses(type$a, {
|
|
1331
1363
|
errors,
|
|
1332
1364
|
disabled
|
|
1333
1365
|
}), {
|
|
@@ -1357,7 +1389,7 @@ Checkbox.create = function (options = {}) {
|
|
|
1357
1389
|
...options
|
|
1358
1390
|
};
|
|
1359
1391
|
};
|
|
1360
|
-
Checkbox.type = type$
|
|
1392
|
+
Checkbox.type = type$a;
|
|
1361
1393
|
Checkbox.label = 'Checkbox';
|
|
1362
1394
|
Checkbox.keyed = true;
|
|
1363
1395
|
Checkbox.emptyValue = false;
|
|
@@ -1372,8 +1404,8 @@ function useService (type, strict) {
|
|
|
1372
1404
|
return getService(type, strict);
|
|
1373
1405
|
}
|
|
1374
1406
|
|
|
1375
|
-
/**
|
|
1376
|
-
* @enum { String }
|
|
1407
|
+
/**
|
|
1408
|
+
* @enum { String }
|
|
1377
1409
|
*/
|
|
1378
1410
|
const LOAD_STATES = {
|
|
1379
1411
|
LOADING: 'loading',
|
|
@@ -1381,17 +1413,17 @@ const LOAD_STATES = {
|
|
|
1381
1413
|
ERROR: 'error'
|
|
1382
1414
|
};
|
|
1383
1415
|
|
|
1384
|
-
/**
|
|
1385
|
-
* @typedef {Object} ValuesGetter
|
|
1386
|
-
* @property {Object[]} values - The values data
|
|
1387
|
-
* @property {(LOAD_STATES)} state - The values data's loading state, to use for conditional rendering
|
|
1416
|
+
/**
|
|
1417
|
+
* @typedef {Object} ValuesGetter
|
|
1418
|
+
* @property {Object[]} values - The values data
|
|
1419
|
+
* @property {(LOAD_STATES)} state - The values data's loading state, to use for conditional rendering
|
|
1388
1420
|
*/
|
|
1389
1421
|
|
|
1390
|
-
/**
|
|
1391
|
-
* A hook to load values for single and multiselect components.
|
|
1392
|
-
*
|
|
1393
|
-
* @param {Object} field - The form field to handle values for
|
|
1394
|
-
* @return {ValuesGetter} valuesGetter - A values getter object providing loading state and values
|
|
1422
|
+
/**
|
|
1423
|
+
* A hook to load values for single and multiselect components.
|
|
1424
|
+
*
|
|
1425
|
+
* @param {Object} field - The form field to handle values for
|
|
1426
|
+
* @return {ValuesGetter} valuesGetter - A values getter object providing loading state and values
|
|
1395
1427
|
*/
|
|
1396
1428
|
function useValuesAsync (field) {
|
|
1397
1429
|
const {
|
|
@@ -1432,7 +1464,222 @@ const buildLoadedState = values => ({
|
|
|
1432
1464
|
state: LOAD_STATES.LOADED
|
|
1433
1465
|
});
|
|
1434
1466
|
|
|
1435
|
-
const
|
|
1467
|
+
const ENTER_KEYDOWN_EVENT = new KeyboardEvent('keydown', {
|
|
1468
|
+
code: 'Enter',
|
|
1469
|
+
key: 'Enter',
|
|
1470
|
+
charCode: 13,
|
|
1471
|
+
keyCode: 13,
|
|
1472
|
+
view: window,
|
|
1473
|
+
bubbles: true
|
|
1474
|
+
});
|
|
1475
|
+
function focusRelevantFlatpickerDay(flatpickrInstance) {
|
|
1476
|
+
if (!flatpickrInstance) return;
|
|
1477
|
+
!flatpickrInstance.isOpen && flatpickrInstance.open();
|
|
1478
|
+
const container = flatpickrInstance.calendarContainer;
|
|
1479
|
+
const dayToFocus = container.querySelector('.flatpickr-day.selected') || container.querySelector('.flatpickr-day.today') || container.querySelector('.flatpickr-day');
|
|
1480
|
+
dayToFocus && dayToFocus.focus();
|
|
1481
|
+
}
|
|
1482
|
+
function formatTime(use24h, minutes) {
|
|
1483
|
+
if (minutes === null) return null;
|
|
1484
|
+
const wrappedMinutes = minutes % (24 * 60);
|
|
1485
|
+
const minute = minutes % 60;
|
|
1486
|
+
let hour = Math.floor(wrappedMinutes / 60);
|
|
1487
|
+
if (use24h) {
|
|
1488
|
+
return _getZeroPaddedString(hour) + ':' + _getZeroPaddedString(minute);
|
|
1489
|
+
}
|
|
1490
|
+
hour = hour % 12 || 12;
|
|
1491
|
+
const isPM = wrappedMinutes >= 12 * 60;
|
|
1492
|
+
return _getZeroPaddedString(hour) + ':' + _getZeroPaddedString(minute) + ' ' + (isPM ? 'PM' : 'AM');
|
|
1493
|
+
}
|
|
1494
|
+
function parseInputTime(stringTime) {
|
|
1495
|
+
let workingString = stringTime.toLowerCase();
|
|
1496
|
+
const is12h = workingString.includes('am') || workingString.includes('pm');
|
|
1497
|
+
if (is12h) {
|
|
1498
|
+
const isPM = workingString.includes('pm');
|
|
1499
|
+
const digits = workingString.match(/\d+/g);
|
|
1500
|
+
const displayHour = parseInt(digits?.[0]);
|
|
1501
|
+
const minute = parseInt(digits?.[1]) || 0;
|
|
1502
|
+
const isValidDisplayHour = minDash.isNumber(displayHour) && displayHour >= 1 && displayHour <= 12;
|
|
1503
|
+
const isValidMinute = minute >= 0 && minute <= 59;
|
|
1504
|
+
if (!isValidDisplayHour || !isValidMinute) return null;
|
|
1505
|
+
const hour = displayHour % 12 + (isPM ? 12 : 0);
|
|
1506
|
+
return hour * 60 + minute;
|
|
1507
|
+
} else {
|
|
1508
|
+
const digits = workingString.match(/\d+/g);
|
|
1509
|
+
const hour = parseInt(digits?.[0]);
|
|
1510
|
+
const minute = parseInt(digits?.[1]);
|
|
1511
|
+
const isValidHour = minDash.isNumber(hour) && hour >= 0 && hour <= 23;
|
|
1512
|
+
const isValidMinute = minDash.isNumber(minute) && minute >= 0 && minute <= 59;
|
|
1513
|
+
if (!isValidHour || !isValidMinute) return null;
|
|
1514
|
+
return hour * 60 + minute;
|
|
1515
|
+
}
|
|
1516
|
+
}
|
|
1517
|
+
function serializeTime(minutes, offset, timeSerializingFormat) {
|
|
1518
|
+
if (timeSerializingFormat === TIME_SERIALISING_FORMATS.UTC_NORMALIZED) {
|
|
1519
|
+
const normalizedMinutes = (minutes + offset + MINUTES_IN_DAY) % MINUTES_IN_DAY;
|
|
1520
|
+
return _getZeroPaddedString(Math.floor(normalizedMinutes / 60)) + ':' + _getZeroPaddedString(normalizedMinutes % 60) + 'Z';
|
|
1521
|
+
}
|
|
1522
|
+
const baseTime = _getZeroPaddedString(Math.floor(minutes / 60)) + ':' + _getZeroPaddedString(minutes % 60);
|
|
1523
|
+
const addUTCOffset = timeSerializingFormat === TIME_SERIALISING_FORMATS.UTC_OFFSET;
|
|
1524
|
+
return baseTime + (addUTCOffset ? formatTimezoneOffset(offset) : '');
|
|
1525
|
+
}
|
|
1526
|
+
function parseIsoTime(isoTimeString) {
|
|
1527
|
+
if (!isoTimeString) return null;
|
|
1528
|
+
const parseBasicMinutes = timeString => {
|
|
1529
|
+
const timeSegments = timeString.split(':');
|
|
1530
|
+
const hour = parseInt(timeSegments[0]);
|
|
1531
|
+
const minute = timeSegments.length > 1 ? parseInt(timeSegments[1]) : 0;
|
|
1532
|
+
if (isNaN(hour) || hour < 0 || hour > 24 || isNaN(minute) || minute < 0 || minute > 60) return null;
|
|
1533
|
+
return hour * 60 + minute;
|
|
1534
|
+
};
|
|
1535
|
+
const localOffset = new Date().getTimezoneOffset();
|
|
1536
|
+
|
|
1537
|
+
// Parse normalized time
|
|
1538
|
+
if (isoTimeString.includes('Z')) {
|
|
1539
|
+
isoTimeString = isoTimeString.replace('Z', '');
|
|
1540
|
+
const minutes = parseBasicMinutes(isoTimeString);
|
|
1541
|
+
if (minutes === null) return null;
|
|
1542
|
+
return (minutes - localOffset + MINUTES_IN_DAY) % MINUTES_IN_DAY;
|
|
1543
|
+
}
|
|
1544
|
+
|
|
1545
|
+
// Parse offset positive time
|
|
1546
|
+
else if (isoTimeString.includes('+')) {
|
|
1547
|
+
const [timeString, offsetString] = isoTimeString.split('+');
|
|
1548
|
+
const minutes = parseBasicMinutes(timeString);
|
|
1549
|
+
let inboundOffset = parseBasicMinutes(offsetString);
|
|
1550
|
+
if (minutes === null || inboundOffset === null) return null;
|
|
1551
|
+
|
|
1552
|
+
// The offset is flipped for consistency with javascript
|
|
1553
|
+
inboundOffset = -inboundOffset;
|
|
1554
|
+
return (minutes + inboundOffset - localOffset + MINUTES_IN_DAY) % MINUTES_IN_DAY;
|
|
1555
|
+
}
|
|
1556
|
+
|
|
1557
|
+
// Parse offset negative time
|
|
1558
|
+
else if (isoTimeString.includes('-')) {
|
|
1559
|
+
const [timeString, offsetString] = isoTimeString.split('-');
|
|
1560
|
+
const minutes = parseBasicMinutes(timeString);
|
|
1561
|
+
let inboundOffset = parseBasicMinutes(offsetString);
|
|
1562
|
+
if (minutes === null || inboundOffset === null) return null;
|
|
1563
|
+
return (minutes + inboundOffset - localOffset + MINUTES_IN_DAY) % MINUTES_IN_DAY;
|
|
1564
|
+
}
|
|
1565
|
+
|
|
1566
|
+
// Default to local parsing
|
|
1567
|
+
else {
|
|
1568
|
+
return parseBasicMinutes(isoTimeString);
|
|
1569
|
+
}
|
|
1570
|
+
}
|
|
1571
|
+
function serializeDate(date) {
|
|
1572
|
+
var d = new Date(date),
|
|
1573
|
+
month = '' + (d.getMonth() + 1),
|
|
1574
|
+
day = '' + d.getDate(),
|
|
1575
|
+
year = d.getFullYear();
|
|
1576
|
+
if (month.length < 2) month = '0' + month;
|
|
1577
|
+
if (day.length < 2) day = '0' + day;
|
|
1578
|
+
return [year, month, day].join('-');
|
|
1579
|
+
}
|
|
1580
|
+
|
|
1581
|
+
// this method is used to make the `new Date(value)` parsing behavior stricter
|
|
1582
|
+
function isDateTimeInputInformationSufficient(value) {
|
|
1583
|
+
if (!value || typeof value !== 'string') return false;
|
|
1584
|
+
const segments = value.split('T');
|
|
1585
|
+
if (segments.length != 2) return false;
|
|
1586
|
+
const dateNumbers = segments[0].split('-');
|
|
1587
|
+
if (dateNumbers.length != 3) return false;
|
|
1588
|
+
return true;
|
|
1589
|
+
}
|
|
1590
|
+
|
|
1591
|
+
// this method checks if the date isn't a datetime, or a partial date
|
|
1592
|
+
function isDateInputInformationMatching(value) {
|
|
1593
|
+
if (!value || typeof value !== 'string') return false;
|
|
1594
|
+
if (value.includes('T')) return false;
|
|
1595
|
+
const dateNumbers = value.split('-');
|
|
1596
|
+
if (dateNumbers.length != 3) return false;
|
|
1597
|
+
return true;
|
|
1598
|
+
}
|
|
1599
|
+
function serializeDateTime(date, time, timeSerializingFormat) {
|
|
1600
|
+
const workingDate = new Date();
|
|
1601
|
+
workingDate.setFullYear(date.getFullYear(), date.getMonth(), date.getDate());
|
|
1602
|
+
workingDate.setHours(Math.floor(time / 60), time % 60, 0, 0);
|
|
1603
|
+
if (timeSerializingFormat === TIME_SERIALISING_FORMATS.UTC_NORMALIZED) {
|
|
1604
|
+
const timezoneOffsetMinutes = workingDate.getTimezoneOffset();
|
|
1605
|
+
const dayOffset = time + timezoneOffsetMinutes < 0 ? -1 : time + timezoneOffsetMinutes > MINUTES_IN_DAY ? 1 : 0;
|
|
1606
|
+
|
|
1607
|
+
// Apply the date rollover pre-emptively
|
|
1608
|
+
workingDate.setHours(workingDate.getHours() + dayOffset * 24);
|
|
1609
|
+
}
|
|
1610
|
+
return serializeDate(workingDate) + 'T' + serializeTime(time, workingDate.getTimezoneOffset(), timeSerializingFormat);
|
|
1611
|
+
}
|
|
1612
|
+
function formatTimezoneOffset(minutes) {
|
|
1613
|
+
return _getSignedPaddedHours(minutes) + ':' + _getZeroPaddedString(Math.abs(minutes % 60));
|
|
1614
|
+
}
|
|
1615
|
+
function isInvalidDateString(value) {
|
|
1616
|
+
return isNaN(new Date(Date.parse(value)).getTime());
|
|
1617
|
+
}
|
|
1618
|
+
function _getSignedPaddedHours(minutes) {
|
|
1619
|
+
if (minutes > 0) {
|
|
1620
|
+
return '-' + _getZeroPaddedString(Math.floor(minutes / 60));
|
|
1621
|
+
} else {
|
|
1622
|
+
return '+' + _getZeroPaddedString(Math.floor((0 - minutes) / 60));
|
|
1623
|
+
}
|
|
1624
|
+
}
|
|
1625
|
+
function _getZeroPaddedString(time) {
|
|
1626
|
+
return time.toString().padStart(2, '0');
|
|
1627
|
+
}
|
|
1628
|
+
|
|
1629
|
+
function sanitizeDateTimePickerValue(options) {
|
|
1630
|
+
const {
|
|
1631
|
+
formField,
|
|
1632
|
+
value
|
|
1633
|
+
} = options;
|
|
1634
|
+
const {
|
|
1635
|
+
subtype
|
|
1636
|
+
} = formField;
|
|
1637
|
+
if (typeof value !== 'string') return null;
|
|
1638
|
+
if (subtype === DATETIME_SUBTYPES.DATE && (isInvalidDateString(value) || !isDateInputInformationMatching(value))) return null;
|
|
1639
|
+
if (subtype === DATETIME_SUBTYPES.TIME && parseIsoTime(value) === null) return null;
|
|
1640
|
+
if (subtype === DATETIME_SUBTYPES.DATETIME && (isInvalidDateString(value) || !isDateTimeInputInformationSufficient(value))) return null;
|
|
1641
|
+
return value;
|
|
1642
|
+
}
|
|
1643
|
+
function sanitizeSingleSelectValue(options) {
|
|
1644
|
+
const {
|
|
1645
|
+
formField,
|
|
1646
|
+
data,
|
|
1647
|
+
value
|
|
1648
|
+
} = options;
|
|
1649
|
+
const {
|
|
1650
|
+
valuesKey,
|
|
1651
|
+
values
|
|
1652
|
+
} = formField;
|
|
1653
|
+
try {
|
|
1654
|
+
const validValues = (valuesKey ? minDash.get(data, [valuesKey]) : values).map(v => v.value) || [];
|
|
1655
|
+
return validValues.includes(value) ? value : null;
|
|
1656
|
+
} catch (error) {
|
|
1657
|
+
// use default value in case of formatting error
|
|
1658
|
+
// TODO(@Skaiir): log a warning when this happens - https://github.com/bpmn-io/form-js/issues/289
|
|
1659
|
+
return null;
|
|
1660
|
+
}
|
|
1661
|
+
}
|
|
1662
|
+
function sanitizeMultiSelectValue(options) {
|
|
1663
|
+
const {
|
|
1664
|
+
formField,
|
|
1665
|
+
data,
|
|
1666
|
+
value
|
|
1667
|
+
} = options;
|
|
1668
|
+
const {
|
|
1669
|
+
valuesKey,
|
|
1670
|
+
values
|
|
1671
|
+
} = formField;
|
|
1672
|
+
try {
|
|
1673
|
+
const validValues = (valuesKey ? minDash.get(data, [valuesKey]) : values).map(v => v.value) || [];
|
|
1674
|
+
return value.filter(v => validValues.includes(v));
|
|
1675
|
+
} catch (error) {
|
|
1676
|
+
// use default value in case of formatting error
|
|
1677
|
+
// TODO(@Skaiir): log a warning when this happens - https://github.com/bpmn-io/form-js/issues/289
|
|
1678
|
+
return [];
|
|
1679
|
+
}
|
|
1680
|
+
}
|
|
1681
|
+
|
|
1682
|
+
const type$9 = 'checklist';
|
|
1436
1683
|
function Checklist(props) {
|
|
1437
1684
|
const {
|
|
1438
1685
|
disabled,
|
|
@@ -1465,7 +1712,7 @@ function Checklist(props) {
|
|
|
1465
1712
|
formId
|
|
1466
1713
|
} = hooks.useContext(FormContext);
|
|
1467
1714
|
return jsxRuntime.jsxs("div", {
|
|
1468
|
-
class: classNames__default['default'](formFieldClasses(type$
|
|
1715
|
+
class: classNames__default['default'](formFieldClasses(type$9, {
|
|
1469
1716
|
errors,
|
|
1470
1717
|
disabled
|
|
1471
1718
|
})),
|
|
@@ -1505,26 +1752,33 @@ Checklist.create = function (options = {}) {
|
|
|
1505
1752
|
...options
|
|
1506
1753
|
};
|
|
1507
1754
|
};
|
|
1508
|
-
Checklist.type = type$
|
|
1755
|
+
Checklist.type = type$9;
|
|
1509
1756
|
Checklist.label = 'Checklist';
|
|
1510
1757
|
Checklist.keyed = true;
|
|
1511
1758
|
Checklist.emptyValue = [];
|
|
1512
1759
|
Checklist.sanitizeValue = sanitizeMultiSelectValue;
|
|
1513
1760
|
|
|
1514
|
-
/**
|
|
1515
|
-
* Check if condition is met with given variables.
|
|
1516
|
-
*
|
|
1517
|
-
* @param {string | undefined} condition
|
|
1518
|
-
* @param {import('../../types').Data} data
|
|
1519
|
-
*
|
|
1520
|
-
* @returns {boolean} true if condition is met or no condition or condition checker exists
|
|
1761
|
+
/**
|
|
1762
|
+
* Check if condition is met with given variables.
|
|
1763
|
+
*
|
|
1764
|
+
* @param {string | undefined} condition
|
|
1765
|
+
* @param {import('../../types').Data} data
|
|
1766
|
+
*
|
|
1767
|
+
* @returns {boolean} true if condition is met or no condition or condition checker exists
|
|
1521
1768
|
*/
|
|
1522
1769
|
function useCondition(condition, data) {
|
|
1770
|
+
const initialData = useService('form')._getState().initialData;
|
|
1523
1771
|
const conditionChecker = useService('conditionChecker', false);
|
|
1524
1772
|
if (!conditionChecker) {
|
|
1525
1773
|
return null;
|
|
1526
1774
|
}
|
|
1527
|
-
|
|
1775
|
+
|
|
1776
|
+
// make sure we do not use data from hidden fields
|
|
1777
|
+
const filteredData = {
|
|
1778
|
+
...initialData,
|
|
1779
|
+
...conditionChecker.applyConditions(data, data)
|
|
1780
|
+
};
|
|
1781
|
+
return conditionChecker.check(condition, filteredData);
|
|
1528
1782
|
}
|
|
1529
1783
|
|
|
1530
1784
|
const noop$1 = () => false;
|
|
@@ -1606,32 +1860,688 @@ Default.create = function (options = {}) {
|
|
|
1606
1860
|
Default.type = 'default';
|
|
1607
1861
|
Default.keyed = false;
|
|
1608
1862
|
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
*/
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1863
|
+
function _extends$h() { _extends$h = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$h.apply(this, arguments); }
|
|
1864
|
+
var CalendarIcon = (({
|
|
1865
|
+
styles = {},
|
|
1866
|
+
...props
|
|
1867
|
+
}) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$h({
|
|
1868
|
+
width: "14",
|
|
1869
|
+
height: "15",
|
|
1870
|
+
viewBox: "0 0 28 30",
|
|
1871
|
+
fill: "none",
|
|
1872
|
+
xmlns: "http://www.w3.org/2000/svg"
|
|
1873
|
+
}, props), /*#__PURE__*/React__default['default'].createElement("path", {
|
|
1874
|
+
fillRule: "evenodd",
|
|
1875
|
+
clipRule: "evenodd",
|
|
1876
|
+
d: "M19 2H9V0H7v2H2a2 2 0 00-2 2v24a2 2 0 002 2h24a2 2 0 002-2V4a2 2 0 00-2-2h-5V0h-2v2zM7 7V4H2v5h24V4h-5v3h-2V4H9v3H7zm-5 4v17h24V11H2z",
|
|
1877
|
+
fill: "#000"
|
|
1878
|
+
})));
|
|
1879
|
+
|
|
1880
|
+
function InputAdorner(props) {
|
|
1881
|
+
const {
|
|
1882
|
+
pre = null,
|
|
1883
|
+
post = null,
|
|
1884
|
+
rootRef,
|
|
1885
|
+
inputRef,
|
|
1886
|
+
children,
|
|
1887
|
+
disabled,
|
|
1888
|
+
hasErrors
|
|
1889
|
+
} = props;
|
|
1890
|
+
const onAdornmentClick = () => inputRef?.current?.focus();
|
|
1891
|
+
return jsxRuntime.jsxs("div", {
|
|
1892
|
+
class: classNames__default['default']('fjs-input-group', {
|
|
1893
|
+
'disabled': disabled
|
|
1894
|
+
}, {
|
|
1895
|
+
'hasErrors': hasErrors
|
|
1896
|
+
}),
|
|
1897
|
+
ref: rootRef,
|
|
1898
|
+
children: [pre !== null && jsxRuntime.jsxs("span", {
|
|
1899
|
+
class: "fjs-input-adornment border-right border-radius-left",
|
|
1900
|
+
onClick: onAdornmentClick,
|
|
1901
|
+
children: [" ", pre, " "]
|
|
1902
|
+
}), children, post !== null && jsxRuntime.jsxs("span", {
|
|
1903
|
+
class: "fjs-input-adornment border-left border-radius-right",
|
|
1904
|
+
onClick: onAdornmentClick,
|
|
1905
|
+
children: [" ", post, " "]
|
|
1627
1906
|
})]
|
|
1628
1907
|
});
|
|
1629
1908
|
}
|
|
1630
|
-
|
|
1909
|
+
|
|
1910
|
+
function Datepicker(props) {
|
|
1631
1911
|
const {
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1912
|
+
id,
|
|
1913
|
+
label,
|
|
1914
|
+
collapseLabelOnEmpty,
|
|
1915
|
+
formId,
|
|
1916
|
+
required,
|
|
1917
|
+
disabled,
|
|
1918
|
+
disallowPassedDates,
|
|
1919
|
+
date,
|
|
1920
|
+
setDate
|
|
1921
|
+
} = props;
|
|
1922
|
+
const dateInputRef = hooks.useRef();
|
|
1923
|
+
const focusScopeRef = hooks.useRef();
|
|
1924
|
+
const [flatpickrInstance, setFlatpickrInstance] = hooks.useState(null);
|
|
1925
|
+
const [isInputDirty, setIsInputDirty] = hooks.useState(false);
|
|
1926
|
+
const [forceFocusCalendar, setForceFocusCalendar] = hooks.useState(false);
|
|
1927
|
+
|
|
1928
|
+
// shorts the date value back to the source
|
|
1929
|
+
hooks.useEffect(() => {
|
|
1930
|
+
if (!flatpickrInstance || !flatpickrInstance.config) return;
|
|
1931
|
+
flatpickrInstance.setDate(date, true);
|
|
1932
|
+
setIsInputDirty(false);
|
|
1933
|
+
}, [flatpickrInstance, date.toString()]);
|
|
1934
|
+
hooks.useEffect(() => {
|
|
1935
|
+
if (!forceFocusCalendar) return;
|
|
1936
|
+
focusRelevantFlatpickerDay(flatpickrInstance);
|
|
1937
|
+
setForceFocusCalendar(false);
|
|
1938
|
+
}, [flatpickrInstance, forceFocusCalendar]);
|
|
1939
|
+
|
|
1940
|
+
// setup flatpickr instance
|
|
1941
|
+
hooks.useEffect(() => {
|
|
1942
|
+
if (disabled) {
|
|
1943
|
+
setFlatpickrInstance(null);
|
|
1944
|
+
return;
|
|
1945
|
+
}
|
|
1946
|
+
let config = {
|
|
1947
|
+
allowInput: true,
|
|
1948
|
+
dateFormat: 'm/d/Y',
|
|
1949
|
+
static: true,
|
|
1950
|
+
clickOpens: false,
|
|
1951
|
+
errorHandler: () => {/* do nothing, we expect the values to sometimes be erronous and we don't want warnings polluting the console */}
|
|
1952
|
+
};
|
|
1953
|
+
if (disallowPassedDates) {
|
|
1954
|
+
config = {
|
|
1955
|
+
...config,
|
|
1956
|
+
minDate: 'today'
|
|
1957
|
+
};
|
|
1958
|
+
}
|
|
1959
|
+
const instance = flatpickr__default['default'](dateInputRef.current, config);
|
|
1960
|
+
setFlatpickrInstance(instance);
|
|
1961
|
+
const onCalendarFocusOut = e => {
|
|
1962
|
+
if (!instance.calendarContainer.contains(e.relatedTarget) && e.relatedTarget != dateInputRef.current) {
|
|
1963
|
+
instance.close();
|
|
1964
|
+
}
|
|
1965
|
+
};
|
|
1966
|
+
|
|
1967
|
+
// remove dirty tag to have mouse day selection prioritize input blur
|
|
1968
|
+
const onCalendarMouseDown = e => {
|
|
1969
|
+
if (e.target.classList.contains('flatpickr-day')) {
|
|
1970
|
+
setIsInputDirty(false);
|
|
1971
|
+
}
|
|
1972
|
+
};
|
|
1973
|
+
|
|
1974
|
+
// when the dropdown of the datepickr opens, we register a few event handlers to re-implement some of the
|
|
1975
|
+
// flatpicker logic that was lost when setting allowInput to true
|
|
1976
|
+
instance.config.onOpen = [() => instance.calendarContainer.addEventListener('focusout', onCalendarFocusOut), () => instance.calendarContainer.addEventListener('mousedown', onCalendarMouseDown)];
|
|
1977
|
+
instance.config.onClose = [() => instance.calendarContainer.removeEventListener('focusout', onCalendarFocusOut), () => instance.calendarContainer.removeEventListener('mousedown', onCalendarMouseDown)];
|
|
1978
|
+
}, [disabled, disallowPassedDates]);
|
|
1979
|
+
|
|
1980
|
+
// onChange is updated dynamically, so not to re-render the flatpicker every time it changes
|
|
1981
|
+
hooks.useEffect(() => {
|
|
1982
|
+
if (!flatpickrInstance || !flatpickrInstance.config) return;
|
|
1983
|
+
flatpickrInstance.config.onChange = [date => setDate(new Date(date)), () => setIsInputDirty(false)];
|
|
1984
|
+
}, [flatpickrInstance, setDate]);
|
|
1985
|
+
const onInputKeyDown = hooks.useCallback(e => {
|
|
1986
|
+
if (!flatpickrInstance) return;
|
|
1987
|
+
if (e.code === 'Escape') {
|
|
1988
|
+
flatpickrInstance.close();
|
|
1989
|
+
}
|
|
1990
|
+
if (e.code === 'ArrowDown') {
|
|
1991
|
+
if (isInputDirty) {
|
|
1992
|
+
// trigger an enter keypress to submit the new input, then focus calendar day on the next render cycle
|
|
1993
|
+
dateInputRef.current.dispatchEvent(ENTER_KEYDOWN_EVENT);
|
|
1994
|
+
setIsInputDirty(false);
|
|
1995
|
+
setForceFocusCalendar(true);
|
|
1996
|
+
} else {
|
|
1997
|
+
// focus calendar day immediately
|
|
1998
|
+
focusRelevantFlatpickerDay(flatpickrInstance);
|
|
1999
|
+
}
|
|
2000
|
+
e.preventDefault();
|
|
2001
|
+
}
|
|
2002
|
+
if (e.code === 'Enter') {
|
|
2003
|
+
setIsInputDirty(false);
|
|
2004
|
+
}
|
|
2005
|
+
}, [flatpickrInstance, isInputDirty]);
|
|
2006
|
+
const onInputFocus = hooks.useCallback(e => {
|
|
2007
|
+
if (!flatpickrInstance || focusScopeRef.current.contains(e.relatedTarget)) return;
|
|
2008
|
+
flatpickrInstance.open();
|
|
2009
|
+
}, [flatpickrInstance]);
|
|
2010
|
+
|
|
2011
|
+
// simulate an enter press on blur to make sure the date value is submitted in all scenarios
|
|
2012
|
+
const onInputBlur = hooks.useCallback(e => {
|
|
2013
|
+
if (!isInputDirty || e.relatedTarget && e.relatedTarget.classList.contains('flatpickr-day')) return;
|
|
2014
|
+
dateInputRef.current.dispatchEvent(ENTER_KEYDOWN_EVENT);
|
|
2015
|
+
setIsInputDirty(false);
|
|
2016
|
+
}, [isInputDirty]);
|
|
2017
|
+
const fullId = `${prefixId(id, formId)}--date`;
|
|
2018
|
+
return jsxRuntime.jsxs("div", {
|
|
2019
|
+
class: "fjs-datetime-subsection",
|
|
2020
|
+
children: [jsxRuntime.jsx(Label, {
|
|
2021
|
+
id: fullId,
|
|
2022
|
+
label: label,
|
|
2023
|
+
collapseOnEmpty: collapseLabelOnEmpty,
|
|
2024
|
+
required: required
|
|
2025
|
+
}), jsxRuntime.jsx(InputAdorner, {
|
|
2026
|
+
pre: jsxRuntime.jsx(CalendarIcon, {}),
|
|
2027
|
+
disabled: disabled,
|
|
2028
|
+
rootRef: focusScopeRef,
|
|
2029
|
+
inputRef: dateInputRef,
|
|
2030
|
+
children: jsxRuntime.jsx("div", {
|
|
2031
|
+
class: "fjs-datepicker",
|
|
2032
|
+
style: {
|
|
2033
|
+
width: '100%'
|
|
2034
|
+
},
|
|
2035
|
+
children: jsxRuntime.jsx("input", {
|
|
2036
|
+
ref: dateInputRef,
|
|
2037
|
+
type: "text",
|
|
2038
|
+
id: fullId,
|
|
2039
|
+
class: 'fjs-input',
|
|
2040
|
+
disabled: disabled,
|
|
2041
|
+
placeholder: "mm/dd/yyyy",
|
|
2042
|
+
autoComplete: "false",
|
|
2043
|
+
onFocus: onInputFocus,
|
|
2044
|
+
onKeyDown: onInputKeyDown,
|
|
2045
|
+
onMouseDown: e => !flatpickrInstance.isOpen && flatpickrInstance.open(),
|
|
2046
|
+
onBlur: onInputBlur,
|
|
2047
|
+
onInput: e => setIsInputDirty(true),
|
|
2048
|
+
"data-input": true
|
|
2049
|
+
})
|
|
2050
|
+
})
|
|
2051
|
+
})]
|
|
2052
|
+
});
|
|
2053
|
+
}
|
|
2054
|
+
|
|
2055
|
+
function _extends$g() { _extends$g = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$g.apply(this, arguments); }
|
|
2056
|
+
var ClockIcon = (({
|
|
2057
|
+
styles = {},
|
|
2058
|
+
...props
|
|
2059
|
+
}) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$g({
|
|
2060
|
+
width: "16",
|
|
2061
|
+
height: "16",
|
|
2062
|
+
viewBox: "0 0 28 29",
|
|
2063
|
+
fill: "none",
|
|
2064
|
+
xmlns: "http://www.w3.org/2000/svg"
|
|
2065
|
+
}, props), /*#__PURE__*/React__default['default'].createElement("path", {
|
|
2066
|
+
d: "M13 14.41L18.59 20 20 18.59l-5-5.01V5h-2v9.41z",
|
|
2067
|
+
fill: "#000"
|
|
2068
|
+
}), /*#__PURE__*/React__default['default'].createElement("path", {
|
|
2069
|
+
fillRule: "evenodd",
|
|
2070
|
+
clipRule: "evenodd",
|
|
2071
|
+
d: "M6.222 25.64A14 14 0 1021.778 2.36 14 14 0 006.222 25.64zM7.333 4.023a12 12 0 1113.334 19.955A12 12 0 017.333 4.022z",
|
|
2072
|
+
fill: "#000"
|
|
2073
|
+
})));
|
|
2074
|
+
|
|
2075
|
+
function useKeyDownAction(targetKey, action, listenerElement = window) {
|
|
2076
|
+
function downHandler({
|
|
2077
|
+
key
|
|
2078
|
+
}) {
|
|
2079
|
+
if (key === targetKey) {
|
|
2080
|
+
action();
|
|
2081
|
+
}
|
|
2082
|
+
}
|
|
2083
|
+
hooks.useEffect(() => {
|
|
2084
|
+
listenerElement.addEventListener('keydown', downHandler);
|
|
2085
|
+
return () => {
|
|
2086
|
+
listenerElement.removeEventListener('keydown', downHandler);
|
|
2087
|
+
};
|
|
2088
|
+
});
|
|
2089
|
+
}
|
|
2090
|
+
|
|
2091
|
+
const DEFAULT_LABEL_GETTER = value => value;
|
|
2092
|
+
const NOOP = () => {};
|
|
2093
|
+
function DropdownList(props) {
|
|
2094
|
+
const {
|
|
2095
|
+
keyEventsListener = window,
|
|
2096
|
+
values = [],
|
|
2097
|
+
getLabel = DEFAULT_LABEL_GETTER,
|
|
2098
|
+
onValueSelected = NOOP,
|
|
2099
|
+
height = 235,
|
|
2100
|
+
emptyListMessage = 'No results',
|
|
2101
|
+
initialFocusIndex = 0
|
|
2102
|
+
} = props;
|
|
2103
|
+
const [mouseControl, setMouseControl] = hooks.useState(false);
|
|
2104
|
+
const [focusedValueIndex, setFocusedValueIndex] = hooks.useState(initialFocusIndex);
|
|
2105
|
+
const [smoothScrolling, setSmoothScrolling] = hooks.useState(false);
|
|
2106
|
+
const dropdownContainer = hooks.useRef();
|
|
2107
|
+
const mouseScreenPos = hooks.useRef();
|
|
2108
|
+
const focusedItem = hooks.useMemo(() => values.length ? values[focusedValueIndex] : null, [focusedValueIndex, values]);
|
|
2109
|
+
const changeFocusedValueIndex = hooks.useCallback(delta => {
|
|
2110
|
+
setFocusedValueIndex(x => Math.min(Math.max(0, x + delta), values.length - 1));
|
|
2111
|
+
}, [values.length]);
|
|
2112
|
+
hooks.useEffect(() => {
|
|
2113
|
+
if (focusedValueIndex === 0) return;
|
|
2114
|
+
if (!focusedValueIndex || !values.length) {
|
|
2115
|
+
setFocusedValueIndex(0);
|
|
2116
|
+
} else if (focusedValueIndex >= values.length) {
|
|
2117
|
+
setFocusedValueIndex(values.length - 1);
|
|
2118
|
+
}
|
|
2119
|
+
}, [focusedValueIndex, values.length]);
|
|
2120
|
+
useKeyDownAction('ArrowUp', () => {
|
|
2121
|
+
if (values.length) {
|
|
2122
|
+
changeFocusedValueIndex(-1);
|
|
2123
|
+
setMouseControl(false);
|
|
2124
|
+
}
|
|
2125
|
+
}, keyEventsListener);
|
|
2126
|
+
useKeyDownAction('ArrowDown', () => {
|
|
2127
|
+
if (values.length) {
|
|
2128
|
+
changeFocusedValueIndex(1);
|
|
2129
|
+
setMouseControl(false);
|
|
2130
|
+
}
|
|
2131
|
+
}, keyEventsListener);
|
|
2132
|
+
useKeyDownAction('Enter', () => {
|
|
2133
|
+
if (focusedItem) {
|
|
2134
|
+
onValueSelected(focusedItem);
|
|
2135
|
+
}
|
|
2136
|
+
}, keyEventsListener);
|
|
2137
|
+
hooks.useEffect(() => {
|
|
2138
|
+
const individualEntries = dropdownContainer.current.children;
|
|
2139
|
+
if (individualEntries.length && !mouseControl) {
|
|
2140
|
+
individualEntries[focusedValueIndex].scrollIntoView({
|
|
2141
|
+
block: 'nearest',
|
|
2142
|
+
inline: 'nearest'
|
|
2143
|
+
});
|
|
2144
|
+
}
|
|
2145
|
+
}, [focusedValueIndex, mouseControl]);
|
|
2146
|
+
hooks.useEffect(() => {
|
|
2147
|
+
setSmoothScrolling(true);
|
|
2148
|
+
}, []);
|
|
2149
|
+
const onMouseMovedInKeyboardMode = (event, valueIndex) => {
|
|
2150
|
+
const userMovedCursor = !mouseScreenPos.current || mouseScreenPos.current.x !== event.screenX && mouseScreenPos.current.y !== event.screenY;
|
|
2151
|
+
if (userMovedCursor) {
|
|
2152
|
+
mouseScreenPos.current = {
|
|
2153
|
+
x: event.screenX,
|
|
2154
|
+
y: event.screenY
|
|
2155
|
+
};
|
|
2156
|
+
setMouseControl(true);
|
|
2157
|
+
setFocusedValueIndex(valueIndex);
|
|
2158
|
+
}
|
|
2159
|
+
};
|
|
2160
|
+
return jsxRuntime.jsxs("div", {
|
|
2161
|
+
ref: dropdownContainer,
|
|
2162
|
+
tabIndex: -1,
|
|
2163
|
+
class: "fjs-dropdownlist",
|
|
2164
|
+
style: {
|
|
2165
|
+
maxHeight: height,
|
|
2166
|
+
scrollBehavior: smoothScrolling ? 'smooth' : 'auto'
|
|
2167
|
+
},
|
|
2168
|
+
children: [values.length > 0 && values.map((v, i) => {
|
|
2169
|
+
return jsxRuntime.jsx("div", {
|
|
2170
|
+
class: classNames__default['default']('fjs-dropdownlist-item', {
|
|
2171
|
+
'focused': focusedValueIndex === i
|
|
2172
|
+
}),
|
|
2173
|
+
onMouseMove: mouseControl ? undefined : e => onMouseMovedInKeyboardMode(e, i),
|
|
2174
|
+
onMouseEnter: mouseControl ? () => setFocusedValueIndex(i) : undefined,
|
|
2175
|
+
onMouseDown: e => {
|
|
2176
|
+
e.preventDefault();
|
|
2177
|
+
onValueSelected(v);
|
|
2178
|
+
},
|
|
2179
|
+
children: getLabel(v)
|
|
2180
|
+
});
|
|
2181
|
+
}), !values.length && jsxRuntime.jsx("div", {
|
|
2182
|
+
class: "fjs-dropdownlist-empty",
|
|
2183
|
+
children: emptyListMessage
|
|
2184
|
+
})]
|
|
2185
|
+
});
|
|
2186
|
+
}
|
|
2187
|
+
|
|
2188
|
+
function Timepicker(props) {
|
|
2189
|
+
const {
|
|
2190
|
+
id,
|
|
2191
|
+
label,
|
|
2192
|
+
collapseLabelOnEmpty,
|
|
2193
|
+
formId,
|
|
2194
|
+
required,
|
|
2195
|
+
disabled,
|
|
2196
|
+
use24h = false,
|
|
2197
|
+
timeInterval,
|
|
2198
|
+
time,
|
|
2199
|
+
setTime
|
|
2200
|
+
} = props;
|
|
2201
|
+
const timeInputRef = hooks.useRef();
|
|
2202
|
+
const [dropdownIsOpen, setDropdownIsOpen] = hooks.useState(false);
|
|
2203
|
+
const useDropdown = hooks.useMemo(() => timeInterval !== 1, [timeInterval]);
|
|
2204
|
+
const [rawValue, setRawValue] = hooks.useState('');
|
|
2205
|
+
|
|
2206
|
+
// populates values from source
|
|
2207
|
+
hooks.useEffect(() => {
|
|
2208
|
+
if (time === null) {
|
|
2209
|
+
setRawValue('');
|
|
2210
|
+
return;
|
|
2211
|
+
}
|
|
2212
|
+
const intervalAdjustedTime = time - time % timeInterval;
|
|
2213
|
+
setRawValue(formatTime(use24h, intervalAdjustedTime));
|
|
2214
|
+
if (intervalAdjustedTime != time) {
|
|
2215
|
+
setTime(intervalAdjustedTime);
|
|
2216
|
+
}
|
|
2217
|
+
}, [time, setTime, use24h, timeInterval]);
|
|
2218
|
+
const propagateRawToMinute = hooks.useCallback(newRawValue => {
|
|
2219
|
+
const localRawValue = newRawValue || rawValue;
|
|
2220
|
+
|
|
2221
|
+
// If no raw value exists, set the minute to null
|
|
2222
|
+
if (!localRawValue) {
|
|
2223
|
+
setTime(null);
|
|
2224
|
+
return;
|
|
2225
|
+
}
|
|
2226
|
+
const minutes = parseInputTime(localRawValue);
|
|
2227
|
+
|
|
2228
|
+
// If raw string couldn't be parsed, clean everything up
|
|
2229
|
+
if (!minDash.isNumber(minutes)) {
|
|
2230
|
+
setRawValue('');
|
|
2231
|
+
setTime(null);
|
|
2232
|
+
return;
|
|
2233
|
+
}
|
|
2234
|
+
|
|
2235
|
+
// Enforce the minutes to match the timeInterval
|
|
2236
|
+
const correctedMinutes = minutes - minutes % timeInterval;
|
|
2237
|
+
|
|
2238
|
+
// Enforce the raw text to be formatted properly
|
|
2239
|
+
setRawValue(formatTime(use24h, correctedMinutes));
|
|
2240
|
+
setTime(correctedMinutes);
|
|
2241
|
+
}, [rawValue, timeInterval, use24h, setTime]);
|
|
2242
|
+
const timeOptions = hooks.useMemo(() => {
|
|
2243
|
+
const minutesInDay = 24 * 60;
|
|
2244
|
+
const intervalCount = Math.floor(minutesInDay / timeInterval);
|
|
2245
|
+
return [...Array(intervalCount).keys()].map(intervalIndex => formatTime(use24h, intervalIndex * timeInterval));
|
|
2246
|
+
}, [timeInterval, use24h]);
|
|
2247
|
+
const initialFocusIndex = hooks.useMemo(() => {
|
|
2248
|
+
// if there are no options, there will not be any focusing
|
|
2249
|
+
if (!timeOptions || !timeInterval) return null;
|
|
2250
|
+
|
|
2251
|
+
// if there is a set minute value, we focus it in the dropdown
|
|
2252
|
+
if (time) return time / timeInterval;
|
|
2253
|
+
const cacheTime = parseInputTime(rawValue);
|
|
2254
|
+
|
|
2255
|
+
// if there is a valid value in the input cache, we try and focus close to it
|
|
2256
|
+
if (cacheTime) {
|
|
2257
|
+
const flooredCacheTime = cacheTime - cacheTime % timeInterval;
|
|
2258
|
+
return flooredCacheTime / timeInterval;
|
|
2259
|
+
}
|
|
2260
|
+
|
|
2261
|
+
// If there is no set value, simply focus the middle of the dropdown (12:00)
|
|
2262
|
+
return Math.floor(timeOptions.length / 2);
|
|
2263
|
+
}, [rawValue, time, timeInterval, timeOptions]);
|
|
2264
|
+
const onInputKeyDown = e => {
|
|
2265
|
+
switch (e.key) {
|
|
2266
|
+
case 'ArrowUp':
|
|
2267
|
+
e.preventDefault();
|
|
2268
|
+
break;
|
|
2269
|
+
case 'ArrowDown':
|
|
2270
|
+
useDropdown && setDropdownIsOpen(true);
|
|
2271
|
+
e.preventDefault();
|
|
2272
|
+
break;
|
|
2273
|
+
case 'Escape':
|
|
2274
|
+
useDropdown && setDropdownIsOpen(false);
|
|
2275
|
+
break;
|
|
2276
|
+
case 'Enter':
|
|
2277
|
+
!dropdownIsOpen && propagateRawToMinute();
|
|
2278
|
+
break;
|
|
2279
|
+
}
|
|
2280
|
+
};
|
|
2281
|
+
const onInputBlur = e => {
|
|
2282
|
+
setDropdownIsOpen(false);
|
|
2283
|
+
propagateRawToMinute();
|
|
2284
|
+
};
|
|
2285
|
+
const onDropdownValueSelected = value => {
|
|
2286
|
+
setDropdownIsOpen(false);
|
|
2287
|
+
propagateRawToMinute(value);
|
|
2288
|
+
};
|
|
2289
|
+
const fullId = `${prefixId(id, formId)}--time`;
|
|
2290
|
+
return jsxRuntime.jsxs("div", {
|
|
2291
|
+
class: "fjs-datetime-subsection",
|
|
2292
|
+
children: [jsxRuntime.jsx(Label, {
|
|
2293
|
+
id: fullId,
|
|
2294
|
+
label: label,
|
|
2295
|
+
collapseOnEmpty: collapseLabelOnEmpty,
|
|
2296
|
+
required: required
|
|
2297
|
+
}), jsxRuntime.jsx(InputAdorner, {
|
|
2298
|
+
pre: jsxRuntime.jsx(ClockIcon, {}),
|
|
2299
|
+
inputRef: timeInputRef,
|
|
2300
|
+
disabled: disabled,
|
|
2301
|
+
children: jsxRuntime.jsxs("div", {
|
|
2302
|
+
class: "fjs-timepicker fjs-timepicker-anchor",
|
|
2303
|
+
children: [jsxRuntime.jsx("input", {
|
|
2304
|
+
ref: timeInputRef,
|
|
2305
|
+
type: "text",
|
|
2306
|
+
id: fullId,
|
|
2307
|
+
class: "fjs-input",
|
|
2308
|
+
value: rawValue,
|
|
2309
|
+
disabled: disabled,
|
|
2310
|
+
placeholder: use24h ? 'hh:mm' : 'hh:mm ?m',
|
|
2311
|
+
autoComplete: "false",
|
|
2312
|
+
onFocus: () => useDropdown && setDropdownIsOpen(true),
|
|
2313
|
+
onClick: () => useDropdown && setDropdownIsOpen(true)
|
|
2314
|
+
|
|
2315
|
+
// @ts-ignore
|
|
2316
|
+
,
|
|
2317
|
+
onInput: e => {
|
|
2318
|
+
setRawValue(e.target.value);
|
|
2319
|
+
useDropdown && setDropdownIsOpen(false);
|
|
2320
|
+
},
|
|
2321
|
+
onBlur: onInputBlur,
|
|
2322
|
+
onKeyDown: onInputKeyDown,
|
|
2323
|
+
"data-input": true
|
|
2324
|
+
}), dropdownIsOpen && jsxRuntime.jsx(DropdownList, {
|
|
2325
|
+
values: timeOptions,
|
|
2326
|
+
height: 150,
|
|
2327
|
+
onValueSelected: onDropdownValueSelected,
|
|
2328
|
+
listenerElement: timeInputRef.current,
|
|
2329
|
+
initialFocusIndex: initialFocusIndex
|
|
2330
|
+
})]
|
|
2331
|
+
})
|
|
2332
|
+
})]
|
|
2333
|
+
});
|
|
2334
|
+
}
|
|
2335
|
+
|
|
2336
|
+
const type$8 = 'datetime';
|
|
2337
|
+
function Datetime(props) {
|
|
2338
|
+
const {
|
|
2339
|
+
disabled,
|
|
2340
|
+
errors = [],
|
|
2341
|
+
field,
|
|
2342
|
+
onChange,
|
|
2343
|
+
value = ''
|
|
2344
|
+
} = props;
|
|
2345
|
+
const {
|
|
2346
|
+
description,
|
|
2347
|
+
id,
|
|
2348
|
+
dateLabel,
|
|
2349
|
+
timeLabel,
|
|
2350
|
+
validate = {},
|
|
2351
|
+
subtype,
|
|
2352
|
+
use24h,
|
|
2353
|
+
disallowPassedDates,
|
|
2354
|
+
timeInterval,
|
|
2355
|
+
timeSerializingFormat
|
|
2356
|
+
} = field;
|
|
2357
|
+
const {
|
|
2358
|
+
required
|
|
2359
|
+
} = validate;
|
|
2360
|
+
const {
|
|
2361
|
+
formId
|
|
2362
|
+
} = hooks.useContext(FormContext);
|
|
2363
|
+
const getNullDateTime = () => ({
|
|
2364
|
+
date: new Date(Date.parse(null)),
|
|
2365
|
+
time: null
|
|
2366
|
+
});
|
|
2367
|
+
const [dateTime, setDateTime] = hooks.useState(getNullDateTime());
|
|
2368
|
+
const [dateTimeUpdateRequest, setDateTimeUpdateRequest] = hooks.useState(null);
|
|
2369
|
+
const isValidDate = date => date && !isNaN(date.getTime());
|
|
2370
|
+
const isValidTime = time => !isNaN(parseInt(time));
|
|
2371
|
+
const useDatePicker = hooks.useMemo(() => subtype === DATETIME_SUBTYPES.DATE || subtype === DATETIME_SUBTYPES.DATETIME, [subtype]);
|
|
2372
|
+
const useTimePicker = hooks.useMemo(() => subtype === DATETIME_SUBTYPES.TIME || subtype === DATETIME_SUBTYPES.DATETIME, [subtype]);
|
|
2373
|
+
hooks.useEffect(() => {
|
|
2374
|
+
let {
|
|
2375
|
+
date,
|
|
2376
|
+
time
|
|
2377
|
+
} = getNullDateTime();
|
|
2378
|
+
if (!disabled) {
|
|
2379
|
+
switch (subtype) {
|
|
2380
|
+
case DATETIME_SUBTYPES.DATE:
|
|
2381
|
+
{
|
|
2382
|
+
date = new Date(Date.parse(value));
|
|
2383
|
+
break;
|
|
2384
|
+
}
|
|
2385
|
+
case DATETIME_SUBTYPES.TIME:
|
|
2386
|
+
{
|
|
2387
|
+
time = parseIsoTime(value);
|
|
2388
|
+
break;
|
|
2389
|
+
}
|
|
2390
|
+
case DATETIME_SUBTYPES.DATETIME:
|
|
2391
|
+
{
|
|
2392
|
+
date = new Date(Date.parse(value));
|
|
2393
|
+
time = isValidDate(date) ? 60 * date.getHours() + date.getMinutes() : null;
|
|
2394
|
+
break;
|
|
2395
|
+
}
|
|
2396
|
+
}
|
|
2397
|
+
}
|
|
2398
|
+
setDateTime({
|
|
2399
|
+
date,
|
|
2400
|
+
time
|
|
2401
|
+
});
|
|
2402
|
+
}, [subtype, value, disabled]);
|
|
2403
|
+
const computeAndSetState = hooks.useCallback(({
|
|
2404
|
+
date,
|
|
2405
|
+
time
|
|
2406
|
+
}) => {
|
|
2407
|
+
let newDateTimeValue = null;
|
|
2408
|
+
if (subtype === DATETIME_SUBTYPES.DATE && isValidDate(date)) {
|
|
2409
|
+
newDateTimeValue = serializeDate(date);
|
|
2410
|
+
} else if (subtype === DATETIME_SUBTYPES.TIME && isValidTime(time)) {
|
|
2411
|
+
newDateTimeValue = serializeTime(time, new Date().getTimezoneOffset(), timeSerializingFormat);
|
|
2412
|
+
} else if (subtype === DATETIME_SUBTYPES.DATETIME && isValidDate(date) && isValidTime(time)) {
|
|
2413
|
+
newDateTimeValue = serializeDateTime(date, time, timeSerializingFormat);
|
|
2414
|
+
}
|
|
2415
|
+
onChange({
|
|
2416
|
+
value: newDateTimeValue,
|
|
2417
|
+
field
|
|
2418
|
+
});
|
|
2419
|
+
}, [field, onChange, subtype, timeSerializingFormat]);
|
|
2420
|
+
hooks.useEffect(() => {
|
|
2421
|
+
if (dateTimeUpdateRequest) {
|
|
2422
|
+
if (dateTimeUpdateRequest.refreshOnly) {
|
|
2423
|
+
computeAndSetState(dateTime);
|
|
2424
|
+
} else {
|
|
2425
|
+
const newDateTime = {
|
|
2426
|
+
...dateTime,
|
|
2427
|
+
...dateTimeUpdateRequest
|
|
2428
|
+
};
|
|
2429
|
+
setDateTime(newDateTime);
|
|
2430
|
+
computeAndSetState(newDateTime);
|
|
2431
|
+
}
|
|
2432
|
+
setDateTimeUpdateRequest(null);
|
|
2433
|
+
}
|
|
2434
|
+
}, [computeAndSetState, dateTime, dateTimeUpdateRequest]);
|
|
2435
|
+
hooks.useEffect(() => {
|
|
2436
|
+
setDateTimeUpdateRequest({
|
|
2437
|
+
refreshOnly: true
|
|
2438
|
+
});
|
|
2439
|
+
}, [timeSerializingFormat]);
|
|
2440
|
+
const allErrors = hooks.useMemo(() => {
|
|
2441
|
+
if (required || subtype !== DATETIME_SUBTYPES.DATETIME) return errors;
|
|
2442
|
+
const isOnlyOneFieldSet = isValidDate(dateTime.date) && !isValidTime(dateTime.time) || !isValidDate(dateTime.date) && isValidTime(dateTime.time);
|
|
2443
|
+
return isOnlyOneFieldSet ? ['Date and time must both be entered.', ...errors] : errors;
|
|
2444
|
+
}, [required, subtype, dateTime, errors]);
|
|
2445
|
+
const setDate = hooks.useCallback(date => {
|
|
2446
|
+
setDateTimeUpdateRequest(prev => prev ? {
|
|
2447
|
+
...prev,
|
|
2448
|
+
date
|
|
2449
|
+
} : {
|
|
2450
|
+
date
|
|
2451
|
+
});
|
|
2452
|
+
}, []);
|
|
2453
|
+
const setTime = hooks.useCallback(time => {
|
|
2454
|
+
setDateTimeUpdateRequest(prev => prev ? {
|
|
2455
|
+
...prev,
|
|
2456
|
+
time
|
|
2457
|
+
} : {
|
|
2458
|
+
time
|
|
2459
|
+
});
|
|
2460
|
+
}, []);
|
|
2461
|
+
const datePickerProps = {
|
|
2462
|
+
id,
|
|
2463
|
+
label: dateLabel,
|
|
2464
|
+
collapseLabelOnEmpty: !timeLabel,
|
|
2465
|
+
formId,
|
|
2466
|
+
required,
|
|
2467
|
+
disabled,
|
|
2468
|
+
disallowPassedDates,
|
|
2469
|
+
date: dateTime.date,
|
|
2470
|
+
setDate
|
|
2471
|
+
};
|
|
2472
|
+
const timePickerProps = {
|
|
2473
|
+
id,
|
|
2474
|
+
label: timeLabel,
|
|
2475
|
+
collapseLabelOnEmpty: !dateLabel,
|
|
2476
|
+
formId,
|
|
2477
|
+
required,
|
|
2478
|
+
disabled,
|
|
2479
|
+
use24h,
|
|
2480
|
+
timeInterval,
|
|
2481
|
+
time: dateTime.time,
|
|
2482
|
+
setTime
|
|
2483
|
+
};
|
|
2484
|
+
return jsxRuntime.jsxs("div", {
|
|
2485
|
+
class: formFieldClasses(type$8, {
|
|
2486
|
+
errors: allErrors,
|
|
2487
|
+
disabled
|
|
2488
|
+
}),
|
|
2489
|
+
children: [jsxRuntime.jsxs("div", {
|
|
2490
|
+
class: classNames__default['default']('fjs-vertical-group'),
|
|
2491
|
+
children: [useDatePicker && jsxRuntime.jsx(Datepicker, {
|
|
2492
|
+
...datePickerProps
|
|
2493
|
+
}), useTimePicker && useDatePicker && jsxRuntime.jsx("div", {
|
|
2494
|
+
class: "fjs-datetime-separator"
|
|
2495
|
+
}), useTimePicker && jsxRuntime.jsx(Timepicker, {
|
|
2496
|
+
...timePickerProps
|
|
2497
|
+
})]
|
|
2498
|
+
}), jsxRuntime.jsx(Description, {
|
|
2499
|
+
description: description
|
|
2500
|
+
}), jsxRuntime.jsx(Errors, {
|
|
2501
|
+
errors: allErrors
|
|
2502
|
+
})]
|
|
2503
|
+
});
|
|
2504
|
+
}
|
|
2505
|
+
Datetime.create = function (options = {}) {
|
|
2506
|
+
const newOptions = {};
|
|
2507
|
+
minDash.set(newOptions, DATETIME_SUBTYPE_PATH, DATETIME_SUBTYPES.DATE);
|
|
2508
|
+
minDash.set(newOptions, DATE_LABEL_PATH, 'Date');
|
|
2509
|
+
return {
|
|
2510
|
+
...newOptions,
|
|
2511
|
+
...options
|
|
2512
|
+
};
|
|
2513
|
+
};
|
|
2514
|
+
Datetime.type = type$8;
|
|
2515
|
+
Datetime.keyed = true;
|
|
2516
|
+
Datetime.emptyValue = null;
|
|
2517
|
+
Datetime.sanitizeValue = sanitizeDateTimePickerValue;
|
|
2518
|
+
|
|
2519
|
+
/**
|
|
2520
|
+
* This file must not be changed or exchanged.
|
|
2521
|
+
*
|
|
2522
|
+
* @see http://bpmn.io/license for more information.
|
|
2523
|
+
*/
|
|
2524
|
+
function Logo() {
|
|
2525
|
+
return jsxRuntime.jsxs("svg", {
|
|
2526
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2527
|
+
viewBox: "0 0 14.02 5.57",
|
|
2528
|
+
width: "53",
|
|
2529
|
+
height: "21",
|
|
2530
|
+
style: "vertical-align:middle",
|
|
2531
|
+
children: [jsxRuntime.jsx("path", {
|
|
2532
|
+
fill: "currentColor",
|
|
2533
|
+
d: "M1.88.92v.14c0 .41-.13.68-.4.8.33.14.46.44.46.86v.33c0 .61-.33.95-.95.95H0V0h.95c.65 0 .93.3.93.92zM.63.57v1.06h.24c.24 0 .38-.1.38-.43V.98c0-.28-.1-.4-.32-.4zm0 1.63v1.22h.36c.2 0 .32-.1.32-.39v-.35c0-.37-.12-.48-.4-.48H.63zM4.18.99v.52c0 .64-.31.98-.94.98h-.3V4h-.62V0h.92c.63 0 .94.35.94.99zM2.94.57v1.35h.3c.2 0 .3-.09.3-.37v-.6c0-.29-.1-.38-.3-.38h-.3zm2.89 2.27L6.25 0h.88v4h-.6V1.12L6.1 3.99h-.6l-.46-2.82v2.82h-.55V0h.87zM8.14 1.1V4h-.56V0h.79L9 2.4V0h.56v4h-.64zm2.49 2.29v.6h-.6v-.6zM12.12 1c0-.63.33-1 .95-1 .61 0 .95.37.95 1v2.04c0 .64-.34 1-.95 1-.62 0-.95-.37-.95-1zm.62 2.08c0 .28.13.39.33.39s.32-.1.32-.4V.98c0-.29-.12-.4-.32-.4s-.33.11-.33.4z"
|
|
2534
|
+
}), jsxRuntime.jsx("path", {
|
|
2535
|
+
fill: "currentColor",
|
|
2536
|
+
d: "M0 4.53h14.02v1.04H0zM11.08 0h.63v.62h-.63zm.63 4V1h-.63v2.98z"
|
|
2537
|
+
})]
|
|
2538
|
+
});
|
|
2539
|
+
}
|
|
2540
|
+
function Lightbox(props) {
|
|
2541
|
+
const {
|
|
2542
|
+
open
|
|
2543
|
+
} = props;
|
|
2544
|
+
if (!open) {
|
|
1635
2545
|
return null;
|
|
1636
2546
|
}
|
|
1637
2547
|
return jsxRuntime.jsxs("div", {
|
|
@@ -1726,22 +2636,29 @@ function FormComponent(props) {
|
|
|
1726
2636
|
});
|
|
1727
2637
|
}
|
|
1728
2638
|
|
|
1729
|
-
/**
|
|
1730
|
-
*
|
|
1731
|
-
* @param {string | undefined} expression
|
|
1732
|
-
* @param {import('../../types').Data} data
|
|
2639
|
+
/**
|
|
2640
|
+
*
|
|
2641
|
+
* @param {string | undefined} expression
|
|
2642
|
+
* @param {import('../../types').Data} data
|
|
1733
2643
|
*/
|
|
1734
2644
|
function useEvaluation(expression, data) {
|
|
2645
|
+
const initialData = useService('form')._getState().initialData;
|
|
1735
2646
|
const conditionChecker = useService('conditionChecker', false);
|
|
1736
2647
|
if (!conditionChecker) {
|
|
1737
2648
|
return null;
|
|
1738
2649
|
}
|
|
1739
|
-
|
|
2650
|
+
|
|
2651
|
+
// make sure we do not use data from hidden fields
|
|
2652
|
+
const filteredData = {
|
|
2653
|
+
...initialData,
|
|
2654
|
+
...conditionChecker.applyConditions(data, data)
|
|
2655
|
+
};
|
|
2656
|
+
return conditionChecker.evaluate(expression, filteredData);
|
|
1740
2657
|
}
|
|
1741
2658
|
|
|
1742
|
-
/**
|
|
1743
|
-
*
|
|
1744
|
-
* @param {string} value
|
|
2659
|
+
/**
|
|
2660
|
+
*
|
|
2661
|
+
* @param {string} value
|
|
1745
2662
|
*/
|
|
1746
2663
|
function useExpressionValue(value) {
|
|
1747
2664
|
const formData = useService('form')._getState().data;
|
|
@@ -1761,11 +2678,11 @@ function isExpression(value) {
|
|
|
1761
2678
|
return minDash.isString(value) && value.startsWith('=');
|
|
1762
2679
|
}
|
|
1763
2680
|
|
|
1764
|
-
function _extends$
|
|
2681
|
+
function _extends$f() { _extends$f = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$f.apply(this, arguments); }
|
|
1765
2682
|
var ImagePlaceholder = (({
|
|
1766
2683
|
styles = {},
|
|
1767
2684
|
...props
|
|
1768
|
-
}) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$
|
|
2685
|
+
}) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$f({
|
|
1769
2686
|
width: "64",
|
|
1770
2687
|
height: "64",
|
|
1771
2688
|
viewBox: "0 0 1280 1280",
|
|
@@ -1845,11 +2762,16 @@ function Numberfield(props) {
|
|
|
1845
2762
|
description,
|
|
1846
2763
|
id,
|
|
1847
2764
|
label,
|
|
2765
|
+
appearance = {},
|
|
1848
2766
|
validate = {},
|
|
1849
2767
|
decimalDigits,
|
|
1850
2768
|
serializeToString = false,
|
|
1851
2769
|
increment: incrementValue
|
|
1852
2770
|
} = field;
|
|
2771
|
+
const {
|
|
2772
|
+
prefixAdorner,
|
|
2773
|
+
suffixAdorner
|
|
2774
|
+
} = appearance;
|
|
1853
2775
|
const {
|
|
1854
2776
|
required
|
|
1855
2777
|
} = validate;
|
|
@@ -1959,45 +2881,52 @@ function Numberfield(props) {
|
|
|
1959
2881
|
id: prefixId(id, formId),
|
|
1960
2882
|
label: label,
|
|
1961
2883
|
required: required
|
|
1962
|
-
}), jsxRuntime.
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
children: [jsxRuntime.jsx("input", {
|
|
1969
|
-
ref: inputRef,
|
|
1970
|
-
class: "fjs-input",
|
|
1971
|
-
disabled: disabled,
|
|
1972
|
-
id: prefixId(id, formId),
|
|
1973
|
-
onKeyDown: onKeyDown,
|
|
1974
|
-
onKeyPress: onKeyPress
|
|
1975
|
-
|
|
1976
|
-
// @ts-ignore
|
|
1977
|
-
,
|
|
1978
|
-
onInput: e => setValue(e.target.value),
|
|
1979
|
-
type: "text",
|
|
1980
|
-
autoComplete: "off",
|
|
1981
|
-
step: arrowIncrementValue,
|
|
1982
|
-
value: displayValue
|
|
1983
|
-
}), jsxRuntime.jsxs("div", {
|
|
1984
|
-
class: classNames__default['default']('fjs-number-arrow-container', {
|
|
2884
|
+
}), jsxRuntime.jsx(InputAdorner, {
|
|
2885
|
+
disabled: disabled,
|
|
2886
|
+
pre: prefixAdorner,
|
|
2887
|
+
post: suffixAdorner,
|
|
2888
|
+
children: jsxRuntime.jsxs("div", {
|
|
2889
|
+
class: classNames__default['default']('fjs-vertical-group', {
|
|
1985
2890
|
'disabled': disabled
|
|
2891
|
+
}, {
|
|
2892
|
+
'hasErrors': errors.length
|
|
1986
2893
|
}),
|
|
1987
|
-
children: [jsxRuntime.jsx("
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
2894
|
+
children: [jsxRuntime.jsx("input", {
|
|
2895
|
+
ref: inputRef,
|
|
2896
|
+
class: "fjs-input",
|
|
2897
|
+
disabled: disabled,
|
|
2898
|
+
id: prefixId(id, formId),
|
|
2899
|
+
onKeyDown: onKeyDown,
|
|
2900
|
+
onKeyPress: onKeyPress
|
|
2901
|
+
|
|
2902
|
+
// @ts-ignore
|
|
2903
|
+
,
|
|
2904
|
+
onInput: e => setValue(e.target.value),
|
|
2905
|
+
type: "text",
|
|
2906
|
+
autoComplete: "off",
|
|
2907
|
+
step: arrowIncrementValue,
|
|
2908
|
+
value: displayValue
|
|
2909
|
+
}), jsxRuntime.jsxs("div", {
|
|
2910
|
+
class: classNames__default['default']('fjs-number-arrow-container', {
|
|
2911
|
+
'disabled': disabled
|
|
2912
|
+
}),
|
|
2913
|
+
children: [jsxRuntime.jsx("button", {
|
|
2914
|
+
class: "fjs-number-arrow-up",
|
|
2915
|
+
type: "button",
|
|
2916
|
+
onClick: () => increment(),
|
|
2917
|
+
tabIndex: -1,
|
|
2918
|
+
children: "\u02C4"
|
|
2919
|
+
}), jsxRuntime.jsx("div", {
|
|
2920
|
+
class: "fjs-number-arrow-separator"
|
|
2921
|
+
}), jsxRuntime.jsx("button", {
|
|
2922
|
+
class: "fjs-number-arrow-down",
|
|
2923
|
+
type: "button",
|
|
2924
|
+
onClick: () => decrement(),
|
|
2925
|
+
tabIndex: -1,
|
|
2926
|
+
children: "\u02C5"
|
|
2927
|
+
})]
|
|
1999
2928
|
})]
|
|
2000
|
-
})
|
|
2929
|
+
})
|
|
2001
2930
|
}), jsxRuntime.jsx(Description, {
|
|
2002
2931
|
description: description
|
|
2003
2932
|
}), jsxRuntime.jsx(Errors, {
|
|
@@ -2180,11 +3109,11 @@ Select.keyed = true;
|
|
|
2180
3109
|
Select.emptyValue = null;
|
|
2181
3110
|
Select.sanitizeValue = sanitizeSingleSelectValue;
|
|
2182
3111
|
|
|
2183
|
-
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
3112
|
+
function _extends$e() { _extends$e = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$e.apply(this, arguments); }
|
|
2184
3113
|
var CloseIcon = (({
|
|
2185
3114
|
styles = {},
|
|
2186
3115
|
...props
|
|
2187
|
-
}) => /*#__PURE__*/React__default['default'].createElement("svg", _extends({
|
|
3116
|
+
}) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$e({
|
|
2188
3117
|
width: "16",
|
|
2189
3118
|
height: "16",
|
|
2190
3119
|
fill: "none",
|
|
@@ -2196,113 +3125,6 @@ var CloseIcon = (({
|
|
|
2196
3125
|
fill: "currentColor"
|
|
2197
3126
|
})));
|
|
2198
3127
|
|
|
2199
|
-
function useKeyDownAction(targetKey, action, listenerElement = window) {
|
|
2200
|
-
function downHandler({
|
|
2201
|
-
key
|
|
2202
|
-
}) {
|
|
2203
|
-
if (key === targetKey) {
|
|
2204
|
-
action();
|
|
2205
|
-
}
|
|
2206
|
-
}
|
|
2207
|
-
hooks.useEffect(() => {
|
|
2208
|
-
listenerElement.addEventListener('keydown', downHandler);
|
|
2209
|
-
return () => {
|
|
2210
|
-
listenerElement.removeEventListener('keydown', downHandler);
|
|
2211
|
-
};
|
|
2212
|
-
});
|
|
2213
|
-
}
|
|
2214
|
-
|
|
2215
|
-
const DEFAULT_LABEL_GETTER = value => value;
|
|
2216
|
-
const NOOP = () => {};
|
|
2217
|
-
function DropdownList(props) {
|
|
2218
|
-
const {
|
|
2219
|
-
keyEventsListener = window,
|
|
2220
|
-
values = [],
|
|
2221
|
-
getLabel = DEFAULT_LABEL_GETTER,
|
|
2222
|
-
onValueSelected = NOOP,
|
|
2223
|
-
height = 235,
|
|
2224
|
-
emptyListMessage = 'No results'
|
|
2225
|
-
} = props;
|
|
2226
|
-
const [mouseControl, setMouseControl] = hooks.useState(true);
|
|
2227
|
-
const [focusedValueIndex, setFocusedValueIndex] = hooks.useState(0);
|
|
2228
|
-
const dropdownContainer = hooks.useRef();
|
|
2229
|
-
const mouseScreenPos = hooks.useRef();
|
|
2230
|
-
const focusedItem = hooks.useMemo(() => values.length ? values[focusedValueIndex] : null, [focusedValueIndex, values]);
|
|
2231
|
-
const changeFocusedValueIndex = hooks.useCallback(delta => {
|
|
2232
|
-
setFocusedValueIndex(x => Math.min(Math.max(0, x + delta), values.length - 1));
|
|
2233
|
-
}, [values.length]);
|
|
2234
|
-
hooks.useEffect(() => {
|
|
2235
|
-
if (focusedValueIndex === 0) return;
|
|
2236
|
-
if (!focusedValueIndex || !values.length) {
|
|
2237
|
-
setFocusedValueIndex(0);
|
|
2238
|
-
} else if (focusedValueIndex >= values.length) {
|
|
2239
|
-
setFocusedValueIndex(values.length - 1);
|
|
2240
|
-
}
|
|
2241
|
-
}, [focusedValueIndex, values.length]);
|
|
2242
|
-
useKeyDownAction('ArrowUp', () => {
|
|
2243
|
-
if (values.length) {
|
|
2244
|
-
changeFocusedValueIndex(-1);
|
|
2245
|
-
setMouseControl(false);
|
|
2246
|
-
}
|
|
2247
|
-
}, keyEventsListener);
|
|
2248
|
-
useKeyDownAction('ArrowDown', () => {
|
|
2249
|
-
if (values.length) {
|
|
2250
|
-
changeFocusedValueIndex(1);
|
|
2251
|
-
setMouseControl(false);
|
|
2252
|
-
}
|
|
2253
|
-
}, keyEventsListener);
|
|
2254
|
-
useKeyDownAction('Enter', () => {
|
|
2255
|
-
if (focusedItem) {
|
|
2256
|
-
onValueSelected(focusedItem);
|
|
2257
|
-
}
|
|
2258
|
-
}, keyEventsListener);
|
|
2259
|
-
hooks.useEffect(() => {
|
|
2260
|
-
const individualEntries = dropdownContainer.current.children;
|
|
2261
|
-
if (individualEntries.length && !mouseControl) {
|
|
2262
|
-
individualEntries[focusedValueIndex].scrollIntoView({
|
|
2263
|
-
block: 'nearest',
|
|
2264
|
-
inline: 'nearest'
|
|
2265
|
-
});
|
|
2266
|
-
}
|
|
2267
|
-
}, [focusedValueIndex, mouseControl]);
|
|
2268
|
-
const mouseMove = (e, i) => {
|
|
2269
|
-
const userMoved = !mouseScreenPos.current || mouseScreenPos.current.x !== e.screenX && mouseScreenPos.current.y !== e.screenY;
|
|
2270
|
-
if (userMoved) {
|
|
2271
|
-
mouseScreenPos.current = {
|
|
2272
|
-
x: e.screenX,
|
|
2273
|
-
y: e.screenY
|
|
2274
|
-
};
|
|
2275
|
-
if (!mouseControl) {
|
|
2276
|
-
setMouseControl(true);
|
|
2277
|
-
setFocusedValueIndex(i);
|
|
2278
|
-
}
|
|
2279
|
-
}
|
|
2280
|
-
};
|
|
2281
|
-
return jsxRuntime.jsxs("div", {
|
|
2282
|
-
ref: dropdownContainer,
|
|
2283
|
-
tabIndex: -1,
|
|
2284
|
-
class: "fjs-dropdownlist",
|
|
2285
|
-
style: {
|
|
2286
|
-
maxHeight: height
|
|
2287
|
-
},
|
|
2288
|
-
children: [!!values.length && values.map((v, i) => {
|
|
2289
|
-
return jsxRuntime.jsx("div", {
|
|
2290
|
-
class: 'fjs-dropdownlist-item' + (focusedValueIndex === i ? ' focused' : ''),
|
|
2291
|
-
onMouseMove: e => mouseMove(e, i),
|
|
2292
|
-
onMouseEnter: mouseControl ? () => setFocusedValueIndex(i) : undefined,
|
|
2293
|
-
onMouseDown: e => {
|
|
2294
|
-
e.preventDefault();
|
|
2295
|
-
onValueSelected(v);
|
|
2296
|
-
},
|
|
2297
|
-
children: getLabel(v)
|
|
2298
|
-
});
|
|
2299
|
-
}), !values.length && jsxRuntime.jsx("div", {
|
|
2300
|
-
class: "fjs-dropdownlist-empty",
|
|
2301
|
-
children: emptyListMessage
|
|
2302
|
-
})]
|
|
2303
|
-
});
|
|
2304
|
-
}
|
|
2305
|
-
|
|
2306
3128
|
const type$3 = 'taglist';
|
|
2307
3129
|
function Taglist(props) {
|
|
2308
3130
|
const {
|
|
@@ -2486,20 +3308,261 @@ Taglist.keyed = true;
|
|
|
2486
3308
|
Taglist.emptyValue = [];
|
|
2487
3309
|
Taglist.sanitizeValue = sanitizeMultiSelectValue;
|
|
2488
3310
|
|
|
3311
|
+
function _extends$d() { _extends$d = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$d.apply(this, arguments); }
|
|
3312
|
+
var ButtonIcon = (({
|
|
3313
|
+
styles = {},
|
|
3314
|
+
...props
|
|
3315
|
+
}) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$d({
|
|
3316
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
3317
|
+
width: "54",
|
|
3318
|
+
height: "54"
|
|
3319
|
+
}, props), /*#__PURE__*/React__default['default'].createElement("path", {
|
|
3320
|
+
fillRule: "evenodd",
|
|
3321
|
+
d: "M45 17a3 3 0 013 3v14a3 3 0 01-3 3H9a3 3 0 01-3-3V20a3 3 0 013-3h36zm-9 8.889H18v2.222h18V25.89z"
|
|
3322
|
+
})));
|
|
3323
|
+
|
|
3324
|
+
function _extends$c() { _extends$c = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$c.apply(this, arguments); }
|
|
3325
|
+
var CheckboxIcon = (({
|
|
3326
|
+
styles = {},
|
|
3327
|
+
...props
|
|
3328
|
+
}) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$c({
|
|
3329
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
3330
|
+
width: "54",
|
|
3331
|
+
height: "54"
|
|
3332
|
+
}, props), /*#__PURE__*/React__default['default'].createElement("path", {
|
|
3333
|
+
d: "M34 18H20a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2V20a2 2 0 00-2-2zm-9 14l-5-5 1.41-1.41L25 29.17l7.59-7.59L34 23l-9 9z"
|
|
3334
|
+
})));
|
|
3335
|
+
|
|
3336
|
+
function _extends$b() { _extends$b = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$b.apply(this, arguments); }
|
|
3337
|
+
var ChecklistIcon = (({
|
|
3338
|
+
styles = {},
|
|
3339
|
+
...props
|
|
3340
|
+
}) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$b({
|
|
3341
|
+
width: "54",
|
|
3342
|
+
height: "54",
|
|
3343
|
+
fill: "none",
|
|
3344
|
+
xmlns: "http://www.w3.org/2000/svg"
|
|
3345
|
+
}, props), /*#__PURE__*/React__default['default'].createElement("path", {
|
|
3346
|
+
fillRule: "evenodd",
|
|
3347
|
+
clipRule: "evenodd",
|
|
3348
|
+
d: "M19 24h-6v6h6v-6zm-6-2a2 2 0 00-2 2v6a2 2 0 002 2h6a2 2 0 002-2v-6a2 2 0 00-2-2h-6zm6 18h-6v6h6v-6zm-6-2a2 2 0 00-2 2v6a2 2 0 002 2h6a2 2 0 002-2v-6a2 2 0 00-2-2h-6zm6-30h-6v6h6V8zm-6-2a2 2 0 00-2 2v6a2 2 0 002 2h6a2 2 0 002-2V8a2 2 0 00-2-2h-6z",
|
|
3349
|
+
fill: "#22242A"
|
|
3350
|
+
}), /*#__PURE__*/React__default['default'].createElement("path", {
|
|
3351
|
+
d: "M26 26a1 1 0 011-1h15a1 1 0 011 1v2a1 1 0 01-1 1H27a1 1 0 01-1-1v-2zm0 16a1 1 0 011-1h15a1 1 0 011 1v2a1 1 0 01-1 1H27a1 1 0 01-1-1v-2zm0-32a1 1 0 011-1h15a1 1 0 011 1v2a1 1 0 01-1 1H27a1 1 0 01-1-1v-2z",
|
|
3352
|
+
fill: "#22242A"
|
|
3353
|
+
})));
|
|
3354
|
+
|
|
3355
|
+
function _extends$a() { _extends$a = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$a.apply(this, arguments); }
|
|
3356
|
+
var DatetimeIcon = (({
|
|
3357
|
+
styles = {},
|
|
3358
|
+
...props
|
|
3359
|
+
}) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$a({
|
|
3360
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
3361
|
+
width: "54",
|
|
3362
|
+
height: "54",
|
|
3363
|
+
fill: "none"
|
|
3364
|
+
}, props), /*#__PURE__*/React__default['default'].createElement("path", {
|
|
3365
|
+
fill: "#000",
|
|
3366
|
+
fillRule: "evenodd",
|
|
3367
|
+
d: "M37.908 13.418h-5.004v-2.354h-1.766v2.354H21.13v-2.354h-1.766v2.354H14.36c-1.132 0-2.06.928-2.06 2.06v23.549c0 1.132.928 2.06 2.06 2.06h6.77v-1.766h-6.358a.707.707 0 01-.706-.706V15.89c0-.39.316-.707.706-.707h4.592v2.355h1.766v-2.355h10.008v2.355h1.766v-2.355h4.592c.39 0 .707.317.707.707v6.358h1.765v-6.77c0-1.133-.927-2.06-2.06-2.06z",
|
|
3368
|
+
clipRule: "evenodd"
|
|
3369
|
+
}), /*#__PURE__*/React__default['default'].createElement("path", {
|
|
3370
|
+
fill: "#000",
|
|
3371
|
+
d: "M35.13 37.603l1.237-1.237-3.468-3.475v-5.926h-1.754v6.654l3.984 3.984z"
|
|
3372
|
+
}), /*#__PURE__*/React__default['default'].createElement("path", {
|
|
3373
|
+
fill: "#000",
|
|
3374
|
+
fillRule: "evenodd",
|
|
3375
|
+
d: "M23.08 36.962a9.678 9.678 0 1017.883-7.408 9.678 9.678 0 00-17.882 7.408zm4.54-10.292a7.924 7.924 0 118.805 13.177A7.924 7.924 0 0127.62 26.67z",
|
|
3376
|
+
clipRule: "evenodd"
|
|
3377
|
+
})));
|
|
3378
|
+
|
|
3379
|
+
function _extends$9() { _extends$9 = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$9.apply(this, arguments); }
|
|
3380
|
+
var TaglistIcon = (({
|
|
3381
|
+
styles = {},
|
|
3382
|
+
...props
|
|
3383
|
+
}) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$9({
|
|
3384
|
+
width: "54",
|
|
3385
|
+
height: "54",
|
|
3386
|
+
fill: "none",
|
|
3387
|
+
xmlns: "http://www.w3.org/2000/svg"
|
|
3388
|
+
}, props), /*#__PURE__*/React__default['default'].createElement("path", {
|
|
3389
|
+
fillRule: "evenodd",
|
|
3390
|
+
clipRule: "evenodd",
|
|
3391
|
+
d: "M45 16a3 3 0 013 3v16a3 3 0 01-3 3H9a3 3 0 01-3-3V19a3 3 0 013-3h36zm0 2H9a1 1 0 00-1 1v16a1 1 0 001 1h36a1 1 0 001-1V19a1 1 0 00-1-1z",
|
|
3392
|
+
fill: "#000"
|
|
3393
|
+
}), /*#__PURE__*/React__default['default'].createElement("path", {
|
|
3394
|
+
d: "M11 22a1 1 0 011-1h19a1 1 0 011 1v10a1 1 0 01-1 1H12a1 1 0 01-1-1V22z",
|
|
3395
|
+
fill: "#505562"
|
|
3396
|
+
})));
|
|
3397
|
+
|
|
3398
|
+
function _extends$8() { _extends$8 = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$8.apply(this, arguments); }
|
|
3399
|
+
var FormIcon = (({
|
|
3400
|
+
styles = {},
|
|
3401
|
+
...props
|
|
3402
|
+
}) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$8({
|
|
3403
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
3404
|
+
width: "54",
|
|
3405
|
+
height: "54"
|
|
3406
|
+
}, props), /*#__PURE__*/React__default['default'].createElement("rect", {
|
|
3407
|
+
x: "15",
|
|
3408
|
+
y: "17",
|
|
3409
|
+
width: "24",
|
|
3410
|
+
height: "4",
|
|
3411
|
+
rx: "1"
|
|
3412
|
+
}), /*#__PURE__*/React__default['default'].createElement("rect", {
|
|
3413
|
+
x: "15",
|
|
3414
|
+
y: "25",
|
|
3415
|
+
width: "24",
|
|
3416
|
+
height: "4",
|
|
3417
|
+
rx: "1"
|
|
3418
|
+
}), /*#__PURE__*/React__default['default'].createElement("rect", {
|
|
3419
|
+
x: "15",
|
|
3420
|
+
y: "33",
|
|
3421
|
+
width: "13",
|
|
3422
|
+
height: "4",
|
|
3423
|
+
rx: "1"
|
|
3424
|
+
})));
|
|
3425
|
+
|
|
3426
|
+
function _extends$7() { _extends$7 = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$7.apply(this, arguments); }
|
|
3427
|
+
var ColumnsIcon = (({
|
|
3428
|
+
styles = {},
|
|
3429
|
+
...props
|
|
3430
|
+
}) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$7({
|
|
3431
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
3432
|
+
width: "54",
|
|
3433
|
+
height: "54"
|
|
3434
|
+
}, props), /*#__PURE__*/React__default['default'].createElement("path", {
|
|
3435
|
+
fillRule: "evenodd",
|
|
3436
|
+
d: "M8 33v5a1 1 0 001 1h4v2H9a3 3 0 01-3-3v-5h2zm18 6v2H15v-2h11zm13 0v2H28v-2h11zm9-6v5a3 3 0 01-3 3h-4v-2h4a1 1 0 00.993-.883L46 38v-5h2zM8 22v9H6v-9h2zm40 0v9h-2v-9h2zm-35-9v2H9a1 1 0 00-.993.883L8 16v4H6v-4a3 3 0 013-3h4zm32 0a3 3 0 013 3v4h-2v-4a1 1 0 00-.883-.993L45 15h-4v-2h4zm-6 0v2H28v-2h11zm-13 0v2H15v-2h11z"
|
|
3437
|
+
})));
|
|
3438
|
+
|
|
3439
|
+
function _extends$6() { _extends$6 = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$6.apply(this, arguments); }
|
|
3440
|
+
var NumberIcon = (({
|
|
3441
|
+
styles = {},
|
|
3442
|
+
...props
|
|
3443
|
+
}) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$6({
|
|
3444
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
3445
|
+
width: "54",
|
|
3446
|
+
height: "54"
|
|
3447
|
+
}, props), /*#__PURE__*/React__default['default'].createElement("path", {
|
|
3448
|
+
fillRule: "evenodd",
|
|
3449
|
+
d: "M45 16a3 3 0 013 3v16a3 3 0 01-3 3H9a3 3 0 01-3-3V19a3 3 0 013-3h36zm0 2H9a1 1 0 00-1 1v16a1 1 0 001 1h36a1 1 0 001-1V19a1 1 0 00-1-1zM35 28.444h7l-3.5 4-3.5-4zM35 26h7l-3.5-4-3.5 4z"
|
|
3450
|
+
})));
|
|
3451
|
+
|
|
3452
|
+
function _extends$5() { _extends$5 = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$5.apply(this, arguments); }
|
|
3453
|
+
var RadioIcon = (({
|
|
3454
|
+
styles = {},
|
|
3455
|
+
...props
|
|
3456
|
+
}) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$5({
|
|
3457
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
3458
|
+
width: "54",
|
|
3459
|
+
height: "54"
|
|
3460
|
+
}, props), /*#__PURE__*/React__default['default'].createElement("path", {
|
|
3461
|
+
d: "M27 22c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.24 5-5-2.24-5-5-5zm0-5c-5.52 0-10 4.48-10 10s4.48 10 10 10 10-4.48 10-10-4.48-10-10-10zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"
|
|
3462
|
+
})));
|
|
3463
|
+
|
|
3464
|
+
function _extends$4() { _extends$4 = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$4.apply(this, arguments); }
|
|
3465
|
+
var SelectIcon = (({
|
|
3466
|
+
styles = {},
|
|
3467
|
+
...props
|
|
3468
|
+
}) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$4({
|
|
3469
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
3470
|
+
width: "54",
|
|
3471
|
+
height: "54"
|
|
3472
|
+
}, props), /*#__PURE__*/React__default['default'].createElement("path", {
|
|
3473
|
+
fillRule: "evenodd",
|
|
3474
|
+
d: "M45 16a3 3 0 013 3v16a3 3 0 01-3 3H9a3 3 0 01-3-3V19a3 3 0 013-3h36zm0 2H9a1 1 0 00-1 1v16a1 1 0 001 1h36a1 1 0 001-1V19a1 1 0 00-1-1zm-12 7h9l-4.5 6-4.5-6z"
|
|
3475
|
+
})));
|
|
3476
|
+
|
|
3477
|
+
function _extends$3() { _extends$3 = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$3.apply(this, arguments); }
|
|
3478
|
+
var TextIcon = (({
|
|
3479
|
+
styles = {},
|
|
3480
|
+
...props
|
|
3481
|
+
}) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$3({
|
|
3482
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
3483
|
+
width: "54",
|
|
3484
|
+
height: "54"
|
|
3485
|
+
}, props), /*#__PURE__*/React__default['default'].createElement("path", {
|
|
3486
|
+
d: "M20.58 33.77h-3l-1.18-3.08H11l-1.1 3.08H7l5.27-13.54h2.89zm-5-5.36l-1.86-5-1.83 5zM22 20.23h5.41a15.47 15.47 0 012.4.14 3.42 3.42 0 011.41.55 3.47 3.47 0 011 1.14 3 3 0 01.42 1.58 3.26 3.26 0 01-1.91 2.94 3.63 3.63 0 011.91 1.22 3.28 3.28 0 01.66 2 4 4 0 01-.43 1.8 3.63 3.63 0 01-1.09 1.4 3.89 3.89 0 01-1.83.65q-.69.07-3.3.09H22zm2.73 2.25v3.13h3.8a1.79 1.79 0 001.1-.49 1.41 1.41 0 00.41-1 1.49 1.49 0 00-.35-1 1.54 1.54 0 00-1-.48c-.27 0-1.05-.05-2.34-.05zm0 5.39v3.62h2.57a11.52 11.52 0 001.88-.09 1.65 1.65 0 001-.54 1.6 1.6 0 00.38-1.14 1.75 1.75 0 00-.29-1 1.69 1.69 0 00-.86-.62 9.28 9.28 0 00-2.41-.23zM44.35 28.79l2.65.84a5.94 5.94 0 01-2 3.29A5.74 5.74 0 0141.38 34a5.87 5.87 0 01-4.44-1.84 7.09 7.09 0 01-1.73-5A7.43 7.43 0 0137 21.87 6 6 0 0141.54 20a5.64 5.64 0 014 1.47A5.33 5.33 0 0147 24l-2.7.65a2.8 2.8 0 00-2.86-2.27A3.09 3.09 0 0039 23.42a5.31 5.31 0 00-.93 3.5 5.62 5.62 0 00.93 3.65 3 3 0 002.4 1.09 2.72 2.72 0 001.82-.66 4 4 0 001.13-2.21z"
|
|
3487
|
+
})));
|
|
3488
|
+
|
|
3489
|
+
function _extends$2() { _extends$2 = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$2.apply(this, arguments); }
|
|
3490
|
+
var TextfieldIcon = (({
|
|
3491
|
+
styles = {},
|
|
3492
|
+
...props
|
|
3493
|
+
}) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$2({
|
|
3494
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
3495
|
+
width: "54",
|
|
3496
|
+
height: "54"
|
|
3497
|
+
}, props), /*#__PURE__*/React__default['default'].createElement("path", {
|
|
3498
|
+
fillRule: "evenodd",
|
|
3499
|
+
d: "M45 16a3 3 0 013 3v16a3 3 0 01-3 3H9a3 3 0 01-3-3V19a3 3 0 013-3h36zm0 2H9a1 1 0 00-1 1v16a1 1 0 001 1h36a1 1 0 001-1V19a1 1 0 00-1-1zm-32 4v10h-2V22h2z"
|
|
3500
|
+
})));
|
|
3501
|
+
|
|
3502
|
+
function _extends$1() { _extends$1 = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$1.apply(this, arguments); }
|
|
3503
|
+
var TextareaIcon = (({
|
|
3504
|
+
styles = {},
|
|
3505
|
+
...props
|
|
3506
|
+
}) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$1({
|
|
3507
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
3508
|
+
width: "54",
|
|
3509
|
+
height: "54"
|
|
3510
|
+
}, props), /*#__PURE__*/React__default['default'].createElement("path", {
|
|
3511
|
+
fillRule: "evenodd",
|
|
3512
|
+
d: "M45 13a3 3 0 013 3v22a3 3 0 01-3 3H9a3 3 0 01-3-3V16a3 3 0 013-3h36zm0 2H9a1 1 0 00-1 1v22a1 1 0 001 1h36a1 1 0 001-1V16a1 1 0 00-1-1zm-1.136 15.5l.848.849-6.363 6.363-.849-.848 6.364-6.364zm.264 3.5l.849.849-2.828 2.828-.849-.849L44.128 34zM13 19v10h-2V19h2z"
|
|
3513
|
+
})));
|
|
3514
|
+
|
|
3515
|
+
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
3516
|
+
var ImageIcon = (({
|
|
3517
|
+
styles = {},
|
|
3518
|
+
...props
|
|
3519
|
+
}) => /*#__PURE__*/React__default['default'].createElement("svg", _extends({
|
|
3520
|
+
width: "54",
|
|
3521
|
+
height: "54",
|
|
3522
|
+
fill: "none",
|
|
3523
|
+
xmlns: "http://www.w3.org/2000/svg"
|
|
3524
|
+
}, props), /*#__PURE__*/React__default['default'].createElement("path", {
|
|
3525
|
+
fillRule: "evenodd",
|
|
3526
|
+
clipRule: "evenodd",
|
|
3527
|
+
d: "M34.636 21.91A3.818 3.818 0 1127 21.908a3.818 3.818 0 017.636 0zm-2 0A1.818 1.818 0 1129 21.908a1.818 1.818 0 013.636 0z",
|
|
3528
|
+
fill: "#000"
|
|
3529
|
+
}), /*#__PURE__*/React__default['default'].createElement("path", {
|
|
3530
|
+
fillRule: "evenodd",
|
|
3531
|
+
clipRule: "evenodd",
|
|
3532
|
+
d: "M15 13a2 2 0 00-2 2v24a2 2 0 002 2h24a2 2 0 002-2V15a2 2 0 00-2-2H15zm24 2H15v12.45l4.71-4.709a1.91 1.91 0 012.702 0l6.695 6.695 2.656-1.77a1.91 1.91 0 012.411.239L39 32.73V15zM15 39v-8.754c.06-.038.116-.083.168-.135l5.893-5.893 6.684 6.685a1.911 1.911 0 002.41.238l2.657-1.77 6.02 6.02c.052.051.108.097.168.135V39H15z",
|
|
3533
|
+
fill: "#000"
|
|
3534
|
+
})));
|
|
3535
|
+
|
|
3536
|
+
const iconsByType = {
|
|
3537
|
+
button: ButtonIcon,
|
|
3538
|
+
checkbox: CheckboxIcon,
|
|
3539
|
+
checklist: ChecklistIcon,
|
|
3540
|
+
columns: ColumnsIcon,
|
|
3541
|
+
datetime: DatetimeIcon,
|
|
3542
|
+
image: ImageIcon,
|
|
3543
|
+
number: NumberIcon,
|
|
3544
|
+
radio: RadioIcon,
|
|
3545
|
+
select: SelectIcon,
|
|
3546
|
+
taglist: TaglistIcon,
|
|
3547
|
+
text: TextIcon,
|
|
3548
|
+
textfield: TextfieldIcon,
|
|
3549
|
+
textarea: TextareaIcon,
|
|
3550
|
+
default: FormIcon
|
|
3551
|
+
};
|
|
3552
|
+
|
|
2489
3553
|
const type$2 = 'text';
|
|
2490
3554
|
function Text(props) {
|
|
2491
3555
|
const {
|
|
2492
|
-
field
|
|
3556
|
+
field,
|
|
3557
|
+
disabled
|
|
2493
3558
|
} = props;
|
|
2494
3559
|
const {
|
|
2495
3560
|
text = ''
|
|
2496
3561
|
} = field;
|
|
3562
|
+
const textValue = useExpressionValue(text) || '';
|
|
2497
3563
|
return jsxRuntime.jsx("div", {
|
|
2498
3564
|
class: formFieldClasses(type$2),
|
|
2499
|
-
children:
|
|
2500
|
-
markup: safeMarkdown(text),
|
|
2501
|
-
trim: false
|
|
2502
|
-
})
|
|
3565
|
+
children: renderText(field, textValue, disabled)
|
|
2503
3566
|
});
|
|
2504
3567
|
}
|
|
2505
3568
|
Text.create = function (options = {}) {
|
|
@@ -2511,6 +3574,37 @@ Text.create = function (options = {}) {
|
|
|
2511
3574
|
Text.type = type$2;
|
|
2512
3575
|
Text.keyed = false;
|
|
2513
3576
|
|
|
3577
|
+
// helper //////////////
|
|
3578
|
+
|
|
3579
|
+
function renderText(field, content, disabled) {
|
|
3580
|
+
const {
|
|
3581
|
+
text
|
|
3582
|
+
} = field;
|
|
3583
|
+
const Icon = iconsByType['text'];
|
|
3584
|
+
if (disabled) {
|
|
3585
|
+
if (!text) {
|
|
3586
|
+
return jsxRuntime.jsxs("div", {
|
|
3587
|
+
class: "fjs-form-field-placeholder",
|
|
3588
|
+
children: [jsxRuntime.jsx(Icon, {
|
|
3589
|
+
viewBox: "0 0 54 54"
|
|
3590
|
+
}), "Text view is empty"]
|
|
3591
|
+
});
|
|
3592
|
+
}
|
|
3593
|
+
if (isExpression$2(text)) {
|
|
3594
|
+
return jsxRuntime.jsxs("div", {
|
|
3595
|
+
class: "fjs-form-field-placeholder",
|
|
3596
|
+
children: [jsxRuntime.jsx(Icon, {
|
|
3597
|
+
viewBox: "0 0 54 54"
|
|
3598
|
+
}), "Text view is populated by an expression"]
|
|
3599
|
+
});
|
|
3600
|
+
}
|
|
3601
|
+
}
|
|
3602
|
+
return jsxRuntime.jsx(Markup__default['default'], {
|
|
3603
|
+
markup: safeMarkdown(content),
|
|
3604
|
+
trim: false
|
|
3605
|
+
});
|
|
3606
|
+
}
|
|
3607
|
+
|
|
2514
3608
|
const type$1 = 'textfield';
|
|
2515
3609
|
function Textfield(props) {
|
|
2516
3610
|
const {
|
|
@@ -2523,8 +3617,13 @@ function Textfield(props) {
|
|
|
2523
3617
|
description,
|
|
2524
3618
|
id,
|
|
2525
3619
|
label,
|
|
3620
|
+
appearance = {},
|
|
2526
3621
|
validate = {}
|
|
2527
3622
|
} = field;
|
|
3623
|
+
const {
|
|
3624
|
+
prefixAdorner,
|
|
3625
|
+
suffixAdorner
|
|
3626
|
+
} = appearance;
|
|
2528
3627
|
const {
|
|
2529
3628
|
required
|
|
2530
3629
|
} = validate;
|
|
@@ -2548,13 +3647,18 @@ function Textfield(props) {
|
|
|
2548
3647
|
id: prefixId(id, formId),
|
|
2549
3648
|
label: label,
|
|
2550
3649
|
required: required
|
|
2551
|
-
}), jsxRuntime.jsx(
|
|
2552
|
-
class: "fjs-input",
|
|
3650
|
+
}), jsxRuntime.jsx(InputAdorner, {
|
|
2553
3651
|
disabled: disabled,
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
3652
|
+
pre: prefixAdorner,
|
|
3653
|
+
post: suffixAdorner,
|
|
3654
|
+
children: jsxRuntime.jsx("input", {
|
|
3655
|
+
class: "fjs-input",
|
|
3656
|
+
disabled: disabled,
|
|
3657
|
+
id: prefixId(id, formId),
|
|
3658
|
+
onInput: onChange,
|
|
3659
|
+
type: "text",
|
|
3660
|
+
value: value
|
|
3661
|
+
})
|
|
2558
3662
|
}), jsxRuntime.jsx(Description, {
|
|
2559
3663
|
description: description
|
|
2560
3664
|
}), jsxRuntime.jsx(Errors, {
|
|
@@ -2656,7 +3760,7 @@ Textarea.sanitizeValue = ({
|
|
|
2656
3760
|
value
|
|
2657
3761
|
}) => minDash.isArray(value) || minDash.isObject(value) ? '' : String(value);
|
|
2658
3762
|
|
|
2659
|
-
const formFields = [Button, Checkbox, Checklist, Default, Image, Numberfield, Radio, Select, Taglist, Text, Textfield, Textarea];
|
|
3763
|
+
const formFields = [Button, Checkbox, Checklist, Default, Image, Numberfield, Datetime, Radio, Select, Taglist, Text, Textfield, Textarea];
|
|
2660
3764
|
|
|
2661
3765
|
class FormFields {
|
|
2662
3766
|
constructor() {
|
|
@@ -3136,6 +4240,12 @@ function createForm(options) {
|
|
|
3136
4240
|
exports.Button = Button;
|
|
3137
4241
|
exports.Checkbox = Checkbox;
|
|
3138
4242
|
exports.Checklist = Checklist;
|
|
4243
|
+
exports.DATETIME_SUBTYPES = DATETIME_SUBTYPES;
|
|
4244
|
+
exports.DATETIME_SUBTYPES_LABELS = DATETIME_SUBTYPES_LABELS;
|
|
4245
|
+
exports.DATETIME_SUBTYPE_PATH = DATETIME_SUBTYPE_PATH;
|
|
4246
|
+
exports.DATE_DISALLOW_PAST_PATH = DATE_DISALLOW_PAST_PATH;
|
|
4247
|
+
exports.DATE_LABEL_PATH = DATE_LABEL_PATH;
|
|
4248
|
+
exports.Datetime = Datetime;
|
|
3139
4249
|
exports.Default = Default;
|
|
3140
4250
|
exports.Form = Form;
|
|
3141
4251
|
exports.FormComponent = FormComponent;
|
|
@@ -3144,13 +4254,25 @@ exports.FormFieldRegistry = FormFieldRegistry;
|
|
|
3144
4254
|
exports.FormFields = FormFields;
|
|
3145
4255
|
exports.FormRenderContext = FormRenderContext;
|
|
3146
4256
|
exports.Image = Image;
|
|
4257
|
+
exports.MINUTES_IN_DAY = MINUTES_IN_DAY;
|
|
3147
4258
|
exports.Numberfield = Numberfield;
|
|
3148
4259
|
exports.Radio = Radio;
|
|
3149
4260
|
exports.Select = Select;
|
|
4261
|
+
exports.TIME_INTERVAL_PATH = TIME_INTERVAL_PATH;
|
|
4262
|
+
exports.TIME_LABEL_PATH = TIME_LABEL_PATH;
|
|
4263
|
+
exports.TIME_SERIALISINGFORMAT_LABELS = TIME_SERIALISINGFORMAT_LABELS;
|
|
4264
|
+
exports.TIME_SERIALISING_FORMATS = TIME_SERIALISING_FORMATS;
|
|
4265
|
+
exports.TIME_SERIALISING_FORMAT_PATH = TIME_SERIALISING_FORMAT_PATH;
|
|
4266
|
+
exports.TIME_USE24H_PATH = TIME_USE24H_PATH;
|
|
3150
4267
|
exports.Taglist = Taglist;
|
|
3151
4268
|
exports.Text = Text;
|
|
3152
4269
|
exports.Textarea = Textarea;
|
|
3153
4270
|
exports.Textfield = Textfield;
|
|
4271
|
+
exports.VALUES_SOURCES = VALUES_SOURCES;
|
|
4272
|
+
exports.VALUES_SOURCES_DEFAULTS = VALUES_SOURCES_DEFAULTS;
|
|
4273
|
+
exports.VALUES_SOURCES_LABELS = VALUES_SOURCES_LABELS;
|
|
4274
|
+
exports.VALUES_SOURCES_PATHS = VALUES_SOURCES_PATHS;
|
|
4275
|
+
exports.VALUES_SOURCE_DEFAULT = VALUES_SOURCE_DEFAULT;
|
|
3154
4276
|
exports.clone = clone;
|
|
3155
4277
|
exports.createForm = createForm;
|
|
3156
4278
|
exports.createFormContainer = createFormContainer;
|
|
@@ -3160,6 +4282,8 @@ exports.formFields = formFields;
|
|
|
3160
4282
|
exports.generateIdForType = generateIdForType;
|
|
3161
4283
|
exports.generateIndexForType = generateIndexForType;
|
|
3162
4284
|
exports.getSchemaVariables = getSchemaVariables;
|
|
4285
|
+
exports.getValuesSource = getValuesSource;
|
|
4286
|
+
exports.iconsByType = iconsByType;
|
|
3163
4287
|
exports.isRequired = isRequired;
|
|
3164
4288
|
exports.pathParse = pathParse;
|
|
3165
4289
|
exports.pathStringify = pathStringify;
|