@lblod/ember-rdfa-editor-lblod-plugins 11.2.0 → 12.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 (54) hide show
  1. package/.changeset/README.md +8 -0
  2. package/.changeset/config.json +11 -0
  3. package/.release-it.json +5 -8
  4. package/.woodpecker/.changeset.yml +9 -0
  5. package/.woodpecker/.test.yml +0 -8
  6. package/CHANGELOG.md +277 -111
  7. package/README.md +14 -12
  8. package/addon/components/citation-plugin/citation-card.ts +23 -19
  9. package/addon/components/citation-plugin/citation-insert.hbs +0 -1
  10. package/addon/components/citation-plugin/citation-insert.ts +5 -7
  11. package/addon/components/citation-plugin/citations/decision-detail.ts +4 -5
  12. package/addon/components/citation-plugin/citations/decision-preview.hbs +61 -15
  13. package/addon/components/citation-plugin/citations/decision-preview.ts +19 -0
  14. package/addon/components/citation-plugin/citations/search-modal.hbs +49 -47
  15. package/addon/components/citation-plugin/citations/search-modal.ts +29 -18
  16. package/addon/components/table-of-contents-plugin/ember-nodes/table-of-contents.ts +1 -1
  17. package/addon/components/variable-plugin/address/edit.ts +1 -1
  18. package/addon/components/variable-plugin/codelist/insert.ts +1 -1
  19. package/addon/components/variable-plugin/insert-variable-card.ts +1 -1
  20. package/addon/components/variable-plugin/location/insert.ts +1 -1
  21. package/addon/components/variable-plugin/number/nodeview.hbs +6 -7
  22. package/addon/components/variable-plugin/number/nodeview.ts +1 -58
  23. package/addon/helpers/capitalize.ts +6 -0
  24. package/addon/plugins/citation-plugin/index.ts +8 -2
  25. package/addon/plugins/citation-plugin/utils/article.ts +193 -0
  26. package/addon/plugins/citation-plugin/utils/cache.ts +7 -0
  27. package/addon/plugins/citation-plugin/utils/legal-documents.ts +133 -0
  28. package/addon/plugins/citation-plugin/utils/process-match.ts +60 -44
  29. package/addon/plugins/citation-plugin/utils/public-decisions.ts +228 -0
  30. package/addon/plugins/citation-plugin/utils/{legislation-types.ts → types.ts} +24 -18
  31. package/addon/plugins/citation-plugin/utils/utils.ts +14 -0
  32. package/addon/plugins/citation-plugin/utils/vlaamse-codex.ts +29 -390
  33. package/addon/utils/strings.ts +6 -0
  34. package/app/helpers/capitalize.js +4 -0
  35. package/components/citation-plugin/citation-card.d.ts +11 -14
  36. package/components/citation-plugin/citation-insert.d.ts +4 -3
  37. package/components/citation-plugin/citations/decision-detail.d.ts +3 -3
  38. package/components/citation-plugin/citations/decision-preview.d.ts +10 -0
  39. package/components/citation-plugin/citations/search-modal.d.ts +15 -16
  40. package/components/variable-plugin/number/nodeview.d.ts +0 -7
  41. package/helpers/capitalize.d.ts +8 -0
  42. package/package.json +8 -7
  43. package/plugins/citation-plugin/index.d.ts +2 -1
  44. package/plugins/citation-plugin/utils/article.d.ts +29 -0
  45. package/plugins/citation-plugin/utils/cache.d.ts +1 -0
  46. package/plugins/citation-plugin/utils/legal-documents.d.ts +48 -0
  47. package/plugins/citation-plugin/utils/public-decisions.d.ts +8 -0
  48. package/plugins/citation-plugin/utils/types.d.ts +28 -0
  49. package/plugins/citation-plugin/utils/utils.d.ts +1 -0
  50. package/plugins/citation-plugin/utils/vlaamse-codex.d.ts +7 -69
  51. package/translations/en-US.yaml +4 -1
  52. package/translations/nl-BE.yaml +4 -0
  53. package/utils/strings.d.ts +1 -0
  54. package/plugins/citation-plugin/utils/legislation-types.d.ts +0 -24
