feat: add Master Admin application functionality
This commit is contained in:
@@ -0,0 +1,164 @@
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
computed,
|
||||
DestroyRef,
|
||||
inject,
|
||||
signal
|
||||
} from '@angular/core';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
import { Router } from '@angular/router';
|
||||
import { ToastrService } from 'ngx-toastr';
|
||||
import { catchError, finalize, of } from 'rxjs';
|
||||
import {
|
||||
OnboardingStep,
|
||||
OnboardingStepper
|
||||
} from './components/onboarding-stepper/onboarding-stepper';
|
||||
import { OrganizationBasicsStepComponent } from './steps/organization-basics/organization-basics';
|
||||
import { OrganizationOnboardingStateService } from './services/organization-onboarding-state.service';
|
||||
import { OrganizationOnboardingService } from './services/organization-onboarding.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-organization-onboarding',
|
||||
standalone: true,
|
||||
imports: [OnboardingStepper, OrganizationBasicsStepComponent],
|
||||
templateUrl: './organization-onboarding.html',
|
||||
styleUrl: './organization-onboarding.scss',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
providers: [OrganizationOnboardingStateService, OrganizationOnboardingService]
|
||||
})
|
||||
export class OrganizationOnboarding {
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
private readonly router = inject(Router);
|
||||
private readonly toastr = inject(ToastrService);
|
||||
private readonly stateService = inject(OrganizationOnboardingStateService);
|
||||
private readonly onboardingService = inject(OrganizationOnboardingService);
|
||||
|
||||
readonly steps: readonly OnboardingStep[] = this.stateService.createStepDefinitions();
|
||||
|
||||
readonly savingDraft = signal(false);
|
||||
readonly finishing = signal(false);
|
||||
|
||||
private basicsStep?: OrganizationBasicsStepComponent;
|
||||
|
||||
readonly currentStepIndex = this.stateService.currentStepIndex;
|
||||
readonly completedStepIndexes = this.stateService.completedStepIndexes;
|
||||
|
||||
readonly currentStep = computed(
|
||||
() => this.steps[this.currentStepIndex()]
|
||||
);
|
||||
|
||||
readonly navigationDisabled = computed(
|
||||
() => this.savingDraft() || this.finishing()
|
||||
);
|
||||
|
||||
constructor() {
|
||||
this.onboardingService.loadDraft()
|
||||
.pipe(
|
||||
catchError(() => {
|
||||
this.toastr.error('Unable to restore the onboarding draft.', 'Draft restore failed');
|
||||
return of(null);
|
||||
}),
|
||||
takeUntilDestroyed(this.destroyRef)
|
||||
)
|
||||
.subscribe(draft => {
|
||||
if (!draft) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.stateService.restoreDraft(draft);
|
||||
});
|
||||
}
|
||||
|
||||
registerBasicsStep(component: OrganizationBasicsStepComponent): void {
|
||||
this.basicsStep = component;
|
||||
const basicsDraft = this.stateService.onboardingDraft().basics;
|
||||
|
||||
if (basicsDraft) {
|
||||
component.patchValue(basicsDraft);
|
||||
}
|
||||
}
|
||||
|
||||
onStepSelected(index: number): void {
|
||||
if (!this.stateService.canOpenStep(index)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.stateService.setCurrentStepIndex(index);
|
||||
}
|
||||
|
||||
onBack(): void {
|
||||
const currentIndex = this.currentStepIndex();
|
||||
|
||||
if (currentIndex <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.stateService.setCurrentStepIndex(currentIndex - 1);
|
||||
}
|
||||
|
||||
onNext(): void {
|
||||
const currentIndex = this.currentStepIndex();
|
||||
|
||||
if (currentIndex >= this.steps.length - 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentIndex === 0) {
|
||||
if (!this.basicsStep?.validate()) {
|
||||
this.stateService.unmarkStepCompleted(currentIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
this.stateService.updateBasics(this.basicsStep.getValue());
|
||||
}
|
||||
|
||||
this.stateService.markStepCompleted(currentIndex);
|
||||
this.stateService.setCurrentStepIndex(currentIndex + 1);
|
||||
}
|
||||
|
||||
onSaveDraft(): void {
|
||||
if (this.savingDraft()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.currentStepIndex() === 0 && this.basicsStep) {
|
||||
this.stateService.updateBasicsDraft(this.basicsStep.getDraftValue());
|
||||
}
|
||||
|
||||
this.savingDraft.set(true);
|
||||
|
||||
this.onboardingService.saveDraft(this.stateService.buildDraft())
|
||||
.pipe(
|
||||
finalize(() => {
|
||||
this.savingDraft.set(false);
|
||||
}),
|
||||
takeUntilDestroyed(this.destroyRef)
|
||||
)
|
||||
.subscribe({
|
||||
next: () => {
|
||||
this.toastr.success('Onboarding draft saved successfully.', 'Draft saved');
|
||||
},
|
||||
error: () => {
|
||||
this.toastr.error('Unable to save the onboarding draft.', 'Draft save failed');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onFinish(): void {
|
||||
if (this.finishing()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.finishing.set(true);
|
||||
|
||||
queueMicrotask(() => {
|
||||
this.finishing.set(false);
|
||||
});
|
||||
}
|
||||
|
||||
onCancel(): void {
|
||||
this.stateService.clear();
|
||||
void this.router.navigate(['/configuration/organizations']);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user