fix pasting in search bar after page load showing no results

This commit is contained in:
undergroundwires
2020-09-16 01:59:11 +01:00
parent 6efed72bf2
commit d169434157
6 changed files with 156 additions and 118 deletions

View File

@@ -2,6 +2,7 @@ import { IFilterResult } from './IFilterResult';
import { ISignal } from '@/infrastructure/Events/Signal'; import { ISignal } from '@/infrastructure/Events/Signal';
export interface IUserFilter { export interface IUserFilter {
readonly currentFilter: IFilterResult | undefined;
readonly filtered: ISignal<IFilterResult>; readonly filtered: ISignal<IFilterResult>;
readonly filterRemoved: ISignal<void>; readonly filterRemoved: ISignal<void>;
setFilter(filter: string): void; setFilter(filter: string): void;

View File

@@ -8,6 +8,7 @@ import { Signal } from '@/infrastructure/Events/Signal';
export class UserFilter implements IUserFilter { export class UserFilter implements IUserFilter {
public readonly filtered = new Signal<IFilterResult>(); public readonly filtered = new Signal<IFilterResult>();
public readonly filterRemoved = new Signal<void>(); public readonly filterRemoved = new Signal<void>();
public currentFilter: IFilterResult | undefined;
constructor(private application: IApplication) { constructor(private application: IApplication) {
@@ -28,11 +29,12 @@ export class UserFilter implements IUserFilter {
filteredCategories, filteredCategories,
filter, filter,
); );
this.currentFilter = matches;
this.filtered.notify(matches); this.filtered.notify(matches);
} }
public removeFilter(): void { public removeFilter(): void {
this.currentFilter = undefined;
this.filterRemoved.notify(); this.filterRemoved.notify();
} }
} }

View File

@@ -49,6 +49,7 @@
state.filter.filtered.on(this.handleFiltered); state.filter.filtered.on(this.handleFiltered);
// Update initial state // Update initial state
await this.initializeNodesAsync(this.categoryId); await this.initializeNodesAsync(this.categoryId);
await this.initializeFilter(state.filter.currentFilter);
} }
public async toggleNodeSelectionAsync(event: INodeSelectedEvent) { public async toggleNodeSelectionAsync(event: INodeSelectedEvent) {
@@ -84,6 +85,14 @@
(category: ICategory) => node.id === getCategoryNodeId(category)); (category: ICategory) => node.id === getCategoryNodeId(category));
} }
private initializeFilter(currentFilter: IFilterResult | undefined) {
if (!currentFilter) {
this.handleFilterRemoved();
} else {
this.handleFiltered(currentFilter);
}
}
private handleSelectionChanged(selectedScripts: ReadonlyArray<SelectedScript>): void { private handleSelectionChanged(selectedScripts: ReadonlyArray<SelectedScript>): void {
this.selectedNodeIds = selectedScripts this.selectedNodeIds = selectedScripts
.map((node) => node.id); .map((node) => node.id);

View File

@@ -35,7 +35,7 @@
Node, Node,
}, },
}) })
export default class SelectableTree extends Vue { export default class SelectableTree extends Vue { // Keep it stateless to make it easier to switch out
@Prop() public filterPredicate?: FilterPredicate; @Prop() public filterPredicate?: FilterPredicate;
@Prop() public filterText?: string; @Prop() public filterText?: string;
@Prop() public selectedNodeIds?: ReadonlyArray<string>; @Prop() public selectedNodeIds?: ReadonlyArray<string>;

View File

@@ -72,7 +72,6 @@
public isSearching = false; public isSearching = false;
public searchHasMatches = false; public searchHasMatches = false;
public async mounted() { public async mounted() {
const state = await this.getCurrentStateAsync(); const state = await this.getCurrentStateAsync();
this.repositoryUrl = state.app.repositoryUrl; this.repositoryUrl = state.app.repositoryUrl;

View File

@@ -7,6 +7,7 @@ import 'mocha';
import { expect } from 'chai'; import { expect } from 'chai';
describe('UserFilter', () => { describe('UserFilter', () => {
describe('removeFilter', () => {
it('signals when removing filter', () => { it('signals when removing filter', () => {
// arrange // arrange
let isCalled = false; let isCalled = false;
@@ -17,6 +18,16 @@ describe('UserFilter', () => {
// assert // assert
expect(isCalled).to.be.equal(true); expect(isCalled).to.be.equal(true);
}); });
it('currentFilter is undefined', () => {
// arrange
const sut = new UserFilter(new ApplicationStub());
// act
sut.removeFilter();
// assert
expect(sut.currentFilter).to.be.equal(undefined);
});
});
describe('setFilter', () => {
it('signals when no matches', () => { it('signals when no matches', () => {
// arrange // arrange
let actual: IFilterResult; let actual: IFilterResult;
@@ -27,8 +38,17 @@ describe('UserFilter', () => {
sut.setFilter(nonMatchingFilter); sut.setFilter(nonMatchingFilter);
// assert // assert
expect(actual.hasAnyMatches()).be.equal(false); expect(actual.hasAnyMatches()).be.equal(false);
expect(actual.categoryMatches).to.have.lengthOf(0); expect(actual.query).to.equal(nonMatchingFilter);
expect(actual.scriptMatches).to.have.lengthOf(0); });
it('sets currentFilter as expected when no matches', () => {
// arrange
const nonMatchingFilter = 'non matching filter';
const sut = new UserFilter(new ApplicationStub());
// act
sut.setFilter(nonMatchingFilter);
// assert
const actual = sut.currentFilter;
expect(actual.hasAnyMatches()).be.equal(false);
expect(actual.query).to.equal(nonMatchingFilter); expect(actual.query).to.equal(nonMatchingFilter);
}); });
describe('signals when script matches', () => { describe('signals when script matches', () => {
@@ -50,6 +70,7 @@ describe('UserFilter', () => {
expect(actual.scriptMatches).to.have.lengthOf(1); expect(actual.scriptMatches).to.have.lengthOf(1);
expect(actual.scriptMatches[0]).to.deep.equal(script); expect(actual.scriptMatches[0]).to.deep.equal(script);
expect(actual.query).to.equal(filter); expect(actual.query).to.equal(filter);
expect(sut.currentFilter).to.deep.equal(actual);
}); });
it('revertCode matches', () => { it('revertCode matches', () => {
// arrange // arrange
@@ -69,6 +90,7 @@ describe('UserFilter', () => {
expect(actual.scriptMatches).to.have.lengthOf(1); expect(actual.scriptMatches).to.have.lengthOf(1);
expect(actual.scriptMatches[0]).to.deep.equal(script); expect(actual.scriptMatches[0]).to.deep.equal(script);
expect(actual.query).to.equal(filter); expect(actual.query).to.equal(filter);
expect(sut.currentFilter).to.deep.equal(actual);
}); });
it('name matches', () => { it('name matches', () => {
// arrange // arrange
@@ -88,8 +110,9 @@ describe('UserFilter', () => {
expect(actual.scriptMatches).to.have.lengthOf(1); expect(actual.scriptMatches).to.have.lengthOf(1);
expect(actual.scriptMatches[0]).to.deep.equal(script); expect(actual.scriptMatches[0]).to.deep.equal(script);
expect(actual.query).to.equal(filter); expect(actual.query).to.equal(filter);
expect(sut.currentFilter).to.deep.equal(actual);
}); });
});
it('signals when category matches', () => { it('signals when category matches', () => {
// arrange // arrange
const categoryName = 'HELLO world'; const categoryName = 'HELLO world';
@@ -107,6 +130,7 @@ describe('UserFilter', () => {
expect(actual.categoryMatches[0]).to.deep.equal(category); expect(actual.categoryMatches[0]).to.deep.equal(category);
expect(actual.scriptMatches).to.have.lengthOf(0); expect(actual.scriptMatches).to.have.lengthOf(0);
expect(actual.query).to.equal(filter); expect(actual.query).to.equal(filter);
expect(sut.currentFilter).to.deep.equal(actual);
}); });
it('signals when category and script matches', () => { it('signals when category and script matches', () => {
// arrange // arrange
@@ -131,5 +155,8 @@ describe('UserFilter', () => {
expect(actual.scriptMatches).to.have.lengthOf(1); expect(actual.scriptMatches).to.have.lengthOf(1);
expect(actual.scriptMatches[0]).to.deep.equal(script); expect(actual.scriptMatches[0]).to.deep.equal(script);
expect(actual.query).to.equal(filter); expect(actual.query).to.equal(filter);
expect(sut.currentFilter).to.deep.equal(actual);
});
});
}); });
}); });