Boris Voropaev 2023-11-20 09:55:21 +03:00
commit 0751f26a4b
16 changed files with 135 additions and 110 deletions

View File

@ -10,6 +10,7 @@ import {AdvisoriesModule} from "@app/_modules/advisories/advisories.module";
import {CompaniesModule} from "@app/_modules/companies/companies.module";
import {AdministrateSitePagesComponent} from "@app/_modules/administration/site-pages/administrate-site-pages.component";
import {PagesModule} from "@app/_modules/pages/pages.module";
import {WidjetModule} from "@app/_modules/widjet/widjet.module";
type PathMatch = "full" | "prefix" | undefined;
const routes = [
@ -18,14 +19,15 @@ const routes = [
];
@NgModule({
imports: [
BrowserModule,
CommonModule,
RouterModule.forRoot(routes),
AdvisoriesModule,
CompaniesModule,
PagesModule,
],
imports: [
BrowserModule,
CommonModule,
RouterModule.forRoot(routes),
AdvisoriesModule,
CompaniesModule,
PagesModule,
WidjetModule,
],
declarations: [
AdministrationPageComponent,
AdministrateCompanyComponent,

View File

@ -1,19 +1,3 @@
<!-- <div class="item home active" >
<div class="bar">
<div class="left">
<button type="button" class="toggle"></button>
</div>
<div class="mid">
<div class="info">
<div class="logo"></div>
<div class="name"><p>Главная страница</p></div>
</div>
</div>
<div class="right right-home">
<div class="menu"><button type="button" class="clear add-child" title="Добавить страницу" (click)="add()"></button></div>
</div>
</div>
</div> -->
<!-- <pages-tree [parent]="mainPage" *ngIf="mainPage"></pages-tree> -->
<button (click)="addLocale()">локаль</button>
<button (click)="addLocale()">Добавить языковую версию</button>
<span (click)="toggle()"><switch [val]="showDeleted"></switch> Показать удаленные</span>
<pages-tree></pages-tree>

View File

@ -8,26 +8,26 @@ import { FormsService } from '@app/_services';
styleUrls: ['administrate-site-pages.component.scss']
})
export class AdministrateSitePagesComponent {
constructor(
private pagesService: PagesService,
private formsService: FormsService,
) {}
constructor(private pagesService: PagesService, private formsService: FormsService) {
}
public mainPage:any;
get showDeleted() {
return this.pagesService.showDeleted;
}
ngOnInit() {
this.fetchRootPage();
}
fetchRootPage() {
let include = ['children.children','parent.children'];
this.pagesService.root({include: include}).subscribe(res => {
this.mainPage = res.data[0].parent?.data;
});
ngOnDestroy() {
this.pagesService.showDeleted = false;
}
addLocale(){
this.formsService.createModel('page', null, null);
addLocale() {
this.formsService.createModel('localePage', null, 'pages-tree-root');
}
toggle() {
this.pagesService.showDeleted = !this.pagesService.showDeleted;
}
}

View File

@ -17,7 +17,7 @@ export class HeaderUserBarComponent {
subscriptionUser: Subscription;
constructor(
public authService: AuthenticationService,
public authService: AuthenticationService,
private router: Router,
private pagesService: PagesService) {
this.subscriptionUser = this.authService.user.subscribe(user => {
@ -33,7 +33,7 @@ export class HeaderUserBarComponent {
}
ngOnInit() {
}
ngOnDestroy() {
@ -44,13 +44,13 @@ export class HeaderUserBarComponent {
close() {
setTimeout(() => {
this.ddHidden = true;
}, 10);
}, 10);
}
logout() {
if (confirm('Вы деествительно хотите выйти из системы?')) {
this.pagesService.editMode.next(false)
this.pagesService.editMode = false;
this.authService.logout();
this.ddHidden = true;
this.router.navigate(['']).then();

View File

@ -30,11 +30,11 @@ export class JumbotronComponent {
}
get editMode(){
return this.pagesService.editMode.value
return this.pagesService.editMode;
}
toggleEditMode(){
this.pagesService.editMode.next(!this.editMode)
this.pagesService.editMode = !this.pagesService.editMode;
}
}

View File

@ -10,7 +10,6 @@ import {ListsService} from "@app/_services";
})
export class PageComponent {
public page: any;
public editMode: boolean;
public loading = false;
private url: string;
private inited = false;
@ -27,6 +26,9 @@ export class PageComponent {
}
get editMode() {
return this.pagesService.editMode;
}
get permissions() {
return this.page?.permissions;
@ -41,9 +43,6 @@ export class PageComponent {
this.listsService.controls().subscribe(res => {
this.inited ? this.fetch() : this.inited = true;
});
this.pagesService.editMode.subscribe(
mode=>this.editMode = mode
)
}
ngOnDestroy() {
@ -51,12 +50,11 @@ export class PageComponent {
}
onNavigationEnd(event: NavigationEnd) {
let url = event.url.split('(')[0];
url = url.split('?')[0];
let url = event.url.split('(')[0].split('?')[0];
if (url !== this.url) {
this.url = url;
this.fetch();
this.pagesService.editMode.next(false);
this.pagesService.editMode = false;
}
}

View File

@ -2,7 +2,6 @@ import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {RouterModule, Routes} from "@angular/router";
import {PageNotFoundComponent} from "@app/_modules/pages/not-found/page-not-found.component";
import {HomepageComponent} from "@app/_modules/pages/home/homepage.component";
import {PageComponent} from "@app/_modules/pages/page/page.component";
import {pageBreadcrumbsComponent} from "@app/_modules/pages/page/breadcrumbs/page-breadcrumbs.component";
import {PageSectionsModule} from "@app/_modules/pages/sections/page-sections.module";

View File

@ -1,24 +1,21 @@
<div class="item" [class.active]="active" (click)="touched = true">
<div class="item" [class.active]="active" [class.red]="isDeleted" [class.hidden]="isDeleted && !showDeleted" [class.home]="!parent" (click)="touched = true">
<div class="bar">
<div class="left">
<button *ngIf="children?.length" type="button" class="toggle" (click)="toggle()"></button>
<button *ngIf="page.hasChildren" type="button" class="toggle" (click)="toggle()"></button>
</div>
<div class="mid">
<div class="info">
<div class="logo" [class.orphan]="!parent">
<img *ngIf="logo" [src]="logo" alt="" />
<span *ngIf="!logo">{{noLogoLetters}}</span>
</div>
<div class="name"><p><a [routerLink]="page.link" target="_blank" [innerHTML]="page.name"></a></p></div>
<div class="logo"></div>
<div class="name"><p><a [routerLink]="page.link" target="_blank">{{page.name}}</a></p></div>
</div>
</div>
<div class="right">
<div class="menu">
<div class="move" title="Переместить" *ngIf="parent"></div>
<!-- <button type="button" class="clear move" title="Переместить"></button> -->
<!--div class="move" title="Переместить"></div-->
<button type="button" class="clear clone" title="Копировать" (click)="clone()" *ngIf="parent"></button>
<button type="button" class="clear add-child" title="Добавить страницу" (click)="add()"></button>
<button type="button" class="clear edit" title="Редактировать" (click)="edit()" [class.orphan]="!parent"></button>
<button type="button" class="clear close-blue" title="Удалить" (click)="delete()" *ngIf="parent"></button>
<button type="button" class="clear close-blue" title="Удалить" (click)="delete()" *ngIf="page.slug"></button>
</div>
</div>
</div>

View File

@ -0,0 +1,2 @@
.red {color: #ff0000;}
.hidden {display: none;}

View File

@ -1,5 +1,4 @@
import {Component, Input} from '@angular/core';
import {Router} from "@angular/router";
import {PagesService} from "@app/_services/pages.service";
import {FormsService, ListsService} from "@app/_services";
import {Subscription} from "rxjs";
@ -16,11 +15,7 @@ export class PagesTreeItemComponent {
public touched = false;
public subscription: Subscription;
constructor(
private router: Router,
private pagesService:
PagesService, private formsService: FormsService,
private listsService: ListsService) {
constructor(public pagesService: PagesService, private formsService: FormsService, private listsService: ListsService) {
}
ngOnInit() {
@ -29,6 +24,10 @@ export class PagesTreeItemComponent {
});
}
ngOnDestroy() {
this.subscription?.unsubscribe();
}
get listId() {
return this.page.id;
@ -50,9 +49,16 @@ export class PagesTreeItemComponent {
return this.page.children?.data;
}
get isDeleted() {
return !!this.page.deletedAt;
}
get showDeleted() {
return this.pagesService.showDeleted;
}
fetch() {
let include = ['children.children'];
let include = ['children'];
this.pagesService.show(this.page.id, {include: include.join(',')}).subscribe(res => {
this.page = res.data;
});
@ -70,12 +76,16 @@ export class PagesTreeItemComponent {
delete() {
if (confirm('r u sure?')) this.pagesService.delete(this.page.id).subscribe(res => {
this.listsService.refresh(this.parentListId);
this.listsService.changed.next(this.page);
});
}
clone() {
if (confirm(`Копировать страницу ${this.page.name}?`)) this.pagesService.clone(this.page.id, {recursive: true}).subscribe(res => {
this.listsService.refresh(this.parentListId);
});
}
toggle() {
this.active = !this.active;
if (this.active) this.fetch();
}
}

View File

@ -1,3 +1,3 @@
<div class="items" [sortablejs]="pages" [sortablejsOptions]="options">
<div class="items" [sortablejs]="pages" [sortablejsOptions]="parent ? optionsPages : optionsLocales">
<pages-tree-item [id]="page.id" [page]="page" [parent]="parent" *ngFor="let page of pages"></pages-tree-item>
</div>

View File

@ -61,6 +61,7 @@
border-radius: 100px;
background-color: var(--prime);
color: #ffffff;
cursor: move;
span{
display: none;
@ -117,6 +118,10 @@
background-image: url('~src/assets/images/icons/drag-n-drop_24.svg');
cursor: move;
}
&.clone {
width: 24px;
background-color: #dedede;
}
}
.orphan{
margin-right: 48px;

View File

@ -15,34 +15,30 @@ export class PagesTreeComponent {
public pages = <any>[];
subscription: Subscription;
public options: SortableOptions = {
public optionsPages: SortableOptions = {
group: 'site-pages',
handle: '.move',
onUpdate: (event: any) => {
this.move(event);
},
onAdd: (event: any) => {
this.move(event);
}
handle: '.logo',
onUpdate: (event: any) => {this.move(event)},
onAdd: (event: any) => {this.move(event)}
};
public optionsLocales: SortableOptions = {
group: 'site-locales',
handle: '.logo',
onUpdate: (event: any) => {this.move(event)},
onAdd: (event: any) => {this.move(event)}
};
constructor(private router: Router, private pagesService: PagesService, private listsService: ListsService, private formsService: FormsService) {
}
get listId() {
return 'pages-tree-root';
return this.parent?.id || 'pages-tree-root';
}
ngOnInit() {
this.fetch()
// if (!this.parent) this.subscription = this.listsService.controls(this.listId).subscribe(res => {
// this.fetch();
// });
}
ngOnChanges() {
this.pages = this.parent?.children?.data;
this.subscription = this.listsService.controls(this.listId).subscribe(res => {
this.fetch();
});
}
ngOnDestroy() {
@ -55,30 +51,27 @@ export class PagesTreeComponent {
fetchRootPages() {
let include = ['children'];
this.pagesService.root({include: include}).subscribe(res => {
this.pagesService.root({include: include.join(','), withTrashed: true}).subscribe(res => {
this.pages = res.data;
});
}
fetchSubpages() {
let include = ['children.children'];
this.pagesService.show(this.parent.id, {include: include.join(',')}).subscribe(res => {
let include = ['children'];
this.pagesService.show(this.parent.id, {include: include.join(','), withTrashed: true}).subscribe(res => {
this.pages = res.data?.children?.data;
});
}
add() {
//this.listsService.result('headerMenu').next(result);
this.formsService.createModel('page', null, this.listId);
}
move(event: any) {
if(this.parent?.id) {
this.pagesService.move(event.item.id, {parent: this.parent?.id, ord: event.newIndex}).subscribe(res => {
this.listsService.changed.next(event);
});
}
this.pagesService.move(event.item.id, {parent: this.parent?.id, ord: event.newIndex}).subscribe(res => {
this.listsService.refresh(this.parent?.id);
});
}
}

View File

@ -4,11 +4,7 @@ import {BehaviorSubject} from "rxjs";
@Injectable({providedIn: 'root'})
export class ListsService {
public lists: any = {};
public changed: BehaviorSubject<any>
constructor(
) {
this.changed =new BehaviorSubject({})
constructor() {
}

View File

@ -9,7 +9,8 @@ export class PagesService {
public currentPageSubject = new BehaviorSubject<any>(null);
public rootPageSubject = new BehaviorSubject<any>(null);
public metaSubject = new BehaviorSubject<any>({title: '', description: '', keywords: ''});
public editMode = new BehaviorSubject<boolean>(false);
public editModeSubject = new BehaviorSubject<boolean>(false);
public showDeletedSubject = new BehaviorSubject<boolean>(false);
public menuSelectedLink: string;
constructor(private http: HttpClient) {
@ -31,9 +32,22 @@ export class PagesService {
this.rootPageSubject.next(val);
}
get editMode() {
return this.editModeSubject.value;
}
set editMode(value: boolean) {
this.editModeSubject.next(value);
}
get showDeleted() {
return this.showDeletedSubject.value;
}
set showDeleted(value: boolean) {
this.showDeletedSubject.next(value);
}
root(params?: {}): Observable<any> {
root(params?: any): Observable<any> {
return this.http.get(`${environment.apiUrl}/api/pages/root`, {params: params});
}
@ -43,11 +57,11 @@ export class PagesService {
return this.http.get(`${environment.apiUrl}/api/pages/find`, {params: params});
}
list(params?: {}): Observable<any> {
list(params?: any): Observable<any> {
return this.http.get(`${environment.apiUrl}/api/pages`, {params: params});
}
show(id: string, params?: {}): Observable<any> {
show(id: string, params?: any): Observable<any> {
return this.http.get<any>(`${environment.apiUrl}/api/pages/${id}`, {params: params});
}
@ -60,9 +74,12 @@ export class PagesService {
}
move(id: string, data: any): Observable<any> {
return this.http.put(`${environment.apiUrl}/api/pages/${id}`, data);
return this.http.put(`${environment.apiUrl}/api/pages/move/${id}`, data);
}
clone(id: string, data: any): Observable<any> {
return this.http.put(`${environment.apiUrl}/api/pages/clone/${id}`, data);
}
setMetaFromPage(page: any) {
this.setMeta({title: page?.title || page?.name, description: page?.description || '', keywords: page?.keywords || ''});

View File

@ -0,0 +1,22 @@
// This file can be replaced during build by using the `fileReplacements` array.
// `ng build` replaces `environment.ts` with `environment.prod.ts`.
// The list of file replacements can be found in `angular.json`.
export const environment = {
production: false,
apiUrl: 'http://api.nircms.lc',
clientId: 2,
clientSecret: 'kzZNPvuxFIhDmJkzdC6ug4b6TplrzGrnCqi0Zgr9',
project: null,
defaultLocale: 'ru'
};
/*
* For easier debugging in development mode, you can import the following file
* to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
*
* This import should be commented out in production mode because it will have a negative impact
* on performance if an error is thrown.
*/
// import 'zone.js/plugins/zone-error'; // Included with Angular CLI.