@k-int/stripes-kint-components 2.2.0 → 2.3.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 +21 -0
- package/es/index.js +124 -4
- package/es/lib/ActionList/ActionList.js +7 -2
- package/es/lib/ActionList/ActionListFieldArray.js +49 -10
- package/es/lib/CustomProperties/Config/CustomPropertiesSettings.js +2 -2
- package/es/lib/CustomProperties/Config/{CustomPropertiesView.js → CustomPropertyView.js} +5 -5
- package/es/lib/CustomProperties/Config/index.js +6 -4
- package/es/lib/CustomProperties/Edit/CustomPropertiesEdit.js +72 -0
- package/es/lib/CustomProperties/Edit/CustomPropertiesEditCtx.js +133 -0
- package/es/lib/CustomProperties/Edit/CustomPropertiesListField.js +279 -0
- package/es/lib/CustomProperties/Edit/CustomPropertyField.js +370 -0
- package/es/lib/CustomProperties/Edit/CustomPropertyFormCard.js +156 -0
- package/es/lib/CustomProperties/Edit/index.js +51 -0
- package/es/lib/CustomProperties/Filter/CustomPropertiesFilter.js +216 -0
- package/es/lib/CustomProperties/Filter/CustomPropertiesFilterField.js +236 -0
- package/es/lib/CustomProperties/Filter/CustomPropertiesFilterFieldArray.js +159 -0
- package/es/lib/CustomProperties/Filter/CustomPropertiesFilterForm.js +119 -0
- package/es/lib/CustomProperties/Filter/CustomPropertiesRule.js +173 -0
- package/es/lib/CustomProperties/Filter/index.js +59 -0
- package/es/lib/CustomProperties/Filter/useOperators.js +138 -0
- package/es/lib/CustomProperties/Filter/useParseActiveFilterStrings.js +97 -0
- package/es/lib/CustomProperties/Filter/useValueProps.js +101 -0
- package/es/lib/CustomProperties/View/CustomPropertiesView.js +73 -0
- package/es/lib/CustomProperties/View/CustomPropertiesViewCtx.js +187 -0
- package/es/lib/CustomProperties/View/CustomPropertyCard.js +204 -0
- package/es/lib/CustomProperties/View/index.js +35 -0
- package/es/lib/CustomProperties/index.js +125 -0
- package/es/lib/EditableRefdataList/EditableRefdataList.js +12 -16
- package/es/lib/FormModal/FormModal.js +18 -4
- package/es/lib/QueryTypedown/QueryTypedown.js +9 -4
- package/es/lib/constants/customProperties.js +4 -1
- package/es/lib/hooks/index.js +16 -0
- package/es/lib/hooks/typedownHooks/useTypedownData.js +9 -2
- package/es/lib/hooks/useAvailableCustomProperties.js +106 -0
- package/es/lib/hooks/useInvalidateRefdata.js +53 -0
- package/es/lib/hooks/useMutateRefdataValue.js +11 -6
- package/es/lib/hooks/useRefdata.js +1 -3
- package/es/lib/utils/groupCustomPropertiesByCtx.js +69 -0
- package/es/lib/utils/index.js +24 -0
- package/es/lib/utils/refdataQueryKey.js +48 -0
- package/es/lib/utils/typedownQueryKey.js +48 -0
- package/es/lib/utils/validators.js +60 -1
- package/git_translate.sh +8 -0
- package/package.json +1 -1
- package/src/index.js +27 -3
- package/src/lib/ActionList/ActionList.js +5 -2
- package/src/lib/ActionList/ActionListFieldArray.js +31 -8
- package/src/lib/ActionList/README.md +23 -20
- package/src/lib/CustomProperties/Config/CustomPropertiesSettings.js +2 -2
- package/src/lib/CustomProperties/Config/{CustomPropertiesView.js → CustomPropertyView.js} +3 -3
- package/src/lib/CustomProperties/Config/index.js +1 -1
- package/src/lib/CustomProperties/Edit/CustomPropertiesEdit.js +35 -0
- package/src/lib/CustomProperties/Edit/CustomPropertiesEditCtx.js +85 -0
- package/src/lib/CustomProperties/Edit/CustomPropertiesListField.js +194 -0
- package/src/lib/CustomProperties/Edit/CustomPropertyField.js +299 -0
- package/src/lib/CustomProperties/Edit/CustomPropertyFormCard.js +131 -0
- package/src/lib/CustomProperties/Edit/index.js +5 -0
- package/src/lib/CustomProperties/Filter/CustomPropertiesFilter.js +125 -0
- package/src/lib/CustomProperties/Filter/CustomPropertiesFilterField.js +148 -0
- package/src/lib/CustomProperties/Filter/CustomPropertiesFilterFieldArray.js +113 -0
- package/src/lib/CustomProperties/Filter/CustomPropertiesFilterForm.js +74 -0
- package/src/lib/CustomProperties/Filter/CustomPropertiesRule.js +122 -0
- package/src/lib/CustomProperties/Filter/index.js +6 -0
- package/src/lib/CustomProperties/Filter/useOperators.js +55 -0
- package/src/lib/CustomProperties/Filter/useParseActiveFilterStrings.js +35 -0
- package/src/lib/CustomProperties/Filter/useValueProps.js +45 -0
- package/src/lib/CustomProperties/View/CustomPropertiesView.js +36 -0
- package/src/lib/CustomProperties/View/CustomPropertiesViewCtx.js +112 -0
- package/src/lib/CustomProperties/View/CustomPropertyCard.js +177 -0
- package/src/lib/CustomProperties/View/index.js +3 -0
- package/src/lib/CustomProperties/index.js +30 -0
- package/src/lib/EditableRefdataList/EditableRefdataList.js +13 -10
- package/src/lib/FormModal/FormModal.js +37 -17
- package/src/lib/QueryTypedown/QueryTypedown.js +3 -1
- package/src/lib/constants/customProperties.js +1 -0
- package/src/lib/hooks/index.js +2 -0
- package/src/lib/hooks/typedownHooks/useTypedownData.js +9 -3
- package/src/lib/hooks/useAvailableCustomProperties.js +40 -0
- package/src/lib/hooks/useInvalidateRefdata.js +11 -0
- package/src/lib/hooks/useMutateRefdataValue.js +7 -3
- package/src/lib/hooks/useRefdata.js +2 -3
- package/src/lib/utils/groupCustomPropertiesByCtx.js +13 -0
- package/src/lib/utils/index.js +5 -0
- package/src/lib/utils/refdataQueryKey.js +9 -0
- package/src/lib/utils/typedownQueryKey.js +9 -0
- package/src/lib/utils/validators.js +40 -0
- package/translate.sh +63 -0
- package/translations/stripes-kint-components/ar.json +105 -0
- package/translations/stripes-kint-components/ca.json +1 -0
- package/translations/stripes-kint-components/cs_CZ.json +105 -0
- package/translations/stripes-kint-components/da.json +1 -0
- package/translations/stripes-kint-components/de.json +105 -0
- package/translations/stripes-kint-components/en.json +54 -2
- package/translations/stripes-kint-components/es.json +105 -0
- package/translations/stripes-kint-components/fr.json +105 -0
- package/translations/stripes-kint-components/he.json +1 -0
- package/translations/stripes-kint-components/hi_IN.json +105 -0
- package/translations/stripes-kint-components/hu.json +105 -0
- package/translations/stripes-kint-components/it_IT.json +105 -0
- package/translations/stripes-kint-components/ja.json +105 -0
- package/translations/stripes-kint-components/ko.json +105 -0
- package/translations/stripes-kint-components/nb.json +1 -0
- package/translations/stripes-kint-components/nn.json +1 -0
- package/translations/stripes-kint-components/pl.json +105 -0
- package/translations/stripes-kint-components/pt_PT.json +105 -0
- package/translations/stripes-kint-components/ru.json +105 -0
- package/translations/stripes-kint-components/sv.json +105 -0
- package/translations/stripes-kint-components/ur.json +1 -0
- package/translations/stripes-kint-components/zh_CN.json +105 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Datepicker, Select, TextField } from '@folio/stripes/components';
|
|
2
|
+
import * as CUSTPROP_TYPES from '../../constants/customProperties';
|
|
3
|
+
import { invalidNumber as invalidNumberValidator, required as requiredValidator } from '../../utils/validators';
|
|
4
|
+
|
|
5
|
+
const {
|
|
6
|
+
REFDATA_CLASS_NAME: REFDATA,
|
|
7
|
+
DECIMAL_CLASS_NAME: DECIMAL,
|
|
8
|
+
INTEGER_CLASS_NAME: INTEGER,
|
|
9
|
+
DATE_CLASS_NAME: DATE,
|
|
10
|
+
TEXT_CLASS_NAME: TEXT,
|
|
11
|
+
} = CUSTPROP_TYPES;
|
|
12
|
+
|
|
13
|
+
const useValueProps = (custPropDefinition) => {
|
|
14
|
+
const props = {
|
|
15
|
+
validate: requiredValidator
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
switch (custPropDefinition.type) {
|
|
19
|
+
case INTEGER:
|
|
20
|
+
case DECIMAL:
|
|
21
|
+
props.component = TextField;
|
|
22
|
+
props.type = 'number';
|
|
23
|
+
props.validate = invalidNumberValidator;
|
|
24
|
+
break;
|
|
25
|
+
case REFDATA:
|
|
26
|
+
props.component = Select;
|
|
27
|
+
props.dataOptions = custPropDefinition.category.values.map(rdv => ({ label: rdv.label, value: rdv.id }));
|
|
28
|
+
props.placeholder = ' ';
|
|
29
|
+
break;
|
|
30
|
+
case DATE:
|
|
31
|
+
props.component = Datepicker;
|
|
32
|
+
props.backendDateStandard = 'YYYY-MM-DD';
|
|
33
|
+
props.timeZone = 'UTC';
|
|
34
|
+
props.usePortal = true;
|
|
35
|
+
break;
|
|
36
|
+
case TEXT:
|
|
37
|
+
default:
|
|
38
|
+
props.component = TextField;
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return props;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export default useValueProps;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import PropTypes from 'prop-types';
|
|
2
|
+
import CustomPropertiesViewCtx from './CustomPropertiesViewCtx';
|
|
3
|
+
|
|
4
|
+
const CustomPropertiesView = ({
|
|
5
|
+
contexts = [],
|
|
6
|
+
customProperties,
|
|
7
|
+
customPropertiesEndpoint,
|
|
8
|
+
id,
|
|
9
|
+
labelOverrides = {},
|
|
10
|
+
}) => {
|
|
11
|
+
return (
|
|
12
|
+
contexts.map(ctx => (
|
|
13
|
+
<CustomPropertiesViewCtx
|
|
14
|
+
key={`customPropertiesView-${ctx}`}
|
|
15
|
+
{...{
|
|
16
|
+
ctx,
|
|
17
|
+
customProperties,
|
|
18
|
+
customPropertiesEndpoint,
|
|
19
|
+
id,
|
|
20
|
+
labelOverrides
|
|
21
|
+
}}
|
|
22
|
+
/>
|
|
23
|
+
))
|
|
24
|
+
);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
CustomPropertiesView.propTypes = {
|
|
28
|
+
contexts: PropTypes.arrayOf(PropTypes.string),
|
|
29
|
+
customProperties: PropTypes.object,
|
|
30
|
+
customPropertiesEndpoint: PropTypes.string,
|
|
31
|
+
id: PropTypes.string,
|
|
32
|
+
labelOverrides: PropTypes.object,
|
|
33
|
+
nameOverride: PropTypes.string
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export default CustomPropertiesView;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import PropTypes from 'prop-types';
|
|
2
|
+
import { FormattedMessage } from 'react-intl';
|
|
3
|
+
import { Accordion, Badge, Spinner } from '@folio/stripes/components';
|
|
4
|
+
|
|
5
|
+
import { useCustomProperties } from '../../hooks';
|
|
6
|
+
|
|
7
|
+
import CustomPropertyCard from './CustomPropertyCard';
|
|
8
|
+
|
|
9
|
+
const CustomPropertiesViewCtx = ({
|
|
10
|
+
ctx,
|
|
11
|
+
customProperties,
|
|
12
|
+
customPropertiesEndpoint,
|
|
13
|
+
id,
|
|
14
|
+
labelOverrides
|
|
15
|
+
}) => {
|
|
16
|
+
// Deal with all the possible label override options
|
|
17
|
+
const getAccordionLabel = () => {
|
|
18
|
+
// Special case for null context
|
|
19
|
+
if (ctx === 'isNull') {
|
|
20
|
+
return (
|
|
21
|
+
labelOverrides.noContext ??
|
|
22
|
+
<FormattedMessage id="stripes-kint-components.customProperties" />
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Label overrides for specific contexts
|
|
27
|
+
if (labelOverrides[ctx]) {
|
|
28
|
+
return labelOverrides[ctx];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Label override for default title, taking ctx into account
|
|
32
|
+
if (labelOverrides.defaultTitle && typeof labelOverrides.defaultTitle === 'function') {
|
|
33
|
+
return (
|
|
34
|
+
labelOverrides.defaultTitle(ctx)
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Label override for default title or finally built in default
|
|
39
|
+
return (
|
|
40
|
+
labelOverrides.defaultTitle ??
|
|
41
|
+
<FormattedMessage id="stripes-kint-components.customProperties.ctx.title" values={{ ctx }} />
|
|
42
|
+
);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const { data: custprops, isLoading } = useCustomProperties({
|
|
46
|
+
ctx,
|
|
47
|
+
endpoint: customPropertiesEndpoint,
|
|
48
|
+
returnQueryObject: true,
|
|
49
|
+
options: {
|
|
50
|
+
sort: [
|
|
51
|
+
{ path: 'retired' }, // Place retired custprops at the end
|
|
52
|
+
{ path: 'primary', direction: 'desc' }, // Primary properties should display before optional
|
|
53
|
+
{ path: 'label' } // Within those groups, sort by label
|
|
54
|
+
]
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
if (isLoading) {
|
|
59
|
+
return (
|
|
60
|
+
<Accordion
|
|
61
|
+
closedByDefault
|
|
62
|
+
displayWhenClosed={<Spinner />}
|
|
63
|
+
displayWhenOpen={<Spinner />}
|
|
64
|
+
id={`${id}-accordion-${ctx}`}
|
|
65
|
+
label={getAccordionLabel()}
|
|
66
|
+
>
|
|
67
|
+
<Spinner />
|
|
68
|
+
</Accordion>
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// We need to display any set properties, along with any non-set primary properties
|
|
73
|
+
const primaryCount = custprops?.filter(cp => cp.primary === true)?.length ?? 0;
|
|
74
|
+
const optionalCount = Object.entries(customProperties)?.filter(
|
|
75
|
+
([_key, cp]) => (
|
|
76
|
+
(cp[0]?.type?.ctx === ctx || (ctx === 'isNull' && !cp[0]?.type?.ctx)) && // Either the ctx string matches, or isNull matches blank
|
|
77
|
+
cp[0]?.type?.primary === false // Only count non-primary set custprops
|
|
78
|
+
)
|
|
79
|
+
)?.length ?? 0;
|
|
80
|
+
|
|
81
|
+
return (
|
|
82
|
+
(primaryCount + optionalCount) > 0 &&
|
|
83
|
+
<Accordion
|
|
84
|
+
closedByDefault
|
|
85
|
+
displayWhenClosed={<Badge>{primaryCount + optionalCount}</Badge>}
|
|
86
|
+
displayWhenOpen={<Badge>{primaryCount + optionalCount}</Badge>}
|
|
87
|
+
id={`${id}-accordion-${ctx}`}
|
|
88
|
+
label={getAccordionLabel()}
|
|
89
|
+
>
|
|
90
|
+
{custprops.map((cp, index) => (
|
|
91
|
+
<CustomPropertyCard
|
|
92
|
+
key={`custom-property-card-${ctx}[${index}]`}
|
|
93
|
+
ctx={ctx}
|
|
94
|
+
customProperty={customProperties?.[cp.name]?.[0]}
|
|
95
|
+
customPropertyDefinition={cp}
|
|
96
|
+
index={index}
|
|
97
|
+
labelOverrides={labelOverrides}
|
|
98
|
+
/>
|
|
99
|
+
))}
|
|
100
|
+
</Accordion>
|
|
101
|
+
);
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
CustomPropertiesViewCtx.propTypes = {
|
|
105
|
+
ctx: PropTypes.string,
|
|
106
|
+
customProperties: PropTypes.object,
|
|
107
|
+
customPropertiesEndpoint: PropTypes.string,
|
|
108
|
+
id: PropTypes.string,
|
|
109
|
+
labelOverrides: PropTypes.object,
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
export default CustomPropertiesViewCtx;
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import PropTypes from 'prop-types';
|
|
2
|
+
import { FormattedMessage, FormattedNumber } from 'react-intl';
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
Card,
|
|
6
|
+
Col,
|
|
7
|
+
FormattedUTCDate,
|
|
8
|
+
InfoPopover,
|
|
9
|
+
KeyValue,
|
|
10
|
+
NoValue,
|
|
11
|
+
Row,
|
|
12
|
+
} from '@folio/stripes/components';
|
|
13
|
+
|
|
14
|
+
import * as CUSTPROP_TYPES from '../../constants/customProperties';
|
|
15
|
+
|
|
16
|
+
const CustomPropertyCard = ({
|
|
17
|
+
ctx,
|
|
18
|
+
customProperty,
|
|
19
|
+
customPropertyDefinition,
|
|
20
|
+
index,
|
|
21
|
+
labelOverrides
|
|
22
|
+
}) => {
|
|
23
|
+
// We only need to display primary and set properties
|
|
24
|
+
const toDisplay = !!(customPropertyDefinition.primary || customProperty);
|
|
25
|
+
|
|
26
|
+
if (!toDisplay) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const internalFalse = customProperty?.internal === false ||
|
|
31
|
+
(customProperty?.internal === undefined && customPropertyDefinition.defaultInternal === false);
|
|
32
|
+
|
|
33
|
+
// Deal with all the possible label override options
|
|
34
|
+
const getRetiredCardTitle = () => {
|
|
35
|
+
// Label override for default card title,
|
|
36
|
+
if (labelOverrides.retiredName && typeof labelOverrides.retiredName === 'function') {
|
|
37
|
+
return (
|
|
38
|
+
labelOverrides.retiredName(customPropertyDefinition)
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Label override for default title or finally built in default
|
|
43
|
+
return (
|
|
44
|
+
labelOverrides.retiredName ??
|
|
45
|
+
<FormattedMessage id="stripes-kint-components.customProperty.retiredName" values={{ name: customPropertyDefinition.label }} />
|
|
46
|
+
);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const getInternalLabel = () => {
|
|
50
|
+
if (internalFalse) {
|
|
51
|
+
return (
|
|
52
|
+
labelOverrides.internalFalse ??
|
|
53
|
+
<FormattedMessage id="stripes-kint-components.customProperty.internalFalse" />
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return (
|
|
58
|
+
labelOverrides.internalTrue ??
|
|
59
|
+
<FormattedMessage id="stripes-kint-components.customProperty.internalTrue" />
|
|
60
|
+
);
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const renderValue = () => {
|
|
64
|
+
if (!customProperty) {
|
|
65
|
+
return (
|
|
66
|
+
labelOverrides.notSet ??
|
|
67
|
+
<FormattedMessage id="stripes-kint-components.customProperty.notSet" />
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
switch (customPropertyDefinition.type) {
|
|
72
|
+
case CUSTPROP_TYPES.REFDATA_CLASS_NAME:
|
|
73
|
+
return customProperty.value?.label ?? customProperty.value?.value;
|
|
74
|
+
case CUSTPROP_TYPES.DECIMAL_CLASS_NAME:
|
|
75
|
+
case CUSTPROP_TYPES.INTEGER_CLASS_NAME:
|
|
76
|
+
return <FormattedNumber value={customProperty.value} />;
|
|
77
|
+
case CUSTPROP_TYPES.DATE_CLASS_NAME:
|
|
78
|
+
return <FormattedUTCDate value={customProperty.value} />;
|
|
79
|
+
case CUSTPROP_TYPES.TEXT_CLASS_NAME:
|
|
80
|
+
default:
|
|
81
|
+
return customProperty.value;
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
return (
|
|
86
|
+
<Card
|
|
87
|
+
key={`customPropertyCard-${ctx}[${index}]`}
|
|
88
|
+
headerStart={
|
|
89
|
+
<>
|
|
90
|
+
<strong>
|
|
91
|
+
{customPropertyDefinition.retired ?
|
|
92
|
+
getRetiredCardTitle() :
|
|
93
|
+
customPropertyDefinition.label
|
|
94
|
+
}
|
|
95
|
+
</strong>
|
|
96
|
+
{customPropertyDefinition.description ? (
|
|
97
|
+
<InfoPopover
|
|
98
|
+
content={customPropertyDefinition.description}
|
|
99
|
+
/>
|
|
100
|
+
) : null}
|
|
101
|
+
</>
|
|
102
|
+
}
|
|
103
|
+
id={`customproperty-card-${index}`}
|
|
104
|
+
>
|
|
105
|
+
<Row>
|
|
106
|
+
<Col xs={6}>
|
|
107
|
+
<KeyValue
|
|
108
|
+
label={
|
|
109
|
+
labelOverrides.value ??
|
|
110
|
+
<FormattedMessage id="stripes-kint-components.customProperty.value" />
|
|
111
|
+
}
|
|
112
|
+
>
|
|
113
|
+
{renderValue()}
|
|
114
|
+
</KeyValue>
|
|
115
|
+
</Col>
|
|
116
|
+
{customProperty?.internalNote ? (
|
|
117
|
+
<Col xs={6}>
|
|
118
|
+
<KeyValue
|
|
119
|
+
label={
|
|
120
|
+
labelOverrides.internalNote ??
|
|
121
|
+
<FormattedMessage id="stripes-kint-components.customProperty.internalNote" />
|
|
122
|
+
}
|
|
123
|
+
>
|
|
124
|
+
<span
|
|
125
|
+
style={{ whiteSpace: 'pre-wrap' }}
|
|
126
|
+
>
|
|
127
|
+
{customProperty.internalNote}
|
|
128
|
+
</span>
|
|
129
|
+
</KeyValue>
|
|
130
|
+
</Col>
|
|
131
|
+
) : null}
|
|
132
|
+
</Row>
|
|
133
|
+
<Row>
|
|
134
|
+
<Col xs={6}>
|
|
135
|
+
<KeyValue
|
|
136
|
+
label={
|
|
137
|
+
labelOverrides.visibility ??
|
|
138
|
+
<FormattedMessage id="stripes-kint-components.customProperty.visibility" />
|
|
139
|
+
}
|
|
140
|
+
>
|
|
141
|
+
{getInternalLabel()}
|
|
142
|
+
</KeyValue>
|
|
143
|
+
</Col>
|
|
144
|
+
{internalFalse &&
|
|
145
|
+
<Col xs={6}>
|
|
146
|
+
<KeyValue
|
|
147
|
+
label={
|
|
148
|
+
labelOverrides.publicNote ??
|
|
149
|
+
<FormattedMessage id="stripes-kint-components.customProperty.publicNote" />
|
|
150
|
+
}
|
|
151
|
+
>
|
|
152
|
+
{customProperty?.publicNote ? (
|
|
153
|
+
<span
|
|
154
|
+
style={{ whiteSpace: 'pre-wrap' }}
|
|
155
|
+
>
|
|
156
|
+
{customProperty.publicNote}
|
|
157
|
+
</span>
|
|
158
|
+
) : (
|
|
159
|
+
<NoValue />
|
|
160
|
+
)}
|
|
161
|
+
</KeyValue>
|
|
162
|
+
</Col>
|
|
163
|
+
}
|
|
164
|
+
</Row>
|
|
165
|
+
</Card>
|
|
166
|
+
);
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
CustomPropertyCard.propTypes = {
|
|
170
|
+
ctx: PropTypes.string,
|
|
171
|
+
customProperty: PropTypes.object,
|
|
172
|
+
customPropertyDefinition: PropTypes.object,
|
|
173
|
+
index: PropTypes.number,
|
|
174
|
+
labelOverrides: PropTypes.object,
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
export default CustomPropertyCard;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export {
|
|
2
|
+
CustomPropertiesLookup,
|
|
3
|
+
CustomPropertyView,
|
|
4
|
+
CustomPropertiesSettings,
|
|
5
|
+
CustomPropertyForm
|
|
6
|
+
} from './Config';
|
|
7
|
+
|
|
8
|
+
export {
|
|
9
|
+
CustomPropertiesEdit,
|
|
10
|
+
CustomPropertiesEditCtx,
|
|
11
|
+
CustomPropertiesListField,
|
|
12
|
+
CustomPropertyFormCard,
|
|
13
|
+
CustomPropertyField
|
|
14
|
+
} from './Edit';
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
export {
|
|
18
|
+
CustomPropertiesView,
|
|
19
|
+
CustomPropertiesViewCtx,
|
|
20
|
+
CustomPropertyCard
|
|
21
|
+
} from './View';
|
|
22
|
+
|
|
23
|
+
export {
|
|
24
|
+
CustomPropertiesFilter,
|
|
25
|
+
CustomPropertiesFilterForm,
|
|
26
|
+
CustomPropertiesFilterField,
|
|
27
|
+
CustomPropertiesFilterFieldArray,
|
|
28
|
+
useOperators,
|
|
29
|
+
useParseActiveFilterStrings,
|
|
30
|
+
} from './Filter';
|
|
@@ -55,25 +55,28 @@ const EditableRefdataList = ({ desc, refdataEndpoint }) => {
|
|
|
55
55
|
// This is the function which will take a row in the table and assign the relevant actions to it
|
|
56
56
|
const actionAssigner = () => {
|
|
57
57
|
const actionArray = [
|
|
58
|
-
{
|
|
58
|
+
{
|
|
59
|
+
name: 'edit',
|
|
60
|
+
label: <FormattedMessage id="stripes-kint-components.editableRefdataList.edit" />,
|
|
61
|
+
icon: 'edit',
|
|
62
|
+
callback: (data) => editRefdataValue(data)
|
|
63
|
+
}
|
|
59
64
|
];
|
|
60
65
|
|
|
61
66
|
if (!refdata?.internal) {
|
|
62
|
-
actionArray.push({
|
|
67
|
+
actionArray.push({
|
|
68
|
+
name: 'delete',
|
|
69
|
+
label: <FormattedMessage id="stripes-kint-components.editableRefdataList.delete" />,
|
|
70
|
+
icon: 'trash',
|
|
71
|
+
callback: (data) => deleteRefdataValue(data.id)
|
|
72
|
+
});
|
|
63
73
|
}
|
|
64
74
|
return actionArray;
|
|
65
75
|
};
|
|
66
76
|
|
|
67
|
-
const actionCalls = {
|
|
68
|
-
create: refdata?.internal ? null : (data) => editRefdataValue(data),
|
|
69
|
-
edit: (data) => editRefdataValue(data),
|
|
70
|
-
delete: (data) => deleteRefdataValue(data.id)
|
|
71
|
-
};
|
|
72
|
-
|
|
73
77
|
return (
|
|
74
78
|
<ActionList
|
|
75
79
|
actionAssigner={actionAssigner}
|
|
76
|
-
actionCalls={actionCalls}
|
|
77
80
|
columnMapping={{
|
|
78
81
|
label: <FormattedMessage id="stripes-kint-components.editableRefdataList.label" />,
|
|
79
82
|
value: <FormattedMessage id="stripes-kint-components.editableRefdataList.value" />
|
|
@@ -82,11 +85,11 @@ const EditableRefdataList = ({ desc, refdataEndpoint }) => {
|
|
|
82
85
|
creatableFields={{
|
|
83
86
|
value: () => false
|
|
84
87
|
}}
|
|
88
|
+
createCallback={refdata?.internal ? null : (data) => editRefdataValue(data)}
|
|
85
89
|
editableFields={{
|
|
86
90
|
value: () => false
|
|
87
91
|
}}
|
|
88
92
|
visibleFields={['label', 'value']}
|
|
89
|
-
// TODO add a field validator/fieldType as options?
|
|
90
93
|
/>
|
|
91
94
|
);
|
|
92
95
|
};
|
|
@@ -4,7 +4,13 @@ import { Form } from 'react-final-form';
|
|
|
4
4
|
import { FormattedMessage } from 'react-intl';
|
|
5
5
|
import { Button, Modal, ModalFooter } from '@folio/stripes/components';
|
|
6
6
|
|
|
7
|
-
const FormModal = ({
|
|
7
|
+
const FormModal = ({
|
|
8
|
+
children,
|
|
9
|
+
labelOverrides = {},
|
|
10
|
+
modalProps: { footer, onClose, ...modalProps },
|
|
11
|
+
onSubmit,
|
|
12
|
+
...formProps
|
|
13
|
+
}) => {
|
|
8
14
|
return (
|
|
9
15
|
<Form
|
|
10
16
|
onSubmit={onSubmit}
|
|
@@ -16,21 +22,33 @@ const FormModal = ({ children, modalProps: { onClose, ...modalProps }, onSubmit,
|
|
|
16
22
|
restart();
|
|
17
23
|
};
|
|
18
24
|
|
|
19
|
-
const renderFooter = () =>
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
25
|
+
const renderFooter = () => {
|
|
26
|
+
if (footer) {
|
|
27
|
+
return footer({ handleSubmit, handleClose });
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<ModalFooter>
|
|
32
|
+
<Button
|
|
33
|
+
buttonStyle="primary"
|
|
34
|
+
onClick={handleSubmit}
|
|
35
|
+
>
|
|
36
|
+
{
|
|
37
|
+
labelOverrides.save ??
|
|
38
|
+
<FormattedMessage id="stripes-kint-components.save" />
|
|
39
|
+
}
|
|
40
|
+
</Button>
|
|
41
|
+
<Button
|
|
42
|
+
onClick={handleClose}
|
|
43
|
+
>
|
|
44
|
+
{
|
|
45
|
+
labelOverrides.cancel ??
|
|
46
|
+
<FormattedMessage id="stripes-kint-components.cancel" />
|
|
47
|
+
}
|
|
48
|
+
</Button>
|
|
49
|
+
</ModalFooter>
|
|
50
|
+
);
|
|
51
|
+
};
|
|
34
52
|
|
|
35
53
|
return (
|
|
36
54
|
<form
|
|
@@ -57,8 +75,10 @@ FormModal.propTypes = {
|
|
|
57
75
|
PropTypes.node,
|
|
58
76
|
PropTypes.func,
|
|
59
77
|
]),
|
|
78
|
+
labelOverrides: PropTypes.object,
|
|
60
79
|
modalProps: PropTypes.shape({
|
|
61
|
-
|
|
80
|
+
footer: PropTypes.func,
|
|
81
|
+
onClose: PropTypes.func,
|
|
62
82
|
}),
|
|
63
83
|
onSubmit: PropTypes.func
|
|
64
84
|
};
|
|
@@ -5,12 +5,13 @@ import Typedown from '../Typedown';
|
|
|
5
5
|
import { useTypedownData } from '../hooks/typedownHooks';
|
|
6
6
|
|
|
7
7
|
const QueryTypedown = ({
|
|
8
|
+
dataFormatter = d => d,
|
|
8
9
|
path,
|
|
9
10
|
pathMutator,
|
|
10
11
|
...rest
|
|
11
12
|
}) => {
|
|
12
13
|
const [callPath, setCallPath] = useState(pathMutator(null, path));
|
|
13
|
-
const data = useTypedownData(callPath);
|
|
14
|
+
const data = dataFormatter(useTypedownData(path, callPath));
|
|
14
15
|
|
|
15
16
|
const onType = e => {
|
|
16
17
|
setCallPath(pathMutator(e.target.value, path));
|
|
@@ -26,6 +27,7 @@ const QueryTypedown = ({
|
|
|
26
27
|
};
|
|
27
28
|
|
|
28
29
|
QueryTypedown.propTypes = {
|
|
30
|
+
dataFormatter: PropTypes.func,
|
|
29
31
|
path: PropTypes.string,
|
|
30
32
|
pathMutator: PropTypes.func
|
|
31
33
|
};
|
|
@@ -7,3 +7,4 @@ export const INTEGER_CLASS_NAME = 'com.k_int.web.toolkit.custprops.types.CustomP
|
|
|
7
7
|
export const REFDATA_CLASS_NAME = 'com.k_int.web.toolkit.custprops.types.CustomPropertyRefdata';
|
|
8
8
|
export const REFDATA_DEFINITION_CLASS_NAME = 'com.k_int.web.toolkit.custprops.types.CustomPropertyRefdataDefinition';
|
|
9
9
|
export const TEXT_CLASS_NAME = 'com.k_int.web.toolkit.custprops.types.CustomPropertyText';
|
|
10
|
+
export const DATE_CLASS_NAME = 'com.k_int.web.toolkit.custprops.types.CustomPropertyLocalDate';
|
package/src/lib/hooks/index.js
CHANGED
|
@@ -10,3 +10,5 @@ export { useSettings, useSettingSection } from './settingsHooks';
|
|
|
10
10
|
export { default as useKiwtFieldArray } from './useKiwtFieldArray';
|
|
11
11
|
export { default as useCustomProperties } from './useCustomProperties';
|
|
12
12
|
export { default as useMutateCustomProperties } from './useMutateCustomProperties';
|
|
13
|
+
export { default as useAvailableCustomProperties } from './useAvailableCustomProperties';
|
|
14
|
+
export { default as useInvalidateRefdata } from './useInvalidateRefdata';
|
|
@@ -2,16 +2,22 @@ import { useEffect, useState } from 'react';
|
|
|
2
2
|
import { useQuery } from 'react-query';
|
|
3
3
|
import { useOkapiKy } from '@folio/stripes/core';
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
import { typedownQueryKey } from '../../utils';
|
|
6
|
+
|
|
7
|
+
const useTypedownData = (path, callPath) => {
|
|
6
8
|
const ky = useOkapiKy();
|
|
7
9
|
|
|
10
|
+
const queryKey = typedownQueryKey(path);
|
|
11
|
+
if (callPath) {
|
|
12
|
+
queryKey.push(callPath);
|
|
13
|
+
}
|
|
14
|
+
|
|
8
15
|
const { data, isLoading } = useQuery(
|
|
9
16
|
// Ensure when multiple apps are using this function that each one gets memoized individually
|
|
10
|
-
|
|
17
|
+
queryKey,
|
|
11
18
|
() => ky(callPath).json()
|
|
12
19
|
);
|
|
13
20
|
|
|
14
|
-
|
|
15
21
|
// Smooth out transitions while data changes by only displaying once call has been loaded.
|
|
16
22
|
const [contentData, setContentData] = useState();
|
|
17
23
|
useEffect(() => {
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
import { useIntl } from 'react-intl';
|
|
3
|
+
|
|
4
|
+
const useAvailableCustomProperties = (customProperties = []) => {
|
|
5
|
+
const intl = useIntl();
|
|
6
|
+
const [custProps, setCustProps] = useState([]);
|
|
7
|
+
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
if (customProperties.length !== custProps.length) {
|
|
10
|
+
setCustProps(customProperties.map(customProperty => {
|
|
11
|
+
let options = customProperty?.category?.values;
|
|
12
|
+
if (options) {
|
|
13
|
+
options = [
|
|
14
|
+
{
|
|
15
|
+
label: intl.formatMessage({
|
|
16
|
+
id: 'stripes-kint-components.notSet',
|
|
17
|
+
}),
|
|
18
|
+
value: '',
|
|
19
|
+
},
|
|
20
|
+
...options,
|
|
21
|
+
];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
description: customProperty.description,
|
|
26
|
+
label: customProperty.label,
|
|
27
|
+
primary: customProperty.primary,
|
|
28
|
+
type: customProperty.type,
|
|
29
|
+
options,
|
|
30
|
+
value: customProperty.name,
|
|
31
|
+
defaultInternal: customProperty.defaultInternal,
|
|
32
|
+
};
|
|
33
|
+
}));
|
|
34
|
+
}
|
|
35
|
+
}, [custProps, customProperties, intl]);
|
|
36
|
+
|
|
37
|
+
return custProps;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export default useAvailableCustomProperties;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { useQueryClient } from 'react-query';
|
|
2
|
+
|
|
3
|
+
import { refdataQueryKey } from '../utils';
|
|
4
|
+
|
|
5
|
+
const useInvalidateRefdata = (desc) => {
|
|
6
|
+
const queryClient = useQueryClient();
|
|
7
|
+
|
|
8
|
+
return () => queryClient.invalidateQueries(refdataQueryKey(desc));
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export default useInvalidateRefdata;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
1
|
import { useMutation } from 'react-query';
|
|
3
2
|
|
|
4
3
|
import { useOkapiKy } from '@folio/stripes/core';
|
|
5
4
|
|
|
5
|
+
import useInvalidateRefdata from './useInvalidateRefdata';
|
|
6
|
+
|
|
6
7
|
const useMutateRefdataValue = ({
|
|
7
8
|
afterQueryCalls,
|
|
8
9
|
endpoint,
|
|
@@ -16,6 +17,7 @@ const useMutateRefdataValue = ({
|
|
|
16
17
|
const returnObj = {};
|
|
17
18
|
|
|
18
19
|
const ky = useOkapiKy();
|
|
20
|
+
const invalidateRefdata = useInvalidateRefdata();
|
|
19
21
|
|
|
20
22
|
const deleteQueryObject = useMutation(
|
|
21
23
|
['stripes-kint-components', 'useMutateRefdataValue', 'delete', id],
|
|
@@ -33,7 +35,8 @@ const useMutateRefdataValue = ({
|
|
|
33
35
|
}
|
|
34
36
|
}
|
|
35
37
|
).json()
|
|
36
|
-
.then(afterQueryCalls?.delete)
|
|
38
|
+
.then(afterQueryCalls?.delete)
|
|
39
|
+
.then(() => invalidateRefdata()),
|
|
37
40
|
queryParams?.delete
|
|
38
41
|
);
|
|
39
42
|
|
|
@@ -50,7 +53,8 @@ const useMutateRefdataValue = ({
|
|
|
50
53
|
}
|
|
51
54
|
}
|
|
52
55
|
).json()
|
|
53
|
-
.then(afterQueryCalls?.put)
|
|
56
|
+
.then(afterQueryCalls?.put)
|
|
57
|
+
.then(() => invalidateRefdata()),
|
|
54
58
|
queryParams?.put
|
|
55
59
|
);
|
|
56
60
|
|