@internetarchive/collection-browser 3.4.0 → 3.4.1-alpha-webdev7761.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.
Files changed (38) hide show
  1. package/dist/src/collection-browser.d.ts +15 -2
  2. package/dist/src/collection-browser.js +185 -10
  3. package/dist/src/collection-browser.js.map +1 -1
  4. package/dist/src/collection-facets/facet-row.js +2 -1
  5. package/dist/src/collection-facets/facet-row.js.map +1 -1
  6. package/dist/src/collection-facets.js +16 -1
  7. package/dist/src/collection-facets.js.map +1 -1
  8. package/dist/src/data-source/collection-browser-data-source-interface.d.ts +10 -1
  9. package/dist/src/data-source/collection-browser-data-source-interface.js.map +1 -1
  10. package/dist/src/data-source/collection-browser-data-source.d.ts +19 -1
  11. package/dist/src/data-source/collection-browser-data-source.js +36 -18
  12. package/dist/src/data-source/collection-browser-data-source.js.map +1 -1
  13. package/dist/src/data-source/collection-browser-query-state.d.ts +1 -2
  14. package/dist/src/data-source/collection-browser-query-state.js.map +1 -1
  15. package/dist/src/data-source/models.d.ts +11 -0
  16. package/dist/src/data-source/models.js.map +1 -1
  17. package/dist/src/models.d.ts +2 -6
  18. package/dist/src/models.js +10 -14
  19. package/dist/src/models.js.map +1 -1
  20. package/dist/src/restoration-state-handler.d.ts +1 -2
  21. package/dist/src/restoration-state-handler.js +3 -9
  22. package/dist/src/restoration-state-handler.js.map +1 -1
  23. package/dist/test/collection-browser.test.js +19 -9
  24. package/dist/test/collection-browser.test.js.map +1 -1
  25. package/dist/test/restoration-state-handler.test.js +5 -37
  26. package/dist/test/restoration-state-handler.test.js.map +1 -1
  27. package/package.json +1 -1
  28. package/src/collection-browser.ts +215 -7
  29. package/src/collection-facets/facet-row.ts +4 -1
  30. package/src/collection-facets.ts +16 -1
  31. package/src/data-source/collection-browser-data-source-interface.ts +12 -0
  32. package/src/data-source/collection-browser-data-source.ts +59 -19
  33. package/src/data-source/collection-browser-query-state.ts +1 -7
  34. package/src/data-source/models.ts +13 -0
  35. package/src/models.ts +12 -16
  36. package/src/restoration-state-handler.ts +9 -11
  37. package/test/collection-browser.test.ts +21 -11
  38. package/test/restoration-state-handler.test.ts +12 -42
@@ -7,7 +7,7 @@ import '@internetarchive/infinite-scroller';
7
7
  import type { ModalManagerInterface } from '@internetarchive/modal-manager';
8
8
  import type { FeatureFeedbackServiceInterface } from '@internetarchive/feature-feedback';
9
9
  import type { RecaptchaManagerInterface } from '@internetarchive/recaptcha-manager';
10
- import { SelectedFacets, SortField, CollectionBrowserContext, TileModel, CollectionDisplayMode, FacetEventDetails, FacetLoadStrategy, TvClipFilterType } from './models';
10
+ import { SelectedFacets, SortField, CollectionBrowserContext, TileModel, CollectionDisplayMode, FacetEventDetails, FacetLoadStrategy } from './models';
11
11
  import { RestorationStateHandlerInterface } from './restoration-state-handler';
12
12
  import type { CollectionBrowserQueryState, CollectionBrowserSearchInterface } from './data-source/collection-browser-query-state';
13
13
  import type { CollectionBrowserDataSourceInterface } from './data-source/collection-browser-data-source-interface';
@@ -59,7 +59,6 @@ export declare class CollectionBrowser extends LitElement implements InfiniteScr
59
59
  selectedSort: SortField;
60
60
  selectedTitleFilter: string | null;
61
61
  selectedCreatorFilter: string | null;
62
- tvClipFilter: TvClipFilterType;
63
62
  sortDirection: SortDirection | null;
64
63
  defaultSortField: Exclude<SortField, SortField.default>;
