@teipublisher/pb-components 2.26.1-next.3 → 3.0.0-next-4.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.
Files changed (262) hide show
  1. package/.github/workflows/docker-cypress.yml +53 -0
  2. package/.github/workflows/node.js.yml +70 -21
  3. package/.releaserc.json +7 -2
  4. package/CHANGELOG.md +363 -11
  5. package/Dockerfile +78 -70
  6. package/README.md +112 -4
  7. package/css/components.css +5 -5
  8. package/css/gridjs/mermaid.min.css +1 -1
  9. package/css/leaflet/Control.Geocoder.css +1 -126
  10. package/css/leaflet/images/layers.png +0 -0
  11. package/css/tify/tify.css +6 -5
  12. package/css/tom-select/tom-select.bootstrap4.min.css +1 -1
  13. package/css/tom-select/tom-select.bootstrap5.min.css +1 -1
  14. package/css/tom-select/tom-select.default.min.css +1 -1
  15. package/css/tom-select/tom-select.default.min.css.map +1 -0
  16. package/css/tom-select/tom-select.min.css +1 -1
  17. package/cypress.config.js +84 -0
  18. package/dist/api.html +1 -1
  19. package/dist/css/design-system.css +607 -0
  20. package/dist/demo/bundle-test.html +4 -3
  21. package/dist/demo/components.css +46 -1
  22. package/dist/demo/design-system.html +710 -0
  23. package/dist/demo/dts-client.html +2 -2
  24. package/dist/demo/pb-autocomplete.html +23 -11
  25. package/dist/demo/pb-autocomplete2.html +66 -55
  26. package/dist/demo/pb-autocomplete3.html +17 -8
  27. package/dist/demo/pb-blacklab-highlight.html +28 -11
  28. package/dist/demo/pb-blacklab-results.html +3 -2
  29. package/dist/demo/pb-browse-docs.html +24 -24
  30. package/dist/demo/pb-browse-docs2.html +3 -3
  31. package/dist/demo/pb-clipboard.html +32 -28
  32. package/dist/demo/pb-code-editor.html +6 -6
  33. package/dist/demo/pb-code-highlight.html +63 -63
  34. package/dist/demo/pb-codepen.html +1 -1
  35. package/dist/demo/pb-collapse.html +1 -1
  36. package/dist/demo/pb-collapse2.html +2 -2
  37. package/dist/demo/pb-combo-box.html +135 -130
  38. package/dist/demo/pb-custom-form.html +64 -55
  39. package/dist/demo/pb-dialog.html +12 -6
  40. package/dist/demo/pb-document.html +1 -1
  41. package/dist/demo/pb-download.html +68 -59
  42. package/dist/demo/pb-drawer.html +67 -46
  43. package/dist/demo/pb-drawer2.html +65 -58
  44. package/dist/demo/pb-edit-app.html +2 -2
  45. package/dist/demo/pb-edit-xml.html +1 -1
  46. package/dist/demo/pb-facsimile-2.html +26 -11
  47. package/dist/demo/pb-facsimile-3.html +25 -10
  48. package/dist/demo/pb-facsimile-dedup-test-2.html +48 -0
  49. package/dist/demo/pb-facsimile-dedup-test.html +48 -0
  50. package/dist/demo/pb-facsimile.html +4 -4
  51. package/dist/demo/pb-formula.html +1 -1
  52. package/dist/demo/pb-grid.html +22 -8
  53. package/dist/demo/pb-highlight.html +2 -2
  54. package/dist/demo/pb-i18n-simple.html +1 -0
  55. package/dist/demo/pb-i18n.html +15 -5
  56. package/dist/demo/pb-image-strip-standalone.html +2 -2
  57. package/dist/demo/pb-image-strip-view.html +2 -2
  58. package/dist/demo/pb-leaflet-map.html +3 -3
  59. package/dist/demo/pb-leaflet-map2.html +2 -2
  60. package/dist/demo/pb-leaflet-map3.html +3 -3
  61. package/dist/demo/pb-link.html +1 -1
  62. package/dist/demo/pb-load.html +2 -6
  63. package/dist/demo/pb-login.html +1 -3
  64. package/dist/demo/pb-manage-odds.html +9 -4
  65. package/dist/demo/pb-markdown.html +1 -1
  66. package/dist/demo/pb-media-query.html +2 -2
  67. package/dist/demo/pb-mei.html +2 -2
  68. package/dist/demo/pb-mei2.html +2 -2
  69. package/dist/demo/pb-message.html +2 -3
  70. package/dist/demo/pb-odd-editor.html +54 -52
  71. package/dist/demo/pb-page-header.html +27 -0
  72. package/dist/demo/pb-popover.html +1 -1
  73. package/dist/demo/pb-print-preview.html +2 -2
  74. package/dist/demo/pb-progress.html +4 -4
  75. package/dist/demo/pb-repeat.html +32 -36
  76. package/dist/demo/pb-search.html +16 -5
  77. package/dist/demo/pb-search2.html +4 -4
  78. package/dist/demo/pb-search3.html +3 -3
  79. package/dist/demo/pb-search4.html +3 -3
  80. package/dist/demo/pb-select-feature.html +4 -4
  81. package/dist/demo/pb-select-feature2.html +4 -4
  82. package/dist/demo/pb-select-feature3.html +2 -2
  83. package/dist/demo/pb-select-i18n.html +58 -53
  84. package/dist/demo/pb-select-odd.html +1 -1
  85. package/dist/demo/pb-select.html +190 -75
  86. package/dist/demo/pb-select2.html +91 -37
  87. package/dist/demo/pb-select3.html +109 -41
  88. package/dist/demo/pb-svg.html +1 -1
  89. package/dist/demo/pb-table-grid.html +26 -15
  90. package/dist/demo/pb-tabs.html +15 -7
  91. package/dist/demo/pb-tify.html +7 -7
  92. package/dist/demo/pb-timeline.html +1 -1
  93. package/dist/demo/pb-timeline2.html +1 -1
  94. package/dist/demo/pb-toggle-feature.html +26 -23
  95. package/dist/demo/pb-toggle-feature2.html +4 -4
  96. package/dist/demo/pb-toggle-feature3.html +2 -2
  97. package/dist/demo/pb-toggle-feature4.html +56 -54
  98. package/dist/demo/pb-version.html +2 -2
  99. package/dist/demo/pb-view.html +78 -40
  100. package/dist/demo/pb-view2.html +69 -46
  101. package/dist/demo/pb-view3.html +53 -48
  102. package/dist/demo/pb-view4.html +70 -49
  103. package/dist/demo/pb-zoom.html +2 -2
  104. package/dist/{es-global-bridge-d8ce175d.js → es-global-bridge-D8ZcUcx_.js} +0 -4
  105. package/dist/focus-mixin-VCsFap6b.js +768 -0
  106. package/dist/images/icons.svg +217 -0
  107. package/dist/jinn-codemirror-DETLdm08.js +1 -0
  108. package/dist/lib/openseadragon.min.js +80 -0
  109. package/dist/lib/openseadragon.min.js.map +1 -0
  110. package/dist/pb-code-editor.js +25 -20
  111. package/dist/pb-component-docs.js +414 -3225
  112. package/dist/pb-components-bundle.js +3046 -4402
  113. package/dist/pb-dialog-tklYGWfc.js +121 -0
  114. package/dist/pb-edit-app.js +208 -107
  115. package/dist/pb-elements.json +716 -249
  116. package/dist/pb-facsimile.js +46 -0
  117. package/dist/pb-i18n-C0NDma4h.js +1 -0
  118. package/dist/pb-leaflet-map.js +23 -23
  119. package/dist/pb-mei.js +152 -134
  120. package/dist/pb-mixin-DHoWQheB.js +1 -0
  121. package/dist/pb-odd-editor.js +1671 -1231
  122. package/dist/pb-tify.js +1 -27
  123. package/dist/unsafe-html-D5VGo9Oq.js +1 -0
  124. package/dist/urls-BEONu_g4.js +1 -0
  125. package/eslint.config.mjs +92 -0
  126. package/gh-pages.js +5 -3
  127. package/i18n/common/en.json +6 -0
  128. package/i18n/common/pl.json +2 -2
  129. package/images/icons.svg +217 -0
  130. package/index.html +0 -5
  131. package/lib/leaflet-src.js.map +1 -0
  132. package/lib/leaflet.markercluster-src.js.map +1 -0
  133. package/lib/openseadragon.min.js +6 -6
  134. package/package.json +56 -81
  135. package/pb-elements.json +716 -249
  136. package/rollup.config.mjs +312 -0
  137. package/src/assets/components.css +5 -5
  138. package/src/assets/design-system.css +607 -0
  139. package/src/authority/airtable.js +20 -21
  140. package/src/authority/anton.js +129 -129
  141. package/src/authority/custom.js +70 -27
  142. package/src/authority/geonames.js +38 -32
  143. package/src/authority/gnd.js +50 -42
  144. package/src/authority/kbga.js +136 -134
  145. package/src/authority/metagrid.js +44 -46
  146. package/src/authority/reconciliation.js +66 -68
  147. package/src/authority/registry.js +4 -4
  148. package/src/docs/demo-utils.js +91 -0
  149. package/src/docs/pb-component-docs.js +287 -147
  150. package/src/docs/pb-component-view.js +380 -273
  151. package/src/docs/pb-components-list.js +115 -51
  152. package/src/docs/pb-demo-snippet.js +199 -174
  153. package/src/dts-client.js +306 -303
  154. package/src/dts-select-endpoint.js +125 -85
  155. package/src/parse-date-service.js +184 -135
  156. package/src/pb-ajax.js +175 -173
  157. package/src/pb-authority-lookup.js +198 -158
  158. package/src/pb-autocomplete.js +731 -313
  159. package/src/pb-blacklab-highlight.js +266 -260
  160. package/src/pb-blacklab-results.js +230 -225
  161. package/src/pb-browse-docs.js +601 -484
  162. package/src/pb-browse.js +68 -65
  163. package/src/pb-clipboard.js +97 -76
  164. package/src/pb-code-editor.js +111 -103
  165. package/src/pb-code-highlight.js +234 -204
  166. package/src/pb-codepen.js +81 -73
  167. package/src/pb-collapse.js +265 -152
  168. package/src/pb-combo-box.js +191 -191
  169. package/src/pb-components-bundle.js +1 -7
  170. package/src/pb-components.js +2 -6
  171. package/src/pb-custom-form.js +230 -141
  172. package/src/pb-dialog.js +99 -63
  173. package/src/pb-document.js +118 -91
  174. package/src/pb-download.js +214 -198
  175. package/src/pb-drawer.js +146 -149
  176. package/src/pb-edit-app.js +471 -240
  177. package/src/pb-edit-xml.js +101 -98
  178. package/src/pb-events.js +126 -107
  179. package/src/pb-facs-link.js +130 -101
  180. package/src/pb-facsimile.js +494 -410
  181. package/src/pb-fetch.js +389 -0
  182. package/src/pb-formula.js +152 -154
  183. package/src/pb-geolocation.js +130 -132
  184. package/src/pb-grid-action.js +59 -56
  185. package/src/pb-grid.js +388 -228
  186. package/src/pb-highlight.js +142 -142
  187. package/src/pb-hotkeys.js +40 -42
  188. package/src/pb-i18n.js +115 -127
  189. package/src/pb-icon-button.js +108 -0
  190. package/src/pb-icon.js +283 -0
  191. package/src/pb-image-strip.js +85 -79
  192. package/src/pb-lang.js +142 -57
  193. package/src/pb-leaflet-map.js +551 -483
  194. package/src/pb-link.js +132 -126
  195. package/src/pb-load.js +495 -428
  196. package/src/pb-login.js +303 -248
  197. package/src/pb-manage-odds.js +384 -338
  198. package/src/pb-map-icon.js +90 -90
  199. package/src/pb-map-layer.js +86 -86
  200. package/src/pb-markdown.js +107 -110
  201. package/src/pb-media-query.js +75 -73
  202. package/src/pb-mei.js +523 -303
  203. package/src/pb-message.js +144 -98
  204. package/src/pb-mixin.js +268 -265
  205. package/src/pb-navigation.js +83 -96
  206. package/src/pb-observable.js +39 -39
  207. package/src/pb-odd-editor.js +1209 -948
  208. package/src/pb-odd-elementspec-editor.js +375 -310
  209. package/src/pb-odd-model-editor.js +1189 -941
  210. package/src/pb-odd-parameter-editor.js +269 -170
  211. package/src/pb-odd-rendition-editor.js +184 -131
  212. package/src/pb-page.js +451 -422
  213. package/src/pb-paginate.js +260 -178
  214. package/src/pb-panel.js +217 -183
  215. package/src/pb-popover-themes.js +16 -9
  216. package/src/pb-popover.js +297 -288
  217. package/src/pb-print-preview.js +128 -128
  218. package/src/pb-progress.js +52 -52
  219. package/src/pb-repeat.js +141 -108
  220. package/src/pb-restricted.js +85 -78
  221. package/src/pb-search.js +258 -230
  222. package/src/pb-select-feature.js +210 -126
  223. package/src/pb-select-odd.js +184 -118
  224. package/src/pb-select-template.js +113 -78
  225. package/src/pb-select.js +330 -229
  226. package/src/pb-split-list.js +181 -176
  227. package/src/pb-svg.js +81 -80
  228. package/src/pb-table-column.js +55 -55
  229. package/src/pb-table-grid.js +334 -205
  230. package/src/pb-tabs.js +238 -61
  231. package/src/pb-tify.js +3331 -126
  232. package/src/pb-timeline.js +394 -255
  233. package/src/pb-toggle-feature.js +196 -188
  234. package/src/pb-upload.js +201 -176
  235. package/src/pb-version.js +22 -34
  236. package/src/pb-view-annotate.js +138 -102
  237. package/src/pb-view.js +1722 -1272
  238. package/src/pb-zoom.js +144 -46
  239. package/src/search-result-service.js +256 -223
  240. package/src/seed-element.js +14 -22
  241. package/src/settings.js +4 -4
  242. package/src/theming.js +98 -91
  243. package/src/urls.js +403 -289
  244. package/src/utils.js +53 -51
  245. package/vite.config.js +86 -0
  246. package/.github/workflows/main.yml +0 -24
  247. package/.github/workflows/release.js.yml +0 -34
  248. package/css/pb-styles.css +0 -51
  249. package/dist/iron-form-3b8dcaa7.js +0 -210
  250. package/dist/jinn-codemirror-da0e2d1f.js +0 -1
  251. package/dist/paper-checkbox-515a5284.js +0 -1597
  252. package/dist/paper-icon-button-b1d31571.js +0 -398
  253. package/dist/paper-listbox-a3b7175c.js +0 -1265
  254. package/dist/pb-i18n-0611135a.js +0 -1
  255. package/dist/pb-mixin-b1caa22e.js +0 -158
  256. package/dist/polymer-hack.js +0 -1
  257. package/dist/vaadin-element-mixin-fe4a4883.js +0 -527
  258. package/lib/Control.Geocoder.min.js +0 -2
  259. package/lib/Control.Geocoder.min.js.map +0 -1
  260. package/src/assets/pb-styles.css +0 -51
  261. package/src/pb-light-dom.js +0 -41
  262. package/src/polymer-hack.js +0 -6
