@lblod/ember-rdfa-editor-lblod-plugins 1.0.0-beta.7 → 1.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.
Files changed (43) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/addon/components/article-structure-plugin/structure-card.hbs +1 -1
  3. package/addon/components/besluit-type-plugin/toolbar-dropdown.hbs +5 -4
  4. package/addon/components/besluit-type-plugin/toolbar-dropdown.ts +7 -10
  5. package/addon/components/rdfa-date-plugin/card.hbs +87 -50
  6. package/addon/components/rdfa-date-plugin/card.ts +210 -61
  7. package/addon/components/rdfa-date-plugin/date-time-picker.hbs +5 -2
  8. package/addon/components/rdfa-date-plugin/date-time-picker.ts +11 -1
  9. package/addon/components/rdfa-date-plugin/help-modal.hbs +91 -0
  10. package/addon/components/rdfa-date-plugin/help-modal.ts +17 -0
  11. package/addon/components/rdfa-date-plugin/insert.ts +23 -0
  12. package/addon/components/roadsign-regulation-plugin/roadsign-regulation-card.hbs +2 -2
  13. package/addon/components/roadsign-regulation-plugin/roadsign-regulation-card.ts +8 -2
  14. package/addon/components/variable-plugin/insert-variable-card.hbs +1 -1
  15. package/addon/components/variable-plugin/template-variable-card.hbs +1 -1
  16. package/addon/plugins/article-structure-plugin/commands/insert-structure.ts +14 -2
  17. package/addon/plugins/article-structure-plugin/commands/move-selected-structure.ts +7 -7
  18. package/addon/plugins/article-structure-plugin/structures/article-paragraph.ts +4 -2
  19. package/addon/plugins/article-structure-plugin/structures/article.ts +4 -2
  20. package/addon/plugins/article-structure-plugin/structures/chapter.ts +2 -2
  21. package/addon/plugins/article-structure-plugin/structures/section.ts +2 -2
  22. package/addon/plugins/article-structure-plugin/structures/structure-header.ts +2 -0
  23. package/addon/plugins/article-structure-plugin/structures/subsection.ts +2 -2
  24. package/addon/plugins/article-structure-plugin/structures/title.ts +2 -2
  25. package/addon/plugins/article-structure-plugin/utils/structure.ts +2 -0
  26. package/addon/plugins/rdfa-date-plugin/index.ts +13 -10
  27. package/addon/plugins/rdfa-date-plugin/nodes/date.ts +22 -9
  28. package/addon/plugins/rdfa-date-plugin/utils.ts +72 -0
  29. package/addon/plugins/standard-template-plugin/utils/nodes.ts +3 -2
  30. package/addon/plugins/variable-plugin/nodes.ts +2 -0
  31. package/app/components/rdfa-date-plugin/help-modal.js +1 -0
  32. package/app/styles/date-plugin.scss +7 -1
  33. package/components/besluit-type-plugin/toolbar-dropdown.d.ts +3 -5
  34. package/components/rdfa-date-plugin/card.d.ts +28 -11
  35. package/components/rdfa-date-plugin/date-time-picker.d.ts +2 -0
  36. package/components/rdfa-date-plugin/help-modal.d.ts +10 -0
  37. package/components/rdfa-date-plugin/insert.d.ts +11 -0
  38. package/components/roadsign-regulation-plugin/roadsign-regulation-card.d.ts +2 -1
  39. package/package.json +5 -4
  40. package/plugins/rdfa-date-plugin/index.d.ts +2 -2
  41. package/plugins/rdfa-date-plugin/utils.d.ts +13 -0
  42. package/translations/en-US.yaml +39 -5
  43. package/translations/nl-BE.yaml +41 -10
