@teipublisher/pb-components 1.43.4 → 1.44.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/main.yml +21 -0
- package/CHANGELOG.md +14 -0
- package/dist/demo/pb-table-grid.html +16 -16
- package/dist/demo/pb-view2.html +135 -135
- package/dist/demo/redirect.html +3 -0
- package/dist/jinn-codemirror-9718e0e0.js +1 -0
- package/dist/pb-code-editor.js +1 -1
- package/dist/pb-components-bundle.js +95 -104
- package/dist/pb-edit-app.js +1 -1
- package/dist/pb-elements.json +1009 -690
- package/dist/{pb-i18n-dc551878.js → pb-i18n-3963b098.js} +1 -1
- package/dist/pb-leaflet-map.js +1 -1
- package/dist/pb-odd-editor.js +1 -1
- package/dist/{pb-message-fbc1b645.js → vaadin-element-mixin-08cf11b5.js} +21 -19
- package/gh-pages.js +23 -0
- package/i18n/common/en.json +7 -2
- package/package.json +6 -4
- package/pb-elements.json +1009 -690
- package/src/pb-ajax.js +37 -19
- package/src/pb-browse-docs.js +520 -520
- package/src/pb-browse.js +77 -0
- package/src/pb-components.js +1 -0
- package/src/pb-message.js +6 -10
- package/src/pb-mixin.js +542 -542
- package/src/pb-page.js +399 -399
- package/src/pb-split-list.js +188 -188
- package/src/pb-table-grid.js +218 -218
- package/src/pb-view.js +1366 -1366
- package/dist/jinn-codemirror-d437848a.js +0 -1
- /package/dist/{pb-mixin-f8b22e51.js → pb-mixin-88125cb2.js} +0 -0
package/src/pb-browse-docs.js
CHANGED
|
@@ -1,521 +1,521 @@
|
|
|
1
|
-
import { html, css } from 'lit-element';
|
|
2
|
-
import { PbLoad } from './pb-load.js';
|
|
3
|
-
import { translate } from "./pb-i18n.js";
|
|
4
|
-
import { themableMixin } from "./theming.js";
|
|
5
|
-
import '@polymer/paper-input/paper-input.js';
|
|
6
|
-
import '@polymer/paper-button';
|
|
7
|
-
import '@polymer/paper-dropdown-menu/paper-dropdown-menu.js';
|
|
8
|
-
import '@polymer/paper-listbox';
|
|
9
|
-
import '@polymer/paper-dialog';
|
|
10
|
-
import '@polymer/paper-dialog-scrollable';
|
|
11
|
-
import '@polymer/iron-ajax';
|
|
12
|
-
import '@cwmr/paper-autocomplete/paper-autocomplete-suggestions.js';
|
|
13
|
-
import { cmpVersion } from './utils.js';
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Component to browse through a collection of documents with sorting, filtering and facets.
|
|
17
|
-
*
|
|
18
|
-
* @slot toolbar - toolbar area
|
|
19
|
-
* @slot - unnamed default slot
|
|
20
|
-
* @slot footer - footer area
|
|
21
|
-
*
|
|
22
|
-
* @fires pb-collection - Sent to inform e.g. pb-upload about current collection
|
|
23
|
-
* @fires pb-search-resubmit - When received, set facet values as received from the event
|
|
24
|
-
* @fires pb-login - When received, refresh the view if the user changed
|
|
25
|
-
*
|
|
26
|
-
* @cssprop --pb-search-suggestions-background - Background for the autocomplete suggestions for the filter field
|
|
27
|
-
* @cssprop --pb-search-suggestions-color - Text color for the autocomplete suggestion for the filter field
|
|
28
|
-
* @cssprop --pb-search-label-color - Determines the color of small label above the sort by/filter by/filter fields
|
|
29
|
-
* @cssprop --pb-search-input-color - Determines the color of the text in the sort by/filter by/filter fields
|
|
30
|
-
* @cssprop --pb-search-focus-color - Color of the field labels and underline when in focus
|
|
31
|
-
* @cssprop --pb-browse-toolbar-justify-content - How to justify the browse toolbar content, following flexbox justify-content property e.g. center, space-evenly, start...
|
|
32
|
-
*
|
|
33
|
-
* @csspart delete-button - the delete button
|
|
34
|
-
* @csspart sort-dropdown - dropdown for sorting
|
|
35
|
-
* @csspart filter-dropdown - dropdown for filtering
|
|
36
|
-
* @csspart filter-input - input for filtering
|
|
37
|
-
*/
|
|
38
|
-
export class PbBrowseDocs extends themableMixin(PbLoad) {
|
|
39
|
-
|
|
40
|
-
static get properties() {
|
|
41
|
-
return {
|
|
42
|
-
...super.properties,
|
|
43
|
-
sortBy: {
|
|
44
|
-
type: String,
|
|
45
|
-
attribute: 'sort-by'
|
|
46
|
-
},
|
|
47
|
-
sortOptions: {
|
|
48
|
-
type: Array,
|
|
49
|
-
attribute: 'sort-options'
|
|
50
|
-
},
|
|
51
|
-
sortLabel: {
|
|
52
|
-
type: String
|
|
53
|
-
},
|
|
54
|
-
filter: {
|
|
55
|
-
type: String
|
|
56
|
-
},
|
|
57
|
-
filterBy: {
|
|
58
|
-
type: String,
|
|
59
|
-
attribute: 'filter-by'
|
|
60
|
-
},
|
|
61
|
-
filterOptions: {
|
|
62
|
-
type: Array,
|
|
63
|
-
attribute: 'filter-options'
|
|
64
|
-
},
|
|
65
|
-
filterByLabel: {
|
|
66
|
-
type: String
|
|
67
|
-
},
|
|
68
|
-
filterPlaceholderLabel: {
|
|
69
|
-
type: String
|
|
70
|
-
},
|
|
71
|
-
collection: {
|
|
72
|
-
type: String
|
|
73
|
-
},
|
|
74
|
-
facets: {
|
|
75
|
-
type: Object
|
|
76
|
-
},
|
|
77
|
-
/** Id of the pb-login element to connect to */
|
|
78
|
-
login: {
|
|
79
|
-
type: String
|
|
80
|
-
},
|
|
81
|
-
/**
|
|
82
|
-
* If set, requires the logged in user to be member of
|
|
83
|
-
* the given group.
|
|
84
|
-
*/
|
|
85
|
-
group: {
|
|
86
|
-
type: String
|
|
87
|
-
},
|
|
88
|
-
subforms: {
|
|
89
|
-
type: String
|
|
90
|
-
},
|
|
91
|
-
/**
|
|
92
|
-
* If set, rewrite URLs to load pages as static HTML files,
|
|
93
|
-
* so no TEI Publisher instance is required
|
|
94
|
-
*/
|
|
95
|
-
static: {
|
|
96
|
-
type: Boolean
|
|
97
|
-
},
|
|
98
|
-
_file: {
|
|
99
|
-
type: String
|
|
100
|
-
},
|
|
101
|
-
_selected: {
|
|
102
|
-
type: Array
|
|
103
|
-
},
|
|
104
|
-
_allowModification: {
|
|
105
|
-
type: Boolean,
|
|
106
|
-
},
|
|
107
|
-
_suggestions: {
|
|
108
|
-
type: Array
|
|
109
|
-
}
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
constructor() {
|
|
114
|
-
super();
|
|
115
|
-
this.sortOptions = [];
|
|
116
|
-
this.sortLabel = 'browse.sort';
|
|
117
|
-
this.sortBy = 'default';
|
|
118
|
-
this.filter = '';
|
|
119
|
-
this.filterOptions = [
|
|
120
|
-
{
|
|
121
|
-
label: 'Title',
|
|
122
|
-
value: 'title'
|
|
123
|
-
}
|
|
124
|
-
];
|
|
125
|
-
this.filterByLabel = 'browse.filter';
|
|
126
|
-
this.filterPlaceholderLabel = 'browse.filterPlaceholder';
|
|
127
|
-
|
|
128
|
-
this.filterBy = 'title';
|
|
129
|
-
this._allowModification = false;
|
|
130
|
-
this._suggestions = [];
|
|
131
|
-
|
|
132
|
-
this.static = false;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
connectedCallback() {
|
|
136
|
-
super.connectedCallback();
|
|
137
|
-
|
|
138
|
-
const sortParam = this.getParameter('sort');
|
|
139
|
-
if (sortParam) {
|
|
140
|
-
this.sortBy = sortParam;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
const filterParam = this.getParameter('filter');
|
|
144
|
-
if (filterParam) {
|
|
145
|
-
this.filter = filterParam;
|
|
146
|
-
this.filterBy = this.getParameter('filterBy', this.filterBy);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
this.facets = this.getParametersMatching(/^facet-.*$/);
|
|
150
|
-
|
|
151
|
-
this.collection = this.getParameter('collection');
|
|
152
|
-
|
|
153
|
-
this.subscribeTo('pb-search-resubmit', this._facets.bind(this));
|
|
154
|
-
this.subscribeTo('pb-login', (ev) => {
|
|
155
|
-
if (ev.detail.userChanged) {
|
|
156
|
-
this._facets(ev);
|
|
157
|
-
}
|
|
158
|
-
}, []);
|
|
159
|
-
document.addEventListener('pb-i18n-update', () => {
|
|
160
|
-
// clear paper-listbox selection after language updates
|
|
161
|
-
const lb = this.shadowRoot.getElementById('sort-list');
|
|
162
|
-
let old = lb.selected;
|
|
163
|
-
lb.selected = undefined;
|
|
164
|
-
lb.selected = old;
|
|
165
|
-
|
|
166
|
-
const fl = this.shadowRoot.getElementById('filter-list');
|
|
167
|
-
old = fl.selected;
|
|
168
|
-
fl.selected = undefined;
|
|
169
|
-
fl.selected = old;
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
firstUpdated() {
|
|
174
|
-
PbBrowseDocs.waitOnce('pb-page-ready', (options) => {
|
|
175
|
-
const loader = this.shadowRoot.getElementById('autocompleteLoader');
|
|
176
|
-
if (cmpVersion(options.apiVersion, '1.0.0') >= 0) {
|
|
177
|
-
loader.url = `${options.endpoint}/api/search/autocomplete`;
|
|
178
|
-
if (!this.url) {
|
|
179
|
-
this.url = 'api/collection';
|
|
180
|
-
}
|
|
181
|
-
} else {
|
|
182
|
-
loader.url = `${options.endpoint}/modules/autocomplete.xql`;
|
|
183
|
-
if (!this.url) {
|
|
184
|
-
this.url = 'collection/';
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
});
|
|
188
|
-
this.shadowRoot.getElementById('autocomplete').addEventListener('autocomplete-change', this._autocomplete.bind(this));
|
|
189
|
-
|
|
190
|
-
if (this.login) {
|
|
191
|
-
const login = document.getElementById(this.login);
|
|
192
|
-
if (!login) {
|
|
193
|
-
console.error('<pb-browse-docs> connected pb-login element not found!');
|
|
194
|
-
} else {
|
|
195
|
-
this.subscribeTo('pb-login', (ev) => {
|
|
196
|
-
this._allowModification = this._loggedIn(ev.detail.user, ev.detail.group);
|
|
197
|
-
}, []);
|
|
198
|
-
this._allowModification = login.loggedIn && this._loggedIn(login.user, login.groups);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
this.shadowRoot.getElementById('sort-list').addEventListener('selected-item-changed', this._sort.bind(this));
|
|
203
|
-
this.shadowRoot.getElementById('delete').addEventListener('click', this._handleDelete.bind(this));
|
|
204
|
-
super.firstUpdated();
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
render() {
|
|
208
|
-
return html`
|
|
209
|
-
<custom-style>
|
|
210
|
-
<style>
|
|
211
|
-
:host {
|
|
212
|
-
--suggestions-item: {
|
|
213
|
-
color: var(--pb-search-suggestions-color, black);
|
|
214
|
-
};
|
|
215
|
-
--suggestions-wrapper: {
|
|
216
|
-
background: var(--pb-search-suggestions-background, white);
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
</style>
|
|
220
|
-
</custom-style>
|
|
221
|
-
<slot name="header"></slot>
|
|
222
|
-
<div class="toolbar">
|
|
223
|
-
<paper-dropdown-menu id="sort" label="${translate(this.sortLabel)}" part="sort-dropdown">
|
|
224
|
-
<paper-listbox id="sort-list" selected="${this.sortBy}" slot="dropdown-content" class="dropdown-content" attr-for-selected="value">
|
|
225
|
-
${this.sortOptions.map(option =>
|
|
226
|
-
html`<paper-item value="${option.value}">${translate(option.label)}</paper-item>`
|
|
227
|
-
)}
|
|
228
|
-
</paper-listbox>
|
|
229
|
-
</paper-dropdown-menu>
|
|
230
|
-
<div>
|
|
231
|
-
<paper-dropdown-menu id="filterSelect" label="${translate(this.filterByLabel)}" part="filter-dropdown">
|
|
232
|
-
<paper-listbox id="filter-list" selected="${this.filterBy}" slot="dropdown-content" class="dropdown-content" attr-for-selected="value" @selected-item-changed="${this._filterChanged}">
|
|
233
|
-
${this.filterOptions.map(option =>
|
|
234
|
-
html`<paper-item value="${option.value}">${translate(option.label)}</paper-item>`
|
|
235
|
-
)}
|
|
236
|
-
</paper-listbox>
|
|
237
|
-
</paper-dropdown-menu>
|
|
238
|
-
<paper-input id="filterString" type="search" name="filter" label="${translate(this.filterPlaceholderLabel)}" value="${this.filter}"
|
|
239
|
-
@keyup="${this._handleEnter}" part="filter-input">
|
|
240
|
-
<iron-icon icon="search" @click="${this._filter}" slot="prefix"></iron-icon>
|
|
241
|
-
</paper-input>
|
|
242
|
-
<paper-autocomplete-suggestions id="autocomplete" for="filterString" source="${this._suggestions}" remote-source></paper-autocomplete-suggestions>
|
|
243
|
-
</div>
|
|
244
|
-
</div>
|
|
245
|
-
<div class="toolbar">
|
|
246
|
-
<slot name="toolbar"></slot>
|
|
247
|
-
<paper-button id="delete" part="delete-button" title="${translate('browse.delete')}" class="${this._canModify(this._allowModification)}">
|
|
248
|
-
<iron-icon icon="delete"></iron-icon>
|
|
249
|
-
<span class="label">${translate('browse.delete')}</span>
|
|
250
|
-
</paper-button>
|
|
251
|
-
</div>
|
|
252
|
-
<slot></slot>
|
|
253
|
-
<slot name="footer"></slot>
|
|
254
|
-
|
|
255
|
-
<iron-ajax
|
|
256
|
-
id="loadContent"
|
|
257
|
-
verbose
|
|
258
|
-
handle-as="text"
|
|
259
|
-
method="get"
|
|
260
|
-
with-credentials
|
|
261
|
-
@response="${this._handleContent}"
|
|
262
|
-
@error="${this._handleError}"></iron-ajax>
|
|
263
|
-
<iron-ajax
|
|
264
|
-
id="autocompleteLoader"
|
|
265
|
-
verbose
|
|
266
|
-
handle-as="json"
|
|
267
|
-
method="get"
|
|
268
|
-
with-credentials
|
|
269
|
-
@response="${this._updateSuggestions}"></iron-ajax>
|
|
270
|
-
|
|
271
|
-
<paper-dialog id="deleteDialog">
|
|
272
|
-
<h2>${translate('browse.delete')}</h2>
|
|
273
|
-
<paper-dialog-scrollable>
|
|
274
|
-
<p>${translate('browse.confirmDeletion', { count: (this._selected ? this._selected.length : 0) })}</p>
|
|
275
|
-
</paper-dialog-scrollable>
|
|
276
|
-
<div class="buttons">
|
|
277
|
-
<paper-button dialog-confirm="dialog-confirm" autofocus @click="${this._confirmDelete}">${translate('dialogs.yes')}</paper-button>
|
|
278
|
-
<paper-button dialog-confirm="dialog-cancel">${translate('dialogs.no')}</paper-button>
|
|
279
|
-
</div>
|
|
280
|
-
</paper-dialog>
|
|
281
|
-
<paper-dialog id="errorDialog">
|
|
282
|
-
<h2>${translate('dialogs.error')}</h2>
|
|
283
|
-
<paper-dialog-scrollable></paper-dialog-scrollable>
|
|
284
|
-
<div class="buttons">
|
|
285
|
-
<paper-button dialog-confirm="dialog-confirm" autofocus="autofocus">
|
|
286
|
-
${translate('dialogs.close')}
|
|
287
|
-
</paper-button>
|
|
288
|
-
</div>
|
|
289
|
-
</paper-dialog>
|
|
290
|
-
`;
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
static get styles() {
|
|
294
|
-
return css`
|
|
295
|
-
:host {
|
|
296
|
-
display: block;
|
|
297
|
-
--paper-input-container-color: var(--pb-search-label-color, var(--paper-grey-500, #303030));
|
|
298
|
-
--paper-input-container-input-color: var(--pb-search-input-color, var(--pb-color-primary, #000000));
|
|
299
|
-
--paper-input-container-focus-color: var(--pb-search-focus-color, var(--paper-grey-500, #303030));
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
.toolbar {
|
|
303
|
-
display: flex;
|
|
304
|
-
justify-content: var(--pb-browse-toolbar-justify-content);
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
[name="toolbar"] {
|
|
308
|
-
flex: 1 0;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
#sort {
|
|
312
|
-
display: block;
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
#filterString {
|
|
316
|
-
position: relative;
|
|
317
|
-
display: inline-block;
|
|
318
|
-
vertical-align: bottom;
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
.hidden {
|
|
322
|
-
display: none;
|
|
323
|
-
}
|
|
324
|
-
`;
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
getURL(params) {
|
|
328
|
-
if (this.static) {
|
|
329
|
-
// use a static URL
|
|
330
|
-
return `collections/${this.collection ? this.collection + '/' : ''}${params.start || '1'}.html`;
|
|
331
|
-
}
|
|
332
|
-
const url = super.getURL(params);
|
|
333
|
-
return this.collection ? `${url}/${this.collection}` : url;
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
prepareParameters(params) {
|
|
337
|
-
params = this._paramsFromSubforms(params);
|
|
338
|
-
params.sort = this.sortBy;
|
|
339
|
-
if (this.filter) {
|
|
340
|
-
params.filter = this.filter;
|
|
341
|
-
params.browse = this.filterBy;
|
|
342
|
-
}
|
|
343
|
-
if (this.facets) {
|
|
344
|
-
params = Object.assign(params, this.facets);
|
|
345
|
-
}
|
|
346
|
-
return params;
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
_paramsFromSubforms(params) {
|
|
350
|
-
if (this.subforms) {
|
|
351
|
-
document.querySelectorAll(this.subforms).forEach((form) => {
|
|
352
|
-
if (form.serializeForm) {
|
|
353
|
-
Object.assign(params, form.serializeForm());
|
|
354
|
-
}
|
|
355
|
-
});
|
|
356
|
-
}
|
|
357
|
-
return params;
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
/**
|
|
361
|
-
* returns selected documents.
|
|
362
|
-
*
|
|
363
|
-
* @returns {Array}
|
|
364
|
-
*/
|
|
365
|
-
getSelected() {
|
|
366
|
-
const selected = [];
|
|
367
|
-
if (this.container) {
|
|
368
|
-
document.querySelectorAll(this.container).forEach((container) =>
|
|
369
|
-
container.querySelectorAll('.document-select paper-checkbox[checked]').forEach((checkbox) => {
|
|
370
|
-
selected.push(checkbox.value);
|
|
371
|
-
})
|
|
372
|
-
);
|
|
373
|
-
} else {
|
|
374
|
-
this.querySelectorAll('.document-select paper-checkbox[checked]').forEach((checkbox) => {
|
|
375
|
-
selected.push(checkbox.value);
|
|
376
|
-
});
|
|
377
|
-
}
|
|
378
|
-
return selected;
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
_filter() {
|
|
382
|
-
const filter = this.shadowRoot.getElementById('filterString').value;
|
|
383
|
-
const filterBy = this.shadowRoot.getElementById('filter-list').selected;
|
|
384
|
-
if (typeof filter !== 'undefined') {
|
|
385
|
-
console.log('<pb-browse-docs> Filter by %s', filter);
|
|
386
|
-
this.filter = filter;
|
|
387
|
-
this.setParameter('filter', filter);
|
|
388
|
-
this.setParameter('filterBy', filterBy);
|
|
389
|
-
this.pushHistory('filter docs');
|
|
390
|
-
|
|
391
|
-
this.load();
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
_filterChanged() {
|
|
396
|
-
const filterBy = this.shadowRoot.getElementById('filter-list').selected;
|
|
397
|
-
if (filterBy && filterBy !== this.filterBy) {
|
|
398
|
-
console.log('<pb-browse-docs> Filtering on %s', filterBy);
|
|
399
|
-
this.filterBy = filterBy;
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
_sort() {
|
|
404
|
-
const sortBy = this.shadowRoot.getElementById('sort-list').selected;
|
|
405
|
-
if (sortBy && sortBy !== this.sortBy) {
|
|
406
|
-
console.log('<pb-browse-docs> Sorting by %s', sortBy);
|
|
407
|
-
this.sortBy = sortBy;
|
|
408
|
-
this.setParameter('sort', sortBy);
|
|
409
|
-
this.pushHistory('sort docs');
|
|
410
|
-
|
|
411
|
-
this.load();
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
_facets(ev) {
|
|
416
|
-
if (ev.detail && ev.detail.params) {
|
|
417
|
-
this.clearParametersMatching(/^(all-|facet-).*/);
|
|
418
|
-
for (let param in ev.detail.params) {
|
|
419
|
-
this.setParameter(param, ev.detail.params[param]);
|
|
420
|
-
}
|
|
421
|
-
this.facets = ev.detail.params;
|
|
422
|
-
this.start = 1;
|
|
423
|
-
this.pushHistory('facets');
|
|
424
|
-
}
|
|
425
|
-
this.load();
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
_onLoad(content) {
|
|
429
|
-
window.scrollTo(0, 0);
|
|
430
|
-
const div = content.querySelector('[data-root]');
|
|
431
|
-
const collection = div && div.getAttribute('data-root');
|
|
432
|
-
const writable = div && div.classList.contains('writable');
|
|
433
|
-
this.emitTo('pb-collection', {
|
|
434
|
-
writable,
|
|
435
|
-
collection
|
|
436
|
-
});
|
|
437
|
-
document.querySelectorAll('[can-write]').forEach((elem) => {
|
|
438
|
-
elem.disabled = !writable;
|
|
439
|
-
});
|
|
440
|
-
content.querySelectorAll('[data-collection]').forEach(link => {
|
|
441
|
-
link.addEventListener('click', (ev) => {
|
|
442
|
-
ev.preventDefault();
|
|
443
|
-
this.collection = link.getAttribute('data-collection');
|
|
444
|
-
this.start = 1;
|
|
445
|
-
this.setParameter('collection', this.collection);
|
|
446
|
-
this.pushHistory('browse collection');
|
|
447
|
-
console.log('<pb-browse-docs> loading collection %s', this.collection);
|
|
448
|
-
this.load();
|
|
449
|
-
});
|
|
450
|
-
});
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
_handleDelete(target, ev) {
|
|
454
|
-
const deleteDialog = this.shadowRoot.getElementById('deleteDialog');
|
|
455
|
-
const selected = this.getSelected();
|
|
456
|
-
if (selected.length > 0) {
|
|
457
|
-
this._selected = selected;
|
|
458
|
-
deleteDialog.open();
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
_confirmDelete() {
|
|
463
|
-
if (!(this._file || this._selected)) {
|
|
464
|
-
return;
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
let files;
|
|
468
|
-
if (this._selected) {
|
|
469
|
-
files = this._selected;
|
|
470
|
-
} else {
|
|
471
|
-
files = [this._file];
|
|
472
|
-
}
|
|
473
|
-
console.log('<pb-browse-docs> Deleting %o', this._file);
|
|
474
|
-
const params = {
|
|
475
|
-
action: 'delete',
|
|
476
|
-
'docs[]': files
|
|
477
|
-
};
|
|
478
|
-
this._file = null;
|
|
479
|
-
this._selected = null;
|
|
480
|
-
this.load(params);
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
_loggedIn(user, groups) {
|
|
484
|
-
if (user == null) {
|
|
485
|
-
return false;
|
|
486
|
-
}
|
|
487
|
-
if (this.group) {
|
|
488
|
-
if (!groups) {
|
|
489
|
-
return false;
|
|
490
|
-
}
|
|
491
|
-
return groups.indexOf(this.group) > -1;
|
|
492
|
-
}
|
|
493
|
-
return true;
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
_canModify(allowModification) {
|
|
497
|
-
return allowModification ? '' : 'hidden';
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
_autocomplete(ev) {
|
|
501
|
-
const autocompleteLoader = this.shadowRoot.getElementById('autocompleteLoader');
|
|
502
|
-
autocompleteLoader.params = {
|
|
503
|
-
query: ev.detail.option.text,
|
|
504
|
-
field: this.filterBy
|
|
505
|
-
};
|
|
506
|
-
autocompleteLoader.generateRequest();
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
_updateSuggestions() {
|
|
510
|
-
const autocomplete = this.shadowRoot.getElementById('autocomplete');
|
|
511
|
-
const autocompleteLoader = this.shadowRoot.getElementById('autocompleteLoader');
|
|
512
|
-
autocomplete.suggestions(autocompleteLoader.lastResponse);
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
_handleEnter(e) {
|
|
516
|
-
if (e.keyCode == 13) {
|
|
517
|
-
this._filter();
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
}
|
|
1
|
+
import { html, css } from 'lit-element';
|
|
2
|
+
import { PbLoad } from './pb-load.js';
|
|
3
|
+
import { translate } from "./pb-i18n.js";
|
|
4
|
+
import { themableMixin } from "./theming.js";
|
|
5
|
+
import '@polymer/paper-input/paper-input.js';
|
|
6
|
+
import '@polymer/paper-button';
|
|
7
|
+
import '@polymer/paper-dropdown-menu/paper-dropdown-menu.js';
|
|
8
|
+
import '@polymer/paper-listbox';
|
|
9
|
+
import '@polymer/paper-dialog';
|
|
10
|
+
import '@polymer/paper-dialog-scrollable';
|
|
11
|
+
import '@polymer/iron-ajax';
|
|
12
|
+
import '@cwmr/paper-autocomplete/paper-autocomplete-suggestions.js';
|
|
13
|
+
import { cmpVersion } from './utils.js';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Component to browse through a collection of documents with sorting, filtering and facets.
|
|
17
|
+
*
|
|
18
|
+
* @slot toolbar - toolbar area
|
|
19
|
+
* @slot - unnamed default slot
|
|
20
|
+
* @slot footer - footer area
|
|
21
|
+
*
|
|
22
|
+
* @fires pb-collection - Sent to inform e.g. pb-upload about current collection
|
|
23
|
+
* @fires pb-search-resubmit - When received, set facet values as received from the event
|
|
24
|
+
* @fires pb-login - When received, refresh the view if the user changed
|
|
25
|
+
*
|
|
26
|
+
* @cssprop --pb-search-suggestions-background - Background for the autocomplete suggestions for the filter field
|
|
27
|
+
* @cssprop --pb-search-suggestions-color - Text color for the autocomplete suggestion for the filter field
|
|
28
|
+
* @cssprop --pb-search-label-color - Determines the color of small label above the sort by/filter by/filter fields
|
|
29
|
+
* @cssprop --pb-search-input-color - Determines the color of the text in the sort by/filter by/filter fields
|
|
30
|
+
* @cssprop --pb-search-focus-color - Color of the field labels and underline when in focus
|
|
31
|
+
* @cssprop --pb-browse-toolbar-justify-content - How to justify the browse toolbar content, following flexbox justify-content property e.g. center, space-evenly, start...
|
|
32
|
+
*
|
|
33
|
+
* @csspart delete-button - the delete button
|
|
34
|
+
* @csspart sort-dropdown - dropdown for sorting
|
|
35
|
+
* @csspart filter-dropdown - dropdown for filtering
|
|
36
|
+
* @csspart filter-input - input for filtering
|
|
37
|
+
*/
|
|
38
|
+
export class PbBrowseDocs extends themableMixin(PbLoad) {
|
|
39
|
+
|
|
40
|
+
static get properties() {
|
|
41
|
+
return {
|
|
42
|
+
...super.properties,
|
|
43
|
+
sortBy: {
|
|
44
|
+
type: String,
|
|
45
|
+
attribute: 'sort-by'
|
|
46
|
+
},
|
|
47
|
+
sortOptions: {
|
|
48
|
+
type: Array,
|
|
49
|
+
attribute: 'sort-options'
|
|
50
|
+
},
|
|
51
|
+
sortLabel: {
|
|
52
|
+
type: String
|
|
53
|
+
},
|
|
54
|
+
filter: {
|
|
55
|
+
type: String
|
|
56
|
+
},
|
|
57
|
+
filterBy: {
|
|
58
|
+
type: String,
|
|
59
|
+
attribute: 'filter-by'
|
|
60
|
+
},
|
|
61
|
+
filterOptions: {
|
|
62
|
+
type: Array,
|
|
63
|
+
attribute: 'filter-options'
|
|
64
|
+
},
|
|
65
|
+
filterByLabel: {
|
|
66
|
+
type: String
|
|
67
|
+
},
|
|
68
|
+
filterPlaceholderLabel: {
|
|
69
|
+
type: String
|
|
70
|
+
},
|
|
71
|
+
collection: {
|
|
72
|
+
type: String
|
|
73
|
+
},
|
|
74
|
+
facets: {
|
|
75
|
+
type: Object
|
|
76
|
+
},
|
|
77
|
+
/** Id of the pb-login element to connect to */
|
|
78
|
+
login: {
|
|
79
|
+
type: String
|
|
80
|
+
},
|
|
81
|
+
/**
|
|
82
|
+
* If set, requires the logged in user to be member of
|
|
83
|
+
* the given group.
|
|
84
|
+
*/
|
|
85
|
+
group: {
|
|
86
|
+
type: String
|
|
87
|
+
},
|
|
88
|
+
subforms: {
|
|
89
|
+
type: String
|
|
90
|
+
},
|
|
91
|
+
/**
|
|
92
|
+
* If set, rewrite URLs to load pages as static HTML files,
|
|
93
|
+
* so no TEI Publisher instance is required
|
|
94
|
+
*/
|
|
95
|
+
static: {
|
|
96
|
+
type: Boolean
|
|
97
|
+
},
|
|
98
|
+
_file: {
|
|
99
|
+
type: String
|
|
100
|
+
},
|
|
101
|
+
_selected: {
|
|
102
|
+
type: Array
|
|
103
|
+
},
|
|
104
|
+
_allowModification: {
|
|
105
|
+
type: Boolean,
|
|
106
|
+
},
|
|
107
|
+
_suggestions: {
|
|
108
|
+
type: Array
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
constructor() {
|
|
114
|
+
super();
|
|
115
|
+
this.sortOptions = [];
|
|
116
|
+
this.sortLabel = 'browse.sort';
|
|
117
|
+
this.sortBy = 'default';
|
|
118
|
+
this.filter = '';
|
|
119
|
+
this.filterOptions = [
|
|
120
|
+
{
|
|
121
|
+
label: 'Title',
|
|
122
|
+
value: 'title'
|
|
123
|
+
}
|
|
124
|
+
];
|
|
125
|
+
this.filterByLabel = 'browse.filter';
|
|
126
|
+
this.filterPlaceholderLabel = 'browse.filterPlaceholder';
|
|
127
|
+
|
|
128
|
+
this.filterBy = 'title';
|
|
129
|
+
this._allowModification = false;
|
|
130
|
+
this._suggestions = [];
|
|
131
|
+
|
|
132
|
+
this.static = false;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
connectedCallback() {
|
|
136
|
+
super.connectedCallback();
|
|
137
|
+
|
|
138
|
+
const sortParam = this.getParameter('sort');
|
|
139
|
+
if (sortParam) {
|
|
140
|
+
this.sortBy = sortParam;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const filterParam = this.getParameter('filter');
|
|
144
|
+
if (filterParam) {
|
|
145
|
+
this.filter = filterParam;
|
|
146
|
+
this.filterBy = this.getParameter('filterBy', this.filterBy);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
this.facets = this.getParametersMatching(/^facet-.*$/);
|
|
150
|
+
|
|
151
|
+
this.collection = this.getParameter('collection');
|
|
152
|
+
|
|
153
|
+
this.subscribeTo('pb-search-resubmit', this._facets.bind(this));
|
|
154
|
+
this.subscribeTo('pb-login', (ev) => {
|
|
155
|
+
if (ev.detail.userChanged) {
|
|
156
|
+
this._facets(ev);
|
|
157
|
+
}
|
|
158
|
+
}, []);
|
|
159
|
+
document.addEventListener('pb-i18n-update', () => {
|
|
160
|
+
// clear paper-listbox selection after language updates
|
|
161
|
+
const lb = this.shadowRoot.getElementById('sort-list');
|
|
162
|
+
let old = lb.selected;
|
|
163
|
+
lb.selected = undefined;
|
|
164
|
+
lb.selected = old;
|
|
165
|
+
|
|
166
|
+
const fl = this.shadowRoot.getElementById('filter-list');
|
|
167
|
+
old = fl.selected;
|
|
168
|
+
fl.selected = undefined;
|
|
169
|
+
fl.selected = old;
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
firstUpdated() {
|
|
174
|
+
PbBrowseDocs.waitOnce('pb-page-ready', (options) => {
|
|
175
|
+
const loader = this.shadowRoot.getElementById('autocompleteLoader');
|
|
176
|
+
if (cmpVersion(options.apiVersion, '1.0.0') >= 0) {
|
|
177
|
+
loader.url = `${options.endpoint}/api/search/autocomplete`;
|
|
178
|
+
if (!this.url) {
|
|
179
|
+
this.url = 'api/collection';
|
|
180
|
+
}
|
|
181
|
+
} else {
|
|
182
|
+
loader.url = `${options.endpoint}/modules/autocomplete.xql`;
|
|
183
|
+
if (!this.url) {
|
|
184
|
+
this.url = 'collection/';
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
this.shadowRoot.getElementById('autocomplete').addEventListener('autocomplete-change', this._autocomplete.bind(this));
|
|
189
|
+
|
|
190
|
+
if (this.login) {
|
|
191
|
+
const login = document.getElementById(this.login);
|
|
192
|
+
if (!login) {
|
|
193
|
+
console.error('<pb-browse-docs> connected pb-login element not found!');
|
|
194
|
+
} else {
|
|
195
|
+
this.subscribeTo('pb-login', (ev) => {
|
|
196
|
+
this._allowModification = this._loggedIn(ev.detail.user, ev.detail.group);
|
|
197
|
+
}, []);
|
|
198
|
+
this._allowModification = login.loggedIn && this._loggedIn(login.user, login.groups);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
this.shadowRoot.getElementById('sort-list').addEventListener('selected-item-changed', this._sort.bind(this));
|
|
203
|
+
this.shadowRoot.getElementById('delete').addEventListener('click', this._handleDelete.bind(this));
|
|
204
|
+
super.firstUpdated();
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
render() {
|
|
208
|
+
return html`
|
|
209
|
+
<custom-style>
|
|
210
|
+
<style>
|
|
211
|
+
:host {
|
|
212
|
+
--suggestions-item: {
|
|
213
|
+
color: var(--pb-search-suggestions-color, black);
|
|
214
|
+
};
|
|
215
|
+
--suggestions-wrapper: {
|
|
216
|
+
background: var(--pb-search-suggestions-background, white);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
</style>
|
|
220
|
+
</custom-style>
|
|
221
|
+
<slot name="header"></slot>
|
|
222
|
+
<div class="toolbar">
|
|
223
|
+
<paper-dropdown-menu id="sort" label="${translate(this.sortLabel)}" part="sort-dropdown">
|
|
224
|
+
<paper-listbox id="sort-list" selected="${this.sortBy}" slot="dropdown-content" class="dropdown-content" attr-for-selected="value">
|
|
225
|
+
${this.sortOptions.map(option =>
|
|
226
|
+
html`<paper-item value="${option.value}">${translate(option.label)}</paper-item>`
|
|
227
|
+
)}
|
|
228
|
+
</paper-listbox>
|
|
229
|
+
</paper-dropdown-menu>
|
|
230
|
+
<div>
|
|
231
|
+
<paper-dropdown-menu id="filterSelect" label="${translate(this.filterByLabel)}" part="filter-dropdown">
|
|
232
|
+
<paper-listbox id="filter-list" selected="${this.filterBy}" slot="dropdown-content" class="dropdown-content" attr-for-selected="value" @selected-item-changed="${this._filterChanged}">
|
|
233
|
+
${this.filterOptions.map(option =>
|
|
234
|
+
html`<paper-item value="${option.value}">${translate(option.label)}</paper-item>`
|
|
235
|
+
)}
|
|
236
|
+
</paper-listbox>
|
|
237
|
+
</paper-dropdown-menu>
|
|
238
|
+
<paper-input id="filterString" type="search" name="filter" label="${translate(this.filterPlaceholderLabel)}" value="${this.filter}"
|
|
239
|
+
@keyup="${this._handleEnter}" part="filter-input">
|
|
240
|
+
<iron-icon icon="search" @click="${this._filter}" slot="prefix"></iron-icon>
|
|
241
|
+
</paper-input>
|
|
242
|
+
<paper-autocomplete-suggestions id="autocomplete" for="filterString" source="${this._suggestions}" remote-source></paper-autocomplete-suggestions>
|
|
243
|
+
</div>
|
|
244
|
+
</div>
|
|
245
|
+
<div class="toolbar">
|
|
246
|
+
<slot name="toolbar"></slot>
|
|
247
|
+
<paper-button id="delete" part="delete-button" title="${translate('browse.delete')}" class="${this._canModify(this._allowModification)}">
|
|
248
|
+
<iron-icon icon="delete"></iron-icon>
|
|
249
|
+
<span class="label">${translate('browse.delete')}</span>
|
|
250
|
+
</paper-button>
|
|
251
|
+
</div>
|
|
252
|
+
<slot></slot>
|
|
253
|
+
<slot name="footer"></slot>
|
|
254
|
+
|
|
255
|
+
<iron-ajax
|
|
256
|
+
id="loadContent"
|
|
257
|
+
verbose
|
|
258
|
+
handle-as="text"
|
|
259
|
+
method="get"
|
|
260
|
+
with-credentials
|
|
261
|
+
@response="${this._handleContent}"
|
|
262
|
+
@error="${this._handleError}"></iron-ajax>
|
|
263
|
+
<iron-ajax
|
|
264
|
+
id="autocompleteLoader"
|
|
265
|
+
verbose
|
|
266
|
+
handle-as="json"
|
|
267
|
+
method="get"
|
|
268
|
+
with-credentials
|
|
269
|
+
@response="${this._updateSuggestions}"></iron-ajax>
|
|
270
|
+
|
|
271
|
+
<paper-dialog id="deleteDialog">
|
|
272
|
+
<h2>${translate('browse.delete')}</h2>
|
|
273
|
+
<paper-dialog-scrollable>
|
|
274
|
+
<p>${translate('browse.confirmDeletion', { count: (this._selected ? this._selected.length : 0) })}</p>
|
|
275
|
+
</paper-dialog-scrollable>
|
|
276
|
+
<div class="buttons">
|
|
277
|
+
<paper-button dialog-confirm="dialog-confirm" autofocus @click="${this._confirmDelete}">${translate('dialogs.yes')}</paper-button>
|
|
278
|
+
<paper-button dialog-confirm="dialog-cancel">${translate('dialogs.no')}</paper-button>
|
|
279
|
+
</div>
|
|
280
|
+
</paper-dialog>
|
|
281
|
+
<paper-dialog id="errorDialog">
|
|
282
|
+
<h2>${translate('dialogs.error')}</h2>
|
|
283
|
+
<paper-dialog-scrollable></paper-dialog-scrollable>
|
|
284
|
+
<div class="buttons">
|
|
285
|
+
<paper-button dialog-confirm="dialog-confirm" autofocus="autofocus">
|
|
286
|
+
${translate('dialogs.close')}
|
|
287
|
+
</paper-button>
|
|
288
|
+
</div>
|
|
289
|
+
</paper-dialog>
|
|
290
|
+
`;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
static get styles() {
|
|
294
|
+
return css`
|
|
295
|
+
:host {
|
|
296
|
+
display: block;
|
|
297
|
+
--paper-input-container-color: var(--pb-search-label-color, var(--paper-grey-500, #303030));
|
|
298
|
+
--paper-input-container-input-color: var(--pb-search-input-color, var(--pb-color-primary, #000000));
|
|
299
|
+
--paper-input-container-focus-color: var(--pb-search-focus-color, var(--paper-grey-500, #303030));
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
.toolbar {
|
|
303
|
+
display: flex;
|
|
304
|
+
justify-content: var(--pb-browse-toolbar-justify-content);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
[name="toolbar"] {
|
|
308
|
+
flex: 1 0;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
#sort {
|
|
312
|
+
display: block;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
#filterString {
|
|
316
|
+
position: relative;
|
|
317
|
+
display: inline-block;
|
|
318
|
+
vertical-align: bottom;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
.hidden {
|
|
322
|
+
display: none;
|
|
323
|
+
}
|
|
324
|
+
`;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
getURL(params) {
|
|
328
|
+
if (this.static) {
|
|
329
|
+
// use a static URL
|
|
330
|
+
return `collections/${this.collection ? this.collection + '/' : ''}${params.start || '1'}.html`;
|
|
331
|
+
}
|
|
332
|
+
const url = super.getURL(params);
|
|
333
|
+
return this.collection ? `${url}/${this.collection}` : url;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
prepareParameters(params) {
|
|
337
|
+
params = this._paramsFromSubforms(params);
|
|
338
|
+
params.sort = this.sortBy;
|
|
339
|
+
if (this.filter) {
|
|
340
|
+
params.filter = this.filter;
|
|
341
|
+
params.browse = this.filterBy;
|
|
342
|
+
}
|
|
343
|
+
if (this.facets) {
|
|
344
|
+
params = Object.assign(params, this.facets);
|
|
345
|
+
}
|
|
346
|
+
return params;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
_paramsFromSubforms(params) {
|
|
350
|
+
if (this.subforms) {
|
|
351
|
+
document.querySelectorAll(this.subforms).forEach((form) => {
|
|
352
|
+
if (form.serializeForm) {
|
|
353
|
+
Object.assign(params, form.serializeForm());
|
|
354
|
+
}
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
return params;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* returns selected documents.
|
|
362
|
+
*
|
|
363
|
+
* @returns {Array}
|
|
364
|
+
*/
|
|
365
|
+
getSelected() {
|
|
366
|
+
const selected = [];
|
|
367
|
+
if (this.container) {
|
|
368
|
+
document.querySelectorAll(this.container).forEach((container) =>
|
|
369
|
+
container.querySelectorAll('.document-select paper-checkbox[checked]').forEach((checkbox) => {
|
|
370
|
+
selected.push(checkbox.value);
|
|
371
|
+
})
|
|
372
|
+
);
|
|
373
|
+
} else {
|
|
374
|
+
this.querySelectorAll('.document-select paper-checkbox[checked]').forEach((checkbox) => {
|
|
375
|
+
selected.push(checkbox.value);
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
return selected;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
_filter() {
|
|
382
|
+
const filter = this.shadowRoot.getElementById('filterString').value;
|
|
383
|
+
const filterBy = this.shadowRoot.getElementById('filter-list').selected;
|
|
384
|
+
if (typeof filter !== 'undefined') {
|
|
385
|
+
console.log('<pb-browse-docs> Filter by %s', filter);
|
|
386
|
+
this.filter = filter;
|
|
387
|
+
this.setParameter('filter', filter);
|
|
388
|
+
this.setParameter('filterBy', filterBy);
|
|
389
|
+
this.pushHistory('filter docs');
|
|
390
|
+
|
|
391
|
+
this.load();
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
_filterChanged() {
|
|
396
|
+
const filterBy = this.shadowRoot.getElementById('filter-list').selected;
|
|
397
|
+
if (filterBy && filterBy !== this.filterBy) {
|
|
398
|
+
console.log('<pb-browse-docs> Filtering on %s', filterBy);
|
|
399
|
+
this.filterBy = filterBy;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
_sort() {
|
|
404
|
+
const sortBy = this.shadowRoot.getElementById('sort-list').selected;
|
|
405
|
+
if (sortBy && sortBy !== this.sortBy) {
|
|
406
|
+
console.log('<pb-browse-docs> Sorting by %s', sortBy);
|
|
407
|
+
this.sortBy = sortBy;
|
|
408
|
+
this.setParameter('sort', sortBy);
|
|
409
|
+
this.pushHistory('sort docs');
|
|
410
|
+
|
|
411
|
+
this.load();
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
_facets(ev) {
|
|
416
|
+
if (ev.detail && ev.detail.params) {
|
|
417
|
+
this.clearParametersMatching(/^(all-|facet-).*/);
|
|
418
|
+
for (let param in ev.detail.params) {
|
|
419
|
+
this.setParameter(param, ev.detail.params[param]);
|
|
420
|
+
}
|
|
421
|
+
this.facets = ev.detail.params;
|
|
422
|
+
this.start = 1;
|
|
423
|
+
this.pushHistory('facets');
|
|
424
|
+
}
|
|
425
|
+
this.load();
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
_onLoad(content) {
|
|
429
|
+
window.scrollTo(0, 0);
|
|
430
|
+
const div = content.querySelector('[data-root]');
|
|
431
|
+
const collection = div && div.getAttribute('data-root');
|
|
432
|
+
const writable = div && div.classList.contains('writable');
|
|
433
|
+
this.emitTo('pb-collection', {
|
|
434
|
+
writable,
|
|
435
|
+
collection
|
|
436
|
+
});
|
|
437
|
+
document.querySelectorAll('[can-write]').forEach((elem) => {
|
|
438
|
+
elem.disabled = !writable;
|
|
439
|
+
});
|
|
440
|
+
content.querySelectorAll('[data-collection]').forEach(link => {
|
|
441
|
+
link.addEventListener('click', (ev) => {
|
|
442
|
+
ev.preventDefault();
|
|
443
|
+
this.collection = link.getAttribute('data-collection');
|
|
444
|
+
this.start = 1;
|
|
445
|
+
this.setParameter('collection', this.collection);
|
|
446
|
+
this.pushHistory('browse collection');
|
|
447
|
+
console.log('<pb-browse-docs> loading collection %s', this.collection);
|
|
448
|
+
this.load();
|
|
449
|
+
});
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
_handleDelete(target, ev) {
|
|
454
|
+
const deleteDialog = this.shadowRoot.getElementById('deleteDialog');
|
|
455
|
+
const selected = this.getSelected();
|
|
456
|
+
if (selected.length > 0) {
|
|
457
|
+
this._selected = selected;
|
|
458
|
+
deleteDialog.open();
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
_confirmDelete() {
|
|
463
|
+
if (!(this._file || this._selected)) {
|
|
464
|
+
return;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
let files;
|
|
468
|
+
if (this._selected) {
|
|
469
|
+
files = this._selected;
|
|
470
|
+
} else {
|
|
471
|
+
files = [this._file];
|
|
472
|
+
}
|
|
473
|
+
console.log('<pb-browse-docs> Deleting %o', this._file);
|
|
474
|
+
const params = {
|
|
475
|
+
action: 'delete',
|
|
476
|
+
'docs[]': files
|
|
477
|
+
};
|
|
478
|
+
this._file = null;
|
|
479
|
+
this._selected = null;
|
|
480
|
+
this.load(params);
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
_loggedIn(user, groups) {
|
|
484
|
+
if (user == null) {
|
|
485
|
+
return false;
|
|
486
|
+
}
|
|
487
|
+
if (this.group) {
|
|
488
|
+
if (!groups) {
|
|
489
|
+
return false;
|
|
490
|
+
}
|
|
491
|
+
return groups.indexOf(this.group) > -1;
|
|
492
|
+
}
|
|
493
|
+
return true;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
_canModify(allowModification) {
|
|
497
|
+
return allowModification ? '' : 'hidden';
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
_autocomplete(ev) {
|
|
501
|
+
const autocompleteLoader = this.shadowRoot.getElementById('autocompleteLoader');
|
|
502
|
+
autocompleteLoader.params = {
|
|
503
|
+
query: ev.detail.option.text,
|
|
504
|
+
field: this.filterBy
|
|
505
|
+
};
|
|
506
|
+
autocompleteLoader.generateRequest();
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
_updateSuggestions() {
|
|
510
|
+
const autocomplete = this.shadowRoot.getElementById('autocomplete');
|
|
511
|
+
const autocompleteLoader = this.shadowRoot.getElementById('autocompleteLoader');
|
|
512
|
+
autocomplete.suggestions(autocompleteLoader.lastResponse);
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
_handleEnter(e) {
|
|
516
|
+
if (e.keyCode == 13) {
|
|
517
|
+
this._filter();
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
521
|
customElements.define('pb-browse-docs', PbBrowseDocs);
|