@internetarchive/collection-browser 0.3.1-alpha.3 → 0.3.2-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/dist/src/collection-browser.d.ts +6 -0
  2. package/dist/src/collection-browser.js +346 -341
  3. package/dist/src/collection-browser.js.map +1 -1
  4. package/dist/src/collection-facets/facets-template.js +150 -150
  5. package/dist/src/collection-facets/facets-template.js.map +1 -1
  6. package/dist/src/collection-facets/more-facets-content.js +134 -134
  7. package/dist/src/collection-facets/more-facets-content.js.map +1 -1
  8. package/dist/src/collection-facets.d.ts +2 -0
  9. package/dist/src/collection-facets.js +158 -147
  10. package/dist/src/collection-facets.js.map +1 -1
  11. package/dist/src/models.js.map +1 -1
  12. package/dist/src/restoration-state-handler.js.map +1 -1
  13. package/dist/src/tiles/list/tile-list.js +204 -204
  14. package/dist/src/tiles/list/tile-list.js.map +1 -1
  15. package/dist/src/utils/format-count.js.map +1 -1
  16. package/dist/test/collection-browser.test.js +26 -26
  17. package/dist/test/collection-browser.test.js.map +1 -1
  18. package/dist/test/collection-facets.test.js +2 -2
  19. package/dist/test/collection-facets.test.js.map +1 -1
  20. package/package.json +1 -1
  21. package/src/collection-browser.ts +1539 -1530
  22. package/src/collection-facets/facets-template.ts +294 -294
  23. package/src/collection-facets/more-facets-content.ts +518 -518
  24. package/src/collection-facets.ts +582 -569
  25. package/src/models.ts +216 -216
  26. package/src/restoration-state-handler.ts +302 -302
  27. package/src/tiles/list/tile-list.ts +509 -509
  28. package/src/utils/format-count.ts +96 -96
  29. package/test/collection-browser.test.ts +490 -490
  30. package/test/collection-facets.test.ts +510 -510