@@ -0,0 +1,91 @@
1
+ <AuModal
2
+ @title={{t 'date-plugin.help.title'}}
3
+ @closeModal={{@closeModal}}
4
+ @modalOpen={{@modalOpen}}
5
+ @size='default'
6
+ as |Modal|>
7
+ <Modal.Body>
8
+ <div>
9
+ <p>{{t 'date-plugin.help.first-line'}}</p>
10
+ {{t 'date-plugin.help.examples'}}
11
+ <AuTable>
12
+ <:header>
13
+ <tr>
14
+ <th>{{t 'date-plugin.help.name'}}</th>
15
+ <th>{{t 'date-plugin.help.symbol'}}</th>
16
+ <th>{{t 'date-plugin.help.result'}}</th>
17
+ </tr>
18
+ </:header>
19
+ <:body>
20
+ <tr>
21
+ <td>{{t 'date-plugin.help.short-weekday-title'}}</td>
22
+ <td>E</td>
23
+ <td>{{this.formatExample 'E'}}</td>
24
+ </tr>
25
+ <tr>
26
+ <td>{{t 'date-plugin.help.long-weekday-title'}}</td>
27
+ <td>EEEE</td>
28
+ <td>{{this.formatExample 'EEEE'}}</td>
29
+ </tr>
30
+ <tr>
31
+ <td>{{t 'date-plugin.help.month-day'}}</td>
32
+ <td>dd</td>
33
+ <td>{{this.formatExample 'dd'}}</td>
34
+ </tr>
35
+ <tr>
36
+ <td>{{t 'date-plugin.help.short-month'}}</td>
37
+ <td>MM</td>
38
+ <td>{{this.formatExample 'MM'}}</td>
39
+ </tr>
40
+ <tr>
41
+ <td>{{t 'date-plugin.help.long-month-title'}}</td>
42
+ <td>MMMM</td>
43
+ <td>{{this.formatExample 'MMMM'}}</td>
44
+ </tr>
45
+ <tr>
46
+ <td>{{t 'date-plugin.help.long-year'}}</td>
47
+ <td>yyyy</td>
48
+ <td>{{this.formatExample 'yyyy'}}</td>
49
+ </tr>
50
+ </:body>
51
+ </AuTable>
52
+ <p>{{t "date-plugin.help.detailed-info"}} <a href="https://date-fns.org/v2.29.3/docs/format">{{t
53
+ "date-plugin.help.docs-link"}}</a></p>
54
+ <p>{{t "date-plugin.help.date-examples"}}</p>
55
+ <AuTable>
56
+ <:header>
57
+ <tr>
58
+ <th>{{t "date-plugin.help.date-format"}}</th>
59
+ <th>{{t "date-plugin.help.result"}}</th>
60
+ </tr>
61
+ </:header>
62
+ <:body>
63
+ <tr>
64
+ <td>EEEE dd MMMM yyyy</td>
65
+ <td>{{this.formatExample 'EEEE dd MMMM yyyy'}}</td>
66
+ </tr>
67
+ <tr>
68
+ <td>dd/MM/yy</td>
69
+ <td>{{this.formatExample 'dd/MM/yy'}}</td>
70
+ </tr>
71
+ <tr>
72
+ <td>dd/M/yyyy</td>
73
+ <td>{{this.formatExample 'dd/M/yyyy'}}</td>
74
+ </tr>
75
+ <tr>
76
+ <td>dd/MM/yy hh:mm:ss</td>
77
+ <td>{{this.formatExample 'dd/MM/yy hh:mm:ss'}}</td>
78
+ </tr>
79
+ <tr>
80
+ <td>'Vandaag is' dd/MM/yy BBBB</td>
81
+ <td>{{this.formatExample "'Vandaag is' dd/MM/yy BBBB"}}</td>
82
+ </tr>
83
+ <tr>
84
+ <td>PPPPpppp</td>
85
+ <td>{{this.formatExample 'PPPPpppp'}}</td>
86
+ </tr>
87
+ </:body>
88
+ </AuTable>
89
+ </div>
90
+ </Modal.Body>
91
+ </AuModal>
@@ -0,0 +1,17 @@
1
+ import { action } from '@ember/object';
2
+ import Component from '@glimmer/component';
3
+ import { formatDate } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/rdfa-date-plugin/utils';
4
+
5
+ interface Args {
6
+ modalOpen: boolean;
7
+ closeModal: () => void;
8
+ }
9
+
10
+ export default class HelpModalComponent extends Component<Args> {
11
+ exampleDate: Date = new Date();
12
+
13
+ @action
14
+ formatExample(format: string) {
15
+ return formatDate(this.exampleDate, format);
16
+ }
17
+ }
@@ -2,9 +2,17 @@ import Component from '@glimmer/component';
2
2
  import { action } from '@ember/object';
