@lblod/ember-rdfa-editor-lblod-plugins 38.0.2 → 38.0.3-dev.9ded4345c52e1bc6f22bb3fbae8dfd96c5d6e6be

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.
Files changed (27) hide show
  1. package/.changeset/early-carrots-smoke.md +5 -0
  2. package/.changeset/friendly-points-yell.md +5 -0
  3. package/.changeset/fuzzy-nails-knock.md +5 -0
  4. package/.changeset/kind-humans-allow.md +5 -0
  5. package/.changeset/lucky-chairs-complain.md +5 -0
  6. package/CHANGELOG.md +6 -0
  7. package/addon/components/snippet-plugin/nodes/placeholder.gts +4 -6
  8. package/addon/components/snippet-plugin/nodes/snippet.gts +34 -8
  9. package/addon/components/snippet-plugin/search-modal.gts +12 -6
  10. package/addon/components/snippet-plugin/snippet-insert-rdfa.gts +0 -2
  11. package/addon/plugins/snippet-plugin/commands/update-snippet-placeholder.ts +2 -11
  12. package/addon/plugins/snippet-plugin/index.ts +2 -1
  13. package/addon/plugins/snippet-plugin/nodes/snippet-placeholder.ts +0 -12
  14. package/addon/plugins/snippet-plugin/nodes/snippet.ts +1 -11
  15. package/addon/plugins/snippet-plugin/utils/fetch-data.ts +55 -16
  16. package/addon/plugins/variable-plugin/contextual-actions/index.ts +3 -3
  17. package/addon/services/snippet-fetch-service.ts +76 -0
  18. package/app/services/snippet-fetch-service.js +1 -0
  19. package/declarations/addon/components/snippet-plugin/nodes/placeholder.d.ts +1 -1
  20. package/declarations/addon/components/snippet-plugin/nodes/snippet.d.ts +7 -1
  21. package/declarations/addon/components/snippet-plugin/search-modal.d.ts +5 -2
  22. package/declarations/addon/plugins/snippet-plugin/index.d.ts +2 -1
  23. package/declarations/addon/plugins/snippet-plugin/nodes/snippet.d.ts +1 -1
  24. package/declarations/addon/plugins/snippet-plugin/utils/fetch-data.d.ts +9 -5
  25. package/declarations/addon/plugins/variable-plugin/contextual-actions/index.d.ts +1 -1
  26. package/declarations/addon/services/snippet-fetch-service.d.ts +20 -0
  27. package/package.json +1 -1
@@ -0,0 +1,5 @@
1
+ ---
2
+ '@lblod/ember-rdfa-editor-lblod-plugins': minor
3
+ ---
4
+
5
+ Cache snippets for insertion when not doing a text search
@@ -0,0 +1,5 @@
1
+ ---
2
+ '@lblod/ember-rdfa-editor-lblod-plugins': minor
3
+ ---
4
+
5
+ Query for snippet list names instead of storing names when inserting
@@ -0,0 +1,5 @@
1
+ ---
2
+ '@lblod/ember-rdfa-editor-lblod-plugins': minor
3
+ ---
4
+
5
+ No longer store snippet list names on snippet nodes. Passing this when creating snippets or placeholders is now deprecated.
@@ -0,0 +1,5 @@
1
+ ---
2
+ '@lblod/ember-rdfa-editor-lblod-plugins': minor
3
+ ---
4
+
5
+ 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
@@ -0,0 +1,5 @@
1
+ ---
2
+ '@lblod/ember-rdfa-editor-lblod-plugins': minor
3
+ ---
4
+
5
+ Cache snippet list names to avoid excess queries
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @lblod/ember-rdfa-editor-lblod-plugins
2
2
 
3
+ ## 38.0.3
4
+
5
+ ### Patch Changes
6
+
7
+ - [`448e7e3`](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/commit/448e7e324996d4422d2ba236bd3fba8970a8bb5d) Thanks [@abeforgit](https://github.com/abeforgit)! - Republish 38.0.2
8
+
3
9
  ## 38.0.2
4
10
 
5
11
  ### 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.listNames.length === 1;
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.listNames[0],
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 this.listNames as |listName|}}
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 { Snippet } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/snippet-plugin';
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: getSnippetListUrisFromNode(this.node),
135
- names: this.node.attrs.snippetListNames,
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: getSnippetListUrisFromNode(this.node),
206
- names: this.node.attrs.snippetListNames,
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.node.attrs.config}}
297
+ @config={{this.config}}
272
298
  @onInsert={{this.onInsert}}
