@internetarchive/collection-browser 2.7.2-alpha.2 → 2.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/collection-browser.d.ts +2 -0
- package/dist/src/collection-browser.js +59 -11
- package/dist/src/collection-browser.js.map +1 -1
- package/dist/src/collection-facets/smart-facets/dedupe.d.ts +10 -0
- package/dist/src/collection-facets/smart-facets/dedupe.js +34 -0
- package/dist/src/collection-facets/smart-facets/dedupe.js.map +1 -0
- package/dist/src/collection-facets/smart-facets/heuristics/browser-language-heuristic.d.ts +5 -0
- package/dist/src/collection-facets/smart-facets/heuristics/browser-language-heuristic.js +24 -0
- package/dist/src/collection-facets/smart-facets/heuristics/browser-language-heuristic.js.map +1 -0
- package/dist/src/collection-facets/smart-facets/heuristics/wikidata-heuristic.js +40 -2
- package/dist/src/collection-facets/smart-facets/heuristics/wikidata-heuristic.js.map +1 -1
- package/dist/src/collection-facets/smart-facets/models.d.ts +2 -0
- package/dist/src/collection-facets/smart-facets/models.js.map +1 -1
- package/dist/src/collection-facets/smart-facets/smart-facet-bar.d.ts +3 -0
- package/dist/src/collection-facets/smart-facets/smart-facet-bar.js +82 -40
- package/dist/src/collection-facets/smart-facets/smart-facet-bar.js.map +1 -1
- package/dist/src/collection-facets/smart-facets/smart-facet-button.d.ts +1 -0
- package/dist/src/collection-facets/smart-facets/smart-facet-button.js +10 -1
- package/dist/src/collection-facets/smart-facets/smart-facet-button.js.map +1 -1
- package/dist/src/collection-facets/smart-facets/smart-facet-dropdown.js +4 -2
- package/dist/src/collection-facets/smart-facets/smart-facet-dropdown.js.map +1 -1
- package/dist/src/collection-facets/smart-facets/smart-facet-equals.d.ts +1 -1
- package/dist/src/collection-facets/smart-facets/smart-facet-equals.js +3 -5
- package/dist/src/collection-facets/smart-facets/smart-facet-equals.js.map +1 -1
- package/dist/src/collection-facets/smart-facets/smart-facet-heuristics.d.ts +1 -9
- package/dist/src/collection-facets/smart-facets/smart-facet-heuristics.js +9 -20
- package/dist/src/collection-facets/smart-facets/smart-facet-heuristics.js.map +1 -1
- package/package.json +4 -4
- package/src/collection-browser.ts +60 -14
- package/src/collection-facets/smart-facets/dedupe.ts +43 -0
- package/src/collection-facets/smart-facets/heuristics/browser-language-heuristic.ts +27 -0
- package/src/collection-facets/smart-facets/heuristics/wikidata-heuristic.ts +40 -2
- package/src/collection-facets/smart-facets/models.ts +2 -0
- package/src/collection-facets/smart-facets/smart-facet-bar.ts +97 -48
- package/src/collection-facets/smart-facets/smart-facet-button.ts +11 -2
- package/src/collection-facets/smart-facets/smart-facet-dropdown.ts +20 -12
- package/src/collection-facets/smart-facets/smart-facet-equals.ts +8 -8
- package/src/collection-facets/smart-facets/smart-facet-heuristics.ts +12 -22
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"smart-facet-dropdown.js","sourceRoot":"","sources":["../../../../src/collection-facets/smart-facets/smart-facet-dropdown.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAkB,OAAO,EAAE,MAAM,KAAK,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAKnE,IAAa,kBAAkB,GAA/B,MAAa,kBAAmB,SAAQ,UAAU;IAShD,EAAE;IACF,8BAA8B;IAC9B,EAAE;IAEF,MAAM;;QACJ,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,cAAc;YAAE,OAAO,OAAO,CAAC;QAC5D,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,OAAO,CAAC;QAEhD,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"smart-facet-dropdown.js","sourceRoot":"","sources":["../../../../src/collection-facets/smart-facets/smart-facet-dropdown.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, LitElement, CSSResultGroup, nothing } from 'lit';\nimport { customElement, property, query } from 'lit/decorators.js';\nimport type { IaDropdown, optionInterface } from '@internetarchive/ia-dropdown';\nimport type { FacetRef, SmartFacet, SmartFacetEvent } from './models';\n\n@customElement('smart-facet-dropdown')\nexport class SmartFacetDropdown extends LitElement {\n @property({ type: Array }) facetInfo?: SmartFacet[];\n\n @property({ type: String }) labelPrefix?: string;\n\n @property({ type: Object }) activeFacetRef?: FacetRef;\n\n @query('ia-dropdown') dropdown?: IaDropdown;\n\n //\n // COMPONENT LIFECYCLE METHODS\n //\n\n render() {\n if (!this.facetInfo || !this.activeFacetRef) return nothing;\n if (this.facetInfo.length === 0) return nothing;\n\n const displayText =\n this.activeFacetRef.displayText ?? this.activeFacetRef.bucketKey;\n if (!displayText) return nothing;\n\n return html`\n <div class=\"dropdown-container\">\n <ia-dropdown\n class=\"dropdown\"\n displayCaret\n openViaButton\n closeOnSelect\n includeSelectedOption\n .options=${this.dropdownOptions}\n .selectedOption=${this.activeDropdownOption}\n @optionSelected=${this.optionSelected}\n >\n <span class=\"dropdown-label\" slot=\"dropdown-label\"\n >${this.labelPrefix ?? nothing} ${displayText}</span\n >\n </ia-dropdown>\n </div>\n `;\n }\n\n //\n // OTHER METHODS\n //\n\n private get dropdownOptions(): optionInterface[] {\n return (\n this.facetInfo?.map(smartFacet => {\n const firstFacet = smartFacet.facets[0];\n return {\n id: firstFacet.bucketKey,\n label:\n smartFacet.label ?? firstFacet.displayText ?? firstFacet.bucketKey,\n };\n }) ?? []\n );\n }\n\n private get activeDropdownOption(): optionInterface | undefined {\n if (!this.activeFacetRef) return undefined;\n return this.dropdownOptions.find(\n opt => opt.id === this.activeFacetRef?.bucketKey\n );\n }\n\n private optionSelected(e: CustomEvent<{ option: optionInterface }>): void {\n if (!this.facetInfo || !this.activeFacetRef) return;\n\n let selectedSmartFacet;\n for (const smartFacet of this.facetInfo) {\n const selectedRef = smartFacet.facets.find(\n b => b.bucketKey === e.detail.option.id\n );\n if (selectedRef) {\n this.activeFacetRef = selectedRef;\n selectedSmartFacet = smartFacet;\n }\n }\n\n if (!selectedSmartFacet) return;\n\n this.dispatchEvent(\n new CustomEvent<SmartFacetEvent>('facetClick', {\n detail: {\n smartFacet: selectedSmartFacet,\n details: [\n {\n facetType: this.activeFacetRef.facetType,\n bucket: {\n key: this.activeFacetRef.bucketKey,\n count: 0,\n state: 'selected',\n },\n negative: false,\n },\n ],\n },\n })\n );\n }\n\n //\n // STYLES\n //\n\n static get styles(): CSSResultGroup {\n return css`\n .dropdown-container {\n padding: 5px 8px;\n border-radius: 5px;\n background: #194880;\n color: white;\n font-size: 1.6rem;\n font-family: inherit;\n box-shadow: 1px 1px rgba(0, 0, 0, 0.4);\n }\n\n .dropdown-label {\n font-size: 1.6rem;\n font-family: inherit;\n }\n\n .dropdown {\n --dropdownBorderWidth: 5px;\n --dropdownBorderColor: transparent;\n --caretWidth: 14px;\n --caretHeight: 14px;\n }\n `;\n }\n}\n"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { SmartFacet } from
|
|
1
|
+
import type { SmartFacet } from './models';
|
|
2
2
|
export declare function smartFacetEquals(sf1: SmartFacet, sf2: SmartFacet): boolean;
|
|
@@ -3,13 +3,11 @@ function facetRefEquals(ref1, ref2) {
|
|
|
3
3
|
return ref2 !== undefined;
|
|
4
4
|
if (ref2 === undefined)
|
|
5
5
|
return ref1 !== undefined;
|
|
6
|
-
return ref1.facetType === ref2.facetType &&
|
|
7
|
-
ref1.bucketKey === ref2.bucketKey &&
|
|
8
|
-
ref1.displayText === ref2.displayText;
|
|
6
|
+
return ref1.facetType === ref2.facetType && ref1.bucketKey === ref2.bucketKey;
|
|
9
7
|
}
|
|
10
8
|
export function smartFacetEquals(sf1, sf2) {
|
|
11
|
-
return sf1.label === sf2.label &&
|
|
9
|
+
return (sf1.label === sf2.label &&
|
|
12
10
|
sf1.facets.length === sf2.facets.length &&
|
|
13
|
-
sf1.facets.every((sf, i) => facetRefEquals(sf, sf2.facets[i]));
|
|
11
|
+
sf1.facets.every((sf, i) => facetRefEquals(sf, sf2.facets[i])));
|
|
14
12
|
}
|
|
15
13
|
//# sourceMappingURL=smart-facet-equals.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"smart-facet-equals.js","sourceRoot":"","sources":["../../../../src/collection-facets/smart-facets/smart-facet-equals.ts"],"names":[],"mappings":"AAEA,SAAS,cAAc,CAAC,IAAe,EAAE,IAAe;IACtD,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,KAAK,SAAS,CAAC;IAClD,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,KAAK,SAAS,CAAC;IAElD,OAAO,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC,SAAS
|
|
1
|
+
{"version":3,"file":"smart-facet-equals.js","sourceRoot":"","sources":["../../../../src/collection-facets/smart-facets/smart-facet-equals.ts"],"names":[],"mappings":"AAEA,SAAS,cAAc,CAAC,IAAe,EAAE,IAAe;IACtD,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,KAAK,SAAS,CAAC;IAClD,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,KAAK,SAAS,CAAC;IAElD,OAAO,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC,SAAS,CAAC;AAChF,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,GAAe,EAAE,GAAe;IAC/D,OAAO,CACL,GAAG,CAAC,KAAK,KAAK,GAAG,CAAC,KAAK;QACvB,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,MAAM;QACvC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAC/D,CAAC;AACJ,CAAC","sourcesContent":["import type { FacetRef, SmartFacet } from './models';\n\nfunction facetRefEquals(ref1?: FacetRef, ref2?: FacetRef): boolean {\n if (ref1 === undefined) return ref2 !== undefined;\n if (ref2 === undefined) return ref1 !== undefined;\n\n return ref1.facetType === ref2.facetType && ref1.bucketKey === ref2.bucketKey;\n}\n\nexport function smartFacetEquals(sf1: SmartFacet, sf2: SmartFacet) {\n return (\n sf1.label === sf2.label &&\n sf1.facets.length === sf2.facets.length &&\n sf1.facets.every((sf, i) => facetRefEquals(sf, sf2.facets[i]))\n );\n}\n"]}
|
|
@@ -1,13 +1,5 @@
|
|
|
1
1
|
import type { SmartFacet, SmartQueryHeuristic } from './models';
|
|
2
2
|
export declare class SmartQueryHeuristicGroup implements SmartQueryHeuristic {
|
|
3
|
+
private static readonly HEURISTICS;
|
|
3
4
|
getRecommendedFacets(query: string): Promise<SmartFacet[]>;
|
|
4
|
-
/**
|
|
5
|
-
* Removes any duplicated smart facets from the given array.
|
|
6
|
-
* Smart facets are equal if they have the same `label` and same
|
|
7
|
-
* set of facet refs. Only the first occurrence of a given smart
|
|
8
|
-
* facet is kept.
|
|
9
|
-
* @param facets The array of smart facets to deduplicate
|
|
10
|
-
* @returns A new array containing the deduplicated set of facets
|
|
11
|
-
*/
|
|
12
|
-
private dedupe;
|
|
13
5
|
}
|
|
@@ -1,27 +1,16 @@
|
|
|
1
|
+
import { dedupe } from './dedupe';
|
|
2
|
+
import { BrowserLanguageHeuristic } from './heuristics/browser-language-heuristic';
|
|
1
3
|
import { QueryKeywordsHeuristic } from './heuristics/query-keywords-heuristic';
|
|
2
4
|
import { WikidataHeuristic } from './heuristics/wikidata-heuristic';
|
|
3
|
-
import { smartFacetEquals } from './smart-facet-equals';
|
|
4
5
|
export class SmartQueryHeuristicGroup {
|
|
5
6
|
async getRecommendedFacets(query) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
...(await new WikidataHeuristic().getRecommendedFacets(query)),
|
|
9
|
-
]);
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
* Removes any duplicated smart facets from the given array.
|
|
13
|
-
* Smart facets are equal if they have the same `label` and same
|
|
14
|
-
* set of facet refs. Only the first occurrence of a given smart
|
|
15
|
-
* facet is kept.
|
|
16
|
-
* @param facets The array of smart facets to deduplicate
|
|
17
|
-
* @returns A new array containing the deduplicated set of facets
|
|
18
|
-
*/
|
|
19
|
-
dedupe(facets) {
|
|
20
|
-
let result = [...facets];
|
|
21
|
-
for (const curFacet of facets) {
|
|
22
|
-
result = result.filter(sf => curFacet === sf || !smartFacetEquals(curFacet, sf));
|
|
23
|
-
}
|
|
24
|
-
return result;
|
|
7
|
+
const promises = SmartQueryHeuristicGroup.HEURISTICS.map(HeuristicCtor => new HeuristicCtor().getRecommendedFacets(query));
|
|
8
|
+
return dedupe((await Promise.all(promises)).flat());
|
|
25
9
|
}
|
|
26
10
|
}
|
|
11
|
+
SmartQueryHeuristicGroup.HEURISTICS = [
|
|
12
|
+
QueryKeywordsHeuristic,
|
|
13
|
+
WikidataHeuristic,
|
|
14
|
+
BrowserLanguageHeuristic,
|
|
15
|
+
];
|
|
27
16
|
//# sourceMappingURL=smart-facet-heuristics.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"smart-facet-heuristics.js","sourceRoot":"","sources":["../../../../src/collection-facets/smart-facets/smart-facet-heuristics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"smart-facet-heuristics.js","sourceRoot":"","sources":["../../../../src/collection-facets/smart-facets/smart-facet-heuristics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,wBAAwB,EAAE,MAAM,yCAAyC,CAAC;AACnF,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAC/E,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAGpE,MAAM,OAAO,wBAAwB;IAOnC,KAAK,CAAC,oBAAoB,CAAC,KAAa;QACtC,MAAM,QAAQ,GAAG,wBAAwB,CAAC,UAAU,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CACvE,IAAI,aAAa,EAAE,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAChD,CAAC;QAEF,OAAO,MAAM,CAAC,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACtD,CAAC;;AAZuB,mCAAU,GAAG;IACnC,sBAAsB;IACtB,iBAAiB;IACjB,wBAAwB;CACzB,CAAC","sourcesContent":["import { dedupe } from './dedupe';\nimport { BrowserLanguageHeuristic } from './heuristics/browser-language-heuristic';\nimport { QueryKeywordsHeuristic } from './heuristics/query-keywords-heuristic';\nimport { WikidataHeuristic } from './heuristics/wikidata-heuristic';\nimport type { SmartFacet, SmartQueryHeuristic } from './models';\n\nexport class SmartQueryHeuristicGroup implements SmartQueryHeuristic {\n private static readonly HEURISTICS = [\n QueryKeywordsHeuristic,\n WikidataHeuristic,\n BrowserLanguageHeuristic,\n ];\n\n async getRecommendedFacets(query: string): Promise<SmartFacet[]> {\n const promises = SmartQueryHeuristicGroup.HEURISTICS.map(HeuristicCtor =>\n new HeuristicCtor().getRecommendedFacets(query)\n );\n\n return dedupe((await Promise.all(promises)).flat());\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "The Internet Archive Collection Browser.",
|
|
4
4
|
"license": "AGPL-3.0-only",
|
|
5
5
|
"author": "Internet Archive",
|
|
6
|
-
"version": "2.7.2
|
|
6
|
+
"version": "2.7.2",
|
|
7
7
|
"main": "dist/index.js",
|
|
8
8
|
"module": "dist/index.js",
|
|
9
9
|
"scripts": {
|
|
@@ -31,10 +31,10 @@
|
|
|
31
31
|
"@internetarchive/ia-dropdown": "^1.3.8",
|
|
32
32
|
"@internetarchive/infinite-scroller": "1.0.1",
|
|
33
33
|
"@internetarchive/modal-manager": "^0.2.8",
|
|
34
|
-
"@internetarchive/search-service": "^1.4.
|
|
34
|
+
"@internetarchive/search-service": "^1.4.1",
|
|
35
35
|
"@internetarchive/shared-resize-observer": "^0.2.0",
|
|
36
36
|
"@lit/localize": "^0.11.2",
|
|
37
|
-
"dompurify": "^
|
|
37
|
+
"dompurify": "^3.1.7",
|
|
38
38
|
"eslint-plugin-lit": "^1.6.1",
|
|
39
39
|
"lit": "^2.2.2",
|
|
40
40
|
"typescript-cookie": "^1.0.3"
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"@internetarchive/result-type": "^0.0.1",
|
|
44
44
|
"@open-wc/eslint-config": "^8.0.2",
|
|
45
45
|
"@open-wc/testing": "^3.0.3",
|
|
46
|
-
"@types/dompurify": "^
|
|
46
|
+
"@types/dompurify": "^3.0.5",
|
|
47
47
|
"@typescript-eslint/eslint-plugin": "^5.3.1",
|
|
48
48
|
"@typescript-eslint/parser": "^5.3.1",
|
|
49
49
|
"@web/dev-server": "^0.1.28",
|
|
@@ -250,6 +250,9 @@ export class CollectionBrowser
|
|
|
250
250
|
/** Whether to replace the default sort options with a slot for customization (default: false) */
|
|
251
251
|
@property({ type: Boolean }) enableSortOptionsSlot = false;
|
|
252
252
|
|
|
253
|
+
/** Whether to display a smart results carousel above the full results */
|
|
254
|
+
@property({ type: Boolean, reflect: true }) showSmartResults = false;
|
|
255
|
+
|
|
253
256
|
/**
|
|
254
257
|
* The results per page so we can paginate.
|
|
255
258
|
*
|
|
@@ -615,7 +618,11 @@ export class CollectionBrowser
|
|
|
615
618
|
*/
|
|
616
619
|
private get desktopLeftColumnTemplate(): TemplateResult {
|
|
617
620
|
return html`
|
|
618
|
-
<div
|
|
621
|
+
<div
|
|
622
|
+
id="left-column"
|
|
623
|
+
class="column"
|
|
624
|
+
?hidden=${this.showSmartFacetBar && !this.facetPaneVisible}
|
|
625
|
+
>
|
|
619
626
|
${this.facetTopViewSlot}
|
|
620
627
|
<div id="facets-header-container">
|
|
621
628
|
<h2 id="facets-header" class="sr-only">Filters</h2>
|
|
@@ -671,18 +678,31 @@ export class CollectionBrowser
|
|
|
671
678
|
*/
|
|
672
679
|
private get rightColumnTemplate(): TemplateResult {
|
|
673
680
|
return html`
|
|
674
|
-
<div
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
${this.
|
|
679
|
-
?
|
|
680
|
-
: this.sortFilterBarTemplate}
|
|
681
|
-
<slot name="cb-results"></slot>
|
|
682
|
-
${this.displayMode === `list-compact` && this.totalResults
|
|
683
|
-
? this.listHeaderTemplate
|
|
681
|
+
<div
|
|
682
|
+
id="right-column"
|
|
683
|
+
class="column ${this.showSmartResults ? 'smart-results-spacing' : ''}"
|
|
684
|
+
>
|
|
685
|
+
${this.showSmartResults
|
|
686
|
+
? html`<slot name="smart-results"></slot>`
|
|
684
687
|
: nothing}
|
|
685
|
-
|
|
688
|
+
<section id="results">
|
|
689
|
+
${this.showSmartResults
|
|
690
|
+
? html`<h2 class="results-section-heading">
|
|
691
|
+
${msg('All results')}
|
|
692
|
+
</h2>`
|
|
693
|
+
: nothing}
|
|
694
|
+
<div id="cb-top-view">
|
|
695
|
+
<slot name="cb-top-slot"></slot>
|
|
696
|
+
</div>
|
|
697
|
+
${this.isManageView
|
|
698
|
+
? this.manageBarTemplate
|
|
699
|
+
: this.sortFilterBarTemplate}
|
|
700
|
+
<slot name="cb-results"></slot>
|
|
701
|
+
${this.displayMode === `list-compact` && this.totalResults
|
|
702
|
+
? this.listHeaderTemplate
|
|
703
|
+
: nothing}
|
|
704
|
+
${this.suppressResultTiles ? nothing : this.infiniteScrollerTemplate}
|
|
705
|
+
</section>
|
|
686
706
|
</div>
|
|
687
707
|
`;
|
|
688
708
|
}
|
|
@@ -2091,14 +2111,34 @@ export class CollectionBrowser
|
|
|
2091
2111
|
min-height: 90vh;
|
|
2092
2112
|
border-left: 1px solid rgb(232, 232, 232);
|
|
2093
2113
|
border-right: 1px solid rgb(232, 232, 232);
|
|
2094
|
-
padding-left: 1rem;
|
|
2095
|
-
padding-right: 1rem;
|
|
2096
2114
|
margin-top: var(--rightColumnMarginTop, 0);
|
|
2097
2115
|
background: #fff;
|
|
2098
2116
|
}
|
|
2099
2117
|
|
|
2118
|
+
#right-column.smart-results-spacing {
|
|
2119
|
+
padding-top: 0.5rem;
|
|
2120
|
+
border-right: none;
|
|
2121
|
+
background: transparent;
|
|
2122
|
+
min-width: 0;
|
|
2123
|
+
}
|
|
2124
|
+
|
|
2125
|
+
#results {
|
|
2126
|
+
background: #fff;
|
|
2127
|
+
padding-left: 1rem;
|
|
2128
|
+
padding-right: 1rem;
|
|
2129
|
+
}
|
|
2130
|
+
|
|
2131
|
+
#right-column.smart-results-spacing #results {
|
|
2132
|
+
border-radius: 10px 10px 0px 0px;
|
|
2133
|
+
padding-top: 0.5rem;
|
|
2134
|
+
margin-top: 1rem;
|
|
2135
|
+
}
|
|
2136
|
+
|
|
2100
2137
|
.mobile #right-column {
|
|
2101
2138
|
border-left: none;
|
|
2139
|
+
}
|
|
2140
|
+
|
|
2141
|
+
.mobile #results {
|
|
2102
2142
|
padding: 5px 5px 0;
|
|
2103
2143
|
}
|
|
2104
2144
|
|
|
@@ -2287,6 +2327,12 @@ export class CollectionBrowser
|
|
|
2287
2327
|
max-height: 2000px;
|
|
2288
2328
|
}
|
|
2289
2329
|
|
|
2330
|
+
.results-section-heading {
|
|
2331
|
+
margin: 0.5rem 0.3rem;
|
|
2332
|
+
font-size: 2rem;
|
|
2333
|
+
line-height: 25px;
|
|
2334
|
+
}
|
|
2335
|
+
|
|
2290
2336
|
#results-total {
|
|
2291
2337
|
display: flex;
|
|
2292
2338
|
align-items: baseline;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { SmartFacet } from './models';
|
|
2
|
+
import { smartFacetEquals } from './smart-facet-equals';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Removes any duplicated smart facets from the given array.
|
|
6
|
+
* Smart facets are equal if they have the same `label` and same
|
|
7
|
+
* set of facet refs. Only the first occurrence of a given smart
|
|
8
|
+
* facet is kept.
|
|
9
|
+
* @param facets The array of smart facets to deduplicate
|
|
10
|
+
* @returns A new array containing the deduplicated set of facets
|
|
11
|
+
*/
|
|
12
|
+
export function dedupe<T extends SmartFacet[] | SmartFacet[][]>(facets: T): T {
|
|
13
|
+
if (!Array.isArray(facets[0])) {
|
|
14
|
+
const facetsUnnested = facets as SmartFacet[];
|
|
15
|
+
|
|
16
|
+
let result: SmartFacet[] = [...facetsUnnested];
|
|
17
|
+
for (const curFacet of facetsUnnested) {
|
|
18
|
+
result = result.filter(
|
|
19
|
+
sf => curFacet === sf || !smartFacetEquals(curFacet, sf)
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return result as T;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const facetsNested = facets as SmartFacet[][];
|
|
27
|
+
|
|
28
|
+
const result: SmartFacet[][] = [];
|
|
29
|
+
for (const curFacetArray of facetsNested) {
|
|
30
|
+
const subresult: SmartFacet[] = [];
|
|
31
|
+
for (const curFacet of curFacetArray) {
|
|
32
|
+
const existing = result.find(sfa =>
|
|
33
|
+
sfa.find(sf => smartFacetEquals(curFacet, sf))
|
|
34
|
+
);
|
|
35
|
+
if (!existing) subresult.push(curFacet);
|
|
36
|
+
}
|
|
37
|
+
if (subresult.length > 0) {
|
|
38
|
+
result.push(subresult);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return result as T;
|
|
43
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { SmartQueryHeuristic, SmartFacet } from '../models';
|
|
2
|
+
|
|
3
|
+
export class BrowserLanguageHeuristic implements SmartQueryHeuristic {
|
|
4
|
+
async getRecommendedFacets(): Promise<SmartFacet[]> {
|
|
5
|
+
const browserLanguageCode = navigator.language;
|
|
6
|
+
const languageName =
|
|
7
|
+
BrowserLanguageHeuristic.getLanguageDisplayName(browserLanguageCode);
|
|
8
|
+
if (!languageName) return [];
|
|
9
|
+
|
|
10
|
+
return [
|
|
11
|
+
{
|
|
12
|
+
facets: [
|
|
13
|
+
{
|
|
14
|
+
facetType: 'language',
|
|
15
|
+
bucketKey: languageName,
|
|
16
|
+
},
|
|
17
|
+
],
|
|
18
|
+
},
|
|
19
|
+
];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
private static getLanguageDisplayName(langCode: string): string | undefined {
|
|
23
|
+
// Strip off any script/region/variant codes for greater generality
|
|
24
|
+
const languageOnly = langCode.split('-')[0];
|
|
25
|
+
return new Intl.DisplayNames(['en'], { type: 'language' }).of(languageOnly);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -15,7 +15,9 @@ import type {
|
|
|
15
15
|
// etc.
|
|
16
16
|
export class WikidataHeuristic implements SmartQueryHeuristic {
|
|
17
17
|
private static readonly ENTITIES: KeywordFacetMap = {
|
|
18
|
-
'written work': [
|
|
18
|
+
'written work': [
|
|
19
|
+
{ facets: [{ facetType: 'mediatype', bucketKey: 'texts' }] },
|
|
20
|
+
],
|
|
19
21
|
literature: [{ facets: [{ facetType: 'mediatype', bucketKey: 'texts' }] }],
|
|
20
22
|
book: [{ facets: [{ facetType: 'mediatype', bucketKey: 'texts' }] }],
|
|
21
23
|
novel: [{ facets: [{ facetType: 'mediatype', bucketKey: 'texts' }] }],
|
|
@@ -73,6 +75,24 @@ export class WikidataHeuristic implements SmartQueryHeuristic {
|
|
|
73
75
|
],
|
|
74
76
|
},
|
|
75
77
|
],
|
|
78
|
+
'visual artist': [
|
|
79
|
+
{
|
|
80
|
+
label: 'Images by __QUERY',
|
|
81
|
+
facets: [
|
|
82
|
+
{ facetType: 'mediatype', bucketKey: 'image' },
|
|
83
|
+
{ facetType: 'creator', bucketKey: '__QUERY' },
|
|
84
|
+
],
|
|
85
|
+
},
|
|
86
|
+
],
|
|
87
|
+
'graphic artist': [
|
|
88
|
+
{
|
|
89
|
+
label: 'Images by __QUERY',
|
|
90
|
+
facets: [
|
|
91
|
+
{ facetType: 'mediatype', bucketKey: 'image' },
|
|
92
|
+
{ facetType: 'creator', bucketKey: '__QUERY' },
|
|
93
|
+
],
|
|
94
|
+
},
|
|
95
|
+
],
|
|
76
96
|
singer: [
|
|
77
97
|
{
|
|
78
98
|
label: 'Music by __QUERY',
|
|
@@ -100,6 +120,24 @@ export class WikidataHeuristic implements SmartQueryHeuristic {
|
|
|
100
120
|
],
|
|
101
121
|
},
|
|
102
122
|
],
|
|
123
|
+
composer: [
|
|
124
|
+
{
|
|
125
|
+
label: 'Music by __QUERY',
|
|
126
|
+
facets: [
|
|
127
|
+
{ facetType: 'mediatype', bucketKey: 'audio' },
|
|
128
|
+
{ facetType: 'creator', bucketKey: '__QUERY' },
|
|
129
|
+
],
|
|
130
|
+
},
|
|
131
|
+
],
|
|
132
|
+
pianist: [
|
|
133
|
+
{
|
|
134
|
+
label: 'Music by __QUERY',
|
|
135
|
+
facets: [
|
|
136
|
+
{ facetType: 'mediatype', bucketKey: 'audio' },
|
|
137
|
+
{ facetType: 'creator', bucketKey: '__QUERY' },
|
|
138
|
+
],
|
|
139
|
+
},
|
|
140
|
+
],
|
|
103
141
|
};
|
|
104
142
|
|
|
105
143
|
async getRecommendedFacets(query: string): Promise<SmartFacet[]> {
|
|
@@ -116,7 +154,7 @@ export class WikidataHeuristic implements SmartQueryHeuristic {
|
|
|
116
154
|
for (const [keyword, facets] of Object.entries(
|
|
117
155
|
WikidataHeuristic.ENTITIES
|
|
118
156
|
)) {
|
|
119
|
-
const keywordRegex = new RegExp(
|
|
157
|
+
const keywordRegex = new RegExp(`\\b${keyword}\\b`);
|
|
120
158
|
if (keywordRegex.test(searchResults.search[0]?.description)) {
|
|
121
159
|
const entityName = searchResults.search[0].label;
|
|
122
160
|
recommendations.push(
|
|
@@ -9,11 +9,13 @@ export interface FacetRef {
|
|
|
9
9
|
interface LabeledSmartFacet {
|
|
10
10
|
label: string;
|
|
11
11
|
facets: FacetRef[];
|
|
12
|
+
selected?: boolean;
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
interface UnlabeledSmartFacet {
|
|
15
16
|
label?: string;
|
|
16
17
|
facets: [FacetRef];
|
|
18
|
+
selected?: boolean;
|
|
17
19
|
}
|
|
18
20
|
|
|
19
21
|
export type SmartFacet = LabeledSmartFacet | UnlabeledSmartFacet;
|