Skip to content

Commit 7d4e9de

Browse files
feat: add membership popup on Access column hover in company members table
Shows a CDK overlay popup on hover of the check_circle icon listing each connection (title + database name) and its groups for the member. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 759f0d1 commit 7d4e9de

5 files changed

Lines changed: 95 additions & 3 deletions

File tree

frontend/src/app/components/company/company.component.css

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,53 @@
112112
color: var(--color-successPalette-500);
113113
}
114114

115+
.access-popup {
116+
background: var(--mat-menu-container-color, #fff);
117+
border-radius: 4px;
118+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
119+
padding: 8px 12px;
120+
min-width: 160px;
121+
white-space: nowrap;
122+
display: flex;
123+
flex-direction: column;
124+
gap: 8px;
125+
}
126+
127+
.access-popup__connection {
128+
display: flex;
129+
flex-direction: column;
130+
gap: 2px;
131+
}
132+
133+
.access-popup__connection-title {
134+
font-weight: 500;
135+
font-size: 13px;
136+
}
137+
138+
.access-popup__connection-db {
139+
font-size: 11px;
140+
color: rgba(0, 0, 0, 0.45);
141+
padding-left: 2px;
142+
}
143+
144+
@media (prefers-color-scheme: dark) {
145+
.access-popup__connection-db {
146+
color: rgba(255, 255, 255, 0.45);
147+
}
148+
}
149+
150+
.access-popup__group {
151+
font-size: 12px;
152+
color: rgba(0, 0, 0, 0.6);
153+
padding-left: 8px;
154+
}
155+
156+
@media (prefers-color-scheme: dark) {
157+
.access-popup__group {
158+
color: rgba(255, 255, 255, 0.6);
159+
}
160+
}
161+
115162
.company-member-cell_not-accessed {
116163
color: var(--color-warnPalette-500);
117164
}

frontend/src/app/components/company/company.component.html

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -199,14 +199,42 @@ <h2 class="heading-2 tableHeader__heading">Members <span *ngIf="currentPlan ===
199199
</td>
200200
</ng-container>
201201

202-
<!-- Active Column -->
202+
<!-- Access Column -->
203203
<ng-container matColumnDef="access">
204204
<th mat-header-cell *matHeaderCellDef matTooltip="Access to connection">Access</th>
205205
<td mat-cell *matCellDef="let element; let i = index"
206206
data-label="Access"
207207
class="company-member-cell company-member-cell_content-center">
208-
<mat-icon *ngIf="element.has_groups" class="company-member-cell_accessed" fontSet="material-symbols-outlined">check_circle</mat-icon>
209-
<mat-icon *ngIf="!element.has_groups" class="company-member-cell_not-accessed" fontSet="material-symbols-outlined">cancel</mat-icon>
208+
@if (element.has_groups) {
209+
<mat-icon class="company-member-cell_accessed" fontSet="material-symbols-outlined"
210+
#overlayOrigin="cdkOverlayOrigin"
211+
cdkOverlayOrigin
212+
(mouseenter)="element._popupOpen = true"
213+
(mouseleave)="element._popupOpen = false">check_circle</mat-icon>
214+
<ng-template
215+
cdkConnectedOverlay
216+
[cdkConnectedOverlayOrigin]="overlayOrigin"
217+
[cdkConnectedOverlayOpen]="element._popupOpen"
218+
[cdkConnectedOverlayPositions]="[
219+
{ originX: 'center', originY: 'top', overlayX: 'center', overlayY: 'bottom', offsetY: -4 },
220+
{ originX: 'center', originY: 'bottom', overlayX: 'center', overlayY: 'top', offsetY: 4 }
221+
]"
222+
[cdkConnectedOverlayHasBackdrop]="false">
223+
<div class="access-popup" (mouseleave)="element._popupOpen = false">
224+
@for (conn of element.user_membership; track conn.id) {
225+
<div class="access-popup__connection">
226+
<span class="access-popup__connection-title">{{ conn.title }}</span>
227+
<span class="access-popup__connection-db">{{ conn.database }}</span>
228+
@for (group of conn.groups; track group.id) {
229+
<span class="access-popup__group">{{ group.title }}</span>
230+
}
231+
</div>
232+
}
233+
</div>
234+
</ng-template>
235+
} @else {
236+
<mat-icon class="company-member-cell_not-accessed" fontSet="material-symbols-outlined">cancel</mat-icon>
237+
}
210238
</td>
211239
</ng-container>
212240

frontend/src/app/components/company/company.component.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { NgIf } from '@angular/common';
2+
import { CdkConnectedOverlay, CdkOverlayOrigin } from '@angular/cdk/overlay';
23
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
34
import { FormsModule } from '@angular/forms';
45
import { MatButtonModule } from '@angular/material/button';
@@ -37,6 +38,8 @@ import { RevokeInvitationDialogComponent } from './revoke-invitation-dialog/revo
3738
styleUrls: ['./company.component.css'],
3839
imports: [
3940
NgIf,
41+
CdkOverlayOrigin,
42+
CdkConnectedOverlay,
4043
FormsModule,
4144
MatFormFieldModule,
4245
MatInputModule,

frontend/src/app/models/company.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,18 @@ export interface Company {
3434
show_test_connections: boolean;
3535
}
3636

37+
export interface CompanyMembershipGroup {
38+
id: string;
39+
title: string;
40+
}
41+
42+
export interface CompanyMembershipConnection {
43+
id: string;
44+
title: string;
45+
database: string;
46+
groups: CompanyMembershipGroup[];
47+
}
48+
3749
export interface CompanyMember {
3850
id: string;
3951
isActive: boolean;
@@ -42,6 +54,7 @@ export interface CompanyMember {
4254
is_2fa_enabled: boolean;
4355
role: CompanyMemberRole;
4456
has_groups: boolean;
57+
user_membership: CompanyMembershipConnection[];
4558
}
4659

4760
export enum CompanyMemberRole {

frontend/src/styles.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// @import 'codemirror/lib/codemirror';
22
// @import 'codemirror/theme/ttcn';
33

4+
45
* {
56
margin: 0;
67
padding: 0;

0 commit comments

Comments
 (0)