Merge pull request #74 from liosha84/development

Development
This commit is contained in:
liosha84
2025-08-07 17:26:32 +03:00
committed by GitHub
4 changed files with 112 additions and 135 deletions
@@ -4,4 +4,5 @@ export class User {
email?:string; email?:string;
password?:string; password?:string;
roles?:any; roles?:any;
isEdit?: boolean;
} }
@@ -5,49 +5,65 @@
{{column.label}} {{column.label}}
</th> </th>
<td mat-cell *matCellDef="let element"> <td mat-cell *matCellDef="let element">
@if(!element.isEdit){
@switch (column.type) { @switch (column.type) {
@case ('list') { @case ('list') {
<mat-form-field class="example-chip-list"> <mat-button-toggle-group
<mat-chip-grid #chipGrid aria-label="Role selection"> name="ingredients"
@for (role of element.roles; track $index) { aria-label="Ingredients"
<mat-chip-row (removed)="remove(role,element)"> [hideMultipleSelectionIndicator]="false"
{{role.name}} multiple
disabled
<mat-icon
matChipRemove
[attr.aria-label]="'remove ' + role.name"
> >
cancel @for (role of allRoles; track $index) {
</mat-icon> <mat-button-toggle value="{{role.name}}"
[checked]=isChecked(element,role)
</mat-chip-row> (change)="onValChange(element,role)"
[disabled]=isDisabled(element,role)
>{{role.name}}</mat-button-toggle>
} }
</mat-chip-grid> </mat-button-toggle-group>
<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> @case('isEdit'){
</mat-form-field> <button mat-button (click)="element.isEdit = !element.isEdit">
Edit
</button>
} }
@default { @default {
{{ element[column.key] }} {{ element[column.key] }}
} }
} }
} @else {
@switch (column.type) {
@case ('list') {
<mat-button-toggle-group
name="ingredients"
aria-label="Ingredients"
[hideMultipleSelectionIndicator]="false"
multiple
>
@for (role of allRoles; track $index) {
<mat-button-toggle value="{{role.name}}"
[checked]=isChecked(element,role)
(change)="onValChange(element,role)"
[disabled]=isDisabled(element,role)
>{{role.name}}</mat-button-toggle>
}
</mat-button-toggle-group>
}
@case('isEdit'){
<button
mat-button
(click)="saveUserRoles(element)"
>
Done
</button>
}
@default {
{{ element[column.key] }}
}
}
}
</td> </td>
</ng-container> </ng-container>
} }
@@ -1,23 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing';
import { UsersComponent } from './users.component'; import { UsersComponent } from './users.component';
//
describe('UsersComponent', () => { // describe('UsersComponent', () => {
let component: UsersComponent; // let component: UsersComponent;
let fixture: ComponentFixture<UsersComponent>; // let fixture: ComponentFixture<UsersComponent>;
//
beforeEach(async () => { // beforeEach(async () => {
await TestBed.configureTestingModule({ // await TestBed.configureTestingModule({
imports: [UsersComponent] // imports: [UsersComponent]
}) // })
.compileComponents(); // .compileComponents();
//
fixture = TestBed.createComponent(UsersComponent); // fixture = TestBed.createComponent(UsersComponent);
component = fixture.componentInstance; // component = fixture.componentInstance;
fixture.detectChanges(); // fixture.detectChanges();
}); // });
//
it('should create', () => { // it('should create', () => {
expect(component).toBeTruthy(); // expect(component).toBeTruthy();
}); // });
}); // });
@@ -1,4 +1,4 @@
import {Component, CUSTOM_ELEMENTS_SCHEMA, model} from '@angular/core'; import {Component, CUSTOM_ELEMENTS_SCHEMA} from '@angular/core';
import {UserService} from '../../../services/user.service'; import {UserService} from '../../../services/user.service';
import {RolesService} from '../../../services/roles.service'; import {RolesService} from '../../../services/roles.service';
import {Role} from '../../../models/role'; import {Role} from '../../../models/role';
@@ -12,26 +12,14 @@ import {
MatRow, MatRow,
MatRowDef, MatTable MatRowDef, MatTable
} from '@angular/material/table'; } from '@angular/material/table';
import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms'; import {FormsModule, ReactiveFormsModule} from '@angular/forms';
import { import {
MatAutocomplete,
MatAutocompleteSelectedEvent,
MatAutocompleteTrigger,
MatOption
} from '@angular/material/autocomplete';
import {
MatChip,
MatChipGrid,
MatChipInput,
MatChipInputEvent,
MatChipRow,
MatChipsModule MatChipsModule
} from '@angular/material/chips'; } 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'; import {AdminModuleService} from '../admin-module.service';
import {MatButtonToggle, MatButtonToggleGroup} from '@angular/material/button-toggle';
import {MatButton} from '@angular/material/button';
@Component({ @Component({
selector: 'app-users.component', selector: 'app-users.component',
@@ -48,15 +36,10 @@ import {AdminModuleService} from '../admin-module.service';
MatHeaderCellDef, MatHeaderCellDef,
FormsModule, FormsModule,
ReactiveFormsModule, ReactiveFormsModule,
MatChipGrid, MatChipsModule,
MatChipRow, MatButtonToggleGroup,
MatIcon, MatButtonToggle,
MatAutocompleteTrigger, MatButton
MatChipInput,
MatAutocomplete,
MatOption,
MatFormField,
MatChipsModule
], ],
templateUrl: './users.component.html', templateUrl: './users.component.html',
styleUrl: './users.component.scss', styleUrl: './users.component.scss',
@@ -64,18 +47,12 @@ import {AdminModuleService} from '../admin-module.service';
}) })
export class UsersComponent { export class UsersComponent {
readonly separatorKeysCodes: number[] = [ENTER, COMMA];
allRoles:Role[] = []; allRoles:Role[] = [];
users: User[] = []; users: User[] = [];
displayedColumns: string[] = UserColumns.map((col) => col.key) displayedColumns: string[] = UserColumns.map((col) => col.key)
columnsSchema: any = UserColumns columnsSchema: any = UserColumns
readonly currentRole = model('');
rolesControl = new FormControl([]);
protected ac = new FormControl('');
constructor(private userService: UserService, constructor(private userService: UserService,
private roleService: RolesService, private roleService: RolesService,
private adminService:AdminModuleService) { private adminService:AdminModuleService) {
@@ -107,58 +84,36 @@ export class UsersComponent {
); );
} }
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){ saveUserRoles(user:User){
this.adminService.updateUserRoles(user.id, user).subscribe( this.adminService.updateUserRoles(user.id, user).subscribe(
(data:any) => { (data:any) => {
console.log(data); console.log(data);
user.isEdit = false
}, },
(err:any) => { (err:any) => {
console.log(err); console.log(err);
} }
) )
} }
isChecked(element: User, role: Role) {
let userRoles: Role[] = element.roles;
return element.roles.some((r:Role) => r.id === role.id);
}
onValChange(element:User, role: Role) {
let userRoles: Role[] = element.roles;
if (this.isChecked(element, role)) {
userRoles = userRoles.filter((r:Role) => r.id !== role.id);
}else {
userRoles.push(role);
}
element.roles = userRoles;
}
isDisabled(element:User, role: Role) {
return role.name?.includes(<string>element.username?.toUpperCase());
}
} }
export const UserColumns = [ export const UserColumns = [
@@ -178,5 +133,10 @@ export const UserColumns = [
type: 'list', type: 'list',
label: 'Roles', label: 'Roles',
required: true, required: true,
} },
{
key: 'isEdit',
type: 'isEdit',
label: '',
},
]; ];