Skip to content

Commit

Permalink
show confirmation dialog before leaving edit mode in some cases
Browse files Browse the repository at this point in the history
  • Loading branch information
christianblos committed Jun 20, 2018
1 parent cbe5d26 commit 731b92c
Show file tree
Hide file tree
Showing 12 changed files with 223 additions and 17 deletions.
8 changes: 8 additions & 0 deletions src/app/renderer/actions/entries/closeEditEntry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import {CloseEditEntry} from '../../../../domain/useCases/entries/CloseEditEntry';
import {container} from '../../container';

const useCase: CloseEditEntry = container.get(CloseEditEntry);

export function closeEditEntry(): Promise<void> {
return useCase.execute();
}
5 changes: 4 additions & 1 deletion src/app/renderer/actions/fileTree/selectFile.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import {SelectFile} from '../../../../domain/useCases/fileTree/SelectFile';
import {container} from '../../container';
import {confirmLeaveEditMode} from '../../helpers/confirmations/confirmLeaveEditMode';

const useCase: SelectFile = container.get(SelectFile);

export function selectFile(filename: string): Promise<void> {
return useCase.execute(filename);
return confirmLeaveEditMode(() => {
return useCase.execute(filename);
});
}
5 changes: 4 additions & 1 deletion src/app/renderer/actions/fileTree/selectFileVariant.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import {SelectFileVariant} from '../../../../domain/useCases/fileTree/SelectFileVariant';
import {container} from '../../container';
import {confirmLeaveEditMode} from '../../helpers/confirmations/confirmLeaveEditMode';

const useCase: SelectFileVariant = container.get(SelectFileVariant);

export function selectFileVariant(basename: string, variantId: string): Promise<void> {
return useCase.execute(basename, variantId);
return confirmLeaveEditMode(() => {
return useCase.execute(basename, variantId);
});
}
5 changes: 4 additions & 1 deletion src/app/renderer/actions/project/reload.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import {Reload} from '../../../../domain/useCases/project/Reload';
import {container} from '../../container';
import {confirmLeaveEditMode} from '../../helpers/confirmations/confirmLeaveEditMode';

const useCase: Reload = container.get(Reload);

