-
Notifications
You must be signed in to change notification settings - Fork 31
/
linear-stepper-control.component.ts
127 lines (113 loc) · 3.42 KB
/
linear-stepper-control.component.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import { Component, ChangeDetectionStrategy, Input, OnInit, OnDestroy } from '@angular/core';
import { TdStepsComponent, TdStepComponent, IStepChangeEvent, StepState } from '@covalent/core';
import { BehaviorSubject } from 'rxjs';
import { Subscription } from 'rxjs';
import { Observable } from 'rxjs';
/**
* Controls a teradata covalent stepper to implement the logic of a linear stepper
*/
@Component({
selector: 'linear-stepper-control',
template: '<ng-content></ng-content>',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class LinearStepperControlComponent implements OnInit, OnDestroy {
@Input() stepper: TdStepsComponent;
activeStep = new BehaviorSubject<TdStepComponent>(null);
disabledSteps = new BehaviorSubject<Set<TdStepComponent>>(new Set());
private monitors = new Map<TdStepComponent, Observable<boolean>>();
private subscriptions: Subscription[] = [];
ngOnInit() {
this.stepper.onStepChange.subscribe((event: IStepChangeEvent) => {
this.activate(event.newStep);
});
const sub = this.activeStep.subscribe(step => {
if (step) {
this.doActivate(step);
}
});
this.subscriptions.push(sub);
}
ngOnDestroy() {
this.subscriptions.forEach(sub => sub.unsubscribe());
}
/**
* Returns an observable notified when the given step active status has changed
*/
monitor(step: TdStepComponent): Observable<boolean> {
let mon = this.monitors.get(step);
if (mon == null) {
const subj = new BehaviorSubject<boolean>(this.activeStep.value === step);
const sub = this.activeStep.subscribe(it => {
if (step === it) {
subj.next(true);
} else if (subj.value) {
subj.next(false);
}
});
this.subscriptions.push(sub);
mon = subj.asObservable();
this.monitors.set(step, mon);
}
return mon;
}
/**
* Activates the given step
*/
activate(step: TdStepComponent): void {
this.activeStep.next(step);
}
/**
* Marks the given step as disabled, so it is never activated
*/
disable(step: TdStepComponent) {
const disabled = this.disabledSteps.value;
if (!disabled.has(step)) {
disabled.add(step);
this.disabledSteps.next(disabled);
}
}
/**
* Re-enables a step previously marked as disabled
*/
enable(step: TdStepComponent) {
const disabled = this.disabledSteps.value;
if (disabled.has(step)) {
disabled.delete(step);
this.disabledSteps.next(disabled);
}
}
/**
* Activates the last step and marks it as complete
*/
complete() {
const steps = this.stepper.steps;
if (steps.length === 0) {
return;
}
const last = steps[steps.length - 1];
this.activate(last);
last.state = StepState.Complete;
}
private doActivate(step: TdStepComponent) {
// Disable all steps greater than the current step
const steps = this.stepper.steps;
const index = steps.indexOf(step);
const disabled = this.disabledSteps.value;
for (let i = 0; i < steps.length; i++) {
const current = steps[i];
current.disabled = disabled.has(current) || i > index;
if (i > index) {
current.state = StepState.None;
} else if (i < index) {
if (this.disabledSteps.value.has(current)) {
current.state = StepState.None;
} else {
current.state = StepState.Complete;
}
}
}
step.state = StepState.None;
step.open();
}
}