@teipublisher/pb-components 1.27.0 → 1.28.2

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.
@@ -0,0 +1,124 @@
1
+ /* eslint-disable class-methods-use-this */
2
+ import { Registry } from './registry.js'
3
+
4
+ // Todo:
5
+ // - strings <- types
6
+ // - use scheme#types in @type output?
7
+ // - test with other providers, inside custom connector
8
+ // - documentation
9
+
10
+ async function getServiceManifest (endpoint) {
11
+ const response = await fetch(endpoint);
12
+ const data = await response.json();
13
+ return data;
14
+ }
15
+
16
+ export class ReconciliationService extends Registry {
17
+ constructor(configElem) {
18
+ super(configElem)
19
+ this.endpoint = configElem.getAttribute('endpoint');
20
+ this.debug = configElem.getAttribute('debug');
21
+ getServiceManifest(this.endpoint).then((result) => {
22
+ this.ORConfig = result;
23
+ if (this.debug) {
24
+ console.log(
25
+ 'OpenReconcile connector for register \'%s\' at endpoint <%s>. Using config: %o',
26
+ this._register, this.endpoint, this.ORConfig
27
+ );
28
+ }
29
+ })
30
+ }
31
+
32
+ /**
33
+ * Query the authority and return a RegistryResult.
34
+ *
35
+ * @param {String} key the search string
36
+ */
37
+ async query(key) {
38
+ const results = [];
39
+ const paramsObj = {
40
+ q1: {
41
+ query: key
42
+ }
43
+ };
44
+
45
+ return new Promise((resolve) => {
46
+ fetch(this.endpoint, {
47
+ method: 'POST',
48
+ headers: {
49
+ 'Accept': 'application/json',
50
+ 'Content-Type': 'application/x-www-form-urlencoded'
51
+ },
52
+ body: "queries=".concat(JSON.stringify(paramsObj))
53
+ })
54
+ .then((response) => response.json())
55
+ .then((json) => {
56
+ json.q1.result.forEach((item) => {
57
+ if (this.ORConfig.view) {
58
+ this.view = this.ORConfig.view.url.replace('{{id}}', item.id);
59
+ } else {
60
+ this.view = item.id;
61
+ }
62
+ if (item.description) {
63
+ this.description = item.description;
64
+ } else if (item.type) {
65
+ this.description = item.type.map(t => t.name.toString() ).join(', ')
66
+ } else {
67
+ this.description = ""
68
+ }
69
+ const result = {
70
+ register: this._register,
71
+ id: (this._prefix ? `${this._prefix}-${item.id}` : item.id),
72
+ label: item.name,
73
+ link: this.view,
74
+ details: this.description,
75
+ provider: 'OpenReconcile'
76
+ };
77
+ results.push(result);
78
+ });
79
+ if (this.debug) {
80
+ console.log(
81
+ 'OpenReconcile results: %o',
82
+ results
83
+ );
84
+ }
85
+ resolve({
86
+ totalItems: json.q1.result.length,
87
+ items: results,
88
+ });
89
+ })
90
+ })
91
+ }
92
+
93
+ /**
94
+ * Retrieve information about a registry entry and display it
95
+ * using the given container.
96
+ *
97
+ * @param {String} id the id to look up
98
+ * @param {HTMLElement} container reference to an element which should be used as container for displaying the information
99
+ * @returns {Promise} a promise
100
+ */
101
+ info(id, container) {
102
+ if (!id) {
103
+ return Promise.resolve({});
104
+ }
105
+ if (!this.ORConfig.preview) {
106
+ container.innerHTML = 'no \'preview\' information in endpoint\'s manifest';
107
+ return Promise.resolve();
108
+ }
109
+
110
+ return new Promise((resolve, reject) => {
111
+ const rawid = this._prefix ? id.substring(this._prefix.length + 1) : id;
112
+ const url = this.ORConfig.preview.url.replace('{{id}}', encodeURIComponent(rawid));
113
+ fetch(url)
114
+ .then(response => response.text())
115
+ .then((output) => {
116
+ container.innerHTML = output;
117
+ resolve({
118
+ id: this._prefix ? `${this._prefix}-${rawid}` : rawid
119
+ });
120
+ })
121
+ .catch(() => reject());
122
+ });
123
+ }
124
+ }
@@ -832,8 +832,9 @@ export class PbOddEditor extends pbHotkeys(pbMixin(LitElement)) {
832
832
  this.serializeAttribute('predicate', model.predicate),
833
833
  model.type === 'model' ? this.serializeAttribute('behaviour', model.behaviour) : '',
834
834
  this.serializeAttribute('cssClass', model.css),
835
- this.serializeAttribute('useSourceRendition', model.sourcerend)
836
- ].join('')
835
+ this.serializeAttribute('useSourceRendition', model.sourcerend),
836
+ this.serializeAttribute('pb:mode', model.mode)
837
+ ].join('');
837
838
 
