mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
Merge pull request #1138 from atmire/w2p-78991_Issue-1112_Fix-date-filter-bugs
Fix date filter bugs
This commit is contained in:
@@ -27,7 +27,10 @@ describe('MyDSpaceConfigurationService', () => {
|
||||
scope: ''
|
||||
});
|
||||
|
||||
const backendFilters = [new SearchFilter('f.namedresourcetype', ['another value']), new SearchFilter('f.dateSubmitted', ['[2013 TO 2018]'])];
|
||||
const backendFilters = [
|
||||
new SearchFilter('f.namedresourcetype', ['another value']),
|
||||
new SearchFilter('f.dateSubmitted', ['[2013 TO 2018]'], 'equals')
|
||||
];
|
||||
|
||||
const spy = jasmine.createSpyObj('RouteService', {
|
||||
getQueryParameterValue: observableOf(value1),
|
||||
|
@@ -23,7 +23,10 @@ describe('SearchConfigurationService', () => {
|
||||
scope: ''
|
||||
});
|
||||
|
||||
const backendFilters = [new SearchFilter('f.author', ['another value']), new SearchFilter('f.date', ['[2013 TO 2018]'])];
|
||||
const backendFilters = [
|
||||
new SearchFilter('f.author', ['another value']),
|
||||
new SearchFilter('f.date', ['[2013 TO 2018]'], 'equals')
|
||||
];
|
||||
|
||||
const routeService = jasmine.createSpyObj('RouteService', {
|
||||
getQueryParameterValue: observableOf(value1),
|
||||
|
@@ -168,7 +168,7 @@ export class SearchConfigurationService implements OnDestroy {
|
||||
if (hasNoValue(filters.find((f) => f.key === realKey))) {
|
||||
const min = filterParams[realKey + '.min'] ? filterParams[realKey + '.min'][0] : '*';
|
||||
const max = filterParams[realKey + '.max'] ? filterParams[realKey + '.max'][0] : '*';
|
||||
filters.push(new SearchFilter(realKey, ['[' + min + ' TO ' + max + ']']));
|
||||
filters.push(new SearchFilter(realKey, ['[' + min + ' TO ' + max + ']'], 'equals'));
|
||||
}
|
||||
} else {
|
||||
filters.push(new SearchFilter(key, filterParams[key]));
|
||||
|
@@ -8,7 +8,12 @@ describe('PaginatedSearchOptions', () => {
|
||||
let options: PaginatedSearchOptions;
|
||||
const sortOptions = new SortOptions('test.field', SortDirection.DESC);
|
||||
const pageOptions = Object.assign(new PaginationComponentOptions(), { pageSize: 40, page: 1 });
|
||||
const filters = [new SearchFilter('f.test', ['value']), new SearchFilter('f.example', ['another value', 'second value'])];
|
||||
const filters = [
|
||||
new SearchFilter('f.test', ['value']),
|
||||
new SearchFilter('f.example', ['another value', 'second value']), // should be split into two arguments, spaces should be URI-encoded
|
||||
new SearchFilter('f.range', ['[2002 TO 2021]'], 'equals'), // value should be URI-encoded, ',equals' should not
|
||||
];
|
||||
const fixedFilter = 'f.fixed=1234,5678,equals'; // '=' and ',equals' should not be URI-encoded
|
||||
const query = 'search query';
|
||||
const scope = '0fde1ecb-82cc-425a-b600-ac3576d76b47';
|
||||
const baseUrl = 'www.rest.com';
|
||||
@@ -19,7 +24,8 @@ describe('PaginatedSearchOptions', () => {
|
||||
filters: filters,
|
||||
query: query,
|
||||
scope: scope,
|
||||
dsoTypes: [DSpaceObjectType.ITEM]
|
||||
dsoTypes: [DSpaceObjectType.ITEM],
|
||||
fixedFilter: fixedFilter,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -31,12 +37,14 @@ describe('PaginatedSearchOptions', () => {
|
||||
'sort=test.field,DESC&' +
|
||||
'page=0&' +
|
||||
'size=40&' +
|
||||
'query=search query&' +
|
||||
'f.fixed=1234%2C5678,equals&' +
|
||||
'query=search%20query&' +
|
||||
'scope=0fde1ecb-82cc-425a-b600-ac3576d76b47&' +
|
||||
'dsoType=ITEM&' +
|
||||
'f.test=value&' +
|
||||
'f.example=another value&' +
|
||||
'f.example=second value'
|
||||
'f.example=another%20value&' +
|
||||
'f.example=second%20value&' +
|
||||
'f.range=%5B2002%20TO%202021%5D,equals'
|
||||
);
|
||||
});
|
||||
|
||||
|
@@ -35,7 +35,7 @@ export class SearchFilterComponent implements OnInit {
|
||||
/**
|
||||
* True when the filter is 100% collapsed in the UI
|
||||
*/
|
||||
closed = true;
|
||||
closed: boolean;
|
||||
|
||||
/**
|
||||
* Emits true when the filter is currently collapsed in the store
|
||||
|
@@ -8,18 +8,16 @@
|
||||
|
||||
::ng-deep
|
||||
{
|
||||
--ds-slider-handle-width: 18px;
|
||||
|
||||
html:not([dir=rtl]) .noUi-horizontal .noUi-handle {
|
||||
right: calc(var(--ds-slider-handle-width) / -2);
|
||||
}
|
||||
.noUi-horizontal .noUi-handle {
|
||||
width: var(--ds-slider-handle-width);
|
||||
&:before {
|
||||
left: calc(calc(calc(var(--ds-slider-handle-width) - 2) / 2) - 2);
|
||||
left: calc(((var(--ds-slider-handle-width) - 2px) / 2) - 2px);
|
||||
}
|
||||
&:after {
|
||||
left: calc(calc(calc(var(--ds-slider-handle-width) - 2) / 2) + 2);
|
||||
left: calc(((var(--ds-slider-handle-width) - 2px) / 2) + 2px);
|
||||
}
|
||||
&:focus {
|
||||
outline: none;
|
||||
|
@@ -56,7 +56,7 @@ export class SearchRangeFilterComponent extends SearchFacetFilterComponent imple
|
||||
/**
|
||||
* Fallback maximum for the range
|
||||
*/
|
||||
max = 2018;
|
||||
max = new Date().getFullYear();
|
||||
|
||||
/**
|
||||
* The current range of the filter
|
||||
|
@@ -4,13 +4,25 @@ import { SearchFilter } from './search-filter.model';
|
||||
import { DSpaceObjectType } from '../../core/shared/dspace-object-type.model';
|
||||
|
||||
describe('SearchOptions', () => {
|
||||
let options: PaginatedSearchOptions;
|
||||
const filters = [new SearchFilter('f.test', ['value']), new SearchFilter('f.example', ['another value', 'second value'])];
|
||||
let options: SearchOptions;
|
||||
|
||||
const filters = [
|
||||
new SearchFilter('f.test', ['value']),
|
||||
new SearchFilter('f.example', ['another value', 'second value']), // should be split into two arguments, spaces should be URI-encoded
|
||||
new SearchFilter('f.range', ['[2002 TO 2021]'], 'equals'), // value should be URI-encoded, ',equals' should not
|
||||
];
|
||||
const fixedFilter = 'f.fixed=1234,5678,equals'; // '=' and ',equals' should not be URI-encoded
|
||||
const query = 'search query';
|
||||
const scope = '0fde1ecb-82cc-425a-b600-ac3576d76b47';
|
||||
const baseUrl = 'www.rest.com';
|
||||
beforeEach(() => {
|
||||
options = new SearchOptions({ filters: filters, query: query, scope: scope, dsoTypes: [DSpaceObjectType.ITEM] });
|
||||
options = new SearchOptions({
|
||||
filters: filters,
|
||||
query: query,
|
||||
scope: scope,
|
||||
dsoTypes: [DSpaceObjectType.ITEM],
|
||||
fixedFilter: fixedFilter,
|
||||
});
|
||||
});
|
||||
|
||||
describe('when toRestUrl is called', () => {
|
||||
@@ -18,12 +30,14 @@ describe('SearchOptions', () => {
|
||||
it('should generate a string with all parameters that are present', () => {
|
||||
const outcome = options.toRestUrl(baseUrl);
|
||||
expect(outcome).toEqual('www.rest.com?' +
|
||||
'query=search query&' +
|
||||
'f.fixed=1234%2C5678,equals&' +
|
||||
'query=search%20query&' +
|
||||
'scope=0fde1ecb-82cc-425a-b600-ac3576d76b47&' +
|
||||
'dsoType=ITEM&' +
|
||||
'f.test=value&' +
|
||||
'f.example=another value&' +
|
||||
'f.example=second value'
|
||||
'f.example=another%20value&' +
|
||||
'f.example=second%20value&' +
|
||||
'f.range=%5B2002%20TO%202021%5D,equals'
|
||||
);
|
||||
});
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { isNotEmpty } from '../empty.util';
|
||||
import { hasValue, isNotEmpty } from '../empty.util';
|
||||
import { URLCombiner } from '../../core/url-combiner/url-combiner';
|
||||
import { SearchFilter } from './search-filter.model';
|
||||
import { DSpaceObjectType } from '../../core/shared/dspace-object-type.model';
|
||||
@@ -13,10 +13,15 @@ export class SearchOptions {
|
||||
scope?: string;
|
||||
query?: string;
|
||||
dsoTypes?: DSpaceObjectType[];
|
||||
filters?: any;
|
||||
fixedFilter?: any;
|
||||
filters?: SearchFilter[];
|
||||
fixedFilter?: string;
|
||||
|
||||
constructor(options: {configuration?: string, scope?: string, query?: string, dsoTypes?: DSpaceObjectType[], filters?: SearchFilter[], fixedFilter?: any}) {
|
||||
constructor(
|
||||
options: {
|
||||
configuration?: string, scope?: string, query?: string, dsoTypes?: DSpaceObjectType[], filters?: SearchFilter[],
|
||||
fixedFilter?: string
|
||||
}
|
||||
) {
|
||||
this.configuration = options.configuration;
|
||||
this.scope = options.scope;
|
||||
this.query = options.query;
|
||||
@@ -33,27 +38,27 @@ export class SearchOptions {
|
||||
*/
|
||||
toRestUrl(url: string, args: string[] = []): string {
|
||||
if (isNotEmpty(this.configuration)) {
|
||||
args.push(`configuration=${this.configuration}`);
|
||||
args.push(`configuration=${encodeURIComponent(this.configuration)}`);
|
||||
}
|
||||
if (isNotEmpty(this.fixedFilter)) {
|
||||
args.push(this.fixedFilter);
|
||||
args.push(this.encodedFixedFilter);
|
||||
}
|
||||
if (isNotEmpty(this.query)) {
|
||||
args.push(`query=${this.query}`);
|
||||
args.push(`query=${encodeURIComponent(this.query)}`);
|
||||
}
|
||||
if (isNotEmpty(this.scope)) {
|
||||
args.push(`scope=${this.scope}`);
|
||||
args.push(`scope=${encodeURIComponent(this.scope)}`);
|
||||
}
|
||||
if (isNotEmpty(this.dsoTypes)) {
|
||||
this.dsoTypes.forEach((dsoType: string) => {
|
||||
args.push(`dsoType=${dsoType}`);
|
||||
args.push(`dsoType=${encodeURIComponent(dsoType)}`);
|
||||
});
|
||||
}
|
||||
if (isNotEmpty(this.filters)) {
|
||||
this.filters.forEach((filter: SearchFilter) => {
|
||||
filter.values.forEach((value) => {
|
||||
const filterValue = value.includes(',') ? `${value}` : value + (filter.operator ? ',' + filter.operator : '');
|
||||
args.push(`${filter.key}=${filterValue}`);
|
||||
args.push(`${filter.key}=${this.encodeFilterQueryValue(filterValue)}`);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -62,4 +67,28 @@ export class SearchOptions {
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
get encodedFixedFilter(): string {
|
||||
// expected format: 'arg=value'
|
||||
// -> split the query agument into (arg=)(value) and only encode 'value'
|
||||
const match = this.fixedFilter.match(/^([^=]+=)(.+)$/);
|
||||
|
||||
if (hasValue(match)) {
|
||||
return match[1] + this.encodeFilterQueryValue(match[2]);
|
||||
} else {
|
||||
return this.encodeFilterQueryValue(this.fixedFilter);
|
||||
}
|
||||
}
|
||||
|
||||
encodeFilterQueryValue(filterQueryValue: string): string {
|
||||
// expected format: 'value' or 'value,operator'
|
||||
// -> split into (value)(,operator) and only encode 'value'
|
||||
const match = filterQueryValue.match(/^(.*)(,\w+)$/);
|
||||
|
||||
if (hasValue(match)) {
|
||||
return encodeURIComponent(match[1]) + match[2];
|
||||
} else {
|
||||
return encodeURIComponent(filterQueryValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -78,4 +78,5 @@
|
||||
--ds-breadcrumb-link-active-color: #{darken($cyan, 30%)};
|
||||
|
||||
--ds-slider-color: #{$green};
|
||||
--ds-slider-handle-width: 18px;
|
||||
}
|
||||
|
Reference in New Issue
Block a user