@lblod/ember-rdfa-editor-lblod-plugins 38.0.3 → 38.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 +27 -0
- package/addon/components/snippet-plugin/nodes/placeholder.gts +4 -6
- package/addon/components/snippet-plugin/nodes/snippet.gts +34 -8
- package/addon/components/snippet-plugin/search-modal.gts +12 -6
- package/addon/components/snippet-plugin/snippet-insert-rdfa.gts +0 -2
- package/addon/plugins/snippet-plugin/commands/update-snippet-placeholder.ts +2 -11
- package/addon/plugins/snippet-plugin/index.ts +2 -1
- package/addon/plugins/snippet-plugin/nodes/snippet-placeholder.ts +0 -12
- package/addon/plugins/snippet-plugin/nodes/snippet.ts +1 -11
- package/addon/plugins/snippet-plugin/utils/fetch-data.ts +55 -16
- package/addon/plugins/variable-plugin/contextual-actions/codelist.ts +132 -0
- package/addon/plugins/variable-plugin/contextual-actions/index.ts +6 -217
- package/addon/plugins/variable-plugin/contextual-actions/place-description.ts +222 -0
- package/addon/plugins/variable-plugin/utils/codelist-utils.ts +46 -25
- package/addon/services/snippet-fetch-service.ts +76 -0
- package/app/services/snippet-fetch-service.js +1 -0
- package/declarations/addon/components/snippet-plugin/nodes/placeholder.d.ts +1 -1
- package/declarations/addon/components/snippet-plugin/nodes/snippet.d.ts +7 -1
- package/declarations/addon/components/snippet-plugin/search-modal.d.ts +5 -2
- package/declarations/addon/plugins/location-plugin/node.d.ts +1 -1
- package/declarations/addon/plugins/locked-placeholder-plugin/nodes/block-locked-placeholder.d.ts +1 -1
- package/declarations/addon/plugins/locked-placeholder-plugin/nodes/inline-locked-placeholder.d.ts +1 -1
- package/declarations/addon/plugins/mandatee-table-plugin/node.d.ts +1 -1
- package/declarations/addon/plugins/snippet-plugin/index.d.ts +2 -1
- package/declarations/addon/plugins/snippet-plugin/nodes/snippet-placeholder.d.ts +1 -1
- package/declarations/addon/plugins/snippet-plugin/nodes/snippet.d.ts +2 -2
- package/declarations/addon/plugins/snippet-plugin/utils/fetch-data.d.ts +9 -5
- package/declarations/addon/plugins/structure-plugin/node.d.ts +2 -2
- package/declarations/addon/plugins/table-of-contents-plugin/nodes/table-of-contents.d.ts +1 -1
- package/declarations/addon/plugins/template-comments-plugin/node.d.ts +1 -1
- package/declarations/addon/plugins/variable-plugin/contextual-actions/codelist.d.ts +14 -0
- package/declarations/addon/plugins/variable-plugin/contextual-actions/index.d.ts +5 -15
- package/declarations/addon/plugins/variable-plugin/contextual-actions/place-description.d.ts +15 -0
- package/declarations/addon/plugins/variable-plugin/utils/codelist-utils.d.ts +3 -1
- package/declarations/addon/plugins/variable-plugin/variables/address.d.ts +1 -1
- package/declarations/addon/plugins/variable-plugin/variables/autofilled.d.ts +1 -1
- package/declarations/addon/plugins/variable-plugin/variables/codelist.d.ts +1 -1
- package/declarations/addon/plugins/variable-plugin/variables/date.d.ts +1 -1
- package/declarations/addon/plugins/variable-plugin/variables/legacy-codelist.d.ts +1 -1
- package/declarations/addon/plugins/variable-plugin/variables/location.d.ts +1 -1
- package/declarations/addon/plugins/variable-plugin/variables/number.d.ts +1 -1
- package/declarations/addon/plugins/variable-plugin/variables/person.d.ts +1 -1
- package/declarations/addon/plugins/variable-plugin/variables/text.d.ts +1 -1
- package/declarations/addon/services/snippet-fetch-service.d.ts +20 -0
- package/package.json +3 -3
- package/pnpm-workspace.yaml +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
# @lblod/ember-rdfa-editor-lblod-plugins
|
|
2
2
|
|
|
3
|
+
## 38.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#674](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/pull/674) [`9ded434`](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/commit/9ded4345c52e1bc6f22bb3fbae8dfd96c5d6e6be) Thanks [@piemonkey](https://github.com/piemonkey)! - Cache snippets for insertion when not doing a text search
|
|
8
|
+
|
|
9
|
+
- [#674](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/pull/674) [`13576c5`](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/commit/13576c5bd749b40bdc33d26c0b31c3a0a11b96b9) Thanks [@piemonkey](https://github.com/piemonkey)! - Query for snippet list names instead of storing names when inserting
|
|
10
|
+
|
|
11
|
+
- [#674](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/pull/674) [`b107980`](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/commit/b10798018e487503613fa3ba4473c91cde20dbef) Thanks [@piemonkey](https://github.com/piemonkey)! - No longer store snippet list names on snippet nodes. Passing this when creating snippets or placeholders is now deprecated.
|
|
12
|
+
|
|
13
|
+
- [#670](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/pull/670) [`530dafc`](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/commit/530dafcf0723bf7f06715633563ae73d19ec9f68) Thanks [@piemonkey](https://github.com/piemonkey)! - Make endpoint arg for location variable config required in the typescript type, which matches the documentation, and the reality of handling locations without a source attribute
|
|
14
|
+
|
|
15
|
+
- [#674](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/pull/674) [`f5e1c0d`](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/commit/f5e1c0dd13b2d3af6ca2f47ad8789247c2e94af4) Thanks [@piemonkey](https://github.com/piemonkey)! - Cache snippet list names to avoid excess queries
|
|
16
|
+
|
|
17
|
+
- [#673](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/pull/673) [`8913ca5`](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/commit/8913ca57dfa9e3ccfabdea405dc7cd38acfb1459) Thanks [@piemonkey](https://github.com/piemonkey)! - Add contextual actions for filling in codelist values. This introduces new contextual actions for
|
|
18
|
+
the variable-plugin, so the import for place description actions has moved to
|
|
19
|
+
`@lblod/ember-rdfa-editor-lblod-plugins/plugins/variable-plugin/contextual-actions/place-description`.
|
|
20
|
+
The old import location remains for backwards compatibility.
|
|
21
|
+
|
|
22
|
+
### Patch Changes
|
|
23
|
+
|
|
24
|
+
- [#673](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/pull/673) [`e2b9436`](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/commit/e2b943657850d63673457233a7aa34676fe42ad3) Thanks [@piemonkey](https://github.com/piemonkey)! - Fix bug in location description context actions where one cache was used for both zonal and non-zonal options
|
|
25
|
+
|
|
26
|
+
- [#673](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/pull/673) [`8a844bd`](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/commit/8a844bd88a2bc1786034136bb02c3d7891ef57ac) Thanks [@piemonkey](https://github.com/piemonkey)! - Keep context menu open after selecting codelist options
|
|
27
|
+
|
|
28
|
+
- [#673](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/pull/673) [`593e95e`](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/commit/593e95e4ae870719bc48cb14d3759d7f0f10041e) Thanks [@piemonkey](https://github.com/piemonkey)! - bump editor to [@lblod](https://github.com/lblod/ember-rdfa-editor/releases/tag/@lblod/ember-rdfa-editor@13.16.0)
|
|
29
|
+
|
|
3
30
|
## 38.0.3
|
|
4
31
|
|
|
5
32
|
### Patch Changes
|
|
@@ -13,6 +13,7 @@ import getClassnamesFromNode from '@lblod/ember-rdfa-editor/utils/get-classnames
|
|
|
13
13
|
interface Signature {
|
|
14
14
|
Args: Pick<EmberNodeArgs, 'node' | 'selectNode'> & {
|
|
15
15
|
insertSnippet: () => void;
|
|
16
|
+
snippetListNames: string[];
|
|
16
17
|
};
|
|
17
18
|
}
|
|
18
19
|
|
|
@@ -22,19 +23,16 @@ export default class SnippetPluginPlaceholder extends Component<Signature> {
|
|
|
22
23
|
get node() {
|
|
23
24
|
return this.args.node;
|
|
24
25
|
}
|
|
25
|
-
get listNames() {
|
|
26
|
-
return this.args.node.attrs.snippetListNames;
|
|
27
|
-
}
|
|
28
26
|
get config(): SnippetPluginConfig {
|
|
29
27
|
return this.node.attrs.config;
|
|
30
28
|
}
|
|
31
29
|
get isSingleList() {
|
|
32
|
-
return this.
|
|
30
|
+
return this.args.snippetListNames.length === 1;
|
|
33
31
|
}
|
|
34
32
|
get alertTitle() {
|
|
35
33
|
if (this.isSingleList) {
|
|
36
34
|
return this.intl.t('snippet-plugin.placeholder.title-single', {
|
|
37
|
-
listName: this.
|
|
35
|
+
listName: this.args.snippetListNames[0],
|
|
38
36
|
});
|
|
39
37
|
} else {
|
|
40
38
|
return this.intl.t('snippet-plugin.placeholder.title-multiple');
|
|
@@ -58,7 +56,7 @@ export default class SnippetPluginPlaceholder extends Component<Signature> {
|
|
|
58
56
|
<p class='say-snippet-placeholder__title'>{{this.alertTitle}}</p>
|
|
59
57
|
{{#unless this.isSingleList}}
|
|
60
58
|
<ul class='say-snippet-placeholder__list'>
|
|
61
|
-
{{#each
|
|
59
|
+
{{#each @snippetListNames as |listName|}}
|
|
62
60
|
<li>{{listName}}</li>
|
|
63
61
|
{{/each}}
|
|
64
62
|
</ul>
|
|
@@ -4,7 +4,9 @@ import SearchModal from '../search-modal';
|
|
|
4
4
|
import { tracked } from '@glimmer/tracking';
|
|
5
5
|
import { action } from '@ember/object';
|
|
6
6
|
import { TemplateOnlyComponent } from '@ember/component/template-only';
|
|
7
|
+
import { service } from '@ember/service';
|
|
7
8
|
import t from 'ember-intl/helpers/t';
|
|
9
|
+
import { trackedFunction } from 'reactiveweb/function';
|
|
8
10
|
import AuIcon, {
|
|
9
11
|
type AuIconSignature,
|
|
10
12
|
} from '@appuniversum/ember-appuniversum/components/au-icon';
|
|
@@ -33,8 +35,12 @@ import { createSnippetPlaceholder } from '@lblod/ember-rdfa-editor-lblod-plugins
|
|
|
33
35
|
import { hasDecendant } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/has-descendant';
|
|
34
36
|
import SnippetPlaceholder from '@lblod/ember-rdfa-editor-lblod-plugins/components/snippet-plugin/nodes/placeholder';
|
|
35
37
|
import { getSnippetListUrisFromNode } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/snippet-plugin/utils/rdfa-predicate';
|
|
36
|
-
import {
|
|
38
|
+
import {
|
|
39
|
+
Snippet,
|
|
40
|
+
SnippetPluginConfig,
|
|
41
|
+
} from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/snippet-plugin';
|
|
37
42
|
import getClassnamesFromNode from '@lblod/ember-rdfa-editor/utils/get-classnames-from-node';
|
|
43
|
+
import SnippetFetchService from '@lblod/ember-rdfa-editor-lblod-plugins/services/snippet-fetch-service';
|
|
38
44
|
|
|
39
45
|
interface ButtonSig {
|
|
40
46
|
Args: {
|
|
@@ -64,8 +70,11 @@ interface Signature {
|
|
|
64
70
|
}
|
|
65
71
|
|
|
66
72
|
export default class SnippetNode extends Component<Signature> {
|
|
73
|
+
@service declare snippetFetchService: SnippetFetchService;
|
|
74
|
+
|
|
67
75
|
@tracked showModal: boolean = false;
|
|
68
76
|
@tracked mode: string = '';
|
|
77
|
+
|
|
69
78
|
get controller() {
|
|
70
79
|
return this.args.controller;
|
|
71
80
|
}
|
|
@@ -87,6 +96,12 @@ export default class SnippetNode extends Component<Signature> {
|
|
|
87
96
|
get allowMultipleSnippets() {
|
|
88
97
|
return this.node.attrs.allowMultipleSnippets as boolean;
|
|
89
98
|
}
|
|
99
|
+
get snippetListUris() {
|
|
100
|
+
return getSnippetListUrisFromNode(this.node);
|
|
101
|
+
}
|
|
102
|
+
get config(): SnippetPluginConfig {
|
|
103
|
+
return this.node.attrs.config;
|
|
104
|
+
}
|
|
90
105
|
|
|
91
106
|
@action
|
|
92
107
|
closeModal() {
|
|
@@ -131,8 +146,8 @@ export default class SnippetNode extends Component<Signature> {
|
|
|
131
146
|
const node = createSnippetPlaceholder({
|
|
132
147
|
listProperties: {
|
|
133
148
|
placeholderId: this.node.attrs.placeholderId,
|
|
134
|
-
listUris:
|
|
135
|
-
names: this.
|
|
149
|
+
listUris: this.snippetListUris,
|
|
150
|
+
names: this.snippetListNames,
|
|
136
151
|
importedResources: this.node.attrs.importedResources,
|
|
137
152
|
},
|
|
138
153
|
schema: this.schema,
|
|
@@ -202,8 +217,8 @@ export default class SnippetNode extends Component<Signature> {
|
|
|
202
217
|
title: snippet.title ?? '',
|
|
203
218
|
listProperties: {
|
|
204
219
|
placeholderId: this.node.attrs.placeholderId,
|
|
205
|
-
listUris:
|
|
206
|
-
names: this.
|
|
220
|
+
listUris: this.snippetListUris,
|
|
221
|
+
names: this.snippetListNames,
|
|
207
222
|
importedResources: this.node.attrs.importedResources,
|
|
208
223
|
},
|
|
209
224
|
range: { start, end },
|
|
@@ -216,12 +231,23 @@ export default class SnippetNode extends Component<Signature> {
|
|
|
216
231
|
return getClassnamesFromNode(this.args.node);
|
|
217
232
|
}
|
|
218
233
|
|
|
234
|
+
loadedListNames = trackedFunction(this, async () => {
|
|
235
|
+
return this.snippetFetchService.getListNames(
|
|
236
|
+
this.config,
|
|
237
|
+
this.snippetListUris,
|
|
238
|
+
);
|
|
239
|
+
});
|
|
240
|
+
get snippetListNames() {
|
|
241
|
+
return this.loadedListNames.value ?? [];
|
|
242
|
+
}
|
|
243
|
+
|
|
219
244
|
<template>
|
|
220
245
|
{{#if this.isPlaceholder}}
|
|
221
246
|
<SnippetPlaceholder
|
|
222
247
|
@node={{@node}}
|
|
223
248
|
@selectNode={{@selectNode}}
|
|
224
249
|
@insertSnippet={{this.editFragment}}
|
|
250
|
+
@snippetListNames={{this.snippetListNames}}
|
|
225
251
|
/>
|
|
226
252
|
{{else}}
|
|
227
253
|
<div class='{{this.class}} say-snippet-card'>
|
|
@@ -268,10 +294,10 @@ export default class SnippetNode extends Component<Signature> {
|
|
|
268
294
|
<SearchModal
|
|
269
295
|
@open={{this.showModal}}
|
|
270
296
|
@closeModal={{this.closeModal}}
|
|
271
|
-
@config={{this.
|
|
297
|
+
@config={{this.config}}
|
|
272
298
|
@onInsert={{this.onInsert}}
|
|
273
|
-
@snippetListUris={{
|
|
274
|
-
@snippetListNames={{this.
|
|
299
|
+
@snippetListUris={{this.snippetListUris}}
|
|
300
|
+
@snippetListNames={{this.snippetListNames}}
|
|
275
301
|
/>
|
|
276
302
|
</template>
|
|
277
303
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import pagination from '@lblod/ember-rdfa-editor-lblod-plugins/helpers/pagination';
|
|
2
1
|
import Component from '@glimmer/component';
|
|
3
2
|
import { assert } from '@ember/debug';
|
|
4
3
|
import { action } from '@ember/object';
|
|
4
|
+
import { service } from '@ember/service';
|
|
5
5
|
import { restartableTask, timeout } from 'ember-concurrency';
|
|
6
6
|
import { task as trackedTask } from 'reactiveweb/ember-concurrency';
|
|
7
7
|
import { tracked } from '@glimmer/tracking';
|
|
@@ -13,10 +13,11 @@ import AuMainContainer from '@appuniversum/ember-appuniversum/components/au-main
|
|
|
13
13
|
import AuHeading from '@appuniversum/ember-appuniversum/components/au-heading';
|
|
14
14
|
import AuLabel from '@appuniversum/ember-appuniversum/components/au-label';
|
|
15
15
|
|
|
16
|
+
import { Option } from '@lblod/ember-rdfa-editor/utils/option';
|
|
17
|
+
import pagination from '@lblod/ember-rdfa-editor-lblod-plugins/helpers/pagination';
|
|
16
18
|
import AuNativeInput from '@lblod/ember-rdfa-editor-lblod-plugins/components/au-native-input';
|
|
17
19
|
import Loading from '@lblod/ember-rdfa-editor-lblod-plugins/components/common/search/loading';
|
|
18
20
|
import AlertLoadError from '@lblod/ember-rdfa-editor-lblod-plugins/components/common/search/alert-load-error';
|
|
19
|
-
import { fetchSnippets } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/snippet-plugin/utils/fetch-data';
|
|
20
21
|
import {
|
|
21
22
|
Snippet,
|
|
22
23
|
SnippetPluginConfig,
|
|
@@ -24,17 +25,20 @@ import {
|
|
|
24
25
|
import PreviewList from '@lblod/ember-rdfa-editor-lblod-plugins/components/common/documents/preview-list';
|
|
25
26
|
import AlertNoItems from '@lblod/ember-rdfa-editor-lblod-plugins/components/common/search/alert-no-items';
|
|
26
27
|
import PaginationView from '@lblod/ember-rdfa-editor-lblod-plugins/components/pagination/pagination-view';
|
|
28
|
+
import SnippetFetchService from '@lblod/ember-rdfa-editor-lblod-plugins/services/snippet-fetch-service';
|
|
27
29
|
|
|
28
30
|
interface Args {
|
|
29
31
|
config: SnippetPluginConfig;
|
|
30
|
-
snippetListUris: string[]
|
|
31
|
-
snippetListNames: string[]
|
|
32
|
+
snippetListUris: Option<string[]>;
|
|
33
|
+
snippetListNames: Option<string[]>;
|
|
32
34
|
closeModal: () => void;
|
|
33
35
|
open: boolean;
|
|
34
36
|
onInsert: (snippet: Snippet) => void;
|
|
35
37
|
}
|
|
36
38
|
|
|
37
39
|
export default class SnippetPluginSearchModalComponent extends Component<Args> {
|
|
40
|
+
@service declare snippetFetchService: SnippetFetchService;
|
|
41
|
+
|
|
38
42
|
// Filtering
|
|
39
43
|
@tracked inputSearchText: string | null = null;
|
|
40
44
|
|
|
@@ -75,12 +79,14 @@ export default class SnippetPluginSearchModalComponent extends Component<Args> {
|
|
|
75
79
|
}
|
|
76
80
|
|
|
77
81
|
snippetsSearch = restartableTask(async () => {
|
|
78
|
-
|
|
82
|
+
if (this.searchText) {
|
|
83
|
+
await timeout(500);
|
|
84
|
+
}
|
|
79
85
|
|
|
80
86
|
const abortController = new AbortController();
|
|
81
87
|
|
|
82
88
|
try {
|
|
83
|
-
const queryResult = await
|
|
89
|
+
const queryResult = await this.snippetFetchService.getSnippets({
|
|
84
90
|
endpoint: this.args.config.endpoint,
|
|
85
91
|
abortSignal: abortController.signal,
|
|
86
92
|
filter: {
|
|
@@ -28,7 +28,6 @@ export default class SnippetInsertRdfaComponent extends Component<Sig> {
|
|
|
28
28
|
return {
|
|
29
29
|
listUris,
|
|
30
30
|
placeholderId: activeNode.attrs.placeholderId,
|
|
31
|
-
names: activeNode.attrs.snippetListNames,
|
|
32
31
|
importedResources: activeNode.attrs.importedResources,
|
|
33
32
|
};
|
|
34
33
|
}
|
|
@@ -50,7 +49,6 @@ export default class SnippetInsertRdfaComponent extends Component<Sig> {
|
|
|
50
49
|
return {
|
|
51
50
|
listUris,
|
|
52
51
|
placeholderId: parentNode.node.attrs.placeholderId,
|
|
53
|
-
names: parentNode.node.attrs.snippetListNames,
|
|
54
52
|
importedResources: parentNode.node.attrs.importedResources,
|
|
55
53
|
};
|
|
56
54
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Command } from '@lblod/ember-rdfa-editor';
|
|
2
2
|
import { addProperty, removeProperty } from '@lblod/ember-rdfa-editor/commands';
|
|
3
|
-
import {
|
|
4
|
-
import { SNIPPET_LIST_RDFA_PREDICATE } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/snippet-plugin/utils/rdfa-predicate';
|
|
3
|
+
import { tripleForSnippetListUri } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/snippet-plugin/utils/rdfa-predicate';
|
|
5
4
|
import { type OutgoingTriple } from '@lblod/ember-rdfa-editor/core/rdfa-processor';
|
|
6
5
|
import { type ResolvedPNode } from '@lblod/ember-rdfa-editor/utils/_private/types';
|
|
7
6
|
import {
|
|
@@ -47,20 +46,12 @@ export const updateSnippetPlaceholder = ({
|
|
|
47
46
|
|
|
48
47
|
addProperty({
|
|
49
48
|
resource,
|
|
50
|
-
property:
|
|
51
|
-
predicate: SNIPPET_LIST_RDFA_PREDICATE.prefixed,
|
|
52
|
-
object: sayDataFactory.namedNode(list.uri),
|
|
53
|
-
},
|
|
49
|
+
property: tripleForSnippetListUri(list.uri),
|
|
54
50
|
transaction,
|
|
55
51
|
})(newState, (newTransaction) => {
|
|
56
52
|
transaction = newTransaction;
|
|
57
53
|
});
|
|
58
54
|
});
|
|
59
|
-
transaction = transaction.setNodeAttribute(
|
|
60
|
-
node.pos,
|
|
61
|
-
'snippetListNames',
|
|
62
|
-
newSnippetLists.map((list) => list.label),
|
|
63
|
-
);
|
|
64
55
|
transaction = transaction.setNodeAttribute(
|
|
65
56
|
node.pos,
|
|
66
57
|
'importedResources',
|
|
@@ -33,7 +33,8 @@ export type ImportedResourceMap = Record<string, Option<string>>;
|
|
|
33
33
|
export type SnippetListProperties = {
|
|
34
34
|
placeholderId: string;
|
|
35
35
|
listUris: string[];
|
|
36
|
-
names
|
|
36
|
+
/** @deprecated Passing snippet list names is no longer necessary */
|
|
37
|
+
names?: string[];
|
|
37
38
|
importedResources: ImportedResourceMap;
|
|
38
39
|
};
|
|
39
40
|
|
|
@@ -81,7 +81,6 @@ export function createSnippetPlaceholder({
|
|
|
81
81
|
return schema.nodes.snippet_placeholder.create({
|
|
82
82
|
rdfaNodeType: 'resource',
|
|
83
83
|
placeholderId: listProps.placeholderId,
|
|
84
|
-
snippetListNames: listProps.names,
|
|
85
84
|
subject: mappingResource,
|
|
86
85
|
properties: [
|
|
87
86
|
{
|
|
@@ -106,7 +105,6 @@ const emberNodeConfig = (config: SnippetPluginConfig): EmberNodeConfig => ({
|
|
|
106
105
|
...rdfaAttrSpec({ rdfaAware: true }),
|
|
107
106
|
typeof: { default: EXT('SnippetPlaceholder') },
|
|
108
107
|
placeholderId: { default: '' },
|
|
109
|
-
snippetListNames: { default: [] },
|
|
110
108
|
importedResources: { default: {} },
|
|
111
109
|
allowMultipleSnippets: { default: false },
|
|
112
110
|
config: {
|
|
@@ -117,13 +115,11 @@ const emberNodeConfig = (config: SnippetPluginConfig): EmberNodeConfig => ({
|
|
|
117
115
|
classNames: ['say-snippet'],
|
|
118
116
|
serialize(node, editorState) {
|
|
119
117
|
const t = getTranslationFunction(editorState);
|
|
120
|
-
const listNames = node.attrs.snippetListNames as string[];
|
|
121
118
|
return renderRdfaAware({
|
|
122
119
|
renderable: node,
|
|
123
120
|
tag: 'div',
|
|
124
121
|
attrs: {
|
|
125
122
|
class: `${getClassnamesFromNode(node)} say-snippet-placeholder`,
|
|
126
|
-
'data-list-names': listNames && JSON.stringify(listNames),
|
|
127
123
|
'data-imported-resources': JSON.stringify(node.attrs.importedResources),
|
|
128
124
|
'data-allow-multiple-snippets': node.attrs.allowMultipleSnippets,
|
|
129
125
|
},
|
|
@@ -149,20 +145,12 @@ const emberNodeConfig = (config: SnippetPluginConfig): EmberNodeConfig => ({
|
|
|
149
145
|
EXT('SnippetPlaceholder'),
|
|
150
146
|
)
|
|
151
147
|
) {
|
|
152
|
-
let snippetListNames = jsonParse(
|
|
153
|
-
node.getAttribute('data-list-names'),
|
|
154
|
-
);
|
|
155
|
-
if (!snippetListNames) {
|
|
156
|
-
// We might have an older version which is comma separated
|
|
157
|
-
snippetListNames = node.getAttribute('data-list-names')?.split(',');
|
|
158
|
-
}
|
|
159
148
|
return {
|
|
160
149
|
...rdfaAttrs,
|
|
161
150
|
// Generate a placeholderId any time we deserialise, this way we don't need to handle
|
|
162
151
|
// generating new ids whenever we re-use parts of a document (e.g. copy-paste or
|
|
163
152
|
// placeholders inside snippets)
|
|
164
153
|
placeholderId: uuidv4(),
|
|
165
|
-
snippetListNames,
|
|
166
154
|
importedResources: jsonParse(
|
|
167
155
|
node.getAttribute('data-imported-resources'),
|
|
168
156
|
),
|
|
@@ -84,12 +84,7 @@ export function createSnippet({
|
|
|
84
84
|
content,
|
|
85
85
|
title,
|
|
86
86
|
allowMultipleSnippets,
|
|
87
|
-
listProperties: {
|
|
88
|
-
listUris,
|
|
89
|
-
names: snippetListNames,
|
|
90
|
-
importedResources,
|
|
91
|
-
placeholderId,
|
|
92
|
-
},
|
|
87
|
+
listProperties: { listUris, importedResources, placeholderId },
|
|
93
88
|
}: CreateSnippetArgs): [PNode, Map<string, OutgoingTriple[]>] {
|
|
94
89
|
// Replace instances of linked to uris with the resources that exist in the outer document.
|
|
95
90
|
let replacedContent = content;
|
|
@@ -116,7 +111,6 @@ export function createSnippet({
|
|
|
116
111
|
{
|
|
117
112
|
placeholderId,
|
|
118
113
|
properties,
|
|
119
|
-
snippetListNames,
|
|
120
114
|
title,
|
|
121
115
|
subject: `http://data.lblod.info/snippets/${uuidv4()}`,
|
|
122
116
|
importedResources,
|
|
@@ -169,7 +163,6 @@ const emberNodeConfig = (options: SnippetPluginConfig): EmberNodeConfig => ({
|
|
|
169
163
|
},
|
|
170
164
|
rdfaNodeType: { default: 'resource' },
|
|
171
165
|
placeholderId: { default: '' },
|
|
172
|
-
snippetListNames: { default: [] },
|
|
173
166
|
importedResources: { default: {} },
|
|
174
167
|
title: { default: '' },
|
|
175
168
|
config: { default: options },
|
|
@@ -180,13 +173,11 @@ const emberNodeConfig = (options: SnippetPluginConfig): EmberNodeConfig => ({
|
|
|
180
173
|
content: options.allowedContent || DEFAULT_CONTENT_STRING,
|
|
181
174
|
classNames: ['say-snippet'],
|
|
182
175
|
serialize(node) {
|
|
183
|
-
const listNames = node.attrs.snippetListNames as string[];
|
|
184
176
|
return renderRdfaAware({
|
|
185
177
|
renderable: node,
|
|
186
178
|
tag: 'div',
|
|
187
179
|
attrs: {
|
|
188
180
|
'data-snippet-placeholder-id': node.attrs.placeholderId,
|
|
189
|
-
'data-list-names': listNames && JSON.stringify(listNames),
|
|
190
181
|
'data-imported-resources': JSON.stringify(node.attrs.importedResources),
|
|
191
182
|
'data-snippet-title': node.attrs.title,
|
|
192
183
|
'data-allow-multiple-snippets': node.attrs.allowMultipleSnippets,
|
|
@@ -225,7 +216,6 @@ const emberNodeConfig = (options: SnippetPluginConfig): EmberNodeConfig => ({
|
|
|
225
216
|
...rdfaAttrs,
|
|
226
217
|
properties,
|
|
227
218
|
placeholderId,
|
|
228
|
-
snippetListNames: jsonParse(node.getAttribute('data-list-names')),
|
|
229
219
|
importedResources: jsonParse(
|
|
230
220
|
node.getAttribute('data-imported-resources'),
|
|
231
221
|
),
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from '@lblod/ember-rdfa-editor-lblod-plugins/utils/sparql-helpers';
|
|
8
8
|
import { Snippet, SnippetList, SnippetListArgs } from '../index';
|
|
9
9
|
|
|
10
|
-
type
|
|
10
|
+
export type SnippetFilter = { name?: string; snippetListUris?: string[] };
|
|
11
11
|
export type OrderBy =
|
|
12
12
|
| 'label'
|
|
13
13
|
| 'created-on'
|
|
@@ -15,9 +15,9 @@ export type OrderBy =
|
|
|
15
15
|
| '-created-on'
|
|
16
16
|
| ''
|
|
17
17
|
| null;
|
|
18
|
-
type Pagination = { pageNumber: number; pageSize: number };
|
|
18
|
+
export type Pagination = { pageNumber: number; pageSize: number };
|
|
19
19
|
|
|
20
|
-
const buildSnippetCountQuery = ({ name, snippetListUris }:
|
|
20
|
+
const buildSnippetCountQuery = ({ name, snippetListUris }: SnippetFilter) => {
|
|
21
21
|
return /* sparql */ `
|
|
22
22
|
PREFIX schema: <http://schema.org/>
|
|
23
23
|
PREFIX dct: <http://purl.org/dc/terms/>
|
|
@@ -52,7 +52,7 @@ const buildSnippetCountQuery = ({ name, snippetListUris }: Filter) => {
|
|
|
52
52
|
`;
|
|
53
53
|
};
|
|
54
54
|
|
|
55
|
-
// const buildSnippetListCountQuery = ({ name }:
|
|
55
|
+
// const buildSnippetListCountQuery = ({ name }: SnippetFilter) => {
|
|
56
56
|
// return `
|
|
57
57
|
// PREFIX ext: <http://mu.semte.ch/vocabularies/ext/>
|
|
58
58
|
// SELECT (COUNT(?snippetLists) AS ?count)
|
|
@@ -72,7 +72,7 @@ const buildSnippetFetchQuery = ({
|
|
|
72
72
|
filter: { name, snippetListUris },
|
|
73
73
|
pagination: { pageSize, pageNumber },
|
|
74
74
|
}: {
|
|
75
|
-
filter:
|
|
75
|
+
filter: SnippetFilter;
|
|
76
76
|
pagination: Pagination;
|
|
77
77
|
}) => {
|
|
78
78
|
return /* sparql */ `
|
|
@@ -138,7 +138,7 @@ const buildSnippetListFetchQuery = ({
|
|
|
138
138
|
filter: { name },
|
|
139
139
|
orderBy,
|
|
140
140
|
}: {
|
|
141
|
-
filter:
|
|
141
|
+
filter: SnippetFilter;
|
|
142
142
|
orderBy: OrderBy;
|
|
143
143
|
}) => {
|
|
144
144
|
return /* sparql */ `
|
|
@@ -161,6 +161,21 @@ const buildSnippetListFetchQuery = ({
|
|
|
161
161
|
`;
|
|
162
162
|
};
|
|
163
163
|
|
|
164
|
+
const buildSnippetListNameFetchQuery = (snippetListUris: string[]) => {
|
|
165
|
+
return /* sparql */ `
|
|
166
|
+
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
|
|
167
|
+
PREFIX say: <https://say.data.gift/ns/>
|
|
168
|
+
|
|
169
|
+
SELECT DISTINCT ?snippetList ?snippetListName WHERE {
|
|
170
|
+
?snippetList a say:SnippetList;
|
|
171
|
+
skos:prefLabel ?snippetListName.
|
|
172
|
+
FILTER (?snippetList IN (${snippetListUris
|
|
173
|
+
.map(sparqlEscapeUri)
|
|
174
|
+
.join(', ')}))
|
|
175
|
+
}
|
|
176
|
+
`;
|
|
177
|
+
};
|
|
178
|
+
|
|
164
179
|
export const fetchSnippets = async ({
|
|
165
180
|
endpoint,
|
|
166
181
|
abortSignal,
|
|
@@ -169,7 +184,7 @@ export const fetchSnippets = async ({
|
|
|
169
184
|
}: {
|
|
170
185
|
endpoint: string;
|
|
171
186
|
abortSignal: AbortSignal;
|
|
172
|
-
filter:
|
|
187
|
+
filter: SnippetFilter;
|
|
173
188
|
pagination: Pagination;
|
|
174
189
|
}) => {
|
|
175
190
|
if (!filter.snippetListUris?.length) {
|
|
@@ -196,14 +211,13 @@ export const fetchSnippets = async ({
|
|
|
196
211
|
abortSignal,
|
|
197
212
|
});
|
|
198
213
|
|
|
199
|
-
const results = queryResult.results.bindings.map(
|
|
200
|
-
(
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
);
|
|
214
|
+
const results = queryResult.results.bindings.map((binding) => {
|
|
215
|
+
return new Snippet({
|
|
216
|
+
title: binding.title?.value,
|
|
217
|
+
createdOn: binding.createdOn?.value,
|
|
218
|
+
content: binding.content?.value,
|
|
219
|
+
});
|
|
220
|
+
});
|
|
207
221
|
|
|
208
222
|
return { totalCount, results };
|
|
209
223
|
};
|
|
@@ -216,7 +230,7 @@ export const fetchSnippetLists = async ({
|
|
|
216
230
|
}: {
|
|
217
231
|
endpoint: string;
|
|
218
232
|
abortSignal: AbortSignal;
|
|
219
|
-
filter:
|
|
233
|
+
filter: SnippetFilter;
|
|
220
234
|
orderBy: OrderBy;
|
|
221
235
|
}) => {
|
|
222
236
|
// We don't currently use this count, so skip the query, but we'll need it if we make pagination
|
|
@@ -263,3 +277,28 @@ export const fetchSnippetLists = async ({
|
|
|
263
277
|
|
|
264
278
|
return { results };
|
|
265
279
|
};
|
|
280
|
+
|
|
281
|
+
export const fetchSnippetListNames = async ({
|
|
282
|
+
endpoint,
|
|
283
|
+
abortSignal,
|
|
284
|
+
snippetListUris,
|
|
285
|
+
}: {
|
|
286
|
+
endpoint: string;
|
|
287
|
+
abortSignal: AbortSignal;
|
|
288
|
+
snippetListUris: string[];
|
|
289
|
+
}) => {
|
|
290
|
+
const queryResult = await executeQuery<
|
|
291
|
+
BindingObject<{ snippetList: string; snippetListName: string }>
|
|
292
|
+
>({
|
|
293
|
+
endpoint,
|
|
294
|
+
query: buildSnippetListNameFetchQuery(snippetListUris),
|
|
295
|
+
abortSignal,
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
return new Map(
|
|
299
|
+
queryResult.results.bindings.map((binding) => [
|
|
300
|
+
binding.snippetList.value,
|
|
301
|
+
binding.snippetListName.value,
|
|
302
|
+
]),
|
|
303
|
+
);
|
|
304
|
+
};
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
2
|
+
import { EditorState } from '@lblod/ember-rdfa-editor';
|
|
3
|
+
import { getActiveEditableNode } from '@lblod/ember-rdfa-editor/plugins/editable-node';
|
|
4
|
+
import { isRdfaAttrs } from '@lblod/ember-rdfa-editor/core/rdfa-types';
|
|
5
|
+
import { ContextualActionGroup } from '@lblod/ember-rdfa-editor/plugins/contextual-actions';
|
|
6
|
+
import { ResolvedPNode } from '@lblod/ember-rdfa-editor/utils/_private/types';
|
|
7
|
+
import { getTranslationFunction } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/translation';
|
|
8
|
+
import { updateCodelistVariableCommand } from '../utils/codelist-utils';
|
|
9
|
+
import {
|
|
10
|
+
type CodeListOptions,
|
|
11
|
+
fetchCodeListOptions,
|
|
12
|
+
CodeListOption,
|
|
13
|
+
} from '../utils/fetch-data';
|
|
14
|
+
import { CodelistAttrs } from '../variables';
|
|
15
|
+
|
|
16
|
+
const codelistGroupId = 'codelist-db36f85d-edbf-45dc-85fc-9fb67649fe00';
|
|
17
|
+
|
|
18
|
+
const codelistOptionsCache: Map<string, CodeListOptions> = new Map();
|
|
19
|
+
|
|
20
|
+
function getSource(codelistAttrs: CodelistAttrs, fallback?: string) {
|
|
21
|
+
if (codelistAttrs) {
|
|
22
|
+
const source = codelistAttrs['source'];
|
|
23
|
+
if (source && source !== 'UNKNOWN') {
|
|
24
|
+
return source;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return fallback;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
type GetContextualActionsAttrs = {
|
|
31
|
+
endpoint?: string;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
function humanReadableLabel(label: string) {
|
|
35
|
+
return label.replace(/\$\{[^}]+\}/g, '…');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function getCodelistOptionsCached(
|
|
39
|
+
activeNode: ResolvedPNode,
|
|
40
|
+
{ endpoint }: GetContextualActionsAttrs,
|
|
41
|
+
) {
|
|
42
|
+
const codelistAttrs = activeNode.value.attrs as CodelistAttrs | undefined;
|
|
43
|
+
const source = codelistAttrs && getSource(codelistAttrs, endpoint);
|
|
44
|
+
const codelistUri = codelistAttrs?.codelist;
|
|
45
|
+
|
|
46
|
+
let result = codelistUri && codelistOptionsCache.get(codelistUri);
|
|
47
|
+
if (!result && codelistAttrs?.hardcodedOptionList) {
|
|
48
|
+
result = {
|
|
49
|
+
type: '',
|
|
50
|
+
options: codelistAttrs.hardcodedOptionList,
|
|
51
|
+
} as CodeListOptions;
|
|
52
|
+
}
|
|
53
|
+
if (!result && source && codelistUri) {
|
|
54
|
+
result = await fetchCodeListOptions(source, codelistUri);
|
|
55
|
+
codelistOptionsCache.set(codelistUri, result);
|
|
56
|
+
if (!result) {
|
|
57
|
+
console.warn(
|
|
58
|
+
`Failed to fetch codelist options for ${codelistUri} from ${source}`,
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return result || { type: '', options: [] };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function getContextualActions(attrs: GetContextualActionsAttrs) {
|
|
67
|
+
return async function (state: EditorState, searchQuery?: string) {
|
|
68
|
+
const activeNode = getActiveEditableNode(state);
|
|
69
|
+
if (!activeNode) return [];
|
|
70
|
+
const result = await getCodelistOptionsCached(activeNode, attrs);
|
|
71
|
+
const isMultiSelect = activeNode.value.attrs['selectionStyle'] === 'multi';
|
|
72
|
+
const selectedOptions: CodeListOption[] = [];
|
|
73
|
+
activeNode.value.content.forEach((contentNode) => {
|
|
74
|
+
selectedOptions.push({
|
|
75
|
+
uri: contentNode.attrs.subject,
|
|
76
|
+
label: contentNode.textContent,
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
return result.options
|
|
81
|
+
.filter(
|
|
82
|
+
(option) =>
|
|
83
|
+
!searchQuery ||
|
|
84
|
+
option.label.toLowerCase().includes(searchQuery.toLowerCase()),
|
|
85
|
+
)
|
|
86
|
+
.map((option) => {
|
|
87
|
+
const selected = selectedOptions.some(
|
|
88
|
+
(selOption) => selOption.uri === option.uri,
|
|
89
|
+
);
|
|
90
|
+
const newOptions = selected
|
|
91
|
+
? selectedOptions.filter((selOption) => selOption.uri !== option.uri)
|
|
92
|
+
: isMultiSelect
|
|
93
|
+
? [...selectedOptions, option]
|
|
94
|
+
: option;
|
|
95
|
+
return {
|
|
96
|
+
id: uuidv4(),
|
|
97
|
+
label: humanReadableLabel(option.label),
|
|
98
|
+
group: codelistGroupId,
|
|
99
|
+
command: updateCodelistVariableCommand(activeNode, newOptions),
|
|
100
|
+
selected,
|
|
101
|
+
};
|
|
102
|
+
});
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function contextualGroupIsVisible(state: EditorState) {
|
|
107
|
+
const activeNode = getActiveEditableNode(state);
|
|
108
|
+
const isCodelist =
|
|
109
|
+
activeNode &&
|
|
110
|
+
isRdfaAttrs(activeNode.value.attrs) &&
|
|
111
|
+
activeNode?.value.type.name === 'codelist';
|
|
112
|
+
|
|
113
|
+
return isCodelist;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function getCodelistActionGroups(attrs: GetContextualActionsAttrs) {
|
|
117
|
+
return function (state: EditorState): ContextualActionGroup[] {
|
|
118
|
+
return contextualGroupIsVisible(state)
|
|
119
|
+
? [
|
|
120
|
+
{
|
|
121
|
+
id: codelistGroupId,
|
|
122
|
+
label: getTranslationFunction(state)(
|
|
123
|
+
'variable.codelist.label',
|
|
124
|
+
'Codelijst',
|
|
125
|
+
),
|
|
126
|
+
keepOpen: true,
|
|
127
|
+
getActions: getContextualActions(attrs),
|
|
128
|
+
},
|
|
129
|
+
]
|
|
130
|
+
: [];
|
|
131
|
+
};
|
|
132
|
+
}
|