* feat(notification): Add undoable notification * feat(notification): Add undoable notification * feat(notification): Use uhk-header to the notification * half ready solution * - fix: "Keymap has been deleted" is displayed for macros. - When a keymap/macro deletion gets undone, please set the route of the restored keymap/macro. - When the user switches to another route, please make the undo notification disappear. * fix(keymap): Store prev user configuration in the application reducer Store the previous state in application reducer, because refactoring the user-config reducer is not easy * feat(keymap): Fix review request
This commit is contained in:
committed by
László Monda
parent
ce55cac380
commit
42683e32f9
@@ -106,6 +106,7 @@ import { AppUpdateRendererService } from './services/app-update-renderer.service
|
||||
import { reducer } from './store';
|
||||
import { AutoUpdateSettings } from './shared/components/auto-update-settings/auto-update-settings';
|
||||
import { angularNotifierConfig } from './shared/models/angular-notifier-config';
|
||||
import { UndoableNotifierComponent } from './shared/components/undoable-notifier';
|
||||
import { UhkHeader } from './shared/components/uhk-header/uhk-header';
|
||||
import { AppRendererService } from './services/app-renderer.service';
|
||||
|
||||
@@ -166,6 +167,7 @@ import { AppRendererService } from './services/app-renderer.service';
|
||||
SafeStylePipe,
|
||||
UpdateAvailableComponent,
|
||||
AutoUpdateSettings,
|
||||
UndoableNotifierComponent,
|
||||
UhkHeader
|
||||
],
|
||||
imports: [
|
||||
|
||||
@@ -14,4 +14,4 @@
|
||||
|
||||
<div *ngIf="!macro" class="not-found">
|
||||
There is no macro with id {{ route.params.select('id') | async }}.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
<uhk-header></uhk-header>
|
||||
<div class="not-found">
|
||||
You don't have any macros. Try to add one!
|
||||
<div class="container-fluid">
|
||||
<uhk-header>
|
||||
<h1> </h1>
|
||||
</uhk-header>
|
||||
<div class="not-found">
|
||||
You don't have any macros. Try to add one!
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
<div>
|
||||
<ng-content></ng-content>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<undoable-notifier [notification]="undoableNotification$ | async"
|
||||
(close)="onDismissLastNotification()"
|
||||
(undo)="onUndoLastNotification($event)">
|
||||
</undoable-notifier>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
|
||||
import { Notification } from '../../models/notification';
|
||||
import { AppState, getUndoableNotification } from '../../store/index';
|
||||
import { DismissUndoNotificationAction, UndoLastAction } from '../../store/actions/app.action';
|
||||
|
||||
@Component({
|
||||
selector: 'uhk-header',
|
||||
@@ -6,4 +12,18 @@ import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class UhkHeader {
|
||||
undoableNotification$: Observable<Notification>;
|
||||
|
||||
constructor(private store: Store<AppState>) {
|
||||
this.undoableNotification$ = this.store.select(getUndoableNotification);
|
||||
}
|
||||
|
||||
onUndoLastNotification(data: any): void {
|
||||
this.store.dispatch(new UndoLastAction(data));
|
||||
}
|
||||
|
||||
onDismissLastNotification(): void {
|
||||
this.store.dispatch(new DismissUndoNotificationAction());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
1
shared/src/components/undoable-notifier/index.ts
Normal file
1
shared/src/components/undoable-notifier/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './undoable-notifier.component';
|
||||
@@ -0,0 +1,12 @@
|
||||
<div class="pull-right">
|
||||
<div class="alert alert-warning alert-dismissible" role="alert" [@slideInOut]="slideInOut">
|
||||
<button type="button"
|
||||
class="close"
|
||||
aria-label="Close"
|
||||
(click)="clickOnClose()">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
{{text}}
|
||||
<a *ngIf="undoable" (click)="clickOnUndo()" class="undo-button">Undo</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,13 @@
|
||||
.alert {
|
||||
padding: 5px 10px 5px 5px;
|
||||
|
||||
margin-bottom: 0.25em;
|
||||
margin-top: -2em;
|
||||
|
||||
.close {
|
||||
right: -5px;
|
||||
}
|
||||
.undo-button {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
|
||||
import { animate, state, style, transition, trigger } from '@angular/animations';
|
||||
|
||||
import { Notification } from '../../models/notification';
|
||||
|
||||
@Component({
|
||||
selector: 'undoable-notifier',
|
||||
templateUrl: './undoable-notifier.component.html',
|
||||
styleUrls: ['./undoable-notifier.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
animations: [
|
||||
trigger('slideInOut', [
|
||||
state('in', style({
|
||||
transform: 'translate3d(0, 0, 0)'
|
||||
})),
|
||||
state('out', style({
|
||||
transform: 'translate3d(200%, 0, 0)'
|
||||
})),
|
||||
transition('in => out', animate('400ms ease-in-out')),
|
||||
transition('out => in', animate('400ms ease-in-out'))
|
||||
])
|
||||
]
|
||||
})
|
||||
export class UndoableNotifierComponent implements OnChanges {
|
||||
text: string;
|
||||
undoable: boolean;
|
||||
@Input() notification: Notification;
|
||||
@Output() close = new EventEmitter();
|
||||
@Output() undo = new EventEmitter();
|
||||
|
||||
get slideInOut() {
|
||||
return this.notification ? 'in' : 'out';
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
if (changes['notification']) {
|
||||
const not: Notification = changes['notification'].currentValue;
|
||||
if (not) {
|
||||
this.text = not.message;
|
||||
this.undoable = !!not.extra;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
clickOnClose(): void {
|
||||
this.close.emit();
|
||||
}
|
||||
|
||||
clickOnUndo(): void {
|
||||
this.undo.emit(this.notification.extra);
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,17 @@
|
||||
import { Action } from '@ngrx/store';
|
||||
|
||||
export enum NotificationType {
|
||||
Default,
|
||||
Success,
|
||||
Error,
|
||||
Warning,
|
||||
Info
|
||||
Default = 'default',
|
||||
Success = 'success',
|
||||
Error = 'error',
|
||||
Warning = 'warning',
|
||||
Info = 'info',
|
||||
Undoable = 'undoable'
|
||||
}
|
||||
|
||||
export interface Notification {
|
||||
type: NotificationType;
|
||||
title?: string;
|
||||
message: string;
|
||||
extra?: any;
|
||||
extra?: Action;
|
||||
}
|
||||
|
||||
4
shared/src/models/undo-user-config-data.ts
Normal file
4
shared/src/models/undo-user-config-data.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export interface UndoUserConfigData {
|
||||
path: string;
|
||||
config: string;
|
||||
}
|
||||
@@ -12,7 +12,10 @@ export const ActionTypes = {
|
||||
APP_STARTED: type(PREFIX + 'started'),
|
||||
APP_SHOW_NOTIFICATION: type(PREFIX + 'show notification'),
|
||||
APP_TOGGLE_ADDON_MENU: type(PREFIX + 'toggle add-on menu'),
|
||||
APP_PROCESS_COMMAND_LINE_ARGS: type(PREFIX + 'process command line args')
|
||||
APP_PROCESS_COMMAND_LINE_ARGS: type(PREFIX + 'process command line args'),
|
||||
UNDO_LAST: type(PREFIX + 'undo last action'),
|
||||
UNDO_LAST_SUCCESS: type(PREFIX + 'undo last action success'),
|
||||
DISMISS_UNDO_NOTIFICATION: type(PREFIX + 'dismiss notification action')
|
||||
};
|
||||
|
||||
export class AppBootsrappedAction implements Action {
|
||||
@@ -41,9 +44,26 @@ export class ProcessCommandLineArgsAction implements Action {
|
||||
constructor(public payload: CommandLineArgs) { }
|
||||
}
|
||||
|
||||
export class UndoLastAction implements Action {
|
||||
type = ActionTypes.UNDO_LAST;
|
||||
|
||||
constructor(public payload: any) {}
|
||||
}
|
||||
|
||||
export class UndoLastSuccessAction implements Action {
|
||||
type = ActionTypes.UNDO_LAST_SUCCESS;
|
||||
}
|
||||
|
||||
export class DismissUndoNotificationAction implements Action {
|
||||
type = ActionTypes.DISMISS_UNDO_NOTIFICATION;
|
||||
}
|
||||
|
||||
export type Actions
|
||||
= AppStartedAction
|
||||
| AppBootsrappedAction
|
||||
| ShowNotificationAction
|
||||
| ToggleAddonMenuAction
|
||||
| ProcessCommandLineArgsAction;
|
||||
| ProcessCommandLineArgsAction
|
||||
| UndoLastAction
|
||||
| UndoLastSuccessAction
|
||||
| DismissUndoNotificationAction;
|
||||
|
||||
@@ -16,6 +16,7 @@ export namespace KeymapActions {
|
||||
export const CHECK_MACRO = KeymapActions.PREFIX + 'Check deleted macro';
|
||||
export const LOAD_KEYMAPS = KeymapActions.PREFIX + 'Load keymaps';
|
||||
export const LOAD_KEYMAPS_SUCCESS = KeymapActions.PREFIX + 'Load keymaps success';
|
||||
export const UNDO_LAST_ACTION = KeymapActions.PREFIX + 'Undo last action';
|
||||
|
||||
export function loadKeymaps(): Action {
|
||||
return {
|
||||
|
||||
@@ -19,13 +19,13 @@ export class LoadUserConfigAction implements Action {
|
||||
export class LoadUserConfigSuccessAction implements Action {
|
||||
type = ActionTypes.LOAD_USER_CONFIG_SUCCESS;
|
||||
|
||||
constructor(public payload: UserConfiguration) {
|
||||
|
||||
}
|
||||
constructor(public payload: UserConfiguration) { }
|
||||
}
|
||||
|
||||
export class SaveUserConfigSuccessAction implements Action {
|
||||
type = ActionTypes.SAVE_USER_CONFIG_SUCCESS;
|
||||
|
||||
constructor(public payload: UserConfiguration) { }
|
||||
}
|
||||
|
||||
export type Actions
|
||||
|
||||
@@ -4,10 +4,13 @@ import { Actions, Effect, toPayload } from '@ngrx/effects';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { NotifierService } from 'angular-notifier';
|
||||
|
||||
import 'rxjs/add/observable/of';
|
||||
import 'rxjs/add/operator/do';
|
||||
import 'rxjs/add/operator/map';
|
||||
import 'rxjs/add/operator/mergeMap';
|
||||
import 'rxjs/add/operator/catch';
|
||||
|
||||
import { ActionTypes, ToggleAddonMenuAction } from '../actions/app.action';
|
||||
import { ActionTypes, DismissUndoNotificationAction, ToggleAddonMenuAction } from '../actions/app.action';
|
||||
import { Notification, NotificationType } from '../../models/notification';
|
||||
import { CommandLineArgs } from '../../models/command-line-args';
|
||||
|
||||
@@ -19,8 +22,10 @@ export class ApplicationEffects {
|
||||
.ofType(ActionTypes.APP_SHOW_NOTIFICATION)
|
||||
.map(toPayload)
|
||||
.do((notification: Notification) => {
|
||||
const type = ApplicationEffects.mapNotificationType(notification.type);
|
||||
this.notifierService.notify(type, notification.message);
|
||||
if (notification.type === NotificationType.Undoable) {
|
||||
return;
|
||||
}
|
||||
this.notifierService.notify(notification.type, notification.message);
|
||||
});
|
||||
|
||||
@Effect()
|
||||
@@ -29,26 +34,10 @@ export class ApplicationEffects {
|
||||
.map(toPayload)
|
||||
.map((args: CommandLineArgs) => new ToggleAddonMenuAction(args.addons || false));
|
||||
|
||||
// TODO: Change typescript -> 2.4 and use string enum.
|
||||
// Corrently ngrx store is not compatible witn typescript 2.4
|
||||
private static mapNotificationType(type: NotificationType): string {
|
||||
switch (type) {
|
||||
case NotificationType.Success:
|
||||
return 'success';
|
||||
|
||||
case NotificationType.Error:
|
||||
return 'error';
|
||||
|
||||
case NotificationType.Info:
|
||||
return 'info';
|
||||
|
||||
case NotificationType.Warning:
|
||||
return 'warning';
|
||||
|
||||
default:
|
||||
return 'default';
|
||||
}
|
||||
}
|
||||
@Effect() undoLastNotification$: Observable<Action> = this.actions$
|
||||
.ofType(ActionTypes.UNDO_LAST)
|
||||
.map(toPayload)
|
||||
.mergeMap((action: Action) => [action, new DismissUndoNotificationAction()]);
|
||||
|
||||
constructor(private actions$: Actions,
|
||||
private notifierService: NotifierService) { }
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Inject, Injectable } from '@angular/core';
|
||||
import { Actions, Effect } from '@ngrx/effects';
|
||||
import { go } from '@ngrx/router-store';
|
||||
import { Actions, Effect, toPayload } from '@ngrx/effects';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { Action, Store } from '@ngrx/store';
|
||||
|
||||
@@ -7,6 +8,7 @@ import 'rxjs/add/operator/map';
|
||||
import 'rxjs/add/operator/switchMap';
|
||||
import 'rxjs/add/operator/startWith';
|
||||
import 'rxjs/add/operator/withLatestFrom';
|
||||
import 'rxjs/add/operator/mergeMap';
|
||||
import 'rxjs/add/observable/of';
|
||||
|
||||
import {
|
||||
@@ -19,9 +21,12 @@ import {
|
||||
import { UserConfiguration } from '../../config-serializer/config-items/user-configuration';
|
||||
import { DATA_STORAGE_REPOSITORY, DataStorageRepositoryService } from '../../services/datastorage-repository.service';
|
||||
import { DefaultUserConfigurationService } from '../../services/default-user-configuration.service';
|
||||
import { AppState, getUserConfiguration } from '../index';
|
||||
import { AppState, getPrevUserConfiguration, getUserConfiguration } from '../index';
|
||||
import { KeymapActions } from '../actions/keymap';
|
||||
import { MacroActions } from '../actions/macro';
|
||||
import { DismissUndoNotificationAction, ShowNotificationAction } from '../actions/app.action';
|
||||
import { NotificationType } from '../../models/notification';
|
||||
import { UndoUserConfigData } from '../../models/undo-user-config-data';
|
||||
|
||||
@Injectable()
|
||||
export class UserConfigEffects {
|
||||
@@ -29,33 +34,49 @@ export class UserConfigEffects {
|
||||
@Effect() loadUserConfig$: Observable<Action> = this.actions$
|
||||
.ofType(ActionTypes.LOAD_USER_CONFIG)
|
||||
.startWith(new LoadUserConfigAction())
|
||||
.switchMap(() => {
|
||||
const configJsonObject = this.dataStorageRepository.getConfig();
|
||||
let config: UserConfiguration;
|
||||
|
||||
if (configJsonObject) {
|
||||
if (configJsonObject.dataModelVersion === this.defaultUserConfigurationService.getDefault().dataModelVersion) {
|
||||
config = new UserConfiguration().fromJsonObject(configJsonObject);
|
||||
}
|
||||
}
|
||||
|
||||
if (!config) {
|
||||
config = this.defaultUserConfigurationService.getDefault();
|
||||
}
|
||||
|
||||
return Observable.of(new LoadUserConfigSuccessAction(config));
|
||||
});
|
||||
.switchMap(() => Observable.of(new LoadUserConfigSuccessAction(this.getUserConfiguration())));
|
||||
|
||||
@Effect() saveUserConfig$: Observable<Action> = this.actions$
|
||||
.ofType(
|
||||
KeymapActions.ADD, KeymapActions.DUPLICATE, KeymapActions.EDIT_NAME, KeymapActions.EDIT_ABBR,
|
||||
KeymapActions.SET_DEFAULT, KeymapActions.REMOVE, KeymapActions.SAVE_KEY, KeymapActions.CHECK_MACRO,
|
||||
KeymapActions.SET_DEFAULT, KeymapActions.REMOVE, KeymapActions.SAVE_KEY,
|
||||
MacroActions.ADD, MacroActions.DUPLICATE, MacroActions.EDIT_NAME, MacroActions.REMOVE, MacroActions.ADD_ACTION,
|
||||
MacroActions.SAVE_ACTION, MacroActions.DELETE_ACTION, MacroActions.REORDER_ACTION)
|
||||
.withLatestFrom(this.store.select(getUserConfiguration))
|
||||
.map(([action, config]) => {
|
||||
.withLatestFrom(this.store.select(getUserConfiguration), this.store.select(getPrevUserConfiguration))
|
||||
.mergeMap(([action, config, prevUserConfiguration]) => {
|
||||
this.dataStorageRepository.saveConfig(config);
|
||||
return new SaveUserConfigSuccessAction();
|
||||
|
||||
if (action.type === KeymapActions.REMOVE || action.type === MacroActions.REMOVE) {
|
||||
const text = action.type === KeymapActions.REMOVE ? 'Keymap' : 'Macro';
|
||||
const pathPrefix = action.type === KeymapActions.REMOVE ? 'keymap' : 'macro';
|
||||
const payload: UndoUserConfigData = {
|
||||
path: `/${pathPrefix}/${action.payload}`,
|
||||
config: prevUserConfiguration.toJsonObject()
|
||||
};
|
||||
|
||||
return [
|
||||
new SaveUserConfigSuccessAction(config),
|
||||
new ShowNotificationAction({
|
||||
type: NotificationType.Undoable,
|
||||
message: `${text} has been deleted`,
|
||||
extra: {
|
||||
payload,
|
||||
type: KeymapActions.UNDO_LAST_ACTION
|
||||
}
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
return [new SaveUserConfigSuccessAction(config), new DismissUndoNotificationAction()];
|
||||
});
|
||||
|
||||
@Effect() undoUserConfig$: Observable<Action> = this.actions$
|
||||
.ofType(KeymapActions.UNDO_LAST_ACTION)
|
||||
.map(toPayload)
|
||||
.mergeMap((payload: UndoUserConfigData) => {
|
||||
const config = new UserConfiguration().fromJsonObject(payload.config);
|
||||
this.dataStorageRepository.saveConfig(config);
|
||||
return [new LoadUserConfigSuccessAction(config), go(payload.path)];
|
||||
});
|
||||
|
||||
constructor(private actions$: Actions,
|
||||
@@ -63,4 +84,22 @@ export class UserConfigEffects {
|
||||
private store: Store<AppState>,
|
||||
private defaultUserConfigurationService: DefaultUserConfigurationService) {
|
||||
}
|
||||
|
||||
private getUserConfiguration() {
|
||||
const configJsonObject = this.dataStorageRepository.getConfig();
|
||||
let config: UserConfiguration;
|
||||
|
||||
if (configJsonObject) {
|
||||
if (configJsonObject.dataModelVersion === this.defaultUserConfigurationService.getDefault().dataModelVersion) {
|
||||
config = new UserConfiguration().fromJsonObject(configJsonObject);
|
||||
}
|
||||
}
|
||||
|
||||
if (!config) {
|
||||
config = this.defaultUserConfigurationService.getDefault();
|
||||
}
|
||||
|
||||
return config;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ export const getUserConfiguration = (state: AppState) => state.userConfiguration
|
||||
|
||||
export const appState = (state: AppState) => state.app;
|
||||
export const showAddonMenu = createSelector(appState, fromApp.showAddonMenu);
|
||||
export const getUndoableNotification = createSelector(appState, fromApp.getUndoableNotification);
|
||||
export const getPrevUserConfiguration = createSelector(appState, fromApp.getPrevUserConfiguration);
|
||||
|
||||
export const appUpdateState = (state: AppState) => state.autoUpdateSettings;
|
||||
|
||||
|
||||
@@ -1,25 +1,81 @@
|
||||
import { routerActions } from '@ngrx/router-store';
|
||||
import { Action } from '@ngrx/store';
|
||||
|
||||
import { ActionTypes } from '../actions/app.action';
|
||||
import { ActionTypes, ShowNotificationAction } from '../actions/app.action';
|
||||
import { ActionTypes as UserConfigActionTypes } from '../actions/user-config';
|
||||
import { Notification, NotificationType } from '../../models/notification';
|
||||
import { UserConfiguration } from '../../config-serializer/config-items/user-configuration';
|
||||
|
||||
export interface State {
|
||||
started: boolean;
|
||||
showAddonMenu: boolean;
|
||||
undoableNotification?: Notification;
|
||||
navigationCountAfterNotification: number;
|
||||
prevUserConfig?: UserConfiguration;
|
||||
}
|
||||
|
||||
const initialState: State = {
|
||||
started: false,
|
||||
showAddonMenu: false
|
||||
showAddonMenu: false,
|
||||
navigationCountAfterNotification: 0
|
||||
};
|
||||
|
||||
export function reducer(state = initialState, action: Action) {
|
||||
switch (action.type) {
|
||||
case ActionTypes.APP_STARTED: {
|
||||
return Object.assign({ ...state }, { started: true });
|
||||
return {
|
||||
...state,
|
||||
started: true
|
||||
};
|
||||
}
|
||||
|
||||
case ActionTypes.APP_TOGGLE_ADDON_MENU: {
|
||||
return Object.assign({ ...state }, { showAddonMenu: action.payload });
|
||||
return {
|
||||
...state,
|
||||
showAddonMenu: action.payload
|
||||
};
|
||||
}
|
||||
|
||||
case ActionTypes.APP_SHOW_NOTIFICATION: {
|
||||
const currentAction = <ShowNotificationAction>action;
|
||||
if (currentAction.payload.type !== NotificationType.Undoable) {
|
||||
return state;
|
||||
}
|
||||
return {
|
||||
...state,
|
||||
undoableNotification: currentAction.payload,
|
||||
navigationCountAfterNotification: 0
|
||||
};
|
||||
}
|
||||
|
||||
// Required to dismiss the undoNotification dialog, when user navigate in the app.
|
||||
// When deleted a keymap or macro the app automaticaly navigate to other keymap, or macro, so
|
||||
// so we have to count the navigations and when reach the 2nd then remove the dialog.
|
||||
case routerActions.UPDATE_LOCATION: {
|
||||
const newState = { ...state };
|
||||
newState.navigationCountAfterNotification++;
|
||||
|
||||
if (newState.navigationCountAfterNotification > 1) {
|
||||
newState.undoableNotification = null;
|
||||
}
|
||||
|
||||
return newState;
|
||||
}
|
||||
|
||||
case ActionTypes.UNDO_LAST_SUCCESS:
|
||||
case ActionTypes.DISMISS_UNDO_NOTIFICATION: {
|
||||
return {
|
||||
...state,
|
||||
undoableNotification: null
|
||||
};
|
||||
}
|
||||
|
||||
case UserConfigActionTypes.LOAD_USER_CONFIG_SUCCESS:
|
||||
case UserConfigActionTypes.SAVE_USER_CONFIG_SUCCESS: {
|
||||
return {
|
||||
...state,
|
||||
prevUserConfig: action.payload
|
||||
};
|
||||
}
|
||||
|
||||
default:
|
||||
@@ -28,3 +84,5 @@ export function reducer(state = initialState, action: Action) {
|
||||
}
|
||||
|
||||
export const showAddonMenu = (state: State) => state.showAddonMenu;
|
||||
export const getUndoableNotification = (state: State) => state.undoableNotification;
|
||||
export const getPrevUserConfiguration = (state: State) => state.prevUserConfig;
|
||||
|
||||
@@ -87,6 +87,7 @@ import { reducer } from './shared/store/reducers/index';
|
||||
import { LogService } from './shared/services/logger.service';
|
||||
import { AutoUpdateSettings } from './shared/components/auto-update-settings/auto-update-settings';
|
||||
import { angularNotifierConfig } from './shared/models/angular-notifier-config';
|
||||
import { UndoableNotifierComponent } from './shared/components/undoable-notifier';
|
||||
import { UhkHeader } from './shared/components/uhk-header/uhk-header';
|
||||
|
||||
@NgModule({
|
||||
@@ -141,6 +142,7 @@ import { UhkHeader } from './shared/components/uhk-header/uhk-header';
|
||||
TooltipDirective,
|
||||
SafeStylePipe,
|
||||
AutoUpdateSettings,
|
||||
UndoableNotifierComponent,
|
||||
UhkHeader
|
||||
],
|
||||
imports: [
|
||||
|
||||
Reference in New Issue
Block a user