@@ -1,19 +1,15 @@
1
- import { html, css } from 'lit-element';
1
+ import { html, css } from 'lit';
2
2
  import { PbLoad } from './pb-load.js';
3
3
  import { waitOnce } from './pb-mixin.js';
4
- import { translate } from "./pb-i18n.js";
5
- import { themableMixin } from "./theming.js";
4
+ import { translate } from './pb-i18n.js';
5
+ import { themableMixin } from './theming.js';
6
6
  import { cmpVersion } from './utils.js';
7
- import { registry } from "./urls.js";
7
+ import { registry } from './urls.js';
8
+ import './pb-icon.js';
9
+ import './pb-dialog.js';
10
+ import './pb-autocomplete.js';
8
11
 
9
- import '@polymer/paper-input/paper-input.js';
10
- import '@polymer/paper-button';
11
- import '@polymer/paper-dropdown-menu/paper-dropdown-menu.js';
12
- import '@polymer/paper-listbox';
13
- import '@polymer/paper-dialog';
14
- import '@polymer/paper-dialog-scrollable';
15
- import '@polymer/iron-ajax';
16
- import '@cwmr/paper-autocomplete/paper-autocomplete-suggestions.js';
12
+ import './pb-fetch.js';
17
13
 
18
14
  /**
19
15
  * Component to browse through a collection of documents with sorting, filtering and facets.
@@ -21,520 +17,641 @@ import '@cwmr/paper-autocomplete/paper-autocomplete-suggestions.js';
21
17
  * @slot toolbar - toolbar area
22
18
  * @slot - unnamed default slot
23
19
  * @slot footer - footer area
24
- *
20
+ *
25
21
  * @fires pb-collection - Sent to inform e.g. pb-upload about current collection
26
22
  * @fires pb-search-resubmit - When received, set facet values as received from the event
27
23
  * @fires pb-login - When received, refresh the view if the user changed
28
- *
24
+ *
29
25
  * @cssprop --pb-search-suggestions-background - Background for the autocomplete suggestions for the filter field
30
26
  * @cssprop --pb-search-suggestions-color - Text color for the autocomplete suggestion for the filter field
31
27
  * @cssprop --pb-search-label-color - Determines the color of small label above the sort by/filter by/filter fields
32
28
  * @cssprop --pb-search-input-color - Determines the color of the text in the sort by/filter by/filter fields
33
29
  * @cssprop --pb-search-focus-color - Color of the field labels and underline when in focus
34
30
  * @cssprop --pb-browse-toolbar-justify-content - How to justify the browse toolbar content, following flexbox justify-content property e.g. center, space-evenly, start...
35
- *
31
+ *
36
32
  * @csspart delete-button - the delete button
37
33
  * @csspart sort-dropdown - dropdown for sorting
38
34
  * @csspart filter-dropdown - dropdown for filtering
39
35
  * @csspart filter-input - input for filtering
40
36
  */
