@lblod/ember-rdfa-editor-lblod-plugins 27.0.2 → 27.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,32 @@
1
1
  # @lblod/ember-rdfa-editor-lblod-plugins
2
2
 
3
+ ## 27.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#546](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/pull/546) [`b3f5a6b`](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/commit/b3f5a6b83ce1e9ce93445756e12e45fb2eb89645) Thanks [@elpoelma](https://github.com/elpoelma)! - Location plugin: add support for configuring the location types to show.
8
+ The location types may be configured through the `@locationTypes` argument of the `location-plugin/insert` component.
9
+
10
+ The `@locationTypes` argument expects an array of `LocationType` values.
11
+ Supported `LocationType` values are:
12
+
13
+ - 'address'
14
+ - 'place'
15
+ - 'area'
16
+
17
+ By default the value of `@locationTypes` is `['address', 'place', 'area']`
18
+
19
+ ## 27.0.3
20
+
21
+ ### Patch Changes
22
+
23
+ - [#545](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/pull/545) [`49f902f`](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/commit/49f902f2b5c89d7799ecd4f0b6732f2e412ee2f5) Thanks [@elpoelma](https://github.com/elpoelma)! - Remove number node when backspacing/deleting inside empty input field
24
+
25
+ - [#544](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/pull/544) [`4e5edc3`](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/commit/4e5edc35b206847be16b4417d26bac95c6ea7750) Thanks [@elpoelma](https://github.com/elpoelma)! - IRGN plugin: use `xsd:boolean` type instead of custom `mu` boolean type in SPARQL queries.
26
+ This fixes the functionality of the mobility measure code dropdown.
27
+
28
+ - [#541](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/pull/541) [`4b7daf7`](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/commit/4b7daf7e212a2f1aea9765908ef5897f49cc9c93) Thanks [@elpoelma](https://github.com/elpoelma)! - Implement quick successive structure title changes using transaction composition
29
+
3
30
  ## 27.0.2
4
31
 
5
32
  ### Patch Changes
@@ -35,7 +35,7 @@ import {
35
35
  } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/location-plugin/utils/address-helpers';
36
36
  import { type Point } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/location-plugin/utils/geo-helpers';
37
37
  import { type NodeContentsUtils } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/location-plugin/node-contents';
38
- import { type LocationType } from './map';
38
+ import { SUPPORTED_LOCATION_TYPES, type LocationType } from './map';
39
39
  import { type SafeString } from '@ember/template';
40
40
 
41
41
  interface Message {
@@ -47,6 +47,7 @@ interface Message {
47
47
 
48
48
  type Signature = {
49
49
  Args: {
50
+ locationTypes?: readonly LocationType[];
50
51
  locationType: LocationType;
51
52
  setLocationType: (type: LocationType) => void;
52
53
  defaultMunicipality?: string;
@@ -107,6 +108,21 @@ export default class LocationPluginEditComponent extends Component<Signature> {
107
108
  })
108
109
  newTruncatedValue?: boolean;
109
110
 
111
+ get locationTypes() {
112
+ return this.args.locationTypes ?? SUPPORTED_LOCATION_TYPES;
113
+ }
114
+
115
+ locationTypeLabel = (locationType: LocationType) => {
116
+ switch (locationType) {
117
+ case 'address':
118
+ return this.intl.t('location-plugin.types.address');
119
+ case 'place':
120
+ return this.intl.t('location-plugin.types.place');
121
+ case 'area':
122
+ return this.intl.t('location-plugin.types.area');
123
+ }
124
+ };
125
+
110
126
  get message(): Message | undefined {
111
127
  const value = this.newAddress.value as Address | undefined;
112
128
 
@@ -372,15 +388,11 @@ export default class LocationPluginEditComponent extends Component<Signature> {
372
388
  @onChange={{@setLocationType}}
373
389
  as |Group|
374
390
  >
375
- <Group.Radio @value='address'>
376
- {{t 'location-plugin.types.address'}}
377
- </Group.Radio>
378
- <Group.Radio @value='place'>
379
- {{t 'location-plugin.types.place'}}
380
- </Group.Radio>
381
- <Group.Radio @value='area'>
382
- {{t 'location-plugin.types.area'}}
383
- </Group.Radio>
391
+ {{#each this.locationTypes as |locationType|}}
392
+ <Group.Radio @value={{locationType}}>
393
+ {{this.locationTypeLabel locationType}}
394
+ </Group.Radio>
395
+ {{/each}}
384
396
  </AuRadioGroup>
385
397
  </fs.content>
386
398
  </AuFieldset>
@@ -28,7 +28,10 @@ import { replaceSelectionWithLocation } from '@lblod/ember-rdfa-editor-lblod-plu
28
28
  import { type LocationPluginConfig } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/location-plugin/node';
29
29
  import { NodeContentsUtils } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/location-plugin/node-contents';
30
30
  import Edit from './edit';
31
- import LocationMap, { type LocationType } from './map';
31
+ import LocationMap, {
32
+ SUPPORTED_LOCATION_TYPES,
33
+ type LocationType,
34
+ } from './map';
32
35
 
33
36
  export type CurrentLocation = Address | GlobalCoordinates | undefined;
34
37
 
@@ -55,6 +58,7 @@ interface Signature {
55
58
  config: LocationPluginConfig;
56
59
  defaultMunicipality?: string;
57
60
  templateMode?: boolean;
61
+ locationTypes?: LocationType[];
58
62
  };
59
63
  Element: HTMLLIElement;
60
64
  }
@@ -65,6 +69,24 @@ export default class LocationPluginInsertComponent extends Component<Signature>
65
69
  @tracked chosenPoint: GeoPos | undefined;
66
70
  @tracked isLoading = false;
67
71
 
72
+ constructor(owner: unknown, args: Signature['Args']) {
73
+ super(owner, args);
74
+ const unsupportedLocationType = this.args.locationTypes?.find(
75
+ (locationType) => !SUPPORTED_LOCATION_TYPES.includes(locationType),
76
+ );
77
+ if (unsupportedLocationType) {
78
+ throw new Error(
79
+ `${unsupportedLocationType} is not supported. Supported location types are ${SUPPORTED_LOCATION_TYPES.join(
80
+ ', ',
81
+ )}`,
82
+ );
83
+ }
84
+ }
85
+
86
+ get locationTypes() {
87
+ return this.args.locationTypes ?? SUPPORTED_LOCATION_TYPES;
88
+ }
89
+
68
90
  @trackedReset({
69
91
  memo: 'modalOpen',
70
92
  update: updateFromNode(Address, (address) => address),
@@ -99,11 +121,13 @@ export default class LocationPluginInsertComponent extends Component<Signature>
99
121
  update(component: LocationPluginInsertComponent) {
100
122
  return (
101
123
  updateFromNode(Place, () => 'place')(component) ??
102
- updateFromNode(Area, () => 'area', 'address')(component)
124
+ updateFromNode(Area, () => 'area')(component) ??
125
+ updateFromNode(Address, () => 'address')(component) ??
126
+ component.locationTypes[0]
103
127
  );
104
128
  },
105
129
  })
106
- locationType: LocationType = 'address';
130
+ declare locationType: LocationType;
107
131
 
108
132
  @trackedReset({
109
133
  memo: 'controller.activeEditorState',
@@ -284,6 +308,7 @@ export default class LocationPluginInsertComponent extends Component<Signature>
284
308
  <Edit
285
309
  @locationType={{this.locationType}}
286
310
  @setLocationType={{this.setLocationType}}
311
+ @locationTypes={{this.locationTypes}}
287
312
  @selectedLocationNode={{this.selectedLocationNode}}
288
313
  @setAddressToInsert={{this.setAddressToInsert}}
289
314
  @setIsLoading={{this.setIsLoading}}
@@ -20,7 +20,8 @@ import {
20
20
  type GlobalCoordinates,
21
21
  } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/location-plugin/utils/geo-helpers';
22
22
 
23
- export type LocationType = 'address' | 'place' | 'area';
23
+ export const SUPPORTED_LOCATION_TYPES = ['address', 'place', 'area'] as const;
24
+ export type LocationType = (typeof SUPPORTED_LOCATION_TYPES)[number];
24
25
 
25
26
  const MAP_TILE_ATTRIBUTION =
26
27
  '&copy; <a target="_blank" href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors';
@@ -27,6 +27,9 @@ import { getNameForStructureType } from '@lblod/ember-rdfa-editor-lblod-plugins/
27
27
  import { StructureType } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/structure-plugin/structure-types';
28
28
  import { romanize } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/structure-plugin/utils/romanize';
29
29
  import { Transaction } from '@lblod/ember-rdfa-editor';
30
+ import { v4 as uuid } from 'uuid';
31
+ import { setCompositionID } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/_private/transaction-utils';
32
+ import { isNone } from '@lblod/ember-rdfa-editor/utils/_private/option';
30
33
 
31
34
  interface Sig {
32
35
  Args: EmberNodeArgs;
@@ -64,7 +67,9 @@ export default class Structure extends Component<Sig> {
64
67
  * A time counter to store the last time an update to the title was added to
65
68
  * the history
66
69
  * */
67
- @tracked historyTimeStamp: number = 0;
70
+ historyTimeStamp: number = 0;
71
+ currentCompositionID?: string;
72
+
68
73
  innerEditor: NestedProsemirror | null = null;
69
74
 
70
75
  get showPlaceholder() {
@@ -154,7 +159,10 @@ export default class Structure extends Component<Sig> {
154
159
  }
155
160
 
156
161
  onTitleUpdate = (content: string, tr: Transaction) => {
157
- let addToHistory = false;
162
+ const pos = this.args.getPos();
163
+ if (isNone(pos)) {
164
+ return;
165
+ }
158
166
  // every character typed would normally trigger a history event
159
167
  // in normal editor operation, this is ok, as the history plugin is smart
160
168
  // enough to group adjacent edits made in a short timespan (default 500ms)
@@ -162,12 +170,19 @@ export default class Structure extends Component<Sig> {
162
170
  // but since we trigger an attribute update, the history plugin can no
163
171
  // longer recognize these edits as adjacent, so each character triggers
164
172
  // a history event. This makes undoing title edits tedious, so we mimic the
165
- // grouping here using the transaction timestamp
166
- if (tr.time - this.historyTimeStamp > 500) {
167
- addToHistory = true;
173
+ // grouping here using the transaction timestamp and compositionID
174
+ if (tr.time - this.historyTimeStamp > 500 || !this.currentCompositionID) {
168
175
  this.historyTimeStamp = tr.time;
176
+ this.currentCompositionID = uuid();
169
177
  }
170
- this.args.updateAttribute('title', content, !addToHistory);
178
+
179
+ this.controller.withTransaction(
180
+ (tr) => {
181
+ setCompositionID(tr, this.currentCompositionID);
182
+ return tr.setNodeAttribute(pos, 'title', content);
183
+ },
184
+ { view: this.args.view },
185
+ );
171
186
  };
172
187
  onInnerEditorFocus = (view: SayView) => {
173
188
  this.controller.setActiveView(view);
@@ -25,6 +25,7 @@
25
25
  placeholder={{t 'variable.number.type-number'}}
26
26
  {{did-insert this.focus}}
27
27
  {{on 'input' this.onInputNumberChange}}
28
+ {{on 'keydown' this.onInputKeydown}}
28
29
  {{leave-with-arrow-keys @controller @getPos}}
29
30
  {{leave-on-enter-key @controller @getPos}}
30
31
  />
@@ -107,6 +107,29 @@ export default class NumberNodeviewComponent extends Component<Args> {
107
107
  this.validateAndSave();
108
108
  }
109
109
 
110
+ @action
111
+ onInputKeydown(event: KeyboardEvent) {
112
+ if (
113
+ (event.key === 'Backspace' || event.key === 'Delete') &&
114
+ !this.inputNumber
115
+ ) {
116
+ event.preventDefault();
117
+ this.remove();
118
+ }
119
+ }
120
+
121
+ @action
122
+ remove() {
123
+ const pos = this.args.getPos();
124
+ if (pos !== undefined) {
125
+ this.controller.withTransaction((tr) => {
126
+ tr.deleteRange(pos, pos + this.node.nodeSize);
127
+ return tr;
128
+ });
129
+ this.controller.focus();
130
+ }
131
+ }
132
+
110
133
  @action
111
134
  changeWrittenNumber() {
112
135
  this.args.updateAttribute('writtenNumber', !this.writtenNumber);
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  executeQuery,
3
3
  objectify,
4
+ sparqlEscapeBool,
4
5
  sparqlEscapeString,
5
6
  sparqlEscapeUri,
6
7
  } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/sparql-helpers';
@@ -89,7 +90,7 @@ export default async function querySignCodes(
89
90
  ?uri mobiliteit:heeftMaatregelconcept ?measure.
90
91
  ?uri a ?signType;
91
92
  skos:prefLabel ?label;
92
- ext:valid "true"^^<http://mu.semte.ch/vocabularies/typed-literals/boolean>.
93
+ ext:valid ${sparqlEscapeBool(true)}.
93
94
  ${filterStatement}
94
95
  }
95
96
  ORDER BY ASC(?label)
@@ -0,0 +1,11 @@
1
+ // TODO: move these utility functions to the `@lblod/ember-rdfa-editor` package
2
+
3
+ import { Transaction } from '@lblod/ember-rdfa-editor';
4
+
5
+ export function setCompositionID(tr: Transaction, compositionID: unknown) {
6
+ return tr.setMeta('composition', compositionID);
7
+ }
8
+
9
+ export function getCompositionID(tr: Transaction): unknown {
10
+ return tr.getMeta('composition');
11
+ }
@@ -20,6 +20,10 @@ interface QueryConfig {
20
20
  export const sparqlEscapeString = (value: string) =>
21
21
  '"""' + value.replace(/[\\"]/g, (match) => '\\' + match) + '"""';
22
22
 
23
+ export const sparqlEscapeBool = (value: boolean) => {
24
+ return value ? '"true"^^xsd:boolean' : '"false"^^xsd:boolean';
25
+ };
26
+
23
27
  export const sparqlEscapeUri = (value: string) => {
24
28
  return (
25
29
  '<' +
@@ -14,6 +14,7 @@ interface Message {
14
14
  }
15
15
  type Signature = {
16
16
  Args: {
17
+ locationTypes?: readonly LocationType[];
17
18
  locationType: LocationType;
18
19
  setLocationType: (type: LocationType) => void;
19
20
  defaultMunicipality?: string;
@@ -34,6 +35,8 @@ export default class LocationPluginEditComponent extends Component<Signature> {
34
35
  newHousenumber?: string;
35
36
  newBusnumber?: string;
36
37
  newTruncatedValue?: boolean;
38
+ get locationTypes(): readonly ("address" | "area" | "place")[];
39
+ locationTypeLabel: (locationType: LocationType) => string;
37
40
  get message(): Message | undefined;
38
41
  get currentAddress(): Address | null;
39
42
  get currentMunicipality(): string | undefined;
@@ -14,6 +14,7 @@ interface Signature {
14
14
  config: LocationPluginConfig;
15
15
  defaultMunicipality?: string;
16
16
  templateMode?: boolean;
17
+ locationTypes?: LocationType[];
17
18
  };
18
19
  Element: HTMLLIElement;
19
20
  }
@@ -22,6 +23,8 @@ export default class LocationPluginInsertComponent extends Component<Signature>
22
23
  modalOpen: boolean;
23
24
  chosenPoint: GeoPos | undefined;
24
25
  isLoading: boolean;
26
+ constructor(owner: unknown, args: Signature['Args']);
27
+ get locationTypes(): readonly ["address", "place", "area"] | ("address" | "area" | "place")[];
25
28
  addressToInsert?: Address;
26
29
  savedLocation: GeoPos | undefined;
27
30
  placeName: string;
@@ -4,7 +4,8 @@ import { type LatLngBoundsExpression } from 'leaflet';
4
4
  import { type LeafletMouseEvent } from 'leaflet';
5
5
  import { Address } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/location-plugin/utils/address-helpers';
6
6
  import { GeoPos, type GlobalCoordinates } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/location-plugin/utils/geo-helpers';
7
- export type LocationType = 'address' | 'place' | 'area';
7
+ export declare const SUPPORTED_LOCATION_TYPES: readonly ["address", "place", "area"];
8
+ export type LocationType = (typeof SUPPORTED_LOCATION_TYPES)[number];
8
9
  interface Signature {
9
10
  Args: {
10
11
  address: Address | undefined;
@@ -20,6 +20,7 @@ export default class Structure extends Component<Sig> {
20
20
  * the history
21
21
  * */
22
22
  historyTimeStamp: number;
23
+ currentCompositionID?: string;
23
24
  innerEditor: NestedProsemirror | null;
24
25
  get showPlaceholder(): boolean;
25
26
  get controller(): import("@lblod/ember-rdfa-editor").SayController;
@@ -31,6 +31,8 @@ export default class NumberNodeviewComponent extends Component<Args> {
31
31
  get maxValue(): number;
32
32
  get label(): string | undefined;
33
33
  onInputNumberChange(event: InputEvent): void;
34
+ onInputKeydown(event: KeyboardEvent): void;
35
+ remove(): void;
34
36
  changeWrittenNumber(): void;
35
37
  get errorMessage(): string;
36
38
  validateAndSave(): void;
@@ -0,0 +1,3 @@
1
+ import { Transaction } from '@lblod/ember-rdfa-editor';
2
+ export declare function setCompositionID(tr: Transaction, compositionID: unknown): Transaction;
3
+ export declare function getCompositionID(tr: Transaction): unknown;
@@ -15,6 +15,7 @@ interface QueryConfig {
15
15
  abortSignal?: AbortSignal;
16
16
  }
17
17
  export declare const sparqlEscapeString: (value: string) => string;
18
+ export declare const sparqlEscapeBool: (value: boolean) => "\"true\"^^xsd:boolean" | "\"false\"^^xsd:boolean";
18
19
  export declare const sparqlEscapeUri: (value: string) => string;
19
20
  export declare function executeQuery<Binding = Record<string, RDF.Term>>({ query, endpoint, abortSignal, }: QueryConfig): Promise<QueryResult<Binding>>;
20
21
  export declare function executeCountQuery(queryConfig: QueryConfig): Promise<number>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lblod/ember-rdfa-editor-lblod-plugins",
3
- "version": "27.0.2",
3
+ "version": "27.1.0",
4
4
  "description": "Ember addon providing lblod specific plugins for the ember-rdfa-editor",
5
5
  "keywords": [
6
6
  "ember-addon",