@lblod/ember-rdfa-editor-lblod-plugins 38.1.0 → 38.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.woodpecker/.changeset.yml +1 -1
- package/.woodpecker/.release-commit.yml +4 -2
- package/.woodpecker/.release.yml +3 -1
- package/.woodpecker/.verify-pr.yml +10 -6
- package/CHANGELOG.md +14 -0
- package/README.md +1 -1
- package/RELEASE.md +2 -2
- package/addon/components/common/search/alert-load-error.gts +15 -2
- package/addon/components/snippet-plugin/nodes/placeholder.gts +27 -11
- package/addon/components/snippet-plugin/nodes/snippet.gts +7 -8
- package/addon/components/snippet-plugin/search-modal.gts +129 -111
- package/addon/components/snippet-plugin/snippet-insert.gts +17 -1
- package/addon/plugins/document-title-plugin/nodes/document-title.ts +1 -1
- package/addon/plugins/snippet-plugin/nodes/snippet-placeholder.ts +0 -1
- package/addon/plugins/table-of-contents-plugin/utils/index.ts +1 -4
- package/addon/utils/types.ts +4 -0
- package/declarations/addon/components/snippet-plugin/nodes/placeholder.d.ts +2 -1
- package/declarations/addon/components/snippet-plugin/nodes/snippet.d.ts +1 -2
- package/declarations/addon/components/snippet-plugin/search-modal.d.ts +5 -11
- package/declarations/addon/components/snippet-plugin/snippet-insert.d.ts +3 -0
- package/declarations/addon/utils/types.d.ts +3 -0
- package/package.json +4 -4
- package/pnpm-workspace.yaml +3 -0
- package/translations/en-US.yaml +2 -0
- package/translations/nl-BE.yaml +2 -0
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
steps:
|
|
2
2
|
install:
|
|
3
|
-
image: node:
|
|
3
|
+
image: node:22-slim
|
|
4
4
|
commands:
|
|
5
|
+
- npm config set ignore-scripts true
|
|
6
|
+
- npm i -g corepack@0.35
|
|
5
7
|
- corepack enable
|
|
6
8
|
- pnpm i --frozen-lockfile
|
|
7
9
|
version:
|
|
8
|
-
image: node:
|
|
10
|
+
image: node:22-slim
|
|
9
11
|
commands:
|
|
10
12
|
- npm version --no-git-tag-version $(npm pkg get version | sed 's/"//g')-dev.${CI_COMMIT_SHA}
|
|
11
13
|
release:
|
package/.woodpecker/.release.yml
CHANGED
|
@@ -1,34 +1,38 @@
|
|
|
1
1
|
steps:
|
|
2
2
|
install:
|
|
3
|
-
image: node:
|
|
3
|
+
image: node:22-slim
|
|
4
4
|
commands:
|
|
5
|
+
- npm config set ignore-scripts true
|
|
6
|
+
- npm i -g corepack@0.35
|
|
5
7
|
- corepack enable
|
|
6
8
|
- pnpm i --frozen-lockfile
|
|
7
9
|
lint-js:
|
|
8
|
-
image: node:
|
|
10
|
+
image: node:22-slim
|
|
9
11
|
group: lint
|
|
10
12
|
commands:
|
|
11
13
|
- corepack enable
|
|
12
14
|
- pnpm lint:js
|
|
13
15
|
lint-hbs:
|
|
14
|
-
image: node:
|
|
16
|
+
image: node:22-slim
|
|
15
17
|
group: lint
|
|
16
18
|
commands:
|
|
17
19
|
- corepack enable
|
|
18
20
|
- pnpm lint:hbs
|
|
19
21
|
lint-prettier:
|
|
20
|
-
image: node:
|
|
22
|
+
image: node:22-slim
|
|
21
23
|
group: lint
|
|
22
24
|
commands:
|
|
23
25
|
- corepack enable
|
|
24
26
|
- pnpm lint:prettier
|
|
25
27
|
test:
|
|
26
|
-
image: danlynn/ember-cli:
|
|
28
|
+
image: danlynn/ember-cli:6.7.2-node_22.19
|
|
27
29
|
commands:
|
|
30
|
+
- npm config set ignore-scripts true
|
|
31
|
+
- npm i -g corepack@0.35
|
|
28
32
|
- corepack enable
|
|
29
33
|
- pnpm test:ember
|
|
30
34
|
precompile:
|
|
31
|
-
image: node:
|
|
35
|
+
image: node:22-slim
|
|
32
36
|
commands:
|
|
33
37
|
- corepack enable
|
|
34
38
|
- pnpm prepack
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @lblod/ember-rdfa-editor-lblod-plugins
|
|
2
2
|
|
|
3
|
+
## 38.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#677](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/pull/677) [`024bc21`](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/commit/024bc215bbe2eec144c6742a932680581799bb2a) Thanks [@piemonkey](https://github.com/piemonkey)! - Add loading feedback and error messages for snippet name loading
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- [#675](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/pull/675) [`e05f335`](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/commit/e05f3357b9e61f80a94c78cef18d3bd5030c07bc) Thanks [@piemonkey](https://github.com/piemonkey)! - Expand peer-dep versions of ember-concurrency and ember-appuniversum based on versions already used in template-builder app
|
|
12
|
+
|
|
13
|
+
- [#675](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/pull/675) [`4a9e617`](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/commit/4a9e617f2335f3f83016147ce8bff0a82ef62fe4) Thanks [@piemonkey](https://github.com/piemonkey)! - Fix bug with document title which caused crashes with some usage
|
|
14
|
+
|
|
15
|
+
- [#671](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/pull/671) [`770fa4e`](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/commit/770fa4e08e1b6cc41b4b4a0bc954005fe513dde7) Thanks [@piemonkey](https://github.com/piemonkey)! - Use node v22 for build process and pnpm v11.10
|
|
16
|
+
|
|
3
17
|
## 38.1.0
|
|
4
18
|
|
|
5
19
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ related to the LBLOD Project.
|
|
|
9
9
|
4.12 is no longer tested and not officially supported, but should still work for now.
|
|
10
10
|
|
|
11
11
|
- Embroider or ember-auto-import v2
|
|
12
|
-
- Node 18 or above (
|
|
12
|
+
- Node 18 or above (22+ recommended)
|
|
13
13
|
|
|
14
14
|
## Installation
|
|
15
15
|
|
package/RELEASE.md
CHANGED
|
@@ -31,7 +31,7 @@ Once the prep work is completed, the actual release is straight forward:
|
|
|
31
31
|
* First, ensure that you have installed your projects dependencies:
|
|
32
32
|
|
|
33
33
|
```sh
|
|
34
|
-
|
|
34
|
+
pnpm install
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
* Second, ensure that you have obtained a
|
|
@@ -50,7 +50,7 @@ npm install
|
|
|
50
50
|
* And last (but not least 😁) do your release.
|
|
51
51
|
|
|
52
52
|
```sh
|
|
53
|
-
|
|
53
|
+
pnpm release
|
|
54
54
|
```
|
|
55
55
|
|
|
56
56
|
[release-it](https://github.com/release-it/release-it/) manages the actual
|
|
@@ -7,6 +7,20 @@ import AuLinkExternal from '@appuniversum/ember-appuniversum/components/au-link-
|
|
|
7
7
|
import { AlertTriangleIcon } from '@appuniversum/ember-appuniversum/components/icons/alert-triangle';
|
|
8
8
|
import { MailIcon } from '@appuniversum/ember-appuniversum/components/icons/mail';
|
|
9
9
|
|
|
10
|
+
function errorMessage(err: unknown): string {
|
|
11
|
+
if (!err) return 'Error';
|
|
12
|
+
if (typeof err !== 'object') return JSON.stringify(err);
|
|
13
|
+
return (
|
|
14
|
+
('message' in err && (err?.message as string)) ||
|
|
15
|
+
// getPromiseState includes the original error, so try to use that to avoid their generic error
|
|
16
|
+
('original' in err && (err?.original as Error | undefined)?.message) ||
|
|
17
|
+
// getPromiseState 'Error's use 'reason' in place of 'message' for some reason
|
|
18
|
+
('reason' in err && (err?.reason as string)) ||
|
|
19
|
+
err?.toString?.() ||
|
|
20
|
+
'Error'
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
10
24
|
interface Sig {
|
|
11
25
|
Args: {
|
|
12
26
|
error: unknown;
|
|
@@ -26,8 +40,7 @@ const AlertLoadError: TemplateOnlyComponent<Sig> = <template>
|
|
|
26
40
|
...attributes
|
|
27
41
|
>
|
|
28
42
|
<p>{{t 'common.search.error-intro'}}</p>
|
|
29
|
-
|
|
30
|
-
<code class='au-u-error error-code'>{{@error}}</code>
|
|
43
|
+
<code class='au-u-error error-code'>{{errorMessage @error}}</code>
|
|
31
44
|
<p>
|
|
32
45
|
{{t 'common.search.error-outro'}}
|
|
33
46
|
<AuLinkExternal
|
|
@@ -3,9 +3,11 @@ import { service } from '@ember/service';
|
|
|
3
3
|
import { on } from '@ember/modifier';
|
|
4
4
|
import IntlService from 'ember-intl/services/intl';
|
|
5
5
|
import t from 'ember-intl/helpers/t';
|
|
6
|
+
import { State } from 'reactiveweb/get-promise-state';
|
|
6
7
|
import { PlusTextIcon } from '@appuniversum/ember-appuniversum/components/icons/plus-text';
|
|
7
8
|
import AuIcon from '@appuniversum/ember-appuniversum/components/au-icon';
|
|
8
9
|
import AuButton from '@appuniversum/ember-appuniversum/components/au-button';
|
|
10
|
+
import AuLoader from '@appuniversum/ember-appuniversum/components/au-loader';
|
|
9
11
|
import { type EmberNodeArgs } from '@lblod/ember-rdfa-editor/utils/_private/ember-node';
|
|
10
12
|
import { type SnippetPluginConfig } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/snippet-plugin';
|
|
11
13
|
import getClassnamesFromNode from '@lblod/ember-rdfa-editor/utils/get-classnames-from-node';
|
|
@@ -13,7 +15,7 @@ import getClassnamesFromNode from '@lblod/ember-rdfa-editor/utils/get-classnames
|
|
|
13
15
|
interface Signature {
|
|
14
16
|
Args: Pick<EmberNodeArgs, 'node' | 'selectNode'> & {
|
|
15
17
|
insertSnippet: () => void;
|
|
16
|
-
snippetListNames: string[]
|
|
18
|
+
snippetListNames: State<string[]>;
|
|
17
19
|
};
|
|
18
20
|
}
|
|
19
21
|
|
|
@@ -27,12 +29,12 @@ export default class SnippetPluginPlaceholder extends Component<Signature> {
|
|
|
27
29
|
return this.node.attrs.config;
|
|
28
30
|
}
|
|
29
31
|
get isSingleList() {
|
|
30
|
-
return this.args.snippetListNames.length === 1;
|
|
32
|
+
return this.args.snippetListNames.resolved?.length === 1;
|
|
31
33
|
}
|
|
32
34
|
get alertTitle() {
|
|
33
35
|
if (this.isSingleList) {
|
|
34
36
|
return this.intl.t('snippet-plugin.placeholder.title-single', {
|
|
35
|
-
listName: this.args.snippetListNames[0],
|
|
37
|
+
listName: this.args.snippetListNames.resolved?.[0],
|
|
36
38
|
});
|
|
37
39
|
} else {
|
|
38
40
|
return this.intl.t('snippet-plugin.placeholder.title-multiple');
|
|
@@ -53,18 +55,32 @@ export default class SnippetPluginPlaceholder extends Component<Signature> {
|
|
|
53
55
|
<AuIcon @icon={{PlusTextIcon}} />
|
|
54
56
|
</div>
|
|
55
57
|
<div class='say-snippet-placeholder__content'>
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
58
|
+
{{#if @snippetListNames.isLoading}}
|
|
59
|
+
<AuLoader @hideMessage={{true}}>
|
|
60
|
+
{{t 'common.search.loading'}}
|
|
61
|
+
</AuLoader>
|
|
62
|
+
{{else}}
|
|
63
|
+
{{#if @snippetListNames.error}}
|
|
64
|
+
<p class='say-snippet-placeholder__title'>{{t
|
|
65
|
+
'snippet-plugin.snippet-list.name-error-message'
|
|
66
|
+
message=@snippetListNames.error.reason
|
|
67
|
+
}}</p>
|
|
68
|
+
{{else}}
|
|
69
|
+
<p class='say-snippet-placeholder__title'>{{this.alertTitle}}</p>
|
|
70
|
+
{{#unless this.isSingleList}}
|
|
71
|
+
<ul class='say-snippet-placeholder__list'>
|
|
72
|
+
{{#each @snippetListNames.resolved as |listName|}}
|
|
73
|
+
<li>{{listName}}</li>
|
|
74
|
+
{{/each}}
|
|
75
|
+
</ul>
|
|
76
|
+
{{/unless}}
|
|
77
|
+
{{/if}}
|
|
78
|
+
{{/if}}
|
|
64
79
|
{{#unless this.config.hidePlaceholderInsertButton}}
|
|
65
80
|
<AuButton
|
|
66
81
|
@skin='link'
|
|
67
82
|
class='say-snippet-placeholder__button'
|
|
83
|
+
@disabled={{@snippetListNames.isLoading}}
|
|
68
84
|
{{on 'click' @insertSnippet}}
|
|
69
85
|
>
|
|
70
86
|
{{t 'snippet-plugin.placeholder.button'}}
|
|
@@ -7,6 +7,7 @@ import { TemplateOnlyComponent } from '@ember/component/template-only';
|
|
|
7
7
|
import { service } from '@ember/service';
|
|
8
8
|
import t from 'ember-intl/helpers/t';
|
|
9
9
|
import { trackedFunction } from 'reactiveweb/function';
|
|
10
|
+
import { getPromiseState } from 'reactiveweb/get-promise-state';
|
|
10
11
|
import AuIcon, {
|
|
11
12
|
type AuIconSignature,
|
|
12
13
|
} from '@appuniversum/ember-appuniversum/components/au-icon';
|
|
@@ -110,6 +111,9 @@ export default class SnippetNode extends Component<Signature> {
|
|
|
110
111
|
openModal() {
|
|
111
112
|
this.controller.focus();
|
|
112
113
|
this.showModal = true;
|
|
114
|
+
if (this.snippetListNames.error) {
|
|
115
|
+
this.snippetListNames.retry();
|
|
116
|
+
}
|
|
113
117
|
}
|
|
114
118
|
|
|
115
119
|
@action
|
|
@@ -147,7 +151,6 @@ export default class SnippetNode extends Component<Signature> {
|
|
|
147
151
|
listProperties: {
|
|
148
152
|
placeholderId: this.node.attrs.placeholderId,
|
|
149
153
|
listUris: this.snippetListUris,
|
|
150
|
-
names: this.snippetListNames,
|
|
151
154
|
importedResources: this.node.attrs.importedResources,
|
|
152
155
|
},
|
|
153
156
|
schema: this.schema,
|
|
@@ -218,7 +221,6 @@ export default class SnippetNode extends Component<Signature> {
|
|
|
218
221
|
listProperties: {
|
|
219
222
|
placeholderId: this.node.attrs.placeholderId,
|
|
220
223
|
listUris: this.snippetListUris,
|
|
221
|
-
names: this.snippetListNames,
|
|
222
224
|
importedResources: this.node.attrs.importedResources,
|
|
223
225
|
},
|
|
224
226
|
range: { start, end },
|
|
@@ -231,15 +233,12 @@ export default class SnippetNode extends Component<Signature> {
|
|
|
231
233
|
return getClassnamesFromNode(this.args.node);
|
|
232
234
|
}
|
|
233
235
|
|
|
234
|
-
|
|
236
|
+
snippetListNames = trackedFunction(this, async () => {
|
|
235
237
|
return this.snippetFetchService.getListNames(
|
|
236
238
|
this.config,
|
|
237
239
|
this.snippetListUris,
|
|
238
240
|
);
|
|
239
241
|
});
|
|
240
|
-
get snippetListNames() {
|
|
241
|
-
return this.loadedListNames.value ?? [];
|
|
242
|
-
}
|
|
243
242
|
|
|
244
243
|
<template>
|
|
245
244
|
{{#if this.isPlaceholder}}
|
|
@@ -247,7 +246,7 @@ export default class SnippetNode extends Component<Signature> {
|
|
|
247
246
|
@node={{@node}}
|
|
248
247
|
@selectNode={{@selectNode}}
|
|
249
248
|
@insertSnippet={{this.editFragment}}
|
|
250
|
-
@snippetListNames={{this.snippetListNames}}
|
|
249
|
+
@snippetListNames={{getPromiseState this.snippetListNames.promise}}
|
|
251
250
|
/>
|
|
252
251
|
{{else}}
|
|
253
252
|
<div class='{{this.class}} say-snippet-card'>
|
|
@@ -297,7 +296,7 @@ export default class SnippetNode extends Component<Signature> {
|
|
|
297
296
|
@config={{this.config}}
|
|
298
297
|
@onInsert={{this.onInsert}}
|
|
299
298
|
@snippetListUris={{this.snippetListUris}}
|
|
300
|
-
@snippetListNames={{this.snippetListNames}}
|
|
299
|
+
@snippetListNames={{getPromiseState this.snippetListNames.promise}}
|
|
301
300
|
/>
|
|
302
301
|
</template>
|
|
303
302
|
}
|
|
@@ -4,8 +4,10 @@ import { action } from '@ember/object';
|
|
|
4
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
|
+
import { State } from 'reactiveweb/get-promise-state';
|
|
7
8
|
import { tracked } from '@glimmer/tracking';
|
|
8
9
|
import { on } from '@ember/modifier';
|
|
10
|
+
import IntlService from 'ember-intl/services/intl';
|
|
9
11
|
import t from 'ember-intl/helpers/t';
|
|
10
12
|
import { not } from 'ember-truth-helpers';
|
|
11
13
|
import AuModal from '@appuniversum/ember-appuniversum/components/au-modal';
|
|
@@ -30,7 +32,7 @@ import SnippetFetchService from '@lblod/ember-rdfa-editor-lblod-plugins/services
|
|
|
30
32
|
interface Args {
|
|
31
33
|
config: SnippetPluginConfig;
|
|
32
34
|
snippetListUris: Option<string[]>;
|
|
33
|
-
snippetListNames:
|
|
35
|
+
snippetListNames: State<string[]>;
|
|
34
36
|
closeModal: () => void;
|
|
35
37
|
open: boolean;
|
|
36
38
|
onInsert: (snippet: Snippet) => void;
|
|
@@ -38,18 +40,11 @@ interface Args {
|
|
|
38
40
|
|
|
39
41
|
export default class SnippetPluginSearchModalComponent extends Component<Args> {
|
|
40
42
|
@service declare snippetFetchService: SnippetFetchService;
|
|
43
|
+
@service declare intl: IntlService;
|
|
41
44
|
|
|
42
45
|
// Filtering
|
|
43
46
|
@tracked inputSearchText: string | null = null;
|
|
44
47
|
|
|
45
|
-
// Display
|
|
46
|
-
@tracked error: unknown;
|
|
47
|
-
|
|
48
|
-
// Pagination
|
|
49
|
-
@tracked pageNumber = 0;
|
|
50
|
-
@tracked pageSize = 20;
|
|
51
|
-
@tracked totalCount = 0;
|
|
52
|
-
|
|
53
48
|
get config() {
|
|
54
49
|
return this.args.config;
|
|
55
50
|
}
|
|
@@ -58,8 +53,17 @@ export default class SnippetPluginSearchModalComponent extends Component<Args> {
|
|
|
58
53
|
return this.inputSearchText;
|
|
59
54
|
}
|
|
60
55
|
|
|
61
|
-
get
|
|
62
|
-
|
|
56
|
+
get modalTitle() {
|
|
57
|
+
const listNames = this.args.snippetListNames;
|
|
58
|
+
return listNames.isLoading
|
|
59
|
+
? this.intl.t('common.search.loading')
|
|
60
|
+
: listNames.error
|
|
61
|
+
? this.intl.t('snippet-plugin.snippet-list.name-error')
|
|
62
|
+
: this.intl.t('snippet-plugin.modal.title', {
|
|
63
|
+
snippetListNames: listNames.resolved
|
|
64
|
+
?.map((name) => `"${name}"`)
|
|
65
|
+
.join(', '),
|
|
66
|
+
});
|
|
63
67
|
}
|
|
64
68
|
|
|
65
69
|
@action
|
|
@@ -72,70 +76,12 @@ export default class SnippetPluginSearchModalComponent extends Component<Args> {
|
|
|
72
76
|
this.inputSearchText = event.target.value;
|
|
73
77
|
}
|
|
74
78
|
|
|
75
|
-
@action
|
|
76
|
-
async closeModal() {
|
|
77
|
-
await this.snippetsResource.cancel();
|
|
78
|
-
this.args.closeModal();
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
snippetsSearch = restartableTask(async () => {
|
|
82
|
-
if (this.searchText) {
|
|
83
|
-
await timeout(500);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
const abortController = new AbortController();
|
|
87
|
-
|
|
88
|
-
try {
|
|
89
|
-
const queryResult = await this.snippetFetchService.getSnippets({
|
|
90
|
-
endpoint: this.args.config.endpoint,
|
|
91
|
-
abortSignal: abortController.signal,
|
|
92
|
-
filter: {
|
|
93
|
-
name: this.inputSearchText ?? undefined,
|
|
94
|
-
snippetListUris: this.args.snippetListUris ?? undefined,
|
|
95
|
-
},
|
|
96
|
-
pagination: {
|
|
97
|
-
pageNumber: this.pageNumber,
|
|
98
|
-
pageSize: this.pageSize,
|
|
99
|
-
},
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
this.totalCount = queryResult.totalCount;
|
|
103
|
-
|
|
104
|
-
return queryResult.results;
|
|
105
|
-
} catch (error) {
|
|
106
|
-
this.error = error;
|
|
107
|
-
return [];
|
|
108
|
-
} finally {
|
|
109
|
-
abortController.abort();
|
|
110
|
-
}
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
snippetsResource = trackedTask<Snippet[]>(this, this.snippetsSearch, () => [
|
|
114
|
-
this.inputSearchText,
|
|
115
|
-
this.pageNumber,
|
|
116
|
-
this.pageSize,
|
|
117
|
-
this.args.snippetListUris,
|
|
118
|
-
]);
|
|
119
|
-
|
|
120
|
-
@action
|
|
121
|
-
previousPage() {
|
|
122
|
-
--this.pageNumber;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
@action
|
|
126
|
-
nextPage() {
|
|
127
|
-
++this.pageNumber;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
79
|
<template>
|
|
131
80
|
<AuModal
|
|
132
81
|
class='snippet-modal'
|
|
133
82
|
@modalOpen={{@open}}
|
|
134
|
-
@closeModal={{
|
|
135
|
-
@title={{
|
|
136
|
-
'snippet-plugin.modal.title'
|
|
137
|
-
snippetListNames=this.snippetListNames
|
|
138
|
-
}}
|
|
83
|
+
@closeModal={{@closeModal}}
|
|
84
|
+
@title={{this.modalTitle}}
|
|
139
85
|
@size='large'
|
|
140
86
|
@padding='none'
|
|
141
87
|
as |modal|
|
|
@@ -174,49 +120,121 @@ export default class SnippetPluginSearchModalComponent extends Component<Args> {
|
|
|
174
120
|
</div>
|
|
175
121
|
</mc.sidebar>
|
|
176
122
|
<mc.content @scroll={{true}}>
|
|
177
|
-
<
|
|
178
|
-
{{
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
{{#if this.error}}
|
|
184
|
-
<AlertLoadError @error={{this.error}} />
|
|
185
|
-
{{else}}
|
|
186
|
-
{{#if this.snippetsResource.value.length}}
|
|
187
|
-
<PreviewList
|
|
188
|
-
@docs={{this.snippetsResource.value}}
|
|
189
|
-
@onInsert={{@onInsert}}
|
|
190
|
-
/>
|
|
191
|
-
{{else}}
|
|
192
|
-
<AlertNoItems />
|
|
193
|
-
{{/if}}
|
|
194
|
-
{{/if}}
|
|
195
|
-
{{/if}}
|
|
196
|
-
</div>
|
|
197
|
-
{{#if this.snippetsResource.value.length}}
|
|
198
|
-
{{#let
|
|
199
|
-
(pagination
|
|
200
|
-
page=this.pageNumber
|
|
201
|
-
pageSize=this.pageSize
|
|
202
|
-
count=this.totalCount
|
|
203
|
-
)
|
|
204
|
-
as |pg|
|
|
205
|
-
}}
|
|
206
|
-
<PaginationView
|
|
207
|
-
@totalCount={{pg.count}}
|
|
208
|
-
@rangeStart={{pg.pageStart}}
|
|
209
|
-
@rangeEnd={{pg.pageEnd}}
|
|
210
|
-
@onNextPage={{this.nextPage}}
|
|
211
|
-
@onPreviousPage={{this.previousPage}}
|
|
212
|
-
@isFirstPage={{not pg.hasPreviousPage}}
|
|
213
|
-
@isLastPage={{not pg.hasNextPage}}
|
|
214
|
-
/>
|
|
215
|
-
{{/let}}
|
|
216
|
-
{{/if}}
|
|
123
|
+
<Inner
|
|
124
|
+
@snippetListUris={{@snippetListUris}}
|
|
125
|
+
@searchText={{this.inputSearchText}}
|
|
126
|
+
@onInsert={{@onInsert}}
|
|
127
|
+
@config={{@config}}
|
|
128
|
+
/>
|
|
217
129
|
</mc.content>
|
|
218
130
|
</AuMainContainer>
|
|
219
131
|
</modal.Body>
|
|
220
132
|
</AuModal>
|
|
221
133
|
</template>
|
|
222
134
|
}
|
|
135
|
+
|
|
136
|
+
type InnerSig = {
|
|
137
|
+
Args: {
|
|
138
|
+
snippetListUris: Option<string[]>;
|
|
139
|
+
searchText: string | null;
|
|
140
|
+
onInsert: (snippet: Snippet) => void;
|
|
141
|
+
config: SnippetPluginConfig;
|
|
142
|
+
};
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
// Split out inner component to allow for easy re-trying of fetch errors
|
|
146
|
+
class Inner extends Component<InnerSig> {
|
|
147
|
+
@service declare snippetFetchService: SnippetFetchService;
|
|
148
|
+
|
|
149
|
+
// Pagination
|
|
150
|
+
@tracked pageNumber = 0;
|
|
151
|
+
@tracked pageSize = 20;
|
|
152
|
+
@tracked totalCount = 0;
|
|
153
|
+
|
|
154
|
+
snippetsSearch = restartableTask(async () => {
|
|
155
|
+
if (this.args.searchText) {
|
|
156
|
+
await timeout(500);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const abortController = new AbortController();
|
|
160
|
+
|
|
161
|
+
try {
|
|
162
|
+
const queryResult = await this.snippetFetchService.getSnippets({
|
|
163
|
+
endpoint: this.args.config.endpoint,
|
|
164
|
+
abortSignal: abortController.signal,
|
|
165
|
+
filter: {
|
|
166
|
+
name: this.args.searchText ?? undefined,
|
|
167
|
+
snippetListUris: this.args.snippetListUris ?? undefined,
|
|
168
|
+
},
|
|
169
|
+
pagination: {
|
|
170
|
+
pageNumber: this.pageNumber,
|
|
171
|
+
pageSize: this.pageSize,
|
|
172
|
+
},
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
this.totalCount = queryResult.totalCount;
|
|
176
|
+
|
|
177
|
+
return queryResult.results;
|
|
178
|
+
} finally {
|
|
179
|
+
abortController.abort();
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
snippetsResource = trackedTask<Snippet[]>(this, this.snippetsSearch, () => [
|
|
184
|
+
this.args.searchText,
|
|
185
|
+
this.pageNumber,
|
|
186
|
+
this.pageSize,
|
|
187
|
+
this.args.snippetListUris,
|
|
188
|
+
]);
|
|
189
|
+
|
|
190
|
+
@action
|
|
191
|
+
previousPage() {
|
|
192
|
+
--this.pageNumber;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
@action
|
|
196
|
+
nextPage() {
|
|
197
|
+
++this.pageNumber;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
<template>
|
|
201
|
+
<div class='au-u-padding-top snippet-modal--list-container'>
|
|
202
|
+
{{#if this.snippetsResource.isRunning}}
|
|
203
|
+
<div class='au-u-margin'>
|
|
204
|
+
<Loading />
|
|
205
|
+
</div>
|
|
206
|
+
{{else}}
|
|
207
|
+
{{#if this.snippetsResource.error}}
|
|
208
|
+
<AlertLoadError @error={{this.snippetsResource.error}} />
|
|
209
|
+
{{else}}
|
|
210
|
+
{{#if this.snippetsResource.value.length}}
|
|
211
|
+
<PreviewList
|
|
212
|
+
@docs={{this.snippetsResource.value}}
|
|
213
|
+
@onInsert={{@onInsert}}
|
|
214
|
+
/>
|
|
215
|
+
{{else}}
|
|
216
|
+
<AlertNoItems />
|
|
217
|
+
{{/if}}
|
|
218
|
+
{{/if}}
|
|
219
|
+
{{/if}}
|
|
220
|
+
</div>
|
|
221
|
+
{{#if this.snippetsResource.value.length}}
|
|
222
|
+
{{#let
|
|
223
|
+
(pagination
|
|
224
|
+
page=this.pageNumber pageSize=this.pageSize count=this.totalCount
|
|
225
|
+
)
|
|
226
|
+
as |pg|
|
|
227
|
+
}}
|
|
228
|
+
<PaginationView
|
|
229
|
+
@totalCount={{pg.count}}
|
|
230
|
+
@rangeStart={{pg.pageStart}}
|
|
231
|
+
@rangeEnd={{pg.pageEnd}}
|
|
232
|
+
@onNextPage={{this.nextPage}}
|
|
233
|
+
@onPreviousPage={{this.previousPage}}
|
|
234
|
+
@isFirstPage={{not pg.hasPreviousPage}}
|
|
235
|
+
@isLastPage={{not pg.hasNextPage}}
|
|
236
|
+
/>
|
|
237
|
+
{{/let}}
|
|
238
|
+
{{/if}}
|
|
239
|
+
</template>
|
|
240
|
+
}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { action } from '@ember/object';
|
|
2
2
|
import { on } from '@ember/modifier';
|
|
3
|
+
import { service } from '@ember/service';
|
|
3
4
|
import Component from '@glimmer/component';
|
|
4
5
|
import { tracked } from '@glimmer/tracking';
|
|
5
6
|
import t from 'ember-intl/helpers/t';
|
|
7
|
+
import { trackedFunction } from 'reactiveweb/function';
|
|
8
|
+
import { getPromiseState } from 'reactiveweb/get-promise-state';
|
|
6
9
|
import { AddIcon } from '@appuniversum/ember-appuniversum/components/icons/add';
|
|
7
10
|
import AuButton from '@appuniversum/ember-appuniversum/components/au-button';
|
|
8
11
|
import {
|
|
@@ -16,6 +19,7 @@ import {
|
|
|
16
19
|
} from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/snippet-plugin';
|
|
17
20
|
import { type SnippetListProperties } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/snippet-plugin';
|
|
18
21
|
import insertSnippet from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/snippet-plugin/commands/insert-snippet';
|
|
22
|
+
import SnippetFetchService from '@lblod/ember-rdfa-editor-lblod-plugins/services/snippet-fetch-service';
|
|
19
23
|
import SearchModal from './search-modal';
|
|
20
24
|
|
|
21
25
|
interface Sig {
|
|
@@ -28,6 +32,8 @@ interface Sig {
|
|
|
28
32
|
}
|
|
29
33
|
|
|
30
34
|
export default class SnippetInsertComponent extends Component<Sig> {
|
|
35
|
+
@service declare snippetFetchService: SnippetFetchService;
|
|
36
|
+
|
|
31
37
|
@tracked showModal = false;
|
|
32
38
|
|
|
33
39
|
get controller() {
|
|
@@ -73,6 +79,16 @@ export default class SnippetInsertComponent extends Component<Sig> {
|
|
|
73
79
|
}
|
|
74
80
|
}
|
|
75
81
|
|
|
82
|
+
snippetListNames = trackedFunction(this, async () => {
|
|
83
|
+
return (
|
|
84
|
+
this.args.listProperties &&
|
|
85
|
+
this.snippetFetchService.getListNames(
|
|
86
|
+
this.args.config,
|
|
87
|
+
this.args.listProperties.listUris,
|
|
88
|
+
)
|
|
89
|
+
);
|
|
90
|
+
});
|
|
91
|
+
|
|
76
92
|
<template>
|
|
77
93
|
<li class='au-c-list__item'>
|
|
78
94
|
<AuButton
|
|
@@ -92,7 +108,7 @@ export default class SnippetInsertComponent extends Component<Sig> {
|
|
|
92
108
|
@config={{@config}}
|
|
93
109
|
@onInsert={{this.onInsert}}
|
|
94
110
|
@snippetListUris={{@listProperties.listUris}}
|
|
95
|
-
@snippetListNames={{
|
|
111
|
+
@snippetListNames={{getPromiseState this.snippetListNames.promise}}
|
|
96
112
|
/>
|
|
97
113
|
</template>
|
|
98
114
|
}
|
|
@@ -4,7 +4,7 @@ import { ELI } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/constants';
|
|
|
4
4
|
|
|
5
5
|
import { hasRDFaAttribute } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/namespace';
|
|
6
6
|
|
|
7
|
-
const rdfaAware =
|
|
7
|
+
const rdfaAware = false;
|
|
8
8
|
export const document_title: NodeSpec = {
|
|
9
9
|
content: 'paragraph{1}',
|
|
10
10
|
inline: false,
|
|
@@ -64,7 +64,6 @@ export function createSnippetPlaceholder({
|
|
|
64
64
|
listProps = {
|
|
65
65
|
// This is a completely new placeholder, so new id
|
|
66
66
|
placeholderId: uuidv4(),
|
|
67
|
-
names: args.lists.map((list) => list.label),
|
|
68
67
|
importedResources: importedResourcesFromSnippetLists(args.lists),
|
|
69
68
|
};
|
|
70
69
|
additionalProperties = args.lists.map((list) =>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { NodeWithPos } from '@curvenote/prosemirror-utils';
|
|
2
2
|
import { LegacyTableOfContentsConfig, TableOfContentsConfig } from '..';
|
|
3
3
|
import { DOMOutputSpec, PNode, EditorState } from '@lblod/ember-rdfa-editor';
|
|
4
|
+
import { Mutable } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/types';
|
|
4
5
|
|
|
5
6
|
export type OutlineEntry = {
|
|
6
7
|
content: string;
|
|
@@ -8,10 +9,6 @@ export type OutlineEntry = {
|
|
|
8
9
|
children?: OutlineEntry[];
|
|
9
10
|
};
|
|
10
11
|
|
|
11
|
-
type Mutable<T> = {
|
|
12
|
-
-readonly [P in keyof T]: T[P];
|
|
13
|
-
};
|
|
14
|
-
|
|
15
12
|
export function createTableOfContents(entries: OutlineEntry[]) {
|
|
16
13
|
const tableOfContents: Mutable<DOMOutputSpec> = [
|
|
17
14
|
'ul',
|
package/addon/utils/types.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import Component from '@glimmer/component';
|
|
2
2
|
import IntlService from 'ember-intl/services/intl';
|
|
3
|
+
import { State } from 'reactiveweb/get-promise-state';
|
|
3
4
|
import { type EmberNodeArgs } from '@lblod/ember-rdfa-editor/utils/_private/ember-node';
|
|
4
5
|
import { type SnippetPluginConfig } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/snippet-plugin';
|
|
5
6
|
interface Signature {
|
|
6
7
|
Args: Pick<EmberNodeArgs, 'node' | 'selectNode'> & {
|
|
7
8
|
insertSnippet: () => void;
|
|
8
|
-
snippetListNames: string[]
|
|
9
|
+
snippetListNames: State<string[]>;
|
|
9
10
|
};
|
|
10
11
|
}
|
|
11
12
|
export default class SnippetPluginPlaceholder extends Component<Signature> {
|
|
@@ -31,7 +31,6 @@ export default class SnippetNode extends Component<Signature> {
|
|
|
31
31
|
get isActive(): boolean;
|
|
32
32
|
onInsert(snippet: Snippet): void;
|
|
33
33
|
get class(): string;
|
|
34
|
-
|
|
35
|
-
get snippetListNames(): string[];
|
|
34
|
+
snippetListNames: import("reactiveweb/function").State<Promise<string[]>>;
|
|
36
35
|
}
|
|
37
36
|
export {};
|
|
@@ -1,30 +1,24 @@
|
|
|
1
1
|
import Component from '@glimmer/component';
|
|
2
|
+
import { State } from 'reactiveweb/get-promise-state';
|
|
3
|
+
import IntlService from 'ember-intl/services/intl';
|
|
2
4
|
import { Option } from '@lblod/ember-rdfa-editor/utils/option';
|
|
3
5
|
import { Snippet, SnippetPluginConfig } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/snippet-plugin';
|
|
4
6
|
import SnippetFetchService from '@lblod/ember-rdfa-editor-lblod-plugins/services/snippet-fetch-service';
|
|
5
7
|
interface Args {
|
|
6
8
|
config: SnippetPluginConfig;
|
|
7
9
|
snippetListUris: Option<string[]>;
|
|
8
|
-
snippetListNames:
|
|
10
|
+
snippetListNames: State<string[]>;
|
|
9
11
|
closeModal: () => void;
|
|
10
12
|
open: boolean;
|
|
11
13
|
onInsert: (snippet: Snippet) => void;
|
|
12
14
|
}
|
|
13
15
|
export default class SnippetPluginSearchModalComponent extends Component<Args> {
|
|
14
16
|
snippetFetchService: SnippetFetchService;
|
|
17
|
+
intl: IntlService;
|
|
15
18
|
inputSearchText: string | null;
|
|
16
|
-
error: unknown;
|
|
17
|
-
pageNumber: number;
|
|
18
|
-
pageSize: number;
|
|
19
|
-
totalCount: number;
|
|
20
19
|
get config(): SnippetPluginConfig;
|
|
21
20
|
get searchText(): string | null;
|
|
22
|
-
get
|
|
21
|
+
get modalTitle(): string;
|
|
23
22
|
setInputSearchText(event: InputEvent): void;
|
|
24
|
-
closeModal(): Promise<void>;
|
|
25
|
-
snippetsSearch: import("ember-concurrency").TaskForAsyncTaskFunction<unknown, () => Promise<Snippet[]>>;
|
|
26
|
-
snippetsResource: import("reactiveweb/ember-concurrency").TaskInstance<Snippet[]>;
|
|
27
|
-
previousPage(): void;
|
|
28
|
-
nextPage(): void;
|
|
29
23
|
}
|
|
30
24
|
export {};
|
|
@@ -2,6 +2,7 @@ import Component from '@glimmer/component';
|
|
|
2
2
|
import { type SayController, Slice } from '@lblod/ember-rdfa-editor';
|
|
3
3
|
import { Snippet, SnippetPluginConfig } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/snippet-plugin';
|
|
4
4
|
import { type SnippetListProperties } 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 Sig {
|
|
6
7
|
Args: {
|
|
7
8
|
controller: SayController;
|
|
@@ -11,6 +12,7 @@ interface Sig {
|
|
|
11
12
|
};
|
|
12
13
|
}
|
|
13
14
|
export default class SnippetInsertComponent extends Component<Sig> {
|
|
15
|
+
snippetFetchService: SnippetFetchService;
|
|
14
16
|
showModal: boolean;
|
|
15
17
|
get controller(): SayController;
|
|
16
18
|
get disabled(): boolean;
|
|
@@ -18,5 +20,6 @@ export default class SnippetInsertComponent extends Component<Sig> {
|
|
|
18
20
|
closeModal(): void;
|
|
19
21
|
createSliceFromElement(element: Element): Slice;
|
|
20
22
|
onInsert(snippet: Snippet): void;
|
|
23
|
+
snippetListNames: import("reactiveweb/function").State<Promise<string[] | undefined>>;
|
|
21
24
|
}
|
|
22
25
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lblod/ember-rdfa-editor-lblod-plugins",
|
|
3
|
-
"version": "38.
|
|
3
|
+
"version": "38.2.0",
|
|
4
4
|
"description": "Ember addon providing lblod specific plugins for the ember-rdfa-editor",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ember-addon",
|
|
@@ -180,11 +180,11 @@
|
|
|
180
180
|
"webpack": "^5.95.0"
|
|
181
181
|
},
|
|
182
182
|
"peerDependencies": {
|
|
183
|
-
"@appuniversum/ember-appuniversum": "^3.12.0",
|
|
183
|
+
"@appuniversum/ember-appuniversum": "^3.12.0 || ^4.0.0",
|
|
184
184
|
"@ember/string": "3.x",
|
|
185
185
|
"@glint/template": "^1.4.0",
|
|
186
186
|
"@lblod/ember-rdfa-editor": "^13.12.0",
|
|
187
|
-
"ember-concurrency": "^4.0.2",
|
|
187
|
+
"ember-concurrency": "^4.0.2 || ^5.0.0",
|
|
188
188
|
"ember-element-helper": "^0.8.6",
|
|
189
189
|
"ember-intl": "^7.0.0",
|
|
190
190
|
"ember-leaflet": "^5.1.3",
|
|
@@ -216,5 +216,5 @@
|
|
|
216
216
|
"ember-addon": {
|
|
217
217
|
"configPath": "tests/dummy/config"
|
|
218
218
|
},
|
|
219
|
-
"packageManager": "pnpm@10.
|
|
219
|
+
"packageManager": "pnpm@11.10.0"
|
|
220
220
|
}
|
package/pnpm-workspace.yaml
CHANGED
package/translations/en-US.yaml
CHANGED
|
@@ -275,6 +275,8 @@ snippet-plugin:
|
|
|
275
275
|
label: Snippet name
|
|
276
276
|
placeholder: Type something...
|
|
277
277
|
snippet-list:
|
|
278
|
+
name-error: Error loading snippet list names
|
|
279
|
+
name-error-message: 'Error loading snippet list names: {message}'
|
|
278
280
|
open-modal: Manage snippet lists
|
|
279
281
|
modal:
|
|
280
282
|
title: Select available snippet lists for this template
|
package/translations/nl-BE.yaml
CHANGED
|
@@ -274,6 +274,8 @@ snippet-plugin:
|
|
|
274
274
|
label: Fragmentnaam
|
|
275
275
|
placeholder: Vul in…
|
|
276
276
|
snippet-list:
|
|
277
|
+
name-error: Probleem bij het laden van de namen van de fragmentlijsten
|
|
278
|
+
name-error-message: 'Probleem bij het laden van de namen van de fragmentlijsten: {message}'
|
|
277
279
|
open-modal: Fragmentlijsten beheren
|
|
278
280
|
modal:
|
|
279
281
|
title: Selecteer beschikbare fragmentlijsten voor deze sjabloon
|