@lblod/ember-rdfa-editor-lblod-plugins 14.0.0 → 14.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/README.md +2 -1
  3. package/addon/components/document-title-plugin/insert-title-card.ts +2 -0
  4. package/addon/components/variable-plugin/date/edit.hbs +12 -10
  5. package/addon/components/variable-plugin/date/edit.ts +7 -0
  6. package/addon/components/variable-plugin/number/nodeview.ts +1 -1
  7. package/addon/plugins/article-structure-plugin/commands/insert-structure.ts +1 -1
  8. package/addon/plugins/article-structure-plugin/commands/move-selected-structure.ts +5 -1
  9. package/addon/plugins/article-structure-plugin/commands/wrap-structure-content.ts +1 -0
  10. package/addon/plugins/article-structure-plugin/index.ts +1 -0
  11. package/addon/plugins/article-structure-plugin/structures/article-paragraph.ts +7 -2
  12. package/addon/plugins/article-structure-plugin/structures/article.ts +11 -3
  13. package/addon/plugins/article-structure-plugin/structures/chapter.ts +11 -3
  14. package/addon/plugins/article-structure-plugin/structures/section.ts +11 -3
  15. package/addon/plugins/article-structure-plugin/structures/subsection.ts +11 -3
  16. package/addon/plugins/article-structure-plugin/structures/title.ts +11 -3
  17. package/addon/plugins/decision-plugin/commands/insert-motivation.ts +28 -6
  18. package/addon/plugins/standard-template-plugin/index.ts +2 -0
  19. package/addon/plugins/standard-template-plugin/utils/instantiate-uuids.ts +5 -13
  20. package/addon/plugins/standard-template-plugin/utils/nodes.ts +7 -2
  21. package/addon/plugins/variable-plugin/utils/address-helpers.ts +6 -4
  22. package/addon/plugins/variable-plugin/utils/number-to-words.ts +8 -3
  23. package/addon/plugins/variable-plugin/variables/date.ts +15 -2
  24. package/addon/plugins/variable-plugin/variables/number.ts +2 -2
  25. package/addon/utils/memoize.ts +11 -3
  26. package/addon/utils/translation.ts +9 -5
  27. package/components/variable-plugin/address/edit.d.ts +1 -1
  28. package/components/variable-plugin/date/edit.d.ts +1 -0
  29. package/package.json +3 -3
  30. package/plugins/article-structure-plugin/index.d.ts +1 -0
  31. package/plugins/standard-template-plugin/index.d.ts +1 -0
  32. package/plugins/variable-plugin/utils/address-helpers.d.ts +1 -1
  33. package/plugins/variable-plugin/utils/number-to-words.d.ts +1 -0
  34. package/utils/memoize.d.ts +6 -1
  35. package/utils/translation.d.ts +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,42 @@
1
1
  # @lblod/ember-rdfa-editor-lblod-plugins
2
2
 
