sanity-plugin-taxonomy-manager 1.0.1 → 1.0.3

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 CHANGED
@@ -6,6 +6,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  <!-- ## [TODO] -->
8
8
 
9
+ ## [1.0.3] - 2022-09-29
10
+ ### Fixed
11
+ - Concept Scheme Tree View bug that caused by missing parent document value on first render.
12
+ ### Changed
13
+ - Improved taxonomy scheme field descriptions.
14
+
15
+ ## [1.0.2] - 2022-09-28
16
+ ### Fixed
17
+ - Fixed bug introduced by Sanity Studio update 2.33.0 that made `parent` unavailable to custom components directly.
18
+ ### Changed
19
+ - Made concept scheme assignment `async` to improve consistency of Concept Scheme Tree View rendering.
20
+
9
21
  ## [1.0.1] - 2022-06-12
10
22
  ### Added
11
23
  - 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;;;;;;;;AARA;AACA;AACA;AACA;AAKqC;AAErC,IAAMA,SAAS,gBAAGC,eAAMC,UAAN,CAAiB,CAACC,KAAD,EAAQC,GAAR,KAAgB;AACjD,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,CADiD,CAejD;;AACA,MAAMC,OAAO,GAAG,oBAAhB,CAhBiD,CAkBjD;;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,CAACW,cAAP,GAAwBX,MAAM,CAACW,cAAP,CAAsBC,QAA9C,GAAyD,yBAF5D,EAGGrB,KAHH,aAGGA,KAHH,uBAGGA,KAAK,CAAEsB,UAAP,CAAkB,GAAlB,EAAuB,EAAvB,CAHH,CApBF,CADF;AA4BD,CAzDiB,CAAlB;;eA2De5B,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 PatchEvent, {set, unset} from '@sanity/form-builder/PatchEvent'\nimport {useId} from '@reach/auto-id' // hook to generate unique IDs\n\nconst PrefLabel = 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,\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\nexport default PrefLabel\n"],"file":"prefLabel.js"}
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, "This scheme does not yet have any concepts assigned to it."), 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 => {
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,10 @@ var RecursiveConcept = props => {
53
55
  })));
54
56
  };
55
57
 
