rdfjs / shacl-ui

SHACL-driven UIs
https://rdf.js.org/shacl-ui/
11 stars 2 forks source link

Use-case : form and model boundaries #30

Open WilliamChelman opened 12 months ago

WilliamChelman commented 12 months ago

When generating the form of "something", it could be useful to define where to start and where to stop when pulling data to be edited, considering that we are not limiting things to one given node or embedded forms. So the idea would be to define the boundaries of a data graph being loaded, ideally independent of the use of named graphs. For a more concrete example, I'll take the example of a form generated to be able to edit a skos:ConceptScheme and all the skos:Concept within.

Defining starting point(s) / root(s)

Concept Scheme form with its concepts In the context of this application, skos:ConceptScheme are defined as "roots", and so whenever a user would land on the form of a skos:Concept, it would always be in the context of its skos:ConceptScheme, as reflected in the tree view on the left.

For now in this app, the solution we use is something that looks like this

<ConceptScheme>
    a sh:NodeShape ;
    sh:targetClass skos:ConceptScheme ;
    hanami:isRoot  true ;
    #...

Defining external boundaries

When going deeper, the tree can expand through any property, like skos:narrower and the likes Belgium concept and its narrowers This makes sense as narrowers are conceptually part of the same skos:ConceptScheme, and so editing them in the same context/data graph feels logical. But let's imagine a sh:PropertyShape for skos:exactMatch. It could look like this

<Concept/exactMatch>
    a           sh:PropertyShape ;
    sh:path     skos:exactMatch ;
    sh:nodeKind sh:IRI ;
    sh:class skos:Concept ;
.

Normally, skos:exactMatch should point to a skos:Concept that belongs to an other skos:ConceptScheme. So if we had something like ex:Belgium skos:exactMatch otherDomain:be, that otherDomain:be node should not be pulled as part of the skos:ConceptScheme form where ex:Belgium belongs to.

For now in our app we made use of something that looks a bit like this

<Concept/exactMatch>
    a           sh:PropertyShape ;
    sh:path     skos:exactMatch ;
    sh:nodeKind sh:IRI ;
    sh:class skos:Concept ;
    hanami:linkingStrategy hanami:ExternalReferenceLinkingStrategy ;
.

hanami:linkingStrategy being [0..n] and only used in shapes with sh:nodeKind being sh:IRI or sh:BlankNode. Here is a revised version of what we use, as some of them are more specific than this use-case:

The 2 last options are sometimes used together, as one of our client needed to cleanup their concept hierarchy, and so hanami:CreateLinkingStartegy and hanami:InternalReferenceLinkingStartegy were both set on most hierarchical properties (skos:hasTopConcept, skos:narrower, etc.)

WilliamChelman commented 12 months ago

Linked to #29 I believe, even though scopes are not entirely the same, as here the tree view would be limited to the defined boundaries, but nothing tells it if some property should or should not be used in the tree (for example in the 2nd screenshot above, it could make sense to hide skos:inScheme in the tree)