838
839
  const desc = model.desc ? nestedIndent + '<desc>' + model.desc + '</desc>\n' : '';
839
840
 
@@ -854,6 +855,9 @@ export class PbOddEditor extends pbHotkeys(pbMixin(LitElement)) {
854
855
  }
855
856
  const name = this.serializeAttribute('name', parameter.name);
856
857
  const value = this.serializeAttribute('value', parameter.value);
858
+ if (parameter.set) {
859
+ return `${indent}<pb:set-param xmlns=""${name}${value}/>\n`
860
+ }
857
861
  return `${indent}<param${name}${value}/>\n`
858
862
  }
859
863
 
@@ -171,6 +171,7 @@ export class PbOddElementspecEditor extends LitElement {
171
171
  type="${model.type}"
172
172
  output="${model.output}"
173
173
  css="${model.css}"
174
+ mode="${model.mode}"
174
175
  .model="${model}"
175
176
  .parameters="${model.parameters}"
176
177
  desc="${model.desc}"
@@ -203,6 +204,7 @@ export class PbOddElementspecEditor extends LitElement {
203
204
  const newModel = {
204
205
  behaviour: 'inline',
205
206
  css: '',
207
+ mode: '',
206
208
  predicate: '',
207
209
  desc: '',
208
210
  type: addModel.selected,
@@ -271,6 +271,9 @@ export class PbOddModelEditor extends LitElement {
271
271
  return value;
272
272
  }
273
273
  },
274
+ mode: {
275
+ type: String
276
+ },
274
277
  model: {
275
278
  type: Object
276
279
  },
@@ -331,6 +334,7 @@ export class PbOddModelEditor extends LitElement {
331
334
  this.template = '';
332
335
  this.output = '';
333
336
  this.css = '';
337
+ this.mode = '';
334
338
  this.model = {};
335
339
  this.model.models = [];
336
340
  this.parameters = [];
@@ -479,6 +483,11 @@ export class PbOddModelEditor extends LitElement {
479
483
  placeholder="${translate('odd.editor.model.css-class-placeholder')}"
480
484
  label="CSS Class"
481
485
  @change="${this._inputCss}"></paper-input>
486
+
487
+ <paper-input id="mode" .value="${this.mode}"
488
+ placeholder="${translate('odd.editor.model.mode-placeholder')}"
489
+ label="Mode"
490
+ @change="${this._inputMode}"></paper-input>
482
491
 
483
492
  <pb-code-editor id="template"
484
493
  code="${this.template}"
@@ -501,6 +510,7 @@ export class PbOddModelEditor extends LitElement {
501
510
  behaviour="${this.behaviour}"
502
511
  name="${parameter.name}"
503
512
  value="${parameter.value}"
513
+ ?set="${parameter.set}"
504
514
  endpoint="${this.endpoint}"
505
515
  apiVersion="${this.apiVersion}"
506
516
  @parameter-remove="${(e) => this._removeParam(e, index)}"
@@ -543,6 +553,7 @@ export class PbOddModelEditor extends LitElement {
543
553
  type="${model.type}"
544
554
  output="${model.output}"
545
555
  css="${model.css}"
556
+ mode="${model.mode}"
546
557
  .model="${model}"
547
558
  .parameters="${model.parameters}"
548
559
  desc="${model.desc}"
@@ -836,6 +847,11 @@ export class PbOddModelEditor extends LitElement {
836
847
  this._fireModelChanged('css', this.css);
837
848
  }
838
849
 
850
+ _inputMode(ev) {
851
+ this.mode = ev.composedPath()[0].value;
852
+ this._fireModelChanged('mode', this.mode);
853
+ }
854
+
839
855
  _updateTemplate(ev) {
840
856
  this.template = this.shadowRoot.getElementById('template').getSource();
841
857
  this._fireModelChanged('template', this.template);
@@ -854,6 +870,7 @@ export class PbOddModelEditor extends LitElement {
854
870
  _updateParam(e, index) {
855
871
  this.parameters[index].name = e.detail.name;
856
872
  this.parameters[index].value = e.detail.value;
873
+ this.parameters[index].set = e.detail.set;
857
874
  this._fireModelChanged('parameters', this.parameters);
858
875
  }
859
876
 
@@ -29,7 +29,7 @@ export class PbOddParameterEditor extends LitElement {
29
29
  }
30
30
  .wrapper{
31
31
  display:grid;
32
- grid-template-columns:150px auto 50px;
32
+ grid-template-columns:150px auto 50px 50px;
33
33
  grid-column-gap:20px;
34
34
  grid-row-gap:20px;
35
35
  margin-bottom:10px;
@@ -37,8 +37,9 @@ export class PbOddParameterEditor extends LitElement {
37
37
  paper-dropdown-menu{
38
38
  align-self:start;
39
39
  }
40
- paper-icon-button{
41
- align-self:center;
40
+ paper-icon-button, paper-checkbox {
41
+ align-self: center;
42
+ margin-top: 16px;
42
43
  }
43
44
  `;
44
45
  }
@@ -56,7 +57,7 @@ export class PbOddParameterEditor extends LitElement {
56
57
  code="${this.value}"
57
58
  linter="${this.endpoint}/${cmpVersion(this.apiVersion, '1.0.0') ? 'modules/editor.xql' : 'api/lint'}"
58
59
  apiVersion="${this.apiVersion}"></pb-code-editor>
59
-
60
+ <paper-checkbox id="set" ?checked="${this.setParam}" @change="${this._handleCodeChange}">set</paper-checkbox>
60
61
  <paper-icon-button @click="${this._delete}" icon="delete" title="delete this parameter"></paper-icon-button>
61
62
  </div>
62
63
 
@@ -87,6 +88,10 @@ export class PbOddParameterEditor extends LitElement {
87
88
  parameters: {
88
89
  type: Object
89
90
  },
91
+ setParam: {
92
+ type: Boolean,
93
+ attribute: 'set'
94
+ },
90
95
  _currentParameters: {
91
96
  type: Array
92
97
  },
@@ -104,6 +109,7 @@ export class PbOddParameterEditor extends LitElement {
104
109
  super();
105
110
  this.name = '';
106
111
  this.value = '';
112
+ this.setParam = false;
107
113
  this.behaviour = '';
108
114
  this.currentParameters = [];
109
115
  this.parameters = {
@@ -189,7 +195,8 @@ export class PbOddParameterEditor extends LitElement {
189
195
  console.log('_handleCodeChange ', e);
190
196
  this.value = this.shadowRoot.getElementById('editor').getSource();
191
197
  this.name = this.shadowRoot.getElementById('combo').text;
192
- this.dispatchEvent(new CustomEvent('parameter-changed', { composed: true, bubbles: true, detail: { name: this.name, value: this.value } }));
198
+ this.setParam = this.shadowRoot.getElementById('set').checked;
199
+ this.dispatchEvent(new CustomEvent('parameter-changed', { composed: true, bubbles: true, detail: { name: this.name, value: this.value, set: this.setParam } }));
193
200
  }
194
201
 
195
202
 
@@ -60,6 +60,13 @@ export class PbTableGrid extends pbMixin(LitElement) {
60
60
  resizable: {
61
61
  type: Boolean
62
62
  },
63
+ perPage: {
64
+ type: Number,
65
+ attribute: 'per-page'
66
+ },
67
+ height: {
68
+ type: String
69
+ },
63
70
  /**
64
71
  * If specified, enable server-side search.
65
72
  */
@@ -79,6 +86,9 @@ export class PbTableGrid extends pbMixin(LitElement) {
79
86
  this._params = {};
80
87
  this.resizable = false;
81
88
  this.search = false;
89
+ this.perPage = 10;
90
+ this.height = null;
91
+ this.fixedHeader = false;
82
92
  }
83
93
 
84
94
  connectedCallback() {
@@ -93,6 +103,15 @@ export class PbTableGrid extends pbMixin(LitElement) {
93
103
  this._params = ev.state;
94
104
  this._submit();
95
105
  });
106
+
107
+ if (!this.height) {
108
+ const property = getComputedStyle(this).getPropertyValue('--pb-table-grid-height');
109
+ if (property) {
110
+ this.height = property;
111
+ } else {
112
+ this.height = 'auto';
113
+ }
114
+ }
96
115
  }
97
116
 
98
117
  firstUpdated() {
@@ -101,11 +120,12 @@ export class PbTableGrid extends pbMixin(LitElement) {
101
120
  const pbColumns = this.querySelectorAll('pb-table-column');
102
121
  const columns = [];
103
122
  pbColumns.forEach((column) => columns.push(column.data()));
104
-
105
123
  PbTableGrid.waitOnce('pb-page-ready', () => {
106
124
  this._params = this.getParameters();
107
125
  const url = this.toAbsoluteURL(this.source);
108
126
  const config = {
127
+ height: this.height,
128
+ fixedHeader: true,
109
129
  columns,
110
130
  resizable: this.resizable,
111
131
  server: {
@@ -115,6 +135,7 @@ export class PbTableGrid extends pbMixin(LitElement) {
115
135
  },
116
136
  sort: {
117
137
  multiColumn: false,
138
+ enabled: true,
118
139
  server: {
119
140
  url: (prev, cols) => {
120
141
  if (!cols.length) return prev;
@@ -125,7 +146,7 @@ export class PbTableGrid extends pbMixin(LitElement) {
125
146
  },
126
147
  pagination: {
127
148
  enabled: true,
128
- limit: 10,
149
+ limit: this.perPage,
129
150
  server: {
130
151
  url: (prev, page, limit) => {
131
152
  const form = this.shadowRoot.getElementById('form');
@@ -133,7 +154,7 @@ export class PbTableGrid extends pbMixin(LitElement) {
133
154
  Object.assign(this._params, form.serializeForm());
134
155
  }
135
156
  this._params.limit = limit;
136
- this._params.start = page * limit;
157
+ this._params.start = page * limit + 1;
137
158
  this.setParameters(this._params);
138
159
  this.pushHistory('grid', this._params);
139
160
 
@@ -142,6 +163,7 @@ export class PbTableGrid extends pbMixin(LitElement) {
142
163
  }
143
164
  }
144
165
  };
166
+
145
167
  this.grid = new Grid(config);
146
168
  this.grid.on('load', () => {
147
169
  this.emitTo('pb-results-received', {
@@ -454,7 +454,8 @@ class PbViewAnnotate extends PbView {
454
454
 
455
455
  console.log('<pb-view-annotate> Range: %o', range);
456
456
  const span = document.createElement('span');
457
- span.className = `annotation annotation-${teiRange.type} ${teiRange.type}`;
457
+ const addClass = teiRange.properties[this.key] === '' ? 'incomplete' : '';
458
+ span.className = `annotation annotation-${teiRange.type} ${teiRange.type} ${addClass}`;
458
459
  span.dataset.type = teiRange.type;
459
460
  span.dataset.annotation = JSON.stringify(teiRange.properties);
460
461
 
@@ -657,9 +658,12 @@ class PbViewAnnotate extends PbView {
657
658
  range = clearProperties(range);
658
659
  this.emitTo('pb-annotations-changed', { ranges: this._ranges });
659
660
  }
660
-
661
- const json = Object.assign(JSON.parse(span.dataset.annotation), properties);
661
+ const jsonOld = JSON.parse(span.dataset.annotation);
662
+ const json = Object.assign(jsonOld || {}, properties);
662
663
  span.dataset.annotation = JSON.stringify(json);
664
+ if (json[this.key] !== '') {
665
+ span.classList.remove('incomplete');
666
+ }
663
667
  }
664
668
 
665
669
  _editAnnotation(ev) {
@@ -753,7 +757,7 @@ class PbViewAnnotate extends PbView {
753
757
  ev.preventDefault();
754
758
  ev.stopPropagation();
755
759
  const type = span.dataset.type;
756
- const data = JSON.parse(span.dataset.annotation);
760
+ const data = JSON.parse(span.dataset.annotation) || {};
757
761
  const color = this._annotationColors.get(type);
758
762
  typeInd.innerHTML = type;
759
763
  typeInd.style.backgroundColor = `var(--pb-annotation-${type})`;
@@ -896,7 +900,7 @@ class PbViewAnnotate extends PbView {
896
900
  const annoData = node.parentNode.dataset.annotation;
897
901
  const annoType = node.parentNode.dataset.type;
898
902
  if (annoData && annoType) {
899
- const parsed = JSON.parse(annoData);
903
+ const parsed = JSON.parse(annoData) || {};
900
904
  isAnnotated = annoType === type;
901
905
  ref = parsed[this.key];
902
906
  }
@@ -1004,6 +1008,17 @@ class PbViewAnnotate extends PbView {
1004
1008
  classes.push(`
1005
1009
  .annotation-${type}::after {
1006
1010
  background-color: var(--pb-annotation-${type});
1011
+ border-color: var(--pb-annotation-${type});
1012
+ color: var(${color.isLight ? '--pb-color-primary' : '--pb-color-inverse'});
1013
+ }
1014
+ .annotation-${type}.incomplete::after {
1015
+ background: repeating-linear-gradient(
1016
+ 315deg,
1017
+ var(--pb-annotation-${type}),
1018
+ var(--pb-annotation-${type}) 5px,
1019
+ var(${color.isLight ? '--pb-annotation-stripes-light' : '--pb-annotation-stripes-dark'}) 5px,
1020
+ var(${color.isLight ? '--pb-annotation-stripes-light' : '--pb-annotation-stripes-dark'}) 10px
1021
+ );
1007
1022
  color: var(${color.isLight ? '--pb-color-primary' : '--pb-color-inverse'});
1008
1023
  }
1009
1024
  `);
@@ -1064,7 +1079,7 @@ class PbViewAnnotate extends PbView {
1064
1079
  font-variant: normal;
1065
1080
  padding: 2px;
1066
1081
  }
1067
-
1082
+
1068
1083
  [part=highlight] {
1069
1084
  border: 3px solid rgb(255, 174, 0);
1070
1085
  border-radius: 8px;
package/src/pb-view.js CHANGED
@@ -496,6 +496,15 @@ export class PbView extends pbMixin(LitElement) {
496
496
 
497
497
  _refresh(ev) {
498
498
  if (ev && ev.detail) {
499
+ if (ev.detail.hash && !(ev.detail.id || ev.detail.path || ev.detail.odd || ev.detail.view || ev.detail.position)) {
500
+ // if only the scroll target has changed: scroll to the element without reloading
501
+ this._scrollTarget = ev.detail.hash;
502
+ const target = this.shadowRoot.getElementById(this._scrollTarget);
503
+ if (target) {
504
+ setTimeout(() => target.scrollIntoView());
505
+ }
506
+ return;
507
+ }
499
508
  if (ev.detail.path) {
500
509
  const doc = this.getDocument();
501
510
  doc.path = ev.detail.path;
@@ -641,7 +650,7 @@ export class PbView extends pbMixin(LitElement) {
641
650
  if (target) {
642
651
  setTimeout(() => {
643
652
  target.scrollIntoView();
644
- });
653
+ }, 100);
645
654
  }
646
655
  this._scrollTarget = null;
647
656
  });