Skip to content

Commit 56edbc9

Browse files
authored
WEBDEV-7090: Style and event updates for federated search (#450)
* Update styling of smart bubbles/dropdowns * Further styling changes * Add more close attrs to dropdowns * Lowercase creator heuristic bucket keys * Add results header property * Omit mediatype smart facets * Add label to smart bubbles * Only show label when there are > 0 smart facets * Hide smart facets if query is cleared * Upgrade search-service to alpha version * Add method to refresh smart facets * Fix alignment/padding on dropdown entries * Version fix * Adjust smart facet bar styling & update cycle * Emit event when facet pane visibility changes * Suppress mediatype-only facets from heuristics * Add missing unit test * Upgrade off alpha search-service
1 parent ace707a commit 56edbc9

File tree

9 files changed

+157
-77
lines changed

9 files changed

+157
-77
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
"@internetarchive/iaux-item-metadata": "^1.0.4",
3333
"@internetarchive/infinite-scroller": "^1.0.1",
3434
"@internetarchive/modal-manager": "^2.0.1",
35-
"@internetarchive/search-service": "^2.0.0",
35+
"@internetarchive/search-service": "^2.1.0",
3636
"@internetarchive/shared-resize-observer": "^0.2.0",
3737
"@lit/localize": "^0.12.2",
3838
"dompurify": "^3.2.4",
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { svg } from 'lit';
2+
3+
export default svg`
4+
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><path d="m50 0c27.6142375 0 50 22.3857625 50 50s-22.3857625 50-50 50-50-22.3857625-50-50 22.3857625-50 50-50zm23.8159475 26.1840525c-1.4033215-1.4033215-3.5816761-1.5592461-5.1572272-.4677738l-.5598841.4677738-18.0988362 18.0989475-18.0988362-18.0989475-.5598841-.4677738c-1.5755511-1.0914723-3.7539057-.9355477-5.1572272.4677738-1.5787367 1.5787367-1.5787367 4.1383746 0 5.7171113l18.0989475 18.0988362-18.0989475 18.0988362c-1.5787367 1.5787367-1.5787367 4.1383746 0 5.7171113 1.4033215 1.4033215 3.5816761 1.5592461 5.1572272.4677738l.5598841-.4677738 18.0988362-18.0989475 18.0988362 18.0989475.5598841.4677738c1.5755511 1.0914723 3.7539057.9355477 5.1572272-.4677738 1.5787367-1.5787367 1.5787367-4.1383746 0-5.7171113l-18.0989475-18.0988362 18.0989475-18.0988362c1.5787367-1.5787367 1.5787367-4.1383746 0-5.7171113z" fill-rule="evenodd"/></svg>
5+
`;

src/collection-browser.ts

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ import { sha1 } from './utils/sha1';
6767
import { log } from './utils/log';
6868
import type { PlaceholderType } from './empty-placeholder';
6969
import type { ManageBar } from './manage/manage-bar';
70+
import type { SmartFacetBar } from './collection-facets/smart-facets/smart-facet-bar';
7071

7172
import './empty-placeholder';
7273
import './tiles/tile-dispatcher';
@@ -250,6 +251,8 @@ export class CollectionBrowser
250251
/** Whether to display a smart results carousel above the full results */
251252
@property({ type: Boolean, reflect: true }) showSmartResults = false;
252253

254+
@property({ type: String }) resultsHeader?: string;
255+
253256
/**
254257
* The maximum number of pages we will load when a privileged user clicks
255258
* the "Manage" button on the search page. Limited to 15 pages.
@@ -304,6 +307,8 @@ export class CollectionBrowser
304307

305308
@query('manage-bar') private manageBar?: ManageBar;
306309

310+
@query('smart-facet-bar') private smartFacetBar?: SmartFacetBar;
311+
307312
@property({ type: Object, attribute: false })
308313
analyticsHandler?: AnalyticsManagerInterface;
309314

@@ -507,7 +512,7 @@ export class CollectionBrowser
507512
render() {
508513
return html`
509514
${this.showSmartFacetBar
510-
? html` <smart-facet-bar
515+
? html`<smart-facet-bar
511516
.query=${this.baseQuery}
512517
.aggregations=${this.dataSource.aggregations}
513518
.selectedFacets=${this.selectedFacets}
@@ -516,6 +521,7 @@ export class CollectionBrowser
516521
@facetsChanged=${this.facetsChanged}
517522
@filtersToggled=${() => {
518523
this.facetPaneVisible = !this.facetPaneVisible;
524+
this.emitFacetPaneVisibilityChanged();
519525
}}
520526
></smart-facet-bar>`
521527
: nothing}
@@ -682,18 +688,21 @@ export class CollectionBrowser
682688
* tiles and sort/filter bar are shown.
683689
*/
684690
private get rightColumnTemplate(): TemplateResult {
691+
const rightColumnClasses = classMap({
692+
column: true,
693+
'full-width': this.showSmartFacetBar && !this.facetPaneVisible,
694+
'smart-results-spacing': !!this.showSmartResults,
695+
});
696+
685697
return html`
686-
<div
687-
id="right-column"
688-
class="column ${this.showSmartResults ? 'smart-results-spacing' : ''}"
689-
>
698+
<div id="right-column" class=${rightColumnClasses}>
690699
${this.showSmartResults
691700
? html`<slot name="smart-results"></slot>`
692701
: nothing}
693702
<section id="results">
694703
${this.showSmartResults
695704
? html`<h2 class="results-section-heading">
696-
${msg('All results')}
705+
${this.resultsHeader ?? msg('All results')}
697706
</h2>`
698707
: nothing}
699708
<div id="cb-top-view">
@@ -841,6 +850,10 @@ export class CollectionBrowser
841850
);
842851
}
843852

853+
refreshSmartFacets(): void {
854+
this.smartFacetBar?.refresh();
855+
}
856+
844857
/**
845858
* Handler to show processing modal while removing item
846859
*/
@@ -1663,6 +1676,18 @@ export class CollectionBrowser
16631676
);
16641677
}
16651678

1679+
/**
1680+
* Emits a `facetPaneVisibilityChanged` event indicating that the facet pane has
1681+
* been toggled open or closed.
1682+
*/
1683+
private emitFacetPaneVisibilityChanged(): void {
1684+
this.dispatchEvent(
1685+
new CustomEvent<boolean>('facetPaneVisibilityChanged', {
1686+
detail: this.facetPaneVisible,
1687+
}),
1688+
);
1689+
}
1690+
16661691
/**
16671692
* Emits a `queryStateChanged` event indicating that one or more of this component's
16681693
* properties have changed in a way that could affect the set of search results.
@@ -2207,13 +2232,16 @@ export class CollectionBrowser
22072232
flex: 1;
22082233
position: relative;
22092234
min-height: 90vh;
2210-
border-left: 1px solid rgb(232, 232, 232);
22112235
border-right: 1px solid rgb(232, 232, 232);
22122236
margin-top: var(--rightColumnMarginTop, 0);
22132237
padding-top: 2rem;
22142238
background: #fff;
22152239
}
22162240
2241+
#left-column:not([hidden]) + #right-column {
2242+
border-left: 1px solid rgb(232, 232, 232);
2243+
}
2244+
22172245
#right-column.smart-results-spacing {
22182246
padding-top: 0.5rem;
22192247
border-right: none;

src/collection-facets/smart-facets/heuristics/wikidata/wikidata-heuristic.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,10 @@ export class WikidataHeuristic implements SmartQueryHeuristic {
4444
facets: smartFacet.facets.map(facet => {
4545
const replaced = {
4646
...facet,
47-
bucketKey: facet.bucketKey.replace('__QUERY', query),
47+
bucketKey: facet.bucketKey.replace(
48+
'__QUERY',
49+
query.toLowerCase(),
50+
),
4851
};
4952

5053
if (facet.displayText) {

src/collection-facets/smart-facets/smart-facet-bar.ts

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
} from 'lit';
1010
import { repeat } from 'lit/directives/repeat.js';
1111
import { customElement, property, state } from 'lit/decorators.js';
12+
import { msg } from '@lit/localize';
1213
import type { Aggregation, Bucket } from '@internetarchive/search-service';
1314
import type { CollectionTitles } from '../../data-source/models';
1415
import type { FacetOption, SelectedFacets } from '../../models';
@@ -18,11 +19,11 @@ import type { SmartFacetDropdown } from './smart-facet-dropdown';
1819
import type { SmartFacet, SmartFacetEvent } from './models';
1920
import { smartFacetEquals } from './smart-facet-equals';
2021
import { dedupe } from './dedupe';
22+
import { log } from '../../utils/log';
2123
import filterIcon from '../../assets/img/icons/filter';
2224

2325
import './smart-facet-button';
2426
import './smart-facet-dropdown';
25-
import { log } from '../../utils/log';
2627

2728
const fieldPrefixes: Partial<Record<FacetOption, string>> = {
2829
collection: 'Collection: ',
@@ -59,9 +60,14 @@ export class SmartFacetBar extends LitElement {
5960
//
6061

6162
render() {
63+
if (!this.query) return nothing;
64+
6265
return html`
6366
<div id="smart-facets-container">
6467
${this.filtersToggleTemplate}
68+
${this.smartFacets.length > 0
69+
? html`<p id="filters-label">${msg('Insights:')}</p>`
70+
: nothing}
6571
${repeat(
6672
this.smartFacets,
6773
f =>
@@ -98,6 +104,11 @@ export class SmartFacetBar extends LitElement {
98104
}
99105
}
100106

107+
refresh(): void {
108+
this.lastAggregations = this.aggregations;
109+
this.updateSmartFacets();
110+
}
111+
101112
private async updateSmartFacets(): Promise<void> {
102113
log('updating smart facets');
103114
if (this.query) {
@@ -164,6 +175,10 @@ export class SmartFacetBar extends LitElement {
164175

165176
if (this.heuristicRecs.length > 0) {
166177
for (const rec of this.heuristicRecs) {
178+
// Suppress mediatype-only facets for now.
179+
if (rec.facets.length === 1 && rec.facets[0].facetType === 'mediatype')
180+
continue;
181+
167182
facets.push([rec]);
168183
}
169184
}
@@ -206,10 +221,8 @@ export class SmartFacetBar extends LitElement {
206221
});
207222

208223
if (facetType === 'mediatype') {
209-
facets.push(
210-
[this.toSmartFacet(facetType, [unusedBuckets[0]])],
211-
[this.toSmartFacet(facetType, [unusedBuckets[1]])],
212-
);
224+
continue;
225+
// Don't include mediatype bubbles
213226
} else if (facetType === 'collection' || facetType === 'subject') {
214227
const topBuckets = unusedBuckets.slice(0, 5);
215228
facets.push(topBuckets.map(b => this.toSmartFacet(facetType, [b])));
@@ -320,33 +333,42 @@ export class SmartFacetBar extends LitElement {
320333
display: flex;
321334
align-items: center;
322335
flex-wrap: wrap;
323-
gap: 5px;
336+
gap: 5px 10px;
324337
padding: 10px 0;
325338
}
326339
327340
#filters-toggle {
328341
margin: 0;
329342
border: 0;
330-
padding: 5px 10px;
331-
border-radius: 15px;
332-
background: #194880;
333-
color: white;
334-
font-size: 1.6rem;
343+
padding: 5px 8px;
344+
border-radius: 50%;
345+
background: white;
346+
color: #2c2c2c;
347+
border: 1px solid #194880;
348+
font-size: 1.4rem;
335349
font-family: inherit;
336350
text-decoration: none;
337-
box-shadow: 1px 1px rgba(0, 0, 0, 0.4);
338351
cursor: pointer;
339352
}
340353
341354
#filters-toggle.active {
342-
background: #09294d;
343-
box-shadow: -1px -1px rgba(0, 0, 0, 0.1);
355+
background: #194880;
356+
color: white;
344357
}
345358
346359
#filters-toggle > svg {
347-
width: 15px;
360+
width: 12px;
361+
filter: invert(0.16667);
362+
vertical-align: -1px;
363+
}
364+
365+
#filters-toggle.active > svg {
348366
filter: invert(1);
349-
vertical-align: text-bottom;
367+
}
368+
369+
#filters-label {
370+
font-weight: bold;
371+
margin: 0 -5px 0 0;
350372
}
351373
`;
352374
}

src/collection-facets/smart-facets/smart-facet-button.ts

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { customElement, property } from 'lit/decorators.js';
33
import { mediatypeConfig } from '../../mediatype/mediatype-config';
44
import type { SmartFacet, SmartFacetEvent } from './models';
55

6+
import closeCircleDark from '../../assets/img/icons/close-circle-dark';
7+
68
function capitalize(str?: string): string | undefined {
79
if (!str) return str;
810
return str.charAt(0).toLocaleUpperCase() + str.slice(1);
@@ -47,7 +49,7 @@ export class SmartFacetButton extends LitElement {
4749
>
4850
${icon} ${displayText}
4951
${this.selected
50-
? html`<span style="margin-left: 5px;">×</span>`
52+
? html`<span class="unselect-button">${closeCircleDark}</span>`
5153
: nothing}
5254
</a>
5355
`;
@@ -101,24 +103,39 @@ export class SmartFacetButton extends LitElement {
101103
static get styles(): CSSResultGroup {
102104
return css`
103105
.smart-facet-button {
104-
padding: 5px 10px;
105-
border-radius: 15px;
106-
background: #194880;
107-
color: white;
108-
font-size: 1.6rem;
106+
display: inline-flex;
107+
align-items: center;
108+
column-gap: 5px;
109+
padding: 5px 5px;
110+
border-radius: 5px;
111+
background: white;
112+
color: #2c2c2c;
113+
border: 1px solid #194880;
114+
font-size: 1.4rem;
109115
font-family: inherit;
116+
line-height: normal;
110117
text-decoration: none;
111-
box-shadow: 1px 1px rgba(0, 0, 0, 0.4);
112118
}
113119
114120
.smart-facet-button.selected {
115-
background: #4c76aa;
121+
background: #194880;
122+
color: white;
123+
}
124+
125+
.unselect-button > svg {
126+
width: 10px;
127+
height: 10px;
128+
filter: invert(1);
116129
}
117130
118131
.smart-facet-button > svg {
119-
width: 15px;
132+
width: 12px;
133+
height: 12px;
134+
filter: invert(0.16667);
135+
}
136+
137+
.smart-facet-button.selected > svg {
120138
filter: invert(1);
121-
vertical-align: text-top;
122139
}
123140
`;
124141
}

src/collection-facets/smart-facets/smart-facet-dropdown.ts

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ export class SmartFacetDropdown extends LitElement {
3333
displayCaret
3434
openViaButton
3535
closeOnSelect
36+
closeOnEscape
37+
closeOnBackdropClick
3638
includeSelectedOption
3739
.options=${this.dropdownOptions}
3840
.selectedOption=${this.activeDropdownOption}
@@ -57,8 +59,11 @@ export class SmartFacetDropdown extends LitElement {
5759
const firstFacet = smartFacet.facets[0];
5860
return {
5961
id: firstFacet.bucketKey,
60-
label:
61-
smartFacet.label ?? firstFacet.displayText ?? firstFacet.bucketKey,
62+
label: html`<span>
63+
${smartFacet.label ??
64+
firstFacet.displayText ??
65+
firstFacet.bucketKey}
66+
</span>`,
6267
};
6368
}) ?? []
6469
);
@@ -127,23 +132,29 @@ export class SmartFacetDropdown extends LitElement {
127132
static get styles(): CSSResultGroup {
128133
return css`
129134
.dropdown-container {
130-
padding: 5px 8px;
135+
padding: 5px 5px;
131136
border-radius: 5px;
132-
background: #194880;
133-
color: white;
134-
font-size: 1.6rem;
137+
background: white;
138+
color: #2c2c2c;
139+
border: 1px solid #194880;
140+
font-size: 1.4rem;
135141
font-family: inherit;
136-
box-shadow: 1px 1px rgba(0, 0, 0, 0.4);
137142
}
138143
139144
.dropdown-label {
140-
font-size: 1.6rem;
145+
font-size: 1.4rem;
141146
font-family: inherit;
142147
}
143148
144149
.dropdown {
145-
--dropdownBorderWidth: 5px;
146-
--dropdownBorderColor: transparent;
150+
--dropdownBorderColor: #194880;
151+
--dropdownBorderWidth: 1px;
152+
--dropdownBgColor: white;
153+
--dropdownHoverBgColor: #f8f8f8;
154+
--dropdownTextColor: #2c2c2c;
155+
--dropdownHoverTextColor: #2c2c2c;
156+
--dropdownCaretColor: #2c2c2c;
157+
--dropdownWhiteSpace: nowrap;
147158
--caretWidth: 14px;
148159
--caretHeight: 14px;
149160
}

0 commit comments

Comments
 (0)