@@ -0,0 +1,228 @@
1
+ import {
2
+ executeCountQuery,
3
+ executeQuery,
4
+ } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/sparql-helpers';
5
+ import {
6
+ dateValue,
7
+ escapeValue,
8
+ } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/strings';
9
+
10
+ import {
11
+ LegalDocumentsQueryConfig,
12
+ LegalDocument,
13
+ LegalDocumentsQueryFilter,
14
+ LegalDocumentsCollection,
15
+ } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/citation-plugin/utils/legal-documents';
16
+ import { Binding } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/citation-plugin/utils/types';
17
+ import { replaceDiacriticsInWord } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/citation-plugin/utils/utils';
18
+
19
+ const getFilters = ({
20
+ words,
21
+ filter,
22
+ }: {
23
+ words: string[];
24
+ filter: LegalDocumentsQueryFilter;
25
+ }) => {
26
+ const { documentDateFrom, documentDateTo } = filter || {};
27
+
28
+ const documentDateFilter =
29
+ documentDateFrom || documentDateTo
30
+ ? ['?session prov:startedAtTime ?documentDate .']
31
+ : ['OPTIONAL { ?session prov:startedAtTime ?documentDate . }'];
32
+
33
+ if (documentDateFrom) {
34
+ documentDateFilter.push(
35
+ `FILTER (?documentDate >= "${documentDateFrom}"^^xsd:date)`,
36
+ );
37
+ }
38
+
39
+ if (documentDateTo) {
40
+ documentDateFilter.push(
41
+ `FILTER (?documentDate <= "${documentDateTo}"^^xsd:date) `,
42
+ );
43
+ }
44
+
45
+ return `
46
+ ${words
47
+ .map(
48
+ (word) =>
49
+ `FILTER (CONTAINS(LCASE(?decisionTitle), "${replaceDiacriticsInWord(
50
+ word,
51
+ ).toLowerCase()}"))`,
52
+ )
53
+ .join('\n')}
54
+ ${documentDateFilter.join('\n')}`;
55
+ };
56
+
57
+ const getCountQuery = ({
58
+ words,
59
+ filter,
60
+ }: {
61
+ words: string[];
62
+ filter: LegalDocumentsQueryFilter;
63
+ }) => {
64
+ const filterString = getFilters({ words, filter });
65
+
66
+ return `
67
+ PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
68
+ PREFIX besluit: <http://data.vlaanderen.be/ns/besluit#>
69
+ PREFIX ext: <http://mu.semte.ch/vocabularies/ext/>
70
+ PREFIX eli: <http://data.europa.eu/eli/ontology#>
71
+ PREFIX prov: <http://www.w3.org/ns/prov#>
72
+ PREFIX schema: <http://schema.org/>
73
+ PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
74
+ PREFIX mandaat: <http://data.vlaanderen.be/ns/mandaat#>
75
+ PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
76
+ PREFIX mu: <http://mu.semte.ch/vocabularies/core/>
77
+
78
+ SELECT (COUNT(DISTINCT(?decision)) as ?count) WHERE {
79
+ ?session rdf:type besluit:Zitting;
80
+ mu:uuid ?zittingUuid;
81
+ (besluit:isGehoudenDoor/mandaat:isTijdspecialisatieVan/skos:prefLabel) ?governmentName;
82
+ ext:besluitenlijst ?decisionList.
83
+ ?decisionList ext:besluitenlijstBesluit ?decision.
84
+ ?decision eli:title ?decisionTitle.
85
+ OPTIONAL {
86
+ ?agenda rdf:type besluit:BehandelingVanAgendapunt;
87
+ prov:generated ?decision.
88
+ ?treatment rdf:type ext:Uittreksel;
89
+ ext:uittrekselBvap ?agenda;
90
+ mu:uuid ?treatmentUuida.
91
+ }
92
+ ${filterString}
93
+ }
94
+ `;
95
+ };
96
+
97
+ const getQuery = ({
98
+ words,
99
+ filter,
100
+ pageNumber,
101
+ pageSize,
102
+ }: {
103
+ words: string[];
104
+ filter: LegalDocumentsQueryFilter;
105
+ pageNumber: number;
106
+ pageSize: number;
107
+ }) => {
108
+ const filterString = getFilters({ words, filter });
109
+
110
+ return `
111
+ PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
112
+ PREFIX besluit: <http://data.vlaanderen.be/ns/besluit#>
113
+ PREFIX ext: <http://mu.semte.ch/vocabularies/ext/>
114
+ PREFIX eli: <http://data.europa.eu/eli/ontology#>
115
+ PREFIX prov: <http://www.w3.org/ns/prov#>
116
+ PREFIX schema: <http://schema.org/>
117
+ PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
118
+ PREFIX mandaat: <http://data.vlaanderen.be/ns/mandaat#>
119
+ PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
120
+ PREFIX mu: <http://mu.semte.ch/vocabularies/core/>
121
+
122
+ SELECT DISTINCT ?governmentName ?decision ?decisionTitle ?documentDate ?zittingUuid ?treatmentUuid WHERE {
123
+ ?session rdf:type besluit:Zitting;
124
+ mu:uuid ?zittingUuid;
125
+ (besluit:isGehoudenDoor/mandaat:isTijdspecialisatieVan/skos:prefLabel) ?governmentName;
126
+ ext:besluitenlijst ?decisionList.
127
+ ?decisionList ext:besluitenlijstBesluit ?decision.
128
+ ?decision eli:title ?decisionTitle.
129
+ OPTIONAL {
130
+ ?agenda rdf:type besluit:BehandelingVanAgendapunt;
131
+ prov:generated ?decision.
132
+ ?treatment rdf:type ext:Uittreksel;
133
+ ext:uittrekselBvap ?agenda;
134
+ mu:uuid ?treatmentUuid.
135
+ }
136
+ ${filterString}
137
+ }
138
+ ORDER BY DESC (?documentDate) (?decisionTitle) LIMIT ${pageSize} OFFSET ${
139
+ pageNumber * pageSize
140
+ }
141
+ `;
142
+ };
143
+
144
+ interface PublicDecisionLegalDocumentBinding {
145
+ governmentName: Binding<string>;
146
+ decision: Binding<string>;
147
+ decisionTitle: Binding<string>;
148
+ documentDate?: Binding<string>;
149
+ zittingUuid: Binding<string>;
150
+ treatmentUuid?: Binding<string>;
151
+ }
152
+
153
+ export async function fetchPublicDecisions({
154
+ words,
155
+ filter,
156
+ pageNumber = 0,
157
+ pageSize = 5,
158
+ config,
159
+ }: {
160
+ words: string[];
161
+ config: LegalDocumentsQueryConfig;
162
+ filter: LegalDocumentsQueryFilter;
163
+ pageNumber?: number;
164
+ pageSize?: number;
165
+ }): Promise<LegalDocumentsCollection> {
166
+ const totalCount = await executeCountQuery({
167
+ query: getCountQuery({ words, filter }),
168
+ ...config,
169
+ });
170
+
171
+ if (totalCount > 0) {
172
+ const response = await executeQuery<PublicDecisionLegalDocumentBinding>({
173
+ query: getQuery({ words, filter, pageNumber, pageSize }),
174
+ ...config,
175
+ });
176
+
177
+ const legalDocuments = response.results.bindings.map((binding) => {
178
+ const escapedGovernmentName =
179
+ escapeValue(binding.governmentName.value) ?? '';
180
+
181
+ const escapedTitle = escapeValue(binding.decisionTitle.value) ?? '';
182
+
183
+ const publicationDate = dateValue(
184
+ binding.documentDate && binding.documentDate.value,
185
+ );
186
+
187
+ const documentDate = dateValue(
188
+ binding.documentDate && binding.documentDate.value,
189
+ );
190
+
191
+ return new LegalDocument({
192
+ uri: binding.decision.value,
193
+ title: `${escapedGovernmentName} - ${escapedTitle}`,
194
+ legislationTypeUri: filter.type,
195
+ publicationDate,
196
+ documentDate,
197
+ meta: {
198
+ publicationLink:
199
+ binding.zittingUuid.value && binding.treatmentUuid?.value
200
+ ? getPublicationLink({
201
+ zittingUuid: binding.zittingUuid.value,
202
+ treatmentUuid: binding.treatmentUuid.value,
203
+ })
204
+ : null,
205
+ },
206
+ });
207
+ });
208
+
209
+ return {
210
+ totalCount,
211
+ legalDocuments,
212
+ };
213
+ }
214
+
215
+ return {
216
+ totalCount,
217
+ legalDocuments: [],
218
+ };
219
+ }
220
+
221
+ const getPublicationLink = ({
222
+ zittingUuid,
223
+ treatmentUuid,
224
+ }: {
225
+ zittingUuid: string;
226
+ treatmentUuid: string;
227
+ }) =>
228
+ `https://publicatie.gelinkt-notuleren.lblod.info/Edegem/Gemeente/zittingen/${zittingUuid}/uittreksels/${treatmentUuid}`;
@@ -1,4 +1,6 @@
1
- const LEGISLATION_TYPES = {
1
+ import { capitalize } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/strings';
2
+
3
+ export const LEGISLATION_TYPES = {
2
4
  decreet: 'https://data.vlaanderen.be/id/concept/AardWetgeving/Decreet',
3
5
  'koninklijk besluit':
4
6
  'https://data.vlaanderen.be/id/concept/AardWetgeving/KoninklijkBesluit',
@@ -24,24 +26,28 @@ const LEGISLATION_TYPES = {
24
26
  'genummerd koninklijk besluit':
25
27
  'https://data.vlaanderen.be/id/concept/AardWetgeving/GenummerdKoninklijkBesluit',
26
28
  protocol: 'https://data.vlaanderen.be/id/concept/AardWetgeving/Protocol',
29
+ besluit: 'https://data.vlaanderen.be/doc/concept/AardWetgeving/Besluit',
27
30
  };
28
31
 
29
- export type Legislations = typeof LEGISLATION_TYPES;
30
- export type LegislationKey = keyof Legislations;
31
- // export type MappedLegislations = {
32
- // [K in LegislationKey]: {
33
- // label: K;
34
- // value: Legislations[K];
35
- // };
36
- // };
37
- // export type MappedLegislation = MappedLegislations[LegislationKey];
38
- const LEGISLATION_TYPE_CONCEPTS = Object.entries(LEGISLATION_TYPES).map(
39
- (pair: [string, string]) => {
40
- return {
41
- label: pair[0],
42
- value: pair[1],
43
- };
44
- },
32
+ export const legislationKeysCapitalized = Object.keys(LEGISLATION_TYPES).map(
33
+ capitalize,
34
+ ) as [Capitalize<keyof typeof LEGISLATION_TYPES>];
35
+
36
+ export const isLegislationType = (
37
+ type: string,
38
+ ): type is keyof typeof LEGISLATION_TYPES =>
39
+ Object.keys(LEGISLATION_TYPES).includes(type);
40
+
41
+ export const isBesluitType = (type: string) =>
42
+ type === LEGISLATION_TYPES['besluit'];
43
+
44
+ export const LEGISLATION_TYPE_CONCEPTS = Object.entries(LEGISLATION_TYPES).map(
45
+ ([label, value]) => ({
46
+ label,
47
+ value,
48
+ }),
45
49
  );
46
50
 
47
- export { LEGISLATION_TYPES, LEGISLATION_TYPE_CONCEPTS };
51
+ export interface Binding<A> {
52
+ value: A;
53
+ }
@@ -0,0 +1,14 @@
1
+ /*
2
+ * flemish codex encodes certain characters as a html character, which breaks our search
3
+ * this is an ugly work around
4
+ */
5
+ export function replaceDiacriticsInWord(word: string): string {
6
+ const characters =
7
+ 'Ë À Ì Â Í Ã Î Ä Ï Ç Ò È Ó É Ô Ê Õ Ö ê Ù ë Ú î Û ï Ü ô Ý õ â û ã ÿ ç'.split(
8
+ ' ',
9
+ );
10
+ for (const char of characters) {
11
+ word = word.replace(new RegExp(`${char}`, 'g'), `&#${char.charCodeAt(0)};`);
12
+ }
13
+ return word;
14
+ }