56
- var TreeView = /*#__PURE__*/_react.default.forwardRef((props, ref) => {
58
+ var TreeView = (0, _formBuilder.withParent)(
59
+ /*#__PURE__*/
60
+ // Not using the ref right now, but likely will when the tree becomes interactive.
61
+ _react.default.forwardRef((props, ref) => {
57
62
  var _useState = (0, _react.useState)([]),
58
63
  _useState2 = _slicedToArray(_useState, 2),
59
64
  concepts = _useState2[0],
@@ -74,7 +79,7 @@ var TreeView = /*#__PURE__*/_react.default.forwardRef((props, ref) => {
74
79
  isError = _useState8[0],
75
80
  setIsError = _useState8[1];
76
81
 
77
- var conceptScheme = props.parent._id; // This function builds the first level of hierarchy, noting Top Concepts and orphans, then calls the recursiveQuery() function
82
+ var conceptScheme = props.parent._id ? props.parent._id.replace('drafts.', '') : undefined; // This function builds the first level of hierarchy, noting Top Concepts and orphans, then calls the recursiveQuery() function
78
83
 
79
84
  var queryBuilder = function queryBuilder() {
80
85
  var depth = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 5;
@@ -82,7 +87,7 @@ var TreeView = /*#__PURE__*/_react.default.forwardRef((props, ref) => {
82
87
  if (depth === 0) {
83
88
  return '';
84
89
  } else {
85
- 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 }");
90
+ 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
91
  }
87
92
  }; // 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
93
 
@@ -93,13 +98,14 @@ var TreeView = /*#__PURE__*/_react.default.forwardRef((props, ref) => {
93
98
  if (depth === 0) {
94
99
  return '';
95
100
  } else {
96
- 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 }");
101
+ 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
102
  }
98
103
  };
99
104
 
100
105
  (0, _react.useEffect)(() => {
101
106
  var fetchConcepts = /*#__PURE__*/function () {
102
107
  var _ref = _asyncToGenerator(function* () {
108
+ if (props.parent._id === undefined) return;
103
109
  setIsError(false);
104
110
  setNoConcept(false);
105
111
  setIsLoading(true);
@@ -113,6 +119,7 @@ var TreeView = /*#__PURE__*/_react.default.forwardRef((props, ref) => {
113
119
 
114
120
  if (response.length < 1) {
115
121
  setNoConcept(true);
122
+ setIsError(false);
116
123
  }
117
124
 
118
125
  setConcepts(response);
@@ -130,7 +137,7 @@ var TreeView = /*#__PURE__*/_react.default.forwardRef((props, ref) => {
130
137
  }();
131
138
 
132
139
  fetchConcepts();
133
- }, []);
140
+ }, [props.parent._id]);
134
141
  return /*#__PURE__*/_react.default.createElement(_ui.Box, null, /*#__PURE__*/_react.default.createElement(_ui.Stack, {
135
142
  space: 2
136
143
  }, /*#__PURE__*/_react.default.createElement(_ui.Text, {
@@ -147,8 +154,7 @@ var TreeView = /*#__PURE__*/_react.default.forwardRef((props, ref) => {
147
154
  noConcept: noConcept,
148
155
  isError: isError
149
156
  }))));
150
- });
151
-
157
+ }));
152
158
  var _default = TreeView;
153
159
  exports.default = _default;
154
160
  //# 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","conceptScheme","parent","_id","queryBuilder","depth","recursiveQuery","count","fetchConcepts","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 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>This scheme does not yet have any concepts assigned to it.</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 = 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 const conceptScheme = props.parent._id\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 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\nexport default TreeView\n"],"file":"treeView.js"}
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","conceptScheme","parent","_id","replace","undefined","queryBuilder","depth","recursiveQuery","count","fetchConcepts","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 \n // Not using the ref right now, but likely will when the tree becomes interactive. \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 const conceptScheme = props.parent._id ? props.parent._id.replace('drafts.', '') : undefined\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 \n if (props.parent._id === undefined ) return\n\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 setIsError(false)\n }\n setConcepts(response)\n } catch (error) {\n setIsError(true)\n console.log(error)\n }\n setIsLoading(false)\n }\n fetchConcepts()\n }, [props.parent._id])\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"}
@@ -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"P
46
+ related: [] // an empty array is needed here in order to return concepts with no "broader" for "related"
46
47
 
47
48
  };
48
49
  });
@@ -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"}
@@ -5,6 +5,8 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
 
8
+ var _react = _interopRequireDefault(require("react"));
9
+
8
10
  var _ri = require("react-icons/ri");
9
11
 
10
12
  var _treeView = _interopRequireDefault(require("./components/treeView"));
@@ -26,18 +28,17 @@ var _default = {
26
28
  name: 'title',
27
29
  title: 'Taxonomy Concept Scheme',
28
30
  type: 'string',
29
- description: 'Concept schemes are used to group concepts into defined sets, such as thesauri, classification schemes, or facets. Concepts may belong on many (or no) concept schemes, and you may create as many (or few) concept schemes as you like.'
31
+ description: 'Schemes group concepts into defined sets, such as thesauri, classification schemes, or facets. Concepts may belong on many (or no) concept schemes, and you may create as many (or few) concept schemes as you like'
30
32
  }, {
31
33
  name: 'treeView',
32
34
  title: 'Concept Scheme Tree View',
33
35
  type: 'string',
34
- description: 'Concept hierarchy is determined by \'Broader Than\' and \'Top Concept\' relationships assigned to each concept. A holistic view of these relationships is shown below. Top Concepts are indicated in bold. Italicized concepts represent polyhierarchy (concepts that appear in more than one branch of the hierarchy tree.)',
36
+ description: /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, "Top Concepts are indicated in ", /*#__PURE__*/_react.default.createElement("strong", null, "bold"), ". Concepts in ", /*#__PURE__*/_react.default.createElement("em", null, "italics"), " represent polyhierarchy (concepts that appear in more than one branch of the hierarchy tree)."),
35
37
  inputComponent: _treeView.default
36
38
  }, {
37
39
  name: 'description',
38
40
  title: 'Description',
39
41
  type: 'text',
40
- rows: 3,
41
42
  description: 'Describe the intended use of this scheme.'
42
43
  }],
43
44
  preview: {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/skosConceptScheme.js"],"names":["name","title","type","icon","RiNodeTree","fields","description","inputComponent","TreeView","rows","preview","select","prepare","media"],"mappings":";;;;;;;AAMA;;AACA;;;;AAPA;AACA;AACA;AACA;AACA;AACA;eAIe;AACbA,EAAAA,IAAI,EAAE,mBADO;AAEbC,EAAAA,KAAK,EAAE,kBAFM;AAGbC,EAAAA,IAAI,EAAE,UAHO;AAIbC,EAAAA,IAAI,EAAEC,cAJO;AAKbC,EAAAA,MAAM,EAAE,CACN;AACEL,IAAAA,IAAI,EAAE,OADR;AAEEC,IAAAA,KAAK,EAAE,yBAFT;AAGEC,IAAAA,IAAI,EAAE,QAHR;AAIEI,IAAAA,WAAW,EACT;AALJ,GADM,EAQN;AACEN,IAAAA,IAAI,EAAE,UADR;AAEEC,IAAAA,KAAK,EAAE,0BAFT;AAGEC,IAAAA,IAAI,EAAE,QAHR;AAIEI,IAAAA,WAAW,EACT,8TALJ;AAMEC,IAAAA,cAAc,EAAEC;AANlB,GARM,EAgBN;AACER,IAAAA,IAAI,EAAE,aADR;AAEEC,IAAAA,KAAK,EAAE,aAFT;AAGEC,IAAAA,IAAI,EAAE,MAHR;AAIEO,IAAAA,IAAI,EAAE,CAJR;AAKEH,IAAAA,WAAW,EAAE;AALf,GAhBM,CALK;AA6BbI,EAAAA,OAAO,EAAE;AACPC,IAAAA,MAAM,EAAE;AACNV,MAAAA,KAAK,EAAE;AADD,KADD;;AAIPW,IAAAA,OAAO,OAAU;AAAA,UAARX,KAAQ,QAARA,KAAQ;AACf,aAAO;AACLA,QAAAA,KAAK,EAAEA,KADF;AAELY,QAAAA,KAAK,EAAET;AAFF,OAAP;AAID;;AATM;AA7BI,C","sourcesContent":["/**\n * Sanity document scheme for SKOS Concept Schemes\n * @todo Afford setting a \"default\" scheme which is used as an initial value for new concepts. When no default is set, concepts are created without any scheme.\n * @todo Add administrative metadata: author, date, last revised, etc.\n * @todo Consider adding informational lists to this view (via custom input component): number of terms, list of terms, links. Perhaps eventually a navigable tree view.\n */\nimport {RiNodeTree} from 'react-icons/ri'\nimport TreeView from './components/treeView'\n\nexport default {\n name: 'skosConceptScheme',\n title: 'Taxonomy Schemes',\n type: 'document',\n icon: RiNodeTree,\n fields: [\n {\n name: 'title',\n title: 'Taxonomy Concept Scheme',\n type: 'string',\n description:\n 'Concept schemes are used to group concepts into defined sets, such as thesauri, classification schemes, or facets. Concepts may belong on many (or no) concept schemes, and you may create as many (or few) concept schemes as you like.',\n },\n {\n name: 'treeView',\n title: 'Concept Scheme Tree View',\n type: 'string',\n description: \n 'Concept hierarchy is determined by \\'Broader Than\\' and \\'Top Concept\\' relationships assigned to each concept. A holistic view of these relationships is shown below. Top Concepts are indicated in bold. Italicized concepts represent polyhierarchy (concepts that appear in more than one branch of the hierarchy tree.)',\n inputComponent: TreeView\n },\n {\n name: 'description',\n title: 'Description',\n type: 'text',\n rows: 3,\n description: 'Describe the intended use of this scheme.',\n },\n ],\n preview: {\n select: {\n title: 'title',\n },\n prepare({title}) {\n return {\n title: title,\n media: RiNodeTree,\n }\n },\n },\n}\n"],"file":"skosConceptScheme.js"}
1
+ {"version":3,"sources":["../src/skosConceptScheme.js"],"names":["name","title","type","icon","RiNodeTree","fields","description","inputComponent","TreeView","preview","select","prepare","media"],"mappings":";;;;;;;AAOA;;AACA;;AACA;;;;AATA;AACA;AACA;AACA;AACA;AACA;eAMe;AACbA,EAAAA,IAAI,EAAE,mBADO;AAEbC,EAAAA,KAAK,EAAE,kBAFM;AAGbC,EAAAA,IAAI,EAAE,UAHO;AAIbC,EAAAA,IAAI,EAAEC,cAJO;AAKbC,EAAAA,MAAM,EAAE,CACN;AACEL,IAAAA,IAAI,EAAE,OADR;AAEEC,IAAAA,KAAK,EAAE,yBAFT;AAGEC,IAAAA,IAAI,EAAE,QAHR;AAIEI,IAAAA,WAAW,EAAG;AAJhB,GADM,EAON;AACEN,IAAAA,IAAI,EAAE,UADR;AAEEC,IAAAA,KAAK,EAAE,0BAFT;AAGEC,IAAAA,IAAI,EAAE,QAHR;AAIEI,IAAAA,WAAW,eAAE,2GAAgC,oDAAhC,iCAAmE,mDAAnE,mGAJf;AAKEC,IAAAA,cAAc,EAAEC;AALlB,GAPM,EAcN;AACER,IAAAA,IAAI,EAAE,aADR;AAEEC,IAAAA,KAAK,EAAE,aAFT;AAGEC,IAAAA,IAAI,EAAE,MAHR;AAIEI,IAAAA,WAAW,EAAE;AAJf,GAdM,CALK;AA0BbG,EAAAA,OAAO,EAAE;AACPC,IAAAA,MAAM,EAAE;AACNT,MAAAA,KAAK,EAAE;AADD,KADD;;AAIPU,IAAAA,OAAO,OAAU;AAAA,UAARV,KAAQ,QAARA,KAAQ;AACf,aAAO;AACLA,QAAAA,KAAK,EAAEA,KADF;AAELW,QAAAA,KAAK,EAAER;AAFF,OAAP;AAID;;AATM;AA1BI,C","sourcesContent":["/**\n * Sanity document scheme for SKOS Concept Schemes\n * @todo Afford setting a \"default\" scheme which is used as an initial value for new concepts. When no default is set, concepts are created without any scheme.\n * @todo Add administrative metadata: author, date, last revised, etc.\n * @todo Consider adding informational lists to this view (via custom input component): number of terms, list of terms, links. Perhaps eventually a navigable tree view.\n */\n\nimport React from 'react';\nimport {RiNodeTree} from 'react-icons/ri'\nimport TreeView from './components/treeView'\n\nexport default {\n name: 'skosConceptScheme',\n title: 'Taxonomy Schemes',\n type: 'document',\n icon: RiNodeTree,\n fields: [\n {\n name: 'title',\n title: 'Taxonomy Concept Scheme',\n type: 'string',\n description: 'Schemes group concepts into defined sets, such as thesauri, classification schemes, or facets. Concepts may belong on many (or no) concept schemes, and you may create as many (or few) concept schemes as you like'\n },\n {\n name: 'treeView',\n title: 'Concept Scheme Tree View',\n type: 'string',\n description: <>Top Concepts are indicated in <strong>bold</strong>. Concepts in <em>italics</em> represent polyhierarchy (concepts that appear in more than one branch of the hierarchy tree).</>,\n inputComponent: TreeView\n },\n {\n name: 'description',\n title: 'Description',\n type: 'text',\n description: 'Describe the intended use of this scheme.',\n },\n ],\n preview: {\n select: {\n title: 'title',\n },\n prepare({title}) {\n return {\n title: title,\n media: RiNodeTree,\n }\n },\n },\n}\n"],"file":"skosConceptScheme.js"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sanity-plugin-taxonomy-manager",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "Create and manage SKOS compliant taxonomies, thesauri, and classification schemes in Sanity Studio.",
5
5
  "scripts": {
6
6
  "lint": "eslint .",
@@ -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 = React.forwardRef((props, ref) => {
12
- const {
13
- type, // Schema information
14
- value, // Current field value
15
- readOnly, // Boolean if field is not editable
16
- placeholder, // Placeholder text from the schema
17
- markers, // Markers including validation rules
18
- presence, // Presence information for collaborative avatars
19
- compareValue, // Value to check for "edited" functionality
20
- onFocus, // Method to handle focus state
21
- onBlur, // Method to handle blur state
22
- onChange, // Method to handle patch events
23
- parent,
24
- } = props
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
- // Creates a unique ID for input
27
- const inputId = useId()
28
+ // Creates a unique ID for input
29
+ const inputId = useId()
28
30
 
29
- // Creates a change handler for patching data
30
- const handleChange = React.useCallback(
31
- // useCallback will help with performance
32
- (event) => {
33
- const inputValue = event.currentTarget.value // get current value
34
- // if the value exists, set the data, if not, unset the data
35
- onChange(PatchEvent.from(inputValue ? set(inputValue) : unset()))
36
- },
37
- [onChange]
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
- return (
41
- <Stack space={1}>
42
- <FormField
43
- description={type.description}
44
- title={type.title}
45
- __unstable_markers={markers} // Handles all markers including validation
46
- __unstable_presence={presence} // Handles presence avatars
47
- compareValue={compareValue} // Handles "edited" status
48
- inputId={inputId} // Allows the label to connect to the input field
49
- >
50
- <TextInput
51
- id={inputId} // A unique ID for this input
52
- onChange={handleChange} // A function to call when the input value changes
53
- value={value} // Current field value
54
- readOnly={readOnly} // If "readOnly" is defined make this field read only
55
- placeholder={placeholder} // If placeholder is defined, display placeholder text
56
- onFocus={onFocus} // Handles focus events
57
- onBlur={onBlur} // Handles blur events
58
- ref={ref}
59
- />
60
- </FormField>
61
- <Text muted size={1}>
62
- <strong>Concept IRI: </strong>
63
- {parent.conceptIriBase ? parent.conceptIriBase.iriValue : '[base URI not defined] '}
64
- {value?.replaceAll(' ', '')}
65
- </Text>
66
- </Stack>
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>This scheme does not yet have any concepts assigned to it.</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,92 @@ const RecursiveConcept = (props) => {
46
47
  )
47
48
  }
48
49
 
49
- const TreeView = React.forwardRef((props, ref) => {
50
- const [concepts, setConcepts] = useState([])
51
- const [isLoading, setIsLoading] = useState(false)
52
- const [noConcept, setNoConcept] = useState(false)
53
- const [isError, setIsError] = useState(false)
50
+ const TreeView = withParent(
51
+
52
+ // Not using the ref right now, but likely will when the tree becomes interactive.
53
+ React.forwardRef((props, ref) => {
54
+ const [concepts, setConcepts] = useState([])
55
+ const [isLoading, setIsLoading] = useState(false)
56
+ const [noConcept, setNoConcept] = useState(false)
57
+ const [isError, setIsError] = useState(false)
54
58
 
55
- const conceptScheme = props.parent._id
56
-
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,
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},
59
+ const conceptScheme = props.parent._id ? props.parent._id.replace('drafts.', '') : undefined
60
+ // This function builds the first level of hierarchy, noting Top Concepts and orphans, then calls the recursiveQuery() function
61
+ const queryBuilder = (depth = 5) => {
62
+ if (depth === 0) {
63
+ return ''
64
+ } else {
65
+ return `*[_type=="skosConcept" && references($conceptScheme) && (count(broader[]) < 1 || broader == null) && !(_id in path("drafts.**"))]|order(prefLabel) {
66
+ "level": 0,
78
67
  "id": _id,
79
68
  prefLabel,
80
- "broaderSchemas": broader[]->scheme->._id,
81
- "parentScheme": $conceptScheme, ${recursiveQuery(depth - 1, count + 1)}
82
- }`
69
+ topConcept,
70
+ ${recursiveQuery(depth)}
71
+ }`
72
+ }
73
+ }
74
+ // 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)
75
+ const recursiveQuery = (depth, count = 1) => {
76
+ if (depth === 0) {
77
+ return ''
78
+ } else {
79
+ return `"narrower": *[_type == "skosConcept" && references($conceptScheme) && references(^._id) && !(_id in path("drafts.**"))]|order(prefLabel) {
80
+ "level": ${count},
81
+ "id": _id,
82
+ prefLabel,
83
+ "broaderSchemas": broader[]->scheme->._id,
84
+ "parentScheme": $conceptScheme, ${recursiveQuery(depth - 1, count + 1)}
85
+ }`
86
+ }
83
87
  }
84
- }
85
88
 
86
- useEffect(() => {
87
- const fetchConcepts = async () => {
88
- setIsError(false)
89
- setNoConcept(false)
90
- setIsLoading(true)
91
- try {
92
- const params = {conceptScheme: conceptScheme}
93
- const query = `${queryBuilder()}`
94
- const response = await client.fetch(query, params)
95
- if (response.length < 1) {
96
- setNoConcept(true)
89
+ useEffect(() => {
90
+ const fetchConcepts = async () => {
91
+
92
+ if (props.parent._id === undefined ) return
93
+
94
+ setIsError(false)
95
+ setNoConcept(false)
96
+ setIsLoading(true)
97
+ try {
98
+ const params = {conceptScheme: conceptScheme}
99
+ const query = `${queryBuilder()}`
100
+ const response = await client.fetch(query, params)
101
+ if (response.length < 1) {
102
+ setNoConcept(true)
103
+ setIsError(false)
104
+ }
105
+ setConcepts(response)
106
+ } catch (error) {
107
+ setIsError(true)
108
+ console.log(error)
97
109
  }
98
- setConcepts(response)
99
- } catch (error) {
100
- setIsError(true)
101
- console.log(error)
110
+ setIsLoading(false)
102
111
  }
103
- setIsLoading(false)
104
- }
105
- fetchConcepts()
106
- }, [])
112
+ fetchConcepts()
113
+ }, [props.parent._id])
107
114
 
108
- return (
109
- <Box>
110
- <Stack space={2}>
111
- <Text size={1} weight="semibold">
112
- {props.type.title}
113
- </Text>
114
- <Text size={1} muted>
115
- {props.type.description}
116
- </Text>
117
- <Text size={2}>
118
- <RecursiveConcept
119
- concepts={concepts}
120
- isLoading={isLoading}
121
- noConcept={noConcept}
122
- isError={isError}
123
- />
124
- </Text>
125
- </Stack>
126
- </Box>
127
- )
128
- })
115
+ return (
116
+ <Box>
117
+ <Stack space={2}>
118
+ <Text size={1} weight="semibold">
119
+ {props.type.title}
120
+ </Text>
121
+ <Text size={1} muted>
122
+ {props.type.description}
123
+ </Text>
124
+ <Text size={2}>
125
+ <RecursiveConcept
126
+ concepts={concepts}
127
+ isLoading={isLoading}
128
+ noConcept={noConcept}
129
+ isError={isError}
130
+ />
131
+ </Text>
132
+ </Stack>
133
+ </Box>
134
+ )
135
+ })
136
+ )
129
137
 
130
138
  export default TreeView
@@ -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"P
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:
@@ -4,6 +4,8 @@
4
4
  * @todo Add administrative metadata: author, date, last revised, etc.
5
5
  * @todo Consider adding informational lists to this view (via custom input component): number of terms, list of terms, links. Perhaps eventually a navigable tree view.
6
6
  */
7
+
8
+ import React from 'react';
7
9
  import {RiNodeTree} from 'react-icons/ri'
8
10
  import TreeView from './components/treeView'
9
11
 
@@ -17,22 +19,19 @@ export default {
17
19
  name: 'title',
18
20
  title: 'Taxonomy Concept Scheme',
19
21
  type: 'string',
20
- description:
21
- 'Concept schemes are used to group concepts into defined sets, such as thesauri, classification schemes, or facets. Concepts may belong on many (or no) concept schemes, and you may create as many (or few) concept schemes as you like.',
22
+ description: 'Schemes group concepts into defined sets, such as thesauri, classification schemes, or facets. Concepts may belong on many (or no) concept schemes, and you may create as many (or few) concept schemes as you like'
22
23
  },
23
24
  {
24
25
  name: 'treeView',
25
26
  title: 'Concept Scheme Tree View',
26
27
  type: 'string',
27
- description:
28
- 'Concept hierarchy is determined by \'Broader Than\' and \'Top Concept\' relationships assigned to each concept. A holistic view of these relationships is shown below. Top Concepts are indicated in bold. Italicized concepts represent polyhierarchy (concepts that appear in more than one branch of the hierarchy tree.)',
28
+ description: <>Top Concepts are indicated in <strong>bold</strong>. Concepts in <em>italics</em> represent polyhierarchy (concepts that appear in more than one branch of the hierarchy tree).</>,
29
29
  inputComponent: TreeView
30
30
  },
31
31
  {
32
32
  name: 'description',
33
33
  title: 'Description',
34
34
  type: 'text',
35
- rows: 3,
36
35
  description: 'Describe the intended use of this scheme.',
37
36
  },
38
37
  ],