Skip to content

Commit d8cb994

Browse files
committed
Adding nicer checkbox, and verifying extended search actually works.
1 parent b67c1b5 commit d8cb994

11 files changed

Lines changed: 165 additions & 8 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,4 @@ yarn-error.log
4242
junit.xml
4343

4444
/src/mirador-viewer/config.local.js
45+
.vscode

karma.conf.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ module.exports = function (config) {
1515
],
1616
client: {
1717
clearContext: false, // leave Jasmine Spec Runner output visible in browser
18-
captureConsole: false,
18+
captureConsole: false, // Set to true to get output from tests in the terminal
1919
jasmine: {
2020
failSpecWithNoExpectations: true
2121
}

src/app/core/shared/search/models/paginated-search-options.model.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export class PaginatedSearchOptions extends SearchOptions {
1414
pagination?: PaginationComponentOptions;
1515
sort?: SortOptions;
1616

17-
constructor(options: {configuration?: string, scope?: string, query?: string, dsoTypes?: DSpaceObjectType[], filters?: SearchFilter[], fixedFilter?: any, pagination?: PaginationComponentOptions, sort?: SortOptions, view?: ViewMode}) {
17+
constructor(options: {configuration?: string, scope?: string, query?: string, dsoTypes?: DSpaceObjectType[], filters?: SearchFilter[], fixedFilter?: any, pagination?: PaginationComponentOptions, sort?: SortOptions, view?: ViewMode, advanced?: boolean}) {
1818
super(options);
1919
this.pagination = options.pagination;
2020
this.sort = options.sort;

src/app/core/shared/search/models/search-options.model.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ export class SearchOptions {
1616
view?: ViewMode = ViewMode.ListElement;
1717
scope?: string;
1818
query?: string;
19+
advanced?: boolean;
1920
dsoTypes?: DSpaceObjectType[];
2021
filters?: SearchFilter[];
2122
fixedFilter?: string;
22-
advanced?: boolean;
2323

2424
constructor(
2525
options: {

src/app/shared/search-form/search-form.component.html

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,14 @@
99
{{dsoNameService.getName(selectedScope | async) || ('search.form.scope.all' | translate)}}
1010
</button>
1111
}
12-
<input type="text" [(ngModel)]="query" name="query" class="form-control"
12+
<div class="checkbox-wrapper-8">
13+
<input class="tgl" id="cb3-8" name="advanced" type="checkbox" [(ngModel)]="advanced"/>
14+
<label class="tgl-btn" [attr.data-tg-off]="('search.form.expert_off' | translate )"
15+
[attr.data-tg-on]="('search.form.expert_on' | translate )" for="cb3-8"></label>
16+
</div>
17+
<input type="text" [(ngModel)]="query" name="query" class="form-control"
1318
[attr.aria-label]="searchPlaceholder" [attr.data-test]="'search-box' | dsBrowserOnly"
1419
[placeholder]="searchPlaceholder" tabindex="0">
15-
<input type="checkbox" [(ngModel)]="advanced" name="advanced" checked /><label for="advanced">{{ "('search.form.advanced' | translate )" }}</label>
1620
<button type="submit" class="search-button btn btn-{{brandColor}}" [attr.data-test]="'search-button' | dsBrowserOnly" role="button" tabindex="0"><i class="fas fa-search"></i> {{ ('search.form.search' | translate) }}</button>
1721
</div>
1822
</div>

src/app/shared/search-form/search-form.component.scss

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,127 @@
77
.scope-button {
88
max-width: var(--ds-search-form-scope-max-width);
99
}
10+
11+
// Copied from https://getcssscan.com/css-checkboxes-examples
12+
.checkbox-wrapper-8 .tgl {
13+
display: none;
14+
}
15+
16+
.checkbox-wrapper-8 .tgl,
17+
.checkbox-wrapper-8 .tgl:after,
18+
.checkbox-wrapper-8 .tgl:before,
19+
.checkbox-wrapper-8 .tgl *,
20+
.checkbox-wrapper-8 .tgl *:after,
21+
.checkbox-wrapper-8 .tgl *:before,
22+
.checkbox-wrapper-8 .tgl+.tgl-btn {
23+
box-sizing: border-box;
24+
}
25+
26+
.checkbox-wrapper-8 .tgl::-moz-selection,
27+
.checkbox-wrapper-8 .tgl:after::-moz-selection,
28+
.checkbox-wrapper-8 .tgl:before::-moz-selection,
29+
.checkbox-wrapper-8 .tgl *::-moz-selection,
30+
.checkbox-wrapper-8 .tgl *:after::-moz-selection,
31+
.checkbox-wrapper-8 .tgl *:before::-moz-selection,
32+
.checkbox-wrapper-8 .tgl+.tgl-btn::-moz-selection,
33+
.checkbox-wrapper-8 .tgl::selection,
34+
.checkbox-wrapper-8 .tgl:after::selection,
35+
.checkbox-wrapper-8 .tgl:before::selection,
36+
.checkbox-wrapper-8 .tgl *::selection,
37+
.checkbox-wrapper-8 .tgl *:after::selection,
38+
.checkbox-wrapper-8 .tgl *:before::selection,
39+
.checkbox-wrapper-8 .tgl+.tgl-btn::selection {
40+
background: none;
41+
}
42+
43+
.checkbox-wrapper-8 .tgl+.tgl-btn {
44+
outline: 0;
45+
display: block;
46+
width: 6em;
47+
height: 100%;
48+
position: relative;
49+
cursor: pointer;
50+
-webkit-user-select: none;
51+
-moz-user-select: none;
52+
-ms-user-select: none;
53+
user-select: none;
54+
}
55+
56+
.checkbox-wrapper-8 .tgl+.tgl-btn:after,
57+
.checkbox-wrapper-8 .tgl+.tgl-btn:before {
58+
position: relative;
59+
display: block;
60+
content: "";
61+
width: 50%;
62+
height: 100%;
63+
}
64+
65+
.checkbox-wrapper-8 .tgl+.tgl-btn:after {
66+
left: 0;
67+
}
68+
69+
.checkbox-wrapper-8 .tgl+.tgl-btn:before {
70+
display: none;
71+
}
72+
73+
.checkbox-wrapper-8 .tgl:checked+.tgl-btn:after {
74+
left: 50%;
75+
}
76+
77+
.checkbox-wrapper-8 .tgl+.tgl-btn {
78+
overflow: hidden;
79+
-webkit-backface-visibility: hidden;
80+
backface-visibility: hidden;
81+
transition: all 0.2s ease;
82+
font-family: sans-serif;
83+
background: #888;
84+
}
85+
86+
.checkbox-wrapper-8 .tgl+.tgl-btn:after,
87+
.checkbox-wrapper-8 .tgl+.tgl-btn:before {
88+
display: inline-block;
89+
transition: all 0.2s ease;
90+
width: 100%;
91+
text-align: center;
92+
position: absolute;
93+
line-height: 2em;
94+
font-weight: bold;
95+
color: #fff;
96+
text-shadow: 0 1px 0 rgba(0, 0, 0, 0.4);
97+
}
98+
99+
.checkbox-wrapper-8 .tgl+.tgl-btn:after {
100+
left: 100%;
101+
margin-top: 3px;
102+
content: attr(data-tg-on);
103+
}
104+
105+
.checkbox-wrapper-8 .tgl+.tgl-btn:before {
106+
left: 0;
107+
margin-top: 3px;
108+
content: attr(data-tg-off);
109+
}
110+
111+
.checkbox-wrapper-8 .tgl+.tgl-btn:active {
112+
background: #888;
113+
}
114+
115+
.checkbox-wrapper-8 .tgl+.tgl-btn:active:before {
116+
left: -10%;
117+
}
118+
119+
.checkbox-wrapper-8 .tgl:checked+.tgl-btn {
120+
background: #86d993;
121+
}
122+
123+
.checkbox-wrapper-8 .tgl:checked+.tgl-btn:before {
124+
left: -100%;
125+
}
126+
127+
.checkbox-wrapper-8 .tgl:checked+.tgl-btn:after {
128+
left: 0;
129+
}
130+
131+
.checkbox-wrapper-8 .tgl:checked+.tgl-btn:active:after {
132+
left: 10%;
133+
}

src/app/shared/search-form/search-form.component.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ describe('SearchFormComponent', () => {
8787

8888
fixture.detectChanges();
8989
tick();
90-
const queryInput = de.query(By.css('input')).nativeElement;
90+
const queryInput = de.query(By.css('input[name="query"]')).nativeElement;
9191

9292
expect(queryInput.value).toBe(testString);
9393
}));

src/app/shared/search/search-configuration.service.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,15 @@ export class SearchConfigurationService implements OnDestroy {
187187
}));
188188
}
189189

190+
/**
191+
* @returns {Observable<boolean>} Emits the current advanced string
192+
*/
193+
getCurrentAdvanced(defaultAdvanced: boolean) {
194+
return this.routeService.getQueryParameterValue('advanced').pipe(map((advanced) => {
195+
return advanced === 'true' || defaultAdvanced;
196+
}));
197+
}
198+
190199
/**
191200
* @returns {Observable<number>} Emits the current DSpaceObject type as a number
192201
*/
@@ -360,6 +369,7 @@ export class SearchConfigurationService implements OnDestroy {
360369
this.getConfigurationPart(defaults.configuration),
361370
this.getScopePart(defaults.scope),
362371
this.getQueryPart(defaults.query),
372+
this.getAdvancedPart(defaults.advanced),
363373
this.getDSOTypePart(),
364374
this.getFiltersPart(),
365375
this.getFixedFilterPart(),
@@ -384,6 +394,7 @@ export class SearchConfigurationService implements OnDestroy {
384394
this.getSortPart(paginationId, defaults.sort),
385395
this.getScopePart(defaults.scope),
386396
this.getQueryPart(defaults.query),
397+
this.getAdvancedPart(defaults.advanced),
387398
this.getDSOTypePart(),
388399
this.getFiltersPart(),
389400
this.getFixedFilterPart(),
@@ -435,6 +446,16 @@ export class SearchConfigurationService implements OnDestroy {
435446
}));
436447
}
437448

449+
/**
450+
* @returns {Observable<{advanced: boolean}>} Emits the current advanced boolean as a partial SearchOptions object
451+
*/
452+
private getAdvancedPart(defaultAdvanced: boolean): Observable<{advanced: boolean}> {
453+
return this.getCurrentAdvanced(defaultAdvanced).pipe(map((advanced) => {
454+
console.log("getAdvancedPart", advanced)
455+
return { advanced };
456+
}));
457+
}
458+
438459
/**
439460
* @returns {Observable<string>} Emits the current query string as a partial SearchOptions object
440461
*/

src/app/shared/search/search.component.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ describe('SearchComponent', () => {
300300
configuration: 'default',
301301
scope: '',
302302
sort: sortOptionsList[0],
303+
advanced: false,
303304
});
304305
expect(comp.currentConfiguration$).toBeObservable(cold('b', {
305306
b: 'default',

src/app/shared/search/search.component.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,15 +426,19 @@ export class SearchComponent implements OnDestroy, OnInit {
426426
debounceTime(100),
427427
).subscribe(([configuration, searchSortOptions, searchOptions, sortOption, scope]: [string, SortOptions[], PaginatedSearchOptions, SortOptions, string]) => {
428428
// Build the PaginatedSearchOptions object
429+
console.log("searchOptions", searchOptions);
429430
const combinedOptions = Object.assign({}, searchOptions,
430431
{
431432
configuration: searchOptions.configuration || configuration,
432433
sort: sortOption || searchOptions.sort,
433434
});
434435
if (combinedOptions.query === '') {
435436
combinedOptions.query = this.query;
437+
}
438+
if (combinedOptions.advanced === undefined) {
436439
combinedOptions.advanced = this.advanced;
437440
}
441+
console.log(this.advanced, combinedOptions.advanced);
438442
if (isEmpty(combinedOptions.scope)) {
439443
combinedOptions.scope = scope;
440444
}
@@ -542,7 +546,7 @@ export class SearchComponent implements OnDestroy, OnInit {
542546
followLinks.push(followLink<WorkspaceItem>('supervisionOrders', { isOptional: true }) as any);
543547
}
544548

545-
const searchOptionsWithHidden = Object.assign (new PaginatedSearchOptions({}), searchOptions);
549+
const searchOptionsWithHidden = Object.assign(new PaginatedSearchOptions({}), searchOptions);
546550
if (isNotEmpty(this.hiddenQuery)) {
547551
if (isNotEmpty(searchOptionsWithHidden.query)) {
548552
searchOptionsWithHidden.query = searchOptionsWithHidden.query + ' AND ' + this.hiddenQuery;

0 commit comments

Comments
 (0)