sanity-plugin-taxonomy-manager 1.0.1 → 1.0.2
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 +6 -0
- package/lib/components/prefLabel.js +5 -4
- package/lib/components/prefLabel.js.map +1 -1
- package/lib/components/treeView.js +9 -8
- package/lib/components/treeView.js.map +1 -1
- package/lib/skosConcept.js +2 -1
- package/lib/skosConcept.js.map +1 -1
- package/package.json +1 -1
- package/src/components/prefLabel.js +58 -55
- package/src/components/treeView.js +75 -73
- package/src/skosConcept.js +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
6
6
|
|
|
7
7
|
<!-- ## [TODO] -->
|
|
8
8
|
|
|
9
|
+
## [1.0.2] - 2022-09-28
|
|
10
|
+
### Fixed
|
|
11
|
+
- Fixed bug introduced by Sanity Studio update 2.33.0 that made `parent` unavailable to custom components directly.
|
|
12
|
+
### Changed
|
|
13
|
+
- Made concept scheme assignment `async` to improve consistency of Concept Scheme Tree View rendering.
|
|
14
|
+
|
|
9
15
|
## [1.0.1] - 2022-06-12
|
|
10
16
|
### Added
|
|
11
17
|
- Add "Concept Scheme Tree View" custom component to Taxonomy Schemes view. List shows hierarchy, Top Concepts, orphans, and polyhierarchial concepts.
|
|
@@ -11,6 +11,8 @@ var _components = require("@sanity/base/components");
|
|
|
11
11
|
|
|
12
12
|
var _ui = require("@sanity/ui");
|
|
13
13
|
|
|
14
|
+
var _formBuilder = require("part:@sanity/form-builder");
|
|
15
|
+
|
|
14
16
|
var _PatchEvent = _interopRequireWildcard(require("@sanity/form-builder/PatchEvent"));
|
|
15
17
|
|
|
16
18
|
var _autoId = require("@reach/auto-id");
|
|
@@ -26,7 +28,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
|
26
28
|
* This component creates a Concept IRI preview to help taxonomy managers avoid errors in minting URIs.
|
|
27
29
|
*/
|
|
28
30
|
// hook to generate unique IDs
|
|
29
|
-
var PrefLabel = /*#__PURE__*/_react.default.forwardRef((props, ref) => {
|
|
31
|
+
var PrefLabel = (0, _formBuilder.withParent)( /*#__PURE__*/_react.default.forwardRef((props, ref) => {
|
|
30
32
|
var type = props.type,
|
|
31
33
|
value = props.value,
|
|
32
34
|
readOnly = props.readOnly,
|
|
@@ -81,9 +83,8 @@ var PrefLabel = /*#__PURE__*/_react.default.forwardRef((props, ref) => {
|
|
|
81
83
|
})), /*#__PURE__*/_react.default.createElement(_ui.Text, {
|
|
82
84
|
muted: true,
|
|
83
85
|
size: 1
|
|
84
|
-
}, /*#__PURE__*/_react.default.createElement("strong", null, "Concept IRI: "), parent.conceptIriBase ? parent.conceptIriBase.iriValue : '[base URI not defined] ', value === null || value === void 0 ? void 0 : value.replaceAll(' ', '')));
|
|
85
|
-
});
|
|
86
|
-
|
|
86
|
+
}, /*#__PURE__*/_react.default.createElement("strong", null, "Concept IRI: "), parent !== null && parent !== void 0 && parent.conceptIriBase ? parent.conceptIriBase.iriValue : '[base URI not defined] ', value === null || value === void 0 ? void 0 : value.replaceAll(' ', '')));
|
|
87
|
+
}));
|
|
87
88
|
var _default = PrefLabel;
|
|
88
89
|
exports.default = _default;
|
|
89
90
|
//# sourceMappingURL=prefLabel.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/prefLabel.js"],"names":["PrefLabel","React","forwardRef","props","ref","type","value","readOnly","placeholder","markers","presence","compareValue","onFocus","onBlur","onChange","parent","inputId","handleChange","useCallback","event","inputValue","currentTarget","PatchEvent","from","description","title","conceptIriBase","iriValue","replaceAll"],"mappings":";;;;;;;AAIA;;AACA;;AACA;;AACA;;AACA;;;;;;;;
|
|
1
|
+
{"version":3,"sources":["../../src/components/prefLabel.js"],"names":["PrefLabel","React","forwardRef","props","ref","type","value","readOnly","placeholder","markers","presence","compareValue","onFocus","onBlur","onChange","parent","inputId","handleChange","useCallback","event","inputValue","currentTarget","PatchEvent","from","description","title","conceptIriBase","iriValue","replaceAll"],"mappings":";;;;;;;AAIA;;AACA;;AACA;;AACA;;AACA;;AACA;;;;;;;;AATA;AACA;AACA;AACA;AAMqC;AAErC,IAAMA,SAAS,GAAG,2CAChBC,eAAMC,UAAN,CAAiB,CAACC,KAAD,EAAQC,GAAR,KAAgB;AAC/B,MACEC,IADF,GAYIF,KAZJ,CACEE,IADF;AAAA,MAEEC,KAFF,GAYIH,KAZJ,CAEEG,KAFF;AAAA,MAGEC,QAHF,GAYIJ,KAZJ,CAGEI,QAHF;AAAA,MAIEC,WAJF,GAYIL,KAZJ,CAIEK,WAJF;AAAA,MAKEC,OALF,GAYIN,KAZJ,CAKEM,OALF;AAAA,MAMEC,QANF,GAYIP,KAZJ,CAMEO,QANF;AAAA,MAOEC,YAPF,GAYIR,KAZJ,CAOEQ,YAPF;AAAA,MAQEC,OARF,GAYIT,KAZJ,CAQES,OARF;AAAA,MASEC,MATF,GAYIV,KAZJ,CASEU,MATF;AAAA,MAUEC,QAVF,GAYIX,KAZJ,CAUEW,QAVF;AAAA,MAWEC,MAXF,GAYIZ,KAZJ,CAWEY,MAXF,CAD+B,CAe/B;;AACA,MAAMC,OAAO,GAAG,oBAAhB,CAhB+B,CAkB/B;;AACA,MAAMC,YAAY,GAAGhB,eAAMiB,WAAN,EACnB;AACCC,EAAAA,KAAD,IAAW;AACT,QAAMC,UAAU,GAAGD,KAAK,CAACE,aAAN,CAAoBf,KAAvC,CADS,CACoC;AAC7C;;AACAQ,IAAAA,QAAQ,CAACQ,oBAAWC,IAAX,CAAgBH,UAAU,GAAG,qBAAIA,UAAJ,CAAH,GAAqB,wBAA/C,CAAD,CAAR;AACD,GANkB,EAOnB,CAACN,QAAD,CAPmB,CAArB;;AAUA,sBACE,6BAAC,SAAD;AAAO,IAAA,KAAK,EAAE;AAAd,kBACE,6BAAC,qBAAD;AACE,IAAA,WAAW,EAAET,IAAI,CAACmB,WADpB;AAEE,IAAA,KAAK,EAAEnB,IAAI,CAACoB,KAFd;AAGE,IAAA,kBAAkB,EAAEhB,OAHtB,CAG+B;AAH/B;AAIE,IAAA,mBAAmB,EAAEC,QAJvB,CAIiC;AAJjC;AAKE,IAAA,YAAY,EAAEC,YALhB,CAK8B;AAL9B;AAME,IAAA,OAAO,EAAEK,OANX,CAMoB;;AANpB,kBAQE,6BAAC,aAAD;AACE,IAAA,EAAE,EAAEA,OADN,CACe;AADf;AAEE,IAAA,QAAQ,EAAEC,YAFZ,CAE0B;AAF1B;AAGE,IAAA,KAAK,EAAEX,KAHT,CAGgB;AAHhB;AAIE,IAAA,QAAQ,EAAEC,QAJZ,CAIsB;AAJtB;AAKE,IAAA,WAAW,EAAEC,WALf,CAK4B;AAL5B;AAME,IAAA,OAAO,EAAEI,OANX,CAMoB;AANpB;AAOE,IAAA,MAAM,EAAEC,MAPV,CAOkB;AAPlB;AAQE,IAAA,GAAG,EAAET;AARP,IARF,CADF,eAoBE,6BAAC,QAAD;AAAM,IAAA,KAAK,MAAX;AAAY,IAAA,IAAI,EAAE;AAAlB,kBACE,6DADF,EAEGW,MAAM,SAAN,IAAAA,MAAM,WAAN,IAAAA,MAAM,CAAEW,cAAR,GAAyBX,MAAM,CAACW,cAAP,CAAsBC,QAA/C,GAA0D,yBAF7D,EAGGrB,KAHH,aAGGA,KAHH,uBAGGA,KAAK,CAAEsB,UAAP,CAAkB,GAAlB,EAAuB,EAAvB,CAHH,CApBF,CADF;AA4BD,CAzDD,CADgB,CAAlB;eA6De5B,S","sourcesContent":["/**\n * PrefLabel input component for SKOS Concept\n * This component creates a Concept IRI preview to help taxonomy managers avoid errors in minting URIs.\n */\nimport React from 'react'\nimport {FormField} from '@sanity/base/components'\nimport {TextInput, Stack, Text} from '@sanity/ui'\nimport {withParent} from 'part:@sanity/form-builder'\nimport PatchEvent, {set, unset} from '@sanity/form-builder/PatchEvent'\nimport {useId} from '@reach/auto-id' // hook to generate unique IDs\n\nconst PrefLabel = withParent(\n React.forwardRef((props, ref) => {\n const {\n type, // Schema information\n value, // Current field value\n readOnly, // Boolean if field is not editable\n placeholder, // Placeholder text from the schema\n markers, // Markers including validation rules\n presence, // Presence information for collaborative avatars\n compareValue, // Value to check for \"edited\" functionality\n onFocus, // Method to handle focus state\n onBlur, // Method to handle blur state\n onChange, // Method to handle patch events\n parent // **Showing up as undefined as of 2022-09-26**\n } = props\n\n // Creates a unique ID for input\n const inputId = useId()\n\n // Creates a change handler for patching data\n const handleChange = React.useCallback(\n // useCallback will help with performance\n (event) => {\n const inputValue = event.currentTarget.value // get current value\n // if the value exists, set the data, if not, unset the data\n onChange(PatchEvent.from(inputValue ? set(inputValue) : unset()))\n },\n [onChange]\n )\n\n return (\n <Stack space={1}>\n <FormField\n description={type.description}\n title={type.title}\n __unstable_markers={markers} // Handles all markers including validation\n __unstable_presence={presence} // Handles presence avatars\n compareValue={compareValue} // Handles \"edited\" status\n inputId={inputId} // Allows the label to connect to the input field\n >\n <TextInput\n id={inputId} // A unique ID for this input\n onChange={handleChange} // A function to call when the input value changes\n value={value} // Current field value\n readOnly={readOnly} // If \"readOnly\" is defined make this field read only\n placeholder={placeholder} // If placeholder is defined, display placeholder text\n onFocus={onFocus} // Handles focus events\n onBlur={onBlur} // Handles blur events\n ref={ref}\n />\n </FormField>\n <Text muted size={1}>\n <strong>Concept IRI: </strong>\n {parent?.conceptIriBase ? parent.conceptIriBase.iriValue : '[base URI not defined] '}\n {value?.replaceAll(' ', '')}\n </Text>\n </Stack>\n )\n })\n)\n\nexport default PrefLabel\n"],"file":"prefLabel.js"}
|
|
@@ -9,6 +9,8 @@ var _react = _interopRequireWildcard(require("react"));
|
|
|
9
9
|
|
|
10
10
|
var _ui = require("@sanity/ui");
|
|
11
11
|
|
|
12
|
+
var _formBuilder = require("part:@sanity/form-builder");
|
|
13
|
+
|
|
12
14
|
var _client = _interopRequireDefault(require("part:@sanity/base/client"));
|
|
13
15
|
|
|
14
16
|
var s = _interopRequireWildcard(require("./treeView.module.css"));
|
|
@@ -41,7 +43,7 @@ var client = _client.default.withConfig({
|
|
|
41
43
|
|
|
42
44
|
|
|
43
45
|
var RecursiveConcept = props => {
|
|
44
|
-
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, props.isError && /*#__PURE__*/_react.default.createElement("p", null, "
|
|
46
|
+
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, props.isError && /*#__PURE__*/_react.default.createElement("p", null, "Sorry, could not get concepts."), props.noConcept && /*#__PURE__*/_react.default.createElement("p", null, "This scheme does not yet have any concepts assigned to it."), props.isLoading ? /*#__PURE__*/_react.default.createElement("p", null, "Loading hierarchy ...") : /*#__PURE__*/_react.default.createElement("ul", null, props.concepts.map(concept => {
|
|
45
47
|
var _concept$broaderSchem, _concept$narrower;
|
|
46
48
|
|
|
47
49
|
return /*#__PURE__*/_react.default.createElement("li", {
|
|
@@ -53,7 +55,7 @@ var RecursiveConcept = props => {
|
|
|
53
55
|
})));
|
|
54
56
|
};
|
|
55
57
|
|
|
56
|
-
var TreeView = /*#__PURE__*/_react.default.forwardRef((props, ref) => {
|
|
58
|
+
var TreeView = (0, _formBuilder.withParent)( /*#__PURE__*/_react.default.forwardRef((props, ref) => {
|
|
57
59
|
var _useState = (0, _react.useState)([]),
|
|
58
60
|
_useState2 = _slicedToArray(_useState, 2),
|
|
59
61
|
concepts = _useState2[0],
|
|
@@ -72,9 +74,8 @@ var TreeView = /*#__PURE__*/_react.default.forwardRef((props, ref) => {
|
|
|
72
74
|
var _useState7 = (0, _react.useState)(false),
|
|
73
75
|
_useState8 = _slicedToArray(_useState7, 2),
|
|
74
76
|
isError = _useState8[0],
|
|
75
|
-
setIsError = _useState8[1];
|
|
77
|
+
setIsError = _useState8[1]; // This function builds the first level of hierarchy, noting Top Concepts and orphans, then calls the recursiveQuery() function
|
|
76
78
|
|
|
77
|
-
var conceptScheme = props.parent._id; // This function builds the first level of hierarchy, noting Top Concepts and orphans, then calls the recursiveQuery() function
|
|
78
79
|
|
|
79
80
|
var queryBuilder = function queryBuilder() {
|
|
80
81
|
var depth = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 5;
|
|
@@ -82,7 +83,7 @@ var TreeView = /*#__PURE__*/_react.default.forwardRef((props, ref) => {
|
|
|
82
83
|
if (depth === 0) {
|
|
83
84
|
return '';
|
|
84
85
|
} else {
|
|
85
|
-
return "*[_type==\"skosConcept\" && references($conceptScheme) && (count(broader[]) < 1 || broader == null) && !(_id in path(\"drafts.**\"))]|order(prefLabel) {\n
|
|
86
|
+
return "*[_type==\"skosConcept\" && references($conceptScheme) && (count(broader[]) < 1 || broader == null) && !(_id in path(\"drafts.**\"))]|order(prefLabel) {\n \"level\": 0,\n \"id\": _id,\n prefLabel,\n topConcept,\n ".concat(recursiveQuery(depth), "\n }");
|
|
86
87
|
}
|
|
87
88
|
}; // This function builds all subsequent levels found in the data and notes any concepts that exist in two places in this Concept Scheme (i.e. which are polyhierarchical)
|
|
88
89
|
|
|
@@ -93,13 +94,14 @@ var TreeView = /*#__PURE__*/_react.default.forwardRef((props, ref) => {
|
|
|
93
94
|
if (depth === 0) {
|
|
94
95
|
return '';
|
|
95
96
|
} else {
|
|
96
|
-
return "\"narrower\": *[_type == \"skosConcept\" && references($conceptScheme) && references(^._id) && !(_id in path(\"drafts.**\"))]|order(prefLabel) {\n
|
|
97
|
+
return "\"narrower\": *[_type == \"skosConcept\" && references($conceptScheme) && references(^._id) && !(_id in path(\"drafts.**\"))]|order(prefLabel) {\n \"level\": ".concat(count, ",\n \"id\": _id,\n prefLabel,\n \"broaderSchemas\": broader[]->scheme->._id, \n \"parentScheme\": $conceptScheme, ").concat(recursiveQuery(depth - 1, count + 1), " \n }");
|
|
97
98
|
}
|
|
98
99
|
};
|
|
99
100
|
|
|
100
101
|
(0, _react.useEffect)(() => {
|
|
101
102
|
var fetchConcepts = /*#__PURE__*/function () {
|
|
102
103
|
var _ref = _asyncToGenerator(function* () {
|
|
104
|
+
var conceptScheme = yield props.parent._id;
|
|
103
105
|
setIsError(false);
|
|
104
106
|
setNoConcept(false);
|
|
105
107
|
setIsLoading(true);
|
|
@@ -147,8 +149,7 @@ var TreeView = /*#__PURE__*/_react.default.forwardRef((props, ref) => {
|
|
|
147
149
|
noConcept: noConcept,
|
|
148
150
|
isError: isError
|
|
149
151
|
}))));
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
+
}));
|
|
152
153
|
var _default = TreeView;
|
|
153
154
|
exports.default = _default;
|
|
154
155
|
//# sourceMappingURL=treeView.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/treeView.js"],"names":["client","sanityClient","withConfig","apiVersion","RecursiveConcept","props","isError","noConcept","isLoading","concepts","map","concept","id","topConcept","s","orphan","broaderSchemas","filter","parentScheme","length","polyHier","prefLabel","narrower","TreeView","React","forwardRef","ref","setConcepts","setIsLoading","setNoConcept","setIsError","
|
|
1
|
+
{"version":3,"sources":["../../src/components/treeView.js"],"names":["client","sanityClient","withConfig","apiVersion","RecursiveConcept","props","isError","noConcept","isLoading","concepts","map","concept","id","topConcept","s","orphan","broaderSchemas","filter","parentScheme","length","polyHier","prefLabel","narrower","TreeView","React","forwardRef","ref","setConcepts","setIsLoading","setNoConcept","setIsError","queryBuilder","depth","recursiveQuery","count","fetchConcepts","conceptScheme","parent","_id","params","query","response","fetch","error","console","log","type","title","description"],"mappings":"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","sourcesContent":["/**\n * Taxonomy Tree View input component for SKOS Concept Schemes\n * This component creates a hierarchical, linked (TDB) display of concepts associated with the associated Concept Scheme\n * @todo Add ability to set hierarchy depth from config file\n * @todo Add links to concepts that open in a pane to the right (see notes below)\n * @todo Add affordance for collapsing and expanding tree view (see notes below)\n * @todo Add affordance for creating new child concept in pane to the right (or modal) from a tree view concept\n * @todo Differentiate \"new concept scheme\" error state from other fetch() error states\n * @todo Add listener to JS client to reflect hierarchy updates as they happen: https://www.sanity.io/plugins/javascript-api-client\n */\n\nimport React, {useState, useEffect} from 'react'\nimport {Box, Stack, Text} from '@sanity/ui'\nimport {withParent} from 'part:@sanity/form-builder'\nimport sanityClient from 'part:@sanity/base/client'\nimport * as s from './treeView.module.css'\n\nconst client = sanityClient.withConfig({apiVersion: '2021-03-25'})\n\n// This component builds the hierarchy tree, messages loading state, messages no concepts found state.\nconst RecursiveConcept = (props) => {\n return (\n <>\n {props.isError && <p>Sorry, could not get concepts.</p>}\n {props.noConcept && <p>This scheme does not yet have any concepts assigned to it.</p>}\n {props.isLoading ? (\n <p>Loading hierarchy ...</p>\n ) : (\n <ul>\n {props.concepts.map((concept) => {\n return (\n <li\n key={concept.id}\n className={`${concept.topConcept ? s.topConcept : s.orphan} ${\n concept.broaderSchemas?.filter((id) => id === concept.parentScheme).length > 1 &&\n s.polyHier\n }`}\n >\n {concept.prefLabel}\n {concept.narrower?.length > 0 && <RecursiveConcept concepts={concept.narrower} />}\n </li>\n )\n })}\n </ul>\n )}\n </>\n )\n}\n\nconst TreeView = withParent(\n React.forwardRef((props, ref) => {\n const [concepts, setConcepts] = useState([])\n const [isLoading, setIsLoading] = useState(false)\n const [noConcept, setNoConcept] = useState(false)\n const [isError, setIsError] = useState(false)\n\n // This function builds the first level of hierarchy, noting Top Concepts and orphans, then calls the recursiveQuery() function\n const queryBuilder = (depth = 5) => {\n if (depth === 0) {\n return ''\n } else {\n return `*[_type==\"skosConcept\" && references($conceptScheme) && (count(broader[]) < 1 || broader == null) && !(_id in path(\"drafts.**\"))]|order(prefLabel) {\n \"level\": 0,\n \"id\": _id,\n prefLabel,\n topConcept,\n ${recursiveQuery(depth)}\n }`\n }\n }\n // This function builds all subsequent levels found in the data and notes any concepts that exist in two places in this Concept Scheme (i.e. which are polyhierarchical)\n const recursiveQuery = (depth, count = 1) => {\n if (depth === 0) {\n return ''\n } else {\n return `\"narrower\": *[_type == \"skosConcept\" && references($conceptScheme) && references(^._id) && !(_id in path(\"drafts.**\"))]|order(prefLabel) {\n \"level\": ${count},\n \"id\": _id,\n prefLabel,\n \"broaderSchemas\": broader[]->scheme->._id, \n \"parentScheme\": $conceptScheme, ${recursiveQuery(depth - 1, count + 1)} \n }`\n }\n }\n\n useEffect(() => {\n const fetchConcepts = async () => {\n const conceptScheme = await props.parent._id;\n setIsError(false)\n setNoConcept(false)\n setIsLoading(true)\n try {\n const params = {conceptScheme: conceptScheme}\n const query = `${queryBuilder()}`\n const response = await client.fetch(query, params)\n if (response.length < 1) {\n setNoConcept(true)\n }\n setConcepts(response)\n } catch (error) {\n setIsError(true)\n console.log(error)\n }\n setIsLoading(false)\n }\n fetchConcepts()\n }, [])\n\n return (\n <Box>\n <Stack space={2}>\n <Text size={1} weight=\"semibold\">\n {props.type.title}\n </Text>\n <Text size={1} muted>\n {props.type.description}\n </Text>\n <Text size={2}>\n <RecursiveConcept\n concepts={concepts}\n isLoading={isLoading}\n noConcept={noConcept}\n isError={isError}\n />\n </Text>\n </Stack>\n </Box>\n )\n })\n)\n\nexport default TreeView\n"],"file":"treeView.js"}
|
package/lib/skosConcept.js
CHANGED
|
@@ -35,6 +35,7 @@ var _default = {
|
|
|
35
35
|
var iriBase = {
|
|
36
36
|
iriValue: _configTaxonomyManager.default.namespace
|
|
37
37
|
};
|
|
38
|
+
console.log(iriBase.iriValue);
|
|
38
39
|
var scheme = (_yield$client$fetch = yield client.fetch("\n *[_type == 'skosConceptScheme']{\n '_type': 'reference',\n '_ref': _id\n }[0]\n ")) !== null && _yield$client$fetch !== void 0 ? _yield$client$fetch : undefined;
|
|
39
40
|
return {
|
|
40
41
|
conceptIriBase: iriBase,
|
|
@@ -42,7 +43,7 @@ var _default = {
|
|
|
42
43
|
topConcept: false,
|
|
43
44
|
broader: [],
|
|
44
45
|
// an empty array is needed here in order to return concepts with no "broader" for "related"
|
|
45
|
-
related: [] // an empty array is needed here in order to return concepts with no "broader" for "related"
|
|
46
|
+
related: [] // an empty array is needed here in order to return concepts with no "broader" for "related"
|
|
46
47
|
|
|
47
48
|
};
|
|
48
49
|
});
|
package/lib/skosConcept.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/skosConcept.js"],"names":["client","sanityClient","withConfig","apiVersion","name","title","type","icon","AiFillTags","initialValue","iriBase","iriValue","config","namespace","scheme","fetch","undefined","conceptIriBase","topConcept","broader","related","validation","Rule","custom","fields","altLabel","hiddenLabel","filter","label","includes","length","prefLabel","groups","group","description","required","context","then","conceptId","document","_id","replace","inputComponent","PrefLabel","of","unique","hidden","to","options","params","self","map","_ref","broaderTrans","response","flatMap","concat","error","console","disableNew","rows","orderings","by","field","direction","preview","select","broaderPlusOne","broaderPlusTwo","prepare","conceptBroader","Boolean","broaderPath","join","hierarchy","subtitle","media","AiOutlineTag","AiFillTag"],"mappings":"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","sourcesContent":["/**\n * Sanity document scheme for SKOS Taxonomy Concepts\n * @todo Hierarchy, Broader, & Associated: enforce disjointedness between Associated and BroaderTransitive (integrity constraint); prohibit cycles in hierarchical relations (best practice). 2022-03-31: Filtering added to Related to five levels of hierarchy, document filtering present for Broader. Consider more robust filtering and validation for future releases.\n * @todo Lexical labels: add child level validation so that offending labels are shown directly when a duplicate is entered. Then consider removing document level validation. cf. https://www.sanity.io/docs/validation#9e69d5db6f72\n * @todo Scheme initial value: Configure \"default\" option in Concept Scheme, for cases when there are multiple schemes; configure initialValue to default to that selection (It's currently configure to take the scheme ordered first. This isn't transparent.)\n * @todo Abstract broader and related concept filter into reusable function, and/or add in validation to cover wider scenarios.\n */\nimport sanityClient from 'part:@sanity/base/client'\nimport config from 'config:taxonomy-manager'\nimport {AiFillTag, AiOutlineTag, AiFillTags} from 'react-icons/ai'\nimport PrefLabel from './components/prefLabel'\n\nconst client = sanityClient.withConfig({apiVersion: '2021-03-25'})\n\nexport default {\n name: 'skosConcept',\n title: 'Concepts',\n type: 'document',\n icon: AiFillTags,\n initialValue: async () => {\n const iriBase = {iriValue: config.namespace}\n const scheme =\n (await client.fetch(`\n *[_type == 'skosConceptScheme']{\n '_type': 'reference',\n '_ref': _id\n }[0]\n `)) ?? undefined\n return {\n conceptIriBase: iriBase,\n scheme: scheme,\n topConcept: false,\n broader: [], // an empty array is needed here in order to return concepts with no \"broader\" for \"related\"\n related: [], // an empty array is needed here in order to return concepts with no \"broader\" for \"related\"P\n }\n },\n // Document level validation for the disjunction between Preferred, Alternate, and Hidden Labels:\n validation: (Rule) =>\n Rule.custom((fields) => {\n if (\n (fields.altLabel &&\n fields.hiddenLabel &&\n fields.altLabel.filter((label) => fields.hiddenLabel.includes(label)).length > 0) ||\n (fields.altLabel && fields.altLabel.includes(fields.prefLabel)) ||\n (fields.hiddenLabel && fields.hiddenLabel.includes(fields.prefLabel))\n )\n return 'Preferred Label, Alternate Labels, and Hidden Labels must all be unique. Please remove any labels duplicated across label types.'\n return true\n }),\n groups: [\n {\n name: 'relationship',\n title: 'Relationships',\n },\n {\n name: 'label',\n title: 'Labels',\n },\n {\n name: 'note',\n title: 'Documentation',\n },\n ],\n fields: [\n {\n name: 'prefLabel',\n title: 'Preferred Label',\n group: ['label', 'relationship'],\n type: 'string',\n description:\n 'The preferred lexical label for this concept. This label is also used to unambiguously represent this concept via the concept IRI.',\n // If there is a published concept with the current document's prefLabel, return an error message, but only for concepts with distinct _ids — otherwise editing an existing concept shows the error message as well.\n validation: (Rule) =>\n Rule.required().custom((prefLabel, context) => {\n return client\n .fetch(\n `*[_type == \"skosConcept\" && prefLabel == \"${prefLabel}\" && !(_id in path(\"drafts.**\"))][0]._id`\n )\n .then((conceptId) => {\n if (conceptId && conceptId !== context.document._id.replace('drafts.', '')) {\n return 'Preferred Label must be unique.'\n } else {\n return true\n }\n })\n }),\n inputComponent: PrefLabel,\n },\n {\n name: 'conceptIriBase',\n title: 'Edit the base IRI',\n type: 'baseIri',\n },\n {\n name: 'altLabel',\n title: 'Alternate Label(s)',\n group: 'label',\n type: 'array',\n description:\n 'Alternative labels can be used to assign synonyms, near-synonyms, abbreviations, and acronyms to a concept. Preferred, alternative, and hidden label sets must not overlap.',\n of: [{type: 'string'}],\n validation: (Rule) => Rule.unique(),\n },\n {\n name: 'hiddenLabel',\n title: 'Hidden Label(s)',\n group: 'label',\n type: 'array',\n description:\n 'Hidden labels are for character strings that need to be accessible to applications performing text-based indexing and search operations, but not visible otherwise. Hidden labels may for instance be used to include misspelled variants of other lexical labels. Preferred, alternative, and hidden label sets must not overlap.',\n of: [{type: 'string'}],\n validation: (Rule) => Rule.unique(),\n },\n {\n name: 'topConcept',\n title: 'Top Concept',\n group: 'relationship',\n type: 'boolean',\n description:\n 'Top concepts provide an efficient entry point to broader/narrower concept hierarchies and/or top level facets. By convention, resources can be a Top Concept, or have Broader relationships, but not both.',\n hidden: ({document}) => (document.broader ? document.broader.length > 0 : false),\n },\n {\n name: 'broader',\n title: 'Broader Concept(s)',\n hidden: ({document}) => document.topConcept,\n description:\n 'Broader relationships create a hierarchy between concepts, for example to create category/subcategory, part/whole, or class/instance relationships.',\n group: 'relationship',\n type: 'array',\n of: [\n {\n type: 'reference',\n to: {type: 'skosConcept'},\n options: {\n filter: ({document}) => {\n return {\n // Broader filter only performs document-level validation for broader-transitive/related disjunction.\n // Consider adding custom validation to prevent broader taxonomy inconsistencies.\n filter:\n '!(_id in $broader || _id in $related || _id in path(\"drafts.**\") || _id == $self)',\n params: {\n self: document._id.replace('drafts.', ''),\n broader: document.broader.map(({_ref}) => _ref),\n related: document.related.map(({_ref}) => _ref),\n },\n }\n },\n },\n },\n ],\n },\n {\n name: 'related',\n title: 'Related Concept(s)',\n description:\n 'Associative links between concepts indicate that the two are inherently \"related\", but that one is not in any way more general than the other. Broader and Associated relationships are mutually exclusive.',\n group: 'relationship',\n type: 'array',\n of: [\n {\n type: 'reference',\n to: [{type: 'skosConcept'}],\n options: {\n filter: async ({document}) => {\n let broaderTrans = []\n try {\n // This filter checks for inconsistencies to five levels of hierarchy. Consider adding custom validation to prevent broader taxonomy inconsistencies.\n // This block starts for the document in question, and looks up the hierarchy tree. Those found to have the document in question as a \"broader transitive\" are added to a list of concepts to exclude from potential \"Related Concept\" candidates.\n const response = await client.fetch(\n `*[_type == \"skosConcept\" && prefLabel == \"${document.prefLabel}\"]{prefLabel,broader[]->{prefLabel,broader[]->{prefLabel,broader[]->{prefLabel,broader[]->{prefLabel,broader[]->{prefLabel}}}}}}`\n )\n // console.log(response); // for troubleshooting\n broaderTrans = await response\n .flatMap((broader) => broader.broader?.flatMap((broader) => broader.prefLabel)) // first broader term\n .concat(\n response.flatMap((broader) =>\n broader.broader?.flatMap((broader) =>\n broader.broader?.flatMap((broader) => broader.prefLabel)\n )\n )\n ) // second broader term\n .concat(\n response.flatMap((broader) =>\n broader.broader?.flatMap((broader) =>\n broader.broader?.flatMap((broader) =>\n broader.broader?.flatMap((broader) => broader.prefLabel)\n )\n )\n )\n ) // third broader term\n .concat(\n response.flatMap((broader) =>\n broader.broader?.flatMap((broader) =>\n broader.broader?.flatMap((broader) =>\n broader.broader?.flatMap((broader) =>\n broader.broader?.flatMap((broader) => broader.prefLabel)\n )\n )\n )\n )\n ) // fourth broader term\n .concat(\n response.flatMap((broader) =>\n broader.broader?.flatMap((broader) =>\n broader.broader?.flatMap((broader) =>\n broader.broader?.flatMap((broader) =>\n broader.broader?.flatMap((broader) =>\n broader.broader?.flatMap((broader) => broader.prefLabel)\n )\n )\n )\n )\n )\n ) // fifth broader term\n .filter((broader) => broader) // remove \"undefined\"\n // console.log(broaderTrans); // for troubleshooting\n\n // The 'broader[]->...' filters below look for the document in question in the broader-transitive path of the remaining concepts and, if found, excludes them from inclusion as a potential \"Related Concept\" candidate\n return {\n filter: `!(_id in $related || \n _id in path(\"drafts.**\") || \n _id == $self ||\n prefLabel in $broaderTrans || \n $self in broader[]->._id ||\n $self in broader[]->broader[]->._id ||\n $self in broader[]->broader[]->broader[]->._id ||\n $self in broader[]->broader[]->broader[]->broader[]->._id ||\n $self in broader[]->broader[]->broader[]->broader[]->broader[]->._id\n )`,\n params: {\n self: document._id.replace('drafts.', ''),\n related: document.related.map(({_ref}) => _ref),\n broaderTrans: broaderTrans,\n },\n }\n } catch (error) {\n console.error(`Could not get broader concepts: ${error}`)\n }\n },\n },\n },\n ],\n },\n {\n name: 'scheme',\n title: 'Concept Scheme(s)',\n group: 'relationship',\n type: 'reference',\n description:\n 'Concept schemes are used to group concepts into defined sets, such as thesauri, classification schemes, or facets.',\n to: [\n {\n type: 'skosConceptScheme',\n },\n ],\n options: {\n disableNew: true,\n },\n },\n {\n name: 'scopeNote',\n title: 'Scope Note',\n type: 'text',\n description:\n 'A brief statement on the intended meaning of this concept, especially as an indication of how the use of the concept is limited in indexing practice',\n rows: 3,\n group: 'note',\n },\n {\n name: 'definition',\n title: 'Definition',\n type: 'text',\n description: 'A complete explanation of the intended meaning of the concept',\n rows: 3,\n group: 'note',\n },\n {\n name: 'example',\n title: 'Examples',\n type: 'text',\n description: 'An example of the use of the concept.',\n rows: 3,\n group: 'note',\n },\n ],\n orderings: [\n {\n title: 'Top Concepts',\n name: 'topConcept',\n by: [\n {field: 'topConcept', direction: 'desc'},\n {field: 'prefLabel', direction: 'asc'},\n ],\n },\n {\n title: 'Preferred Label',\n name: 'prefLabel',\n by: [{field: 'prefLabel', direction: 'asc'}],\n },\n ],\n preview: {\n select: {\n title: 'prefLabel',\n topConcept: 'topConcept',\n broader: 'broader.0.prefLabel',\n broaderPlusOne: 'broader.0.broader.0.prefLabel',\n broaderPlusTwo: 'broader.0.broader.0.broader.0.prefLabel',\n },\n prepare({title, topConcept, broader, broaderPlusOne, broaderPlusTwo}) {\n const conceptBroader = [broaderPlusOne, broader].filter(Boolean)\n const broaderPath =\n conceptBroader.length > 0 ? `${conceptBroader.join(' ▷ ')} ▶︎ ${title}` : ''\n const hierarchy = broaderPlusTwo ? `... ${broaderPath}` : broaderPath\n return {\n title: title,\n subtitle: topConcept ? 'Top Concept' : hierarchy,\n media: topConcept ? AiOutlineTag : AiFillTag,\n }\n },\n },\n}\n"],"file":"skosConcept.js"}
|
|
1
|
+
{"version":3,"sources":["../src/skosConcept.js"],"names":["client","sanityClient","withConfig","apiVersion","name","title","type","icon","AiFillTags","initialValue","iriBase","iriValue","config","namespace","console","log","scheme","fetch","undefined","conceptIriBase","topConcept","broader","related","validation","Rule","custom","fields","altLabel","hiddenLabel","filter","label","includes","length","prefLabel","groups","group","description","required","context","then","conceptId","document","_id","replace","inputComponent","PrefLabel","of","unique","hidden","to","options","params","self","map","_ref","broaderTrans","response","flatMap","concat","error","disableNew","rows","orderings","by","field","direction","preview","select","broaderPlusOne","broaderPlusTwo","prepare","conceptBroader","Boolean","broaderPath","join","hierarchy","subtitle","media","AiOutlineTag","AiFillTag"],"mappings":"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","sourcesContent":["/**\n * Sanity document scheme for SKOS Taxonomy Concepts\n * @todo Hierarchy, Broader, & Associated: enforce disjointedness between Associated and BroaderTransitive (integrity constraint); prohibit cycles in hierarchical relations (best practice). 2022-03-31: Filtering added to Related to five levels of hierarchy, document filtering present for Broader. Consider more robust filtering and validation for future releases.\n * @todo Lexical labels: add child level validation so that offending labels are shown directly when a duplicate is entered. Then consider removing document level validation. cf. https://www.sanity.io/docs/validation#9e69d5db6f72\n * @todo Scheme initial value: Configure \"default\" option in Concept Scheme, for cases when there are multiple schemes; configure initialValue to default to that selection (It's currently configure to take the scheme ordered first. This isn't transparent.)\n * @todo Abstract broader and related concept filter into reusable function, and/or add in validation to cover wider scenarios.\n */\nimport sanityClient from 'part:@sanity/base/client'\nimport config from 'config:taxonomy-manager'\nimport {AiFillTag, AiOutlineTag, AiFillTags} from 'react-icons/ai'\nimport PrefLabel from './components/prefLabel'\n\nconst client = sanityClient.withConfig({apiVersion: '2021-03-25'})\n\nexport default {\n name: 'skosConcept',\n title: 'Concepts',\n type: 'document',\n icon: AiFillTags,\n initialValue: async () => {\n const iriBase = {iriValue: config.namespace}\n console.log(iriBase.iriValue);\n const scheme =\n (await client.fetch(`\n *[_type == 'skosConceptScheme']{\n '_type': 'reference',\n '_ref': _id\n }[0]\n `)) ?? undefined\n return {\n conceptIriBase: iriBase,\n scheme: scheme,\n topConcept: false,\n broader: [], // an empty array is needed here in order to return concepts with no \"broader\" for \"related\"\n related: [], // an empty array is needed here in order to return concepts with no \"broader\" for \"related\"\n }\n },\n // Document level validation for the disjunction between Preferred, Alternate, and Hidden Labels:\n validation: (Rule) =>\n Rule.custom((fields) => {\n if (\n (fields.altLabel &&\n fields.hiddenLabel &&\n fields.altLabel.filter((label) => fields.hiddenLabel.includes(label)).length > 0) ||\n (fields.altLabel && fields.altLabel.includes(fields.prefLabel)) ||\n (fields.hiddenLabel && fields.hiddenLabel.includes(fields.prefLabel))\n )\n return 'Preferred Label, Alternate Labels, and Hidden Labels must all be unique. Please remove any labels duplicated across label types.'\n return true\n }),\n groups: [\n {\n name: 'relationship',\n title: 'Relationships',\n },\n {\n name: 'label',\n title: 'Labels',\n },\n {\n name: 'note',\n title: 'Documentation',\n },\n ],\n fields: [\n {\n name: 'prefLabel',\n title: 'Preferred Label',\n group: ['label', 'relationship'],\n type: 'string',\n description:\n 'The preferred lexical label for this concept. This label is also used to unambiguously represent this concept via the concept IRI.',\n // If there is a published concept with the current document's prefLabel, return an error message, but only for concepts with distinct _ids — otherwise editing an existing concept shows the error message as well.\n validation: (Rule) =>\n Rule.required().custom((prefLabel, context) => {\n return client\n .fetch(\n `*[_type == \"skosConcept\" && prefLabel == \"${prefLabel}\" && !(_id in path(\"drafts.**\"))][0]._id`\n )\n .then((conceptId) => {\n if (conceptId && conceptId !== context.document._id.replace('drafts.', '')) {\n return 'Preferred Label must be unique.'\n } else {\n return true\n }\n })\n }),\n inputComponent: PrefLabel,\n },\n {\n name: 'conceptIriBase',\n title: 'Edit the base IRI',\n type: 'baseIri',\n },\n {\n name: 'altLabel',\n title: 'Alternate Label(s)',\n group: 'label',\n type: 'array',\n description:\n 'Alternative labels can be used to assign synonyms, near-synonyms, abbreviations, and acronyms to a concept. Preferred, alternative, and hidden label sets must not overlap.',\n of: [{type: 'string'}],\n validation: (Rule) => Rule.unique(),\n },\n {\n name: 'hiddenLabel',\n title: 'Hidden Label(s)',\n group: 'label',\n type: 'array',\n description:\n 'Hidden labels are for character strings that need to be accessible to applications performing text-based indexing and search operations, but not visible otherwise. Hidden labels may for instance be used to include misspelled variants of other lexical labels. Preferred, alternative, and hidden label sets must not overlap.',\n of: [{type: 'string'}],\n validation: (Rule) => Rule.unique(),\n },\n {\n name: 'topConcept',\n title: 'Top Concept',\n group: 'relationship',\n type: 'boolean',\n description:\n 'Top concepts provide an efficient entry point to broader/narrower concept hierarchies and/or top level facets. By convention, resources can be a Top Concept, or have Broader relationships, but not both.',\n hidden: ({document}) => (document.broader ? document.broader.length > 0 : false),\n },\n {\n name: 'broader',\n title: 'Broader Concept(s)',\n hidden: ({document}) => document.topConcept,\n description:\n 'Broader relationships create a hierarchy between concepts, for example to create category/subcategory, part/whole, or class/instance relationships.',\n group: 'relationship',\n type: 'array',\n of: [\n {\n type: 'reference',\n to: {type: 'skosConcept'},\n options: {\n filter: ({document}) => {\n return {\n // Broader filter only performs document-level validation for broader-transitive/related disjunction.\n // Consider adding custom validation to prevent broader taxonomy inconsistencies.\n filter:\n '!(_id in $broader || _id in $related || _id in path(\"drafts.**\") || _id == $self)',\n params: {\n self: document._id.replace('drafts.', ''),\n broader: document.broader.map(({_ref}) => _ref),\n related: document.related.map(({_ref}) => _ref),\n },\n }\n },\n },\n },\n ],\n },\n {\n name: 'related',\n title: 'Related Concept(s)',\n description:\n 'Associative links between concepts indicate that the two are inherently \"related\", but that one is not in any way more general than the other. Broader and Associated relationships are mutually exclusive.',\n group: 'relationship',\n type: 'array',\n of: [\n {\n type: 'reference',\n to: [{type: 'skosConcept'}],\n options: {\n filter: async ({document}) => {\n let broaderTrans = []\n try {\n // This filter checks for inconsistencies to five levels of hierarchy. Consider adding custom validation to prevent broader taxonomy inconsistencies.\n // This block starts for the document in question, and looks up the hierarchy tree. Those found to have the document in question as a \"broader transitive\" are added to a list of concepts to exclude from potential \"Related Concept\" candidates.\n const response = await client.fetch(\n `*[_type == \"skosConcept\" && prefLabel == \"${document.prefLabel}\"]{prefLabel,broader[]->{prefLabel,broader[]->{prefLabel,broader[]->{prefLabel,broader[]->{prefLabel,broader[]->{prefLabel}}}}}}`\n )\n // console.log(response); // for troubleshooting\n broaderTrans = await response\n .flatMap((broader) => broader.broader?.flatMap((broader) => broader.prefLabel)) // first broader term\n .concat(\n response.flatMap((broader) =>\n broader.broader?.flatMap((broader) =>\n broader.broader?.flatMap((broader) => broader.prefLabel)\n )\n )\n ) // second broader term\n .concat(\n response.flatMap((broader) =>\n broader.broader?.flatMap((broader) =>\n broader.broader?.flatMap((broader) =>\n broader.broader?.flatMap((broader) => broader.prefLabel)\n )\n )\n )\n ) // third broader term\n .concat(\n response.flatMap((broader) =>\n broader.broader?.flatMap((broader) =>\n broader.broader?.flatMap((broader) =>\n broader.broader?.flatMap((broader) =>\n broader.broader?.flatMap((broader) => broader.prefLabel)\n )\n )\n )\n )\n ) // fourth broader term\n .concat(\n response.flatMap((broader) =>\n broader.broader?.flatMap((broader) =>\n broader.broader?.flatMap((broader) =>\n broader.broader?.flatMap((broader) =>\n broader.broader?.flatMap((broader) =>\n broader.broader?.flatMap((broader) => broader.prefLabel)\n )\n )\n )\n )\n )\n ) // fifth broader term\n .filter((broader) => broader) // remove \"undefined\"\n // console.log(broaderTrans); // for troubleshooting\n\n // The 'broader[]->...' filters below look for the document in question in the broader-transitive path of the remaining concepts and, if found, excludes them from inclusion as a potential \"Related Concept\" candidate\n return {\n filter: `!(_id in $related || \n _id in path(\"drafts.**\") || \n _id == $self ||\n prefLabel in $broaderTrans || \n $self in broader[]->._id ||\n $self in broader[]->broader[]->._id ||\n $self in broader[]->broader[]->broader[]->._id ||\n $self in broader[]->broader[]->broader[]->broader[]->._id ||\n $self in broader[]->broader[]->broader[]->broader[]->broader[]->._id\n )`,\n params: {\n self: document._id.replace('drafts.', ''),\n related: document.related.map(({_ref}) => _ref),\n broaderTrans: broaderTrans,\n },\n }\n } catch (error) {\n console.error(`Could not get broader concepts: ${error}`)\n }\n },\n },\n },\n ],\n },\n {\n name: 'scheme',\n title: 'Concept Scheme(s)',\n group: 'relationship',\n type: 'reference',\n description:\n 'Concept schemes are used to group concepts into defined sets, such as thesauri, classification schemes, or facets.',\n to: [\n {\n type: 'skosConceptScheme',\n },\n ],\n options: {\n disableNew: true,\n },\n },\n {\n name: 'scopeNote',\n title: 'Scope Note',\n type: 'text',\n description:\n 'A brief statement on the intended meaning of this concept, especially as an indication of how the use of the concept is limited in indexing practice',\n rows: 3,\n group: 'note',\n },\n {\n name: 'definition',\n title: 'Definition',\n type: 'text',\n description: 'A complete explanation of the intended meaning of the concept',\n rows: 3,\n group: 'note',\n },\n {\n name: 'example',\n title: 'Examples',\n type: 'text',\n description: 'An example of the use of the concept.',\n rows: 3,\n group: 'note',\n },\n ],\n orderings: [\n {\n title: 'Top Concepts',\n name: 'topConcept',\n by: [\n {field: 'topConcept', direction: 'desc'},\n {field: 'prefLabel', direction: 'asc'},\n ],\n },\n {\n title: 'Preferred Label',\n name: 'prefLabel',\n by: [{field: 'prefLabel', direction: 'asc'}],\n },\n ],\n preview: {\n select: {\n title: 'prefLabel',\n topConcept: 'topConcept',\n broader: 'broader.0.prefLabel',\n broaderPlusOne: 'broader.0.broader.0.prefLabel',\n broaderPlusTwo: 'broader.0.broader.0.broader.0.prefLabel',\n },\n prepare({title, topConcept, broader, broaderPlusOne, broaderPlusTwo}) {\n const conceptBroader = [broaderPlusOne, broader].filter(Boolean)\n const broaderPath =\n conceptBroader.length > 0 ? `${conceptBroader.join(' ▷ ')} ▶︎ ${title}` : ''\n const hierarchy = broaderPlusTwo ? `... ${broaderPath}` : broaderPath\n return {\n title: title,\n subtitle: topConcept ? 'Top Concept' : hierarchy,\n media: topConcept ? AiOutlineTag : AiFillTag,\n }\n },\n },\n}\n"],"file":"skosConcept.js"}
|
package/package.json
CHANGED
|
@@ -5,66 +5,69 @@
|
|
|
5
5
|
import React from 'react'
|
|
6
6
|
import {FormField} from '@sanity/base/components'
|
|
7
7
|
import {TextInput, Stack, Text} from '@sanity/ui'
|
|
8
|
+
import {withParent} from 'part:@sanity/form-builder'
|
|
8
9
|
import PatchEvent, {set, unset} from '@sanity/form-builder/PatchEvent'
|
|
9
10
|
import {useId} from '@reach/auto-id' // hook to generate unique IDs
|
|
10
11
|
|
|
11
|
-
const PrefLabel =
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
12
|
+
const PrefLabel = withParent(
|
|
13
|
+
React.forwardRef((props, ref) => {
|
|
14
|
+
const {
|
|
15
|
+
type, // Schema information
|
|
16
|
+
value, // Current field value
|
|
17
|
+
readOnly, // Boolean if field is not editable
|
|
18
|
+
placeholder, // Placeholder text from the schema
|
|
19
|
+
markers, // Markers including validation rules
|
|
20
|
+
presence, // Presence information for collaborative avatars
|
|
21
|
+
compareValue, // Value to check for "edited" functionality
|
|
22
|
+
onFocus, // Method to handle focus state
|
|
23
|
+
onBlur, // Method to handle blur state
|
|
24
|
+
onChange, // Method to handle patch events
|
|
25
|
+
parent // **Showing up as undefined as of 2022-09-26**
|
|
26
|
+
} = props
|
|
25
27
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
+
// Creates a unique ID for input
|
|
29
|
+
const inputId = useId()
|
|
28
30
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
31
|
+
// Creates a change handler for patching data
|
|
32
|
+
const handleChange = React.useCallback(
|
|
33
|
+
// useCallback will help with performance
|
|
34
|
+
(event) => {
|
|
35
|
+
const inputValue = event.currentTarget.value // get current value
|
|
36
|
+
// if the value exists, set the data, if not, unset the data
|
|
37
|
+
onChange(PatchEvent.from(inputValue ? set(inputValue) : unset()))
|
|
38
|
+
},
|
|
39
|
+
[onChange]
|
|
40
|
+
)
|
|
39
41
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
})
|
|
42
|
+
return (
|
|
43
|
+
<Stack space={1}>
|
|
44
|
+
<FormField
|
|
45
|
+
description={type.description}
|
|
46
|
+
title={type.title}
|
|
47
|
+
__unstable_markers={markers} // Handles all markers including validation
|
|
48
|
+
__unstable_presence={presence} // Handles presence avatars
|
|
49
|
+
compareValue={compareValue} // Handles "edited" status
|
|
50
|
+
inputId={inputId} // Allows the label to connect to the input field
|
|
51
|
+
>
|
|
52
|
+
<TextInput
|
|
53
|
+
id={inputId} // A unique ID for this input
|
|
54
|
+
onChange={handleChange} // A function to call when the input value changes
|
|
55
|
+
value={value} // Current field value
|
|
56
|
+
readOnly={readOnly} // If "readOnly" is defined make this field read only
|
|
57
|
+
placeholder={placeholder} // If placeholder is defined, display placeholder text
|
|
58
|
+
onFocus={onFocus} // Handles focus events
|
|
59
|
+
onBlur={onBlur} // Handles blur events
|
|
60
|
+
ref={ref}
|
|
61
|
+
/>
|
|
62
|
+
</FormField>
|
|
63
|
+
<Text muted size={1}>
|
|
64
|
+
<strong>Concept IRI: </strong>
|
|
65
|
+
{parent?.conceptIriBase ? parent.conceptIriBase.iriValue : '[base URI not defined] '}
|
|
66
|
+
{value?.replaceAll(' ', '')}
|
|
67
|
+
</Text>
|
|
68
|
+
</Stack>
|
|
69
|
+
)
|
|
70
|
+
})
|
|
71
|
+
)
|
|
69
72
|
|
|
70
73
|
export default PrefLabel
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
import React, {useState, useEffect} from 'react'
|
|
13
13
|
import {Box, Stack, Text} from '@sanity/ui'
|
|
14
|
+
import {withParent} from 'part:@sanity/form-builder'
|
|
14
15
|
import sanityClient from 'part:@sanity/base/client'
|
|
15
16
|
import * as s from './treeView.module.css'
|
|
16
17
|
|
|
@@ -20,7 +21,7 @@ const client = sanityClient.withConfig({apiVersion: '2021-03-25'})
|
|
|
20
21
|
const RecursiveConcept = (props) => {
|
|
21
22
|
return (
|
|
22
23
|
<>
|
|
23
|
-
{props.isError && <p>
|
|
24
|
+
{props.isError && <p>Sorry, could not get concepts.</p>}
|
|
24
25
|
{props.noConcept && <p>This scheme does not yet have any concepts assigned to it.</p>}
|
|
25
26
|
{props.isLoading ? (
|
|
26
27
|
<p>Loading hierarchy ...</p>
|
|
@@ -46,85 +47,86 @@ const RecursiveConcept = (props) => {
|
|
|
46
47
|
)
|
|
47
48
|
}
|
|
48
49
|
|
|
49
|
-
const TreeView =
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
const TreeView = withParent(
|
|
51
|
+
React.forwardRef((props, ref) => {
|
|
52
|
+
const [concepts, setConcepts] = useState([])
|
|
53
|
+
const [isLoading, setIsLoading] = useState(false)
|
|
54
|
+
const [noConcept, setNoConcept] = useState(false)
|
|
55
|
+
const [isError, setIsError] = useState(false)
|
|
54
56
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
return `*[_type=="skosConcept" && references($conceptScheme) && (count(broader[]) < 1 || broader == null) && !(_id in path("drafts.**"))]|order(prefLabel) {
|
|
63
|
-
"level": 0,
|
|
64
|
-
"id": _id,
|
|
65
|
-
prefLabel,
|
|
66
|
-
topConcept,
|
|
67
|
-
${recursiveQuery(depth)}
|
|
68
|
-
}`
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
// This function builds all subsequent levels found in the data and notes any concepts that exist in two places in this Concept Scheme (i.e. which are polyhierarchical)
|
|
72
|
-
const recursiveQuery = (depth, count = 1) => {
|
|
73
|
-
if (depth === 0) {
|
|
74
|
-
return ''
|
|
75
|
-
} else {
|
|
76
|
-
return `"narrower": *[_type == "skosConcept" && references($conceptScheme) && references(^._id) && !(_id in path("drafts.**"))]|order(prefLabel) {
|
|
77
|
-
"level": ${count},
|
|
57
|
+
// This function builds the first level of hierarchy, noting Top Concepts and orphans, then calls the recursiveQuery() function
|
|
58
|
+
const queryBuilder = (depth = 5) => {
|
|
59
|
+
if (depth === 0) {
|
|
60
|
+
return ''
|
|
61
|
+
} else {
|
|
62
|
+
return `*[_type=="skosConcept" && references($conceptScheme) && (count(broader[]) < 1 || broader == null) && !(_id in path("drafts.**"))]|order(prefLabel) {
|
|
63
|
+
"level": 0,
|
|
78
64
|
"id": _id,
|
|
79
65
|
prefLabel,
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
66
|
+
topConcept,
|
|
67
|
+
${recursiveQuery(depth)}
|
|
68
|
+
}`
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// This function builds all subsequent levels found in the data and notes any concepts that exist in two places in this Concept Scheme (i.e. which are polyhierarchical)
|
|
72
|
+
const recursiveQuery = (depth, count = 1) => {
|
|
73
|
+
if (depth === 0) {
|
|
74
|
+
return ''
|
|
75
|
+
} else {
|
|
76
|
+
return `"narrower": *[_type == "skosConcept" && references($conceptScheme) && references(^._id) && !(_id in path("drafts.**"))]|order(prefLabel) {
|
|
77
|
+
"level": ${count},
|
|
78
|
+
"id": _id,
|
|
79
|
+
prefLabel,
|
|
80
|
+
"broaderSchemas": broader[]->scheme->._id,
|
|
81
|
+
"parentScheme": $conceptScheme, ${recursiveQuery(depth - 1, count + 1)}
|
|
82
|
+
}`
|
|
83
|
+
}
|
|
83
84
|
}
|
|
84
|
-
}
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
86
|
+
useEffect(() => {
|
|
87
|
+
const fetchConcepts = async () => {
|
|
88
|
+
const conceptScheme = await props.parent._id;
|
|
89
|
+
setIsError(false)
|
|
90
|
+
setNoConcept(false)
|
|
91
|
+
setIsLoading(true)
|
|
92
|
+
try {
|
|
93
|
+
const params = {conceptScheme: conceptScheme}
|
|
94
|
+
const query = `${queryBuilder()}`
|
|
95
|
+
const response = await client.fetch(query, params)
|
|
96
|
+
if (response.length < 1) {
|
|
97
|
+
setNoConcept(true)
|
|
98
|
+
}
|
|
99
|
+
setConcepts(response)
|
|
100
|
+
} catch (error) {
|
|
101
|
+
setIsError(true)
|
|
102
|
+
console.log(error)
|
|
97
103
|
}
|
|
98
|
-
|
|
99
|
-
} catch (error) {
|
|
100
|
-
setIsError(true)
|
|
101
|
-
console.log(error)
|
|
104
|
+
setIsLoading(false)
|
|
102
105
|
}
|
|
103
|
-
|
|
104
|
-
}
|
|
105
|
-
fetchConcepts()
|
|
106
|
-
}, [])
|
|
106
|
+
fetchConcepts()
|
|
107
|
+
}, [])
|
|
107
108
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
})
|
|
109
|
+
return (
|
|
110
|
+
<Box>
|
|
111
|
+
<Stack space={2}>
|
|
112
|
+
<Text size={1} weight="semibold">
|
|
113
|
+
{props.type.title}
|
|
114
|
+
</Text>
|
|
115
|
+
<Text size={1} muted>
|
|
116
|
+
{props.type.description}
|
|
117
|
+
</Text>
|
|
118
|
+
<Text size={2}>
|
|
119
|
+
<RecursiveConcept
|
|
120
|
+
concepts={concepts}
|
|
121
|
+
isLoading={isLoading}
|
|
122
|
+
noConcept={noConcept}
|
|
123
|
+
isError={isError}
|
|
124
|
+
/>
|
|
125
|
+
</Text>
|
|
126
|
+
</Stack>
|
|
127
|
+
</Box>
|
|
128
|
+
)
|
|
129
|
+
})
|
|
130
|
+
)
|
|
129
131
|
|
|
130
132
|
export default TreeView
|
package/src/skosConcept.js
CHANGED
|
@@ -19,6 +19,7 @@ export default {
|
|
|
19
19
|
icon: AiFillTags,
|
|
20
20
|
initialValue: async () => {
|
|
21
21
|
const iriBase = {iriValue: config.namespace}
|
|
22
|
+
console.log(iriBase.iriValue);
|
|
22
23
|
const scheme =
|
|
23
24
|
(await client.fetch(`
|
|
24
25
|
*[_type == 'skosConceptScheme']{
|
|
@@ -31,7 +32,7 @@ export default {
|
|
|
31
32
|
scheme: scheme,
|
|
32
33
|
topConcept: false,
|
|
33
34
|
broader: [], // an empty array is needed here in order to return concepts with no "broader" for "related"
|
|
34
|
-
related: [], // an empty array is needed here in order to return concepts with no "broader" for "related"
|
|
35
|
+
related: [], // an empty array is needed here in order to return concepts with no "broader" for "related"
|
|
35
36
|
}
|
|
36
37
|
},
|
|
37
38
|
// Document level validation for the disjunction between Preferred, Alternate, and Hidden Labels:
|