Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(resource): migrate viewer from UI-lib (DSP-1850) #504

Merged
merged 12 commits into from Aug 31, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/main.yml
Expand Up @@ -26,6 +26,8 @@ jobs:
run: ./find-ignored-tests.sh
- name: Run unit tests
run: npm run test-ci
env:
TZ: Europe/Zurich
- name: Run e2e tests
run: |
npm run webdriver-update
Expand Down
15 changes: 7 additions & 8 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

66 changes: 66 additions & 0 deletions src/app/app.module.ts
Expand Up @@ -114,6 +114,39 @@ import { KnoraDatePipe } from './main/pipes/formatting/knoradate.pipe';
import { LinkifyPipe } from './main/pipes/string-transformation/linkify.pipe';
import { StringifyStringLiteralPipe } from './main/pipes/string-transformation/stringify-string-literal.pipe';
import { TruncatePipe } from './main/pipes/string-transformation/truncate.pipe';
import { DragDropDirective } from './workspace/resource/directives/drag-drop.directive';
import { TextValueHtmlLinkDirective } from './workspace/resource/directives/text-value-html-link.directive';
import { BooleanValueComponent } from './workspace/resource/values/boolean-value/boolean-value.component';
import { ColorValueComponent } from './workspace/resource/values/color-value/color-value.component';
import { ColorPickerComponent } from './workspace/resource/values/color-value/color-picker/color-picker.component';
import { JDNDatepickerDirective } from './workspace/resource/values/jdn-datepicker-directive/jdndatepicker.directive';
import { DateValueComponent } from './workspace/resource/values/date-value/date-value.component';
import { CalendarHeaderComponent } from './workspace/resource/values/date-value/calendar-header/calendar-header.component';
import { DateInputComponent } from './workspace/resource/values/date-value/date-input/date-input.component';
import { DateInputTextComponent } from './workspace/resource/values/date-value/date-input-text/date-input-text.component';
import { DateEditComponent } from './workspace/resource/values/date-value/date-input-text/date-edit/date-edit.component';
import { ColorPickerModule } from 'ngx-color-picker';
import { DecimalValueComponent } from './workspace/resource/values/decimal-value/decimal-value.component';
import { GeonameValueComponent } from './workspace/resource/values/geoname-value/geoname-value.component';
import { IntValueComponent } from './workspace/resource/values/int-value/int-value.component';
import { IntervalValueComponent } from './workspace/resource/values/interval-value/interval-value.component';
import { IntervalInputComponent } from './workspace/resource/values/interval-value/interval-input/interval-input.component';
import { LinkValueComponent } from './workspace/resource/values/link-value/link-value.component';
import { ListValueComponent } from './workspace/resource/values/list-value/list-value.component';
import { SublistValueComponent } from './workspace/resource/values/list-value/subList-value/sublist-value.component';
import { TextValueAsHtmlComponent } from './workspace/resource/values/text-value/text-value-as-html/text-value-as-html.component';
import { TextValueAsStringComponent } from './workspace/resource/values/text-value/text-value-as-string/text-value-as-string.component';
import { TextValueAsXMLComponent } from './workspace/resource/values/text-value/text-value-as-xml/text-value-as-xml.component';
import { CKEditorModule } from '@ckeditor/ckeditor5-angular';
import { TimeValueComponent } from './workspace/resource/values/time-value/time-value.component';
import { TimeInputComponent } from './workspace/resource/values/time-value/time-input/time-input.component';
import { UriValueComponent } from './workspace/resource/values/uri-value/uri-value.component';
import { AddValueComponent } from './workspace/resource/operations/add-value/add-value.component';
import { DisplayEditComponent } from './workspace/resource/operations/display-edit/display-edit.component';
import { ListViewComponent } from './workspace/results/list-view/list-view.component';
import { ResourceGridComponent } from './workspace/results/list-view/resource-grid/resource-grid.component';
import { ResourceListComponent } from './workspace/results/list-view/resource-list/resource-list.component';
import { ComparisonComponent } from './workspace/comparison/comparison.component';