65
64
  defaultSortDirection: SortDirection | null;
@@ -280,6 +279,10 @@ export declare class CollectionBrowser extends LitElement implements InfiniteScr
280
279
  letterFilters?: boolean | undefined;
281
280
  sort?: boolean | undefined;
282
281
  }): void;
282
+ /**
283
+ * Resets any selected TV network/show dropdowns to their default state
284
+ */
285
+ private clearTVDropdowns;
283
286
  /**
284
287
  * Returns true if the current value of `this.selectedFacets` contains
285
288
  * any facet buckets than have been selected or negated, or false otherwise.
@@ -460,6 +463,16 @@ export declare class CollectionBrowser extends LitElement implements InfiniteScr
460
463
  * including the collapsible container (with header) and the facets themselves.
461
464
  */
462
465
  private get mobileFacetsTemplate();
466
+ private selectedTVNetwork?;
467
+ private selectedTVShow?;
468
+ private shouldPopulateShows;
469
+ private tvNetworksDropdown?;
470
+ private tvShowsDropdown?;
471
+ private networksDropdownClicked;
472
+ private showsDropdownClicked;
473
+ private networksDropdownChanged;
474
+ private showsDropdownChanged;
475
+ private get tvDropdownFiltersTemplate();
463
476
  /**
464
477
  * The template for the facets component alone, without any surrounding wrappers.
465
478
  */
@@ -1,6 +1,7 @@
1
1
  import { __decorate } from "tslib";
2
2
  import { html, css, LitElement, nothing, } from 'lit';
3
3
  import { customElement, property, query, state } from 'lit/decorators.js';
4
+ import { map } from 'lit/directives/map.js';
4
5
  import { classMap } from 'lit/directives/class-map.js';
5
6
  import { msg } from '@lit/localize';
6
7
  import { SearchType, } from '@internetarchive/search-service';
@@ -22,6 +23,7 @@ import './manage/manage-bar';
22
23
  import './collection-facets';
23
24
  import './circular-activity-indicator';
24
25
  import './collection-facets/smart-facets/smart-facet-bar';
