@teipublisher/pb-components 1.42.7 → 1.43.1

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.
@@ -1,6 +1,7 @@
1
1
  import { LitElement, html, css } from 'lit-element';
2
2
  import { unsafeHTML } from 'lit-html/directives/unsafe-html.js';
3
3
  import { pbMixin } from './pb-mixin.js';
4
+ import { themableMixin } from "./theming.js";
4
5
 
5
6
  /**
6
7
  * Implements a list which is split into different categories
@@ -23,7 +24,7 @@ import { pbMixin } from './pb-mixin.js';
23
24
  * @fires pb-start-update - sent before the element sends the request to the server
24
25
  * @fires pb-end-update - sent after new content has been received
25
26
  */
26
- export class PbSplitList extends pbMixin(LitElement) {
27
+ export class PbSplitList extends themableMixin(pbMixin(LitElement)) {
27
28
  static get properties() {
28
29
  return {
29
30
  /**
@@ -1,212 +1,219 @@
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
- perPage: {
64
- type: Number,
65
- attribute: 'per-page'
66
- },
67
- height: {
68
- type: String
69
- },
70
- /**
71
- * If specified, enable server-side search.
72
- */
73
- search: {
74
- type: Boolean
75
- },
76
- _params: {
77
- type: Object
78
- },
79
- ...super.properties
80
- };
81
- }
82
-
83
- constructor() {
84
- super();
85
- this.cssPath = '../css/gridjs';
86
- this._params = {};
87
- this.resizable = false;
88
- this.search = false;
89
- this.perPage = 10;
90
- this.height = null;
91
- this.fixedHeader = false;
92
- }
93
-
94
- connectedCallback() {
95
- super.connectedCallback();
96
-
97
- this.subscribeTo('pb-search-resubmit', (ev) => {
98
- this._params = Object.assign({}, ev.detail.params);
99
- this._submit();
100
- });
101
-
102
- window.addEventListener('popstate', (ev) => {
103
- this._params = ev.state;
104
- this._submit();
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
- }
115
- }
116
-
117
- firstUpdated() {
118
- const table = this.shadowRoot.getElementById('table');
119
-
120
- const pbColumns = this.querySelectorAll('pb-table-column');
121
- const columns = [];
122
- pbColumns.forEach((column) => columns.push(column.data()));
123
- PbTableGrid.waitOnce('pb-page-ready', () => {
124
- this._params = this.getParameters();
125
- const url = this.toAbsoluteURL(this.source);
126
- const config = {
127
- height: this.height,
128
- fixedHeader: true,
129
- columns,
130
- resizable: this.resizable,
131
- server: {
132
- url,
133
- then: data => data.results,
134
- total: data => data.count
135
- },
136
- sort: {
137
- multiColumn: false,
138
- enabled: true,
139
- server: {
140
- url: (prev, cols) => {
141
- if (!cols.length) return prev;
142
- const col = cols[0];
143
- return `${prev}${prev.indexOf('?') > -1 ? '&' : '?'}order=${columns[col.index].id}&dir=${col.direction === 1 ? 'asc' : 'desc'}`;
144
- }
145
- }
146
- },
147
- pagination: {
148
- enabled: true,
149
- limit: this.perPage,
150
- server: {
151
- url: (prev, page, limit) => {
152
- const form = this.shadowRoot.getElementById('form');
153
- if (form) {
154
- Object.assign(this._params, form.serializeForm());
155
- }
156
- this._params.limit = limit;
157
- this._params.start = page * limit + 1;
158
- this.setParameters(this._params);
159
- this.pushHistory('grid', this._params);
160
-
161
- return `${prev}${prev.indexOf('?') > -1 ? '&' : '?'}${new URLSearchParams(this._params).toString()}`;
162
- }
163
- }
164
- }
165
- };
166
-
167
- this.grid = new Grid(config);
168
- this.grid.on('load', () => {
169
- this.emitTo('pb-results-received', {
170
- "params": this._params
171
- });
172
- });
173
-
174
- this.grid.render(table);
175
- });
176
- }
177
-
178
- _submit() {
179
- this.grid.forceRender();
180
- }
181
-
182
- render() {
183
- const themes = resolveURL(this.cssPath);
184
- return html`
185
- <link href="${themes}/mermaid.min.css" rel="stylesheet">
186
- ${
187
- this.search ? html`
188
- <iron-form id="form">
189
- <form action="">
190
- <paper-input id="search" name="search" label="Search" @keyup="${(e) => e.keyCode == 13 ? this._submit() : null}">
191
- <paper-icon-button icon="search" @click="${this._submit}" slot="suffix"></paper-icon-button>
192
- </paper-input>
193
- </form>
194
- </iron-form>
195
- ` : null
196
- }
197
- <div id="table"></div>
198
- `;
199
- }
200
-
201
- static get styles() {
202
- return css`
203
- :host {
204
- display: block;
205
- }
206
- button {
207
- border: 0;
208
- }
209
- `;
210
- }
211
- }
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 { loadStylesheets, importStyles } from "./theming.js";
6
+ import '@polymer/paper-input/paper-input';
7
+ import '@polymer/iron-icons';
8
+ import '@polymer/iron-form';
9
+ import '@polymer/paper-icon-button';
10
+ import './pb-table-column.js';
11
+
12
+ /**
13
+ * A table grid based on [gridjs](https://gridjs.io/), which loads its data from a server endpoint
14
+ * specified in `source`. If `source` is a relative URI, it will be resolved relative to the
15
+ * TEI Publisher endpoint.
16
+ *
17
+ * The JSON data returned by the endpoint should be an object with two properties:
18
+ *
19
+ * * `count`: the overall number of rows available on the server
20
+ * * `results`: an array containing each record as an object
21
+ *
22
+ * The parameters send to the server are as follows:
23
+ *
24
+ *
25
+ * Parameter | Description
26
+ * ---------|----------
27
+ * limit | number of records to return for each page
28
+ * start | start offset from which to return records
29
+ * order | the id of the column to sort by
30
+ * dir | sort direction: either 'asc' or 'desc'
31
+ * search | an optional search string entered by the user
32
+ *
33
+ * Table columns are configured via nested `<pb-table-column>` elements:
34
+ *
35
+ * ```html
36
+ * <pb-table-column label="Name" property="name" sort width="33%"></pb-table-column>
37
+ * <pb-table-column label="Born" property="birth"></pb-table-column>
38
+ * <pb-table-column label="Died" property="death"></pb-table-column>
39
+ * ```
40
+ */
41
+ export class PbTableGrid extends pbMixin(LitElement) {
42
+ static get properties() {
43
+ return {
44
+ /**
45
+ * URI of the server-side endpoint to retrieve data from.
46
+ * Relative URIs are resolved relative to the configured TEI Publisher endpoint.
47
+ */
48
+ source: {
49
+ type: String
50
+ },
51
+ /**
52
+ * Path to the gridjs theme CSS files.
53
+ */
54
+ cssPath: {
55
+ type: String,
56
+ attribute: 'css-path'
57
+ },
58
+ /**
59
+ * If specified, columns (without a fixed width) will be resizable.
60
+ */
61
+ resizable: {
62
+ type: Boolean
63
+ },
64
+ perPage: {
65
+ type: Number,
66
+ attribute: 'per-page'
67
+ },
68
+ height: {
69
+ type: String
70
+ },
71
+ /**
72
+ * If specified, enable server-side search.
73
+ */
74
+ search: {
75
+ type: Boolean
76
+ },
77
+ _params: {
78
+ type: Object
79
+ },
80
+ ...super.properties
81
+ };
82
+ }
83
+
84
+ constructor() {
85
+ super();
86
+ this.cssPath = '../css/gridjs';
87
+ this._params = {};
88
+ this.resizable = false;
89
+ this.search = false;
90
+ this.perPage = 10;
91
+ this.height = null;
92
+ this.fixedHeader = false;
93
+ }
94
+
95
+ async connectedCallback() {
96
+ super.connectedCallback();
97
+
98
+ this.subscribeTo('pb-search-resubmit', (ev) => {
99
+ this._params = Object.assign({}, ev.detail.params);
100
+ this._submit();
101
+ });
102
+
103
+ window.addEventListener('popstate', (ev) => {
104
+ this._params = ev.state;
105
+ this._submit();
106
+ });
107
+
108
+ if (!this.height) {
109
+ const property = getComputedStyle(this).getPropertyValue('--pb-table-grid-height');
110
+ if (property) {
111
+ this.height = property;
112
+ } else {
113
+ this.height = 'auto';
114
+ }
115
+ }
116
+
117
+ const gridjsTheme = await loadStylesheets([`${resolveURL(this.cssPath)}/mermaid.min.css`]);
118
+ const theme = importStyles(this);
119
+ const sheets = [...this.shadowRoot.adoptedStyleSheets, gridjsTheme];
120
+ if (theme) {
121
+ sheets.push(theme);
122
+ }
123
+ this.shadowRoot.adoptedStyleSheets = sheets;
124
+ }
125
+
126
+ firstUpdated() {
127
+ const table = this.shadowRoot.getElementById('table');
128
+
129
+ const pbColumns = this.querySelectorAll('pb-table-column');
130
+ const columns = [];
131
+ pbColumns.forEach((column) => columns.push(column.data()));
132
+ PbTableGrid.waitOnce('pb-page-ready', () => {
133
+ this._params = this.getParameters();
134
+ const url = this.toAbsoluteURL(this.source);
135
+ const config = {
136
+ height: this.height,
137
+ fixedHeader: true,
138
+ columns,
139
+ resizable: this.resizable,
140
+ server: {
141
+ url,
142
+ then: data => data.results,
143
+ total: data => data.count
144
+ },
145
+ sort: {
146
+ multiColumn: false,
147
+ enabled: true,
148
+ server: {
149
+ url: (prev, cols) => {
150
+ if (!cols.length) return prev;
151
+ const col = cols[0];
152
+ return `${prev}${prev.indexOf('?') > -1 ? '&' : '?'}order=${columns[col.index].id}&dir=${col.direction === 1 ? 'asc' : 'desc'}`;
153
+ }
154
+ }
155
+ },
156
+ pagination: {
157
+ enabled: true,
158
+ limit: this.perPage,
159
+ server: {
160
+ url: (prev, page, limit) => {
161
+ const form = this.shadowRoot.getElementById('form');
162
+ if (form) {
163
+ Object.assign(this._params, form.serializeForm());
164
+ }
165
+ this._params.limit = limit;
166
+ this._params.start = page * limit + 1;
167
+ this.setParameters(this._params);
168
+ this.pushHistory('grid', this._params);
169
+
170
+ return `${prev}${prev.indexOf('?') > -1 ? '&' : '?'}${new URLSearchParams(this._params).toString()}`;
171
+ }
172
+ }
173
+ }
174
+ };
175
+
176
+ this.grid = new Grid(config);
177
+ this.grid.on('load', () => {
178
+ this.emitTo('pb-results-received', {
179
+ "params": this._params
180
+ });
181
+ });
182
+
183
+ this.grid.render(table);
184
+ });
185
+ }
186
+
187
+ _submit() {
188
+ this.grid.forceRender();
189
+ }
190
+
191
+ render() {
192
+ return html`
193
+ ${
194
+ this.search ? html`
195
+ <iron-form id="form">
196
+ <form action="">
197
+ <paper-input id="search" name="search" label="Search" @keyup="${(e) => e.keyCode == 13 ? this._submit() : null}">
198
+ <paper-icon-button icon="search" @click="${this._submit}" slot="suffix"></paper-icon-button>
199
+ </paper-input>
200
+ </form>
201
+ </iron-form>
202
+ ` : null
203
+ }
204
+ <div id="table"></div>
205
+ `;
206
+ }
207
+
208
+ static get styles() {
209
+ return css`
210
+ :host {
211
+ display: block;
212
+ }
213
+ button {
214
+ border: 0;
215
+ }
216
+ `;
217
+ }
218
+ }
212
219
  customElements.define('pb-table-grid', PbTableGrid);