diff --git a/config/environment.default.js b/config/environment.default.js index 1d121f5fbe..6a32874e4d 100644 --- a/config/environment.default.js +++ b/config/environment.default.js @@ -49,33 +49,60 @@ module.exports = { // NOTE: every how many minutes submission is saved automatically timer: 5 }, - metadata: { - // NOTE: allow to set icons used to represent metadata belonging to a relation group - icons: [ + icons: { + metadata: [ /** * NOTE: example of configuration * { * // NOTE: metadata name * name: 'dc.author', - * config: { - * // NOTE: used when metadata value has an authority - * withAuthority: { - * // NOTE: fontawesome (v4.x) icon classes and bootstrap color utility classes can be used - * style: 'fa-user' - * }, - * // NOTE: used when metadata value has not an authority - * withoutAuthority: { - * style: 'fa-user text-muted' - * } - * } + * // NOTE: fontawesome (v4.x) icon classes and bootstrap utility classes can be used + * style: 'fa-user' * } */ + { + // NOTE: metadata name + name: 'dc.author', + // NOTE: fontawesome (v4.x) icon classes and bootstrap utility classes can be used + style: 'fa-user' + }, // default configuration { name: 'default', - config: {} + style: '' } - ] + ], + authority: { + confidence: [ + /** + * NOTE: example of configuration + * { + * // NOTE: confidence value + * value: 'dc.author', + * // NOTE: fontawesome (v4.x) icon classes and bootstrap utility classes can be used + * style: 'fa-user' + * } + */ + { + value: 600, + style: 'text-success' + }, + { + value: 500, + style: 'text-info' + }, + { + value: 400, + style: 'text-warning' + }, + // default configuration + { + value: 'default', + style: 'text-muted' + }, + + ] + } } }, // Angular Universal settings diff --git a/src/app/core/integration/models/confidence-type.ts b/src/app/core/integration/models/confidence-type.ts new file mode 100644 index 0000000000..3630d02970 --- /dev/null +++ b/src/app/core/integration/models/confidence-type.ts @@ -0,0 +1,44 @@ +export enum ConfidenceType { + /** + * This authority value has been confirmed as accurate by an + * interactive user or authoritative policy + */ + CF_ACCEPTED = 600, + + /** + * Value is singular and valid but has not been seen and accepted + * by a human, so its provenance is uncertain. + */ + CF_UNCERTAIN = 500, + + /** + * There are multiple matching authority values of equal validity. + */ + CF_AMBIGUOUS = 400, + + /** + * There are no matching answers from the authority. + */ + CF_NOTFOUND = 300, + + /** + * The authority encountered an internal failure - this preserves a + * record in the metadata of why there is no value. + */ + CF_FAILED = 200, + + /** + * The authority recommends this submission be rejected. + */ + CF_REJECTED = 100, + + /** + * No reasonable confidence value is available + */ + CF_NOVALUE = 0, + + /** + * Value has not been set (DB default). + */ + CF_UNSET = -1 +} diff --git a/src/app/shared/authority-confidence/authority-confidence-state.directive.ts b/src/app/shared/authority-confidence/authority-confidence-state.directive.ts new file mode 100644 index 0000000000..81d39c157e --- /dev/null +++ b/src/app/shared/authority-confidence/authority-confidence-state.directive.ts @@ -0,0 +1,95 @@ +import { + Directive, + ElementRef, EventEmitter, + HostListener, + Inject, + Input, + OnChanges, + Output, + Renderer2, + SimpleChanges +} from '@angular/core'; + +import { findIndex } from 'lodash'; + +import { AuthorityValue } from '../../core/integration/models/authority.value'; +import { FormFieldMetadataValueObject } from '../form/builder/models/form-field-metadata-value.model'; +import { ConfidenceType } from '../../core/integration/models/confidence-type'; +import { isNotEmpty, isNull } from '../empty.util'; +import { GLOBAL_CONFIG, GlobalConfig } from '../../../config'; +import { ConfidenceIconConfig } from '../../../config/submission-config.interface'; + +@Directive({ + selector: '[dsAuthorityConfidenceState]' +}) +export class AuthorityConfidenceStateDirective implements OnChanges { + + @Input() authorityValue: AuthorityValue | FormFieldMetadataValueObject | string; + + private previousClass: string = null; + private newClass: string; + + @Output() whenClickOnConfidenceNotAccepted: EventEmitter = new EventEmitter(); + + @HostListener('click') onClick() { + if (isNotEmpty(this.authorityValue) && this.getConfidenceByValue(this.authorityValue) !== ConfidenceType.CF_ACCEPTED) { + this.whenClickOnConfidenceNotAccepted.emit(this.getConfidenceByValue(this.authorityValue)); + } + } + + constructor( + @Inject(GLOBAL_CONFIG) protected EnvConfig: GlobalConfig, + private elem: ElementRef, + private renderer: Renderer2 + ) { + } + + ngOnChanges(changes: SimpleChanges): void { + if (!changes.authorityValue.firstChange) { + this.previousClass = this.getClassByConfidence(this.getConfidenceByValue(changes.authorityValue.previousValue)) + } + this.newClass = this.getClassByConfidence(this.getConfidenceByValue(changes.authorityValue.currentValue)); + + if (isNull(this.previousClass)) { + this.renderer.addClass(this.elem.nativeElement, this.newClass); + } else if (this.previousClass !== this.newClass) { + this.renderer.removeClass(this.elem.nativeElement, this.previousClass); + this.renderer.addClass(this.elem.nativeElement, this.newClass); + } + } + + ngAfterViewInit() { + if (isNull(this.previousClass)) { + this.renderer.addClass(this.elem.nativeElement, this.newClass); + } else if (this.previousClass !== this.newClass) { + this.renderer.removeClass(this.elem.nativeElement, this.previousClass); + this.renderer.addClass(this.elem.nativeElement, this.newClass); + } + } + + private getConfidenceByValue(value: any): ConfidenceType { + let confidence: ConfidenceType = ConfidenceType.CF_UNSET; + + if (isNotEmpty(value) && value instanceof AuthorityValue && value.hasAuthority()) { + confidence = ConfidenceType.CF_ACCEPTED; + } + + if (isNotEmpty(value) && value instanceof FormFieldMetadataValueObject) { + confidence = value.confidence; + } + + return confidence; + } + + private getClassByConfidence(confidence: any): string { + const confidenceIcons: ConfidenceIconConfig[] = this.EnvConfig.submission.icons.authority.confidence; + + const confidenceIndex: number = findIndex(confidenceIcons, {value: confidence}); + + const defaultconfidenceIndex: number = findIndex(confidenceIcons, {value: 'default'}); + const defaultClass: string = (defaultconfidenceIndex !== -1) ? confidenceIcons[defaultconfidenceIndex].style : ''; + + return (confidenceIndex !== -1) ? confidenceIcons[confidenceIndex].style : defaultClass; + } + +} diff --git a/src/app/shared/chips/chips.component.html b/src/app/shared/chips/chips.component.html index 8e6ca4ebc9..0b632d1073 100644 --- a/src/app/shared/chips/chips.component.html +++ b/src/app/shared/chips/chips.component.html @@ -20,7 +20,8 @@ [ngClass]="{'chip-selected disabled': (editable && c.editMode) || dragged == i}" (click)="chipsSelected($event, i);"> - + +