refactoring linear workflow directives

This commit is contained in:
alecmerdler 2017-02-21 15:59:26 -08:00 committed by Joseph Schorr
parent a83a7fe47a
commit e59d394491
10 changed files with 240 additions and 22 deletions

View file

@ -0,0 +1,7 @@
<div class="linear-workflow-section-element"
ng-show="$ctrl.sectionVisible"
ng-class="$ctrl.isCurrentSection ? 'current-section' : ''">
<form ng-submit="$ctrl.submitSection()">
<div ng-transclude />
</form>
</div>

View file

@ -0,0 +1,25 @@
import { LinearWorkflowSectionComponent } from './linear-workflow-section.component';
import { LinearWorkflowComponent } from './linear-workflow.component';
import Spy = jasmine.Spy;
describe("LinearWorkflowSectionComponent", () => {
var component: LinearWorkflowSectionComponent;
var parentMock: LinearWorkflowComponent;
beforeEach(() => {
component = new LinearWorkflowSectionComponent();
parentMock = new LinearWorkflowComponent();
component.parent = parentMock;
});
describe("$onInit", () => {
it("calls parent component to add itself as a section", () => {
var addSectionSpy: Spy = spyOn(parentMock, "addSection").and.returnValue(null);
component.$onInit();
expect(addSectionSpy.calls.argsFor(0)[0]).toBe(component);
});
});
});

View file

@ -0,0 +1,32 @@
import { Component, Output, Input } from 'angular-ts-decorators';
import { LinearWorkflowComponent } from './linear-workflow.component';
/**
* A component which displays a single section in a linear workflow.
*/
@Component({
selector: 'linearWorkflowSection',
templateUrl: '/static/js/directives/ui/linear-workflow/linear-workflow-section.component.html',
transclude: true,
require: {
parent: '^linearWorkflow'
}
})
export class LinearWorkflowSectionComponent implements ng.IComponentController {
@Input('@') public sectionId: string;
@Input('@') public sectionTitle: string;
@Input() public sectionValid: boolean = false;
public sectionVisible: boolean = false;
public isCurrentSection: boolean = false;
public parent: LinearWorkflowComponent;
constructor() {
}
public $onInit(): void {
this.parent.addSection(this);
}
}

View file

@ -0,0 +1,39 @@
<div class="linear-workflow-element">
<!-- Contents -->
<div ng-transclude />
<div class="bottom-controls">
<table class="upcoming-table">
<tr>
<td>
<!-- Next button -->
<button class="btn btn-primary"
ng-disabled="!$ctrl.currentSection.valid"
ng-click="$ctrl.onNextSection()"
ng-class="{
'btn-success': $ctrl.currentSection.index == $ctrl.sections.length - 1,
'btn-lg': $ctrl.currentSection.index == $ctrl.sections.length - 1
}">
<span ng-if="$ctrl.currentSection.index != sections.length - 1">Continue</span>
<span ng-if="$ctrl.currentSection.index == sections.length - 1">
<i class="fa fa-check-circle"></i>{{ $ctrl.doneTitle }}
</span>
</button>
</td>
<td>
<!-- Next sections -->
<div class="upcoming"
ng-if="$ctrl.currentSection.index != $ctrl.sections.length - 1">
<b>Next:</b>
<ul>
<li ng-repeat="section in $ctrl.sections"
ng-if="section.index > $ctrl.currentSection.index">
{{ section.title }}
</li>
</ul>
</div>
</td>
</tr>
</table>
</div>
</div>

View file

@ -0,0 +1,19 @@
import { LinearWorkflowComponent, SectionInfo } from './linear-workflow.component';
import { LinearWorkflowSectionComponent } from './linear-workflow-section.component';
describe("LinearWorkflowComponent", () => {
var component: LinearWorkflowComponent;
beforeEach(() => {
component = new LinearWorkflowComponent();
});
describe("addSection", () => {
});
describe("onNextSection", () => {
});
});

View file

@ -1,10 +1,56 @@
import { Component, Output, Input } from 'angular-ts-decorators';
import { LinearWorkflowSectionComponent } from './linear-workflow-section.component';
/**
* A component that which displays a linear workflow of sections, each completed in order before the next
* step is made visible.
*/
@Component({
selector: 'linearWorkflow',
templateUrl: '/static/js/directives/ui/linear-workflow/linear-workflow.component.html'
templateUrl: '/static/js/directives/ui/linear-workflow/linear-workflow.component.html',
transclude: true
})
export class LinearWorkflowComponent implements ng.IComponentController {
@Input('@') public doneTitle: string;
@Output() public onWorkflowComplete: (event: any) => void;
private sections: SectionInfo[] = [];
private currentSection: SectionInfo;
constructor() {
}
public $onInit(): void {
}
public addSection(section: LinearWorkflowSectionComponent): void {
this.sections.push({
index: this.sections.length,
section: section,
});
}
public onNextSection(): void {
if (this.currentSection.section.sectionValid) {
if (this.currentSection.index + 1 >= this.sections.length) {
this.onWorkflowComplete({});
}
else {
this.currentSection = this.sections[this.currentSection.index];
}
}
}
}
/**
* A type representing a section of the linear workflow.
*/
export type SectionInfo = {
index: number;
section: LinearWorkflowSectionComponent;
}