@internetarchive/collection-browser 4.4.1 → 4.5.1-alpha-webdev8221.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 +27 -27
- 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 +1 -1
- package/.prettierignore +1 -1
- package/LICENSE +661 -661
- package/README.md +83 -83
- package/dist/index.d.ts +1 -0
- package/dist/index.js.map +1 -1
- package/dist/src/app-root.d.ts +8 -0
- package/dist/src/app-root.js +26 -0
- package/dist/src/app-root.js.map +1 -1
- package/dist/src/collection-browser.d.ts +8 -4
- package/dist/src/collection-browser.js +20 -11
- package/dist/src/collection-browser.js.map +1 -1
- package/dist/src/collection-facets/facet-row.d.ts +6 -0
- package/dist/src/collection-facets/facet-row.js +19 -1
- package/dist/src/collection-facets/facet-row.js.map +1 -1
- package/dist/src/collection-facets/facets-template.js +2 -0
- package/dist/src/collection-facets/facets-template.js.map +1 -1
- package/dist/src/data-source/collection-browser-data-source-interface.d.ts +5 -0
- package/dist/src/data-source/collection-browser-data-source-interface.js.map +1 -1
- package/dist/src/data-source/collection-browser-data-source.d.ts +1 -1
- package/dist/src/data-source/collection-browser-data-source.js +8 -6
- package/dist/src/data-source/collection-browser-data-source.js.map +1 -1
- package/dist/src/restoration-state-handler.js +2 -4
- package/dist/src/restoration-state-handler.js.map +1 -1
- package/dist/src/styles/tile-action-styles.d.ts +14 -0
- package/dist/src/styles/tile-action-styles.js +59 -0
- package/dist/src/styles/tile-action-styles.js.map +1 -0
- package/dist/src/tiles/base-tile-component.d.ts +17 -1
- package/dist/src/tiles/base-tile-component.js +50 -1
- package/dist/src/tiles/base-tile-component.js.map +1 -1
- package/dist/src/tiles/grid/item-tile.js +1 -0
- package/dist/src/tiles/grid/item-tile.js.map +1 -1
- package/dist/src/tiles/list/tile-list-compact-header.js +27 -2
- package/dist/src/tiles/list/tile-list-compact-header.js.map +1 -1
- package/dist/src/tiles/list/tile-list-compact.d.ts +1 -1
- package/dist/src/tiles/list/tile-list-compact.js +113 -75
- package/dist/src/tiles/list/tile-list-compact.js.map +1 -1
- package/dist/src/tiles/list/tile-list.d.ts +1 -1
- package/dist/src/tiles/list/tile-list.js +164 -146
- package/dist/src/tiles/list/tile-list.js.map +1 -1
- package/dist/src/tiles/models.d.ts +11 -0
- package/dist/src/tiles/models.js.map +1 -1
- package/dist/src/tiles/tile-dispatcher.d.ts +14 -0
- package/dist/src/tiles/tile-dispatcher.js +107 -4
- package/dist/src/tiles/tile-dispatcher.js.map +1 -1
- package/dist/src/utils/date-filter-field.d.ts +6 -0
- package/dist/src/utils/date-filter-field.js +9 -0
- package/dist/src/utils/date-filter-field.js.map +1 -0
- package/dist/test/collection-browser.test.js +81 -0
- package/dist/test/collection-browser.test.js.map +1 -1
- package/dist/test/collection-facets/facet-row.test.js +32 -0
- package/dist/test/collection-facets/facet-row.test.js.map +1 -1
- package/eslint.config.mjs +53 -53
- package/index.html +24 -24
- package/index.ts +1 -0
- package/local.archive.org.cert +86 -86
- package/local.archive.org.key +27 -27
- package/package.json +120 -120
- package/renovate.json +6 -6
- package/src/app-root.ts +30 -0
- package/src/collection-browser.ts +17 -13
- package/src/collection-facets/facet-row.ts +11 -1
- package/src/collection-facets/facets-template.ts +2 -0
- package/src/data-source/collection-browser-data-source-interface.ts +6 -0
- package/src/data-source/collection-browser-data-source.ts +16 -7
- package/src/restoration-state-handler.ts +5 -5
- package/src/styles/tile-action-styles.ts +59 -0
- package/src/tiles/base-tile-component.ts +60 -1
- package/src/tiles/grid/item-tile.ts +1 -0
- package/src/tiles/list/tile-list-compact-header.ts +28 -2
- package/src/tiles/list/tile-list-compact.ts +114 -75
- package/src/tiles/list/tile-list.ts +190 -172
- package/src/tiles/models.ts +13 -0
- package/src/tiles/tile-dispatcher.ts +114 -4
- package/src/utils/date-filter-field.ts +11 -0
- package/test/collection-browser.test.ts +132 -0
- package/test/collection-facets/facet-row.test.ts +46 -0
- package/tsconfig.json +25 -25
- package/web-dev-server.config.mjs +30 -30
- package/web-test-runner.config.mjs +52 -52
package/package.json
CHANGED
|
@@ -1,120 +1,120 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@internetarchive/collection-browser",
|
|
3
|
-
"description": "The Internet Archive Collection Browser.",
|
|
4
|
-
"license": "AGPL-3.0-only",
|
|
5
|
-
"author": "Internet Archive",
|
|
6
|
-
"version": "4.
|
|
7
|
-
"main": "dist/index.js",
|
|
8
|
-
"module": "dist/index.js",
|
|
9
|
-
"scripts": {
|
|
10
|
-
"start": "vite",
|
|
11
|
-
"prepare:ghpages": "rimraf ghpages && yarn run prepare && vite build",
|
|
12
|
-
"prepare": "rimraf dist && tsc && husky install",
|
|
13
|
-
"lint": "eslint . && prettier \"**/*.ts\" --check",
|
|
14
|
-
"format": "eslint . --fix && prettier \"**/*.ts\" --write",
|
|
15
|
-
"circular": "madge --circular --extensions ts .",
|
|
16
|
-
"test": "tsc && yarn run lint && yarn run circular && wtr --coverage",
|
|
17
|
-
"test:fast": "tsc && wtr --coverage",
|
|
18
|
-
"test:watch": "tsc && concurrently -k -r \"tsc --watch --preserveWatchOutput\" \"wtr --watch\"",
|
|
19
|
-
"deploy": "yarn run deploy:run -e $(git branch --show-current)",
|
|
20
|
-
"deploy:run": "yarn run prepare:ghpages && touch ghpages/.nojekyll && yarn run deploy:gh",
|
|
21
|
-
"deploy:gh": "gh-pages -t -d ghpages -m \"Build for $(git log --pretty=format:\"%h %an %ai %s\" -n1) [skip ci]\"",
|
|
22
|
-
"typecheck": "yarn tsc --noEmit"
|
|
23
|
-
},
|
|
24
|
-
"types": "dist/index.d.ts",
|
|
25
|
-
"dependencies": {
|
|
26
|
-
"@a11y/focus-trap": "^1.0.5",
|
|
27
|
-
"@internetarchive/analytics-manager": "^0.1.4",
|
|
28
|
-
"@internetarchive/elements": "^0.2.2",
|
|
29
|
-
"@internetarchive/feature-feedback": "^1.0.0",
|
|
30
|
-
"@internetarchive/field-parsers": "^1.0.0",
|
|
31
|
-
"@internetarchive/histogram-date-range": "^1.4.2",
|
|
32
|
-
"@internetarchive/ia-dropdown": "^2.0.0",
|
|
33
|
-
"@internetarchive/iaux-item-metadata": "^1.0.5",
|
|
34
|
-
"@internetarchive/infinite-scroller": "^2.0.0",
|
|
35
|
-
"@internetarchive/modal-manager": "^2.0.5",
|
|
36
|
-
"@internetarchive/search-service": "2.7.2",
|
|
37
|
-
"@internetarchive/shared-resize-observer": "^0.2.0",
|
|
38
|
-
"@lit/localize": "^0.12.2",
|
|
39
|
-
"dompurify": "^3.2.4",
|
|
40
|
-
"lit": "^2.8.0 || ^3.3.2",
|
|
41
|
-
"typescript-cookie": "^1.0.6"
|
|
42
|
-
},
|
|
43
|
-
"devDependencies": {
|
|
44
|
-
"@internetarchive/result-type": "^0.0.1",
|
|
45
|
-
"@open-wc/eslint-config": "^13.0.0",
|
|
46
|
-
"@open-wc/testing": "^4.0.0",
|
|
47
|
-
"@rollup/plugin-image": "^3.0.3",
|
|
48
|
-
"@types/dompurify": "^3.2.0",
|
|
49
|
-
"@types/mocha": "^10.0.10",
|
|
50
|
-
"@typescript-eslint/eslint-plugin": "^8.27.0",
|
|
51
|
-
"@typescript-eslint/parser": "^8.27.0",
|
|
52
|
-
"@vitejs/plugin-basic-ssl": "^2.1.4",
|
|
53
|
-
"@web/dev-server": "^0.4.6",
|
|
54
|
-
"@web/dev-server-rollup": "^0.6.4",
|
|
55
|
-
"@web/test-runner": "^0.20.0",
|
|
56
|
-
"concurrently": "^9.1.2",
|
|
57
|
-
"eslint": "^9.22.0",
|
|
58
|
-
"eslint-config-prettier": "^10.1.1",
|
|
59
|
-
"eslint-plugin-html": "^8.1.2",
|
|
60
|
-
"eslint-plugin-import": "^2.31.0",
|
|
61
|
-
"eslint-plugin-lit": "^2.0.0",
|
|
62
|
-
"eslint-plugin-lit-a11y": "^5.0.0",
|
|
63
|
-
"eslint-plugin-no-only-tests": "^3.3.0",
|
|
64
|
-
"eslint-plugin-wc": "^3.0.0",
|
|
65
|
-
"gh-pages": "^6.3.0",
|
|
66
|
-
"husky": "^9.1.7",
|
|
67
|
-
"madge": "^8.0.0",
|
|
68
|
-
"prettier": "^3.5.3",
|
|
69
|
-
"rimraf": "^6.0.1",
|
|
70
|
-
"sinon": "^19.0.4",
|
|
71
|
-
"tslib": "^2.8.1",
|
|
72
|
-
"typescript": "^5.8.2",
|
|
73
|
-
"vite": "^8.0.0"
|
|
74
|
-
},
|
|
75
|
-
"publishConfig": {
|
|
76
|
-
"access": "public"
|
|
77
|
-
},
|
|
78
|
-
"eslintConfig": {
|
|
79
|
-
"parser": "@typescript-eslint/parser",
|
|
80
|
-
"extends": [
|
|
81
|
-
"@open-wc",
|
|
82
|
-
"prettier"
|
|
83
|
-
],
|
|
84
|
-
"plugins": [
|
|
85
|
-
"@typescript-eslint"
|
|
86
|
-
],
|
|
87
|
-
"rules": {
|
|
88
|
-
"no-unused-vars": "off",
|
|
89
|
-
"@typescript-eslint/no-unused-vars": [
|
|
90
|
-
"error"
|
|
91
|
-
],
|
|
92
|
-
"no-shadow": "off",
|
|
93
|
-
"@typescript-eslint/no-shadow": [
|
|
94
|
-
"error"
|
|
95
|
-
],
|
|
96
|
-
"class-methods-use-this": "off",
|
|
97
|
-
"import/no-unresolved": "off",
|
|
98
|
-
"import/extensions": [
|
|
99
|
-
"off",
|
|
100
|
-
"ignorePackages",
|
|
101
|
-
{
|
|
102
|
-
"js": "never",
|
|
103
|
-
"ts": "never"
|
|
104
|
-
}
|
|
105
|
-
],
|
|
106
|
-
"no-unsafe-optional-chaining": "warn",
|
|
107
|
-
"default-param-last": "warn"
|
|
108
|
-
}
|
|
109
|
-
},
|
|
110
|
-
"prettier": {
|
|
111
|
-
"singleQuote": true,
|
|
112
|
-
"arrowParens": "avoid"
|
|
113
|
-
},
|
|
114
|
-
"lint-staged": {
|
|
115
|
-
"*.ts": [
|
|
116
|
-
"eslint --fix",
|
|
117
|
-
"prettier --write"
|
|
118
|
-
]
|
|
119
|
-
}
|
|
120
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@internetarchive/collection-browser",
|
|
3
|
+
"description": "The Internet Archive Collection Browser.",
|
|
4
|
+
"license": "AGPL-3.0-only",
|
|
5
|
+
"author": "Internet Archive",
|
|
6
|
+
"version": "4.5.1-alpha-webdev8221.0",
|
|
7
|
+
"main": "dist/index.js",
|
|
8
|
+
"module": "dist/index.js",
|
|
9
|
+
"scripts": {
|
|
10
|
+
"start": "vite",
|
|
11
|
+
"prepare:ghpages": "rimraf ghpages && yarn run prepare && vite build",
|
|
12
|
+
"prepare": "rimraf dist && tsc && husky install",
|
|
13
|
+
"lint": "eslint . && prettier \"**/*.ts\" --check",
|
|
14
|
+
"format": "eslint . --fix && prettier \"**/*.ts\" --write",
|
|
15
|
+
"circular": "madge --circular --extensions ts .",
|
|
16
|
+
"test": "tsc && yarn run lint && yarn run circular && wtr --coverage",
|
|
17
|
+
"test:fast": "tsc && wtr --coverage",
|
|
18
|
+
"test:watch": "tsc && concurrently -k -r \"tsc --watch --preserveWatchOutput\" \"wtr --watch\"",
|
|
19
|
+
"deploy": "yarn run deploy:run -e $(git branch --show-current)",
|
|
20
|
+
"deploy:run": "yarn run prepare:ghpages && touch ghpages/.nojekyll && yarn run deploy:gh",
|
|
21
|
+
"deploy:gh": "gh-pages -t -d ghpages -m \"Build for $(git log --pretty=format:\"%h %an %ai %s\" -n1) [skip ci]\"",
|
|
22
|
+
"typecheck": "yarn tsc --noEmit"
|
|
23
|
+
},
|
|
24
|
+
"types": "dist/index.d.ts",
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@a11y/focus-trap": "^1.0.5",
|
|
27
|
+
"@internetarchive/analytics-manager": "^0.1.4",
|
|
28
|
+
"@internetarchive/elements": "^0.2.2",
|
|
29
|
+
"@internetarchive/feature-feedback": "^1.0.0",
|
|
30
|
+
"@internetarchive/field-parsers": "^1.0.0",
|
|
31
|
+
"@internetarchive/histogram-date-range": "^1.4.2",
|
|
32
|
+
"@internetarchive/ia-dropdown": "^2.0.0",
|
|
33
|
+
"@internetarchive/iaux-item-metadata": "^1.0.5",
|
|
34
|
+
"@internetarchive/infinite-scroller": "^2.0.0",
|
|
35
|
+
"@internetarchive/modal-manager": "^2.0.5",
|
|
36
|
+
"@internetarchive/search-service": "^2.7.2",
|
|
37
|
+
"@internetarchive/shared-resize-observer": "^0.2.0",
|
|
38
|
+
"@lit/localize": "^0.12.2",
|
|
39
|
+
"dompurify": "^3.2.4",
|
|
40
|
+
"lit": "^2.8.0 || ^3.3.2",
|
|
41
|
+
"typescript-cookie": "^1.0.6"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@internetarchive/result-type": "^0.0.1",
|
|
45
|
+
"@open-wc/eslint-config": "^13.0.0",
|
|
46
|
+
"@open-wc/testing": "^4.0.0",
|
|
47
|
+
"@rollup/plugin-image": "^3.0.3",
|
|
48
|
+
"@types/dompurify": "^3.2.0",
|
|
49
|
+
"@types/mocha": "^10.0.10",
|
|
50
|
+
"@typescript-eslint/eslint-plugin": "^8.27.0",
|
|
51
|
+
"@typescript-eslint/parser": "^8.27.0",
|
|
52
|
+
"@vitejs/plugin-basic-ssl": "^2.1.4",
|
|
53
|
+
"@web/dev-server": "^0.4.6",
|
|
54
|
+
"@web/dev-server-rollup": "^0.6.4",
|
|
55
|
+
"@web/test-runner": "^0.20.0",
|
|
56
|
+
"concurrently": "^9.1.2",
|
|
57
|
+
"eslint": "^9.22.0",
|
|
58
|
+
"eslint-config-prettier": "^10.1.1",
|
|
59
|
+
"eslint-plugin-html": "^8.1.2",
|
|
60
|
+
"eslint-plugin-import": "^2.31.0",
|
|
61
|
+
"eslint-plugin-lit": "^2.0.0",
|
|
62
|
+
"eslint-plugin-lit-a11y": "^5.0.0",
|
|
63
|
+
"eslint-plugin-no-only-tests": "^3.3.0",
|
|
64
|
+
"eslint-plugin-wc": "^3.0.0",
|
|
65
|
+
"gh-pages": "^6.3.0",
|
|
66
|
+
"husky": "^9.1.7",
|
|
67
|
+
"madge": "^8.0.0",
|
|
68
|
+
"prettier": "^3.5.3",
|
|
69
|
+
"rimraf": "^6.0.1",
|
|
70
|
+
"sinon": "^19.0.4",
|
|
71
|
+
"tslib": "^2.8.1",
|
|
72
|
+
"typescript": "^5.8.2",
|
|
73
|
+
"vite": "^8.0.0"
|
|
74
|
+
},
|
|
75
|
+
"publishConfig": {
|
|
76
|
+
"access": "public"
|
|
77
|
+
},
|
|
78
|
+
"eslintConfig": {
|
|
79
|
+
"parser": "@typescript-eslint/parser",
|
|
80
|
+
"extends": [
|
|
81
|
+
"@open-wc",
|
|
82
|
+
"prettier"
|
|
83
|
+
],
|
|
84
|
+
"plugins": [
|
|
85
|
+
"@typescript-eslint"
|
|
86
|
+
],
|
|
87
|
+
"rules": {
|
|
88
|
+
"no-unused-vars": "off",
|
|
89
|
+
"@typescript-eslint/no-unused-vars": [
|
|
90
|
+
"error"
|
|
91
|
+
],
|
|
92
|
+
"no-shadow": "off",
|
|
93
|
+
"@typescript-eslint/no-shadow": [
|
|
94
|
+
"error"
|
|
95
|
+
],
|
|
96
|
+
"class-methods-use-this": "off",
|
|
97
|
+
"import/no-unresolved": "off",
|
|
98
|
+
"import/extensions": [
|
|
99
|
+
"off",
|
|
100
|
+
"ignorePackages",
|
|
101
|
+
{
|
|
102
|
+
"js": "never",
|
|
103
|
+
"ts": "never"
|
|
104
|
+
}
|
|
105
|
+
],
|
|
106
|
+
"no-unsafe-optional-chaining": "warn",
|
|
107
|
+
"default-param-last": "warn"
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
"prettier": {
|
|
111
|
+
"singleQuote": true,
|
|
112
|
+
"arrowParens": "avoid"
|
|
113
|
+
},
|
|
114
|
+
"lint-staged": {
|
|
115
|
+
"*.ts": [
|
|
116
|
+
"eslint --fix",
|
|
117
|
+
"prettier --write"
|
|
118
|
+
]
|
|
119
|
+
}
|
|
120
|
+
}
|
package/renovate.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": [
|
|
3
|
-
"config:base",
|
|
4
|
-
":preserveSemverRanges"
|
|
5
|
-
]
|
|
6
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"extends": [
|
|
3
|
+
"config:base",
|
|
4
|
+
":preserveSemverRanges"
|
|
5
|
+
]
|
|
6
|
+
}
|
package/src/app-root.ts
CHANGED
|
@@ -384,6 +384,16 @@ export class AppRoot extends LitElement {
|
|
|
384
384
|
/>
|
|
385
385
|
<label for="enable-smart-facet-bar">Enable smart facet bar</label>
|
|
386
386
|
</div>
|
|
387
|
+
<div class="checkbox-control">
|
|
388
|
+
<input
|
|
389
|
+
type="checkbox"
|
|
390
|
+
id="enable-tile-actions"
|
|
391
|
+
@click=${this.tileActionsCheckboxChanged}
|
|
392
|
+
/>
|
|
393
|
+
<label for="enable-tile-actions"
|
|
394
|
+
>Enable tile action buttons</label
|
|
395
|
+
>
|
|
396
|
+
</div>
|
|
387
397
|
</fieldset>
|
|
388
398
|
|
|
389
399
|
<fieldset class="cb-visual-appearance">
|
|
@@ -584,6 +594,7 @@ export class AppRoot extends LitElement {
|
|
|
584
594
|
@manageModeChanged=${this.manageModeChanged}
|
|
585
595
|
@itemRemovalRequested=${this.handleItemRemovalRequest}
|
|
586
596
|
@itemManagerRequested=${this.handleItemManagerRequest}
|
|
597
|
+
@tileActionClicked=${this.handleTileActionClicked}
|
|
587
598
|
>
|
|
588
599
|
${this.toggleSlots
|
|
589
600
|
? html`<div slot="sortbar-left-slot">Sort Slot</div>`
|
|
@@ -805,6 +816,25 @@ export class AppRoot extends LitElement {
|
|
|
805
816
|
this.collectionBrowser.showSmartFacetBar = target.checked;
|
|
806
817
|
}
|
|
807
818
|
|
|
819
|
+
/**
|
|
820
|
+
* Handler for when the dev panel's "Enable tile action buttons" checkbox is changed.
|
|
821
|
+
*/
|
|
822
|
+
private tileActionsCheckboxChanged(e: Event) {
|
|
823
|
+
const target = e.target as HTMLInputElement;
|
|
824
|
+
this.collectionBrowser.tileActions = target.checked
|
|
825
|
+
? [{ id: 'demo-action', label: 'Return' }]
|
|
826
|
+
: [];
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
/**
|
|
830
|
+
* Handler for tile action button clicks (logs to console for QA).
|
|
831
|
+
*/
|
|
832
|
+
private handleTileActionClicked(
|
|
833
|
+
e: CustomEvent<{ actionId: string; model: unknown }>,
|
|
834
|
+
) {
|
|
835
|
+
console.log('Tile action clicked:', e.detail.actionId, e.detail.model);
|
|
836
|
+
}
|
|
837
|
+
|
|
808
838
|
/**
|
|
809
839
|
* Handler for when the dev panel's "Show facet top slot" checkbox is changed.
|
|
810
840
|
*/
|
|
@@ -78,6 +78,7 @@ import { sha1 } from './utils/sha1';
|
|
|
78
78
|
import type { PlaceholderType } from './empty-placeholder';
|
|
79
79
|
import type { ManageBar } from './manage/manage-bar';
|
|
80
80
|
import type { SmartFacetBar } from './collection-facets/smart-facets/smart-facet-bar';
|
|
81
|
+
import type { LayoutType, TileAction } from './tiles/models';
|
|
81
82
|
|
|
82
83
|
import '@internetarchive/elements/ia-combo-box/ia-combo-box';
|
|
83
84
|
import './empty-placeholder';
|
|
@@ -297,6 +298,15 @@ export class CollectionBrowser
|
|
|
297
298
|
*/
|
|
298
299
|
@property({ type: Boolean }) isManageView = false;
|
|
299
300
|
|
|
301
|
+
/** Action buttons to display on each tile */
|
|
302
|
+
@property({ type: Array }) tileActions: TileAction[] = [];
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* The simplified layout to apply to grid-mode tiles, if any. See
|
|
306
|
+
* `LayoutType` for available options. Has no effect on list display modes.
|
|
307
|
+
*/
|
|
308
|
+
@property({ type: String }) tileLayoutType: LayoutType = 'default';
|
|
309
|
+
|
|
300
310
|
@property({ type: String }) manageViewLabel = 'Select items to remove';
|
|
301
311
|
|
|
302
312
|
/** Whether to replace the default sort options with a slot for customization (default: false) */
|
|
@@ -1652,6 +1662,7 @@ export class CollectionBrowser
|
|
|
1652
1662
|
.mobileBreakpoint=${this.mobileBreakpoint}
|
|
1653
1663
|
.loggedIn=${this.loggedIn}
|
|
1654
1664
|
.suppressBlurring=${this.shouldSuppressTileBlurring}
|
|
1665
|
+
.tileActions=${this.tileActions}
|
|
1655
1666
|
>
|
|
1656
1667
|
</tile-dispatcher>
|
|
1657
1668
|
</div>
|
|
@@ -1673,21 +1684,10 @@ export class CollectionBrowser
|
|
|
1673
1684
|
this.analyticsHandler?.sendEvent({
|
|
1674
1685
|
category: this.searchContext,
|
|
1675
1686
|
action: analyticsActions.histogramChanged,
|
|
1676
|
-
label: this.dateRangeQueryClause,
|
|
1687
|
+
label: this.dataSource.dateRangeQueryClause,
|
|
1677
1688
|
});
|
|
1678
1689
|
}
|
|
1679
1690
|
|
|
1680
|
-
/**
|
|
1681
|
-
* The Lucene query corresponding to the current date range.
|
|
1682
|
-
*/
|
|
1683
|
-
private get dateRangeQueryClause() {
|
|
1684
|
-
if (!this.minSelectedDate || !this.maxSelectedDate) {
|
|
1685
|
-
return undefined;
|
|
1686
|
-
}
|
|
1687
|
-
|
|
1688
|
-
return `year:[${this.minSelectedDate} TO ${this.maxSelectedDate}]`;
|
|
1689
|
-
}
|
|
1690
|
-
|
|
1691
1691
|
/**
|
|
1692
1692
|
* Emits an event indicating a change in whether the manage mode is shown.
|
|
1693
1693
|
*/
|
|
@@ -1801,7 +1801,9 @@ export class CollectionBrowser
|
|
|
1801
1801
|
changed.has('displayMode') ||
|
|
1802
1802
|
changed.has('baseNavigationUrl') ||
|
|
1803
1803
|
changed.has('baseImageUrl') ||
|
|
1804
|
-
changed.has('loggedIn')
|
|
1804
|
+
changed.has('loggedIn') ||
|
|
1805
|
+
changed.has('tileActions') ||
|
|
1806
|
+
changed.has('tileLayoutType')
|
|
1805
1807
|
) {
|
|
1806
1808
|
this.infiniteScroller?.reload();
|
|
1807
1809
|
}
|
|
@@ -2635,6 +2637,8 @@ export class CollectionBrowser
|
|
|
2635
2637
|
.loggedIn=${this.loggedIn}
|
|
2636
2638
|
.suppressBlurring=${this.shouldSuppressTileBlurring}
|
|
2637
2639
|
.isManageView=${this.isManageView}
|
|
2640
|
+
.tileActions=${this.tileActions}
|
|
2641
|
+
.layoutType=${this.tileLayoutType}
|
|
2638
2642
|
?showTvClips=${isTVSearch || isTVCollection}
|
|
2639
2643
|
?enableHoverPane=${true}
|
|
2640
2644
|
?useLocalTime=${shouldUseLocalTime}
|
|
@@ -30,6 +30,13 @@ export class FacetRow extends LitElement {
|
|
|
30
30
|
/** The facet bucket containing details about the state, count, and key for this row */
|
|
31
31
|
@property({ type: Object }) bucket?: FacetBucket;
|
|
32
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Whether to omit the negative/hide button from this facet row if possible.
|
|
35
|
+
* Has no effect if the facet bucket is itself hidden, in which case the hide
|
|
36
|
+
* button *must* be shown to represent the state accurately.
|
|
37
|
+
*/
|
|
38
|
+
@property({ type: Boolean, reflect: true }) omitHideButton = false;
|
|
39
|
+
|
|
33
40
|
/** The collection name cache for converting collection identifiers to titles */
|
|
34
41
|
@property({ type: Object })
|
|
35
42
|
collectionTitles?: CollectionTitles;
|
|
@@ -102,7 +109,10 @@ export class FacetRow extends LitElement {
|
|
|
102
109
|
id=${showOnlyCheckboxId}
|
|
103
110
|
data-testid=${showOnlyCheckboxId}
|
|
104
111
|
/>
|
|
105
|
-
<div
|
|
112
|
+
<div
|
|
113
|
+
class="hide-facet-container"
|
|
114
|
+
?hidden=${this.omitHideButton && !facetHidden}
|
|
115
|
+
>
|
|
106
116
|
<input
|
|
107
117
|
type="checkbox"
|
|
108
118
|
id=${negativeCheckboxId}
|
|
@@ -36,6 +36,7 @@ export class FacetsTemplate extends LitElement {
|
|
|
36
36
|
if (!facetGroup) return nothing;
|
|
37
37
|
|
|
38
38
|
const facetBuckets = facetGroup.buckets as FacetBucket[];
|
|
39
|
+
const isLoneBucket = facetBuckets.length === 1;
|
|
39
40
|
|
|
40
41
|
// Added data-testid for Playwright testing
|
|
41
42
|
// Using className and aria-labels is not ideal for Playwright locator
|
|
@@ -49,6 +50,7 @@ export class FacetsTemplate extends LitElement {
|
|
|
49
50
|
.facetType=${facetGroup.key}
|
|
50
51
|
.bucket=${bucket}
|
|
51
52
|
.collectionTitles=${this.collectionTitles}
|
|
53
|
+
?omitHideButton=${isLoneBucket}
|
|
52
54
|
@facetClick=${this.facetClicked}
|
|
53
55
|
></facet-row>`,
|
|
54
56
|
)}
|
|
@@ -71,6 +71,12 @@ export interface CollectionBrowserDataSourceInterface
|
|
|
71
71
|
*/
|
|
72
72
|
readonly pageSpecifierParams: PageSpecifierParams | null;
|
|
73
73
|
|
|
74
|
+
/**
|
|
75
|
+
* The Lucene query clause corresponding to the current date range,
|
|
76
|
+
* e.g. `year:[2000 TO 2020]` or `date:[2020-01 TO 2020-12]`.
|
|
77
|
+
*/
|
|
78
|
+
readonly dateRangeQueryClause: string | undefined;
|
|
79
|
+
|
|
74
80
|
/**
|
|
75
81
|
* A FilterMap object representing all filters applied to the current search,
|
|
76
82
|
* including any facets, letter filters, and date ranges.
|
|
@@ -33,6 +33,7 @@ import type { CollectionBrowserDataSourceInterface } from './collection-browser-
|
|
|
33
33
|
import type { CollectionBrowserSearchInterface } from './collection-browser-query-state';
|
|
34
34
|
import { sha1 } from '../utils/sha1';
|
|
35
35
|
import { mergeSelectedFacets } from '../utils/facet-utils';
|
|
36
|
+
import { dateFilterField } from '../utils/date-filter-field';
|
|
36
37
|
|
|
37
38
|
export class CollectionBrowserDataSource
|
|
38
39
|
implements CollectionBrowserDataSourceInterface
|
|
@@ -746,7 +747,10 @@ export class CollectionBrowserDataSource
|
|
|
746
747
|
selectedCreatorFilter,
|
|
747
748
|
} = this.host;
|
|
748
749
|
|
|
749
|
-
const dateField =
|
|
750
|
+
const dateField = dateFilterField(
|
|
751
|
+
this.host.minSelectedDate,
|
|
752
|
+
this.host.maxSelectedDate,
|
|
753
|
+
);
|
|
750
754
|
|
|
751
755
|
if (minSelectedDate) {
|
|
752
756
|
builder.addFilter(
|
|
@@ -901,12 +905,16 @@ export class CollectionBrowserDataSource
|
|
|
901
905
|
return this.joinFacetClauses(facetClauses)?.trim();
|
|
902
906
|
}
|
|
903
907
|
|
|
904
|
-
|
|
908
|
+
get dateRangeQueryClause(): string | undefined {
|
|
905
909
|
if (!this.host.minSelectedDate || !this.host.maxSelectedDate) {
|
|
906
910
|
return undefined;
|
|
907
911
|
}
|
|
908
912
|
|
|
909
|
-
|
|
913
|
+
const dateField = dateFilterField(
|
|
914
|
+
this.host.minSelectedDate,
|
|
915
|
+
this.host.maxSelectedDate,
|
|
916
|
+
);
|
|
917
|
+
return `${dateField}:[${this.host.minSelectedDate} TO ${this.host.maxSelectedDate}]`;
|
|
910
918
|
}
|
|
911
919
|
|
|
912
920
|
private get sortFilterQueries(): string {
|
|
@@ -1069,10 +1077,11 @@ export class CollectionBrowserDataSource
|
|
|
1069
1077
|
success.response;
|
|
1070
1078
|
this.aggregations = aggregations;
|
|
1071
1079
|
|
|
1072
|
-
|
|
1073
|
-
this.host.searchType === SearchType.TV
|
|
1074
|
-
|
|
1075
|
-
|
|
1080
|
+
const useDateHistogram =
|
|
1081
|
+
this.host.searchType === SearchType.TV || this.host.isTVCollection;
|
|
1082
|
+
this.histogramAggregation = useDateHistogram
|
|
1083
|
+
? (aggregations?.date_histogram ?? aggregations?.year_histogram)
|
|
1084
|
+
: aggregations?.year_histogram;
|
|
1076
1085
|
|
|
1077
1086
|
if (collectionTitles) {
|
|
1078
1087
|
for (const [id, title] of Object.entries(collectionTitles)) {
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
tvClipURLParamsToFilters,
|
|
15
15
|
} from './models';
|
|
16
16
|
import { arrayEquals } from './utils/array-equals';
|
|
17
|
+
import { dateFilterField } from './utils/date-filter-field';
|
|
17
18
|
|
|
18
19
|
export interface RestorationState {
|
|
19
20
|
displayMode?: CollectionDisplayMode;
|
|
@@ -190,11 +191,10 @@ export class RestorationStateHandler
|
|
|
190
191
|
}
|
|
191
192
|
}
|
|
192
193
|
|
|
193
|
-
const dateField =
|
|
194
|
-
state.minSelectedDate
|
|
195
|
-
state.maxSelectedDate
|
|
196
|
-
|
|
197
|
-
: 'year';
|
|
194
|
+
const dateField = dateFilterField(
|
|
195
|
+
state.minSelectedDate,
|
|
196
|
+
state.maxSelectedDate,
|
|
197
|
+
);
|
|
198
198
|
|
|
199
199
|
if (state.minSelectedDate && state.maxSelectedDate) {
|
|
200
200
|
newParams.append(
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { css } from 'lit';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Shared styles for tile action buttons rendered in grid, list-detail, and
|
|
5
|
+
* list-compact display modes. Layout positioning is handled by each tile
|
|
6
|
+
* component; these styles cover only the button appearance and the row
|
|
7
|
+
* container's default flex behavior.
|
|
8
|
+
*
|
|
9
|
+
* Customizable via CSS custom properties:
|
|
10
|
+
* - `--tileActionColor` (defaults to --primaryErrorCTAFill, then #d9534f)
|
|
11
|
+
* - `--tileActionBg` (default: #fff)
|
|
12
|
+
* - `--tileActionBorderColor` (defaults to --primaryErrorCTAFill, then #d9534f)
|
|
13
|
+
* - `--tileActionHoverBg` (defaults to --primaryErrorCTAFillRGB at 20% alpha)
|
|
14
|
+
* - `--tileActionHoverColor` (defaults to --tileActionColor)
|
|
15
|
+
*/
|
|
16
|
+
export const tileActionStyles = css`
|
|
17
|
+
.tile-actions {
|
|
18
|
+
flex-shrink: 0;
|
|
19
|
+
display: flex;
|
|
20
|
+
gap: var(--tileActionGap, 0);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.tile-action-btn {
|
|
24
|
+
flex: 1;
|
|
25
|
+
padding: 6px 5px;
|
|
26
|
+
border: 2px solid
|
|
27
|
+
var(--tileActionBorderColor, var(--primaryErrorCTAFill, #d9534f));
|
|
28
|
+
border-radius: var(--tileActionBorderRadius, 0);
|
|
29
|
+
/* Inherit from the surrounding tile rather than the UA default for <button> */
|
|
30
|
+
font-family: inherit;
|
|
31
|
+
font-size: 1.2rem;
|
|
32
|
+
font-weight: bold;
|
|
33
|
+
cursor: pointer;
|
|
34
|
+
color: var(--tileActionColor, var(--primaryErrorCTAFill, #d9534f));
|
|
35
|
+
background: var(--tileActionBg, #fff);
|
|
36
|
+
transition:
|
|
37
|
+
background 0.15s,
|
|
38
|
+
color 0.15s;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/*
|
|
42
|
+
* When buttons are flush against each other (no gap), overlap their shared
|
|
43
|
+
* edge by 1px so adjacent borders don't double up.
|
|
44
|
+
*/
|
|
45
|
+
.tile-action-btn + .tile-action-btn {
|
|
46
|
+
margin-left: -1px;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.tile-action-btn:hover {
|
|
50
|
+
background: var(
|
|
51
|
+
--tileActionHoverBg,
|
|
52
|
+
rgba(var(--primaryErrorCTAFillRGB, 229, 28, 38), 0.2)
|
|
53
|
+
);
|
|
54
|
+
color: var(
|
|
55
|
+
--tileActionHoverColor,
|
|
56
|
+
var(--tileActionColor, var(--primaryErrorCTAFill, #d9534f))
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
`;
|
|
@@ -1,13 +1,18 @@
|
|
|
1
|
-
import { LitElement, PropertyValues } from 'lit';
|
|
1
|
+
import { html, LitElement, nothing, PropertyValues, TemplateResult } from 'lit';
|
|
2
2
|
import { property } from 'lit/decorators.js';
|
|
3
|
+
import { classMap } from 'lit/directives/class-map.js';
|
|
3
4
|
import type { SortParam } from '@internetarchive/search-service';
|
|
4
5
|
import { TileDisplayValueProvider } from './tile-display-value-provider';
|
|
5
6
|
import type { TileModel } from '../models';
|
|
6
7
|
import { DateFormat, formatDate } from '../utils/format-date';
|
|
8
|
+
import type { TileAction } from './models';
|
|
7
9
|
|
|
8
10
|
export abstract class BaseTileComponent extends LitElement {
|
|
9
11
|
@property({ type: Object }) model?: TileModel;
|
|
10
12
|
|
|
13
|
+
/** Action buttons to display on this tile (rendered by subclasses) */
|
|
14
|
+
@property({ type: Array }) tileActions: TileAction[] = [];
|
|
15
|
+
|
|
11
16
|
@property({ type: Number }) currentWidth?: number;
|
|
12
17
|
|
|
13
18
|
@property({ type: Number }) currentHeight?: number;
|
|
@@ -62,4 +67,58 @@ export abstract class BaseTileComponent extends LitElement {
|
|
|
62
67
|
const { useLocalTime } = this;
|
|
63
68
|
return formatDate(date, format, { useLocalTime });
|
|
64
69
|
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Renders the action buttons configured for this tile, or `nothing` if
|
|
73
|
+
* there are none. Optional `extraClass` is appended to the container's
|
|
74
|
+
* class list so subclasses can target their own layout tweaks.
|
|
75
|
+
*/
|
|
76
|
+
protected renderTileActions(
|
|
77
|
+
extraClass: string = '',
|
|
78
|
+
): TemplateResult | typeof nothing {
|
|
79
|
+
if (!this.tileActions.length) return nothing;
|
|
80
|
+
|
|
81
|
+
const containerClasses = classMap({
|
|
82
|
+
'tile-actions': true,
|
|
83
|
+
...(extraClass && { [extraClass]: true }),
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
return html`
|
|
87
|
+
<div class=${containerClasses}>
|
|
88
|
+
${this.tileActions.map(
|
|
89
|
+
action => html`
|
|
90
|
+
<button
|
|
91
|
+
class="tile-action-btn"
|
|
92
|
+
@click=${(e: Event) => this.handleTileActionClick(e, action)}
|
|
93
|
+
>
|
|
94
|
+
${action.label}
|
|
95
|
+
</button>
|
|
96
|
+
`,
|
|
97
|
+
)}
|
|
98
|
+
</div>
|
|
99
|
+
`;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Click handler for tile action buttons. Stops propagation so the click
|
|
104
|
+
* doesn't activate a wrapping tile link, and dispatches a
|
|
105
|
+
* `tileActionClicked` event (bubbling + composed) carrying the action ID
|
|
106
|
+
* and the tile model.
|
|
107
|
+
*/
|
|
108
|
+
protected handleTileActionClick(e: Event, action: TileAction): void {
|
|
109
|
+
e.preventDefault();
|
|
110
|
+
e.stopPropagation();
|
|
111
|
+
// Pre-set the hover pane controller's clicking flag so that focus
|
|
112
|
+
// restoration after a consumer-opened modal won't trigger the hover pane.
|
|
113
|
+
this.dispatchEvent(
|
|
114
|
+
new PointerEvent('pointerdown', { bubbles: true, composed: true }),
|
|
115
|
+
);
|
|
116
|
+
this.dispatchEvent(
|
|
117
|
+
new CustomEvent('tileActionClicked', {
|
|
118
|
+
detail: { actionId: action.id, model: this.model },
|
|
119
|
+
bubbles: true,
|
|
120
|
+
composed: true,
|
|
121
|
+
}),
|
|
122
|
+
);
|
|
123
|
+
}
|
|
65
124
|
}
|
|
@@ -24,6 +24,7 @@ export class ItemTile extends BaseTileComponent {
|
|
|
24
24
|
/*
|
|
25
25
|
* Reactive properties inherited from BaseTileComponent:
|
|
26
26
|
* - model?: TileModel;
|
|
27
|
+
* - tileActions: TileAction[] = [];
|
|
27
28
|
* - currentWidth?: number;
|
|
28
29
|
* - currentHeight?: number;
|
|
29
30
|
* - baseNavigationUrl?: string;
|