@k-int/stripes-kint-components 5.2.3 → 5.3.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/CHANGELOG.md +15 -0
- package/es/index.js +8 -0
- package/es/lib/ActionList/ActionListFieldArray.js +61 -43
- package/es/lib/ComboButton/ComboButton.js +6 -5
- package/es/lib/CustomProperties/Config/CustomPropertiesLookup.js +7 -4
- package/es/lib/CustomProperties/Config/CustomPropertiesSettings.js +32 -30
- package/es/lib/CustomProperties/Config/CustomPropertyForm.js +58 -58
- package/es/lib/CustomProperties/Config/CustomPropertyForm.test.js +2 -2
- package/es/lib/CustomProperties/Config/CustomPropertyView.js +33 -32
- package/es/lib/CustomProperties/Config/CustomPropertyView.test.js +1 -1
- package/es/lib/CustomProperties/Edit/CustomPropertiesEdit.js +1 -1
- package/es/lib/CustomProperties/Edit/CustomPropertiesEditCtx.js +3 -3
- package/es/lib/CustomProperties/Edit/CustomPropertiesListField.js +10 -5
- package/es/lib/CustomProperties/Edit/CustomPropertyField.js +25 -19
- package/es/lib/CustomProperties/Edit/CustomPropertyField.test.js +5 -5
- package/es/lib/CustomProperties/Edit/CustomPropertyFormCard.js +2 -2
- package/es/lib/CustomProperties/Edit/CustomPropertyFormCard.test.js +1 -1
- package/es/lib/CustomProperties/Edit/testResources.js +12 -11
- package/es/lib/CustomProperties/Filter/CustomPropertiesFilter.js +11 -7
- package/es/lib/CustomProperties/Filter/CustomPropertiesFilterField.js +28 -20
- package/es/lib/CustomProperties/Filter/CustomPropertiesFilterField.test.js +1 -1
- package/es/lib/CustomProperties/Filter/CustomPropertiesFilterFieldArray.js +6 -6
- package/es/lib/CustomProperties/Filter/CustomPropertiesRule.js +8 -8
- package/es/lib/CustomProperties/Filter/testResources.js +2 -1
- package/es/lib/CustomProperties/Filter/useParseActiveFilterStrings.js +2 -1
- package/es/lib/CustomProperties/View/CustomPropertiesView.js +1 -1
- package/es/lib/CustomProperties/View/CustomPropertiesViewCtx.js +26 -19
- package/es/lib/CustomProperties/View/CustomPropertyCard.js +11 -7
- package/es/lib/CycleButton/CycleButton.js +1 -1
- package/es/lib/EditableRefdataCategoryList/EditableRefdataCategoryList.js +82 -29
- package/es/lib/EditableRefdataList/EditableRefdataList.js +33 -27
- package/es/lib/EditableSettingsList/EditableSettingsListFieldArray.js +1 -1
- package/es/lib/EditableSettingsList/SettingField/EditSettingValue.js +5 -6
- package/es/lib/EditableSettingsList/SettingField/RenderSettingValue.js +12 -10
- package/es/lib/EditableSettingsList/SettingField/RenderSettingValue.test.js +0 -1
- package/es/lib/EditableSettingsList/SettingField/SettingField.js +4 -4
- package/es/lib/FormattedKintMessage/FormattedKintMessage.js +7 -4
- package/es/lib/IconSelect/IconSelect.js +9 -5
- package/es/lib/NoResultsMessage/NoResultsMessage.js +4 -4
- package/es/lib/RefdataButtons/RefdataButtons.js +3 -3
- package/es/lib/RefdataCategoriesSettings/RefdataCategoriesSettings.js +158 -0
- package/es/lib/RefdataCategoriesSettings/index.js +13 -0
- package/es/lib/ResponsiveButtonGroup/ResponsiveButtonGroup.js +28 -21
- package/es/lib/ResponsiveButtonGroup/useResponsiveButtonGroupSizing.js +6 -5
- package/es/lib/RichSelect/RichSelect.js +19 -14
- package/es/lib/RichSelect/useSelectedOption.js +2 -1
- package/es/lib/SASQLookupComponent/SASQLookupComponent.js +17 -14
- package/es/lib/SASQLookupComponent/TableBody/TableBody.js +6 -4
- package/es/lib/SASQRoute/SASQRoute.js +2 -2
- package/es/lib/SASQViewComponent/SASQViewComponent.js +9 -5
- package/es/lib/SettingPage/SettingPagePane.js +2 -2
- package/es/lib/SettingsFormContainer/SettingsFormContainer.js +2 -3
- package/es/lib/Typedown/Typedown.js +26 -20
- package/es/lib/hooks/__mocks__/index.js +4 -0
- package/es/lib/hooks/index.js +7 -0
- package/es/lib/hooks/typedownHooks/useTypedown.js +2 -2
- package/es/lib/hooks/typedownHooks/useTypedownToggle.js +2 -2
- package/es/lib/hooks/useActionListRef.js +34 -0
- package/es/lib/hooks/useActiveElement.js +1 -1
- package/es/lib/hooks/useCustomProperties.js +2 -2
- package/es/lib/hooks/useHelperApp.js +6 -6
- package/es/lib/hooks/useIntlKeyStore.js +7 -4
- package/es/lib/hooks/useKintIntl.js +11 -5
- package/es/lib/hooks/useKiwtSASQuery.js +1 -1
- package/es/lib/hooks/useModConfigEntries.js +2 -2
- package/es/lib/hooks/useMutateCustomProperties.js +8 -8
- package/es/lib/hooks/useMutateModConfigEntry.js +2 -2
- package/es/lib/hooks/useMutateRefdataCategory.js +4 -4
- package/es/lib/hooks/useMutateRefdataValue.js +6 -6
- package/es/lib/hooks/useQIndex.js +17 -9
- package/es/lib/hooks/useRefdata.js +3 -3
- package/es/lib/hooks/useTemplates.js +4 -4
- package/es/lib/settingsHooks/useAppSettings.js +11 -7
- package/es/lib/settingsHooks/useSettingSection.js +2 -2
- package/es/lib/settingsHooks/useSettings.js +3 -3
- package/es/lib/utils/buildUrl.js +3 -2
- package/es/lib/utils/filterParsers/deparseKiwtQueryFilters.js +5 -5
- package/es/lib/utils/filterParsers/parseKiwtQueryFilters.js +2 -2
- package/es/lib/utils/filterParsers/parseKiwtQueryGroups.js +5 -4
- package/es/lib/utils/filterParsers/parseKiwtQueryString.js +3 -2
- package/es/lib/utils/generateKiwtQueryParams.js +37 -28
- package/es/lib/utils/groupCustomPropertiesByCtx.js +3 -2
- package/es/lib/utils/matchString.js +1 -1
- package/es/lib/utils/parseErrorResponse.js +3 -2
- package/es/lib/utils/parseModConfigEntry.js +0 -1
- package/es/lib/utils/selectorSafe.js +3 -2
- package/es/lib/utils/sortByLabel.js +3 -2
- package/es/lib/validators/validators.js +3 -3
- package/package.json +1 -1
- package/src/index.js +3 -0
- package/src/lib/ActionList/ActionListFieldArray.js +29 -15
- package/src/lib/EditableRefdataCategoryList/EditableRefdataCategoryList.js +67 -13
- package/src/lib/RefdataCategoriesSettings/RefdataCategoriesSettings.js +176 -0
- package/src/lib/RefdataCategoriesSettings/index.js +1 -0
- package/src/lib/hooks/__mocks__/index.js +4 -0
- package/src/lib/hooks/index.js +1 -0
- package/src/lib/hooks/useActionListRef.js +36 -0
- package/src/lib/hooks/useQIndex.js +12 -4
|
@@ -17,36 +17,40 @@ const conditionalEncodeURIComponent = function (str) {
|
|
|
17
17
|
const buildFilterOptionBlock = function (opf) {
|
|
18
18
|
let isNested = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
19
19
|
let encode = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
|
|
20
|
-
if (opf
|
|
20
|
+
if (opf !== null && opf !== void 0 && opf.groupValues) {
|
|
21
21
|
const groupValues = opf.groupValues;
|
|
22
22
|
|
|
23
23
|
// Small utility function to add negation and brackets to the options block where necessary
|
|
24
|
-
const negationAndNesting = str =>
|
|
24
|
+
const negationAndNesting = str => "".concat(groupValues !== null && groupValues !== void 0 && groupValues.NOT ? '!' : '').concat(isNested || groupValues !== null && groupValues !== void 0 && groupValues.NOT ? '(' : '').concat(str).concat(isNested || groupValues !== null && groupValues !== void 0 && groupValues.NOT ? ')' : '');
|
|
25
25
|
|
|
26
26
|
// First check whether groupValues is ANDed or ORed together
|
|
27
|
-
if (groupValues
|
|
27
|
+
if (groupValues !== null && groupValues !== void 0 && groupValues.AND && Array.isArray(groupValues.AND) || groupValues !== null && groupValues !== void 0 && groupValues.OR && Array.isArray(groupValues.OR)) {
|
|
28
|
+
var _groupValues$OR;
|
|
28
29
|
// AND takes precedence
|
|
29
30
|
if (groupValues.AND) {
|
|
30
|
-
|
|
31
|
+
var _groupValues$AND;
|
|
32
|
+
return negationAndNesting(groupValues === null || groupValues === void 0 || (_groupValues$AND = groupValues.AND) === null || _groupValues$AND === void 0 || (_groupValues$AND = _groupValues$AND.map(gvo => buildFilterOptionBlock(gvo, true, encode))) === null || _groupValues$AND === void 0 ? void 0 : _groupValues$AND.join('&&'));
|
|
31
33
|
}
|
|
32
|
-
return negationAndNesting(groupValues
|
|
34
|
+
return negationAndNesting(groupValues === null || groupValues === void 0 || (_groupValues$OR = groupValues.OR) === null || _groupValues$OR === void 0 || (_groupValues$OR = _groupValues$OR.map(gvo => buildFilterOptionBlock(gvo, true, encode))) === null || _groupValues$OR === void 0 ? void 0 : _groupValues$OR.join('||'));
|
|
33
35
|
}
|
|
34
36
|
// If neither valid OR nor AND exist, ignore the block
|
|
35
|
-
} else if (opf
|
|
37
|
+
} else if (opf !== null && opf !== void 0 && opf.values) {
|
|
36
38
|
// Build the values filter block
|
|
37
39
|
const innerFilters = [];
|
|
38
40
|
opf.values.forEach(opfv => {
|
|
39
41
|
if (opf.path) {
|
|
40
|
-
|
|
42
|
+
var _opf$comparator;
|
|
43
|
+
innerFilters.push("".concat(opf.path).concat((_opf$comparator = opf.comparator) !== null && _opf$comparator !== void 0 ? _opf$comparator : '==').concat(opfv));
|
|
41
44
|
} else {
|
|
42
45
|
innerFilters.push(opfv);
|
|
43
46
|
}
|
|
44
47
|
});
|
|
45
48
|
return conditionalEncodeURIComponent(innerFilters.join('||'), encode);
|
|
46
|
-
} else if (opf
|
|
49
|
+
} else if (opf !== null && opf !== void 0 && opf.value) {
|
|
47
50
|
// If no value OR values, then ignore
|
|
48
51
|
if (opf.path) {
|
|
49
|
-
|
|
52
|
+
var _opf$comparator2;
|
|
53
|
+
const filterString = "".concat(opf.path).concat((_opf$comparator2 = opf.comparator) !== null && _opf$comparator2 !== void 0 ? _opf$comparator2 : '==').concat(opf.value);
|
|
50
54
|
return conditionalEncodeURIComponent(filterString, encode);
|
|
51
55
|
}
|
|
52
56
|
return conditionalEncodeURIComponent(opf.value, encode);
|
|
@@ -104,8 +108,9 @@ const generateKiwtQueryParams = function (options, nsValues) {
|
|
|
104
108
|
} = options;
|
|
105
109
|
const paramsArray = [];
|
|
106
110
|
if (query) {
|
|
107
|
-
|
|
108
|
-
paramsArray.push(
|
|
111
|
+
var _split, _ref;
|
|
112
|
+
paramsArray.push(...((_split = (_ref = qindex || searchKey) === null || _ref === void 0 ? void 0 : _ref.split(',')) !== null && _split !== void 0 ? _split : []).map(m => "match=".concat(conditionalEncodeURIComponent(m, encode))));
|
|
113
|
+
paramsArray.push("term=".concat(conditionalEncodeURIComponent(query, encode)));
|
|
109
114
|
}
|
|
110
115
|
|
|
111
116
|
// Actually build the optionsFilters block (Moved logic to its own function to allow recursion)
|
|
@@ -113,67 +118,71 @@ const generateKiwtQueryParams = function (options, nsValues) {
|
|
|
113
118
|
optionsFilters.forEach(opf => {
|
|
114
119
|
const optionsBlock = buildFilterOptionBlock(opf, false, encode);
|
|
115
120
|
if (optionsBlock) {
|
|
116
|
-
paramsArray.push(
|
|
121
|
+
paramsArray.push("filters=".concat(optionsBlock));
|
|
117
122
|
}
|
|
118
123
|
});
|
|
119
124
|
}
|
|
120
125
|
if (filters) {
|
|
121
126
|
const filterMap = {};
|
|
122
127
|
filters.split(',').forEach(filter => {
|
|
123
|
-
|
|
128
|
+
var _filter$trim$split, _filter$trim;
|
|
129
|
+
const [filterName, ...filterRest] = (_filter$trim$split = (_filter$trim = filter.trim()) === null || _filter$trim === void 0 ? void 0 : _filter$trim.split('.')) !== null && _filter$trim$split !== void 0 ? _filter$trim$split : [];
|
|
124
130
|
const filterValue = filterRest.join('.');
|
|
125
131
|
if (filterMap[filterName] === undefined) filterMap[filterName] = [];
|
|
126
132
|
filterMap[filterName].push(filterValue);
|
|
127
133
|
});
|
|
128
134
|
|
|
129
135
|
// We now have a filterMap of shape { status: ['active', 'cancelled'], type: ['local'] }
|
|
130
|
-
Object.entries(filterMap).forEach(
|
|
131
|
-
let [filterName, filterValues] =
|
|
136
|
+
Object.entries(filterMap).forEach(_ref2 => {
|
|
137
|
+
let [filterName, filterValues] = _ref2;
|
|
132
138
|
const filterConfigEntry = filterConfig.find(conf => conf.name === filterName);
|
|
133
139
|
const filterKey = filterKeys[filterName];
|
|
134
140
|
if (filterConfigEntry) {
|
|
135
141
|
// We have a direct mapping instruction, use it
|
|
136
142
|
const filterString = filterValues.map(v => {
|
|
137
|
-
|
|
138
|
-
|
|
143
|
+
var _filterConfigEntry$va;
|
|
144
|
+
const fceValue = filterConfigEntry === null || filterConfigEntry === void 0 || (_filterConfigEntry$va = filterConfigEntry.values) === null || _filterConfigEntry$va === void 0 || (_filterConfigEntry$va = _filterConfigEntry$va.find(fce => fce.name === v)) === null || _filterConfigEntry$va === void 0 ? void 0 : _filterConfigEntry$va.value;
|
|
145
|
+
return "".concat(filterName, "==").concat(fceValue !== null && fceValue !== void 0 ? fceValue : v);
|
|
139
146
|
}).join('||');
|
|
140
|
-
paramsArray.push(
|
|
147
|
+
paramsArray.push("filters=".concat(conditionalEncodeURIComponent(filterString, encode)));
|
|
141
148
|
} else if (!filterKey) {
|
|
142
149
|
// These filters have no key mapping so we just pass the values to the backend as-is.
|
|
143
|
-
paramsArray.push(...(filterValues
|
|
150
|
+
paramsArray.push(...(filterValues !== null && filterValues !== void 0 ? filterValues : []).map(f => "filters=".concat(conditionalEncodeURIComponent(f, encode))));
|
|
144
151
|
} else {
|
|
145
|
-
const filterString = filterValues.map(v =>
|
|
146
|
-
paramsArray.push(
|
|
152
|
+
const filterString = filterValues.map(v => "".concat(filterKey, "==").concat(v)).join('||');
|
|
153
|
+
paramsArray.push("filters=".concat(conditionalEncodeURIComponent(filterString, encode)));
|
|
147
154
|
}
|
|
148
155
|
});
|
|
149
156
|
}
|
|
150
157
|
if (optionsSort && optionsSort.length > 0) {
|
|
151
158
|
optionsSort.forEach(os => {
|
|
152
159
|
if (os.value) {
|
|
153
|
-
paramsArray.push(
|
|
160
|
+
paramsArray.push("sort=".concat(conditionalEncodeURIComponent(os.value, encode)));
|
|
154
161
|
} else if (os.path) {
|
|
162
|
+
var _os$direction;
|
|
155
163
|
// If no path then ignore
|
|
156
|
-
const sortString =
|
|
157
|
-
paramsArray.push(
|
|
164
|
+
const sortString = "".concat(os.path, ";").concat((_os$direction = os.direction) !== null && _os$direction !== void 0 ? _os$direction : 'asc');
|
|
165
|
+
paramsArray.push("sort=".concat(conditionalEncodeURIComponent(sortString, encode)));
|
|
158
166
|
}
|
|
159
167
|
});
|
|
160
168
|
}
|
|
161
169
|
if (sort) {
|
|
162
|
-
|
|
170
|
+
var _sort$trim$split, _sort$trim;
|
|
171
|
+
paramsArray.push(...((_sort$trim$split = (_sort$trim = sort.trim()) === null || _sort$trim === void 0 ? void 0 : _sort$trim.split(',')) !== null && _sort$trim$split !== void 0 ? _sort$trim$split : []).map(sortKey => {
|
|
163
172
|
const descending = sortKey.startsWith('-');
|
|
164
173
|
let term = sortKey.replace('-', '');
|
|
165
174
|
if (term in sortKeys) {
|
|
166
175
|
term = term.replace(term, sortKeys[term]);
|
|
167
176
|
}
|
|
168
|
-
const sortString =
|
|
169
|
-
return
|
|
177
|
+
const sortString = "".concat(term, ";").concat(descending ? 'desc' : 'asc');
|
|
178
|
+
return "sort=".concat(conditionalEncodeURIComponent(sortString, encode));
|
|
170
179
|
}));
|
|
171
180
|
}
|
|
172
181
|
if (stats) {
|
|
173
182
|
paramsArray.push('stats=true');
|
|
174
183
|
}
|
|
175
184
|
for (const [key, value] of Object.entries(rest)) {
|
|
176
|
-
paramsArray.push(
|
|
185
|
+
paramsArray.push("".concat(key, "=").concat(conditionalEncodeURIComponent(value, encode)));
|
|
177
186
|
}
|
|
178
187
|
return paramsArray;
|
|
179
188
|
};
|
|
@@ -7,11 +7,12 @@ exports.default = void 0;
|
|
|
7
7
|
const groupCustomPropertiesByCtx = function () {
|
|
8
8
|
let customProperties = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
9
9
|
return customProperties.reduce((acc, curr) => {
|
|
10
|
-
|
|
10
|
+
var _curr$ctx, _acc$ctx;
|
|
11
|
+
const ctx = (_curr$ctx = curr.ctx) !== null && _curr$ctx !== void 0 ? _curr$ctx : 'isNull';
|
|
11
12
|
const returnObj = {
|
|
12
13
|
...acc
|
|
13
14
|
};
|
|
14
|
-
returnObj[ctx] = [...(acc
|
|
15
|
+
returnObj[ctx] = [...((_acc$ctx = acc === null || acc === void 0 ? void 0 : acc[ctx]) !== null && _acc$ctx !== void 0 ? _acc$ctx : []), curr];
|
|
15
16
|
return returnObj;
|
|
16
17
|
}, {});
|
|
17
18
|
};
|
|
@@ -8,7 +8,7 @@ var _escapeRegExp = _interopRequireDefault(require("lodash/escapeRegExp"));
|
|
|
8
8
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
9
9
|
const matchString = function (match, str) {
|
|
10
10
|
let ignoreNull = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
|
|
11
|
-
const regex = new RegExp(
|
|
11
|
+
const regex = new RegExp("".concat(match.split(/(\s+)/).filter(h => h.trim()).map(hl => '(' + (0, _escapeRegExp.default)(hl) + ')').join('|')), 'gi');
|
|
12
12
|
if (ignoreNull && !match) {
|
|
13
13
|
const nullRegex = /a^/gi; // Should match nothing
|
|
14
14
|
|
|
@@ -5,9 +5,10 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
const parseErrorResponse = async responseObj => {
|
|
8
|
+
var _ref;
|
|
8
9
|
let errorResp;
|
|
9
|
-
const code = responseObj
|
|
10
|
-
const contentType = [...responseObj
|
|
10
|
+
const code = responseObj === null || responseObj === void 0 ? void 0 : responseObj.status;
|
|
11
|
+
const contentType = (_ref = [...(responseObj === null || responseObj === void 0 ? void 0 : responseObj.headers)]) === null || _ref === void 0 || (_ref = _ref.find(header => header[0] === 'content-type')) === null || _ref === void 0 ? void 0 : _ref[1];
|
|
11
12
|
if (contentType.includes('json')) {
|
|
12
13
|
errorResp = await responseObj.json();
|
|
13
14
|
} else {
|
|
@@ -5,11 +5,12 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
const selectorSafe = string => {
|
|
8
|
+
var _string$normalize;
|
|
8
9
|
// Normalise to separate diacritics from their base characters as "marks"
|
|
9
10
|
// then strip out all marks.
|
|
10
|
-
return string.normalize('NFKD')
|
|
11
|
+
return (_string$normalize = string.normalize('NFKD')) === null || _string$normalize === void 0 || (_string$normalize = _string$normalize.replace(/\p{M}/gu, '')
|
|
11
12
|
// Then swap out any non-letter/number characters (Also ignore - and _) for `_`
|
|
12
|
-
|
|
13
|
+
) === null || _string$normalize === void 0 ? void 0 : _string$normalize.replace(/[^\p{L}\p{N}\-_]/gu, '_');
|
|
13
14
|
};
|
|
14
15
|
var _default = exports.default = selectorSafe;
|
|
15
16
|
/*
|
|
@@ -5,8 +5,9 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
const sortByLabel = (a, b) => {
|
|
8
|
-
|
|
9
|
-
const
|
|
8
|
+
var _a$label$toLowerCase, _a$label, _a$id, _b$label$toLowerCase, _b$label, _b$id;
|
|
9
|
+
const al = (_a$label$toLowerCase = (_a$label = a.label) === null || _a$label === void 0 ? void 0 : _a$label.toLowerCase()) !== null && _a$label$toLowerCase !== void 0 ? _a$label$toLowerCase : (_a$id = a.id) === null || _a$id === void 0 ? void 0 : _a$id.toLowerCase();
|
|
10
|
+
const bl = (_b$label$toLowerCase = (_b$label = b.label) === null || _b$label === void 0 ? void 0 : _b$label.toLowerCase()) !== null && _b$label$toLowerCase !== void 0 ? _b$label$toLowerCase : (_b$id = b.id) === null || _b$id === void 0 ? void 0 : _b$id.toLowerCase();
|
|
10
11
|
if (al < bl) {
|
|
11
12
|
return -1;
|
|
12
13
|
}
|
|
@@ -64,7 +64,7 @@ const invalidNumber = function (value, _min, _max, intlKey, intlNS) {
|
|
|
64
64
|
id: "errors.invalidNumber",
|
|
65
65
|
intlKey: intlKey,
|
|
66
66
|
intlNS: intlNS,
|
|
67
|
-
overrideValue: labelOverrides
|
|
67
|
+
overrideValue: labelOverrides === null || labelOverrides === void 0 ? void 0 : labelOverrides.invalidNumberError
|
|
68
68
|
});
|
|
69
69
|
}
|
|
70
70
|
return undefined;
|
|
@@ -77,7 +77,7 @@ const rangeOverflow = function (value, min, max, intlKey, intlNS) {
|
|
|
77
77
|
id: "errors.decimalValueNotInRange",
|
|
78
78
|
intlKey: intlKey,
|
|
79
79
|
intlNS: intlNS,
|
|
80
|
-
overrideValue: labelOverrides
|
|
80
|
+
overrideValue: labelOverrides === null || labelOverrides === void 0 ? void 0 : labelOverrides.decimalValueNotInRangeError,
|
|
81
81
|
values: {
|
|
82
82
|
min,
|
|
83
83
|
max
|
|
@@ -94,7 +94,7 @@ const rangeUnderflow = function (value, min, max, intlKey, intlNS) {
|
|
|
94
94
|
id: "errors.decimalValueNotInRange",
|
|
95
95
|
intlKey: intlKey,
|
|
96
96
|
intlNS: intlNS,
|
|
97
|
-
overrideValue: labelOverrides
|
|
97
|
+
overrideValue: labelOverrides === null || labelOverrides === void 0 ? void 0 : labelOverrides.decimalValueNotInRangeError,
|
|
98
98
|
values: {
|
|
99
99
|
min,
|
|
100
100
|
max
|
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -92,6 +92,9 @@ export {
|
|
|
92
92
|
useParseActiveFilterStrings
|
|
93
93
|
} from './lib/CustomProperties';
|
|
94
94
|
|
|
95
|
+
// Refdata categories
|
|
96
|
+
export { default as RefdataCategoriesSettings } from './lib/RefdataCategoriesSettings';
|
|
97
|
+
|
|
95
98
|
export * as customPropertyConstants from './lib/constants/customProperties';
|
|
96
99
|
|
|
97
100
|
export * as endpoints from './lib/constants/endpoints';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { forwardRef, useImperativeHandle, useState } from 'react';
|
|
1
|
+
import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useState } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
|
|
4
4
|
import get from 'lodash/get';
|
|
@@ -70,6 +70,8 @@ ActionTrigger.propTypes = {
|
|
|
70
70
|
})
|
|
71
71
|
};
|
|
72
72
|
|
|
73
|
+
const NEW_ROW = 'NEW_ROW';
|
|
74
|
+
|
|
73
75
|
const ActionListFieldArray = forwardRef(({
|
|
74
76
|
actionAssigner,
|
|
75
77
|
columnMapping,
|
|
@@ -100,21 +102,29 @@ const ActionListFieldArray = forwardRef(({
|
|
|
100
102
|
null for no field, string id if we are editing an existing field and
|
|
101
103
|
'NEW_ROW' for a new row
|
|
102
104
|
*/
|
|
103
|
-
const [editing, setEditing] = useState(
|
|
105
|
+
const [editing, setEditing] = useState((fields?.value?.filter(f => f._isNewActionListRow)?.length ?? 0) > 0 ? NEW_ROW : undefined);
|
|
104
106
|
|
|
105
|
-
const toggleEditing = (id) => {
|
|
107
|
+
const toggleEditing = useCallback((id) => {
|
|
106
108
|
if (editing) {
|
|
107
|
-
setEditing(
|
|
109
|
+
setEditing();
|
|
108
110
|
} else {
|
|
109
111
|
setEditing(id);
|
|
110
112
|
}
|
|
111
|
-
};
|
|
113
|
+
}, [editing]);
|
|
114
|
+
|
|
115
|
+
// Ensure editing doesn't get stuck in "NEW_ROW" state;
|
|
116
|
+
useEffect(() => {
|
|
117
|
+
if (editing === NEW_ROW && (fields?.value?.filter(f => f._isNewActionListRow)?.length ?? 0) === 0) {
|
|
118
|
+
setEditing();
|
|
119
|
+
}
|
|
120
|
+
}, [editing, fields?.value]);
|
|
112
121
|
|
|
113
122
|
const handleSave = (index) => {
|
|
114
123
|
const {
|
|
115
124
|
actionListActions: _a,
|
|
116
125
|
fieldName: _fn,
|
|
117
126
|
fieldIndex: _fi,
|
|
127
|
+
_isNewActionListRow: _inalr,
|
|
118
128
|
...rowData
|
|
119
129
|
} = fields.value[index];
|
|
120
130
|
|
|
@@ -130,6 +140,7 @@ const ActionListFieldArray = forwardRef(({
|
|
|
130
140
|
actionListActions: _a,
|
|
131
141
|
fieldName: _fn,
|
|
132
142
|
fieldIndex: _fi,
|
|
143
|
+
_isNewActionListRow: _inalr,
|
|
133
144
|
...rowData
|
|
134
145
|
} = fields.value[index];
|
|
135
146
|
|
|
@@ -138,16 +149,19 @@ const ActionListFieldArray = forwardRef(({
|
|
|
138
149
|
}
|
|
139
150
|
};
|
|
140
151
|
|
|
141
|
-
const handleClickCreate = () => {
|
|
142
|
-
toggleEditing(
|
|
143
|
-
fields.unshift(
|
|
144
|
-
|
|
152
|
+
const handleClickCreate = useCallback(() => {
|
|
153
|
+
toggleEditing(NEW_ROW);
|
|
154
|
+
fields.unshift({
|
|
155
|
+
...defaultNewObject,
|
|
156
|
+
_isNewActionListRow: true
|
|
157
|
+
});
|
|
158
|
+
}, [defaultNewObject, fields, toggleEditing]);
|
|
145
159
|
|
|
146
160
|
// Way to go into create mode from external component, and way to tell internal editing state
|
|
147
161
|
useImperativeHandle(ref, () => ({
|
|
148
162
|
create: handleClickCreate,
|
|
149
163
|
editing
|
|
150
|
-
}));
|
|
164
|
+
}), [editing, handleClickCreate]);
|
|
151
165
|
|
|
152
166
|
const getColumnWidths = () => {
|
|
153
167
|
const widthNotInUseByActions = editing ?
|
|
@@ -173,7 +187,7 @@ const ActionListFieldArray = forwardRef(({
|
|
|
173
187
|
const fieldName = `contentData[${data.rowIndex}]`;
|
|
174
188
|
const { actionListActions: actions, ...rest } = data;
|
|
175
189
|
|
|
176
|
-
if (data.id === editing || (!data.id && editing ===
|
|
190
|
+
if (data.id === editing || (!data.id && editing === NEW_ROW)) {
|
|
177
191
|
// Render the save/cancel buttons
|
|
178
192
|
return (
|
|
179
193
|
<div id={`action-button-parent-${data.rowIndex + 1}`}>
|
|
@@ -186,12 +200,12 @@ const ActionListFieldArray = forwardRef(({
|
|
|
186
200
|
triggerFormSubmit(); // This is set up as () => null in ActionList, so essentially only acts here to force validation
|
|
187
201
|
|
|
188
202
|
if (!hasValidationErrors) {
|
|
189
|
-
if (!data.id && editing ===
|
|
203
|
+
if (!data.id && editing === NEW_ROW) {
|
|
190
204
|
handleCreate(data.rowIndex);
|
|
191
205
|
} else {
|
|
192
206
|
handleSave(data.rowIndex);
|
|
193
207
|
}
|
|
194
|
-
toggleEditing(
|
|
208
|
+
toggleEditing();
|
|
195
209
|
}
|
|
196
210
|
}}
|
|
197
211
|
type="submit"
|
|
@@ -206,9 +220,9 @@ const ActionListFieldArray = forwardRef(({
|
|
|
206
220
|
data-type-button="cancel"
|
|
207
221
|
marginBottom0
|
|
208
222
|
onClick={() => {
|
|
209
|
-
if (!data.id && editing ===
|
|
223
|
+
if (!data.id && editing === NEW_ROW) {
|
|
210
224
|
fields.remove(data.rowIndex);
|
|
211
|
-
toggleEditing(
|
|
225
|
+
toggleEditing(NEW_ROW);
|
|
212
226
|
} else {
|
|
213
227
|
change(fieldName, get(initialValues, fieldName));
|
|
214
228
|
toggleEditing(data.id);
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useEffect, useState, useContext, forwardRef } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
|
|
4
|
-
import { ConfirmationModal } from '@folio/stripes/components';
|
|
4
|
+
import { Button, ConfirmationModal } from '@folio/stripes/components';
|
|
5
5
|
import { CalloutContext } from '@folio/stripes/core';
|
|
6
6
|
|
|
7
7
|
import { useKintIntl, useMutateRefdataCategory, useRefdata } from '../hooks';
|
|
8
8
|
|
|
9
|
+
import SearchField from '../SearchField';
|
|
9
10
|
import ActionList from '../ActionList';
|
|
10
11
|
import { required } from '../validators';
|
|
11
12
|
import { parseErrorResponse } from '../utils';
|
|
13
|
+
import css from '../../../styles/CustomProperties.css';
|
|
12
14
|
|
|
13
15
|
const propTypes = {
|
|
14
16
|
afterQueryCalls: PropTypes.object,
|
|
@@ -18,17 +20,21 @@ const propTypes = {
|
|
|
18
20
|
delete: PropTypes.bool,
|
|
19
21
|
view: PropTypes.bool,
|
|
20
22
|
}),
|
|
23
|
+
handleRefdataCategoryClick: PropTypes.func,
|
|
24
|
+
hideCreateButton: PropTypes.bool,
|
|
21
25
|
intlKey: PropTypes.string,
|
|
22
26
|
intlNS: PropTypes.string,
|
|
27
|
+
isSearchDisabled: PropTypes.bool,
|
|
23
28
|
label: PropTypes.oneOfType([
|
|
24
29
|
PropTypes.string,
|
|
25
30
|
PropTypes.node
|
|
26
31
|
]),
|
|
27
32
|
labelOverrides: PropTypes.object,
|
|
28
|
-
|
|
33
|
+
onConfirmDelete: PropTypes.func,
|
|
34
|
+
refdataEndpoint: PropTypes.string,
|
|
29
35
|
};
|
|
30
36
|
|
|
31
|
-
const EditableRefdataCategoryList = ({
|
|
37
|
+
const EditableRefdataCategoryList = forwardRef(({
|
|
32
38
|
afterQueryCalls,
|
|
33
39
|
catchQueryCalls,
|
|
34
40
|
/*
|
|
@@ -42,12 +48,18 @@ const EditableRefdataCategoryList = ({
|
|
|
42
48
|
create: true,
|
|
43
49
|
delete: true,
|
|
44
50
|
},
|
|
51
|
+
handleRefdataCategoryClick,
|
|
52
|
+
hideCreateButton,
|
|
53
|
+
isSearchDisabled,
|
|
45
54
|
intlKey: passedIntlKey,
|
|
46
55
|
intlNS: passedIntlNS,
|
|
47
56
|
label,
|
|
48
57
|
labelOverrides = {}, // An object containing translation alternatives
|
|
49
|
-
|
|
50
|
-
|
|
58
|
+
// A function which will fire on confirmation of delete,
|
|
59
|
+
// with id of deleted Refdata category
|
|
60
|
+
onConfirmDelete = (_id) => null,
|
|
61
|
+
refdataEndpoint,
|
|
62
|
+
}, ref) => {
|
|
51
63
|
/* A component that allows for editing of refdata categories */
|
|
52
64
|
const callout = useContext(CalloutContext);
|
|
53
65
|
const kintIntl = useKintIntl(passedIntlKey, passedIntlNS);
|
|
@@ -63,6 +75,7 @@ const EditableRefdataCategoryList = ({
|
|
|
63
75
|
returnQueryObject: true
|
|
64
76
|
});
|
|
65
77
|
|
|
78
|
+
const [searchTerm, setSearchTerm] = useState('');
|
|
66
79
|
const [contentData, setContentData] = useState([]);
|
|
67
80
|
const [deleteModal, setDeleteModal] = useState({
|
|
68
81
|
visible: false,
|
|
@@ -73,9 +86,14 @@ const EditableRefdataCategoryList = ({
|
|
|
73
86
|
|
|
74
87
|
useEffect(() => {
|
|
75
88
|
if (!isRefdataLoading) {
|
|
76
|
-
|
|
89
|
+
if (searchTerm) {
|
|
90
|
+
const filteredRefdata = refdata?.filter(rd => rd.desc.toLowerCase().includes(searchTerm.toLowerCase()));
|
|
91
|
+
setContentData(filteredRefdata?.sort(sortByDesc) ?? []);
|
|
92
|
+
} else {
|
|
93
|
+
setContentData(refdata?.sort(sortByDesc) ?? []);
|
|
94
|
+
}
|
|
77
95
|
}
|
|
78
|
-
}, [isRefdataLoading, refdata]);
|
|
96
|
+
}, [isRefdataLoading, refdata, searchTerm]);
|
|
79
97
|
|
|
80
98
|
// Edit and Create will use the same POST mutation
|
|
81
99
|
const { delete: deleteRefdataCategory, post: createRefdataCategory } = useMutateRefdataCategory({
|
|
@@ -101,10 +119,10 @@ const EditableRefdataCategoryList = ({
|
|
|
101
119
|
id: 'refdataCategory.deleteRefdataCategory.errorMessage',
|
|
102
120
|
overrideValue: labelOverrides?.deleteError
|
|
103
121
|
},
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
122
|
+
{
|
|
123
|
+
label: deleteModal?.refdata?.label,
|
|
124
|
+
error: errorResp?.message
|
|
125
|
+
}),
|
|
108
126
|
type: 'error',
|
|
109
127
|
});
|
|
110
128
|
},
|
|
@@ -153,7 +171,28 @@ const EditableRefdataCategoryList = ({
|
|
|
153
171
|
|
|
154
172
|
return (
|
|
155
173
|
<>
|
|
174
|
+
{!isSearchDisabled ?
|
|
175
|
+
<div
|
|
176
|
+
className={css.lookupSearchContainer}
|
|
177
|
+
>
|
|
178
|
+
<SearchField
|
|
179
|
+
ariaLabel={
|
|
180
|
+
kintIntl.formatKintMessage({
|
|
181
|
+
id: 'refdataCategories.config.searchAriaLabel',
|
|
182
|
+
overrideValue: labelOverrides.searchAriaLabel,
|
|
183
|
+
fallbackMessage: 'refdata-category-search-field'
|
|
184
|
+
})
|
|
185
|
+
}
|
|
186
|
+
className={css.lookupSearch}
|
|
187
|
+
marginBottom0
|
|
188
|
+
onChange={e => setSearchTerm(e.target.value)}
|
|
189
|
+
value={searchTerm}
|
|
190
|
+
/>
|
|
191
|
+
</div>
|
|
192
|
+
: null
|
|
193
|
+
}
|
|
156
194
|
<ActionList
|
|
195
|
+
ref={ref}
|
|
157
196
|
actionAssigner={actionAssigner}
|
|
158
197
|
columnMapping={{
|
|
159
198
|
desc: kintIntl.formatKintMessage({
|
|
@@ -174,6 +213,19 @@ const EditableRefdataCategoryList = ({
|
|
|
174
213
|
(data) => createRefdataCategory(data)
|
|
175
214
|
}
|
|
176
215
|
formatter={{
|
|
216
|
+
desc: (rowData) => {
|
|
217
|
+
if (handleRefdataCategoryClick) {
|
|
218
|
+
return (
|
|
219
|
+
<Button
|
|
220
|
+
buttonStyle="link"
|
|
221
|
+
onClick={() => handleRefdataCategoryClick(rowData)}
|
|
222
|
+
>
|
|
223
|
+
{rowData?.desc}
|
|
224
|
+
</Button>
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
return rowData?.desc;
|
|
228
|
+
},
|
|
177
229
|
values: (rowData) => rowData?.values?.length
|
|
178
230
|
}}
|
|
179
231
|
/* Hide actions column when no permissions, or no deletable refdata categories */
|
|
@@ -181,6 +233,7 @@ const EditableRefdataCategoryList = ({
|
|
|
181
233
|
(!createCondition && !deleteCondition) ||
|
|
182
234
|
!contentData?.find(cd => cd?.values?.length === 0)
|
|
183
235
|
}
|
|
236
|
+
hideCreateButton={hideCreateButton}
|
|
184
237
|
label={label}
|
|
185
238
|
validateFields={{
|
|
186
239
|
desc: () => required
|
|
@@ -209,13 +262,14 @@ const EditableRefdataCategoryList = ({
|
|
|
209
262
|
onCancel={() => setDeleteModal({ visible: false, refdata: null })}
|
|
210
263
|
onConfirm={() => {
|
|
211
264
|
deleteRefdataCategory(deleteModal?.refdata?.id);
|
|
265
|
+
onConfirmDelete(deleteModal?.refdata?.id);
|
|
212
266
|
setDeleteModal({ visible: false, refdata: null });
|
|
213
267
|
}}
|
|
214
268
|
open={deleteModal?.visible}
|
|
215
269
|
/>
|
|
216
270
|
</>
|
|
217
271
|
);
|
|
218
|
-
};
|
|
272
|
+
});
|
|
219
273
|
|
|
220
274
|
EditableRefdataCategoryList.propTypes = propTypes;
|
|
221
275
|
|