@internetarchive/collection-browser 1.13.0-alpha2 → 1.14.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/.editorconfig +29 -29
- package/.github/workflows/ci.yml +26 -26
- package/.github/workflows/gh-pages-main.yml +39 -39
- package/.github/workflows/npm-publish.yml +39 -39
- package/.github/workflows/pr-preview.yml +38 -38
- package/.husky/pre-commit +4 -4
- package/LICENSE +661 -661
- package/README.md +83 -83
- package/dist/index.d.ts +9 -9
- package/dist/index.js +9 -9
- package/dist/src/app-root.d.ts +64 -54
- package/dist/src/app-root.js +320 -293
- package/dist/src/app-root.js.map +1 -1
- package/dist/src/assets/img/icons/arrow-left.d.ts +2 -2
- package/dist/src/assets/img/icons/arrow-left.js +2 -2
- package/dist/src/assets/img/icons/arrow-right.d.ts +2 -2
- package/dist/src/assets/img/icons/arrow-right.js +2 -2
- package/dist/src/assets/img/icons/chevron.d.ts +2 -2
- package/dist/src/assets/img/icons/chevron.js +2 -2
- package/dist/src/assets/img/icons/contract.d.ts +2 -2
- package/dist/src/assets/img/icons/contract.js +2 -2
- package/dist/src/assets/img/icons/empty-query.d.ts +2 -2
- package/dist/src/assets/img/icons/empty-query.js +2 -2
- package/dist/src/assets/img/icons/expand.d.ts +2 -2
- package/dist/src/assets/img/icons/expand.js +2 -2
- package/dist/src/assets/img/icons/eye-closed.d.ts +2 -2
- package/dist/src/assets/img/icons/eye-closed.js +2 -2
- package/dist/src/assets/img/icons/eye.d.ts +2 -2
- package/dist/src/assets/img/icons/eye.js +2 -2
- package/dist/src/assets/img/icons/favorite-filled.d.ts +1 -1
- package/dist/src/assets/img/icons/favorite-filled.js +2 -2
- package/dist/src/assets/img/icons/login-required.d.ts +1 -1
- package/dist/src/assets/img/icons/login-required.js +2 -2
- package/dist/src/assets/img/icons/mediatype/account.d.ts +1 -1
- package/dist/src/assets/img/icons/mediatype/account.js +2 -2
- package/dist/src/assets/img/icons/mediatype/audio.d.ts +1 -1
- package/dist/src/assets/img/icons/mediatype/audio.js +2 -2
- package/dist/src/assets/img/icons/mediatype/collection.d.ts +1 -1
- package/dist/src/assets/img/icons/mediatype/collection.js +2 -2
- package/dist/src/assets/img/icons/mediatype/data.d.ts +1 -1
- package/dist/src/assets/img/icons/mediatype/data.js +2 -2
- package/dist/src/assets/img/icons/mediatype/etree.d.ts +1 -1
- package/dist/src/assets/img/icons/mediatype/etree.js +2 -2
- package/dist/src/assets/img/icons/mediatype/film.d.ts +1 -1
- package/dist/src/assets/img/icons/mediatype/film.js +2 -2
- package/dist/src/assets/img/icons/mediatype/images.d.ts +1 -1
- package/dist/src/assets/img/icons/mediatype/images.js +2 -2
- package/dist/src/assets/img/icons/mediatype/radio.d.ts +1 -1
- package/dist/src/assets/img/icons/mediatype/radio.js +2 -2
- package/dist/src/assets/img/icons/mediatype/software.d.ts +1 -1
- package/dist/src/assets/img/icons/mediatype/software.js +2 -2
- package/dist/src/assets/img/icons/mediatype/texts.d.ts +1 -1
- package/dist/src/assets/img/icons/mediatype/texts.js +2 -2
- package/dist/src/assets/img/icons/mediatype/tv.d.ts +1 -1
- package/dist/src/assets/img/icons/mediatype/tv.js +2 -2
- package/dist/src/assets/img/icons/mediatype/video.d.ts +1 -1
- package/dist/src/assets/img/icons/mediatype/video.js +2 -2
- package/dist/src/assets/img/icons/mediatype/web.d.ts +1 -1
- package/dist/src/assets/img/icons/mediatype/web.js +2 -2
- package/dist/src/assets/img/icons/null-result.d.ts +2 -2
- package/dist/src/assets/img/icons/null-result.js +2 -2
- package/dist/src/assets/img/icons/restricted.d.ts +1 -1
- package/dist/src/assets/img/icons/restricted.js +2 -2
- package/dist/src/assets/img/icons/reviews.d.ts +1 -1
- package/dist/src/assets/img/icons/reviews.js +2 -2
- package/dist/src/assets/img/icons/upload.d.ts +1 -1
- package/dist/src/assets/img/icons/upload.js +2 -2
- package/dist/src/assets/img/icons/views.d.ts +1 -1
- package/dist/src/assets/img/icons/views.js +2 -2
- package/dist/src/circular-activity-indicator.d.ts +5 -5
- package/dist/src/circular-activity-indicator.js +17 -17
- package/dist/src/collection-browser.d.ts +522 -473
- package/dist/src/collection-browser.js +1846 -1697
- package/dist/src/collection-browser.js.map +1 -1
- package/dist/src/collection-facets/facet-tombstone-row.d.ts +5 -5
- package/dist/src/collection-facets/facet-tombstone-row.js +15 -15
- package/dist/src/collection-facets/facets-template.d.ts +20 -20
- package/dist/src/collection-facets/facets-template.js +152 -152
- package/dist/src/collection-facets/more-facets-content.d.ts +77 -77
- package/dist/src/collection-facets/more-facets-content.js +359 -359
- package/dist/src/collection-facets/more-facets-pagination.d.ts +36 -36
- package/dist/src/collection-facets/more-facets-pagination.js +196 -196
- package/dist/src/collection-facets/toggle-switch.d.ts +41 -41
- package/dist/src/collection-facets/toggle-switch.js +94 -94
- package/dist/src/collection-facets.d.ts +104 -103
- package/dist/src/collection-facets.js +511 -498
- package/dist/src/collection-facets.js.map +1 -1
- package/dist/src/empty-placeholder.d.ts +23 -23
- package/dist/src/empty-placeholder.js +74 -74
- package/dist/src/expanded-date-picker.d.ts +43 -43
- package/dist/src/expanded-date-picker.js +109 -109
- package/dist/src/language-code-handler/language-code-handler.d.ts +37 -37
- package/dist/src/language-code-handler/language-code-handler.js +26 -26
- package/dist/src/language-code-handler/language-code-mapping.d.ts +1 -1
- package/dist/src/language-code-handler/language-code-mapping.js +562 -562
- package/dist/src/manage/manage-bar.d.ts +26 -0
- package/dist/src/manage/manage-bar.js +147 -0
- package/dist/src/manage/manage-bar.js.map +1 -0
- package/dist/src/mediatype/mediatype-config.d.ts +3 -3
- package/dist/src/mediatype/mediatype-config.js +85 -85
- package/dist/src/models.d.ts +164 -163
- package/dist/src/models.js +269 -269
- package/dist/src/models.js.map +1 -1
- package/dist/src/restoration-state-handler.d.ts +70 -70
- package/dist/src/restoration-state-handler.js +355 -355
- package/dist/src/sort-filter-bar/alpha-bar-tooltip.d.ts +6 -6
- package/dist/src/sort-filter-bar/alpha-bar-tooltip.js +24 -24
- package/dist/src/sort-filter-bar/alpha-bar.d.ts +21 -21
- package/dist/src/sort-filter-bar/alpha-bar.js +128 -128
- package/dist/src/sort-filter-bar/img/compact.d.ts +1 -1
- package/dist/src/sort-filter-bar/img/compact.js +2 -2
- package/dist/src/sort-filter-bar/img/list.d.ts +1 -1
- package/dist/src/sort-filter-bar/img/list.js +2 -2
- package/dist/src/sort-filter-bar/img/sort-toggle-disabled.d.ts +1 -1
- package/dist/src/sort-filter-bar/img/sort-toggle-disabled.js +2 -2
- package/dist/src/sort-filter-bar/img/sort-toggle-down.d.ts +1 -1
- package/dist/src/sort-filter-bar/img/sort-toggle-down.js +2 -2
- package/dist/src/sort-filter-bar/img/sort-toggle-up.d.ts +1 -1
- package/dist/src/sort-filter-bar/img/sort-toggle-up.js +2 -2
- package/dist/src/sort-filter-bar/img/sort-triangle.d.ts +1 -1
- package/dist/src/sort-filter-bar/img/sort-triangle.js +2 -2
- package/dist/src/sort-filter-bar/img/tile.d.ts +1 -1
- package/dist/src/sort-filter-bar/img/tile.js +2 -2
- package/dist/src/sort-filter-bar/sort-filter-bar.d.ts +208 -208
- package/dist/src/sort-filter-bar/sort-filter-bar.js +637 -637
- package/dist/src/styles/item-image-styles.d.ts +8 -8
- package/dist/src/styles/item-image-styles.js +9 -9
- package/dist/src/styles/sr-only.d.ts +1 -1
- package/dist/src/styles/sr-only.js +2 -2
- package/dist/src/tiles/base-tile-component.d.ts +18 -18
- package/dist/src/tiles/base-tile-component.js +59 -59
- package/dist/src/tiles/collection-browser-loading-tile.d.ts +5 -5
- package/dist/src/tiles/collection-browser-loading-tile.js +15 -15
- package/dist/src/tiles/grid/account-tile.d.ts +18 -18
- package/dist/src/tiles/grid/account-tile.js +72 -72
- package/dist/src/tiles/grid/collection-tile.d.ts +15 -15
- package/dist/src/tiles/grid/collection-tile.js +80 -80
- package/dist/src/tiles/grid/item-tile.d.ts +27 -27
- package/dist/src/tiles/grid/item-tile.js +134 -134
- package/dist/src/tiles/grid/styles/tile-grid-shared-styles.d.ts +1 -1
- package/dist/src/tiles/grid/styles/tile-grid-shared-styles.js +8 -8
- package/dist/src/tiles/grid/tile-stats.d.ts +11 -11
- package/dist/src/tiles/grid/tile-stats.js +48 -48
- package/dist/src/tiles/hover/hover-pane-controller.d.ts +219 -219
- package/dist/src/tiles/hover/hover-pane-controller.js +352 -352
- package/dist/src/tiles/hover/tile-hover-pane.d.ts +15 -15
- package/dist/src/tiles/hover/tile-hover-pane.js +38 -38
- package/dist/src/tiles/image-block.d.ts +17 -17
- package/dist/src/tiles/image-block.js +72 -72
- package/dist/src/tiles/item-image.d.ts +35 -35
- package/dist/src/tiles/item-image.js +117 -117
- package/dist/src/tiles/list/tile-list-compact-header.d.ts +6 -6
- package/dist/src/tiles/list/tile-list-compact-header.js +38 -38
- package/dist/src/tiles/list/tile-list-compact.d.ts +15 -15
- package/dist/src/tiles/list/tile-list-compact.js +114 -114
- package/dist/src/tiles/list/tile-list.d.ts +46 -46
- package/dist/src/tiles/list/tile-list.js +298 -298
- package/dist/src/tiles/mediatype-icon.d.ts +9 -9
- package/dist/src/tiles/mediatype-icon.js +47 -47
- package/dist/src/tiles/overlay/icon-overlay.d.ts +10 -10
- package/dist/src/tiles/overlay/icon-overlay.js +40 -40
- package/dist/src/tiles/overlay/icon-text-overlay.d.ts +9 -9
- package/dist/src/tiles/overlay/icon-text-overlay.js +38 -38
- package/dist/src/tiles/overlay/text-overlay.d.ts +10 -10
- package/dist/src/tiles/overlay/text-overlay.js +42 -42
- package/dist/src/tiles/text-snippet-block.d.ts +27 -27
- package/dist/src/tiles/text-snippet-block.js +73 -73
- package/dist/src/tiles/tile-dispatcher.d.ts +63 -50
- package/dist/src/tiles/tile-dispatcher.js +255 -187
- package/dist/src/tiles/tile-dispatcher.js.map +1 -1
- package/dist/src/tiles/tile-display-value-provider.d.ts +43 -43
- package/dist/src/tiles/tile-display-value-provider.js +80 -80
- package/dist/src/utils/analytics-events.d.ts +25 -25
- package/dist/src/utils/analytics-events.js +27 -27
- package/dist/src/utils/array-equals.d.ts +4 -4
- package/dist/src/utils/array-equals.js +10 -10
- package/dist/src/utils/format-count.d.ts +7 -7
- package/dist/src/utils/format-count.js +76 -76
- package/dist/src/utils/format-date.d.ts +2 -2
- package/dist/src/utils/format-date.js +25 -25
- package/dist/src/utils/format-unit-size.d.ts +2 -2
- package/dist/src/utils/format-unit-size.js +33 -33
- package/dist/src/utils/local-date-from-utc.d.ts +9 -9
- package/dist/src/utils/local-date-from-utc.js +15 -15
- package/dist/src/utils/sha1.d.ts +2 -2
- package/dist/src/utils/sha1.js +8 -8
- package/dist/test/collection-browser.test.d.ts +1 -1
- package/dist/test/collection-browser.test.js +1122 -979
- package/dist/test/collection-browser.test.js.map +1 -1
- package/dist/test/collection-facets/facets-template.test.d.ts +1 -1
- package/dist/test/collection-facets/facets-template.test.js +134 -134
- package/dist/test/collection-facets/more-facets-content.test.d.ts +1 -1
- package/dist/test/collection-facets/more-facets-content.test.js +133 -133
- package/dist/test/collection-facets/more-facets-pagination.test.d.ts +1 -1
- package/dist/test/collection-facets/more-facets-pagination.test.js +117 -117
- package/dist/test/collection-facets/toggle-switch.test.d.ts +1 -1
- package/dist/test/collection-facets/toggle-switch.test.js +73 -73
- package/dist/test/collection-facets.test.d.ts +2 -2
- package/dist/test/collection-facets.test.js +682 -682
- package/dist/test/empty-placeholder.test.d.ts +1 -1
- package/dist/test/empty-placeholder.test.js +63 -63
- package/dist/test/expanded-date-picker.test.d.ts +1 -1
- package/dist/test/expanded-date-picker.test.js +95 -95
- package/dist/test/icon-overlay.test.d.ts +1 -1
- package/dist/test/icon-overlay.test.js +24 -24
- package/dist/test/image-block.test.d.ts +1 -1
- package/dist/test/image-block.test.js +48 -48
- package/dist/test/item-image.test.d.ts +1 -1
- package/dist/test/item-image.test.js +86 -84
- package/dist/test/item-image.test.js.map +1 -1
- package/dist/test/manage/manage-bar.test.d.ts +1 -0
- package/dist/test/manage/manage-bar.test.js +73 -0
- package/dist/test/manage/manage-bar.test.js.map +1 -0
- package/dist/test/mediatype-config.test.d.ts +1 -1
- package/dist/test/mediatype-config.test.js +16 -16
- package/dist/test/mocks/mock-analytics-handler.d.ts +10 -10
- package/dist/test/mocks/mock-analytics-handler.js +15 -15
- package/dist/test/mocks/mock-collection-name-cache.d.ts +9 -9
- package/dist/test/mocks/mock-collection-name-cache.js +17 -17
- package/dist/test/mocks/mock-search-responses.d.ts +21 -21
- package/dist/test/mocks/mock-search-responses.js +709 -707
- package/dist/test/mocks/mock-search-responses.js.map +1 -1
- package/dist/test/mocks/mock-search-service.d.ts +15 -15
- package/dist/test/mocks/mock-search-service.js +50 -50
- package/dist/test/restoration-state-handler.test.d.ts +1 -1
- package/dist/test/restoration-state-handler.test.js +270 -270
- package/dist/test/sort-filter-bar/alpha-bar-tooltip.test.d.ts +1 -1
- package/dist/test/sort-filter-bar/alpha-bar-tooltip.test.js +12 -12
- package/dist/test/sort-filter-bar/alpha-bar.test.d.ts +1 -1
- package/dist/test/sort-filter-bar/alpha-bar.test.js +73 -73
- package/dist/test/sort-filter-bar/sort-filter-bar.test.d.ts +1 -1
- package/dist/test/sort-filter-bar/sort-filter-bar.test.js +378 -378
- package/dist/test/text-overlay.test.d.ts +1 -1
- package/dist/test/text-overlay.test.js +48 -48
- package/dist/test/text-snippet-block.test.d.ts +1 -1
- package/dist/test/text-snippet-block.test.js +57 -57
- package/dist/test/tile-stats.test.d.ts +1 -1
- package/dist/test/tile-stats.test.js +33 -33
- package/dist/test/tiles/grid/account-tile.test.d.ts +1 -1
- package/dist/test/tiles/grid/account-tile.test.js +76 -76
- package/dist/test/tiles/grid/collection-tile.test.d.ts +1 -1
- package/dist/test/tiles/grid/collection-tile.test.js +73 -73
- package/dist/test/tiles/grid/item-tile.test.d.ts +1 -1
- package/dist/test/tiles/grid/item-tile.test.js +254 -254
- package/dist/test/tiles/hover/hover-pane-controller.test.d.ts +1 -1
- package/dist/test/tiles/hover/hover-pane-controller.test.js +258 -257
- package/dist/test/tiles/hover/hover-pane-controller.test.js.map +1 -1
- package/dist/test/tiles/hover/tile-hover-pane.test.d.ts +1 -1
- package/dist/test/tiles/hover/tile-hover-pane.test.js +13 -13
- package/dist/test/tiles/list/tile-list-compact.test.d.ts +1 -1
- package/dist/test/tiles/list/tile-list-compact.test.js +143 -143
- package/dist/test/tiles/list/tile-list.test.d.ts +1 -1
- package/dist/test/tiles/list/tile-list.test.js +242 -242
- package/dist/test/tiles/tile-dispatcher.test.d.ts +1 -1
- package/dist/test/tiles/tile-dispatcher.test.js +107 -67
- package/dist/test/tiles/tile-dispatcher.test.js.map +1 -1
- package/dist/test/tiles/tile-display-value-provider.test.d.ts +1 -1
- package/dist/test/tiles/tile-display-value-provider.test.js +141 -141
- package/dist/test/utils/array-equals.test.d.ts +1 -1
- package/dist/test/utils/array-equals.test.js +26 -26
- package/dist/test/utils/format-count.test.d.ts +1 -1
- package/dist/test/utils/format-count.test.js +23 -23
- package/dist/test/utils/format-date.test.d.ts +1 -1
- package/dist/test/utils/format-date.test.js +17 -17
- package/dist/test/utils/format-unit-size.test.d.ts +1 -1
- package/dist/test/utils/format-unit-size.test.js +17 -17
- package/dist/test/utils/local-date-from-utc.test.d.ts +1 -1
- package/dist/test/utils/local-date-from-utc.test.js +26 -26
- package/local.archive.org.cert +86 -86
- package/local.archive.org.key +27 -27
- package/package.json +2 -2
- package/renovate.json +6 -6
- package/src/app-root.ts +29 -0
- package/src/collection-browser.ts +197 -23
- package/src/collection-facets.ts +13 -1
- package/src/manage/manage-bar.ts +151 -0
- package/src/models.ts +1 -0
- package/src/tiles/tile-dispatcher.ts +71 -5
- package/test/collection-browser.test.ts +198 -1
- package/test/item-image.test.ts +2 -0
- package/test/manage/manage-bar.test.ts +107 -0
- package/test/mocks/mock-search-responses.ts +2 -0
- package/test/tiles/hover/hover-pane-controller.test.ts +1 -0
- package/test/tiles/tile-dispatcher.test.ts +52 -0
- package/tsconfig.json +21 -21
- package/web-dev-server.config.mjs +30 -30
- package/web-test-runner.config.mjs +41 -41
|
@@ -41,9 +41,9 @@ import type { RecaptchaManagerInterface } from '@internetarchive/recaptcha-manag
|
|
|
41
41
|
import './tiles/tile-dispatcher';
|
|
42
42
|
import './tiles/collection-browser-loading-tile';
|
|
43
43
|
import './sort-filter-bar/sort-filter-bar';
|
|
44
|
+
import './manage/manage-bar';
|
|
44
45
|
import './collection-facets';
|
|
45
46
|
import './circular-activity-indicator';
|
|
46
|
-
import './sort-filter-bar/sort-filter-bar';
|
|
47
47
|
import {
|
|
48
48
|
SelectedFacets,
|
|
49
49
|
SortField,
|
|
@@ -75,6 +75,8 @@ import {
|
|
|
75
75
|
import { srOnlyStyle } from './styles/sr-only';
|
|
76
76
|
import { sha1 } from './utils/sha1';
|
|
77
77
|
import type { CollectionFacets } from './collection-facets';
|
|
78
|
+
import type { ManageableItem } from './manage/manage-bar';
|
|
79
|
+
import { formatDate } from './utils/format-date';
|
|
78
80
|
|
|
79
81
|
type RequestKind = 'full' | 'hits' | 'aggregations';
|
|
80
82
|
|
|
@@ -241,8 +243,9 @@ export class CollectionBrowser
|
|
|
241
243
|
private placeholderCellTemplate = html`<collection-browser-loading-tile></collection-browser-loading-tile>`;
|
|
242
244
|
|
|
243
245
|
private tileModelAtCellIndex(index: number): TileModel | undefined {
|
|
244
|
-
const
|
|
245
|
-
const
|
|
246
|
+
const offsetIndex = index + this.tileModelOffset;
|
|
247
|
+
const pageNumber = Math.floor(offsetIndex / this.pageSize) + 1;
|
|
248
|
+
const itemIndex = offsetIndex % this.pageSize;
|
|
246
249
|
const model = this.dataSource[pageNumber]?.[itemIndex];
|
|
247
250
|
/**
|
|
248
251
|
* If we encounter a model we don't have yet and we're not in the middle of an
|
|
@@ -279,6 +282,11 @@ export class CollectionBrowser
|
|
|
279
282
|
*/
|
|
280
283
|
private dataSource: Record<string, TileModel[]> = {};
|
|
281
284
|
|
|
285
|
+
/**
|
|
286
|
+
* How many tiles to offset the data source by, to account for any removed tiles.
|
|
287
|
+
*/
|
|
288
|
+
private tileModelOffset = 0;
|
|
289
|
+
|
|
282
290
|
@query('infinite-scroller')
|
|
283
291
|
private infiniteScroller!: InfiniteScroller;
|
|
284
292
|
|
|
@@ -531,7 +539,9 @@ export class CollectionBrowser
|
|
|
531
539
|
private get rightColumnTemplate(): TemplateResult {
|
|
532
540
|
return html`
|
|
533
541
|
<div id="right-column" class="column">
|
|
534
|
-
${this.
|
|
542
|
+
${this.isManageView
|
|
543
|
+
? this.manageBarTemplate
|
|
544
|
+
: this.sortFilterBarTemplate}
|
|
535
545
|
${this.displayMode === `list-compact`
|
|
536
546
|
? this.listHeaderTemplate
|
|
537
547
|
: nothing}
|
|
@@ -582,6 +592,153 @@ export class CollectionBrowser
|
|
|
582
592
|
`;
|
|
583
593
|
}
|
|
584
594
|
|
|
595
|
+
private get manageBarTemplate(): TemplateResult {
|
|
596
|
+
return html`
|
|
597
|
+
<manage-bar
|
|
598
|
+
showSelectAll
|
|
599
|
+
showUnselectAll
|
|
600
|
+
@removeItems=${this.handleRemoveItems}
|
|
601
|
+
@selectAll=${this.checkAllTiles}
|
|
602
|
+
@unselectAll=${this.uncheckAllTiles}
|
|
603
|
+
@cancel=${() => {
|
|
604
|
+
this.isManageView = false;
|
|
605
|
+
this.uncheckAllTiles();
|
|
606
|
+
}}
|
|
607
|
+
></manage-bar>
|
|
608
|
+
`;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
/**
|
|
612
|
+
* Handler for when the user requests to remove all checked items via the manage bar.
|
|
613
|
+
* Emits an `itemRemovalRequested` event with all checked tile models.
|
|
614
|
+
*/
|
|
615
|
+
private handleRemoveItems(): void {
|
|
616
|
+
this.dispatchEvent(
|
|
617
|
+
new CustomEvent<{ items: ManageableItem[] }>('itemRemovalRequested', {
|
|
618
|
+
detail: {
|
|
619
|
+
items: this.checkedTileModels.map(model => ({
|
|
620
|
+
...model,
|
|
621
|
+
date: formatDate(model.datePublished, 'long'),
|
|
622
|
+
})),
|
|
623
|
+
},
|
|
624
|
+
})
|
|
625
|
+
);
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
/**
|
|
629
|
+
* Removes all tile models that are currently checked & adjusts the paging
|
|
630
|
+
* of the data source to account for any new gaps in the data.
|
|
631
|
+
*/
|
|
632
|
+
removeCheckedTiles(): void {
|
|
633
|
+
// To make sure our data source remains page-aligned, we will offset our data source by
|
|
634
|
+
// the number of removed tiles, so that we can just add the offset when the infinite
|
|
635
|
+
// scroller queries for cell contents.
|
|
636
|
+
// This only matters while we're still viewing the same set of results. If the user changes
|
|
637
|
+
// their query/filters/sort, then the data source is overwritten and the offset cleared.
|
|
638
|
+
const { checkedTileModels, uncheckedTileModels } = this;
|
|
639
|
+
const numChecked = checkedTileModels.length;
|
|
640
|
+
if (numChecked === 0) return;
|
|
641
|
+
this.tileModelOffset += numChecked;
|
|
642
|
+
|
|
643
|
+
const newDataSource: typeof this.dataSource = {};
|
|
644
|
+
|
|
645
|
+
// Which page the remaining tile models start on, post-offset
|
|
646
|
+
let offsetPageNumber = Math.floor(this.tileModelOffset / this.pageSize) + 1;
|
|
647
|
+
let indexOnPage = this.tileModelOffset % this.pageSize;
|
|
648
|
+
|
|
649
|
+
// Fill the pages up to that point with empty models
|
|
650
|
+
for (let page = 1; page <= offsetPageNumber; page += 1) {
|
|
651
|
+
const remainingHidden = this.tileModelOffset - this.pageSize * (page - 1);
|
|
652
|
+
const offsetCellsOnPage = Math.min(this.pageSize, remainingHidden);
|
|
653
|
+
newDataSource[page] = Array(offsetCellsOnPage).fill(undefined);
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
// Shift all the remaining tiles into their new positions in the data source
|
|
657
|
+
for (const model of uncheckedTileModels) {
|
|
658
|
+
if (!newDataSource[offsetPageNumber])
|
|
659
|
+
newDataSource[offsetPageNumber] = [];
|
|
660
|
+
newDataSource[offsetPageNumber].push(model);
|
|
661
|
+
indexOnPage += 1;
|
|
662
|
+
if (indexOnPage >= this.pageSize) {
|
|
663
|
+
offsetPageNumber += 1;
|
|
664
|
+
indexOnPage = 0;
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
// Swap in the new data source and update the infinite scroller
|
|
669
|
+
this.dataSource = newDataSource;
|
|
670
|
+
if (this.totalResults) this.totalResults -= numChecked;
|
|
671
|
+
if (this.infiniteScroller) {
|
|
672
|
+
this.infiniteScroller.itemCount -= numChecked;
|
|
673
|
+
this.infiniteScroller.refreshAllVisibleCells();
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
/**
|
|
678
|
+
* Checks every tile's management checkbox
|
|
679
|
+
*/
|
|
680
|
+
checkAllTiles(): void {
|
|
681
|
+
this.mapDataSource(model => ({ ...model, checked: true }));
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
/**
|
|
685
|
+
* Unchecks every tile's management checkbox
|
|
686
|
+
*/
|
|
687
|
+
uncheckAllTiles(): void {
|
|
688
|
+
this.mapDataSource(model => ({ ...model, checked: false }));
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
/**
|
|
692
|
+
* Applies the given map function to all of the tile models in every page of the data
|
|
693
|
+
* source. This method updates the data source object in immutable fashion.
|
|
694
|
+
*
|
|
695
|
+
* @param mapFn A callback function to apply on each tile model, as with Array.map
|
|
696
|
+
*/
|
|
697
|
+
private mapDataSource(
|
|
698
|
+
mapFn: (model: TileModel, index: number, array: TileModel[]) => TileModel
|
|
699
|
+
): void {
|
|
700
|
+
this.dataSource = Object.fromEntries(
|
|
701
|
+
Object.entries(this.dataSource).map(([page, tileModels]) => [
|
|
702
|
+
page,
|
|
703
|
+
tileModels.map((model, index, array) =>
|
|
704
|
+
model ? mapFn(model, index, array) : model
|
|
705
|
+
),
|
|
706
|
+
])
|
|
707
|
+
);
|
|
708
|
+
this.infiniteScroller?.refreshAllVisibleCells();
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
/**
|
|
712
|
+
* An array of all the tile models whose management checkboxes are checked
|
|
713
|
+
*/
|
|
714
|
+
get checkedTileModels(): TileModel[] {
|
|
715
|
+
return this.getFilteredTileModels(model => model.checked);
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
/**
|
|
719
|
+
* An array of all the tile models whose management checkboxes are unchecked
|
|
720
|
+
*/
|
|
721
|
+
get uncheckedTileModels(): TileModel[] {
|
|
722
|
+
return this.getFilteredTileModels(model => !model.checked);
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
/**
|
|
726
|
+
* Returns a flattened, filtered array of all the tile models in the data source
|
|
727
|
+
* for which the given predicate returns a truthy value.
|
|
728
|
+
*
|
|
729
|
+
* @param predicate A callback function to apply on each tile model, as with Array.filter
|
|
730
|
+
* @returns A filtered array of tile models satisfying the predicate
|
|
731
|
+
*/
|
|
732
|
+
private getFilteredTileModels(
|
|
733
|
+
predicate: (model: TileModel, index: number, array: TileModel[]) => unknown
|
|
734
|
+
): TileModel[] {
|
|
735
|
+
return Object.values(this.dataSource)
|
|
736
|
+
.flat()
|
|
737
|
+
.filter((model, index, array) =>
|
|
738
|
+
model ? predicate(model, index, array) : false
|
|
739
|
+
);
|
|
740
|
+
}
|
|
741
|
+
|
|
585
742
|
private userChangedSort(
|
|
586
743
|
e: CustomEvent<{
|
|
587
744
|
selectedSort: SortField;
|
|
@@ -781,6 +938,7 @@ export class CollectionBrowser
|
|
|
781
938
|
.contentWidth=${this.contentWidth}
|
|
782
939
|
.query=${this.baseQuery}
|
|
783
940
|
.filterMap=${this.filterMap}
|
|
941
|
+
.isManageView=${this.isManageView}
|
|
784
942
|
.modalManager=${this.modalManager}
|
|
785
943
|
?collapsableFacets=${this.mobileView}
|
|
786
944
|
?facetsLoading=${this.facetsLoading}
|
|
@@ -869,6 +1027,17 @@ export class CollectionBrowser
|
|
|
869
1027
|
return `year:[${this.minSelectedDate} TO ${this.maxSelectedDate}]`;
|
|
870
1028
|
}
|
|
871
1029
|
|
|
1030
|
+
/**
|
|
1031
|
+
* Emits an event indicating a change in whether the manage mode is shown.
|
|
1032
|
+
*/
|
|
1033
|
+
private emitManageModeChangedEvent(): void {
|
|
1034
|
+
this.dispatchEvent(
|
|
1035
|
+
new CustomEvent<boolean>('manageModeChanged', {
|
|
1036
|
+
detail: this.isManageView,
|
|
1037
|
+
})
|
|
1038
|
+
);
|
|
1039
|
+
}
|
|
1040
|
+
|
|
872
1041
|
firstUpdated(): void {
|
|
873
1042
|
this.setupStateRestorationObserver();
|
|
874
1043
|
this.restoreState();
|
|
@@ -891,7 +1060,7 @@ export class CollectionBrowser
|
|
|
891
1060
|
changed.has('baseImageUrl') ||
|
|
892
1061
|
changed.has('loggedIn')
|
|
893
1062
|
) {
|
|
894
|
-
this.infiniteScroller?.
|
|
1063
|
+
this.infiniteScroller?.refreshAllVisibleCells();
|
|
895
1064
|
}
|
|
896
1065
|
|
|
897
1066
|
if (
|
|
@@ -1000,6 +1169,12 @@ export class CollectionBrowser
|
|
|
1000
1169
|
}
|
|
1001
1170
|
}
|
|
1002
1171
|
|
|
1172
|
+
if (changed.has('isManageView')) {
|
|
1173
|
+
if (this.isManageView) this.displayMode = 'grid';
|
|
1174
|
+
this.infiniteScroller?.refreshAllVisibleCells();
|
|
1175
|
+
this.emitManageModeChangedEvent();
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1003
1178
|
if (changed.has('resizeObserver')) {
|
|
1004
1179
|
const oldObserver = changed.get(
|
|
1005
1180
|
'resizeObserver'
|
|
@@ -1125,14 +1300,6 @@ export class CollectionBrowser
|
|
|
1125
1300
|
);
|
|
1126
1301
|
}
|
|
1127
1302
|
|
|
1128
|
-
private emitTabChanged(tabId: string) {
|
|
1129
|
-
this.dispatchEvent(
|
|
1130
|
-
new CustomEvent<String>('tabChanged', {
|
|
1131
|
-
detail: tabId,
|
|
1132
|
-
})
|
|
1133
|
-
);
|
|
1134
|
-
}
|
|
1135
|
-
|
|
1136
1303
|
private disconnectResizeObserver(
|
|
1137
1304
|
resizeObserver: SharedResizeObserverInterface
|
|
1138
1305
|
) {
|
|
@@ -1222,6 +1389,7 @@ export class CollectionBrowser
|
|
|
1222
1389
|
this.previousQueryKey = this.pageFetchQueryKey;
|
|
1223
1390
|
|
|
1224
1391
|
this.dataSource = {};
|
|
1392
|
+
this.tileModelOffset = 0;
|
|
1225
1393
|
this.totalResults = undefined;
|
|
1226
1394
|
this.aggregations = undefined;
|
|
1227
1395
|
this.fullYearsHistogramAggregation = undefined;
|
|
@@ -1654,7 +1822,7 @@ export class CollectionBrowser
|
|
|
1654
1822
|
// giving it 0.5s to finish.
|
|
1655
1823
|
setTimeout(() => {
|
|
1656
1824
|
this.isScrollingToCell = false;
|
|
1657
|
-
this.infiniteScroller?.
|
|
1825
|
+
this.infiniteScroller?.refreshAllVisibleCells();
|
|
1658
1826
|
resolve();
|
|
1659
1827
|
}, 500);
|
|
1660
1828
|
}, 0);
|
|
@@ -1810,12 +1978,7 @@ export class CollectionBrowser
|
|
|
1810
1978
|
return;
|
|
1811
1979
|
}
|
|
1812
1980
|
|
|
1813
|
-
this.totalResults = success.response.totalResults;
|
|
1814
|
-
|
|
1815
|
-
// switch tab to ?tab=about if this.totalResults is 0
|
|
1816
|
-
if (this.totalResults === 0) {
|
|
1817
|
-
this.emitTabChanged('about');
|
|
1818
|
-
}
|
|
1981
|
+
this.totalResults = success.response.totalResults - this.tileModelOffset;
|
|
1819
1982
|
|
|
1820
1983
|
if (this.withinCollection) {
|
|
1821
1984
|
this.collectionInfo = success.response.collectionExtraInfo;
|
|
@@ -1858,8 +2021,7 @@ export class CollectionBrowser
|
|
|
1858
2021
|
if (resultCountDiscrepancy > 0) {
|
|
1859
2022
|
this.endOfDataReached = true;
|
|
1860
2023
|
if (this.infiniteScroller) {
|
|
1861
|
-
this.infiniteScroller.itemCount =
|
|
1862
|
-
this.estimatedTileCount - resultCountDiscrepancy;
|
|
2024
|
+
this.infiniteScroller.itemCount = this.totalResults;
|
|
1863
2025
|
}
|
|
1864
2026
|
}
|
|
1865
2027
|
|
|
@@ -1975,6 +2137,7 @@ export class CollectionBrowser
|
|
|
1975
2137
|
|
|
1976
2138
|
tiles.push({
|
|
1977
2139
|
averageRating: result.avg_rating?.value,
|
|
2140
|
+
checked: false,
|
|
1978
2141
|
collections: result.collection?.values ?? [],
|
|
1979
2142
|
collectionFilesCount: result.collection_files_count?.value ?? 0,
|
|
1980
2143
|
collectionSize: result.collection_size?.value ?? 0,
|
|
@@ -2008,7 +2171,7 @@ export class CollectionBrowser
|
|
|
2008
2171
|
const visiblePages = this.currentVisiblePageNumbers;
|
|
2009
2172
|
const needsReload = visiblePages.includes(pageNumber);
|
|
2010
2173
|
if (needsReload) {
|
|
2011
|
-
this.infiniteScroller?.
|
|
2174
|
+
this.infiniteScroller?.refreshAllVisibleCells();
|
|
2012
2175
|
}
|
|
2013
2176
|
}
|
|
2014
2177
|
|
|
@@ -2116,6 +2279,16 @@ export class CollectionBrowser
|
|
|
2116
2279
|
* Callback when a result is selected
|
|
2117
2280
|
*/
|
|
2118
2281
|
resultSelected(event: CustomEvent<TileModel>): void {
|
|
2282
|
+
if (this.isManageView) {
|
|
2283
|
+
// Checked/unchecked state change -- rerender to ensure it propagates
|
|
2284
|
+
// this.mapDataSource(model => ({ ...model }));
|
|
2285
|
+
const cellIndex = Object.values(this.dataSource)
|
|
2286
|
+
.flat()
|
|
2287
|
+
.indexOf(event.detail);
|
|
2288
|
+
if (cellIndex >= 0)
|
|
2289
|
+
this.infiniteScroller?.refreshCell(cellIndex - this.tileModelOffset);
|
|
2290
|
+
}
|
|
2291
|
+
|
|
2119
2292
|
this.analyticsHandler?.sendEvent({
|
|
2120
2293
|
category: this.searchContext,
|
|
2121
2294
|
action: analyticsActions.resultSelected,
|
|
@@ -2146,6 +2319,7 @@ export class CollectionBrowser
|
|
|
2146
2319
|
.creatorFilter=${this.selectedCreatorFilter}
|
|
2147
2320
|
.mobileBreakpoint=${this.mobileBreakpoint}
|
|
2148
2321
|
.loggedIn=${this.loggedIn}
|
|
2322
|
+
.isManageView=${this.isManageView}
|
|
2149
2323
|
?enableHoverPane=${true}
|
|
2150
2324
|
@resultSelected=${(e: CustomEvent) => this.resultSelected(e)}
|
|
2151
2325
|
>
|
package/src/collection-facets.ts
CHANGED
|
@@ -11,6 +11,7 @@ import { customElement, property, state } from 'lit/decorators.js';
|
|
|
11
11
|
import { map } from 'lit/directives/map.js';
|
|
12
12
|
import { ref } from 'lit/directives/ref.js';
|
|
13
13
|
import { msg } from '@lit/localize';
|
|
14
|
+
import { classMap } from 'lit/directives/class-map.js';
|
|
14
15
|
import type {
|
|
15
16
|
Aggregation,
|
|
16
17
|
AggregationSortType,
|
|
@@ -99,6 +100,8 @@ export class CollectionFacets extends LitElement {
|
|
|
99
100
|
|
|
100
101
|
@property({ type: String }) collectionPagePath: string = '/details/';
|
|
101
102
|
|
|
103
|
+
@property({ type: Boolean }) isManageView = false;
|
|
104
|
+
|
|
102
105
|
@property({ type: Object, attribute: false })
|
|
103
106
|
modalManager?: ModalManagerInterface;
|
|
104
107
|
|
|
@@ -133,9 +136,14 @@ export class CollectionFacets extends LitElement {
|
|
|
133
136
|
private allowedFacetCount = 6;
|
|
134
137
|
|
|
135
138
|
render() {
|
|
139
|
+
const containerClasses = classMap({
|
|
140
|
+
loading: this.facetsLoading,
|
|
141
|
+
managing: this.isManageView,
|
|
142
|
+
});
|
|
143
|
+
|
|
136
144
|
const datePickerLabelId = 'date-picker-label';
|
|
137
145
|
return html`
|
|
138
|
-
<div id="container" class
|
|
146
|
+
<div id="container" class=${containerClasses}>
|
|
139
147
|
${this.showHistogramDatePicker &&
|
|
140
148
|
(this.fullYearsHistogramAggregation || this.fullYearAggregationLoading)
|
|
141
149
|
? html`
|
|
@@ -715,6 +723,10 @@ export class CollectionFacets extends LitElement {
|
|
|
715
723
|
opacity: 0.5;
|
|
716
724
|
}
|
|
717
725
|
|
|
726
|
+
#container.managing {
|
|
727
|
+
opacity: 0.3;
|
|
728
|
+
}
|
|
729
|
+
|
|
718
730
|
.histogram-loading-indicator {
|
|
719
731
|
width: 100%;
|
|
720
732
|
height: 2.25rem;
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { msg } from '@lit/localize';
|
|
2
|
+
import { LitElement, html, css, TemplateResult, CSSResultGroup } from 'lit';
|
|
3
|
+
import { customElement, property } from 'lit/decorators.js';
|
|
4
|
+
import { when } from 'lit/directives/when.js';
|
|
5
|
+
|
|
6
|
+
export interface ManageableItem {
|
|
7
|
+
identifier: string;
|
|
8
|
+
title?: string;
|
|
9
|
+
date?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
@customElement('manage-bar')
|
|
13
|
+
export class ManageBar extends LitElement {
|
|
14
|
+
/**
|
|
15
|
+
* The label displayed in front of the management buttons
|
|
16
|
+
*/
|
|
17
|
+
@property({ type: String }) label = msg('Select items to un-favorite');
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Whether to show the "Select All" button (default false)
|
|
21
|
+
*/
|
|
22
|
+
@property({ type: Boolean }) showSelectAll = false;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Whether to show the "Unselect All" button (default false)
|
|
26
|
+
*/
|
|
27
|
+
@property({ type: Boolean }) showUnselectAll = false;
|
|
28
|
+
|
|
29
|
+
render(): TemplateResult {
|
|
30
|
+
return html`
|
|
31
|
+
<div class="manage-container">
|
|
32
|
+
<span class="manage-label">${this.label}</span>
|
|
33
|
+
<div class="manage-buttons">
|
|
34
|
+
<button class="cancel-btn" @click=${this.cancelClicked}>
|
|
35
|
+
${msg('Cancel')}
|
|
36
|
+
</button>
|
|
37
|
+
<button class="remove-btn" @click=${this.removeClicked}>
|
|
38
|
+
${msg('Remove selected items')}
|
|
39
|
+
</button>
|
|
40
|
+
<div class="selection-buttons">
|
|
41
|
+
${when(
|
|
42
|
+
this.showSelectAll,
|
|
43
|
+
() => html` <button
|
|
44
|
+
class="link-styled select-all-btn"
|
|
45
|
+
@click=${this.selectAllClicked}
|
|
46
|
+
>
|
|
47
|
+
${msg('Select all')}
|
|
48
|
+
</button>`
|
|
49
|
+
)}
|
|
50
|
+
${when(
|
|
51
|
+
this.showUnselectAll,
|
|
52
|
+
() => html` <button
|
|
53
|
+
class="link-styled unselect-all-btn"
|
|
54
|
+
@click=${this.unselectAllClicked}
|
|
55
|
+
>
|
|
56
|
+
${msg('Unselect all')}
|
|
57
|
+
</button>`
|
|
58
|
+
)}
|
|
59
|
+
</div>
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
`;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
private cancelClicked(): void {
|
|
66
|
+
this.dispatchEvent(new CustomEvent('cancel'));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
private removeClicked(): void {
|
|
70
|
+
this.dispatchEvent(new CustomEvent('removeItems'));
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
private selectAllClicked(): void {
|
|
74
|
+
this.dispatchEvent(new CustomEvent('selectAll'));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
private unselectAllClicked(): void {
|
|
78
|
+
this.dispatchEvent(new CustomEvent('unselectAll'));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
static get styles(): CSSResultGroup {
|
|
82
|
+
return css`
|
|
83
|
+
.manage-container {
|
|
84
|
+
display: flex;
|
|
85
|
+
align-items: center;
|
|
86
|
+
column-gap: 5px;
|
|
87
|
+
padding: 10px 0 20px;
|
|
88
|
+
flex-wrap: wrap;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.manage-label {
|
|
92
|
+
display: inline-block;
|
|
93
|
+
font-weight: bold;
|
|
94
|
+
font-size: 1.8rem;
|
|
95
|
+
padding-right: 10px;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.manage-buttons {
|
|
99
|
+
display: flex;
|
|
100
|
+
align-items: center;
|
|
101
|
+
column-gap: 5px;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
button {
|
|
105
|
+
display: inline-block;
|
|
106
|
+
font-size: 1.4rem;
|
|
107
|
+
cursor: pointer;
|
|
108
|
+
white-space: nowrap;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
button.link-styled {
|
|
112
|
+
margin: 0;
|
|
113
|
+
padding: 6px;
|
|
114
|
+
border: 0;
|
|
115
|
+
appearance: none;
|
|
116
|
+
background: none;
|
|
117
|
+
color: var(--ia-theme-link-color, #4b64ff);
|
|
118
|
+
text-decoration: none;
|
|
119
|
+
}
|
|
120
|
+
button.link-styled:hover {
|
|
121
|
+
text-decoration: underline;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
button:not(.link-styled) {
|
|
125
|
+
margin: 0;
|
|
126
|
+
padding: 6px 12px;
|
|
127
|
+
border-radius: 4px;
|
|
128
|
+
color: white;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/* Button styles derived from legacy version */
|
|
132
|
+
.cancel-btn {
|
|
133
|
+
background: #777777;
|
|
134
|
+
border: 1px solid #666666;
|
|
135
|
+
}
|
|
136
|
+
.cancel-btn:hover {
|
|
137
|
+
background: #6b6b6b;
|
|
138
|
+
border: 1px solid #505050;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.remove-btn {
|
|
142
|
+
background: #d9534f;
|
|
143
|
+
border: 1px solid #d43f3a;
|
|
144
|
+
}
|
|
145
|
+
.remove-btn:hover {
|
|
146
|
+
background: #d2322d;
|
|
147
|
+
border: 1px solid #ac2925;
|
|
148
|
+
}
|
|
149
|
+
`;
|
|
150
|
+
}
|
|
151
|
+
}
|
package/src/models.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { css, html, nothing, PropertyValues } from 'lit';
|
|
2
2
|
import { customElement, property, query } from 'lit/decorators.js';
|
|
3
3
|
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
4
|
+
import { msg } from '@lit/localize';
|
|
4
5
|
import type {
|
|
5
6
|
SharedResizeObserverInterface,
|
|
6
7
|
SharedResizeObserverResizeHandlerInterface,
|
|
@@ -46,6 +47,8 @@ export class TileDispatcher
|
|
|
46
47
|
|
|
47
48
|
@property({ type: String }) tileDisplayMode?: TileDisplayMode;
|
|
48
49
|
|
|
50
|
+
@property({ type: Boolean }) isManageView = false;
|
|
51
|
+
|
|
49
52
|
@property({ type: Object }) resizeObserver?: SharedResizeObserverInterface;
|
|
50
53
|
|
|
51
54
|
@property({ type: Object })
|
|
@@ -54,6 +57,10 @@ export class TileDispatcher
|
|
|
54
57
|
/** Whether this tile should include a hover pane at all (for applicable tile modes) */
|
|
55
58
|
@property({ type: Boolean }) enableHoverPane = false;
|
|
56
59
|
|
|
60
|
+
@property({ type: String }) manageCheckTitle = msg(
|
|
61
|
+
'Remove this item from the list'
|
|
62
|
+
);
|
|
63
|
+
|
|
57
64
|
private hoverPaneController?: HoverPaneControllerInterface;
|
|
58
65
|
|
|
59
66
|
@query('#container')
|
|
@@ -82,7 +89,7 @@ export class TileDispatcher
|
|
|
82
89
|
${this.tileDisplayMode === 'list-header'
|
|
83
90
|
? this.headerTemplate
|
|
84
91
|
: this.tileTemplate}
|
|
85
|
-
${hoverPaneTemplate}
|
|
92
|
+
${this.manageCheckTemplate} ${hoverPaneTemplate}
|
|
86
93
|
</div>
|
|
87
94
|
`;
|
|
88
95
|
}
|
|
@@ -125,10 +132,8 @@ export class TileDispatcher
|
|
|
125
132
|
title=${this.shouldPrepareHoverPane
|
|
126
133
|
? nothing // Don't show title tooltips when we have the tile info popups
|
|
127
134
|
: ifDefined(this.model?.title)}
|
|
128
|
-
@click=${
|
|
129
|
-
|
|
130
|
-
new CustomEvent('resultSelected', { detail: this.model })
|
|
131
|
-
)}
|
|
135
|
+
@click=${this.handleLinkClicked}
|
|
136
|
+
@contextmenu=${this.handleLinkContextMenu}
|
|
132
137
|
>
|
|
133
138
|
${this.tile}
|
|
134
139
|
</a>
|
|
@@ -151,6 +156,23 @@ export class TileDispatcher
|
|
|
151
156
|
);
|
|
152
157
|
}
|
|
153
158
|
|
|
159
|
+
private get manageCheckTemplate() {
|
|
160
|
+
if (!this.isManageView || this.tileDisplayMode !== 'grid') return nothing;
|
|
161
|
+
|
|
162
|
+
return html`
|
|
163
|
+
<div class="manage-check">
|
|
164
|
+
<input
|
|
165
|
+
type="checkbox"
|
|
166
|
+
title=${this.manageCheckTitle}
|
|
167
|
+
.checked=${this.model?.checked}
|
|
168
|
+
@change=${() => {
|
|
169
|
+
if (this.model) this.model.checked = !this.model.checked;
|
|
170
|
+
}}
|
|
171
|
+
/>
|
|
172
|
+
</div>
|
|
173
|
+
`;
|
|
174
|
+
}
|
|
175
|
+
|
|
154
176
|
/**
|
|
155
177
|
* Whether hover pane behavior should be prepared for this tile
|
|
156
178
|
* (e.g., whether mouse listeners should be attached, etc.)
|
|
@@ -211,6 +233,32 @@ export class TileDispatcher
|
|
|
211
233
|
}
|
|
212
234
|
}
|
|
213
235
|
|
|
236
|
+
/**
|
|
237
|
+
* Handler for when the tile link is left-clicked. Emits the `resultSelected` event.
|
|
238
|
+
* In manage view, it also checks/unchecks the tile.
|
|
239
|
+
*/
|
|
240
|
+
private handleLinkClicked(e: Event): void {
|
|
241
|
+
if (this.isManageView) {
|
|
242
|
+
e.preventDefault();
|
|
243
|
+
if (this.model) this.model.checked = !this.model.checked;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
this.dispatchEvent(
|
|
247
|
+
new CustomEvent('resultSelected', { detail: this.model })
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Handler for when the tile link is right-clicked.
|
|
253
|
+
* In manage view, it opens the item in a new tab. Otherwise, does nothing.
|
|
254
|
+
*/
|
|
255
|
+
private handleLinkContextMenu(e: Event): void {
|
|
256
|
+
if (this.isManageView && this.linkTileHref !== nothing) {
|
|
257
|
+
e.preventDefault();
|
|
258
|
+
window.open(this.linkTileHref, '_blank');
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
214
262
|
private tileInfoButtonPressed(
|
|
215
263
|
e: CustomEvent<{ x: number; y: number }>
|
|
216
264
|
): void {
|
|
@@ -245,6 +293,7 @@ export class TileDispatcher
|
|
|
245
293
|
.currentWidth=${currentWidth}
|
|
246
294
|
.currentHeight=${currentHeight}
|
|
247
295
|
.creatorFilter=${creatorFilter}
|
|
296
|
+
.isManageView=${this.isManageView}
|
|
248
297
|
?showInfoButton=${!this.isHoverEnabled}
|
|
249
298
|
@infoButtonPressed=${this.tileInfoButtonPressed}
|
|
250
299
|
>
|
|
@@ -257,6 +306,7 @@ export class TileDispatcher
|
|
|
257
306
|
.currentWidth=${currentWidth}
|
|
258
307
|
.currentHeight=${currentHeight}
|
|
259
308
|
.creatorFilter=${creatorFilter}
|
|
309
|
+
.isManageView=${this.isManageView}
|
|
260
310
|
?showInfoButton=${!this.isHoverEnabled}
|
|
261
311
|
@infoButtonPressed=${this.tileInfoButtonPressed}
|
|
262
312
|
>
|
|
@@ -272,6 +322,7 @@ export class TileDispatcher
|
|
|
272
322
|
.sortParam=${sortParam}
|
|
273
323
|
.creatorFilter=${creatorFilter}
|
|
274
324
|
.loggedIn=${this.loggedIn}
|
|
325
|
+
.isManageView=${this.isManageView}
|
|
275
326
|
?showInfoButton=${!this.isHoverEnabled}
|
|
276
327
|
@infoButtonPressed=${this.tileInfoButtonPressed}
|
|
277
328
|
>
|
|
@@ -358,6 +409,21 @@ export class TileDispatcher
|
|
|
358
409
|
height: 100%;
|
|
359
410
|
}
|
|
360
411
|
|
|
412
|
+
.manage-check {
|
|
413
|
+
position: absolute;
|
|
414
|
+
right: 0;
|
|
415
|
+
top: 0;
|
|
416
|
+
border: 5px solid #2c2c2c;
|
|
417
|
+
border-radius: 3px;
|
|
418
|
+
background-color: #2c2c2c;
|
|
419
|
+
z-index: 1;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
.manage-check > input[type='checkbox'] {
|
|
423
|
+
display: block;
|
|
424
|
+
margin: 0;
|
|
425
|
+
}
|
|
426
|
+
|
|
361
427
|
#touch-backdrop {
|
|
362
428
|
position: fixed;
|
|
363
429
|
width: 100vw;
|