@k-int/stripes-kint-components 1.7.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/es/index.js +51 -8
  3. package/es/lib/ActionList/ActionList.js +48 -28
  4. package/es/lib/ActionList/ActionListFieldArray.js +56 -16
  5. package/es/lib/CustomProperties/Config/CustomPropertiesLookup.js +198 -0
  6. package/es/lib/CustomProperties/Config/CustomPropertiesSettings.js +326 -0
  7. package/es/lib/CustomProperties/Config/CustomPropertiesView.js +166 -0
  8. package/es/lib/CustomProperties/Config/CustomPropertyForm.js +360 -0
  9. package/es/lib/CustomProperties/Config/index.js +41 -0
  10. package/es/lib/EditableRefdataList/EditableRefdataList.js +0 -1
  11. package/es/lib/FormModal/FormModal.js +126 -0
  12. package/es/lib/{TypeDown → FormModal}/index.js +2 -2
  13. package/es/lib/NoResultsMessage/NoResultsMessage.js +1 -1
  14. package/es/lib/SASQRoute/SASQRoute.js +15 -11
  15. package/es/lib/SASQViewComponent/SASQViewComponent.js +6 -3
  16. package/es/lib/Typedown/Typedown.js +50 -18
  17. package/es/lib/constants/customProperties.js +60 -0
  18. package/es/lib/hooks/index.js +16 -0
  19. package/es/lib/hooks/useCustomProperties.js +122 -0
  20. package/es/lib/hooks/useMutateCustomProperties.js +143 -0
  21. package/es/lib/utils/generateKiwtQueryParams.js +51 -8
  22. package/junit.xml +40 -40
  23. package/package.json +5 -3
  24. package/src/artifacts/coverage-jest/lcov-report/ActionList/ActionList.js.html +47 -26
  25. package/src/artifacts/coverage-jest/lcov-report/ActionList/ActionListFieldArray.js.html +122 -8
  26. package/src/artifacts/coverage-jest/lcov-report/ActionList/index.html +10 -10
  27. package/src/artifacts/coverage-jest/lcov-report/ActionList/index.js.html +1 -1
  28. package/src/artifacts/coverage-jest/lcov-report/CustomProperties/Config/CustomPropertiesLookup.js.html +418 -0
  29. package/src/artifacts/coverage-jest/lcov-report/{TypeDown/TypeDown.js.html → CustomProperties/Config/CustomPropertiesSettings.js.html} +268 -232
  30. package/src/artifacts/coverage-jest/lcov-report/CustomProperties/Config/CustomPropertiesView.js.html +535 -0
  31. package/src/artifacts/coverage-jest/lcov-report/CustomProperties/Config/CustomPropertyForm.js.html +973 -0
  32. package/src/artifacts/coverage-jest/lcov-report/CustomProperties/Config/index.html +176 -0
  33. package/src/artifacts/coverage-jest/lcov-report/CustomProperties/Config/index.js.html +97 -0
  34. package/src/artifacts/coverage-jest/lcov-report/EditableRefdataList/EditableRefdataList.js.html +2 -5
  35. package/src/artifacts/coverage-jest/lcov-report/EditableRefdataList/index.html +1 -1
  36. package/src/artifacts/coverage-jest/lcov-report/EditableRefdataList/index.js.html +1 -1
  37. package/src/artifacts/coverage-jest/lcov-report/EditableSettingsList/EditableSettingsList.js.html +1 -1
  38. package/src/artifacts/coverage-jest/lcov-report/EditableSettingsList/EditableSettingsListFieldArray.js.html +1 -1
  39. package/src/artifacts/coverage-jest/lcov-report/EditableSettingsList/SettingField/EditSettingValue.js.html +1 -1
  40. package/src/artifacts/coverage-jest/lcov-report/EditableSettingsList/SettingField/RenderSettingValue.js.html +1 -1
  41. package/src/artifacts/coverage-jest/lcov-report/EditableSettingsList/SettingField/SettingField.js.html +1 -1
  42. package/src/artifacts/coverage-jest/lcov-report/EditableSettingsList/SettingField/index.html +1 -1
  43. package/src/artifacts/coverage-jest/lcov-report/EditableSettingsList/SettingField/index.js.html +1 -1
  44. package/src/artifacts/coverage-jest/lcov-report/EditableSettingsList/index.html +1 -1
  45. package/src/artifacts/coverage-jest/lcov-report/EditableSettingsList/index.js.html +1 -1
  46. package/src/artifacts/coverage-jest/lcov-report/FormModal/FormModal.js.html +298 -0
  47. package/src/artifacts/coverage-jest/lcov-report/{TypeDown → FormModal}/index.html +14 -14
  48. package/src/artifacts/coverage-jest/lcov-report/{TypeDown → FormModal}/index.js.html +4 -4
  49. package/src/artifacts/coverage-jest/lcov-report/NoResultsMessage/NoResultsMessage.js.html +3 -3
  50. package/src/artifacts/coverage-jest/lcov-report/NoResultsMessage/index.html +1 -1
  51. package/src/artifacts/coverage-jest/lcov-report/NoResultsMessage/index.js.html +1 -1
  52. package/src/artifacts/coverage-jest/lcov-report/QueryTypedown/QueryTypedown.js.html +1 -1
  53. package/src/artifacts/coverage-jest/lcov-report/QueryTypedown/index.html +1 -1
  54. package/src/artifacts/coverage-jest/lcov-report/QueryTypedown/index.js.html +1 -1
  55. package/src/artifacts/coverage-jest/lcov-report/RefdataButtons/RefdataButtons.js.html +3 -3
  56. package/src/artifacts/coverage-jest/lcov-report/RefdataButtons/index.html +1 -1
  57. package/src/artifacts/coverage-jest/lcov-report/RefdataButtons/index.js.html +1 -1
  58. package/src/artifacts/coverage-jest/lcov-report/SASQLookupComponent/SASQLookupComponent.js.html +1 -1
  59. package/src/artifacts/coverage-jest/lcov-report/SASQLookupComponent/index.html +1 -1
  60. package/src/artifacts/coverage-jest/lcov-report/SASQLookupComponent/index.js.html +1 -1
  61. package/src/artifacts/coverage-jest/lcov-report/SASQRoute/SASQRoute.js.html +43 -16
  62. package/src/artifacts/coverage-jest/lcov-report/SASQRoute/index.html +1 -1
  63. package/src/artifacts/coverage-jest/lcov-report/SASQRoute/index.js.html +1 -1
  64. package/src/artifacts/coverage-jest/lcov-report/SASQViewComponent/SASQViewComponent.js.html +6 -3
  65. package/src/artifacts/coverage-jest/lcov-report/SASQViewComponent/index.html +1 -1
  66. package/src/artifacts/coverage-jest/lcov-report/SASQViewComponent/index.js.html +1 -1
  67. package/src/artifacts/coverage-jest/lcov-report/SearchField/SearchField.js.html +1 -1
  68. package/src/artifacts/coverage-jest/lcov-report/SearchField/index.html +1 -1
  69. package/src/artifacts/coverage-jest/lcov-report/SearchField/index.js.html +1 -1
  70. package/src/artifacts/coverage-jest/lcov-report/SettingPage/SettingPage.js.html +1 -1
  71. package/src/artifacts/coverage-jest/lcov-report/SettingPage/SettingPagePane.js.html +1 -1
  72. package/src/artifacts/coverage-jest/lcov-report/SettingPage/index.html +1 -1
  73. package/src/artifacts/coverage-jest/lcov-report/SettingPage/index.js.html +1 -1
  74. package/src/artifacts/coverage-jest/lcov-report/Typedown/Typedown.js.html +150 -21
  75. package/src/artifacts/coverage-jest/lcov-report/Typedown/index.html +7 -7
  76. package/src/artifacts/coverage-jest/lcov-report/Typedown/index.js.html +1 -1
  77. package/src/artifacts/coverage-jest/lcov-report/constants/customProperties.js.html +112 -0
  78. package/src/artifacts/coverage-jest/lcov-report/constants/eventCodes.js.html +1 -1
  79. package/src/artifacts/coverage-jest/lcov-report/constants/index.html +18 -3
  80. package/src/artifacts/coverage-jest/lcov-report/contexts/SettingsContext.js.html +1 -1
  81. package/src/artifacts/coverage-jest/lcov-report/contexts/index.html +1 -1
  82. package/src/artifacts/coverage-jest/lcov-report/contexts/index.js.html +1 -1
  83. package/src/artifacts/coverage-jest/lcov-report/hooks/index.html +35 -5
  84. package/src/artifacts/coverage-jest/lcov-report/hooks/index.js.html +8 -2
  85. package/src/artifacts/coverage-jest/lcov-report/hooks/settingsHooks/index.html +1 -1
  86. package/src/artifacts/coverage-jest/lcov-report/hooks/settingsHooks/index.js.html +1 -1
  87. package/src/artifacts/coverage-jest/lcov-report/hooks/settingsHooks/useSettingSection.js.html +1 -1
  88. package/src/artifacts/coverage-jest/lcov-report/hooks/settingsHooks/useSettings.js.html +1 -1
  89. package/src/artifacts/coverage-jest/lcov-report/hooks/typedownHooks/index.html +1 -1
  90. package/src/artifacts/coverage-jest/lcov-report/hooks/typedownHooks/index.js.html +1 -1
  91. package/src/artifacts/coverage-jest/lcov-report/hooks/typedownHooks/useTypedown.js.html +1 -1
  92. package/src/artifacts/coverage-jest/lcov-report/hooks/typedownHooks/useTypedownData.js.html +1 -1
  93. package/src/artifacts/coverage-jest/lcov-report/hooks/typedownHooks/useTypedownToggle.js.html +1 -1
  94. package/src/artifacts/coverage-jest/lcov-report/hooks/useActiveElement.js.html +1 -1
  95. package/src/artifacts/coverage-jest/lcov-report/hooks/useCustomProperties.js.html +313 -0
  96. package/src/artifacts/coverage-jest/lcov-report/hooks/useHelperApp.js.html +1 -1
  97. package/src/artifacts/coverage-jest/lcov-report/hooks/useKiwtFieldArray.js.html +1 -1
  98. package/src/artifacts/coverage-jest/lcov-report/hooks/useKiwtSASQuery.js.html +1 -1
  99. package/src/artifacts/coverage-jest/lcov-report/hooks/useLocalStorageState.js.html +1 -1
  100. package/src/artifacts/coverage-jest/lcov-report/hooks/useMutateCustomProperties.js.html +271 -0
  101. package/src/artifacts/coverage-jest/lcov-report/hooks/useMutateRefdataValue.js.html +1 -1
  102. package/src/artifacts/coverage-jest/lcov-report/hooks/useQIndex.js.html +1 -1
  103. package/src/artifacts/coverage-jest/lcov-report/hooks/useRefdata.js.html +1 -1
  104. package/src/artifacts/coverage-jest/lcov-report/hooks/useTemplates.js.html +1 -1
  105. package/src/artifacts/coverage-jest/lcov-report/index.html +62 -47
  106. package/src/artifacts/coverage-jest/lcov-report/utils/buildUrl.js.html +1 -1
  107. package/src/artifacts/coverage-jest/lcov-report/utils/generateKiwtQuery.js.html +1 -1
  108. package/src/artifacts/coverage-jest/lcov-report/utils/generateKiwtQueryParams.js.html +174 -12
  109. package/src/artifacts/coverage-jest/lcov-report/utils/index.html +17 -17
  110. package/src/artifacts/coverage-jest/lcov-report/utils/index.js.html +1 -1
  111. package/src/artifacts/coverage-jest/lcov-report/utils/refdataOptions.js.html +1 -1
  112. package/src/artifacts/coverage-jest/lcov-report/utils/renderHelpText.js.html +1 -1
  113. package/src/artifacts/coverage-jest/lcov-report/utils/selectorSafe.js.html +1 -1
  114. package/src/artifacts/coverage-jest/lcov-report/utils/sortByLabel.js.html +1 -1
  115. package/src/artifacts/coverage-jest/lcov-report/utils/toCamelCase.js.html +1 -1
  116. package/src/artifacts/coverage-jest/lcov.info +841 -348
  117. package/src/index.js +14 -4
  118. package/src/lib/ActionList/ActionList.js +30 -23
  119. package/src/lib/ActionList/ActionListFieldArray.js +40 -2
  120. package/src/lib/ActionList/README.md +4 -1
  121. package/src/lib/CustomProperties/Config/CustomPropertiesLookup.js +111 -0
  122. package/src/lib/CustomProperties/Config/CustomPropertiesSettings.js +240 -0
  123. package/src/lib/CustomProperties/Config/CustomPropertiesView.js +150 -0
  124. package/src/lib/CustomProperties/Config/CustomPropertyForm.js +296 -0
  125. package/src/lib/CustomProperties/Config/index.js +4 -0
  126. package/src/lib/EditableRefdataList/EditableRefdataList.js +0 -1
  127. package/src/lib/FormModal/FormModal.js +71 -0
  128. package/src/lib/FormModal/index.js +1 -0
  129. package/src/lib/NoResultsMessage/NoResultsMessage.js +2 -2
  130. package/src/lib/SASQRoute/SASQRoute.js +23 -14
  131. package/src/lib/SASQViewComponent/SASQViewComponent.js +2 -1
  132. package/src/lib/Typedown/Typedown.js +56 -13
  133. package/src/lib/constants/customProperties.js +9 -0
  134. package/src/lib/hooks/index.js +2 -0
  135. package/src/lib/hooks/useCustomProperties.js +76 -0
  136. package/src/lib/hooks/useMutateCustomProperties.js +62 -0
  137. package/src/lib/utils/generateKiwtQueryParams.js +58 -4
  138. package/styles/TypeDown.css +7 -0
  139. package/translations/stripes-kint-components/en.json +49 -1
  140. package/es/lib/TypeDown/TypeDown.js +0 -251
  141. package/src/lib/TypeDown/README.md +0 -1
  142. package/src/lib/TypeDown/TypeDown.js +0 -228
  143. package/src/lib/TypeDown/index.js +0 -1