273
- @snippetListUris={{getSnippetListUrisFromNode this.node}}
274
- @snippetListNames={{this.node.attrs.snippetListNames}}
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[] | undefined;
31
- snippetListNames: string[] | undefined;
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
- await timeout(500);
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 fetchSnippets({
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 { sayDataFactory } from '@lblod/ember-rdfa-editor/core/say-data-factory';
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: string[];
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 Filter = { name?: string; snippetListUris?: string[] };
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 }: Filter) => {
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 }: Filter) => {
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: 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: 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: 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
- (binding) =>
201
- new Snippet({
202
- title: binding.title?.value,
203
- createdOn: binding.createdOn?.value,
204
- content: binding.content?.value,
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: 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
+ };
@@ -51,11 +51,11 @@ function getSelectedLocation(state: EditorState) {
51
51
  }
52
52
  }
53
53
 
54
- function getSource(state: EditorState, fallback?: string) {
54
+ function getSource(state: EditorState, fallback: string) {
55
55
  const selectedLocation = getSelectedLocation(state);
56
56
  if (selectedLocation) {
57
57
  const { node } = selectedLocation;
58
- const source = node.attrs.source;
58
+ const source = node.attrs.source as string | undefined;
59
59
  if (source) {
60
60
  return source;
61
61
  }
@@ -92,7 +92,7 @@ function getIsZonal(state: EditorState) {
92
92
  type GetContextualActionsAttrs = {
93
93
  zonalLocationCodelistUri: string;
94
94
  nonZonalLocationCodelistUri: string;
95
- endpoint?: string;
95
+ endpoint: string;
96
96
  };
97
97
 
98
98
  function humanReadableLabel(label: string) {
@@ -0,0 +1,76 @@
1
+ import Service from '@ember/service';
2
+ import { tracked } from '@glimmer/tracking';
3
+ import {
4
+ fetchSnippetListNames,
5
+ fetchSnippets,
6
+ Pagination,
7
+ SnippetFilter,
8
+ } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/snippet-plugin/utils/fetch-data';
9
+ import {
10
+ Snippet,
11
+ SnippetPluginConfig,
12
+ } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/snippet-plugin';
13
+
14
+ export default class SnippetFetchService extends Service {
15
+ @tracked listNameCache = new Map<string, string>();
16
+ @tracked snippetPageCache = new Map<
17
+ string,
18
+ { totalCount: number; pages: Map<number, Snippet[]> }
19
+ >();
20
+
21
+ async getListNames(
22
+ config: SnippetPluginConfig,
23
+ listUris: string[],
24
+ ): Promise<string[]> {
25
+ if (listUris.every((uri) => this.listNameCache.has(uri))) {
26
+ return listUris.map((uri) => this.listNameCache.get(uri) as string);
27
+ }
28
+ const abortController = new AbortController();
29
+ const listNames = await fetchSnippetListNames({
30
+ endpoint: config.endpoint,
31
+ abortSignal: abortController.signal,
32
+ snippetListUris: listUris,
33
+ });
34
+ listNames.forEach((name, uri) => this.listNameCache.set(uri, name));
35
+
36
+ return [...listNames.values()];
37
+ }
38
+
39
+ async getSnippets({
40
+ endpoint,
41
+ abortSignal,
42
+ filter,
43
+ pagination,
44
+ }: {
45
+ endpoint: string;
46
+ abortSignal: AbortSignal;
47
+ filter: SnippetFilter;
48
+ pagination: Pagination;
49
+ }) {
50
+ if (filter.name || !filter.snippetListUris?.length) {
51
+ // Filtering, so just search, to avoid mess of re-implementing local filtering to match that
52
+ // of the server. Undefined or empty uri lists are ignored by the fetch function, so pass
53
+ // those through too.
54
+ return fetchSnippets({ endpoint, abortSignal, filter, pagination });
55
+ }
56
+ const cacheKey = filter.snippetListUris.join('---');
57
+ let cachedPages = this.snippetPageCache.get(cacheKey);
58
+ if (!cachedPages) {
59
+ cachedPages = { totalCount: -1, pages: new Map() };
60
+ this.snippetPageCache.set(cacheKey, cachedPages);
61
+ }
62
+ const cachedPage = cachedPages.pages.get(pagination.pageNumber);
63
+ if (!cachedPage) {
64
+ const fetched = await fetchSnippets({
65
+ endpoint,
66
+ abortSignal,
67
+ filter,
68
+ pagination,
69
+ });
70
+ cachedPages.totalCount = fetched.totalCount;
71
+ cachedPages.pages.set(pagination.pageNumber, fetched.results);
72
+ return fetched;
73
+ }
74
+ return { totalCount: cachedPages.totalCount, results: cachedPage };
75
+ }
76
+ }
@@ -0,0 +1 @@
1
+ export { default } from '@lblod/ember-rdfa-editor-lblod-plugins/services/snippet-fetch-service';
@@ -5,12 +5,12 @@ import { type SnippetPluginConfig } from '@lblod/ember-rdfa-editor-lblod-plugins
5
5
  interface Signature {
6
6
  Args: Pick<EmberNodeArgs, 'node' | 'selectNode'> & {
7
7
  insertSnippet: () => void;
8
+ snippetListNames: string[];
8
9
  };
9
10
  }
10
11
  export default class SnippetPluginPlaceholder extends Component<Signature> {
11
12
  intl: IntlService;
12
13
  get node(): import("prosemirror-model").Node;
13
- get listNames(): any;
14
14
  get config(): SnippetPluginConfig;
15
15
  get isSingleList(): boolean;
16
16
  get alertTitle(): string;
@@ -1,7 +1,8 @@
1
1
  import Component from '@glimmer/component';
2
2
  import { type EmberNodeArgs } from '@lblod/ember-rdfa-editor/utils/_private/ember-node';
3
3
  import { type PNode, type Selection, Slice } from '@lblod/ember-rdfa-editor';
4
- import { Snippet } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/snippet-plugin';
4
+ import { Snippet, SnippetPluginConfig } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/snippet-plugin';
5
+ import SnippetFetchService from '@lblod/ember-rdfa-editor-lblod-plugins/services/snippet-fetch-service';
5
6
  interface Signature {
6
7
  Args: EmberNodeArgs;
7
8
  Blocks: {
@@ -9,6 +10,7 @@ interface Signature {
9
10
  };
10
11
  }
11
12
  export default class SnippetNode extends Component<Signature> {
13
+ snippetFetchService: SnippetFetchService;
12
14
  showModal: boolean;
13
15
  mode: string;
14
16
  get controller(): import("@lblod/ember-rdfa-editor").SayController;
@@ -17,6 +19,8 @@ export default class SnippetNode extends Component<Signature> {
17
19
  get node(): PNode;
18
20
  get isPlaceholder(): boolean;
19
21
  get allowMultipleSnippets(): boolean;
22
+ get snippetListUris(): string[];
23
+ get config(): SnippetPluginConfig;
20
24
  closeModal(): void;
21
25
  openModal(): void;
22
26
  addFragment(): void;
@@ -27,5 +31,7 @@ export default class SnippetNode extends Component<Signature> {
27
31
  get isActive(): boolean;
28
32
  onInsert(snippet: Snippet): void;
29
33
  get class(): string;
34
+ loadedListNames: import("reactiveweb/function").State<Promise<string[]>>;
35
+ get snippetListNames(): string[];
30
36
  }
31
37
  export {};
@@ -1,14 +1,17 @@
1
1
  import Component from '@glimmer/component';
2
+ import { Option } from '@lblod/ember-rdfa-editor/utils/option';
2
3
  import { Snippet, SnippetPluginConfig } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/snippet-plugin';
4
+ import SnippetFetchService from '@lblod/ember-rdfa-editor-lblod-plugins/services/snippet-fetch-service';
3
5
  interface Args {
4
6
  config: SnippetPluginConfig;
5
- snippetListUris: string[] | undefined;
6
- snippetListNames: string[] | undefined;
7
+ snippetListUris: Option<string[]>;
8
+ snippetListNames: Option<string[]>;
7
9
  closeModal: () => void;
8
10
  open: boolean;
9
11
  onInsert: (snippet: Snippet) => void;
10
12
  }
11
13
  export default class SnippetPluginSearchModalComponent extends Component<Args> {
14
+ snippetFetchService: SnippetFetchService;
12
15
  inputSearchText: string | null;
13
16
  error: unknown;
14
17
  pageNumber: number;
@@ -21,7 +21,8 @@ export type ImportedResourceMap = Record<string, Option<string>>;
21
21
  export type SnippetListProperties = {
22
22
  placeholderId: string;
23
23
  listUris: string[];
24
- names: string[];
24
+ /** @deprecated Passing snippet list names is no longer necessary */
25
+ names?: string[];
25
26
  importedResources: ImportedResourceMap;
26
27
  };
27
28
  export type SnippetListArgs = {
@@ -14,7 +14,7 @@ interface CreateSnippetArgs {
14
14
  * @returns a tuple containing the Node and the map of imported resources to the new outgoing
15
15
  * properties that these resources will have after the snippet is inserted into the document.
16
16
  **/
17
- export declare function createSnippet({ schema, content, title, allowMultipleSnippets, listProperties: { listUris, names: snippetListNames, importedResources, placeholderId, }, }: CreateSnippetArgs): [PNode, Map<string, OutgoingTriple[]>];
17
+ export declare function createSnippet({ schema, content, title, allowMultipleSnippets, listProperties: { listUris, importedResources, placeholderId }, }: CreateSnippetArgs): [PNode, Map<string, OutgoingTriple[]>];
18
18
  export declare const snippet: (config: SnippetPluginConfig) => import("@lblod/ember-rdfa-editor/core/say-node-spec").default;
19
19
  export declare const snippetView: (config: SnippetPluginConfig) => (controller: import("@lblod/ember-rdfa-editor").SayController) => import("@lblod/ember-rdfa-editor/utils/ember-node").SayNodeViewConstructor;
20
20
  export {};
@@ -1,17 +1,17 @@
1
1
  import { Snippet, SnippetList } from '../index';
2
- type Filter = {
2
+ export type SnippetFilter = {
3
3
  name?: string;
4
4
  snippetListUris?: string[];
5
5
  };
6
6
  export type OrderBy = 'label' | 'created-on' | '-label' | '-created-on' | '' | null;
7
- type Pagination = {
7
+ export type Pagination = {
8
8
  pageNumber: number;
9
9
  pageSize: number;
10
10
  };
11
11
  export declare const fetchSnippets: ({ endpoint, abortSignal, filter, pagination, }: {
12
12
  endpoint: string;
13
13
  abortSignal: AbortSignal;
14
- filter: Filter;
14
+ filter: SnippetFilter;
15
15
  pagination: Pagination;
16
16
  }) => Promise<{
17
17
  totalCount: number;
@@ -20,9 +20,13 @@ export declare const fetchSnippets: ({ endpoint, abortSignal, filter, pagination
20
20
  export declare const fetchSnippetLists: ({ endpoint, abortSignal, filter, orderBy, }: {
21
21
  endpoint: string;
22
22
  abortSignal: AbortSignal;
23
- filter: Filter;
23
+ filter: SnippetFilter;
24
24
  orderBy: OrderBy;
25
25
  }) => Promise<{
26
26
  results: SnippetList[];
27
27
  }>;
28
- export {};
28
+ export declare const fetchSnippetListNames: ({ endpoint, abortSignal, snippetListUris, }: {
29
+ endpoint: string;
30
+ abortSignal: AbortSignal;
31
+ snippetListUris: string[];
32
+ }) => Promise<Map<string, string>>;
@@ -3,7 +3,7 @@ import { ContextualActionGroup } from '@lblod/ember-rdfa-editor/plugins/contextu
3
3
  type GetContextualActionsAttrs = {
4
4
  zonalLocationCodelistUri: string;
5
5
  nonZonalLocationCodelistUri: string;
6
- endpoint?: string;
6
+ endpoint: string;
7
7
  };
8
8
  export declare function getContextualActions(attrs: GetContextualActionsAttrs): (state: EditorState, searchQuery?: string) => Promise<{
9
9
  id: string;
@@ -0,0 +1,20 @@
1
+ import Service from '@ember/service';
2
+ import { Pagination, SnippetFilter } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/snippet-plugin/utils/fetch-data';
3
+ import { Snippet, SnippetPluginConfig } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/snippet-plugin';
4
+ export default class SnippetFetchService extends Service {
5
+ listNameCache: Map<string, string>;
6
+ snippetPageCache: Map<string, {
7
+ totalCount: number;
8
+ pages: Map<number, Snippet[]>;
9
+ }>;
10
+ getListNames(config: SnippetPluginConfig, listUris: string[]): Promise<string[]>;
11
+ getSnippets({ endpoint, abortSignal, filter, pagination, }: {
12
+ endpoint: string;
13
+ abortSignal: AbortSignal;
14
+ filter: SnippetFilter;
15
+ pagination: Pagination;
16
+ }): Promise<{
17
+ totalCount: number;
18
+ results: Snippet[];
19
+ }>;
20
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lblod/ember-rdfa-editor-lblod-plugins",
3
- "version": "38.0.2",
3
+ "version": "38.0.3-dev.9ded4345c52e1bc6f22bb3fbae8dfd96c5d6e6be",
4
4
  "description": "Ember addon providing lblod specific plugins for the ember-rdfa-editor",
5
5
  "keywords": [
6
6
  "ember-addon",