3
3
  import { ProseController } from '@lblod/ember-rdfa-editor/core/prosemirror';
4
4
  import { NodeSelection } from '@lblod/ember-rdfa-editor';
5
+ import { DateFormat } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/rdfa-date-plugin';
6
+ import { Option } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/option';
5
7
 
6
8
  type Args = {
7
9
  controller: ProseController;
10
+ widgetArgs: {
11
+ options: {
12
+ formats: [DateFormat];
13
+ allowCustomFormat: boolean;
14
+ };
15
+ };
8
16
  };
9
17
 
10
18
  export default class RdfaDatePluginInsertComponent extends Component<Args> {
@@ -16,12 +24,27 @@ export default class RdfaDatePluginInsertComponent extends Component<Args> {
16
24
  return this.controller.schema;
17
25
  }
18
26
 
27
+ get formats(): DateFormat[] {
28
+ return this.args.widgetArgs.options.formats;
29
+ }
30
+
31
+ get defaultDateFormat(): Option<string> {
32
+ return this.formats[0].dateFormat;
33
+ }
34
+
35
+ get defaultDateTimeFormat(): Option<string> {
36
+ return this.formats[0].dateTimeFormat;
37
+ }
38
+
19
39
  @action
20
40
  insertDate(onlyDate: boolean) {
21
41
  this.controller.withTransaction((tr) => {
22
42
  tr.replaceSelectionWith(
23
43
  this.schema.node('date', {
24
44
  onlyDate,
45
+ format: onlyDate
46
+ ? this.defaultDateFormat
47
+ : this.defaultDateTimeFormat,
25
48
  })
26
49
  );
27
50
  if (tr.selection.$anchor.nodeBefore) {
@@ -4,9 +4,9 @@
4
4
  @icon="add"
5
5
  @iconAlignment="left"
6
6
  @disabled={{not this.showCard}}
7
- {{on "click" this.toggleModal}}
7
+ {{on "click" this.openModal}}
8
8
  >
9
9
  Voeg mobiliteitsmaatregel in
10
10
  </AuButton>
11
11
  </AuList::Item>
12
- <RoadsignRegulationPlugin::RoadsignsModal @modalOpen={{this.modalOpen}} @closeModal={{this.toggleModal}} @controller={{@controller}}/>
12
+ <RoadsignRegulationPlugin::RoadsignsModal @modalOpen={{this.modalOpen}} @closeModal={{this.closeModal}} @controller={{@controller}}/>
@@ -29,8 +29,14 @@ export default class RoadsignRegulationCard extends Component<Args> {
29
29
  @tracked modalOpen = false;
30
30
 
31
31
  @action
32
- toggleModal() {
33
- this.modalOpen = !this.modalOpen;
32
+ openModal() {
33
+ this.controller.focus();
34
+ this.modalOpen = true;
35
+ }
36
+
37
+ @action
38
+ closeModal() {
39
+ this.modalOpen = false;
34
40
  }
35
41
 
36
42
  get controller() {
@@ -2,7 +2,7 @@
2
2
  <AuCard @flex={{true}} @divided={{true}} @isOpenInitially={{true}} @expandable={{true}} @shadow={{true}} @size="small" as |c|>
3
3
  <c.header>
4
4
  <AuHeading @level="3" @skin="6">
5
- {{t "variable-plugin.insertVariable"}}
5
+ {{t "variable-plugin.insert-variable"}}
6
6
  </AuHeading>
7
7
  </c.header>
8
8
  <c.content>
@@ -3,7 +3,7 @@
3
3
  <AuCard @flex={{true}} @divided={{true}} @isOpenInitially={{true}} @expandable={{true}} @shadow={{true}} @size="small" as |c|>
4
4
  <c.header>
5
5
  <AuHeading @level="3" @skin="6">
6
- {{t "variable-plugin.enterVariableValue"}}
6
+ {{t "variable-plugin.enter-variable-value"}}
7
7
  </AuHeading>
8
8
  </c.header>
9
9
  <c.content>
@@ -108,8 +108,20 @@ function findInsertionRange(args: {
108
108
  return false;
109
109
  };
110
110
  const nextContainerRange =
111
- findNodes(doc, selection.from, true, false, filterFunction).next().value ??
112
- findNodes(doc, selection.from, true, true, filterFunction).next().value;
111
+ findNodes({
112
+ doc,
113
+ start: selection.from,
114
+ visitParentUpwards: true,
115
+ reverse: false,
116
+ filter: filterFunction,
117
+ }).next().value ??
118
+ findNodes({
119
+ doc,
120
+ start: selection.from,
121
+ visitParentUpwards: true,
122
+ reverse: true,
123
+ filter: filterFunction,
124
+ }).next().value;
113
125
  if (nextContainerRange) {
114
126
  const { from, to } = nextContainerRange;
115
127
  const containerNode = doc.nodeAt(from);
@@ -111,12 +111,12 @@ export function calculateInsertionRange(args: {
111
111
  to: limitContainer.pos + limitContainer.node.nodeSize,
112
112
  }
113
113
  : { from: 0, to: doc.nodeSize };
114
- const containerRange = findNodes(
114
+ const containerRange = findNodes({
115
115
  doc,
116
- pos,
117
- true,
118
- direction === 'up',
119
- ({ from, to }) => {
116
+ start: pos,
117
+ visitParentUpwards: true,
118
+ reverse: direction === 'up',
119
+ filter: ({ from, to }) => {
120
120
  if (from >= limitContainerRange.from && to <= limitContainerRange.to) {
121
121
  const node = doc.nodeAt(from);
122
122
  if (node && node !== containerNode) {
@@ -127,8 +127,8 @@ export function calculateInsertionRange(args: {
127
127
  }
128
128
  }
129
129
  return false;
130
- }
131
- ).next().value;
130
+ },
131
+ }).next().value;
132
132
  if (containerRange) {
133
133
  const { from, to } = containerRange;
134
134
  const containerNode = doc.nodeAt(from);
@@ -17,8 +17,8 @@ export const articleParagraphSpec: StructureSpec = {
17
17
  translations: {
18
18
  insert: 'article-structure-plugin.insert.paragraph',
19
19
  move: {
20
- up: 'article-structure-plugin.moveUp.paragraph',
21
- down: 'article-structure-plugin.moveDown.paragraph',
20
+ up: 'article-structure-plugin.move-up.paragraph',
21
+ down: 'article-structure-plugin.move-down.paragraph',
22
22
  },
23
23
  remove: 'article-structure-plugin.remove.paragraph',
24
24
  },
@@ -49,6 +49,8 @@ const contentSelector = `span[property~='${SAY('body').prefixed}'],
49
49
  export const article_paragraph: NodeSpec = {
50
50
  content: 'inline*',
51
51
  inline: false,
52
+ isolating: true,
53
+ defining: true,
52
54
  attrs: {
53
55
  typeof: {
54
56
  default: SAY('Paragraph').prefixed,
@@ -23,8 +23,8 @@ export const articleSpec: StructureSpec = {
23
23
  translations: {
24
24
  insert: 'article-structure-plugin.insert.article',
25
25
  move: {
26
- up: 'article-structure-plugin.moveUp.article',
27
- down: 'article-structure-plugin.moveDown.article',
26
+ up: 'article-structure-plugin.move-up.article',
27
+ down: 'article-structure-plugin.move-down.article',
28
28
  },
29
29
  remove: 'article-structure-plugin.remove.article',
30
30
  },
@@ -85,6 +85,8 @@ export const article = constructStructureNodeSpec({
85
85
  export const article_header: NodeSpec = {
86
86
  content: 'text*|placeholder',
87
87
  inline: false,
88
+ isolating: true,
89
+ defining: true,
88
90
  attrs: {
89
91
  number: {
90
92
  default: '1',
@@ -18,8 +18,8 @@ export const chapterSpec: StructureSpec = {
18
18
  translations: {
19
19
  insert: 'article-structure-plugin.insert.chapter',
20
20
  move: {
21
- up: 'article-structure-plugin.moveUp.chapter',
22
- down: 'article-structure-plugin.moveDown.chapter',
21
+ up: 'article-structure-plugin.move-up.chapter',
22
+ down: 'article-structure-plugin.move-down.chapter',
23
23
  },
24
24
  remove: 'article-structure-plugin.remove.chapter',
25
25
  },
@@ -18,8 +18,8 @@ export const sectionSpec: StructureSpec = {
18
18
  translations: {
19
19
  insert: 'article-structure-plugin.insert.section',
20
20
  move: {
21
- up: 'article-structure-plugin.moveUp.section',
22
- down: 'article-structure-plugin.moveDown.section',
21
+ up: 'article-structure-plugin.move-up.section',
22
+ down: 'article-structure-plugin.move-down.section',
23
23
  },
24
24
  remove: 'article-structure-plugin.remove.section',
25
25
  },
@@ -19,6 +19,8 @@ const TAG_TO_LEVEL = new Map([
19
19
  export const structure_header: NodeSpec = {
20
20
  content: 'text*|placeholder',
21
21
  inline: false,
22
+ defining: true,
23
+ isolating: true,
22
24
  attrs: {
23
25
  property: {
24
26
  default: SAY('heading').prefixed,
@@ -19,8 +19,8 @@ export const subsectionSpec: StructureSpec = {
19
19
  translations: {
20
20
  insert: 'article-structure-plugin.insert.subsection',
21
21
  move: {
22
- up: 'article-structure-plugin.moveUp.subsection',
23
- down: 'article-structure-plugin.moveDown.subsection',
22
+ up: 'article-structure-plugin.move-up.subsection',
23
+ down: 'article-structure-plugin.move-down.subsection',
24
24
  },
25
25
  remove: 'article-structure-plugin.remove.subsection',
26
26
  },
@@ -18,8 +18,8 @@ export const titleSpec: StructureSpec = {
18
18
  translations: {
19
19
  insert: 'article-structure-plugin.insert.title',
20
20
  move: {
21
- up: 'article-structure-plugin.moveUp.title',
22
- down: 'article-structure-plugin.moveDown.title',
21
+ up: 'article-structure-plugin.move-up.title',
22
+ down: 'article-structure-plugin.move-down.title',
23
23
  },
24
24
  remove: 'article-structure-plugin.remove.title',
25
25
  },
@@ -71,6 +71,8 @@ export function constructStructureBodyNodeSpec(config: {
71
71
  return {
72
72
  content,
73
73
  inline: false,
74
+ defining: true,
75
+ isolating: true,
74
76
  toDOM() {
75
77
  return [
76
78
  'div',
@@ -2,7 +2,7 @@ import { WidgetSpec } from '@lblod/ember-rdfa-editor';
2
2
 
3
3
  export const defaultDateFormats: DateFormat[] = [
4
4
  {
5
- label: 'Short small Date',
5
+ label: 'Short Date',
6
6
  key: 'short',
7
7
  dateFormat: 'dd/MM/yy',
8
8
  dateTimeFormat: 'dd/MM/yy HH:mm',
@@ -11,7 +11,7 @@ export const defaultDateFormats: DateFormat[] = [
11
11
  label: 'Long Date',
12
12
  key: 'long',
13
13
  dateFormat: 'EEEE dd MMMM yyyy',
14
- dateTimeFormat: 'EEEE dd MMMM yyyy at HH:mm',
14
+ dateTimeFormat: 'PPPPp',
15
15
  },
16
16
  ];
17
17
 
@@ -20,9 +20,7 @@ const defaultOptions = {
20
20
  allowCustomFormat: true,
21
21
  };
22
22
 
23
- export const rdfaDateCardWidget: (options?: DatePluginOptions) => WidgetSpec = (
24
- options
25
- ) => {
23
+ export function rdfaDateCardWidget(options?: DatePluginOptions): WidgetSpec {
26
24
  return {
27
25
  componentName: 'rdfa-date-plugin/card',
28
26
  desiredLocation: 'sidebar',
@@ -30,12 +28,17 @@ export const rdfaDateCardWidget: (options?: DatePluginOptions) => WidgetSpec = (
30
28
  options: options ? options : defaultOptions,
31
29
  },
32
30
  };
33
- };
31
+ }
34
32
 
35
- export const rdfaDateInsertWidget: WidgetSpec = {
36
- componentName: 'rdfa-date-plugin/insert',
37
- desiredLocation: 'insertSidebar',
38
- };
33
+ export function rdfaDateInsertWidget(options?: DatePluginOptions): WidgetSpec {
34
+ return {
35
+ componentName: 'rdfa-date-plugin/insert',
36
+ desiredLocation: 'insertSidebar',
37
+ widgetArgs: {
38
+ options: options ? options : defaultOptions,
39
+ },
40
+ };
41
+ }
39
42
 
40
43
  export type DateFormat = {
41
44
  label: string;
@@ -5,7 +5,7 @@ import {
5
5
  XSD,
6
6
  } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/constants';
7
7
  import { hasRDFaAttribute } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/namespace';
8
- import { formatDate } from '../utils';
8
+ import { formatDate, validateDateFormat } from '../utils';
9
9
 
10
10
  export type DateOptions = {
11
11
  placeholder: {
@@ -22,14 +22,17 @@ const date: (options: DateOptions) => NodeSpec = (options) => {
22
22
  default: null,
23
23
  },
24
24
  value: {
25
- default: null,
25
+ default: new Date().toISOString(),
26
26
  },
27
27
  format: {
28
- default: 'dd/mm/yyyy',
28
+ default: 'dd/MM/yyyy',
29
29
  },
30
30
  onlyDate: {
31
31
  default: true,
32
32
  },
33
+ custom: {
34
+ default: false,
35
+ },
33
36
  },
34
37
  selectable: true,
35
38
  leafText: (node) => {
@@ -42,17 +45,25 @@ const date: (options: DateOptions) => NodeSpec = (options) => {
42
45
  return humanReadableDate;
43
46
  },
44
47
  toDOM: (node) => {
45
- const { value, onlyDate, format, mappingResource } = node.attrs;
48
+ const { value, onlyDate, format, mappingResource, custom } = node.attrs;
46
49
  const datatype = onlyDate ? XSD('date') : XSD('dateTime');
47
- const humanReadableDate = value
48
- ? formatDate(new Date(value), format)
49
- : onlyDate
50
- ? options.placeholder.insertDate
51
- : options.placeholder.insertDateTime;
50
+ let humanReadableDate: string;
51
+ if (value) {
52
+ if (validateDateFormat(format).type === 'ok') {
53
+ humanReadableDate = formatDate(new Date(value), format);
54
+ } else {
55
+ humanReadableDate = 'Ongeldig formaat';
56
+ }
57
+ } else {
58
+ humanReadableDate = onlyDate
59
+ ? options.placeholder.insertDate
60
+ : options.placeholder.insertDateTime;
61
+ }
52
62
  const dateAttrs = {
53
63
  datatype: datatype.prefixed,
54
64
  property: EXT('content').prefixed,
55
65
  'data-format': format as string,
66
+ 'data-custom': custom ? 'true' : 'false',
56
67
  ...(!!value && { content: value as string }),
57
68
  };
58
69
  if (mappingResource) {
@@ -83,6 +94,7 @@ const date: (options: DateOptions) => NodeSpec = (options) => {
83
94
  value: node.getAttribute('content'),
84
95
  onlyDate,
85
96
  format: node.dataset.format,
97
+ custom: node.dataset.custom === 'true',
86
98
  };
87
99
  }
88
100
  return false;
@@ -114,6 +126,7 @@ const date: (options: DateOptions) => NodeSpec = (options) => {
114
126
  onlyDate,
115
127
  value: dateNode?.getAttribute('content'),
116
128
  format: dateNode?.getAttribute('data-format'),
129
+ custom: dateNode?.getAttribute('data-custom') === 'true',
117
130
  };
118
131
  }
119
132
  }
@@ -1,5 +1,6 @@
1
1
  import { formatWithOptions } from 'date-fns/fp';
2
2
  import { nlBE } from 'date-fns/locale';
3
+ import { RegexpMatchArrayWithIndices } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/citation-plugin/utils/process-match';
3
4
 
4
5
  export function formatDate(date: Date, format: string) {
5
6
  try {
@@ -8,3 +9,74 @@ export function formatDate(date: Date, format: string) {
8
9
  return '';
9
10
  }
10
11
  }
12
+
13
+ type ValidationErrorType =
14
+ | 'date'
15
+ | 'locale'
16
+ | 'use-yyyy'
17
+ | 'use-yy'
18
+ | 'use-d'
19
+ | 'use-dd'
20
+ | 'character'
21
+ | 'required'
22
+ | 'fractions'
23
+ | 'unknown';
24
+
25
+ interface ValidationOk {
26
+ type: 'ok';
27
+ value: string;
28
+ }
29
+
30
+ export interface ValidationError {
31
+ type: 'error';
32
+ error: ValidationErrorType;
33
+ payload?: Record<string, string>;
34
+ }
35
+
36
+ type ValidationResult = ValidationOk | ValidationError;
37
+ const INVALID_CHAR_REGEX = new RegExp('Format string.*`(?<char>\\S+)`');
38
+ const FRACTIONS_REGEX = new RegExp('[ST]');
39
+
40
+ export function validateDateFormat(format?: string): ValidationResult {
41
+ try {
42
+ if (!format || format.length === 0) {
43
+ return { type: 'error', error: 'required' };
44
+ }
45
+ if (FRACTIONS_REGEX.test(format)) {
46
+ return { type: 'error', error: 'fractions' };
47
+ }
48
+ const value = formatWithOptions({ locale: nlBE }, format)(new Date());
49
+ return { type: 'ok', value };
50
+ } catch (e) {
51
+ if (e instanceof RangeError) {
52
+ const msg = e.message;
53
+
54
+ if (msg.startsWith('Use `yyyy`')) {
55
+ return { type: 'error', error: 'use-yyyy' };
56
+ } else if (msg.startsWith('Use `yy`')) {
57
+ return { type: 'error', error: 'use-yy' };
58
+ } else if (msg.startsWith('Use `d`')) {
59
+ return { type: 'error', error: 'use-d' };
60
+ } else if (msg.startsWith('Use `dd`')) {
61
+ return { type: 'error', error: 'use-dd' };
62
+ } else {
63
+ const match = INVALID_CHAR_REGEX.exec(
64
+ msg
65
+ ) as RegexpMatchArrayWithIndices | null;
66
+ if (match) {
67
+ const invalidCharacters = match.groups?.char;
68
+ if (invalidCharacters) {
69
+ return {
70
+ type: 'error',
71
+ error: 'character',
72
+ payload: { invalidCharacters },
73
+ };
74
+ }
75
+ }
76
+ }
77
+ return { type: 'error', error: 'unknown' };
78
+ } else {
79
+ throw e;
80
+ }
81
+ }
82
+ }
@@ -173,8 +173,8 @@ export const besluitArticleStructure: StructureSpec = {
173
173
  translations: {
174
174
  insert: 'article-structure-plugin.insert.article',
175
175
  move: {
176
- up: 'article-structure-plugin.moveUp.article',
177
- down: 'article-structure-plugin.moveDown.article',
176
+ up: 'article-structure-plugin.move-up.article',
177
+ down: 'article-structure-plugin.move-down.article',
178
178
  },
179
179
  remove: 'article-structure-plugin.remove.article',
180
180
  },
@@ -226,6 +226,7 @@ export const besluitArticleStructure: StructureSpec = {
226
226
 
227
227
  export const besluit_article_header: NodeSpec = {
228
228
  inline: false,
229
+ selectable: false,
229
230
  attrs: {
230
231
  ...rdfaAttrs,
231
232
  number: {
@@ -20,6 +20,8 @@ const emberNodeConfig: EmberNodeConfig = {
20
20
  group: 'inline',
21
21
  content: 'inline*',
22
22
  atom: true,
23
+ recreateUri: true,
24
+ uriAttributes: ['variableInstance'],
23
25
  draggable: false,
24
26
  attrs: {
25
27
  mappingResource: {},
@@ -0,0 +1 @@
1
+ export { default } from '@lblod/ember-rdfa-editor-lblod-plugins/components/rdfa-date-plugin/help-modal';
@@ -5,13 +5,19 @@ span.date {
5
5
  padding: 0 0.2rem !important;
6
6
  line-height: 1.2rem !important;
7
7
  transition: border 0.1s ease-in-out, background-color 0.1s ease-in-out;
8
+
8
9
  &::selection {
9
10
  background-color: var(--au-blue-200);
10
11
  }
12
+
11
13
  user-select: none;
12
14
  }
13
15
 
14
16
  span.date.ProseMirror-selectednode {
15
17
  background-color: var(--au-blue-200);
16
18
  outline: 2px solid var(--au-blue-500);
17
- }
19
+ }
20
+
21
+ #date-plugin-time-info-tooltip {
22
+ z-index: 3;
23
+ }
@@ -21,16 +21,14 @@ export default class EditorPluginsToolbarDropdownComponent extends Component<Arg
21
21
  */
22
22
  besluitType?: BesluitType;
23
23
  previousBesluitType?: string;
24
- types: BesluitType[];
25
24
  besluit?: BesluitType;
26
25
  subBesluit?: BesluitType;
27
26
  subSubBesluit?: BesluitType;
28
27
  cardExpanded: boolean;
29
- loadDataTaskInstance: import("ember-concurrency").TaskInstance<void>;
30
28
  constructor(parent: unknown, args: Args);
31
29
  get controller(): ProseController;
32
30
  get doc(): import("prosemirror-model").Node;
33
- loadData: import("ember-concurrency").TaskForAsyncTaskFunction<unknown, () => Promise<void>>;
31
+ types: import("ember-resources/util/function").State<BesluitType[]>;
34
32
  get currentBesluitRange(): ResolvedPNode | undefined;
35
33
  get currentBesluitURI(): string | undefined;
36
34
  get showCard(): boolean;
@@ -38,8 +36,8 @@ export default class EditorPluginsToolbarDropdownComponent extends Component<Arg
38
36
  updateBesluitType(selected: BesluitType): void;
39
37
  updateBesluitSubType(selected: BesluitType): void;
40
38
  updateBesluitSubSubType(selected: BesluitType): void;
41
- findBesluitTypeParent(besluitType?: BesluitType, array?: BesluitType[], parent?: BesluitType): BesluitType | undefined;
42
- findBesluitTypeByURI(uri: string, types?: BesluitType[]): BesluitType | undefined;
39
+ findBesluitTypeParent(besluitType?: BesluitType, array?: BesluitType[] | null, parent?: BesluitType): BesluitType | undefined;
40
+ findBesluitTypeByURI(uri: string, types?: BesluitType[] | null): BesluitType | undefined;
43
41
  insert(): void;
44
42
  toggleCard(): void;
45
43
  }