From 6e89b7d0a1af158de5c15246512998089e039bc8 Mon Sep 17 00:00:00 2001 From: Max Peintner Date: Thu, 20 Oct 2022 14:08:13 +0200 Subject: [PATCH] feat(console): rename org (#4542) * rename org * add data-e2e * e2e test * restore state after * use ngIf instead of hasrole directive and initialized regex * rm h2 check * Update e2e/cypress/e2e/organization/organizations.cy.ts Co-authored-by: Elio Bischof * Update console/src/assets/i18n/de.json Co-authored-by: Elio Bischof * Update console/src/assets/i18n/de.json Co-authored-by: Elio Bischof * Update console/src/assets/i18n/en.json Co-authored-by: Elio Bischof * change e2e test * org param * reintroduct org param * use org query param * org rename test * no initial focus on button * contain name Co-authored-by: Elio Bischof --- console/src/app/app.component.ts | 7 ++- .../name-dialog/name-dialog.component.html | 4 +- .../modules/top-view/top-view.component.html | 3 +- .../orgs/org-detail/org-detail.component.html | 11 +++-- .../orgs/org-detail/org-detail.component.ts | 48 ++++++++++++++++++- console/src/app/pages/orgs/org.module.ts | 2 + console/src/app/services/mgmt.service.ts | 8 ++++ console/src/assets/i18n/de.json | 7 +++ console/src/assets/i18n/en.json | 7 +++ console/src/assets/i18n/fr.json | 7 +++ console/src/assets/i18n/it.json | 7 +++ console/src/assets/i18n/zh.json | 7 +++ .../e2e/organization/organizations.cy.ts | 35 ++++++++++++++ e2e/cypress/support/api/orgs.ts | 2 +- e2e/package-lock.json | 45 ++++++++++++++--- e2e/package.json | 1 + 16 files changed, 186 insertions(+), 15 deletions(-) diff --git a/console/src/app/app.component.ts b/console/src/app/app.component.ts index 57d9c5d796..39e331c6bc 100644 --- a/console/src/app/app.component.ts +++ b/console/src/app/app.component.ts @@ -8,7 +8,7 @@ import { DomSanitizer } from '@angular/platform-browser'; import { ActivatedRoute, Router, RouterOutlet } from '@angular/router'; import { LangChangeEvent, TranslateService } from '@ngx-translate/core'; import { Observable, of, Subject } from 'rxjs'; -import { map, takeUntil } from 'rxjs/operators'; +import { filter, map, takeUntil } from 'rxjs/operators'; import { accountCard, adminLineAnimation, navAnimations, routeAnimations, toolbarAnimation } from './animations'; import { Org } from './proto/generated/zitadel/org_pb'; @@ -191,6 +191,11 @@ export class AppComponent implements OnDestroy { } }); + this.activatedRoute.queryParams.pipe(filter((params) => !!params.org)).subscribe((params) => { + const { org } = params; + this.authService.getActiveOrg(org); + }); + this.authenticationService.authenticationChanged.pipe(takeUntil(this.destroy$)).subscribe((authenticated) => { if (authenticated) { this.authService diff --git a/console/src/app/modules/name-dialog/name-dialog.component.html b/console/src/app/modules/name-dialog/name-dialog.component.html index 7582e10ebe..fe1f6782ea 100644 --- a/console/src/app/modules/name-dialog/name-dialog.component.html +++ b/console/src/app/modules/name-dialog/name-dialog.component.html @@ -5,7 +5,7 @@
{{ data.labelKey | translate }} - +
@@ -13,7 +13,7 @@ {{ 'ACTIONS.CLOSE' | translate }} -
diff --git a/console/src/app/modules/top-view/top-view.component.html b/console/src/app/modules/top-view/top-view.component.html index ab6b7f2a16..63e85e962d 100644 --- a/console/src/app/modules/top-view/top-view.component.html +++ b/console/src/app/modules/top-view/top-view.component.html @@ -7,7 +7,7 @@
-

{{ title }}

+

{{ title }}

- + + + { + if (name) { + this.updateOrg(name); + } + }); + } + + public updateOrg(name: string): void { + if (this.org) { + this.mgmtService + .updateOrg(name) + .then(() => { + this.toast.showInfo('ORG.TOAST.UPDATED', true); + if (this.org) { + this.org.name = name; + } + this.mgmtService + .getMyOrg() + .then((resp) => { + if (resp.org) { + this.org = resp.org; + this.auth.setActiveOrg(resp.org); + } + }) + .catch((error) => { + this.toast.showError(error); + }); + }) + .catch((error) => { + this.toast.showError(error); + }); + } + } } diff --git a/console/src/app/pages/orgs/org.module.ts b/console/src/app/pages/orgs/org.module.ts index a80c6b1854..ce1120c9e9 100644 --- a/console/src/app/pages/orgs/org.module.ts +++ b/console/src/app/pages/orgs/org.module.ts @@ -19,6 +19,7 @@ import { InfoSectionModule } from 'src/app/modules/info-section/info-section.mod import { InputModule } from 'src/app/modules/input/input.module'; import { MetaLayoutModule } from 'src/app/modules/meta-layout/meta-layout.module'; import { MetadataModule } from 'src/app/modules/metadata/metadata.module'; +import { NameDialogModule } from 'src/app/modules/name-dialog/name-dialog.module'; import { SettingsGridModule } from 'src/app/modules/settings-grid/settings-grid.module'; import { SharedModule } from 'src/app/modules/shared/shared.module'; import { TopViewModule } from 'src/app/modules/top-view/top-view.module'; @@ -52,6 +53,7 @@ import { OrgRoutingModule } from './org-routing.module'; WarnDialogModule, MemberCreateDialogModule, MatMenuModule, + NameDialogModule, ChangesModule, MatProgressSpinnerModule, MetadataModule, diff --git a/console/src/app/services/mgmt.service.ts b/console/src/app/services/mgmt.service.ts index 5b311576e2..ba54824f35 100644 --- a/console/src/app/services/mgmt.service.ts +++ b/console/src/app/services/mgmt.service.ts @@ -425,6 +425,8 @@ import { UpdateOrgIDPResponse, UpdateOrgMemberRequest, UpdateOrgMemberResponse, + UpdateOrgRequest, + UpdateOrgResponse, UpdateProjectGrantMemberRequest, UpdateProjectGrantMemberResponse, UpdateProjectGrantRequest, @@ -2353,6 +2355,12 @@ export class ManagementService { return this.grpcService.mgmt.updateApp(req, null).then((resp) => resp.toObject()); } + public updateOrg(name: string): Promise { + const req = new UpdateOrgRequest(); + req.setName(name); + return this.grpcService.mgmt.updateOrg(req, null).then((resp) => resp.toObject()); + } + public updateOIDCAppConfig(req: UpdateOIDCAppConfigRequest): Promise { return this.grpcService.mgmt.updateOIDCAppConfig(req, null).then((resp) => resp.toObject()); } diff --git a/console/src/assets/i18n/de.json b/console/src/assets/i18n/de.json index 9585e182fb..d72905592b 100644 --- a/console/src/assets/i18n/de.json +++ b/console/src/assets/i18n/de.json @@ -777,6 +777,12 @@ "ORGDETAIL_TITLE": "Gebe den Namen und die Domain für die neue Organisation ein.", "ORGDETAIL_TITLE_WITHOUT_DOMAIN": "Geben Sie den Namen der neuen Organisation ein.", "ORGDETAILUSER_TITLE": "Organisationsbesitzer hinzufügen", + "RENAME": { + "ACTION": "Umbenennen", + "TITLE": "Organisation umbenennen", + "DESCRIPTION": "Geben Sie den neuen Namen Ihrer Organisation an.", + "BTN": "Umbenennen" + }, "ORGDOMAIN": { "TITLE": "Verifikation der Domain der Organisation", "VERIFICATION": "Überprüfe den Besitz Deiner Domain, indem Du eine Bestätigungsdatei herunterlädst und unter der angegebenen URL speicherst, oder indem Du sie mit einem DNS-Eintrag verifizierst.", @@ -828,6 +834,7 @@ "DESCRIPTION": "Definiere hier die Benutzer, die Operationen auf Deinen Organisationen vornehmen dürfen." }, "TOAST": { + "UPDATED": "Organisation geändert", "DEACTIVATED": "Organisation deaktiviert.", "REACTIVATED": "Organisation reaktiviert.", "DOMAINADDED": "Domain hinzugefügt.", diff --git a/console/src/assets/i18n/en.json b/console/src/assets/i18n/en.json index 1691cc66fe..8155ea3fd9 100644 --- a/console/src/assets/i18n/en.json +++ b/console/src/assets/i18n/en.json @@ -777,6 +777,12 @@ "ORGDETAIL_TITLE": "Enter the name and domain of your new organization.", "ORGDETAIL_TITLE_WITHOUT_DOMAIN": "Enter the name of your new organization.", "ORGDETAILUSER_TITLE": "Configure Organization Owner", + "RENAME": { + "ACTION": "Rename", + "TITLE": "Rename Organization", + "DESCRIPTION": "Enter the new name for your organization", + "BTN": "Rename" + }, "ORGDOMAIN": { "TITLE": "Organization Domain Ownership Verification", "VERIFICATION": "To verify the ownership of your domain, you need to download a verification file and upload it at the provided URL listed below, or place a TXT Record DNS entry for the provided URL. To complete, click the button to verify.", @@ -828,6 +834,7 @@ "DESCRIPTION": "Define the users who can change your organizations preferences." }, "TOAST": { + "UPDATED": "Organization updated successfully.", "DEACTIVATED": "Organization deactivated.", "REACTIVATED": "Organization reactivated.", "DOMAINADDED": "Added domain.", diff --git a/console/src/assets/i18n/fr.json b/console/src/assets/i18n/fr.json index 6ea68a40e8..69a98f8d09 100644 --- a/console/src/assets/i18n/fr.json +++ b/console/src/assets/i18n/fr.json @@ -777,6 +777,12 @@ "ORGDETAIL_TITLE": "Saisissez le nom et le domaine de votre nouvelle organisation.", "ORGDETAIL_TITLE_WITHOUT_DOMAIN": "Saisissez le nom de votre nouvelle organisation.", "ORGDETAILUSER_TITLE": "Configurer le propriétaire de l'organisation", + "RENAME": { + "ACTION": "Renommer", + "TITLE": "Renommer l'organisation", + "DESCRIPTION": "Entrez le nouveau nom de votre organisation", + "BTN": "Renommer" + }, "ORGDOMAIN": { "TITLE": "Vérification de la propriété du domaine de l'organisation", "VERIFICATION": "Pour vérifier la propriété de votre domaine, vous devez télécharger un fichier de vérification et le charger à l'URL indiquée ci-dessous, ou placer une entrée DNS TXT Record pour l'URL indiquée. Pour terminer, cliquez sur le bouton de vérification.", @@ -828,6 +834,7 @@ "DESCRIPTION": "Définissez les utilisateurs qui peuvent modifier les préférences de votre organisation." }, "TOAST": { + "UPDATED": "L'organisation a été mise à jour", "DEACTIVATED": "Organisation désactivée.", "REACTIVATED": "Organisation réactivée.", "DOMAINADDED": "Domaine ajouté.", diff --git a/console/src/assets/i18n/it.json b/console/src/assets/i18n/it.json index 1541b0fa9d..cf32bf80ef 100644 --- a/console/src/assets/i18n/it.json +++ b/console/src/assets/i18n/it.json @@ -777,6 +777,12 @@ "ORGDETAIL_TITLE": "Inserisci il nome e il dominio della tua nuova organizzazione.", "ORGDETAIL_TITLE_WITHOUT_DOMAIN": "Inserisci il nome della tua nuova organizzazione.", "ORGDETAILUSER_TITLE": "Configurare il proprietario dell'organizzazione", + "RENAME": { + "ACTION": "Rinomina", + "TITLE": "Rinomina organizzazione", + "DESCRIPTION": "Inserisci il nuovo nome per la tua organizzazione", + "BTN": "Rinomina" + }, "ORGDOMAIN": { "TITLE": "Verificazione della propriet\u00e0 del dominio dell'organizzazione", "VERIFICATION": "Verifica la propriet\u00e0 del tuo dominio. \u00c8 necessario scaricare un file di verifica e caricarlo all'URL fornito elencato di seguito, o inserire una voce DNS TXT Record per l'URL fornito. Per completare, clicca sul pulsante di verifica.", @@ -828,6 +834,7 @@ "DESCRIPTION": "Definisci gli utenti che possono cambiare le preferenze delle tue organizzazioni." }, "TOAST": { + "UPDATED": "L'organizzazione es stata aggiornata.", "DEACTIVATED": "Organizzazione disattivata.", "REACTIVATED": "Organizzazione riattivata.", "DOMAINADDED": "Aggiunto dominio.", diff --git a/console/src/assets/i18n/zh.json b/console/src/assets/i18n/zh.json index 7f23ca8f4e..54392afe4c 100644 --- a/console/src/assets/i18n/zh.json +++ b/console/src/assets/i18n/zh.json @@ -777,6 +777,12 @@ "ORGDETAIL_TITLE": "输入新组织的名称和域名。", "ORGDETAIL_TITLE_WITHOUT_DOMAIN": "输入新组织的名称。", "ORGDETAILUSER_TITLE": "配置组织所有者", + "RENAME": { + "ACTION": "改名", + "TITLE": "重命名组织", + "DESCRIPTION": "输入组织的新名称", + "BTN": "改名" + }, "ORGDOMAIN": { "TITLE": "组织域所有权验证", "VERIFICATION": "要验证您对域的所有权,您需要下载验证文件并将其上传到下面列出的提供的 URL,或者为提供的域名添加一条类型为TXT的DNS解析记录。完成后请单击按钮进行验证。", @@ -828,6 +834,7 @@ "DESCRIPTION": "定义可以更改组织首选项的用户。" }, "TOAST": { + "UPDATED": "组织已更新", "DEACTIVATED": "组织已停用。", "REACTIVATED": "组织重新启用。", "DOMAINADDED": "域名已添加。", diff --git a/e2e/cypress/e2e/organization/organizations.cy.ts b/e2e/cypress/e2e/organization/organizations.cy.ts index a224b69a40..152da56659 100644 --- a/e2e/cypress/e2e/organization/organizations.cy.ts +++ b/e2e/cypress/e2e/organization/organizations.cy.ts @@ -1,4 +1,39 @@ +import { ensureOrgExists } from 'support/api/orgs'; +import { apiAuth } from '../../support/api/apiauth'; +import { v4 as uuidv4 } from 'uuid'; + +const orgPath = `/org`; + +const orgNameOnCreation = 'e2eorgrename'; +const testOrgNameChange = uuidv4(); + describe('organizations', () => { + describe('rename', () => { + beforeEach(() => { + apiAuth() + .as('api') + .then((api) => { + ensureOrgExists(api, orgNameOnCreation) + .as('newOrgId') + .then((newOrgId) => { + cy.visit(`${orgPath}?org=${newOrgId}`).as('orgsite'); + }); + }); + }); + + it('should rename the organization', () => { + cy.get('[data-e2e="actions"]').click(); + cy.get('[data-e2e="rename"]', { timeout: 1000 }).should('be.visible').click(); + + cy.get('[data-e2e="name"]').focus().clear().type(testOrgNameChange); + cy.get('[data-e2e="dialog-submit"]').click(); + cy.get('.data-e2e-success'); + cy.shouldNotExist({ selector: '.data-e2e-failure' }); + cy.visit(orgPath); + cy.get('[data-e2e="top-view-title"').should('contain', testOrgNameChange); + }); + }); + it('should add an organization with the personal account as org owner'); describe('changing the current organization', () => { it('should update displayed organization details'); diff --git a/e2e/cypress/support/api/orgs.ts b/e2e/cypress/support/api/orgs.ts index 18c8be6924..e41f285112 100644 --- a/e2e/cypress/support/api/orgs.ts +++ b/e2e/cypress/support/api/orgs.ts @@ -18,7 +18,7 @@ export function ensureOrgExists(api: API, name: string): Cypress.Chainable `${api.mgmtBaseURL}/orgs`, 'POST', { name: name }, - (org: any) => org?.name === name, + (org) => org?.name === name, (res) => res.id, ); } diff --git a/e2e/package-lock.json b/e2e/package-lock.json index 5e3fb7d41d..a189901a39 100644 --- a/e2e/package-lock.json +++ b/e2e/package-lock.json @@ -14,6 +14,7 @@ "mochawesome": "^7.1.3", "prettier": "^2.7.1", "typescript": "^4.8.4", + "uuid": "^9.0.0", "wait-on": "^6.0.1" }, "devDependencies": { @@ -60,6 +61,15 @@ "node": ">= 6" } }, + "node_modules/@cypress/request/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/@cypress/xvfb": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz", @@ -1945,6 +1955,14 @@ "node": ">=12" } }, + "node_modules/mochawesome/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -2594,9 +2612,9 @@ } }, "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", "bin": { "uuid": "dist/bin/uuid" } @@ -2794,6 +2812,14 @@ "tough-cookie": "~2.5.0", "tunnel-agent": "^0.6.0", "uuid": "^8.3.2" + }, + "dependencies": { + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true + } } }, "@cypress/xvfb": { @@ -4174,6 +4200,13 @@ "mochawesome-report-generator": "^6.2.0", "strip-ansi": "^6.0.1", "uuid": "^8.3.2" + }, + "dependencies": { + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + } } }, "mochawesome-report-generator": { @@ -4690,9 +4723,9 @@ "dev": true }, "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==" }, "validator": { "version": "13.7.0", diff --git a/e2e/package.json b/e2e/package.json index c429897a24..61f7cdca2f 100644 --- a/e2e/package.json +++ b/e2e/package.json @@ -17,6 +17,7 @@ "mochawesome": "^7.1.3", "prettier": "^2.7.1", "typescript": "^4.8.4", + "uuid": "^9.0.0", "wait-on": "^6.0.1" }, "devDependencies": {