@lblod/ember-rdfa-editor-lblod-plugins 22.0.2 → 22.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/addon/commands/insert-data-table.ts +48 -0
  3. package/addon/components/lmb-plugin/search-modal.ts +2 -48
  4. package/addon/components/mandatee-table-plugin/configure.gts +122 -0
  5. package/addon/components/mandatee-table-plugin/insert.gts +53 -0
  6. package/addon/components/mandatee-table-plugin/node.gts +52 -0
  7. package/addon/plugins/besluit-topic-plugin/utils/helpers.ts +7 -3
  8. package/addon/plugins/lmb-plugin/utils/fetchMandatees.ts +55 -0
  9. package/addon/plugins/mandatee-table-plugin/index.ts +2 -0
  10. package/addon/plugins/mandatee-table-plugin/node.ts +58 -0
  11. package/addon/plugins/mandatee-table-plugin/sync-document.ts +40 -0
  12. package/addon/utils/build-data-table.ts +68 -0
  13. package/app/components/mandatee-table-plugin/configure.js +1 -0
  14. package/app/components/mandatee-table-plugin/insert.js +1 -0
  15. package/app/styles/mandatee-table-plugin.scss +14 -0
  16. package/declarations/addon/commands/insert-data-table.d.ts +12 -0
  17. package/declarations/addon/components/mandatee-table-plugin/configure.d.ts +25 -0
  18. package/declarations/addon/components/mandatee-table-plugin/insert.d.ts +15 -0
  19. package/declarations/addon/components/mandatee-table-plugin/node.d.ts +17 -0
  20. package/declarations/addon/plugins/besluit-topic-plugin/utils/helpers.d.ts +2 -2
  21. package/declarations/addon/plugins/lmb-plugin/utils/fetchMandatees.d.ts +6 -0
  22. package/declarations/addon/plugins/mandatee-table-plugin/index.d.ts +2 -0
  23. package/declarations/addon/plugins/mandatee-table-plugin/node.d.ts +4 -0
  24. package/declarations/addon/plugins/mandatee-table-plugin/sync-document.d.ts +9 -0
  25. package/declarations/addon/utils/build-data-table.d.ts +13 -0
  26. package/package.json +2 -2
  27. package/pnpm-lock.yaml +5 -5
  28. package/translations/en-US.yaml +15 -0
  29. package/translations/nl-BE.yaml +15 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # @lblod/ember-rdfa-editor-lblod-plugins
2
2
 