@@ -1 +1 @@
1
- {"version":3,"file":"restoration-state-handler.js","sourceRoot":"","sources":["../../src/restoration-state-handler.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SortDirection, SortParam } from '@internetarchive/search-service';\r\nimport { getCookie, setCookie } from 'typescript-cookie';\r\nimport {\r\n MetadataFieldToSortField,\r\n MetadataSortField,\r\n FacetOption,\r\n CollectionBrowserContext,\r\n CollectionDisplayMode,\r\n SelectedFacets,\r\n SortField,\r\n FacetBucket,\r\n FacetState,\r\n} from './models';\r\n\r\nexport interface RestorationState {\r\n displayMode?: CollectionDisplayMode;\r\n sortParam?: SortParam;\r\n selectedSort?: SortField;\r\n sortDirection?: SortDirection;\r\n selectedFacets: SelectedFacets;\r\n baseQuery?: string;\r\n currentPage?: number;\r\n dateRangeQueryClause?: string;\r\n titleQuery?: string;\r\n creatorQuery?: string;\r\n minSelectedDate?: string;\r\n maxSelectedDate?: string;\r\n selectedTitleFilter?: string;\r\n selectedCreatorFilter?: string;\r\n}\r\n\r\nexport interface RestorationStateHandlerInterface {\r\n persistState(state: RestorationState): void;\r\n getRestorationState(): RestorationState;\r\n}\r\n\r\nexport class RestorationStateHandler\r\n implements RestorationStateHandlerInterface\r\n{\r\n private context: CollectionBrowserContext;\r\n\r\n private cookieDomain = '.archive.org';\r\n\r\n private cookieExpiration = 30;\r\n\r\n private cookiePath = '/';\r\n\r\n constructor(options: { context: CollectionBrowserContext }) {\r\n this.context = options.context;\r\n }\r\n\r\n persistState(state: RestorationState): void {\r\n if (state.displayMode) this.persistViewStateToCookies(state.displayMode);\r\n this.persistQueryStateToUrl(state);\r\n }\r\n\r\n getRestorationState(): RestorationState {\r\n const restorationState = this.loadQueryStateFromUrl();\r\n const displayMode = this.loadTileViewStateFromCookies();\r\n restorationState.displayMode = displayMode;\r\n return restorationState;\r\n }\r\n\r\n private persistViewStateToCookies(displayMode: CollectionDisplayMode) {\r\n const gridState = displayMode === 'grid' ? 'tiles' : 'lists';\r\n setCookie(`view-${this.context}`, gridState, {\r\n domain: this.cookieDomain,\r\n expires: this.cookieExpiration,\r\n path: this.cookiePath,\r\n });\r\n const detailsState = displayMode === 'list-detail' ? 'showdetails' : '';\r\n setCookie(`showdetails-${this.context}`, detailsState, {\r\n domain: this.cookieDomain,\r\n expires: this.cookieExpiration,\r\n path: this.cookiePath,\r\n });\r\n }\r\n\r\n private loadTileViewStateFromCookies(): CollectionDisplayMode {\r\n const viewState = getCookie(`view-${this.context}`);\r\n const detailsState = getCookie(`showdetails-${this.context}`);\r\n if (viewState === 'tiles' || viewState === undefined) return 'grid';\r\n if (detailsState === 'showdetails') return 'list-detail';\r\n return 'list-compact';\r\n }\r\n\r\n private persistQueryStateToUrl(state: RestorationState) {\r\n const url = new URL(window.location.href);\r\n const { searchParams } = url;\r\n searchParams.delete('sort');\r\n searchParams.delete('query');\r\n searchParams.delete('page');\r\n searchParams.delete('and[]');\r\n searchParams.delete('not[]');\r\n\r\n if (state.sortParam) {\r\n const prefix = state.sortParam.direction === 'desc' ? '-' : '';\r\n searchParams.set('sort', `${prefix}${state.sortParam.field}`);\r\n }\r\n\r\n if (state.baseQuery) {\r\n searchParams.set('query', state.baseQuery);\r\n }\r\n\r\n if (state.currentPage) {\r\n if (state.currentPage > 1) {\r\n searchParams.set('page', state.currentPage.toString());\r\n } else {\r\n searchParams.delete('page');\r\n }\r\n }\r\n\r\n if (state.selectedFacets) {\r\n for (const [facetName, facetValues] of Object.entries(\r\n state.selectedFacets\r\n )) {\r\n const facetEntries = Object.entries(facetValues);\r\n // eslint-disable-next-line no-continue\r\n if (facetEntries.length === 0) continue;\r\n for (const [key, data] of facetEntries) {\r\n const notValue = data.state === 'hidden';\r\n const paramValue = `${facetName}:\"${key}\"`;\r\n if (notValue) {\r\n searchParams.append('not[]', paramValue);\r\n } else {\r\n searchParams.append('and[]', paramValue);\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (state.dateRangeQueryClause) {\r\n searchParams.append('and[]', state.dateRangeQueryClause);\r\n }\r\n if (state.titleQuery) {\r\n searchParams.append('and[]', state.titleQuery);\r\n }\r\n if (state.creatorQuery) {\r\n searchParams.append('and[]', state.creatorQuery);\r\n }\r\n\r\n window.history.pushState(\r\n {\r\n sort: state.sortParam,\r\n query: state.baseQuery,\r\n page: state.currentPage,\r\n and: state.selectedFacets,\r\n not: state.selectedFacets,\r\n dateRange: state.dateRangeQueryClause,\r\n },\r\n '',\r\n url\r\n );\r\n }\r\n\r\n private loadQueryStateFromUrl(): RestorationState {\r\n const url = new URL(window.location.href);\r\n const pageNumber = url.searchParams.get('page');\r\n const searchQuery = url.searchParams.get('query');\r\n const sortQuery = url.searchParams.get('sort');\r\n const facetAnds = url.searchParams.getAll('and[]');\r\n const facetNots = url.searchParams.getAll('not[]');\r\n\r\n const restorationState: RestorationState = {\r\n selectedFacets: {\r\n subject: {},\r\n lending: {},\r\n creator: {},\r\n mediatype: {},\r\n language: {},\r\n collection: {},\r\n year: {},\r\n },\r\n };\r\n\r\n if (pageNumber) {\r\n const parsed = parseInt(pageNumber, 10);\r\n restorationState.currentPage = parsed;\r\n } else {\r\n restorationState.currentPage = 1;\r\n }\r\n if (searchQuery) {\r\n restorationState.baseQuery = searchQuery;\r\n }\r\n if (sortQuery) {\r\n // check for two different sort formats: `date desc` and `-date`\r\n const hasSpace = sortQuery.indexOf(' ') > -1;\r\n if (hasSpace) {\r\n const [field, direction] = sortQuery.split(' ');\r\n const metadataField =\r\n MetadataFieldToSortField[field as MetadataSortField];\r\n if (metadataField) {\r\n restorationState.selectedSort = metadataField;\r\n }\r\n if (direction === 'desc' || direction === 'asc') {\r\n restorationState.sortDirection = direction as SortDirection;\r\n }\r\n } else {\r\n const sortDirection = sortQuery.startsWith('-') ? 'desc' : 'asc';\r\n const sortField = sortQuery.startsWith('-')\r\n ? sortQuery.slice(1)\r\n : sortQuery;\r\n const metadataField =\r\n MetadataFieldToSortField[sortField as MetadataSortField];\r\n if (metadataField) restorationState.selectedSort = metadataField;\r\n restorationState.sortDirection = sortDirection as SortDirection;\r\n }\r\n }\r\n if (facetAnds) {\r\n facetAnds.forEach(and => {\r\n const [field, value] = and.split(':');\r\n\r\n switch (field) {\r\n case 'year': {\r\n const [minDate, maxDate] = value.split(' TO ');\r\n // we have two potential ways of filtering by date:\r\n // the range with \"date TO date\" or the single date with \"date\"\r\n // this is checking for the range case and if we don't have those, fall\r\n // back to the single date case\r\n if (minDate && maxDate) {\r\n restorationState.minSelectedDate = minDate.substring(\r\n 1,\r\n minDate.length\r\n );\r\n restorationState.maxSelectedDate = maxDate.substring(\r\n 0,\r\n maxDate.length - 1\r\n );\r\n restorationState.dateRangeQueryClause = `year:${value}`;\r\n } else {\r\n this.setSelectedFacetState(\r\n restorationState.selectedFacets,\r\n field as FacetOption,\r\n value,\r\n 'selected'\r\n );\r\n }\r\n break;\r\n }\r\n case 'firstTitle':\r\n restorationState.selectedTitleFilter = value;\r\n break;\r\n case 'firstCreator':\r\n restorationState.selectedCreatorFilter = value;\r\n break;\r\n default:\r\n this.setSelectedFacetState(\r\n restorationState.selectedFacets,\r\n field as FacetOption,\r\n value,\r\n 'selected'\r\n );\r\n }\r\n });\r\n }\r\n if (facetNots) {\r\n facetNots.forEach(not => {\r\n const [field, value] = not.split(':');\r\n this.setSelectedFacetState(\r\n restorationState.selectedFacets,\r\n field as FacetOption,\r\n value,\r\n 'hidden'\r\n );\r\n });\r\n }\r\n return restorationState;\r\n }\r\n\r\n // remove optional opening and closing quotes from a string\r\n private stripQuotes(value: string): string {\r\n if (value.startsWith('\"') && value.endsWith('\"')) {\r\n return value.substring(1, value.length - 1);\r\n }\r\n return value;\r\n }\r\n\r\n /**\r\n * Sets the facet state for the given field & value to the given state,\r\n * creating any previously-undefined buckets as needed.\r\n */\r\n private setSelectedFacetState(\r\n selectedFacets: SelectedFacets,\r\n field: FacetOption,\r\n value: string,\r\n state: FacetState\r\n ): void {\r\n const facet = selectedFacets[field];\r\n const unQuotedValue = this.stripQuotes(value);\r\n facet[unQuotedValue] ??= this.getDefaultBucket(value);\r\n facet[unQuotedValue].state = state;\r\n }\r\n\r\n /** Returns a default bucket with the given key, count of 0, and state 'none'. */\r\n private getDefaultBucket(key: string): FacetBucket {\r\n return {\r\n key,\r\n count: 0,\r\n state: 'none',\r\n };\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"restoration-state-handler.js","sourceRoot":"","sources":["../../src/restoration-state-handler.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SortDirection, SortParam } from '@internetarchive/search-service';\nimport { getCookie, setCookie } from 'typescript-cookie';\nimport {\n MetadataFieldToSortField,\n MetadataSortField,\n FacetOption,\n CollectionBrowserContext,\n CollectionDisplayMode,\n SelectedFacets,\n SortField,\n FacetBucket,\n FacetState,\n} from './models';\n\nexport interface RestorationState {\n displayMode?: CollectionDisplayMode;\n sortParam?: SortParam;\n selectedSort?: SortField;\n sortDirection?: SortDirection;\n selectedFacets: SelectedFacets;\n baseQuery?: string;\n currentPage?: number;\n dateRangeQueryClause?: string;\n titleQuery?: string;\n creatorQuery?: string;\n minSelectedDate?: string;\n maxSelectedDate?: string;\n selectedTitleFilter?: string;\n selectedCreatorFilter?: string;\n}\n\nexport interface RestorationStateHandlerInterface {\n persistState(state: RestorationState): void;\n getRestorationState(): RestorationState;\n}\n\nexport class RestorationStateHandler\n implements RestorationStateHandlerInterface\n{\n private context: CollectionBrowserContext;\n\n private cookieDomain = '.archive.org';\n\n private cookieExpiration = 30;\n\n private cookiePath = '/';\n\n constructor(options: { context: CollectionBrowserContext }) {\n this.context = options.context;\n }\n\n persistState(state: RestorationState): void {\n if (state.displayMode) this.persistViewStateToCookies(state.displayMode);\n this.persistQueryStateToUrl(state);\n }\n\n getRestorationState(): RestorationState {\n const restorationState = this.loadQueryStateFromUrl();\n const displayMode = this.loadTileViewStateFromCookies();\n restorationState.displayMode = displayMode;\n return restorationState;\n }\n\n private persistViewStateToCookies(displayMode: CollectionDisplayMode) {\n const gridState = displayMode === 'grid' ? 'tiles' : 'lists';\n setCookie(`view-${this.context}`, gridState, {\n domain: this.cookieDomain,\n expires: this.cookieExpiration,\n path: this.cookiePath,\n });\n const detailsState = displayMode === 'list-detail' ? 'showdetails' : '';\n setCookie(`showdetails-${this.context}`, detailsState, {\n domain: this.cookieDomain,\n expires: this.cookieExpiration,\n path: this.cookiePath,\n });\n }\n\n private loadTileViewStateFromCookies(): CollectionDisplayMode {\n const viewState = getCookie(`view-${this.context}`);\n const detailsState = getCookie(`showdetails-${this.context}`);\n if (viewState === 'tiles' || viewState === undefined) return 'grid';\n if (detailsState === 'showdetails') return 'list-detail';\n return 'list-compact';\n }\n\n private persistQueryStateToUrl(state: RestorationState) {\n const url = new URL(window.location.href);\n const { searchParams } = url;\n searchParams.delete('sort');\n searchParams.delete('query');\n searchParams.delete('page');\n searchParams.delete('and[]');\n searchParams.delete('not[]');\n\n if (state.sortParam) {\n const prefix = state.sortParam.direction === 'desc' ? '-' : '';\n searchParams.set('sort', `${prefix}${state.sortParam.field}`);\n }\n\n if (state.baseQuery) {\n searchParams.set('query', state.baseQuery);\n }\n\n if (state.currentPage) {\n if (state.currentPage > 1) {\n searchParams.set('page', state.currentPage.toString());\n } else {\n searchParams.delete('page');\n }\n }\n\n if (state.selectedFacets) {\n for (const [facetName, facetValues] of Object.entries(\n state.selectedFacets\n )) {\n const facetEntries = Object.entries(facetValues);\n // eslint-disable-next-line no-continue\n if (facetEntries.length === 0) continue;\n for (const [key, data] of facetEntries) {\n const notValue = data.state === 'hidden';\n const paramValue = `${facetName}:\"${key}\"`;\n if (notValue) {\n searchParams.append('not[]', paramValue);\n } else {\n searchParams.append('and[]', paramValue);\n }\n }\n }\n }\n\n if (state.dateRangeQueryClause) {\n searchParams.append('and[]', state.dateRangeQueryClause);\n }\n if (state.titleQuery) {\n searchParams.append('and[]', state.titleQuery);\n }\n if (state.creatorQuery) {\n searchParams.append('and[]', state.creatorQuery);\n }\n\n window.history.pushState(\n {\n sort: state.sortParam,\n query: state.baseQuery,\n page: state.currentPage,\n and: state.selectedFacets,\n not: state.selectedFacets,\n dateRange: state.dateRangeQueryClause,\n },\n '',\n url\n );\n }\n\n private loadQueryStateFromUrl(): RestorationState {\n const url = new URL(window.location.href);\n const pageNumber = url.searchParams.get('page');\n const searchQuery = url.searchParams.get('query');\n const sortQuery = url.searchParams.get('sort');\n const facetAnds = url.searchParams.getAll('and[]');\n const facetNots = url.searchParams.getAll('not[]');\n\n const restorationState: RestorationState = {\n selectedFacets: {\n subject: {},\n lending: {},\n creator: {},\n mediatype: {},\n language: {},\n collection: {},\n year: {},\n },\n };\n\n if (pageNumber) {\n const parsed = parseInt(pageNumber, 10);\n restorationState.currentPage = parsed;\n } else {\n restorationState.currentPage = 1;\n }\n if (searchQuery) {\n restorationState.baseQuery = searchQuery;\n }\n if (sortQuery) {\n // check for two different sort formats: `date desc` and `-date`\n const hasSpace = sortQuery.indexOf(' ') > -1;\n if (hasSpace) {\n const [field, direction] = sortQuery.split(' ');\n const metadataField =\n MetadataFieldToSortField[field as MetadataSortField];\n if (metadataField) {\n restorationState.selectedSort = metadataField;\n }\n if (direction === 'desc' || direction === 'asc') {\n restorationState.sortDirection = direction as SortDirection;\n }\n } else {\n const sortDirection = sortQuery.startsWith('-') ? 'desc' : 'asc';\n const sortField = sortQuery.startsWith('-')\n ? sortQuery.slice(1)\n : sortQuery;\n const metadataField =\n MetadataFieldToSortField[sortField as MetadataSortField];\n if (metadataField) restorationState.selectedSort = metadataField;\n restorationState.sortDirection = sortDirection as SortDirection;\n }\n }\n if (facetAnds) {\n facetAnds.forEach(and => {\n const [field, value] = and.split(':');\n\n switch (field) {\n case 'year': {\n const [minDate, maxDate] = value.split(' TO ');\n // we have two potential ways of filtering by date:\n // the range with \"date TO date\" or the single date with \"date\"\n // this is checking for the range case and if we don't have those, fall\n // back to the single date case\n if (minDate && maxDate) {\n restorationState.minSelectedDate = minDate.substring(\n 1,\n minDate.length\n );\n restorationState.maxSelectedDate = maxDate.substring(\n 0,\n maxDate.length - 1\n );\n restorationState.dateRangeQueryClause = `year:${value}`;\n } else {\n this.setSelectedFacetState(\n restorationState.selectedFacets,\n field as FacetOption,\n value,\n 'selected'\n );\n }\n break;\n }\n case 'firstTitle':\n restorationState.selectedTitleFilter = value;\n break;\n case 'firstCreator':\n restorationState.selectedCreatorFilter = value;\n break;\n default:\n this.setSelectedFacetState(\n restorationState.selectedFacets,\n field as FacetOption,\n value,\n 'selected'\n );\n }\n });\n }\n if (facetNots) {\n facetNots.forEach(not => {\n const [field, value] = not.split(':');\n this.setSelectedFacetState(\n restorationState.selectedFacets,\n field as FacetOption,\n value,\n 'hidden'\n );\n });\n }\n return restorationState;\n }\n\n // remove optional opening and closing quotes from a string\n private stripQuotes(value: string): string {\n if (value.startsWith('\"') && value.endsWith('\"')) {\n return value.substring(1, value.length - 1);\n }\n return value;\n }\n\n /**\n * Sets the facet state for the given field & value to the given state,\n * creating any previously-undefined buckets as needed.\n */\n private setSelectedFacetState(\n selectedFacets: SelectedFacets,\n field: FacetOption,\n value: string,\n state: FacetState\n ): void {\n const facet = selectedFacets[field];\n const unQuotedValue = this.stripQuotes(value);\n facet[unQuotedValue] ??= this.getDefaultBucket(value);\n facet[unQuotedValue].state = state;\n }\n\n /** Returns a default bucket with the given key, count of 0, and state 'none'. */\n private getDefaultBucket(key: string): FacetBucket {\n return {\n key,\n count: 0,\n state: 'none',\n };\n }\n}\n"]}
@@ -44,76 +44,76 @@ let TileList = class TileList extends LitElement {
44
44
  this.collectionLinks = newCollellectionLinks;
45
45
  }
46
46
  render() {
47
- return html `
48
- <div id="list-line" class="${this.classSize}">
47
+ return html `
48
+ <div id="list-line" class="${this.classSize}">
49
49
  ${this.classSize === 'mobile'
50
50
  ? this.mobileTemplate
51
- : this.desktopTemplate}
52
- </div>
51
+ : this.desktopTemplate}
52
+ </div>
53
53
  `;
54
54
  }
55
55
  get mobileTemplate() {
56
- return html `
57
- <div id="list-line-top">
58
- <div id="list-line-left">${this.imageBlockTemplate}</div>
59
- <div id="list-line-right">
60
- <div id="title-line">
61
- <div id="title">${this.titleTemplate}</div>
62
- ${this.iconRightTemplate}
63
- </div>
64
- </div>
65
- </div>
66
- <div id="list-line-bottom">${this.detailsTemplate}</div>
56
+ return html `
57
+ <div id="list-line-top">
58
+ <div id="list-line-left">${this.imageBlockTemplate}</div>
59
+ <div id="list-line-right">
60
+ <div id="title-line">
61
+ <div id="title">${this.titleTemplate}</div>
62
+ ${this.iconRightTemplate}
63
+ </div>
64
+ </div>
65
+ </div>
66
+ <div id="list-line-bottom">${this.detailsTemplate}</div>
67
67
  `;
68
68
  }
69
69
  get desktopTemplate() {
70
- return html `
71
- <div id="list-line-left">${this.imageBlockTemplate}</div>
72
- <div id="list-line-right">
73
- <div id="title-line">
74
- <div id="title">${this.titleTemplate}</div>
75
- ${this.iconRightTemplate}
76
- </div>
77
- ${this.detailsTemplate}
78
- </div>
70
+ return html `
71
+ <div id="list-line-left">${this.imageBlockTemplate}</div>
72
+ <div id="list-line-right">
73
+ <div id="title-line">
74
+ <div id="title">${this.titleTemplate}</div>
75
+ ${this.iconRightTemplate}
76
+ </div>
77
+ ${this.detailsTemplate}
78
+ </div>
79
79
  `;
80
80
  }
81
81
  get imageBlockTemplate() {
82
- return html `
83
- <image-block
84
- .model=${this.model}
85
- .baseImageUrl=${this.baseImageUrl}
86
- .isCompactTile=${false}
87
- .isListTile=${true}
88
- .viewSize=${this.classSize}
89
- >
90
- </image-block>
82
+ return html `
83
+ <image-block
84
+ .model=${this.model}
85
+ .baseImageUrl=${this.baseImageUrl}
86
+ .isCompactTile=${false}
87
+ .isListTile=${true}
88
+ .viewSize=${this.classSize}
89
+ >
90
+ </image-block>
91
91
  `;
92
92
  }
93
93
  get detailsTemplate() {
94
- return html `
95
- ${this.itemLineTemplate} ${this.creatorTemplate}
96
- <div id="dates-line">
97
- ${this.datePublishedTemplate} ${this.dateSortByTemplate}
98
- </div>
99
- <div id="views-line">
100
- ${this.viewsTemplate} ${this.ratingTemplate} ${this.reviewsTemplate}
101
- </div>
102
- ${this.topicsTemplate} ${this.collectionsTemplate}
103
- ${this.descriptionTemplate} ${this.textSnippetsTemplate}
94
+ return html `
95
+ ${this.itemLineTemplate} ${this.creatorTemplate}
96
+ <div id="dates-line">
97
+ ${this.datePublishedTemplate} ${this.dateSortByTemplate}
98
+ </div>
99
+ <div id="views-line">
100
+ ${this.viewsTemplate} ${this.ratingTemplate} ${this.reviewsTemplate}
101
+ </div>
102
+ ${this.topicsTemplate} ${this.collectionsTemplate}
103
+ ${this.descriptionTemplate} ${this.textSnippetsTemplate}
104
104
  `;
105
105
  }
106
106
  // Data templates
107
107
  get iconRightTemplate() {
108
108
  var _a, _b;
109
- return html `
110
- <div id="icon-right">
111
- <mediatype-icon
112
- .mediatype=${(_a = this.model) === null || _a === void 0 ? void 0 : _a.mediatype}
113
- .collections=${(_b = this.model) === null || _b === void 0 ? void 0 : _b.collections}
114
- >
115
- </mediatype-icon>
116
- </div>
109
+ return html `
110
+ <div id="icon-right">
111
+ <mediatype-icon
112
+ .mediatype=${(_a = this.model) === null || _a === void 0 ? void 0 : _a.mediatype}
113
+ .collections=${(_b = this.model) === null || _b === void 0 ? void 0 : _b.collections}
114
+ >
115
+ </mediatype-icon>
116
+ </div>
117
117
  `;
118
118
  }
119
119
  get titleTemplate() {
@@ -137,11 +137,11 @@ let TileList = class TileList extends LitElement {
137
137
  if (!((_a = this.model) === null || _a === void 0 ? void 0 : _a.source)) {
138
138
  return nothing;
139
139
  }
140
- return html `
141
- <div id="source" class="metadata">
142
- ${this.labelTemplate('Source')}
143
- ${this.searchLink('source', this.model.source)}
144
- </div>
140
+ return html `
141
+ <div id="source" class="metadata">
142
+ ${this.labelTemplate('Source')}
143
+ ${this.searchLink('source', this.model.source)}
144
+ </div>
145
145
  `;
146
146
  }
147
147
  get volumeTemplate() {
@@ -156,21 +156,21 @@ let TileList = class TileList extends LitElement {
156
156
  var _a, _b, _c;
157
157
  // "Achivist since" if account
158
158
  if (((_a = this.model) === null || _a === void 0 ? void 0 : _a.mediatype) === 'account') {
159
- return html `
160
- <div id="creator" class="metadata">
161
- <span class="label"> ${accountLabel((_b = this.model) === null || _b === void 0 ? void 0 : _b.dateAdded)} </span>
162
- </div>
159
+ return html `
160
+ <div id="creator" class="metadata">
161
+ <span class="label"> ${accountLabel((_b = this.model) === null || _b === void 0 ? void 0 : _b.dateAdded)} </span>
162
+ </div>
163
163
  `;
164
164
  }
165
165
  // "Creator" if not account tile
166
166
  if (!((_c = this.model) === null || _c === void 0 ? void 0 : _c.creators) || this.model.creators.length === 0) {
167
167
  return nothing;
168
168
  }
169
- return html `
170
- <div id="creator" class="metadata">
171
- ${this.labelTemplate('By')}
172
- ${join(map(this.model.creators, id => this.searchLink('creator', id)), html `, `)}
173
- </div>
169
+ return html `
170
+ <div id="creator" class="metadata">
171
+ ${this.labelTemplate('By')}
172
+ ${join(map(this.model.creators, id => this.searchLink('creator', id)), html `, `)}
173
+ </div>
174
174
  `;
175
175
  }
176
176
  get datePublishedTemplate() {
@@ -205,22 +205,22 @@ let TileList = class TileList extends LitElement {
205
205
  if (!((_a = this.model) === null || _a === void 0 ? void 0 : _a.subjects) || this.model.subjects.length === 0) {
206
206
  return nothing;
207
207
  }
208
- return html `
209
- <div id="topics" class="metadata">
210
- ${this.labelTemplate('Topics')}
211
- ${join(map(this.model.subjects, id => this.searchLink('subject', id)), html `, `)}
212
- </div>
208
+ return html `
209
+ <div id="topics" class="metadata">
210
+ ${this.labelTemplate('Topics')}
211
+ ${join(map(this.model.subjects, id => this.searchLink('subject', id)), html `, `)}
212
+ </div>
213
213
  `;
214
214
  }
215
215
  get collectionsTemplate() {
216
216
  if (!this.collectionLinks || this.collectionLinks.length === 0) {
217
217
  return nothing;
218
218
  }
219
- return html `
220
- <div id="collections" class="metadata">
221
- ${this.labelTemplate('Collections')}
222
- ${join(this.collectionLinks, html `, `)}
223
- </div>
219
+ return html `
220
+ <div id="collections" class="metadata">
221
+ ${this.labelTemplate('Collections')}
222
+ ${join(this.collectionLinks, html `, `)}
223
+ </div>
224
224
  `;
225
225
  }
226
226
  get descriptionTemplate() {
@@ -231,9 +231,9 @@ let TileList = class TileList extends LitElement {
231
231
  var _a;
232
232
  if (!this.hasSnippets)
233
233
  return nothing;
234
- return html `<text-snippet-block
235
- viewsize="list"
236
- .snippets=${(_a = this.model) === null || _a === void 0 ? void 0 : _a.snippets}
234
+ return html `<text-snippet-block
235
+ viewsize="list"
236
+ .snippets=${(_a = this.model) === null || _a === void 0 ? void 0 : _a.snippets}
237
237
  ></text-snippet-block>`;
238
238
  }
239
239
  get hasSnippets() {
@@ -245,10 +245,10 @@ let TileList = class TileList extends LitElement {
245
245
  metadataTemplate(text, label = '', id) {
246
246
  if (!text)
247
247
  return nothing;
248
- return html `
249
- <div id=${ifDefined(id)} class="metadata">
250
- ${this.labelTemplate(label)} ${text}
251
- </div>
248
+ return html `
249
+ <div id=${ifDefined(id)} class="metadata">
250
+ ${this.labelTemplate(label)} ${text}
251
+ </div>
252
252
  `;
253
253
  }
254
254
  labelTemplate(label) {
@@ -264,17 +264,17 @@ let TileList = class TileList extends LitElement {
264
264
  // No whitespace after closing tag
265
265
  // Note: single ' for href='' to wrap " in query var gets changed back by yarn format
266
266
  // eslint-disable-next-line lit/no-invalid-html
267
- return html `<a href="${this.baseNavigationUrl}/search.php?query=${query}">
268
- ${DOMPurify.sanitize(searchTerm)}</a
267
+ return html `<a href="${this.baseNavigationUrl}/search.php?query=${query}">
268
+ ${DOMPurify.sanitize(searchTerm)}</a
269
269
  >`;
270
270
  }
271
271
  detailsLink(identifier, text) {
272
272
  const linkText = text !== null && text !== void 0 ? text : identifier;
273
273
  // No whitespace after closing tag
274
274
  // identifiers (all ASCII in their creation) should be safe to use in href, but sanitize anyway
275
- return html `<a
276
- href="${this.baseNavigationUrl}/details/${encodeURI(identifier)}"
277
- >${DOMPurify.sanitize(linkText)}</a
275
+ return html `<a
276
+ href="${this.baseNavigationUrl}/details/${encodeURI(identifier)}"
277
+ >${DOMPurify.sanitize(linkText)}</a
278
278
  >`;
279
279
  }
280
280
  /*
@@ -312,123 +312,123 @@ let TileList = class TileList extends LitElement {
312
312
  return 'long';
313
313
  }
314
314
  static get styles() {
315
- return css `
316
- html {
317
- font-size: unset;
318
- }
319
-
320
- div {
321
- font-size: 14px;
322
- }
323
-
324
- div a {
325
- text-decoration: none;
326
- }
327
-
328
- .label {
329
- font-weight: bold;
330
- }
331
-
332
- #list-line.mobile {
333
- --infiniteScrollerRowGap: 20px;
334
- --infiniteScrollerRowHeight: auto;
335
- }
336
-
337
- #list-line.desktop {
338
- --infiniteScrollerRowGap: 30px;
339
- --infiniteScrollerRowHeight: auto;
340
- }
341
-
342
- /* fields */
343
- #icon-right {
344
- width: 20px;
345
- padding-top: 5px;
346
- --iconHeight: 20px;
347
- --iconWidth: 20px;
348
- --iconTextAlign: right;
349
- margin-top: -8px;
350
- text-align: right;
351
- }
352
-
353
- #title {
354
- color: #4b64ff;
355
- text-decoration: none;
356
- font-size: 22px;
357
- font-weight: bold;
358
- /* align top of text with image */
359
- line-height: 25px;
360
- margin-top: -4px;
361
- padding-bottom: 2px;
362
- flex-grow: 1;
363
- }
364
-
365
- .metadata {
366
- line-height: 20px;
367
- }
368
-
369
- #description,
370
- #creator,
371
- #topics,
372
- #source {
373
- text-align: left;
374
- overflow: hidden;
375
- text-overflow: ellipsis;
376
- -webkit-box-orient: vertical;
377
- display: -webkit-box;
378
- word-break: break-word;
379
- -webkit-line-clamp: 3; /* number of lines to show */
380
- line-clamp: 3;
381
- }
382
-
383
- #icon {
384
- padding-top: 5px;
385
- }
386
-
387
- #description {
388
- padding-top: 10px;
389
- }
390
-
391
- /* Top level container */
392
- #list-line {
393
- display: flex;
394
- }
395
-
396
- #list-line.mobile {
397
- flex-direction: column;
398
- }
399
-
400
- #list-line.desktop {
401
- column-gap: 10px;
402
- }
403
-
404
- #list-line-top {
405
- display: flex;
406
- column-gap: 7px;
407
- }
408
-
409
- #list-line-bottom {
410
- padding-top: 4px;
411
- }
412
-
413
- #list-line-right,
414
- #list-line-top,
415
- #list-line-bottom {
416
- width: 100%;
417
- }
418
-
419
- div a:hover {
420
- text-decoration: underline;
421
- }
422
-
423
- /* Lines containing multiple div as row */
424
- #item-line,
425
- #dates-line,
426
- #views-line,
427
- #title-line {
428
- display: flex;
429
- flex-direction: row;
430
- gap: 10px;
431
- }
315
+ return css `
316
+ html {
317
+ font-size: unset;
318
+ }
319
+
320
+ div {
321
+ font-size: 14px;
322
+ }
323
+
324
+ div a {
325
+ text-decoration: none;
326
+ }
327
+
328
+ .label {
329
+ font-weight: bold;
330
+ }
331
+
332
+ #list-line.mobile {
333
+ --infiniteScrollerRowGap: 20px;
334
+ --infiniteScrollerRowHeight: auto;
335
+ }
336
+
337
+ #list-line.desktop {
338
+ --infiniteScrollerRowGap: 30px;
339
+ --infiniteScrollerRowHeight: auto;
340
+ }
341
+
342
+ /* fields */
343
+ #icon-right {
344
+ width: 20px;
345
+ padding-top: 5px;
346
+ --iconHeight: 20px;
347
+ --iconWidth: 20px;
348
+ --iconTextAlign: right;
349
+ margin-top: -8px;
350
+ text-align: right;
351
+ }
352
+
353
+ #title {
354
+ color: #4b64ff;
355
+ text-decoration: none;
356
+ font-size: 22px;
357
+ font-weight: bold;
358
+ /* align top of text with image */
359
+ line-height: 25px;
360
+ margin-top: -4px;
361
+ padding-bottom: 2px;
362
+ flex-grow: 1;
363
+ }
364
+
365
+ .metadata {
366
+ line-height: 20px;
367
+ }
368
+
369
+ #description,
370
+ #creator,
371
+ #topics,
372
+ #source {
373
+ text-align: left;
374
+ overflow: hidden;
375
+ text-overflow: ellipsis;
376
+ -webkit-box-orient: vertical;
377
+ display: -webkit-box;
378
+ word-break: break-word;
379
+ -webkit-line-clamp: 3; /* number of lines to show */
380
+ line-clamp: 3;
381
+ }
382
+
383
+ #icon {
384
+ padding-top: 5px;
385
+ }
386
+
387
+ #description {
388
+ padding-top: 10px;
389
+ }
390
+
391
+ /* Top level container */
392
+ #list-line {
393
+ display: flex;
394
+ }
395
+
396
+ #list-line.mobile {
397
+ flex-direction: column;
398
+ }
399
+
400
+ #list-line.desktop {
401
+ column-gap: 10px;
402
+ }
403
+
404
+ #list-line-top {
405
+ display: flex;
406
+ column-gap: 7px;
407
+ }
408
+
409
+ #list-line-bottom {
410
+ padding-top: 4px;
411
+ }
412
+
413
+ #list-line-right,
414
+ #list-line-top,
415
+ #list-line-bottom {
416
+ width: 100%;
417
+ }
418
+
419
+ div a:hover {
420
+ text-decoration: underline;
421
+ }
422
+
423
+ /* Lines containing multiple div as row */
424
+ #item-line,
425
+ #dates-line,
426
+ #views-line,
427
+ #title-line {
428
+ display: flex;
429
+ flex-direction: row;
430
+ gap: 10px;
431
+ }
432
432
  `;
433
433
  }
434
434
  };