package/src/index.js CHANGED
@@ -1,10 +1,12 @@
1
1
  // Useful hooks
2
2
  export {
3
3
  useActiveElement,
4
+ useCustomProperties,
4
5
  useHelperApp,
5
6
  useKiwtFieldArray,
6
7
  useKiwtSASQuery,
7
8
  useLocalStorageState,
9
+ useMutateCustomProperties,
8
10
  useMutateRefdataValue,
9
11
  useQIndex,
10
12
  useRefdata,
@@ -36,10 +38,6 @@ export { default as ActionList } from './lib/ActionList';
36
38
  export { default as EditableRefdataList } from './lib/EditableRefdataList';
37
39
 
38
40
  // Typedown
39
- export {
40
- default as TypeDown
41
- } from './lib/TypeDown';
42
-
43
41
  export {
44
42
  default as Typedown
45
43
  } from './lib/Typedown';
@@ -73,3 +71,15 @@ export { default as NoResultsMessage } from './lib/NoResultsMessage';
73
71
 
74
72
  // RefdataButtons
75
73
  export { default as RefdataButtons } from './lib/RefdataButtons';
74
+
75
+ // FormModal
76
+ export { default as FormModal } from './lib/FormModal';
77
+
78
+ // Custom properties
79
+ export {
80
+ CustomPropertiesLookup,
81
+ CustomPropertiesSettings,
82
+ CustomPropertiesView
83
+ } from './lib/CustomProperties/Config';
84
+
85
+ export * as customPropertyContants from './lib/constants/customProperties';
@@ -14,6 +14,7 @@ const propTypes = {
14
14
  contentData: PropTypes.arrayOf(PropTypes.object),
15
15
  creatableFields: PropTypes.object,
16
16
  editableFields: PropTypes.object,
17
+ fieldComponents: PropTypes.object,
17
18
  visibleFields: PropTypes.arrayOf(PropTypes.string)
18
19
  };
19
20
 
@@ -24,31 +25,37 @@ const ActionList = ({
24
25
  contentData,
25
26
  creatableFields = {},
26
27
  editableFields = {},
27
- visibleFields
28
+ fieldComponents = {},
29
+ visibleFields,
30
+ ...mclProps // Assume anything left over is to directly apply to the MCL
28
31
  }) => {
29
32
  return (
30
- <Form
31
- enableReinitialize
32
- initialValues={{ contentData }}
33
- mutators={arrayMutators}
34
- onSubmit={actionCalls.edit}
35
- subscription={{ contentData: true }}
36
- >
37
- {() => (
38
- <form onSubmit={e => { e.preventDefault(); }}>
39
- <FieldArray
40
- actionAssigner={actionAssigner}
41
- actionCalls={actionCalls}
42
- columnMapping={columnMapping}
43
- component={ActionListFieldArray}
44
- creatableFields={creatableFields}
45
- editableFields={editableFields}
46
- name="contentData"
47
- visibleFields={visibleFields}
48
- />
49
- </form>
50
- )}
51
- </Form>
33
+ <>
34
+ <Form
35
+ enableReinitialize
36
+ initialValues={{ contentData }}
37
+ mutators={arrayMutators}
38
+ onSubmit={actionCalls.edit}
39
+ subscription={{ contentData: true }}
40
+ >
41
+ {() => (
42
+ <form onSubmit={e => { e.preventDefault(); }}>
43
+ <FieldArray
44
+ actionAssigner={actionAssigner}
45
+ actionCalls={actionCalls}
46
+ columnMapping={columnMapping}
47
+ component={ActionListFieldArray}
48
+ creatableFields={creatableFields}
49
+ editableFields={editableFields}
50
+ fieldComponents={fieldComponents}
51
+ name="contentData"
52
+ visibleFields={visibleFields}
53
+ {...mclProps}
54
+ />
55
+ </form>
56
+ )}
57
+ </Form>
58
+ </>
52
59
  );
53
60
  };
54
61
 
@@ -18,6 +18,8 @@ const propTypes = {
18
18
  creatableFields: PropTypes.object,
19
19
  editableFields: PropTypes.object,
20
20
  fields: PropTypes.object,
21
+ fieldComponents: PropTypes.object,
22
+ formatter: PropTypes.object,
21
23
  visibleFields: PropTypes.arrayOf(PropTypes.string)
22
24
  };
23
25
 
@@ -28,7 +30,9 @@ const ActionListFieldArray = ({
28
30
  creatableFields,
29
31
  editableFields,
30
32
  fields,
31
- visibleFields
33
+ fieldComponents,
34
+ visibleFields,
35
+ ...mclProps // Assume anything left over is to directly apply to the MCL
32
36
  }) => {
33
37
  // Grab finalForm functions/values from form hooks
34
38
  const { change } = useForm();
@@ -92,6 +96,7 @@ const ActionListFieldArray = ({
92
96
  key={`save[${data.rowIndex}]`}
93
97
  buttonStyle="primary"
94
98
  disabled={submitting || pristine}
99
+ marginBottom0
95
100
  onClick={() => {
96
101
  if (!data.id && editing === 'NEW_ROW') {
97
102
  handleCreate(data.rowIndex);
@@ -106,6 +111,7 @@ const ActionListFieldArray = ({
106
111
  <Button
107
112
  key={`cancel[${data.rowIndex}]`}
108
113
  data-type-button="cancel"
114
+ marginBottom0
109
115
  onClick={() => {
110
116
  if (!data.id && editing === 'NEW_ROW') {
111
117
  fields.remove(data.rowIndex);
@@ -138,6 +144,7 @@ const ActionListFieldArray = ({
138
144
  key={`action-${action.name}[${data.rowIndex}]`}
139
145
  disabled={editing}
140
146
  icon={action.icon}
147
+ marginBottom0
141
148
  onClick={actionFunction}
142
149
  />
143
150
  );
@@ -148,6 +155,7 @@ const ActionListFieldArray = ({
148
155
  <Button
149
156
  key={`action-${action.name}[${data.rowIndex}]`}
150
157
  disabled={editing}
158
+ marginBottom0
151
159
  onClick={actionFunction}
152
160
  >
153
161
  {action.label ?? action.name}
@@ -191,10 +199,16 @@ const ActionListFieldArray = ({
191
199
  (editFunction(cd))
192
200
  ) {
193
201
  returnObj[key] =
202
+ fieldComponents[key] ?
203
+ fieldComponents[key]({
204
+ name: `${fieldName}.${key}`
205
+ }) :
194
206
  <Field
195
207
  autofocus={fieldIndex === 0}
196
208
  component={TextField}
209
+ marginBottom0
197
210
  name={`${fieldName}.${key}`}
211
+ parse={v => v}
198
212
  />;
199
213
  }
200
214
  }
@@ -204,6 +218,28 @@ const ActionListFieldArray = ({
204
218
  );
205
219
  };
206
220
 
221
+ const { formatter, ...restOfMclProps } = mclProps; // Destructure formatter part of mclProps
222
+ const fieldAwareFormatter = () => {
223
+ const returnObj = {};
224
+ // For each visible field, if it's being edited then ignore passed formatters, else use them
225
+ visibleFields.forEach(key => {
226
+ returnObj[key] = cd => {
227
+ // Row is being edited if it has no id, or its id is in the editing string
228
+ const editingRow = cd.id === editing || !cd.id;
229
+ // If not editing, use the passed formatter values
230
+
231
+ let returnValue = cd[key];
232
+
233
+ if (!editingRow && formatter?.[key]) {
234
+ returnValue = formatter[key](cd);
235
+ }
236
+
237
+ return returnValue;
238
+ };
239
+ });
240
+ return returnObj;
241
+ };
242
+
207
243
  return (
208
244
  <>
209
245
  <Button
@@ -224,10 +260,12 @@ const ActionListFieldArray = ({
224
260
  columnWidths={getColumnWidths()}
225
261
  contentData={formatContent()}
226
262
  formatter={{
227
- actionListActions: renderActionButtons
263
+ actionListActions: renderActionButtons,
264
+ ...fieldAwareFormatter()
228
265
  }}
229
266
  interactive={false}
230
267
  visibleColumns={[...visibleFields, 'actionListActions']}
268
+ {...restOfMclProps}
231
269
  />
232
270
  </>
233
271
  );
@@ -62,5 +62,8 @@ actionCalls | object<function> | An object with keys matching any "actions" the
62
62
  columnMapping | object | An object which will act on the rendered MultiColumnList headers to map the labels for each `visibleField` | | ✕ |
63
63
  contentData | array | An array of objects to render along with their actions | | ✓ |
64
64
  creatableFields | object<function> | An object with keys from the `visibleFields` array, and values of functions which take the entire row object and return a boolean indicating whether that field is fillable on create or not. | | ✕ |
65
- editableFields | object<function> | An object with keys from the `visibleFields` array, and values of functions which take the entire row object and return a boolean indicating whether that field is editable or not. | | ✕ |
65
+ editableFields | object<function> | An object with keys from the `visibleFields` array, and values of functions which take the entire row object and return a boolean indicating whether that field is editable or not. No key for a given field will be interpreted as () => true, so a field is editable by default. | | ✕ |
66
+ fieldComponents | object<function> | An object with keys from the `visibleFields` array, and values of functions which take some `fieldProps` (currently only the name of the field `name`), and returns a Field component to be used in "edit mode" for the visible field specified. | | ✕ |
67
+ formatter | object<function> | A "formatter" object that takes the same shape as an MCL formatter, and is used in the same way whilst a row is NOT being edited. While editing a given row, this formatter entry is ignored. | | ✕ |
66
68
  visibleFields | array<String> | An array of strings corresponding to those fields to be displayed in the rendered MultiColumnList | | ✓ |
69
+ ...mclProps | any | Any other props supplied to ActionList will be applied to the MCL directly. *WARNING* Some MCL props may override important functionality within ActionList | | ✕ |
@@ -0,0 +1,111 @@
1
+ import { useState } from 'react';
2
+ import PropTypes from 'prop-types';
3
+
4
+ import { FormattedMessage } from 'react-intl';
5
+
6
+ import debounce from 'lodash/debounce';
7
+
8
+ import { Col, MultiColumnList, Row, Spinner, Select } from '@folio/stripes/components';
9
+
10
+ import SearchField from '../../SearchField';
11
+ import { useCustomProperties } from '../../hooks';
12
+
13
+ const DEBOUNCE_TIME = 500;
14
+
15
+ const CustomPropertiesLookup = ({
16
+ contextFilterOptions, // expects an array of the form [{value: "OpenAccess", label: "Open Access"}, {value: false, label: "None"}]
17
+ customPropertiesEndpoint: endpoint,
18
+ labelOverrides,
19
+ mclProps,
20
+ onSelectCustomProperty,
21
+ queryParams
22
+ }) => {
23
+ const [nsValues, setNsValues] = useState({
24
+ sort: 'label'
25
+ });
26
+ const [selectedContext, setSelectedContext] = useState();
27
+
28
+ const { data: custprops, isLoading } = useCustomProperties({
29
+ endpoint,
30
+ nsValues,
31
+ queryParams,
32
+ returnQueryObject: true,
33
+ ctx: selectedContext
34
+ });
35
+
36
+ const handleSearch = debounce((query) => {
37
+ setNsValues({
38
+ ...nsValues,
39
+ query,
40
+ });
41
+ }, DEBOUNCE_TIME);
42
+
43
+ return (
44
+ <>
45
+ <SearchField fullWidth onChange={e => handleSearch(e.target.value)} />
46
+ <Row>
47
+ <Col xs={6}>
48
+ <Select
49
+ dataOptions={contextFilterOptions}
50
+ onChange={(e) => {
51
+ setSelectedContext(e.target.value);
52
+ }}
53
+ value={selectedContext}
54
+ />
55
+ </Col>
56
+ </Row>
57
+ {isLoading ?
58
+ <Spinner /> :
59
+ <MultiColumnList
60
+ columnMapping={{
61
+ 'label': labelOverrides?.label ?? <FormattedMessage id="stripes-kint-components.customProperties.label" />,
62
+ 'primary': labelOverrides?.primary ?? <FormattedMessage id="stripes-kint-components.customProperties.primary" />,
63
+ 'ctx': labelOverrides?.ctx ?? <FormattedMessage id="stripes-kint-components.customProperties.ctx" />,
64
+ 'weight': labelOverrides?.weight ?? <FormattedMessage id="stripes-kint-components.customProperties.weight" />,
65
+ 'type': labelOverrides?.type ?? <FormattedMessage id="stripes-kint-components.customProperties.type" />,
66
+ 'category': labelOverrides?.category ?? <FormattedMessage id="stripes-kint-components.customProperties.category" />
67
+ }}
68
+ contentData={custprops}
69
+ formatter={{
70
+ primary: data => {
71
+ if (data?.primary) {
72
+ return (
73
+ <FormattedMessage id="stripes-kint-components.yes" />
74
+ );
75
+ } else {
76
+ return (
77
+ <FormattedMessage id="stripes-kint-components.no" />
78
+ );
79
+ }
80
+ },
81
+ type: data => (
82
+ <FormattedMessage id={`stripes-kint-components.customProperties.type.${data?.type}`} />
83
+ ),
84
+ category: data => data?.category?.desc
85
+ }}
86
+ onRowClick={onSelectCustomProperty}
87
+ visibleColumns={['label', 'primary', 'ctx', 'weight', 'type', 'category']}
88
+ {...mclProps}
89
+ />
90
+ }
91
+ </>
92
+ );
93
+ };
94
+
95
+ CustomPropertiesLookup.propTypes = {
96
+ contextFilterOptions: PropTypes.arrayOf(PropTypes.shape({
97
+ value: PropTypes.string,
98
+ label: PropTypes.oneOfType([
99
+ PropTypes.element,
100
+ PropTypes.string
101
+ ])
102
+ })),
103
+ customPropertiesEndpoint: PropTypes.string,
104
+ labelOverrides: PropTypes.object,
105
+ mclProps: PropTypes.object,
106
+ onSelectCustomProperty: PropTypes.func,
107
+ queryParams: PropTypes.object,
108
+ refdataEndpoint: PropTypes.string,
109
+ };
110
+
111
+ export default CustomPropertiesLookup;
@@ -0,0 +1,240 @@
1
+ import { useState } from 'react';
2
+ import PropTypes from 'prop-types';
3
+
4
+ import compose from 'compose-function';
5
+
6
+ import { FormattedMessage, useIntl } from 'react-intl';
7
+
8
+ import { useQueryClient } from 'react-query';
9
+
10
+ import SafeHTMLMessage from '@folio/react-intl-safe-html';
11
+
12
+ import { Button, ConfirmationModal, Pane } from '@folio/stripes/components';
13
+
14
+ import FormModal from '../../FormModal/FormModal';
15
+
16
+ import CustomPropertiesLookup from './CustomPropertiesLookup';
17
+ import CustomPropertiesView from './CustomPropertiesView';
18
+ import CustomPropertiesForm from './CustomPropertyForm';
19
+ import { useMutateCustomProperties, useRefdata } from '../../hooks';
20
+
21
+ const EDITING = 'edit';
22
+ const CREATING = 'create';
23
+ const VIEWING = 'view';
24
+
25
+ // A default option for setting up panes manually
26
+ const CustomPropertiesSettings = ({
27
+ afterQueryCalls,
28
+ contextFilterOptions,
29
+ customPropertiesEndpoint,
30
+ helpPopovers,
31
+ labelOverrides,
32
+ refdataEndpoint,
33
+ }) => {
34
+ const queryClient = useQueryClient();
35
+
36
+ const intl = useIntl();
37
+ const [customProperty, setCustomProperty] = useState();
38
+ const [deleteModal, setDeleteModal] = useState(false);
39
+
40
+ const refdata = useRefdata({
41
+ endpoint: refdataEndpoint,
42
+ });
43
+
44
+ const [mode, setMode] = useState(VIEWING);
45
+
46
+ // Default props that need hooks are hard
47
+ let renderContextFilterOptions = contextFilterOptions;
48
+ if (!contextFilterOptions) {
49
+ /*
50
+ Default is {value: '', label: 'All'}, empty string will map to ALL contexts
51
+ If null context is needed, use
52
+ {value: 'isNull', label: ...}
53
+ */
54
+ renderContextFilterOptions = [
55
+ {
56
+ value: '', // empty string is all custoprop contexts
57
+ label: intl.formatMessage({ id: 'stripes-kint-components.customProperties.all' })
58
+ }
59
+ ];
60
+ }
61
+
62
+ let renderViewPaneTitle = labelOverrides?.viewPaneTitle;
63
+ if (renderViewPaneTitle instanceof Function) {
64
+ renderViewPaneTitle = renderViewPaneTitle(customProperty);
65
+ }
66
+
67
+ // Defaulting is hard
68
+ const afterQueryCallsSafe = {
69
+ put: () => null,
70
+ post: () => null,
71
+ delete: () => null,
72
+ ...afterQueryCalls
73
+ };
74
+
75
+ const {
76
+ post: createCustprop,
77
+ put: editCustProp,
78
+ delete: deleteCustProp
79
+ } = useMutateCustomProperties({
80
+ afterQueryCalls: {
81
+ put: () => {
82
+ setMode(VIEWING);
83
+ queryClient.invalidateQueries(['stripes-kint-components', 'useCustomProperties', 'custprops']);
84
+ afterQueryCallsSafe.put();
85
+ },
86
+ post: () => {
87
+ setMode(VIEWING);
88
+ queryClient.invalidateQueries(['stripes-kint-components', 'useCustomProperties', 'custprops']);
89
+ afterQueryCallsSafe.post();
90
+ },
91
+ delete: () => {
92
+ setMode(VIEWING);
93
+ queryClient.invalidateQueries(['stripes-kint-components', 'useCustomProperties', 'custprops']);
94
+ afterQueryCallsSafe.delete();
95
+ }
96
+ },
97
+ endpoint: customPropertiesEndpoint,
98
+ id: customProperty?.id
99
+ });
100
+
101
+ const handeContextSubmit = (submitData) => {
102
+ return {
103
+ ...submitData,
104
+ ctx: submitData?.ctx?.[0]?.value
105
+ };
106
+ };
107
+
108
+ return (
109
+ <>
110
+ <Pane
111
+ defaultWidth="fill"
112
+ id="settings-customProperties.lookupPane"
113
+ lastMenu={
114
+ <Button
115
+ marginBottom0
116
+ onClick={() => setMode(CREATING)} // TODO do we need to clear form here too?
117
+ >
118
+ <FormattedMessage id="stripes-kint-components.create" />
119
+ </Button>
120
+ }
121
+ paneTitle={labelOverrides.paneTitle ??
122
+ <FormattedMessage id="stripes-kint-components.customProperties" /> // This should be configurable?
123
+ }
124
+ >
125
+ <CustomPropertiesLookup
126
+ contextFilterOptions={renderContextFilterOptions}
127
+ customPropertiesEndpoint={customPropertiesEndpoint}
128
+ labelOverrides={labelOverrides}
129
+ onSelectCustomProperty={(_e, cp) => setCustomProperty(cp)}
130
+ />
131
+ </Pane>
132
+ {customProperty &&
133
+ <Pane
134
+ actionMenu={({ onToggle }) => (
135
+ [
136
+ <Button
137
+ buttonStyle="dropdownItem"
138
+ marginBottom0
139
+ onClick={() => setMode(EDITING)}
140
+ >
141
+ <FormattedMessage id="stripes-kint-components.edit" />
142
+ </Button>,
143
+ <Button
144
+ buttonStyle="dropdownItem"
145
+ marginBottom0
146
+ onClick={() => {
147
+ setDeleteModal(true);
148
+ onToggle();
149
+ }}
150
+ >
151
+ <FormattedMessage id="stripes-kint-components.delete" />
152
+ </Button>
153
+ ]
154
+ )}
155
+ defaultWidth="fill"
156
+ dismissible
157
+ id="settings-customProperties-viewPane"
158
+ onClose={() => setCustomProperty()}
159
+ paneTitle={
160
+ renderViewPaneTitle ?? customProperty?.label ?? customProperty?.name
161
+ }
162
+ >
163
+ <CustomPropertiesView
164
+ customProperty={customProperty}
165
+ labelOverrides={labelOverrides}
166
+ />
167
+ </Pane>
168
+ }
169
+ <FormModal
170
+ initialValues={mode === CREATING ?
171
+ {
172
+ weight: 0,
173
+ primary: true,
174
+ defaultInternal: true
175
+ } :
176
+ {
177
+ ...customProperty,
178
+ ctx: customProperty?.ctx ? [{ value: customProperty.ctx, label: customProperty.ctx }] : null
179
+ }
180
+ }
181
+ modalProps={{
182
+ dismissible: true,
183
+ onClose: () => setMode(VIEWING),
184
+ open: (mode === CREATING || mode === EDITING)
185
+ }}
186
+ onSubmit={mode === CREATING ?
187
+ compose(createCustprop, handeContextSubmit) :
188
+ compose(editCustProp, handeContextSubmit)
189
+ }
190
+ >
191
+ <CustomPropertiesForm
192
+ contextFilterOptions={renderContextFilterOptions}
193
+ helpPopovers={helpPopovers}
194
+ labelOverrides={labelOverrides}
195
+ refdata={refdata.map(rdc => ({ label: rdc.desc, value: rdc.id }))}
196
+ />
197
+ </FormModal>
198
+ <ConfirmationModal
199
+ buttonStyle="danger"
200
+ confirmLabel={
201
+ labelOverrides?.confirmLabel ??
202
+ <FormattedMessage id="stripes-kint-components.customProperties.delete.confirmLabel" />
203
+ }
204
+ heading={
205
+ labelOverrides?.confirmHeading ??
206
+ <FormattedMessage id="stripes-kint-components.customProperties.delete.confirmHeading" />
207
+ }
208
+ id="delete-job-confirmation"
209
+ message={
210
+ labelOverrides?.confirmMessage ??
211
+ <SafeHTMLMessage id="stripes-kint-components.customProperties.delete.confirmMessage" values={{ name: customProperty?.name }} />
212
+ }
213
+ onCancel={() => setDeleteModal(false)}
214
+ onConfirm={() => {
215
+ deleteCustProp();
216
+ setCustomProperty();
217
+ setDeleteModal(false);
218
+ }}
219
+ open={deleteModal}
220
+ />
221
+ </>
222
+ );
223
+ };
224
+
225
+ CustomPropertiesSettings.propTypes = {
226
+ afterQueryCalls: PropTypes.object,
227
+ contextFilterOptions: PropTypes.arrayOf(PropTypes.shape({
228
+ value: PropTypes.string,
229
+ label: PropTypes.oneOfType([
230
+ PropTypes.element,
231
+ PropTypes.string
232
+ ])
233
+ })),
234
+ customPropertiesEndpoint: PropTypes.string,
235
+ helpPopovers: PropTypes.object,
236
+ labelOverrides: PropTypes.object,
237
+ refdataEndpoint: PropTypes.string,
238
+ };
239
+
240
+ export default CustomPropertiesSettings;