3
+ ## 14.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#322](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/pull/322) [`a168dc5`](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/commit/a168dc54b5ddc0a4a5b3bf8c521ccb914bb91b7a) Thanks [@x-m-el](https://github.com/x-m-el)! - For article-structure plugin
8
+
9
+ - The `StructureSpec`'s `constructor` now also contains the optional argument `state` (an EditorState)
10
+ - The existing structures' placeholders are translated using the document language
11
+ - This is only the case if emberApplication plugin is configured.
12
+ **Recommended change**: activate emberApplication plugin
13
+ - Will fallback to translating based on browser locale (=old logic) if emberApplication plugin is not configured
14
+
15
+ - [#322](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/pull/322) [`690738f`](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/commit/690738f56692555880c5ad29c25c76f400a48bcb) Thanks [@x-m-el](https://github.com/x-m-el)! - For decision-plugin and standard-template-plugin
16
+
17
+ Make use of `state` argument to translate placeholders based on document language instead of browser locale
18
+ Depending on the place where placeholders are defined either of the following logic happens:
19
+
20
+ - will always use document language
21
+ - will use document language if emberApplication plugin is active. If not, defaults to browser locale (like before)
22
+
23
+ ### Patch Changes
24
+
25
+ - [#322](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/pull/322) [`5ceca68`](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/commit/5ceca68ec271477dfcf75c7d9fba35c21880642e) Thanks [@x-m-el](https://github.com/x-m-el)! - Using "show as words" for a number variable will convert the number to a string in the language in the document, instead of always showing Dutch.
26
+
27
+ ## 14.1.0
28
+
29
+ ### Minor Changes
30
+
31
+ - [#315](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/pull/315) [`01163d8`](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/commit/01163d8d45b801a50728b9aeabaf0e52a1cf9a33) Thanks [@piemonkey](https://github.com/piemonkey)! - Export standard-template-plugin's uuid instantiation function
32
+
33
+ ### Patch Changes
34
+
35
+ - [#317](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/pull/317) [`1d28bc9`](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/commit/1d28bc9b9b0e07e8eb5698988dfe0e3dd946c2a3) Thanks [@dkozickis](https://github.com/dkozickis)! - GN-4538: Display correctly that there are no streets when searching in the address plugin
36
+
37
+ - [#316](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/pull/316) [`e109035`](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/commit/e109035809df341ede0a03fb0b146909883903ef) Thanks [@x-m-el](https://github.com/x-m-el)! - - Bugfix: `allowCustomFormat` for rdfa-date variable will now disable custom formats if set to false.
38
+ - No changes for old documents: date variables in old documents will allow custom formats, which is the default.
39
+
3
40
  ## 14.0.0
4
41
 
5
42
  ### Major Changes
package/README.md CHANGED
@@ -140,6 +140,7 @@ export type StructureSpec = {
140
140
  number?: number;
141
141
  intl?: IntlService;
142
142
  content?: PNode | Fragment;
143
+ state?: EditorState;
143
144
  }) => {
144
145
  node: PNode;
145
146
  selectionConfig: {
@@ -695,7 +696,7 @@ get dateOptions(){
695
696
  - `key`: A **unique** identifier used for identification in the internal code.
696
697
  - `dateFormat`: The date format used when this is selected.
697
698
  - `dateTimeFormat`: The datetime format to use when this is selected. Used when the user selects "Include time".
698
- - `allowCustomFormat`: true/false, determines if the option to insert a fully custom format is available.
699
+ - `allowCustomFormat`: true by default, determines if the option to insert a fully custom format is available for newly created date nodes.
699
700
 
700
701
  The syntax of formats can be found at [date-fns](https://date-fns.org/v2.29.3/docs/format).
701
702
 
@@ -17,6 +17,7 @@ export default class InsertTitleCardComponent extends Component<Args> {
17
17
  insertDocumentTitle({
18
18
  placeholder: this.intl.t(
19
19
  'document-title-plugin.document-title-placeholder',
20
+ { locale: this.args.controller.documentLanguage },
20
21
  ),
21
22
  }),
22
23
  {
@@ -31,6 +32,7 @@ export default class InsertTitleCardComponent extends Component<Args> {
31
32
  insertDocumentTitle({
32
33
  placeholder: this.intl.t(
33
34
  'document-title-plugin.document-title-placeholder',
35
+ { locale: this.args.controller.documentLanguage },
34
36
  ),
35
37
  }),
36
38
  {
@@ -56,16 +56,18 @@
56
56
  />
57
57
  </AuFormRow>
58
58
  {{/each}}
59
- <AuFormRow>
60
- <AuControlRadio
61
- @label={{t "date-plugin.card.custom-date" }}
62
- @identifier="custom"
63
- @name="dateFormat"
64
- @value="custom"
65
- checked={{eq this.dateFormatType "custom"}}
66
- @onChange={{this.setDateFormatFromKey}}
67
- />
68
- </AuFormRow>
59
+ {{#if this.isCustomAllowed}}
60
+ <AuFormRow>
61
+ <AuControlRadio
62
+ @label={{t "date-plugin.card.custom-date" }}
63
+ @identifier="custom"
64
+ @name="dateFormat"
65
+ @value="custom"
66
+ checked={{eq this.dateFormatType "custom"}}
67
+ @onChange={{this.setDateFormatFromKey}}
68
+ />
69
+ </AuFormRow>
70
+ {{/if}}
69
71
  {{#if (eq this.dateFormatType "custom")}}
70
72
  <AuFormRow @alignment="post">
71
73
  <AuButton @skin="secondary" @icon="info-circle"
@@ -125,6 +125,13 @@ export default class DateEditComponent extends Component<Args> {
125
125
  return unwrapOr(false, this.selectedDateNode?.attrs.custom as boolean);
126
126
  }
127
127
 
128
+ get isCustomAllowed(): boolean {
129
+ return unwrapOr(
130
+ true,
131
+ this.selectedDateNode?.attrs.customAllowed as boolean,
132
+ );
133
+ }
134
+
128
135
  get dateFormatType(): string {
129
136
  if (this.isCustom) {
130
137
  return 'custom';
@@ -63,7 +63,7 @@ export default class NumberNodeviewComponent extends Component<Args> {
63
63
  if (!this.writtenNumber) {
64
64
  return value;
65
65
  } else {
66
- return numberToWords(Number(value), { lang: 'nl' });
66
+ return numberToWords(Number(value), { lang: this.documentLanguage });
67
67
  }
68
68
  }
69
69
 
@@ -32,7 +32,7 @@ const insertStructure = (
32
32
  }
33
33
  if (dispatch) {
34
34
  const { node: newStructureNode, selectionConfig } =
35
- structureSpec.constructor({ schema, intl, content });
35
+ structureSpec.constructor({ schema, intl, content, state });
36
36
  const transaction = state.tr;
37
37
 
38
38
  transaction.replaceWith(
@@ -14,6 +14,7 @@ import { findNodes } from '@lblod/ember-rdfa-editor/utils/position-utils';
14
14
  import IntlService from 'ember-intl/services/intl';
15
15
  import { findParentNodeOfType } from '@curvenote/prosemirror-utils';
16
16
  import { unwrap } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/option';
17
+ import { getTranslationFunction } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/translation';
17
18
  const moveSelectedStructure = (
18
19
  options: ArticleStructurePluginOptions,
19
20
  direction: 'up' | 'down',
@@ -52,11 +53,14 @@ const moveSelectedStructure = (
52
53
  );
53
54
  const parent = doc.resolve(currentStructure.pos).parent;
54
55
  if (parent.childCount === 1) {
56
+ const translationWithDocLang = getTranslationFunction(state);
55
57
  transaction.insert(
56
58
  currentStructure.pos,
57
59
  schema.node(schema.nodes['placeholder'], {
58
- placeholderText: intl.t(
60
+ placeholderText: translationWithDocLang(
59
61
  'article-structure-plugin.placeholder.generic.body',
62
+ intl?.t('article-structure-plugin.placeholder.generic.body') ||
63
+ '',
60
64
  ),
61
65
  }),
62
66
  );
@@ -41,6 +41,7 @@ const wrapStructureContent = (
41
41
  schema,
42
42
  content: contentToWrap,
43
43
  intl,
44
+ state,
44
45
  });
45
46
  } catch (e) {
46
47
  return false;
@@ -25,6 +25,7 @@ export type StructureSpec = {
25
25
  number?: number;
26
26
  intl?: IntlService;
27
27
  content?: PNode | Fragment;
28
+ state?: EditorState;
28
29
  }) => {
29
30
  node: PNode;
30
31
  selectionConfig: {
@@ -7,6 +7,7 @@ import {
7
7
  XSD,
8
8
  } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/constants';
9
9
  import { hasRDFaAttribute } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/namespace';
10
+ import { getTranslationFunction } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/translation';
10
11
 
11
12
  const PLACEHOLDERS = {
12
13
  body: 'article-structure-plugin.placeholder.paragraph.body',
@@ -25,8 +26,9 @@ export const articleParagraphSpec: StructureSpec = {
25
26
  },
26
27
  continuous: false,
27
28
  noUnwrap: true,
28
- constructor: ({ schema, number, intl }) => {
29
+ constructor: ({ schema, number, intl, state }) => {
29
30
  const numberConverted = number?.toString() ?? '1';
31
+ const translationWithDocLang = getTranslationFunction(state);
30
32
  const node = schema.node(
31
33
  `article_paragraph`,
32
34
  {
@@ -37,7 +39,10 @@ export const articleParagraphSpec: StructureSpec = {
37
39
  'paragraph',
38
40
  {},
39
41
  schema.node('placeholder', {
40
- placeholderText: intl?.t(PLACEHOLDERS.body),
42
+ placeholderText: translationWithDocLang(
43
+ PLACEHOLDERS.body,
44
+ intl?.t(PLACEHOLDERS.body) || '',
45
+ ),
41
46
  }),
42
47
  ),
43
48
  );
@@ -13,6 +13,7 @@ import {
13
13
  XSD,
14
14
  } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/constants';
15
15
  import { unwrap } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/option';
16
+ import { getTranslationFunction } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/translation';
16
17
 
17
18
  const PLACEHOLDERS = {
18
19
  title: 'article-structure-plugin.placeholder.article.heading',
@@ -30,8 +31,9 @@ export const articleSpec: StructureSpec = {
30
31
  removeWithContent: 'article-structure-plugin.remove-with-content.article',
31
32
  },
32
33
  continuous: true,
33
- constructor: ({ schema, number, content, intl }) => {
34
+ constructor: ({ schema, number, content, intl, state }) => {
34
35
  const numberConverted = number?.toString() ?? '1';
36
+ const translationWithDocLang = getTranslationFunction(state);
35
37
  const node = schema.node(
36
38
  `article`,
37
39
  { resource: `http://data.lblod.info/articles/${uuid()}` },
@@ -40,7 +42,10 @@ export const articleSpec: StructureSpec = {
40
42
  'article_header',
41
43
  { level: 4, number: numberConverted },
42
44
  schema.node('placeholder', {
43
- placeholderText: intl?.t(PLACEHOLDERS.title),
45
+ placeholderText: translationWithDocLang(
46
+ PLACEHOLDERS.title,
47
+ intl?.t(PLACEHOLDERS.title) || '',
48
+ ),
44
49
  }),
45
50
  ),
46
51
  schema.node(
@@ -51,7 +56,10 @@ export const articleSpec: StructureSpec = {
51
56
  'paragraph',
52
57
  {},
53
58
  schema.node('placeholder', {
54
- placeholderText: intl?.t(PLACEHOLDERS.body),
59
+ placeholderText: translationWithDocLang(
60
+ PLACEHOLDERS.body,
61
+ intl?.t(PLACEHOLDERS.body) || '',
62
+ ),
55
63
  }),
56
64
  ),
57
65
  ),
@@ -7,6 +7,7 @@ import {
7
7
  import { v4 as uuid } from 'uuid';
8
8
  import { SAY } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/constants';
9
9
  import { unwrap } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/option';
10
+ import { getTranslationFunction } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/translation';
10
11
 
11
12
  const PLACEHOLDERS = {
12
13
  title: 'article-structure-plugin.placeholder.chapter.heading',
@@ -24,8 +25,9 @@ export const chapterSpec: StructureSpec = {
24
25
  remove: 'article-structure-plugin.remove.chapter',
25
26
  removeWithContent: 'article-structure-plugin.remove-with-content.chapter',
26
27
  },
27
- constructor: ({ schema, number, content, intl }) => {
28
+ constructor: ({ schema, number, content, intl, state }) => {
28
29
  const numberConverted = romanize(number ?? 1);
30
+ const translationWithDocLang = getTranslationFunction(state);
29
31
  const node = schema.node(
30
32
  `chapter`,
31
33
  { resource: `http://data.lblod.info/chapters/${uuid()}` },
@@ -34,7 +36,10 @@ export const chapterSpec: StructureSpec = {
34
36
  'structure_header',
35
37
  { level: 4, number: numberConverted },
36
38
  schema.node('placeholder', {
37
- placeholderText: intl?.t(PLACEHOLDERS.title),
39
+ placeholderText: translationWithDocLang(
40
+ PLACEHOLDERS.title,
41
+ intl?.t(PLACEHOLDERS.title) || '',
42
+ ),
38
43
  }),
39
44
  ),
40
45
  schema.node(
@@ -45,7 +50,10 @@ export const chapterSpec: StructureSpec = {
45
50
  'paragraph',
46
51
  {},
47
52
  schema.node('placeholder', {
48
- placeholderText: intl?.t(PLACEHOLDERS.body),
53
+ placeholderText: translationWithDocLang(
54
+ PLACEHOLDERS.body,
55
+ intl?.t(PLACEHOLDERS.body) || '',
56
+ ),
49
57
  }),
50
58
  ),
51
59
  ),
@@ -7,6 +7,7 @@ import { v4 as uuid } from 'uuid';
7
7
  import { StructureSpec } from '..';
8
8
  import { SAY } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/constants';
9
9
  import { unwrap } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/option';
10
+ import { getTranslationFunction } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/translation';
10
11
 
11
12
  const PLACEHOLDERS = {
12
13
  title: 'article-structure-plugin.placeholder.section.heading',
@@ -24,8 +25,9 @@ export const sectionSpec: StructureSpec = {
24
25
  remove: 'article-structure-plugin.remove.section',
25
26
  removeWithContent: 'article-structure-plugin.remove-with-content.section',
26
27
  },
27
- constructor: ({ schema, number, content, intl }) => {
28
+ constructor: ({ schema, number, content, intl, state }) => {
28
29
  const numberConverted = romanize(number || 1);
30
+ const translationWithDocLang = getTranslationFunction(state);
29
31
  const node = schema.node(
30
32
  `section`,
31
33
  { resource: `http://data.lblod.info/sections/${uuid()}` },
@@ -34,7 +36,10 @@ export const sectionSpec: StructureSpec = {
34
36
  'structure_header',
35
37
  { level: 5, number: numberConverted },
36
38
  schema.node('placeholder', {
37
- placeholderText: intl?.t(PLACEHOLDERS.title),
39
+ placeholderText: translationWithDocLang(
40
+ PLACEHOLDERS.title,
41
+ intl?.t(PLACEHOLDERS.title) || '',
42
+ ),
38
43
  }),
39
44
  ),
40
45
  schema.node(
@@ -45,7 +50,10 @@ export const sectionSpec: StructureSpec = {
45
50
  'paragraph',
46
51
  {},
47
52
  schema.node('placeholder', {
48
- placeholderText: intl?.t(PLACEHOLDERS.body),
53
+ placeholderText: translationWithDocLang(
54
+ PLACEHOLDERS.body,
55
+ intl?.t(PLACEHOLDERS.body) || '',
56
+ ),
49
57
  }),
50
58
  ),
51
59
  ),
@@ -7,6 +7,7 @@ import {
7
7
  import { v4 as uuid } from 'uuid';
8
8
  import { SAY } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/constants';
9
9
  import { unwrap } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/option';
10
+ import { getTranslationFunction } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/translation';
10
11
 
11
12
  const PLACEHOLDERS = {
12
13
  title: 'article-structure-plugin.placeholder.subsection.heading',
@@ -26,8 +27,9 @@ export const subsectionSpec: StructureSpec = {
26
27
  removeWithContent:
27
28
  'article-structure-plugin.remove-with-content.subsection',
28
29
  },
29
- constructor: ({ schema, number, intl, content }) => {
30
+ constructor: ({ schema, number, intl, content, state }) => {
30
31
  const numberConverted = romanize(number ?? 1);
32
+ const translationWithDocLang = getTranslationFunction(state);
31
33
  const node = schema.node(
32
34
  `subsection`,
33
35
  { resource: `http://data.lblod.info/subsections/${uuid()}` },
@@ -36,7 +38,10 @@ export const subsectionSpec: StructureSpec = {
36
38
  'structure_header',
37
39
  { level: 6, number: numberConverted },
38
40
  schema.node('placeholder', {
39
- placeholderText: intl?.t(PLACEHOLDERS.title),
41
+ placeholderText: translationWithDocLang(
42
+ PLACEHOLDERS.title,
43
+ intl?.t(PLACEHOLDERS.title) || '',
44
+ ),
40
45
  }),
41
46
  ),
42
47
  schema.node(
@@ -47,7 +52,10 @@ export const subsectionSpec: StructureSpec = {
47
52
  'paragraph',
48
53
  {},
49
54
  schema.node('placeholder', {
50
- placeholderText: intl?.t(PLACEHOLDERS.body),
55
+ placeholderText: translationWithDocLang(
56
+ PLACEHOLDERS.body,
57
+ intl?.t(PLACEHOLDERS.body) || '',
58
+ ),
51
59
  }),
52
60
  ),
53
61
  ),
@@ -7,6 +7,7 @@ import {
7
7
  import { v4 as uuid } from 'uuid';
8
8
  import { SAY } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/constants';
9
9
  import { unwrap } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/option';
10
+ import { getTranslationFunction } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/translation';
10
11
 
11
12
  const PLACEHOLDERS = {
12
13
  heading: 'article-structure-plugin.placeholder.generic.heading',
@@ -24,8 +25,9 @@ export const titleSpec: StructureSpec = {
24
25
  remove: 'article-structure-plugin.remove.title',
25
26
  removeWithContent: 'article-structure-plugin.remove-with-content.title',
26
27
  },
27
- constructor: ({ schema, number, content, intl }) => {
28
+ constructor: ({ schema, number, content, intl, state }) => {
28
29
  const numberConverted = romanize(number ?? 1);
30
+ const translationWithDocLang = getTranslationFunction(state);
29
31
  const node = schema.node(
30
32
  `title`,
31
33
  { resource: `http://data.lblod.info/titles/${uuid()}` },
@@ -34,7 +36,10 @@ export const titleSpec: StructureSpec = {
34
36
  'structure_header',
35
37
  { level: 3, number: numberConverted },
36
38
  schema.node('placeholder', {
37
- placeholderText: intl?.t(PLACEHOLDERS.heading),
39
+ placeholderText: translationWithDocLang(
40
+ PLACEHOLDERS.heading,
41
+ intl?.t(PLACEHOLDERS.heading) || '',
42
+ ),
38
43
  }),
39
44
  ),
40
45
  schema.node(
@@ -45,7 +50,10 @@ export const titleSpec: StructureSpec = {
45
50
  'paragraph',
46
51
  {},
47
52
  schema.node('placeholder', {
48
- placeholderText: intl?.t(PLACEHOLDERS.body),
53
+ placeholderText: translationWithDocLang(
54
+ PLACEHOLDERS.body,
55
+ intl?.t(PLACEHOLDERS.body) || '',
56
+ ),
49
57
  }),
50
58
  ),
51
59
  ),
@@ -9,6 +9,7 @@ import { isNone } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/option';
9
9
  import { transactionCompliesWithShapes } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/validation/utils/transaction-complies-with-shapes';
10
10
  import { findInsertionPosInAncestorOfType } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/find-insertion-pos-in-ancestor-of-type';
11
11
  import IntlService from 'ember-intl/services/intl';
12
+ import { getTranslationFunction } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/translation';
12
13
 
13
14
  interface InsertMotivationArgs {
14
15
  intl: IntlService;
@@ -20,13 +21,17 @@ export default function insertMotivation({
20
21
  validateShapes,
21
22
  }: InsertMotivationArgs): Command {
22
23
  return function (state: EditorState, dispatch?: (tr: Transaction) => void) {
24
+ const translationWithDocLang = getTranslationFunction(state);
23
25
  const { selection, schema } = state;
24
26
  const nodeToInsert = schema.node('motivering', { __rdfaId: uuid() }, [
25
27
  schema.node(
26
28
  'paragraph',
27
29
  null,
28
30
  schema.node('placeholder', {
29
- placeholderText: intl.t('besluit-plugin.placeholder.government-body'),
31
+ placeholderText: translationWithDocLang(
32
+ 'besluit-plugin.placeholder.government-body',
33
+ intl.t('besluit-plugin.placeholder.government-body'),
34
+ ),
30
35
  }),
31
36
  ),
32
37
  schema.node(
@@ -40,8 +45,9 @@ export default function insertMotivation({
40
45
  schema.node('list_item', null, [
41
46
  schema.node('paragraph', null, [
42
47
  schema.node('placeholder', {
43
- placeholderText: intl.t(
48
+ placeholderText: translationWithDocLang(
44
49
  'besluit-plugin.placeholder.legal-jurisdiction',
50
+ intl.t('besluit-plugin.placeholder.legal-jurisdiction'),
45
51
  ),
46
52
  }),
47
53
  ]),
@@ -52,14 +58,22 @@ export default function insertMotivation({
52
58
  {
53
59
  level: 5,
54
60
  },
55
- [schema.text(intl.t('besluit-plugin.text.legal-context'))],
61
+ [
62
+ schema.text(
63
+ translationWithDocLang(
64
+ 'besluit-plugin.text.legal-context',
65
+ intl.t('besluit-plugin.text.legal-context'),
66
+ ),
67
+ ),
68
+ ],
56
69
  ),
57
70
  schema.node('bullet_list', null, [
58
71
  schema.node('list_item', null, [
59
72
  schema.node('paragraph', null, [
60
73
  schema.node('placeholder', {
61
- placeholderText: intl.t(
74
+ placeholderText: translationWithDocLang(
62
75
  'besluit-plugin.placeholder.insert-legal-context',
76
+ intl.t('besluit-plugin.placeholder.insert-legal-context'),
63
77
  ),
64
78
  }),
65
79
  ]),
@@ -70,14 +84,22 @@ export default function insertMotivation({
70
84
  {
71
85
  level: 5,
72
86
  },
73
- [schema.text(intl.t('besluit-plugin.text.factual-context'))],
87
+ [
88
+ schema.text(
89
+ translationWithDocLang(
90
+ 'besluit-plugin.text.factual-context',
91
+ intl.t('besluit-plugin.text.factual-context'),
92
+ ),
93
+ ),
94
+ ],
74
95
  ),
75
96
  schema.node('bullet_list', null, [
76
97
  schema.node('list_item', null, [
77
98
  schema.node('paragraph', null, [
78
99
  schema.node('placeholder', {
79
- placeholderText: intl.t(
100
+ placeholderText: translationWithDocLang(
80
101
  'besluit-plugin.placeholder.insert-factual-context',
102
+ intl.t('besluit-plugin.placeholder.insert-factual-context'),
81
103
  ),
82
104
  }),
83
105
  ]),
@@ -11,6 +11,8 @@ import {
11
11
  besluitArticleStructure,
12
12
  } from './utils/nodes';
13
13
 
14
+ export { default as instantiateUuids } from './utils/instantiate-uuids';
15
+
14
16
  export const besluitNodes = {
15
17
  besluit,
16
18
  besluit_title,
@@ -17,7 +17,8 @@ import { v4 as uuidv4 } from 'uuid';
17
17
  */
18
18
 
19
19
  export default function instantiateUuids(templateString: string) {
20
- const generateBoundUuid = memoize(uuidv4) as (...args: unknown[]) => string;
20
+ // We're not interested in the args in this case, we just use them to memoize
21
+ const generateBoundUuid = memoize((..._args: unknown[]) => uuidv4());
21
22
 
22
23
  const determineFunction = (string: string) => {
23
24
  switch (string) {
@@ -31,18 +32,9 @@ export default function instantiateUuids(templateString: string) {
31
32
  };
32
33
  return templateString.replace(
33
34
  /\$\{(generateUuid|generateBoundUuid)\(([^()]*)\)\}/g,
34
- (string) => {
35
- const match = /\$\{(generateUuid|generateBoundUuid)\(([^()]*)\)\}/.exec(
36
- string,
37
- );
38
- if (match) {
39
- const functionName = match[1];
40
- const functionArgs = match[2];
41
- const func = determineFunction(functionName);
42
- return functionArgs ? func(functionArgs) : func();
43
- } else {
44
- return string;
45
- }
35
+ (_match, functionName, functionArgs) => {
36
+ const func = determineFunction(functionName);
37
+ return functionArgs ? func(functionArgs) : func();
46
38
  },
47
39
  );
48
40
  }
@@ -15,6 +15,7 @@ import { hasRDFaAttribute } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/n
15
15
  import { StructureSpec } from '../../article-structure-plugin';
16
16
  import { v4 as uuid } from 'uuid';
17
17
  import { unwrap } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/option';
18
+ import { getTranslationFunction } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/translation';
18
19
 
19
20
  export const besluit_title: NodeSpec = {
20
21
  content: 'paragraph+',
@@ -180,7 +181,8 @@ export const besluitArticleStructure: StructureSpec = {
180
181
  remove: 'article-structure-plugin.remove.article',
181
182
  },
182
183
  limitTo: 'besluit',
183
- constructor: ({ schema, number, content, intl }) => {
184
+ constructor: ({ schema, number, content, intl, state }) => {
185
+ const translationWithDocLang = getTranslationFunction(state);
184
186
  const numberConverted = number?.toString() ?? '1';
185
187
  const node = schema.node(
186
188
  `besluit_article`,
@@ -201,8 +203,11 @@ export const besluitArticleStructure: StructureSpec = {
201
203
  'paragraph',
202
204
  {},
203
205
  schema.node('placeholder', {
204
- placeholderText: intl?.t(
206
+ placeholderText: translationWithDocLang(
205
207
  'article-structure-plugin.placeholder.article.body',
208
+ intl?.t(
209
+ 'article-structure-plugin.placeholder.article.body',
210
+ ) || '',
206
211
  ),
207
212
  }),
208
213
  ),
@@ -22,7 +22,7 @@ type StreetSearchResult = {
22
22
  gemeente: {
23
23
  gemeentenaam: { geografischeNaam: { spelling: string } };
24
24
  };
25
- straatnaam: {
25
+ straatnaam?: {
26
26
  straatnaam: {
27
27
  geografischeNaam: { spelling: string };
28
28
  };
@@ -135,9 +135,11 @@ export async function fetchStreets(term: string, municipality: string) {
135
135
  });
136
136
  if (result.ok) {
137
137
  const jsonResult = (await result.json()) as StreetSearchResult;
138
- const streetnames = jsonResult.adresMatches.map((entry) => {
139
- return entry.straatnaam.straatnaam.geografischeNaam.spelling;
140
- });
138
+
139
+ const streetnames = jsonResult.adresMatches
140
+ .map((entry) => entry.straatnaam?.straatnaam.geografischeNaam.spelling)
141
+ .filter(Boolean);
142
+
141
143
  return streetnames;
142
144
  } else {
143
145
  throw new AddressError({
@@ -2,14 +2,19 @@ import n2words from 'n2words';
2
2
 
3
3
  /**
4
4
  * Wrapper around the `n2words` function which catches possible errors thrown by n2words.
5
+ * If an invalid `lang` is used, `nl` is used by default.
5
6
  * If `n2words` throws an error (because of inability to convert the number),
6
7
  * this function displays the error as a warning and returns the provided number as a string.
7
8
  */
8
9
  export function numberToWords(number: number, options: { lang: string }) {
9
10
  try {
10
11
  return n2words(number, options);
11
- } catch (e) {
12
- console.warn(e);
13
- return number.toString();
12
+ } catch {
13
+ try {
14
+ return n2words(number, { ...options, lang: 'nl' });
15
+ } catch (e) {
16
+ console.warn(e);
17
+ return number.toString();
18
+ }
14
19
  }
15
20
  }
@@ -65,6 +65,7 @@ const parseDOM = [
65
65
  onlyDate,
66
66
  format: node.dataset.format,
67
67
  custom: node.dataset.custom === 'true',
68
+ customAllowed: node.dataset.customAllowed !== 'false',
68
69
  };
69
70
  }
70
71
  return false;
@@ -96,6 +97,7 @@ const parseDOM = [
96
97
  value: value,
97
98
  format: format,
98
99
  custom: dateNode?.dataset.custom === 'true',
100
+ customAllowed: dateNode?.dataset.customAllowed !== 'false',
99
101
  label,
100
102
  };
101
103
  }
@@ -108,8 +110,15 @@ const parseDOM = [
108
110
  const serialize = (node: PNode, state: EditorState) => {
109
111
  const t = getTranslationFunction(state);
110
112
 
111
- const { value, onlyDate, format, mappingResource, custom, label } =
112
- node.attrs;
113
+ const {
114
+ value,
115
+ onlyDate,
116
+ format,
117
+ mappingResource,
118
+ custom,
119
+ customAllowed,
120
+ label,
121
+ } = node.attrs;
113
122
  const datatype = onlyDate ? XSD('date') : XSD('dateTime');
114
123
  let humanReadableDate: string;
115
124
  if (value) {
@@ -130,6 +139,7 @@ const serialize = (node: PNode, state: EditorState) => {
130
139
  datatype: datatype.prefixed,
131
140
  'data-format': format as string,
132
141
  'data-custom': custom ? 'true' : 'false',
142
+ 'data-custom-allowed': customAllowed ? 'true' : 'false',
133
143
  ...(!!value && { content: value as string }),
134
144
  };
135
145
  return mappingSpan(
@@ -164,6 +174,9 @@ const emberNodeConfig = (options: DateOptions): EmberNodeConfig => ({
164
174
  custom: {
165
175
  default: false,
166
176
  },
177
+ customAllowed: {
178
+ default: options.allowCustomFormat,
179
+ },
167
180
  label: { default: null },
168
181
  },
169
182
  // TODO: is this property still required?
@@ -73,7 +73,7 @@ const parseDOM = [
73
73
 
74
74
  const serialize = (node: PNode, state: EditorState): DOMOutputSpec => {
75
75
  const t = getTranslationFunction(state);
76
-
76
+ const docLang = state.doc.attrs.lang as string;
77
77
  const {
78
78
  mappingResource,
79
79
  variableInstance,
@@ -88,7 +88,7 @@ const serialize = (node: PNode, state: EditorState): DOMOutputSpec => {
88
88
 
89
89
  if (isNumber(value)) {
90
90
  if (writtenNumber) {
91
- humanReadableContent = numberToWords(Number(value), { lang: 'nl' });
91
+ humanReadableContent = numberToWords(Number(value), { lang: docLang });
92
92
  } else {
93
93
  humanReadableContent = value as string;
94
94
  }
@@ -1,8 +1,16 @@
1
- export default function memoize(func: (...a: unknown[]) => unknown) {
2
- const cache: Record<string, unknown> = {};
1
+ /**
2
+ * Return memoized version of the passed function.
3
+ * Memoization is done on the JSON stringified arguments, passing no args, undefined, or any number
4
+ * of only undefined arguments does not do any caching.
5
+ */
6
+ export default function memoize<T>(func: (...a: unknown[]) => T) {
7
+ const cache: Record<string, T> = {};
3
8
  return (...args: unknown[]) => {
9
+ if (args.length === 0 || args.every((arg) => arg === undefined)) {
10
+ return func(...args);
11
+ }
4
12
  const serializedArgs = JSON.stringify(args);
5
- cache[serializedArgs] = cache[serializedArgs] || func(args);
13
+ cache[serializedArgs] = cache[serializedArgs] || func(...args);
6
14
  return cache[serializedArgs];
7
15
  };
8
16
  }
@@ -2,12 +2,16 @@ import type { EditorState } from '@lblod/ember-rdfa-editor';
2
2
  import IntlService, { type TOptions } from 'ember-intl/services/intl';
3
3
  import { emberApplicationPluginKey } from '@lblod/ember-rdfa-editor/plugins/ember-application';
4
4
 
5
- export const getTranslationFunction = (state: EditorState) => {
6
- const intl = emberApplicationPluginKey
7
- .getState(state)
8
- ?.application.lookup('service:intl') as IntlService | undefined;
5
+ /* Get a function that will translate the string through `intl` based on the document language
6
+ or returns the fallback string if no state is provided or emberApplication plugin is not found */
7
+ export const getTranslationFunction = (state?: EditorState) => {
8
+ const intl =
9
+ state &&
10
+ (emberApplicationPluginKey
11
+ .getState(state)
12
+ ?.application.lookup('service:intl') as IntlService | undefined);
9
13
 
10
- const locale = state.doc.attrs.lang as string;
14
+ const locale = state?.doc.attrs.lang as string;
11
15
 
12
16
  return (key: string, fallback: string, options?: TOptions) => {
13
17
  if (!intl) {
@@ -43,6 +43,6 @@ export default class AddressEditComponent extends Component<Args> {
43
43
  updateBusnumber(event: InputEvent): void;
44
44
  get controller(): SayController;
45
45
  searchMunicipality: import("ember-concurrency").TaskForAsyncTaskFunction<unknown, (term: string) => Promise<string[]>>;
46
- searchStreet: import("ember-concurrency").TaskForAsyncTaskFunction<unknown, (term: string) => Promise<string[]>>;
46
+ searchStreet: import("ember-concurrency").TaskForAsyncTaskFunction<unknown, (term: string) => Promise<(string | undefined)[]>>;
47
47
  }
48
48
  export {};
@@ -25,6 +25,7 @@ export default class DateEditComponent extends Component<Args> {
25
25
  get documentDateFormat(): Option<string>;
26
26
  get documentDateFormatType(): Option<DateFormat>;
27
27
  get isCustom(): boolean;
28
+ get isCustomAllowed(): boolean;
28
29
  get dateFormatType(): string;
29
30
  get customDateFormatError(): ValidationError | null;
30
31
  get humanError(): string | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lblod/ember-rdfa-editor-lblod-plugins",
3
- "version": "14.0.0",
3
+ "version": "14.2.0",
4
4
  "description": "Ember addon providing lblod specific plugins for the ember-rdfa-editor",
5
5
  "keywords": [
6
6
  "ember-addon",
@@ -52,7 +52,7 @@
52
52
  "ember-resources": "^6.1.1",
53
53
  "ember-velcro": "^2.1.0",
54
54
  "fetch-sparql-endpoint": "^3.0.0",
55
- "n2words": "^1.16.4",
55
+ "n2words": "^1.18.0",
56
56
  "process": "0.11.10",
57
57
  "rdf-ext": "^2.1.0",
58
58
  "rdf-validate-shacl": "^0.4.5",
@@ -126,7 +126,7 @@
126
126
  "ember-template-lint": "^4.16.1",
127
127
  "ember-try": "^2.0.0",
128
128
  "eslint": "^8.44.0",
129
- "eslint-config-prettier": "^8.5.0",
129
+ "eslint-config-prettier": "^9.0.0",
130
130
  "eslint-plugin-ember": "^11.1.0",
131
131
  "eslint-plugin-node": "^11.1.0",
132
132
  "eslint-plugin-prettier": "^5.0.0",
@@ -17,6 +17,7 @@ export type StructureSpec = {
17
17
  number?: number;
18
18
  intl?: IntlService;
19
19
  content?: PNode | Fragment;
20
+ state?: EditorState;
20
21
  }) => {
21
22
  node: PNode;
22
23
  selectionConfig: {
@@ -1,3 +1,4 @@
1
+ export { default as instantiateUuids } from './utils/instantiate-uuids';
1
2
  export declare const besluitNodes: {
2
3
  besluit: import("prosemirror-model").NodeSpec;
3
4
  besluit_title: import("prosemirror-model").NodeSpec;
@@ -15,7 +15,7 @@ export declare class AddressError extends Error {
15
15
  }
16
16
  export declare const replaceAccents: (string: string) => string;
17
17
  export declare function fetchMunicipalities(term: string): Promise<string[]>;
18
- export declare function fetchStreets(term: string, municipality: string): Promise<string[]>;
18
+ export declare function fetchStreets(term: string, municipality: string): Promise<(string | undefined)[]>;
19
19
  type StreetInfo = {
20
20
  municipality: string;
21
21
  street: string;
@@ -1,5 +1,6 @@
1
1
  /**
2
2
  * Wrapper around the `n2words` function which catches possible errors thrown by n2words.
3
+ * If an invalid `lang` is used, `nl` is used by default.
3
4
  * If `n2words` throws an error (because of inability to convert the number),
4
5
  * this function displays the error as a warning and returns the provided number as a string.
5
6
  */
@@ -1 +1,6 @@
1
- export default function memoize(func: (...a: unknown[]) => unknown): (...args: unknown[]) => unknown;
1
+ /**
2
+ * Return memoized version of the passed function.
3
+ * Memoization is done on the JSON stringified arguments, passing no args, undefined, or any number
4
+ * of only undefined arguments does not do any caching.
5
+ */
6
+ export default function memoize<T>(func: (...a: unknown[]) => T): (...args: unknown[]) => T;
@@ -1,3 +1,3 @@
1
1
  import type { EditorState } from '@lblod/ember-rdfa-editor';
2
2
  import { type TOptions } from 'ember-intl/services/intl';
3
- export declare const getTranslationFunction: (state: EditorState) => (key: string, fallback: string, options?: TOptions) => string;
3
+ export declare const getTranslationFunction: (state?: EditorState) => (key: string, fallback: string, options?: TOptions) => string;