@ulb-darmstadt/shacl-form 3.1.1 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -8
- package/dist/assets/mode-BriAnl-6.js +13 -0
- package/dist/assets/mode-f6xgDLiM.js +13 -0
- package/dist/assets/query-CpoZo0uf.js +501 -0
- package/dist/assets/query-DLp_5-vp.js +84 -0
- package/dist/bundle.d.ts +3 -3
- package/dist/bundle.js +34 -447
- package/dist/config.d.ts +13 -5
- package/dist/constants.d.ts +3 -0
- package/dist/constraints.d.ts +3 -3
- package/dist/exports.d.ts +11 -10
- package/dist/form.d.ts +12 -6
- package/dist/graph-loader.d.ts +2 -2
- package/dist/group.d.ts +1 -1
- package/dist/index.js +6 -87
- package/dist/linker.d.ts +4 -4
- package/dist/node-template.d.ts +2 -2
- package/dist/node.d.ts +9 -4
- package/dist/plugin.d.ts +3 -1
- package/dist/plugins/file-upload.d.ts +2 -2
- package/dist/plugins/leaflet.d.ts +7 -4
- package/dist/plugins/leaflet.js +18 -10
- package/dist/property-template.d.ts +2 -2
- package/dist/property.d.ts +4 -2
- package/dist/query/editor.d.ts +3 -0
- package/dist/query/index.d.ts +55 -0
- package/dist/query/mode.d.ts +24 -0
- package/dist/query/sparql.d.ts +75 -0
- package/dist/rdf-loader.d.ts +1 -1
- package/dist/serialize.d.ts +1 -1
- package/dist/sparql.js +9 -0
- package/dist/theme.d.ts +1 -1
- package/dist/theme.default.d.ts +2 -2
- package/dist/util.d.ts +2 -2
- package/package.json +36 -17
- package/src/query/query-mode.md +319 -0
package/README.md
CHANGED
|
@@ -56,7 +56,7 @@ npm i @ulb-darmstadt/shacl-form
|
|
|
56
56
|
This package has peer dependencies; install them in your app as well:
|
|
57
57
|
|
|
58
58
|
```console
|
|
59
|
-
npm i @ro-kit/ui-widgets jsonld leaflet leaflet-editable leaflet.fullscreen n3 rdfxml-streaming-parser shacl-engine uuid
|
|
59
|
+
npm i @ro-kit/ui-widgets jsonld leaflet leaflet-editable leaflet.fullscreen leaflet.heat n3 rdfxml-streaming-parser shacl-engine uuid
|
|
60
60
|
```
|
|
61
61
|
|
|
62
62
|
Load the web component in your app. For a Vite/webpack-style project, import it once at startup:
|
|
@@ -93,6 +93,7 @@ data-language | Language for `langString` values (e.g. in `sh:name` or `rdfs:lab
|
|
|
93
93
|
data-loading | Text displayed while the component initializes. Default is `"Loading..."`
|
|
94
94
|
data-ignore-owl-imports | By default, `owl:imports` URLs are fetched and merged into the shapes graph. Set this attribute to disable that behavior
|
|
95
95
|
data-view | When set, turns the component into a viewer that displays the data graph without editing
|
|
96
|
+
data-mode | Explicit component mode: `edit` (default), `view`, or `query`. When omitted, the legacy `data-view` attribute continues to select viewer mode
|
|
96
97
|
data-collapse | When set, `sh:group`s and properties with `sh:node` and `sh:maxCount` != 1 are rendered in a collapsible accordion. Use value `"open"` to start expanded
|
|
97
98
|
data-submit-button | [Ignored when `data-view` is set] Adds a submit button. The attribute value is used as the label. `submit` events fire only when the data validates
|
|
98
99
|
data-generate-node-shape-reference | When generating RDF data, adds a triple that references the root `sh:NodeShape`. Default predicate is `http://purl.org/dc/terms/conformsTo`. Set to an empty string to disable
|
|
@@ -146,6 +147,21 @@ setResourceLinkProvider(provider: ResourceLinkProvider)
|
|
|
146
147
|
```
|
|
147
148
|
Registers a provider for linking existing resources. It can list resources that conform to a node shape and load RDF for the selected resources. See [below](#resourceLinkProvider).
|
|
148
149
|
|
|
150
|
+
```typescript
|
|
151
|
+
setQueryFacetProvider(provider: QueryFacetProvider)
|
|
152
|
+
```
|
|
153
|
+
See the [query mode guide](./src/query/query-mode.md)
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
getQuery(): Query
|
|
157
|
+
```
|
|
158
|
+
See the [query mode guide](./src/query/query-mode.md)
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
refreshQueryFacets()
|
|
162
|
+
```
|
|
163
|
+
See the [query mode guide](./src/query/query-mode.md)
|
|
164
|
+
|
|
149
165
|
## Features
|
|
150
166
|
|
|
151
167
|
### Validation
|
|
@@ -160,6 +176,10 @@ In edit mode, `<shacl-form>` validates the constructed data graph using [shacl-e
|
|
|
160
176
|
|
|
161
177
|
`<shacl-form>` is both an editor and a viewer. Set `data-view` and bind a shapes graph and a data graph to render a read-only view. See the [demo](https://ulb-darmstadt.github.io/shacl-form/#viewer-mode).
|
|
162
178
|
|
|
179
|
+
### Query mode
|
|
180
|
+
|
|
181
|
+
See the [query mode guide](./src/query/query-mode.md)
|
|
182
|
+
|
|
163
183
|
### Additional RDF for the shapes graph
|
|
164
184
|
|
|
165
185
|
Besides `data-shapes` and `data-shapes-url`, `shacl-form` can enrich the shapes graph in three ways:
|
|
@@ -168,7 +188,7 @@ Besides `data-shapes` and `data-shapes-url`, `shacl-form` can enrich the shapes
|
|
|
168
188
|
|
|
169
189
|
While parsing the shapes graph, any `owl:imports` predicate with a valid HTTP URL is fetched, parsed, and added as a named graph. That graph is scoped to the node where the `owl:imports` statement appears and its child nodes.
|
|
170
190
|
|
|
171
|
-
The [example shapes graph](https://ulb-darmstadt.github.io/shacl-form/#
|
|
191
|
+
The [example shapes graph](https://ulb-darmstadt.github.io/shacl-form/#edit-mode) contains the following triples:
|
|
172
192
|
|
|
173
193
|
```
|
|
174
194
|
example:Attribution
|
|
@@ -211,7 +231,7 @@ Besides `data-shapes` and `data-shapes-url`, `shacl-form` can enrich the shapes
|
|
|
211
231
|
|
|
212
232
|
Use this when a property has `sh:class` and the available instances should come from an external source. The callback returns RDF, for example `text/turtle`, containing instances of the requested class.
|
|
213
233
|
|
|
214
|
-
In [this example](https://ulb-darmstadt.github.io/shacl-form/#
|
|
234
|
+
In [this example](https://ulb-darmstadt.github.io/shacl-form/#edit-mode), the code:
|
|
215
235
|
|
|
216
236
|
```typescript
|
|
217
237
|
form.setClassInstanceProvider((clazz) => {
|
|
@@ -232,11 +252,11 @@ Besides `data-shapes` and `data-shapes-url`, `shacl-form` can enrich the shapes
|
|
|
232
252
|
|
|
233
253
|
When a property shape has an `sh:class`, `shacl-form` scans all available graphs for matching instances so users can choose from them. `rdfs:subClassOf` is also considered when building the list of class instances.
|
|
234
254
|
|
|
235
|
-
`shacl-form` also supports class instance hierarchies modelled with `skos:broader` and/or `skos:narrower`. This is illustrated by the "Subject classification" property in the [example](https://ulb-darmstadt.github.io/shacl-form/#
|
|
255
|
+
`shacl-form` also supports class instance hierarchies modelled with `skos:broader` and/or `skos:narrower`. This is illustrated by the "Subject classification" property in the [example](https://ulb-darmstadt.github.io/shacl-form/#edit-mode).
|
|
236
256
|
|
|
237
257
|
### SHACL constraints sh:or and sh:xone
|
|
238
258
|
|
|
239
|
-
`<shacl-form>` supports [sh:or](https://www.w3.org/TR/shacl/#OrConstraintComponent) and [sh:xone](https://www.w3.org/TR/shacl/#XoneConstraintComponent) to let users choose between different options on nodes or properties. The [example shapes graph](https://ulb-darmstadt.github.io/shacl-form/#
|
|
259
|
+
`<shacl-form>` supports [sh:or](https://www.w3.org/TR/shacl/#OrConstraintComponent) and [sh:xone](https://www.w3.org/TR/shacl/#XoneConstraintComponent) to let users choose between different options on nodes or properties. The [example shapes graph](https://ulb-darmstadt.github.io/shacl-form/#edit-mode) includes:
|
|
240
260
|
|
|
241
261
|
```
|
|
242
262
|
example:Attribution
|
|
@@ -282,7 +302,7 @@ The provider supports both eager loading during initialization and lazy loading
|
|
|
282
302
|
|
|
283
303
|
### SHACL shape inheritance
|
|
284
304
|
|
|
285
|
-
SHACL defines two ways of inheriting shapes: [sh:and](https://www.w3.org/TR/shacl/#AndConstraintComponent) and [sh:node](https://www.w3.org/TR/shacl/#NodeConstraintComponent). `<shacl-form>` supports both. In [this example](https://ulb-darmstadt.github.io/shacl-form/#
|
|
305
|
+
SHACL defines two ways of inheriting shapes: [sh:and](https://www.w3.org/TR/shacl/#AndConstraintComponent) and [sh:node](https://www.w3.org/TR/shacl/#NodeConstraintComponent). `<shacl-form>` supports both. In [this example](https://ulb-darmstadt.github.io/shacl-form/#edit-mode), node shape `example:ArchitectureModelDataset` extends `example:Dataset` by defining:
|
|
286
306
|
|
|
287
307
|
```
|
|
288
308
|
example:ArchitectureModelDataset sh:node example:Dataset .
|
|
@@ -292,7 +312,7 @@ Properties of inherited shapes are displayed first.
|
|
|
292
312
|
|
|
293
313
|
### Plugins
|
|
294
314
|
|
|
295
|
-
Plugins can modify rendering and add edit/view functionality for specific RDF datatypes or predicates (or both). For example, the JavaScript on [this page](https://ulb-darmstadt.github.io/shacl-form/#
|
|
315
|
+
Plugins can modify rendering and add edit/view functionality for specific RDF datatypes or predicates (or both). For example, the JavaScript on [this page](https://ulb-darmstadt.github.io/shacl-form/#edit-mode) includes:
|
|
296
316
|
|
|
297
317
|
```typescript
|
|
298
318
|
import { LeafletPlugin } from '@ulb-darmstadt/shacl-form/plugins/leaflet.js'
|
|
@@ -314,7 +334,7 @@ Custom plugins can be built by extending [Plugin](https://github.com/ULB-Darmsta
|
|
|
314
334
|
|
|
315
335
|
### Property grouping and collapsing
|
|
316
336
|
|
|
317
|
-
Properties can be grouped using [sh:group](https://www.w3.org/TR/shacl/#group) in the shapes graph. [This example](https://ulb-darmstadt.github.io/shacl-form/#
|
|
337
|
+
Properties can be grouped using [sh:group](https://www.w3.org/TR/shacl/#group) in the shapes graph. [This example](https://ulb-darmstadt.github.io/shacl-form/#edit-mode) defines a group "Physical properties" and assigns certain properties to it.
|
|
318
338
|
|
|
319
339
|
When `data-collapse` is set, `<shacl-form>` creates an accordion-like widget that toggles grouped properties to reduce visual complexity. If the grouped properties should start open, set `data-collapse="open"`.
|
|
320
340
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import{A as e,B as t,N as n,S as r,U as i,Y as a,a as o,n as s,o as c,p as l,t as u,v as d,w as f,z as p}from"./query-DLp_5-vp.js";import{DataFactory as m}from"n3";import{RokitInput as h,RokitSelect as g,RokitSlider as _,epochToDate as v}from"@ro-kit/ui-widgets";function y(e,t){let n=document.createElement(`div`),r=!!(t.in||t.class||t.datatype?.equals(a));n.classList.add(`query-editor`),n.dataset.queryFieldId=e.id,n.setAttribute(`part`,`query-editor`);let o=document.createElement(`label`);o.textContent=t.label,t.description&&(o.title=t.description.value),n.appendChild(o);let s=document.createElement(`div`);s.classList.add(`query-controls`),n.appendChild(s);let c,l=O(t),d,f=(e=``)=>{let n=document.createElement(`div`);n.classList.add(`query-value-row`);let r=new g;r.classList.add(`editor`,`query-choice`),r.clearable=!0,r.dense=t.config.theme.dense,r.placeholder=``,r.setAttribute(`exportparts`,`facet-count`);let i=document.createElement(`ul`);for(let e of l){let t=document.createElement(`li`);if(t.dataset.value=N(e.term),t.textContent=e.label,e.count!==void 0){let n=document.createElement(`span`);n.classList.add(`facet-count`),n.setAttribute(`part`,`facet-count`),n.dataset.count=String(e.count),t.append(` `,n)}i.appendChild(t)}return r.appendChild(i),r.value=e,n.appendChild(r),n},p=(e=[])=>{s.replaceChildren(),s.appendChild(f(e[0]??``))},m=(e,n=``)=>{let r=new h;return r.classList.add(`editor`,`query-range-bound`),r.type=M(t),r.label=e,r.clearable=!0,r.dense=t.config.theme.dense,r.value=n,r},v=e=>{s.replaceChildren();let n=b(t,c);n&&n[0]<n[1]&&(d=n);let r=D(n,e&&d);if(!r||r[0]===r[1]){s.append(m(`Minimum`,e?.min?.value),m(`Maximum`,e?.max?.value));return}let i=new _;i.classList.add(`editor`,`query-range-slider`),i.dense=t.config.theme.dense,i.clearable=!0,i.range=``,i.setAttribute(`range`,``),i.min=String(r[0]),i.max=String(r[1]),i.step=String(x(t,r)),i.labelFormatter=e=>S(e,t);let a=e?.min?C(e.min,t):r[0],o=e?.max?C(e.max,t):r[1];i.value=JSON.stringify([E(a??r[0],r[0],r[1]),E(o??r[1],r[0],r[1])]),i.dataset.active=e?.min||e?.max?`true`:`false`,i.addEventListener(`change`,()=>{i.dataset.active=`true`}),s.appendChild(i)};return n.getQueryCriteria=()=>{if(u(e)){let n=s.querySelector(`rokit-slider`);if(n){if(n.dataset.active!==`true`)return[];let r=T(n.value);return r?[{field:e,operator:`range`,min:w(r[0],t),max:w(r[1],t)}]:[]}let r=s.querySelectorAll(`rokit-input`),i=A(r[0]?.value,t),a=A(r[1]?.value,t);return i||a?[{field:e,operator:`range`,min:i,max:a}]:[]}if(r)return Array.from(s.querySelectorAll(`rokit-select`)).flatMap(t=>{if(!t.value)return[];let n=l.find(e=>N(e.term)===t.value)?.term;return n?[{field:e,operator:`equals`,value:n}]:[]});let n=j(t)&&!t.class&&!t.nodeKind?.value.endsWith(`#IRI`)?`contains`:`equals`;return Array.from(s.querySelectorAll(`.query-value-row`)).flatMap(r=>{let i=r.querySelector(`.query-value`),a=r.querySelector(`.query-language`)?.value,o=A(i?.value,t,a);return o?[{field:e,operator:n,value:o}]:[]})},n.setQueryFacet=i=>{let a=n.getQueryCriteria();if(c=i,r&&c?.buckets){let e=new Map(O(t).map(e=>[N(e.term),e])),n=new Map(a.flatMap(e=>e.value?[[N(e.value),e.value]]:[]));l=c.buckets.flatMap(n=>{let r=e.get(N(n.value));return t.in&&!r?[]:[{term:n.value,label:n.label??r?.label??n.value.value,count:n.count}]});for(let[t,r]of n)l.some(e=>N(e.term)===t)||l.push({term:r,label:e.get(t)?.label??r.value,count:0});p([...n.keys()])}else if(u(e)){let e=a[0];v(e?{min:e.min,max:e.max}:void 0)}else if(!i)for(let e of s.querySelectorAll(`.query-value`))e.value=``},u(e)?v():r?p():(s.replaceChildren(),s.appendChild((()=>{let e=document.createElement(`div`);e.classList.add(`query-value-row`);let r=new h;r.classList.add(`editor`,`query-value`),r.type=M(t),r.clearable=!0,r.dense=t.config.theme.dense;let a;if(r.addEventListener(`input`,()=>{clearTimeout(a),a=setTimeout(()=>{n.dispatchEvent(new Event(`change`,{bubbles:!0}))},300)}),e.appendChild(r),t.datatype?.equals(i)){let n=t.languageIn?.length?document.createElement(`select`):document.createElement(`input`);if(n.classList.add(`lang-chooser`,`query-language`),n.title=`Language of the text`,n.setAttribute(`aria-label`,`Language of the text`),n instanceof HTMLSelectElement)for(let e of t.languageIn??[]){let t=document.createElement(`option`);t.value=e.value,t.textContent=e.value,n.appendChild(t)}else n.maxLength=35,n.placeholder=`lang?`,n.value=t.config.languages.find(e=>e.length>0)??``;e.appendChild(n)}return e})())),n}function b(e,t){let n=t?.min?C(t.min,e):void 0,r=t?.max?C(t.max,e):void 0,i=e.minInclusive??(e.minExclusive===void 0?void 0:e.minExclusive+1),a=e.maxInclusive??(e.maxExclusive===void 0?void 0:e.maxExclusive-1),o=n===void 0?i:i===void 0?n:Math.max(n,i),s=r===void 0?a:a===void 0?r:Math.min(r,a);return o!==void 0&&s!==void 0&&Number.isFinite(o)&&Number.isFinite(s)&&o<=s?[o,s]:void 0}function x(e,t){return e.datatype?.value===`http://www.w3.org/2001/XMLSchema#integer`?1:e.datatype?.value===`http://www.w3.org/2001/XMLSchema#date`?86400:e.datatype?.value===`http://www.w3.org/2001/XMLSchema#dateTime`?1:Math.max((t[1]-t[0])/1e3,2**-52)}function S(e,t){return t.datatype?.value===`http://www.w3.org/2001/XMLSchema#date`?v(e,!0):t.datatype?.value===`http://www.w3.org/2001/XMLSchema#dateTime`?v(e):String(Math.round(e*1e3)/1e3)}function C(e,t){if(t.datatype?.value===`http://www.w3.org/2001/XMLSchema#date`||t.datatype?.value===`http://www.w3.org/2001/XMLSchema#dateTime`){let t=Date.parse(e.value);return Number.isFinite(t)?t/1e3:void 0}let n=Number(e.value);return Number.isFinite(n)?n:void 0}function w(e,t){let n=t.datatype;return n?.value===`http://www.w3.org/2001/XMLSchema#date`?m.literal(v(e,!0),n):n?.value===`http://www.w3.org/2001/XMLSchema#dateTime`?m.literal(v(e),n):m.literal(String(e),n)}function T(e){try{let t=JSON.parse(e);return Array.isArray(t)&&t.length===2&&t.every(Number.isFinite)?[Number(t[0]),Number(t[1])]:void 0}catch{return}}function E(e,t,n){return Math.min(n,Math.max(t,e))}function D(e,t){return e&&e[0]<e[1]?e:t||e}function O(t){if(t.datatype?.equals(a))return[{term:m.literal(`true`,a),label:`true`},{term:m.literal(`false`,a),label:`false`}];let r=[];return t.in?r=e(t.config.lists[t.in]??[],t.config.store,t.config.languages):t.class&&(r=n(t.class,t)),k(r)}function k(e){return e.flatMap(e=>[...typeof e.value==`string`?[]:[{term:e.value,label:e.label||e.value.value}],...k(e.children??[])])}function A(e,t,n){if(e)return t.class||t.nodeKind?.value.endsWith(`#IRI`)?m.namedNode(e):t.datatype?.equals(i)?n?m.literal(e,n):void 0:t.datatype?m.literal(e,t.datatype):m.literal(e)}function j(e){return!e.datatype||e.datatype.value===`http://www.w3.org/2001/XMLSchema#string`||e.datatype.equals(i)}function M(e){let t=e.datatype?.value;return[`http://www.w3.org/2001/XMLSchema#integer`,`http://www.w3.org/2001/XMLSchema#float`,`http://www.w3.org/2001/XMLSchema#double`,`http://www.w3.org/2001/XMLSchema#decimal`].includes(t??``)?`number`:t===`http://www.w3.org/2001/XMLSchema#date`?`date`:t===`http://www.w3.org/2001/XMLSchema#dateTime`?`datetime-local`:`text`}function N(e){if(e.termType===`Literal`){let t=e;return`${e.termType}:${e.value}:${t.language}:${t.datatype?.value}`}return`${e.termType}:${e.value}`}var P=`form.mode-query { padding: 0; }
|
|
2
|
+
form.mode-query.query-facets-pending > shacl-node { display: none; }
|
|
3
|
+
.mode-query shacl-property.query-unavailable { display: none; }
|
|
4
|
+
.mode-query .shacl-group:not(:has(shacl-property:not(.query-unavailable))), .mode-query shacl-node:not(:has(shacl-property:not(.query-unavailable))) { display: none; }
|
|
5
|
+
.query-editor { display: flex; align-items: center; width: 100%; padding: 3px 0; }
|
|
6
|
+
.query-editor > label { width: var(--label-width); flex-shrink: 0; padding-right: 1em; word-break: break-word; }
|
|
7
|
+
.query-controls { display: flex; flex: 1; min-width: 0; }
|
|
8
|
+
.query-controls > rokit-input, .query-controls > rokit-slider, .query-value-row > rokit-input, .query-value-row > rokit-select { min-height: 28px; width: 100%; flex-grow: 1; }
|
|
9
|
+
.query-value-row { display: flex; flex: 1; width: 100%; min-width: 0; gap: 4px; }
|
|
10
|
+
.query-language { min-height: 28px; flex: 0 0 auto; }
|
|
11
|
+
.query-range-slider[data-active='false'] { opacity: 0.7; }
|
|
12
|
+
.query-facet-error .query-editor > label { color: var(--shacl-error-color); }
|
|
13
|
+
`,F=0,I=class{constructor(e){this.stylesheet=new CSSStyleSheet,this.facetRequest=0,this.facetsApplied=!1,this.host=e,this.stylesheet.replaceSync(P)}async initialize(){await this.emitQueryAndRefreshFacets()}handleChange(){this.emitQueryAndRefreshFacets()}getQuery(){let e=this.host.shape;return e?{rootShapeId:e.template.id.value,targetClass:e.template.targetClass?.value,criteria:Array.from(this.host.form.querySelectorAll(`.query-editor`)).flatMap(e=>e.getQueryCriteria())}:{rootShapeId:``,criteria:[]}}refreshFacets(){this.host.shape&&this.requestFacets(this.getQuery())}dispose(){this.facetAbortController?.abort(),this.host.classList.remove(`query-facets-empty`)}async emitQueryAndRefreshFacets(){if(!this.host.shape)return;let e=this.getQuery();this.host.dispatchEvent(new CustomEvent(`query`,{bubbles:!0,composed:!0,detail:e})),await this.requestFacets(e)}async requestFacets(e){let t=this.host.config.queryFacetProvider;if(!t)return;this.facetAbortController?.abort();let n=new AbortController;this.facetAbortController=n;let r=++this.facetRequest;this.facetsApplied||this.setFacetsPending(!0);try{let i=Array.from(this.host.form.querySelectorAll(`.query-editor`)).map(e=>e.queryField),a=await t.getFacets({query:e,fields:i,signal:n.signal});if(n.signal.aborted||r!==this.facetRequest)return;this.applyFacets(a),this.facetsApplied=!0,this.setFacetsPending(!1)}catch(e){if(n.signal.aborted)return;this.setFacetsPending(!1),this.host.dispatchEvent(new CustomEvent(`queryerror`,{bubbles:!0,composed:!0,detail:e}))}}applyFacets(e){let t=new Map(e.map(e=>[e.fieldId,e]));for(let e of Array.from(this.host.form.querySelectorAll(`.query-editor`))){let n=t.get(e.queryField.id),r=e.getQueryCriteria().length>0;e.setQueryFacet(n);let i=e.closest(`shacl-property`);i?.classList.toggle(`query-unavailable`,n?.count===0&&!r),i?.classList.toggle(`query-facet-error`,n?.error===!0)}let n=Array.from(this.host.form.querySelectorAll(`shacl-property`)).reverse();for(let e of n){if(e.querySelector(`:scope > .query-editor, :scope > .collapsible > .query-editor`))continue;let t=Array.from(e.querySelectorAll(`.query-editor`)).some(e=>!e.closest(`shacl-property`)?.classList.contains(`query-unavailable`));e.classList.toggle(`query-unavailable`,!t)}let r=Array.from(this.host.form.querySelectorAll(`.query-editor`)).some(e=>!e.closest(`shacl-property`)?.classList.contains(`query-unavailable`));this.host.classList.toggle(`query-facets-empty`,!r)}setFacetsPending(e){this.host.form.classList.toggle(`query-facets-pending`,e);let t=this.host.form.querySelector(`.query-facets-loading`);if(!e)t?.remove();else if(!t){let e=document.createElement(`div`);e.classList.add(`query-facets-loading`),e.textContent=this.host.config.attributes.loading,this.host.form.prepend(e)}}};async function L(e){let t=e.template;if(t.or?.length||t.xone?.length){let n=V(t);if(n){e.container.appendChild(R(n,e.parent));return}let r=t.or?.length?t.or:t.xone;e.container.appendChild(d(r,e,t.config));return}if(!t.nodeShapes.size){e.container.appendChild(R(t,e.parent));return}for(let n of t.nodeShapes){let r=new Set(e.parent.ancestorShapeIds);if(r.add(e.parent.template.id.value),r.has(n.id.value))continue;let i=e.parent.queryContext??{path:[],shapePath:[]},a=new s(n,void 0,t.nodeKind,t.label,!1,r,{path:[...i.path,t.path],shapePath:[...i.shapePath,H(t)]}),o=document.createElement(`div`);o.classList.add(`property-instance`,`query-structure`),o.setAttribute(`part`,`property-instance`),t.config.hierarchyColorsStyleSheet!==void 0&&o.appendChild(c(!0)),o.appendChild(a),e.container.appendChild(o),await a.ready}}function R(e,t){let n=t.queryContext??{path:[],shapePath:[]},r={id:`qf${(F++).toString(36)}`,path:[...n.path,e.path],shapePath:[...n.shapePath,H(e)],datatype:e.datatype?.value},i=l(e.path,e.datatype?.value)?.createQueryEditor?.(r,e)??y(r,e);return i.queryField=r,i.classList.add(`property-instance`,`query-editor`),i.dataset.path=e.path,i}async function z(e,t){if(!e.length)return;for(let t of e)await t.initializeQuery();let n=e[0];t.replaceWith(n);for(let t=1;t<e.length;t++)n.after(e[t]),n=e[t];n.dispatchEvent(new Event(`change`,{bubbles:!0}))}async function B(e,t,n){e.or=void 0,e.xone=void 0;let r=new o(e,t.parent);await r.initializeQuery(),n.replaceWith(r),r.dispatchEvent(new Event(`change`,{bubbles:!0}))}function V(e){let n=e.or??e.xone;if(!n?.length)return;let i=n.map(t=>{let n=r(e);return n.or=void 0,n.xone=void 0,f(n,e.config.store.getQuads(t,null,null,null)),n.nodeShapes.size===0?n.datatype:void 0});if(i.some(e=>!e||!t.has(e.value)))return;let a=r(e);return a.or=void 0,a.xone=void 0,a.datatype=i.find(e=>e&&p.has(e.value))??i[0],a}function H(e){return e.qualifiedValueShape?e.id.value:e.path}export{I as QueryModeController,z as activateNodeConstraintOption,B as activatePropertyConstraintOption,L as initializeQueryProperty};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import{A as e,E as t,H as n,J as r,M as i,Q as a,Y as o,a as s,b as c,h as l,it as u,m as d,n as f,o as p,ot as m,p as h,t as g,v as _,z as v}from"./query-CpoZo0uf.js";function y(e,t){let n=document.createElement(`div`),r=!!(t.in||t.class||t.datatype?.equals(u));n.classList.add(`query-editor`),n.dataset.queryFieldId=e.id,n.setAttribute(`part`,`query-editor`);let i=document.createElement(`label`);i.textContent=t.label,t.description&&(i.title=t.description.value),n.appendChild(i);let o=document.createElement(`div`);o.classList.add(`query-controls`),n.appendChild(o);let s,c=O(t),f,p=(e=``)=>{let n=document.createElement(`div`);n.classList.add(`query-value-row`);let r=new d;r.classList.add(`editor`,`query-choice`),r.clearable=!0,r.dense=t.config.theme.dense,r.placeholder=``,r.setAttribute(`exportparts`,`facet-count`);let i=document.createElement(`ul`);for(let e of c){let t=document.createElement(`li`);if(t.dataset.value=N(e.term),t.textContent=e.label,e.count!==void 0){let n=document.createElement(`span`);n.classList.add(`facet-count`),n.setAttribute(`part`,`facet-count`),n.dataset.count=String(e.count),t.append(` `,n)}i.appendChild(t)}return r.appendChild(i),r.value=e,n.appendChild(r),n},m=(e=[])=>{o.replaceChildren(),o.appendChild(p(e[0]??``))},h=(e,n=``)=>{let r=new l;return r.classList.add(`editor`,`query-range-bound`),r.type=M(t),r.label=e,r.clearable=!0,r.dense=t.config.theme.dense,r.value=n,r},v=e=>{o.replaceChildren();let n=b(t,s);n&&n[0]<n[1]&&(f=n);let r=D(n,e&&f);if(!r||r[0]===r[1]){o.append(h(`Minimum`,e?.min?.value),h(`Maximum`,e?.max?.value));return}let i=new _;i.classList.add(`editor`,`query-range-slider`),i.dense=t.config.theme.dense,i.clearable=!0,i.range=``,i.setAttribute(`range`,``),i.min=String(r[0]),i.max=String(r[1]),i.step=String(x(t,r)),i.labelFormatter=e=>S(e,t);let a=e?.min?C(e.min,t):r[0],c=e?.max?C(e.max,t):r[1];i.value=JSON.stringify([E(a??r[0],r[0],r[1]),E(c??r[1],r[0],r[1])]),i.dataset.active=e?.min||e?.max?`true`:`false`,i.addEventListener(`change`,()=>{i.dataset.active=`true`}),o.appendChild(i)};return n.getQueryCriteria=()=>{if(g(e)){let n=o.querySelector(`rokit-slider`);if(n){if(n.dataset.active!==`true`)return[];let r=T(n.value);return r?[{field:e,operator:`range`,min:w(r[0],t),max:w(r[1],t)}]:[]}let r=o.querySelectorAll(`rokit-input`),i=A(r[0]?.value,t),a=A(r[1]?.value,t);return i||a?[{field:e,operator:`range`,min:i,max:a}]:[]}if(r)return Array.from(o.querySelectorAll(`rokit-select`)).flatMap(t=>{if(!t.value)return[];let n=c.find(e=>N(e.term)===t.value)?.term;return n?[{field:e,operator:`equals`,value:n}]:[]});let n=j(t)&&!t.class&&!t.nodeKind?.value.endsWith(`#IRI`)?`contains`:`equals`;return Array.from(o.querySelectorAll(`.query-value-row`)).flatMap(r=>{let i=r.querySelector(`.query-value`),a=r.querySelector(`.query-language`)?.value,o=A(i?.value,t,a);return o?[{field:e,operator:n,value:o}]:[]})},n.setQueryFacet=i=>{let a=n.getQueryCriteria();if(s=i,r&&s?.buckets){let e=new Map(O(t).map(e=>[N(e.term),e])),n=new Map(a.flatMap(e=>e.value?[[N(e.value),e.value]]:[]));c=s.buckets.flatMap(n=>{let r=e.get(N(n.value));return t.in&&!r?[]:[{term:n.value,label:n.label??r?.label??n.value.value,count:n.count}]});for(let[t,r]of n)c.some(e=>N(e.term)===t)||c.push({term:r,label:e.get(t)?.label??r.value,count:0});m([...n.keys()])}else if(g(e)){let e=a[0];v(e?{min:e.min,max:e.max}:void 0)}else if(!i)for(let e of o.querySelectorAll(`.query-value`))e.value=``},g(e)?v():r?m():(o.replaceChildren(),o.appendChild((()=>{let e=document.createElement(`div`);e.classList.add(`query-value-row`);let r=new l;r.classList.add(`editor`,`query-value`),r.type=M(t),r.clearable=!0,r.dense=t.config.theme.dense;let i;if(r.addEventListener(`input`,()=>{clearTimeout(i),i=setTimeout(()=>{n.dispatchEvent(new Event(`change`,{bubbles:!0}))},300)}),e.appendChild(r),t.datatype?.equals(a)){let n=t.languageIn?.length?document.createElement(`select`):document.createElement(`input`);if(n.classList.add(`lang-chooser`,`query-language`),n.title=`Language of the text`,n.setAttribute(`aria-label`,`Language of the text`),n instanceof HTMLSelectElement)for(let e of t.languageIn??[]){let t=document.createElement(`option`);t.value=e.value,t.textContent=e.value,n.appendChild(t)}else n.maxLength=35,n.placeholder=`lang?`,n.value=t.config.languages.find(e=>e.length>0)??``;e.appendChild(n)}return e})())),n}function b(e,t){let n=t?.min?C(t.min,e):void 0,r=t?.max?C(t.max,e):void 0,i=e.minInclusive??(e.minExclusive===void 0?void 0:e.minExclusive+1),a=e.maxInclusive??(e.maxExclusive===void 0?void 0:e.maxExclusive-1),o=n===void 0?i:i===void 0?n:Math.max(n,i),s=r===void 0?a:a===void 0?r:Math.min(r,a);return o!==void 0&&s!==void 0&&Number.isFinite(o)&&Number.isFinite(s)&&o<=s?[o,s]:void 0}function x(e,t){return e.datatype?.value===`http://www.w3.org/2001/XMLSchema#integer`?1:e.datatype?.value===`http://www.w3.org/2001/XMLSchema#date`?86400:e.datatype?.value===`http://www.w3.org/2001/XMLSchema#dateTime`?1:Math.max((t[1]-t[0])/1e3,2**-52)}function S(e,t){return t.datatype?.value===`http://www.w3.org/2001/XMLSchema#date`?h(e,!0):t.datatype?.value===`http://www.w3.org/2001/XMLSchema#dateTime`?h(e):String(Math.round(e*1e3)/1e3)}function C(e,t){if(t.datatype?.value===`http://www.w3.org/2001/XMLSchema#date`||t.datatype?.value===`http://www.w3.org/2001/XMLSchema#dateTime`){let t=Date.parse(e.value);return Number.isFinite(t)?t/1e3:void 0}let n=Number(e.value);return Number.isFinite(n)?n:void 0}function w(e,t){let n=t.datatype;return n?.value===`http://www.w3.org/2001/XMLSchema#date`?m.literal(h(e,!0),n):n?.value===`http://www.w3.org/2001/XMLSchema#dateTime`?m.literal(h(e),n):m.literal(String(e),n)}function T(e){try{let t=JSON.parse(e);return Array.isArray(t)&&t.length===2&&t.every(Number.isFinite)?[Number(t[0]),Number(t[1])]:void 0}catch{return}}function E(e,t,n){return Math.min(n,Math.max(t,e))}function D(e,t){return e&&e[0]<e[1]?e:t||e}function O(e){if(e.datatype?.equals(u))return[{term:m.literal(`true`,u),label:`true`},{term:m.literal(`false`,u),label:`false`}];let t=[];return e.in?t=v(e.config.lists[e.in]??[],e.config.store,e.config.languages):e.class&&(t=n(e.class,e)),k(t)}function k(e){return e.flatMap(e=>[...typeof e.value==`string`?[]:[{term:e.value,label:e.label||e.value.value}],...k(e.children??[])])}function A(e,t,n){if(e)return t.class||t.nodeKind?.value.endsWith(`#IRI`)?m.namedNode(e):t.datatype?.equals(a)?n?m.literal(e,n):void 0:t.datatype?m.literal(e,t.datatype):m.literal(e)}function j(e){return!e.datatype||e.datatype.value===`http://www.w3.org/2001/XMLSchema#string`||e.datatype.equals(a)}function M(e){let t=e.datatype?.value;return[`http://www.w3.org/2001/XMLSchema#integer`,`http://www.w3.org/2001/XMLSchema#float`,`http://www.w3.org/2001/XMLSchema#double`,`http://www.w3.org/2001/XMLSchema#decimal`].includes(t??``)?`number`:t===`http://www.w3.org/2001/XMLSchema#date`?`date`:t===`http://www.w3.org/2001/XMLSchema#dateTime`?`datetime-local`:`text`}function N(e){if(e.termType===`Literal`){let t=e;return`${e.termType}:${e.value}:${t.language}:${t.datatype?.value}`}return`${e.termType}:${e.value}`}var P=`form.mode-query { padding: 0; }
|
|
2
|
+
form.mode-query.query-facets-pending > shacl-node { display: none; }
|
|
3
|
+
.mode-query shacl-property.query-unavailable { display: none; }
|
|
4
|
+
.mode-query .shacl-group:not(:has(shacl-property:not(.query-unavailable))), .mode-query shacl-node:not(:has(shacl-property:not(.query-unavailable))) { display: none; }
|
|
5
|
+
.query-editor { display: flex; align-items: center; width: 100%; padding: 3px 0; }
|
|
6
|
+
.query-editor > label { width: var(--label-width); flex-shrink: 0; padding-right: 1em; word-break: break-word; }
|
|
7
|
+
.query-controls { display: flex; flex: 1; min-width: 0; }
|
|
8
|
+
.query-controls > rokit-input, .query-controls > rokit-slider, .query-value-row > rokit-input, .query-value-row > rokit-select { min-height: 28px; width: 100%; flex-grow: 1; }
|
|
9
|
+
.query-value-row { display: flex; flex: 1; width: 100%; min-width: 0; gap: 4px; }
|
|
10
|
+
.query-language { min-height: 28px; flex: 0 0 auto; }
|
|
11
|
+
.query-range-slider[data-active='false'] { opacity: 0.7; }
|
|
12
|
+
.query-facet-error .query-editor > label { color: var(--shacl-error-color); }
|
|
13
|
+
`,F=0,I=class{constructor(e){this.stylesheet=new CSSStyleSheet,this.facetRequest=0,this.facetsApplied=!1,this.host=e,this.stylesheet.replaceSync(P)}async initialize(){await this.emitQueryAndRefreshFacets()}handleChange(){this.emitQueryAndRefreshFacets()}getQuery(){let e=this.host.shape;return e?{rootShapeId:e.template.id.value,targetClass:e.template.targetClass?.value,criteria:Array.from(this.host.form.querySelectorAll(`.query-editor`)).flatMap(e=>e.getQueryCriteria())}:{rootShapeId:``,criteria:[]}}refreshFacets(){this.host.shape&&this.requestFacets(this.getQuery())}dispose(){this.facetAbortController?.abort(),this.host.classList.remove(`query-facets-empty`)}async emitQueryAndRefreshFacets(){if(!this.host.shape)return;let e=this.getQuery();this.host.dispatchEvent(new CustomEvent(`query`,{bubbles:!0,composed:!0,detail:e})),await this.requestFacets(e)}async requestFacets(e){let t=this.host.config.queryFacetProvider;if(!t)return;this.facetAbortController?.abort();let n=new AbortController;this.facetAbortController=n;let r=++this.facetRequest;this.facetsApplied||this.setFacetsPending(!0);try{let i=Array.from(this.host.form.querySelectorAll(`.query-editor`)).map(e=>e.queryField),a=await t.getFacets({query:e,fields:i,signal:n.signal});if(n.signal.aborted||r!==this.facetRequest)return;this.applyFacets(a),this.facetsApplied=!0,this.setFacetsPending(!1)}catch(e){if(n.signal.aborted)return;this.setFacetsPending(!1),this.host.dispatchEvent(new CustomEvent(`queryerror`,{bubbles:!0,composed:!0,detail:e}))}}applyFacets(e){let t=new Map(e.map(e=>[e.fieldId,e]));for(let e of Array.from(this.host.form.querySelectorAll(`.query-editor`))){let n=t.get(e.queryField.id),r=e.getQueryCriteria().length>0;e.setQueryFacet(n);let i=e.closest(`shacl-property`);i?.classList.toggle(`query-unavailable`,n?.count===0&&!r),i?.classList.toggle(`query-facet-error`,n?.error===!0)}let n=Array.from(this.host.form.querySelectorAll(`shacl-property`)).reverse();for(let e of n){if(e.querySelector(`:scope > .query-editor, :scope > .collapsible > .query-editor`))continue;let t=Array.from(e.querySelectorAll(`.query-editor`)).some(e=>!e.closest(`shacl-property`)?.classList.contains(`query-unavailable`));e.classList.toggle(`query-unavailable`,!t)}let r=Array.from(this.host.form.querySelectorAll(`.query-editor`)).some(e=>!e.closest(`shacl-property`)?.classList.contains(`query-unavailable`));this.host.classList.toggle(`query-facets-empty`,!r)}setFacetsPending(e){this.host.form.classList.toggle(`query-facets-pending`,e);let t=this.host.form.querySelector(`.query-facets-loading`);if(!e)t?.remove();else if(!t){let e=document.createElement(`div`);e.classList.add(`query-facets-loading`),e.textContent=this.host.config.attributes.loading,this.host.form.prepend(e)}}};async function L(e){let n=e.template;if(n.or?.length||n.xone?.length){let r=V(n);if(r){e.container.appendChild(R(r,e.parent));return}let i=n.or?.length?n.or:n.xone;e.container.appendChild(t(i,e,n.config));return}if(!n.nodeShapes.size){e.container.appendChild(R(n,e.parent));return}for(let t of n.nodeShapes){let r=new Set(e.parent.ancestorShapeIds);if(r.add(e.parent.template.id.value),r.has(t.id.value))continue;let i=e.parent.queryContext??{path:[],shapePath:[]},a=new f(t,void 0,n.nodeKind,n.label,!1,r,{path:[...i.path,n.path],shapePath:[...i.shapePath,H(n)]}),o=document.createElement(`div`);o.classList.add(`property-instance`,`query-structure`),o.setAttribute(`part`,`property-instance`),n.config.hierarchyColorsStyleSheet!==void 0&&o.appendChild(p(!0)),o.appendChild(a),e.container.appendChild(o),await a.ready}}function R(e,t){let n=t.queryContext??{path:[],shapePath:[]},r={id:`qf${(F++).toString(36)}`,path:[...n.path,e.path],shapePath:[...n.shapePath,H(e)],datatype:e.datatype?.value},i=c(e.path,e.datatype?.value)?.createQueryEditor?.(r,e)??y(r,e);return i.queryField=r,i.classList.add(`property-instance`,`query-editor`),i.dataset.path=e.path,i}async function z(e,t){if(!e.length)return;for(let t of e)await t.initializeQuery();let n=e[0];t.replaceWith(n);for(let t=1;t<e.length;t++)n.after(e[t]),n=e[t];n.dispatchEvent(new Event(`change`,{bubbles:!0}))}async function B(e,t,n){e.or=void 0,e.xone=void 0;let r=new s(e,t.parent);await r.initializeQuery(),n.replaceWith(r),r.dispatchEvent(new Event(`change`,{bubbles:!0}))}function V(t){let n=t.or??t.xone;if(!n?.length)return;let a=n.map(n=>{let r=e(t);return r.or=void 0,r.xone=void 0,i(r,t.config.store.getQuads(n,null,null,null)),r.nodeShapes.size===0?r.datatype:void 0});if(a.some(e=>!e||!o.has(e.value)))return;let s=e(t);return s.or=void 0,s.xone=void 0,s.datatype=a.find(e=>e&&r.has(e.value))??a[0],s}function H(e){return e.qualifiedValueShape?e.id.value:e.path}export{I as QueryModeController,z as activateNodeConstraintOption,B as activatePropertyConstraintOption,L as initializeQueryProperty};
|