Skip to content

Commit

Permalink
Merge pull request #578 from DSD-DBS/restructure-project-and-model-se…
Browse files Browse the repository at this point in the history
…rvice

Restructure project and model service
  • Loading branch information
dominik003 authored Feb 22, 2023
2 parents b6fec36 + 9862fdd commit 80a1eca
Show file tree
Hide file tree
Showing 55 changed files with 926 additions and 1,086 deletions.
29 changes: 26 additions & 3 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"@angular/platform-browser": "~15.1.2",
"@angular/platform-browser-dynamic": "~15.1.2",
"@angular/router": "~15.1.2",
"@ngneat/until-destroy": "^9.2.3",
"@types/semver": "^7.3.13",
"buffer": "^6.0.3",
"file-saver": "^2.0.5",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,9 @@
</mat-step>

<mat-step label="Add team members">
<div *ngIf="projectService.project" class="flex-center">
<div *ngIf="projectService.project | async" class="flex-center">
<div>
<app-project-user-settings
[project]="projectService.project"
></app-project-user-settings>
<app-project-user-settings></app-project-user-settings>
<mat-card class="mat-card-default">
<div class="flex-space-between">
<button
Expand Down Expand Up @@ -100,7 +98,10 @@
<div class="flex-center">
<a
mat-flat-button
[routerLink]="['/project', projectService.project?.slug]"
[routerLink]="[
'/project',
(projectService.project | async)?.slug
]"
[color]="getColorByModelCreationStep()"
data-testId="a-skipModelAndFinishProjectCreation"
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,20 @@
import { SpyLocation } from '@angular/common/testing';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ReactiveFormsModule } from '@angular/forms';
import {
AbstractControl,
AsyncValidatorFn,
ReactiveFormsModule,
ValidationErrors,
} from '@angular/forms';
import { MatLegacyCardModule as MatCardModule } from '@angular/material/legacy-card';
import { MatLegacyFormFieldModule as MatFormFieldModule } from '@angular/material/legacy-form-field';
import { MatLegacyInputModule as MatInputModule } from '@angular/material/legacy-input';
import { MatStepperModule } from '@angular/material/stepper';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { RouterTestingModule } from '@angular/router/testing';
import { BehaviorSubject, Observable, of } from 'rxjs';
import { BehaviorSubject, map, Observable, of, take } from 'rxjs';
import slugify from 'slugify';
import {
click,
findComponent,
Expand All @@ -22,7 +28,11 @@ import {
} from 'src/../tests/spec-helper/element.spec-helper';

import { ToastService } from '../../helpers/toast/toast.service';
import { Project, ProjectService } from '../service/project.service';
import {
PatchProject,
Project,
ProjectService,
} from '../service/project.service';
import { CreateProjectComponent } from './create-project.component';

const mockProjects: Project[] = [
Expand Down Expand Up @@ -50,31 +60,49 @@ describe('CreateProjectComponent', () => {
showSuccess(): void {},
};

const fakeProjectService: Pick<
ProjectService,
'_project' | '_projects' | 'list' | 'createProject' | 'project' | 'projects'
> = {
const fakeProjectService = {
_project: new BehaviorSubject<Project | undefined>(undefined),
_projects: new BehaviorSubject<Project[] | undefined>(undefined),
list() {

get project(): Observable<Project | undefined> {
return this._project.asObservable();
},

get projects(): Observable<Project[] | undefined> {
return this._projects.asObservable();
},

loadProjects() {
this._projects.next(mockProjects);
return of(mockProjects);
},
createProject(project: Project): Observable<Project> {
createProject(project: PatchProject): Observable<Project> {
let projectToCreate: Project = {
name: project.name,
description: project.description,
slug: project.name,
name: project.name!,
description: project.description!,
slug: project.name!,
users: { leads: 1, contributors: 0, subscribers: 0 },
};
this._project.next(projectToCreate);
return of(projectToCreate);
},
get projects(): Project[] | undefined {
return this._projects.value;
clearProject(): void {
this._project.next(undefined);
},
get project(): Project | undefined {
return this._project.value;
asyncSlugValidator(): AsyncValidatorFn {
return (
control: AbstractControl
): Observable<ValidationErrors | null> => {
const projectSlug = slugify(control.value, { lower: true });
return this.projects.pipe(
take(1),
map((projects) => {
return projects?.find((project) => project.slug === projectSlug)
? { uniqueSlug: { value: projectSlug } }
: null;
})
);
};
},
};

Expand Down Expand Up @@ -129,13 +157,10 @@ describe('CreateProjectComponent', () => {

fixture.detectChanges();

expect(fakeProjectService.createProject).toHaveBeenCalledOnceWith(
{
name: testProjectName,
description: '',
},
true
);
expect(fakeProjectService.createProject).toHaveBeenCalledOnceWith({
name: testProjectName,
description: '',
});
expect(fakeToastService.showSuccess).toHaveBeenCalledTimes(1);
});

Expand All @@ -149,13 +174,10 @@ describe('CreateProjectComponent', () => {

fixture.detectChanges();

expect(fakeProjectService.createProject).toHaveBeenCalledOnceWith(
{
name: testProjectName,
description: testProjectDescription,
},
true
);
expect(fakeProjectService.createProject).toHaveBeenCalledOnceWith({
name: testProjectName,
description: testProjectDescription,
});
expect(fakeToastService.showSuccess).toHaveBeenCalledTimes(1);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,8 @@
*/

import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
import {
AbstractControl,
FormControl,
FormGroup,
ValidationErrors,
ValidatorFn,
Validators,
} from '@angular/forms';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { MatStepper } from '@angular/material/stepper';
import { Router } from '@angular/router';
import slugify from 'slugify';
import {
CreateModelComponent,
CreateModelStep,
Expand All @@ -30,41 +21,36 @@ import { ProjectService } from '../service/project.service';
export class CreateProjectComponent implements OnInit, OnDestroy {
@ViewChild('model_creator') model_creator!: CreateModelComponent;

private projectDetails = false;

public modelCreationStep: CreateModelStep = 'create-model';

form = new FormGroup({
name: new FormControl('', [Validators.required, this.slugValidator()]),
description: new FormControl(''),
});

constructor(
public projectService: ProjectService,
private router: Router,
private toastService: ToastService
) {}

form = new FormGroup({
name: new FormControl('', {
validators: Validators.required,
asyncValidators: this.projectService.asyncSlugValidator(),
}),
description: new FormControl(''),
});

ngOnInit(): void {
this.projectService.list().subscribe();
this.projectService.loadProjects();
}

ngOnDestroy(): void {
if (!this.projectDetails) {
this.projectService._project.next(undefined);
}
this.projectService.clearProject();
}

createProject(stepper: MatStepper): void {
if (this.form.valid) {
this.projectService
.createProject(
{
name: this.form.value.name!,
description: this.form.value.description!,
},
true
)
.createProject({
name: this.form.value.name!,
description: this.form.value.description!,
})
.subscribe((project) => {
this.toastService.showSuccess(
`The project “${project.name}” was successfuly created.`,
Expand All @@ -77,25 +63,6 @@ export class CreateProjectComponent implements OnInit, OnDestroy {
}
}

finish(): void {
this.projectDetails = true;
this.router.navigate(['/project', this.projectService.project!.slug]);
}

slugValidator(): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
const slug = slugify(control.value, { lower: true });
if (
this.projectService.projects
?.map((project) => project.slug)
.includes(slug)
) {
return { uniqueSlug: { value: slug } };
}
return null;
};
}

getColorByModelCreationStep(): string {
switch (this.modelCreationStep) {
case 'create-model':
Expand Down
Loading

0 comments on commit 80a1eca

Please sign in to comment.