// translate: AoT requires an exported function for factories
export function httpLoaderFactory(httpClient: HttpClient) {
Expand Down Expand Up @@ -214,13 +247,46 @@ export function httpLoaderFactory(httpClient: HttpClient) {
LinkifyPipe,
StringifyStringLiteralPipe,
TruncatePipe,
DragDropDirective,
TextValueHtmlLinkDirective,
BooleanValueComponent,
ColorValueComponent,
ColorPickerComponent,
JDNDatepickerDirective,
DateValueComponent,
CalendarHeaderComponent,
DateInputComponent,
DateInputTextComponent,
DateEditComponent,
DecimalValueComponent,
GeonameValueComponent,
IntValueComponent,
IntervalValueComponent,
IntervalInputComponent,
LinkValueComponent,
ListValueComponent,
SublistValueComponent,
TextValueAsHtmlComponent,
TextValueAsStringComponent,
TextValueAsXMLComponent,
TimeValueComponent,
TimeInputComponent,
UriValueComponent,
AddValueComponent,
DisplayEditComponent,
ListViewComponent,
ResourceGridComponent,
ResourceListComponent,
ComparisonComponent,
],
imports: [
AppRoutingModule,
AngularSplitModule.forRoot(),
BrowserAnimationsModule,
BrowserModule,
CKEditorModule,
ClipboardModule,
ColorPickerModule,
CommonModule,
DspActionModule,
DspCoreModule,
Expand Down
57 changes: 49 additions & 8 deletions src/app/main/directive/base-value.directive.ts
Expand Up @@ -6,7 +6,6 @@ import { Subscription } from 'rxjs';
@Directive()
export abstract class BaseValueDirective {


/**
* value to be displayed, if any.
*/
Expand All @@ -17,6 +16,21 @@ export abstract class BaseValueDirective {
*/
@Input() mode: 'read' | 'update' | 'create' | 'search';

/**
* parent FormGroup that contains all child FormGroups
*/
@Input() parentForm?: FormGroup;

/**
* name of the FormGroup, used to add to the parentForm because the name needs to be unique
*/
@Input() formName = 'Untitled FormGroup';

/**
* controls if the value should be required.
*/
@Input() valueRequiredValidator = true;

shouldShowComment = false;

/**
Expand Down Expand Up @@ -67,7 +81,7 @@ export abstract class BaseValueDirective {
=> ValidatorFn = (initValue: any, initComment: string, commentFormControl: FormControl): ValidatorFn => (control: AbstractControl): { [key: string]: any } | null => {

const invalid = this.standardValueComparisonFunc(initValue, control.value)
&& (initComment === commentFormControl.value || (initComment === null && commentFormControl.value === ''));
&& (initComment === commentFormControl.value || (initComment === null && commentFormControl.value === ''));

return invalid ? { valueNotChanged: { value: control.value } } : null;
};
Expand Down Expand Up @@ -107,8 +121,11 @@ export abstract class BaseValueDirective {
this.valueFormControl.setValidators([Validators.required, this.standardValidatorFunc(initialValue, initialComment, this.commentFormControl)].concat(this.customValidators));
} else {
// console.log('reset read/create validators');
this.valueFormControl.setValidators([Validators.required].concat(this.customValidators));

if (this.valueRequiredValidator) {
this.valueFormControl.setValidators([Validators.required].concat(this.customValidators));
} else {
this.valueFormControl.setValidators(this.customValidators);
}
}

this.valueFormControl.updateValueAndValidity();
Expand Down Expand Up @@ -138,6 +155,31 @@ export abstract class BaseValueDirective {
this.shouldShowComment = !this.shouldShowComment;
}

/**
* add the value components FormGroup to a parent FormGroup if one is defined
*/
addToParentFormGroup(name: string, form: FormGroup) {
if (this.parentForm) {
this.parentForm.addControl(name, form);
}
}

/**
* remove the value components FormGroup from a parent FormGroup if one is defined
*/
removeFromParentFormGroup(name: string) {
if (this.parentForm) {
this.parentForm.removeControl(name);
}
}

/**
* checks if the value is empty.
*/
isEmptyVal(): boolean {
return this.valueFormControl.value === null || this.valueFormControl.value === '';
}

/**
* returns the initially given value set via displayValue.
* Returns null if no value was given.
Expand All @@ -151,10 +193,9 @@ export abstract class BaseValueDirective {
abstract getNewValue(): CreateValue | false;

/**
* returns a value that is to be updated.
* Returns false if invalid.
*/
* returns a value that is to be updated.
* Returns false if invalid.
*/
abstract getUpdatedValue(): UpdateValue | false;


}
48 changes: 48 additions & 0 deletions src/app/search/services/advanced-search-params.service.spec.ts
@@ -0,0 +1,48 @@
import { TestBed } from '@angular/core/testing';

import { AdvancedSearchParams, AdvancedSearchParamsService } from './advanced-search-params.service';

describe('SearchParamsService', () => {
let service: AdvancedSearchParamsService;

beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(AdvancedSearchParamsService);
});

it('should be created', () => {
expect(service).toBeTruthy();
});

it('should return false when initialized', () => {
const searchParams: AdvancedSearchParams = service.getSearchParams();

expect(searchParams.generateGravsearch(0)).toBeFalsy();
});

it('should set the parameters of an advanced search', () => {
const testMethod1 = (offset: number) => 'test1';

service.changeSearchParamsMsg(new AdvancedSearchParams(testMethod1));

const searchParams: AdvancedSearchParams = service.getSearchParams();

expect(searchParams.generateGravsearch(0)).toEqual('test1');

// check if value is still present
expect(searchParams.generateGravsearch(0)).toEqual('test1');

const testMethod2 = (offset: number) => 'test2';

service.changeSearchParamsMsg(new AdvancedSearchParams(testMethod2));

const searchParams2: AdvancedSearchParams = service.getSearchParams();

expect(searchParams2.generateGravsearch(0)).toEqual('test2');

// check if value is still present
expect(searchParams2.generateGravsearch(0)).toEqual('test2');

});

});
53 changes: 53 additions & 0 deletions src/app/search/services/advanced-search-params.service.ts
@@ -0,0 +1,53 @@
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

/*
* represents the parameters of an advanced search.
*/
export class AdvancedSearchParams {

/**
*
* @param generateGravsearch a function that generates a Gravsearch query.
*
* The function takes the offset
* as a parameter and returns a Gravsearch query string.
* Returns false if not set correctly (init state).
*/
constructor(public generateGravsearch: (offset: number) => string | boolean) {

}

}

@Injectable({
providedIn: 'root'
})
export class AdvancedSearchParamsService {

private _currentSearchParams;

constructor() {
// init with a dummy function that returns false
// if the application is reloaded, this will be returned
this._currentSearchParams = new BehaviorSubject<AdvancedSearchParams>(new AdvancedSearchParams((offset: number) => false));
}

/**
* updates the parameters of an advanced search.
*
* @param searchParams new advanced search params.
*/
changeSearchParamsMsg(searchParams: AdvancedSearchParams): void {
this._currentSearchParams.next(searchParams);
}

/**
* gets the search params of an advanced search.
*
*/
getSearchParams(): AdvancedSearchParams {
return this._currentSearchParams.getValue();
}

}