Add macro

This commit is contained in:
NejcZdovc
2016-10-21 08:42:44 +02:00
committed by József Farkas
parent 3a69726257
commit b5eb8601e2
21 changed files with 112 additions and 47 deletions

View File

@@ -15,7 +15,6 @@ import { KeymapAddComponent, KeymapComponent, KeymapHeaderComponent } from './co
import { LayersComponent } from './components/layers'; import { LayersComponent } from './components/layers';
import { import {
MacroActionEditorComponent, MacroActionEditorComponent,
MacroAddComponent,
MacroDelayTabComponent, MacroDelayTabComponent,
MacroEditComponent, MacroEditComponent,
MacroHeaderComponent, MacroHeaderComponent,
@@ -115,7 +114,6 @@ const storeConfig = {
MacroEditComponent, MacroEditComponent,
MacroListComponent, MacroListComponent,
MacroHeaderComponent, MacroHeaderComponent,
MacroAddComponent,
MacroItemComponent, MacroItemComponent,
MacroActionEditorComponent, MacroActionEditorComponent,
MacroDelayTabComponent, MacroDelayTabComponent,

View File

@@ -1,5 +1,5 @@
<div> <div>
<h4>Type text</h4> <h4>Type text</h4>
<p>Input the text you want to type with this macro action.</p> <p>Input the text you want to type with this macro action.</p>
<textarea #macroTextInput name="macro-text" [(ngModel)]="macroAction.text" class="macro__text-input"></textarea> <textarea #macroTextInput name="macro-text" (change)="onTextChange()" class="macro__text-input">{{ macroAction.text }}</textarea>
</div> </div>

View File

@@ -25,4 +25,8 @@ export class MacroTextTabComponent implements AfterViewInit {
this.renderer.invokeElementMethod(this.input.nativeElement, 'focus'); this.renderer.invokeElementMethod(this.input.nativeElement, 'focus');
} }
onTextChange() {
this.macroAction.text = this.input.nativeElement.value;
}
} }

View File

@@ -1,7 +0,0 @@
<div class="row">
<h1 class="col-xs-12 pane-title">
<i class="fa fa-play"></i>
<span class="macro__name pane-title__name">Add macro</span>
</h1>
</div>
To be done...

View File

@@ -1,10 +0,0 @@
import { Component } from '@angular/core';
@Component({
selector: 'macro-add',
template: require('./macro-add.component.html'),
styles: [require('./macro-add.component.scss')]
})
export class MacroAddComponent {
constructor() { }
}

View File

@@ -1,5 +1,8 @@
<template [ngIf]="macro"> <template [ngIf]="macro">
<macro-header [macro]="macro"></macro-header> <macro-header
[macro]="macro"
[isNew]="isNew"
></macro-header>
<macro-list <macro-list
[macro]="macro" [macro]="macro"
(add)="addAction($event.macroId, $event.action)" (add)="addAction($event.macroId, $event.action)"

View File