41
37
  export class PbBrowseDocs extends themableMixin(PbLoad) {
38
+ static get properties() {
39
+ return {
40
+ ...super.properties,
41
+ sortBy: {
42
+ type: String,
43
+ attribute: 'sort-by',
44
+ },
45
+ sortOptions: {
46
+ type: Array,
47
+ attribute: 'sort-options',
48
+ },
49
+ sortLabel: {
50
+ type: String,
51
+ },
52
+ filter: {
53
+ type: String,
54
+ },
55
+ filterBy: {
56
+ type: String,
57
+ attribute: 'filter-by',
58
+ },
59
+ filterOptions: {
60
+ type: Array,
61
+ attribute: 'filter-options',
62
+ },
63
+ filterByLabel: {
64
+ type: String,
65
+ },
66
+ filterPlaceholderLabel: {
67
+ type: String,
68
+ },
69
+ collection: {
70
+ type: String,
71
+ },
72
+ facets: {
73
+ type: Object,
74
+ },
75
+ /** Id of the pb-login element to connect to */
76
+ login: {
77
+ type: String,
78
+ },
79
+ /**
80
+ * If set, requires the logged in user to be member of
81
+ * the given group.
82
+ */
83
+ group: {
84
+ type: String,
85
+ },
86
+ subforms: {
87
+ type: String,
88
+ },
89
+ /**
90
+ * If set, rewrite URLs to load pages as static HTML files,
91
+ * so no TEI Publisher instance is required
92
+ */
93
+ static: {
94
+ type: Boolean,
95
+ },
96
+ _file: {
97
+ type: String,
98
+ },
99
+ _selected: {
100
+ type: Array,
101
+ },
102
+ _allowModification: {
103
+ type: Boolean,
104
+ },
105
+ };
106
+ }
107
+
108
+ constructor() {
109
+ super();
110
+ this.sortOptions = [];
111
+ this.sortLabel = 'browse.sort';
112
+ this.sortBy = 'default';
113
+ this.filter = '';
114
+ this.filterOptions = [
115
+ {
116
+ label: 'Title',
117
+ value: 'title',
118
+ },
119
+ ];
120
+ this.filterByLabel = 'browse.filter';
121
+ this.filterPlaceholderLabel = 'browse.filterPlaceholder';
122
+
123
+ this.filterBy = 'title';
124
+ this._allowModification = false;
125
+
126
+ this.static = false;
127
+ }
128
+
129
+ connectedCallback() {
130
+ super.connectedCallback();
131
+
132
+ waitOnce('pb-page-ready', () => {
133
+ if (registry.state.sort) {
134
+ this.sortBy = registry.state.sort;
135
+ }
136
+
137
+ if (registry.state.filter) {
138
+ this.filter = registry.state.filter;
139
+ this.filterBy = registry.state.filterBy || this.filterBy;
140
+ }
141
+
142
+ this.facets = {};
143
+ // registry get state by regex
144
+ // this.facets = registry.getParametersMatching(this, /^facet-.*$/)
145
+ Object.keys(registry.state).forEach(key => {
146
+ if (/^facet-.*$/.test(key)) {
147
+ const param = registry.state[key];
148
+ if (this.facets[key]) {
149
+ this.facets[key].push(param);
150
+ } else if (Array.isArray(param)) {
151
+ this.facets[key] = param;
152
+ } else {
153
+ this.facets[key] = [param];
154
+ }
155
+ }
156
+ });
42
157
 
43
- static get properties() {
44
- return {
45
- ...super.properties,
46
- sortBy: {
47
- type: String,
48
- attribute: 'sort-by'
49
- },
50
- sortOptions: {
51
- type: Array,
52
- attribute: 'sort-options'
53
- },
54
- sortLabel: {
55
- type: String
56
- },
57
- filter: {
58
- type: String
59
- },
60
- filterBy: {
61
- type: String,
62
- attribute: 'filter-by'
63
- },
64
- filterOptions: {
65
- type: Array,
66
- attribute: 'filter-options'
67
- },
68
- filterByLabel: {
69
- type: String
70
- },
71
- filterPlaceholderLabel: {
72
- type: String
73
- },
74
- collection: {
75
- type: String
76
- },
77
- facets: {
78
- type: Object
79
- },
80
- /** Id of the pb-login element to connect to */
81
- login: {
82
- type: String
83
- },
84
- /**
85
- * If set, requires the logged in user to be member of
86
- * the given group.
87
- */
88
- group: {
89
- type: String
90
- },
91
- subforms: {
92
- type: String
93
- },
94
- /**
95
- * If set, rewrite URLs to load pages as static HTML files,
96
- * so no TEI Publisher instance is required
97
- */
98
- static: {
99
- type: Boolean
100
- },
101
- _file: {
102
- type: String
103
- },
104
- _selected: {
105
- type: Array
106
- },
107
- _allowModification: {
108
- type: Boolean,
109
- },
110
- _suggestions: {
111
- type: Array
112
- }
113
- };
114
- }
115
-
116
- constructor() {
117
- super();
118
- this.sortOptions = [];
119
- this.sortLabel = 'browse.sort';
120
- this.sortBy = 'default';
121
- this.filter = '';
122
- this.filterOptions = [
123
- {
124
- label: 'Title',
125
- value: 'title'
126
- }
127
- ];
128
- this.filterByLabel = 'browse.filter';
129
- this.filterPlaceholderLabel = 'browse.filterPlaceholder';
130
-
131
- this.filterBy = 'title';
132
- this._allowModification = false;
133
- this._suggestions = [];
134
-
135
- this.static = false;
136
- }
137
-
138
- connectedCallback() {
139
- super.connectedCallback();
140
-
141
- waitOnce('pb-page-ready', () => {
142
- if (registry.state.sort) {
143
- this.sortBy = registry.state.sort;
144
- }
145
-
146
- if (registry.state.filter) {
147
- this.filter = registry.state.filter;
148
- this.filterBy = registry.state.filterBy || this.filterBy;
149
- }
150
-
151
- this.facets = {};
152
- // registry get state by regex
153
- // this.facets = registry.getParametersMatching(this, /^facet-.*$/)
154
- Object.keys(registry.state).forEach((key) => {
155
- if (/^facet-.*$/.test(key)) {
156
- const param = registry.state[key];
157
- if (this.facets[key]) {
158
- this.facets[key].push(param);
159
- } else if (Array.isArray(param)) {
160
- this.facets[key] = param;
161
- } else {
162
- this.facets[key] = [param];
163
- }
164
- }
165
- });
166
-
167
- this.collection = registry.state.collection;
168
-
169
- if (this.collection) {
170
- registry.replace(this, {
171
- collection: this.collection
172
- });
173
- }
174
- registry.subscribe(this, (state) => {
175
- this.collection = state.collection;
176
- this.load();
177
- });
178
- });
179
-
180
- this.subscribeTo('pb-search-resubmit', this._facets.bind(this));
181
- this.subscribeTo('pb-login', (ev) => {
182
- if (ev.detail.userChanged) {
183
- this._facets(ev);
184
- }
185
- }, []);
186
- document.addEventListener('pb-i18n-update', () => {
187
- // clear paper-listbox selection after language updates
188
- const lb = this.shadowRoot.getElementById('sort-list');
189
- let old = lb.selected;
190
- lb.selected = undefined;
191
- lb.selected = old;
192
-
193
- const fl = this.shadowRoot.getElementById('filter-list');
194
- old = fl.selected;
195
- fl.selected = undefined;
196
- fl.selected = old;
197
- });
198
- }
158
+ this.collection = registry.state.collection;
199
159
 
200
- firstUpdated() {
201
- waitOnce('pb-page-ready', (options) => {
202
- const loader = this.shadowRoot.getElementById('autocompleteLoader');
203
- if (cmpVersion(options.apiVersion, '1.0.0') >= 0) {
204
- loader.url = `${options.endpoint}/api/search/autocomplete`;
205
- if (!this.url) {
206
- this.url = 'api/collection';
207
- }
208
- } else {
209
- loader.url = `${options.endpoint}/modules/autocomplete.xql`;
210
- if (!this.url) {
211
- this.url = 'collection/';
212
- }
213
- }
160
+ if (this.collection) {
161
+ registry.replace(this, {
162
+ collection: this.collection,
214
163
  });
215
- this.shadowRoot.getElementById('autocomplete').addEventListener('autocomplete-change', this._autocomplete.bind(this));
216
-
217
- if (this.login) {
218
- const login = document.getElementById(this.login);
219
- if (!login) {
220
- console.error('<pb-browse-docs> connected pb-login element not found!');
221
- } else {
222
- this.subscribeTo('pb-login', (ev) => {
223
- this._allowModification = this._loggedIn(ev.detail.user, ev.detail.group);
224
- }, []);
225
- this._allowModification = login.loggedIn && this._loggedIn(login.user, login.groups);
226
- }
164
+ }
165
+ registry.subscribe(this, state => {
166
+ this.collection = state.collection;
167
+ this.load();
168
+ });
169
+ });
170
+
171
+ this.subscribeTo('pb-search-resubmit', this._facets.bind(this));
172
+ this.subscribeTo(
173
+ 'pb-login',
174
+ ev => {
175
+ if (ev.detail.userChanged) {
176
+ this._facets(ev);
227
177
  }
228
-
229
- this.shadowRoot.getElementById('sort-list').addEventListener('selected-item-changed', this._sort.bind(this));
230
- this.shadowRoot.getElementById('delete').addEventListener('click', this._handleDelete.bind(this));
231
- super.firstUpdated();
178
+ },
179
+ [],
180
+ );
181
+ this.subscribeTo(
182
+ 'pb-i18n-update',
183
+ () => {
184
+ this.requestUpdate();
185
+ },
186
+ [],
187
+ );
188
+ }
189
+
190
+ firstUpdated() {
191
+ waitOnce('pb-page-ready', options => {
192
+ const autocomplete = this.shadowRoot.getElementById('filterString');
193
+ let autocompleteUrl;
194
+ if (cmpVersion(options.apiVersion, '1.0.0') >= 0) {
195
+ autocompleteUrl = `${options.endpoint}/api/search/autocomplete`;
196
+ if (!this.url) {
197
+ this.url = 'api/collection';
198
+ }
199
+ } else {
200
+ autocompleteUrl = `${options.endpoint}/modules/autocomplete.xql`;
201
+ if (!this.url) {
202
+ this.url = 'collection/';
203
+ }
204
+ }
205
+ if (autocomplete) {
206
+ autocomplete.source = autocompleteUrl;
207
+ autocomplete.substring = true;
208
+ autocomplete.requestParams = { field: this.filterBy };
209
+ }
210
+ });
211
+
212
+ const autocomplete = this.shadowRoot.getElementById('filterString');
213
+ if (autocomplete) {
214
+ autocomplete.addEventListener(
215
+ 'pb-autocomplete-selected',
216
+ this._handleAutocompleteSelected.bind(this),
217
+ );
218
+ autocomplete.addEventListener(
219
+ 'pb-autocomplete-input',
220
+ this._handleAutocompleteInput.bind(this),
221
+ );
232
222
  }
233
223
 
234
- render() {
235
- return html`
236
- <custom-style>
237
- <style>
238
- :host {
239
- --suggestions-item: {
240
- color: var(--pb-search-suggestions-color, black);
241
- };
242
- --suggestions-wrapper: {
243
- background: var(--pb-search-suggestions-background, white);
244
- }
245
- }
246
- </style>
247
- </custom-style>
248
- <slot name="header"></slot>
249
- <div class="toolbar">
250
- <paper-dropdown-menu id="sort" label="${translate(this.sortLabel)}" part="sort-dropdown">
251
- <paper-listbox id="sort-list" selected="${this.sortBy}" slot="dropdown-content" class="dropdown-content" attr-for-selected="value">
252
- ${this.sortOptions.map(option =>
253
- html`<paper-item value="${option.value}">${translate(option.label)}</paper-item>`
254
- )}
255
- </paper-listbox>
256
- </paper-dropdown-menu>
257
- <div>
258
- <paper-dropdown-menu id="filterSelect" label="${translate(this.filterByLabel)}" part="filter-dropdown">
259
- <paper-listbox id="filter-list" selected="${this.filterBy}" slot="dropdown-content" class="dropdown-content" attr-for-selected="value" @selected-item-changed="${this._filterChanged}">
260
- ${this.filterOptions.map(option =>
261
- html`<paper-item value="${option.value}">${translate(option.label)}</paper-item>`
262
- )}
263
- </paper-listbox>
264
- </paper-dropdown-menu>
265
- <paper-input id="filterString" type="search" name="filter" label="${translate(this.filterPlaceholderLabel)}" value="${this.filter}"
266
- @keyup="${this._handleEnter}" part="filter-input">
267
- <iron-icon icon="search" @click="${this._filter}" slot="prefix"></iron-icon>
268
- </paper-input>
269
- <paper-autocomplete-suggestions id="autocomplete" for="filterString" source="${this._suggestions}" remote-source></paper-autocomplete-suggestions>
270
- </div>
271
- </div>
272
- <div class="toolbar">
273
- <slot name="toolbar"></slot>
274
- <paper-button id="delete" part="delete-button" title="${translate('browse.delete')}" class="${this._canModify(this._allowModification)}">
275
- <iron-icon icon="delete"></iron-icon>
276
- <span class="label">${translate('browse.delete')}</span>
277
- </paper-button>
278
- </div>
279
- <slot></slot>
280
- <slot name="footer"></slot>
281
-
282
- <iron-ajax
283
- id="loadContent"
284
- verbose
285
- handle-as="text"
286
- method="get"
287
- with-credentials
288
- @response="${this._handleContent}"
289
- @error="${this._handleError}"></iron-ajax>
290
- <iron-ajax
291
- id="autocompleteLoader"
292
- verbose
293
- handle-as="json"
294
- method="get"
295
- with-credentials
296
- @response="${this._updateSuggestions}"></iron-ajax>
297
-
298
- <paper-dialog id="deleteDialog">
299
- <h2>${translate('browse.delete')}</h2>
300
- <paper-dialog-scrollable>
301
- <p>${translate('browse.confirmDeletion', { count: (this._selected ? this._selected.length : 0) })}</p>
302
- </paper-dialog-scrollable>
303
- <div class="buttons">
304
- <paper-button dialog-confirm="dialog-confirm" autofocus @click="${this._confirmDelete}">${translate('dialogs.yes')}</paper-button>
305
- <paper-button dialog-confirm="dialog-cancel">${translate('dialogs.no')}</paper-button>
306
- </div>
307
- </paper-dialog>
308
- <paper-dialog id="errorDialog">
309
- <h2>${translate('dialogs.error')}</h2>
310
- <paper-dialog-scrollable></paper-dialog-scrollable>
311
- <div class="buttons">
312
- <paper-button dialog-confirm="dialog-confirm" autofocus="autofocus">
313
- ${translate('dialogs.close')}
314
- </paper-button>
315
- </div>
316
- </paper-dialog>
317
- `;
224
+ const sortSelect = this.shadowRoot.getElementById('sortSelect');
225
+ if (sortSelect) {
226
+ sortSelect.addEventListener('change', this._sort.bind(this));
318
227
  }
319
228
 
320
- static get styles() {
321
- return css`
322
- :host {
323
- display: block;
324
- --paper-input-container-color: var(--pb-search-label-color, var(--paper-grey-500, #303030));
325
- --paper-input-container-input-color: var(--pb-search-input-color, var(--pb-color-primary, #000000));
326
- --paper-input-container-focus-color: var(--pb-search-focus-color, var(--paper-grey-500, #303030));
327
- }
328
-
329
- .toolbar {
330
- display: flex;
331
- justify-content: var(--pb-browse-toolbar-justify-content);
332
- }
333
-
334
- [name="toolbar"] {
335
- flex: 1 0;
336
- }
337
-
338
- #sort {
339
- display: block;
340
- }
341
-
342
- #filterString {
343
- position: relative;
344
- display: inline-block;
345
- vertical-align: bottom;
346
- }
347
-
348
- .hidden {
349
- display: none;
350
- }
351
- `;
229
+ if (this.login) {
230
+ const login = document.getElementById(this.login);
231
+ if (!login) {
232
+ console.error('<pb-browse-docs> connected pb-login element not found!');
233
+ } else {
234
+ this.subscribeTo(
235
+ 'pb-login',
236
+ ev => {
237
+ this._allowModification = this._loggedIn(ev.detail.user, ev.detail.group);
238
+ },
239
+ [],
240
+ );
241
+ this._allowModification = login.loggedIn && this._loggedIn(login.user, login.groups);
242
+ }
352
243
  }
353
-
354
- getURL(params) {
355
- if (this.static) {
356
- // use a static URL
357
- return `collections/${this.collection ? this.collection + '/' : ''}${params.start || '1'}.html`;
358
- }
359
- const url = super.getURL(params);
360
- return this.collection ? `${url}/${this.collection}` : url;
244
+ this.shadowRoot
245
+ .getElementById('delete')
246
+ .addEventListener('click', this._handleDelete.bind(this));
247
+ super.firstUpdated();
248
+ }
249
+
250
+ render() {
251
+ return html`
252
+ <slot name="header"></slot>
253
+ <div class="toolbar toolbar--primary">
254
+ <div class="toolbar__group">
255
+ <label class="field">
256
+ <span class="field__label">${translate(this.sortLabel)}</span>
257
+ <select
258
+ id="sortSelect"
259
+ class="field__select"
260
+ @change="${this._sort}"
261
+ .value=${this.sortBy || ''}
262
+ >
263
+ ${this.sortOptions.map(
264
+ option => html`<option value="${option.value}">${translate(option.label)}</option>`,
265
+ )}
266
+ </select>
267
+ </label>
268
+ </div>
269
+ <div class="toolbar__group toolbar__group--filter">
270
+ <label class="field">
271
+ <span class="field__label">${translate(this.filterByLabel)}</span>
272
+ <select
273
+ id="filterSelect"
274
+ class="field__select"
275
+ @change="${this._filterChanged}"
276
+ .value=${this.filterBy || ''}
277
+ >
278
+ ${this.filterOptions.map(
279
+ option => html`<option value="${option.value}">${translate(option.label)}</option>`,
280
+ )}
281
+ </select>
282
+ </label>
283
+ <div class="filter-control">
284
+ <pb-autocomplete
285
+ id="filterString"
286
+ class="filter-control__input"
287
+ name="filter"
288
+ .value=${this.filter || ''}
289
+ placeholder="${translate(this.filterPlaceholderLabel)}"
290
+ icon="search"
291
+ @keydown=${this._handleEnter}
292
+ ></pb-autocomplete>
293
+ <button
294
+ class="pb-button pb-button--icon filter-control__submit"
295
+ type="button"
296
+ @click=${this._filter}
297
+ aria-label="${translate('browse.filter')}"
298
+ title="${translate('browse.filter')}"
299
+ >
300
+ <pb-icon icon="search" decorative></pb-icon>
301
+ </button>
302
+ </div>
303
+ </div>
304
+ </div>
305
+ <div class="toolbar toolbar--secondary">
306
+ <slot name="toolbar"></slot>
307
+ <button
308
+ id="delete"
309
+ part="delete-button"
310
+ type="button"
311
+ class="pb-button pb-button--text ${this._canModify(this._allowModification)}"
312
+ title="${translate('browse.delete')}"
313
+ >
314
+ <pb-icon icon="delete" decorative></pb-icon>
315
+ <span class="label">${translate('browse.delete')}</span>
316
+ </button>
317
+ </div>
318
+ <slot></slot>
319
+ <slot name="footer"></slot>
320
+
321
+ <pb-fetch
322
+ id="loadContent"
323
+ verbose
324
+ handle-as="text"
325
+ method="get"
326
+ with-credentials
327
+ @response="${this._handleContent}"
328
+ @error="${this._handleError}"
329
+ ></pb-fetch>
330
+ <pb-dialog id="deleteDialog" title="${translate('browse.delete')}">
331
+ <p>
332
+ ${translate('browse.confirmDeletion', {
333
+ count: this._selected ? this._selected.length : 0,
334
+ })}
335
+ </p>
336
+ <div slot="footer" class="buttons">
337
+ <button
338
+ class="pb-button pb-button--text"
339
+ type="button"
340
+ autofocus
341
+ @click="${this._confirmDelete}"
342
+ >
343
+ ${translate('dialogs.yes')}
344
+ </button>
345
+ <button class="pb-button pb-button--text" type="button" rel="prev">
346
+ ${translate('dialogs.no')}
347
+ </button>
348
+ </div>
349
+ </pb-dialog>
350
+ <pb-dialog id="errorDialog" title="${translate('dialogs.error')}">
351
+ <p id="errorMessage"></p>
352
+ <div slot="footer">
353
+ <button class="pb-button pb-button--text" type="button" rel="prev">
354
+ ${translate('dialogs.close')}
355
+ </button>
356
+ </div>
357
+ </pb-dialog>
358
+ `;
359
+ }
360
+
361
+ static get styles() {
362
+ return css`
363
+ :host {
364
+ display: block;
365
+ }
366
+
367
+ .toolbar {
368
+ display: flex;
369
+ flex-wrap: wrap;
370
+ gap: 1rem;
371
+ align-items: flex-end;
372
+ justify-content: var(--pb-browse-toolbar-justify-content, space-between);
373
+ margin-bottom: 1rem;
374
+ }
375
+
376
+ .toolbar--secondary {
377
+ align-items: center;
378
+ }
379
+
380
+ .toolbar__group {
381
+ display: flex;
382
+ align-items: flex-end;
383
+ flex-wrap: wrap;
384
+ gap: 1rem;
385
+ }
386
+
387
+ .toolbar__group--filter {
388
+ flex: 1 1 320px;
389
+ justify-content: flex-end;
390
+ }
391
+
392
+ .field {
393
+ display: flex;
394
+ flex-direction: column;
395
+ gap: 0.35rem;
396
+ min-width: 160px;
397
+ }
398
+
399
+ .field__label {
400
+ font-size: 0.8rem;
401
+ font-weight: 600;
402
+ letter-spacing: 0.05em;
403
+ text-transform: uppercase;
404
+ color: rgba(0, 0, 0, 0.6);
405
+ }
406
+
407
+ .field__select {
408
+ appearance: none;
409
+ min-width: 160px;
410
+ padding: 0.45rem 2.25rem 0.45rem 0.75rem;
411
+ border-radius: 8px;
412
+ border: 1px solid rgba(0, 0, 0, 0.16);
413
+ background-image: linear-gradient(45deg, transparent 50%, rgba(0, 0, 0, 0.5) 50%),
414
+ linear-gradient(135deg, rgba(0, 0, 0, 0.5) 50%, transparent 50%),
415
+ linear-gradient(to right, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.1));
416
+ background-position: calc(100% - 18px) calc(1em + 2px), calc(100% - 13px) calc(1em + 2px),
417
+ calc(100% - 2.5rem) 0.5em;
418
+ background-size: 5px 5px, 5px 5px, 1px 2.25em;
419
+ background-repeat: no-repeat;
420
+ font: inherit;
421
+ color: inherit;
422
+ line-height: 1.2;
423
+ }
424
+
425
+ .field__select:focus {
426
+ outline: none;
427
+ border-color: #1976d2;
428
+ box-shadow: 0 0 0 3px rgba(25, 118, 210, 0.16);
429
+ }
430
+
431
+ .filter-control {
432
+ display: inline-flex;
433
+ align-items: center;
434
+ gap: 0.5rem;
435
+ flex: 1 1 280px;
436
+ }
437
+
438
+ .filter-control__input {
439
+ flex: 1 1 auto;
440
+ }
441
+
442
+ .filter-control__submit {
443
+ margin-bottom: 4px;
444
+ }
445
+
446
+ .filter-control__submit pb-icon {
447
+ --pb-icon-size: 1.25rem;
448
+ }
449
+
450
+ [name='toolbar'] {
451
+ flex: 1 0;
452
+ }
453
+
454
+ .hidden {
455
+ display: none !important;
456
+ }
457
+ `;
458
+ }
459
+
460
+ getURL(params) {
461
+ if (this.static) {
462
+ // use a static URL
463
+ return `collections/${this.collection ? `${this.collection}/` : ''}${
464
+ params.start || '1'
465
+ }.html`;
361
466
  }
362
-
363
- prepareParameters(params) {
364
- params = this._paramsFromSubforms(params);
365
- params.sort = this.sortBy;
366
- if (this.filter) {
367
- params.filter = this.filter;
368
- params.browse = this.filterBy;
369
- }
370
- if (this.facets) {
371
- params = Object.assign(params, this.facets);
372
- }
373
- return params;
467
+ const url = super.getURL(params);
468
+ return this.collection ? `${url}/${this.collection}` : url;
469
+ }
470
+
471
+ prepareParameters(params) {
472
+ params = this._paramsFromSubforms(params);
473
+ params.sort = this.sortBy;
474
+ if (this.filter) {
475
+ params.filter = this.filter;
476
+ params.browse = this.filterBy;
374
477
  }
375
-
376
- _paramsFromSubforms(params) {
377
- if (this.subforms) {
378
- document.querySelectorAll(this.subforms).forEach((form) => {
379
- if (form.serializeForm) {
380
- Object.assign(params, form.serializeForm());
381
- }
382
- });
383
- }
384
- return params;
478
+ if (this.facets) {
479
+ params = Object.assign(params, this.facets);
385
480
  }
386
-
387
- /**
388
- * returns selected documents.
389
- *
390
- * @returns {Array}
391
- */
392
- getSelected() {
393
- const selected = [];
394
- if (this.container) {
395
- document.querySelectorAll(this.container).forEach((container) =>
396
- container.querySelectorAll('.document-select paper-checkbox[checked]').forEach((checkbox) => {
397
- selected.push(checkbox.value);
398
- })
399
- );
400
- } else {
401
- this.querySelectorAll('.document-select paper-checkbox[checked]').forEach((checkbox) => {
402
- selected.push(checkbox.value);
403
- });
481
+ return params;
482
+ }
483
+
484
+ _paramsFromSubforms(params) {
485
+ if (this.subforms) {
486
+ document.querySelectorAll(this.subforms).forEach(form => {
487
+ if (form.serializeForm) {
488
+ Object.assign(params, form.serializeForm());
404
489
  }
405
- return selected;
490
+ });
406
491
  }
407
-
408
- _filter() {
409
- const filter = this.shadowRoot.getElementById('filterString').value;
410
- const filterBy = this.shadowRoot.getElementById('filter-list').selected;
411
- if (typeof filter !== 'undefined') {
412
- console.log('<pb-browse-docs> Filter by %s', filter);
413
- this.filter = filter;
414
- registry.commit(this, { filter, filterBy })
415
- this.load();
416
- }
492
+ return params;
493
+ }
494
+
495
+ /**
496
+ * returns selected documents.
497
+ *
498
+ * @returns {Array}
499
+ */
500
+ getSelected() {
501
+ const selected = [];
502
+ if (this.container) {
503
+ document.querySelectorAll(this.container).forEach(container =>
504
+ container
505
+ .querySelectorAll('.document-select input[type="checkbox"]:checked')
506
+ .forEach(checkbox => {
507
+ selected.push(checkbox.value);
508
+ }),
509
+ );
510
+ } else {
511
+ this.querySelectorAll('.document-select input[type="checkbox"]:checked').forEach(checkbox => {
512
+ selected.push(checkbox.value);
513
+ });
417
514
  }
418
-
419
- _filterChanged() {
420
- const filterBy = this.shadowRoot.getElementById('filter-list').selected;
421
- if (filterBy && filterBy !== this.filterBy) {
422
- console.log('<pb-browse-docs> Filtering on %s', filterBy);
423
- this.filterBy = filterBy;
424
- }
515
+ return selected;
516
+ }
517
+
518
+ _filter() {
519
+ const filterInput = this.shadowRoot.getElementById('filterString');
520
+ const filterSelect = this.shadowRoot.getElementById('filterSelect');
521
+ const filter = filterInput ? filterInput.value : this.filter;
522
+ const filterBy = filterSelect ? filterSelect.value : this.filterBy;
523
+ if (typeof filter !== 'undefined') {
524
+ console.log('<pb-browse-docs> Filter by %s', filter);
525
+ this.filter = filter;
526
+ registry.commit(this, { filter, filterBy });
527
+ this.load();
425
528
  }
426
-
427
- _sort() {
428
- const sortBy = this.shadowRoot.getElementById('sort-list').selected;
429
- if (sortBy && sortBy !== this.sortBy) {
430
- console.log('<pb-browse-docs> Sorting by %s', sortBy);
431
- this.sortBy = sortBy;
432
- registry.commit(this, { sort: sortBy })
433
-
434
- this.load();
435
- }
529
+ }
530
+
531
+ _filterChanged(ev) {
532
+ const filterSelect = ev?.target ?? this.shadowRoot.getElementById('filterSelect');
533
+ const filterBy = filterSelect ? filterSelect.value : null;
534
+ if (filterBy && filterBy !== this.filterBy) {
535
+ console.log('<pb-browse-docs> Filtering on %s', filterBy);
536
+ this.filterBy = filterBy;
537
+ const autocomplete = this.shadowRoot.getElementById('filterString');
538
+ if (autocomplete) {
539
+ autocomplete.requestParams = { field: this.filterBy };
540
+ }
436
541
  }
542
+ }
437
543
 
438
- _facets(ev) {
439
- if (ev.detail && ev.detail.params) {
440
- registry.clearParametersMatching(this, /^(all-|facet-).*/);
441
- this.facets = ev.detail.params;
442
- this.start = 1;
443
- registry.commit(this, ev.detail.params)
444
- }
445
- this.load();
446
- }
544
+ _sort(ev) {
545
+ const sortSelect = ev?.target ?? this.shadowRoot.getElementById('sortSelect');
546
+ const sortBy = sortSelect ? sortSelect.value : null;
547
+ if (sortBy && sortBy !== this.sortBy) {
548
+ console.log('<pb-browse-docs> Sorting by %s', sortBy);
549
+ this.sortBy = sortBy;
550
+ registry.commit(this, { sort: sortBy });
447
551
 
448
- _onLoad(content) {
449
- window.scrollTo(0, 0);
450
- const div = content.querySelector('[data-root]');
451
- const collection = div && div.getAttribute('data-root');
452
- const writable = div && div.classList.contains('writable');
453
- this.emitTo('pb-collection', {
454
- writable,
455
- collection
456
- });
457
- document.querySelectorAll('[can-write]').forEach((elem) => {
458
- elem.disabled = !writable;
459
- });
460
- content.querySelectorAll('[data-collection]').forEach(link => {
461
- link.addEventListener('click', (ev) => {
462
- ev.preventDefault();
463
- this.collection = link.getAttribute('data-collection');
464
- this.start = 1;
465
- registry.commit(this, { collection: this.collection });
466
- console.log('<pb-browse-docs> loading collection %s', this.collection);
467
- this.load();
468
- });
469
- });
552
+ this.load();
470
553
  }
471
-
472
- _handleDelete(target, ev) {
473
- const deleteDialog = this.shadowRoot.getElementById('deleteDialog');
474
- const selected = this.getSelected();
475
- if (selected.length > 0) {
476
- this._selected = selected;
477
- deleteDialog.open();
478
- }
554
+ }
555
+
556
+ _facets(ev) {
557
+ if (ev.detail && ev.detail.params) {
558
+ registry.clearParametersMatching(this, /^(all-|facet-).*/);
559
+ this.facets = ev.detail.params;
560
+ this.start = 1;
561
+ registry.commit(this, ev.detail.params);
479
562
  }
480
-
481
- _confirmDelete() {
482
- if (!(this._file || this._selected)) {
483
- return;
484
- }
485
-
486
- let files;
487
- if (this._selected) {
488
- files = this._selected;
489
- } else {
490
- files = [this._file];
491
- }
492
- console.log('<pb-browse-docs> Deleting %o', this._file);
493
- const params = {
494
- action: 'delete',
495
- 'docs[]': files
496
- };
497
- this._file = null;
498
- this._selected = null;
499
- this.load(params);
563
+ this.load();
564
+ }
565
+
566
+ _onLoad(content) {
567
+ window.scrollTo(0, 0);
568
+ const div = content.querySelector('[data-root]');
569
+ const collection = div && div.getAttribute('data-root');
570
+ const writable = div && div.classList.contains('writable');
571
+ this.emitTo('pb-collection', {
572
+ writable,
573
+ collection,
574
+ });
575
+ document.querySelectorAll('[can-write]').forEach(elem => {
576
+ elem.disabled = !writable;
577
+ });
578
+ content.querySelectorAll('[data-collection]').forEach(link => {
579
+ link.addEventListener('click', ev => {
580
+ ev.preventDefault();
581
+ this.collection = link.getAttribute('data-collection');
582
+ this.start = 1;
583
+ registry.commit(this, { collection: this.collection });
584
+ console.log('<pb-browse-docs> loading collection %s', this.collection);
585
+ this.load();
586
+ });
587
+ });
588
+ }
589
+
590
+ _handleDelete(target, ev) {
591
+ const deleteDialog = this.shadowRoot.getElementById('deleteDialog');
592
+ const selected = this.getSelected();
593
+ if (selected.length > 0) {
594
+ this._selected = selected;
595
+ deleteDialog.openDialog();
500
596
  }
597
+ }
501
598
 
502
- _loggedIn(user, groups) {
503
- if (user == null) {
504
- return false;
505
- }
506
- if (this.group) {
507
- if (!groups) {
508
- return false;
509
- }
510
- return groups.indexOf(this.group) > -1;
511
- }
512
- return true;
599
+ _confirmDelete() {
600
+ if (!(this._file || this._selected)) {
601
+ return;
513
602
  }
514
603
 
515
- _canModify(allowModification) {
516
- return allowModification ? '' : 'hidden';
604
+ let files;
605
+ if (this._selected) {
606
+ files = this._selected;
607
+ } else {
608
+ files = [this._file];
517
609
  }
518
-
519
- _autocomplete(ev) {
520
- const autocompleteLoader = this.shadowRoot.getElementById('autocompleteLoader');
521
- autocompleteLoader.params = {
522
- query: ev.detail.option.text,
523
- field: this.filterBy
524
- };
525
- autocompleteLoader.generateRequest();
610
+ console.log('<pb-browse-docs> Deleting %o', this._file);
611
+ const params = {
612
+ action: 'delete',
613
+ 'docs[]': files,
614
+ };
615
+ this._file = null;
616
+ this._selected = null;
617
+ this.load(params);
618
+ }
619
+
620
+ _loggedIn(user, groups) {
621
+ if (user == null) {
622
+ return false;
526
623
  }
527
-
528
- _updateSuggestions() {
529
- const autocomplete = this.shadowRoot.getElementById('autocomplete');
530
- const autocompleteLoader = this.shadowRoot.getElementById('autocompleteLoader');
531
- autocomplete.suggestions(autocompleteLoader.lastResponse);
624
+ if (this.group) {
625
+ if (!groups) {
626
+ return false;
627
+ }
628
+ return groups.indexOf(this.group) > -1;
532
629
  }
533
-
534
- _handleEnter(e) {
535
- if (e.keyCode === 13) {
536
- this._filter();
537
- }
630
+ return true;
631
+ }
632
+
633
+ _canModify(allowModification) {
634
+ return allowModification ? '' : 'hidden';
635
+ }
636
+
637
+ _handleAutocompleteInput(ev) {
638
+ const detail = ev.detail || {};
639
+ const value = detail.value ?? detail.text ?? '';
640
+ this.filter = value;
641
+ }
642
+
643
+ _handleAutocompleteSelected(ev) {
644
+ const detail = ev.detail || {};
645
+ const value = detail.value ?? detail.text ?? '';
646
+ this.filter = value;
647
+ this._filter();
648
+ }
649
+
650
+ _handleEnter(e) {
651
+ const key = e.key || e.code || e.keyCode;
652
+ if (key === 'Enter' || key === 'NumpadEnter' || key === 13) {
653
+ this._filter();
538
654
  }
655
+ }
539
656
  }
540
- customElements.define('pb-browse-docs', PbBrowseDocs);
657
+ customElements.define('pb-browse-docs', PbBrowseDocs);