Merge branch 'feature-context-help-7.2' into feature-context-help-7.4

This commit is contained in:
Koen Pauwels
2023-01-16 11:11:33 +01:00
9 changed files with 34 additions and 32 deletions

View File

@@ -10,7 +10,7 @@ describe('ContextHelpToggleComponent', () => {
let component: ContextHelpToggleComponent; let component: ContextHelpToggleComponent;
let fixture: ComponentFixture<ContextHelpToggleComponent>; let fixture: ComponentFixture<ContextHelpToggleComponent>;
let contextHelpService; let contextHelpService;
let contextHelpEmpty$ = new BehaviorSubject(true); const contextHelpEmpty$ = new BehaviorSubject(true);
beforeEach(async () => { beforeEach(async () => {
contextHelpService = jasmine.createSpyObj('contextHelpService', contextHelpService = jasmine.createSpyObj('contextHelpService',

View File

@@ -53,9 +53,9 @@ describe('ContextHelpWrapperComponent', () => {
let shouldShowIcons$: BehaviorSubject<boolean>; let shouldShowIcons$: BehaviorSubject<boolean>;
function makeWrappedElement(): HTMLElement { function makeWrappedElement(): HTMLElement {
let el: HTMLElement = document.createElement('div') const wrapped: HTMLElement = document.createElement('div');
el.innerHTML = 'example element'; wrapped.innerHTML = 'example element';
return el; return wrapped;
} }
beforeEach(waitForAsync( () => { beforeEach(waitForAsync( () => {
@@ -96,8 +96,8 @@ describe('ContextHelpWrapperComponent', () => {
fixture = TestBed.createComponent(TemplateComponent); fixture = TestBed.createComponent(TemplateComponent);
el = fixture.debugElement; el = fixture.debugElement;
templateComponent = fixture.componentInstance; templateComponent = fixture.componentInstance;
templateComponent.content = 'lorem' templateComponent.content = 'lorem';
templateComponent.id = 'test-tooltip' templateComponent.id = 'test-tooltip';
templateComponent.tooltipPlacement = ['bottom']; templateComponent.tooltipPlacement = ['bottom'];
templateComponent.iconPlacement = 'left'; templateComponent.iconPlacement = 'left';
wrapperComponent = el.query(By.css('ds-context-help-wrapper')).componentInstance; wrapperComponent = el.query(By.css('ds-context-help-wrapper')).componentInstance;
@@ -111,7 +111,7 @@ describe('ContextHelpWrapperComponent', () => {
it('should not show the context help icon while icon visibility is not turned on', (done) => { it('should not show the context help icon while icon visibility is not turned on', (done) => {
fixture.whenStable().then(() => { fixture.whenStable().then(() => {
let wrapper = el.query(By.css('ds-context-help-wrapper')).nativeElement; const wrapper = el.query(By.css('ds-context-help-wrapper')).nativeElement;
expect(wrapper.children.length).toBe(0); expect(wrapper.children.length).toBe(0);
done(); done();
}); });
@@ -127,9 +127,9 @@ describe('ContextHelpWrapperComponent', () => {
it('should show the context help button', (done) => { it('should show the context help button', (done) => {
fixture.whenStable().then(() => { fixture.whenStable().then(() => {
let wrapper = el.query(By.css('ds-context-help-wrapper')).nativeElement; const wrapper = el.query(By.css('ds-context-help-wrapper')).nativeElement;
expect(wrapper.children.length).toBe(1); expect(wrapper.children.length).toBe(1);
let [i] = wrapper.children; const [i] = wrapper.children;
expect(i.tagName).toBe('I'); expect(i.tagName).toBe('I');
done(); done();
}); });
@@ -160,7 +160,7 @@ describe('ContextHelpWrapperComponent', () => {
const nodeList: NodeList = fixture.debugElement.query(By.css('.ds-context-help-content')) const nodeList: NodeList = fixture.debugElement.query(By.css('.ds-context-help-content'))
.nativeElement .nativeElement
.childNodes; .childNodes;
const relevantNodes = Array.from(nodeList).filter(node => node.nodeType != Node.COMMENT_NODE); const relevantNodes = Array.from(nodeList).filter(node => node.nodeType !== Node.COMMENT_NODE);
expect(relevantNodes.length).toBe(4); expect(relevantNodes.length).toBe(4);
const [text1, link1, text2, link2] = relevantNodes; const [text1, link1, text2, link2] = relevantNodes;
@@ -190,7 +190,7 @@ describe('ContextHelpWrapperComponent', () => {
const nodeList: NodeList = fixture.debugElement.query(By.css('.ds-context-help-content')) const nodeList: NodeList = fixture.debugElement.query(By.css('.ds-context-help-content'))
.nativeElement .nativeElement
.childNodes; .childNodes;
const relevantNodes = Array.from(nodeList).filter(node => node.nodeType != Node.COMMENT_NODE); const relevantNodes = Array.from(nodeList).filter(node => node.nodeType !== Node.COMMENT_NODE);
expect(relevantNodes.length).toBe(1); expect(relevantNodes.length).toBe(1);
const [text] = relevantNodes; const [text] = relevantNodes;

View File

@@ -55,8 +55,8 @@ export class ContextHelpWrapperComponent implements OnInit, OnDestroy {
tooltip: NgbTooltip; tooltip: NgbTooltip;
@Input() set content(content : string) { @Input() set content(translateKey: string) {
this.content$.next(content); this.content$.next(translateKey);
} }
private content$: BehaviorSubject<string | undefined> = new BehaviorSubject(undefined); private content$: BehaviorSubject<string | undefined> = new BehaviorSubject(undefined);
@@ -72,11 +72,11 @@ export class ContextHelpWrapperComponent implements OnInit, OnDestroy {
ngOnInit() { ngOnInit() {
this.parsedContent$ = combineLatest([ this.parsedContent$ = combineLatest([
this.content$.pipe(distinctUntilChanged(), mergeMap(content => this.translateService.get(content))), this.content$.pipe(distinctUntilChanged(), mergeMap(translateKey => this.translateService.get(translateKey))),
this.dontParseLinks$.pipe(distinctUntilChanged()) this.dontParseLinks$.pipe(distinctUntilChanged())
]).pipe( ]).pipe(
map(([content, dontParseLinks]) => map(([text, dontParseLinks]) =>
dontParseLinks ? [content] : this.parseLinks(content)) dontParseLinks ? [text] : this.parseLinks(text))
); );
this.shouldShowIcon$ = this.contextHelpService.shouldShowIcons$(); this.shouldShowIcon$ = this.contextHelpService.shouldShowIcons$();
this.subs.always = [this.parsedContent$.subscribe(), this.shouldShowIcon$.subscribe()]; this.subs.always = [this.parsedContent$.subscribe(), this.shouldShowIcon$.subscribe()];
@@ -136,7 +136,7 @@ export class ContextHelpWrapperComponent implements OnInit, OnDestroy {
* {href: "https://youtube.com", text: "so is this"} * {href: "https://youtube.com", text: "so is this"}
* ] * ]
*/ */
private parseLinks(content: string): ParsedContent { private parseLinks(text: string): ParsedContent {
// Implementation note: due to `matchAll` method on strings not being available for all versions, // Implementation note: due to `matchAll` method on strings not being available for all versions,
// separate "split" and "parse" steps are needed. // separate "split" and "parse" steps are needed.
@@ -152,7 +152,7 @@ export class ContextHelpWrapperComponent implements OnInit, OnDestroy {
// {href: string, text: string} objects. // {href: string, text: string} objects.
const parseRegexp = /^\[([^\]]*)\]\(([^\)]*)\)$/; const parseRegexp = /^\[([^\]]*)\]\(([^\)]*)\)$/;
return content.match(splitRegexp).map((substring: string) => { return text.match(splitRegexp).map((substring: string) => {
const match = substring.match(parseRegexp); const match = substring.match(parseRegexp);
return match === null return match === null
? substring ? substring

View File

@@ -1,3 +1,5 @@
/* eslint-disable max-classes-per-file */
import { Action } from '@ngrx/store'; import { Action } from '@ngrx/store';
import { type } from './ngrx/type'; import { type } from './ngrx/type';
import { ContextHelp } from './context-help.model'; import { ContextHelp } from './context-help.model';

View File

@@ -62,7 +62,7 @@ describe('ContextHelpDirective', () => {
{ provide: ContextHelpService, useValue: contextHelpService } { provide: ContextHelpService, useValue: contextHelpService }
], ],
declarations: [TestComponent, ContextHelpWrapperComponent, ContextHelpDirective] declarations: [TestComponent, ContextHelpWrapperComponent, ContextHelpDirective]
}).compileComponents() }).compileComponents();
})); }));
beforeEach(() => { beforeEach(() => {
@@ -85,10 +85,10 @@ describe('ContextHelpDirective', () => {
it('should generate the context help wrapper component', (done) => { it('should generate the context help wrapper component', (done) => {
fixture.whenStable().then(() => { fixture.whenStable().then(() => {
expect(fixture.nativeElement.children.length).toBe(1); expect(fixture.nativeElement.children.length).toBe(1);
let [wrapper] = fixture.nativeElement.children; const [wrapper] = fixture.nativeElement.children;
expect(component).toBeDefined(); expect(component).toBeDefined();
expect(wrapper.tagName).toBe('DS-CONTEXT-HELP-WRAPPER'); expect(wrapper.tagName).toBe('DS-CONTEXT-HELP-WRAPPER');
expect(contextHelpService.add).toHaveBeenCalledWith(exampleContextHelp) expect(contextHelpService.add).toHaveBeenCalledWith(exampleContextHelp);
done(); done();
}); });
}); });

View File

@@ -47,7 +47,7 @@ export class ContextHelpDirective implements OnChanges, OnDestroy {
private viewContainerRef: ViewContainerRef, private viewContainerRef: ViewContainerRef,
private componentFactoryResolver: ComponentFactoryResolver, private componentFactoryResolver: ComponentFactoryResolver,
private contextHelpService: ContextHelpService private contextHelpService: ContextHelpService
){} ) {}
ngOnChanges() { ngOnChanges() {
this.clearMostRecentId(); this.clearMostRecentId();

View File

@@ -1,4 +1,4 @@
export class ContextHelp { export class ContextHelp {
id: string; id: string;
isTooltipVisible?: boolean = false; isTooltipVisible = false;
} }

View File

@@ -1,9 +1,9 @@
import { ContextHelp } from './context-help.model'; import { ContextHelp } from './context-help.model';
import { ContextHelpAction, ContextHelpActionTypes } from './context-help.actions'; import { ContextHelpAction, ContextHelpActionTypes } from './context-help.actions';
export type ContextHelpModels = { export interface ContextHelpModels {
[id: string]: ContextHelp; [id: string]: ContextHelp;
}; }
export interface ContextHelpState { export interface ContextHelpState {
allIconsVisible: boolean; allIconsVisible: boolean;
@@ -40,8 +40,7 @@ export function contextHelpReducer(state: ContextHelpState = initialState, actio
} }
} }
function modifyTooltipVisibility(state: ContextHelpState, id: string, modify: (vis: boolean) => boolean) function modifyTooltipVisibility(state: ContextHelpState, id: string, modify: (vis: boolean) => boolean): ContextHelpState {
: ContextHelpState {
const {[id]: matchingModel, ...otherModels} = state.models; const {[id]: matchingModel, ...otherModels} = state.models;
const modifiedModel = {...matchingModel, isTooltipVisible: modify(matchingModel.isTooltipVisible)}; const modifiedModel = {...matchingModel, isTooltipVisible: modify(matchingModel.isTooltipVisible)};
const newModels = {...otherModels, [id]: modifiedModel}; const newModels = {...otherModels, [id]: modifiedModel};

View File

@@ -8,10 +8,9 @@ import { TestScheduler } from 'rxjs/testing';
describe('ContextHelpService', () => { describe('ContextHelpService', () => {
let service: ContextHelpService; let service: ContextHelpService;
let store; let store;
let initialState;
let testScheduler; let testScheduler;
const booleans = { f: false, t: true }; const booleans = { f: false, t: true };
const mkContextHelp = (id: string) => ({ 0: {id, isTooltipVisible: false}, 1: {id, isTooltipVisible: true} }) const mkContextHelp = (id: string) => ({ 0: {id, isTooltipVisible: false}, 1: {id, isTooltipVisible: true} });
beforeEach(async () => { beforeEach(async () => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
@@ -42,11 +41,13 @@ describe('ContextHelpService', () => {
it('add and remove calls should be observable in getContextHelp$', () => { it('add and remove calls should be observable in getContextHelp$', () => {
testScheduler.run(({cold, expectObservable}) => { testScheduler.run(({cold, expectObservable}) => {
const modifications = cold('-abAcCB', { const modifications = cold('-abAcCB', {
a: () => service.add({id: 'a'}), b: () => service.add({id: 'b'}), c: () => service.add({id: 'c'}), a: () => service.add({id: 'a', isTooltipVisible: false}),
b: () => service.add({id: 'b', isTooltipVisible: false}),
c: () => service.add({id: 'c', isTooltipVisible: false}),
A: () => service.remove('a'), B: () => service.remove('b'), C: () => service.remove('c'), A: () => service.remove('a'), B: () => service.remove('b'), C: () => service.remove('c'),
}) });
modifications.subscribe(mod => mod()); modifications.subscribe(mod => mod());
const match = (id) => ({ 0: undefined, 1: {id} }); const match = (id) => ({ 0: undefined, 1: {id, isTooltipVisible: false} });
expectObservable(service.getContextHelp$('a')).toBe('01-0---', match('a')); expectObservable(service.getContextHelp$('a')).toBe('01-0---', match('a'));
expectObservable(service.getContextHelp$('b')).toBe('0-1---0', match('b')); expectObservable(service.getContextHelp$('b')).toBe('0-1---0', match('b'));
expectObservable(service.getContextHelp$('c')).toBe('0---10-', match('c')); expectObservable(service.getContextHelp$('c')).toBe('0---10-', match('c'));