@lblod/ember-rdfa-editor-lblod-plugins 19.3.1 → 20.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/.dockerignore +3 -0
- package/CHANGELOG.md +14 -0
- package/addon/components/besluit-topic-plugin/besluit-topic-toolbar-dropdown.ts +8 -10
- package/addon/components/besluit-type-plugin/toolbar-dropdown.ts +4 -20
- package/addon/components/decision-plugin/decision-plugin-card.gts +231 -0
- package/addon/components/decision-plugin/insert-article.gts +81 -0
- package/addon/components/hover-tooltip.gts +68 -0
- package/addon/components/prosemirror-editor.hbs +15 -0
- package/addon/components/prosemirror-editor.ts +98 -0
- package/addon/components/roadsign-regulation-plugin/roadsign-regulation-card.ts +16 -19
- package/addon/components/roadsign-regulation-plugin/roadsigns-modal.ts +23 -3
- package/addon/components/structure-plugin/_private/control-card.gts +192 -0
- package/addon/components/structure-plugin/_private/structure.gts +159 -0
- package/addon/plugins/besluit-topic-plugin/utils/helpers.ts +19 -10
- package/addon/plugins/decision-plugin/commands/insert-article-command.ts +82 -0
- package/addon/plugins/decision-plugin/commands/insert-article-container.ts +33 -35
- package/addon/plugins/decision-plugin/commands/insert-description.ts +31 -28
- package/addon/plugins/decision-plugin/commands/insert-motivation.ts +106 -106
- package/addon/plugins/decision-plugin/commands/insert-title.ts +30 -28
- package/addon/plugins/decision-plugin/utils/build-article-structure.ts +44 -0
- package/addon/plugins/roadsign-regulation-plugin/index.ts +1 -0
- package/addon/plugins/structure-plugin/move-structure.ts +120 -0
- package/addon/plugins/structure-plugin/node.ts +148 -0
- package/addon/plugins/structure-plugin/recalculate-structure-numbers.ts +28 -0
- package/addon/utils/find-insertion-pos-in-node.ts +21 -0
- package/addon/utils/nested-prosemirror.ts +111 -0
- package/app/styles/structure-plugin.scss +53 -0
- package/declarations/addon/components/besluit-topic-plugin/besluit-topic-toolbar-dropdown.d.ts +2 -1
- package/declarations/addon/components/besluit-type-plugin/toolbar-dropdown.d.ts +1 -2
- package/declarations/addon/components/decision-plugin/decision-plugin-card.d.ts +20 -11
- package/declarations/addon/components/decision-plugin/insert-article.d.ts +23 -0
- package/declarations/addon/components/hover-tooltip.d.ts +26 -9
- package/declarations/addon/components/prosemirror-editor.d.ts +23 -0
- package/declarations/addon/components/roadsign-regulation-plugin/roadsigns-modal.d.ts +6 -0
- package/declarations/addon/components/structure-plugin/_private/control-card.d.ts +22 -0
- package/declarations/addon/components/structure-plugin/_private/structure.d.ts +32 -0
- package/declarations/addon/plugins/besluit-topic-plugin/utils/helpers.d.ts +2 -2
- package/declarations/addon/plugins/decision-plugin/commands/insert-article-command.d.ts +8 -0
- package/declarations/addon/plugins/decision-plugin/commands/insert-article-container.d.ts +4 -2
- package/declarations/addon/plugins/decision-plugin/commands/insert-description.d.ts +3 -2
- package/declarations/addon/plugins/decision-plugin/commands/insert-motivation.d.ts +3 -2
- package/declarations/addon/plugins/decision-plugin/commands/insert-title.d.ts +3 -2
- package/declarations/addon/plugins/decision-plugin/utils/build-article-structure.d.ts +2 -0
- package/declarations/addon/plugins/roadsign-regulation-plugin/index.d.ts +1 -0
- package/declarations/addon/plugins/structure-plugin/move-structure.d.ts +2 -0
- package/declarations/addon/plugins/structure-plugin/node.d.ts +4 -0
- package/declarations/addon/plugins/structure-plugin/recalculate-structure-numbers.d.ts +3 -0
- package/declarations/addon/utils/find-insertion-pos-in-node.d.ts +3 -0
- package/declarations/addon/utils/nested-prosemirror.d.ts +23 -0
- package/package.json +10 -5
- package/pnpm-lock.yaml +73 -14
- package/translations/en-US.yaml +9 -0
- package/translations/nl-BE.yaml +10 -3
- package/types/ember-power-select/components/power-select.d.ts +3 -3
- package/addon/components/decision-plugin/decision-plugin-card.hbs +0 -55
- package/addon/components/decision-plugin/decision-plugin-card.ts +0 -71
- package/addon/components/hover-tooltip.hbs +0 -12
- package/addon/components/hover-tooltip.ts +0 -41
package/.dockerignore
ADDED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @lblod/ember-rdfa-editor-lblod-plugins
|
|
2
2
|
|
|
3
|
+
## 20.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- [#440](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/pull/440) [`8c242fe2eda10725e2bce59a77c86e905b6878b9`](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/commit/8c242fe2eda10725e2bce59a77c86e905b6878b9) Thanks [@abeforgit](https://github.com/abeforgit)! - Convert plugins that used decision nodes to work on any nodes that have the rdf decision type
|
|
8
|
+
|
|
9
|
+
### Minor Changes
|
|
10
|
+
|
|
11
|
+
- [#440](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/pull/440) [`8c242fe2eda10725e2bce59a77c86e905b6878b9`](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/commit/8c242fe2eda10725e2bce59a77c86e905b6878b9) Thanks [@abeforgit](https://github.com/abeforgit)! - Add new structure node using a nodeview approach
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- [#441](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/pull/441) [`45aad15462f89eede7cd2633ccf129189367d8db`](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/commit/45aad15462f89eede7cd2633ccf129189367d8db) Thanks [@piemonkey](https://github.com/piemonkey)! - Fix docker image builds
|
|
16
|
+
|
|
3
17
|
## 19.3.1
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
|
@@ -2,7 +2,6 @@ import { tracked } from '@glimmer/tracking';
|
|
|
2
2
|
import Component from '@glimmer/component';
|
|
3
3
|
import { action } from '@ember/object';
|
|
4
4
|
import { SayController } from '@lblod/ember-rdfa-editor';
|
|
5
|
-
import { findAncestorOfType } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/article-structure-plugin/utils/structure';
|
|
6
5
|
import { trackedFunction } from 'ember-resources/util/function';
|
|
7
6
|
import { ELI } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/constants';
|
|
8
7
|
import { AlertTriangleIcon } from '@appuniversum/ember-appuniversum/components/icons/alert-triangle';
|
|
@@ -48,6 +47,13 @@ export default class BesluitTopicToolbarDropdownComponent extends Component<Args
|
|
|
48
47
|
get doc() {
|
|
49
48
|
return this.controller.mainEditorState.doc;
|
|
50
49
|
}
|
|
50
|
+
get decisionRange() {
|
|
51
|
+
return getCurrentBesluitRange(this.controller);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
get showCard() {
|
|
55
|
+
return !!this.decisionRange;
|
|
56
|
+
}
|
|
51
57
|
|
|
52
58
|
topics = trackedFunction(this, async () => {
|
|
53
59
|
const result = await fetchBesluitTopics({
|
|
@@ -74,11 +80,7 @@ export default class BesluitTopicToolbarDropdownComponent extends Component<Args
|
|
|
74
80
|
return;
|
|
75
81
|
}
|
|
76
82
|
|
|
77
|
-
const besluit =
|
|
78
|
-
this.controller.mainEditorState.selection,
|
|
79
|
-
this.controller.schema.nodes['besluit'],
|
|
80
|
-
);
|
|
81
|
-
|
|
83
|
+
const besluit = this.decisionRange;
|
|
82
84
|
if (!besluit) {
|
|
83
85
|
console.warn(
|
|
84
86
|
`We have a besluit URI (${currentBesluitURI}), but can't find a besluit ancestor`,
|
|
@@ -114,10 +116,6 @@ export default class BesluitTopicToolbarDropdownComponent extends Component<Args
|
|
|
114
116
|
}
|
|
115
117
|
}
|
|
116
118
|
|
|
117
|
-
get showCard() {
|
|
118
|
-
return !!getCurrentBesluitRange(this.controller);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
119
|
@action
|
|
122
120
|
upsertBesluitTopic(selected: BesluitTopic[]) {
|
|
123
121
|
this.besluitTopicsSelected = selected;
|
|
@@ -4,11 +4,9 @@ import { action } from '@ember/object';
|
|
|
4
4
|
import { addProperty, removeProperty } from '@lblod/ember-rdfa-editor/commands';
|
|
5
5
|
import { SayController } from '@lblod/ember-rdfa-editor';
|
|
6
6
|
import { sayDataFactory } from '@lblod/ember-rdfa-editor/core/say-data-factory';
|
|
7
|
-
import { ResolvedPNode } from '@lblod/ember-rdfa-editor/plugins/datastore';
|
|
8
7
|
import fetchBesluitTypes, {
|
|
9
8
|
BesluitType,
|
|
10
9
|
} from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/besluit-type-plugin/utils/fetchBesluitTypes';
|
|
11
|
-
import { findAncestorOfType } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/article-structure-plugin/utils/structure';
|
|
12
10
|
import { trackedFunction } from 'ember-resources/util/function';
|
|
13
11
|
import { unwrap } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/option';
|
|
14
12
|
import { BesluitTypePluginOptions } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/besluit-type-plugin';
|
|
@@ -18,6 +16,7 @@ import { AlertTriangleIcon } from '@appuniversum/ember-appuniversum/components/i
|
|
|
18
16
|
import { CrossIcon } from '@appuniversum/ember-appuniversum/components/icons/cross';
|
|
19
17
|
import { MailIcon } from '@appuniversum/ember-appuniversum/components/icons/mail';
|
|
20
18
|
import { CircleXIcon } from '@appuniversum/ember-appuniversum/components/icons/circle-x';
|
|
19
|
+
import { getCurrentBesluitRange } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/besluit-topic-plugin/utils/helpers';
|
|
21
20
|
|
|
22
21
|
type Args = {
|
|
23
22
|
controller: SayController;
|
|
@@ -65,20 +64,8 @@ export default class EditorPluginsToolbarDropdownComponent extends Component<Arg
|
|
|
65
64
|
return types;
|
|
66
65
|
});
|
|
67
66
|
|
|
68
|
-
get currentBesluitRange()
|
|
69
|
-
|
|
70
|
-
const besluit = findAncestorOfType(
|
|
71
|
-
selection,
|
|
72
|
-
this.controller.schema.nodes['besluit'],
|
|
73
|
-
);
|
|
74
|
-
if (!besluit) {
|
|
75
|
-
return undefined;
|
|
76
|
-
}
|
|
77
|
-
return {
|
|
78
|
-
node: besluit.node,
|
|
79
|
-
from: besluit.start - 1,
|
|
80
|
-
to: besluit.start + besluit.node.nodeSize - 1,
|
|
81
|
-
};
|
|
67
|
+
get currentBesluitRange() {
|
|
68
|
+
return getCurrentBesluitRange(this.controller);
|
|
82
69
|
}
|
|
83
70
|
|
|
84
71
|
get currentBesluitURI() {
|
|
@@ -98,10 +85,7 @@ export default class EditorPluginsToolbarDropdownComponent extends Component<Arg
|
|
|
98
85
|
if (!this.currentBesluitURI || !this.types.value) {
|
|
99
86
|
return;
|
|
100
87
|
}
|
|
101
|
-
const besluit =
|
|
102
|
-
this.controller.mainEditorState.selection,
|
|
103
|
-
this.controller.schema.nodes['besluit'],
|
|
104
|
-
);
|
|
88
|
+
const besluit = this.currentBesluitRange;
|
|
105
89
|
if (!besluit) {
|
|
106
90
|
console.warn(
|
|
107
91
|
`We have a besluit URI (${this.currentBesluitURI}), but can't find a besluit ancestor`,
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import Component from '@glimmer/component';
|
|
2
|
+
import { action } from '@ember/object';
|
|
3
|
+
import {
|
|
4
|
+
insertMotivation,
|
|
5
|
+
insertArticleContainer,
|
|
6
|
+
insertDescription,
|
|
7
|
+
insertTitle,
|
|
8
|
+
} from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/decision-plugin/commands';
|
|
9
|
+
import type { PNode, SayController, Selection } from '@lblod/ember-rdfa-editor';
|
|
10
|
+
import { service } from '@ember/service';
|
|
11
|
+
import IntlService from 'ember-intl/services/intl';
|
|
12
|
+
import { AlertTriangleIcon } from '@appuniversum/ember-appuniversum/components/icons/alert-triangle';
|
|
13
|
+
import { findAncestors } from '@lblod/ember-rdfa-editor/utils/position-utils';
|
|
14
|
+
import {
|
|
15
|
+
getOutgoingTriple,
|
|
16
|
+
hasOutgoingNamedNodeTriple,
|
|
17
|
+
} from '@lblod/ember-rdfa-editor-lblod-plugins/utils/namespace';
|
|
18
|
+
import {
|
|
19
|
+
BESLUIT,
|
|
20
|
+
ELI,
|
|
21
|
+
PROV,
|
|
22
|
+
RDF,
|
|
23
|
+
} from '@lblod/ember-rdfa-editor-lblod-plugins/utils/constants';
|
|
24
|
+
import { NodeWithPos } from '@curvenote/prosemirror-utils';
|
|
25
|
+
import AuAlert from '@appuniversum/ember-appuniversum/components/au-alert';
|
|
26
|
+
import AuButton from '@appuniversum/ember-appuniversum/components/au-button';
|
|
27
|
+
import { on } from '@ember/modifier';
|
|
28
|
+
import { not } from 'ember-truth-helpers';
|
|
29
|
+
import t from 'ember-intl/helpers/t';
|
|
30
|
+
import { TemplateOnlyComponent } from '@ember/component/template-only';
|
|
31
|
+
|
|
32
|
+
interface DecisionCardOptions {
|
|
33
|
+
articleUriGenerator?: () => string;
|
|
34
|
+
}
|
|
35
|
+
interface Sig {
|
|
36
|
+
Args: {
|
|
37
|
+
controller: SayController;
|
|
38
|
+
options?: DecisionCardOptions;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export default class DecisionPluginCard extends Component<Sig> {
|
|
43
|
+
@service declare intl: IntlService;
|
|
44
|
+
|
|
45
|
+
get controller() {
|
|
46
|
+
return this.args.controller;
|
|
47
|
+
}
|
|
48
|
+
get selection(): Selection {
|
|
49
|
+
return this.controller.mainEditorState.selection;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
get decisionNodeLocation(): NodeWithPos | null {
|
|
53
|
+
return (
|
|
54
|
+
findAncestors(this.selection.$from, (node: PNode) => {
|
|
55
|
+
return hasOutgoingNamedNodeTriple(
|
|
56
|
+
node.attrs,
|
|
57
|
+
RDF('type'),
|
|
58
|
+
BESLUIT('Besluit'),
|
|
59
|
+
);
|
|
60
|
+
})[0] ?? null
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@action
|
|
65
|
+
focus() {
|
|
66
|
+
this.controller.focus();
|
|
67
|
+
}
|
|
68
|
+
get canInsertTitle() {
|
|
69
|
+
return (
|
|
70
|
+
this.decisionNodeLocation &&
|
|
71
|
+
!getOutgoingTriple(this.decisionNodeLocation.node.attrs, ELI('title'))
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
@action
|
|
75
|
+
insertTitle() {
|
|
76
|
+
if (this.decisionNodeLocation) {
|
|
77
|
+
this.controller.doCommand(
|
|
78
|
+
insertTitle({
|
|
79
|
+
placeholderText: this.intl.t(
|
|
80
|
+
'besluit-plugin.placeholder.decision-title',
|
|
81
|
+
),
|
|
82
|
+
decisionLocation: this.decisionNodeLocation,
|
|
83
|
+
}),
|
|
84
|
+
{ view: this.controller.mainEditorView },
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
this.focus();
|
|
88
|
+
}
|
|
89
|
+
get canInsertDescription() {
|
|
90
|
+
return (
|
|
91
|
+
this.decisionNodeLocation &&
|
|
92
|
+
!getOutgoingTriple(
|
|
93
|
+
this.decisionNodeLocation.node.attrs,
|
|
94
|
+
ELI('description'),
|
|
95
|
+
)
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
@action
|
|
99
|
+
insertDescription() {
|
|
100
|
+
if (this.decisionNodeLocation) {
|
|
101
|
+
this.controller.doCommand(
|
|
102
|
+
insertDescription({
|
|
103
|
+
placeholderText: this.intl.t(
|
|
104
|
+
'besluit-plugin.placeholder.decision-description',
|
|
105
|
+
),
|
|
106
|
+
decisionLocation: this.decisionNodeLocation,
|
|
107
|
+
}),
|
|
108
|
+
{
|
|
109
|
+
view: this.controller.mainEditorView,
|
|
110
|
+
},
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
this.focus();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
get canInsertMotivation() {
|
|
117
|
+
return (
|
|
118
|
+
this.decisionNodeLocation &&
|
|
119
|
+
!getOutgoingTriple(
|
|
120
|
+
this.decisionNodeLocation.node.attrs,
|
|
121
|
+
BESLUIT('motivering'),
|
|
122
|
+
)
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
@action
|
|
127
|
+
insertMotivation() {
|
|
128
|
+
if (this.decisionNodeLocation) {
|
|
129
|
+
this.controller.doCommand(
|
|
130
|
+
insertMotivation({
|
|
131
|
+
intl: this.intl,
|
|
132
|
+
decisionLocation: this.decisionNodeLocation,
|
|
133
|
+
}),
|
|
134
|
+
{
|
|
135
|
+
view: this.controller.mainEditorView,
|
|
136
|
+
},
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
this.focus();
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
get missingArticleBlock() {
|
|
143
|
+
return (
|
|
144
|
+
this.decisionNodeLocation &&
|
|
145
|
+
!getOutgoingTriple(this.decisionNodeLocation.node.attrs, PROV('value'))
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
@action
|
|
149
|
+
insertArticleBlock() {
|
|
150
|
+
if (this.decisionNodeLocation) {
|
|
151
|
+
this.controller.doCommand(
|
|
152
|
+
insertArticleContainer({
|
|
153
|
+
intl: this.intl,
|
|
154
|
+
decisionLocation: this.decisionNodeLocation,
|
|
155
|
+
articleUriGenerator: this.args.options?.articleUriGenerator,
|
|
156
|
+
}),
|
|
157
|
+
{
|
|
158
|
+
view: this.controller.mainEditorView,
|
|
159
|
+
},
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
this.focus();
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
<template>
|
|
166
|
+
{{#if this.canInsertTitle}}
|
|
167
|
+
<ValidationCard
|
|
168
|
+
@enabled={{this.canInsertTitle}}
|
|
169
|
+
@title={{t 'besluit-plugin.missing-title-warning'}}
|
|
170
|
+
@onClickFix={{this.insertTitle}}
|
|
171
|
+
>
|
|
172
|
+
{{t 'besluit-plugin.insert.decision-title'}}
|
|
173
|
+
</ValidationCard>
|
|
174
|
+
{{/if}}
|
|
175
|
+
{{#if this.canInsertDescription}}
|
|
176
|
+
<ValidationCard
|
|
177
|
+
@enabled={{this.canInsertDescription}}
|
|
178
|
+
@title={{t 'besluit-plugin.missing-description-warning'}}
|
|
179
|
+
@onClickFix={{this.insertDescription}}
|
|
180
|
+
>
|
|
181
|
+
{{t 'besluit-plugin.insert.description'}}
|
|
182
|
+
</ValidationCard>
|
|
183
|
+
{{/if}}
|
|
184
|
+
{{#if this.canInsertMotivation}}
|
|
185
|
+
<ValidationCard
|
|
186
|
+
@enabled={{this.canInsertMotivation}}
|
|
187
|
+
@title={{t 'besluit-plugin.missing-motivation-warning'}}
|
|
188
|
+
@onClickFix={{this.insertMotivation}}
|
|
189
|
+
>
|
|
190
|
+
{{t 'besluit-plugin.insert.motivation'}}
|
|
191
|
+
</ValidationCard>
|
|
192
|
+
{{/if}}
|
|
193
|
+
{{#if this.missingArticleBlock}}
|
|
194
|
+
<ValidationCard
|
|
195
|
+
@enabled={{this.missingArticleBlock}}
|
|
196
|
+
@title={{t 'besluit-plugin.missing-article-block-warning'}}
|
|
197
|
+
@onClickFix={{this.insertArticleBlock}}
|
|
198
|
+
>
|
|
199
|
+
{{t 'besluit-plugin.insert.article-block'}}
|
|
200
|
+
</ValidationCard>
|
|
201
|
+
{{/if}}
|
|
202
|
+
</template>
|
|
203
|
+
}
|
|
204
|
+
interface ValidationCardSig {
|
|
205
|
+
Args: {
|
|
206
|
+
enabled: boolean;
|
|
207
|
+
onClickFix: () => void;
|
|
208
|
+
title: string;
|
|
209
|
+
};
|
|
210
|
+
Blocks: {
|
|
211
|
+
default: [];
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
const ValidationCard: TemplateOnlyComponent<ValidationCardSig> = <template>
|
|
215
|
+
<AuAlert
|
|
216
|
+
class='say-validation-alert'
|
|
217
|
+
@skin='warning'
|
|
218
|
+
@closable={{false}}
|
|
219
|
+
@icon={{AlertTriangleIcon}}
|
|
220
|
+
@title={{@title}}
|
|
221
|
+
>
|
|
222
|
+
<AuButton
|
|
223
|
+
@iconAlignment='left'
|
|
224
|
+
@skin='link-secondary'
|
|
225
|
+
@disabled={{not @enabled}}
|
|
226
|
+
{{on 'click' @onClickFix}}
|
|
227
|
+
>
|
|
228
|
+
{{yield}}
|
|
229
|
+
</AuButton>
|
|
230
|
+
</AuAlert>
|
|
231
|
+
</template>;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import AuButton from '@appuniversum/ember-appuniversum/components/au-button';
|
|
2
|
+
import { on } from '@ember/modifier';
|
|
3
|
+
import { action } from '@ember/object';
|
|
4
|
+
import Component from '@glimmer/component';
|
|
5
|
+
import { SayController } from '@lblod/ember-rdfa-editor';
|
|
6
|
+
import { getCurrentBesluitRange } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/besluit-topic-plugin/utils/helpers';
|
|
7
|
+
import insertArticle from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/decision-plugin/commands/insert-article-command';
|
|
8
|
+
import { buildArticleStructure } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/decision-plugin/utils/build-article-structure';
|
|
9
|
+
import t from 'ember-intl/helpers/t';
|
|
10
|
+
import { not } from 'ember-truth-helpers';
|
|
11
|
+
|
|
12
|
+
export interface InsertArticleOptions {
|
|
13
|
+
uriGenerator?: () => string;
|
|
14
|
+
}
|
|
15
|
+
interface Sig {
|
|
16
|
+
Args: { controller: SayController; options?: InsertArticleOptions };
|
|
17
|
+
}
|
|
18
|
+
export default class InsertArticleComponent extends Component<Sig> {
|
|
19
|
+
get controller() {
|
|
20
|
+
return this.args.controller;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
get schema() {
|
|
24
|
+
return this.controller.schema;
|
|
25
|
+
}
|
|
26
|
+
get decisionRange() {
|
|
27
|
+
return getCurrentBesluitRange(this.controller);
|
|
28
|
+
}
|
|
29
|
+
get decisionLocation() {
|
|
30
|
+
return this.decisionRange
|
|
31
|
+
? { pos: this.decisionRange.from, node: this.decisionRange.node }
|
|
32
|
+
: null;
|
|
33
|
+
}
|
|
34
|
+
get canInsert() {
|
|
35
|
+
if (!this.decisionLocation) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
const article = buildArticleStructure(
|
|
39
|
+
this.schema,
|
|
40
|
+
this.args.options?.uriGenerator,
|
|
41
|
+
);
|
|
42
|
+
return this.controller.checkCommand(
|
|
43
|
+
insertArticle({ node: article, decisionLocation: this.decisionLocation }),
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
@action
|
|
48
|
+
doInsert() {
|
|
49
|
+
const structureNode = buildArticleStructure(
|
|
50
|
+
this.schema,
|
|
51
|
+
this.args.options?.uriGenerator,
|
|
52
|
+
);
|
|
53
|
+
if (!structureNode) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (!this.decisionLocation) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
this.controller.doCommand(
|
|
60
|
+
insertArticle({
|
|
61
|
+
node: structureNode,
|
|
62
|
+
decisionLocation: this.decisionLocation,
|
|
63
|
+
}),
|
|
64
|
+
);
|
|
65
|
+
this.controller.focus();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
<template>
|
|
69
|
+
<li class='au-csidebar-list__item'>
|
|
70
|
+
<AuButton
|
|
71
|
+
@icon='add'
|
|
72
|
+
@iconAlignment='left'
|
|
73
|
+
@skin='link'
|
|
74
|
+
@disabled={{not this.canInsert}}
|
|
75
|
+
{{on 'click' this.doInsert}}
|
|
76
|
+
>
|
|
77
|
+
{{t 'besluit-plugin.insert.article'}}
|
|
78
|
+
</AuButton>
|
|
79
|
+
</li>
|
|
80
|
+
</template>
|
|
81
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { hash } from '@ember/helper';
|
|
2
|
+
import Component from '@glimmer/component';
|
|
3
|
+
import { tracked } from '@glimmer/tracking';
|
|
4
|
+
import { FunctionBasedModifier, modifier } from 'ember-modifier';
|
|
5
|
+
import { Velcro } from 'ember-velcro';
|
|
6
|
+
import { Signature as VelcroModifierSignature } from 'ember-velcro/modifiers/velcro';
|
|
7
|
+
import { ModifierLike } from '@glint/template';
|
|
8
|
+
export type Placement = VelcroModifierSignature['Args']['Named']['placement'];
|
|
9
|
+
|
|
10
|
+
interface HoverModifierSig {
|
|
11
|
+
Element: HTMLElement;
|
|
12
|
+
}
|
|
13
|
+
interface Sig {
|
|
14
|
+
Args: { placement?: Placement };
|
|
15
|
+
Blocks: {
|
|
16
|
+
hover: [
|
|
17
|
+
hover: {
|
|
18
|
+
velcroHook: ModifierLike<Velcro['velcroHook']>;
|
|
19
|
+
handleHover: ModifierLike<FunctionBasedModifier<HoverModifierSig>>;
|
|
20
|
+
},
|
|
21
|
+
];
|
|
22
|
+
tooltip: [loop: ModifierLike<Velcro['velcroLoop']>];
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export default class HoverTooltip extends Component<Sig> {
|
|
27
|
+
hover = modifier<HoverModifierSig>(
|
|
28
|
+
(element) => {
|
|
29
|
+
element.addEventListener('mouseenter', this.showTooltip);
|
|
30
|
+
element.addEventListener('mouseleave', this.hideTooltip);
|
|
31
|
+
element.addEventListener('focus', this.showTooltip);
|
|
32
|
+
element.addEventListener('blur', this.hideTooltip);
|
|
33
|
+
return () => {
|
|
34
|
+
element.removeEventListener('mouseenter', this.showTooltip);
|
|
35
|
+
element.removeEventListener('mouseleave', this.hideTooltip);
|
|
36
|
+
element.removeEventListener('focus', this.showTooltip);
|
|
37
|
+
element.removeEventListener('blur', this.hideTooltip);
|
|
38
|
+
};
|
|
39
|
+
},
|
|
40
|
+
{ eager: false },
|
|
41
|
+
);
|
|
42
|
+
@tracked tooltipOpen = false;
|
|
43
|
+
|
|
44
|
+
get placement(): Placement | undefined {
|
|
45
|
+
return this.args.placement ?? 'top';
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
showTooltip = () => {
|
|
49
|
+
this.tooltipOpen = true;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
hideTooltip = () => {
|
|
53
|
+
this.tooltipOpen = false;
|
|
54
|
+
};
|
|
55
|
+
<template>
|
|
56
|
+
<Velcro @placement={{this.placement}} as |velcro|>
|
|
57
|
+
{{#let velcro.loop as |loop|}}
|
|
58
|
+
{{yield
|
|
59
|
+
(hash velcroHook=velcro.hook handleHover=(modifier this.hover))
|
|
60
|
+
to='hover'
|
|
61
|
+
}}
|
|
62
|
+
{{#if this.tooltipOpen}}
|
|
63
|
+
{{yield loop to='tooltip'}}
|
|
64
|
+
{{/if}}
|
|
65
|
+
{{/let}}
|
|
66
|
+
</Velcro>
|
|
67
|
+
</template>
|
|
68
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{{! @glint-nocheck: not typesafe yet }}
|
|
2
|
+
{{! template-lint-disable no-bare-strings }}
|
|
3
|
+
{{#if @inline}}
|
|
4
|
+
<span
|
|
5
|
+
{{did-insert this.handleInit}}
|
|
6
|
+
{{did-update this.onContentUpdate @content}}
|
|
7
|
+
...attributes
|
|
8
|
+
/>
|
|
9
|
+
{{else}}
|
|
10
|
+
<div
|
|
11
|
+
{{did-insert this.handleInit}}
|
|
12
|
+
{{did-update this.onContentUpdate @content}}
|
|
13
|
+
...attributes
|
|
14
|
+
/>
|
|
15
|
+
{{/if}}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import {
|
|
2
|
+
EditorState,
|
|
3
|
+
NodeSelection,
|
|
4
|
+
ProseParser,
|
|
5
|
+
SayController,
|
|
6
|
+
SayView,
|
|
7
|
+
Schema,
|
|
8
|
+
Transaction,
|
|
9
|
+
} from '@lblod/ember-rdfa-editor';
|
|
10
|
+
import { action } from '@ember/object';
|
|
11
|
+
import Component from '@glimmer/component';
|
|
12
|
+
|
|
13
|
+
type Args = {
|
|
14
|
+
onInit?(view: SayView): void;
|
|
15
|
+
onUpdate?(content: string): void;
|
|
16
|
+
onFocus?(view: SayView): void;
|
|
17
|
+
getPos(): number;
|
|
18
|
+
schema: Schema;
|
|
19
|
+
content?: string;
|
|
20
|
+
inline?: boolean;
|
|
21
|
+
controller: SayController;
|
|
22
|
+
outerView: SayView;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export default class ProseMirrorEditor extends Component<Args> {
|
|
26
|
+
view?: SayView;
|
|
27
|
+
|
|
28
|
+
initialContent: string;
|
|
29
|
+
constructor(owner: unknown, args: Args) {
|
|
30
|
+
super(owner, args);
|
|
31
|
+
this.initialContent = this.args.content || '';
|
|
32
|
+
}
|
|
33
|
+
get outerView(): SayView {
|
|
34
|
+
return this.args.outerView;
|
|
35
|
+
}
|
|
36
|
+
@action
|
|
37
|
+
handleInit(target: HTMLElement) {
|
|
38
|
+
const state = EditorState.create({ schema: this.args.schema });
|
|
39
|
+
const parser = ProseParser.fromSchema(this.args.schema);
|
|
40
|
+
|
|
41
|
+
this.view = new SayView(
|
|
42
|
+
{ mount: target },
|
|
43
|
+
{
|
|
44
|
+
state,
|
|
45
|
+
domParser: parser,
|
|
46
|
+
dispatchTransaction: this.dispatch,
|
|
47
|
+
handleDOMEvents: {
|
|
48
|
+
mousedown: () => {
|
|
49
|
+
// Kludge to prevent issues due to the fact that the whole
|
|
50
|
+
// footnote is node-selected (and thus DOM-selected) when
|
|
51
|
+
// the parent editor is focused.
|
|
52
|
+
|
|
53
|
+
if (this.outerView.hasFocus()) this.view?.focus();
|
|
54
|
+
},
|
|
55
|
+
focus: () => {
|
|
56
|
+
const pos = this.args.getPos();
|
|
57
|
+
if (pos !== undefined) {
|
|
58
|
+
const outerSelectionTr = this.outerView.state.tr;
|
|
59
|
+
const outerSelection = new NodeSelection(
|
|
60
|
+
this.outerView.state.doc.resolve(pos),
|
|
61
|
+
);
|
|
62
|
+
outerSelectionTr.setSelection(outerSelection);
|
|
63
|
+
this.outerView.dispatch(outerSelectionTr);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (this.view) {
|
|
67
|
+
this.args.controller.setActiveView(this.view);
|
|
68
|
+
this.args.onFocus?.(this.view);
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
);
|
|
74
|
+
if (this.args.content) {
|
|
75
|
+
this.view.setHtmlContent(this.initialContent);
|
|
76
|
+
}
|
|
77
|
+
this.args.onInit?.(this.view);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
@action
|
|
81
|
+
onContentUpdate() {
|
|
82
|
+
if (this.view) {
|
|
83
|
+
const newContent = this.args.content;
|
|
84
|
+
const currentContent = this.view.htmlContent;
|
|
85
|
+
if (currentContent !== newContent) {
|
|
86
|
+
this.view.setHtmlContent(newContent ?? '');
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
dispatch = (tr: Transaction) => {
|
|
92
|
+
if (this.view) {
|
|
93
|
+
const newState = this.view.state.apply(tr);
|
|
94
|
+
this.view.updateState(newState);
|
|
95
|
+
this.args.onUpdate?.(this.view.htmlContent);
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { findParentNode } from '@curvenote/prosemirror-utils';
|
|
2
1
|
import { action } from '@ember/object';
|
|
3
2
|
import Component from '@glimmer/component';
|
|
4
3
|
import { tracked } from '@glimmer/tracking';
|
|
@@ -6,6 +5,7 @@ import { SayController } from '@lblod/ember-rdfa-editor';
|
|
|
6
5
|
import { AddIcon } from '@appuniversum/ember-appuniversum/components/icons/add';
|
|
7
6
|
import { OutgoingTriple } from '@lblod/ember-rdfa-editor/core/rdfa-processor';
|
|
8
7
|
import { RDF } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/constants';
|
|
8
|
+
import { getCurrentBesluitRange } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/besluit-topic-plugin/utils/helpers';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Card displaying a hint of the Date plugin
|
|
@@ -53,24 +53,21 @@ export default class RoadsignRegulationCard extends Component<Args> {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
get showCard() {
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
if (node.type === this.schema.nodes['besluit']) {
|
|
59
|
-
const properties = node.attrs.properties as OutgoingTriple[];
|
|
60
|
-
const decisionHasAcceptedType = Boolean(
|
|
61
|
-
properties.find((property) => {
|
|
62
|
-
const { predicate, object } = property;
|
|
63
|
-
return (
|
|
64
|
-
RDF('type').matches(predicate) &&
|
|
65
|
-
object.termType === 'NamedNode' &&
|
|
66
|
-
acceptedTypes.includes(object.value)
|
|
67
|
-
);
|
|
68
|
-
}),
|
|
69
|
-
);
|
|
70
|
-
return decisionHasAcceptedType;
|
|
71
|
-
}
|
|
56
|
+
const decisionRange = getCurrentBesluitRange(this.controller);
|
|
57
|
+
if (!decisionRange) {
|
|
72
58
|
return false;
|
|
73
|
-
}
|
|
74
|
-
|
|
59
|
+
}
|
|
60
|
+
const decisionNode = decisionRange.node;
|
|
61
|
+
const properties: OutgoingTriple[] = decisionNode.attrs.properties;
|
|
62
|
+
|
|
63
|
+
const decisionHasAcceptedType = properties.some((property) => {
|
|
64
|
+
const { predicate, object } = property;
|
|
65
|
+
return (
|
|
66
|
+
RDF('type').matches(predicate) &&
|
|
67
|
+
object.termType === 'NamedNode' &&
|
|
68
|
+
acceptedTypes.includes(object.value)
|
|
69
|
+
);
|
|
70
|
+
});
|
|
71
|
+
return decisionHasAcceptedType;
|
|
75
72
|
}
|
|
76
73
|
}
|