@lblod/ember-rdfa-editor-lblod-plugins 27.1.0 → 28.0.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 +16 -0
- package/addon/components/common/documents/preview-list.gts +35 -0
- package/addon/components/{snippet-plugin/snippets/snippet-preview.gts → common/documents/preview.gts} +38 -22
- package/addon/components/common/documents/types.ts +19 -0
- package/addon/components/common/search/alert-load-error.gts +17 -6
- package/addon/components/common/search/alert-no-items.gts +15 -6
- package/addon/components/common/search/loading.gts +13 -0
- package/addon/components/common/vote-star-unfilled-icon.gts +25 -0
- package/addon/components/snippet-plugin/nodes/snippet.gts +4 -3
- package/addon/components/snippet-plugin/search-modal.gts +216 -0
- package/addon/components/snippet-plugin/snippet-insert.gts +7 -4
- package/addon/components/table-of-contents-plugin/ember-nodes/outline.hbs +1 -1
- package/addon/components/table-of-contents-plugin/ember-nodes/table-of-contents.hbs +4 -1
- package/addon/components/table-of-contents-plugin/ember-nodes/table-of-contents.ts +9 -4
- package/addon/helpers/pagination.ts +15 -3
- package/addon/plugins/structure-plugin/node.ts +44 -3
- package/addon/plugins/table-of-contents-plugin/index.ts +4 -1
- package/addon/plugins/table-of-contents-plugin/nodes/table-of-contents.ts +4 -4
- package/addon/plugins/table-of-contents-plugin/utils/index.ts +47 -4
- package/app/components/{snippet-plugin/snippets/snippet-list.js → common/documents/preview-list.js} +1 -1
- package/app/components/{snippet-plugin/snippets/snippet-preview.js → common/documents/preview.js} +1 -1
- package/declarations/addon/components/common/documents/preview-list.d.ts +14 -0
- package/declarations/addon/components/common/documents/preview.d.ts +21 -0
- package/declarations/addon/components/common/documents/types.d.ts +11 -0
- package/declarations/addon/components/common/search/alert-load-error.d.ts +11 -2
- package/declarations/addon/components/common/search/alert-no-items.d.ts +10 -2
- package/declarations/addon/components/common/search/loading.d.ts +5 -1
- package/declarations/addon/components/common/vote-star-unfilled-icon.d.ts +9 -0
- package/declarations/addon/components/snippet-plugin/nodes/snippet.d.ts +2 -1
- package/declarations/addon/components/snippet-plugin/search-modal.d.ts +4 -4
- package/declarations/addon/components/snippet-plugin/snippet-insert.d.ts +2 -2
- package/declarations/addon/components/table-of-contents-plugin/ember-nodes/table-of-contents.d.ts +1 -1
- package/declarations/addon/helpers/pagination.d.ts +4 -3
- package/declarations/addon/plugins/table-of-contents-plugin/index.d.ts +4 -1
- package/declarations/addon/plugins/table-of-contents-plugin/nodes/table-of-contents.d.ts +3 -3
- package/declarations/addon/plugins/table-of-contents-plugin/utils/index.d.ts +5 -7
- package/package.json +5 -5
- package/pnpm-lock.yaml +48 -56
- package/addon/components/common/search/loading.hbs +0 -3
- package/addon/components/snippet-plugin/search-modal.hbs +0 -85
- package/addon/components/snippet-plugin/search-modal.ts +0 -107
- package/addon/components/snippet-plugin/snippets/snippet-list.hbs +0 -12
- package/declarations/addon/components/snippet-plugin/snippets/snippet-list.d.ts +0 -1
- package/declarations/addon/components/snippet-plugin/snippets/snippet-preview.d.ts +0 -19
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @lblod/ember-rdfa-editor-lblod-plugins
|
|
2
2
|
|
|
3
|
+
## 28.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- [#547](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/pull/547) [`8dc7f0f`](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/commit/8dc7f0f3f57755ae2807e38c7f75a6b6fbff6248) Thanks [@abeforgit](https://github.com/abeforgit)! - Bump peerdeps to be compatible with editor v11
|
|
8
|
+
|
|
9
|
+
### Minor Changes
|
|
10
|
+
|
|
11
|
+
- [#547](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/pull/547) [`648e04b`](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/commit/648e04b4c4d59d717f9e9c2f24a57c22f45c222d) Thanks [@abeforgit](https://github.com/abeforgit)! - Make ToC compatible with new structure nodes
|
|
12
|
+
|
|
13
|
+
- [#548](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/pull/548) [`9b90845`](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/commit/9b90845c524d8255dda98b872876b8fbd1728026) Thanks [@piemonkey](https://github.com/piemonkey)! - Convert snippet preview list into a generic component for displaying a list of documents
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- [#548](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/pull/548) [`704b9b7`](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/commit/704b9b776ed61e374852c0cdf51fb7330dac557b) Thanks [@piemonkey](https://github.com/piemonkey)! - Add ability to mark favourites in a preview list
|
|
18
|
+
|
|
3
19
|
## 27.1.0
|
|
4
20
|
|
|
5
21
|
### Minor Changes
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import Component from '@glimmer/component';
|
|
2
|
+
import AuList from '@appuniversum/ember-appuniversum/components/au-list';
|
|
3
|
+
import Preview from './preview';
|
|
4
|
+
import { PreviewableDocument } from './types';
|
|
5
|
+
|
|
6
|
+
interface Sig<Doc extends PreviewableDocument> {
|
|
7
|
+
Args: {
|
|
8
|
+
docs: Doc[];
|
|
9
|
+
onInsert: (toInsert: Doc) => void;
|
|
10
|
+
isFavourite?: (doc: Doc) => boolean;
|
|
11
|
+
toggleFavourite?: (doc: Doc) => void;
|
|
12
|
+
};
|
|
13
|
+
Element: HTMLDivElement;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export default class PreviewList<
|
|
17
|
+
Doc extends PreviewableDocument,
|
|
18
|
+
> extends Component<Sig<Doc>> {
|
|
19
|
+
<template>
|
|
20
|
+
{{#if @docs.length}}
|
|
21
|
+
<AuList as |Item|>
|
|
22
|
+
{{#each @docs as |doc|}}
|
|
23
|
+
<Item>
|
|
24
|
+
<Preview
|
|
25
|
+
@doc={{doc}}
|
|
26
|
+
@onInsert={{@onInsert}}
|
|
27
|
+
@isFavourite={{@isFavourite}}
|
|
28
|
+
@toggleFavourite={{@toggleFavourite}}
|
|
29
|
+
/>
|
|
30
|
+
</Item>
|
|
31
|
+
{{/each}}
|
|
32
|
+
</AuList>
|
|
33
|
+
{{/if}}
|
|
34
|
+
</template>
|
|
35
|
+
}
|
|
@@ -2,41 +2,35 @@ import AuButton from '@appuniversum/ember-appuniversum/components/au-button';
|
|
|
2
2
|
import AuIcon from '@appuniversum/ember-appuniversum/components/au-icon';
|
|
3
3
|
import { NavDownIcon } from '@appuniversum/ember-appuniversum/components/icons/nav-down';
|
|
4
4
|
import { NavUpIcon } from '@appuniversum/ember-appuniversum/components/icons/nav-up';
|
|
5
|
+
import { VoteStarFilledIcon } from '@appuniversum/ember-appuniversum/components/icons/vote-star-filled';
|
|
5
6
|
import { on } from '@ember/modifier';
|
|
6
7
|
import { action } from '@ember/object';
|
|
7
8
|
import Component from '@glimmer/component';
|
|
8
9
|
import { tracked } from '@glimmer/tracking';
|
|
9
|
-
|
|
10
|
-
import { SayController } from '@lblod/ember-rdfa-editor';
|
|
11
|
-
import {
|
|
12
|
-
Snippet,
|
|
13
|
-
SnippetPluginConfig,
|
|
14
|
-
} from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/snippet-plugin';
|
|
15
10
|
import t from 'ember-intl/helpers/t';
|
|
11
|
+
import { SayController } from '@lblod/ember-rdfa-editor';
|
|
12
|
+
import { PreviewableDocument } from './types';
|
|
13
|
+
import { VoteStarUnfilledIcon } from '../vote-star-unfilled-icon';
|
|
16
14
|
|
|
17
|
-
interface Signature {
|
|
15
|
+
interface Signature<Doc extends PreviewableDocument> {
|
|
18
16
|
Args: {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
doc: Doc;
|
|
18
|
+
onInsert: (toInsert: Doc) => void;
|
|
19
|
+
isFavourite?: (doc: Doc) => boolean;
|
|
20
|
+
toggleFavourite?: (doc: Doc) => void;
|
|
22
21
|
};
|
|
23
22
|
Element: HTMLDivElement;
|
|
24
23
|
}
|
|
25
24
|
|
|
26
|
-
export default class
|
|
25
|
+
export default class DocumentPreview<
|
|
26
|
+
Doc extends PreviewableDocument,
|
|
27
|
+
> extends Component<Signature<Doc>> {
|
|
27
28
|
@tracked controller?: SayController;
|
|
28
29
|
@tracked isExpanded = false;
|
|
29
30
|
|
|
30
|
-
get snippet(): Snippet {
|
|
31
|
-
return this.args.snippet;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
31
|
@action
|
|
35
32
|
onInsert() {
|
|
36
|
-
this.args.onInsert(
|
|
37
|
-
this.args.snippet.content?.toHTML() ?? '',
|
|
38
|
-
this.args.snippet.title ?? '',
|
|
39
|
-
);
|
|
33
|
+
this.args.onInsert(this.args.doc);
|
|
40
34
|
}
|
|
41
35
|
|
|
42
36
|
@action
|
|
@@ -44,6 +38,14 @@ export default class SnippetPreviewComponent extends Component<Signature> {
|
|
|
44
38
|
this.isExpanded = !this.isExpanded;
|
|
45
39
|
}
|
|
46
40
|
|
|
41
|
+
get isFavourite() {
|
|
42
|
+
return this.args.isFavourite?.(this.args.doc);
|
|
43
|
+
}
|
|
44
|
+
toggleFavourite = (event: MouseEvent) => {
|
|
45
|
+
event.stopPropagation();
|
|
46
|
+
this.args.toggleFavourite?.(this.args.doc);
|
|
47
|
+
};
|
|
48
|
+
|
|
47
49
|
<template>
|
|
48
50
|
<div
|
|
49
51
|
class='snippet-preview {{if this.isExpanded "snippet-preview--expanded"}}'
|
|
@@ -63,9 +65,23 @@ export default class SnippetPreviewComponent extends Component<Signature> {
|
|
|
63
65
|
<AuIcon @icon={{NavDownIcon}} @size='large' />
|
|
64
66
|
{{/if}}
|
|
65
67
|
</AuButton>
|
|
68
|
+
{{#if @isFavourite}}
|
|
69
|
+
{{#if this.isFavourite}}
|
|
70
|
+
<AuButton
|
|
71
|
+
@skin='naked'
|
|
72
|
+
@icon={{VoteStarFilledIcon}}
|
|
73
|
+
{{on 'click' this.toggleFavourite}}
|
|
74
|
+
/>
|
|
75
|
+
{{else}}
|
|
76
|
+
{{! This is weird but needed to get around the stroke-width styling of svgs in au-icons }}
|
|
77
|
+
<AuButton @skin='naked' {{on 'click' this.toggleFavourite}}>
|
|
78
|
+
<VoteStarUnfilledIcon />
|
|
79
|
+
</AuButton>
|
|
80
|
+
{{/if}}
|
|
81
|
+
{{/if}}
|
|
66
82
|
{{! template-lint-disable no-heading-inside-button}}
|
|
67
83
|
<h3 class='snippet-preview__title'>
|
|
68
|
-
{{@
|
|
84
|
+
{{@doc.title}}
|
|
69
85
|
</h3>
|
|
70
86
|
</div>
|
|
71
87
|
<div
|
|
@@ -84,8 +100,8 @@ export default class SnippetPreviewComponent extends Component<Signature> {
|
|
|
84
100
|
<div
|
|
85
101
|
class='say-editor say-content rdfa-annotations rdfa-annotations-highlight rdfa-annotations-hover snippet-preview__content'
|
|
86
102
|
>
|
|
87
|
-
{{#if @
|
|
88
|
-
{{@
|
|
103
|
+
{{#if @doc.content}}
|
|
104
|
+
{{@doc.content}}
|
|
89
105
|
{{else}}
|
|
90
106
|
<p class='au-u-italic'>{{t 'snippet-plugin.modal.no-content'}}</p>
|
|
91
107
|
{{/if}}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { htmlSafe } from '@ember/template';
|
|
2
|
+
|
|
3
|
+
import { optionMapOr } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/option';
|
|
4
|
+
import { SafeString } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/types';
|
|
5
|
+
|
|
6
|
+
interface PreviewableDocumentArgs {
|
|
7
|
+
title: string | null;
|
|
8
|
+
content: string | null;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export class PreviewableDocument {
|
|
12
|
+
content: SafeString | null;
|
|
13
|
+
title: string | null;
|
|
14
|
+
|
|
15
|
+
constructor({ title, content }: PreviewableDocumentArgs) {
|
|
16
|
+
this.content = optionMapOr(null, htmlSafe, content);
|
|
17
|
+
this.title = title;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -1,23 +1,32 @@
|
|
|
1
|
+
import { TemplateOnlyComponent } from '@ember/component/template-only';
|
|
1
2
|
import t from 'ember-intl/helpers/t';
|
|
2
|
-
import AuAlert
|
|
3
|
+
import AuAlert, {
|
|
4
|
+
AuAlertSignature,
|
|
5
|
+
} from '@appuniversum/ember-appuniversum/components/au-alert';
|
|
3
6
|
import AuLinkExternal from '@appuniversum/ember-appuniversum/components/au-link-external';
|
|
4
7
|
import { AlertTriangleIcon } from '@appuniversum/ember-appuniversum/components/icons/alert-triangle';
|
|
5
8
|
import { MailIcon } from '@appuniversum/ember-appuniversum/components/icons/mail';
|
|
6
9
|
|
|
7
|
-
|
|
10
|
+
interface Sig {
|
|
11
|
+
Args: {
|
|
12
|
+
error: unknown;
|
|
13
|
+
fullSize?: boolean;
|
|
14
|
+
};
|
|
15
|
+
Element: AuAlertSignature['Element'];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const AlertLoadError: TemplateOnlyComponent<Sig> = <template>
|
|
8
19
|
<AuAlert
|
|
9
20
|
@title={{t 'common.search.error-title'}}
|
|
10
21
|
@skin='error'
|
|
11
22
|
@icon={{AlertTriangleIcon}}
|
|
12
23
|
@closable={{false}}
|
|
13
|
-
{{! @glint-expect-error: not typesafe yet }}
|
|
14
24
|
@size={{if @fullSize undefined 'small'}}
|
|
15
25
|
class='au-u-margin'
|
|
16
|
-
{{! @glint-expect-error: not typesafe yet }}
|
|
17
26
|
...attributes
|
|
18
27
|
>
|
|
19
28
|
<p>{{t 'common.search.error-intro'}}</p>
|
|
20
|
-
{{! @glint-expect-error:
|
|
29
|
+
{{! @glint-expect-error: This seems to work... I guess Error has a toString that is called? }}
|
|
21
30
|
<code class='au-u-error error-code'>{{@error}}</code>
|
|
22
31
|
<p>
|
|
23
32
|
{{t 'common.search.error-outro'}}
|
|
@@ -31,4 +40,6 @@ import { MailIcon } from '@appuniversum/ember-appuniversum/components/icons/mail
|
|
|
31
40
|
</AuLinkExternal>.
|
|
32
41
|
</p>
|
|
33
42
|
</AuAlert>
|
|
34
|
-
</template
|
|
43
|
+
</template>;
|
|
44
|
+
|
|
45
|
+
export default AlertLoadError;
|
|
@@ -1,18 +1,27 @@
|
|
|
1
|
+
import { TemplateOnlyComponent } from '@ember/component/template-only';
|
|
1
2
|
import t from 'ember-intl/helpers/t';
|
|
2
|
-
import AuAlert
|
|
3
|
+
import AuAlert, {
|
|
4
|
+
AuAlertSignature,
|
|
5
|
+
} from '@appuniversum/ember-appuniversum/components/au-alert';
|
|
3
6
|
import { CrossIcon } from '@appuniversum/ember-appuniversum/components/icons/cross';
|
|
4
7
|
|
|
5
|
-
|
|
8
|
+
interface Sig {
|
|
9
|
+
Args: {
|
|
10
|
+
fullSize?: boolean;
|
|
11
|
+
};
|
|
12
|
+
Element: AuAlertSignature['Element'];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const AlertNoItems: TemplateOnlyComponent<Sig> = <template>
|
|
6
16
|
<AuAlert
|
|
7
17
|
@title={{t 'common.search.no-results'}}
|
|
8
18
|
@skin='warning'
|
|
9
19
|
@icon={{CrossIcon}}
|
|
10
|
-
{{! @glint-expect-error: not typesafe yet }}
|
|
11
20
|
@size={{if @fullSize undefined 'small'}}
|
|
12
21
|
@closable={{false}}
|
|
13
|
-
{{! @glint-expect-error: not typesafe yet }}
|
|
14
22
|
class={{unless @fullSize 'au-u-margin-small'}}
|
|
15
|
-
{{! @glint-expect-error: not typesafe yet }}
|
|
16
23
|
...attributes
|
|
17
24
|
/>
|
|
18
|
-
</template
|
|
25
|
+
</template>;
|
|
26
|
+
|
|
27
|
+
export default AlertNoItems;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { TemplateOnlyComponent } from '@ember/component/template-only';
|
|
2
|
+
import t from 'ember-intl/helpers/t';
|
|
3
|
+
import AuLoader from '@appuniversum/ember-appuniversum/components/au-loader';
|
|
4
|
+
|
|
5
|
+
interface Sig {}
|
|
6
|
+
|
|
7
|
+
const SearchLoading: TemplateOnlyComponent<Sig> = <template>
|
|
8
|
+
<AuLoader @hideMessage={{true}}>
|
|
9
|
+
{{t 'common.search.loading'}}
|
|
10
|
+
</AuLoader>
|
|
11
|
+
</template>;
|
|
12
|
+
|
|
13
|
+
export default SearchLoading;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { TOC } from '@ember/component/template-only';
|
|
2
|
+
|
|
3
|
+
export interface VoteStarUnfilledIconSignature {
|
|
4
|
+
Element: SVGSVGElement;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* There is no unfilled version in AU. Unfortunately, due to AU including a `stroke-width: 0` style
|
|
9
|
+
* for icons, this icon shouldn't be used inside an `AuIcon`, it should be used in place of one.
|
|
10
|
+
*/
|
|
11
|
+
export const VoteStarUnfilledIcon: TOC<VoteStarUnfilledIconSignature> =
|
|
12
|
+
<template>
|
|
13
|
+
<svg
|
|
14
|
+
xmlns='http://www.w3.org/2000/svg'
|
|
15
|
+
viewBox='0 0 16 17'
|
|
16
|
+
class='au-c-icon'
|
|
17
|
+
{{! template-lint-disable no-inline-styles }}
|
|
18
|
+
style='stroke-width:10%;'
|
|
19
|
+
...attributes
|
|
20
|
+
><path
|
|
21
|
+
{{! template-lint-disable no-inline-styles }}
|
|
22
|
+
style='fill:none;'
|
|
23
|
+
d='M12 15.167a.668.668 0 0 1-.37-.112L8 12.635l-3.63 2.42a.667.667 0 0 1-1.01-.737l1.225-4.29-3.056-3.056A.668.668 0 0 1 2 5.834h3.588l1.816-3.631c.226-.452.967-.452 1.193 0l1.816 3.631H14a.667.667 0 0 1 .471 1.138l-3.056 3.056 1.226 4.29a.667.667 0 0 1-.641.85Z'
|
|
24
|
+
/></svg>
|
|
25
|
+
</template>;
|
|
@@ -33,6 +33,7 @@ import { createSnippetPlaceholder } from '@lblod/ember-rdfa-editor-lblod-plugins
|
|
|
33
33
|
import { hasDecendant } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/has-descendant';
|
|
34
34
|
import SnippetPlaceholder from '@lblod/ember-rdfa-editor-lblod-plugins/components/snippet-plugin/nodes/placeholder';
|
|
35
35
|
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';
|
|
36
37
|
|
|
37
38
|
interface ButtonSig {
|
|
38
39
|
Args: {
|
|
@@ -177,7 +178,7 @@ export default class SnippetNode extends Component<Signature> {
|
|
|
177
178
|
return ancestor && ancestor.node === this.node;
|
|
178
179
|
}
|
|
179
180
|
@action
|
|
180
|
-
onInsert(
|
|
181
|
+
onInsert(snippet: Snippet) {
|
|
181
182
|
this.closeModal();
|
|
182
183
|
let start = 0;
|
|
183
184
|
let end = 0;
|
|
@@ -196,8 +197,8 @@ export default class SnippetNode extends Component<Signature> {
|
|
|
196
197
|
}
|
|
197
198
|
this.controller.doCommand(
|
|
198
199
|
insertSnippet({
|
|
199
|
-
content,
|
|
200
|
-
title,
|
|
200
|
+
content: snippet.content?.toHTML() ?? '',
|
|
201
|
+
title: snippet.title ?? '',
|
|
201
202
|
listProperties: {
|
|
202
203
|
placeholderId: this.node.attrs.placeholderId,
|
|
203
204
|
listUris: getSnippetListUrisFromNode(this.node),
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import pagination from '@lblod/ember-rdfa-editor-lblod-plugins/helpers/pagination';
|
|
2
|
+
import Component from '@glimmer/component';
|
|
3
|
+
import { assert } from '@ember/debug';
|
|
4
|
+
import { action } from '@ember/object';
|
|
5
|
+
import { restartableTask, timeout } from 'ember-concurrency';
|
|
6
|
+
import { task as trackedTask } from 'reactiveweb/ember-concurrency';
|
|
7
|
+
import { tracked } from '@glimmer/tracking';
|
|
8
|
+
import { on } from '@ember/modifier';
|
|
9
|
+
import t from 'ember-intl/helpers/t';
|
|
10
|
+
import { not } from 'ember-truth-helpers';
|
|
11
|
+
import AuModal from '@appuniversum/ember-appuniversum/components/au-modal';
|
|
12
|
+
import AuMainContainer from '@appuniversum/ember-appuniversum/components/au-main-container';
|
|
13
|
+
import AuHeading from '@appuniversum/ember-appuniversum/components/au-heading';
|
|
14
|
+
import AuLabel from '@appuniversum/ember-appuniversum/components/au-label';
|
|
15
|
+
|
|
16
|
+
import AuNativeInput from '@lblod/ember-rdfa-editor-lblod-plugins/components/au-native-input';
|
|
17
|
+
import Loading from '@lblod/ember-rdfa-editor-lblod-plugins/components/common/search/loading';
|
|
18
|
+
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
|
+
import {
|
|
21
|
+
Snippet,
|
|
22
|
+
SnippetPluginConfig,
|
|
23
|
+
} from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/snippet-plugin';
|
|
24
|
+
import PreviewList from '@lblod/ember-rdfa-editor-lblod-plugins/components/common/documents/preview-list';
|
|
25
|
+
import AlertNoItems from '@lblod/ember-rdfa-editor-lblod-plugins/components/common/search/alert-no-items';
|
|
26
|
+
import PaginationView from '@lblod/ember-rdfa-editor-lblod-plugins/components/pagination/pagination-view';
|
|
27
|
+
|
|
28
|
+
interface Args {
|
|
29
|
+
config: SnippetPluginConfig;
|
|
30
|
+
snippetListUris: string[] | undefined;
|
|
31
|
+
snippetListNames: string[] | undefined;
|
|
32
|
+
closeModal: () => void;
|
|
33
|
+
open: boolean;
|
|
34
|
+
onInsert: (snippet: Snippet) => void;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export default class SnippetPluginSearchModalComponent extends Component<Args> {
|
|
38
|
+
// Filtering
|
|
39
|
+
@tracked inputSearchText: string | null = null;
|
|
40
|
+
|
|
41
|
+
// Display
|
|
42
|
+
@tracked error: unknown;
|
|
43
|
+
|
|
44
|
+
// Pagination
|
|
45
|
+
@tracked pageNumber = 0;
|
|
46
|
+
@tracked pageSize = 20;
|
|
47
|
+
@tracked totalCount = 0;
|
|
48
|
+
|
|
49
|
+
get config() {
|
|
50
|
+
return this.args.config;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
get searchText() {
|
|
54
|
+
return this.inputSearchText;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
get snippetListNames() {
|
|
58
|
+
return this.args.snippetListNames?.map((name) => `"${name}"`).join(', ');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@action
|
|
62
|
+
setInputSearchText(event: InputEvent) {
|
|
63
|
+
assert(
|
|
64
|
+
'inputSearchText must be bound to an input element',
|
|
65
|
+
event.target instanceof HTMLInputElement,
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
this.inputSearchText = event.target.value;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
@action
|
|
72
|
+
async closeModal() {
|
|
73
|
+
await this.snippetsResource.cancel();
|
|
74
|
+
this.args.closeModal();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
snippetsSearch = restartableTask(async () => {
|
|
78
|
+
await timeout(500);
|
|
79
|
+
|
|
80
|
+
const abortController = new AbortController();
|
|
81
|
+
|
|
82
|
+
try {
|
|
83
|
+
const queryResult = await fetchSnippets({
|
|
84
|
+
endpoint: this.args.config.endpoint,
|
|
85
|
+
abortSignal: abortController.signal,
|
|
86
|
+
filter: {
|
|
87
|
+
name: this.inputSearchText ?? undefined,
|
|
88
|
+
snippetListUris: this.args.snippetListUris ?? undefined,
|
|
89
|
+
},
|
|
90
|
+
pagination: {
|
|
91
|
+
pageNumber: this.pageNumber,
|
|
92
|
+
pageSize: this.pageSize,
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
this.totalCount = queryResult.totalCount;
|
|
97
|
+
|
|
98
|
+
return queryResult.results;
|
|
99
|
+
} catch (error) {
|
|
100
|
+
this.error = error;
|
|
101
|
+
return [];
|
|
102
|
+
} finally {
|
|
103
|
+
abortController.abort();
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
snippetsResource = trackedTask<Snippet[]>(this, this.snippetsSearch, () => [
|
|
108
|
+
this.inputSearchText,
|
|
109
|
+
this.pageNumber,
|
|
110
|
+
this.pageSize,
|
|
111
|
+
this.args.snippetListUris,
|
|
112
|
+
]);
|
|
113
|
+
|
|
114
|
+
@action
|
|
115
|
+
previousPage() {
|
|
116
|
+
--this.pageNumber;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
@action
|
|
120
|
+
nextPage() {
|
|
121
|
+
++this.pageNumber;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
<template>
|
|
125
|
+
<AuModal
|
|
126
|
+
class='snippet-modal'
|
|
127
|
+
@modalOpen={{@open}}
|
|
128
|
+
@closeModal={{this.closeModal}}
|
|
129
|
+
@title={{t
|
|
130
|
+
'snippet-plugin.modal.title'
|
|
131
|
+
snippetListNames=this.snippetListNames
|
|
132
|
+
}}
|
|
133
|
+
@size='large'
|
|
134
|
+
@padding='none'
|
|
135
|
+
as |modal|
|
|
136
|
+
>
|
|
137
|
+
<modal.Body>
|
|
138
|
+
<AuMainContainer class='snippet-modal--main-container' as |mc|>
|
|
139
|
+
<mc.sidebar>
|
|
140
|
+
<div class='au-c-sidebar'>
|
|
141
|
+
<div class='au-c-sidebar__content au-u-padding'>
|
|
142
|
+
<AuHeading
|
|
143
|
+
@level='3'
|
|
144
|
+
@skin='4'
|
|
145
|
+
class='au-u-padding-bottom-small'
|
|
146
|
+
>
|
|
147
|
+
{{t 'snippet-plugin.modal.search.title'}}
|
|
148
|
+
</AuHeading>
|
|
149
|
+
<AuLabel
|
|
150
|
+
class='au-margin-bottom-small'
|
|
151
|
+
for='searchTerm'
|
|
152
|
+
@inline={{false}}
|
|
153
|
+
@required={{false}}
|
|
154
|
+
@error={{false}}
|
|
155
|
+
@warning={{false}}
|
|
156
|
+
>
|
|
157
|
+
{{t 'snippet-plugin.modal.search.label'}}
|
|
158
|
+
</AuLabel>
|
|
159
|
+
<AuNativeInput
|
|
160
|
+
@type='text'
|
|
161
|
+
@width='block'
|
|
162
|
+
id='searchTerm'
|
|
163
|
+
value={{this.searchText}}
|
|
164
|
+
placeholder={{t 'snippet-plugin.modal.search.placeholder'}}
|
|
165
|
+
{{on 'input' this.setInputSearchText}}
|
|
166
|
+
/>
|
|
167
|
+
</div>
|
|
168
|
+
</div>
|
|
169
|
+
</mc.sidebar>
|
|
170
|
+
<mc.content @scroll={{true}}>
|
|
171
|
+
<div class='au-u-padding-top snippet-modal--list-container'>
|
|
172
|
+
{{#if this.snippetsResource.isRunning}}
|
|
173
|
+
<div class='au-u-margin'>
|
|
174
|
+
<Loading />
|
|
175
|
+
</div>
|
|
176
|
+
{{else}}
|
|
177
|
+
{{#if this.error}}
|
|
178
|
+
<AlertLoadError @error={{this.error}} />
|
|
179
|
+
{{else}}
|
|
180
|
+
{{#if this.snippetsResource.value.length}}
|
|
181
|
+
<PreviewList
|
|
182
|
+
@docs={{this.snippetsResource.value}}
|
|
183
|
+
@onInsert={{@onInsert}}
|
|
184
|
+
/>
|
|
185
|
+
{{else}}
|
|
186
|
+
<AlertNoItems />
|
|
187
|
+
{{/if}}
|
|
188
|
+
{{/if}}
|
|
189
|
+
{{/if}}
|
|
190
|
+
</div>
|
|
191
|
+
{{#if this.snippetsResource.value.length}}
|
|
192
|
+
{{#let
|
|
193
|
+
(pagination
|
|
194
|
+
page=this.pageNumber
|
|
195
|
+
pageSize=this.pageSize
|
|
196
|
+
count=this.totalCount
|
|
197
|
+
)
|
|
198
|
+
as |pg|
|
|
199
|
+
}}
|
|
200
|
+
<PaginationView
|
|
201
|
+
@totalCount={{pg.count}}
|
|
202
|
+
@rangeStart={{pg.pageStart}}
|
|
203
|
+
@rangeEnd={{pg.pageEnd}}
|
|
204
|
+
@onNextPage={{this.nextPage}}
|
|
205
|
+
@onPreviousPage={{this.previousPage}}
|
|
206
|
+
@isFirstPage={{not pg.hasPreviousPage}}
|
|
207
|
+
@isLastPage={{not pg.hasNextPage}}
|
|
208
|
+
/>
|
|
209
|
+
{{/let}}
|
|
210
|
+
{{/if}}
|
|
211
|
+
</mc.content>
|
|
212
|
+
</AuMainContainer>
|
|
213
|
+
</modal.Body>
|
|
214
|
+
</AuModal>
|
|
215
|
+
</template>
|
|
216
|
+
}
|
|
@@ -10,7 +10,10 @@ import {
|
|
|
10
10
|
type SayController,
|
|
11
11
|
Slice,
|
|
12
12
|
} from '@lblod/ember-rdfa-editor';
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
Snippet,
|
|
15
|
+
SnippetPluginConfig,
|
|
16
|
+
} from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/snippet-plugin';
|
|
14
17
|
import { type SnippetListProperties } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/snippet-plugin';
|
|
15
18
|
import insertSnippet from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/snippet-plugin/commands/insert-snippet';
|
|
16
19
|
import SearchModal from './search-modal';
|
|
@@ -56,13 +59,13 @@ export default class SnippetInsertComponent extends Component<Sig> {
|
|
|
56
59
|
}
|
|
57
60
|
|
|
58
61
|
@action
|
|
59
|
-
onInsert(
|
|
62
|
+
onInsert(snippet: Snippet) {
|
|
60
63
|
this.closeModal();
|
|
61
64
|
if (this.args.listProperties) {
|
|
62
65
|
this.controller.doCommand(
|
|
63
66
|
insertSnippet({
|
|
64
|
-
content,
|
|
65
|
-
title,
|
|
67
|
+
content: snippet.content?.toHTML() ?? '',
|
|
68
|
+
title: snippet.title ?? '',
|
|
66
69
|
listProperties: this.args.listProperties,
|
|
67
70
|
allowMultipleSnippets: this.args.allowMultipleSnippets,
|
|
68
71
|
}),
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
{{! @glint-nocheck: not typesafe yet }}
|
|
2
|
-
<div
|
|
2
|
+
<div
|
|
3
|
+
class='au-u-background-gray-100 au-u-padding-tiny table-of-contents'
|
|
4
|
+
contenteditable='false'
|
|
5
|
+
>
|
|
3
6
|
<h3>{{this.title}}</h3>
|
|
4
7
|
{{#if this.outline}}
|
|
5
8
|
<TableOfContentsPlugin::EmberNodes::Outline
|
|
@@ -8,8 +8,8 @@ import { service } from '@ember/service';
|
|
|
8
8
|
import IntlService from 'ember-intl/services/intl';
|
|
9
9
|
export default class TableOfContentsComponent extends Component<EmberNodeArgs> {
|
|
10
10
|
@service declare intl: IntlService;
|
|
11
|
-
get config() {
|
|
12
|
-
return this.args.node.attrs['config'] as TableOfContentsConfig;
|
|
11
|
+
get config(): TableOfContentsConfig | undefined {
|
|
12
|
+
return this.args.node.attrs['config'] as TableOfContentsConfig | undefined;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
get documentLanguage() {
|
|
@@ -49,9 +49,14 @@ export default class TableOfContentsComponent extends Component<EmberNodeArgs> {
|
|
|
49
49
|
const coords = this.controller.mainEditorView.coordsAtPos(
|
|
50
50
|
selection.from,
|
|
51
51
|
);
|
|
52
|
-
|
|
52
|
+
let config;
|
|
53
|
+
if (Array.isArray(this.config)) {
|
|
54
|
+
config = this.config[0];
|
|
55
|
+
} else {
|
|
56
|
+
config = this.config;
|
|
57
|
+
}
|
|
53
58
|
let scrollContainer: HTMLElement | undefined;
|
|
54
|
-
if (config
|
|
59
|
+
if (config?.scrollContainer) {
|
|
55
60
|
scrollContainer = config.scrollContainer();
|
|
56
61
|
} else {
|
|
57
62
|
scrollContainer = this.getScrollContainer();
|
|
@@ -7,12 +7,24 @@ interface PaginationArguments {
|
|
|
7
7
|
pageSize: number;
|
|
8
8
|
page: number;
|
|
9
9
|
}
|
|
10
|
+
interface PaginationResult {
|
|
11
|
+
count: number;
|
|
12
|
+
pageSize: number;
|
|
13
|
+
page: number;
|
|
14
|
+
totalPages: number;
|
|
15
|
+
pageStart: number;
|
|
16
|
+
pageEnd: number;
|
|
17
|
+
nextPage: number | null;
|
|
18
|
+
previousPage: number | null;
|
|
19
|
+
hasPreviousPage: boolean;
|
|
20
|
+
hasNextPage: boolean;
|
|
21
|
+
}
|
|
10
22
|
|
|
11
23
|
export function pagination({
|
|
12
24
|
page = 0,
|
|
13
25
|
count = 0,
|
|
14
26
|
pageSize = 20,
|
|
15
|
-
}: PaginationArguments) {
|
|
27
|
+
}: PaginationArguments): PaginationResult {
|
|
16
28
|
const totalPages = count / pageSize;
|
|
17
29
|
const pageStart = page * pageSize + 1;
|
|
18
30
|
const pageEnd = Math.min((page + 1) * pageSize, count);
|
|
@@ -35,6 +47,6 @@ export function pagination({
|
|
|
35
47
|
};
|
|
36
48
|
}
|
|
37
49
|
|
|
38
|
-
export default helper<unknown[], PaginationArguments>(
|
|
39
|
-
pagination(named),
|
|
50
|
+
export default helper<unknown[], PaginationArguments, PaginationResult>(
|
|
51
|
+
(_, named) => pagination(named),
|
|
40
52
|
);
|