Implement admin and user sidebars with routing and styling updates
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { AdminModuleService } from './admin-module.service';
|
||||
|
||||
describe('AdminModuleService', () => {
|
||||
let service: AdminModuleService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(AdminModuleService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,19 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import {Observable} from 'rxjs';
|
||||
import {HttpClient} from '@angular/common/http';
|
||||
import {User} from '../models/user.model';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class AdminModuleService {
|
||||
baseUrl = 'http://localhost:8080/api';
|
||||
|
||||
constructor(private http: HttpClient) {
|
||||
|
||||
}
|
||||
|
||||
updateUserRoles(id: any,data: User): Observable<any> {
|
||||
return this.http.put(`${this.baseUrl}/users/${id}`, data);
|
||||
}
|
||||
}
|
||||
@@ -1,28 +1,13 @@
|
||||
<!--<p>admin.component works!</p>-->
|
||||
|
||||
<app-navigation
|
||||
class="pc-sidebar"
|
||||
[ngClass]="{
|
||||
'navbar-collapsed': navCollapsed,
|
||||
'mob-open': navCollapsedMob
|
||||
}"
|
||||
(NavCollapse)="this.navCollapsed = !this.navCollapsed"
|
||||
/>
|
||||
<app-nav-bar (NavCollapsedMob)="navMobClick()" (NavCollapse)="this.navCollapsed = !this.navCollapsed"/>
|
||||
<app-side-bar-admin
|
||||
class="pc-sidebar"
|
||||
>
|
||||
</app-side-bar-admin>
|
||||
<div class="pc-container">
|
||||
<div class="coded-wrapper">
|
||||
<div class="coded-content">
|
||||
<div class="coded-inner-content">
|
||||
|
||||
<app-breadcrumb />
|
||||
<div class="main-body">
|
||||
<div class="page-wrapper">
|
||||
|
||||
<router-outlet />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pc-menu-overlay" (click)="closeMenu()" (keydown)="handleKeyDown($event)" tabindex="0"></div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@@ -1,22 +1,16 @@
|
||||
.example-container {
|
||||
width: 500px;
|
||||
height: 300px;
|
||||
border: 1px solid rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.example-sidenav-content {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.example-sidenav {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
//---------------
|
||||
.pc-sidebar{
|
||||
top: 120px;
|
||||
top: 65px;
|
||||
overflow-y: auto;
|
||||
background-color: rgba(153, 153, 153, 0.16);
|
||||
|
||||
backdrop-filter: blur(8px);
|
||||
}
|
||||
.pc-container{
|
||||
top: 0px;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import {MatButton} from '@angular/material/button';
|
||||
import { ScrollPanelModule } from 'primeng/scrollpanel';
|
||||
import {MenuItem} from 'primeng/api';
|
||||
import {PanelMenu} from 'primeng/panelmenu';
|
||||
import {SideBarAdminComponent} from '../side-bar-admin.component/side-bar-admin.component';
|
||||
@Component({
|
||||
selector: 'app-admin.component',
|
||||
imports: [
|
||||
@@ -24,6 +25,7 @@ import {PanelMenu} from 'primeng/panelmenu';
|
||||
RouterLink,
|
||||
PanelMenu,
|
||||
NgStyle,
|
||||
SideBarAdminComponent,
|
||||
|
||||
],
|
||||
schemas:[CUSTOM_ELEMENTS_SCHEMA],
|
||||
|
||||
@@ -8,7 +8,7 @@ const ADMIN_ROUTES: Routes = [
|
||||
|
||||
children: [
|
||||
{
|
||||
path: 'welcome',
|
||||
path: 'admin-welcome',
|
||||
loadComponent: () => import('../admin-module/admin-welcome.component/admin-welcome.component').then((c) => c.AdminWelcomeComponent),
|
||||
},
|
||||
{
|
||||
@@ -17,9 +17,12 @@ const ADMIN_ROUTES: Routes = [
|
||||
},
|
||||
{
|
||||
path: 'system',
|
||||
|
||||
loadComponent: () => import('../admin-module/system.component/system.component').then((c) => c.SystemComponent)
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'users',
|
||||
loadComponent: () => import('../admin-module/users.component/users.component').then((c) => c.UsersComponent)
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
<mat-nav-list>
|
||||
<a mat-list-item routerLink="admin-welcome">
|
||||
<span class="entry">
|
||||
<mat-icon>house</mat-icon>
|
||||
@if (!isCollapsed) {
|
||||
<span >Dashboard</span>
|
||||
}
|
||||
</span>
|
||||
</a>
|
||||
<a mat-list-item routerLink="users">
|
||||
<span class="entry">
|
||||
<mat-icon>newspaper</mat-icon>
|
||||
@if (!isCollapsed) {
|
||||
<span >Users</span>
|
||||
}
|
||||
</span>
|
||||
</a>
|
||||
<a mat-list-item routerLink="settings">
|
||||
<span class="entry">
|
||||
<mat-icon>newspaper</mat-icon>
|
||||
@if (!isCollapsed) {
|
||||
<span >Settings</span>
|
||||
}
|
||||
</span>
|
||||
</a>
|
||||
<a mat-list-item routerLink="system">
|
||||
<span class="entry">
|
||||
<mat-icon>newspaper</mat-icon>
|
||||
@if (!isCollapsed) {
|
||||
<span >System</span>
|
||||
}
|
||||
</span>
|
||||
</a>
|
||||
</mat-nav-list>
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
.entry{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
padding:0.75rem;
|
||||
color: rgba(24, 255, 255, 0.96);
|
||||
|
||||
}
|
||||
|
||||
a.mdc-list-item
|
||||
{
|
||||
|
||||
background-color: rgba(24,255,255,0.04);
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SideBarAdminComponent } from './side-bar-admin.component';
|
||||
|
||||
describe('SideBarAdminComponent', () => {
|
||||
let component: SideBarAdminComponent;
|
||||
let fixture: ComponentFixture<SideBarAdminComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [SideBarAdminComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(SideBarAdminComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
import {Component, CUSTOM_ELEMENTS_SCHEMA} from '@angular/core';
|
||||
import {MatListItem, MatNavList} from '@angular/material/list';
|
||||
import {RouterLink} from '@angular/router';
|
||||
import {MatIcon} from '@angular/material/icon';
|
||||
|
||||
@Component({
|
||||
selector: 'app-side-bar-admin',
|
||||
imports: [
|
||||
MatIcon,
|
||||
MatListItem,
|
||||
MatNavList,
|
||||
RouterLink
|
||||
],
|
||||
templateUrl: './side-bar-admin.component.html',
|
||||
styleUrl: './side-bar-admin.component.scss',
|
||||
schemas:[CUSTOM_ELEMENTS_SCHEMA]
|
||||
})
|
||||
export class SideBarAdminComponent {
|
||||
isCollapsed = false;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<table mat-table [dataSource]="users">
|
||||
@for (column of columnsSchema; track column){
|
||||
<ng-container [matColumnDef]="column.key">
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
{{column.label}}
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
@switch (column.type) {
|
||||
@case ('list') {
|
||||
<mat-form-field class="example-chip-list">
|
||||
<mat-chip-grid #chipGrid aria-label="Role selection">
|
||||
@for (role of element.roles; track $index) {
|
||||
<mat-chip-row (removed)="remove(role,element)">
|
||||
{{role.name}}
|
||||
|
||||
<mat-icon
|
||||
matChipRemove
|
||||
[attr.aria-label]="'remove ' + role.name"
|
||||
>
|
||||
cancel
|
||||
</mat-icon>
|
||||
|
||||
</mat-chip-row>
|
||||
}
|
||||
</mat-chip-grid>
|
||||
<input
|
||||
name="currentRole"
|
||||
placeholder="Add role..."
|
||||
[matChipInputFor]="chipGrid"
|
||||
[matAutocomplete]="auto"
|
||||
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
|
||||
[formControl]="rolesControl"
|
||||
[matChipInputAddOnBlur]="true"
|
||||
(matChipInputTokenEnd)="add($event,element)"
|
||||
(input)="change($event,filteredRoles(element.roles))"
|
||||
/>
|
||||
<mat-autocomplete [formControl]="ac"
|
||||
autoActiveFirstOption
|
||||
#auto
|
||||
(optionSelected)="selected(element,$event); ">
|
||||
@for (role of filteredRoles(element.roles); track role) {
|
||||
<mat-option [value]="role">{{role.name}}</mat-option>
|
||||
}
|
||||
</mat-autocomplete>
|
||||
</mat-form-field>
|
||||
}
|
||||
@default {
|
||||
{{ element[column.key] }}
|
||||
}
|
||||
}
|
||||
</td>
|
||||
</ng-container>
|
||||
}
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
||||
</table>
|
||||
@@ -0,0 +1,3 @@
|
||||
.example-chip-list {
|
||||
width: 100%;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { UsersComponent } from './users.component';
|
||||
|
||||
describe('UsersComponent', () => {
|
||||
let component: UsersComponent;
|
||||
let fixture: ComponentFixture<UsersComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [UsersComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(UsersComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,185 @@
|
||||
import {ChangeDetectionStrategy, Component, CUSTOM_ELEMENTS_SCHEMA, model} from '@angular/core';
|
||||
import {UserService} from '../../services/user.service';
|
||||
import {RolesService} from '../../services/roles.service';
|
||||
import {Role} from '../../models/role';
|
||||
import {User} from '../../models/user.model';
|
||||
import {
|
||||
MatCell,
|
||||
MatCellDef, MatColumnDef,
|
||||
MatHeaderCell, MatHeaderCellDef,
|
||||
MatHeaderRow,
|
||||
MatHeaderRowDef,
|
||||
MatRow,
|
||||
MatRowDef, MatTable
|
||||
} from '@angular/material/table';
|
||||
import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms';
|
||||
import {
|
||||
MatAutocomplete,
|
||||
MatAutocompleteSelectedEvent,
|
||||
MatAutocompleteTrigger,
|
||||
MatOption
|
||||
} from '@angular/material/autocomplete';
|
||||
import {
|
||||
MatChip,
|
||||
MatChipGrid,
|
||||
MatChipInput,
|
||||
MatChipInputEvent,
|
||||
MatChipRow,
|
||||
MatChipsModule
|
||||
} from '@angular/material/chips';
|
||||
import {MatIcon} from '@angular/material/icon';
|
||||
import {COMMA, ENTER} from '@angular/cdk/keycodes';
|
||||
import {MatFormField} from '@angular/material/input';
|
||||
import {MatSelect, MatSelectTrigger} from '@angular/material/select';
|
||||
import {AdminModuleService} from '../admin-module.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-users.component',
|
||||
imports: [
|
||||
MatCell,
|
||||
MatCellDef,
|
||||
MatHeaderCell,
|
||||
MatHeaderRow,
|
||||
MatHeaderRowDef,
|
||||
MatRow,
|
||||
MatRowDef,
|
||||
MatTable,
|
||||
MatColumnDef,
|
||||
MatHeaderCellDef,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
MatChipGrid,
|
||||
MatChipRow,
|
||||
MatIcon,
|
||||
MatAutocompleteTrigger,
|
||||
MatChipInput,
|
||||
MatAutocomplete,
|
||||
MatOption,
|
||||
MatFormField,
|
||||
MatSelect,
|
||||
MatSelectTrigger,
|
||||
MatChip,
|
||||
MatChipsModule
|
||||
],
|
||||
templateUrl: './users.component.html',
|
||||
styleUrl: './users.component.scss',
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
||||
})
|
||||
export class UsersComponent {
|
||||
|
||||
readonly separatorKeysCodes: number[] = [ENTER, COMMA];
|
||||
allRoles:Role[] = [];
|
||||
users: User[] = [];
|
||||
|
||||
displayedColumns: string[] = UserColumns.map((col) => col.key)
|
||||
columnsSchema: any = UserColumns
|
||||
|
||||
readonly currentRole = model('');
|
||||
|
||||
rolesControl = new FormControl([]);
|
||||
protected ac = new FormControl('');
|
||||
|
||||
constructor(private userService: UserService,
|
||||
private roleService: RolesService,
|
||||
private adminService:AdminModuleService) {
|
||||
this.getAllRoles();
|
||||
this.getUsers();
|
||||
}
|
||||
|
||||
getAllRoles():any{
|
||||
this.roleService.getAllRoles().subscribe(
|
||||
(data : any) => {
|
||||
this.allRoles = data;
|
||||
console.log(data);
|
||||
},
|
||||
(err : any)=> {
|
||||
this.allRoles = JSON.parse(err.error).message;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
getUsers(){
|
||||
this.userService.getAdminBoard().subscribe(
|
||||
(data : any) => {
|
||||
this.users = data;
|
||||
console.log(data);
|
||||
},
|
||||
(err : any)=> {
|
||||
console.log(JSON.parse(err.error).message);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
filteredRoles(roles : Role[]):any {
|
||||
return this.allRoles.filter(
|
||||
(r:Role) => !roles.some((item) => item.id === r.id),
|
||||
);
|
||||
}
|
||||
|
||||
change($event: Event, roles: Role[]) {
|
||||
roles.filter(
|
||||
(r:Role) => !roles.some((item) => item.name?.toLowerCase() === r.name?.toLowerCase()),
|
||||
)
|
||||
}
|
||||
|
||||
selected(user: User, $event: MatAutocompleteSelectedEvent) {
|
||||
user.roles.push($event.option.value);
|
||||
this.saveUserRoles(user);
|
||||
this.currentRole.set('');
|
||||
$event.option.deselect();
|
||||
}
|
||||
|
||||
add($event: MatChipInputEvent, user:User) {
|
||||
/*const value = ($event.value || '').trim();
|
||||
|
||||
const role = this.allRoles.find(value1 => value1.name === value);
|
||||
if(role){
|
||||
user.roles.push(value);
|
||||
this.saveUserRoles(user);
|
||||
}*/
|
||||
// Clear the input value
|
||||
this.currentRole.set('');
|
||||
}
|
||||
|
||||
remove(role: any, user: User) {
|
||||
const updatedRoles: Role[] = user.roles.filter(
|
||||
(r: Role) => r.id !== role.id // Simple comparison with the role to remove
|
||||
);
|
||||
|
||||
if (updatedRoles && updatedRoles.length >= 1) {
|
||||
user.roles = updatedRoles;
|
||||
this.saveUserRoles(user);
|
||||
}
|
||||
}
|
||||
|
||||
saveUserRoles(user:User){
|
||||
this.adminService.updateUserRoles(user.id, user).subscribe(
|
||||
(data:any) => {
|
||||
console.log(data);
|
||||
},
|
||||
(err:any) => {
|
||||
console.log(err);
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export const UserColumns = [
|
||||
{
|
||||
key: 'username',
|
||||
type: 'text',
|
||||
label: 'Name',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
key: 'email',
|
||||
type: 'text',
|
||||
label: 'Email',
|
||||
},
|
||||
{
|
||||
key: 'roles',
|
||||
type: 'list',
|
||||
label: 'Roles',
|
||||
required: true,
|
||||
}
|
||||
];
|
||||
@@ -80,7 +80,6 @@ export class BoardAdminComponent implements OnInit {
|
||||
return this.allRoles.filter(
|
||||
(r:Role) => !roles.some((item) => item.id === r.id),
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
// private _filter(value: string): string[] {
|
||||
@@ -111,7 +110,7 @@ export class BoardAdminComponent implements OnInit {
|
||||
// this.announcer.announce(`Removed ${fruit}`);
|
||||
// return [...fruits];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
</button>
|
||||
<mat-menu #menu="matMenu">
|
||||
@if (showAdminBoard) {
|
||||
<button mat-menu-item routerLink="admin/welcome">
|
||||
<button mat-menu-item routerLink="admin/admin-welcome">
|
||||
<mat-icon>admin_panel_settings</mat-icon>
|
||||
Admin Panel
|
||||
</button>
|
||||
|
||||
@@ -186,7 +186,9 @@ export class MainComponent implements OnInit{
|
||||
|
||||
this.refreshToolbar();
|
||||
dialogLoginRef.close()
|
||||
this.router.navigate(['main/user/user-welcome']);
|
||||
|
||||
|
||||
this.router.navigate(['main/tutorials']);
|
||||
},
|
||||
err => {
|
||||
dialogLoginRef.componentInstance.openLoginFailedSnackBar(err.error.message);
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<mat-nav-list>
|
||||
<a mat-list-item routerLink="user-welcome">
|
||||
<span class="entry">
|
||||
<mat-icon>house</mat-icon>
|
||||
@if (!isCollapsed) {
|
||||
<span >Dashboard</span>
|
||||
}
|
||||
</span>
|
||||
</a>
|
||||
<a mat-list-item routerLink="tutorials-list">
|
||||
<span class="entry">
|
||||
<mat-icon>newspaper</mat-icon>
|
||||
@if (!isCollapsed) {
|
||||
<span >Tutorials</span>
|
||||
}
|
||||
</span>
|
||||
</a>
|
||||
</mat-nav-list>
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
.entry{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
padding:0.75rem;
|
||||
color: rgba(24, 255, 255, 0.96);
|
||||
|
||||
}
|
||||
|
||||
a.mdc-list-item
|
||||
{
|
||||
|
||||
background-color: rgba(24,255,255,0.04);
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SideBarUserComponent } from './side-bar-user.component';
|
||||
|
||||
describe('SideBarUserComponent', () => {
|
||||
let component: SideBarUserComponent;
|
||||
let fixture: ComponentFixture<SideBarUserComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [SideBarUserComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(SideBarUserComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,20 @@
|
||||
import {Component, CUSTOM_ELEMENTS_SCHEMA} from '@angular/core';
|
||||
import {MatListItem, MatNavList} from '@angular/material/list';
|
||||
import {RouterLink} from '@angular/router';
|
||||
import {MatIcon} from '@angular/material/icon';
|
||||
|
||||
@Component({
|
||||
selector: 'app-side-bar-user',
|
||||
imports: [
|
||||
MatIcon,
|
||||
MatListItem,
|
||||
MatNavList,
|
||||
RouterLink
|
||||
],
|
||||
templateUrl: './side-bar-user.component.html',
|
||||
styleUrl: './side-bar-user.component.scss',
|
||||
schemas:[CUSTOM_ELEMENTS_SCHEMA]
|
||||
})
|
||||
export class SideBarUserComponent {
|
||||
isCollapsed = false;
|
||||
}
|
||||
+1
-1
@@ -200,7 +200,7 @@ export const TutorialColumns = [
|
||||
required: true
|
||||
},
|
||||
{
|
||||
key: 'toBePublished',
|
||||
key: 'tobepublished',
|
||||
type: 'boolean',
|
||||
label: 'To be published',
|
||||
required: true
|
||||
|
||||
@@ -1,34 +1,9 @@
|
||||
<app-side-bar
|
||||
<app-side-bar-user
|
||||
class="pc-sidebar"
|
||||
>
|
||||
|
||||
</app-side-bar>
|
||||
</app-side-bar-user>
|
||||
|
||||
<div class="pc-container">
|
||||
<router-outlet></router-outlet>
|
||||
</div>
|
||||
<!--<mat-toolbar color="primary">-->
|
||||
<!-- <button mat-icon-button aria-label="Menu icon" (click)="toggleMenu()">-->
|
||||
<!-- <mat-icon>menu</mat-icon>-->
|
||||
<!-- </button>-->
|
||||
<!-- <h1>Responsive Material Sidenavigation</h1>-->
|
||||
<!--</mat-toolbar>-->
|
||||
<!--<mat-sidenav-container autosize="true">-->
|
||||
<!-- <mat-sidenav [ngClass]="!isCollapsed ? 'expanded' : ''" [mode]="isMobile ? 'over' : 'side'" [opened]="isMobile ? 'false' : 'true'">-->
|
||||
<!-- <mat-nav-list>-->
|
||||
<!-- <a mat-list-item>-->
|
||||
<!-- <span class="entry">-->
|
||||
<!-- <mat-icon>house</mat-icon>-->
|
||||
<!-- @if (!isCollapsed) {-->
|
||||
<!-- <span >Dashboard</span>-->
|
||||
<!-- }-->
|
||||
<!-- </span>-->
|
||||
<!-- </a>-->
|
||||
<!-- </mat-nav-list>-->
|
||||
<!-- </mat-sidenav>-->
|
||||
<!-- <mat-sidenav-content>-->
|
||||
<!-- Content-->
|
||||
<!-- <router-outlet></router-outlet>-->
|
||||
<!-- </mat-sidenav-content>-->
|
||||
<!--</mat-sidenav-container>-->
|
||||
|
||||
|
||||
@@ -1,49 +1,10 @@
|
||||
|
||||
mat-toolbar{
|
||||
position:fixed;
|
||||
top:0;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
mat-sidenav-container {
|
||||
height:100%;
|
||||
}
|
||||
|
||||
// Move the content down so that it won't be hidden by the toolbar
|
||||
mat-sidenav {
|
||||
padding-top: 3.5rem;
|
||||
transition: width 0.3s ease;
|
||||
@media screen and (min-width: 600px) {
|
||||
padding-top: 4rem;
|
||||
}
|
||||
|
||||
.entry{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
padding:0.75rem;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Move the content down so that it won't be hidden by the toolbar
|
||||
mat-sidenav-content{
|
||||
padding-top: 3.5rem;
|
||||
@media screen and (min-width: 600px) {
|
||||
padding-top: 4rem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.expanded {
|
||||
width: 250px;
|
||||
}
|
||||
|
||||
//---------------
|
||||
.pc-sidebar{
|
||||
top: 65px;
|
||||
overflow-y: auto;
|
||||
background-color: rgba(153, 153, 153, 0.16);
|
||||
|
||||
backdrop-filter: blur(8px);
|
||||
}
|
||||
.pc-container{
|
||||
top: 0px;
|
||||
|
||||
@@ -8,6 +8,7 @@ import {MatIcon} from '@angular/material/icon';
|
||||
import {BreakpointObserver} from '@angular/cdk/layout';
|
||||
import {MatToolbar} from '@angular/material/toolbar';
|
||||
import {MatIconButton} from '@angular/material/button';
|
||||
import {SideBarUserComponent} from '../side-bar-user.component/side-bar-user.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-user.component',
|
||||
@@ -21,7 +22,8 @@ import {MatIconButton} from '@angular/material/button';
|
||||
MatListItem,
|
||||
MatIcon,
|
||||
MatToolbar,
|
||||
MatIconButton
|
||||
MatIconButton,
|
||||
SideBarUserComponent
|
||||
],
|
||||
templateUrl: './user.component.html',
|
||||
styleUrl: './user.component.scss',
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.jambotronGroup.jambotron.controllers;
|
||||
|
||||
|
||||
import com.jambotronGroup.jambotron.model.Tutorial;
|
||||
import com.jambotronGroup.jambotron.model.User;
|
||||
import com.jambotronGroup.jambotron.repository.UserRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -8,8 +9,7 @@ import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
@CrossOrigin(origins = "${app.origin}", maxAge = 3600, allowCredentials="true")
|
||||
@RestController
|
||||
@@ -35,4 +35,31 @@ public class UsersController {
|
||||
return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
@PutMapping("users/{id}")
|
||||
public ResponseEntity<?> updateUserRoles(@PathVariable("id") long id, @RequestBody User user) {
|
||||
Optional<User> userData = userRepository.findById(id);
|
||||
Map<String, Object> map = new LinkedHashMap<String, Object>();
|
||||
if (userData.isPresent()) {
|
||||
User servUser = userData.get();
|
||||
if(user.getRoles().size() > 0)
|
||||
servUser.setRoles(user.getRoles());
|
||||
else {
|
||||
map.put("status", 0);
|
||||
map.put("message", "User must have at least one role");
|
||||
return new ResponseEntity<>(map, HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
try {
|
||||
servUser = userRepository.save(servUser);
|
||||
} catch (Exception e) {
|
||||
|
||||
map.put("status", 0);
|
||||
map.put("message", e.getMessage());
|
||||
return new ResponseEntity<>(map,HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
return new ResponseEntity<>(servUser, HttpStatus.OK);
|
||||
} else {
|
||||
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user