3
+ ## 22.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#460](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/pull/460) [`b792b75`](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/commit/b792b756267548d1b29fce8e9b8c64c3219b47b2) Thanks [@elpoelma](https://github.com/elpoelma)! - Addition of a mandatee table plugin
8
+ - Addition of a `mandatee_table` node-spec and `mandateeTableView` node-view
9
+ - `mandatee_table` nodes support two attributes: `tag` and `title` which can be configured by a template-creator
10
+ - Addition of two components used to insert and configure mandatee tables
11
+ - `MandateeTablePlugin::Insert` allows a user/template-creator to insert empty `mandatee_table` nodes
12
+ - `MandateeTablePlugin::Configure` allows a user/template-creator to configure the title/tag of a `mandatee_table` node
13
+ - Addition of a `syncDocument` function.
14
+ - Synchronizes the `mandatee_table` nodes in a document based on a supplied configuration
15
+ - Can work in a headless way (does not require a prosemirror view). It accepts and outputs a `ProseMirrorState` object.
16
+
17
+ ### Patch Changes
18
+
19
+ - [#459](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/pull/459) [`cfe0d3b`](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/commit/cfe0d3bdec8c9d3fe313b75eb3ed9a9aabd8fae1) Thanks [@lagartoverde](https://github.com/lagartoverde)! - Add body to templates so they can be inserted in the dummy app
20
+
3
21
  ## 22.0.2
4
22
 
5
23
  ### Patch Changes
@@ -0,0 +1,48 @@
1
+ import { Command } from '@lblod/ember-rdfa-editor';
2
+ import { buildDataTable } from '../utils/build-data-table';
3
+ interface HasToString {
4
+ toString(): string;
5
+ }
6
+
7
+ type Args<T extends string> = {
8
+ fields: readonly T[];
9
+ records: Record<T, HasToString>[];
10
+ includeHeader?: boolean;
11
+ labels?: Record<T, string>;
12
+ };
13
+
14
+ export function insertDataTable<T extends string>({
15
+ fields,
16
+ records,
17
+ includeHeader = true,
18
+ labels,
19
+ }: Args<T>): Command {
20
+ return (state, dispatch) => {
21
+ const {
22
+ schema,
23
+ selection: { $from },
24
+ } = state;
25
+
26
+ const specAllowSplitByTable = $from.parent.type.spec[
27
+ 'allowSplitByTable'
28
+ ] as boolean | undefined;
29
+
30
+ const allowSplitByTable: boolean =
31
+ specAllowSplitByTable === undefined ? true : specAllowSplitByTable;
32
+
33
+ if (!allowSplitByTable) return false;
34
+
35
+ if (dispatch) {
36
+ const tr = state.tr;
37
+ dispatch(
38
+ tr
39
+ .replaceSelectionWith(
40
+ buildDataTable({ schema, fields, records, includeHeader, labels }),
41
+ )
42
+ .scrollIntoView(),
43
+ );
44
+ }
45
+
46
+ return true;
47
+ };
48
+ }
@@ -7,7 +7,7 @@ import { task as trackedTask } from 'ember-resources/util/ember-concurrency';
7
7
  import { LmbPluginConfig } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/lmb-plugin';
8
8
 
9
9
  import Mandatee from '@lblod/ember-rdfa-editor-lblod-plugins/models/mandatee';
10
- import { IBindings } from 'fetch-sparql-endpoint';
10
+ import { fetchMandatees } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/lmb-plugin/utils/fetchMandatees';
11
11
  type SearchSort = [keyof Mandatee, 'ASC' | 'DESC'] | false;
12
12
 
13
13
  interface Args {
@@ -17,12 +17,6 @@ interface Args {
17
17
  onInsert: () => void;
18
18
  }
19
19
 
20
- interface SparqlResponse {
21
- results: {
22
- bindings: IBindings[];
23
- };
24
- }
25
-
26
20
  export default class LmbPluginSearchModalComponent extends Component<Args> {
27
21
  // Display
28
22
  @tracked error: unknown;
@@ -45,47 +39,7 @@ export default class LmbPluginSearchModalComponent extends Component<Args> {
45
39
  }
46
40
 
47
41
  fetchData = restartableTask(async () => {
48
- const endpoint = this.args.config.endpoint;
49
- const queryResponse = await fetch(endpoint, {
50
- method: 'POST',
51
- headers: {
52
- 'Content-Type': 'application/json',
53
- },
54
- body: JSON.stringify({
55
- query: `
56
- PREFIX besluit: <http://data.vlaanderen.be/ns/besluit#>
57
- PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
58
- PREFIX mandaat: <http://data.vlaanderen.be/ns/mandaat#>
59
- PREFIX foaf: <http://xmlns.com/foaf/0.1/>
60
- PREFIX persoon: <http://data.vlaanderen.be/ns/persoon#>
61
- PREFIX org: <http://www.w3.org/ns/org#>
62
- PREFIX regorg: <https://www.w3.org/ns/regorg#>
63
- SELECT DISTINCT ?mandatee ?person ?firstName ?lastName ?statusLabel ?fractieLabel ?roleLabel WHERE {
64
- ?mandatee a mandaat:Mandataris;
65
- org:holds ?mandaat;
66
- mandaat:status ?status;
67
- mandaat:isBestuurlijkeAliasVan ?person.
68
- ?person foaf:familyName ?lastName;
69
- persoon:gebruikteVoornaam ?firstName.
70
- ?status skos:prefLabel ?statusLabel.
71
- ?mandaat org:role ?role.
72
- ?role skos:prefLabel ?roleLabel.
73
- OPTIONAL {
74
- ?mandatee mandaat:einde ?endDate
75
- }
76
- OPTIONAL {
77
- ?mandatee org:hasMembership ?membership.
78
- ?membership org:organisation ?fractie.
79
- ?fractie regorg:legalName ?fractieLabel.
80
- }
81
- filter (!bound(?endDate) || ?endDate > now()).
82
- }
83
- `,
84
- }),
85
- });
86
- const queryJson: SparqlResponse = await queryResponse.json();
87
- const mandatees = queryJson.results.bindings.map(Mandatee.fromBinding);
88
- return mandatees;
42
+ return fetchMandatees({ endpoint: this.args.config.endpoint });
89
43
  });
90
44
 
91
45
  search = restartableTask(async () => {
@@ -0,0 +1,122 @@
1
+ import Component from '@glimmer/component';
2
+ import { SayController } from '@lblod/ember-rdfa-editor';
3
+ import { action } from '@ember/object';
4
+ import AuCard from '@appuniversum/ember-appuniversum/components/au-card';
5
+ import AuHeading from '@appuniversum/ember-appuniversum/components/au-heading';
6
+ import AuLabel from '@appuniversum/ember-appuniversum/components/au-label';
7
+ import AuInput from '@appuniversum/ember-appuniversum/components/au-input';
8
+ import PowerSelect from 'ember-power-select/components/power-select';
9
+ import { findParentNodeOfType } from '@curvenote/prosemirror-utils';
10
+ import { on } from '@ember/modifier';
11
+ import AuFormRow from '@appuniversum/ember-appuniversum/components/au-form-row';
12
+ import t from 'ember-intl/helpers/t';
13
+
14
+ interface Sig {
15
+ Args: { controller: SayController; supportedTags: string[] };
16
+ }
17
+
18
+ export default class ConfigureMandateeTableComponent extends Component<Sig> {
19
+ get controller() {
20
+ return this.args.controller;
21
+ }
22
+
23
+ get schema() {
24
+ return this.controller.schema;
25
+ }
26
+
27
+ get mandateeTableNode() {
28
+ const { mandatee_table } = this.schema.nodes;
29
+ if (!mandatee_table) {
30
+ return undefined;
31
+ }
32
+ return findParentNodeOfType(mandatee_table)(
33
+ this.controller.activeEditorState.selection,
34
+ );
35
+ }
36
+
37
+ get showCard() {
38
+ return Boolean(this.mandateeTableNode);
39
+ }
40
+
41
+ get currentTag() {
42
+ return this.mandateeTableNode?.node.attrs.tag as string | undefined;
43
+ }
44
+
45
+ get nodeTitle() {
46
+ return this.mandateeTableNode?.node.attrs.title as string | undefined;
47
+ }
48
+
49
+ updateAttribute(key: string, value: unknown) {
50
+ if (this.mandateeTableNode) {
51
+ const { pos } = this.mandateeTableNode;
52
+ this.controller.withTransaction((tr) => {
53
+ return tr.setNodeAttribute(pos, key, value);
54
+ });
55
+ }
56
+ }
57
+
58
+ @action
59
+ updateTag(tag: string) {
60
+ this.updateAttribute('tag', tag);
61
+ }
62
+
63
+ @action
64
+ updateNodeTitle(event: InputEvent) {
65
+ this.updateAttribute('title', (event.target as HTMLInputElement).value);
66
+ }
67
+
68
+ <template>
69
+ {{#if this.showCard}}
70
+ <AuCard
71
+ @flex={{true}}
72
+ @divided={{true}}
73
+ @isOpenInitially={{true}}
74
+ @expandable={{true}}
75
+ @shadow={{true}}
76
+ @size='small'
77
+ as |c|
78
+ >
79
+ <c.header>
80
+ <AuHeading @level='3' @skin='6'>
81
+ {{t 'mandatee-table-plugin.configure.title'}}
82
+ </AuHeading>
83
+ </c.header>
84
+ <c.content>
85
+ <AuFormRow>
86
+ <AuLabel for='mandatee-table-tag-select'>
87
+ {{t 'mandatee-table-plugin.configure.tag-input.label'}}
88
+ </AuLabel>
89
+ <PowerSelect
90
+ id='mandatee-table-tag-select'
91
+ @allowClear={{false}}
92
+ @searchEnabled={{false}}
93
+ @options={{@supportedTags}}
94
+ @selected={{this.currentTag}}
95
+ @onChange={{this.updateTag}}
96
+ @placeholder={{t
97
+ 'mandatee-table-plugin.configure.tag-input.placeholder'
98
+ }}
99
+ as |tag|
100
+ >
101
+ {{tag}}
102
+ </PowerSelect>
103
+ </AuFormRow>
104
+ <AuFormRow>
105
+ <AuLabel for='mandatee-table-title-input'>
106
+ {{t 'mandatee-table-plugin.configure.title-input.label'}}
107
+ </AuLabel>
108
+ <AuInput
109
+ @width='block'
110
+ placeholder={{t
111
+ 'mandatee-table-plugin.configure.title-input.placeholder'
112
+ }}
113
+ id='mandatee-table-title-input'
114
+ value={{this.nodeTitle}}
115
+ {{on 'input' this.updateNodeTitle}}
116
+ />
117
+ </AuFormRow>
118
+ </c.content>
119
+ </AuCard>
120
+ {{/if}}
121
+ </template>
122
+ }
@@ -0,0 +1,53 @@
1
+ import AuButton from '@appuniversum/ember-appuniversum/components/au-button';
2
+ import { AddIcon } from '@appuniversum/ember-appuniversum/components/icons/add';
3
+ import { on } from '@ember/modifier';
4
+ import Component from '@glimmer/component';
5
+ import { SayController } from '@lblod/ember-rdfa-editor';
6
+ import { not } from 'ember-truth-helpers';
7
+ import { getCurrentBesluitRange } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/besluit-topic-plugin/utils/helpers';
8
+ import { action } from '@ember/object';
9
+ import { unwrap } from '@lblod/ember-rdfa-editor/utils/_private/option';
10
+ import t from 'ember-intl/helpers/t';
11
+
12
+ interface Sig {
13
+ Args: { controller: SayController; defaultTag: string };
14
+ }
15
+
16
+ export default class InsertMandateeTableComponent extends Component<Sig> {
17
+ get controller() {
18
+ return this.args.controller;
19
+ }
20
+ get decisionRange() {
21
+ return getCurrentBesluitRange(this.controller);
22
+ }
23
+
24
+ @action
25
+ insert() {
26
+ const mandatee_table = unwrap(
27
+ this.controller.schema.nodes.mandatee_table.createAndFill({
28
+ tag: this.args.defaultTag,
29
+ }),
30
+ );
31
+ this.args.controller.withTransaction((tr) => {
32
+ return tr.replaceSelectionWith(mandatee_table);
33
+ });
34
+ }
35
+
36
+ get canInsert() {
37
+ return Boolean(this.decisionRange);
38
+ }
39
+
40
+ <template>
41
+ <li class='au-c-list__item'>
42
+ <AuButton
43
+ {{on 'click' this.insert}}
44
+ @icon={{AddIcon}}
45
+ @iconAlignment='left'
46
+ @skin='link'
47
+ @disabled={{not this.canInsert}}
48
+ >
49
+ {{t 'mandatee-table-plugin.insert.title'}}
50
+ </AuButton>
51
+ </li>
52
+ </template>
53
+ }
@@ -0,0 +1,52 @@
1
+ import AuIcon from '@appuniversum/ember-appuniversum/components/au-icon';
2
+
3
+ import { UserIcon } from '@appuniversum/ember-appuniversum/components/icons/user';
4
+ import { service } from '@ember/service';
5
+ import Component from '@glimmer/component';
6
+ import { EmberNodeArgs } from '@lblod/ember-rdfa-editor/utils/ember-node';
7
+ import IntlService from 'ember-intl/services/intl';
8
+
9
+ interface Sig {
10
+ Args: EmberNodeArgs;
11
+ Blocks: {
12
+ default: [];
13
+ };
14
+ }
15
+ export default class MandateeTableNode extends Component<Sig> {
16
+ @service declare intl: IntlService;
17
+
18
+ get controller() {
19
+ return this.args.controller;
20
+ }
21
+
22
+ get title() {
23
+ return this.args.node.attrs.title as string | undefined;
24
+ }
25
+
26
+ get documentLanguage() {
27
+ return this.controller.documentLanguage;
28
+ }
29
+
30
+ get warning() {
31
+ return this.intl.t('mandatee-table-plugin.node.warning', {
32
+ locale: this.documentLanguage,
33
+ });
34
+ }
35
+
36
+ <template>
37
+ <div class='say-mandatee-table-node'>
38
+ <div
39
+ class='say-mandatee-table-header au-u-flex au-u-flex--row au-u-flex--vertical-center'
40
+ >
41
+ <AuIcon @icon={{UserIcon}} @size='large' class='au-u-margin-small' />
42
+ <div>
43
+ <strong>{{this.title}}</strong>
44
+ <p>
45
+ {{this.warning}}
46
+ </p>
47
+ </div>
48
+ </div>
49
+ <div class='say-mandatee-table-content'>{{yield}}</div>
50
+ </div>
51
+ </template>
52
+ }
@@ -1,4 +1,4 @@
1
- import { PNode, SayController } from '@lblod/ember-rdfa-editor';
1
+ import { EditorState, PNode, SayController } from '@lblod/ember-rdfa-editor';
2
2
  import {
3
3
  BESLUIT,
4
4
  RDF,
@@ -9,9 +9,13 @@ import { ElementPNode } from '@lblod/ember-rdfa-editor/plugins/datastore';
9
9
  import { findAncestors } from '@lblod/ember-rdfa-editor/utils/position-utils';
10
10
 
11
11
  export const getCurrentBesluitRange = (
12
- controller: SayController,
12
+ controllerOrState: SayController | EditorState,
13
13
  ): ElementPNode | undefined => {
14
- const selection = controller.mainEditorState.selection;
14
+ const state =
15
+ controllerOrState instanceof SayController
16
+ ? controllerOrState.mainEditorState
17
+ : controllerOrState;
18
+ const selection = state.selection;
15
19
 
16
20
  const besluit =
17
21
  findAncestors(selection.$from, (node: PNode) => {
@@ -0,0 +1,55 @@
1
+ import Mandatee from '@lblod/ember-rdfa-editor-lblod-plugins/models/mandatee';
2
+ import { IBindings } from 'fetch-sparql-endpoint';
3
+
4
+ type SparqlResponse = {
5
+ results: {
6
+ bindings: IBindings[];
7
+ };
8
+ };
9
+
10
+ type FetchMandateesArgs = {
11
+ endpoint: string;
12
+ };
13
+
14
+ export async function fetchMandatees({ endpoint }: FetchMandateesArgs) {
15
+ const queryResponse = await fetch(endpoint, {
16
+ method: 'POST',
17
+ headers: {
18
+ 'Content-Type': 'application/json',
19
+ },
20
+ body: JSON.stringify({
21
+ query: `
22
+ PREFIX besluit: <http://data.vlaanderen.be/ns/besluit#>
23
+ PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
24
+ PREFIX mandaat: <http://data.vlaanderen.be/ns/mandaat#>
25
+ PREFIX foaf: <http://xmlns.com/foaf/0.1/>
26
+ PREFIX persoon: <http://data.vlaanderen.be/ns/persoon#>
27
+ PREFIX org: <http://www.w3.org/ns/org#>
28
+ PREFIX regorg: <https://www.w3.org/ns/regorg#>
29
+ SELECT DISTINCT ?mandatee ?person ?firstName ?lastName ?statusLabel ?fractieLabel ?roleLabel WHERE {
30
+ ?mandatee a mandaat:Mandataris;
31
+ org:holds ?mandaat;
32
+ mandaat:status ?status;
33
+ mandaat:isBestuurlijkeAliasVan ?person.
34
+ ?person foaf:familyName ?lastName;
35
+ persoon:gebruikteVoornaam ?firstName.
36
+ ?status skos:prefLabel ?statusLabel.
37
+ ?mandaat org:role ?role.
38
+ ?role skos:prefLabel ?roleLabel.
39
+ OPTIONAL {
40
+ ?mandatee mandaat:einde ?endDate
41
+ }
42
+ OPTIONAL {
43
+ ?mandatee org:hasMembership ?membership.
44
+ ?membership org:organisation ?fractie.
45
+ ?fractie regorg:legalName ?fractieLabel.
46
+ }
47
+ filter (!bound(?endDate) || ?endDate > now()).
48
+ }
49
+ `,
50
+ }),
51
+ });
52
+ const queryJson: SparqlResponse = await queryResponse.json();
53
+ const mandatees = queryJson.results.bindings.map(Mandatee.fromBinding);
54
+ return mandatees;
55
+ }
@@ -0,0 +1,2 @@
1
+ export * from './sync-document';
2
+ export * from './node';
@@ -0,0 +1,58 @@
1
+ import type { ComponentLike } from '@glint/template';
2
+ import {
3
+ createEmberNodeSpec,
4
+ createEmberNodeView,
5
+ EmberNodeConfig,
6
+ } from '@lblod/ember-rdfa-editor/utils/ember-node';
7
+ import MandateeTableNode from '@lblod/ember-rdfa-editor-lblod-plugins/components/mandatee-table-plugin/node';
8
+
9
+ export const emberNodeConfig: () => EmberNodeConfig = () => {
10
+ return {
11
+ name: 'mandatee-table',
12
+ component: MandateeTableNode as unknown as ComponentLike,
13
+ inline: false,
14
+ content: 'block+',
15
+ group: 'block',
16
+ draggable: false,
17
+ selectable: true,
18
+ editable: true,
19
+ atom: false,
20
+ isolating: true,
21
+ attrs: {
22
+ tag: {},
23
+ title: {
24
+ default: 'Mandatarissen',
25
+ },
26
+ },
27
+ serialize(node) {
28
+ const tag = node.attrs.tag as string;
29
+ const title = node.attrs.title as string;
30
+ return [
31
+ 'div',
32
+ {
33
+ 'data-mandatee-table': true,
34
+ 'data-tag': tag,
35
+ 'data-title': title,
36
+ },
37
+ 0,
38
+ ];
39
+ },
40
+ parseDOM: [
41
+ {
42
+ tag: 'div',
43
+ getAttrs(element: HTMLElement) {
44
+ if (element.dataset.mandateeTable && element.dataset.tag) {
45
+ return {
46
+ tag: element.dataset.tag,
47
+ title: element.dataset.title,
48
+ };
49
+ }
50
+ return false;
51
+ },
52
+ },
53
+ ],
54
+ };
55
+ };
56
+
57
+ export const mandatee_table = createEmberNodeSpec(emberNodeConfig());
58
+ export const mandateeTableView = createEmberNodeView(emberNodeConfig());
@@ -0,0 +1,40 @@
1
+ import { EditorState } from '@lblod/ember-rdfa-editor';
2
+ import {
3
+ TransactionMonad,
4
+ transactionCombinator,
5
+ } from '@lblod/ember-rdfa-editor/utils/transaction-utils';
6
+
7
+ export type MandateeTableTag = string;
8
+ export type MandateeTableConfig<R> = Record<
9
+ MandateeTableTag,
10
+ MandateeTableConfigEntry<R>
11
+ >;
12
+ export type MandateeTableConfigEntry<R> = {
13
+ query: () => Promise<R>;
14
+ updateContent: (pos: number, queryResult: R) => TransactionMonad<boolean>;
15
+ };
16
+
17
+ export async function syncDocument<R>(
18
+ state: EditorState,
19
+ config: MandateeTableConfig<R>,
20
+ ) {
21
+ const { doc, schema } = state;
22
+
23
+ const nodesToSync: { pos: number; tag: MandateeTableTag }[] = [];
24
+ const queries: Promise<R>[] = [];
25
+ doc.descendants((node, pos) => {
26
+ if (node.type === schema.nodes.mandatee_table) {
27
+ const tag = node.attrs.tag as MandateeTableTag;
28
+ nodesToSync.push({ pos, tag });
29
+ queries.push(config[node.attrs.tag as MandateeTableTag].query());
30
+ }
31
+ });
32
+ const queryResults = await Promise.all(queries);
33
+ const transactionMonads = [];
34
+ for (let i = nodesToSync.length - 1; i >= 0; i--) {
35
+ const { pos, tag } = nodesToSync[i];
36
+ transactionMonads.push(config[tag].updateContent(pos, queryResults[i]));
37
+ }
38
+ const { transaction } = transactionCombinator(state)(transactionMonads);
39
+ return state.applyTransaction(transaction).state;
40
+ }
@@ -0,0 +1,68 @@
1
+ import { PNode, Schema } from '@lblod/ember-rdfa-editor';
2
+ import { unwrap } from '../utils/option';
3
+ interface HasToString {
4
+ toString(): string;
5
+ }
6
+
7
+ type Args<T extends string> = {
8
+ schema: Schema;
9
+ fields: readonly T[];
10
+ records: Record<T, HasToString>[];
11
+ includeHeader?: boolean;
12
+ labels?: Record<T, string>;
13
+ };
14
+
15
+ export function buildDataTable<T extends string>({
16
+ schema,
17
+ fields,
18
+ records,
19
+ includeHeader = true,
20
+ labels,
21
+ }: Args<T>) {
22
+ const rows: PNode[] = [];
23
+ const proportionalWidth = 100 / fields.length;
24
+ if (includeHeader) {
25
+ const headerCells = [];
26
+ for (const field of fields) {
27
+ headerCells.push(
28
+ unwrap(
29
+ schema.nodes['table_header'].createAndFill(
30
+ proportionalWidth
31
+ ? {
32
+ colwidth: [proportionalWidth],
33
+ }
34
+ : undefined,
35
+ schema.nodes.paragraph.create(
36
+ null,
37
+ schema.text(labels?.[field] ?? field),
38
+ ),
39
+ ),
40
+ ),
41
+ );
42
+ }
43
+ rows.push(schema.node('table_row', null, headerCells));
44
+ }
45
+
46
+ for (const record of records) {
47
+ const cells = [];
48
+ for (const field of fields) {
49
+ cells.push(
50
+ unwrap(
51
+ schema.nodes['table_cell'].createAndFill(
52
+ proportionalWidth
53
+ ? {
54
+ colwidth: [proportionalWidth],
55
+ }
56
+ : undefined,
57
+ schema.nodes.paragraph.create(
58
+ null,
59
+ schema.text(record[field].toString()),
60
+ ),
61
+ ),
62
+ ),
63
+ );
64
+ }
65
+ rows.push(schema.node('table_row', null, cells));
66
+ }
67
+ return schema.node('table', null, rows);
68
+ }
@@ -0,0 +1 @@
1
+ export { default } from '@lblod/ember-rdfa-editor-lblod-plugins/components/mandatee-table-plugin/configure';
@@ -0,0 +1 @@
1
+ export { default } from '@lblod/ember-rdfa-editor-lblod-plugins/components/mandatee-table-plugin/insert';
@@ -0,0 +1,14 @@
1
+ .say-mandatee-table-node {
2
+ border: 1px solid var(--au-blue-300);
3
+ .say-mandatee-table-header {
4
+ display: flex;
5
+ flex-direction: row;
6
+ align-items: center;
7
+ background-color: var(--au-blue-300);
8
+ padding: 0.6rem 0.6rem 0.6rem 0;
9
+ cursor: default;
10
+ }
11
+ .say-mandatee-table-content {
12
+ padding: 1.2rem;
13
+ }
14
+ }
@@ -0,0 +1,12 @@
1
+ import { Command } from '@lblod/ember-rdfa-editor';
2
+ interface HasToString {
3
+ toString(): string;
4
+ }
5
+ type Args<T extends string> = {
6
+ fields: readonly T[];
7
+ records: Record<T, HasToString>[];
8
+ includeHeader?: boolean;
9
+ labels?: Record<T, string>;
10
+ };
11
+ export declare function insertDataTable<T extends string>({ fields, records, includeHeader, labels, }: Args<T>): Command;
12
+ export {};
@@ -0,0 +1,25 @@
1
+ import Component from '@glimmer/component';
2
+ import { SayController } from '@lblod/ember-rdfa-editor';
3
+ interface Sig {
4
+ Args: {
5
+ controller: SayController;
6
+ supportedTags: string[];
7
+ };
8
+ }
9
+ export default class ConfigureMandateeTableComponent extends Component<Sig> {
10
+ get controller(): SayController;
11
+ get schema(): import("prosemirror-model").Schema<any, any>;
12
+ get mandateeTableNode(): {
13
+ pos: number;
14
+ start: number;
15
+ depth: number;
16
+ node: import("prosemirror-model").Node;
17
+ } | undefined;
18
+ get showCard(): boolean;
19
+ get currentTag(): string | undefined;
20
+ get nodeTitle(): string | undefined;
21
+ updateAttribute(key: string, value: unknown): void;
22
+ updateTag(tag: string): void;
23
+ updateNodeTitle(event: InputEvent): void;
24
+ }
25
+ export {};
@@ -0,0 +1,15 @@
1
+ import Component from '@glimmer/component';
2
+ import { SayController } from '@lblod/ember-rdfa-editor';
3
+ interface Sig {
4
+ Args: {
5
+ controller: SayController;
6
+ defaultTag: string;
7
+ };
8
+ }
9
+ export default class InsertMandateeTableComponent extends Component<Sig> {
10
+ get controller(): SayController;
11
+ get decisionRange(): import("@lblod/ember-rdfa-editor/plugins/datastore").ElementPNode | undefined;
12
+ insert(): void;
13
+ get canInsert(): boolean;
14
+ }
15
+ export {};
@@ -0,0 +1,17 @@
1
+ import Component from '@glimmer/component';
2
+ import { EmberNodeArgs } from '@lblod/ember-rdfa-editor/utils/ember-node';
3
+ import IntlService from 'ember-intl/services/intl';
4
+ interface Sig {
5
+ Args: EmberNodeArgs;
6
+ Blocks: {
7
+ default: [];
8
+ };
9
+ }
10
+ export default class MandateeTableNode extends Component<Sig> {
11
+ intl: IntlService;
12
+ get controller(): import("@lblod/ember-rdfa-editor").SayController;
13
+ get title(): string | undefined;
14
+ get documentLanguage(): string;
15
+ get warning(): string;
16
+ }
17
+ export {};
@@ -1,4 +1,4 @@
1
- import { SayController } from '@lblod/ember-rdfa-editor';
1
+ import { EditorState, SayController } from '@lblod/ember-rdfa-editor';
2
2
  import { ElementPNode } from '@lblod/ember-rdfa-editor/plugins/datastore';
3
- export declare const getCurrentBesluitRange: (controller: SayController) => ElementPNode | undefined;
3
+ export declare const getCurrentBesluitRange: (controllerOrState: SayController | EditorState) => ElementPNode | undefined;
4
4
  export declare const getCurrentBesluitURI: (controller: SayController) => string | undefined;
@@ -0,0 +1,6 @@
1
+ import Mandatee from '@lblod/ember-rdfa-editor-lblod-plugins/models/mandatee';
2
+ type FetchMandateesArgs = {
3
+ endpoint: string;
4
+ };
5
+ export declare function fetchMandatees({ endpoint }: FetchMandateesArgs): Promise<Mandatee[]>;
6
+ export {};
@@ -0,0 +1,2 @@
1
+ export * from './sync-document';
2
+ export * from './node';
@@ -0,0 +1,4 @@
1
+ import { EmberNodeConfig } from '@lblod/ember-rdfa-editor/utils/ember-node';
2
+ export declare const emberNodeConfig: () => EmberNodeConfig;
3
+ export declare const mandatee_table: import("@lblod/ember-rdfa-editor/core/say-node-spec").default;
4
+ export declare const mandateeTableView: (controller: import("@lblod/ember-rdfa-editor").SayController) => import("@lblod/ember-rdfa-editor/utils/ember-node").SayNodeViewConstructor;
@@ -0,0 +1,9 @@
1
+ import { EditorState } from '@lblod/ember-rdfa-editor';
2
+ import { TransactionMonad } from '@lblod/ember-rdfa-editor/utils/transaction-utils';
3
+ export type MandateeTableTag = string;
4
+ export type MandateeTableConfig<R> = Record<MandateeTableTag, MandateeTableConfigEntry<R>>;
5
+ export type MandateeTableConfigEntry<R> = {
6
+ query: () => Promise<R>;
7
+ updateContent: (pos: number, queryResult: R) => TransactionMonad<boolean>;
8
+ };
9
+ export declare function syncDocument<R>(state: EditorState, config: MandateeTableConfig<R>): Promise<EditorState>;
@@ -0,0 +1,13 @@
1
+ import { PNode, Schema } from '@lblod/ember-rdfa-editor';
2
+ interface HasToString {
3
+ toString(): string;
4
+ }
5
+ type Args<T extends string> = {
6
+ schema: Schema;
7
+ fields: readonly T[];
8
+ records: Record<T, HasToString>[];
9
+ includeHeader?: boolean;
10
+ labels?: Record<T, string>;
11
+ };
12
+ export declare function buildDataTable<T extends string>({ schema, fields, records, includeHeader, labels, }: Args<T>): PNode;
13
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lblod/ember-rdfa-editor-lblod-plugins",
3
- "version": "22.0.2",
3
+ "version": "22.1.0",
4
4
  "description": "Ember addon providing lblod specific plugins for the ember-rdfa-editor",
5
5
  "keywords": [
6
6
  "ember-addon",
@@ -102,7 +102,7 @@
102
102
  "@glint/template": "^1.4.0",
103
103
  "@graphy/content.ttl.write": "^4.3.7",
104
104
  "@graphy/memory.dataset.fast": "4.3.3",
105
- "@lblod/ember-rdfa-editor": "10.0.1",
105
+ "@lblod/ember-rdfa-editor": "10.0.2",
106
106
  "@rdfjs/types": "^1.1.0",
107
107
  "@release-it/keep-a-changelog": "^4.0.0",
108
108
  "@tsconfig/ember": "^3.0.8",
package/pnpm-lock.yaml CHANGED
@@ -160,8 +160,8 @@ importers:
160
160
  specifier: 4.3.3
161
161
  version: 4.3.3
162
162
  '@lblod/ember-rdfa-editor':
163
- specifier: 10.0.1
164
- version: 10.0.1(2ef3gpurqxbttnmniw6grhzpuy)
163
+ specifier: 10.0.2
164
+ version: 10.0.2(2ef3gpurqxbttnmniw6grhzpuy)
165
165
  '@rdfjs/types':
166
166
  specifier: ^1.1.0
167
167
  version: 1.1.0
@@ -1586,8 +1586,8 @@ packages:
1586
1586
  '@jridgewell/trace-mapping@0.3.25':
1587
1587
  resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
1588
1588
 
1589
- '@lblod/ember-rdfa-editor@10.0.1':
1590
- resolution: {integrity: sha512-wYI3LIPQIMrulE1E1PzCrOhOpVgMEiEmGmMdThTYTljnZpzTJggGNqrJJCpVJ6wvaM4KFPZq3PtuRYeTfZlfeQ==}
1589
+ '@lblod/ember-rdfa-editor@10.0.2':
1590
+ resolution: {integrity: sha512-2tVTQeedXufvIPjt894Lr/7DpwdRXOH7WA5v2MK2Q4JMPdgTdLpb/JZYCrUIAVIen8qB/V2bFqcjNDitzrBq1w==}
1591
1591
  engines: {node: 16.* || 18.* || >= 20}
1592
1592
  peerDependencies:
1593
1593
  '@appuniversum/ember-appuniversum': ^3.4.2
@@ -10718,7 +10718,7 @@ snapshots:
10718
10718
  '@jridgewell/resolve-uri': 3.1.2
10719
10719
  '@jridgewell/sourcemap-codec': 1.4.15
10720
10720
 
10721
- '@lblod/ember-rdfa-editor@10.0.1(2ef3gpurqxbttnmniw6grhzpuy)':
10721
+ '@lblod/ember-rdfa-editor@10.0.2(2ef3gpurqxbttnmniw6grhzpuy)':
10722
10722
  dependencies:
10723
10723
  '@appuniversum/ember-appuniversum': 3.4.2(yenc6o4wruytt4u2jbwlbsqcl4)
10724
10724
  '@babel/core': 7.24.7
@@ -513,3 +513,18 @@ lpdc-plugin:
513
513
  name: Name
514
514
  search:
515
515
  placeholder: LPDC Name/Description
516
+
517
+ mandatee-table-plugin:
518
+ insert:
519
+ title: Insert mandatee table
520
+ configure:
521
+ title: Configure mandatee table
522
+ tag-input:
523
+ label: Tag
524
+ placeholder: Select tag
525
+ title-input:
526
+ label: Title
527
+ placeholder: Title
528
+ node:
529
+ warning: Information which you enter below may be removed upon
530
+ synchronisation of the inauguration meeting.
@@ -512,3 +512,18 @@ lpdc-plugin:
512
512
  name: Naam
513
513
  search:
514
514
  placeholder: LPDC-naam/beschrijving
515
+
516
+ mandatee-table-plugin:
517
+ insert:
518
+ title: Mandatarissen-tabel invoegen
519
+ configure:
520
+ title: Mandatarissen-tabel configureren
521
+ tag-input:
522
+ label: Tag
523
+ placeholder: Selecteer tag
524
+ title-input:
525
+ label: Titel
526
+ placeholder: Titel
527
+ node:
528
+ warning: Informatie die u hieronder manueel ingeeft, wordt mogelijks
529
+ verwijderd bij synchronisatie van de installatievergadering.