- @if (grantedProject?.details?.changeDate; as changeDate) {
+ @if (grantedProject.details?.changeDate; as changeDate) {
{{ changeDate | timestampToDate | localizedDate: 'dd. MMMM yyyy, HH:mm' }}
{{ 'APP.PAGES.STATE' | translate }}
- @if (app?.state) {
+ @if (app.state) {
}
- @if (app?.apiConfig?.authMethodType; as authMethodType) {
+ @if (app.apiConfig?.authMethodType; as authMethodType) {
{{ 'APP.AUTHMETHOD' | translate }}
@@ -294,7 +294,7 @@
}
- @if (app?.oidcConfig?.authMethodType; as authMethodType) {
+ @if (app.oidcConfig?.authMethodType; as authMethodType) {
{{ 'APP.AUTHMETHOD' | translate }}
@@ -304,13 +304,13 @@
}
{{ 'APP.PAGES.ID' | translate }}
- @if (app?.id) {
+ @if (app.id) {
{{ app.id }}
}
{{ 'APP.PAGES.DATECREATED' | translate }}
- @if (app?.details?.creationDate; as creationDate) {
+ @if (app.details?.creationDate; as creationDate) {
{{ creationDate | timestampToDate | localizedDate: 'dd. MMMM yyyy, HH:mm' }}
@@ -318,46 +318,44 @@
{{ 'APP.PAGES.DATECHANGED' | translate }}
- @if (app?.details?.changeDate; as changeDate) {
+ @if (app.details?.changeDate; as changeDate) {
{{ changeDate | timestampToDate | localizedDate: 'dd. MMMM yyyy, HH:mm' }}
}
- @if (app) {
-
-
{{ 'APP.OIDC.INFO.CLIENTID' | translate }}
- @if (app.oidcConfig?.clientId) {
-
- @if (app.oidcConfig?.clientId; as clientId) {
-
- }
-
- }
- @if (app.apiConfig?.clientId) {
-
- @if (app.apiConfig?.clientId; as clientId) {
-
- }
-
- }
-
- }
+
+
{{ 'APP.OIDC.INFO.CLIENTID' | translate }}
+ @if (app.oidcConfig?.clientId) {
+
+ @if (app.oidcConfig?.clientId; as clientId) {
+
+ }
+
+ }
+ @if (app.apiConfig?.clientId) {
+
+ @if (app.apiConfig?.clientId; as clientId) {
+
+ }
+
+ }
+
}
diff --git a/console/src/app/modules/keyboard-shortcuts/keyboard-shortcuts.component.scss b/console/src/app/modules/keyboard-shortcuts/keyboard-shortcuts.component.scss
index 1df9a9d57..b7254b1c3 100644
--- a/console/src/app/modules/keyboard-shortcuts/keyboard-shortcuts.component.scss
+++ b/console/src/app/modules/keyboard-shortcuts/keyboard-shortcuts.component.scss
@@ -104,7 +104,7 @@
}
.keyboard-shortcuts-group {
- $border-color: if($is-dark-theme, rgba(#8795a1, 0.2), rgba(#8795a1, 0.2));
+ $border-color: if(sass($is-dark-theme): rgba(#8795a1, 0.2) ; else: rgba(#8795a1, 0.2));
border: 1px solid $border-color;
background-color: $card-background-color;
@@ -128,7 +128,7 @@
.keyboard-shortcuts-action-key {
.keyboard-shortcuts-key-overlay {
- background: if($is-dark-theme, #fff, #000);
+ background: if(sass($is-dark-theme): #fff; else: #000);
}
}
}
diff --git a/console/src/app/modules/label/label.component.scss b/console/src/app/modules/label/label.component.scss
index c116b38f3..e6e50bdbf 100644
--- a/console/src/app/modules/label/label.component.scss
+++ b/console/src/app/modules/label/label.component.scss
@@ -26,7 +26,7 @@
.cnsl-form-field-disabled {
.cnsl-label-wrapper {
- color: if($is-dark-theme, #ffffff80, #00000061);
+ color: if(sass($is-dark-theme): #ffffff80; else: #00000061);
}
}
diff --git a/console/src/app/modules/nav-toggle/nav-toggle.component.scss b/console/src/app/modules/nav-toggle/nav-toggle.component.scss
index d69e6c497..5482347f4 100644
--- a/console/src/app/modules/nav-toggle/nav-toggle.component.scss
+++ b/console/src/app/modules/nav-toggle/nav-toggle.component.scss
@@ -51,7 +51,7 @@
padding: 2px;
margin: -2px -9px -2px 8px;
margin-left: 6px;
- background-color: if($is-dark-theme, #ffffff20, #00000020);
+ background-color: if(sass($is-dark-theme): #ffffff20; else: #00000020);
line-height: 18px;
font-size: 11px;
transition: background 0.2s ease;
@@ -69,7 +69,7 @@
}
&:hover {
- background: if($is-dark-theme, #ffffff40, #00000010);
+ background: if(sass($is-dark-theme): #ffffff40; else: #00000010);
}
&.active {
@@ -78,7 +78,7 @@
.c_label {
.count {
- background-color: if($is-dark-theme, #00000020, #ffffff20);
+ background-color: if(sass($is-dark-theme): #00000020; else: #ffffff20);
}
}
}
diff --git a/console/src/app/modules/nav/nav.component.scss b/console/src/app/modules/nav/nav.component.scss
index 18a809b0a..345b620d0 100644
--- a/console/src/app/modules/nav/nav.component.scss
+++ b/console/src/app/modules/nav/nav.component.scss
@@ -82,7 +82,7 @@
padding: 2px;
margin: -2px -9px -2px 8px;
margin-left: 6px;
- background-color: if($is-dark-theme, #ffffff20, #00000020);
+ background-color: if(sass($is-dark-theme): #ffffff20; else: #00000020);
line-height: 18px;
font-size: 11px;
transition: background 0.2s ease;
@@ -100,7 +100,7 @@
}
&:hover {
- background: if($is-dark-theme, #ffffff40, #00000010);
+ background: if(sass($is-dark-theme): #ffffff40; else: #00000010);
}
&.active {
@@ -110,7 +110,7 @@
.c_label {
.count {
display: inline-block;
- background-color: if($is-dark-theme, #00000020, #ffffff20);
+ background-color: if(sass($is-dark-theme): #00000020; else: #ffffff20);
}
}
}
@@ -136,7 +136,7 @@
transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
.slash {
- color: if($is-dark-theme, #525454, #d1d5d9);
+ color: if(sass($is-dark-theme): #525454; else: #d1d5d9);
}
.org-button {
@@ -185,7 +185,7 @@
margin-right: 0.5rem;
width: 100px;
min-width: 50px;
- background: if($is-dark-theme, #ffffff20, #00000010);
+ background: if(sass($is-dark-theme): #ffffff20; else: #00000010);
border: none;
padding: 2px;
border-radius: 50vw;
@@ -193,7 +193,7 @@
display: flex;
&:hover {
- background: if($is-dark-theme, #ffffff, $primary-color);
+ background: if(sass($is-dark-theme): #ffffff; else: $primary-color);
transition: background ease 0.15s;
}
@@ -227,7 +227,7 @@
right: 0;
bottom: 0;
left: 0;
- background: if($is-dark-theme, #fff, #000);
+ background: if(sass($is-dark-theme): #fff; else: #000);
opacity: 0.15;
border-radius: 4px;
}
diff --git a/console/src/app/modules/onboarding-card/onboarding-card.component.scss b/console/src/app/modules/onboarding-card/onboarding-card.component.scss
index b70226075..f740b04ca 100644
--- a/console/src/app/modules/onboarding-card/onboarding-card.component.scss
+++ b/console/src/app/modules/onboarding-card/onboarding-card.component.scss
@@ -70,7 +70,7 @@
width: 1.5rem;
border-radius: 50vw;
margin-right: 1rem;
- background-color: if($is-dark-theme, map-get($background, state), #e4e7e4);
+ background-color: if(sass($is-dark-theme): map-get($background, state) ; else: #e4e7e4);
box-shadow: 0 0 3px #0000001a;
border: 1px solid rgba(#8795a1, 0.2);
diff --git a/console/src/app/modules/onboarding/onboarding.component.scss b/console/src/app/modules/onboarding/onboarding.component.scss
index ac35ea6d0..4c1a92a26 100644
--- a/console/src/app/modules/onboarding/onboarding.component.scss
+++ b/console/src/app/modules/onboarding/onboarding.component.scss
@@ -13,8 +13,8 @@
$list-background-color: map-get($background, 300);
$card-background-color: map-get($background, cards);
- $border-color: if($is-dark-theme, rgba(#8795a1, 0.2), rgba(#8795a1, 0.2));
- $border-selected-color: if($is-dark-theme, #fff, #000);
+ $border-color: if(sass($is-dark-theme): rgba(#8795a1, 0.2) ; else: rgba(#8795a1, 0.2));
+ $border-selected-color: if(sass($is-dark-theme): #fff; else: #000);
.onboarding-header {
display: flex;
@@ -141,7 +141,7 @@
width: 1.5rem;
border-radius: 50vw;
margin-right: 1rem;
- background-color: if($is-dark-theme, map-get($background, state), #e4e7e4);
+ background-color: if(sass($is-dark-theme): map-get($background, state) ; else: #e4e7e4);
box-shadow: 0 0 3px #0000001a;
border: 1px solid rgba(#8795a1, 0.2);
diff --git a/console/src/app/modules/policies/idp-settings/idp-settings.component.scss b/console/src/app/modules/policies/idp-settings/idp-settings.component.scss
index c9a5d11e8..61316ff02 100644
--- a/console/src/app/modules/policies/idp-settings/idp-settings.component.scss
+++ b/console/src/app/modules/policies/idp-settings/idp-settings.component.scss
@@ -87,11 +87,11 @@
}
&.dark {
- display: if($is-dark-theme, block, none);
+ display: if(sass($is-dark-theme): block; else: none);
}
&.light {
- display: if($is-dark-theme, none, block);
+ display: if(sass($is-dark-theme): none; else: block);
}
}
diff --git a/console/src/app/modules/policies/notification-smtp-provider/notification-smtp-provider.component.scss b/console/src/app/modules/policies/notification-smtp-provider/notification-smtp-provider.component.scss
index 55c44e74b..38795bee8 100644
--- a/console/src/app/modules/policies/notification-smtp-provider/notification-smtp-provider.component.scss
+++ b/console/src/app/modules/policies/notification-smtp-provider/notification-smtp-provider.component.scss
@@ -69,11 +69,11 @@
}
&.dark {
- display: if($is-dark-theme, block, none);
+ display: if(sass($is-dark-theme): block; else: none);
}
&.light {
- display: if($is-dark-theme, none, block);
+ display: if(sass($is-dark-theme): none; else: block);
}
}
diff --git a/console/src/app/modules/policies/private-labeling-policy/preview/preview.component.scss b/console/src/app/modules/policies/private-labeling-policy/preview/preview.component.scss
index 1970b00a4..b8d215711 100644
--- a/console/src/app/modules/policies/private-labeling-policy/preview/preview.component.scss
+++ b/console/src/app/modules/policies/private-labeling-policy/preview/preview.component.scss
@@ -2,7 +2,7 @@
@use '../../../label/label.component.scss' as label;
@mixin preview-theme($show-dark) {
- $theme: if($show-dark, $caos-dark-app-theme, $caos-light-app-theme);
+ $theme: if(sass($show-dark): $caos-dark-app-theme; else: $caos-light-app-theme);
@include input.input-theme($theme);
@include label.cnsl-label-theme($theme);
diff --git a/console/src/app/modules/policies/private-labeling-policy/private-labeling-policy.component.scss b/console/src/app/modules/policies/private-labeling-policy/private-labeling-policy.component.scss
index 6713b223e..987245a92 100644
--- a/console/src/app/modules/policies/private-labeling-policy/private-labeling-policy.component.scss
+++ b/console/src/app/modules/policies/private-labeling-policy/private-labeling-policy.component.scss
@@ -7,8 +7,8 @@
$is-dark-theme: map.get($theme, is-dark);
$background: map.get($theme, background);
$foreground: map.get($theme, foreground);
- $p-border-color: if($is-dark-theme, rgba(#8795a1, 0.2), rgba(#8795a1, 0.2));
- $border-color: if($is-dark-theme, rgba(#8795a1, 0.2), rgba(#8795a1, 0.2));
+ $p-border-color: if(sass($is-dark-theme): rgba(#8795a1, 0.2) ; else: rgba(#8795a1, 0.2));
+ $border-color: if(sass($is-dark-theme): rgba(#8795a1, 0.2) ; else: rgba(#8795a1, 0.2));
.privatelabeling-policy {
.header {
diff --git a/console/src/app/modules/project-role-chip/project-role-chip.component.scss b/console/src/app/modules/project-role-chip/project-role-chip.component.scss
index ca030e8d6..ec3372c5c 100644
--- a/console/src/app/modules/project-role-chip/project-role-chip.component.scss
+++ b/console/src/app/modules/project-role-chip/project-role-chip.component.scss
@@ -13,8 +13,8 @@
$list-background-color: map-get($background, 300);
$card-background-color: map-get($background, cards);
- $border-color: if($is-dark-theme, rgba(#8795a1, 0.2), rgba(#8795a1, 0.2));
- $border-selected-color: if($is-dark-theme, #fff, #000);
+ $border-color: if(sass($is-dark-theme): rgba(#8795a1, 0.2) ; else: rgba(#8795a1, 0.2));
+ $border-selected-color: if(sass($is-dark-theme): #fff; else: #000);
.project-role-chip {
display: flex;
diff --git a/console/src/app/modules/project-roles-table/project-roles-table.component.html b/console/src/app/modules/project-roles-table/project-roles-table.component.html
index 1e2ae7e21..66dd540a9 100644
--- a/console/src/app/modules/project-roles-table/project-roles-table.component.html
+++ b/console/src/app/modules/project-roles-table/project-roles-table.component.html
@@ -118,7 +118,7 @@
- @if ((dataSource.loading$ | async) === false && !dataSource?.totalResult) {
+ @if ((dataSource.loading$ | async) === false && !dataSource.totalResult) {
{{ 'PROJECT.ROLE.EMPTY' | translate }}
diff --git a/console/src/app/modules/providers/providers.scss b/console/src/app/modules/providers/providers.scss
index 7baffada8..8964d5277 100644
--- a/console/src/app/modules/providers/providers.scss
+++ b/console/src/app/modules/providers/providers.scss
@@ -25,11 +25,11 @@
}
&.dark {
- display: if($is-dark-theme, block, none);
+ display: if(sass($is-dark-theme): block; else: none);
}
&.light {
- display: if($is-dark-theme, none, block);
+ display: if(sass($is-dark-theme): none; else: block);
}
}
diff --git a/console/src/app/modules/search-org-autocomplete/search-org-autocomplete.component.html b/console/src/app/modules/search-org-autocomplete/search-org-autocomplete.component.html
index 6c9e1378d..348ceb065 100644
--- a/console/src/app/modules/search-org-autocomplete/search-org-autocomplete.component.html
+++ b/console/src/app/modules/search-org-autocomplete/search-org-autocomplete.component.html
@@ -1,36 +1,57 @@
diff --git a/console/src/app/modules/search-org-autocomplete/search-org-autocomplete.component.scss b/console/src/app/modules/search-org-autocomplete/search-org-autocomplete.component.scss
deleted file mode 100644
index dbf3f4af1..000000000
--- a/console/src/app/modules/search-org-autocomplete/search-org-autocomplete.component.scss
+++ /dev/null
@@ -1,38 +0,0 @@
-.full-width {
- width: 100%;
-}
-
-input {
- max-width: 500px;
-}
-
-.org-option {
- display: flex;
- align-items: center;
-
- .org-option-column {
- display: flex;
- flex-direction: column;
- align-items: flex-start;
- justify-content: center;
- width: 100%;
-
- span {
- line-height: normal;
- }
-
- .fill-space {
- flex: 1;
- }
-
- .smaller {
- font-size: 13px;
- }
- }
-}
-
-.org-autocomplete-target-desc {
- font-size: 14px;
- display: block;
- margin-top: 0.5rem;
-}
diff --git a/console/src/app/modules/search-org-autocomplete/search-org-autocomplete.component.spec.ts b/console/src/app/modules/search-org-autocomplete/search-org-autocomplete.component.spec.ts
deleted file mode 100644
index 03a2bda40..000000000
--- a/console/src/app/modules/search-org-autocomplete/search-org-autocomplete.component.spec.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
-
-import { SearchOrgAutocompleteComponent } from './search-org-autocomplete.component';
-
-describe('SearchOrgComponent', () => {
- let component: SearchOrgAutocompleteComponent;
- let fixture: ComponentFixture
;
-
- beforeEach(waitForAsync(() => {
- TestBed.configureTestingModule({
- declarations: [SearchOrgAutocompleteComponent],
- }).compileComponents();
- }));
-
- beforeEach(() => {
- fixture = TestBed.createComponent(SearchOrgAutocompleteComponent);
- component = fixture.componentInstance;
- fixture.detectChanges();
- });
-
- it('should create', () => {
- expect(component).toBeTruthy();
- });
-});
diff --git a/console/src/app/modules/search-org-autocomplete/search-org-autocomplete.component.ts b/console/src/app/modules/search-org-autocomplete/search-org-autocomplete.component.ts
index d7dbc6128..45ace06ff 100644
--- a/console/src/app/modules/search-org-autocomplete/search-org-autocomplete.component.ts
+++ b/console/src/app/modules/search-org-autocomplete/search-org-autocomplete.component.ts
@@ -1,85 +1,135 @@
-import { Component, EventEmitter, OnDestroy, OnInit, Output, ViewChild } from '@angular/core';
-import { UntypedFormControl } from '@angular/forms';
-import { MatAutocomplete, MatAutocompleteSelectedEvent } from '@angular/material/autocomplete';
-import { debounceTime, from, map, Subject, switchMap, takeUntil, tap } from 'rxjs';
-import { TextQueryMethod } from 'src/app/proto/generated/zitadel/object_pb';
-import { Org, OrgNameQuery, OrgQuery, OrgState, OrgStateQuery } from 'src/app/proto/generated/zitadel/org_pb';
-import { AuthenticationService } from 'src/app/services/authentication.service';
-import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
+import { ChangeDetectionStrategy, Component, effect, inject, output, signal } from '@angular/core';
+import { NewAuthService } from 'src/app/services/new-auth.service';
+import { injectInfiniteQuery, keepPreviousData } from '@tanstack/angular-query-experimental';
+import { UserService } from 'src/app/services/user.service';
+import { AuthService, ListMyProjectOrgsRequestSchema } from '@zitadel/proto/zitadel/auth_pb';
+import { MatAutocompleteModule } from '@angular/material/autocomplete';
+import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms';
+import { MatInputModule } from '@angular/material/input';
+import { InputModule } from '../input/input.module';
+import { TranslatePipe } from '@ngx-translate/core';
+import { TextQueryMethod } from '@zitadel/proto/zitadel/object_pb';
+import { ScrollingModule } from '@angular/cdk/scrolling';
+import { Org, OrgFieldName, OrgState } from '@zitadel/proto/zitadel/org_pb';
+import { MessageInitShape } from '@bufbuild/protobuf';
+import { MatTooltip } from '@angular/material/tooltip';
+import { requiredValidator } from '../form-field/validators/validators';
+import { ScrollableDirective } from 'src/app/directives/scrollable/scrollable.directive';
+import { toObservable, toSignal } from '@angular/core/rxjs-interop';
+import { debounceTime } from 'rxjs';
+import { MatProgressSpinner } from '@angular/material/progress-spinner';
+import { ToastService } from 'src/app/services/toast.service';
@Component({
selector: 'cnsl-search-org-autocomplete',
templateUrl: './search-org-autocomplete.component.html',
- styleUrls: ['./search-org-autocomplete.component.scss'],
- standalone: false,
+ standalone: true,
+ changeDetection: ChangeDetectionStrategy.OnPush,
+ imports: [
+ ScrollingModule,
+ MatInputModule,
+ MatAutocompleteModule,
+ ReactiveFormsModule,
+ InputModule,
+ TranslatePipe,
+ FormsModule,
+ MatTooltip,
+ ScrollableDirective,
+ MatProgressSpinner,
+ ],
})
-export class SearchOrgAutocompleteComponent implements OnInit, OnDestroy {
- public myControl: UntypedFormControl = new UntypedFormControl();
- public filteredOrgs: Array = [];
- public isLoading: boolean = false;
- @ViewChild('auto') public matAutocomplete!: MatAutocomplete;
- @Output() public selectionChanged: EventEmitter = new EventEmitter();
+export class SearchOrgAutocompleteComponent {
+ public readonly selectionChanged = output();
- private unsubscribed$: Subject = new Subject();
- constructor(
- public authService: AuthenticationService,
- private auth: GrpcAuthService,
- ) {
- this.myControl.valueChanges
- .pipe(
- takeUntil(this.unsubscribed$),
- debounceTime(200),
- tap(() => (this.isLoading = true)),
- switchMap((value) => {
- const stateQuery = new OrgQuery();
- const orgStateQuery = new OrgStateQuery();
- orgStateQuery.setState(OrgState.ORG_STATE_ACTIVE);
- stateQuery.setStateQuery(orgStateQuery);
+ protected readonly searchControl = new FormControl(null, { validators: [requiredValidator] });
+ protected readonly searchSignal = signal('');
+ protected readonly debouncedSearchSignal = toSignal(toObservable(this.searchSignal).pipe(debounceTime(250)), {
+ initialValue: this.searchSignal(),
+ });
- let queries: OrgQuery[] = [stateQuery];
+ private readonly authService = inject(NewAuthService);
+ private readonly userService = inject(UserService);
- if (value) {
- const nameQuery = new OrgQuery();
- const orgNameQuery = new OrgNameQuery();
- orgNameQuery.setName(value);
- orgNameQuery.setMethod(TextQueryMethod.TEXT_QUERY_METHOD_CONTAINS_IGNORE_CASE);
- nameQuery.setNameQuery(orgNameQuery);
- queries = [stateQuery, nameQuery];
- }
+ protected readonly query = injectInfiniteQuery(() => {
+ const search = this.debouncedSearchSignal();
- return from(this.auth.listMyProjectOrgs(undefined, 0, queries)).pipe(
- map((resp) => {
- return resp.resultList.sort((left, right) => left.name.localeCompare(right.name));
- }),
- );
- }),
- )
- .subscribe((returnValue) => {
- this.isLoading = false;
- this.filteredOrgs = returnValue;
- });
- }
+ const stateQuery = [
+ {
+ query: {
+ case: 'stateQuery',
+ value: {
+ state: OrgState.ACTIVE,
+ },
+ },
+ },
+ ] satisfies MessageInitShape['queries'];
- public ngOnInit(): void {
- const query = new OrgQuery();
- const orgStateQuery = new OrgStateQuery();
- orgStateQuery.setState(OrgState.ORG_STATE_ACTIVE);
- query.setStateQuery(orgStateQuery);
+ return {
+ queryKey: [this.userService.userId(), AuthService.name, AuthService.method.listMyProjectOrgs.name, 'infinite', search],
+ placeholderData: keepPreviousData,
+ queryFn: async ({ pageParam, signal }) =>
+ this.authService.listMyProjectOrgs(
+ {
+ query: {
+ limit: 20,
+ offset: BigInt(pageParam.offset),
+ },
+ sortingColumn: OrgFieldName.NAME,
+ queries: search
+ ? [
+ ...stateQuery,
+ {
+ query: {
+ case: 'nameQuery',
+ value: {
+ name: search,
+ method: TextQueryMethod.CONTAINS_IGNORE_CASE,
+ },
+ },
+ },
+ ]
+ : stateQuery,
+ },
+ signal,
+ ),
+ initialPageParam: {
+ offset: 0,
+ },
+ getNextPageParam: (lastPage, allPages, { offset }) => {
+ const nextPageParam = { offset: offset + lastPage.result.length };
+ const loadedCount = allPages.reduce((count, page) => count + page.result.length, 0);
- this.auth.listMyProjectOrgs(undefined, 0, [query]).then((orgs) => {
- this.filteredOrgs = orgs.resultList;
+ if (loadedCount < lastPage.details!.totalResult) {
+ return nextPageParam;
+ }
+
+ return undefined;
+ },
+ };
+ });
+
+ // used to only open matTooltip if the text gets truncated
+ protected readonly showTooltip = signal(false);
+
+ constructor() {
+ const toastService = inject(ToastService);
+ effect(() => {
+ const error = this.query.error();
+ if (error) {
+ toastService.showError(error);
+ }
});
}
- public ngOnDestroy(): void {
- this.unsubscribed$.next();
+ protected async onScroll(position: 'bottom' | 'top') {
+ if (this.query.isFetchingNextPage() || !this.query.hasNextPage() || position === 'top') {
+ return;
+ }
+
+ await this.query.fetchNextPage();
}
- public displayFn(org?: Org.AsObject): string {
- return org ? `${org.name}` : '';
- }
-
- public selected(event: MatAutocompleteSelectedEvent): void {
- this.selectionChanged.emit(event.option.value);
+ protected displayOrg(org: Org | null) {
+ return org?.name ?? '';
}
}
diff --git a/console/src/app/modules/search-org-autocomplete/search-org-autocomplete.module.ts b/console/src/app/modules/search-org-autocomplete/search-org-autocomplete.module.ts
deleted file mode 100644
index 26bf94292..000000000
--- a/console/src/app/modules/search-org-autocomplete/search-org-autocomplete.module.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import { CommonModule } from '@angular/common';
-import { NgModule } from '@angular/core';
-import { FormsModule, ReactiveFormsModule } from '@angular/forms';
-import { MatAutocompleteModule } from '@angular/material/autocomplete';
-import { MatButtonModule } from '@angular/material/button';
-import { MatChipsModule } from '@angular/material/chips';
-import { MatIconModule } from '@angular/material/icon';
-import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
-import { MatSelectModule } from '@angular/material/select';
-import { TranslateModule } from '@ngx-translate/core';
-import { InputModule } from 'src/app/modules/input/input.module';
-
-import { SearchOrgAutocompleteComponent } from './search-org-autocomplete.component';
-
-@NgModule({
- declarations: [SearchOrgAutocompleteComponent],
- imports: [
- CommonModule,
- MatAutocompleteModule,
- MatChipsModule,
- MatButtonModule,
- InputModule,
- MatIconModule,
- ReactiveFormsModule,
- MatProgressSpinnerModule,
- FormsModule,
- TranslateModule,
- MatSelectModule,
- ],
- exports: [SearchOrgAutocompleteComponent],
-})
-export class SearchOrgAutocompleteModule {}
diff --git a/console/src/app/modules/search-user-autocomplete/search-user-autocomplete.component.scss b/console/src/app/modules/search-user-autocomplete/search-user-autocomplete.component.scss
index 4f2b91883..aff81f7ad 100644
--- a/console/src/app/modules/search-user-autocomplete/search-user-autocomplete.component.scss
+++ b/console/src/app/modules/search-user-autocomplete/search-user-autocomplete.component.scss
@@ -9,8 +9,8 @@
$secondary-text: map-get($foreground, secondary-text);
$is-dark-theme: map-get($theme, is-dark);
- $link-hover-color: if($is-dark-theme, map-get($primary, 200), $primary-color);
- $link-color: if($is-dark-theme, $lighter-primary-color, $primary-color);
+ $link-hover-color: if(sass($is-dark-theme): map-get($primary, 200) ; else: $primary-color);
+ $link-color: if(sass($is-dark-theme): $lighter-primary-color; else: $primary-color);
.user-autocomplete-found {
margin: 0.5rem 0;
diff --git a/console/src/app/modules/shortcuts/shortcuts.component.scss b/console/src/app/modules/shortcuts/shortcuts.component.scss
index 5dce51813..4243880d8 100644
--- a/console/src/app/modules/shortcuts/shortcuts.component.scss
+++ b/console/src/app/modules/shortcuts/shortcuts.component.scss
@@ -13,8 +13,8 @@
$list-background-color: map-get($background, 300);
$card-background-color: map-get($background, cards);
- $border-color: if($is-dark-theme, rgba(#8795a1, 0.2), rgba(#8795a1, 0.2));
- $border-selected-color: if($is-dark-theme, #fff, #000);
+ $border-color: if(sass($is-dark-theme): rgba(#8795a1, 0.2) ; else: rgba(#8795a1, 0.2));
+ $border-selected-color: if(sass($is-dark-theme): #fff; else: #000);
.shortcut-container {
width: 100%;
diff --git a/console/src/app/modules/sidenav/sidenav.component.scss b/console/src/app/modules/sidenav/sidenav.component.scss
index bb55a6999..78a0ade17 100644
--- a/console/src/app/modules/sidenav/sidenav.component.scss
+++ b/console/src/app/modules/sidenav/sidenav.component.scss
@@ -32,12 +32,12 @@
font-size: 11px;
letter-spacing: 0.05em;
text-transform: uppercase;
- color: if($is-dark-theme, #ffffff60, #00000060);
+ color: if(sass($is-dark-theme): #ffffff60; else: #00000060);
margin-top: 1rem;
font-weight: 600;
margin-bottom: 0.5rem;
padding-top: 1rem;
- border-top: 1px solid if($is-dark-theme, rgba(#8795a1, 0.2), rgba(#8795a1, 0.2));
+ border-top: 1px solid if(sass($is-dark-theme): rgba(#8795a1, 0.2) ; else: rgba(#8795a1, 0.2));
&:nth-child(2) {
border-top: none;
diff --git a/console/src/app/modules/smtp-table/smtp-table.component.html b/console/src/app/modules/smtp-table/smtp-table.component.html
index 912d0f301..14df27d32 100644
--- a/console/src/app/modules/smtp-table/smtp-table.component.html
+++ b/console/src/app/modules/smtp-table/smtp-table.component.html
@@ -131,7 +131,7 @@
- @if ((loading$ | async) === false && !dataSource?.data?.length) {
+ @if ((loading$ | async) === false && !dataSource.data.length) {
- @if ((dataSource.loading$ | async) === false && !dataSource?.totalResult) {
+ @if ((dataSource.loading$ | async) === false && !dataSource.totalResult) {
{{ 'GRANTS.EMPTY' | translate }}
diff --git a/console/src/app/pages/home/home.component.scss b/console/src/app/pages/home/home.component.scss
index eafcbcdd5..96ed721cc 100644
--- a/console/src/app/pages/home/home.component.scss
+++ b/console/src/app/pages/home/home.component.scss
@@ -13,8 +13,8 @@
$list-background-color: map-get($background, 300);
$card-background-color: map-get($background, cards);
- $border-color: if($is-dark-theme, rgba(#8795a1, 0.2), rgba(#8795a1, 0.2));
- $border-selected-color: if($is-dark-theme, #fff, #000);
+ $border-color: if(sass($is-dark-theme): rgba(#8795a1, 0.2) ; else: rgba(#8795a1, 0.2));
+ $border-selected-color: if(sass($is-dark-theme): #fff; else: #000);
.home-title {
font-size: 2rem;
diff --git a/console/src/app/pages/org-actions/actions.component.html b/console/src/app/pages/org-actions/actions.component.html
index 20cb8a7b6..4eaeb53e7 100644
--- a/console/src/app/pages/org-actions/actions.component.html
+++ b/console/src/app/pages/org-actions/actions.component.html
@@ -50,7 +50,7 @@
{{ flow.type?.name?.localizedMessage }}
- @if (flow.type && (flow.triggerActionsList?.length ?? 0) > 0) {
+ @if (flow.type && flow.triggerActionsList.length > 0) {
-
+
@for (action of trigger.actionsList; track action) {
diff --git a/console/src/app/pages/org-actions/actions.component.ts b/console/src/app/pages/org-actions/actions.component.ts
index 937e1a214..420a06325 100644
--- a/console/src/app/pages/org-actions/actions.component.ts
+++ b/console/src/app/pages/org-actions/actions.component.ts
@@ -21,7 +21,7 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
standalone: false,
})
export class ActionsComponent {
- protected flow!: Flow.AsObject;
+ protected flow?: Flow.AsObject;
protected typeControl: UntypedFormControl = new UntypedFormControl();
@@ -124,23 +124,23 @@ export class ActionsComponent {
});
}
- drop(triggerActionsListIndex: number, array: any[], event: CdkDragDrop
) {
+ drop(flow: Flow.AsObject, triggerActionsListIndex: number, array: any[], event: CdkDragDrop) {
moveItemInArray(array, event.previousIndex, event.currentIndex);
- this.saveFlow(triggerActionsListIndex);
+ this.saveFlow(flow, triggerActionsListIndex);
}
- saveFlow(index: number) {
+ saveFlow(flow: Flow.AsObject, index: number) {
if (
- this.flow.type &&
- this.flow.triggerActionsList &&
- this.flow.triggerActionsList[index] &&
- this.flow.triggerActionsList[index]?.triggerType
+ flow.type &&
+ flow.triggerActionsList &&
+ flow.triggerActionsList[index] &&
+ flow.triggerActionsList[index]?.triggerType
) {
this.mgmtService
.setTriggerActions(
- this.flow.triggerActionsList[index].actionsList.map((action) => action.id),
- this.flow.type.id,
- this.flow.triggerActionsList[index].triggerType?.id ?? '',
+ flow.triggerActionsList[index].actionsList.map((action) => action.id),
+ flow.type.id,
+ flow.triggerActionsList[index].triggerType?.id ?? '',
)
.then(() => {
this.toast.showInfo('FLOWS.TOAST.ACTIONSSET', true);
@@ -151,8 +151,8 @@ export class ActionsComponent {
}
}
- protected removeTriggerActionsList(index: number) {
- if (this.flow.type && this.flow.triggerActionsList && this.flow.triggerActionsList[index]) {
+ protected removeTriggerActionsList(flow: Flow.AsObject, index: number) {
+ if (flow.type && flow.triggerActionsList && flow.triggerActionsList[index]) {
const dialogRef = this.dialog.open(WarnDialogComponent, {
data: {
confirmKey: 'ACTIONS.CLEAR',
@@ -166,10 +166,10 @@ export class ActionsComponent {
dialogRef.afterClosed().subscribe((resp) => {
if (resp) {
this.mgmtService
- .setTriggerActions([], this.flow?.type?.id ?? '', this.flow.triggerActionsList[index].triggerType?.id ?? '')
+ .setTriggerActions([], flow?.type?.id ?? '', flow.triggerActionsList[index].triggerType?.id ?? '')
.then(() => {
this.toast.showInfo('FLOWS.TOAST.ACTIONSSET', true);
- this.loadFlow(this.flow?.type?.id ?? '');
+ this.loadFlow(flow?.type?.id ?? '');
})
.catch((error) => {
this.toast.showError(error);
diff --git a/console/src/app/pages/projects/apps/app-detail/app-detail.component.html b/console/src/app/pages/projects/apps/app-detail/app-detail.component.html
index 24875bd04..5a4c35273 100644
--- a/console/src/app/pages/projects/apps/app-detail/app-detail.component.html
+++ b/console/src/app/pages/projects/apps/app-detail/app-detail.component.html
@@ -68,12 +68,12 @@
}
- @if (app && app.oidcConfig && app.oidcConfig.complianceProblemsList && app.oidcConfig.complianceProblemsList?.length) {
+ @if (app && app.oidcConfig && app.oidcConfig.complianceProblemsList && app.oidcConfig.complianceProblemsList.length) {
{{ 'APP.COMPLIANCE' | translate }}
@@ -92,13 +92,13 @@
[disabled]="
(['project.grant.member.write', 'project.grant.member.write:' + grant.grantId] | hasRole | async) === false
"
- (click)="openAddMember()"
+ (click)="openAddMember(grant)"
color="primary"
mat-raised-button
>
add{{ 'ACTIONS.NEW' | translate }}
-
+
diff --git a/console/src/app/pages/projects/owned-projects/project-grant-detail/project-grant-detail.component.ts b/console/src/app/pages/projects/owned-projects/project-grant-detail/project-grant-detail.component.ts
index ba3dac6e8..32a2f5e56 100644
--- a/console/src/app/pages/projects/owned-projects/project-grant-detail/project-grant-detail.component.ts
+++ b/console/src/app/pages/projects/owned-projects/project-grant-detail/project-grant-detail.component.ts
@@ -27,7 +27,7 @@ import { ProjectGrantMembersDataSource } from './project-grant-members-datasourc
export class ProjectGrantDetailComponent {
public INITIALPAGESIZE: number = 25;
- public grant!: GrantedProject.AsObject;
+ public grant: GrantedProject.AsObject | undefined;
public projectid: string = '';
public grantid: string = '';
@@ -99,13 +99,13 @@ export class ProjectGrantDetailComponent {
});
}
- public changeState(newState: ProjectGrantState): void {
+ public changeState(grant: GrantedProject.AsObject, newState: ProjectGrantState): void {
if (newState === ProjectGrantState.PROJECT_GRANT_STATE_ACTIVE) {
this.mgmtService
.reactivateProjectGrant(this.grantid, this.projectid)
.then(() => {
this.toast.showInfo('PROJECT.TOAST.REACTIVATED', true);
- this.grant.state = newState;
+ grant.state = newState;
})
.catch((error) => {
this.toast.showError(error);
@@ -115,7 +115,7 @@ export class ProjectGrantDetailComponent {
.deactivateProjectGrant(this.grantid, this.projectid)
.then(() => {
this.toast.showInfo('PROJECT.TOAST.DEACTIVATED', true);
- this.grant.state = newState;
+ grant.state = newState;
setTimeout(() => {
this.changePage.emit();
}, 1000);
@@ -144,56 +144,25 @@ export class ProjectGrantDetailComponent {
});
}
- updateRoles(selectionChange: string[]): void {
- this.mgmtService
- .updateProjectGrant(this.grant.grantId, this.grant.projectId, selectionChange)
- .then(() => {
- this.toast.showInfo('PROJECT.GRANT.TOAST.PROJECTGRANTUPDATED', true);
- setTimeout(() => {
- this.changePage.emit();
- }, 1000);
- })
- .catch((error) => {
- this.toast.showError(error);
- this.changePage.emit();
- });
+ public async removeProjectMemberSelection(grant: GrantedProject.AsObject) {
+ await Promise.all(this.selection.map((member) => this.removeProjectMember(grant, member)));
}
- public removeProjectMemberSelection(): void {
- Promise.all(
- this.selection.map((member) => {
- return this.mgmtService
- .removeProjectGrantMember(this.grant.projectId, this.grant.grantId, member.userId)
- .then(() => {
- this.toast.showInfo('PROJECT.GRANT.TOAST.PROJECTGRANTMEMBERREMOVED', true);
- setTimeout(() => {
- this.changePage.emit();
- }, 1000);
- })
- .catch((error) => {
- this.changePage.emit();
- this.toast.showError(error);
- });
- }),
- );
+ public async removeProjectMember(grant: GrantedProject.AsObject, member: Member.AsObject) {
+ try {
+ await this.mgmtService.removeProjectGrantMember(grant.projectId, grant.grantId, member.userId);
+
+ this.toast.showInfo('PROJECT.GRANT.TOAST.PROJECTGRANTMEMBERREMOVED', true);
+
+ await new Promise((res) => setTimeout(res, 1000));
+ } catch (error) {
+ this.toast.showError(error);
+ } finally {
+ this.changePage.emit();
+ }
}
- public removeProjectMember(member: Member.AsObject): void {
- this.mgmtService
- .removeProjectGrantMember(this.grant.projectId, this.grant.grantId, member.userId)
- .then(() => {
- this.toast.showInfo('PROJECT.GRANT.TOAST.PROJECTGRANTMEMBERREMOVED', true);
- setTimeout(() => {
- this.changePage.emit();
- }, 1000);
- })
- .catch((error) => {
- this.changePage.emit();
- this.toast.showError(error);
- });
- }
-
- public async openAddMember(): Promise {
+ public async openAddMember(grant: GrantedProject.AsObject): Promise {
const dialogRef = this.dialog.open(MemberCreateDialogComponent, {
data: {
creationType: CreationType.PROJECT_GRANTED,
@@ -210,7 +179,7 @@ export class ProjectGrantDetailComponent {
const userIds = users.map((user) => user.id);
Promise.all(
userIds.map((userid: string) => {
- return this.mgmtService.addProjectGrantMember(this.grant.projectId, this.grant.grantId, userid, resp.roles);
+ return this.mgmtService.addProjectGrantMember(grant.projectId, grant.grantId, userid, resp.roles);
}),
)
.then(() => {
@@ -228,9 +197,9 @@ export class ProjectGrantDetailComponent {
});
}
- updateMemberRoles(member: Member.AsObject, selectionChange: string[]): void {
+ updateMemberRoles(grant: GrantedProject.AsObject, member: Member.AsObject, selectionChange: string[]): void {
this.mgmtService
- .updateProjectGrantMember(this.grant.projectId, this.grant.grantId, member.userId, selectionChange)
+ .updateProjectGrantMember(grant.projectId, grant.grantId, member.userId, selectionChange)
.then(() => {
setTimeout(() => {
this.changePage.emit();
@@ -243,13 +212,13 @@ export class ProjectGrantDetailComponent {
});
}
- removeRole(role: string): void {
- const index = this.grant.grantedRoleKeysList.findIndex((r) => r === role);
+ removeRole(grant: GrantedProject.AsObject, role: string): void {
+ const index = grant.grantedRoleKeysList.findIndex((r) => r === role);
if (index > -1) {
- this.grant.grantedRoleKeysList.splice(index, 1);
+ grant.grantedRoleKeysList.splice(index, 1);
this.mgmtService
- .updateProjectGrant(this.grant.grantId, this.grant.projectId, this.grant.grantedRoleKeysList)
+ .updateProjectGrant(grant.grantId, grant.projectId, grant.grantedRoleKeysList)
.then(() => {
setTimeout(() => {
this.changePage.emit();
@@ -263,13 +232,13 @@ export class ProjectGrantDetailComponent {
}
}
- public editRoles(): void {
+ public editRoles(grant: GrantedProject.AsObject): void {
const dialogRef = this.dialog.open(
UserGrantRoleDialogComponent,
{
data: {
- projectId: this.grant.projectId,
- selectedRoleKeysList: this.grant.grantedRoleKeysList,
+ projectId: grant.projectId,
+ selectedRoleKeysList: grant.grantedRoleKeysList,
i18nTitle: 'PROJECT.GRANT.EDITTITLE',
},
width: '600px',
@@ -281,10 +250,10 @@ export class ProjectGrantDetailComponent {
return;
}
this.mgmtService
- .updateProjectGrant(this.grant.grantId, this.grant.projectId, resp.roles)
+ .updateProjectGrant(grant.grantId, grant.projectId, resp.roles)
.then(() => {
this.toast.showInfo('PROJECT.GRANT.TOAST.PROJECTGRANTUPDATED', true);
- this.grant.grantedRoleKeysList = resp.roles;
+ grant.grantedRoleKeysList = resp.roles;
setTimeout(() => {
this.changePage.emit();
}, 1000);
diff --git a/console/src/app/pages/projects/owned-projects/project-grant-detail/project-grant-illustration/project-grant-illustration.component.scss b/console/src/app/pages/projects/owned-projects/project-grant-detail/project-grant-illustration/project-grant-illustration.component.scss
index af0c35d8c..fad12d5fa 100644
--- a/console/src/app/pages/projects/owned-projects/project-grant-detail/project-grant-illustration/project-grant-illustration.component.scss
+++ b/console/src/app/pages/projects/owned-projects/project-grant-detail/project-grant-illustration/project-grant-illustration.component.scss
@@ -1,9 +1,9 @@
@mixin project-grant-illustration-theme($theme) {
$foreground: map-get($theme, foreground);
$is-dark-theme: map-get($theme, is-dark);
- $overlayColor: if($is-dark-theme, #ffffff10, #00000008);
- $highlightedOverlayColor: if($is-dark-theme, #68c4cf14, #68c4cf14);
- $borderColor: if($is-dark-theme, #ffffff20, #00000020);
+ $overlayColor: if(sass($is-dark-theme): #ffffff10; else: #00000008);
+ $highlightedOverlayColor: if(sass($is-dark-theme): #68c4cf14; else: #68c4cf14);
+ $borderColor: if(sass($is-dark-theme): #ffffff20; else: #00000020);
.pgi {
display: flex;
diff --git a/console/src/app/pages/projects/owned-projects/project-grants/project-grants.component.html b/console/src/app/pages/projects/owned-projects/project-grants/project-grants.component.html
index b3c438914..34bd5f18a 100644
--- a/console/src/app/pages/projects/owned-projects/project-grants/project-grants.component.html
+++ b/console/src/app/pages/projects/owned-projects/project-grants/project-grants.component.html
@@ -136,7 +136,7 @@
- @if ((dataSource.loading$ | async) === false && !dataSource?.totalResult) {
+ @if ((dataSource.loading$ | async) === false && !dataSource.totalResult) {
{{ 'PROJECT.GRANT.EMPTY' | translate }}
diff --git a/console/src/app/pages/projects/project-list/project-list.component.html b/console/src/app/pages/projects/project-list/project-list.component.html
index d7994338b..c6144a8e9 100644
--- a/console/src/app/pages/projects/project-list/project-list.component.html
+++ b/console/src/app/pages/projects/project-list/project-list.component.html
@@ -158,7 +158,7 @@
- @if ((loading$ | async) === false && !dataSource?.data?.length) {
+ @if ((loading$ | async) === false && !dataSource.data.length) {
{{ 'PROJECT.TABLE.EMPTY' | translate }}
diff --git a/console/src/app/pages/users/user-detail/auth-user-detail/auth-passwordless/auth-passwordless.component.html b/console/src/app/pages/users/user-detail/auth-user-detail/auth-passwordless/auth-passwordless.component.html
index 8e163ba5d..ad9cadf9e 100644
--- a/console/src/app/pages/users/user-detail/auth-user-detail/auth-passwordless/auth-passwordless.component.html
+++ b/console/src/app/pages/users/user-detail/auth-user-detail/auth-passwordless/auth-passwordless.component.html
@@ -73,7 +73,7 @@
|
- @if ((loading$ | async) === false && !dataSource?.data?.length) {
+ @if ((loading$ | async) === false && !dataSource.data.length) {
{{ 'USER.PASSWORDLESS.EMPTY' | translate }}
diff --git a/console/src/app/pages/users/user-detail/auth-user-detail/auth-user-mfa/auth-user-mfa.component.html b/console/src/app/pages/users/user-detail/auth-user-detail/auth-user-mfa/auth-user-mfa.component.html
index efcb66b82..cbe5b91f6 100644
--- a/console/src/app/pages/users/user-detail/auth-user-detail/auth-user-mfa/auth-user-mfa.component.html
+++ b/console/src/app/pages/users/user-detail/auth-user-detail/auth-user-mfa/auth-user-mfa.component.html
@@ -93,7 +93,7 @@
|
- @if ((loading$ | async) === false && !dataSource?.data?.length) {
+ @if ((loading$ | async) === false && !dataSource.data.length) {
{{ 'USER.MFA.EMPTY' | translate }}
diff --git a/console/src/app/pages/users/user-detail/external-idps/external-idps.component.html b/console/src/app/pages/users/user-detail/external-idps/external-idps.component.html
index 5d296aadb..8ecaa6ab5 100644
--- a/console/src/app/pages/users/user-detail/external-idps/external-idps.component.html
+++ b/console/src/app/pages/users/user-detail/external-idps/external-idps.component.html
@@ -74,7 +74,7 @@
- @if ((loading$ | async) === false && !dataSource?.data?.length) {
+ @if ((loading$ | async) === false && !dataSource.data.length) {
{{ 'USER.EXTERNALIDP.EMPTY' | translate }}
diff --git a/console/src/app/pages/users/user-detail/user-detail/passwordless/passwordless.component.html b/console/src/app/pages/users/user-detail/user-detail/passwordless/passwordless.component.html
index e100e18aa..5026ee090 100644
--- a/console/src/app/pages/users/user-detail/user-detail/passwordless/passwordless.component.html
+++ b/console/src/app/pages/users/user-detail/user-detail/passwordless/passwordless.component.html
@@ -72,7 +72,7 @@
|
- @if ((loading$ | async) === false && !dataSource?.data?.length) {
+ @if ((loading$ | async) === false && !dataSource.data.length) {
{{ 'USER.PASSWORDLESS.EMPTY' | translate }}
diff --git a/console/src/app/pages/users/user-list/user-table/user-table.component.html b/console/src/app/pages/users/user-list/user-table/user-table.component.html
index 2570aa353..2bb04b5b0 100644
--- a/console/src/app/pages/users/user-list/user-table/user-table.component.html
+++ b/console/src/app/pages/users/user-list/user-table/user-table.component.html
@@ -233,7 +233,7 @@
>
- @if (!loading() && !dataSource?.data?.length) {
+ @if (!loading() && !dataSource.data.length) {
{{ 'USER.TABLE.EMPTY' | translate }}
diff --git a/console/src/app/services/new-auth.service.ts b/console/src/app/services/new-auth.service.ts
index c0f552f52..c8b723b6c 100644
--- a/console/src/app/services/new-auth.service.ts
+++ b/console/src/app/services/new-auth.service.ts
@@ -1,6 +1,6 @@
import { Injectable } from '@angular/core';
import { GrpcService } from './grpc.service';
-import { create } from '@bufbuild/protobuf';
+import { create, MessageInitShape } from '@bufbuild/protobuf';
import {
AddMyAuthFactorOTPSMSResponse,
GetMyLoginPolicyResponse,
@@ -19,6 +19,7 @@ import {
ListMyMetadataResponse,
VerifyMyPhoneResponse,
ListMyZitadelPermissionsResponse,
+ ListMyProjectOrgsRequestSchema,
} from '@zitadel/proto/zitadel/auth_pb';
import { injectQuery } from '@tanstack/angular-query-experimental';
import { UserService } from './user.service';
@@ -82,4 +83,8 @@ export class NewAuthService {
queryFn: () => this.listMyZitadelPermissions().then(({ result }) => result),
}));
}
+
+ public listMyProjectOrgs(req: MessageInitShape
, signal?: AbortSignal) {
+ return this.grpcService.authNew.listMyProjectOrgs(req, { signal });
+ }
}
diff --git a/console/src/app/services/new-mgmt.service.ts b/console/src/app/services/new-mgmt.service.ts
index 3847a6c20..0f59bc0bf 100644
--- a/console/src/app/services/new-mgmt.service.ts
+++ b/console/src/app/services/new-mgmt.service.ts
@@ -2,6 +2,7 @@ import { Injectable } from '@angular/core';
import { GrpcService } from './grpc.service';
import {
AddOrgResponse,
+ AddProjectGrantRequestSchema,
DeactivateOrgResponse,
GenerateMachineSecretRequestSchema,
GenerateMachineSecretResponse,
@@ -123,4 +124,8 @@ export class NewMgmtService {
public addOrg(name: string): Promise {
return this.grpcService.mgmtNew.addOrg({ name });
}
+
+ public addProjectGrant(req: MessageInitShape) {
+ return this.grpcService.mgmtNew.addProjectGrant(req);
+ }
}
diff --git a/console/src/styles/codemirror.scss b/console/src/styles/codemirror.scss
index 78e0fac7e..94026c3c8 100644
--- a/console/src/styles/codemirror.scss
+++ b/console/src/styles/codemirror.scss
@@ -4,11 +4,11 @@
$is-dark-theme: map.get($theme, is-dark);
.cm-s-material.CodeMirror {
- background-color: if($is-dark-theme, #00000020, #263238);
+ background-color: if(sass($is-dark-theme): #00000020; else: #263238);
color: #eff;
font-size: 14px;
border-radius: 4px;
- border: 1px solid if($is-dark-theme, #403e3e, #00000040);
+ border: 1px solid if(sass($is-dark-theme): #403e3e; else: #00000040);
}
}
diff --git a/console/src/styles/input.scss b/console/src/styles/input.scss
index 1efb75a9a..7c557d8a9 100644
--- a/console/src/styles/input.scss
+++ b/console/src/styles/input.scss
@@ -20,8 +20,8 @@
transform: all 0.2 linear;
font-size: 1rem;
border: none;
- border: 1px solid if($is-dark-theme, #f9f7f775, #1a191954);
- background-color: if($is-dark-theme, #00000040, #00000004);
+ border: 1px solid if(sass($is-dark-theme): #f9f7f775; else: #1a191954);
+ background-color: if(sass($is-dark-theme): #00000040; else: #00000004);
border-radius: 4px;
height: 40px;
padding: 10px;
@@ -34,7 +34,7 @@
margin-bottom: 2px;
&:hover {
- border-color: if($is-dark-theme, #e0e0e0, #1a1b1b);
+ border-color: if(sass($is-dark-theme): #e0e0e0; else: #1a1b1b);
}
&:active,
@@ -49,11 +49,11 @@
}
&[disabled] {
- border-color: if($is-dark-theme, #36373850, #cccdce50);
- color: if($is-dark-theme, #ffffff80, #00000061);
+ border-color: if(sass($is-dark-theme): #36373850; else: #cccdce50);
+ color: if(sass($is-dark-theme): #ffffff80; else: #00000061);
&::placeholder {
- color: if($is-dark-theme, #ffffff80, #00000061);
+ color: if(sass($is-dark-theme): #ffffff80; else: #00000061);
}
}
}
diff --git a/console/src/styles/table.scss b/console/src/styles/table.scss
index 7ae4edaf7..0f73a0348 100644
--- a/console/src/styles/table.scss
+++ b/console/src/styles/table.scss
@@ -88,7 +88,7 @@
}
.no-content-row {
- background-color: if($is-dark-theme, #ffffff10, #f4f4f470);
+ background-color: if(sass($is-dark-theme): #ffffff10; else: #f4f4f470);
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
display: flex;
@@ -123,41 +123,41 @@
font-weight: 500;
font-size: 12px;
white-space: nowrap;
- background-color: if($is-dark-theme, map.get($background, state), #e4e7e4);
+ background-color: if(sass($is-dark-theme): map.get($background, state) ; else: #e4e7e4);
box-shadow: 0 0 3px #0000001a;
&.active {
- background-color: if($is-dark-theme, map.get($background, state-active), #cbf4c9);
- color: if($is-dark-theme, #cbf4c9, #0e6245);
+ background-color: if(sass($is-dark-theme): map.get($background, state-active) ; else: #cbf4c9);
+ color: if(sass($is-dark-theme): #cbf4c9; else: #0e6245);
}
&.inactive {
- color: if($is-dark-theme, #ffc1c1, #620e0e);
- background-color: if($is-dark-theme, map.get($background, state-inactive), #ffc1c1);
+ color: if(sass($is-dark-theme): #ffc1c1; else: #620e0e);
+ background-color: if(sass($is-dark-theme): map.get($background, state-inactive) ; else: #ffc1c1);
}
&.neutral {
- background: if($is-dark-theme, #01489c78, #47a8ff82);
- color: if($is-dark-theme, #47a8ff, #01489c);
+ background: if(sass($is-dark-theme): #01489c78; else: #47a8ff82);
+ color: if(sass($is-dark-theme): #47a8ff; else: #01489c);
}
}
.bg-state {
- background-color: if($is-dark-theme, map.get($background, state), #e4e7e4) !important;
+ background-color: if(sass($is-dark-theme): map.get($background, state) ; else: #e4e7e4) !important;
&.active {
- background-color: if($is-dark-theme, map.get($background, state-active), #cbf4c9) !important;
- color: if($is-dark-theme, #cbf4c9, #0e6245) !important;
+ background-color: if(sass($is-dark-theme): map.get($background, state-active) ; else: #cbf4c9) !important;
+ color: if(sass($is-dark-theme): #cbf4c9; else: #0e6245) !important;
}
&.inactive {
- color: if($is-dark-theme, #ffc1c1, #620e0e) !important;
- background-color: if($is-dark-theme, map.get($background, state-inactive), #ffc1c1) !important;
+ color: if(sass($is-dark-theme): #ffc1c1; else: #620e0e) !important;
+ background-color: if(sass($is-dark-theme): map.get($background, state-inactive) ; else: #ffc1c1) !important;
}
}
.color-shadow {
- border: 1px solid if($is-dark-theme, rgba(#8795a1, 0.2), rgba(#8795a1, 0.2));
+ border: 1px solid if(sass($is-dark-theme): rgba(#8795a1, 0.2) ; else: rgba(#8795a1, 0.2));
box-shadow: 0 0 3px #0000001a;
}
}
diff --git a/console/src/tailwind.css b/console/src/tailwind.css
new file mode 100644
index 000000000..bd14e97ad
--- /dev/null
+++ b/console/src/tailwind.css
@@ -0,0 +1,5 @@
+/* https://github.com/tailwindlabs/tailwindcss-intellisense/issues/1158#issuecomment-2968949608 */
+@import 'tailwindcss/utilities' prefix(tw);
+@import 'tailwindcss/theme' prefix(tw);
+
+@custom-variant dark (&:where(.dark-theme, .dark-theme *));
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index f59c903fb..1eadfffe3 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -432,14 +432,14 @@ importers:
specifier: ^8.5.8
version: 8.5.8
prettier:
- specifier: ^3.8.1
- version: 3.8.1
+ specifier: ^3.8.3
+ version: 3.8.3
prettier-plugin-organize-imports:
specifier: ^4.3.0
- version: 4.3.0(prettier@3.8.1)(typescript@5.9.3)
+ version: 4.3.0(prettier@3.8.3)(typescript@5.9.3)
prettier-plugin-tailwindcss:
specifier: ^0.7.2
- version: 0.7.2(prettier-plugin-organize-imports@4.3.0(prettier@3.8.1)(typescript@5.9.3))(prettier@3.8.1)
+ version: 0.7.2(prettier-plugin-organize-imports@4.3.0(prettier@3.8.3)(typescript@5.9.3))(prettier@3.8.3)
sass:
specifier: ^1.98.0
version: 1.98.0
@@ -624,6 +624,9 @@ importers:
'@eslint/js':
specifier: ^10.0.1
version: 10.0.1(eslint@10.1.0(jiti@2.6.1))
+ '@tailwindcss/postcss':
+ specifier: ^4.2.2
+ version: 4.2.2
'@types/file-saver':
specifier: ^2.0.7
version: 2.0.7
@@ -699,12 +702,18 @@ importers:
karma-jasmine-html-reporter:
specifier: ^2.2.0
version: 2.2.0(jasmine-core@5.12.1)(karma-jasmine@5.1.0(karma@6.4.4))(karma@6.4.4)
+ postcss:
+ specifier: ^8.5.8
+ version: 8.5.8
prettier:
- specifier: ^3.8.1
- version: 3.8.1
+ specifier: ^3.8.3
+ version: 3.8.3
prettier-plugin-organize-imports:
specifier: ^4.3.0
- version: 4.3.0(prettier@3.8.1)(typescript@5.9.2)
+ version: 4.3.0(prettier@3.8.3)(typescript@5.9.2)
+ tailwindcss:
+ specifier: ^4.2.2
+ version: 4.2.2
typescript:
specifier: 5.9.2
version: 5.9.2
@@ -807,8 +816,8 @@ importers:
specifier: ^9.0.3
version: 9.0.3
prettier:
- specifier: ^3.8.1
- version: 3.8.1
+ specifier: ^3.8.3
+ version: 3.8.3
typescript:
specifier: ^5.9.3
version: 5.9.3
@@ -10450,8 +10459,8 @@ packages:
engines: {node: '>=10.13.0'}
hasBin: true
- prettier@3.8.1:
- resolution: {integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==}
+ prettier@3.8.3:
+ resolution: {integrity: sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==}
engines: {node: '>=14'}
hasBin: true
@@ -23386,25 +23395,25 @@ snapshots:
prelude-ls@1.2.1: {}
- prettier-plugin-organize-imports@4.3.0(prettier@3.8.1)(typescript@5.9.2):
+ prettier-plugin-organize-imports@4.3.0(prettier@3.8.3)(typescript@5.9.2):
dependencies:
- prettier: 3.8.1
+ prettier: 3.8.3
typescript: 5.9.2
- prettier-plugin-organize-imports@4.3.0(prettier@3.8.1)(typescript@5.9.3):
+ prettier-plugin-organize-imports@4.3.0(prettier@3.8.3)(typescript@5.9.3):
dependencies:
- prettier: 3.8.1
+ prettier: 3.8.3
typescript: 5.9.3
- prettier-plugin-tailwindcss@0.7.2(prettier-plugin-organize-imports@4.3.0(prettier@3.8.1)(typescript@5.9.3))(prettier@3.8.1):
+ prettier-plugin-tailwindcss@0.7.2(prettier-plugin-organize-imports@4.3.0(prettier@3.8.3)(typescript@5.9.3))(prettier@3.8.3):
dependencies:
- prettier: 3.8.1
+ prettier: 3.8.3
optionalDependencies:
- prettier-plugin-organize-imports: 4.3.0(prettier@3.8.1)(typescript@5.9.3)
+ prettier-plugin-organize-imports: 4.3.0(prettier@3.8.3)(typescript@5.9.3)
prettier@2.8.8: {}
- prettier@3.8.1: {}
+ prettier@3.8.3: {}
pretty-bytes@5.6.0: {}
diff --git a/tests/functional-ui/package.json b/tests/functional-ui/package.json
index 9073920db..450b2f124 100644
--- a/tests/functional-ui/package.json
+++ b/tests/functional-ui/package.json
@@ -12,7 +12,7 @@
"cypress": "^15.13.0",
"cypress-wait-until": "^3.0.2",
"jsonwebtoken": "^9.0.3",
- "prettier": "^3.8.1",
+ "prettier": "^3.8.3",
"typescript": "^5.9.3",
"uuid": "^13.0.0"
}