export function reload(): Promise<void> {
return useCase.execute();
return confirmLeaveEditMode(() => {
return useCase.execute();
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {bySearch} from '../../../../../../../domain/context/data/filter/bySearch
import {ActiveFile} from '../../../../../../../domain/states/objects/editor/ActiveFile';
import {DataEntry, EntryId} from '../../../../../../../domain/states/objects/editor/DataEntry';
import {VariantTypeConfig} from '../../../../../../../domain/states/objects/ProjectConfig';
import {closeEditEntry} from '../../../../../actions/entries/closeEditEntry';
import {confirmDeleteEntry} from '../../../../../actions/entries/confirmDeleteEntry';
import {createEntry} from '../../../../../actions/entries/createEntry';
import {openCreateEntry} from '../../../../../actions/entries/openCreateEntry';
Expand Down Expand Up @@ -202,9 +203,7 @@ export class FileEditor extends React.Component<Props, State> {

private onClickAdd = (): void => {
if (!this.props.showFormInline) {
this.props.activeFile.entries.all.forEach((entry: DataEntry) => {
entry.toggleEditMode(false);
});
closeEditEntry();
}
openCreateEntry();
};
Expand Down
26 changes: 15 additions & 11 deletions src/app/renderer/container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,33 @@ import {ProjectRepo} from '../../domain/repositories/ProjectRepo';
import {SchemaRepo} from '../../domain/repositories/SchemaRepo';
import {SettingsRepo} from '../../domain/repositories/SettingsRepo';
import {GetAllVariantIds} from '../../domain/stateQueries/GetAllVariantIds';
import {IsEditing} from '../../domain/stateQueries/IsEditing';
import {EditorState} from '../../domain/states/EditorState';
import {ProjectState} from '../../domain/states/ProjectState';
import {SettingsState} from '../../domain/states/SettingsState';
import {CloseCreateEntry} from '../../domain/useCases/entries/CloseCreateEntry';
import {CloseCreateVariant} from '../../domain/useCases/variants/CloseCreateVariant';
import {CloseProject} from '../../domain/useCases/project/CloseProject';
import {CloseEditEntry} from '../../domain/useCases/entries/CloseEditEntry';
import {CreateEntry} from '../../domain/useCases/entries/CreateEntry';
import {CreateVariant} from '../../domain/useCases/variants/CreateVariant';
import {DeleteEntry} from '../../domain/useCases/entries/DeleteEntry';
import {OpenCreateEntry} from '../../domain/useCases/entries/OpenCreateEntry';
import {SearchInFile} from '../../domain/useCases/entries/SearchInFile';
import {ToggleCollapseEntries} from '../../domain/useCases/entries/ToggleCollapseEntries';
import {UpdateEntry} from '../../domain/useCases/entries/UpdateEntry';
import {CollapseAllDirs} from '../../domain/useCases/fileTree/CollapseAllDirs';
import {ExpandAllDirs} from '../../domain/useCases/fileTree/ExpandAllDirs';
import {ResetFilter} from '../../domain/useCases/fileTree/ResetFilter';
import {SelectFile} from '../../domain/useCases/fileTree/SelectFile';
import {SelectFileVariant} from '../../domain/useCases/fileTree/SelectFileVariant';
import {SelectFilter} from '../../domain/useCases/fileTree/SelectFilter';
import {ToggleCollapseDir} from '../../domain/useCases/fileTree/ToggleCollapseDir';
import {OpenCreateEntry} from '../../domain/useCases/entries/OpenCreateEntry';
import {OpenCreateVariant} from '../../domain/useCases/variants/OpenCreateVariant';
import {CloseProject} from '../../domain/useCases/project/CloseProject';
import {OpenProject} from '../../domain/useCases/project/OpenProject';
import {Reload} from '../../domain/useCases/project/Reload';
import {SearchInFile} from '../../domain/useCases/entries/SearchInFile';
import {SelectFile} from '../../domain/useCases/fileTree/SelectFile';
import {SelectFileVariant} from '../../domain/useCases/fileTree/SelectFileVariant';
import {UpdateEntry} from '../../domain/useCases/entries/UpdateEntry';
import {CloseCreateVariant} from '../../domain/useCases/variants/CloseCreateVariant';
import {CreateVariant} from '../../domain/useCases/variants/CreateVariant';
import {OpenCreateVariant} from '../../domain/useCases/variants/OpenCreateVariant';
import {FilesystemImpl} from './services/FilesystemImpl';
import {SettingsStorageImpl} from './services/SettingsStorageImpl';
import {SelectFilter} from '../../domain/useCases/fileTree/SelectFilter';
import {ResetFilter} from '../../domain/useCases/fileTree/ResetFilter';

let container: Container = new Container();

Expand All @@ -56,6 +58,7 @@ container.bind<SettingsStorageInterface>(SettingsStorageId).to(SettingsStorageIm
// use cases
// - entries
container.bind<CloseCreateEntry>(CloseCreateEntry).toSelf().inSingletonScope();
container.bind<CloseEditEntry>(CloseEditEntry).toSelf().inSingletonScope();
container.bind<CreateEntry>(CreateEntry).toSelf().inSingletonScope();
container.bind<DeleteEntry>(DeleteEntry).toSelf().inSingletonScope();
container.bind<OpenCreateEntry>(OpenCreateEntry).toSelf().inSingletonScope();
Expand All @@ -81,5 +84,6 @@ container.bind<OpenCreateVariant>(OpenCreateVariant).toSelf().inSingletonScope()

// queries
container.bind<GetAllVariantIds>(GetAllVariantIds).toSelf().inSingletonScope();
container.bind<IsEditing>(IsEditing).toSelf().inSingletonScope();

export {container};
38 changes: 38 additions & 0 deletions src/app/renderer/helpers/confirmations/confirmLeaveEditMode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import {remote} from 'electron';
import {closeCreateEntry} from '../../actions/entries/closeCreateEntry';
import {closeEditEntry} from '../../actions/entries/closeEditEntry';
import {closeCreateVariant} from '../../actions/variants/closeCreateVariant';
import {isEditing} from '../../queries/isEditing';

export function confirmLeaveEditMode<R = void>(onOk: Function): Promise<R | void> {
return new Promise((resolve) => {
if (!isEditing()) {
resolve(onOk());
return;
}

remote.dialog.showMessageBox(
{
type: 'warning',
title: 'Leave Edit Mode?',
message: 'You are currently in edit mode. If you proceed, your current form changes will be lost. Do you want to proceed?',
buttons: ['Oh, wait!', 'Yes, leave edit mode'],
cancelId: 0,
defaultId: 1,
},
(buttonId: number) => {
if (buttonId == 1) {
Promise.all([
closeCreateVariant(),
closeCreateEntry(),
closeEditEntry(),
]).then(() => {
resolve(onOk());
});
} else {
resolve();
}
},
);
});
}
8 changes: 8 additions & 0 deletions src/app/renderer/queries/isEditing.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import {IsEditing} from '../../../domain/stateQueries/IsEditing';
import {container} from '../container';

const query: IsEditing = container.get(IsEditing);

export function isEditing(): boolean {
return query.fetch();
}
32 changes: 32 additions & 0 deletions src/domain/stateQueries/IsEditing.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import {injectable} from 'inversify';
import {EditorState} from '../states/EditorState';
import {ActiveFile} from '../states/objects/editor/ActiveFile';
import {DataEntry} from '../states/objects/editor/DataEntry';

@injectable()
export class IsEditing {

constructor(
private editorState: EditorState,
) {
}

fetch(): boolean {
if (this.editorState.isAddVariantMode) {
return true;
}

const currentFile: ActiveFile | null = this.editorState.currentFile;
if (currentFile) {
if (currentFile.isCreateMode) {
return true;
}

if (currentFile.entries.all.some((entry: DataEntry) => entry.editMode)) {
return true;
}
}

return false;
}
}
49 changes: 49 additions & 0 deletions src/domain/stateQueries/__tests__/IsEditing.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import 'jest';
import 'reflect-metadata';
import {EditorState} from '../../states/EditorState';
import {ActiveFile} from '../../states/objects/editor/ActiveFile';
import {DataEntries} from '../../states/objects/editor/DataEntries';
import {DataEntry} from '../../states/objects/editor/DataEntry';
import {IsEditing} from '../IsEditing';

let query: IsEditing;
let editorState: EditorState;
let activeFile: ActiveFile;

beforeEach(() => {
editorState = new EditorState();

activeFile = new ActiveFile('myFile', '/temp/myFile.json');
editorState.open(activeFile);

query = new IsEditing(editorState);
});

describe('IsEditing', () => {
it('returns false when not editing', () => {
expect(query.fetch()).toEqual(false);
});

it('returns true when in create mode', () => {
activeFile.openCreateMode();

expect(query.fetch()).toEqual(true);
});

it('returns true when in edit mode', () => {
let entry1: DataEntry = new DataEntry(1, {id: 1});
let entry2: DataEntry = new DataEntry(2, {id: 2});

entry1.toggleEditMode(true);

activeFile.setLoaded({schema: {}, uiSchema: {}}, new DataEntries([entry1, entry2]));

expect(query.fetch()).toEqual(true);
});

it('returns true when in create variant mode', () => {
editorState.setAddVariantMode(true);

expect(query.fetch()).toEqual(true);
});
});
24 changes: 24 additions & 0 deletions src/domain/useCases/entries/CloseEditEntry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import {injectable} from 'inversify';
import {EditorState} from '../../states/EditorState';
import {DataEntry} from '../../states/objects/editor/DataEntry';

@injectable()
export class CloseEditEntry {

constructor(
private editorState: EditorState,
) {
}

execute(): Promise<void> {
if (!this.editorState.currentFile) {
return Promise.resolve();
}

this.editorState.currentFile.entries.all.forEach((entry: DataEntry) => {
entry.toggleEditMode(false);
});

return Promise.resolve();
}
}
35 changes: 35 additions & 0 deletions src/domain/useCases/entries/__tests__/CloseEditEntry.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import 'jest';
import 'reflect-metadata';
import {EditorState} from '../../../states/EditorState';
import {ActiveFile} from '../../../states/objects/editor/ActiveFile';
import {DataEntries} from '../../../states/objects/editor/DataEntries';
import {DataEntry} from '../../../states/objects/editor/DataEntry';
import {CloseEditEntry} from '../CloseEditEntry';

let useCase: CloseEditEntry;
let editorState: EditorState;

beforeEach(() => {
editorState = new EditorState();

useCase = new CloseEditEntry(editorState);
});

describe('CloseEditEntry', () => {
it('closes edit modes', () => {
let entry1: DataEntry = new DataEntry(1, {id: 1});
let entry2: DataEntry = new DataEntry(2, {id: 2});

entry1.toggleEditMode(true);
entry2.toggleEditMode(true);

editorState.open(new ActiveFile('myFile', '/temp/myFile.json'));
editorState.currentFile!.setLoaded({schema: {}, uiSchema: {}}, new DataEntries([entry1, entry2]));

return useCase.execute()
.then(() => {
expect(editorState.currentFile!.entries.getById(1)!.editMode).toBe(false);
expect(editorState.currentFile!.entries.getById(2)!.editMode).toBe(false);
});
});
});

0 comments on commit 731b92c

Please sign in to comment.