26
+ import { updateSelectedFacetBucket, } from './utils/facet-utils';
25
27
  let CollectionBrowser = class CollectionBrowser extends LitElement {
26
28
  constructor() {
27
29
  super();
@@ -33,7 +35,6 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
33
35
  this.selectedSort = SortField.default;
34
36
  this.selectedTitleFilter = null;
35
37
  this.selectedCreatorFilter = null;
36
- this.tvClipFilter = 'all';
37
38
  this.sortDirection = null;
38
39
  this.defaultSortField = SortField.relevance;
39
40
  this.defaultSortDirection = null;
@@ -183,6 +184,9 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
183
184
  */
184
185
  this.dataSourceInstallInProgress = false;
185
186
  this.placeholderCellTemplate = html `<collection-browser-loading-tile></collection-browser-loading-tile>`;
187
+ this.selectedTVNetwork = undefined;
188
+ this.selectedTVShow = undefined;
189
+ this.shouldPopulateShows = false;
186
190
  /**
187
191
  * Updates the height of the left column according to its position on the page.
188
192
  * Arrow function ensures proper `this` binding.
@@ -322,10 +326,24 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
322
326
  this.sortDirection = null;
323
327
  this.selectedSort = SortField.default;
324
328
  }
329
+ this.clearTVDropdowns();
325
330
  if (this.smartFacetBar) {
326
331
  this.smartFacetBar.deselectAll();
327
332
  }
328
333
  }
334
+ /**
335
+ * Resets any selected TV network/show dropdowns to their default state
336
+ */
337
+ clearTVDropdowns() {
338
+ this.selectedTVNetwork = undefined;
339
+ this.selectedTVShow = undefined;
340
+ if (this.tvNetworksDropdown) {
341
+ this.tvNetworksDropdown.selectedIndex = 0;
342
+ }
343
+ if (this.tvShowsDropdown) {
344
+ this.tvShowsDropdown.selectedIndex = 0;
345
+ }
346
+ }
329
347
  /**
330
348
  * Returns true if the current value of `this.selectedFacets` contains
331
349
  * any facet buckets than have been selected or negated, or false otherwise.
@@ -969,6 +987,129 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
969
987
  </details>
970
988
  `;
971
989
  }
990
+ async networksDropdownClicked() {
991
+ var _a, _b;
992
+ (_a = this.tvNetworksDropdown) === null || _a === void 0 ? void 0 : _a.classList.add('loading');
993
+ await this.dataSource.populateTVChannelMaps();
994
+ (_b = this.tvNetworksDropdown) === null || _b === void 0 ? void 0 : _b.classList.remove('loading');
995
+ }
996
+ async showsDropdownClicked() {
997
+ var _a, _b;
998
+ (_a = this.tvShowsDropdown) === null || _a === void 0 ? void 0 : _a.classList.add('loading');
999
+ await this.dataSource.populateTVChannelMaps();
1000
+ // Delay for a single tick so that the loading indicator will be rendered
1001
+ // while the dropdown options are being added
1002
+ await new Promise(res => setTimeout(res, 0));
1003
+ this.shouldPopulateShows = true;
1004
+ await this.updateComplete;
1005
+ (_b = this.tvShowsDropdown) === null || _b === void 0 ? void 0 : _b.classList.remove('loading');
1006
+ }
1007
+ async networksDropdownChanged() {
1008
+ const previousNetwork = this.selectedTVNetwork;
1009
+ this.selectedTVNetwork =
1010
+ this.tvNetworksDropdown.selectedOptions[0].value || undefined;
1011
+ const entries = this.dataSource.tvChannelMaps.channelToNetwork.entries();
1012
+ for (const [channel, network] of entries) {
1013
+ if (network === previousNetwork) {
1014
+ // Remove any previously-applied network filter
1015
+ const removedBucket = {
1016
+ key: channel.toLowerCase(),
1017
+ count: 0,
1018
+ state: 'none',
1019
+ };
1020
+ this.selectedFacets = updateSelectedFacetBucket(this.selectedFacets, 'creator', removedBucket, true);
1021
+ }
1022
+ else if (network === this.selectedTVNetwork) {
1023
+ const newBucket = {
1024
+ key: channel.toLowerCase(),
1025
+ count: 0,
1026
+ state: 'selected',
1027
+ };
1028
+ this.selectedFacets = updateSelectedFacetBucket(this.selectedFacets, 'creator', newBucket);
1029
+ }
1030
+ }
1031
+ }
1032
+ async showsDropdownChanged() {
1033
+ const previousShow = this.selectedTVShow;
1034
+ this.selectedTVShow =
1035
+ this.tvShowsDropdown.selectedOptions[0].value || undefined;
1036
+ // Remove any previously-applied shows filter
1037
+ if (previousShow !== undefined) {
1038
+ const removedBucket = {
1039
+ key: previousShow,
1040
+ count: 0,
1041
+ state: 'none',
1042
+ };
1043
+ this.selectedFacets = updateSelectedFacetBucket(this.selectedFacets, 'program', removedBucket, true);
1044
+ }
1045
+ if (this.selectedTVShow) {
1046
+ const newBucket = {
1047
+ key: this.selectedTVShow,
1048
+ count: 0,
1049
+ state: 'selected',
1050
+ };
1051
+ this.selectedFacets = updateSelectedFacetBucket(this.selectedFacets, 'program', newBucket);
1052
+ }
1053
+ }
1054
+ get tvDropdownFiltersTemplate() {
1055
+ if (this.searchType !== SearchType.TV)
1056
+ return nothing;
1057
+ log('start filters template preprocess', Date.now());
1058
+ const { channelToNetwork, programToChannels } = this.dataSource.tvChannelMaps;
1059
+ const networks = channelToNetwork
1060
+ ? [...new Set(channelToNetwork.values())]
1061
+ : [];
1062
+ let showEntries = programToChannels ? [...programToChannels.entries()] : [];
1063
+ if (channelToNetwork && this.selectedTVNetwork) {
1064
+ showEntries = showEntries.filter(([, channels]) => Object.keys(channels).some(c => channelToNetwork.get(c) === this.selectedTVNetwork));
1065
+ }
1066
+ const shows = showEntries.map(([show]) => show);
1067
+ log('end filters template preprocess', Date.now());
1068
+ const makeNetworkOption = (network) => html `
1069
+ <option ?selected=${this.selectedTVNetwork === network}>
1070
+ ${network}
1071
+ </option>
1072
+ `;
1073
+ const makeShowOption = (show) => html `
1074
+ <option ?selected=${this.selectedTVShow === show}>${show}</option>
1075
+ `;
1076
+ const loadingIndicator = html `
1077
+ <img src="https://archive.org/images/loading.gif" />
1078
+ `;
1079
+ return html `
1080
+ <div id="tv-filters" slot="facets-top">
1081
+ <div class="tv-filter-dropdown-wrap">
1082
+ <select
1083
+ id="tv-networks"
1084
+ class="tv-filter-dropdown"
1085
+ @click=${this.networksDropdownClicked}
1086
+ @change=${this.networksDropdownChanged}
1087
+ >
1088
+ <option value="" ?selected=${!this.selectedTVNetwork}>
1089
+ ${msg('Filter by Network')}
1090
+ </option>
1091
+ ${map(networks, makeNetworkOption)}
1092
+ </select>
1093
+ ${loadingIndicator}
1094
+ </div>
1095
+
1096
+ <div class="tv-filter-dropdown-wrap">
1097
+ <select
1098
+ id="tv-shows"
1099
+ class="tv-filter-dropdown"
1100
+ @click=${this.showsDropdownClicked}
1101
+ @change=${this.showsDropdownChanged}
1102
+ >
1103
+ <option value="" ?selected=${!this.selectedTVShow}>
1104
+ ${msg('Filter by Show')}
1105
+ </option>
1106
+ ${this.shouldPopulateShows ? map(shows, makeShowOption) : nothing}
1107
+ </select>
1108
+ ${loadingIndicator}
1109
+ </div>
1110
+ </div>
1111
+ `;
1112
+ }
972
1113
  /**
973
1114
  * The template for the facets component alone, without any surrounding wrappers.
974
1115
  */
@@ -1026,6 +1167,7 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
1026
1167
  @facetsChanged=${this.facetsChanged}
1027
1168
  @histogramDateRangeUpdated=${this.histogramDateRangeUpdated}
1028
1169
  >
1170
+ ${this.tvDropdownFiltersTemplate}
1029
1171
  </collection-facets>
1030
1172
  `;
1031
1173
  // If we are using one of the opt-in facet load strategies, we may need to wrap the
@@ -1141,7 +1283,7 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
1141
1283
  * represent, such as the search query, sort option, and any filters applied.
1142
1284
  */
1143
1285
  async installDataSourceAndQueryState(dataSource, queryState) {
1144
- var _a, _b, _c;
1286
+ var _a, _b;
1145
1287
  log('Installing data source & query state in CB:', dataSource, queryState);
1146
1288
  if (this.dataSource)
1147
1289
  this.removeController(this.dataSource);
@@ -1159,7 +1301,6 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
1159
1301
  this.sortDirection = queryState.sortDirection;
1160
1302
  this.selectedTitleFilter = queryState.selectedTitleFilter;
1161
1303
  this.selectedCreatorFilter = queryState.selectedCreatorFilter;
1162
- this.tvClipFilter = (_c = queryState.tvClipFilter) !== null && _c !== void 0 ? _c : 'all';
1163
1304
  this.pagesToRender = this.initialPageNumber;
1164
1305
  // We set this flag during the update to prevent the URL state persistence
1165
1306
  // from creating an unwanted extra history entry.
@@ -1488,7 +1629,6 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
1488
1629
  sortDirection: this.sortDirection,
1489
1630
  selectedTitleFilter: this.selectedTitleFilter,
1490
1631
  selectedCreatorFilter: this.selectedCreatorFilter,
1491
- tvClipFilter: this.tvClipFilter,
1492
1632
  },
1493
1633
  }));
1494
1634
  }
@@ -1606,7 +1746,7 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
1606
1746
  this.restoreState();
1607
1747
  }
1608
1748
  restoreState() {
1609
- var _a, _b, _c, _d, _e, _f;
1749
+ var _a, _b, _c, _d, _e;
1610
1750
  const restorationState = this.restorationStateHandler.getRestorationState();
1611
1751
  this.displayMode = restorationState.displayMode;
1612
1752
  if (!this.suppressURLSinParam && restorationState.searchType != null)
@@ -1621,7 +1761,6 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
1621
1761
  this.currentPage = (_e = restorationState.currentPage) !== null && _e !== void 0 ? _e : 1;
1622
1762
  this.minSelectedDate = restorationState.minSelectedDate;
1623
1763
  this.maxSelectedDate = restorationState.maxSelectedDate;
1624
- this.tvClipFilter = (_f = restorationState.tvClipFilter) !== null && _f !== void 0 ? _f : 'all';
1625
1764
  if (this.currentPage > 1) {
1626
1765
  this.goToPage(this.currentPage);
1627
1766
  }
@@ -1642,7 +1781,6 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
1642
1781
  maxSelectedDate: this.maxSelectedDate,
1643
1782
  selectedTitleFilter: (_c = this.selectedTitleFilter) !== null && _c !== void 0 ? _c : undefined,
1644
1783
  selectedCreatorFilter: (_d = this.selectedCreatorFilter) !== null && _d !== void 0 ? _d : undefined,
1645
- tvClipFilter: this.tvClipFilter,
1646
1784
  };
1647
1785
  const persistOptions = {
1648
1786
  forceReplace: this.dataSourceInstallInProgress,
@@ -2184,6 +2322,31 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
2184
2322
  line-height: 1.3rem;
2185
2323
  }
2186
2324
 
2325
+ #tv-filters {
2326
+ margin-bottom: 15px;
2327
+ }
2328
+
2329
+ .tv-filter-dropdown {
2330
+ width: 100%;
2331
+ padding: 3px;
2332
+ }
2333
+
2334
+ .tv-filter-dropdown-wrap {
2335
+ display: flex;
2336
+ align-items: center;
2337
+ column-gap: 5px;
2338
+ margin-bottom: 5px;
2339
+ }
2340
+
2341
+ .tv-filter-dropdown-wrap > img {
2342
+ flex: 1;
2343
+ visibility: hidden;
2344
+ }
2345
+
2346
+ .tv-filter-dropdown.loading + img {
2347
+ visibility: visible;
2348
+ }
2349
+
2187
2350
  #facets-container {
2188
2351
  position: relative;
2189
2352
  max-height: 0;
@@ -2389,9 +2552,6 @@ __decorate([
2389
2552
  __decorate([
2390
2553
  property({ type: String })
2391
2554
  ], CollectionBrowser.prototype, "selectedCreatorFilter", void 0);
2392
- __decorate([
2393
- property({ type: String })
2394
- ], CollectionBrowser.prototype, "tvClipFilter", void 0);
2395
2555
  __decorate([
2396
2556
  property({ type: String })
2397
2557
  ], CollectionBrowser.prototype, "sortDirection", void 0);
@@ -2560,6 +2720,21 @@ __decorate([
2560
2720
  __decorate([
2561
2721
  query('infinite-scroller')
2562
2722
  ], CollectionBrowser.prototype, "infiniteScroller", void 0);
2723
+ __decorate([
2724
+ state()
2725
+ ], CollectionBrowser.prototype, "selectedTVNetwork", void 0);
2726
+ __decorate([
2727
+ state()
2728
+ ], CollectionBrowser.prototype, "selectedTVShow", void 0);
2729
+ __decorate([
2730
+ state()
2731
+ ], CollectionBrowser.prototype, "shouldPopulateShows", void 0);
2732
+ __decorate([
2733
+ query('#tv-networks')
2734
+ ], CollectionBrowser.prototype, "tvNetworksDropdown", void 0);
2735
+ __decorate([
2736
+ query('#tv-shows')
2737
+ ], CollectionBrowser.prototype, "tvShowsDropdown", void 0);
2563
2738
  CollectionBrowser = __decorate([
2564
2739
  customElement('collection-browser')
2565
2740
  ], CollectionBrowser);