@lblod/ember-rdfa-editor-lblod-plugins 33.0.0 → 33.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/addon/components/besluit-topic-plugin/besluit-topic-toolbar-dropdown.ts +1 -1
- package/addon/components/besluit-type-plugin/toolbar-dropdown.gts +1 -1
- package/addon/components/decision-plugin/decision-plugin-card.gts +3 -2
- package/addon/components/decision-plugin/insert-article.gts +1 -1
- package/addon/components/document-validation-plugin/card.gts +130 -33
- package/addon/components/lpdc-plugin/lpdc-insert.ts +1 -1
- package/addon/components/roadsign-regulation-plugin/roadsign-regulation-card.gts +1 -1
- package/addon/components/roadsign-regulation-plugin/roadsigns-modal.gts +1 -1
- package/addon/plugins/besluit-type-plugin/utils/besluit-type-instances.ts +1 -1
- package/addon/plugins/besluit-type-plugin/utils/set-besluit-type.ts +1 -1
- package/addon/plugins/decision-plugin/commands/insert-article-container.ts +14 -1
- package/addon/plugins/decision-plugin/commands/insert-description.ts +9 -1
- package/addon/plugins/decision-plugin/commands/insert-motivation.ts +9 -1
- package/addon/plugins/decision-plugin/commands/insert-title.ts +9 -1
- package/addon/plugins/document-validation-plugin/common-fixes.ts +125 -0
- package/addon/plugins/document-validation-plugin/index.ts +61 -32
- package/addon/plugins/roadsign-regulation-plugin/queries/mobility-measure-concept.ts +9 -1
- package/addon/{plugins/besluit-topic-plugin/utils/helpers.ts → utils/decision-utils.ts} +33 -9
- package/declarations/addon/components/document-validation-plugin/card.d.ts +51 -1
- package/declarations/addon/plugins/decision-plugin/commands/insert-article-container.d.ts +3 -1
- package/declarations/addon/plugins/document-validation-plugin/common-fixes.d.ts +6 -0
- package/declarations/addon/plugins/document-validation-plugin/index.d.ts +30 -6
- package/declarations/addon/{plugins/besluit-topic-plugin/utils/helpers.d.ts → utils/decision-utils.d.ts} +5 -1
- package/package.json +2 -2
- package/pnpm-lock.yaml +5 -5
- package/translations/en-US.yaml +1 -0
- package/translations/nl-BE.yaml +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# @lblod/ember-rdfa-editor-lblod-plugins
|
|
2
2
|
|
|
3
|
+
## 33.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#589](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/pull/589) [`380f999`](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/commit/380f9998e6c8f37f1c7be5bf2be528884f24a850) Thanks [@lagartoverde](https://github.com/lagartoverde)! - Add actions to document validation plugin
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- [#608](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/pull/608) [`7d01346`](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/commit/7d01346456985efa3fc4438c828b4fbc31de297e) Thanks [@lagartoverde](https://github.com/lagartoverde)! - Fix ordering of measures in IRGN plugin
|
|
12
|
+
|
|
3
13
|
## 33.0.0
|
|
4
14
|
|
|
5
15
|
### Major Changes
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
import {
|
|
16
16
|
getCurrentBesluitRange,
|
|
17
17
|
getCurrentBesluitURI,
|
|
18
|
-
} from '@lblod/ember-rdfa-editor-lblod-plugins/
|
|
18
|
+
} from '@lblod/ember-rdfa-editor-lblod-plugins/utils/decision-utils';
|
|
19
19
|
import {
|
|
20
20
|
updateBesluitTopicResource,
|
|
21
21
|
TOPIC_PREDICATE,
|
|
@@ -16,7 +16,7 @@ import { CircleXIcon } from '@appuniversum/ember-appuniversum/components/icons/c
|
|
|
16
16
|
import { SayController } from '@lblod/ember-rdfa-editor';
|
|
17
17
|
import fetchBesluitTypes from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/besluit-type-plugin/utils/fetchBesluitTypes';
|
|
18
18
|
import { BesluitTypePluginOptions } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/besluit-type-plugin';
|
|
19
|
-
import { getCurrentBesluitRange } from '@lblod/ember-rdfa-editor-lblod-plugins/
|
|
19
|
+
import { getCurrentBesluitRange } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/decision-utils';
|
|
20
20
|
import {
|
|
21
21
|
BesluitTypeInstance,
|
|
22
22
|
checkBesluitTypeInstance,
|
|
@@ -23,7 +23,7 @@ import { on } from '@ember/modifier';
|
|
|
23
23
|
import { not } from 'ember-truth-helpers';
|
|
24
24
|
import t from 'ember-intl/helpers/t';
|
|
25
25
|
import { TemplateOnlyComponent } from '@ember/component/template-only';
|
|
26
|
-
import { getCurrentBesluitRange } from '@lblod/ember-rdfa-editor-lblod-plugins/
|
|
26
|
+
import { getCurrentBesluitRange } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/decision-utils';
|
|
27
27
|
|
|
28
28
|
interface DecisionCardOptions {
|
|
29
29
|
articleUriGenerator?: () => string;
|
|
@@ -145,12 +145,13 @@ export default class DecisionPluginCard extends Component<Sig> {
|
|
|
145
145
|
}
|
|
146
146
|
@action
|
|
147
147
|
insertArticleBlock() {
|
|
148
|
-
if (this.decisionUri) {
|
|
148
|
+
if (this.decisionUri && this.decisionNodeLocation) {
|
|
149
149
|
this.controller.doCommand(
|
|
150
150
|
insertArticleContainer({
|
|
151
151
|
intl: this.intl,
|
|
152
152
|
decisionUri: this.decisionUri,
|
|
153
153
|
articleUriGenerator: this.args.options?.articleUriGenerator,
|
|
154
|
+
decisionLocation: this.decisionNodeLocation,
|
|
154
155
|
}),
|
|
155
156
|
{
|
|
156
157
|
view: this.controller.mainEditorView,
|
|
@@ -4,7 +4,7 @@ import { action } from '@ember/object';
|
|
|
4
4
|
import Component from '@glimmer/component';
|
|
5
5
|
import { AddIcon } from '@appuniversum/ember-appuniversum/components/icons/add';
|
|
6
6
|
import { PNode, SayController } from '@lblod/ember-rdfa-editor';
|
|
7
|
-
import { getCurrentBesluitRange } from '@lblod/ember-rdfa-editor-lblod-plugins/
|
|
7
|
+
import { getCurrentBesluitRange } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/decision-utils';
|
|
8
8
|
import { buildArticleStructure } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/decision-plugin/utils/build-article-structure';
|
|
9
9
|
import { not } from 'ember-truth-helpers';
|
|
10
10
|
import { service } from '@ember/service';
|
|
@@ -12,6 +12,8 @@ import AuButton from '@appuniversum/ember-appuniversum/components/au-button';
|
|
|
12
12
|
import { ExternalLinkIcon } from '@appuniversum/ember-appuniversum/components/icons/external-link';
|
|
13
13
|
import t from 'ember-intl/helpers/t';
|
|
14
14
|
import { eq } from 'ember-truth-helpers';
|
|
15
|
+
import ValidationReport from 'rdf-validate-shacl/src/validation-report';
|
|
16
|
+
import { CircleInfoIcon } from '@appuniversum/ember-appuniversum/components/icons/circle-info';
|
|
15
17
|
|
|
16
18
|
interface Sig {
|
|
17
19
|
Args: {
|
|
@@ -19,6 +21,17 @@ interface Sig {
|
|
|
19
21
|
};
|
|
20
22
|
}
|
|
21
23
|
|
|
24
|
+
type ExtractWithKey<T, K extends PropertyKey> = T extends Record<K, unknown>
|
|
25
|
+
? T
|
|
26
|
+
: never;
|
|
27
|
+
|
|
28
|
+
function hasProperty<
|
|
29
|
+
O extends object = object,
|
|
30
|
+
K extends PropertyKey = PropertyKey,
|
|
31
|
+
>(obj: O, key: K): obj is ExtractWithKey<O, K> {
|
|
32
|
+
return key in obj;
|
|
33
|
+
}
|
|
34
|
+
|
|
22
35
|
export default class DocumentValidationPluginCard extends Component<Sig> {
|
|
23
36
|
get controller() {
|
|
24
37
|
return this.args.controller;
|
|
@@ -37,10 +50,26 @@ export default class DocumentValidationPluginCard extends Component<Sig> {
|
|
|
37
50
|
}
|
|
38
51
|
get documentValidationErrors() {
|
|
39
52
|
if (!this.validationState) return [];
|
|
40
|
-
|
|
53
|
+
|
|
54
|
+
const { propertiesWithErrors, rules } = this.validationState;
|
|
41
55
|
if (!propertiesWithErrors) return undefined;
|
|
42
56
|
|
|
43
|
-
|
|
57
|
+
const documentValidationErrors = propertiesWithErrors.map((property) => {
|
|
58
|
+
const rule = rules.find((rule) => property?.shape === rule.shaclRule);
|
|
59
|
+
if (rule && 'violations' in rule) {
|
|
60
|
+
const rulePerConstraint = rule.violations[property?.constraint];
|
|
61
|
+
return {
|
|
62
|
+
...property,
|
|
63
|
+
rule: rulePerConstraint,
|
|
64
|
+
};
|
|
65
|
+
} else {
|
|
66
|
+
return {
|
|
67
|
+
...property,
|
|
68
|
+
rule: rule,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
return documentValidationErrors;
|
|
44
73
|
}
|
|
45
74
|
get propertiesWithoutErrors() {
|
|
46
75
|
if (!this.validationState) return [];
|
|
@@ -65,6 +94,53 @@ export default class DocumentValidationPluginCard extends Component<Sig> {
|
|
|
65
94
|
return ['valid', 'no-matches'].includes(this.status);
|
|
66
95
|
}
|
|
67
96
|
|
|
97
|
+
doActionAndTriggerValidation = async (
|
|
98
|
+
action: (controller: SayController, report: ValidationReport) => void,
|
|
99
|
+
) => {
|
|
100
|
+
action(this.controller, this.validationState?.report as ValidationReport);
|
|
101
|
+
const pluginState = documentValidationPluginKey.getState(
|
|
102
|
+
this.controller.mainEditorView.state,
|
|
103
|
+
);
|
|
104
|
+
if (!pluginState) return;
|
|
105
|
+
const { validationCallback } = pluginState;
|
|
106
|
+
await validationCallback(
|
|
107
|
+
this.controller.mainEditorView,
|
|
108
|
+
this.controller.htmlContent,
|
|
109
|
+
);
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
oldVal: typeof this.documentValidationErrors;
|
|
113
|
+
|
|
114
|
+
dedupeDocumentValidationErrors = (
|
|
115
|
+
val: typeof this.documentValidationErrors,
|
|
116
|
+
) => {
|
|
117
|
+
if (this.compareDocumentValidationErrors(val, this.oldVal)) {
|
|
118
|
+
return this.oldVal;
|
|
119
|
+
} else {
|
|
120
|
+
this.oldVal = val;
|
|
121
|
+
return val;
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
compareDocumentValidationErrors = (
|
|
126
|
+
val1: typeof this.documentValidationErrors,
|
|
127
|
+
val2: typeof this.documentValidationErrors,
|
|
128
|
+
) => {
|
|
129
|
+
if (!val1?.length) return false;
|
|
130
|
+
if (val1.length !== val2?.length) return false;
|
|
131
|
+
for (let i = 0; i < val1.length; i++) {
|
|
132
|
+
if (
|
|
133
|
+
!val1 ||
|
|
134
|
+
!val2 ||
|
|
135
|
+
!val1[i] ||
|
|
136
|
+
!val2[i] ||
|
|
137
|
+
val1[i].shape !== val2[i].shape
|
|
138
|
+
)
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
return true;
|
|
142
|
+
};
|
|
143
|
+
|
|
68
144
|
<template>
|
|
69
145
|
<AuCard
|
|
70
146
|
@flex={{true}}
|
|
@@ -94,42 +170,63 @@ export default class DocumentValidationPluginCard extends Component<Sig> {
|
|
|
94
170
|
</p>
|
|
95
171
|
</c.header>
|
|
96
172
|
<c.content>
|
|
97
|
-
<
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
<
|
|
103
|
-
@icon={{CloseFilledIcon}}
|
|
104
|
-
@size='large'
|
|
105
|
-
@ariaHidden={{true}}
|
|
106
|
-
class='say-document-validation__icon-error au-u-margin-right-small'
|
|
107
|
-
/>
|
|
108
|
-
<div>
|
|
109
|
-
{{error.message}}
|
|
110
|
-
<AuButton
|
|
111
|
-
class='au-u-padding-left-none au-u-padding-right-none'
|
|
112
|
-
@icon={{ExternalLinkIcon}}
|
|
113
|
-
@skin='link'
|
|
114
|
-
title={{error.subject}}
|
|
115
|
-
{{on 'click' (fn this.goToSubject error.subject)}}
|
|
116
|
-
>{{t 'document-validation-plugin.see-related-node'}}</AuButton>
|
|
117
|
-
</div>
|
|
118
|
-
</div>
|
|
119
|
-
{{/each}}
|
|
120
|
-
{{#each this.propertiesWithoutErrors as |property|}}
|
|
121
|
-
<div class='say-document-validation__error-container'>
|
|
122
|
-
<div class='au-u-margin-right-small'>
|
|
173
|
+
<div>
|
|
174
|
+
{{#each
|
|
175
|
+
(this.dedupeDocumentValidationErrors this.documentValidationErrors)
|
|
176
|
+
as |error|
|
|
177
|
+
}}
|
|
178
|
+
<div class='say-document-validation__error-container'>
|
|
123
179
|
<AuIcon
|
|
124
|
-
@icon={{
|
|
180
|
+
@icon={{CloseFilledIcon}}
|
|
125
181
|
@size='large'
|
|
126
182
|
@ariaHidden={{true}}
|
|
127
|
-
class='say-document-validation__icon-
|
|
183
|
+
class='say-document-validation__icon-error au-u-margin-right-small'
|
|
128
184
|
/>
|
|
185
|
+
<div>
|
|
186
|
+
{{error.message}}
|
|
187
|
+
<AuButton
|
|
188
|
+
class='au-u-padding-left-none au-u-padding-right-none'
|
|
189
|
+
@icon={{ExternalLinkIcon}}
|
|
190
|
+
@skin='link'
|
|
191
|
+
title={{error.subject}}
|
|
192
|
+
{{on 'click' (fn this.goToSubject error.subject)}}
|
|
193
|
+
>{{t 'document-validation-plugin.see-related-node'}}</AuButton>
|
|
194
|
+
{{#if error.rule}}
|
|
195
|
+
{{#if (hasProperty error.rule 'action')}}
|
|
196
|
+
<AuButton
|
|
197
|
+
class='au-u-padding-left-none au-u-padding-right-none'
|
|
198
|
+
@icon={{ExternalLinkIcon}}
|
|
199
|
+
@skin='link'
|
|
200
|
+
title={{error.subject}}
|
|
201
|
+
{{on
|
|
202
|
+
'click'
|
|
203
|
+
(fn this.doActionAndTriggerValidation error.rule.action)
|
|
204
|
+
}}
|
|
205
|
+
>{{error.rule.buttonTitle}}</AuButton>
|
|
206
|
+
{{/if}}
|
|
207
|
+
{{#if (hasProperty error.rule 'helpText')}}
|
|
208
|
+
<span title={{error.rule.helpText}}>
|
|
209
|
+
<AuIcon @icon={{CircleInfoIcon}} />
|
|
210
|
+
</span>
|
|
211
|
+
{{/if}}
|
|
212
|
+
{{/if}}
|
|
213
|
+
</div>
|
|
214
|
+
</div>
|
|
215
|
+
{{/each}}
|
|
216
|
+
{{#each this.propertiesWithoutErrors as |property|}}
|
|
217
|
+
<div class='say-document-validation__error-container'>
|
|
218
|
+
<div class='au-u-margin-right-small'>
|
|
219
|
+
<AuIcon
|
|
220
|
+
@icon={{CheckFilledIcon}}
|
|
221
|
+
@size='large'
|
|
222
|
+
@ariaHidden={{true}}
|
|
223
|
+
class='say-document-validation__icon-success'
|
|
224
|
+
/>
|
|
225
|
+
</div>
|
|
226
|
+
{{property.message}}
|
|
129
227
|
</div>
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
{{/each}}
|
|
228
|
+
{{/each}}
|
|
229
|
+
</div>
|
|
133
230
|
</c.content>
|
|
134
231
|
|
|
135
232
|
</AuCard>
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
type LpdcPluginConfig,
|
|
12
12
|
} from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/lpdc-plugin';
|
|
13
13
|
import { v4 as uuidv4 } from 'uuid';
|
|
14
|
-
import { getCurrentBesluitURI } from '
|
|
14
|
+
import { getCurrentBesluitURI } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/decision-utils';
|
|
15
15
|
import { SRO } from '../../utils/constants';
|
|
16
16
|
|
|
17
17
|
interface Args {
|
|
@@ -3,7 +3,7 @@ import { action } from '@ember/object';
|
|
|
3
3
|
import Component from '@glimmer/component';
|
|
4
4
|
import { tracked } from '@glimmer/tracking';
|
|
5
5
|
import { SayController } from '@lblod/ember-rdfa-editor';
|
|
6
|
-
import { getCurrentBesluitRange } from '@lblod/ember-rdfa-editor-lblod-plugins/
|
|
6
|
+
import { getCurrentBesluitRange } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/decision-utils';
|
|
7
7
|
import { RoadsignRegulationPluginOptions } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/roadsign-regulation-plugin';
|
|
8
8
|
import { RDF } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/constants';
|
|
9
9
|
import { OutgoingTriple } from '@lblod/ember-rdfa-editor/core/rdfa-processor';
|
|
@@ -6,7 +6,7 @@ import { action } from '@ember/object';
|
|
|
6
6
|
import Component from '@glimmer/component';
|
|
7
7
|
import { tracked } from '@glimmer/tracking';
|
|
8
8
|
import { SayController } from '@lblod/ember-rdfa-editor';
|
|
9
|
-
import { getCurrentBesluitRange } from '@lblod/ember-rdfa-editor-lblod-plugins/
|
|
9
|
+
import { getCurrentBesluitRange } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/decision-utils';
|
|
10
10
|
import { RoadsignRegulationPluginOptions } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/roadsign-regulation-plugin';
|
|
11
11
|
import {
|
|
12
12
|
countMobilityMeasures,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type EditorState } from '@lblod/ember-rdfa-editor';
|
|
2
2
|
import { getOutgoingTripleList } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/namespace';
|
|
3
|
-
import { getCurrentBesluitRange } from '@lblod/ember-rdfa-editor-lblod-plugins/
|
|
3
|
+
import { getCurrentBesluitRange } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/decision-utils';
|
|
4
4
|
import { RDF } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/constants';
|
|
5
5
|
import { type BesluitType } from './fetchBesluitTypes';
|
|
6
6
|
import { type NamedNodeTriple } from '@lblod/ember-rdfa-editor/core/rdfa-processor';
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
removePropertyFromNode,
|
|
9
9
|
} from '@lblod/ember-rdfa-editor/utils/rdfa-utils';
|
|
10
10
|
import { sayDataFactory } from '@lblod/ember-rdfa-editor/core/say-data-factory';
|
|
11
|
-
import { getCurrentBesluitURI } from '@lblod/ember-rdfa-editor-lblod-plugins/
|
|
11
|
+
import { getCurrentBesluitURI } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/decision-utils';
|
|
12
12
|
import {
|
|
13
13
|
extractBesluitTypeUris,
|
|
14
14
|
isValidTypeChoice,
|
|
@@ -8,16 +8,19 @@ import { buildArticleStructure } from '../utils/build-article-structure';
|
|
|
8
8
|
import { transactionCombinator } from '@lblod/ember-rdfa-editor/utils/transaction-utils';
|
|
9
9
|
import { insertArticle } from '../actions/insert-article';
|
|
10
10
|
import { recalculateNumbers } from '../../structure-plugin/monads/recalculate-structure-numbers';
|
|
11
|
+
import { NodeWithPos } from '@curvenote/prosemirror-utils';
|
|
11
12
|
|
|
12
13
|
interface InsertArticleContainerArgs {
|
|
13
14
|
intl: IntlService;
|
|
14
15
|
decisionUri: string;
|
|
15
16
|
articleUriGenerator?: () => string;
|
|
17
|
+
decisionLocation: NodeWithPos;
|
|
16
18
|
}
|
|
17
19
|
|
|
18
20
|
export default function insertArticleContainer({
|
|
19
21
|
decisionUri,
|
|
20
22
|
articleUriGenerator,
|
|
23
|
+
decisionLocation,
|
|
21
24
|
}: InsertArticleContainerArgs): Command {
|
|
22
25
|
return function (state: EditorState, dispatch?: (tr: Transaction) => void) {
|
|
23
26
|
const { schema } = state;
|
|
@@ -33,9 +36,19 @@ export default function insertArticleContainer({
|
|
|
33
36
|
const articleNode = buildArticleStructure(schema, articleUriGenerator);
|
|
34
37
|
|
|
35
38
|
const factory = new SayDataFactory();
|
|
39
|
+
let replaceTr;
|
|
40
|
+
if (state.selection.$from.pos === decisionLocation.pos) {
|
|
41
|
+
replaceTr = state.tr.replaceRangeWith(
|
|
42
|
+
decisionLocation.pos + decisionLocation.node.nodeSize - 1,
|
|
43
|
+
decisionLocation.pos + decisionLocation.node.nodeSize - 1,
|
|
44
|
+
containerNode,
|
|
45
|
+
);
|
|
46
|
+
} else {
|
|
47
|
+
replaceTr = state.tr.replaceSelectionWith(containerNode);
|
|
48
|
+
}
|
|
36
49
|
const { transaction: newTr, result } = transactionCombinator<boolean>(
|
|
37
50
|
state,
|
|
38
|
-
|
|
51
|
+
replaceTr,
|
|
39
52
|
)([
|
|
40
53
|
addPropertyToNode({
|
|
41
54
|
resource: decisionUri,
|
|
@@ -31,7 +31,15 @@ export default function insertDescription({
|
|
|
31
31
|
);
|
|
32
32
|
const tr = state.tr;
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
if (state.selection.$from.pos === decisionLocation.pos) {
|
|
35
|
+
tr.replaceRangeWith(
|
|
36
|
+
decisionLocation.pos + decisionLocation.node.nodeSize - 1,
|
|
37
|
+
decisionLocation.pos + decisionLocation.node.nodeSize - 1,
|
|
38
|
+
nodeToInsert,
|
|
39
|
+
);
|
|
40
|
+
} else {
|
|
41
|
+
tr.replaceSelectionWith(nodeToInsert);
|
|
42
|
+
}
|
|
35
43
|
|
|
36
44
|
const factory = new SayDataFactory();
|
|
37
45
|
const { transaction: newTr, result } = transactionCombinator<boolean>(
|
|
@@ -110,7 +110,15 @@ export default function insertMotivation({
|
|
|
110
110
|
],
|
|
111
111
|
);
|
|
112
112
|
const tr = state.tr;
|
|
113
|
-
|
|
113
|
+
if (state.selection.$from.pos === decisionLocation.pos) {
|
|
114
|
+
tr.replaceRangeWith(
|
|
115
|
+
decisionLocation.pos + decisionLocation.node.nodeSize - 1,
|
|
116
|
+
decisionLocation.pos + decisionLocation.node.nodeSize - 1,
|
|
117
|
+
nodeToInsert,
|
|
118
|
+
);
|
|
119
|
+
} else {
|
|
120
|
+
tr.replaceSelectionWith(nodeToInsert);
|
|
121
|
+
}
|
|
114
122
|
const factory = new SayDataFactory();
|
|
115
123
|
|
|
116
124
|
const { transaction: newTr, result } = transactionCombinator<boolean>(
|
|
@@ -31,7 +31,15 @@ export default function insertTitle({
|
|
|
31
31
|
);
|
|
32
32
|
|
|
33
33
|
const tr = state.tr;
|
|
34
|
-
|
|
34
|
+
if (state.selection.$from.pos === decisionLocation.pos) {
|
|
35
|
+
tr.replaceRangeWith(
|
|
36
|
+
decisionLocation.pos + decisionLocation.node.nodeSize - 1,
|
|
37
|
+
decisionLocation.pos + decisionLocation.node.nodeSize - 1,
|
|
38
|
+
nodeToInsert,
|
|
39
|
+
);
|
|
40
|
+
} else {
|
|
41
|
+
tr.replaceSelectionWith(nodeToInsert);
|
|
42
|
+
}
|
|
35
43
|
|
|
36
44
|
const factory = new SayDataFactory();
|
|
37
45
|
const { transaction: newTr, result } = transactionCombinator<boolean>(
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { SayController } from '@lblod/ember-rdfa-editor';
|
|
2
|
+
import { getDecisionNodeLocation } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/decision-utils';
|
|
3
|
+
import IntlService from 'ember-intl/services/intl';
|
|
4
|
+
import {
|
|
5
|
+
Notification,
|
|
6
|
+
notificationPluginKey,
|
|
7
|
+
} from '@lblod/ember-rdfa-editor/plugins/notification';
|
|
8
|
+
import {
|
|
9
|
+
insertMotivation,
|
|
10
|
+
insertArticleContainer,
|
|
11
|
+
insertDescription,
|
|
12
|
+
insertTitle,
|
|
13
|
+
} from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/decision-plugin/commands';
|
|
14
|
+
import { CircleXIcon } from '@appuniversum/ember-appuniversum/components/icons/circle-x';
|
|
15
|
+
|
|
16
|
+
export function insertTitleAtCursor(
|
|
17
|
+
controller: SayController,
|
|
18
|
+
intl: IntlService,
|
|
19
|
+
) {
|
|
20
|
+
const decisionNodeLocation = getDecisionNodeLocation(controller);
|
|
21
|
+
if (!decisionNodeLocation) {
|
|
22
|
+
return sendNotificationError(
|
|
23
|
+
controller,
|
|
24
|
+
intl.t('document-validation-plugin.decision-node-not-found'),
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
controller.doCommand(
|
|
28
|
+
insertTitle({
|
|
29
|
+
placeholderText: intl.t('besluit-plugin.placeholder.decision-title'),
|
|
30
|
+
decisionLocation: decisionNodeLocation,
|
|
31
|
+
}),
|
|
32
|
+
{ view: controller.mainEditorView },
|
|
33
|
+
);
|
|
34
|
+
controller.focus();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function insertDescriptionAtCursor(
|
|
38
|
+
controller: SayController,
|
|
39
|
+
intl: IntlService,
|
|
40
|
+
) {
|
|
41
|
+
const decisionNodeLocation = getDecisionNodeLocation(controller);
|
|
42
|
+
if (!decisionNodeLocation) {
|
|
43
|
+
return sendNotificationError(
|
|
44
|
+
controller,
|
|
45
|
+
intl.t('document-validation-plugin.decision-node-not-found'),
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
controller.doCommand(
|
|
49
|
+
insertDescription({
|
|
50
|
+
placeholderText: intl.t(
|
|
51
|
+
'besluit-plugin.placeholder.decision-description',
|
|
52
|
+
),
|
|
53
|
+
decisionLocation: decisionNodeLocation,
|
|
54
|
+
}),
|
|
55
|
+
{
|
|
56
|
+
view: controller.mainEditorView,
|
|
57
|
+
},
|
|
58
|
+
);
|
|
59
|
+
controller.focus();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function insertMotivationAtCursor(
|
|
63
|
+
controller: SayController,
|
|
64
|
+
intl: IntlService,
|
|
65
|
+
) {
|
|
66
|
+
const decisionNodeLocation = getDecisionNodeLocation(controller);
|
|
67
|
+
if (!decisionNodeLocation) {
|
|
68
|
+
return sendNotificationError(
|
|
69
|
+
controller,
|
|
70
|
+
intl.t('document-validation-plugin.decision-node-not-found'),
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
controller.doCommand(
|
|
74
|
+
insertMotivation({
|
|
75
|
+
intl: intl,
|
|
76
|
+
decisionLocation: decisionNodeLocation,
|
|
77
|
+
}),
|
|
78
|
+
{
|
|
79
|
+
view: controller.mainEditorView,
|
|
80
|
+
},
|
|
81
|
+
);
|
|
82
|
+
controller.focus();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function insertArticleContainerAtCursor(
|
|
86
|
+
controller: SayController,
|
|
87
|
+
intl: IntlService,
|
|
88
|
+
articleUriGenerator?: () => string,
|
|
89
|
+
) {
|
|
90
|
+
const decisionNodeLocation = getDecisionNodeLocation(controller);
|
|
91
|
+
if (!decisionNodeLocation) {
|
|
92
|
+
return sendNotificationError(
|
|
93
|
+
controller,
|
|
94
|
+
intl.t('document-validation-plugin.decision-node-not-found'),
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
controller.doCommand(
|
|
98
|
+
insertArticleContainer({
|
|
99
|
+
intl: intl,
|
|
100
|
+
decisionUri: decisionNodeLocation?.node.attrs.subject,
|
|
101
|
+
articleUriGenerator: articleUriGenerator,
|
|
102
|
+
decisionLocation: decisionNodeLocation,
|
|
103
|
+
}),
|
|
104
|
+
{
|
|
105
|
+
view: controller.mainEditorView,
|
|
106
|
+
},
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function sendNotificationError(controller: SayController, text: string) {
|
|
111
|
+
// Show a notification via the notification plugin
|
|
112
|
+
const { notificationCallback } = notificationPluginKey.getState(
|
|
113
|
+
controller.mainEditorState,
|
|
114
|
+
) as {
|
|
115
|
+
notificationCallback: (notification: Notification) => void;
|
|
116
|
+
intl: IntlService;
|
|
117
|
+
};
|
|
118
|
+
notificationCallback({
|
|
119
|
+
title: text,
|
|
120
|
+
options: {
|
|
121
|
+
type: 'error',
|
|
122
|
+
icon: CircleXIcon,
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
}
|
|
@@ -2,14 +2,17 @@ import factory from '@rdfjs/dataset';
|
|
|
2
2
|
import SHACLValidator from 'rdf-validate-shacl';
|
|
3
3
|
import { Parser as ParserN3 } from 'n3';
|
|
4
4
|
import { RdfaParser } from 'rdfa-streaming-parser';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
ProsePlugin,
|
|
7
|
+
PluginKey,
|
|
8
|
+
EditorView,
|
|
9
|
+
SayController,
|
|
10
|
+
} from '@lblod/ember-rdfa-editor';
|
|
6
11
|
import removeQuotes from '@lblod/ember-rdfa-editor-lblod-plugins/utils/remove-quotes';
|
|
7
12
|
import {
|
|
8
|
-
BlankNode,
|
|
9
13
|
DataFactory,
|
|
10
14
|
DatasetCore,
|
|
11
15
|
DatasetCoreFactory,
|
|
12
|
-
NamedNode,
|
|
13
16
|
Quad,
|
|
14
17
|
} from '@rdfjs/types';
|
|
15
18
|
import ValidationReport from 'rdf-validate-shacl/src/validation-report';
|
|
@@ -18,8 +21,34 @@ import { SayDataFactory } from '@lblod/ember-rdfa-editor/core/say-data-factory';
|
|
|
18
21
|
export const documentValidationPluginKey =
|
|
19
22
|
new PluginKey<DocumentValidationPluginState>('DOCUMENT_VALIDATION');
|
|
20
23
|
|
|
21
|
-
|
|
24
|
+
type Violation =
|
|
25
|
+
| {
|
|
26
|
+
action: (controller: SayController, report: ValidationReport) => void;
|
|
27
|
+
buttonTitle: string;
|
|
28
|
+
}
|
|
29
|
+
| {
|
|
30
|
+
helpText: string;
|
|
31
|
+
};
|
|
32
|
+
type Rule =
|
|
33
|
+
| {
|
|
34
|
+
shaclRule: string;
|
|
35
|
+
violations: {
|
|
36
|
+
[key: string]: Violation;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
| {
|
|
40
|
+
shaclRule: string;
|
|
41
|
+
action: (controller: SayController, report: ValidationReport) => void;
|
|
42
|
+
buttonTitle: string;
|
|
43
|
+
}
|
|
44
|
+
| {
|
|
45
|
+
shaclRule: string;
|
|
46
|
+
helpText: string;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export interface DocumentValidationPluginArgs {
|
|
22
50
|
documentShape: string;
|
|
51
|
+
rules: Rule[];
|
|
23
52
|
}
|
|
24
53
|
|
|
25
54
|
export type ShaclValidationReport = ValidationReport.ValidationReport<
|
|
@@ -27,17 +56,16 @@ export type ShaclValidationReport = ValidationReport.ValidationReport<
|
|
|
27
56
|
DatasetCoreFactory<Quad, Quad, DatasetCore<Quad, Quad>>
|
|
28
57
|
>;
|
|
29
58
|
|
|
59
|
+
type PropertyWithError = {
|
|
60
|
+
message: string;
|
|
61
|
+
subject: string | undefined;
|
|
62
|
+
shape: string;
|
|
63
|
+
constraint: string;
|
|
64
|
+
};
|
|
30
65
|
interface DocumentValidationResult {
|
|
31
66
|
report?: ValidationReport;
|
|
32
67
|
propertiesWithoutErrors: { message: string }[];
|
|
33
|
-
propertiesWithErrors:
|
|
34
|
-
| {
|
|
35
|
-
message: string;
|
|
36
|
-
subject: string | undefined;
|
|
37
|
-
}
|
|
38
|
-
// TODO get rid of this?
|
|
39
|
-
| undefined
|
|
40
|
-
)[];
|
|
68
|
+
propertiesWithErrors: PropertyWithError[];
|
|
41
69
|
}
|
|
42
70
|
export interface DocumentValidationTransactionMeta
|
|
43
71
|
extends DocumentValidationResult {
|
|
@@ -47,6 +75,7 @@ export interface DocumentValidationPluginState
|
|
|
47
75
|
extends DocumentValidationResult {
|
|
48
76
|
documentShape: string;
|
|
49
77
|
validationCallback: typeof validationCallback;
|
|
78
|
+
rules: Rule[];
|
|
50
79
|
}
|
|
51
80
|
|
|
52
81
|
export const documentValidationPlugin = (
|
|
@@ -61,6 +90,7 @@ export const documentValidationPlugin = (
|
|
|
61
90
|
documentShape: options.documentShape,
|
|
62
91
|
propertiesWithoutErrors: [],
|
|
63
92
|
propertiesWithErrors: [],
|
|
93
|
+
rules: options.rules,
|
|
64
94
|
};
|
|
65
95
|
},
|
|
66
96
|
apply(tr, state) {
|
|
@@ -107,31 +137,30 @@ async function validationCallback(view: EditorView, documentHtml: string) {
|
|
|
107
137
|
...shacl.match(undefined, propertyPred, undefined),
|
|
108
138
|
].map((quad: Quad) => quad.object);
|
|
109
139
|
|
|
110
|
-
const propertiesWithErrors: {
|
|
111
|
-
sourceShape: BlankNode | NamedNode<string>;
|
|
112
|
-
focusNode: BlankNode | NamedNode<string> | null;
|
|
113
|
-
}[] = [];
|
|
114
|
-
for (const r of report.results) {
|
|
115
|
-
const sourceShape = r.sourceShape;
|
|
116
|
-
if (sourceShape)
|
|
117
|
-
propertiesWithErrors.push({ sourceShape, focusNode: r.focusNode });
|
|
118
|
-
}
|
|
119
140
|
const errorMessagePred = sayFactory.namedNode(
|
|
120
141
|
'http://www.w3.org/ns/shacl#resultMessage',
|
|
121
142
|
);
|
|
122
|
-
const
|
|
123
|
-
|
|
143
|
+
const propertiesWithErrors: PropertyWithError[] = [];
|
|
144
|
+
for (const r of report.results) {
|
|
145
|
+
const sourceShape = r.sourceShape;
|
|
146
|
+
if (sourceShape) {
|
|
124
147
|
const match = shacl.match(sourceShape, errorMessagePred, undefined);
|
|
125
148
|
const message = [...match][0]?.object.value;
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
149
|
+
if (message) {
|
|
150
|
+
propertiesWithErrors.push({
|
|
151
|
+
message: removeQuotes(message),
|
|
152
|
+
subject: r.focusNode?.value,
|
|
153
|
+
shape: sourceShape.value,
|
|
154
|
+
constraint: r.sourceConstraintComponent?.value as string,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
131
160
|
const propertiesWithoutErrorsArray = propertyNodes.filter((propertyNode) =>
|
|
132
|
-
propertiesWithErrors.
|
|
133
|
-
|
|
134
|
-
|
|
161
|
+
propertiesWithErrors.every(
|
|
162
|
+
(propertyWithError) => propertyWithError.shape !== propertyNode.value,
|
|
163
|
+
),
|
|
135
164
|
);
|
|
136
165
|
|
|
137
166
|
const successMessagePred = sayFactory.namedNode(
|
|
@@ -149,7 +178,7 @@ async function validationCallback(view: EditorView, documentHtml: string) {
|
|
|
149
178
|
type: 'setNewReport',
|
|
150
179
|
report,
|
|
151
180
|
propertiesWithoutErrors,
|
|
152
|
-
propertiesWithErrors:
|
|
181
|
+
propertiesWithErrors: propertiesWithErrors,
|
|
153
182
|
});
|
|
154
183
|
transaction.setMeta('addToHistory', false);
|
|
155
184
|
view.dispatch(transaction);
|
|
@@ -92,8 +92,15 @@ async function _queryMobilityMeasures<Count extends boolean>(
|
|
|
92
92
|
: /* sparql */ `SELECT DISTINCT ?uri ?label ?preview ?zonality ?variableSignage`;
|
|
93
93
|
|
|
94
94
|
const filterStatement = _buildFilters(options).join('\n');
|
|
95
|
+
const orderBindings = !count
|
|
96
|
+
? `
|
|
97
|
+
BIND(REPLACE(?label, "^(\\\\D+).*", "$1", "i") AS ?firstLetters)
|
|
98
|
+
BIND(xsd:decimal(REPLACE(?label, "^\\\\D+(\\\\d*\\\\.?\\\\d*).*", "$1", "i")) AS ?number)
|
|
99
|
+
BIND(REPLACE(?label, "^\\\\D+\\\\d*\\\\.?\\\\d*(.*)", "$1", "i") AS ?secondLetters)
|
|
100
|
+
`
|
|
101
|
+
: '';
|
|
95
102
|
const orderByStatement = !count
|
|
96
|
-
? /* sparql */ `ORDER BY ASC(
|
|
103
|
+
? /* sparql */ `ORDER BY ASC(UCASE(?firstLetters)) ASC(?number) ASC(LCASE(?secondLetters))`
|
|
97
104
|
: '';
|
|
98
105
|
const paginationStatement = !count
|
|
99
106
|
? /* sparql */ `LIMIT ${pageSize} OFFSET ${page * pageSize}`
|
|
@@ -126,6 +133,7 @@ async function _queryMobilityMeasures<Count extends boolean>(
|
|
|
126
133
|
?signUri dct:type ?signClassification.
|
|
127
134
|
}
|
|
128
135
|
${filterStatement}
|
|
136
|
+
${orderBindings}
|
|
129
137
|
}
|
|
130
138
|
${orderByStatement}
|
|
131
139
|
${paginationStatement}
|
|
@@ -7,6 +7,16 @@ import { hasOutgoingNamedNodeTriple } from '@lblod/ember-rdfa-editor-lblod-plugi
|
|
|
7
7
|
import { ElementPNode } from '@lblod/ember-rdfa-editor/plugins/datastore';
|
|
8
8
|
import { findAncestors } from '@lblod/ember-rdfa-editor/utils/position-utils';
|
|
9
9
|
|
|
10
|
+
export function getDecisionNodeLocation(controller: SayController) {
|
|
11
|
+
const besluitRange = getCurrentBesluitRange(controller);
|
|
12
|
+
if (!besluitRange) return;
|
|
13
|
+
const decisionNodeLocation = {
|
|
14
|
+
pos: besluitRange.from,
|
|
15
|
+
node: besluitRange.node,
|
|
16
|
+
};
|
|
17
|
+
return decisionNodeLocation;
|
|
18
|
+
}
|
|
19
|
+
|
|
10
20
|
export const getCurrentBesluitRange = (
|
|
11
21
|
controllerOrState: SayController | EditorState,
|
|
12
22
|
): ElementPNode | undefined => {
|
|
@@ -15,15 +25,29 @@ export const getCurrentBesluitRange = (
|
|
|
15
25
|
? controllerOrState.mainEditorState
|
|
16
26
|
: controllerOrState;
|
|
17
27
|
const selection = state.selection;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
28
|
+
let besluit;
|
|
29
|
+
if (
|
|
30
|
+
selection.$from.nodeAfter &&
|
|
31
|
+
hasOutgoingNamedNodeTriple(
|
|
32
|
+
selection.$from.nodeAfter.attrs,
|
|
33
|
+
RDF('type'),
|
|
34
|
+
BESLUIT('Besluit'),
|
|
35
|
+
)
|
|
36
|
+
) {
|
|
37
|
+
besluit = {
|
|
38
|
+
node: selection.$from.nodeAfter,
|
|
39
|
+
pos: selection.$from.pos,
|
|
40
|
+
};
|
|
41
|
+
} else {
|
|
42
|
+
besluit =
|
|
43
|
+
findAncestors(selection.$from, (node: PNode) => {
|
|
44
|
+
return hasOutgoingNamedNodeTriple(
|
|
45
|
+
node.attrs,
|
|
46
|
+
RDF('type'),
|
|
47
|
+
BESLUIT('Besluit'),
|
|
48
|
+
);
|
|
49
|
+
})[0] ?? null;
|
|
50
|
+
}
|
|
27
51
|
if (!besluit) {
|
|
28
52
|
return undefined;
|
|
29
53
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import Component from '@glimmer/component';
|
|
2
2
|
import { SayController } from '@lblod/ember-rdfa-editor';
|
|
3
|
+
import ValidationReport from 'rdf-validate-shacl/src/validation-report';
|
|
3
4
|
interface Sig {
|
|
4
5
|
Args: {
|
|
5
6
|
controller: SayController;
|
|
@@ -9,14 +10,63 @@ export default class DocumentValidationPluginCard extends Component<Sig> {
|
|
|
9
10
|
get controller(): SayController;
|
|
10
11
|
get validationState(): import("@lblod/ember-rdfa-editor-lblod-plugins/plugins/document-validation-plugin").DocumentValidationPluginState | undefined;
|
|
11
12
|
get documentValidationErrors(): ({
|
|
13
|
+
rule: {
|
|
14
|
+
action: (controller: SayController, report: ValidationReport) => void;
|
|
15
|
+
buttonTitle: string;
|
|
16
|
+
} | {
|
|
17
|
+
helpText: string;
|
|
18
|
+
};
|
|
12
19
|
message: string;
|
|
13
20
|
subject: string | undefined;
|
|
14
|
-
|
|
21
|
+
shape: string;
|
|
22
|
+
constraint: string;
|
|
23
|
+
} | {
|
|
24
|
+
rule: {
|
|
25
|
+
shaclRule: string;
|
|
26
|
+
action: (controller: SayController, report: ValidationReport) => void;
|
|
27
|
+
buttonTitle: string;
|
|
28
|
+
} | {
|
|
29
|
+
shaclRule: string;
|
|
30
|
+
helpText: string;
|
|
31
|
+
} | undefined;
|
|
32
|
+
message: string;
|
|
33
|
+
subject: string | undefined;
|
|
34
|
+
shape: string;
|
|
35
|
+
constraint: string;
|
|
36
|
+
})[] | undefined;
|
|
15
37
|
get propertiesWithoutErrors(): {
|
|
16
38
|
message: string;
|
|
17
39
|
}[];
|
|
18
40
|
goToSubject: (subject: string) => void;
|
|
19
41
|
get status(): "not-run" | "no-matches" | "valid" | "invalid";
|
|
20
42
|
get isSuccesslike(): boolean;
|
|
43
|
+
doActionAndTriggerValidation: (action: (controller: SayController, report: ValidationReport) => void) => Promise<void>;
|
|
44
|
+
oldVal: typeof this.documentValidationErrors;
|
|
45
|
+
dedupeDocumentValidationErrors: (val: typeof this.documentValidationErrors) => ({
|
|
46
|
+
rule: {
|
|
47
|
+
action: (controller: SayController, report: ValidationReport) => void;
|
|
48
|
+
buttonTitle: string;
|
|
49
|
+
} | {
|
|
50
|
+
helpText: string;
|
|
51
|
+
};
|
|
52
|
+
message: string;
|
|
53
|
+
subject: string | undefined;
|
|
54
|
+
shape: string;
|
|
55
|
+
constraint: string;
|
|
56
|
+
} | {
|
|
57
|
+
rule: {
|
|
58
|
+
shaclRule: string;
|
|
59
|
+
action: (controller: SayController, report: ValidationReport) => void;
|
|
60
|
+
buttonTitle: string;
|
|
61
|
+
} | {
|
|
62
|
+
shaclRule: string;
|
|
63
|
+
helpText: string;
|
|
64
|
+
} | undefined;
|
|
65
|
+
message: string;
|
|
66
|
+
subject: string | undefined;
|
|
67
|
+
shape: string;
|
|
68
|
+
constraint: string;
|
|
69
|
+
})[] | undefined;
|
|
70
|
+
compareDocumentValidationErrors: (val1: typeof this.documentValidationErrors, val2: typeof this.documentValidationErrors) => boolean;
|
|
21
71
|
}
|
|
22
72
|
export {};
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { Command } from '@lblod/ember-rdfa-editor';
|
|
2
2
|
import IntlService from 'ember-intl/services/intl';
|
|
3
|
+
import { NodeWithPos } from '@curvenote/prosemirror-utils';
|
|
3
4
|
interface InsertArticleContainerArgs {
|
|
4
5
|
intl: IntlService;
|
|
5
6
|
decisionUri: string;
|
|
6
7
|
articleUriGenerator?: () => string;
|
|
8
|
+
decisionLocation: NodeWithPos;
|
|
7
9
|
}
|
|
8
|
-
export default function insertArticleContainer({ decisionUri, articleUriGenerator, }: InsertArticleContainerArgs): Command;
|
|
10
|
+
export default function insertArticleContainer({ decisionUri, articleUriGenerator, decisionLocation, }: InsertArticleContainerArgs): Command;
|
|
9
11
|
export {};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { SayController } from '@lblod/ember-rdfa-editor';
|
|
2
|
+
import IntlService from 'ember-intl/services/intl';
|
|
3
|
+
export declare function insertTitleAtCursor(controller: SayController, intl: IntlService): void;
|
|
4
|
+
export declare function insertDescriptionAtCursor(controller: SayController, intl: IntlService): void;
|
|
5
|
+
export declare function insertMotivationAtCursor(controller: SayController, intl: IntlService): void;
|
|
6
|
+
export declare function insertArticleContainerAtCursor(controller: SayController, intl: IntlService, articleUriGenerator?: () => string): void;
|
|
@@ -1,20 +1,43 @@
|
|
|
1
|
-
import { ProsePlugin, PluginKey, EditorView } from '@lblod/ember-rdfa-editor';
|
|
1
|
+
import { ProsePlugin, PluginKey, EditorView, SayController } from '@lblod/ember-rdfa-editor';
|
|
2
2
|
import { DataFactory, DatasetCore, DatasetCoreFactory, Quad } from '@rdfjs/types';
|
|
3
3
|
import ValidationReport from 'rdf-validate-shacl/src/validation-report';
|
|
4
4
|
export declare const documentValidationPluginKey: PluginKey<DocumentValidationPluginState>;
|
|
5
|
-
|
|
5
|
+
type Violation = {
|
|
6
|
+
action: (controller: SayController, report: ValidationReport) => void;
|
|
7
|
+
buttonTitle: string;
|
|
8
|
+
} | {
|
|
9
|
+
helpText: string;
|
|
10
|
+
};
|
|
11
|
+
type Rule = {
|
|
12
|
+
shaclRule: string;
|
|
13
|
+
violations: {
|
|
14
|
+
[key: string]: Violation;
|
|
15
|
+
};
|
|
16
|
+
} | {
|
|
17
|
+
shaclRule: string;
|
|
18
|
+
action: (controller: SayController, report: ValidationReport) => void;
|
|
19
|
+
buttonTitle: string;
|
|
20
|
+
} | {
|
|
21
|
+
shaclRule: string;
|
|
22
|
+
helpText: string;
|
|
23
|
+
};
|
|
24
|
+
export interface DocumentValidationPluginArgs {
|
|
6
25
|
documentShape: string;
|
|
26
|
+
rules: Rule[];
|
|
7
27
|
}
|
|
8
28
|
export type ShaclValidationReport = ValidationReport.ValidationReport<DataFactory<Quad, Quad> & DatasetCoreFactory<Quad, Quad, DatasetCore<Quad, Quad>>>;
|
|
29
|
+
type PropertyWithError = {
|
|
30
|
+
message: string;
|
|
31
|
+
subject: string | undefined;
|
|
32
|
+
shape: string;
|
|
33
|
+
constraint: string;
|
|
34
|
+
};
|
|
9
35
|
interface DocumentValidationResult {
|
|
10
36
|
report?: ValidationReport;
|
|
11
37
|
propertiesWithoutErrors: {
|
|
12
38
|
message: string;
|
|
13
39
|
}[];
|
|
14
|
-
propertiesWithErrors:
|
|
15
|
-
message: string;
|
|
16
|
-
subject: string | undefined;
|
|
17
|
-
} | undefined)[];
|
|
40
|
+
propertiesWithErrors: PropertyWithError[];
|
|
18
41
|
}
|
|
19
42
|
export interface DocumentValidationTransactionMeta extends DocumentValidationResult {
|
|
20
43
|
type: string;
|
|
@@ -22,6 +45,7 @@ export interface DocumentValidationTransactionMeta extends DocumentValidationRes
|
|
|
22
45
|
export interface DocumentValidationPluginState extends DocumentValidationResult {
|
|
23
46
|
documentShape: string;
|
|
24
47
|
validationCallback: typeof validationCallback;
|
|
48
|
+
rules: Rule[];
|
|
25
49
|
}
|
|
26
50
|
export declare const documentValidationPlugin: (options: DocumentValidationPluginArgs) => ProsePlugin<DocumentValidationPluginState>;
|
|
27
51
|
declare function validationCallback(view: EditorView, documentHtml: string): Promise<void>;
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import { EditorState, SayController } from '@lblod/ember-rdfa-editor';
|
|
1
|
+
import { EditorState, PNode, SayController } from '@lblod/ember-rdfa-editor';
|
|
2
2
|
import { ElementPNode } from '@lblod/ember-rdfa-editor/plugins/datastore';
|
|
3
|
+
export declare function getDecisionNodeLocation(controller: SayController): {
|
|
4
|
+
pos: number;
|
|
5
|
+
node: PNode;
|
|
6
|
+
} | undefined;
|
|
3
7
|
export declare const getCurrentBesluitRange: (controllerOrState: SayController | EditorState) => ElementPNode | undefined;
|
|
4
8
|
export declare const getCurrentBesluitURI: (controllerOrState: SayController | EditorState) => string | undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lblod/ember-rdfa-editor-lblod-plugins",
|
|
3
|
-
"version": "33.
|
|
3
|
+
"version": "33.1.0",
|
|
4
4
|
"description": "Ember addon providing lblod specific plugins for the ember-rdfa-editor",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ember-addon",
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
"ember-resources": "^7.0.2",
|
|
76
76
|
"ember-template-imports": "^4.3.0",
|
|
77
77
|
"ember-velcro": "^2.2.0",
|
|
78
|
-
"@lblod/lib-decision-shapes": "^0.0.
|
|
78
|
+
"@lblod/lib-decision-shapes": "^0.0.25",
|
|
79
79
|
"n2words": "^1.21.0",
|
|
80
80
|
"n3": "^1.26.0",
|
|
81
81
|
"process": "0.11.10",
|
package/pnpm-lock.yaml
CHANGED
|
@@ -30,8 +30,8 @@ importers:
|
|
|
30
30
|
specifier: ^1.16.5
|
|
31
31
|
version: 1.19.2(@glint/template@1.5.1)
|
|
32
32
|
'@lblod/lib-decision-shapes':
|
|
33
|
-
specifier: ^0.0.
|
|
34
|
-
version: 0.0.
|
|
33
|
+
specifier: ^0.0.25
|
|
34
|
+
version: 0.0.25(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(jest@29.7.0(@types/node@20.14.9)(node-notifier@10.0.1))(typescript@5.7.3)
|
|
35
35
|
'@lblod/marawa':
|
|
36
36
|
specifier: 0.8.0-beta.6
|
|
37
37
|
version: 0.8.0-beta.6
|
|
@@ -1753,8 +1753,8 @@ packages:
|
|
|
1753
1753
|
'@glint/template':
|
|
1754
1754
|
optional: true
|
|
1755
1755
|
|
|
1756
|
-
'@lblod/lib-decision-shapes@0.0.
|
|
1757
|
-
resolution: {integrity: sha512-
|
|
1756
|
+
'@lblod/lib-decision-shapes@0.0.25':
|
|
1757
|
+
resolution: {integrity: sha512-4pTmFBro+RLPtaN4SiWt5EYqZ2bbtDqpo+EYsNEDe1wtiMLg6RhOD4RwQwLQrH3mjbuJCyQd3DF3TaZBDcOiSQ==}
|
|
1758
1758
|
|
|
1759
1759
|
'@lblod/marawa@0.8.0-beta.6':
|
|
1760
1760
|
resolution: {integrity: sha512-BW3yCpeQlk9EPnQAEQnM9uViA8RC5DkuoiaPJzbuhMcLvKHfI4cjc6dTg9i8qAijbL/xObmQ/Aexko2Xcj9ktw==}
|
|
@@ -12152,7 +12152,7 @@ snapshots:
|
|
|
12152
12152
|
- socks
|
|
12153
12153
|
- supports-color
|
|
12154
12154
|
|
|
12155
|
-
'@lblod/lib-decision-shapes@0.0.
|
|
12155
|
+
'@lblod/lib-decision-shapes@0.0.25(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(jest@29.7.0(@types/node@20.14.9)(node-notifier@10.0.1))(typescript@5.7.3)':
|
|
12156
12156
|
dependencies:
|
|
12157
12157
|
ts-jest: 29.3.4(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(jest@29.7.0(@types/node@20.14.9)(node-notifier@10.0.1))(typescript@5.7.3)
|
|
12158
12158
|
optionalDependencies:
|
package/translations/en-US.yaml
CHANGED
|
@@ -515,3 +515,4 @@ document-validation-plugin:
|
|
|
515
515
|
no-matching-rules: There is nothing to validate in the document
|
|
516
516
|
see-related-node: See related node
|
|
517
517
|
description: Some parts are required to allow our system to parse this document.
|
|
518
|
+
decision-node-not-found: Please put the cursor inside a decision node
|
package/translations/nl-BE.yaml
CHANGED
|
@@ -512,3 +512,4 @@ document-validation-plugin:
|
|
|
512
512
|
no-matching-rules: Er is niets te valideren in dit document
|
|
513
513
|
see-related-node: Zie gerelateerde node
|
|
514
514
|
description: Sommige onderdelen zijn nodig om ons systeem toe te laten dit document te ontleden.
|
|
515
|
+
decision-node-not-found: Plaats de cursor in een besluit
|