-
-
-
-
-
-
+
+ {{('SEARCH.LOGICAL_SEARCH.' + field + '_LABEL') | translate}}
+
+
diff --git a/lib/content-services/src/lib/search/components/search-logical-filter/search-logical-filter.component.scss b/lib/content-services/src/lib/search/components/search-logical-filter/search-logical-filter.component.scss
index 99943c9939..a467b7e956 100644
--- a/lib/content-services/src/lib/search/components/search-logical-filter/search-logical-filter.component.scss
+++ b/lib/content-services/src/lib/search/components/search-logical-filter/search-logical-filter.component.scss
@@ -1,4 +1,21 @@
.adf-search-logical-filter-container {
- display: flex;
- flex-direction: column;
+ .adf-search-input {
+ display: flex;
+ flex-direction: column;
+ padding-bottom: 15px;
+
+ &:last-child {
+ padding: 0;
+ }
+
+ input {
+ height: 25px;
+ border: 1px solid var(--adf-theme-mat-grey-color-a400);
+ border-radius: 5px;
+ margin-top: 5px;
+ padding: 5px;
+ font-size: 14px;
+ color: var(--adf-theme-foreground-text-color);
+ }
+ }
}
diff --git a/lib/content-services/src/lib/search/components/search-logical-filter/search-logical-filter.component.spec.ts b/lib/content-services/src/lib/search/components/search-logical-filter/search-logical-filter.component.spec.ts
index dc08d69c5a..27077aaaaa 100644
--- a/lib/content-services/src/lib/search/components/search-logical-filter/search-logical-filter.component.spec.ts
+++ b/lib/content-services/src/lib/search/components/search-logical-filter/search-logical-filter.component.spec.ts
@@ -19,7 +19,6 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { TranslateModule } from '@ngx-translate/core';
import { ContentTestingModule } from '../../../testing/content.testing.module';
-import { SearchChipInputComponent } from '../search-chip-input/search-chip-input.component';
import { LogicalSearchCondition, LogicalSearchFields, SearchLogicalFilterComponent } from './search-logical-filter.component';
describe('SearchLogicalFilterComponent', () => {
@@ -28,7 +27,7 @@ describe('SearchLogicalFilterComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
- declarations: [SearchLogicalFilterComponent, SearchChipInputComponent],
+ declarations: [SearchLogicalFilterComponent],
imports: [
TranslateModule.forRoot(),
ContentTestingModule
@@ -48,19 +47,19 @@ describe('SearchLogicalFilterComponent', () => {
fixture.detectChanges();
});
- function getChipInputs(): HTMLInputElement[] {
- return fixture.debugElement.queryAll(By.css('adf-search-chip-input input')).map((input) => input.nativeElement);
+ function getInputs(): HTMLInputElement[] {
+ return fixture.debugElement.queryAll(By.css('.adf-search-input input')).map((input) => input.nativeElement);
}
- function getChipInputsLabels(): string[] {
- return fixture.debugElement.queryAll(By.css('adf-search-chip-input mat-label')).map((label) => label.nativeElement.innerText);
+ function getInputsLabels(): string[] {
+ return fixture.debugElement.queryAll(By.css('.adf-search-input mat-label')).map((label) => label.nativeElement.innerText);
}
function enterNewPhrase(value: string, index: number) {
- const inputs = getChipInputs();
+ const inputs = getInputs();
inputs[index].value = value;
- fixture.detectChanges();
- inputs[index].dispatchEvent(new KeyboardEvent('keydown', {keyCode: 13}));
+ inputs[index].dispatchEvent(new Event('input'));
+ inputs[index].dispatchEvent(new Event('change'));
fixture.detectChanges();
}
@@ -74,12 +73,13 @@ describe('SearchLogicalFilterComponent', () => {
expect(component.hasValidValue()).toBeFalse();
});
- it('should contain 3 chip input components with correct labels', () => {
- const labels = getChipInputsLabels();
- expect(labels.length).toBe(3);
+ it('should contain 4 inputs with correct labels', () => {
+ const labels = getInputsLabels();
+ expect(labels.length).toBe(4);
expect(labels[0]).toBe('SEARCH.LOGICAL_SEARCH.MATCH_ALL_LABEL');
expect(labels[1]).toBe('SEARCH.LOGICAL_SEARCH.MATCH_ANY_LABEL');
expect(labels[2]).toBe('SEARCH.LOGICAL_SEARCH.EXCLUDE_LABEL');
+ expect(labels[3]).toBe('SEARCH.LOGICAL_SEARCH.MATCH_EXACT_LABEL');
});
it('should has valid value after phrase is entered', () => {
@@ -88,36 +88,34 @@ describe('SearchLogicalFilterComponent', () => {
});
it('should update display value after phrases changes', () => {
- spyOn(component, 'onPhraseChange').and.callThrough();
spyOn(component.displayValue$, 'next');
enterNewPhrase('test2', 0);
- expect(component.onPhraseChange).toHaveBeenCalled();
- expect(component.displayValue$.next).toHaveBeenCalledOnceWith(` SEARCH.LOGICAL_SEARCH.${Object.keys(LogicalSearchFields)[0]}: test2`);
+ expect(component.displayValue$.next).toHaveBeenCalledOnceWith(` SEARCH.LOGICAL_SEARCH.${Object.keys(LogicalSearchFields)[0]}: test2`);
});
it('should have correct display value after each field has at least one phrase', () => {
- spyOn(component, 'onPhraseChange').and.callThrough();
spyOn(component.displayValue$, 'next');
enterNewPhrase('test1', 0);
enterNewPhrase('test2', 1);
enterNewPhrase('test3', 2);
- const displayVal1 = ` SEARCH.LOGICAL_SEARCH.${Object.keys(LogicalSearchFields)[0]}: test1`;
- const displayVal2 = ` SEARCH.LOGICAL_SEARCH.${Object.keys(LogicalSearchFields)[1]}: test2`;
- const displayVal3 = ` SEARCH.LOGICAL_SEARCH.${Object.keys(LogicalSearchFields)[2]}: test3`;
- expect(component.onPhraseChange).toHaveBeenCalled();
- expect(component.displayValue$.next).toHaveBeenCalledWith(displayVal1 + displayVal2 + displayVal3);
+ enterNewPhrase('test4', 3);
+ const displayVal1 = ` SEARCH.LOGICAL_SEARCH.${Object.keys(LogicalSearchFields)[0]}: test1`;
+ const displayVal2 = ` SEARCH.LOGICAL_SEARCH.${Object.keys(LogicalSearchFields)[1]}: test2`;
+ const displayVal3 = ` SEARCH.LOGICAL_SEARCH.${Object.keys(LogicalSearchFields)[2]}: test3`;
+ const displayVal4 = ` SEARCH.LOGICAL_SEARCH.${Object.keys(LogicalSearchFields)[3]}: test4`;
+ expect(component.displayValue$.next).toHaveBeenCalledWith(displayVal1 + displayVal2 + displayVal4 + displayVal3);
});
it('should set correct value and update display value', () => {
spyOn(component.displayValue$, 'next');
- const searchCondition: LogicalSearchCondition = { matchAll: ['test1'], matchAny: ['test2'], exclude: ['test3'] };
+ const searchCondition: LogicalSearchCondition = { matchAll: 'test1', matchAny: 'test2', exclude: 'test3', matchExact: 'test4' };
component.setValue(searchCondition);
expect(component.getCurrentValue()).toEqual(searchCondition);
expect(component.displayValue$.next).toHaveBeenCalled();
});
it('should reset value and display value when reset is called', () => {
- const searchCondition: LogicalSearchCondition = { matchAll: ['test1'], matchAny: ['test2'], exclude: ['test3'] };
+ const searchCondition: LogicalSearchCondition = { matchAll: 'test1', matchAny: 'test2', exclude: 'test3', matchExact: 'test4' };
component.setValue(searchCondition);
fixture.detectChanges();
spyOn(component.context, 'update');
@@ -125,14 +123,13 @@ describe('SearchLogicalFilterComponent', () => {
component.reset();
expect(component.context.queryFragments[component.id]).toBe('');
expect(component.context.update).toHaveBeenCalled();
- expect(component.getCurrentValue()).toEqual({ matchAll: [], matchAny: [], exclude: [] });
+ expect(component.getCurrentValue()).toEqual({ matchAll: '', matchAny: '', exclude: '', matchExact: '' });
expect(component.displayValue$.next).toHaveBeenCalledWith('');
});
it('should form correct query from match all field', () => {
spyOn(component.context, 'update');
- enterNewPhrase('test1', 0);
- enterNewPhrase('test2', 0);
+ enterNewPhrase(' test1 test2 ', 0);
component.submitValues();
expect(component.context.update).toHaveBeenCalled();
expect(component.context.queryFragments[component.id]).toBe('((field1:"test1" AND field1:"test2") OR (field2:"test1" AND field2:"test2"))');
@@ -140,8 +137,7 @@ describe('SearchLogicalFilterComponent', () => {
it('should form correct query from match any field', () => {
spyOn(component.context, 'update');
- enterNewPhrase('test3', 1);
- enterNewPhrase('test4', 1);
+ enterNewPhrase(' test3 test4', 1);
component.submitValues();
expect(component.context.update).toHaveBeenCalled();
expect(component.context.queryFragments[component.id]).toBe('((field1:"test3" OR field1:"test4") OR (field2:"test3" OR field2:"test4"))');
@@ -149,23 +145,32 @@ describe('SearchLogicalFilterComponent', () => {
it('should form correct query from exclude field', () => {
spyOn(component.context, 'update');
- enterNewPhrase('test5', 2);
- enterNewPhrase('test6', 2);
+ enterNewPhrase('test5 test6 ', 2);
component.submitValues();
expect(component.context.update).toHaveBeenCalled();
expect(component.context.queryFragments[component.id]).toBe('((NOT field1:"test5" AND NOT field1:"test6") AND (NOT field2:"test5" AND NOT field2:"test6"))');
});
+ it('should form correct query from match exact field and trim it', () => {
+ spyOn(component.context, 'update');
+ enterNewPhrase(' test7 test8 ', 3);
+ component.submitValues();
+ expect(component.context.update).toHaveBeenCalled();
+ expect(component.context.queryFragments[component.id]).toBe('((field1:"test7 test8") OR (field2:"test7 test8"))');
+ });
+
it('should form correct joined query from all fields', () => {
spyOn(component.context, 'update');
enterNewPhrase('test1', 0);
enterNewPhrase('test2', 1);
enterNewPhrase('test3', 2);
+ enterNewPhrase('test4', 3);
component.submitValues();
const subQuery1 = '((field1:"test1") OR (field2:"test1"))';
const subQuery2 = '((field1:"test2") OR (field2:"test2"))';
const subQuery3 = '((NOT field1:"test3") AND (NOT field2:"test3"))';
+ const subQuery4 = '((field1:"test4") OR (field2:"test4"))';
expect(component.context.update).toHaveBeenCalled();
- expect(component.context.queryFragments[component.id]).toBe(`${subQuery1} AND ${subQuery2} AND ${subQuery3}`);
+ expect(component.context.queryFragments[component.id]).toBe(`${subQuery1} AND ${subQuery2} AND ${subQuery4} AND ${subQuery3}`);
});
});
diff --git a/lib/content-services/src/lib/search/components/search-logical-filter/search-logical-filter.component.ts b/lib/content-services/src/lib/search/components/search-logical-filter/search-logical-filter.component.ts
index 6ae5784ff9..5bbeed7703 100644
--- a/lib/content-services/src/lib/search/components/search-logical-filter/search-logical-filter.component.ts
+++ b/lib/content-services/src/lib/search/components/search-logical-filter/search-logical-filter.component.ts
@@ -25,10 +25,11 @@ import { TranslationService } from '@alfresco/adf-core';
export enum LogicalSearchFields {
MATCH_ALL = 'matchAll',
MATCH_ANY = 'matchAny',
- EXCLUDE = 'exclude'
+ EXCLUDE = 'exclude',
+ MATCH_EXACT = 'matchExact'
}
-export type LogicalSearchConditionEnumValuedKeys = { [T in LogicalSearchFields]: string[]; };
+export type LogicalSearchConditionEnumValuedKeys = { [T in LogicalSearchFields]: string; };
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface LogicalSearchCondition extends LogicalSearchConditionEnumValuedKeys {}
@@ -39,26 +40,22 @@ export interface LogicalSearchCondition extends LogicalSearchConditionEnumValued
encapsulation: ViewEncapsulation.None
})
export class SearchLogicalFilterComponent implements SearchWidget, OnInit {
- private searchCondition: LogicalSearchCondition;
- private reset$ = new Subject