@@ -20,6 +20,7 @@ import { getMacro } from '../../../store/reducers/macro';
export class MacroEditComponent implements OnDestroy { export class MacroEditComponent implements OnDestroy {
private subscription: Subscription; private subscription: Subscription;
private macro: Macro; private macro: Macro;
private isNew: boolean;
constructor(private store: Store<AppState>, private route: ActivatedRoute) { constructor(private store: Store<AppState>, private route: ActivatedRoute) {
this.subscription = route this.subscription = route
@@ -29,6 +30,8 @@ export class MacroEditComponent implements OnDestroy {
.subscribe((macro: Macro) => { .subscribe((macro: Macro) => {
this.macro = macro; this.macro = macro;
}); });
this.isNew = this.route.snapshot.params['empty'] === 'new';
} }
ngOnDestroy() { ngOnDestroy() {

View File

@@ -4,6 +4,7 @@
<input class="pane-title__name" <input class="pane-title__name"
value="{{ macro.name }}" value="{{ macro.name }}"
(change)="editMacroName($event.target.value)" (change)="editMacroName($event.target.value)"
#macroName
/> />
<i class="glyphicon glyphicon-trash macro__remove pull-right" title="" <i class="glyphicon glyphicon-trash macro__remove pull-right" title=""
data-toggle="tooltip" data-toggle="tooltip"

View File

@@ -1,4 +1,4 @@
import { Component, Input } from '@angular/core'; import { ChangeDetectionStrategy, Component, ElementRef, Input, Renderer, ViewChild } from '@angular/core';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
@@ -10,12 +10,21 @@ import { AppState } from '../../../store/index';
@Component({ @Component({
selector: 'macro-header', selector: 'macro-header',
template: require('./macro-header.component.html'), template: require('./macro-header.component.html'),
styles: [require('./macro-header.component.scss')] styles: [require('./macro-header.component.scss')],
changeDetection: ChangeDetectionStrategy.OnPush
}) })
export class MacroHeaderComponent { export class MacroHeaderComponent {
@Input() macro: Macro; @Input() macro: Macro;
@Input() isNew: boolean;
@ViewChild('macroName') macroName: ElementRef;
constructor(private store: Store<AppState>) { } constructor(private store: Store<AppState>, private renderer: Renderer) { }
ngOnChanges() {
if (this.isNew) {
this.renderer.invokeElementMethod(this.macroName.nativeElement, 'focus', []);
}
}
removeMacro() { removeMacro() {
this.store.dispatch(MacroActions.removeMacro(this.macro.id)); this.store.dispatch(MacroActions.removeMacro(this.macro.id));

View File

@@ -1,4 +1,3 @@
export * from './add/macro-add.component';
export * from './edit/macro-edit.component'; export * from './edit/macro-edit.component';
export * from './list/macro-list.component'; export * from './list/macro-list.component';
export * from './header/macro-header.component'; export * from './header/macro-header.component';

View File

@@ -70,9 +70,7 @@ export class MacroItemComponent implements OnInit, OnChanges {
} }
ngOnChanges(changes: SimpleChanges) { ngOnChanges(changes: SimpleChanges) {
/* tslint:disable:no-string-literal */
if (changes['macroAction']) { if (changes['macroAction']) {
/* tslint:enable:no-string-literal */
this.updateView(); this.updateView();
} }
} }
@@ -88,6 +86,7 @@ export class MacroItemComponent implements OnInit, OnChanges {
if (!this.editable || this.editing) { if (!this.editable || this.editing) {
return; return;
} }
this.editing = true; this.editing = true;
this.edit.emit(); this.edit.emit();
} }

View File

@@ -5,7 +5,7 @@
[macroAction]="macroAction" [macroAction]="macroAction"
[editable]="true" [editable]="true"
[deletable]="true" [deletable]="true"
[moveable]="true" [movable]="true"
(save)="saveAction($event, macroActionIndex)" (save)="saveAction($event, macroActionIndex)"
(edit)="editAction(macroActionIndex)" (edit)="editAction(macroActionIndex)"
(cancel)="cancelAction()" (cancel)="cancelAction()"
@@ -13,15 +13,17 @@
[attr.data-index]="macroActionIndex" [attr.data-index]="macroActionIndex"
></macro-item> ></macro-item>
<macro-item *ngIf="showNew" [macroAction]="newMacro" <macro-item *ngIf="showNew"
[@togglerNew]="showNew ? 'active' : 'inactive'"
[macroAction]="newMacro"
[editable]="true" [editable]="true"
[deletable]="false" [deletable]="false"
[moveable]="false" [movable]="false"
(save)="addNewAction($event)" (save)="addNewAction($event)"
(cancel)="hideNewAction()" (cancel)="hideNewAction()"
></macro-item> ></macro-item>
</div> </div>
<div class="list-group add-new__action-container" *ngIf="!showNew"> <div class="list-group add-new__action-container" [@toggler]="(!showNew) ? 'active' : 'inactive'">
<div class="list-group-item action--item add-new__action-item no-reorder clearfix"> <div class="list-group-item action--item add-new__action-item no-reorder clearfix">
<a class="add-new__action-item--link" (click)="showNewAction()"> <a class="add-new__action-item--link" (click)="showNewAction()">
<i class="fa fa-plus"></i> Add new macro action <i class="fa fa-plus"></i> Add new macro action

View File

@@ -8,12 +8,6 @@
.list-container { .list-container {
display: flex; display: flex;
flex: 1; flex: 1;
> div {
display: flex;
flex-direction: column;
flex: 1;
}
} }
} }
@@ -103,6 +97,7 @@ h1 {
.add-new__action-container { .add-new__action-container {
overflow: hidden; overflow: hidden;
flex-shrink: 0; flex-shrink: 0;
border-top: 1px solid #ddd;
} }
.add-new__action-item { .add-new__action-item {

View File

@@ -1,4 +1,17 @@
import { Component, EventEmitter, Input, Output, QueryList, ViewChild, forwardRef } from '@angular/core'; import {
Component,
EventEmitter,
Input,
Output,
QueryList,
ViewChildren,
animate,
forwardRef,
state,
style,
transition,
trigger
} from '@angular/core';
import { DragulaService } from 'ng2-dragula/ng2-dragula'; import { DragulaService } from 'ng2-dragula/ng2-dragula';
@@ -7,6 +20,27 @@ import { MacroAction } from '../../../config-serializer/config-items/macro-actio
import { MacroItemComponent } from './../index'; import { MacroItemComponent } from './../index';
@Component({ @Component({
animations: [
trigger('toggler', [
state('inactive', style({
height: '0px'
})),
state('active', style({
height: '*'
})),
transition('inactive <=> active', animate('500ms ease-out'))
]),
trigger('togglerNew', [
state('void', style({
height: '0px'
})),
state('active', style({
height: '*'
})),
transition(':enter', animate('500ms ease-out')),
transition(':leave', animate('500ms ease-out'))
])
],
selector: 'macro-list', selector: 'macro-list',
template: require('./macro-list.component.html'), template: require('./macro-list.component.html'),
styles: [require('./macro-list.component.scss')], styles: [require('./macro-list.component.scss')],
@@ -14,17 +48,17 @@ import { MacroItemComponent } from './../index';
}) })
export class MacroListComponent { export class MacroListComponent {
@Input() macro: Macro; @Input() macro: Macro;
@ViewChild(forwardRef(() => MacroItemComponent)) macroItems: QueryList<MacroItemComponent>; @ViewChildren(forwardRef(() => MacroItemComponent)) macroItems: QueryList<MacroItemComponent>;
@Output() add = new EventEmitter(); @Output() add = new EventEmitter();
@Output() edit = new EventEmitter(); @Output() edit = new EventEmitter();
@Output() delete = new EventEmitter(); @Output() delete = new EventEmitter();
@Output() reorder = new EventEmitter(); @Output() reorder = new EventEmitter();
private showNew: boolean = false;
private newMacro: Macro = undefined; private newMacro: Macro = undefined;
private activeEdit: number = undefined; private activeEdit: number = undefined;
private dragIndex: number; private dragIndex: number;
private showNew: boolean = false;
constructor(private dragulaService: DragulaService) { constructor(private dragulaService: DragulaService) {
/* tslint:disable:no-unused-variable: Used by Dragula. */ /* tslint:disable:no-unused-variable: Used by Dragula. */

View File

@@ -1,6 +1,5 @@
import { Routes } from '@angular/router'; import { Routes } from '@angular/router';
import { MacroAddComponent } from './add/macro-add.component';
import { MacroEditComponent } from './edit/macro-edit.component'; import { MacroEditComponent } from './edit/macro-edit.component';
export const macroRoutes: Routes = [ export const macroRoutes: Routes = [
@@ -9,11 +8,11 @@ export const macroRoutes: Routes = [
component: MacroEditComponent component: MacroEditComponent
}, },
{ {
path: 'macro/add', path: 'macro/:id',
component: MacroAddComponent component: MacroEditComponent
}, },
{ {
path: 'macro/:id', path: 'macro/:id/:empty',
component: MacroEditComponent component: MacroEditComponent
} }
]; ];

View File

@@ -19,7 +19,7 @@
<li class="sidebar__level-1--item"> <li class="sidebar__level-1--item">
<div class="sidebar__level-1"> <div class="sidebar__level-1">
<i class="fa fa-play"></i> Macros <i class="fa fa-play"></i> Macros
<a [routerLink]="['/macro/add']" class="btn btn-default pull-right btn-sm"> <a (click)="addMacro()" class="btn btn-default pull-right btn-sm">
<i class="fa fa-plus"></i> <i class="fa fa-plus"></i>
</a> </a>
<i class="fa fa-chevron-up pull-right" (click)="toggleHide($event, 'macro')"></i> <i class="fa fa-chevron-up pull-right" (click)="toggleHide($event, 'macro')"></i>

View File

@@ -1,12 +1,15 @@
import { Component, Renderer, animate, state, style, transition, trigger } from '@angular/core'; import { Component, Renderer, animate, state, style, transition, trigger } from '@angular/core';
import { Store } from '@ngrx/store';
import { Observable } from 'rxjs/Observable';
import { Keymap } from '../../config-serializer/config-items/Keymap'; import { Keymap } from '../../config-serializer/config-items/Keymap';
import { Macro } from '../../config-serializer/config-items/Macro'; import { Macro } from '../../config-serializer/config-items/Macro';
import { AppState } from '../../store'; import { AppState } from '../../store';
import { MacroActions } from '../../store/actions';
import { getKeymapEntities, getMacroEntities } from '../../store/reducers'; import { getKeymapEntities, getMacroEntities } from '../../store/reducers';
import { Store } from '@ngrx/store';
import { Observable } from 'rxjs/Observable';
@Component({ @Component({
animations: [ animations: [
@@ -54,4 +57,8 @@ export class SideMenuComponent {
this.renderer.setElementClass(event.target, 'fa-chevron-up', show); this.renderer.setElementClass(event.target, 'fa-chevron-up', show);
this.renderer.setElementClass(event.target, 'fa-chevron-down', !show); this.renderer.setElementClass(event.target, 'fa-chevron-down', !show);
} }
addMacro() {
this.store.dispatch(MacroActions.addMacro());
}
} }

View File

@@ -9,12 +9,19 @@ export namespace MacroActions {
export const DUPLICATE = MacroActions.PREFIX + 'Duplicate macro'; export const DUPLICATE = MacroActions.PREFIX + 'Duplicate macro';
export const EDIT_NAME = MacroActions.PREFIX + 'Edit macro title'; export const EDIT_NAME = MacroActions.PREFIX + 'Edit macro title';
export const REMOVE = MacroActions.PREFIX + 'Remove macro'; export const REMOVE = MacroActions.PREFIX + 'Remove macro';
export const ADD = MacroActions.PREFIX + 'Add macro';
export const ADD_ACTION = MacroActions.PREFIX + 'Add macro action'; export const ADD_ACTION = MacroActions.PREFIX + 'Add macro action';
export const SAVE_ACTION = MacroActions.PREFIX + 'Save macro action'; export const SAVE_ACTION = MacroActions.PREFIX + 'Save macro action';
export const DELETE_ACTION = MacroActions.PREFIX + 'Delete macro action'; export const DELETE_ACTION = MacroActions.PREFIX + 'Delete macro action';
export const REORDER_ACTION = MacroActions.PREFIX + 'Reorder macro action'; export const REORDER_ACTION = MacroActions.PREFIX + 'Reorder macro action';
export function addMacro(): Action {
return {
type: MacroActions.ADD
};
}
export function removeMacro(id: number): Action { export function removeMacro(id: number): Action {
return { return {
type: MacroActions.REMOVE, type: MacroActions.REMOVE,

View File

@@ -26,5 +26,15 @@ export class MacroEffects {
} }
}); });
@Effect({dispatch: false}) add$: any = this.actions$
.ofType(MacroActions.ADD)
.withLatestFrom(this.store)
.do((latest) => {
let state: AppState = latest[1];
let id: number = state.macros.entities.length - 1;
this.router.navigate(['/macro', id, 'new']);
});
constructor(private actions$: Actions, private router: Router, private store: Store<AppState>) {} constructor(private actions$: Actions, private router: Router, private store: Store<AppState>) {}
} }

View File

@@ -18,6 +18,18 @@ export default function(state = initialState, action: Action): MacroState {
let newState: Macro[]; let newState: Macro[];
switch (action.type) { switch (action.type) {
case MacroActions.ADD:
newMacro = new Macro();
newMacro.id = generateId(state.entities);
newMacro.name = generateName(state.entities, 'New macro');
newMacro.isLooped = false;
newMacro.isPrivate = true;
newMacro.macroActions = [];
return {
entities: [...state.entities, newMacro]
};
case MacroActions.DUPLICATE: case MacroActions.DUPLICATE:
newMacro = new Macro(action.payload); newMacro = new Macro(action.payload);