diff --git a/src/app/actions/windows-meta/windows-meta.ts b/src/app/actions/windows-meta/windows-meta.ts
index fff7bfc760..7ed02a4493 100644
--- a/src/app/actions/windows-meta/windows-meta.ts
+++ b/src/app/actions/windows-meta/windows-meta.ts
@@ -1,6 +1,8 @@
import { Action } from '@ngrx/store';
export const SET_ACTIVE_WINDOW_ID = 'SET_ACTIVE_WINDOW_ID';
+export const SET_WINDOW_IDS = 'SET_WINDOW_IDS';
+export const REPOSITION_WINDOW = 'REPOSITION_WINDOW';
export class SetActiveWindowIdAction implements Action {
readonly type = SET_ACTIVE_WINDOW_ID;
@@ -8,4 +10,16 @@ export class SetActiveWindowIdAction implements Action {
constructor(public payload: { windowId: string }) {}
}
-export type Action = SetActiveWindowIdAction;
+export class SetWindowIdsAction implements Action {
+ readonly type = SET_WINDOW_IDS;
+
+ constructor(public payload: { ids: string[]}) {}
+}
+
+export class RepositionWindowAction implements Action {
+ readonly type = REPOSITION_WINDOW;
+
+ constructor(public payload: { currentPosition: number, newPosition: number }) { }
+}
+
+export type Action = SetActiveWindowIdAction | SetWindowIdsAction | RepositionWindowAction;
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 2a77bc4852..1721bba058 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -22,6 +22,7 @@ import { SharedModule } from './shared/shared.module';
import { reducer, metaReducers, reducerToken, reducerProvider } from './reducers';
import { QueryEffects } from './effects/query';
+import { WindowsEffects } from './effects/windows';
import { ComponentModule } from './components';
import { DocViewerModule } from './components/doc-viewer/doc-viewer.module';
@@ -73,7 +74,7 @@ const providers = [
ComponentModule,
DocViewerModule,
StoreModule.forRoot(reducerToken, { metaReducers }),
- EffectsModule.forRoot([ QueryEffects ]),
+ EffectsModule.forRoot([ QueryEffects, WindowsEffects ]),
StoreDevtoolsModule.instrument(),
ToastModule.forRoot(),
TranslateModule.forRoot({
diff --git a/src/app/components/window-switcher/window-switcher.component.html b/src/app/components/window-switcher/window-switcher.component.html
index 15a146c37b..595ce087e9 100644
--- a/src/app/components/window-switcher/window-switcher.component.html
+++ b/src/app/components/window-switcher/window-switcher.component.html
@@ -1,23 +1,23 @@
+ *ngIf="windowIds.length < maxWindowCount">
{{ 'ADD_NEW_WINDOW_TEXT' | translate }}
diff --git a/src/app/components/window-switcher/window-switcher.component.ts b/src/app/components/window-switcher/window-switcher.component.ts
index a08211c997..3dc1e22125 100644
--- a/src/app/components/window-switcher/window-switcher.component.ts
+++ b/src/app/components/window-switcher/window-switcher.component.ts
@@ -15,13 +15,15 @@ import config from '../../config';
})
export class WindowSwitcherComponent implements OnInit {
- @Input() windows = [];
+ @Input() windows = {};
+ @Input() windowIds = [];
@Input() activeWindowId = '';
@Input() isElectron = false;
@Output() activeWindowChange = new EventEmitter();
@Output() newWindowChange = new EventEmitter();
@Output() removeWindowChange = new EventEmitter();
@Output() windowNameChange = new EventEmitter();
+ @Output() repositionWindowChange = new EventEmitter();
windowNameEditing = null;
maxWindowCount = config.max_windows;
@@ -42,4 +44,8 @@ export class WindowSwitcherComponent implements OnInit {
this.windowNameEditing = null;
}
+ moveWindow(currentPosition, newPosition) {
+ this.repositionWindowChange.next(({ currentPosition, newPosition }));
+ }
+
}
diff --git a/src/app/containers/app/app.component.html b/src/app/containers/app/app.component.html
index 7a4d8eb36d..965d6c204c 100644
--- a/src/app/containers/app/app.component.html
+++ b/src/app/containers/app/app.component.html
@@ -17,25 +17,28 @@
-
+ (windowNameChange)="setWindowName($event)"
+ (repositionWindowChange)="repositionWindow($event)"
+ >
+
diff --git a/src/app/containers/app/app.component.ts b/src/app/containers/app/app.component.ts
index 73475fe4ee..b911f540ae 100644
--- a/src/app/containers/app/app.component.ts
+++ b/src/app/containers/app/app.component.ts
@@ -36,14 +36,14 @@ export class AppComponent {
settings$: Observable;
windowIds = [];
- windowsArr = [];
+ windows = {};
activeWindowId = '';
isElectron = isElectron;
isReady = false; // determines if the app is fully loaded. Assets, translations, etc.
constructor(
private windowService: WindowService,
- private store: Store,
+ private store: Store,
private translate: TranslateService,
private electron: ElectronService
) {
@@ -83,18 +83,26 @@ export class AppComponent {
});
this.store
.subscribe(data => {
+ this.windows = data.windows;
this.windowIds = Object.keys(data.windows);
- console.log(data.windows, this.windowIds);
- this.windowsArr = this.windowIds.map(id => data.windows[id]);
+
+ // Set the window IDs in the meta state if it does not already exist
+ if (data.windowsMeta.windowIds) {
+ this.windowIds = data.windowsMeta.windowIds;
+ } else {
+ this.store.dispatch(new windowsMetaActions.SetWindowIdsAction( { ids: this.windowIds }));
+ }
+
this.activeWindowId = data.windowsMeta.activeWindowId;
+ console.log(data.windows, this.windowIds);
// If the active window has not been set, default it
- if (this.windowsArr.length && (!this.activeWindowId || !data.windows[this.activeWindowId])) {
+ if (this.windowIds.length && (!this.activeWindowId || !data.windows[this.activeWindowId])) {
this.store.dispatch(new windowsMetaActions.SetActiveWindowIdAction({ windowId: this.windowIds[0] }));
}
});
- if (!this.windowsArr.length) {
+ if (!this.windowIds.length) {
this.windowService.newWindow();
}
}
@@ -151,6 +159,11 @@ export class AppComponent {
this.store.dispatch(new layoutActions.SetWindowNameAction(windowId, windowName));
}
+ repositionWindow(data) {
+ const { currentPosition, newPosition } = data;
+ this.store.dispatch(new windowsMetaActions.RepositionWindowAction({ currentPosition, newPosition }));
+ }
+
showSettingsDialog() {
this.store.dispatch(new settingsActions.ShowSettingsAction());
}
diff --git a/src/app/containers/window/window.component.ts b/src/app/containers/window/window.component.ts
index 8e4b231439..27104a7c0d 100644
--- a/src/app/containers/window/window.component.ts
+++ b/src/app/containers/window/window.component.ts
@@ -43,7 +43,7 @@ export class WindowComponent implements OnInit {
responseTime$: Observable;
responseStatusText$: Observable;
isSubscribed$: Observable;
- subscriptionResponses$: Observable>;
+ subscriptionResponses$: Observable;
@Input() windowId: string;
diff --git a/src/app/effects/windows.ts b/src/app/effects/windows.ts
new file mode 100644
index 0000000000..825c987160
--- /dev/null
+++ b/src/app/effects/windows.ts
@@ -0,0 +1,28 @@
+import { Injectable } from '@angular/core';
+import { Store, Action } from '@ngrx/store';
+import { Effect, Actions, toPayload } from '@ngrx/effects';
+import { Observable } from 'rxjs/Observable';
+
+import * as fromRoot from '../reducers';
+
+import * as windowActions from '../actions/windows/windows';
+import * as windowsMetaActions from '../actions/windows-meta/windows-meta';
+
+@Injectable()
+export class WindowsEffects {
+
+ @Effect() // remove, add, reposition
+ setWindowIDs$: Observable = this.actions$
+ .ofType(windowActions.ADD_WINDOW, windowActions.REMOVE_WINDOW)
+ .withLatestFrom(this.store, (action: windowActions.Action, state) => {
+ return { windows: state.windows, action };
+ }).switchMap(data => {
+ const windowIds = Object.keys(data.windows);
+ return Observable.of(new windowsMetaActions.SetWindowIdsAction({ ids: windowIds }));
+ });
+
+ constructor(
+ private actions$: Actions,
+ private store: Store
+ ) {}
+}
diff --git a/src/app/reducers/windows-meta/windows-meta.ts b/src/app/reducers/windows-meta/windows-meta.ts
index 6dce01cebc..bf8842bff0 100644
--- a/src/app/reducers/windows-meta/windows-meta.ts
+++ b/src/app/reducers/windows-meta/windows-meta.ts
@@ -4,16 +4,31 @@ import * as windowsMeta from '../../actions/windows-meta/windows-meta';
export interface State {
activeWindowId: string;
+ windowIds: Array;
}
const initialState: State = {
- activeWindowId: ''
+ activeWindowId: '',
+ windowIds: []
};
export function windowsMetaReducer(state = initialState, action: windowsMeta.Action): State {
switch (action.type) {
case windowsMeta.SET_ACTIVE_WINDOW_ID:
- return Object.assign({}, state, { activeWindowId: action.payload.windowId });
+ return { ...state, activeWindowId: action.payload.windowId };
+ case windowsMeta.SET_WINDOW_IDS:
+ return { ...state, windowIds: action.payload.ids };
+ case windowsMeta.REPOSITION_WINDOW:
+ const curPos = action.payload.currentPosition;
+ const newPos = action.payload.newPosition;
+
+ if (curPos > -1 && curPos < state.windowIds.length && newPos > -1 && newPos < state.windowIds.length) {
+ const arr = [ ...state.windowIds ];
+ arr.splice(newPos, 0, arr.splice(curPos, 1)[0]);
+
+ return { ...state, windowIds: [ ...arr ] };
+ }
+ return state;
default:
return state;
}