@k-int/stripes-kint-components 1.5.0 → 2.0.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.
- package/CHANGELOG.md +40 -1
- package/es/index.js +80 -25
- package/es/lib/ActionList/ActionList.js +92 -33
- package/es/lib/ActionList/ActionListFieldArray.js +202 -104
- package/es/lib/ActionList/index.js +7 -3
- package/es/lib/CustomProperties/Config/CustomPropertiesLookup.js +198 -0
- package/es/lib/CustomProperties/Config/CustomPropertiesSettings.js +321 -0
- package/es/lib/CustomProperties/Config/CustomPropertiesView.js +166 -0
- package/es/lib/CustomProperties/Config/CustomPropertyForm.js +357 -0
- package/es/lib/CustomProperties/Config/index.js +41 -0
- package/es/lib/EditableRefdataList/EditableRefdataList.js +69 -24
- package/es/lib/EditableRefdataList/index.js +7 -3
- package/es/lib/EditableSettingsList/EditableSettingsList.js +90 -0
- package/es/lib/EditableSettingsList/EditableSettingsListFieldArray.js +90 -0
- package/es/lib/EditableSettingsList/EditableSettingsListFieldArray.test.js +181 -0
- package/es/lib/{Settings → EditableSettingsList/SettingField}/EditSettingValue.js +72 -9
- package/es/lib/EditableSettingsList/SettingField/EditSettingValue.test.js +447 -0
- package/es/lib/{Settings → EditableSettingsList/SettingField}/RenderSettingValue.js +45 -7
- package/es/lib/EditableSettingsList/SettingField/RenderSettingValue.test.js +495 -0
- package/es/lib/EditableSettingsList/SettingField/SettingField.js +187 -0
- package/es/lib/EditableSettingsList/SettingField/SettingField.test.js +180 -0
- package/es/lib/EditableSettingsList/SettingField/index.js +35 -0
- package/es/lib/EditableSettingsList/index.js +35 -0
- package/es/lib/FormModal/FormModal.js +126 -0
- package/es/lib/FormModal/index.js +19 -0
- package/es/lib/NoResultsMessage/NoResultsMessage.js +65 -32
- package/es/lib/NoResultsMessage/index.js +7 -3
- package/es/lib/QueryTypedown/QueryTypedown.js +48 -9
- package/es/lib/QueryTypedown/index.js +6 -2
- package/es/lib/RefdataButtons/RefdataButtons.js +143 -0
- package/es/lib/RefdataButtons/index.js +19 -0
- package/es/lib/SASQLookupComponent/SASQLookupComponent.js +194 -140
- package/es/lib/SASQLookupComponent/index.js +6 -2
- package/es/lib/SASQRoute/SASQRoute.js +55 -18
- package/es/lib/SASQRoute/index.js +6 -2
- package/es/lib/SASQViewComponent/SASQViewComponent.js +50 -11
- package/es/lib/SASQViewComponent/index.js +6 -2
- package/es/lib/SearchField/SearchField.js +48 -13
- package/es/lib/SearchField/index.js +6 -2
- package/es/lib/SettingPage/SettingPage.js +99 -0
- package/es/lib/SettingPage/SettingPagePane.js +83 -0
- package/es/lib/SettingPage/index.js +27 -0
- package/es/lib/Typedown/Typedown.js +174 -99
- package/es/lib/Typedown/index.js +6 -2
- package/es/lib/constants/customProperties.js +60 -0
- package/es/lib/constants/eventCodes.js +31 -1
- package/es/lib/contexts/SettingsContext.js +41 -0
- package/es/lib/contexts/index.js +19 -0
- package/es/lib/hooks/index.js +44 -10
- package/es/lib/hooks/settingsHooks/index.js +27 -0
- package/es/lib/hooks/settingsHooks/useSettingSection.js +74 -0
- package/es/lib/hooks/settingsHooks/useSettings.js +175 -0
- package/es/lib/hooks/typedownHooks/index.js +8 -28
- package/es/lib/hooks/typedownHooks/useTypedown.js +129 -12
- package/es/lib/hooks/typedownHooks/useTypedownData.js +35 -2
- package/es/lib/hooks/typedownHooks/useTypedownToggle.js +39 -6
- package/es/lib/hooks/useActiveElement.js +33 -2
- package/es/lib/hooks/useCustomProperties.js +112 -0
- package/es/lib/hooks/useHelperApp.js +44 -11
- package/es/lib/hooks/useKiwtFieldArray.js +37 -4
- package/es/lib/hooks/useKiwtSASQuery.js +43 -9
- package/es/lib/hooks/useLocalStorageState.js +37 -4
- package/es/lib/hooks/useMutateCustomProperties.js +143 -0
- package/es/lib/hooks/useMutateRefdataValue.js +42 -9
- package/es/lib/hooks/useQIndex.js +42 -9
- package/es/lib/hooks/useRefdata.js +43 -16
- package/es/lib/hooks/useTemplates.js +36 -3
- package/es/lib/utils/buildUrl.js +43 -10
- package/es/lib/utils/generateKiwtQuery.js +33 -4
- package/es/lib/utils/generateKiwtQueryParams.js +31 -2
- package/es/lib/utils/index.js +41 -5
- package/es/lib/utils/refdataOptions.js +43 -0
- package/es/lib/utils/renderHelpText.js +109 -0
- package/es/lib/utils/selectorSafe.js +31 -2
- package/es/lib/utils/sortByLabel.js +55 -0
- package/es/lib/utils/toCamelCase.js +48 -0
- package/jest.config.js +15 -1
- package/package.json +19 -10
- package/src/index.js +25 -10
- package/src/lib/ActionList/ActionList.js +32 -22
- package/src/lib/ActionList/ActionListFieldArray.js +56 -10
- package/src/lib/ActionList/README.md +5 -1
- package/src/lib/ActionList/index.js +1 -1
- package/src/lib/CustomProperties/Config/CustomPropertiesLookup.js +111 -0
- package/src/lib/CustomProperties/Config/CustomPropertiesSettings.js +237 -0
- package/src/lib/CustomProperties/Config/CustomPropertiesView.js +150 -0
- package/src/lib/CustomProperties/Config/CustomPropertyForm.js +295 -0
- package/src/lib/CustomProperties/Config/index.js +4 -0
- package/src/lib/EditableRefdataList/EditableRefdataList.js +10 -5
- package/src/lib/EditableRefdataList/index.js +1 -1
- package/src/lib/{Settings → EditableSettingsList}/EditableSettingsList.js +0 -0
- package/src/lib/{Settings → EditableSettingsList}/EditableSettingsListFieldArray.js +2 -2
- package/src/lib/EditableSettingsList/EditableSettingsListFieldArray.test.js +111 -0
- package/src/lib/{Settings → EditableSettingsList/SettingField}/EditSettingValue.js +24 -1
- package/src/lib/EditableSettingsList/SettingField/EditSettingValue.test.js +379 -0
- package/src/lib/{Settings → EditableSettingsList/SettingField}/RenderSettingValue.js +2 -1
- package/src/lib/EditableSettingsList/SettingField/RenderSettingValue.test.js +368 -0
- package/src/lib/{Settings → EditableSettingsList/SettingField}/SettingField.js +7 -7
- package/src/lib/EditableSettingsList/SettingField/SettingField.test.js +80 -0
- package/src/lib/EditableSettingsList/SettingField/index.js +3 -0
- package/src/lib/EditableSettingsList/index.js +3 -0
- package/src/lib/FormModal/FormModal.js +71 -0
- package/src/lib/FormModal/index.js +1 -0
- package/src/lib/NoResultsMessage/NoResultsMessage.js +2 -2
- package/src/lib/NoResultsMessage/index.js +1 -1
- package/src/lib/{Settings → RefdataButtons}/RefdataButtons.js +1 -1
- package/src/lib/RefdataButtons/index.js +1 -0
- package/src/lib/SASQLookupComponent/SASQLookupComponent.js +7 -1
- package/src/lib/{Settings → SettingPage}/SettingPage.js +5 -5
- package/src/lib/{Settings → SettingPage}/SettingPagePane.js +12 -2
- package/src/lib/SettingPage/index.js +2 -0
- package/src/lib/Typedown/Typedown.js +52 -9
- package/src/lib/constants/customProperties.js +9 -0
- package/src/lib/{Settings → contexts}/SettingsContext.js +1 -1
- package/src/lib/contexts/index.js +2 -0
- package/src/lib/hooks/index.js +3 -0
- package/src/lib/hooks/settingsHooks/index.js +2 -0
- package/src/lib/{Settings → hooks/settingsHooks}/useSettingSection.js +0 -0
- package/src/lib/{Settings → hooks/settingsHooks}/useSettings.js +14 -6
- package/src/lib/hooks/typedownHooks/index.js +0 -3
- package/src/lib/hooks/typedownHooks/useTypedown.js +93 -11
- package/src/lib/hooks/useCustomProperties.js +73 -0
- package/src/lib/hooks/useMutateCustomProperties.js +62 -0
- package/src/lib/hooks/useRefdata.js +2 -8
- package/src/lib/utils/index.js +7 -0
- package/src/lib/utils/refdataOptions.js +7 -0
- package/src/lib/{Settings/utils → utils}/renderHelpText.js +1 -1
- package/src/lib/{Settings/utils → utils}/sortByLabel.js +1 -1
- package/src/lib/{Settings/utils → utils}/toCamelCase.js +0 -0
- package/test/helpers/index.js +1 -0
- package/test/helpers/translationsProperties.js +40 -0
- package/test/jest/helpers/KintHarness.js +36 -0
- package/test/jest/helpers/index.js +2 -0
- package/test/jest/helpers/renderWithKintHarness.js +15 -0
- package/test/jest/jest-transformer.js +4 -0
- package/test/jest/setupTests.js +1 -0
- package/translations/stripes-kint-components/en.json +48 -1
- package/yarn-error.log +14118 -0
- package/babelOptions.js +0 -30
- package/es/lib/Settings/EditableSettingsList.js +0 -57
- package/es/lib/Settings/EditableSettingsListFieldArray.js +0 -59
- package/es/lib/Settings/RefdataButtons.js +0 -100
- package/es/lib/Settings/SettingField.js +0 -144
- package/es/lib/Settings/SettingPage.js +0 -64
- package/es/lib/Settings/SettingPagePane.js +0 -43
- package/es/lib/Settings/SettingsContext.js +0 -18
- package/es/lib/Settings/index.js +0 -71
- package/es/lib/Settings/useSettingSection.js +0 -41
- package/es/lib/Settings/useSettings.js +0 -126
- package/es/lib/Settings/utils/index.js +0 -31
- package/es/lib/Settings/utils/renderHelpText.js +0 -57
- package/es/lib/Settings/utils/sortByLabel.js +0 -26
- package/es/lib/Settings/utils/toCamelCase.js +0 -19
- package/es/lib/TypeDown/TypeDown.js +0 -209
- package/es/lib/TypeDown/index.js +0 -15
- package/es/lib/hooks/typedownHooks/useTypedownFooter.js +0 -47
- package/es/lib/hooks/typedownHooks/useTypedownList.js +0 -45
- package/es/lib/hooks/typedownHooks/useTypedownSearchField.js +0 -47
- package/es/lib/utils/getFocusableElements.js +0 -132
- package/src/lib/Settings/index.js +0 -8
- package/src/lib/Settings/utils/index.js +0 -3
- package/src/lib/TypeDown/README.md +0 -1
- package/src/lib/TypeDown/TypeDown.js +0 -226
- package/src/lib/TypeDown/index.js +0 -1
- package/src/lib/hooks/typedownHooks/useTypedownFooter.js +0 -43
- package/src/lib/hooks/typedownHooks/useTypedownList.js +0 -36
- package/src/lib/hooks/typedownHooks/useTypedownSearchField.js +0 -39
- package/src/lib/utils/getFocusableElements.js +0 -99
|
@@ -4,7 +4,7 @@ import classnames from 'classnames';
|
|
|
4
4
|
|
|
5
5
|
import get from 'lodash/get';
|
|
6
6
|
|
|
7
|
-
import { EndOfList, IconButton, Popper } from '@folio/stripes/components';
|
|
7
|
+
import { EndOfList, IconButton, Label, Popper } from '@folio/stripes/components';
|
|
8
8
|
|
|
9
9
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
10
10
|
import { interactionStyles } from '@folio/stripes-components/lib/sharedStyles/interactionStyles.css';
|
|
@@ -17,19 +17,29 @@ import selectorSafe from '../utils/selectorSafe';
|
|
|
17
17
|
|
|
18
18
|
const Typedown = ({
|
|
19
19
|
dataOptions,
|
|
20
|
+
endOfList,
|
|
21
|
+
id,
|
|
20
22
|
input,
|
|
23
|
+
isSelected,
|
|
21
24
|
filterPath,
|
|
25
|
+
label,
|
|
22
26
|
meta,
|
|
23
27
|
onChange,
|
|
24
28
|
onType,
|
|
25
29
|
renderFooter = null,
|
|
26
30
|
renderListItem = null,
|
|
31
|
+
required,
|
|
27
32
|
uniqueIdentificationPath = 'id'
|
|
28
33
|
}) => {
|
|
29
34
|
const selectedUniqueId = get(input.value, uniqueIdentificationPath);
|
|
30
35
|
|
|
31
36
|
// Display data needs to be in line with data options but also able to react to default handleType
|
|
32
37
|
const [displayData, setDisplayData] = useState(dataOptions);
|
|
38
|
+
|
|
39
|
+
// keep track of what we've typed and whether we've typed an exact match or not
|
|
40
|
+
const [currentlyTyped, setCurrentlyTyped] = useState('');
|
|
41
|
+
const [exactMatch, setExactMatch] = useState(false);
|
|
42
|
+
|
|
33
43
|
useEffect(() => {
|
|
34
44
|
setDisplayData(dataOptions);
|
|
35
45
|
}, [dataOptions]);
|
|
@@ -46,6 +56,14 @@ const Typedown = ({
|
|
|
46
56
|
} else {
|
|
47
57
|
setDisplayData(dataOptions);
|
|
48
58
|
}
|
|
59
|
+
|
|
60
|
+
setCurrentlyTyped(e.target.value);
|
|
61
|
+
|
|
62
|
+
if (displayData.length === 1 && get(displayData[0], filterPath) === e.target.value) {
|
|
63
|
+
setExactMatch(true);
|
|
64
|
+
} else {
|
|
65
|
+
setExactMatch(false);
|
|
66
|
+
}
|
|
49
67
|
};
|
|
50
68
|
|
|
51
69
|
// Hook to set up all the essentials
|
|
@@ -74,11 +92,11 @@ const Typedown = ({
|
|
|
74
92
|
className={css.listItem}
|
|
75
93
|
>
|
|
76
94
|
{renderListItem ?
|
|
77
|
-
renderListItem(option) :
|
|
95
|
+
renderListItem(option, currentlyTyped, exactMatch) :
|
|
78
96
|
get(option, uniqueIdentificationPath)
|
|
79
97
|
}
|
|
80
98
|
</div>
|
|
81
|
-
), [renderListItem, uniqueIdentificationPath]);
|
|
99
|
+
), [currentlyTyped, exactMatch, renderListItem, uniqueIdentificationPath]);
|
|
82
100
|
|
|
83
101
|
const handleChange = useCallback(value => {
|
|
84
102
|
input.onChange(value);
|
|
@@ -101,7 +119,7 @@ const Typedown = ({
|
|
|
101
119
|
id="typedown-list"
|
|
102
120
|
>
|
|
103
121
|
{displayData?.length ? displayData?.map((d, index) => {
|
|
104
|
-
const
|
|
122
|
+
const isSelectedEval = isSelected ? isSelected(input.value, d) : get(input.value, uniqueIdentificationPath) === get(d, uniqueIdentificationPath);
|
|
105
123
|
return (
|
|
106
124
|
<button
|
|
107
125
|
key={`typedown-button-[${index}]`}
|
|
@@ -110,7 +128,7 @@ const Typedown = ({
|
|
|
110
128
|
css.fullWidth,
|
|
111
129
|
css.menuButton
|
|
112
130
|
)}
|
|
113
|
-
data-selected={
|
|
131
|
+
data-selected={isSelectedEval}
|
|
114
132
|
id={`typedown-button-[${index}]`}
|
|
115
133
|
onClick={() => {
|
|
116
134
|
handleChange(d);
|
|
@@ -123,27 +141,30 @@ const Typedown = ({
|
|
|
123
141
|
</button>
|
|
124
142
|
);
|
|
125
143
|
}) :
|
|
126
|
-
|
|
127
|
-
<EndOfList />
|
|
144
|
+
endOfList || <EndOfList />
|
|
128
145
|
}
|
|
129
146
|
</div>
|
|
130
147
|
{renderFooter &&
|
|
131
148
|
<div
|
|
132
149
|
ref={footerRef}
|
|
133
150
|
className={css.footer}
|
|
134
|
-
id=
|
|
151
|
+
id={`typedown-footer-${selectorSafe(input.name)}`}
|
|
135
152
|
>
|
|
136
|
-
{renderFooter()}
|
|
153
|
+
{renderFooter(displayData, currentlyTyped, exactMatch)}
|
|
137
154
|
</div>
|
|
138
155
|
}
|
|
139
156
|
</div>
|
|
140
157
|
);
|
|
141
158
|
}, [
|
|
159
|
+
currentlyTyped,
|
|
142
160
|
displayData,
|
|
161
|
+
endOfList,
|
|
162
|
+
exactMatch,
|
|
143
163
|
footerRef,
|
|
144
164
|
handleChange,
|
|
145
165
|
handleNextFocus,
|
|
146
166
|
input,
|
|
167
|
+
isSelected,
|
|
147
168
|
listKeyDownHandler,
|
|
148
169
|
listRef,
|
|
149
170
|
renderFooter,
|
|
@@ -174,6 +195,15 @@ const Typedown = ({
|
|
|
174
195
|
<div
|
|
175
196
|
ref={resizeRef}
|
|
176
197
|
>
|
|
198
|
+
{label &&
|
|
199
|
+
<Label
|
|
200
|
+
htmlFor={id}
|
|
201
|
+
id={`${id}-label`}
|
|
202
|
+
required={required}
|
|
203
|
+
>
|
|
204
|
+
{label}
|
|
205
|
+
</Label>
|
|
206
|
+
}
|
|
177
207
|
{renderSearchField()}
|
|
178
208
|
<Popper
|
|
179
209
|
key="typedown-menu-toggle"
|
|
@@ -222,12 +252,25 @@ const Typedown = ({
|
|
|
222
252
|
|
|
223
253
|
Typedown.propTypes = {
|
|
224
254
|
dataOptions: PropTypes.arrayOf(PropTypes.object),
|
|
255
|
+
endOfList: PropTypes.oneOfType([
|
|
256
|
+
PropTypes.func,
|
|
257
|
+
PropTypes.node,
|
|
258
|
+
PropTypes.element
|
|
259
|
+
]),
|
|
260
|
+
filterPath: PropTypes.string,
|
|
261
|
+
id: PropTypes.string,
|
|
225
262
|
input: PropTypes.object,
|
|
263
|
+
isSelected: PropTypes.func,
|
|
264
|
+
label: PropTypes.oneOfType([
|
|
265
|
+
PropTypes.string,
|
|
266
|
+
PropTypes.element
|
|
267
|
+
]),
|
|
226
268
|
meta: PropTypes.object,
|
|
227
269
|
onChange: PropTypes.func,
|
|
228
270
|
onType: PropTypes.func,
|
|
229
271
|
renderFooter: PropTypes.func,
|
|
230
272
|
renderListItem: PropTypes.func,
|
|
273
|
+
required: PropTypes.bool,
|
|
231
274
|
uniqueIdentificationPath: PropTypes.string
|
|
232
275
|
};
|
|
233
276
|
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export const TYPE_CLASS_PREFIX = 'com.k_int.web.toolkit.custprops.types.CustomProperty';
|
|
2
|
+
export const BLOB_CLASS_NAME = 'com.k_int.web.toolkit.custprops.types.CustomPropertyBlob';
|
|
3
|
+
export const BOOLEAN_CLASS_NAME = 'com.k_int.web.toolkit.custprops.types.CustomPropertyBoolean';
|
|
4
|
+
export const CONTAINER_CLASS_NAME = 'com.k_int.web.toolkit.custprops.types.CustomPropertyContainer';
|
|
5
|
+
export const DECIMAL_CLASS_NAME = 'com.k_int.web.toolkit.custprops.types.CustomPropertyDecimal';
|
|
6
|
+
export const INTEGER_CLASS_NAME = 'com.k_int.web.toolkit.custprops.types.CustomPropertyInteger';
|
|
7
|
+
export const REFDATA_CLASS_NAME = 'com.k_int.web.toolkit.custprops.types.CustomPropertyRefdata';
|
|
8
|
+
export const REFDATA_DEFINITION_CLASS_NAME = 'com.k_int.web.toolkit.custprops.types.CustomPropertyRefdataDefinition';
|
|
9
|
+
export const TEXT_CLASS_NAME = 'com.k_int.web.toolkit.custprops.types.CustomPropertyText';
|
package/src/lib/hooks/index.js
CHANGED
|
@@ -6,4 +6,7 @@ export { default as useKiwtSASQuery } from './useKiwtSASQuery';
|
|
|
6
6
|
export { default as useHelperApp } from './useHelperApp';
|
|
7
7
|
export { default as useLocalStorageState } from './useLocalStorageState';
|
|
8
8
|
export { default as useQIndex } from './useQIndex';
|
|
9
|
+
export { useSettings, useSettingSection } from './settingsHooks';
|
|
9
10
|
export { default as useKiwtFieldArray } from './useKiwtFieldArray';
|
|
11
|
+
export { default as useCustomProperties } from './useCustomProperties';
|
|
12
|
+
export { default as useMutateCustomProperties } from './useMutateCustomProperties';
|
|
File without changes
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import React, { useContext } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
|
|
2
4
|
import { useQuery } from 'react-query';
|
|
3
5
|
import { FormattedMessage, useIntl } from 'react-intl';
|
|
4
6
|
import { useOkapiKy } from '@folio/stripes/core';
|
|
5
7
|
|
|
6
8
|
import { Settings } from '@folio/stripes/smart-components';
|
|
7
9
|
|
|
8
|
-
import SettingPage from '
|
|
9
|
-
import
|
|
10
|
-
import SettingsContext from './SettingsContext';
|
|
10
|
+
import { SettingPage, SettingPagePane } from '../../SettingPage';
|
|
11
|
+
import { SettingsContext } from '../../contexts';
|
|
11
12
|
|
|
12
|
-
import { sortByLabel, toCamelCase } from '
|
|
13
|
+
import { sortByLabel, toCamelCase } from '../../utils';
|
|
13
14
|
|
|
14
15
|
const useSettings = ({
|
|
15
16
|
dynamicPageExclusions,
|
|
@@ -21,7 +22,7 @@ const useSettings = ({
|
|
|
21
22
|
}) => {
|
|
22
23
|
const ky = useOkapiKy();
|
|
23
24
|
const intl = useIntl();
|
|
24
|
-
const extraPathItems = dynamicPageExclusions.map(dpe => `filters=section!=${dpe}`)
|
|
25
|
+
const extraPathItems = dynamicPageExclusions.map(dpe => `filters=section!=${dpe}`);
|
|
25
26
|
extraPathItems.push('max=500');
|
|
26
27
|
|
|
27
28
|
const { data: appSettings = [], isLoading } = useQuery(
|
|
@@ -50,7 +51,7 @@ const useSettings = ({
|
|
|
50
51
|
);
|
|
51
52
|
});
|
|
52
53
|
|
|
53
|
-
const pageList = persistentPages.concat(dynamic).sort(sortByLabel)
|
|
54
|
+
const pageList = persistentPages.concat(dynamic).sort(sortByLabel);
|
|
54
55
|
|
|
55
56
|
const SettingsContextProvider = ({ children }) => {
|
|
56
57
|
return (
|
|
@@ -67,6 +68,13 @@ const useSettings = ({
|
|
|
67
68
|
);
|
|
68
69
|
};
|
|
69
70
|
|
|
71
|
+
SettingsContextProvider.propTypes = {
|
|
72
|
+
children: PropTypes.oneOfType([
|
|
73
|
+
PropTypes.func,
|
|
74
|
+
PropTypes.node
|
|
75
|
+
])
|
|
76
|
+
};
|
|
77
|
+
|
|
70
78
|
const SettingsComponent = (props) => {
|
|
71
79
|
const settingsData = useContext(SettingsContext);
|
|
72
80
|
|
|
@@ -1,6 +1,3 @@
|
|
|
1
1
|
export { default as useTypedown } from './useTypedown';
|
|
2
|
-
export { default as useTypedownFooter } from './useTypedownFooter';
|
|
3
|
-
export { default as useTypedownList } from './useTypedownList';
|
|
4
|
-
export { default as useTypedownSearchField } from './useTypedownSearchField';
|
|
5
2
|
export { default as useTypedownToggle } from './useTypedownToggle';
|
|
6
3
|
export { default as useTypedownData } from './useTypedownData';
|
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
import { useRef } from 'react';
|
|
2
2
|
import { useResizeDetector } from 'react-resize-detector';
|
|
3
3
|
|
|
4
|
-
// TODO swap to stripes-components export once available (Will need <= peer dep bump)
|
|
5
4
|
import {
|
|
5
|
+
getFirstFocusable,
|
|
6
|
+
getLastFocusable,
|
|
6
7
|
getNextFocusable,
|
|
7
|
-
|
|
8
|
+
getPreviousFocusable,
|
|
9
|
+
} from '@folio/stripes/components';
|
|
10
|
+
|
|
11
|
+
import {
|
|
12
|
+
DOWN_ARROW,
|
|
13
|
+
TAB,
|
|
14
|
+
UP_ARROW
|
|
15
|
+
} from '../../constants/eventCodes';
|
|
8
16
|
|
|
9
17
|
import selectorSafe from '../../utils/selectorSafe';
|
|
10
18
|
|
|
11
|
-
import
|
|
12
|
-
useTypedownToggle,
|
|
13
|
-
useTypedownFooter,
|
|
14
|
-
useTypedownSearchField,
|
|
15
|
-
useTypedownList
|
|
16
|
-
} from '.';
|
|
19
|
+
import useTypedownToggle from './useTypedownToggle';
|
|
17
20
|
|
|
18
21
|
const useTypedown = (name) => {
|
|
19
22
|
// SEARCHFIELD COMPONENT
|
|
@@ -23,11 +26,90 @@ const useTypedown = (name) => {
|
|
|
23
26
|
const listRef = useRef();
|
|
24
27
|
const triggerRef = useRef();
|
|
25
28
|
const overlayRef = useRef();
|
|
26
|
-
const footerRef =
|
|
29
|
+
const footerRef = useRef();
|
|
30
|
+
|
|
31
|
+
const footer = document.getElementById(`typedown-footer-${selectorSafe(name)}`);
|
|
32
|
+
// Add an event listener to the footer, so that we can control tab behaviour between footer elements
|
|
33
|
+
|
|
34
|
+
if (footer && footer.getAttribute('hasListener') !== 'true') {
|
|
35
|
+
footer.addEventListener('keydown', e => {
|
|
36
|
+
// We want special behaviour on tab
|
|
37
|
+
if (e.code === TAB) {
|
|
38
|
+
// Prevent the default behaviour
|
|
39
|
+
e.preventDefault();
|
|
40
|
+
const focusFunc = e.shiftKey ? getPreviousFocusable : getNextFocusable;
|
|
41
|
+
const elem = focusFunc(footerRef.current, true, true, false, true);
|
|
42
|
+
|
|
43
|
+
if (elem) {
|
|
44
|
+
// Focus on next focusable element
|
|
45
|
+
elem.focus();
|
|
46
|
+
} else if (e.shiftKey) {
|
|
47
|
+
// We are at the beginning of the list, refocus on search bar
|
|
48
|
+
searchFieldComponent.focus();
|
|
49
|
+
} else {
|
|
50
|
+
// We are at the end of the list, move onto next focusable element in page
|
|
51
|
+
getNextFocusable(searchFieldComponent, false).focus();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
footer.setAttribute('hasListener', 'true');
|
|
57
|
+
}
|
|
27
58
|
|
|
28
59
|
// SET UP HANDLERS
|
|
29
|
-
const searchFieldKeyDownHandler =
|
|
30
|
-
|
|
60
|
+
const searchFieldKeyDownHandler = e => {
|
|
61
|
+
if (e.code === UP_ARROW) {
|
|
62
|
+
const elem = getLastFocusable(listRef.current, true, true);
|
|
63
|
+
if (elem) {
|
|
64
|
+
elem.focus();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (e.code === DOWN_ARROW) {
|
|
69
|
+
const elem = getFirstFocusable(listRef.current, true, true);
|
|
70
|
+
if (elem) {
|
|
71
|
+
elem.focus();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Tab key (But not while shifting)
|
|
76
|
+
if (e.code === TAB && !e.shiftKey) {
|
|
77
|
+
e.preventDefault();
|
|
78
|
+
// If we have focusable elements in the footer, then focus on them, else unfocus searchbar
|
|
79
|
+
const elem = getNextFocusable(footerRef.current, true, true, true, true);
|
|
80
|
+
if (elem) {
|
|
81
|
+
elem.focus();
|
|
82
|
+
} else {
|
|
83
|
+
getNextFocusable(searchFieldComponent, false).focus();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const listKeyDownHandler = e => {
|
|
89
|
+
if (e.code === DOWN_ARROW) {
|
|
90
|
+
const elem = getNextFocusable(listRef.current, true, true);
|
|
91
|
+
elem.focus();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (e.code === UP_ARROW) {
|
|
95
|
+
const elem = getPreviousFocusable(listRef.current, true, true);
|
|
96
|
+
elem.focus();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (e.code === TAB) {
|
|
100
|
+
e.preventDefault();
|
|
101
|
+
let elem;
|
|
102
|
+
if (!e.shiftKey && !footerRef.current) {
|
|
103
|
+
elem = getNextFocusable(searchFieldComponent, false);
|
|
104
|
+
} else if (!e.shiftKey) {
|
|
105
|
+
elem = getNextFocusable(footerRef.current, true, true, true, true);
|
|
106
|
+
} else {
|
|
107
|
+
elem = searchFieldComponent;
|
|
108
|
+
}
|
|
109
|
+
elem.focus();
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
|
|
31
113
|
const handleNextFocus = () => getNextFocusable(searchFieldComponent, false).focus();
|
|
32
114
|
|
|
33
115
|
// SET UP VARIABLES
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import PropTypes from 'prop-types';
|
|
2
|
+
|
|
3
|
+
import { useQuery } from 'react-query';
|
|
4
|
+
import { useOkapiKy } from '@folio/stripes/core';
|
|
5
|
+
|
|
6
|
+
import { generateKiwtQuery } from '../utils';
|
|
7
|
+
|
|
8
|
+
const useCustomProperties = ({
|
|
9
|
+
endpoint,
|
|
10
|
+
ctx,
|
|
11
|
+
nsValues = {
|
|
12
|
+
sort: 'id'
|
|
13
|
+
},
|
|
14
|
+
options = {
|
|
15
|
+
searchKey: 'label,name,description',
|
|
16
|
+
filterKeys: {
|
|
17
|
+
ContextKey: 'ctx'
|
|
18
|
+
},
|
|
19
|
+
stats: false,
|
|
20
|
+
max: 100
|
|
21
|
+
},
|
|
22
|
+
queryParams,
|
|
23
|
+
returnQueryObject = false,
|
|
24
|
+
}) => {
|
|
25
|
+
const ky = useOkapiKy();
|
|
26
|
+
|
|
27
|
+
// Allow passing of 'false' for isNull
|
|
28
|
+
if (Array.isArray(ctx)) {
|
|
29
|
+
// If we have an array, append a context filter for each ctx given
|
|
30
|
+
nsValues.filters = ctx.map(c => {
|
|
31
|
+
if (c === 'isNull') {
|
|
32
|
+
return 'ContextWithoutKey.ctx isNull';
|
|
33
|
+
} else {
|
|
34
|
+
return `ContextKey.${c}`;
|
|
35
|
+
}
|
|
36
|
+
}).join(',');
|
|
37
|
+
} else if (ctx === 'isNull') { // isNull is a special case
|
|
38
|
+
nsValues.filters = 'ContextWithoutKey.ctx isNull';
|
|
39
|
+
} else if (ctx) {
|
|
40
|
+
// If we just have a string, append a single ctx filter
|
|
41
|
+
nsValues.filters = `ContextKey.${ctx}`;
|
|
42
|
+
} else {
|
|
43
|
+
nsValues.filters = null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const query = generateKiwtQuery(options, nsValues);
|
|
47
|
+
const path = `${endpoint}${query}`;
|
|
48
|
+
|
|
49
|
+
const queryObject = useQuery(
|
|
50
|
+
['stripes-kint-components', 'useCustomProperties', 'custprops', ctx, path],
|
|
51
|
+
() => ky(path).json(),
|
|
52
|
+
queryParams
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
if (returnQueryObject) {
|
|
56
|
+
return queryObject || {};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const { data: custprops } = queryObject;
|
|
60
|
+
return custprops || [];
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
useCustomProperties.propTypes = {
|
|
64
|
+
endpoint: PropTypes.string,
|
|
65
|
+
ctx: PropTypes.oneOfType([
|
|
66
|
+
PropTypes.string,
|
|
67
|
+
PropTypes.arrayOf(PropTypes.string)
|
|
68
|
+
]),
|
|
69
|
+
queryParams: PropTypes.object,
|
|
70
|
+
returnQueryObject: PropTypes.bool
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export default useCustomProperties;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { useMutation } from 'react-query';
|
|
2
|
+
|
|
3
|
+
import { useOkapiKy } from '@folio/stripes/core';
|
|
4
|
+
|
|
5
|
+
const useMutateCustomProperties = ({
|
|
6
|
+
afterQueryCalls,
|
|
7
|
+
endpoint,
|
|
8
|
+
id,
|
|
9
|
+
queryParams,
|
|
10
|
+
returnQueryObject = {
|
|
11
|
+
post: false,
|
|
12
|
+
put: false,
|
|
13
|
+
delete: false
|
|
14
|
+
}
|
|
15
|
+
}) => {
|
|
16
|
+
const returnObj = {};
|
|
17
|
+
|
|
18
|
+
const ky = useOkapiKy();
|
|
19
|
+
|
|
20
|
+
const deleteQueryObject = useMutation(
|
|
21
|
+
['stripes-kint-components', 'useMutateCustomProperties', 'delete', id],
|
|
22
|
+
async () => ky.delete(`${endpoint}/${id}`).json()
|
|
23
|
+
.then(afterQueryCalls?.delete),
|
|
24
|
+
queryParams?.delete
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
const putQueryObject = useMutation(
|
|
28
|
+
['stripes-kint-components', 'useMutateCustomProperties', 'put', id],
|
|
29
|
+
async (data) => ky.put(`${endpoint}/${id}`, { json: data }).json()
|
|
30
|
+
.then(afterQueryCalls?.put),
|
|
31
|
+
queryParams?.put
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
const postQueryObject = useMutation(
|
|
35
|
+
['stripes-kint-components', 'useMutateCustomProperties', 'post'],
|
|
36
|
+
async (data) => ky.post(`${endpoint}`, { json: data }).json()
|
|
37
|
+
.then(afterQueryCalls?.post),
|
|
38
|
+
queryParams?.post
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
if (returnQueryObject?.delete) {
|
|
42
|
+
returnObj.delete = deleteQueryObject;
|
|
43
|
+
} else {
|
|
44
|
+
returnObj.delete = deleteQueryObject.mutateAsync;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (returnQueryObject?.put) {
|
|
48
|
+
returnObj.put = putQueryObject;
|
|
49
|
+
} else {
|
|
50
|
+
returnObj.put = putQueryObject.mutateAsync;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (returnQueryObject?.post) {
|
|
54
|
+
returnObj.post = postQueryObject;
|
|
55
|
+
} else {
|
|
56
|
+
returnObj.post = postQueryObject.mutateAsync;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return returnObj;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export default useMutateCustomProperties;
|
|
@@ -4,20 +4,14 @@ import PropTypes from 'prop-types';
|
|
|
4
4
|
import { useQuery } from 'react-query';
|
|
5
5
|
import { useOkapiKy } from '@folio/stripes/core';
|
|
6
6
|
|
|
7
|
-
import { generateKiwtQuery } from '../utils';
|
|
7
|
+
import { generateKiwtQuery, refdataOptions } from '../utils';
|
|
8
8
|
|
|
9
9
|
const useRefdata = ({
|
|
10
10
|
endpoint,
|
|
11
11
|
desc,
|
|
12
|
+
options = refdataOptions,
|
|
12
13
|
queryParams,
|
|
13
14
|
returnQueryObject = false,
|
|
14
|
-
options = {
|
|
15
|
-
filterKeys: {
|
|
16
|
-
DescKey: 'desc'
|
|
17
|
-
},
|
|
18
|
-
stats: false,
|
|
19
|
-
max: 100
|
|
20
|
-
}
|
|
21
15
|
}) => {
|
|
22
16
|
const ky = useOkapiKy();
|
|
23
17
|
|
package/src/lib/utils/index.js
CHANGED
|
@@ -3,3 +3,10 @@ export { default as generateKiwtQueryParams } from './generateKiwtQueryParams';
|
|
|
3
3
|
export { default as selectorSafe } from './selectorSafe';
|
|
4
4
|
|
|
5
5
|
export { default as buildUrl } from './buildUrl';
|
|
6
|
+
|
|
7
|
+
export { default as refdataOptions } from './refdataOptions';
|
|
8
|
+
|
|
9
|
+
// Settings utils
|
|
10
|
+
export { default as renderHelpText } from './renderHelpText';
|
|
11
|
+
export { default as sortByLabel } from './sortByLabel';
|
|
12
|
+
export { default as toCamelCase } from './toCamelCase'; // I hate that this exists
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './translationsProperties';
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import translations from '../../translations/stripes-kint-components/en';
|
|
2
|
+
|
|
3
|
+
const translationsProperties = [
|
|
4
|
+
{
|
|
5
|
+
prefix: 'stripes-kint-components',
|
|
6
|
+
translations,
|
|
7
|
+
},
|
|
8
|
+
/* Don't think we're using any of the below rn */
|
|
9
|
+
{
|
|
10
|
+
prefix: 'stripes-core',
|
|
11
|
+
translations: {
|
|
12
|
+
'label.missingRequiredField': 'Please fill this in to continue',
|
|
13
|
+
'button.save': 'Save',
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
prefix: 'stripes-components',
|
|
18
|
+
translations: {
|
|
19
|
+
'saveAndClose': 'Save and close',
|
|
20
|
+
'cancel': 'Cancel',
|
|
21
|
+
'paneMenuActionsToggleLabel': 'Actions',
|
|
22
|
+
'collapseAll': 'Collapse all',
|
|
23
|
+
'button.edit': 'Edit'
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
prefix: 'stripes-smart-components',
|
|
28
|
+
translations: {
|
|
29
|
+
'permissionError': 'Sorry - your permissions do not allow access to this page.',
|
|
30
|
+
'searchAndFilter': 'Search and filter',
|
|
31
|
+
'hideSearchPane': 'Hide search pane',
|
|
32
|
+
'search': 'Search',
|
|
33
|
+
'resetAll': 'Reset all',
|
|
34
|
+
'searchResultsCountHeader': '"{count, number} {count, plural, one {record found} other {records found}}"',
|
|
35
|
+
'new': 'New'
|
|
36
|
+
},
|
|
37
|
+
}
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
export default translationsProperties;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { Harness } from '@folio/stripes-erm-components/test/jest/helpers';
|
|
4
|
+
|
|
5
|
+
import { SettingsContext } from '../../../src/lib/contexts';
|
|
6
|
+
import translationsProperties from '../../helpers';
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
export default function KintHarness({
|
|
10
|
+
children,
|
|
11
|
+
settingsValues = {
|
|
12
|
+
intlKey: 'stripes-kint-components',
|
|
13
|
+
refdataEndpoint: 'path/to/refdata',
|
|
14
|
+
settingEndpoint: 'path/to/settings',
|
|
15
|
+
templateEndpoint: 'path/to/templates'
|
|
16
|
+
},
|
|
17
|
+
translations = translationsProperties,
|
|
18
|
+
...harnessProps
|
|
19
|
+
}) {
|
|
20
|
+
return (
|
|
21
|
+
<SettingsContext.Provider value={settingsValues}>
|
|
22
|
+
<Harness
|
|
23
|
+
translations={translations}
|
|
24
|
+
{...harnessProps}
|
|
25
|
+
>
|
|
26
|
+
{children}
|
|
27
|
+
</Harness>
|
|
28
|
+
</SettingsContext.Provider>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
KintHarness.propTypes = {
|
|
33
|
+
children: PropTypes.node,
|
|
34
|
+
settingsValues: PropTypes.object,
|
|
35
|
+
translations: PropTypes.object
|
|
36
|
+
};
|