Skip to content

Commit 916fae8

Browse files
authored
Fix project creation onboarding (#726)
* method for closing subscripton modal * add create subscription to project onboarding * update flow * connect project onboarding * fix project onboarding flow * update private services url
1 parent a5917c2 commit 916fae8

38 files changed

+223
-168
lines changed

web/ui/dashboard/post-build-css.js

+1-4
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,7 @@ const path = require('path');
66
const files = getFilesFromPath('./dist', '.css');
77
let data = [];
88

9-
if (!files && files.length <= 0) {
10-
console.log('cannot find style files to purge');
11-
return;
12-
}
9+
if (!files && files.length == 0) return console.log('cannot find style files to purge');
1310

1411
for (let f of files) {
1512
// get original file size

web/ui/dashboard/src/app/private/components/create-app/create-app.component.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ export class CreateAppComponent implements OnInit {
115115
: await this.createAppService.createApp({ body: this.addNewAppForm.value });
116116

117117
if (!this.editAppMode) {
118-
this.appUid = response?.data?.uid;
118+
this.appUid = response.data.uid;
119119
const endpointData = this.addNewAppForm.value.endpoints;
120120
endpointData.forEach((item: any) => {
121121
requests.push(this.addNewEndpoint(item));

web/ui/dashboard/src/app/private/components/create-app/create-app.service.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,13 @@ import { PrivateService } from '../../private.service';
77
providedIn: 'root'
88
})
99
export class CreateAppService {
10-
projectId: string = this.privateService.activeProjectId;
1110
constructor(private http: HttpService, private privateService: PrivateService) {}
1211

1312
async updateApp(requestDetails: { appId: string; body: any }): Promise<HTTP_RESPONSE> {
1413
return new Promise(async (resolve, reject) => {
1514
try {
1615
const response = await this.http.request({
17-
url: `/apps/${requestDetails.appId}?groupId=${this.projectId}`,
16+
url: `${this.privateService.urlFactory('org_project')}/apps/${requestDetails.appId}`,
1817
method: 'put',
1918
body: requestDetails.body
2019
});
@@ -30,7 +29,7 @@ export class CreateAppService {
3029
return new Promise(async (resolve, reject) => {
3130
try {
3231
const response = await this.http.request({
33-
url: `/apps?groupId=${this.projectId}`,
32+
url: `${this.privateService.urlFactory('org_project')}/apps`,
3433
method: 'post',
3534
body: requestDetails.body
3635
});
@@ -46,7 +45,7 @@ export class CreateAppService {
4645
return new Promise(async (resolve, reject) => {
4746
try {
4847
const response = await this.http.request({
49-
url: `/apps/${requestDetails.appId}/endpoints?groupId=${this.projectId}`,
48+
url: `${this.privateService.urlFactory('org_project')}/apps/${requestDetails.appId}/endpoints`,
5049
body: requestDetails.body,
5150
method: 'post'
5251
});

web/ui/dashboard/src/app/private/components/create-project-component/create-project-component.component.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,13 @@ export class CreateProjectComponent implements OnInit {
6969

7070
try {
7171
const response = await this.createProjectService.createProject(this.projectForm.value);
72-
const projectId = response?.data?.uid;
73-
this.privateService.activeProjectId = projectId;
72+
this.privateService.activeProjectDetails = response.data;
7473
this.isCreatingProject = false;
7574
this.generalService.showNotification({ message: 'Project created successfully!', style: 'success' });
7675
this.onAction.emit({ action: 'createProject', data: response.data });
77-
} catch (error) {
76+
} catch (error: any) {
7877
this.isCreatingProject = false;
78+
this.generalService.showNotification({ message: error.message, style: 'error' });
7979
}
8080
}
8181

web/ui/dashboard/src/app/private/components/create-project-component/create-project-component.service.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export class CreateProjectComponentService {
1919
}): Promise<HTTP_RESPONSE> {
2020
try {
2121
const response = await this.http.request({
22-
url: `/groups`,
22+
url: `${this.privateService.urlFactory('org')}/groups`,
2323
body: requestDetails,
2424
method: 'post'
2525
});
@@ -39,7 +39,7 @@ export class CreateProjectComponentService {
3939
}): Promise<HTTP_RESPONSE> {
4040
try {
4141
const response = await this.http.request({
42-
url: `/groups/${this.privateService.activeProjectId}`,
42+
url: `${this.privateService.urlFactory('org')}/groups/${this.privateService.activeProjectDetails.uid}`,
4343
body: requestDetails,
4444
method: 'put'
4545
});

web/ui/dashboard/src/app/private/components/create-source/create-source.component.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,7 @@ export class CreateSourceComponent implements OnInit {
6565
try {
6666
const response = await this.createSourceService.createSource({ sourceData });
6767
this.onAction.emit(response.data);
68-
} catch (error) {
69-
console.log(error);
70-
}
68+
} catch (error) {}
7169
}
7270

7371
isSourceFormValid(): boolean {

web/ui/dashboard/src/app/private/components/create-source/create-source.service.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,13 @@ import { PrivateService } from '../../private.service';
88
providedIn: 'root'
99
})
1010
export class CreateSourceService {
11-
projectId: string = this.privateService.activeProjectId;
12-
1311
constructor(private http: HttpService, private privateService: PrivateService) {}
1412

1513
createSource(requestData: { sourceData: SOURCE }): Promise<HTTP_RESPONSE> {
1614
return new Promise(async (resolve, reject) => {
1715
try {
1816
const sourceResponse = await this.http.request({
19-
url: `/sources?groupId=${this.projectId}`,
17+
url: `${this.privateService.urlFactory('org_project')}/sources`,
2018
method: 'post',
2119
body: requestData.sourceData
2220
});

web/ui/dashboard/src/app/private/components/create-subscription/create-subscription.component.html

+26-22
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
<form class="padding-bottom__40px" [formGroup]="subscriptonForm" (ngSubmit)="createSubscription()">
1+
<form class="padding-bottom__40px position__relative" [formGroup]="subscriptonForm" (ngSubmit)="createSubscription()">
2+
<convoy-loader *ngIf="isLoadingForm"></convoy-loader>
3+
24
<section class="card padding-all__24px">
35
<div class="input">
46
<label for="source-name">Subscription name</label>
@@ -9,26 +11,28 @@
911
</div>
1012
</div>
1113

12-
<div class="input margin-bottom__0px">
13-
<label for="source" class="position__relative">
14-
Source
15-
<span class="bg__grey__light rounded__4px padding-x__4px position__absolute position--right__0px font__10px font__weight-400">required</span>
16-
</label>
17-
<select id="source" formControlName="source_id">
18-
<option value="">Select source</option>
19-
<option [value]="source.uid" *ngFor="let source of sources">{{ source.name }}</option>
20-
</select>
21-
<div class="input__error input__error__danger" *ngIf="subscriptonForm.get('source_id')?.touched && subscriptonForm.get('source_id')?.invalid">
22-
<img src="assets/img/input-error-icon.svg" alt="input error icon" />
23-
<span>Select or create a source</span>
14+
<ng-container *ngIf="projectType === 'incoming'">
15+
<div class="input margin-bottom__0px">
16+
<label for="source" class="position__relative">
17+
Source
18+
<span class="bg__grey__light rounded__4px padding-x__4px position__absolute position--right__0px font__10px font__weight-400">required</span>
19+
</label>
20+
<select id="source" formControlName="source_id">
21+
<option value="">Select source</option>
22+
<option [value]="source.uid" *ngFor="let source of sources">{{ source.name }}</option>
23+
</select>
24+
<div class="input__error input__error__danger" *ngIf="subscriptonForm.get('source_id')?.touched && subscriptonForm.get('source_id')?.invalid">
25+
<img src="assets/img/input-error-icon.svg" alt="input error icon" />
26+
<span>Select or create a source</span>
27+
</div>
2428
</div>
25-
</div>
26-
<button class="button button__clear button--has-icon font__12px margin-top__4px margin-bottom__20px" type="button" (click)="showCreateSourceModal = true">
27-
<svg width="14" height="14" class="margin-right__4px" fill="var(--primary-color)">
28-
<use xlink:href="#plus-icon"></use>
29-
</svg>
30-
New Source
31-
</button>
29+
<button class="button button__clear button--has-icon font__12px margin-top__4px margin-bottom__20px" type="button" (click)="showCreateSourceModal = true">
30+
<svg width="14" height="14" class="margin-right__4px" fill="var(--primary-color)">
31+
<use xlink:href="#plus-icon"></use>
32+
</svg>
33+
New Source
34+
</button>
35+
</ng-container>
3236

3337
<div class="input margin-bottom__0px">
3438
<label for="application" class="position__relative">
@@ -68,9 +72,9 @@
6872
</section>
6973

7074
<div class="button-container flex flex__justify-end margin-top__32px">
71-
<button class="button button__white padding-y__12px padding-x__28px rounded__8px margin-right__16px" type="button">Cancel</button>
75+
<button class="button button__white padding-y__12px padding-x__28px rounded__8px margin-right__16px" type="button" (click)="onAction.emit({ action: 'cancel' })">Cancel</button>
7276

73-
<button class="button button__primary button--has-icon padding-y__12px rounded__8px" type="submit">
77+
<button class="button button__primary button--has-icon padding-y__12px rounded__8px" type="submit" [disabled]="isCreatingSubscription">
7478
Create Subscription
7579
<svg width="24" height="24" class="margin-left__8px" fill="#FCFCFC">
7680
<use xlink:href="#arrow-right-icon"></use>

web/ui/dashboard/src/app/private/components/create-subscription/create-subscription.component.ts

+33-10
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Component, OnInit } from '@angular/core';
1+
import { Component, EventEmitter, OnInit, Output } from '@angular/core';
22
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
33
import { Router } from '@angular/router';
44
import { APP, ENDPOINT } from 'src/app/models/app.model';
@@ -26,28 +26,36 @@ export class CreateSubscriptionComponent implements OnInit {
2626
endPoints?: ENDPOINT[];
2727
showCreateAppModal = false;
2828
showCreateSourceModal = false;
29+
isCreatingSubscription = false;
30+
@Output() onAction = new EventEmitter();
31+
projectType: 'incoming' | 'outgoing' = 'incoming';
32+
isLoadingForm = true;
2933

3034
constructor(private formBuilder: FormBuilder, private privateService: PrivateService, private createSubscriptionService: CreateSubscriptionService, private router: Router) {}
3135

32-
ngOnInit(): void {
33-
Promise.all([this.getApps(), this.getSources(), this.getGetProjectDetails()]);
36+
async ngOnInit() {
37+
this.isLoadingForm = true;
38+
await Promise.all([this.getApps(), this.getSources(), this.getGetProjectDetails()]);
39+
this.isLoadingForm = false;
3440
}
3541

3642
async getApps() {
3743
try {
3844
const appsResponse = await this.privateService.getApps();
3945
this.apps = appsResponse.data.content;
46+
return;
4047
} catch (error) {
41-
console.log(error);
48+
return error;
4249
}
4350
}
4451

4552
async getSources() {
4653
try {
4754
const sourcesResponse = await this.privateService.getSources();
4855
this.sources = sourcesResponse.data.content;
56+
return;
4957
} catch (error) {
50-
console.log(error);
58+
return;
5159
}
5260
}
5361

@@ -58,8 +66,10 @@ export class CreateSubscriptionComponent implements OnInit {
5866
group_id: response.data.uid,
5967
type: 'incoming'
6068
});
69+
this.projectType = response.data.type;
70+
return;
6171
} catch (error) {
62-
console.log(error);
72+
return;
6373
}
6474
}
6575

@@ -74,14 +84,27 @@ export class CreateSubscriptionComponent implements OnInit {
7484
}
7585

7686
async createSubscription() {
77-
console.log(this.subscriptonForm.value);
78-
if (this.subscriptonForm.invalid) return this.subscriptonForm.markAllAsTouched();
87+
if (this.projectType === 'incoming' && this.subscriptonForm.invalid) return this.subscriptonForm.markAllAsTouched();
88+
if (
89+
this.subscriptonForm.get('name')?.invalid &&
90+
this.subscriptonForm.get('type')?.invalid &&
91+
this.subscriptonForm.get('app_id')?.invalid &&
92+
this.subscriptonForm.get('endpoint_id')?.invalid &&
93+
this.subscriptonForm.get('group_id')?.invalid
94+
) {
95+
return this.subscriptonForm.markAllAsTouched();
96+
}
97+
98+
const subscription = this.subscriptonForm.value;
99+
if (this.projectType === 'outgoing') delete subscription.source_id;
100+
this.isCreatingSubscription = true;
79101

80102
try {
81103
const response = await this.createSubscriptionService.createSubscription(this.subscriptonForm.value);
82-
this.router.navigateByUrl('/projects/' + this.privateService.activeProjectId + '/subscriptions');
104+
this.isCreatingSubscription = false;
105+
this.onAction.emit(response.data);
83106
} catch (error) {
84-
console.log(error);
107+
this.isCreatingSubscription = false;
85108
}
86109
}
87110

web/ui/dashboard/src/app/private/components/create-subscription/create-subscription.module.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ import { CreateSubscriptionComponent } from './create-subscription.component';
44
import { ReactiveFormsModule } from '@angular/forms';
55
import { CreateAppModule } from '../create-app/create-app.module';
66
import { CreateSourceModule } from '../create-source/create-source.module';
7+
import { LoaderModule } from '../loader/loader.module';
78

89
@NgModule({
910
declarations: [CreateSubscriptionComponent],
10-
imports: [CommonModule, ReactiveFormsModule, CreateAppModule, CreateSourceModule],
11+
imports: [CommonModule, ReactiveFormsModule, CreateAppModule, CreateSourceModule, LoaderModule],
1112
exports: [CreateSubscriptionComponent]
1213
})
1314
export class CreateSubscriptionModule {}

web/ui/dashboard/src/app/private/components/create-subscription/create-subscription.service.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@ import { PrivateService } from '../../private.service';
77
providedIn: 'root'
88
})
99
export class CreateSubscriptionService {
10-
projectId: string = this.privateService.activeProjectId;
10+
projectId: string = this.privateService.activeProjectDetails.uid;
1111

1212
constructor(private http: HttpService, private privateService: PrivateService) {}
1313

1414
createSubscription(requestDetails: any): Promise<HTTP_RESPONSE> {
1515
return new Promise(async (resolve, reject) => {
1616
try {
1717
const projectResponse = await this.http.request({
18-
url: `/subscriptions?groupId=${this.projectId}`,
18+
url: `${this.privateService.urlFactory('org_project')}/subscriptions`,
1919
method: 'post',
2020
body: requestDetails
2121
});

web/ui/dashboard/src/app/private/pages/create-project/create-project.component.html

+23-12
Original file line numberDiff line numberDiff line change
@@ -16,25 +16,27 @@ <h2 class="font__16px font__weight-600">Create Project</h2>
1616
</div>
1717

1818
<div class="modal--body padding-all__0px">
19-
<app-create-project-component (onAction)="$event.action == 'cancel' ? cancel() : createProject($event)" *ngIf="projectStage === 'createProject'"></app-create-project-component>
19+
<app-create-project-component (onAction)="$event.action == 'cancel' ? cancel() : createProject($event?.data)" *ngIf="projectStage === 'createProject'"></app-create-project-component>
2020

2121
<div class="card padding-all__24px margin-bottom__24px" *ngIf="projectStage !== 'createProject'">
2222
<ul class="setup-steps flex flex__align-items-center border__bottom padding-bottom__24px">
23-
<li class="setup-step--step done" *ngIf="projectType === 'incoming'">
23+
<li class="setup-step--step" *ngIf="projectType === 'incoming'" [ngClass]="{ done: projectStage !== 'createSource', current: projectStage == 'createSource' }">
2424
<div class="line"></div>
2525
<div class="margin-top__4px flex flex__align-items-center">
2626
<div class="checkbox margin-all__0px width__16px height__16px border__all rounded__50px"></div>
2727
<div class="text margin-left__8px font__14px font__weight-500">Create Source</div>
2828
</div>
2929
</li>
30-
<li class="setup-step--step current">
30+
31+
<li class="setup-step--step" [ngClass]="{ done: projectStage == 'createSubscription', current: projectStage == 'createApplication' }">
3132
<div class="line bg__primary"></div>
3233
<div class="margin-top__4px flex flex__align-items-center">
3334
<div class="checkbox margin-all__0px width__16px height__16px border__all rounded__50px"></div>
3435
<div class="text margin-left__8px font__14px font__weight-500">Create Application</div>
3536
</div>
3637
</li>
37-
<li class="setup-step--step">
38+
39+
<li class="setup-step--step" [ngClass]="{ current: projectStage == 'createSubscription' }">
3840
<div class="line bg__primary"></div>
3941
<div class="margin-top__4px flex flex__align-items-center">
4042
<div class="checkbox margin-all__0px width__16px height__16px border__all rounded__50px"></div>
@@ -45,20 +47,29 @@ <h2 class="font__16px font__weight-600">Create Project</h2>
4547

4648
<div *ngIf="projectStage === 'createSource'">
4749
<h3 class="margin-top__24px font__weight-600 font__18px">Create your first source</h3>
48-
<p class="font__14px color__grey margin-top__8px width__80">
49-
Your source represents the etiam diam mi, egestas tortor nulla quis consectetur mauris eget. Penatibus placerat massa, lectus lectus
50-
</p>
50+
<p class="font__14px color__grey margin-top__8px width__80">Create a source that'll triger a webhook event in your project</p>
5151
</div>
5252
<div *ngIf="projectStage === 'createApplication'">
5353
<h3 class="margin-top__24px font__weight-600 font__18px">Create your first application</h3>
54-
<p class="font__14px color__grey margin-top__8px width__80">
55-
Your source represents the etiam diam mi, egestas tortor nulla quis consectetur mauris eget. Penatibus placerat massa, lectus lectus
56-
</p>
54+
<p class="font__14px color__grey margin-top__8px width__80">Create and aplication and endpoint(s) that'll listen to events on this project</p>
55+
</div>
56+
<div *ngIf="projectStage === 'createSubscription'">
57+
<h3 class="margin-top__24px font__weight-600 font__18px">Create your first subscription</h3>
58+
<p class="font__14px color__grey margin-top__8px width__80">Create a subscription that'll listen to events from your source</p>
5759
</div>
5860
</div>
5961

60-
<app-create-source *ngIf="projectStage === 'createSource'"></app-create-source>
62+
<app-create-source
63+
*ngIf="projectStage === 'createSource' && privateService.activeProjectDetails.uid"
64+
(onAction)="$event?.action == 'cancel' ? cancel() : projectType == 'incoming' ? onProjectOnboardingComplete() : (projectStage = 'createApplication')"
65+
></app-create-source>
66+
67+
<app-create-app
68+
*ngIf="projectStage === 'createApplication' && privateService.activeProjectDetails.uid"
69+
(discardApp)="cancel()"
70+
(createApp)="projectType == 'incoming' ? (projectStage = 'createSource') : (projectStage = 'createSubscription')"
71+
></app-create-app>
6172

62-
<app-create-app *ngIf="projectStage === 'createApplication'" (discardApp)="cancel()" (createApp)="projectStage = 'createSubscription'"></app-create-app>
73+
<app-create-subscription *ngIf="projectStage === 'createSubscription' && privateService.activeProjectDetails.uid" (onAction)="onProjectOnboardingComplete()"></app-create-subscription>
6374
</div>
6475
</div>

0 commit comments

Comments
 (0)