Skip to content

Commit e0ed583

Browse files
committed
Fix redirect if empty list
1 parent a2e65bf commit e0ed583

6 files changed

Lines changed: 63 additions & 11 deletions

File tree

cypress/e2e/billingentities.cy.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ describe('Test billing entity list', () => {
2525
cy.get(':nth-child(3) > .flex-row > .text-3xl').should('contain.text', 'be-2347');
2626
});
2727

28-
it('empty list', () => {
28+
it('empty list should redirect to new', () => {
2929
setBillingEntities(cy);
3030
cy.visit('/billingentities');
31-
cy.get('#billingentities-title').should('contain.text', 'Billing');
32-
cy.get('#addButton').should('contain.text', 'Add new Billing');
33-
cy.get('#no-billingentity-message').should('contain.text', 'No billing entities available.');
31+
cy.get('#title').should('contain.text', 'New Billing');
32+
33+
cy.url().should('contain', 'billingentities/$new?edit=y');
3434
});
3535

3636
it('request failed', () => {
@@ -91,6 +91,7 @@ describe('no permissions', () => {
9191
cy.visit('/billingentities');
9292
cy.get('h1').should('contain.text', 'Billing');
9393
cy.get('addButton').should('not.exist');
94+
cy.get('#no-billingentity-message').should('contain.text', 'No billing entities available.');
9495
});
9596

9697
it('no edit permission', () => {

cypress/e2e/billingentity-form.cy.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ describe('Test billing entity form elements', () => {
162162
});
163163

164164
it('should cancel editing', () => {
165-
setBillingEntities(cy);
165+
setBillingEntities(cy, billingEntityNxt); // give at least 1 item to avoid redirect back to form.
166166

167167
['.p-button-secondary', 'a[appbacklink]'].forEach((cancelSelector) => {
168168
cy.visit('/billingentities/$new?edit=y');
@@ -171,7 +171,7 @@ describe('Test billing entity form elements', () => {
171171
cy.get(cancelSelector).click();
172172
cy.get('app-billingentity-form').should('not.exist');
173173

174-
cy.get('p-messages').should('contain.text', 'No billing entities available');
174+
cy.get('.text-3xl').should('have.length', 1);
175175
});
176176
});
177177
});

cypress/e2e/organizations.cy.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import { OrganizationPermissions } from '../../src/app/types/organization';
1010
import { BillingEntityPermissions } from '../../src/app/types/billing-entity';
1111
import { billingEntityNxt, billingEntityVshn, setBillingEntities } from '../fixtures/billingentities';
1212
import { OrganizationMembersPermissions } from '../../src/app/types/organization-members';
13+
import { ZonePermissions } from '../../src/app/types/zone';
14+
import { zoneCloudscale1 } from '../fixtures/zone';
1315

1416
describe('Test organization list', () => {
1517
beforeEach(() => {
@@ -268,6 +270,36 @@ describe('Test organization add', () => {
268270
cy.get(':nth-child(3) > .flex-row [title="Edit members"]').should('exist');
269271
});
270272

273+
it('add organization for first-time', () => {
274+
cy.setPermission(
275+
{ verb: 'list', ...OrganizationPermissions },
276+
{ verb: 'create', ...OrganizationPermissions },
277+
{ verb: 'list', ...BillingEntityPermissions },
278+
{ verb: 'list', ...ZonePermissions },
279+
{ verb: 'update', ...OrganizationPermissions, namespace: organizationVshn.metadata.name },
280+
{ verb: 'list', ...OrganizationMembersPermissions, namespace: organizationVshn.metadata.name }
281+
);
282+
283+
setOrganization(cy, organizationNxt);
284+
setBillingEntities(cy, billingEntityNxt);
285+
cy.intercept('GET', 'appuio-api/apis/appuio.io/v1/zones', {
286+
body: { items: [zoneCloudscale1] },
287+
});
288+
289+
cy.intercept('POST', 'appuio-api/apis/organization.appuio.io/v1/organizations', {
290+
body: organizationVshn,
291+
}).as('add');
292+
cy.visit('/organizations/$new?firstTime=y');
293+
cy.get('#title').should('contain.text', 'New Organization');
294+
295+
cy.get('#id').type('nxt');
296+
cy.get('#selectedBillingEntity').click().contains('Engineering').click();
297+
cy.get('button[type=submit]').click();
298+
cy.wait('@add');
299+
cy.url().should('contain', '/zones');
300+
cy.get('#zones-title').should('contain.text', 'Zones');
301+
});
302+
271303
it('add organization with invalid id', () => {
272304
cy.setPermission(
273305
{ verb: 'list', ...OrganizationPermissions },

src/app/billingentity/billing-entity.component.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { faAdd, faEdit, faInfo, faMagnifyingGlass, faUserGroup, faWarning } from
55
import { combineLatestAll, forkJoin, from, map, Observable, of } from 'rxjs';
66
import { BillingEntityCollectionService } from '../store/billingentity-collection.service';
77
import { switchMap } from 'rxjs/operators';
8+
import { ActivatedRoute, Router } from '@angular/router';
89

910
@Component({
1011
selector: 'app-billing-entity',
@@ -21,7 +22,11 @@ export class BillingEntityComponent implements OnInit {
2122

2223
payload$?: Observable<ViewModel>;
2324

24-
constructor(public billingEntityService: BillingEntityCollectionService) {}
25+
constructor(
26+
public billingEntityService: BillingEntityCollectionService,
27+
private router: Router,
28+
private route: ActivatedRoute
29+
) {}
2530

2631
ngOnInit(): void {
2732
this.payload$ = forkJoin([
@@ -30,6 +35,13 @@ export class BillingEntityComponent implements OnInit {
3035
]).pipe(
3136
switchMap(([entities, canCreateBilling]) => {
3237
if (entities.length === 0) {
38+
if (canCreateBilling) {
39+
void this.router.navigate(['$new'], {
40+
queryParams: { firstTime: undefined, edit: 'y' },
41+
queryParamsHandling: 'merge',
42+
relativeTo: this.route,
43+
});
44+
}
3345
// no billing entities
3446
return of({
3547
canCreateBilling: canCreateBilling,

src/app/first-time-login-dialog/first-time-login-dialog.component.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core';
22
import { ActivatedRoute, ActivationStart, Router } from '@angular/router';
3-
import { faAdd, faCog, faDollarSign, faSitemap } from '@fortawesome/free-solid-svg-icons';
3+
import { faAdd, faCog, faSitemap } from '@fortawesome/free-solid-svg-icons';
44
import { FormControl } from '@angular/forms';
55
import { IdentityService } from '../core/identity.service';
66
import { filter, forkJoin, map, Observable, of, take } from 'rxjs';
@@ -24,9 +24,7 @@ export class FirstTimeLoginDialogComponent implements OnInit {
2424
faSitemap = faSitemap;
2525
faAdd = faAdd;
2626
faCoq = faCog;
27-
faDollarSign = faDollarSign;
2827
hideFirstTimeLoginDialogControl = new FormControl(false);
29-
nextAction?: 'join' | 'add';
3028

3129
constructor(
3230
private router: Router,

src/app/organizations/organization-form/organization-form.component.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,16 @@ export class OrganizationFormComponent implements OnInit, OnDestroy {
134134
severity: 'success',
135135
summary: $localize`Successfully saved`,
136136
});
137-
void this.router.navigate([this.navigationService.previousLocation()], { relativeTo: this.activatedRoute });
137+
const firstTime = this.activatedRoute.snapshot.queryParamMap.get('firstTime') === 'y';
138+
if (firstTime) {
139+
void this.router.navigate(['zones'], {
140+
queryParams: { edit: undefined, firstTime: undefined },
141+
queryParamsHandling: 'merge',
142+
});
143+
return;
144+
}
145+
const previous = this.navigationService.previousRoute('..');
146+
void this.router.navigate([previous.path], { relativeTo: this.activatedRoute, queryParams: previous.queryParams });
138147
}
139148

140149
private saveOrUpdateFailure(err: Error): void {

0 commit comments

Comments
 (0)