@teipublisher/pb-components 1.24.19 → 1.27.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/.github/workflows/node.js.yml +6 -5
- package/CHANGELOG.md +36 -0
- package/css/gridjs/mermaid.min.css +1 -0
- package/dist/demo/demos.json +4 -1
- package/dist/demo/pb-table-grid.html +17 -0
- package/dist/demo/people.json +35 -0
- package/dist/pb-components-bundle.js +245 -217
- package/dist/pb-elements.json +221 -9
- package/package.json +2 -1
- package/pb-elements.json +221 -9
- package/src/authority/connectors.js +4 -0
- package/src/authority/gf.js +152 -0
- package/src/dts-client.js +51 -14
- package/src/dts-select-endpoint.js +5 -3
- package/src/pb-components.js +1 -0
- package/src/pb-load.js +6 -0
- package/src/pb-table-column.js +66 -0
- package/src/pb-table-grid.js +190 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { Registry } from "./registry.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Connector for the corporate archive of Georgfischer AG.
|
|
5
|
+
*/
|
|
6
|
+
export class GF extends Registry {
|
|
7
|
+
|
|
8
|
+
constructor(configElem) {
|
|
9
|
+
super(configElem);
|
|
10
|
+
this._api = configElem.getAttribute('api');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async query(key) {
|
|
14
|
+
const results = [];
|
|
15
|
+
|
|
16
|
+
const register = this.getRegister();
|
|
17
|
+
const url = `https://archives.georgfischer.com/api/${register}?search=${encodeURIComponent(key)}`;
|
|
18
|
+
const label = this.getLabelField();
|
|
19
|
+
return new Promise((resolve) => {
|
|
20
|
+
fetch(url)
|
|
21
|
+
.then(response => response.json())
|
|
22
|
+
.then(json => {
|
|
23
|
+
if (!json.data) {
|
|
24
|
+
resolve({
|
|
25
|
+
totalItems: 0,
|
|
26
|
+
items: []
|
|
27
|
+
});
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
json.data.forEach(item => {
|
|
31
|
+
if ((this._register === 'organization' && item.authority_type === 'Person') ||
|
|
32
|
+
(this._register === 'person' && item.authority_type !== 'Person')) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const result = {
|
|
36
|
+
register: this._register,
|
|
37
|
+
id: (this._prefix ? `${this._prefix}-${item.id}` : item.id),
|
|
38
|
+
label: item[label],
|
|
39
|
+
details: `${item.id}`,
|
|
40
|
+
link: `https://archives.georgfischer.com/api/${register}/${item.id}`,
|
|
41
|
+
strings: [item[label]],
|
|
42
|
+
provider: 'GF'
|
|
43
|
+
};
|
|
44
|
+
results.push(result);
|
|
45
|
+
});
|
|
46
|
+
resolve({
|
|
47
|
+
totalItems: json.meta.total,
|
|
48
|
+
items: results,
|
|
49
|
+
});
|
|
50
|
+
})
|
|
51
|
+
.catch((reason) => Promise.reject(reason));
|
|
52
|
+
})
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
info(key, container) {
|
|
56
|
+
if (!key) {
|
|
57
|
+
return Promise.resolve({});
|
|
58
|
+
}
|
|
59
|
+
const id = this._prefix ? key.substring(this._prefix.length + 1) : key;
|
|
60
|
+
const label = this.getLabelField();
|
|
61
|
+
return new Promise((resolve) => {
|
|
62
|
+
this.getRecord(id)
|
|
63
|
+
.then(json => {
|
|
64
|
+
const died = json.data.death ? `† ${json.data.death}` : '';
|
|
65
|
+
const dates = json.data.birth ? `<p>* ${json.data.birth} ${died}</p>` : '';
|
|
66
|
+
const note = json.data.note_bio ? `<p>${json.data.note_bio}</p>` : '';
|
|
67
|
+
const output = `
|
|
68
|
+
<h3 class="label"><a href="https://${json.wikipediaURL}" target="_blank">${json.data[label]}</a></h3>
|
|
69
|
+
${dates}
|
|
70
|
+
${note}
|
|
71
|
+
`;
|
|
72
|
+
container.innerHTML = output;
|
|
73
|
+
resolve({
|
|
74
|
+
id: (this._prefix ? `${this._prefix}-${json.data.id}` : json.data.id),
|
|
75
|
+
strings: [json.data[label]]
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Retrieve a raw JSON record for the given key as returned by the endpoint.
|
|
83
|
+
*
|
|
84
|
+
* @param {string} key the key to look up
|
|
85
|
+
* @returns {Promise<any>} promise resolving to the JSON record returned by the endpoint
|
|
86
|
+
*/
|
|
87
|
+
async getRecord(key) {
|
|
88
|
+
const id = key.replace(/^.*-([^-]+)$/, '$1');
|
|
89
|
+
const url = `https://archives.georgfischer.com/api/${this.getRegister()}/${id}`;
|
|
90
|
+
return fetch(url)
|
|
91
|
+
.then(response => response.json())
|
|
92
|
+
.then(json => {
|
|
93
|
+
const output = Object.assign({}, json);
|
|
94
|
+
output.name = json.data[this.getLabelField()];
|
|
95
|
+
switch (this._register) {
|
|
96
|
+
case 'place':
|
|
97
|
+
output.country = json.data.country;
|
|
98
|
+
output.location = json.data.location.coordinates;
|
|
99
|
+
output.links = json.data.links.map((link) => link.url);
|
|
100
|
+
break;
|
|
101
|
+
case 'person':
|
|
102
|
+
output.birth = json.data.birth;
|
|
103
|
+
output.death = json.data.death;
|
|
104
|
+
output.note = json.data.note_bio;
|
|
105
|
+
output.links = [`https://${json.wikipediaURL}`];
|
|
106
|
+
break;
|
|
107
|
+
default:
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
return output;
|
|
111
|
+
})
|
|
112
|
+
.catch((reason) => Promise.reject(reason));
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
getLabelField() {
|
|
116
|
+
let label;
|
|
117
|
+
switch (this._register) {
|
|
118
|
+
case 'term':
|
|
119
|
+
label = 'label';
|
|
120
|
+
break;
|
|
121
|
+
default:
|
|
122
|
+
label = 'fullname';
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
return label;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
getRegister() {
|
|
129
|
+
if (this._api) {
|
|
130
|
+
return this._api;
|
|
131
|
+
}
|
|
132
|
+
let register;
|
|
133
|
+
switch(this._register) {
|
|
134
|
+
case 'person':
|
|
135
|
+
case 'organization':
|
|
136
|
+
register = 'actors';
|
|
137
|
+
break;
|
|
138
|
+
case 'place':
|
|
139
|
+
register = 'places';
|
|
140
|
+
break;
|
|
141
|
+
case 'term':
|
|
142
|
+
register = 'keywords';
|
|
143
|
+
break;
|
|
144
|
+
case 'abbreviation':
|
|
145
|
+
register = 'abbreviations';
|
|
146
|
+
break;
|
|
147
|
+
default:
|
|
148
|
+
register = this._register;
|
|
149
|
+
}
|
|
150
|
+
return register;
|
|
151
|
+
}
|
|
152
|
+
}
|
package/src/dts-client.js
CHANGED
|
@@ -4,6 +4,7 @@ import { translate } from "./pb-i18n.js";
|
|
|
4
4
|
import '@polymer/iron-ajax';
|
|
5
5
|
import '@polymer/iron-icon';
|
|
6
6
|
import '@polymer/iron-icons';
|
|
7
|
+
import '@polymer/paper-button';
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* A client for the Distributed Text Services (DTS) protocol. This defines an API
|
|
@@ -13,6 +14,13 @@ import '@polymer/iron-icons';
|
|
|
13
14
|
* @slot toolbar - toolbar area
|
|
14
15
|
* @slot pagination - pagination area
|
|
15
16
|
*
|
|
17
|
+
* @csspart parent-link - Link to parent collection
|
|
18
|
+
* @csspart collection-title - Collection title
|
|
19
|
+
* @csspart title - Member title
|
|
20
|
+
* @csspart author - Author
|
|
21
|
+
* @csspart license - License information
|
|
22
|
+
* @csspart link - Links
|
|
23
|
+
*
|
|
16
24
|
* @fires pb-start-update - Fired before the element updates its content
|
|
17
25
|
* @fires pb-results-received - Fired when results are received from the server
|
|
18
26
|
* @fires pb-end-update - Fired after the element has finished updating its content
|
|
@@ -44,6 +52,12 @@ export class DtsClient extends pbMixin(LitElement) {
|
|
|
44
52
|
};
|
|
45
53
|
}
|
|
46
54
|
|
|
55
|
+
constructor() {
|
|
56
|
+
super();
|
|
57
|
+
this._parentCollections = [];
|
|
58
|
+
this.collection = 'default';
|
|
59
|
+
}
|
|
60
|
+
|
|
47
61
|
connectedCallback() {
|
|
48
62
|
super.connectedCallback();
|
|
49
63
|
|
|
@@ -51,7 +65,7 @@ export class DtsClient extends pbMixin(LitElement) {
|
|
|
51
65
|
this.page = this.getParameter('page');
|
|
52
66
|
|
|
53
67
|
this.subscribeTo('dts-endpoint', (ev) => {
|
|
54
|
-
this._setEndpoint(ev.detail.endpoint, ev.detail.reload);
|
|
68
|
+
this._setEndpoint(ev.detail.endpoint, ev.detail.collection, ev.detail.reload);
|
|
55
69
|
});
|
|
56
70
|
this.subscribeTo('pb-load', (ev) => {
|
|
57
71
|
this.page = ev.detail.params.page;
|
|
@@ -68,11 +82,11 @@ export class DtsClient extends pbMixin(LitElement) {
|
|
|
68
82
|
this.signalReady();
|
|
69
83
|
}
|
|
70
84
|
|
|
71
|
-
_setEndpoint(endpoint, reload) {
|
|
85
|
+
_setEndpoint(endpoint, collection, reload) {
|
|
72
86
|
if (!reload) {
|
|
73
87
|
this.page = null;
|
|
74
|
-
this.collection = null;
|
|
75
88
|
}
|
|
89
|
+
this.collection = collection;
|
|
76
90
|
this._configureEndpoint(endpoint);
|
|
77
91
|
this.baseUri = endpoint;
|
|
78
92
|
}
|
|
@@ -86,14 +100,24 @@ export class DtsClient extends pbMixin(LitElement) {
|
|
|
86
100
|
}
|
|
87
101
|
}
|
|
88
102
|
|
|
89
|
-
_navigate(ev, member) {
|
|
103
|
+
_navigate(ev, member, downwards = true) {
|
|
90
104
|
ev.preventDefault();
|
|
91
|
-
|
|
105
|
+
if (downwards) {
|
|
106
|
+
this._parentCollections.push(this.collection);
|
|
107
|
+
}
|
|
108
|
+
this.collection = member && typeof member === 'object' ? member['@id'] : member;
|
|
92
109
|
this.page = null;
|
|
93
110
|
console.log('<dts-client> navigating to collection %s', this.collection);
|
|
94
111
|
this._update();
|
|
95
112
|
}
|
|
96
113
|
|
|
114
|
+
_navigateUp(ev) {
|
|
115
|
+
if (this._parentCollections.length === 0) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
this._navigate(ev, this._parentCollections.pop(), false);
|
|
119
|
+
}
|
|
120
|
+
|
|
97
121
|
_preview(ev, member) {
|
|
98
122
|
ev.preventDefault();
|
|
99
123
|
this.emitTo('pb-start-update');
|
|
@@ -236,8 +260,17 @@ export class DtsClient extends pbMixin(LitElement) {
|
|
|
236
260
|
_renderClient() {
|
|
237
261
|
return html`
|
|
238
262
|
<div class="uri">${this.baseUri}</div>
|
|
239
|
-
<h3>${this.data ? this.data.title : 'Loading ...'}</h3>
|
|
263
|
+
<h3 part="collection-title">${this.data ? this.data.title : 'Loading ...'}</h3>
|
|
240
264
|
<slot name="pagination"></slot>
|
|
265
|
+
${
|
|
266
|
+
this._parentCollections.length > 0 || this.collection ?
|
|
267
|
+
html`
|
|
268
|
+
<paper-button part="parent-link" @click="${this._navigateUp}">
|
|
269
|
+
<iron-icon icon="icons:arrow-upward"></iron-icon>
|
|
270
|
+
${translate('browse.up')}
|
|
271
|
+
</paper-button>`
|
|
272
|
+
: null
|
|
273
|
+
}
|
|
241
274
|
${this.data ? this._renderMembers() : ''}
|
|
242
275
|
`;
|
|
243
276
|
}
|
|
@@ -255,9 +288,11 @@ export class DtsClient extends pbMixin(LitElement) {
|
|
|
255
288
|
return html`
|
|
256
289
|
<iron-icon icon="icons:folder-open"></iron-icon>
|
|
257
290
|
<div class="details">
|
|
258
|
-
<
|
|
259
|
-
<
|
|
260
|
-
|
|
291
|
+
<a href="#" @click="${(ev) => this._navigate(ev, member)}" part="link">
|
|
292
|
+
<h4 class="collection" part="collection-title">
|
|
293
|
+
${member.title}
|
|
294
|
+
</h4>
|
|
295
|
+
</a>
|
|
261
296
|
</div>
|
|
262
297
|
`;
|
|
263
298
|
}
|
|
@@ -266,11 +301,13 @@ export class DtsClient extends pbMixin(LitElement) {
|
|
|
266
301
|
<iron-icon icon="icons:code"></iron-icon>
|
|
267
302
|
<div class="details">
|
|
268
303
|
<div>
|
|
269
|
-
<
|
|
270
|
-
<
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
304
|
+
<a href="#" @click="${(ev) => this._preview(ev, member)}" part="link">
|
|
305
|
+
<h4 part="title">
|
|
306
|
+
${member.title}
|
|
307
|
+
</h4>
|
|
308
|
+
</a>
|
|
309
|
+
<p part="creator" class="creator">${DtsClient._getCreator(member)}</p>
|
|
310
|
+
${license ? html`<p part="license" class="license"><a href="${license}">${translate('dts.licence')}</a></p>` : ''}
|
|
274
311
|
</div>
|
|
275
312
|
<iron-icon title="${translate('dts.import')}" icon="icons:file-download"
|
|
276
313
|
@click="${(ev) => this._download(ev, member)}">
|
|
@@ -95,14 +95,16 @@ export class DtsSelectEndpoint extends pbMixin(LitElement) {
|
|
|
95
95
|
if (!newEndpoint) {
|
|
96
96
|
return;
|
|
97
97
|
}
|
|
98
|
-
this.
|
|
98
|
+
const endpoint = this.endpoints.find((endp) => endp.url === newEndpoint);
|
|
99
|
+
this.setParameter('endpoint', endpoint.url);
|
|
99
100
|
this.pushHistory('dts-endpoint');
|
|
100
101
|
console.log('<dts-select-endpoint> Setting endpoint to %s', newEndpoint);
|
|
101
102
|
this.emitTo('dts-endpoint', {
|
|
102
|
-
endpoint:
|
|
103
|
+
endpoint: endpoint.url,
|
|
104
|
+
collection: endpoint.collection,
|
|
103
105
|
reload: !this.endpoint
|
|
104
106
|
});
|
|
105
|
-
this.endpoint =
|
|
107
|
+
this.endpoint = endpoint.url;
|
|
106
108
|
}
|
|
107
109
|
}
|
|
108
110
|
customElements.define('dts-select-endpoint', DtsSelectEndpoint);
|
package/src/pb-components.js
CHANGED
|
@@ -56,6 +56,7 @@ import './pb-authority-lookup.js';
|
|
|
56
56
|
import './pb-message.js';
|
|
57
57
|
import './pb-blacklab-results.js';
|
|
58
58
|
import './pb-blacklab-highlight.js';
|
|
59
|
+
import './pb-table-grid.js';
|
|
59
60
|
|
|
60
61
|
import '@polymer/iron-icons/editor-icons';
|
|
61
62
|
import '@polymer/iron-icons/social-icons';
|
package/src/pb-load.js
CHANGED
|
@@ -160,6 +160,12 @@ export class PbLoad extends pbMixin(LitElement) {
|
|
|
160
160
|
}
|
|
161
161
|
this.wait(() => this.load());
|
|
162
162
|
});
|
|
163
|
+
} else {
|
|
164
|
+
PbLoad.waitOnce('pb-page-ready', (data) => {
|
|
165
|
+
if (data && data.language) {
|
|
166
|
+
this.language = data.language;
|
|
167
|
+
}
|
|
168
|
+
});
|
|
163
169
|
}
|
|
164
170
|
}
|
|
165
171
|
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { LitElement } from 'lit-element';
|
|
2
|
+
import { html } from "gridjs";
|
|
3
|
+
import './pb-popover.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Defines a column within `pb-table-grid`.
|
|
7
|
+
*/
|
|
8
|
+
export class PbTableColumn extends LitElement {
|
|
9
|
+
static get properties() {
|
|
10
|
+
return {
|
|
11
|
+
/**
|
|
12
|
+
* Column heading to display
|
|
13
|
+
*/
|
|
14
|
+
label: {
|
|
15
|
+
type: String
|
|
16
|
+
},
|
|
17
|
+
/**
|
|
18
|
+
* Name of the JSON property containing the data
|
|
19
|
+
*/
|
|
20
|
+
property: {
|
|
21
|
+
type: String
|
|
22
|
+
},
|
|
23
|
+
/**
|
|
24
|
+
* Should the column support sorting?
|
|
25
|
+
*/
|
|
26
|
+
sort: {
|
|
27
|
+
type: Boolean
|
|
28
|
+
},
|
|
29
|
+
/**
|
|
30
|
+
* Optional fixed width of the column (e.g. '200px' or '30%')
|
|
31
|
+
*/
|
|
32
|
+
width: {
|
|
33
|
+
type: String
|
|
34
|
+
},
|
|
35
|
+
...super.properties
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
constructor() {
|
|
40
|
+
super();
|
|
41
|
+
this.label = 'no-label';
|
|
42
|
+
this.property = null;
|
|
43
|
+
this.sort = false;
|
|
44
|
+
this.width = null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
connectedCallback() {
|
|
48
|
+
super.connectedCallback();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
data() {
|
|
52
|
+
const config = {
|
|
53
|
+
name: this.label,
|
|
54
|
+
sort: { enabled: this.sort },
|
|
55
|
+
formatter: (cell) => html(cell)
|
|
56
|
+
};
|
|
57
|
+
if (this.property) {
|
|
58
|
+
config.id = this.property;
|
|
59
|
+
}
|
|
60
|
+
if (this.width) {
|
|
61
|
+
config.width = this.width;
|
|
62
|
+
}
|
|
63
|
+
return config;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
customElements.define('pb-table-column', PbTableColumn);
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { LitElement, html, css } from 'lit-element';
|
|
2
|
+
import { Grid } from "gridjs";
|
|
3
|
+
import { pbMixin } from './pb-mixin.js';
|
|
4
|
+
import { resolveURL } from './utils.js';
|
|
5
|
+
import '@polymer/paper-input/paper-input';
|
|
6
|
+
import '@polymer/iron-icons';
|
|
7
|
+
import '@polymer/iron-form';
|
|
8
|
+
import '@polymer/paper-icon-button';
|
|
9
|
+
import './pb-table-column.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* A table grid based on [gridjs](https://gridjs.io/), which loads its data from a server endpoint
|
|
13
|
+
* specified in `source`. If `source` is a relative URI, it will be resolved relative to the
|
|
14
|
+
* TEI Publisher endpoint.
|
|
15
|
+
*
|
|
16
|
+
* The JSON data returned by the endpoint should be an object with two properties:
|
|
17
|
+
*
|
|
18
|
+
* * `count`: the overall number of rows available on the server
|
|
19
|
+
* * `results`: an array containing each record as an object
|
|
20
|
+
*
|
|
21
|
+
* The parameters send to the server are as follows:
|
|
22
|
+
*
|
|
23
|
+
*
|
|
24
|
+
* Parameter | Description
|
|
25
|
+
* ---------|----------
|
|
26
|
+
* limit | number of records to return for each page
|
|
27
|
+
* start | start offset from which to return records
|
|
28
|
+
* order | the id of the column to sort by
|
|
29
|
+
* dir | sort direction: either 'asc' or 'desc'
|
|
30
|
+
* search | an optional search string entered by the user
|
|
31
|
+
*
|
|
32
|
+
* Table columns are configured via nested `<pb-table-column>` elements:
|
|
33
|
+
*
|
|
34
|
+
* ```html
|
|
35
|
+
* <pb-table-column label="Name" property="name" sort width="33%"></pb-table-column>
|
|
36
|
+
* <pb-table-column label="Born" property="birth"></pb-table-column>
|
|
37
|
+
* <pb-table-column label="Died" property="death"></pb-table-column>
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export class PbTableGrid extends pbMixin(LitElement) {
|
|
41
|
+
static get properties() {
|
|
42
|
+
return {
|
|
43
|
+
/**
|
|
44
|
+
* URI of the server-side endpoint to retrieve data from.
|
|
45
|
+
* Relative URIs are resolved relative to the configured TEI Publisher endpoint.
|
|
46
|
+
*/
|
|
47
|
+
source: {
|
|
48
|
+
type: String
|
|
49
|
+
},
|
|
50
|
+
/**
|
|
51
|
+
* Path to the gridjs theme CSS files.
|
|
52
|
+
*/
|
|
53
|
+
cssPath: {
|
|
54
|
+
type: String,
|
|
55
|
+
attribute: 'css-path'
|
|
56
|
+
},
|
|
57
|
+
/**
|
|
58
|
+
* If specified, columns (without a fixed width) will be resizable.
|
|
59
|
+
*/
|
|
60
|
+
resizable: {
|
|
61
|
+
type: Boolean
|
|
62
|
+
},
|
|
63
|
+
/**
|
|
64
|
+
* If specified, enable server-side search.
|
|
65
|
+
*/
|
|
66
|
+
search: {
|
|
67
|
+
type: Boolean
|
|
68
|
+
},
|
|
69
|
+
_params: {
|
|
70
|
+
type: Object
|
|
71
|
+
},
|
|
72
|
+
...super.properties
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
constructor() {
|
|
77
|
+
super();
|
|
78
|
+
this.cssPath = '../css/gridjs';
|
|
79
|
+
this._params = {};
|
|
80
|
+
this.resizable = false;
|
|
81
|
+
this.search = false;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
connectedCallback() {
|
|
85
|
+
super.connectedCallback();
|
|
86
|
+
|
|
87
|
+
this.subscribeTo('pb-search-resubmit', (ev) => {
|
|
88
|
+
this._params = Object.assign({}, ev.detail.params);
|
|
89
|
+
this._submit();
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
window.addEventListener('popstate', (ev) => {
|
|
93
|
+
this._params = ev.state;
|
|
94
|
+
this._submit();
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
firstUpdated() {
|
|
99
|
+
const table = this.shadowRoot.getElementById('table');
|
|
100
|
+
|
|
101
|
+
const pbColumns = this.querySelectorAll('pb-table-column');
|
|
102
|
+
const columns = [];
|
|
103
|
+
pbColumns.forEach((column) => columns.push(column.data()));
|
|
104
|
+
|
|
105
|
+
PbTableGrid.waitOnce('pb-page-ready', () => {
|
|
106
|
+
this._params = this.getParameters();
|
|
107
|
+
const url = this.toAbsoluteURL(this.source);
|
|
108
|
+
const config = {
|
|
109
|
+
columns,
|
|
110
|
+
resizable: this.resizable,
|
|
111
|
+
server: {
|
|
112
|
+
url,
|
|
113
|
+
then: data => data.results,
|
|
114
|
+
total: data => data.count
|
|
115
|
+
},
|
|
116
|
+
sort: {
|
|
117
|
+
multiColumn: false,
|
|
118
|
+
server: {
|
|
119
|
+
url: (prev, cols) => {
|
|
120
|
+
if (!cols.length) return prev;
|
|
121
|
+
const col = cols[0];
|
|
122
|
+
return `${prev}${prev.indexOf('?') > -1 ? '&' : '?'}order=${columns[col.index].id}&dir=${col.direction === 1 ? 'asc' : 'desc'}`;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
pagination: {
|
|
127
|
+
enabled: true,
|
|
128
|
+
limit: 10,
|
|
129
|
+
server: {
|
|
130
|
+
url: (prev, page, limit) => {
|
|
131
|
+
const form = this.shadowRoot.getElementById('form');
|
|
132
|
+
if (form) {
|
|
133
|
+
Object.assign(this._params, form.serializeForm());
|
|
134
|
+
}
|
|
135
|
+
this._params.limit = limit;
|
|
136
|
+
this._params.start = page * limit;
|
|
137
|
+
this.setParameters(this._params);
|
|
138
|
+
this.pushHistory('grid', this._params);
|
|
139
|
+
|
|
140
|
+
return `${prev}${prev.indexOf('?') > -1 ? '&' : '?'}${new URLSearchParams(this._params).toString()}`;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
this.grid = new Grid(config);
|
|
146
|
+
this.grid.on('load', () => {
|
|
147
|
+
this.emitTo('pb-results-received', {
|
|
148
|
+
"params": this._params
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
this.grid.render(table);
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
_submit() {
|
|
157
|
+
this.grid.forceRender();
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
render() {
|
|
161
|
+
const themes = resolveURL(this.cssPath);
|
|
162
|
+
return html`
|
|
163
|
+
<link href="${themes}/mermaid.min.css" rel="stylesheet">
|
|
164
|
+
${
|
|
165
|
+
this.search ? html`
|
|
166
|
+
<iron-form id="form">
|
|
167
|
+
<form action="">
|
|
168
|
+
<paper-input id="search" name="search" label="Search" @keyup="${(e) => e.keyCode == 13 ? this._submit() : null}">
|
|
169
|
+
<paper-icon-button icon="search" @click="${this._submit}" slot="suffix"></paper-icon-button>
|
|
170
|
+
</paper-input>
|
|
171
|
+
</form>
|
|
172
|
+
</iron-form>
|
|
173
|
+
` : null
|
|
174
|
+
}
|
|
175
|
+
<div id="table"></div>
|
|
176
|
+
`;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
static get styles() {
|
|
180
|
+
return css`
|
|
181
|
+
:host {
|
|
182
|
+
display: block;
|
|
183
|
+
}
|
|
184
|
+
button {
|
|
185
|
+
border: 0;
|
|
186
|
+
}
|
|
187
|
+
`;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
customElements.define('pb-table-grid', PbTableGrid);
|