Skip to content

Commit 56537d6

Browse files
authored
Standardize admin page headers and main page layout (#686)
* Add template indicator badge to admin views list Display a "TEMPLATE" badge next to view names in the admin views list when isTemplate is true, making it easier to distinguish template views from regular views at a glance. * Standardize admin page headers and main page layout - Update admin sidebar header to use mat-toolbar with app icon - Reorder admin menu items to match other apps - Fix admin Users section table layout and row height - Update main Views page to match CITE layout - Add consistent spacing and Material Design styling - Remove unnecessary wrapper divs and CSS classes - Fix table cell padding and alignment * Use routerLink for admin header to support middle-click navigation Replace click event handler with routerLink directive to enable proper browser navigation behavior including middle-click to open in new tab * Make topbar icon middle-clickable Change icon from button with click handler to link with routerLink * Fix topbar icon color Add explicit color style to maintain icon color after changing to anchor tag * Fix topbar icon cutoff on view page Update focused-app container top position from 40px to 46px to match topbar height and prevent overlap * Match sidebar header height with admin panel - Change sidebar header to use mat-toolbar for consistency - Set header height to 40px to match admin panel - Use 35px icon size matching admin styling - Apply same border-bottom styling as admin header * Implement Blueprint-style collapsible sidebar for Player Refactored view page sidebar to match Blueprint's collapsible design with 50px mini mode. Added toggle buttons for collapse/expand, improved icon sizing and centering, and included small Crucible logos for both themes in collapsed state. Made all navigation elements middle-clickable for better UX. * adjustments to icon sizes * Fix admin header link to support middle-click navigation Moved routerLink from mat-toolbar to anchor tag to enable middle-click opening in new tab. Addresses PR feedback to maintain middle-click functionality on administration header. * Remove unused goToHome function from topbar and admin components * Set default sidebar width to 250px to match admin panel * Fix confirm dialog text color in dark theme
1 parent 455923f commit 56537d6

23 files changed

+464
-338
lines changed

src/app/components/admin-app/admin-app.component.html

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,15 @@
1010
mode="side"
1111
[opened]="true"
1212
>
13+
<mat-toolbar class="sidenav-header">
14+
<a class="nolink" [routerLink]="['/']" title="Exit Administration">
15+
<div class="cssLayoutRowStartCenter">
16+
<mat-icon class="icon-35px player-icon-header" svgIcon="ic_crucible_player"></mat-icon>
17+
<h2 class="icon-text">Administration</h2>
18+
</div>
19+
</a>
20+
</mat-toolbar>
1321
<mat-list class="appitems-container">
14-
<mat-list-item class="appslist">
15-
<a class="nolink" [routerLink]="['/']">
16-
<div class="d-flex align-items-center">
17-
<mat-icon
18-
class="player-icon"
19-
svgIcon="ic_crucible_player"
20-
></mat-icon>
21-
<h2 class="icon-text">Administration</h2>
22-
</div>
23-
</a>
24-
<mat-divider></mat-divider>
25-
</mat-list-item>
2622
@for (sectionItem of sectionItems; track sectionItem) {
2723
@if (permissions$ | async; as permissions) {
2824
@if (permissions.includes(sectionItem.permission)) {

src/app/components/admin-app/admin-app.component.scss

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
}
2525

2626
.appbarmenu-container {
27-
min-width: 50px;
27+
width: 250px;
28+
border-right: solid var(--mat-sys-surface-container);
2829
}
2930

3031
.lefticon {
@@ -43,7 +44,7 @@
4344

4445
.icon-text {
4546
margin-left: 10px;
46-
font-family: open_sansbold;
47+
font-weight: bold;
4748
}
4849

4950
.player-icon {
@@ -60,3 +61,25 @@
6061
cursor: pointer;
6162
color: var(--mat-sys-primary);
6263
}
64+
65+
.sidenav-header {
66+
height: 40px;
67+
border-bottom: 2px solid var(--mat-sys-surface-container);
68+
}
69+
70+
.player-icon-header {
71+
color: var(--mat-sys-primary);
72+
}
73+
74+
.icon-35px {
75+
width: 35px;
76+
height: 35px;
77+
font-size: 35px;
78+
}
79+
80+
.cssLayoutRowStartCenter {
81+
display: flex;
82+
flex-direction: row;
83+
justify-content: flex-start;
84+
align-items: center;
85+
}

src/app/components/admin-app/admin-app.component.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,20 +41,20 @@ export class AdminAppComponent implements OnInit, OnDestroy {
4141
svgIcon: true,
4242
permission: SystemPermission.ViewViews,
4343
},
44-
{
45-
name: 'Users',
46-
section: Section.ADMIN_USERS,
47-
icon: 'assets/img/SP_Icon_User.png',
48-
svgIcon: false,
49-
permission: SystemPermission.ViewUsers,
50-
},
5144
{
5245
name: 'Application Templates',
5346
section: Section.ADMIN_APP_TEMP,
5447
icon: 'assets/img/SP_Icon_Intel.png',
5548
svgIcon: false,
5649
permission: SystemPermission.ViewApplications,
5750
},
51+
{
52+
name: 'Users',
53+
section: Section.ADMIN_USERS,
54+
icon: 'assets/img/SP_Icon_User.png',
55+
svgIcon: false,
56+
permission: SystemPermission.ViewUsers,
57+
},
5858
{
5959
name: 'Roles',
6060
section: Section.ADMIN_ROLE_PERM,

src/app/components/admin-app/admin-user-search/admin-user-search.component.html

Lines changed: 53 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -2,120 +2,64 @@
22
Copyright 2021 Carnegie Mellon University. All Rights Reserved.
33
Released under a MIT (SEI)-style license. See LICENSE.md in the project root for license information.
44
-->
5-
<div
6-
[class.hidden]="userToEdit !== undefined"
7-
class="user-list-container mat-elevation-z8"
8-
>
9-
<div class="d-flex align-items-center gap-4">
10-
<div class="sp-icon">
11-
<img height="35" src="assets/img/SP_Icon_User.png" alt="Users" />
12-
</div>
13-
<span class="header-text">Users</span>
14-
<div class="my-1">
15-
<mat-form-field style="width: 320px" subscriptSizing="dynamic">
16-
<mat-icon
17-
matPrefix
18-
style="transform: scale(0.85)"
19-
svgIcon="ic_magnify_search"
20-
></mat-icon>
21-
<input
22-
matInput
23-
[(ngModel)]="filterString"
24-
(keyup)="applyFilter($event.target.value)"
25-
placeholder="Search"
26-
/>
27-
@if (filterString !== '') {
28-
<button
29-
mat-icon-button
30-
matSuffix
31-
(click)="clearFilter()"
32-
title="Clear Search"
33-
>
34-
<mat-icon
35-
style="transform: scale(0.85)"
36-
svgIcon="ic_cancel_circle"
37-
></mat-icon>
38-
</button>
39-
}
40-
</mat-form-field>
41-
</div>
5+
6+
<div class="cssLayoutRowStartCenter">
7+
<div class="sp-icon">
8+
<mat-icon class="mdi-24px" fontIcon="mdi-account-multiple"></mat-icon>
9+
</div>
10+
<mat-form-field style="width: 300px">
11+
<input matInput [(ngModel)]="filterString" (keyup)="applyFilter($event.target.value)" placeholder="Search" />
12+
@if (filterString) {
13+
<button mat-icon-button matSuffix (click)="applyFilter('')" title="Clear Search">
14+
<mat-icon style="transform: scale(0.85)" fontIcon="mdi-close-circle-outline"></mat-icon>
15+
</button>
16+
}
17+
</mat-form-field>
18+
<div class="button-end">
19+
<mat-paginator #paginator [pageIndex]="0" [pageSize]="20"
20+
[pageSizeOptions]="[5, 10, 15, 20, 25, 50, 100, 200]"></mat-paginator>
4221
</div>
22+
</div>
4323

44-
@if (isLoading) {
45-
<mat-card class="d-flex content-center align-items-center">
46-
<mat-progress-spinner color="primary" mode="indeterminate">
47-
</mat-progress-spinner>
48-
</mat-card>
49-
}
24+
<div class="table-container">
25+
<table mat-table [dataSource]="userDataSource" matSort>
26+
<ng-container matColumnDef="id">
27+
<th mat-header-cell *matHeaderCellDef mat-sort-header>
28+
ID
29+
</th>
30+
<td mat-cell *matCellDef="let element">
31+
<button mat-icon-button ngxClipboard [cbContent]="element.id" (click)="$event.stopPropagation()"
32+
title="Copy: {{ element.id }}">
33+
<mat-icon class="mdi-24px" fontIcon="mdi-content-copy"></mat-icon>
34+
</button>
35+
{{ element.id }}
36+
</td>
37+
</ng-container>
5038

51-
<mat-accordion>
52-
<mat-table #table [dataSource]="userDataSource" matSort>
53-
<ng-container matColumnDef="name">
54-
<mat-header-cell *matHeaderCellDef mat-sort-header
55-
>User Name</mat-header-cell
56-
>
57-
<mat-cell *matCellDef="let element">
58-
<button
59-
mat-icon-button
60-
ngxClipboard
61-
[cbContent]="element.id"
62-
title="Copy: {{ element.id }}"
63-
>
64-
<mat-icon
65-
style="transform: scale(0.85)"
66-
svgIcon="ic_clipboard_copy"
67-
></mat-icon>
68-
</button>
69-
@if (element.name !== null) {
70-
<div>{{ element.name }}</div>
71-
}
72-
@if (element.name === null) {
73-
<div>{{ element.id }}</div>
74-
}
75-
</mat-cell>
76-
</ng-container>
39+
<ng-container matColumnDef="name">
40+
<th mat-header-cell *matHeaderCellDef mat-sort-header>Name</th>
41+
<td mat-cell *matCellDef="let element">{{ element.name }}</td>
42+
</ng-container>
7743

78-
<ng-container matColumnDef="roleName">
79-
<mat-header-cell *matHeaderCellDef mat-sort-header>
80-
Role
81-
</mat-header-cell>
82-
<mat-cell *matCellDef="let element; let i = index">
83-
<app-roles-permissions-select
84-
[user]="element"
85-
></app-roles-permissions-select>
86-
</mat-cell>
87-
</ng-container>
44+
<ng-container matColumnDef="role">
45+
<th mat-header-cell *matHeaderCellDef>Role</th>
46+
<td mat-cell *matCellDef="let element">
47+
<app-roles-permissions-select [user]="element"></app-roles-permissions-select>
48+
<button mat-icon-button (click)="deleteUser(element); $event.stopPropagation()"
49+
title="Delete User">
50+
<mat-icon class="mdi-24px" fontIcon="mdi-trash-can-outline"></mat-icon>
51+
</button>
52+
</td>
53+
</ng-container>
8854

89-
<ng-container matColumnDef="actions">
90-
<mat-header-cell *matHeaderCellDef> Actions </mat-header-cell>
91-
<mat-cell *matCellDef="let element">
92-
<button
93-
mat-icon-button
94-
color="primary"
95-
(click)="deleteUser(element)"
96-
title="Delete User"
97-
>
98-
<mat-icon
99-
class="mdi-24px"
100-
fontIcon="mdi-delete-forever-outline"
101-
></mat-icon>
102-
</button>
103-
</mat-cell>
104-
</ng-container>
55+
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
56+
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
57+
</table>
10558

106-
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
107-
<mat-row *matRowDef="let row; columns: displayedColumns"></mat-row>
108-
</mat-table>
109-
</mat-accordion>
110-
@if (userDataSource.filteredData.length === 0) {
111-
<div>No results found</div>
59+
@if (isLoading) {
60+
<mat-card style="display: flex; justify-content: center; align-items: center">
61+
<mat-progress-spinner color="primary" mode="indeterminate">
62+
</mat-progress-spinner>
63+
</mat-card>
11264
}
113-
<mat-paginator
114-
#paginator
115-
[pageSize]="defaultPageSize"
116-
[pageSizeOptions]="[10, 20, 30]"
117-
[showFirstLastButtons]="true"
118-
(page)="pageEvent = $event"
119-
>
120-
</mat-paginator>
12165
</div>
Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,53 @@
11
// Copyright 2021 Carnegie Mellon University. All Rights Reserved.
22
// Released under a MIT (SEI)-style license. See LICENSE.md in the project root for license information.
3-
.user-list-container {
4-
min-width: 600px;
5-
margin-top: 40px;
6-
width: 600px;
3+
4+
:host {
5+
display: flex;
6+
flex-direction: column;
7+
flex: 1;
8+
min-height: 0;
79
}
810

9-
.mat-expansion-panel-header {
10-
padding-left: 0;
11+
.cssLayoutRowStartCenter {
12+
display: flex;
13+
flex-direction: row;
14+
justify-content: flex-start;
15+
align-items: center;
16+
flex-shrink: 0;
1117
}
1218

13-
.sp-icon {
14-
margin-left: 10px;
19+
.table-container {
20+
flex: 1;
21+
overflow: auto;
22+
padding-bottom: 20px;
23+
}
24+
25+
table {
26+
width: 100%;
27+
--mat-table-row-item-container-height: auto;
1528
}
1629

17-
.hidden {
18-
display: none !important;
30+
.mat-mdc-cell,
31+
.mat-mdc-header-cell {
32+
overflow: hidden;
33+
word-wrap: break-word;
34+
padding-right: 10px;
35+
padding-top: 2px;
36+
padding-bottom: 2px;
37+
vertical-align: middle;
38+
39+
button[mat-icon-button] {
40+
vertical-align: middle;
41+
}
42+
}
43+
44+
.button-end {
45+
margin-left: 100px;
1946
}
2047

21-
.mat-column-name {
22-
max-width: 30%;
48+
.sp-icon {
49+
width: 5%;
50+
color: var(--mat-sys-primary);
51+
text-align: center;
52+
min-width: 30px;
2353
}

0 commit comments

Comments
 (0)