Boris Voropaev 2023-12-13 14:03:57 +03:00
commit 3c58b50ada
15 changed files with 257 additions and 17 deletions

View File

@ -12,6 +12,8 @@ import {AdministrateSitePagesComponent} from "@app/_modules/administration/site-
import {PagesModule} from "@app/_modules/pages/pages.module";
import {WidjetModule} from "@app/_modules/widjet/widjet.module";
import {AdministrateLicenceComponent} from "@app/_modules/administration/licence/administrate-licence.component";
import {AdministrateUsersComponent} from "@app/_modules/administration/users/administrate-users.component";
import {UsersModule} from "@app/_modules/users/users.module";
type PathMatch = "full" | "prefix" | undefined;
const routes = [
@ -20,21 +22,23 @@ const routes = [
];
@NgModule({
imports: [
BrowserModule,
CommonModule,
RouterModule.forRoot(routes),
AdvisoriesModule,
CompaniesModule,
PagesModule,
WidjetModule,
],
imports: [
BrowserModule,
CommonModule,
RouterModule.forRoot(routes),
AdvisoriesModule,
CompaniesModule,
PagesModule,
WidjetModule,
UsersModule,
],
declarations: [
AdministrationPageComponent,
AdministrateCompanyComponent,
AdministrateCommitteeComponent,
AdministrateSitePagesComponent,
AdministrateLicenceComponent
AdministrateLicenceComponent,
AdministrateUsersComponent
],
exports: [
RouterModule

View File

@ -11,6 +11,7 @@
<administrate-committee *ngSwitchCase="'committee'"></administrate-committee>
<administrate-site-pages *ngSwitchCase="'site-pages'"></administrate-site-pages>
<administrate-licence *ngSwitchCase="'licence'"></administrate-licence>
<administrate-users *ngSwitchCase="'users'"></administrate-users>
<p *ngSwitchDefault>Страница не найдена</p>
</div>
</div>

View File

@ -35,7 +35,7 @@ export class AdministrationPageComponent {
makeTabs() {
//this.tabs = [{name: 'company', title: 'Структура ФАУ «ФЦС»'}, {name: 'committee', title: 'Структура ТК 465'}];
//if (this.authService.isSuperAdmin) this.tabs.push({name: 'site-pages', title: 'Структура сайта'});
this.tabs = [{name: 'site-pages', title: 'Структура сайта'}, {name: 'licence', title: 'Данные о лицензии'}];
this.tabs = [{name: 'site-pages', title: 'Структура сайта'}, {name: 'users', title: 'Пользователи'}, {name: 'licence', title: 'Данные о лицензии'}];
this.switchTab(this.route.snapshot.paramMap.get('tab'));
}

View File

@ -0,0 +1,2 @@
<users-list *ngIf="isAdmin"></users-list>
<p *ngIf="!isAdmin">У вас нет прав на просмотр этого раздела</p>

View File

@ -0,0 +1,19 @@
import {Component} from '@angular/core';
import {AuthenticationService} from "@app/_services";
@Component({
selector: 'administrate-users',
templateUrl: 'administrate-users.component.html',
styleUrls: ['administrate-users.component.scss']
})
export class AdministrateUsersComponent {
constructor(private authService: AuthenticationService) {
}
get isAdmin() {
return this.authService.isAdmin;
}
ngOnInit() {
}
}

View File

@ -0,0 +1,16 @@
<div class="item">
<div class="left">
<div class="avatar">
<img *ngIf="avatar" [src]="avatar.links.thumb" />
<span *ngIf="!avatar" class="initials">{{user.initials}}</span>
</div>
</div>
<div class="middle">
<div class="name">{{user.name}} • <span class="role {{role.name}}">{{role.title}}</span></div>
<div class="position">{{user.position}}</div>
</div>
<div class="right">
<button class="btn icon edit" (click)="edit()" title="Редактировать"></button>
<button class="btn icon trash" (click)="delete()" title="Удалить"></button>
</div>
</div>

View File

@ -0,0 +1,66 @@
.item {
display: flex;
flex-direction: row;
align-items: center;
.left {
margin-right: 8px;
flex-shrink: 0;
.avatar {
display: flex;
width: 40px;
height: 40px;
border-radius: 100px;
background-color: #167ABF;
overflow: hidden;
img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
}
.initials {
margin: auto;
color: #ffffff;
text-align: center;
}
}
}
.middle {
flex-grow: 1;
.name {
}
.role {
&.User {color: #20802D;}
&.Editor {color: #999926;}
&.Administrator {color: #D91519;}
}
.position {
color: #666666;
}
}
.right {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-end;
gap: 24px;
margin-left: 24px;
}
}
@media screen and (max-width: 600px) {
.item {
.right {
gap: 12px;
margin-left: 12px;
}
}
}

View File

@ -0,0 +1,37 @@
import {Component, Input} from '@angular/core';
import {FormsService, ListsService, UsersService} from "@app/_services";
@Component({
selector: 'users-list-item',
templateUrl: 'users-list-item.component.html',
styleUrls: ['users-list-item.component.scss']
})
export class UsersListItemComponent {
@Input() user: any;
@Input() listId: string;
constructor(private usersService: UsersService, private formsService: FormsService, private listsService: ListsService) {
}
get role() {
return this.user.roles?.data[0];
}
get avatar() {
return this.user.avatar?.data;
}
ngOnInit() {
}
edit() {
this.formsService.editModel('user', this.user.id, null, this.listId);
}
delete() {
if (confirm(`Удалить пользователя ${this.user.name}?`)) this.usersService.delete(this.user.id).subscribe(res => {
this.listsService.refresh(this.listId, true);
});
}
}

View File

@ -0,0 +1,5 @@
<div class="bar">
<div class="title">Список сотрудников</div>
<div class="buttons"><button type="button" class="btn" (click)="add()" title="Создать сотрудника">+</button></div>
</div>
<users-list-item [user]="user" [listId]="listId" *ngFor="let user of users"></users-list-item>

View File

@ -0,0 +1,25 @@
.bar {
display: flex;
flex-direction: row;
align-items: stretch;
padding: 12px 0;
border-top: #E0E0E0 solid 1px;
border-bottom: #E0E0E0 solid 1px;
.title {
flex-grow: 1;
font-weight: bold;
}
.buttons {
display: flex;
flex-direction: row;
align-items: center;
gap: 24px;
flex-shrink: 0;
}
}
users-list-item {
display: block;
padding: 12px 0;
border-bottom: #E0E0E0 solid 1px;
}

View File

@ -0,0 +1,49 @@
import {Component} from '@angular/core';
import {AuthenticationService, FormsService, ListsService, UsersService} from "@app/_services";
import {Subscription} from "rxjs";
@Component({
selector: 'users-list',
templateUrl: 'users-list.component.html',
styleUrls: ['users-list.component.scss']
})
export class UsersListComponent {
controlsSubscription: Subscription;
constructor(private usersService: UsersService, private listsService: ListsService, private formsService: FormsService, private authService: AuthenticationService) {
}
get listId(): string {
return 'users-list';
}
get users() {
return this.listsService.result(this.listId).value?.data;
}
ngOnInit() {
this.controlsSubscription = this.listsService.controls(this.listId).subscribe(data => {
this.fetch();
});
}
ngOnDestroy() {
this.controlsSubscription?.unsubscribe();
}
fetch() {
let include = ['avatar', 'roles'];
this.usersService.list({include: include.join(',')}).subscribe(res => {
this.listsService.result(this.listId).next(res);
this.authService.getCurrentUser();
});
}
add() {
this.formsService.createModel('user', null, this.listId);
}
}

View File

@ -3,6 +3,8 @@ import {CommonModule} from '@angular/common';
import {RouterModule} from "@angular/router";
import {AuthGuard} from "@app/_helpers";
import {UserProfileComponent} from "@app/_modules/users/profile/user-profile.component";
import {UsersListComponent} from "@app/_modules/users/list/users-list.component";
import {UsersListItemComponent} from "@app/_modules/users/list/item/users-list-item.component";
const routes = [
{path: 'profile', component: UserProfileComponent, canActivate: [AuthGuard]}
@ -14,10 +16,13 @@ const routes = [
RouterModule.forRoot(routes)
],
declarations: [
UserProfileComponent
UserProfileComponent,
UsersListComponent,
UsersListItemComponent
],
exports: [
RouterModule
RouterModule,
UsersListComponent
]
})
export class UsersModule {}

View File

@ -8,9 +8,20 @@ export class UsersService {
constructor(private http: HttpClient) {
}
me(params: any): Observable<any> {
if (!params) params = {include: 'avatar,membership.company,roles,privileges'};
return this.http.get<any>(`${environment.apiUrl}/api/me`, {params: params});
list(params?: any): Observable<any> {
return this.http.get(`${environment.apiUrl}/api/users`, {params: params});
}
show(id: string, params?: any): Observable<any> {
return this.http.get(`${environment.apiUrl}/api/users/${id}`, {params: params});
}
me(params?: any): Observable<any> {
if (!params) params = {include: 'avatar,membership.company,roles,privileges'};
return this.http.get(`${environment.apiUrl}/api/me`, {params: params});
}
delete(id: string): Observable<any> {
return this.http.delete(`${environment.apiUrl}/api/users/${id}`);
}
}

View File

@ -6,7 +6,7 @@ export const environment = {
production: false,
apiUrl: 'http://api.nircms.lc',
clientId: 2,
clientSecret: 'E4BoAclC9X3gre4Wr4XXmU3Y7sXTEtFSk3iCSkIm',
clientSecret: 'SSLFpp0u4fAgqSTNamgQdqUsb2mNzj921Ak3DVRI',
project: null,
licence: 'POUFLO4YW7SU',
defaultLocale: 'ru'