Handle redirects & First design steps
This commit is contained in:
parent
7b8e818339
commit
99960572ea
@ -1,16 +1,27 @@
|
||||
from flask import redirect
|
||||
from flask import redirect, jsonify
|
||||
|
||||
from api.route import Route
|
||||
from core.logger import Logger
|
||||
from data.schemas.public.short_url import ShortUrl
|
||||
from data.schemas.public.short_url_dao import shortUrlDao
|
||||
|
||||
BasePath = f"/"
|
||||
logger = Logger(__name__)
|
||||
|
||||
|
||||
@Route.get(f"{BasePath}/<path:path>")
|
||||
@Route.get(f"/api/find/<path:path>")
|
||||
async def find(path: str):
|
||||
from_db = await shortUrlDao.find_single_by({ShortUrl.short_url: path})
|
||||
if from_db is None:
|
||||
return jsonify(None)
|
||||
|
||||
return jsonify(from_db.to_dto())
|
||||
|
||||
|
||||
@Route.get(f"/api/redirect/<path:path>")
|
||||
async def handle_short_url(path: str):
|
||||
if path.startswith("api/"):
|
||||
path = path.replace("api/", "")
|
||||
|
||||
from_db = await shortUrlDao.find_single_by({ShortUrl.short_url: path})
|
||||
if from_db is None:
|
||||
return {"error": "Short URL not found"}, 404
|
||||
|
@ -22,7 +22,7 @@ class FilterABC[T](ABC):
|
||||
filter_type: Union[Type["FilterABC"], Type[Union[int, str, bool, datetime]]],
|
||||
db_name=None,
|
||||
):
|
||||
if field not in self._obj:
|
||||
if field not in self._obj and db_name not in self._obj:
|
||||
return
|
||||
|
||||
if db_name is None:
|
||||
|
@ -8,6 +8,8 @@ type Group implements DbModel {
|
||||
id: ID
|
||||
name: String
|
||||
|
||||
shortUrls: [ShortUrl]
|
||||
|
||||
deleted: Boolean
|
||||
editor: User
|
||||
createdUtc: String
|
||||
|
@ -21,7 +21,6 @@ input ShortUrlSort {
|
||||
id: SortOrder
|
||||
name: SortOrder
|
||||
description: SortOrder
|
||||
group: GroupSort
|
||||
|
||||
deleted: SortOrder
|
||||
editorId: SortOrder
|
||||
@ -33,7 +32,6 @@ input ShortUrlFilter {
|
||||
id: IntFilter
|
||||
name: StringFilter
|
||||
description: StringFilter
|
||||
group: GroupFilter
|
||||
|
||||
deleted: BooleanFilter
|
||||
editor: IntFilter
|
||||
|
@ -1,4 +1,7 @@
|
||||
from api_graphql.abc.db_model_query_abc import DbModelQueryABC
|
||||
from data.schemas.public.group import Group
|
||||
from data.schemas.public.short_url import ShortUrl
|
||||
from data.schemas.public.short_url_dao import shortUrlDao
|
||||
|
||||
|
||||
class GroupQuery(DbModelQueryABC):
|
||||
@ -6,3 +9,8 @@ class GroupQuery(DbModelQueryABC):
|
||||
DbModelQueryABC.__init__(self, "Group")
|
||||
|
||||
self.set_field("name", lambda x, *_: x.name)
|
||||
self.set_field("shortUrls", self._get_urls)
|
||||
|
||||
@staticmethod
|
||||
async def _get_urls(group: Group, *_):
|
||||
return await shortUrlDao.find_by({ShortUrl.group_id: group.id})
|
||||
|
@ -85,7 +85,13 @@ class Query(QueryABC):
|
||||
.with_dao(groupDao)
|
||||
.with_filter(GroupFilter)
|
||||
.with_sort(Sort[Group])
|
||||
.with_require_any_permission([Permissions.groups, Permissions.short_urls_create, Permissions.short_urls_update])
|
||||
.with_require_any_permission(
|
||||
[
|
||||
Permissions.groups,
|
||||
Permissions.short_urls_create,
|
||||
Permissions.short_urls_update,
|
||||
]
|
||||
)
|
||||
)
|
||||
# partially public to load redirect if not resolved/redirected by api
|
||||
self.field(
|
||||
|
@ -5,6 +5,7 @@ from async_property import async_property
|
||||
|
||||
from core.database.abc.db_model_abc import DbModelABC
|
||||
from core.typing import SerialId
|
||||
from data.schemas.public.group import Group
|
||||
|
||||
|
||||
class ShortUrl(DbModelABC):
|
||||
@ -59,7 +60,16 @@ class ShortUrl(DbModelABC):
|
||||
self._group_id = value
|
||||
|
||||
@async_property
|
||||
async def group(self):
|
||||
async def group(self) -> Optional[Group]:
|
||||
if self._group_id is None:
|
||||
return None
|
||||
|
||||
from data.schemas.public.group_dao import groupDao
|
||||
|
||||
return await groupDao.get_by_id(self._group_id)
|
||||
|
||||
def to_dto(self) -> dict:
|
||||
return {
|
||||
"id": self.id,
|
||||
"target_url": self.target_url,
|
||||
}
|
||||
|
@ -1,34 +1,23 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { NotFoundComponent } from 'src/app/components/error/not-found/not-found.component';
|
||||
import { AuthGuard } from 'src/app/core/guard/auth.guard';
|
||||
import { NgModule } from "@angular/core";
|
||||
import { RouterModule, Routes } from "@angular/router";
|
||||
import { NotFoundComponent } from "src/app/components/error/not-found/not-found.component";
|
||||
import { AuthGuard } from "src/app/core/guard/auth.guard";
|
||||
import { HomeComponent } from "src/app/components/home/home.component";
|
||||
import { RedirectComponent } from "src/app/components/redirect/redirect.component";
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
redirectTo: 'home',
|
||||
pathMatch: 'full',
|
||||
},
|
||||
{
|
||||
path: 'about',
|
||||
redirectTo: 'home',
|
||||
},
|
||||
{
|
||||
path: 'home',
|
||||
path: "",
|
||||
component: HomeComponent,
|
||||
},
|
||||
{
|
||||
path: 'admin',
|
||||
path: "admin",
|
||||
loadChildren: () =>
|
||||
import('./modules/admin/admin.module').then(m => m.AdminModule),
|
||||
import("./modules/admin/admin.module").then((m) => m.AdminModule),
|
||||
canActivate: [AuthGuard],
|
||||
},
|
||||
{ path: '404', component: NotFoundComponent },
|
||||
{
|
||||
path: '**',
|
||||
redirectTo: '404',
|
||||
},
|
||||
{ path: "404", component: NotFoundComponent },
|
||||
{ path: "**", component: RedirectComponent },
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
|
@ -1,4 +1,4 @@
|
||||
<main>
|
||||
<main *ngIf="isLoggedIn; else home">
|
||||
<app-header></app-header>
|
||||
|
||||
<div class="app">
|
||||
@ -30,3 +30,7 @@
|
||||
</p-confirmDialog>
|
||||
</main>
|
||||
<app-spinner></app-spinner>
|
||||
|
||||
<ng-template #home>
|
||||
<router-outlet></router-outlet>
|
||||
</ng-template>
|
@ -1,22 +1,22 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { AppComponent } from './app.component';
|
||||
import { SharedModule } from 'src/app/modules/shared/shared.module';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { AuthService } from 'src/app/service/auth.service';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
import { ErrorHandlingService } from 'src/app/service/error-handling.service';
|
||||
import { ToastService } from 'src/app/service/toast.service';
|
||||
import { ConfirmationService, MessageService } from 'primeng/api';
|
||||
import { of } from 'rxjs';
|
||||
import { HomeComponent } from 'src/app/components/home/home.component';
|
||||
import { FooterComponent } from 'src/app/components/footer/footer.component';
|
||||
import { HeaderComponent } from 'src/app/components/header/header.component';
|
||||
import { NotFoundComponent } from 'src/app/components/error/not-found/not-found.component';
|
||||
import { SpinnerComponent } from 'src/app/components/spinner/spinner.component';
|
||||
import { SidebarComponent } from 'src/app/components/sidebar/sidebar.component';
|
||||
import { TestBed } from "@angular/core/testing";
|
||||
import { ActivatedRoute } from "@angular/router";
|
||||
import { AppComponent } from "./app.component";
|
||||
import { SharedModule } from "src/app/modules/shared/shared.module";
|
||||
import { TranslateModule } from "@ngx-translate/core";
|
||||
import { AuthService } from "src/app/service/auth.service";
|
||||
import { KeycloakService } from "keycloak-angular";
|
||||
import { ErrorHandlingService } from "src/app/service/error-handling.service";
|
||||
import { ToastService } from "src/app/service/toast.service";
|
||||
import { ConfirmationService, MessageService } from "primeng/api";
|
||||
import { of } from "rxjs";
|
||||
import { HomeComponent } from "src/app/components/home/home.component";
|
||||
import { FooterComponent } from "src/app/components/footer/footer.component";
|
||||
import { HeaderComponent } from "src/app/components/header/header.component";
|
||||
import { NotFoundComponent } from "src/app/components/error/not-found/not-found.component";
|
||||
import { SpinnerComponent } from "src/app/components/spinner/spinner.component";
|
||||
import { SidebarComponent } from "src/app/components/sidebar/sidebar.component";
|
||||
|
||||
describe('AppComponent', () => {
|
||||
describe("AppComponent", () => {
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [
|
||||
@ -46,7 +46,7 @@ describe('AppComponent', () => {
|
||||
}).compileComponents();
|
||||
});
|
||||
|
||||
it('should create the app', () => {
|
||||
it("should create the app", () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.componentInstance;
|
||||
expect(app).toBeTruthy();
|
||||
|
@ -1,27 +1,32 @@
|
||||
import { Component, OnDestroy } from '@angular/core';
|
||||
import { SidebarService } from 'src/app/service/sidebar.service';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { AuthService } from 'src/app/service/auth.service';
|
||||
import { Component, OnDestroy } from "@angular/core";
|
||||
import { SidebarService } from "src/app/service/sidebar.service";
|
||||
import { Subject } from "rxjs";
|
||||
import { takeUntil } from "rxjs/operators";
|
||||
import { AuthService } from "src/app/service/auth.service";
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrl: './app.component.scss',
|
||||
selector: "app-root",
|
||||
templateUrl: "./app.component.html",
|
||||
styleUrl: "./app.component.scss",
|
||||
})
|
||||
export class AppComponent implements OnDestroy {
|
||||
showSidebar = false;
|
||||
|
||||
isLoggedIn = false;
|
||||
unsubscribe$ = new Subject<void>();
|
||||
|
||||
constructor(
|
||||
private sidebar: SidebarService,
|
||||
private auth: AuthService
|
||||
private auth: AuthService,
|
||||
) {
|
||||
this.auth.loadUser();
|
||||
|
||||
this.auth.user$.pipe(takeUntil(this.unsubscribe$)).subscribe((user) => {
|
||||
this.isLoggedIn = user !== null && user !== undefined;
|
||||
});
|
||||
|
||||
this.sidebar.visible$
|
||||
.pipe(takeUntil(this.unsubscribe$))
|
||||
.subscribe(visible => {
|
||||
.subscribe((visible) => {
|
||||
this.showSidebar = visible;
|
||||
});
|
||||
}
|
||||
|
@ -1,26 +1,27 @@
|
||||
import { APP_INITIALIZER, ErrorHandler, NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { APP_INITIALIZER, ErrorHandler, NgModule } from "@angular/core";
|
||||
import { BrowserModule } from "@angular/platform-browser";
|
||||
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
import { AppComponent } from './app.component';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
import { HomeComponent } from './components/home/home.component';
|
||||
import { initializeKeycloak } from './core/init-keycloak';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { environment } from '../environments/environment';
|
||||
import { FooterComponent } from 'src/app/components/footer/footer.component';
|
||||
import { HeaderComponent } from 'src/app/components/header/header.component';
|
||||
import { NotFoundComponent } from 'src/app/components/error/not-found/not-found.component';
|
||||
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
|
||||
import { Logger } from 'src/app/service/logger.service';
|
||||
import { SharedModule } from 'src/app/modules/shared/shared.module';
|
||||
import { SpinnerComponent } from 'src/app/components/spinner/spinner.component';
|
||||
import { ConfirmationService, MessageService } from 'primeng/api';
|
||||
import { DialogService } from 'primeng/dynamicdialog';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { SidebarComponent } from './components/sidebar/sidebar.component';
|
||||
import { ErrorHandlingService } from 'src/app/service/error-handling.service';
|
||||
import { AppRoutingModule } from "./app-routing.module";
|
||||
import { AppComponent } from "./app.component";
|
||||
import { KeycloakService } from "keycloak-angular";
|
||||
import { initializeKeycloak } from "./core/init-keycloak";
|
||||
import { HttpClient } from "@angular/common/http";
|
||||
import { environment } from "../environments/environment";
|
||||
import { FooterComponent } from "src/app/components/footer/footer.component";
|
||||
import { HeaderComponent } from "src/app/components/header/header.component";
|
||||
import { NotFoundComponent } from "src/app/components/error/not-found/not-found.component";
|
||||
import { TranslateLoader, TranslateModule } from "@ngx-translate/core";
|
||||
import { TranslateHttpLoader } from "@ngx-translate/http-loader";
|
||||
import { Logger } from "src/app/service/logger.service";
|
||||
import { SharedModule } from "src/app/modules/shared/shared.module";
|
||||
import { SpinnerComponent } from "src/app/components/spinner/spinner.component";
|
||||
import { ConfirmationService, MessageService } from "primeng/api";
|
||||
import { DialogService } from "primeng/dynamicdialog";
|
||||
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
|
||||
import { SidebarComponent } from "./components/sidebar/sidebar.component";
|
||||
import { ErrorHandlingService } from "src/app/service/error-handling.service";
|
||||
import { HomeComponent } from "./components/home/home.component";
|
||||
import { RedirectComponent } from "./components/redirect/redirect.component";
|
||||
|
||||
if (environment.production) {
|
||||
Logger.enableProductionMode();
|
||||
@ -35,12 +36,13 @@ export function HttpLoaderFactory(http: HttpClient) {
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent,
|
||||
HomeComponent,
|
||||
FooterComponent,
|
||||
HeaderComponent,
|
||||
NotFoundComponent,
|
||||
SpinnerComponent,
|
||||
SidebarComponent,
|
||||
HomeComponent,
|
||||
RedirectComponent,
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
@ -48,7 +50,7 @@ export function HttpLoaderFactory(http: HttpClient) {
|
||||
AppRoutingModule,
|
||||
SharedModule,
|
||||
TranslateModule.forRoot({
|
||||
defaultLanguage: 'en',
|
||||
defaultLanguage: "en",
|
||||
loader: {
|
||||
provide: TranslateLoader,
|
||||
useFactory: HttpLoaderFactory,
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed } from "@angular/core/testing";
|
||||
|
||||
import { NotFoundComponent } from 'src/app/components/error/not-found/not-found.component';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { NotFoundComponent } from "src/app/components/error/not-found/not-found.component";
|
||||
import { TranslateModule } from "@ngx-translate/core";
|
||||
|
||||
describe('NotFoundComponent', () => {
|
||||
describe("NotFoundComponent", () => {
|
||||
let component: NotFoundComponent;
|
||||
let fixture: ComponentFixture<NotFoundComponent>;
|
||||
|
||||
@ -20,7 +20,7 @@ describe('NotFoundComponent', () => {
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
it("should create", () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Component } from "@angular/core";
|
||||
|
||||
@Component({
|
||||
selector: 'app-not-found',
|
||||
templateUrl: './not-found.component.html',
|
||||
styleUrls: ['./not-found.component.scss'],
|
||||
selector: "app-not-found",
|
||||
templateUrl: "./not-found.component.html",
|
||||
styleUrls: ["./not-found.component.scss"],
|
||||
})
|
||||
export class NotFoundComponent {}
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed } from "@angular/core/testing";
|
||||
|
||||
import { FooterComponent } from 'src/app/components/footer/footer.component';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { SharedModule } from 'src/app/modules/shared/shared.module';
|
||||
import { FooterComponent } from "src/app/components/footer/footer.component";
|
||||
import { TranslateModule } from "@ngx-translate/core";
|
||||
import { BrowserModule } from "@angular/platform-browser";
|
||||
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
|
||||
import { SharedModule } from "src/app/modules/shared/shared.module";
|
||||
|
||||
describe('FooterComponent', () => {
|
||||
describe("FooterComponent", () => {
|
||||
let component: FooterComponent;
|
||||
let fixture: ComponentFixture<FooterComponent>;
|
||||
|
||||
@ -28,7 +28,7 @@ describe('FooterComponent', () => {
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
it("should create", () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { SettingsService } from 'src/app/service/settings.service';
|
||||
import { Component } from "@angular/core";
|
||||
import { SettingsService } from "src/app/service/settings.service";
|
||||
|
||||
@Component({
|
||||
selector: 'app-footer',
|
||||
templateUrl: './footer.component.html',
|
||||
styleUrls: ['./footer.component.scss'],
|
||||
selector: "app-footer",
|
||||
templateUrl: "./footer.component.html",
|
||||
styleUrls: ["./footer.component.scss"],
|
||||
})
|
||||
export class FooterComponent {
|
||||
constructor(private settings: SettingsService) {}
|
||||
|
@ -1,6 +1,12 @@
|
||||
<header>
|
||||
<div class="header">
|
||||
<div class="flex items-center justify-center">
|
||||
<p-button
|
||||
*ngIf="user"
|
||||
icon="pi pi-bars"
|
||||
class="btn icon-btn p-button-text"
|
||||
(onClick)="toggleSidebar()"
|
||||
></p-button>
|
||||
</div>
|
||||
<div class="logo">
|
||||
<!-- <img src="/assets/images/logo.svg" alt="logo"/>-->
|
||||
|
@ -1,16 +1,16 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { HeaderComponent } from 'src/app/components/header/header.component';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { ConfirmationService, MessageService } from 'primeng/api';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { of } from 'rxjs';
|
||||
import { SharedModule } from 'src/app/modules/shared/shared.module';
|
||||
import { ErrorHandlingService } from 'src/app/service/error-handling.service';
|
||||
import { ToastService } from 'src/app/service/toast.service';
|
||||
import { AuthService } from 'src/app/service/auth.service';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
import { ComponentFixture, TestBed } from "@angular/core/testing";
|
||||
import { HeaderComponent } from "src/app/components/header/header.component";
|
||||
import { TranslateModule } from "@ngx-translate/core";
|
||||
import { ConfirmationService, MessageService } from "primeng/api";
|
||||
import { ActivatedRoute } from "@angular/router";
|
||||
import { of } from "rxjs";
|
||||
import { SharedModule } from "src/app/modules/shared/shared.module";
|
||||
import { ErrorHandlingService } from "src/app/service/error-handling.service";
|
||||
import { ToastService } from "src/app/service/toast.service";
|
||||
import { AuthService } from "src/app/service/auth.service";
|
||||
import { KeycloakService } from "keycloak-angular";
|
||||
|
||||
describe('HeaderComponent', () => {
|
||||
describe("HeaderComponent", () => {
|
||||
let component: HeaderComponent;
|
||||
let fixture: ComponentFixture<HeaderComponent>;
|
||||
|
||||
@ -41,7 +41,7 @@ describe('HeaderComponent', () => {
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
it("should create", () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
@ -1,17 +1,18 @@
|
||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { MenuItem, PrimeNGConfig } from 'primeng/api';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { GuiService } from 'src/app/service/gui.service';
|
||||
import { User } from 'src/app/model/auth/user';
|
||||
import { AuthService } from 'src/app/service/auth.service';
|
||||
import { MenuElement } from 'src/app/model/view/menu-element';
|
||||
import { Component, OnDestroy, OnInit } from "@angular/core";
|
||||
import { MenuItem, PrimeNGConfig } from "primeng/api";
|
||||
import { Subject } from "rxjs";
|
||||
import { takeUntil } from "rxjs/operators";
|
||||
import { TranslateService } from "@ngx-translate/core";
|
||||
import { GuiService } from "src/app/service/gui.service";
|
||||
import { User } from "src/app/model/auth/user";
|
||||
import { AuthService } from "src/app/service/auth.service";
|
||||
import { MenuElement } from "src/app/model/view/menu-element";
|
||||
import { SidebarService } from "src/app/service/sidebar.service";
|
||||
|
||||
@Component({
|
||||
selector: 'app-header',
|
||||
templateUrl: './header.component.html',
|
||||
styleUrls: ['./header.component.scss'],
|
||||
selector: "app-header",
|
||||
templateUrl: "./header.component.html",
|
||||
styleUrls: ["./header.component.scss"],
|
||||
})
|
||||
export class HeaderComponent implements OnInit, OnDestroy {
|
||||
langList: MenuItem[] = [];
|
||||
@ -26,15 +27,21 @@ export class HeaderComponent implements OnInit, OnDestroy {
|
||||
private translateService: TranslateService,
|
||||
private config: PrimeNGConfig,
|
||||
private guiService: GuiService,
|
||||
private auth: AuthService
|
||||
private auth: AuthService,
|
||||
private sidebarService: SidebarService,
|
||||
) {
|
||||
this.guiService.isMobile$
|
||||
.pipe(takeUntil(this.unsubscribe$))
|
||||
.subscribe(isMobile => {
|
||||
.subscribe((isMobile) => {
|
||||
this.isMobile = isMobile;
|
||||
if (isMobile) {
|
||||
this.sidebarService.hide();
|
||||
}
|
||||
});
|
||||
|
||||
this.auth.user$.pipe(takeUntil(this.unsubscribe$)).subscribe(async user => {
|
||||
this.auth.user$
|
||||
.pipe(takeUntil(this.unsubscribe$))
|
||||
.subscribe(async (user) => {
|
||||
this.user = user;
|
||||
await this.initMenuLists();
|
||||
});
|
||||
@ -55,49 +62,24 @@ export class HeaderComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
async initMenuLists() {
|
||||
await this.initMenuList();
|
||||
await this.initLangMenuList();
|
||||
await this.initUserMenuList();
|
||||
}
|
||||
|
||||
async initMenuList() {
|
||||
this.menu = [
|
||||
{
|
||||
label: 'common.news',
|
||||
routerLink: ['/'],
|
||||
icon: 'pi pi-home',
|
||||
},
|
||||
{
|
||||
label: 'header.menu.about',
|
||||
routerLink: ['/about'],
|
||||
icon: 'pi pi-info',
|
||||
},
|
||||
];
|
||||
|
||||
if (this.auth.user$.value) {
|
||||
this.menu.push({
|
||||
label: 'header.menu.admin',
|
||||
routerLink: ['/admin'],
|
||||
icon: 'pi pi-cog',
|
||||
visible: await this.auth.isAdmin(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async initLangMenuList() {
|
||||
this.langList = [
|
||||
{
|
||||
label: 'English',
|
||||
label: "English",
|
||||
command: () => {
|
||||
this.translate('en');
|
||||
this.setLang('en');
|
||||
this.translate("en");
|
||||
this.setLang("en");
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Deutsch',
|
||||
label: "Deutsch",
|
||||
command: () => {
|
||||
this.translate('de');
|
||||
this.setLang('de');
|
||||
this.translate("de");
|
||||
this.setLang("de");
|
||||
},
|
||||
},
|
||||
];
|
||||
@ -114,13 +96,13 @@ export class HeaderComponent implements OnInit, OnDestroy {
|
||||
separator: true,
|
||||
},
|
||||
{
|
||||
label: this.translateService.instant('header.logout'),
|
||||
label: this.translateService.instant("header.logout"),
|
||||
command: () => {
|
||||
this.auth.logout().then(() => {
|
||||
console.log('logout');
|
||||
console.log("logout");
|
||||
});
|
||||
},
|
||||
icon: 'pi pi-sign-out',
|
||||
icon: "pi pi-sign-out",
|
||||
},
|
||||
];
|
||||
}
|
||||
@ -128,18 +110,27 @@ export class HeaderComponent implements OnInit, OnDestroy {
|
||||
translate(lang: string) {
|
||||
this.translateService.use(lang);
|
||||
this.translateService
|
||||
.get('primeng')
|
||||
.subscribe(res => this.config.setTranslation(res));
|
||||
.get("primeng")
|
||||
.subscribe((res) => this.config.setTranslation(res));
|
||||
}
|
||||
|
||||
async loadLang() {
|
||||
const lang = 'en';
|
||||
const lang = "en";
|
||||
this.setLang(lang);
|
||||
this.translate(lang);
|
||||
}
|
||||
|
||||
setLang(lang: string) {
|
||||
// this.settings.setSetting(`lang`, lang);
|
||||
console.log('setLang', lang);
|
||||
console.log("setLang", lang);
|
||||
}
|
||||
|
||||
toggleSidebar() {
|
||||
if (this.sidebarService.visible$.value) {
|
||||
this.sidebarService.hide();
|
||||
return;
|
||||
}
|
||||
|
||||
this.sidebarService.show();
|
||||
}
|
||||
}
|
||||
|
@ -1 +0,0 @@
|
||||
<p>home works!</p>
|
@ -1,8 +1,8 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed } from "@angular/core/testing";
|
||||
|
||||
import { HomeComponent } from './home.component';
|
||||
import { HomeComponent } from "./home.component";
|
||||
|
||||
describe('HomeComponent', () => {
|
||||
describe("HomeComponent", () => {
|
||||
let component: HomeComponent;
|
||||
let fixture: ComponentFixture<HomeComponent>;
|
||||
|
||||
@ -16,7 +16,7 @@ describe('HomeComponent', () => {
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
it("should create", () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
@ -1,8 +1,17 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Component } from "@angular/core";
|
||||
import { AuthService } from "src/app/service/auth.service";
|
||||
|
||||
@Component({
|
||||
selector: 'app-home',
|
||||
templateUrl: './home.component.html',
|
||||
styleUrl: './home.component.scss',
|
||||
selector: "app-home",
|
||||
templateUrl: "./home.component.html",
|
||||
styleUrl: "./home.component.scss",
|
||||
})
|
||||
export class HomeComponent {}
|
||||
export class HomeComponent {
|
||||
constructor(private auth: AuthService) {
|
||||
if (this.auth.user$.value !== undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.auth.login().then(() => {});
|
||||
}
|
||||
}
|
||||
|
1
web/src/app/components/redirect/redirect.component.html
Normal file
1
web/src/app/components/redirect/redirect.component.html
Normal file
@ -0,0 +1 @@
|
||||
<p>redirect works!</p>
|
22
web/src/app/components/redirect/redirect.component.spec.ts
Normal file
22
web/src/app/components/redirect/redirect.component.spec.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import { ComponentFixture, TestBed } from "@angular/core/testing";
|
||||
|
||||
import { RedirectComponent } from "./redirect.component";
|
||||
|
||||
describe("RedirectComponent", () => {
|
||||
let component: RedirectComponent;
|
||||
let fixture: ComponentFixture<RedirectComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [RedirectComponent],
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(RedirectComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it("should create", () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
47
web/src/app/components/redirect/redirect.component.ts
Normal file
47
web/src/app/components/redirect/redirect.component.ts
Normal file
@ -0,0 +1,47 @@
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { SidebarService } from "src/app/service/sidebar.service";
|
||||
import { Router } from "@angular/router";
|
||||
import { HttpClient } from "@angular/common/http";
|
||||
import { environment } from "src/environments/environment";
|
||||
import { ShortUrlDto } from "src/app/model/entities/short-url";
|
||||
|
||||
@Component({
|
||||
selector: "app-redirect",
|
||||
templateUrl: "./redirect.component.html",
|
||||
styleUrl: "./redirect.component.scss",
|
||||
})
|
||||
export class RedirectComponent implements OnInit {
|
||||
constructor(
|
||||
private sidebar: SidebarService,
|
||||
private router: Router,
|
||||
private http: HttpClient,
|
||||
) {
|
||||
this.sidebar.hide();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.handleUrl();
|
||||
}
|
||||
|
||||
handleUrl() {
|
||||
let shortUrl = this.router.url;
|
||||
if (shortUrl === "/") {
|
||||
return;
|
||||
}
|
||||
|
||||
if (shortUrl.startsWith("/")) {
|
||||
shortUrl = shortUrl.substring(1);
|
||||
}
|
||||
|
||||
this.http
|
||||
.get<ShortUrlDto | undefined>(`${environment.api.url}/find/${shortUrl}`)
|
||||
.subscribe(async (response) => {
|
||||
if (!response) {
|
||||
await this.router.navigate(["/404"]);
|
||||
return;
|
||||
}
|
||||
|
||||
window.location.href = `${environment.api.url}/redirect/${shortUrl}`;
|
||||
});
|
||||
}
|
||||
}
|
@ -1,17 +1,17 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed } from "@angular/core/testing";
|
||||
|
||||
import { SidebarComponent } from './sidebar.component';
|
||||
import { SharedModule } from 'src/app/modules/shared/shared.module';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { AuthService } from 'src/app/service/auth.service';
|
||||
import { ErrorHandlingService } from 'src/app/service/error-handling.service';
|
||||
import { ToastService } from 'src/app/service/toast.service';
|
||||
import { ConfirmationService, MessageService } from 'primeng/api';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { of } from 'rxjs';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
import { SidebarComponent } from "./sidebar.component";
|
||||
import { SharedModule } from "src/app/modules/shared/shared.module";
|
||||
import { TranslateModule } from "@ngx-translate/core";
|
||||
import { AuthService } from "src/app/service/auth.service";
|
||||
import { ErrorHandlingService } from "src/app/service/error-handling.service";
|
||||
import { ToastService } from "src/app/service/toast.service";
|
||||
import { ConfirmationService, MessageService } from "primeng/api";
|
||||
import { ActivatedRoute } from "@angular/router";
|
||||
import { of } from "rxjs";
|
||||
import { KeycloakService } from "keycloak-angular";
|
||||
|
||||
describe('SidebarComponent', () => {
|
||||
describe("SidebarComponent", () => {
|
||||
let component: SidebarComponent;
|
||||
let fixture: ComponentFixture<SidebarComponent>;
|
||||
|
||||
@ -40,7 +40,7 @@ describe('SidebarComponent', () => {
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
it("should create", () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
@ -1,13 +1,13 @@
|
||||
import {Component, OnDestroy} from '@angular/core';
|
||||
import {MenuElement} from 'src/app/model/view/menu-element';
|
||||
import {Subject} from 'rxjs';
|
||||
import {SidebarService} from 'src/app/service/sidebar.service';
|
||||
import {takeUntil} from 'rxjs/operators';
|
||||
import { Component, OnDestroy } from "@angular/core";
|
||||
import { MenuElement } from "src/app/model/view/menu-element";
|
||||
import { Subject } from "rxjs";
|
||||
import { SidebarService } from "src/app/service/sidebar.service";
|
||||
import { takeUntil } from "rxjs/operators";
|
||||
|
||||
@Component({
|
||||
selector: 'app-sidebar',
|
||||
templateUrl: './sidebar.component.html',
|
||||
styleUrl: './sidebar.component.scss',
|
||||
selector: "app-sidebar",
|
||||
templateUrl: "./sidebar.component.html",
|
||||
styleUrl: "./sidebar.component.scss",
|
||||
})
|
||||
export class SidebarComponent implements OnDestroy {
|
||||
elements: MenuElement[] = [];
|
||||
@ -17,7 +17,7 @@ export class SidebarComponent implements OnDestroy {
|
||||
constructor(private sidebar: SidebarService) {
|
||||
this.sidebar.elements$
|
||||
.pipe(takeUntil(this.unsubscribe$))
|
||||
.subscribe(elements => {
|
||||
.subscribe((elements) => {
|
||||
this.elements = elements;
|
||||
});
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed } from "@angular/core/testing";
|
||||
|
||||
import { SpinnerComponent } from 'src/app/components/spinner/spinner.component';
|
||||
import { SpinnerComponent } from "src/app/components/spinner/spinner.component";
|
||||
|
||||
describe('SpinnerComponent', () => {
|
||||
describe("SpinnerComponent", () => {
|
||||
let component: SpinnerComponent;
|
||||
let fixture: ComponentFixture<SpinnerComponent>;
|
||||
|
||||
@ -18,7 +18,7 @@ describe('SpinnerComponent', () => {
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
it("should create", () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
@ -1,16 +1,16 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { SpinnerService } from 'src/app/service/spinner.service';
|
||||
import { Component } from "@angular/core";
|
||||
import { SpinnerService } from "src/app/service/spinner.service";
|
||||
|
||||
@Component({
|
||||
selector: 'app-spinner',
|
||||
templateUrl: './spinner.component.html',
|
||||
styleUrls: ['./spinner.component.scss'],
|
||||
selector: "app-spinner",
|
||||
templateUrl: "./spinner.component.html",
|
||||
styleUrls: ["./spinner.component.scss"],
|
||||
})
|
||||
export class SpinnerComponent {
|
||||
showSpinnerState = false;
|
||||
|
||||
constructor(public spinnerService: SpinnerService) {
|
||||
this.spinnerService.showSpinnerState$.subscribe(value => {
|
||||
this.spinnerService.showSpinnerState$.subscribe((value) => {
|
||||
this.showSpinnerState = value;
|
||||
});
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { Directive, inject } from '@angular/core';
|
||||
import { PageDataService } from 'src/app/core/base/page.data.service';
|
||||
import { SpinnerService } from 'src/app/service/spinner.service';
|
||||
import { FilterService } from 'src/app/service/filter.service';
|
||||
import { FormGroup } from '@angular/forms';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { Directive, inject } from "@angular/core";
|
||||
import { PageDataService } from "src/app/core/base/page.data.service";
|
||||
import { SpinnerService } from "src/app/service/spinner.service";
|
||||
import { FilterService } from "src/app/service/filter.service";
|
||||
import { FormGroup } from "@angular/forms";
|
||||
import { ActivatedRoute, Router } from "@angular/router";
|
||||
|
||||
@Directive()
|
||||
export abstract class FormPageBase<
|
||||
@ -27,7 +27,7 @@ export abstract class FormPageBase<
|
||||
protected dataService = inject(PageDataService) as S;
|
||||
|
||||
protected constructor() {
|
||||
const id = this.route.snapshot.params['id'];
|
||||
const id = this.route.snapshot.params["id"];
|
||||
this.validateRoute(id);
|
||||
|
||||
this.buildForm();
|
||||
@ -35,18 +35,18 @@ export abstract class FormPageBase<
|
||||
|
||||
validateRoute(id: string | undefined) {
|
||||
const url = this.router.url;
|
||||
if (url.endsWith('create') && id !== undefined) {
|
||||
throw new Error('Route ends with create but id is defined');
|
||||
if (url.endsWith("create") && id !== undefined) {
|
||||
throw new Error("Route ends with create but id is defined");
|
||||
}
|
||||
if (url.endsWith('edit') && (id === undefined || isNaN(+id))) {
|
||||
throw new Error('Route ends with edit but id is not a number');
|
||||
if (url.endsWith("edit") && (id === undefined || isNaN(+id))) {
|
||||
throw new Error("Route ends with edit but id is not a number");
|
||||
}
|
||||
|
||||
this.nodeId = id ? +id : undefined;
|
||||
}
|
||||
|
||||
close() {
|
||||
const backRoute = this.nodeId ? '../..' : '..';
|
||||
const backRoute = this.nodeId ? "../.." : "..";
|
||||
|
||||
this.router.navigate([backRoute], { relativeTo: this.route }).then(() => {
|
||||
this.filterService.onLoad.emit();
|
||||
|
@ -1,21 +1,21 @@
|
||||
import { Directive, inject, OnDestroy } from '@angular/core';
|
||||
import { PageDataService } from 'src/app/core/base/page.data.service';
|
||||
import { Subject } from 'rxjs';
|
||||
import { Logger } from 'src/app/service/logger.service';
|
||||
import { QueryResult } from 'src/app/model/entities/query-result';
|
||||
import { SpinnerService } from 'src/app/service/spinner.service';
|
||||
import { FilterService } from 'src/app/service/filter.service';
|
||||
import { Filter } from 'src/app/model/graphql/filter/filter.model';
|
||||
import { Sort } from 'src/app/model/graphql/filter/sort.model';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { PaginatorState } from 'primeng/paginator';
|
||||
import { PageColumns } from 'src/app/core/base/page.columns';
|
||||
import { Directive, inject, OnDestroy } from "@angular/core";
|
||||
import { PageDataService } from "src/app/core/base/page.data.service";
|
||||
import { Subject } from "rxjs";
|
||||
import { Logger } from "src/app/service/logger.service";
|
||||
import { QueryResult } from "src/app/model/entities/query-result";
|
||||
import { SpinnerService } from "src/app/service/spinner.service";
|
||||
import { FilterService } from "src/app/service/filter.service";
|
||||
import { Filter } from "src/app/model/graphql/filter/filter.model";
|
||||
import { Sort } from "src/app/model/graphql/filter/sort.model";
|
||||
import { takeUntil } from "rxjs/operators";
|
||||
import { PaginatorState } from "primeng/paginator";
|
||||
import { PageColumns } from "src/app/core/base/page.columns";
|
||||
import {
|
||||
TableColumn,
|
||||
TableRequireAnyPermissions,
|
||||
} from 'src/app/modules/shared/components/table/table.model';
|
||||
} from "src/app/modules/shared/components/table/table.model";
|
||||
|
||||
const logger = new Logger('PageBase');
|
||||
const logger = new Logger("PageBase");
|
||||
|
||||
@Directive()
|
||||
export abstract class PageBase<
|
||||
@ -96,13 +96,13 @@ export abstract class PageBase<
|
||||
}
|
||||
|
||||
columns: TableColumn<T>[] =
|
||||
'get' in this.columnsService ? this.columnsService.get() : [];
|
||||
"get" in this.columnsService ? this.columnsService.get() : [];
|
||||
|
||||
protected unsubscribe$ = new Subject<void>();
|
||||
|
||||
protected constructor(
|
||||
useQueryParams = false,
|
||||
permissions?: TableRequireAnyPermissions
|
||||
permissions?: TableRequireAnyPermissions,
|
||||
) {
|
||||
this.subscribeToFilterService();
|
||||
this.filterService.reset({
|
||||
@ -113,7 +113,7 @@ export abstract class PageBase<
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
logger.trace('Destroy component');
|
||||
logger.trace("Destroy component");
|
||||
this.unsubscribe$.next();
|
||||
this.unsubscribe$.complete();
|
||||
}
|
||||
@ -125,26 +125,26 @@ export abstract class PageBase<
|
||||
|
||||
this.filterService.filter$
|
||||
.pipe(takeUntil(this.unsubscribe$))
|
||||
.subscribe(filter => {
|
||||
.subscribe((filter) => {
|
||||
this._filter = filter;
|
||||
});
|
||||
|
||||
this.filterService.sort$
|
||||
.pipe(takeUntil(this.unsubscribe$))
|
||||
.subscribe(sort => {
|
||||
.subscribe((sort) => {
|
||||
this._sort = sort;
|
||||
});
|
||||
|
||||
this.filterService.skip$
|
||||
.pipe(takeUntil(this.unsubscribe$))
|
||||
.subscribe(skip => {
|
||||
.subscribe((skip) => {
|
||||
this._skip = skip;
|
||||
});
|
||||
|
||||
this.filterService.take$
|
||||
.pipe(takeUntil(this.unsubscribe$))
|
||||
.subscribe(take => {
|
||||
if (take && Object.prototype.hasOwnProperty.call(take, 'showAll')) {
|
||||
.subscribe((take) => {
|
||||
if (take && Object.prototype.hasOwnProperty.call(take, "showAll")) {
|
||||
this._take = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -1,67 +1,67 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { TableColumn } from 'src/app/modules/shared/components/table/table.model';
|
||||
import { DbModel } from 'src/app/model/entities/db-model';
|
||||
import { Injectable } from "@angular/core";
|
||||
import { TableColumn } from "src/app/modules/shared/components/table/table.model";
|
||||
import { DbModel } from "src/app/model/entities/db-model";
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
providedIn: "root",
|
||||
})
|
||||
export abstract class PageColumns<T> {
|
||||
abstract get(): TableColumn<T>[];
|
||||
}
|
||||
|
||||
export const ID_COLUMN = {
|
||||
name: 'id',
|
||||
label: 'common.id',
|
||||
type: 'number',
|
||||
name: "id",
|
||||
label: "common.id",
|
||||
type: "number",
|
||||
filterable: true,
|
||||
value: (row: { id?: number }) => row.id,
|
||||
class: 'max-w-24',
|
||||
class: "max-w-24",
|
||||
};
|
||||
|
||||
export const NAME_COLUMN = {
|
||||
name: 'name',
|
||||
label: 'common.name',
|
||||
type: 'text',
|
||||
name: "name",
|
||||
label: "common.name",
|
||||
type: "text",
|
||||
filterable: true,
|
||||
value: (row: { name?: string }) => row.name,
|
||||
};
|
||||
|
||||
export const DESCRIPTION_COLUMN = {
|
||||
name: 'description',
|
||||
label: 'common.description',
|
||||
type: 'text',
|
||||
name: "description",
|
||||
label: "common.description",
|
||||
type: "text",
|
||||
filterable: true,
|
||||
value: (row: { description?: string }) => row.description,
|
||||
};
|
||||
|
||||
export const DELETED_COLUMN = {
|
||||
name: 'deleted',
|
||||
label: 'common.deleted',
|
||||
type: 'bool',
|
||||
name: "deleted",
|
||||
label: "common.deleted",
|
||||
type: "bool",
|
||||
filterable: true,
|
||||
value: (row: DbModel) => row.deleted,
|
||||
};
|
||||
|
||||
export const EDITOR_COLUMN = {
|
||||
name: 'editor',
|
||||
label: 'common.editor',
|
||||
name: "editor",
|
||||
label: "common.editor",
|
||||
value: (row: DbModel) => row.editor?.username,
|
||||
};
|
||||
|
||||
export const CREATED_UTC_COLUMN = {
|
||||
name: 'createdUtc',
|
||||
label: 'common.created',
|
||||
type: 'date',
|
||||
name: "createdUtc",
|
||||
label: "common.created",
|
||||
type: "date",
|
||||
value: (row: DbModel) => row.createdUtc,
|
||||
class: 'max-w-32',
|
||||
class: "max-w-32",
|
||||
};
|
||||
|
||||
export const UPDATED_UTC_COLUMN = {
|
||||
name: 'updatedUtc',
|
||||
label: 'common.updated',
|
||||
type: 'date',
|
||||
name: "updatedUtc",
|
||||
label: "common.updated",
|
||||
type: "date",
|
||||
value: (row: DbModel) => row.updatedUtc,
|
||||
class: 'max-w-32',
|
||||
class: "max-w-32",
|
||||
};
|
||||
|
||||
export const DB_MODEL_COLUMNS = [
|
||||
|
@ -1,19 +1,19 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { MutationResult } from 'apollo-angular';
|
||||
import { Filter } from 'src/app/model/graphql/filter/filter.model';
|
||||
import { Sort } from 'src/app/model/graphql/filter/sort.model';
|
||||
import { QueryResult } from 'src/app/model/entities/query-result';
|
||||
import { Injectable } from "@angular/core";
|
||||
import { Observable } from "rxjs";
|
||||
import { MutationResult } from "apollo-angular";
|
||||
import { Filter } from "src/app/model/graphql/filter/filter.model";
|
||||
import { Sort } from "src/app/model/graphql/filter/sort.model";
|
||||
import { QueryResult } from "src/app/model/entities/query-result";
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
providedIn: "root",
|
||||
})
|
||||
export abstract class PageDataService<T> {
|
||||
abstract load(
|
||||
filter?: Filter[],
|
||||
sort?: Sort[],
|
||||
skip?: number,
|
||||
take?: number
|
||||
take?: number,
|
||||
): Observable<QueryResult<T>>;
|
||||
|
||||
abstract loadById(id: number): Observable<T>;
|
||||
@ -29,12 +29,12 @@ export interface Update<T, U> {
|
||||
|
||||
export interface Delete<T> {
|
||||
delete(
|
||||
object: T
|
||||
object: T,
|
||||
): Observable<T | undefined | boolean> | Observable<MutationResult>;
|
||||
}
|
||||
|
||||
export interface Restore<T> {
|
||||
restore(
|
||||
object: T
|
||||
object: T,
|
||||
): Observable<T | undefined | boolean> | Observable<MutationResult>;
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { CanActivate } from '@angular/router';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
import { Injectable } from "@angular/core";
|
||||
import { CanActivate } from "@angular/router";
|
||||
import { KeycloakService } from "keycloak-angular";
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
providedIn: "root",
|
||||
})
|
||||
export class AuthGuard implements CanActivate {
|
||||
constructor(private keycloak: KeycloakService) {}
|
||||
|
@ -1,24 +1,24 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, Router } from '@angular/router';
|
||||
import { Logger } from 'src/app/service/logger.service';
|
||||
import { ToastService } from 'src/app/service/toast.service';
|
||||
import { AuthService } from 'src/app/service/auth.service';
|
||||
import { PermissionsEnum } from 'src/app/model/auth/permissionsEnum';
|
||||
import { Injectable } from "@angular/core";
|
||||
import { ActivatedRouteSnapshot, Router } from "@angular/router";
|
||||
import { Logger } from "src/app/service/logger.service";
|
||||
import { ToastService } from "src/app/service/toast.service";
|
||||
import { AuthService } from "src/app/service/auth.service";
|
||||
import { PermissionsEnum } from "src/app/model/auth/permissionsEnum";
|
||||
|
||||
const log = new Logger('PermissionGuard');
|
||||
const log = new Logger("PermissionGuard");
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
providedIn: "root",
|
||||
})
|
||||
export class PermissionGuard {
|
||||
constructor(
|
||||
private router: Router,
|
||||
private toast: ToastService,
|
||||
private auth: AuthService
|
||||
private auth: AuthService,
|
||||
) {}
|
||||
|
||||
async canActivate(route: ActivatedRouteSnapshot): Promise<boolean> {
|
||||
const permissions = route.data['permissions'] as PermissionsEnum[];
|
||||
const permissions = route.data["permissions"] as PermissionsEnum[];
|
||||
|
||||
if (!permissions || permissions.length === 0) {
|
||||
return true;
|
||||
@ -26,11 +26,11 @@ export class PermissionGuard {
|
||||
|
||||
const validate = await this.auth.hasAnyPermissionLazy(permissions);
|
||||
if (!validate) {
|
||||
log.debug('Permission denied', permissions);
|
||||
this.toast.warn('common.warning', 'error.permission_denied');
|
||||
this.router.navigate(['/']).then();
|
||||
log.debug("Permission denied", permissions);
|
||||
this.toast.warn("common.warning", "error.permission_denied");
|
||||
this.router.navigate(["/"]).then();
|
||||
}
|
||||
log.debug('Permission granted', permissions);
|
||||
log.debug("Permission granted", permissions);
|
||||
return validate;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {KeycloakService} from 'keycloak-angular';
|
||||
import {environment} from 'src/environments/environment';
|
||||
import { KeycloakService } from "keycloak-angular";
|
||||
import { environment } from "src/environments/environment";
|
||||
|
||||
export function initializeKeycloak(keycloak: KeycloakService) {
|
||||
return () =>
|
||||
@ -10,7 +10,7 @@ export function initializeKeycloak(keycloak: KeycloakService) {
|
||||
clientId: environment.auth.clientId,
|
||||
},
|
||||
initOptions: {
|
||||
onLoad: 'check-sso',
|
||||
onLoad: "check-sso",
|
||||
},
|
||||
enableBearerInterceptor: false,
|
||||
});
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { HttpInterceptorFn } from '@angular/common/http';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
import { inject } from '@angular/core';
|
||||
import { from, switchMap } from 'rxjs';
|
||||
import { HttpInterceptorFn } from "@angular/common/http";
|
||||
import { KeycloakService } from "keycloak-angular";
|
||||
import { inject } from "@angular/core";
|
||||
import { from, switchMap } from "rxjs";
|
||||
|
||||
export const tokenInterceptor: HttpInterceptorFn = (req, next) => {
|
||||
const keycloak = inject(KeycloakService);
|
||||
@ -15,14 +15,14 @@ export const tokenInterceptor: HttpInterceptorFn = (req, next) => {
|
||||
}
|
||||
|
||||
return from(keycloak.getToken()).pipe(
|
||||
switchMap(token => {
|
||||
switchMap((token) => {
|
||||
const modifiedReq = token
|
||||
? req.clone({
|
||||
headers: req.headers.set('Authorization', `Bearer ${token}`),
|
||||
headers: req.headers.set("Authorization", `Bearer ${token}`),
|
||||
})
|
||||
: req;
|
||||
|
||||
return next(modifiedReq);
|
||||
})
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Role } from 'src/app/model/entities/role';
|
||||
import { DbModel } from 'src/app/model/entities/db-model';
|
||||
import { Role } from "src/app/model/entities/role";
|
||||
import { DbModel } from "src/app/model/entities/db-model";
|
||||
|
||||
export interface NotExistingUser {
|
||||
keycloakId: string;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Theme } from 'src/app/model/view/theme';
|
||||
import { Theme } from "src/app/model/view/theme";
|
||||
|
||||
export interface AppSettings {
|
||||
TermsUrl: string;
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { DbModel } from 'src/app/model/entities/db-model';
|
||||
import { Permission } from 'src/app/model/entities/role';
|
||||
import { DbModel } from "src/app/model/entities/db-model";
|
||||
import { Permission } from "src/app/model/entities/role";
|
||||
|
||||
export interface ApiKey extends DbModel {
|
||||
identifier?: string;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { User } from 'src/app/model/auth/user';
|
||||
import { User } from "src/app/model/auth/user";
|
||||
|
||||
export interface DbModel {
|
||||
id?: number;
|
||||
|
@ -2,7 +2,7 @@ import { DbModel } from "src/app/model/entities/db-model";
|
||||
import { Permission } from "src/app/model/entities/role";
|
||||
|
||||
export interface Group extends DbModel {
|
||||
name?: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface GroupCreateInput {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { DbModel } from 'src/app/model/entities/db-model';
|
||||
import { DbModel } from "src/app/model/entities/db-model";
|
||||
|
||||
export interface News extends DbModel {
|
||||
title: string;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { DbModel } from 'src/app/model/entities/db-model';
|
||||
import { DbModel } from "src/app/model/entities/db-model";
|
||||
|
||||
export interface Role extends DbModel {
|
||||
name?: string;
|
||||
|
@ -9,6 +9,11 @@ export interface ShortUrl extends DbModel {
|
||||
group?: Group;
|
||||
}
|
||||
|
||||
export interface ShortUrlDto {
|
||||
id: number;
|
||||
targetUrl: string;
|
||||
}
|
||||
|
||||
export interface ShortUrlCreateInput {
|
||||
shortUrl: string;
|
||||
targetUrl: string;
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { gql } from 'apollo-angular';
|
||||
import { EDITOR_FRAGMENT } from 'src/app/model/graphql/editor.query';
|
||||
import { gql } from "apollo-angular";
|
||||
import { EDITOR_FRAGMENT } from "src/app/model/graphql/editor.query";
|
||||
|
||||
export const DB_MODEL_FRAGMENT = gql`
|
||||
fragment DB_MODEL on DbModel {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { gql } from 'apollo-angular';
|
||||
import { gql } from "apollo-angular";
|
||||
|
||||
export const EDITOR_FRAGMENT = gql`
|
||||
fragment EDITOR on User {
|
||||
|
@ -2,6 +2,6 @@
|
||||
export type Sort = { [key: string]: any };
|
||||
|
||||
export enum SortOrder {
|
||||
ASC = 'ASC',
|
||||
DESC = 'DESC',
|
||||
ASC = "ASC",
|
||||
DESC = "DESC",
|
||||
}
|
||||
|
@ -1,3 +1,3 @@
|
||||
export enum Themes {
|
||||
Default = 'maxlan-dark-theme',
|
||||
Default = "maxlan-dark-theme",
|
||||
}
|
||||
|
@ -1,38 +1,38 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { PermissionGuard } from 'src/app/core/guard/permission.guard';
|
||||
import { PermissionsEnum } from 'src/app/model/auth/permissionsEnum';
|
||||
import { SharedModule } from 'src/app/modules/shared/shared.module';
|
||||
import { NgModule } from "@angular/core";
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { RouterModule, Routes } from "@angular/router";
|
||||
import { PermissionGuard } from "src/app/core/guard/permission.guard";
|
||||
import { PermissionsEnum } from "src/app/model/auth/permissionsEnum";
|
||||
import { SharedModule } from "src/app/modules/shared/shared.module";
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: 'users',
|
||||
title: 'Users | Maxlan',
|
||||
path: "users",
|
||||
title: "Users | Maxlan",
|
||||
loadChildren: () =>
|
||||
import('src/app/modules/admin/administration/users/users.module').then(
|
||||
m => m.UsersModule
|
||||
import("src/app/modules/admin/administration/users/users.module").then(
|
||||
(m) => m.UsersModule,
|
||||
),
|
||||
canActivate: [PermissionGuard],
|
||||
data: { permissions: [PermissionsEnum.users] },
|
||||
},
|
||||
{
|
||||
path: 'roles',
|
||||
title: 'Roles | Maxlan',
|
||||
path: "roles",
|
||||
title: "Roles | Maxlan",
|
||||
loadChildren: () =>
|
||||
import('src/app/modules/admin/administration/roles/roles.module').then(
|
||||
m => m.RolesModule
|
||||
import("src/app/modules/admin/administration/roles/roles.module").then(
|
||||
(m) => m.RolesModule,
|
||||
),
|
||||
canActivate: [PermissionGuard],
|
||||
data: { permissions: [PermissionsEnum.roles] },
|
||||
},
|
||||
{
|
||||
path: 'api-keys',
|
||||
title: 'API Key | Maxlan',
|
||||
path: "api-keys",
|
||||
title: "API Key | Maxlan",
|
||||
loadChildren: () =>
|
||||
import(
|
||||
'src/app/modules/admin/administration/api-keys/api-keys.module'
|
||||
).then(m => m.ApiKeysModule),
|
||||
"src/app/modules/admin/administration/api-keys/api-keys.module"
|
||||
).then((m) => m.ApiKeysModule),
|
||||
canActivate: [PermissionGuard],
|
||||
data: { permissions: [PermissionsEnum.apiKeys] },
|
||||
},
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { Injectable, Provider } from '@angular/core';
|
||||
import { Injectable, Provider } from "@angular/core";
|
||||
import {
|
||||
DB_MODEL_COLUMNS,
|
||||
ID_COLUMN,
|
||||
PageColumns,
|
||||
} from 'src/app/core/base/page.columns';
|
||||
import { TableColumn } from 'src/app/modules/shared/components/table/table.model';
|
||||
import { ApiKey } from 'src/app/model/entities/api-key';
|
||||
} from "src/app/core/base/page.columns";
|
||||
import { TableColumn } from "src/app/modules/shared/components/table/table.model";
|
||||
import { ApiKey } from "src/app/model/entities/api-key";
|
||||
|
||||
@Injectable()
|
||||
export class ApiKeysColumns extends PageColumns<ApiKey> {
|
||||
@ -13,16 +13,16 @@ export class ApiKeysColumns extends PageColumns<ApiKey> {
|
||||
return [
|
||||
ID_COLUMN,
|
||||
{
|
||||
name: 'identifier',
|
||||
label: 'common.identifier',
|
||||
type: 'text',
|
||||
name: "identifier",
|
||||
label: "common.identifier",
|
||||
type: "text",
|
||||
filterable: true,
|
||||
value: (row: ApiKey) => row.identifier,
|
||||
},
|
||||
{
|
||||
name: 'key',
|
||||
label: 'common.key',
|
||||
type: 'password',
|
||||
name: "key",
|
||||
label: "common.key",
|
||||
type: "password",
|
||||
value: (row: ApiKey) => row.key,
|
||||
},
|
||||
...DB_MODEL_COLUMNS,
|
||||
|
@ -1,25 +1,25 @@
|
||||
import { Injectable, Provider } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { Injectable, Provider } from "@angular/core";
|
||||
import { Observable } from "rxjs";
|
||||
import {
|
||||
Create,
|
||||
Delete,
|
||||
PageDataService,
|
||||
Restore,
|
||||
Update,
|
||||
} from 'src/app/core/base/page.data.service';
|
||||
import { Permission } from 'src/app/model/entities/role';
|
||||
import { Filter } from 'src/app/model/graphql/filter/filter.model';
|
||||
import { Sort } from 'src/app/model/graphql/filter/sort.model';
|
||||
import { Apollo, gql } from 'apollo-angular';
|
||||
import { QueryResult } from 'src/app/model/entities/query-result';
|
||||
import { DB_MODEL_FRAGMENT } from 'src/app/model/graphql/db-model.query';
|
||||
import { catchError, map } from 'rxjs/operators';
|
||||
import { SpinnerService } from 'src/app/service/spinner.service';
|
||||
} from "src/app/core/base/page.data.service";
|
||||
import { Permission } from "src/app/model/entities/role";
|
||||
import { Filter } from "src/app/model/graphql/filter/filter.model";
|
||||
import { Sort } from "src/app/model/graphql/filter/sort.model";
|
||||
import { Apollo, gql } from "apollo-angular";
|
||||
import { QueryResult } from "src/app/model/entities/query-result";
|
||||
import { DB_MODEL_FRAGMENT } from "src/app/model/graphql/db-model.query";
|
||||
import { catchError, map } from "rxjs/operators";
|
||||
import { SpinnerService } from "src/app/service/spinner.service";
|
||||
import {
|
||||
ApiKey,
|
||||
ApiKeyCreateInput,
|
||||
ApiKeyUpdateInput,
|
||||
} from 'src/app/model/entities/api-key';
|
||||
} from "src/app/model/entities/api-key";
|
||||
|
||||
@Injectable()
|
||||
export class ApiKeysDataService
|
||||
@ -32,7 +32,7 @@ export class ApiKeysDataService
|
||||
{
|
||||
constructor(
|
||||
private spinner: SpinnerService,
|
||||
private apollo: Apollo
|
||||
private apollo: Apollo,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
@ -41,7 +41,7 @@ export class ApiKeysDataService
|
||||
filter?: Filter[] | undefined,
|
||||
sort?: Sort[] | undefined,
|
||||
skip?: number | undefined,
|
||||
take?: number | undefined
|
||||
take?: number | undefined,
|
||||
): Observable<QueryResult<ApiKey>> {
|
||||
return this.apollo
|
||||
.query<{ apiKeys: QueryResult<ApiKey> }>({
|
||||
@ -78,12 +78,12 @@ export class ApiKeysDataService
|
||||
},
|
||||
})
|
||||
.pipe(
|
||||
catchError(err => {
|
||||
catchError((err) => {
|
||||
this.spinner.hide();
|
||||
throw err;
|
||||
})
|
||||
}),
|
||||
)
|
||||
.pipe(map(result => result.data.apiKeys));
|
||||
.pipe(map((result) => result.data.apiKeys));
|
||||
}
|
||||
|
||||
loadById(id: number): Observable<ApiKey> {
|
||||
@ -109,12 +109,12 @@ export class ApiKeysDataService
|
||||
},
|
||||
})
|
||||
.pipe(
|
||||
catchError(err => {
|
||||
catchError((err) => {
|
||||
this.spinner.hide();
|
||||
throw err;
|
||||
})
|
||||
}),
|
||||
)
|
||||
.pipe(map(result => result.data.apiKeys.nodes[0]));
|
||||
.pipe(map((result) => result.data.apiKeys.nodes[0]));
|
||||
}
|
||||
|
||||
create(object: ApiKeyCreateInput): Observable<ApiKey | undefined> {
|
||||
@ -140,17 +140,17 @@ export class ApiKeysDataService
|
||||
variables: {
|
||||
input: {
|
||||
identifier: object.identifier,
|
||||
permissions: object.permissions?.map(x => x.id),
|
||||
permissions: object.permissions?.map((x) => x.id),
|
||||
},
|
||||
},
|
||||
})
|
||||
.pipe(
|
||||
catchError(err => {
|
||||
catchError((err) => {
|
||||
this.spinner.hide();
|
||||
throw err;
|
||||
})
|
||||
}),
|
||||
)
|
||||
.pipe(map(result => result.data?.apiKey.create));
|
||||
.pipe(map((result) => result.data?.apiKey.create));
|
||||
}
|
||||
|
||||
update(object: ApiKeyUpdateInput): Observable<ApiKey | undefined> {
|
||||
@ -177,17 +177,17 @@ export class ApiKeysDataService
|
||||
input: {
|
||||
id: object.id,
|
||||
identifier: object.identifier,
|
||||
permissions: object.permissions?.map(x => x.id),
|
||||
permissions: object.permissions?.map((x) => x.id),
|
||||
},
|
||||
},
|
||||
})
|
||||
.pipe(
|
||||
catchError(err => {
|
||||
catchError((err) => {
|
||||
this.spinner.hide();
|
||||
throw err;
|
||||
})
|
||||
}),
|
||||
)
|
||||
.pipe(map(result => result.data?.apiKey.update));
|
||||
.pipe(map((result) => result.data?.apiKey.update));
|
||||
}
|
||||
|
||||
delete(object: ApiKey): Observable<boolean> {
|
||||
@ -205,12 +205,12 @@ export class ApiKeysDataService
|
||||
},
|
||||
})
|
||||
.pipe(
|
||||
catchError(err => {
|
||||
catchError((err) => {
|
||||
this.spinner.hide();
|
||||
throw err;
|
||||
})
|
||||
}),
|
||||
)
|
||||
.pipe(map(result => result.data?.apiKey.delete ?? false));
|
||||
.pipe(map((result) => result.data?.apiKey.delete ?? false));
|
||||
}
|
||||
|
||||
restore(object: ApiKey): Observable<boolean> {
|
||||
@ -228,12 +228,12 @@ export class ApiKeysDataService
|
||||
},
|
||||
})
|
||||
.pipe(
|
||||
catchError(err => {
|
||||
catchError((err) => {
|
||||
this.spinner.hide();
|
||||
throw err;
|
||||
})
|
||||
}),
|
||||
)
|
||||
.pipe(map(result => result.data?.apiKey.restore ?? false));
|
||||
.pipe(map((result) => result.data?.apiKey.restore ?? false));
|
||||
}
|
||||
|
||||
getAllPermissions(): Observable<Permission[]> {
|
||||
@ -251,12 +251,12 @@ export class ApiKeysDataService
|
||||
`,
|
||||
})
|
||||
.pipe(
|
||||
catchError(err => {
|
||||
catchError((err) => {
|
||||
this.spinner.hide();
|
||||
throw err;
|
||||
})
|
||||
}),
|
||||
)
|
||||
.pipe(map(result => result.data.permissions.nodes));
|
||||
.pipe(map((result) => result.data.permissions.nodes));
|
||||
}
|
||||
|
||||
static provide(): Provider[] {
|
||||
|
@ -1,22 +1,22 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { SharedModule } from 'src/app/modules/shared/shared.module';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { PermissionGuard } from 'src/app/core/guard/permission.guard';
|
||||
import { PermissionsEnum } from 'src/app/model/auth/permissionsEnum';
|
||||
import { ApiKeyFormPageComponent } from 'src/app/modules/admin/administration/api-keys/form-page/api-key-form-page.component';
|
||||
import { ApiKeysPage } from 'src/app/modules/admin/administration/api-keys/api-keys.page';
|
||||
import { ApiKeysDataService } from 'src/app/modules/admin/administration/api-keys/api-keys.data.service';
|
||||
import { ApiKeysColumns } from 'src/app/modules/admin/administration/api-keys/api-keys.columns';
|
||||
import { NgModule } from "@angular/core";
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { SharedModule } from "src/app/modules/shared/shared.module";
|
||||
import { RouterModule, Routes } from "@angular/router";
|
||||
import { PermissionGuard } from "src/app/core/guard/permission.guard";
|
||||
import { PermissionsEnum } from "src/app/model/auth/permissionsEnum";
|
||||
import { ApiKeyFormPageComponent } from "src/app/modules/admin/administration/api-keys/form-page/api-key-form-page.component";
|
||||
import { ApiKeysPage } from "src/app/modules/admin/administration/api-keys/api-keys.page";
|
||||
import { ApiKeysDataService } from "src/app/modules/admin/administration/api-keys/api-keys.data.service";
|
||||
import { ApiKeysColumns } from "src/app/modules/admin/administration/api-keys/api-keys.columns";
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
title: 'Admin - ApiKeys | Maxlan',
|
||||
path: "",
|
||||
title: "Admin - ApiKeys | Maxlan",
|
||||
component: ApiKeysPage,
|
||||
children: [
|
||||
{
|
||||
path: 'create',
|
||||
path: "create",
|
||||
component: ApiKeyFormPageComponent,
|
||||
canActivate: [PermissionGuard],
|
||||
data: {
|
||||
@ -24,7 +24,7 @@ const routes: Routes = [
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'edit/:id',
|
||||
path: "edit/:id",
|
||||
component: ApiKeyFormPageComponent,
|
||||
canActivate: [PermissionGuard],
|
||||
data: {
|
||||
|
@ -1,18 +1,18 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ApiKeysPage } from 'src/app/modules/admin/administration/api-keys/api-keys.page';
|
||||
import { SharedModule } from 'src/app/modules/shared/shared.module';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { AuthService } from 'src/app/service/auth.service';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
import { ErrorHandlingService } from 'src/app/service/error-handling.service';
|
||||
import { ToastService } from 'src/app/service/toast.service';
|
||||
import { ConfirmationService, MessageService } from 'primeng/api';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { of } from 'rxjs';
|
||||
import { PageDataService } from 'src/app/core/base/page.data.service';
|
||||
import { ApiKeysDataService } from 'src/app/modules/admin/administration/api-keys/api-keys.data.service';
|
||||
import { ComponentFixture, TestBed } from "@angular/core/testing";
|
||||
import { ApiKeysPage } from "src/app/modules/admin/administration/api-keys/api-keys.page";
|
||||
import { SharedModule } from "src/app/modules/shared/shared.module";
|
||||
import { TranslateModule } from "@ngx-translate/core";
|
||||
import { AuthService } from "src/app/service/auth.service";
|
||||
import { KeycloakService } from "keycloak-angular";
|
||||
import { ErrorHandlingService } from "src/app/service/error-handling.service";
|
||||
import { ToastService } from "src/app/service/toast.service";
|
||||
import { ConfirmationService, MessageService } from "primeng/api";
|
||||
import { ActivatedRoute } from "@angular/router";
|
||||
import { of } from "rxjs";
|
||||
import { PageDataService } from "src/app/core/base/page.data.service";
|
||||
import { ApiKeysDataService } from "src/app/modules/admin/administration/api-keys/api-keys.data.service";
|
||||
|
||||
describe('ApiKeysComponent', () => {
|
||||
describe("ApiKeysComponent", () => {
|
||||
let component: ApiKeysPage;
|
||||
let fixture: ComponentFixture<ApiKeysPage>;
|
||||
|
||||
@ -45,7 +45,7 @@ describe('ApiKeysComponent', () => {
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
it("should create", () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
@ -1,16 +1,16 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { PageBase } from 'src/app/core/base/page-base';
|
||||
import { ToastService } from 'src/app/service/toast.service';
|
||||
import { ConfirmationDialogService } from 'src/app/service/confirmation-dialog.service';
|
||||
import { PermissionsEnum } from 'src/app/model/auth/permissionsEnum';
|
||||
import { ApiKey } from 'src/app/model/entities/api-key';
|
||||
import { ApiKeysDataService } from 'src/app/modules/admin/administration/api-keys/api-keys.data.service';
|
||||
import { ApiKeysColumns } from 'src/app/modules/admin/administration/api-keys/api-keys.columns';
|
||||
import { Component } from "@angular/core";
|
||||
import { PageBase } from "src/app/core/base/page-base";
|
||||
import { ToastService } from "src/app/service/toast.service";
|
||||
import { ConfirmationDialogService } from "src/app/service/confirmation-dialog.service";
|
||||
import { PermissionsEnum } from "src/app/model/auth/permissionsEnum";
|
||||
import { ApiKey } from "src/app/model/entities/api-key";
|
||||
import { ApiKeysDataService } from "src/app/modules/admin/administration/api-keys/api-keys.data.service";
|
||||
import { ApiKeysColumns } from "src/app/modules/admin/administration/api-keys/api-keys.columns";
|
||||
|
||||
@Component({
|
||||
selector: 'app-api-keys',
|
||||
templateUrl: './api-keys.page.html',
|
||||
styleUrl: './api-keys.page.scss',
|
||||
selector: "app-api-keys",
|
||||
templateUrl: "./api-keys.page.html",
|
||||
styleUrl: "./api-keys.page.scss",
|
||||
})
|
||||
export class ApiKeysPage extends PageBase<
|
||||
ApiKey,
|
||||
@ -19,7 +19,7 @@ export class ApiKeysPage extends PageBase<
|
||||
> {
|
||||
constructor(
|
||||
private toast: ToastService,
|
||||
private confirmation: ConfirmationDialogService
|
||||
private confirmation: ConfirmationDialogService,
|
||||
) {
|
||||
super(true, {
|
||||
read: [PermissionsEnum.apiKeys],
|
||||
@ -34,7 +34,7 @@ export class ApiKeysPage extends PageBase<
|
||||
this.loading = true;
|
||||
this.dataService
|
||||
.load(this.filter, this.sort, this.skip, this.take)
|
||||
.subscribe(result => {
|
||||
.subscribe((result) => {
|
||||
this.result = result;
|
||||
this.loading = false;
|
||||
});
|
||||
@ -42,12 +42,12 @@ export class ApiKeysPage extends PageBase<
|
||||
|
||||
delete(apiKey: ApiKey): void {
|
||||
this.confirmation.confirmDialog({
|
||||
header: 'dialog.delete.header',
|
||||
message: 'dialog.delete.message',
|
||||
header: "dialog.delete.header",
|
||||
message: "dialog.delete.message",
|
||||
accept: () => {
|
||||
this.loading = true;
|
||||
this.dataService.delete(apiKey).subscribe(() => {
|
||||
this.toast.success('action.deleted');
|
||||
this.toast.success("action.deleted");
|
||||
this.load();
|
||||
});
|
||||
},
|
||||
@ -57,12 +57,12 @@ export class ApiKeysPage extends PageBase<
|
||||
|
||||
restore(apiKey: ApiKey): void {
|
||||
this.confirmation.confirmDialog({
|
||||
header: 'dialog.restore.header',
|
||||
message: 'dialog.restore.message',
|
||||
header: "dialog.restore.header",
|
||||
message: "dialog.restore.message",
|
||||
accept: () => {
|
||||
this.loading = true;
|
||||
this.dataService.restore(apiKey).subscribe(() => {
|
||||
this.toast.success('action.restored');
|
||||
this.toast.success("action.restored");
|
||||
this.load();
|
||||
});
|
||||
},
|
||||
|
@ -1,17 +1,17 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { RoleFormPageComponent } from 'src/app/modules/admin/administration/roles/form-page/role-form-page.component';
|
||||
import { SharedModule } from 'src/app/modules/shared/shared.module';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { AuthService } from 'src/app/service/auth.service';
|
||||
import { ErrorHandlingService } from 'src/app/service/error-handling.service';
|
||||
import { ToastService } from 'src/app/service/toast.service';
|
||||
import { ConfirmationService, MessageService } from 'primeng/api';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { of } from 'rxjs';
|
||||
import { ApiKeysDataService } from 'src/app/modules/admin/administration/api-keys/api-keys.data.service';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { ComponentFixture, TestBed } from "@angular/core/testing";
|
||||
import { RoleFormPageComponent } from "src/app/modules/admin/administration/roles/form-page/role-form-page.component";
|
||||
import { SharedModule } from "src/app/modules/shared/shared.module";
|
||||
import { TranslateModule } from "@ngx-translate/core";
|
||||
import { AuthService } from "src/app/service/auth.service";
|
||||
import { ErrorHandlingService } from "src/app/service/error-handling.service";
|
||||
import { ToastService } from "src/app/service/toast.service";
|
||||
import { ConfirmationService, MessageService } from "primeng/api";
|
||||
import { ActivatedRoute } from "@angular/router";
|
||||
import { of } from "rxjs";
|
||||
import { ApiKeysDataService } from "src/app/modules/admin/administration/api-keys/api-keys.data.service";
|
||||
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
|
||||
|
||||
describe('ApiKeyFormpageComponent', () => {
|
||||
describe("ApiKeyFormpageComponent", () => {
|
||||
let component: RoleFormPageComponent;
|
||||
let fixture: ComponentFixture<RoleFormPageComponent>;
|
||||
|
||||
@ -44,7 +44,7 @@ describe('ApiKeyFormpageComponent', () => {
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
it("should create", () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
@ -1,21 +1,21 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { FormControl, FormGroup, Validators } from '@angular/forms';
|
||||
import { InputSwitchChangeEvent } from 'primeng/inputswitch';
|
||||
import { ToastService } from 'src/app/service/toast.service';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import { FormPageBase } from 'src/app/core/base/form-page-base';
|
||||
import { Permission } from 'src/app/model/entities/role';
|
||||
import { Component } from "@angular/core";
|
||||
import { FormControl, FormGroup, Validators } from "@angular/forms";
|
||||
import { InputSwitchChangeEvent } from "primeng/inputswitch";
|
||||
import { ToastService } from "src/app/service/toast.service";
|
||||
import { firstValueFrom } from "rxjs";
|
||||
import { FormPageBase } from "src/app/core/base/form-page-base";
|
||||
import { Permission } from "src/app/model/entities/role";
|
||||
import {
|
||||
ApiKey,
|
||||
ApiKeyCreateInput,
|
||||
ApiKeyUpdateInput,
|
||||
} from 'src/app/model/entities/api-key';
|
||||
import { ApiKeysDataService } from 'src/app/modules/admin/administration/api-keys/api-keys.data.service';
|
||||
} from "src/app/model/entities/api-key";
|
||||
import { ApiKeysDataService } from "src/app/modules/admin/administration/api-keys/api-keys.data.service";
|
||||
|
||||
@Component({
|
||||
selector: 'app-api-key-form-page',
|
||||
templateUrl: './api-key-form-page.component.html',
|
||||
styleUrl: './api-key-form-page.component.scss',
|
||||
selector: "app-api-key-form-page",
|
||||
templateUrl: "./api-key-form-page.component.html",
|
||||
styleUrl: "./api-key-form-page.component.scss",
|
||||
})
|
||||
export class ApiKeyFormPageComponent extends FormPageBase<
|
||||
ApiKey,
|
||||
@ -38,7 +38,7 @@ export class ApiKeyFormPageComponent extends FormPageBase<
|
||||
|
||||
this.dataService
|
||||
.load([{ id: { equal: this.nodeId } }])
|
||||
.subscribe(apiKey => {
|
||||
.subscribe((apiKey) => {
|
||||
this.node = apiKey.nodes[0];
|
||||
this.setForm(this.node);
|
||||
});
|
||||
@ -47,12 +47,12 @@ export class ApiKeyFormPageComponent extends FormPageBase<
|
||||
|
||||
async initializePermissions() {
|
||||
const permissions = await firstValueFrom(
|
||||
this.dataService.getAllPermissions()
|
||||
this.dataService.getAllPermissions(),
|
||||
);
|
||||
this.allPermissions = permissions;
|
||||
this.permissionGroups = permissions.reduce(
|
||||
(acc, p) => {
|
||||
const group = p.name.includes('.') ? p.name.split('.')[0] : p.name;
|
||||
const group = p.name.includes(".") ? p.name.split(".")[0] : p.name;
|
||||
|
||||
if (!acc[group]) {
|
||||
acc[group] = [];
|
||||
@ -60,10 +60,10 @@ export class ApiKeyFormPageComponent extends FormPageBase<
|
||||
acc[group].push(p);
|
||||
return acc;
|
||||
},
|
||||
{} as { [key: string]: Permission[] }
|
||||
{} as { [key: string]: Permission[] },
|
||||
);
|
||||
|
||||
permissions.forEach(p => {
|
||||
permissions.forEach((p) => {
|
||||
this.form.addControl(p.name, new FormControl<boolean>(false));
|
||||
});
|
||||
}
|
||||
@ -77,48 +77,48 @@ export class ApiKeyFormPageComponent extends FormPageBase<
|
||||
id: new FormControl<number | undefined>(undefined),
|
||||
identifier: new FormControl<string | undefined>(
|
||||
undefined,
|
||||
Validators.required
|
||||
Validators.required,
|
||||
),
|
||||
});
|
||||
this.form.controls['id'].disable();
|
||||
this.form.controls["id"].disable();
|
||||
}
|
||||
|
||||
setForm(node?: ApiKey) {
|
||||
this.form.controls['id'].setValue(node?.id);
|
||||
this.form.controls['identifier'].setValue(node?.identifier);
|
||||
this.form.controls["id"].setValue(node?.id);
|
||||
this.form.controls["identifier"].setValue(node?.identifier);
|
||||
|
||||
if (!node) return;
|
||||
|
||||
const permissions = node.permissions ?? [];
|
||||
|
||||
permissions.forEach(p => {
|
||||
permissions.forEach((p) => {
|
||||
this.form.controls[p.name].setValue(true);
|
||||
});
|
||||
}
|
||||
|
||||
getCreateInput(): ApiKeyCreateInput {
|
||||
return {
|
||||
identifier: this.form.controls['identifier'].pristine
|
||||
identifier: this.form.controls["identifier"].pristine
|
||||
? undefined
|
||||
: (this.form.controls['identifier'].value ?? undefined),
|
||||
: (this.form.controls["identifier"].value ?? undefined),
|
||||
permissions: this.allPermissions.filter(
|
||||
p => this.form.controls[p.name].value
|
||||
(p) => this.form.controls[p.name].value,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
getUpdateInput(): ApiKeyUpdateInput {
|
||||
if (!this.node?.id) {
|
||||
throw new Error('Node id is missing');
|
||||
throw new Error("Node id is missing");
|
||||
}
|
||||
|
||||
return {
|
||||
id: this.form.controls['id'].value,
|
||||
identifier: this.form.controls['identifier'].pristine
|
||||
id: this.form.controls["id"].value,
|
||||
identifier: this.form.controls["identifier"].pristine
|
||||
? undefined
|
||||
: (this.form.controls['identifier'].value ?? undefined),
|
||||
: (this.form.controls["identifier"].value ?? undefined),
|
||||
permissions: this.allPermissions.filter(
|
||||
p => this.form.controls[p.name].value
|
||||
(p) => this.form.controls[p.name].value,
|
||||
),
|
||||
};
|
||||
}
|
||||
@ -126,7 +126,7 @@ export class ApiKeyFormPageComponent extends FormPageBase<
|
||||
create(apiKey: ApiKeyCreateInput): void {
|
||||
this.dataService.create(apiKey).subscribe(() => {
|
||||
this.spinner.hide();
|
||||
this.toast.success('action.created');
|
||||
this.toast.success("action.created");
|
||||
this.close();
|
||||
});
|
||||
}
|
||||
@ -134,20 +134,20 @@ export class ApiKeyFormPageComponent extends FormPageBase<
|
||||
update(apiKey: ApiKeyUpdateInput): void {
|
||||
this.dataService.update(apiKey).subscribe(() => {
|
||||
this.spinner.hide();
|
||||
this.toast.success('action.created');
|
||||
this.toast.success("action.created");
|
||||
this.close();
|
||||
});
|
||||
}
|
||||
|
||||
toggleGroup(event: InputSwitchChangeEvent, group: string) {
|
||||
this.permissionGroups[group].forEach(p => {
|
||||
this.permissionGroups[group].forEach((p) => {
|
||||
this.form.controls[p.name].setValue(event.checked);
|
||||
});
|
||||
}
|
||||
|
||||
isGroupChecked(group: string) {
|
||||
return this.permissionGroups[group].every(
|
||||
p => this.form.controls[p.name].value
|
||||
(p) => this.form.controls[p.name].value,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,17 +1,17 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { RoleFormPageComponent } from 'src/app/modules/admin/administration/roles/form-page/role-form-page.component';
|
||||
import { SharedModule } from 'src/app/modules/shared/shared.module';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { AuthService } from 'src/app/service/auth.service';
|
||||
import { ErrorHandlingService } from 'src/app/service/error-handling.service';
|
||||
import { ToastService } from 'src/app/service/toast.service';
|
||||
import { ConfirmationService, MessageService } from 'primeng/api';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { of } from 'rxjs';
|
||||
import { RolesDataService } from 'src/app/modules/admin/administration/roles/roles.data.service';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { ComponentFixture, TestBed } from "@angular/core/testing";
|
||||
import { RoleFormPageComponent } from "src/app/modules/admin/administration/roles/form-page/role-form-page.component";
|
||||
import { SharedModule } from "src/app/modules/shared/shared.module";
|
||||
import { TranslateModule } from "@ngx-translate/core";
|
||||
import { AuthService } from "src/app/service/auth.service";
|
||||
import { ErrorHandlingService } from "src/app/service/error-handling.service";
|
||||
import { ToastService } from "src/app/service/toast.service";
|
||||
import { ConfirmationService, MessageService } from "primeng/api";
|
||||
import { ActivatedRoute } from "@angular/router";
|
||||
import { of } from "rxjs";
|
||||
import { RolesDataService } from "src/app/modules/admin/administration/roles/roles.data.service";
|
||||
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
|
||||
|
||||
describe('RoleFormpageComponent', () => {
|
||||
describe("RoleFormpageComponent", () => {
|
||||
let component: RoleFormPageComponent;
|
||||
let fixture: ComponentFixture<RoleFormPageComponent>;
|
||||
|
||||
@ -44,7 +44,7 @@ describe('RoleFormpageComponent', () => {
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
it("should create", () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
@ -1,21 +1,21 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Component } from "@angular/core";
|
||||
import {
|
||||
Permission,
|
||||
Role,
|
||||
RoleCreateInput,
|
||||
RoleUpdateInput,
|
||||
} from 'src/app/model/entities/role';
|
||||
import { InputSwitchChangeEvent } from 'primeng/inputswitch';
|
||||
import { ToastService } from 'src/app/service/toast.service';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import { FormPageBase } from 'src/app/core/base/form-page-base';
|
||||
import { RolesDataService } from 'src/app/modules/admin/administration/roles/roles.data.service';
|
||||
import { FormControl, FormGroup, Validators } from '@angular/forms';
|
||||
} from "src/app/model/entities/role";
|
||||
import { InputSwitchChangeEvent } from "primeng/inputswitch";
|
||||
import { ToastService } from "src/app/service/toast.service";
|
||||
import { firstValueFrom } from "rxjs";
|
||||
import { FormPageBase } from "src/app/core/base/form-page-base";
|
||||
import { RolesDataService } from "src/app/modules/admin/administration/roles/roles.data.service";
|
||||
import { FormControl, FormGroup, Validators } from "@angular/forms";
|
||||
|
||||
@Component({
|
||||
selector: 'app-role-form-page',
|
||||
templateUrl: './role-form-page.component.html',
|
||||
styleUrl: './role-form-page.component.scss',
|
||||
selector: "app-role-form-page",
|
||||
templateUrl: "./role-form-page.component.html",
|
||||
styleUrl: "./role-form-page.component.scss",
|
||||
})
|
||||
export class RoleFormPageComponent extends FormPageBase<
|
||||
Role,
|
||||
@ -36,7 +36,7 @@ export class RoleFormPageComponent extends FormPageBase<
|
||||
return;
|
||||
}
|
||||
|
||||
this.dataService.loadById(this.nodeId).subscribe(role => {
|
||||
this.dataService.loadById(this.nodeId).subscribe((role) => {
|
||||
this.node = role;
|
||||
this.setForm(this.node);
|
||||
});
|
||||
@ -45,12 +45,12 @@ export class RoleFormPageComponent extends FormPageBase<
|
||||
|
||||
async initializePermissions() {
|
||||
const permissions = await firstValueFrom(
|
||||
this.dataService.getAllPermissions()
|
||||
this.dataService.getAllPermissions(),
|
||||
);
|
||||
this.allPermissions = permissions;
|
||||
this.permissionGroups = permissions.reduce(
|
||||
(acc, p) => {
|
||||
const group = p.name.includes('.') ? p.name.split('.')[0] : p.name;
|
||||
const group = p.name.includes(".") ? p.name.split(".")[0] : p.name;
|
||||
|
||||
if (!acc[group]) {
|
||||
acc[group] = [];
|
||||
@ -58,10 +58,10 @@ export class RoleFormPageComponent extends FormPageBase<
|
||||
acc[group].push(p);
|
||||
return acc;
|
||||
},
|
||||
{} as { [key: string]: Permission[] }
|
||||
{} as { [key: string]: Permission[] },
|
||||
);
|
||||
|
||||
permissions.forEach(p => {
|
||||
permissions.forEach((p) => {
|
||||
this.form.addControl(p.name, new FormControl<boolean>(false));
|
||||
});
|
||||
}
|
||||
@ -76,48 +76,48 @@ export class RoleFormPageComponent extends FormPageBase<
|
||||
name: new FormControl<string | undefined>(undefined, Validators.required),
|
||||
description: new FormControl<string | undefined>(undefined),
|
||||
});
|
||||
this.form.controls['id'].disable();
|
||||
this.form.controls["id"].disable();
|
||||
}
|
||||
|
||||
setForm(node?: Role) {
|
||||
this.form.controls['id'].setValue(node?.id);
|
||||
this.form.controls['name'].setValue(node?.name);
|
||||
this.form.controls['description'].setValue(node?.description);
|
||||
this.form.controls["id"].setValue(node?.id);
|
||||
this.form.controls["name"].setValue(node?.name);
|
||||
this.form.controls["description"].setValue(node?.description);
|
||||
|
||||
if (!node) return;
|
||||
|
||||
const permissions = node.permissions ?? [];
|
||||
|
||||
permissions.forEach(p => {
|
||||
permissions.forEach((p) => {
|
||||
this.form.controls[p.name].setValue(true);
|
||||
});
|
||||
}
|
||||
|
||||
getCreateInput(): RoleCreateInput {
|
||||
return {
|
||||
name: this.form.controls['name'].pristine
|
||||
name: this.form.controls["name"].pristine
|
||||
? undefined
|
||||
: (this.form.controls['name'].value ?? undefined),
|
||||
description: this.form.controls['description'].pristine
|
||||
: (this.form.controls["name"].value ?? undefined),
|
||||
description: this.form.controls["description"].pristine
|
||||
? undefined
|
||||
: (this.form.controls['description'].value ?? undefined),
|
||||
: (this.form.controls["description"].value ?? undefined),
|
||||
permissions: this.allPermissions.filter(
|
||||
p => this.form.controls[p.name].value
|
||||
(p) => this.form.controls[p.name].value,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
getUpdateInput(): RoleUpdateInput {
|
||||
return {
|
||||
id: this.form.controls['id'].value,
|
||||
name: this.form.controls['name'].pristine
|
||||
id: this.form.controls["id"].value,
|
||||
name: this.form.controls["name"].pristine
|
||||
? undefined
|
||||
: this.form.controls['name'].value,
|
||||
description: this.form.controls['description'].pristine
|
||||
: this.form.controls["name"].value,
|
||||
description: this.form.controls["description"].pristine
|
||||
? undefined
|
||||
: this.form.controls['description'].value,
|
||||
: this.form.controls["description"].value,
|
||||
permissions: this.allPermissions.filter(
|
||||
p => this.form.controls[p.name].value
|
||||
(p) => this.form.controls[p.name].value,
|
||||
),
|
||||
};
|
||||
}
|
||||
@ -125,7 +125,7 @@ export class RoleFormPageComponent extends FormPageBase<
|
||||
create(role: RoleCreateInput): void {
|
||||
this.dataService.create(role).subscribe(() => {
|
||||
this.spinner.hide();
|
||||
this.toast.success('action.created');
|
||||
this.toast.success("action.created");
|
||||
this.close();
|
||||
});
|
||||
}
|
||||
@ -133,20 +133,20 @@ export class RoleFormPageComponent extends FormPageBase<
|
||||
update(role: RoleUpdateInput): void {
|
||||
this.dataService.update(role).subscribe(() => {
|
||||
this.spinner.hide();
|
||||
this.toast.success('action.created');
|
||||
this.toast.success("action.created");
|
||||
this.close();
|
||||
});
|
||||
}
|
||||
|
||||
toggleGroup(event: InputSwitchChangeEvent, group: string) {
|
||||
this.permissionGroups[group].forEach(p => {
|
||||
this.permissionGroups[group].forEach((p) => {
|
||||
this.form.controls[p.name].setValue(event.checked);
|
||||
});
|
||||
}
|
||||
|
||||
isGroupChecked(group: string) {
|
||||
return this.permissionGroups[group].every(
|
||||
p => this.form.controls[p.name].value
|
||||
(p) => this.form.controls[p.name].value,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
import { Injectable, Provider } from '@angular/core';
|
||||
import { Role } from 'src/app/model/entities/role';
|
||||
import { Injectable, Provider } from "@angular/core";
|
||||
import { Role } from "src/app/model/entities/role";
|
||||
import {
|
||||
DB_MODEL_COLUMNS,
|
||||
DESCRIPTION_COLUMN,
|
||||
ID_COLUMN,
|
||||
NAME_COLUMN,
|
||||
PageColumns,
|
||||
} from 'src/app/core/base/page.columns';
|
||||
import { TableColumn } from 'src/app/modules/shared/components/table/table.model';
|
||||
} from "src/app/core/base/page.columns";
|
||||
import { TableColumn } from "src/app/modules/shared/components/table/table.model";
|
||||
|
||||
@Injectable()
|
||||
export class RolesColumns extends PageColumns<Role> {
|
||||
|
@ -1,25 +1,25 @@
|
||||
import { Injectable, Provider } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { Injectable, Provider } from "@angular/core";
|
||||
import { Observable } from "rxjs";
|
||||
import {
|
||||
Create,
|
||||
Delete,
|
||||
PageDataService,
|
||||
Restore,
|
||||
Update,
|
||||
} from 'src/app/core/base/page.data.service';
|
||||
} from "src/app/core/base/page.data.service";
|
||||
import {
|
||||
Permission,
|
||||
Role,
|
||||
RoleCreateInput,
|
||||
RoleUpdateInput,
|
||||
} from 'src/app/model/entities/role';
|
||||
import { Filter } from 'src/app/model/graphql/filter/filter.model';
|
||||
import { Sort } from 'src/app/model/graphql/filter/sort.model';
|
||||
import { Apollo, gql } from 'apollo-angular';
|
||||
import { QueryResult } from 'src/app/model/entities/query-result';
|
||||
import { DB_MODEL_FRAGMENT } from 'src/app/model/graphql/db-model.query';
|
||||
import { catchError, map } from 'rxjs/operators';
|
||||
import { SpinnerService } from 'src/app/service/spinner.service';
|
||||
} from "src/app/model/entities/role";
|
||||
import { Filter } from "src/app/model/graphql/filter/filter.model";
|
||||
import { Sort } from "src/app/model/graphql/filter/sort.model";
|
||||
import { Apollo, gql } from "apollo-angular";
|
||||
import { QueryResult } from "src/app/model/entities/query-result";
|
||||
import { DB_MODEL_FRAGMENT } from "src/app/model/graphql/db-model.query";
|
||||
import { catchError, map } from "rxjs/operators";
|
||||
import { SpinnerService } from "src/app/service/spinner.service";
|
||||
|
||||
@Injectable()
|
||||
export class RolesDataService
|
||||
@ -32,7 +32,7 @@ export class RolesDataService
|
||||
{
|
||||
constructor(
|
||||
private spinner: SpinnerService,
|
||||
private apollo: Apollo
|
||||
private apollo: Apollo,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
@ -41,7 +41,7 @@ export class RolesDataService
|
||||
filter?: Filter[] | undefined,
|
||||
sort?: Sort[] | undefined,
|
||||
skip?: number | undefined,
|
||||
take?: number | undefined
|
||||
take?: number | undefined,
|
||||
): Observable<QueryResult<Role>> {
|
||||
return this.apollo
|
||||
.query<{ roles: QueryResult<Role> }>({
|
||||
@ -75,12 +75,12 @@ export class RolesDataService
|
||||
},
|
||||
})
|
||||
.pipe(
|
||||
catchError(err => {
|
||||
catchError((err) => {
|
||||
this.spinner.hide();
|
||||
throw err;
|
||||
})
|
||||
}),
|
||||
)
|
||||
.pipe(map(result => result.data.roles));
|
||||
.pipe(map((result) => result.data.roles));
|
||||
}
|
||||
|
||||
loadById(id: number): Observable<Role> {
|
||||
@ -112,12 +112,12 @@ export class RolesDataService
|
||||
},
|
||||
})
|
||||
.pipe(
|
||||
catchError(err => {
|
||||
catchError((err) => {
|
||||
this.spinner.hide();
|
||||
throw err;
|
||||
})
|
||||
}),
|
||||
)
|
||||
.pipe(map(result => result.data.roles.nodes[0]));
|
||||
.pipe(map((result) => result.data.roles.nodes[0]));
|
||||
}
|
||||
|
||||
create(object: RoleCreateInput): Observable<Role | undefined> {
|
||||
@ -145,17 +145,17 @@ export class RolesDataService
|
||||
input: {
|
||||
name: object.name,
|
||||
description: object.description,
|
||||
permissions: object.permissions?.map(x => x.id),
|
||||
permissions: object.permissions?.map((x) => x.id),
|
||||
},
|
||||
},
|
||||
})
|
||||
.pipe(
|
||||
catchError(err => {
|
||||
catchError((err) => {
|
||||
this.spinner.hide();
|
||||
throw err;
|
||||
})
|
||||
}),
|
||||
)
|
||||
.pipe(map(result => result.data?.role.create));
|
||||
.pipe(map((result) => result.data?.role.create));
|
||||
}
|
||||
|
||||
update(object: RoleUpdateInput): Observable<Role | undefined> {
|
||||
@ -184,17 +184,17 @@ export class RolesDataService
|
||||
id: object.id,
|
||||
name: object.name,
|
||||
description: object.description,
|
||||
permissions: object.permissions?.map(x => x.id),
|
||||
permissions: object.permissions?.map((x) => x.id),
|
||||
},
|
||||
},
|
||||
})
|
||||
.pipe(
|
||||
catchError(err => {
|
||||
catchError((err) => {
|
||||
this.spinner.hide();
|
||||
throw err;
|
||||
})
|
||||
}),
|
||||
)
|
||||
.pipe(map(result => result.data?.role.update));
|
||||
.pipe(map((result) => result.data?.role.update));
|
||||
}
|
||||
|
||||
delete(object: Role): Observable<boolean> {
|
||||
@ -212,12 +212,12 @@ export class RolesDataService
|
||||
},
|
||||
})
|
||||
.pipe(
|
||||
catchError(err => {
|
||||
catchError((err) => {
|
||||
this.spinner.hide();
|
||||
throw err;
|
||||
})
|
||||
}),
|
||||
)
|
||||
.pipe(map(result => result.data?.role.delete ?? false));
|
||||
.pipe(map((result) => result.data?.role.delete ?? false));
|
||||
}
|
||||
|
||||
restore(object: Role): Observable<boolean> {
|
||||
@ -235,12 +235,12 @@ export class RolesDataService
|
||||
},
|
||||
})
|
||||
.pipe(
|
||||
catchError(err => {
|
||||
catchError((err) => {
|
||||
this.spinner.hide();
|
||||
throw err;
|
||||
})
|
||||
}),
|
||||
)
|
||||
.pipe(map(result => result.data?.role.restore ?? false));
|
||||
.pipe(map((result) => result.data?.role.restore ?? false));
|
||||
}
|
||||
|
||||
getAllPermissions(): Observable<Permission[]> {
|
||||
@ -258,12 +258,12 @@ export class RolesDataService
|
||||
`,
|
||||
})
|
||||
.pipe(
|
||||
catchError(err => {
|
||||
catchError((err) => {
|
||||
this.spinner.hide();
|
||||
throw err;
|
||||
})
|
||||
}),
|
||||
)
|
||||
.pipe(map(result => result.data.permissions.nodes));
|
||||
.pipe(map((result) => result.data.permissions.nodes));
|
||||
}
|
||||
|
||||
static provide(): Provider[] {
|
||||
|
@ -1,22 +1,22 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { SharedModule } from 'src/app/modules/shared/shared.module';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { PermissionGuard } from 'src/app/core/guard/permission.guard';
|
||||
import { PermissionsEnum } from 'src/app/model/auth/permissionsEnum';
|
||||
import { RoleFormPageComponent } from 'src/app/modules/admin/administration/roles/form-page/role-form-page.component';
|
||||
import { RolesPage } from 'src/app/modules/admin/administration/roles/roles.page';
|
||||
import { RolesDataService } from 'src/app/modules/admin/administration/roles/roles.data.service';
|
||||
import { RolesColumns } from 'src/app/modules/admin/administration/roles/roles.columns';
|
||||
import { NgModule } from "@angular/core";
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { SharedModule } from "src/app/modules/shared/shared.module";
|
||||
import { RouterModule, Routes } from "@angular/router";
|
||||
import { PermissionGuard } from "src/app/core/guard/permission.guard";
|
||||
import { PermissionsEnum } from "src/app/model/auth/permissionsEnum";
|
||||
import { RoleFormPageComponent } from "src/app/modules/admin/administration/roles/form-page/role-form-page.component";
|
||||
import { RolesPage } from "src/app/modules/admin/administration/roles/roles.page";
|
||||
import { RolesDataService } from "src/app/modules/admin/administration/roles/roles.data.service";
|
||||
import { RolesColumns } from "src/app/modules/admin/administration/roles/roles.columns";
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
title: 'Admin - Roles | Maxlan',
|
||||
path: "",
|
||||
title: "Admin - Roles | Maxlan",
|
||||
component: RolesPage,
|
||||
children: [
|
||||
{
|
||||
path: 'create',
|
||||
path: "create",
|
||||
component: RoleFormPageComponent,
|
||||
canActivate: [PermissionGuard],
|
||||
data: {
|
||||
@ -24,7 +24,7 @@ const routes: Routes = [
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'edit/:id',
|
||||
path: "edit/:id",
|
||||
component: RoleFormPageComponent,
|
||||
canActivate: [PermissionGuard],
|
||||
data: {
|
||||
|
@ -1,18 +1,18 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { RolesPage } from 'src/app/modules/admin/administration/roles/roles.page';
|
||||
import { SharedModule } from 'src/app/modules/shared/shared.module';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { AuthService } from 'src/app/service/auth.service';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
import { ErrorHandlingService } from 'src/app/service/error-handling.service';
|
||||
import { ToastService } from 'src/app/service/toast.service';
|
||||
import { ConfirmationService, MessageService } from 'primeng/api';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { of } from 'rxjs';
|
||||
import { PageDataService } from 'src/app/core/base/page.data.service';
|
||||
import { RolesDataService } from 'src/app/modules/admin/administration/roles/roles.data.service';
|
||||
import { ComponentFixture, TestBed } from "@angular/core/testing";
|
||||
import { RolesPage } from "src/app/modules/admin/administration/roles/roles.page";
|
||||
import { SharedModule } from "src/app/modules/shared/shared.module";
|
||||
import { TranslateModule } from "@ngx-translate/core";
|
||||
import { AuthService } from "src/app/service/auth.service";
|
||||
import { KeycloakService } from "keycloak-angular";
|
||||
import { ErrorHandlingService } from "src/app/service/error-handling.service";
|
||||
import { ToastService } from "src/app/service/toast.service";
|
||||
import { ConfirmationService, MessageService } from "primeng/api";
|
||||
import { ActivatedRoute } from "@angular/router";
|
||||
import { of } from "rxjs";
|
||||
import { PageDataService } from "src/app/core/base/page.data.service";
|
||||
import { RolesDataService } from "src/app/modules/admin/administration/roles/roles.data.service";
|
||||
|
||||
describe('RolesComponent', () => {
|
||||
describe("RolesComponent", () => {
|
||||
let component: RolesPage;
|
||||
let fixture: ComponentFixture<RolesPage>;
|
||||
|
||||
@ -45,7 +45,7 @@ describe('RolesComponent', () => {
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
it("should create", () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
@ -1,21 +1,21 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { PageBase } from 'src/app/core/base/page-base';
|
||||
import { Role } from 'src/app/model/entities/role';
|
||||
import { ToastService } from 'src/app/service/toast.service';
|
||||
import { ConfirmationDialogService } from 'src/app/service/confirmation-dialog.service';
|
||||
import { PermissionsEnum } from 'src/app/model/auth/permissionsEnum';
|
||||
import { RolesColumns } from 'src/app/modules/admin/administration/roles/roles.columns';
|
||||
import { RolesDataService } from 'src/app/modules/admin/administration/roles/roles.data.service';
|
||||
import { Component } from "@angular/core";
|
||||
import { PageBase } from "src/app/core/base/page-base";
|
||||
import { Role } from "src/app/model/entities/role";
|
||||
import { ToastService } from "src/app/service/toast.service";
|
||||
import { ConfirmationDialogService } from "src/app/service/confirmation-dialog.service";
|
||||
import { PermissionsEnum } from "src/app/model/auth/permissionsEnum";
|
||||
import { RolesColumns } from "src/app/modules/admin/administration/roles/roles.columns";
|
||||
import { RolesDataService } from "src/app/modules/admin/administration/roles/roles.data.service";
|
||||
|
||||
@Component({
|
||||
selector: 'app-roles',
|
||||
templateUrl: './roles.page.html',
|
||||
styleUrl: './roles.page.scss',
|
||||
selector: "app-roles",
|
||||
templateUrl: "./roles.page.html",
|
||||
styleUrl: "./roles.page.scss",
|
||||
})
|
||||
export class RolesPage extends PageBase<Role, RolesDataService, RolesColumns> {
|
||||
constructor(
|
||||
private toast: ToastService,
|
||||
private confirmation: ConfirmationDialogService
|
||||
private confirmation: ConfirmationDialogService,
|
||||
) {
|
||||
super(true, {
|
||||
read: [PermissionsEnum.roles],
|
||||
@ -30,7 +30,7 @@ export class RolesPage extends PageBase<Role, RolesDataService, RolesColumns> {
|
||||
this.loading = true;
|
||||
this.dataService
|
||||
.load(this.filter, this.sort, this.skip, this.take)
|
||||
.subscribe(result => {
|
||||
.subscribe((result) => {
|
||||
this.result = result;
|
||||
this.loading = false;
|
||||
});
|
||||
@ -38,12 +38,12 @@ export class RolesPage extends PageBase<Role, RolesDataService, RolesColumns> {
|
||||
|
||||
delete(role: Role): void {
|
||||
this.confirmation.confirmDialog({
|
||||
header: 'dialog.delete.header',
|
||||
message: 'dialog.delete.message',
|
||||
header: "dialog.delete.header",
|
||||
message: "dialog.delete.message",
|
||||
accept: () => {
|
||||
this.loading = true;
|
||||
this.dataService.delete(role).subscribe(() => {
|
||||
this.toast.success('action.deleted');
|
||||
this.toast.success("action.deleted");
|
||||
this.load();
|
||||
});
|
||||
},
|
||||
@ -53,12 +53,12 @@ export class RolesPage extends PageBase<Role, RolesDataService, RolesColumns> {
|
||||
|
||||
restore(role: Role): void {
|
||||
this.confirmation.confirmDialog({
|
||||
header: 'dialog.restore.header',
|
||||
message: 'dialog.restore.message',
|
||||
header: "dialog.restore.header",
|
||||
message: "dialog.restore.message",
|
||||
accept: () => {
|
||||
this.loading = true;
|
||||
this.dataService.restore(role).subscribe(() => {
|
||||
this.toast.success('action.restored');
|
||||
this.toast.success("action.restored");
|
||||
this.load();
|
||||
});
|
||||
},
|
||||
|
@ -1,17 +1,17 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { RoleFormPageComponent } from 'src/app/modules/admin/administration/roles/form-page/role-form-page.component';
|
||||
import { SharedModule } from 'src/app/modules/shared/shared.module';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { AuthService } from 'src/app/service/auth.service';
|
||||
import { ErrorHandlingService } from 'src/app/service/error-handling.service';
|
||||
import { ToastService } from 'src/app/service/toast.service';
|
||||
import { ConfirmationService, MessageService } from 'primeng/api';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { of } from 'rxjs';
|
||||
import { UsersDataService } from 'src/app/modules/admin/administration/users/users.data.service';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { ComponentFixture, TestBed } from "@angular/core/testing";
|
||||
import { RoleFormPageComponent } from "src/app/modules/admin/administration/roles/form-page/role-form-page.component";
|
||||
import { SharedModule } from "src/app/modules/shared/shared.module";
|
||||
import { TranslateModule } from "@ngx-translate/core";
|
||||
import { AuthService } from "src/app/service/auth.service";
|
||||
import { ErrorHandlingService } from "src/app/service/error-handling.service";
|
||||
import { ToastService } from "src/app/service/toast.service";
|
||||
import { ConfirmationService, MessageService } from "primeng/api";
|
||||
import { ActivatedRoute } from "@angular/router";
|
||||
import { of } from "rxjs";
|
||||
import { UsersDataService } from "src/app/modules/admin/administration/users/users.data.service";
|
||||
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
|
||||
|
||||
describe('UserFormpageComponent', () => {
|
||||
describe("UserFormpageComponent", () => {
|
||||
let component: RoleFormPageComponent;
|
||||
let fixture: ComponentFixture<RoleFormPageComponent>;
|
||||
|
||||
@ -44,7 +44,7 @@ describe('UserFormpageComponent', () => {
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
it("should create", () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
@ -1,20 +1,20 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { FormControl, FormGroup } from '@angular/forms';
|
||||
import { ToastService } from 'src/app/service/toast.service';
|
||||
import { FormPageBase } from 'src/app/core/base/form-page-base';
|
||||
import { Component } from "@angular/core";
|
||||
import { FormControl, FormGroup } from "@angular/forms";
|
||||
import { ToastService } from "src/app/service/toast.service";
|
||||
import { FormPageBase } from "src/app/core/base/form-page-base";
|
||||
import {
|
||||
NotExistingUser,
|
||||
User,
|
||||
UserCreateInput,
|
||||
UserUpdateInput,
|
||||
} from 'src/app/model/auth/user';
|
||||
import { Role } from 'src/app/model/entities/role';
|
||||
import { UsersDataService } from 'src/app/modules/admin/administration/users/users.data.service';
|
||||
} from "src/app/model/auth/user";
|
||||
import { Role } from "src/app/model/entities/role";
|
||||
import { UsersDataService } from "src/app/modules/admin/administration/users/users.data.service";
|
||||
|
||||
@Component({
|
||||
selector: 'app-user-form-page',
|
||||
templateUrl: './user-form-page.component.html',
|
||||
styleUrl: './user-form-page.component.scss',
|
||||
selector: "app-user-form-page",
|
||||
templateUrl: "./user-form-page.component.html",
|
||||
styleUrl: "./user-form-page.component.scss",
|
||||
})
|
||||
export class UserFormPageComponent extends FormPageBase<
|
||||
User,
|
||||
@ -27,12 +27,12 @@ export class UserFormPageComponent extends FormPageBase<
|
||||
|
||||
constructor(private toast: ToastService) {
|
||||
super();
|
||||
this.dataService.getAllRoles().subscribe(roles => {
|
||||
this.dataService.getAllRoles().subscribe((roles) => {
|
||||
this.roles = roles;
|
||||
});
|
||||
|
||||
if (!this.nodeId) {
|
||||
this.dataService.getNotExistingUsersFromKeycloak().subscribe(users => {
|
||||
this.dataService.getNotExistingUsersFromKeycloak().subscribe((users) => {
|
||||
this.notExistingUsers = users;
|
||||
this.node = this.new();
|
||||
this.setForm(this.node);
|
||||
@ -41,7 +41,7 @@ export class UserFormPageComponent extends FormPageBase<
|
||||
return;
|
||||
}
|
||||
|
||||
this.dataService.loadById(this.nodeId).subscribe(user => {
|
||||
this.dataService.loadById(this.nodeId).subscribe((user) => {
|
||||
this.node = user;
|
||||
this.setForm(this.node);
|
||||
});
|
||||
@ -59,47 +59,47 @@ export class UserFormPageComponent extends FormPageBase<
|
||||
email: new FormControl<string | undefined>(undefined),
|
||||
roles: new FormControl<Role[]>([]),
|
||||
});
|
||||
this.form.controls['id'].disable();
|
||||
this.form.controls['username'].disable();
|
||||
this.form.controls['email'].disable();
|
||||
this.form.controls["id"].disable();
|
||||
this.form.controls["username"].disable();
|
||||
this.form.controls["email"].disable();
|
||||
}
|
||||
|
||||
setForm(node?: User) {
|
||||
this.form.controls['id'].setValue(node?.id);
|
||||
this.form.controls['username'].setValue(node?.username);
|
||||
this.form.controls['email'].setValue(node?.email);
|
||||
this.form.controls['roles'].setValue(node?.roles ?? []);
|
||||
this.form.controls["id"].setValue(node?.id);
|
||||
this.form.controls["username"].setValue(node?.username);
|
||||
this.form.controls["email"].setValue(node?.email);
|
||||
this.form.controls["roles"].setValue(node?.roles ?? []);
|
||||
|
||||
if (this.notExistingUsers.length > 0) {
|
||||
this.form.controls['id'].enable();
|
||||
this.form.controls['keycloakId'].reset(undefined, { required: true });
|
||||
this.form.controls["id"].enable();
|
||||
this.form.controls["keycloakId"].reset(undefined, { required: true });
|
||||
}
|
||||
}
|
||||
|
||||
getCreateInput(): UserCreateInput {
|
||||
return {
|
||||
keycloakId: this.form.controls['keycloakId'].pristine
|
||||
keycloakId: this.form.controls["keycloakId"].pristine
|
||||
? undefined
|
||||
: this.form.controls['keycloakId'].value,
|
||||
roles: this.form.controls['roles'].pristine
|
||||
: this.form.controls["keycloakId"].value,
|
||||
roles: this.form.controls["roles"].pristine
|
||||
? undefined
|
||||
: this.form.controls['roles'].value,
|
||||
: this.form.controls["roles"].value,
|
||||
};
|
||||
}
|
||||
|
||||
getUpdateInput(): UserUpdateInput {
|
||||
return {
|
||||
id: this.form.controls['id'].value,
|
||||
roles: this.form.controls['roles'].pristine
|
||||
id: this.form.controls["id"].value,
|
||||
roles: this.form.controls["roles"].pristine
|
||||
? undefined
|
||||
: this.form.controls['roles'].value,
|
||||
: this.form.controls["roles"].value,
|
||||
};
|
||||
}
|
||||
|
||||
create(user: UserCreateInput): void {
|
||||
this.dataService.create(user).subscribe(() => {
|
||||
this.spinner.hide();
|
||||
this.toast.success('action.created');
|
||||
this.toast.success("action.created");
|
||||
this.close();
|
||||
});
|
||||
}
|
||||
@ -107,7 +107,7 @@ export class UserFormPageComponent extends FormPageBase<
|
||||
update(user: UserUpdateInput): void {
|
||||
this.dataService.update(user).subscribe(() => {
|
||||
this.spinner.hide();
|
||||
this.toast.success('action.created');
|
||||
this.toast.success("action.created");
|
||||
this.close();
|
||||
});
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { Injectable, Provider } from '@angular/core';
|
||||
import { Injectable, Provider } from "@angular/core";
|
||||
import {
|
||||
DB_MODEL_COLUMNS,
|
||||
ID_COLUMN,
|
||||
PageColumns,
|
||||
} from 'src/app/core/base/page.columns';
|
||||
import { TableColumn } from 'src/app/modules/shared/components/table/table.model';
|
||||
import { User } from 'src/app/model/auth/user';
|
||||
} from "src/app/core/base/page.columns";
|
||||
import { TableColumn } from "src/app/modules/shared/components/table/table.model";
|
||||
import { User } from "src/app/model/auth/user";
|
||||
|
||||
@Injectable()
|
||||
export class UsersColumns extends PageColumns<User> {
|
||||
@ -13,15 +13,15 @@ export class UsersColumns extends PageColumns<User> {
|
||||
return [
|
||||
ID_COLUMN,
|
||||
{
|
||||
name: 'username',
|
||||
label: 'user.username',
|
||||
type: 'text',
|
||||
name: "username",
|
||||
label: "user.username",
|
||||
type: "text",
|
||||
value: (row: User) => row.username,
|
||||
},
|
||||
{
|
||||
name: 'email',
|
||||
label: 'user.email',
|
||||
type: 'text',
|
||||
name: "email",
|
||||
label: "user.email",
|
||||
type: "text",
|
||||
value: (row: User) => row.email,
|
||||
},
|
||||
...DB_MODEL_COLUMNS,
|
||||
|
@ -1,26 +1,26 @@
|
||||
import { Injectable, Provider } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { Injectable, Provider } from "@angular/core";
|
||||
import { Observable } from "rxjs";
|
||||
import {
|
||||
Create,
|
||||
Delete,
|
||||
PageDataService,
|
||||
Restore,
|
||||
Update,
|
||||
} from 'src/app/core/base/page.data.service';
|
||||
import { Filter } from 'src/app/model/graphql/filter/filter.model';
|
||||
import { Sort } from 'src/app/model/graphql/filter/sort.model';
|
||||
import { Apollo, gql } from 'apollo-angular';
|
||||
import { QueryResult } from 'src/app/model/entities/query-result';
|
||||
import { DB_MODEL_FRAGMENT } from 'src/app/model/graphql/db-model.query';
|
||||
import { catchError, map } from 'rxjs/operators';
|
||||
import { SpinnerService } from 'src/app/service/spinner.service';
|
||||
} from "src/app/core/base/page.data.service";
|
||||
import { Filter } from "src/app/model/graphql/filter/filter.model";
|
||||
import { Sort } from "src/app/model/graphql/filter/sort.model";
|
||||
import { Apollo, gql } from "apollo-angular";
|
||||
import { QueryResult } from "src/app/model/entities/query-result";
|
||||
import { DB_MODEL_FRAGMENT } from "src/app/model/graphql/db-model.query";
|
||||
import { catchError, map } from "rxjs/operators";
|
||||
import { SpinnerService } from "src/app/service/spinner.service";
|
||||
import {
|
||||
NotExistingUser,
|
||||
User,
|
||||
UserCreateInput,
|
||||
UserUpdateInput,
|
||||
} from 'src/app/model/auth/user';
|
||||
import { Role } from 'src/app/model/entities/role';
|
||||
} from "src/app/model/auth/user";
|
||||
import { Role } from "src/app/model/entities/role";
|
||||
|
||||
@Injectable()
|
||||
export class UsersDataService
|
||||
@ -33,7 +33,7 @@ export class UsersDataService
|
||||
{
|
||||
constructor(
|
||||
private spinner: SpinnerService,
|
||||
private apollo: Apollo
|
||||
private apollo: Apollo,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
@ -42,7 +42,7 @@ export class UsersDataService
|
||||
filter?: Filter[] | undefined,
|
||||
sort?: Sort[] | undefined,
|
||||
skip?: number | undefined,
|
||||
take?: number | undefined
|
||||
take?: number | undefined,
|
||||
): Observable<QueryResult<User>> {
|
||||
return this.apollo
|
||||
.query<{ users: QueryResult<User> }>({
|
||||
@ -77,12 +77,12 @@ export class UsersDataService
|
||||
},
|
||||
})
|
||||
.pipe(
|
||||
catchError(err => {
|
||||
catchError((err) => {
|
||||
this.spinner.hide();
|
||||
throw err;
|
||||
})
|
||||
}),
|
||||
)
|
||||
.pipe(map(result => result.data.users));
|
||||
.pipe(map((result) => result.data.users));
|
||||
}
|
||||
|
||||
loadById(id: number): Observable<User> {
|
||||
@ -115,12 +115,12 @@ export class UsersDataService
|
||||
},
|
||||
})
|
||||
.pipe(
|
||||
catchError(err => {
|
||||
catchError((err) => {
|
||||
this.spinner.hide();
|
||||
throw err;
|
||||
})
|
||||
}),
|
||||
)
|
||||
.pipe(map(result => result.data.users.nodes[0]));
|
||||
.pipe(map((result) => result.data.users.nodes[0]));
|
||||
}
|
||||
|
||||
create(object: UserCreateInput): Observable<User | undefined> {
|
||||
@ -145,17 +145,17 @@ export class UsersDataService
|
||||
variables: {
|
||||
input: {
|
||||
keycloakId: object.keycloakId,
|
||||
roles: object.roles?.map(x => x.id),
|
||||
roles: object.roles?.map((x) => x.id),
|
||||
},
|
||||
},
|
||||
})
|
||||
.pipe(
|
||||
catchError(err => {
|
||||
catchError((err) => {
|
||||
this.spinner.hide();
|
||||
throw err;
|
||||
})
|
||||
}),
|
||||
)
|
||||
.pipe(map(result => result.data?.user.create));
|
||||
.pipe(map((result) => result.data?.user.create));
|
||||
}
|
||||
|
||||
update(object: UserUpdateInput): Observable<User | undefined> {
|
||||
@ -180,17 +180,17 @@ export class UsersDataService
|
||||
variables: {
|
||||
input: {
|
||||
id: object.id,
|
||||
roles: object.roles?.map(x => x.id),
|
||||
roles: object.roles?.map((x) => x.id),
|
||||
},
|
||||
},
|
||||
})
|
||||
.pipe(
|
||||
catchError(err => {
|
||||
catchError((err) => {
|
||||
this.spinner.hide();
|
||||
throw err;
|
||||
})
|
||||
}),
|
||||
)
|
||||
.pipe(map(result => result.data?.user.update));
|
||||
.pipe(map((result) => result.data?.user.update));
|
||||
}
|
||||
|
||||
delete(object: User): Observable<boolean> {
|
||||
@ -208,12 +208,12 @@ export class UsersDataService
|
||||
},
|
||||
})
|
||||
.pipe(
|
||||
catchError(err => {
|
||||
catchError((err) => {
|
||||
this.spinner.hide();
|
||||
throw err;
|
||||
})
|
||||
}),
|
||||
)
|
||||
.pipe(map(result => result.data?.user.delete ?? false));
|
||||
.pipe(map((result) => result.data?.user.delete ?? false));
|
||||
}
|
||||
|
||||
restore(object: User): Observable<boolean> {
|
||||
@ -231,12 +231,12 @@ export class UsersDataService
|
||||
},
|
||||
})
|
||||
.pipe(
|
||||
catchError(err => {
|
||||
catchError((err) => {
|
||||
this.spinner.hide();
|
||||
throw err;
|
||||
})
|
||||
}),
|
||||
)
|
||||
.pipe(map(result => result.data?.user.restore ?? false));
|
||||
.pipe(map((result) => result.data?.user.restore ?? false));
|
||||
}
|
||||
|
||||
getAllRoles(): Observable<Role[]> {
|
||||
@ -254,12 +254,12 @@ export class UsersDataService
|
||||
`,
|
||||
})
|
||||
.pipe(
|
||||
catchError(err => {
|
||||
catchError((err) => {
|
||||
this.spinner.hide();
|
||||
throw err;
|
||||
})
|
||||
}),
|
||||
)
|
||||
.pipe(map(result => result.data.roles.nodes));
|
||||
.pipe(map((result) => result.data.roles.nodes));
|
||||
}
|
||||
|
||||
getNotExistingUsersFromKeycloak(): Observable<NotExistingUser[]> {
|
||||
@ -277,12 +277,12 @@ export class UsersDataService
|
||||
`,
|
||||
})
|
||||
.pipe(
|
||||
catchError(err => {
|
||||
catchError((err) => {
|
||||
this.spinner.hide();
|
||||
throw err;
|
||||
})
|
||||
}),
|
||||
)
|
||||
.pipe(map(result => result.data.notExistingUsersFromKeycloak.nodes));
|
||||
.pipe(map((result) => result.data.notExistingUsersFromKeycloak.nodes));
|
||||
}
|
||||
|
||||
static provide(): Provider[] {
|
||||
|
@ -1,22 +1,22 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { SharedModule } from 'src/app/modules/shared/shared.module';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { PermissionGuard } from 'src/app/core/guard/permission.guard';
|
||||
import { PermissionsEnum } from 'src/app/model/auth/permissionsEnum';
|
||||
import { UserFormPageComponent } from 'src/app/modules/admin/administration/users/form-page/user-form-page.component';
|
||||
import { UsersPage } from 'src/app/modules/admin/administration/users/users.page';
|
||||
import { UsersDataService } from 'src/app/modules/admin/administration/users/users.data.service';
|
||||
import { UsersColumns } from 'src/app/modules/admin/administration/users/users.columns';
|
||||
import { NgModule } from "@angular/core";
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { SharedModule } from "src/app/modules/shared/shared.module";
|
||||
import { RouterModule, Routes } from "@angular/router";
|
||||
import { PermissionGuard } from "src/app/core/guard/permission.guard";
|
||||
import { PermissionsEnum } from "src/app/model/auth/permissionsEnum";
|
||||
import { UserFormPageComponent } from "src/app/modules/admin/administration/users/form-page/user-form-page.component";
|
||||
import { UsersPage } from "src/app/modules/admin/administration/users/users.page";
|
||||
import { UsersDataService } from "src/app/modules/admin/administration/users/users.data.service";
|
||||
import { UsersColumns } from "src/app/modules/admin/administration/users/users.columns";
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
title: 'Admin - Users | Maxlan',
|
||||
path: "",
|
||||
title: "Admin - Users | Maxlan",
|
||||
component: UsersPage,
|
||||
children: [
|
||||
{
|
||||
path: 'create',
|
||||
path: "create",
|
||||
component: UserFormPageComponent,
|
||||
canActivate: [PermissionGuard],
|
||||
data: {
|
||||
@ -24,7 +24,7 @@ const routes: Routes = [
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'edit/:id',
|
||||
path: "edit/:id",
|
||||
component: UserFormPageComponent,
|
||||
canActivate: [PermissionGuard],
|
||||
data: {
|
||||
|
@ -1,18 +1,18 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { UsersPage } from 'src/app/modules/admin/administration/users/users.page';
|
||||
import { SharedModule } from 'src/app/modules/shared/shared.module';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { AuthService } from 'src/app/service/auth.service';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
import { ErrorHandlingService } from 'src/app/service/error-handling.service';
|
||||
import { ToastService } from 'src/app/service/toast.service';
|
||||
import { ConfirmationService, MessageService } from 'primeng/api';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { of } from 'rxjs';
|
||||
import { PageDataService } from 'src/app/core/base/page.data.service';
|
||||
import { UsersDataService } from 'src/app/modules/admin/administration/users/users.data.service';
|
||||
import { ComponentFixture, TestBed } from "@angular/core/testing";
|
||||
import { UsersPage } from "src/app/modules/admin/administration/users/users.page";
|
||||
import { SharedModule } from "src/app/modules/shared/shared.module";
|
||||
import { TranslateModule } from "@ngx-translate/core";
|
||||
import { AuthService } from "src/app/service/auth.service";
|
||||
import { KeycloakService } from "keycloak-angular";
|
||||
import { ErrorHandlingService } from "src/app/service/error-handling.service";
|
||||
import { ToastService } from "src/app/service/toast.service";
|
||||
import { ConfirmationService, MessageService } from "primeng/api";
|
||||
import { ActivatedRoute } from "@angular/router";
|
||||
import { of } from "rxjs";
|
||||
import { PageDataService } from "src/app/core/base/page.data.service";
|
||||
import { UsersDataService } from "src/app/modules/admin/administration/users/users.data.service";
|
||||
|
||||
describe('UsersComponent', () => {
|
||||
describe("UsersComponent", () => {
|
||||
let component: UsersPage;
|
||||
let fixture: ComponentFixture<UsersPage>;
|
||||
|
||||
@ -45,7 +45,7 @@ describe('UsersComponent', () => {
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
it("should create", () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
@ -1,21 +1,21 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { PageBase } from 'src/app/core/base/page-base';
|
||||
import { ToastService } from 'src/app/service/toast.service';
|
||||
import { ConfirmationDialogService } from 'src/app/service/confirmation-dialog.service';
|
||||
import { PermissionsEnum } from 'src/app/model/auth/permissionsEnum';
|
||||
import { User } from 'src/app/model/auth/user';
|
||||
import { UsersColumns } from 'src/app/modules/admin/administration/users/users.columns';
|
||||
import { UsersDataService } from 'src/app/modules/admin/administration/users/users.data.service';
|
||||
import { Component } from "@angular/core";
|
||||
import { PageBase } from "src/app/core/base/page-base";
|
||||
import { ToastService } from "src/app/service/toast.service";
|
||||
import { ConfirmationDialogService } from "src/app/service/confirmation-dialog.service";
|
||||
import { PermissionsEnum } from "src/app/model/auth/permissionsEnum";
|
||||
import { User } from "src/app/model/auth/user";
|
||||
import { UsersColumns } from "src/app/modules/admin/administration/users/users.columns";
|
||||
import { UsersDataService } from "src/app/modules/admin/administration/users/users.data.service";
|
||||
|
||||
@Component({
|
||||
selector: 'app-users',
|
||||
templateUrl: './users.page.html',
|
||||
styleUrl: './users.page.scss',
|
||||
selector: "app-users",
|
||||
templateUrl: "./users.page.html",
|
||||
styleUrl: "./users.page.scss",
|
||||
})
|
||||
export class UsersPage extends PageBase<User, UsersDataService, UsersColumns> {
|
||||
constructor(
|
||||
private toast: ToastService,
|
||||
private confirmation: ConfirmationDialogService
|
||||
private confirmation: ConfirmationDialogService,
|
||||
) {
|
||||
super(true, {
|
||||
read: [PermissionsEnum.users],
|
||||
@ -30,7 +30,7 @@ export class UsersPage extends PageBase<User, UsersDataService, UsersColumns> {
|
||||
this.loading = true;
|
||||
this.dataService
|
||||
.load(this.filter, this.sort, this.skip, this.take)
|
||||
.subscribe(result => {
|
||||
.subscribe((result) => {
|
||||
this.result = result;
|
||||
this.loading = false;
|
||||
});
|
||||
@ -38,12 +38,12 @@ export class UsersPage extends PageBase<User, UsersDataService, UsersColumns> {
|
||||
|
||||
delete(user: User): void {
|
||||
this.confirmation.confirmDialog({
|
||||
header: 'dialog.delete.header',
|
||||
message: 'dialog.delete.message',
|
||||
header: "dialog.delete.header",
|
||||
message: "dialog.delete.message",
|
||||
accept: () => {
|
||||
this.loading = true;
|
||||
this.dataService.delete(user).subscribe(() => {
|
||||
this.toast.success('action.deleted');
|
||||
this.toast.success("action.deleted");
|
||||
this.load();
|
||||
});
|
||||
},
|
||||
@ -53,12 +53,12 @@ export class UsersPage extends PageBase<User, UsersDataService, UsersColumns> {
|
||||
|
||||
restore(user: User): void {
|
||||
this.confirmation.confirmDialog({
|
||||
header: 'dialog.restore.header',
|
||||
message: 'dialog.restore.message',
|
||||
header: "dialog.restore.header",
|
||||
message: "dialog.restore.message",
|
||||
accept: () => {
|
||||
this.loading = true;
|
||||
this.dataService.restore(user).subscribe(() => {
|
||||
this.toast.success('action.restored');
|
||||
this.toast.success("action.restored");
|
||||
this.load();
|
||||
});
|
||||
},
|
||||
|
@ -1,17 +1,17 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { RoleFormPageComponent } from 'src/app/modules/admin/administration/roles/form-page/role-form-page.component';
|
||||
import { SharedModule } from 'src/app/modules/shared/shared.module';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { AuthService } from 'src/app/service/auth.service';
|
||||
import { ErrorHandlingService } from 'src/app/service/error-handling.service';
|
||||
import { ToastService } from 'src/app/service/toast.service';
|
||||
import { ConfirmationService, MessageService } from 'primeng/api';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { of } from 'rxjs';
|
||||
import { ApiKeysDataService } from 'src/app/modules/admin/administration/api-keys/api-keys.data.service';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { ComponentFixture, TestBed } from "@angular/core/testing";
|
||||
import { RoleFormPageComponent } from "src/app/modules/admin/administration/roles/form-page/role-form-page.component";
|
||||
import { SharedModule } from "src/app/modules/shared/shared.module";
|
||||
import { TranslateModule } from "@ngx-translate/core";
|
||||
import { AuthService } from "src/app/service/auth.service";
|
||||
import { ErrorHandlingService } from "src/app/service/error-handling.service";
|
||||
import { ToastService } from "src/app/service/toast.service";
|
||||
import { ConfirmationService, MessageService } from "primeng/api";
|
||||
import { ActivatedRoute } from "@angular/router";
|
||||
import { of } from "rxjs";
|
||||
import { ApiKeysDataService } from "src/app/modules/admin/administration/api-keys/api-keys.data.service";
|
||||
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
|
||||
|
||||
describe('ApiKeyFormpageComponent', () => {
|
||||
describe("ApiKeyFormpageComponent", () => {
|
||||
let component: RoleFormPageComponent;
|
||||
let fixture: ComponentFixture<RoleFormPageComponent>;
|
||||
|
||||
@ -44,7 +44,7 @@ describe('ApiKeyFormpageComponent', () => {
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
it("should create", () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
@ -1,18 +1,18 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ApiKeysPage } from 'src/app/modules/admin/administration/api-keys/api-keys.page';
|
||||
import { SharedModule } from 'src/app/modules/shared/shared.module';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { AuthService } from 'src/app/service/auth.service';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
import { ErrorHandlingService } from 'src/app/service/error-handling.service';
|
||||
import { ToastService } from 'src/app/service/toast.service';
|
||||
import { ConfirmationService, MessageService } from 'primeng/api';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { of } from 'rxjs';
|
||||
import { PageDataService } from 'src/app/core/base/page.data.service';
|
||||
import { ApiKeysDataService } from 'src/app/modules/admin/administration/api-keys/api-keys.data.service';
|
||||
import { ComponentFixture, TestBed } from "@angular/core/testing";
|
||||
import { ApiKeysPage } from "src/app/modules/admin/administration/api-keys/api-keys.page";
|
||||
import { SharedModule } from "src/app/modules/shared/shared.module";
|
||||
import { TranslateModule } from "@ngx-translate/core";
|
||||
import { AuthService } from "src/app/service/auth.service";
|
||||
import { KeycloakService } from "keycloak-angular";
|
||||
import { ErrorHandlingService } from "src/app/service/error-handling.service";
|
||||
import { ToastService } from "src/app/service/toast.service";
|
||||
import { ConfirmationService, MessageService } from "primeng/api";
|
||||
import { ActivatedRoute } from "@angular/router";
|
||||
import { of } from "rxjs";
|
||||
import { PageDataService } from "src/app/core/base/page.data.service";
|
||||
import { ApiKeysDataService } from "src/app/modules/admin/administration/api-keys/api-keys.data.service";
|
||||
|
||||
describe('ApiKeysComponent', () => {
|
||||
describe("ApiKeysComponent", () => {
|
||||
let component: ApiKeysPage;
|
||||
let fixture: ComponentFixture<ApiKeysPage>;
|
||||
|
||||
@ -45,7 +45,7 @@ describe('ApiKeysComponent', () => {
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
it("should create", () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
@ -1,10 +1,9 @@
|
||||
import {NgModule} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {RouterModule, Routes} from '@angular/router';
|
||||
import {SharedModule} from 'src/app/modules/shared/shared.module';
|
||||
import { NgModule } from "@angular/core";
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { RouterModule, Routes } from "@angular/router";
|
||||
import { SharedModule } from "src/app/modules/shared/shared.module";
|
||||
|
||||
const routes: Routes = [
|
||||
];
|
||||
const routes: Routes = [];
|
||||
|
||||
@NgModule({
|
||||
declarations: [],
|
||||
|
@ -20,7 +20,7 @@
|
||||
<input pInputText class="value" type="number" formControlName="id"/>
|
||||
</div>
|
||||
<div class="form-page-input">
|
||||
<p class="label">{{ 'common.short_url' | translate }}</p>
|
||||
<p class="label">{{ 'short_url.short_url' | translate }}</p>
|
||||
<input
|
||||
pInputText
|
||||
class="value"
|
||||
@ -28,7 +28,7 @@
|
||||
formControlName="shortUrl"/>
|
||||
</div>
|
||||
<div class="form-page-input">
|
||||
<p class="label">{{ 'common.target_url' | translate }}</p>
|
||||
<p class="label">{{ 'short_url.target_url' | translate }}</p>
|
||||
<input
|
||||
pInputText
|
||||
class="value"
|
||||
|
@ -1,17 +1,17 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { RoleFormPageComponent } from 'src/app/modules/admin/administration/roles/form-page/role-form-page.component';
|
||||
import { SharedModule } from 'src/app/modules/shared/shared.module';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { AuthService } from 'src/app/service/auth.service';
|
||||
import { ErrorHandlingService } from 'src/app/service/error-handling.service';
|
||||
import { ToastService } from 'src/app/service/toast.service';
|
||||
import { ConfirmationService, MessageService } from 'primeng/api';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { of } from 'rxjs';
|
||||
import { ApiKeysDataService } from 'src/app/modules/admin/administration/api-keys/api-keys.data.service';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { ComponentFixture, TestBed } from "@angular/core/testing";
|
||||
import { RoleFormPageComponent } from "src/app/modules/admin/administration/roles/form-page/role-form-page.component";
|
||||
import { SharedModule } from "src/app/modules/shared/shared.module";
|
||||
import { TranslateModule } from "@ngx-translate/core";
|
||||
import { AuthService } from "src/app/service/auth.service";
|
||||
import { ErrorHandlingService } from "src/app/service/error-handling.service";
|
||||
import { ToastService } from "src/app/service/toast.service";
|
||||
import { ConfirmationService, MessageService } from "primeng/api";
|
||||
import { ActivatedRoute } from "@angular/router";
|
||||
import { of } from "rxjs";
|
||||
import { ApiKeysDataService } from "src/app/modules/admin/administration/api-keys/api-keys.data.service";
|
||||
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
|
||||
|
||||
describe('ApiKeyFormpageComponent', () => {
|
||||
describe("ApiKeyFormpageComponent", () => {
|
||||
let component: RoleFormPageComponent;
|
||||
let fixture: ComponentFixture<RoleFormPageComponent>;
|
||||
|
||||
@ -44,7 +44,7 @@ describe('ApiKeyFormpageComponent', () => {
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
it("should create", () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
@ -65,9 +65,22 @@ export class ShortUrlFormPageComponent extends FormPageBase<
|
||||
this.form.controls["id"].disable();
|
||||
}
|
||||
|
||||
private generateRandomString(length: number): string {
|
||||
const characters =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
let result = "";
|
||||
const charactersLength = characters.length;
|
||||
for (let i = 0; i < length; i++) {
|
||||
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
setForm(node?: ShortUrl) {
|
||||
this.form.controls["id"].setValue(node?.id);
|
||||
this.form.controls["shortUrl"].setValue(node?.shortUrl);
|
||||
this.form.controls["shortUrl"].setValue(
|
||||
node?.shortUrl ?? this.generateRandomString(8),
|
||||
);
|
||||
this.form.controls["targetUrl"].setValue(node?.targetUrl);
|
||||
this.form.controls["description"].setValue(node?.description);
|
||||
this.form.controls["groupId"].setValue(node?.group?.id);
|
||||
@ -75,9 +88,7 @@ export class ShortUrlFormPageComponent extends FormPageBase<
|
||||
|
||||
getCreateInput(): ShortUrlCreateInput {
|
||||
return {
|
||||
shortUrl: this.form.controls["shortUrl"].pristine
|
||||
? undefined
|
||||
: (this.form.controls["shortUrl"].value ?? undefined),
|
||||
shortUrl: this.form.controls["shortUrl"].value ?? undefined,
|
||||
targetUrl: this.form.controls["targetUrl"].pristine
|
||||
? undefined
|
||||
: (this.form.controls["targetUrl"].value ?? undefined),
|
||||
|
@ -14,14 +14,14 @@ export class ShortUrlsColumns extends PageColumns<ShortUrl> {
|
||||
ID_COLUMN,
|
||||
{
|
||||
name: "short_url",
|
||||
label: "common.short_url",
|
||||
label: "short_url.short_url",
|
||||
type: "text",
|
||||
filterable: true,
|
||||
value: (row: ShortUrl) => row.shortUrl,
|
||||
},
|
||||
{
|
||||
name: "target_url",
|
||||
label: "common.target_url",
|
||||
label: "short_url.target_url",
|
||||
type: "text",
|
||||
filterable: true,
|
||||
value: (row: ShortUrl) => row.targetUrl,
|
||||
@ -33,13 +33,6 @@ export class ShortUrlsColumns extends PageColumns<ShortUrl> {
|
||||
filterable: true,
|
||||
value: (row: ShortUrl) => row.description,
|
||||
},
|
||||
{
|
||||
name: "group",
|
||||
label: "common.group",
|
||||
type: "text",
|
||||
filterable: true,
|
||||
value: (row: ShortUrl) => row.group?.name,
|
||||
},
|
||||
...DB_MODEL_COLUMNS,
|
||||
];
|
||||
}
|
||||
|
@ -1,19 +1,107 @@
|
||||
<app-table
|
||||
[rows]="result.nodes"
|
||||
[columns]="columns"
|
||||
[rowsPerPageOptions]="rowsPerPageOptions"
|
||||
[totalCount]="result.totalCount"
|
||||
[requireAnyPermissions]="requiredPermissions"
|
||||
countHeaderTranslation="group.count_header"
|
||||
[loading]="loading"
|
||||
[(filter)]="filter"
|
||||
[(sort)]="sort"
|
||||
[(skip)]="skip"
|
||||
[(take)]="take"
|
||||
(load)="load()"
|
||||
[create]="true"
|
||||
[update]="true"
|
||||
(delete)="delete($event)"
|
||||
(restore)="restore($event)"></app-table>
|
||||
|
||||
<router-outlet></router-outlet>
|
||||
|
||||
<ng-template #shortUrl let-url>
|
||||
<div class="flex flex-col gap-2 bg rounded-l p-3">
|
||||
<div class="flex flex-col gap-2">
|
||||
<h3>{{ url.shortUrl }}</h3>
|
||||
<div class="grid-container">
|
||||
<span class="grid-label font-bold">{{ 'short_url.target_url' | translate }}:</span>
|
||||
<a class="grid-value" [href]="url.targetUrl" target="_blank">{{ url.targetUrl }}</a>
|
||||
</div>
|
||||
<div class="grid-container">
|
||||
<span class="grid-label font-bold">{{ 'common.description' | translate }}:</span>
|
||||
<span class="grid-value">{{ url.description }}</span>
|
||||
</div>
|
||||
<div class="grid-container">
|
||||
<span class="grid-label font-bold">{{ 'short_url.visits' | translate }}:</span>
|
||||
<span class="grid-value">{{ url.visits }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-end">
|
||||
<p-button
|
||||
class="icon-btn btn"
|
||||
icon="pi pi-clone"
|
||||
(onClick)="copy(url.shortUrl)"></p-button>
|
||||
<p-button
|
||||
class="icon-btn btn"
|
||||
icon="pi pi-external-link"
|
||||
(onClick)="open(url.shortUrl)"></p-button>
|
||||
|
||||
<p-button
|
||||
*ngIf="hasPermissions.update"
|
||||
class="icon-btn btn"
|
||||
icon="pi pi-pencil"
|
||||
tooltipPosition="left"
|
||||
pTooltip="{{ 'table.update' | translate }}"
|
||||
[disabled]="url?.deleted"
|
||||
routerLink="edit/{{ url.id }}"></p-button>
|
||||
<p-button
|
||||
*ngIf="hasPermissions.delete"
|
||||
class="icon-btn btn danger-icon-btn"
|
||||
icon="pi pi-trash"
|
||||
tooltipPosition="left"
|
||||
pTooltip="{{ 'table.delete' | translate }}"
|
||||
[disabled]="url?.deleted"
|
||||
(click)="delete(url)"></p-button>
|
||||
<p-button
|
||||
*ngIf="url?.deleted && hasPermissions.restore"
|
||||
class="icon-btn btn"
|
||||
icon="pi pi-undo"
|
||||
tooltipPosition="left"
|
||||
pTooltip="{{ 'table.restore' | translate }}"
|
||||
(click)="restore(url)"></p-button>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="flex justify-between gap-1">
|
||||
<div><h1>{{ 'short_url.short_url' | translate }}</h1></div>
|
||||
<div class="flex space-x-2">
|
||||
<p-button
|
||||
*ngIf="hasPermissions.create"
|
||||
class="icon-btn btn"
|
||||
icon="pi pi-plus"
|
||||
tooltipPosition="left"
|
||||
pTooltip="{{ 'table.create' | translate }}"
|
||||
routerLink="create"></p-button>
|
||||
<p-button
|
||||
class="icon-btn btn"
|
||||
[styleClass]="showDeleted ? 'highlight2' : ''"
|
||||
icon="pi pi-trash"
|
||||
tooltipPosition="left"
|
||||
pTooltip="{{
|
||||
(showDeleted ? 'table.hide_deleted' : 'table.show_deleted')
|
||||
| translate
|
||||
}}"
|
||||
(click)="toggleShowDeleted()"></p-button>
|
||||
<p-button
|
||||
class="icon-btn btn"
|
||||
icon="pi pi-sort-alt-slash"
|
||||
tooltipPosition="left"
|
||||
pTooltip="{{ 'table.reset_sort' | translate }}"
|
||||
(click)="resetSort()"></p-button>
|
||||
<p-button
|
||||
class="icon-btn btn"
|
||||
icon="pi pi-filter-slash"
|
||||
tooltipPosition="left"
|
||||
pTooltip="{{ 'table.reset_filters' | translate }}"
|
||||
(click)="resetFilters()"></p-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="divider"></div>
|
||||
<div class="bg2 rounded-xl p-3">
|
||||
<div *ngFor="let url of shortUrlsWithoutGroup">
|
||||
<ng-template [ngTemplateOutlet]="shortUrl" [ngTemplateOutletContext]="{ $implicit: url }"></ng-template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div *ngFor="let group of groupsFromGroupedShortUrls" class="bg2 rounded-xl p-3">
|
||||
<div><h2>{{ group }}</h2></div>
|
||||
<div class="flex flex-col gap-1.5">
|
||||
<ng-template *ngFor="let url of groupedShortUrls[group]" [ngTemplateOutlet]="shortUrl"
|
||||
[ngTemplateOutletContext]="{ $implicit: url }"></ng-template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,14 @@
|
||||
.grid-container {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-gap: 10px;
|
||||
|
||||
.grid-label {
|
||||
grid-column: 1;
|
||||
}
|
||||
|
||||
.grid-value {
|
||||
grid-column: 2;
|
||||
word-break: break-all;
|
||||
}
|
||||
}
|
@ -1,18 +1,18 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ApiKeysPage } from 'src/app/modules/admin/administration/api-keys/api-keys.page';
|
||||
import { SharedModule } from 'src/app/modules/shared/shared.module';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { AuthService } from 'src/app/service/auth.service';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
import { ErrorHandlingService } from 'src/app/service/error-handling.service';
|
||||
import { ToastService } from 'src/app/service/toast.service';
|
||||
import { ConfirmationService, MessageService } from 'primeng/api';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { of } from 'rxjs';
|
||||
import { PageDataService } from 'src/app/core/base/page.data.service';
|
||||
import { ApiKeysDataService } from 'src/app/modules/admin/administration/api-keys/api-keys.data.service';
|
||||
import { ComponentFixture, TestBed } from "@angular/core/testing";
|
||||
import { ApiKeysPage } from "src/app/modules/admin/administration/api-keys/api-keys.page";
|
||||
import { SharedModule } from "src/app/modules/shared/shared.module";
|
||||
import { TranslateModule } from "@ngx-translate/core";
|
||||
import { AuthService } from "src/app/service/auth.service";
|
||||
import { KeycloakService } from "keycloak-angular";
|
||||
import { ErrorHandlingService } from "src/app/service/error-handling.service";
|
||||
import { ToastService } from "src/app/service/toast.service";
|
||||
import { ConfirmationService, MessageService } from "primeng/api";
|
||||
import { ActivatedRoute } from "@angular/router";
|
||||
import { of } from "rxjs";
|
||||
import { PageDataService } from "src/app/core/base/page.data.service";
|
||||
import { ApiKeysDataService } from "src/app/modules/admin/administration/api-keys/api-keys.data.service";
|
||||
|
||||
describe('ApiKeysComponent', () => {
|
||||
describe("ApiKeysComponent", () => {
|
||||
let component: ApiKeysPage;
|
||||
let fixture: ComponentFixture<ApiKeysPage>;
|
||||
|
||||
@ -45,7 +45,7 @@ describe('ApiKeysComponent', () => {
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
it("should create", () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Component } from "@angular/core";
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { PageBase } from "src/app/core/base/page-base";
|
||||
import { ToastService } from "src/app/service/toast.service";
|
||||
import { ConfirmationDialogService } from "src/app/service/confirmation-dialog.service";
|
||||
@ -6,20 +6,44 @@ import { PermissionsEnum } from "src/app/model/auth/permissionsEnum";
|
||||
import { ShortUrl } from "src/app/model/entities/short-url";
|
||||
import { ShortUrlsDataService } from "src/app/modules/admin/short-urls/short-urls.data.service";
|
||||
import { ShortUrlsColumns } from "src/app/modules/admin/short-urls/short-urls.columns";
|
||||
import { AuthService } from "src/app/service/auth.service";
|
||||
import { Filter } from "src/app/model/graphql/filter/filter.model";
|
||||
|
||||
@Component({
|
||||
selector: "app-short-urls",
|
||||
templateUrl: "./short-urls.page.html",
|
||||
styleUrl: "./short-urls.page.scss",
|
||||
})
|
||||
export class ShortUrlsPage extends PageBase<
|
||||
ShortUrl,
|
||||
ShortUrlsDataService,
|
||||
ShortUrlsColumns
|
||||
> {
|
||||
export class ShortUrlsPage
|
||||
extends PageBase<ShortUrl, ShortUrlsDataService, ShortUrlsColumns>
|
||||
implements OnInit
|
||||
{
|
||||
shortUrlsWithoutGroup: ShortUrl[] = [];
|
||||
groupedShortUrls: { [key: string]: ShortUrl[] } = {};
|
||||
|
||||
get groupsFromGroupedShortUrls() {
|
||||
return Object.keys(this.groupedShortUrls);
|
||||
}
|
||||
|
||||
private hide_deleted_filter: Filter = { deleted: { equal: false } };
|
||||
get showDeleted() {
|
||||
return !this.filter.some(
|
||||
(f) => JSON.stringify(f) === JSON.stringify(this.hide_deleted_filter),
|
||||
);
|
||||
}
|
||||
|
||||
protected hasPermissions = {
|
||||
read: false,
|
||||
create: false,
|
||||
update: false,
|
||||
delete: false,
|
||||
restore: false,
|
||||
};
|
||||
|
||||
constructor(
|
||||
private toast: ToastService,
|
||||
private confirmation: ConfirmationDialogService,
|
||||
private auth: AuthService,
|
||||
) {
|
||||
super(true, {
|
||||
read: [PermissionsEnum.shortUrls],
|
||||
@ -30,12 +54,41 @@ export class ShortUrlsPage extends PageBase<
|
||||
});
|
||||
}
|
||||
|
||||
async ngOnInit() {
|
||||
this.hasPermissions = {
|
||||
read: await this.auth.hasAnyPermissionLazy(
|
||||
this.requiredPermissions.read ?? [],
|
||||
),
|
||||
create: await this.auth.hasAnyPermissionLazy(
|
||||
this.requiredPermissions.create ?? [],
|
||||
),
|
||||
update: await this.auth.hasAnyPermissionLazy(
|
||||
this.requiredPermissions.update ?? [],
|
||||
),
|
||||
delete: await this.auth.hasAnyPermissionLazy(
|
||||
this.requiredPermissions.delete ?? [],
|
||||
),
|
||||
restore: await this.auth.hasAnyPermissionLazy(
|
||||
this.requiredPermissions.restore ?? [],
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
load(): void {
|
||||
this.loading = true;
|
||||
this.dataService
|
||||
.load(this.filter, this.sort, this.skip, this.take)
|
||||
.subscribe((result) => {
|
||||
this.result = result;
|
||||
this.shortUrlsWithoutGroup = this.getShortUrlsWithoutGroup();
|
||||
this.groupedShortUrls = this.getShortUrlsWithGroup();
|
||||
|
||||
console.warn(
|
||||
"result",
|
||||
result,
|
||||
this.shortUrlsWithoutGroup,
|
||||
this.groupedShortUrls,
|
||||
);
|
||||
this.loading = false;
|
||||
});
|
||||
}
|
||||
@ -69,4 +122,54 @@ export class ShortUrlsPage extends PageBase<
|
||||
messageParams: { entity: group.shortUrl },
|
||||
});
|
||||
}
|
||||
|
||||
toggleShowDeleted() {
|
||||
if (!this.showDeleted) {
|
||||
this.filter.splice(this.filter.indexOf(this.hide_deleted_filter), 1);
|
||||
} else {
|
||||
this.filter.push(this.hide_deleted_filter);
|
||||
}
|
||||
|
||||
this.load();
|
||||
}
|
||||
|
||||
resetSort() {
|
||||
this.sort = [];
|
||||
this.load();
|
||||
}
|
||||
|
||||
resetFilters() {
|
||||
this.filter = [];
|
||||
this.load();
|
||||
}
|
||||
|
||||
open(url: string) {
|
||||
window.open(url, "_blank");
|
||||
}
|
||||
|
||||
copy(val: string) {
|
||||
navigator.clipboard.writeText(`${window.origin}/${val}`).then(() => {
|
||||
this.toast.info("common.copied", "common.copied_to_clipboard");
|
||||
});
|
||||
}
|
||||
|
||||
getShortUrlsWithoutGroup(): ShortUrl[] {
|
||||
return this.result.nodes.filter((shortUrl) => !shortUrl.group);
|
||||
}
|
||||
|
||||
getShortUrlsWithGroup() {
|
||||
const groupedShortUrls: { [key: string]: ShortUrl[] } = {};
|
||||
|
||||
this.result.nodes.forEach((shortUrl) => {
|
||||
if (!shortUrl.group) return;
|
||||
|
||||
const groupName = shortUrl.group.name;
|
||||
if (!groupedShortUrls[groupName]) {
|
||||
groupedShortUrls[groupName] = [];
|
||||
}
|
||||
groupedShortUrls[groupName].push(shortUrl);
|
||||
});
|
||||
|
||||
return groupedShortUrls;
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed } from "@angular/core/testing";
|
||||
|
||||
import { MenuBarComponent } from 'src/app/modules/shared/components/menu-bar/menu-bar.component';
|
||||
import { MenuBarComponent } from "src/app/modules/shared/components/menu-bar/menu-bar.component";
|
||||
|
||||
describe('MenuBarComponent', () => {
|
||||
describe("MenuBarComponent", () => {
|
||||
let component: MenuBarComponent;
|
||||
let fixture: ComponentFixture<MenuBarComponent>;
|
||||
|
||||
@ -16,7 +16,7 @@ describe('MenuBarComponent', () => {
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
it("should create", () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { MenuElement } from 'src/app/model/view/menu-element';
|
||||
import { Component, Input } from "@angular/core";
|
||||
import { MenuElement } from "src/app/model/view/menu-element";
|
||||
|
||||
@Component({
|
||||
selector: 'app-menu-bar',
|
||||
templateUrl: './menu-bar.component.html',
|
||||
styleUrl: './menu-bar.component.scss',
|
||||
selector: "app-menu-bar",
|
||||
templateUrl: "./menu-bar.component.html",
|
||||
styleUrl: "./menu-bar.component.scss",
|
||||
})
|
||||
export class MenuBarComponent {
|
||||
@Input() elements: MenuElement[] = [];
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed } from "@angular/core/testing";
|
||||
|
||||
import { SideMenuComponent } from './side-menu.component';
|
||||
import { SideMenuComponent } from "./side-menu.component";
|
||||
|
||||
describe('SideMenuComponent', () => {
|
||||
describe("SideMenuComponent", () => {
|
||||
let component: SideMenuComponent;
|
||||
let fixture: ComponentFixture<SideMenuComponent>;
|
||||
|
||||
@ -16,7 +16,7 @@ describe('SideMenuComponent', () => {
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
it("should create", () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { MenuElement } from 'src/app/model/view/menu-element';
|
||||
import { Component, Input } from "@angular/core";
|
||||
import { MenuElement } from "src/app/model/view/menu-element";
|
||||
|
||||
@Component({
|
||||
selector: 'app-side-menu',
|
||||
templateUrl: './side-menu.component.html',
|
||||
styleUrl: './side-menu.component.scss',
|
||||
selector: "app-side-menu",
|
||||
templateUrl: "./side-menu.component.html",
|
||||
styleUrl: "./side-menu.component.scss",
|
||||
})
|
||||
export class SideMenuComponent {
|
||||
@Input() elements: MenuElement[] = [];
|
||||
|
@ -1,7 +1,7 @@
|
||||
<p-sidebar
|
||||
[visible]="true"
|
||||
position="right"
|
||||
[style]="{ width: 'min-content', minWidth: '500px' }"
|
||||
[style]="{ width: 'min-content', minWidth: '350px' }"
|
||||
(onHide)="onClose.emit()"
|
||||
(visibleChange)="!$event ? onClose.emit() : undefined">
|
||||
<ng-template pTemplate="headless">
|
||||
|
@ -1,18 +1,18 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { FormPageComponent } from 'src/app/modules/shared/components/slidein/form-page.component';
|
||||
import { SharedModule } from 'src/app/modules/shared/shared.module';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { AuthService } from 'src/app/service/auth.service';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
import { ErrorHandlingService } from 'src/app/service/error-handling.service';
|
||||
import { ToastService } from 'src/app/service/toast.service';
|
||||
import { ConfirmationService, MessageService } from 'primeng/api';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { of } from 'rxjs';
|
||||
import { FormGroup } from '@angular/forms';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { ComponentFixture, TestBed } from "@angular/core/testing";
|
||||
import { FormPageComponent } from "src/app/modules/shared/components/slidein/form-page.component";
|
||||
import { SharedModule } from "src/app/modules/shared/shared.module";
|
||||
import { TranslateModule } from "@ngx-translate/core";
|
||||
import { AuthService } from "src/app/service/auth.service";
|
||||
import { KeycloakService } from "keycloak-angular";
|
||||
import { ErrorHandlingService } from "src/app/service/error-handling.service";
|
||||
import { ToastService } from "src/app/service/toast.service";
|
||||
import { ConfirmationService, MessageService } from "primeng/api";
|
||||
import { ActivatedRoute } from "@angular/router";
|
||||
import { of } from "rxjs";
|
||||
import { FormGroup } from "@angular/forms";
|
||||
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
|
||||
|
||||
describe('FormpageComponent', () => {
|
||||
describe("FormpageComponent", () => {
|
||||
let component: FormPageComponent<string>;
|
||||
let fixture: ComponentFixture<FormPageComponent<string>>;
|
||||
|
||||
@ -46,7 +46,7 @@ describe('FormpageComponent', () => {
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
it("should create", () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
@ -5,18 +5,18 @@ import {
|
||||
Input,
|
||||
Output,
|
||||
TemplateRef,
|
||||
} from '@angular/core';
|
||||
import { FormGroup } from '@angular/forms';
|
||||
import { SpinnerService } from 'src/app/service/spinner.service';
|
||||
} from "@angular/core";
|
||||
import { FormGroup } from "@angular/forms";
|
||||
import { SpinnerService } from "src/app/service/spinner.service";
|
||||
import {
|
||||
FormPageContentDirective,
|
||||
FormPageHeaderDirective,
|
||||
} from 'src/app/modules/shared/form';
|
||||
} from "src/app/modules/shared/form";
|
||||
|
||||
@Component({
|
||||
selector: 'app-form-page',
|
||||
templateUrl: './form-page.component.html',
|
||||
styleUrl: './form-page.component.scss',
|
||||
selector: "app-form-page",
|
||||
templateUrl: "./form-page.component.html",
|
||||
styleUrl: "./form-page.component.scss",
|
||||
})
|
||||
export class FormPageComponent<T> {
|
||||
@Input({ required: true }) formGroup!: FormGroup;
|
||||
|
@ -73,7 +73,7 @@
|
||||
[class]="column.class ?? ''">
|
||||
<div class="flex items-center space-x-2">
|
||||
<span>{{ column.label | translate }}</span>
|
||||
<p-sortIcon [field]="column.name"></p-sortIcon>
|
||||
<p-sortIcon *ngIf="column.sortable !== false" [field]="column.name"></p-sortIcon>
|
||||
</div>
|
||||
</th>
|
||||
<th *ngIf="update || delete.observed"></th>
|
||||
@ -136,7 +136,12 @@
|
||||
</ng-container>
|
||||
</td>
|
||||
</ng-container>
|
||||
<td class="flex max-w-32">
|
||||
<td class="flex overflow-hidden">
|
||||
<ng-container
|
||||
*ngTemplateOutlet="
|
||||
customActions;
|
||||
context: { $implicit: row }
|
||||
"></ng-container>
|
||||
<p-button
|
||||
*ngIf="update && hasPermissions.update"
|
||||
class="icon-btn btn"
|
||||
|
@ -1,17 +1,17 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed } from "@angular/core/testing";
|
||||
|
||||
import { TableComponent } from './table.component';
|
||||
import { SharedModule } from 'src/app/modules/shared/shared.module';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { AuthService } from 'src/app/service/auth.service';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
import { ErrorHandlingService } from 'src/app/service/error-handling.service';
|
||||
import { ToastService } from 'src/app/service/toast.service';
|
||||
import { ConfirmationService, MessageService } from 'primeng/api';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { of } from 'rxjs';
|
||||
import { TableComponent } from "./table.component";
|
||||
import { SharedModule } from "src/app/modules/shared/shared.module";
|
||||
import { TranslateModule } from "@ngx-translate/core";
|
||||
import { AuthService } from "src/app/service/auth.service";
|
||||
import { KeycloakService } from "keycloak-angular";
|
||||
import { ErrorHandlingService } from "src/app/service/error-handling.service";
|
||||
import { ToastService } from "src/app/service/toast.service";
|
||||
import { ConfirmationService, MessageService } from "primeng/api";
|
||||
import { ActivatedRoute } from "@angular/router";
|
||||
import { of } from "rxjs";
|
||||
|
||||
describe('TableComponent', () => {
|
||||
describe("TableComponent", () => {
|
||||
let component: TableComponent<string>;
|
||||
let fixture: ComponentFixture<TableComponent<string>>;
|
||||
|
||||
@ -40,7 +40,7 @@ describe('TableComponent', () => {
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
it("should create", () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
@ -1,26 +1,44 @@
|
||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
import {
|
||||
Component,
|
||||
ContentChild,
|
||||
Directive,
|
||||
EventEmitter,
|
||||
Input,
|
||||
OnInit,
|
||||
Output,
|
||||
TemplateRef,
|
||||
} from "@angular/core";
|
||||
import {
|
||||
FilterMode,
|
||||
ResolvedTableColumn,
|
||||
TableColumn,
|
||||
TableRequireAnyPermissions,
|
||||
} from 'src/app/modules/shared/components/table/table.model';
|
||||
import { TableLazyLoadEvent } from 'primeng/table';
|
||||
import { RowsPerPageOption } from 'src/app/service/filter.service';
|
||||
import { Filter } from 'src/app/model/graphql/filter/filter.model';
|
||||
import { Sort, SortOrder } from 'src/app/model/graphql/filter/sort.model';
|
||||
import { FormControl, FormGroup } from '@angular/forms';
|
||||
import { debounceTime, Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { Logger } from 'src/app/service/logger.service';
|
||||
import { AuthService } from 'src/app/service/auth.service';
|
||||
import { ToastService } from 'src/app/service/toast.service';
|
||||
} from "src/app/modules/shared/components/table/table.model";
|
||||
import { TableLazyLoadEvent } from "primeng/table";
|
||||
import { RowsPerPageOption } from "src/app/service/filter.service";
|
||||
import { Filter } from "src/app/model/graphql/filter/filter.model";
|
||||
import { Sort, SortOrder } from "src/app/model/graphql/filter/sort.model";
|
||||
import { FormControl, FormGroup } from "@angular/forms";
|
||||
import { debounceTime, Subject } from "rxjs";
|
||||
import { takeUntil } from "rxjs/operators";
|
||||
import { Logger } from "src/app/service/logger.service";
|
||||
import { AuthService } from "src/app/service/auth.service";
|
||||
import { ToastService } from "src/app/service/toast.service";
|
||||
|
||||
const logger = new Logger('TableComponent');
|
||||
const logger = new Logger("TableComponent");
|
||||
|
||||
@Directive({
|
||||
// eslint-disable-next-line @angular-eslint/directive-selector
|
||||
selector: "[customAction]",
|
||||
})
|
||||
export class CustomActionDirective {
|
||||
constructor(public templateRef: TemplateRef<unknown>) {}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-table',
|
||||
templateUrl: './table.component.html',
|
||||
styleUrl: './table.component.scss',
|
||||
selector: "app-table",
|
||||
templateUrl: "./table.component.html",
|
||||
styleUrl: "./table.component.scss",
|
||||
})
|
||||
export class TableComponent<T> implements OnInit {
|
||||
private _rows: T[] = [];
|
||||
@ -57,17 +75,20 @@ export class TableComponent<T> implements OnInit {
|
||||
@Output() load = new EventEmitter<void>();
|
||||
@Input() loading = true;
|
||||
|
||||
@Input() dataKey = 'id';
|
||||
@Input() responsiveLayout: 'stack' | 'scroll' = 'stack';
|
||||
@Input() dataKey = "id";
|
||||
@Input() responsiveLayout: "stack" | "scroll" = "stack";
|
||||
|
||||
@Input() create = false;
|
||||
@Input() update = false;
|
||||
@Input() createBaseUrl = '';
|
||||
@Input() updateBaseUrl = '';
|
||||
@Input() createBaseUrl = "";
|
||||
@Input() updateBaseUrl = "";
|
||||
|
||||
@Output() delete: EventEmitter<T> = new EventEmitter<T>();
|
||||
@Output() restore: EventEmitter<T> = new EventEmitter<T>();
|
||||
|
||||
@ContentChild(CustomActionDirective, { read: TemplateRef })
|
||||
customActions!: TemplateRef<never>;
|
||||
|
||||
protected resolvedColumns: ResolvedTableColumn<T>[][] = [];
|
||||
protected filterForm!: FormGroup;
|
||||
protected defaultFilterForm!: FormGroup;
|
||||
@ -76,12 +97,12 @@ export class TableComponent<T> implements OnInit {
|
||||
|
||||
get showDeleted() {
|
||||
return !this.filter.some(
|
||||
f => JSON.stringify(f) === JSON.stringify(this.hide_deleted_filter)
|
||||
(f) => JSON.stringify(f) === JSON.stringify(this.hide_deleted_filter),
|
||||
);
|
||||
}
|
||||
|
||||
get showFilters() {
|
||||
return this.columns.some(x => x.filterable);
|
||||
return this.columns.some((x) => x.filterable);
|
||||
}
|
||||
|
||||
protected unsubscriber$ = new Subject<void>();
|
||||
@ -96,25 +117,25 @@ export class TableComponent<T> implements OnInit {
|
||||
|
||||
constructor(
|
||||
private auth: AuthService,
|
||||
private toast: ToastService
|
||||
private toast: ToastService,
|
||||
) {}
|
||||
|
||||
async ngOnInit() {
|
||||
this.hasPermissions = {
|
||||
read: await this.auth.hasAnyPermissionLazy(
|
||||
this.requireAnyPermissions.read ?? []
|
||||
this.requireAnyPermissions.read ?? [],
|
||||
),
|
||||
create: await this.auth.hasAnyPermissionLazy(
|
||||
this.requireAnyPermissions.create ?? []
|
||||
this.requireAnyPermissions.create ?? [],
|
||||
),
|
||||
update: await this.auth.hasAnyPermissionLazy(
|
||||
this.requireAnyPermissions.update ?? []
|
||||
this.requireAnyPermissions.update ?? [],
|
||||
),
|
||||
delete: await this.auth.hasAnyPermissionLazy(
|
||||
this.requireAnyPermissions.delete ?? []
|
||||
this.requireAnyPermissions.delete ?? [],
|
||||
),
|
||||
restore: await this.auth.hasAnyPermissionLazy(
|
||||
this.requireAnyPermissions.restore ?? []
|
||||
this.requireAnyPermissions.restore ?? [],
|
||||
),
|
||||
};
|
||||
|
||||
@ -131,9 +152,9 @@ export class TableComponent<T> implements OnInit {
|
||||
}
|
||||
|
||||
const resolvedColumns: ResolvedTableColumn<T>[][] = [];
|
||||
this.rows.forEach(row => {
|
||||
this.rows.forEach((row) => {
|
||||
const resolvedRow: ResolvedTableColumn<T>[] = [];
|
||||
this.columns.forEach(column => {
|
||||
this.columns.forEach((column) => {
|
||||
resolvedRow.push({
|
||||
value: column.value(row),
|
||||
data: row,
|
||||
@ -147,7 +168,7 @@ export class TableComponent<T> implements OnInit {
|
||||
}
|
||||
|
||||
loadData(event: TableLazyLoadEvent) {
|
||||
logger.trace('lazy load event', event);
|
||||
logger.trace("lazy load event", event);
|
||||
|
||||
const { rows, first, sortField, sortOrder } = event;
|
||||
const reload =
|
||||
@ -172,9 +193,9 @@ export class TableComponent<T> implements OnInit {
|
||||
) {
|
||||
if (sortField instanceof Array) {
|
||||
this.sortChange.emit(
|
||||
sortField.map(x => ({
|
||||
sortField.map((x) => ({
|
||||
[x]: sortOrder === 1 ? SortOrder.ASC : SortOrder.DESC,
|
||||
}))
|
||||
})),
|
||||
);
|
||||
} else {
|
||||
this.sortChange.emit([
|
||||
@ -211,17 +232,17 @@ export class TableComponent<T> implements OnInit {
|
||||
buildDefaultFilterForm() {
|
||||
this.defaultFilterForm = new FormGroup({});
|
||||
this.columns
|
||||
.filter(x => x.filterable)
|
||||
.forEach(x => {
|
||||
.filter((x) => x.filterable)
|
||||
.forEach((x) => {
|
||||
let control!: FormControl;
|
||||
|
||||
if (x.type === 'text') {
|
||||
if (x.type === "text") {
|
||||
control = new FormControl<string | undefined>(undefined);
|
||||
} else if (x.type === 'number') {
|
||||
} else if (x.type === "number") {
|
||||
control = new FormControl<number | undefined>(undefined);
|
||||
} else if (x.type === 'bool') {
|
||||
} else if (x.type === "bool") {
|
||||
control = new FormControl<boolean | undefined>(undefined);
|
||||
} else if (x.type === 'date') {
|
||||
} else if (x.type === "date") {
|
||||
control = new FormControl<Date | undefined>(undefined);
|
||||
} else {
|
||||
control = new FormControl<unknown | undefined>(undefined);
|
||||
@ -231,14 +252,14 @@ export class TableComponent<T> implements OnInit {
|
||||
}
|
||||
|
||||
setDefaultFilterForm() {
|
||||
this.defaultFilter.forEach(x => {
|
||||
Object.keys(x).forEach(key => {
|
||||
this.defaultFilter.forEach((x) => {
|
||||
Object.keys(x).forEach((key) => {
|
||||
const value = x[key];
|
||||
if (!(key in this.defaultFilterForm.controls)) {
|
||||
return;
|
||||
}
|
||||
if (typeof value === 'object' && value !== null) {
|
||||
Object.keys(value).forEach(subKey => {
|
||||
if (typeof value === "object" && value !== null) {
|
||||
Object.keys(value).forEach((subKey) => {
|
||||
this.defaultFilterForm.get([key])?.setValue(value[subKey]);
|
||||
});
|
||||
} else {
|
||||
@ -253,38 +274,41 @@ export class TableComponent<T> implements OnInit {
|
||||
|
||||
this.filterForm.valueChanges
|
||||
.pipe(takeUntil(this.unsubscriber$), debounceTime(200))
|
||||
.subscribe(changes => {
|
||||
logger.trace('Filter input', changes);
|
||||
.subscribe((changes) => {
|
||||
logger.trace("Filter input", changes);
|
||||
if (this.filterForm.disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
const filter = Object.keys(changes)
|
||||
.filter(
|
||||
key =>
|
||||
(key) =>
|
||||
changes[key] !== undefined &&
|
||||
changes[key] !== null &&
|
||||
changes[key] !== ''
|
||||
changes[key] !== "",
|
||||
)
|
||||
.map(key => {
|
||||
const column = this.columns.find(x => x.name === key);
|
||||
.map((key) => {
|
||||
const column = this.columns.find((x) => x.name === key);
|
||||
if (!column || !column.filterable) {
|
||||
return {};
|
||||
}
|
||||
|
||||
let value = changes[key];
|
||||
let defaultFilterMode = 'contains';
|
||||
let defaultFilterMode: FilterMode = "contains";
|
||||
switch (column.type) {
|
||||
case 'number':
|
||||
defaultFilterMode = 'equal';
|
||||
case "number":
|
||||
defaultFilterMode = "equal";
|
||||
value = +value;
|
||||
break;
|
||||
case 'bool':
|
||||
defaultFilterMode = 'equal';
|
||||
case "bool":
|
||||
defaultFilterMode = "equal";
|
||||
}
|
||||
|
||||
const filterMode = column.filterMode || defaultFilterMode;
|
||||
|
||||
if (column.filterFactory) {
|
||||
return column.filterFactory(key, filterMode, value);
|
||||
}
|
||||
return { [key]: { [filterMode]: value } };
|
||||
});
|
||||
|
||||
@ -300,7 +324,7 @@ export class TableComponent<T> implements OnInit {
|
||||
|
||||
copy(val: T | T[keyof T] | string) {
|
||||
navigator.clipboard.writeText(val as string).then(() => {
|
||||
this.toast.info('common.copied', 'common.copied_to_clipboard');
|
||||
this.toast.info("common.copied", "common.copied_to_clipboard");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
import { PermissionsEnum } from 'src/app/model/auth/permissionsEnum';
|
||||
import { PermissionsEnum } from "src/app/model/auth/permissionsEnum";
|
||||
import { Filter } from "src/app/model/graphql/filter/filter.model";
|
||||
|
||||
export type TableColumnValue<T> = T | T[keyof T] | string;
|
||||
export type FilterMode = "contains" | "startsWith" | "endsWith" | "equal";
|
||||
|
||||
export interface TableColumn<T> {
|
||||
name: string;
|
||||
@ -12,7 +14,8 @@ export interface TableColumn<T> {
|
||||
hidden?: boolean;
|
||||
sortable?: boolean;
|
||||
filterable?: boolean;
|
||||
filterMode?: 'contains' | 'startsWith' | 'endsWith' | 'equals';
|
||||
filterMode?: FilterMode;
|
||||
filterFactory?: (key: string, mode: FilterMode, value: T) => Filter;
|
||||
sort?: (a: T, b: T) => number;
|
||||
filter?: (row: T, filter: string) => boolean;
|
||||
width?: string;
|
||||
|
@ -1,17 +1,17 @@
|
||||
import { addMinutes, format, parseISO } from 'date-fns';
|
||||
import { addMinutes, format, parseISO } from "date-fns";
|
||||
|
||||
export function formatUTCDateToClientTimezone(date: string) {
|
||||
const dateTZ = addMinutes(
|
||||
parseISO(date),
|
||||
new Date().getTimezoneOffset() * -1
|
||||
new Date().getTimezoneOffset() * -1,
|
||||
);
|
||||
return format(dateTZ, 'yyyy-MM-dd HH:mm:ss');
|
||||
return format(dateTZ, "yyyy-MM-dd HH:mm:ss");
|
||||
}
|
||||
|
||||
export function formatUTCDateToGermanLocaleAndTimezone(date: string) {
|
||||
const dateTZ = addMinutes(
|
||||
parseISO(date),
|
||||
new Date().getTimezoneOffset() * -1
|
||||
new Date().getTimezoneOffset() * -1,
|
||||
);
|
||||
return format(dateTZ, 'dd.MM.yy HH:mm:ss');
|
||||
return format(dateTZ, "dd.MM.yy HH:mm:ss");
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { Directive, TemplateRef } from '@angular/core';
|
||||
import { Directive, TemplateRef } from "@angular/core";
|
||||
|
||||
@Directive({
|
||||
// eslint-disable-next-line @angular-eslint/directive-selector
|
||||
selector: '[formPageHeader]',
|
||||
selector: "[formPageHeader]",
|
||||
})
|
||||
export class FormPageHeaderDirective {
|
||||
constructor(public templateRef: TemplateRef<unknown>) {}
|
||||
@ -10,7 +10,7 @@ export class FormPageHeaderDirective {
|
||||
|
||||
@Directive({
|
||||
// eslint-disable-next-line @angular-eslint/directive-selector
|
||||
selector: '[formPageContent]',
|
||||
selector: "[formPageContent]",
|
||||
})
|
||||
export class FormPageContentDirective {
|
||||
constructor(public templateRef: TemplateRef<unknown>) {}
|
||||
|
@ -1,15 +1,15 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { Pipe, PipeTransform } from "@angular/core";
|
||||
import { TranslateService } from "@ngx-translate/core";
|
||||
|
||||
@Pipe({
|
||||
name: 'bool',
|
||||
name: "bool",
|
||||
})
|
||||
export class BoolPipe implements PipeTransform {
|
||||
constructor(private translate: TranslateService) {}
|
||||
|
||||
transform(value: unknown): string {
|
||||
return this.translate.instant(
|
||||
value === true || value === 'true' ? 'bool.true' : 'bool.false'
|
||||
value === true || value === "true" ? "bool.true" : "bool.false",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,23 +1,23 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
import { format } from 'date-fns';
|
||||
import { Pipe, PipeTransform } from "@angular/core";
|
||||
import { format } from "date-fns";
|
||||
|
||||
@Pipe({
|
||||
name: 'customDate',
|
||||
name: "customDate",
|
||||
})
|
||||
export class CustomDatePipe implements PipeTransform {
|
||||
transform(value: unknown, dateFormat: string = 'yyyy-MM-dd'): string {
|
||||
transform(value: unknown, dateFormat: string = "yyyy-MM-dd"): string {
|
||||
if (!value) {
|
||||
return '';
|
||||
return "";
|
||||
}
|
||||
try {
|
||||
const date =
|
||||
typeof value === 'string' || typeof value === 'number'
|
||||
typeof value === "string" || typeof value === "number"
|
||||
? new Date(value)
|
||||
: value;
|
||||
return format(date as Date, dateFormat);
|
||||
} catch (error) {
|
||||
console.error('Error formatting date:', error);
|
||||
return '';
|
||||
console.error("Error formatting date:", error);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,14 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
import { Pipe, PipeTransform } from "@angular/core";
|
||||
|
||||
@Pipe({
|
||||
name: 'protect',
|
||||
name: "protect",
|
||||
})
|
||||
export class ProtectPipe implements PipeTransform {
|
||||
transform(text?: unknown): string {
|
||||
const len = 8;
|
||||
if (text && typeof text === 'string' && text.length) {
|
||||
return '*'.repeat(text.length);
|
||||
if (text && typeof text === "string" && text.length) {
|
||||
return "*".repeat(text.length);
|
||||
}
|
||||
return '*'.repeat(len);
|
||||
return "*".repeat(len);
|
||||
}
|
||||
}
|
||||
|
@ -1,63 +1,66 @@
|
||||
import { inject, NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { StepsModule } from 'primeng/steps';
|
||||
import { DialogModule } from 'primeng/dialog';
|
||||
import { ToastModule } from 'primeng/toast';
|
||||
import { ProgressSpinnerModule } from 'primeng/progressspinner';
|
||||
import { ButtonModule } from 'primeng/button';
|
||||
import { ButtonGroupModule } from 'primeng/buttongroup';
|
||||
import { ConfirmDialogModule } from 'primeng/confirmdialog';
|
||||
import { TableModule } from 'primeng/table';
|
||||
import { InputTextModule } from 'primeng/inputtext';
|
||||
import { CheckboxModule } from 'primeng/checkbox';
|
||||
import { DropdownModule } from 'primeng/dropdown';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { ImageModule } from 'primeng/image';
|
||||
import { TabMenuModule } from 'primeng/tabmenu';
|
||||
import { MenubarModule } from 'primeng/menubar';
|
||||
import { PanelMenuModule } from 'primeng/panelmenu';
|
||||
import { CardModule } from 'primeng/card';
|
||||
import { MultiSelectModule } from 'primeng/multiselect';
|
||||
import { SplitButtonModule } from 'primeng/splitbutton';
|
||||
import { CalendarModule } from 'primeng/calendar';
|
||||
import { PaginatorModule } from 'primeng/paginator';
|
||||
import { DataViewModule } from 'primeng/dataview';
|
||||
import { TagModule } from 'primeng/tag';
|
||||
import { SidebarModule } from 'primeng/sidebar';
|
||||
import { FileUploadModule } from 'primeng/fileupload';
|
||||
import { MenuModule } from 'primeng/menu';
|
||||
import { ChipModule } from 'primeng/chip';
|
||||
import { BadgeModule } from 'primeng/badge';
|
||||
import { ContextMenuModule } from 'primeng/contextmenu';
|
||||
import { DragDropModule } from 'primeng/dragdrop';
|
||||
import { InputSwitchModule } from 'primeng/inputswitch';
|
||||
import { SelectButtonModule } from 'primeng/selectbutton';
|
||||
import { BreadcrumbModule } from 'primeng/breadcrumb';
|
||||
import { OverlayPanelModule } from 'primeng/overlaypanel';
|
||||
import { TerminalModule } from 'primeng/terminal';
|
||||
import { RatingModule } from 'primeng/rating';
|
||||
import { FocusTrapModule } from 'primeng/focustrap';
|
||||
import { InputMaskModule } from 'primeng/inputmask';
|
||||
import { TriStateCheckboxModule } from 'primeng/tristatecheckbox';
|
||||
import { InputTextareaModule } from 'primeng/inputtextarea';
|
||||
import { MenuBarComponent } from 'src/app/modules/shared/components/menu-bar/menu-bar.component';
|
||||
import { SideMenuComponent } from './components/side-menu/side-menu.component';
|
||||
import { TableComponent } from './components/table/table.component';
|
||||
import { BoolPipe } from 'src/app/modules/shared/pipes/bool.pipe';
|
||||
import { CustomDatePipe } from 'src/app/modules/shared/pipes/customDate.pipe';
|
||||
import { FormPageComponent } from 'src/app/modules/shared/components/slidein/form-page.component';
|
||||
import { inject, NgModule } from "@angular/core";
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { FormsModule, ReactiveFormsModule } from "@angular/forms";
|
||||
import { StepsModule } from "primeng/steps";
|
||||
import { DialogModule } from "primeng/dialog";
|
||||
import { ToastModule } from "primeng/toast";
|
||||
import { ProgressSpinnerModule } from "primeng/progressspinner";
|
||||
import { ButtonModule } from "primeng/button";
|
||||
import { ButtonGroupModule } from "primeng/buttongroup";
|
||||
import { ConfirmDialogModule } from "primeng/confirmdialog";
|
||||
import { TableModule } from "primeng/table";
|
||||
import { InputTextModule } from "primeng/inputtext";
|
||||
import { CheckboxModule } from "primeng/checkbox";
|
||||
import { DropdownModule } from "primeng/dropdown";
|
||||
import { TranslateModule } from "@ngx-translate/core";
|
||||
import { ImageModule } from "primeng/image";
|
||||
import { TabMenuModule } from "primeng/tabmenu";
|
||||
import { MenubarModule } from "primeng/menubar";
|
||||
import { PanelMenuModule } from "primeng/panelmenu";
|
||||
import { CardModule } from "primeng/card";
|
||||
import { MultiSelectModule } from "primeng/multiselect";
|
||||
import { SplitButtonModule } from "primeng/splitbutton";
|
||||
import { CalendarModule } from "primeng/calendar";
|
||||
import { PaginatorModule } from "primeng/paginator";
|
||||
import { DataViewModule } from "primeng/dataview";
|
||||
import { TagModule } from "primeng/tag";
|
||||
import { SidebarModule } from "primeng/sidebar";
|
||||
import { FileUploadModule } from "primeng/fileupload";
|
||||
import { MenuModule } from "primeng/menu";
|
||||
import { ChipModule } from "primeng/chip";
|
||||
import { BadgeModule } from "primeng/badge";
|
||||
import { ContextMenuModule } from "primeng/contextmenu";
|
||||
import { DragDropModule } from "primeng/dragdrop";
|
||||
import { InputSwitchModule } from "primeng/inputswitch";
|
||||
import { SelectButtonModule } from "primeng/selectbutton";
|
||||
import { BreadcrumbModule } from "primeng/breadcrumb";
|
||||
import { OverlayPanelModule } from "primeng/overlaypanel";
|
||||
import { TerminalModule } from "primeng/terminal";
|
||||
import { RatingModule } from "primeng/rating";
|
||||
import { FocusTrapModule } from "primeng/focustrap";
|
||||
import { InputMaskModule } from "primeng/inputmask";
|
||||
import { TriStateCheckboxModule } from "primeng/tristatecheckbox";
|
||||
import { InputTextareaModule } from "primeng/inputtextarea";
|
||||
import { MenuBarComponent } from "src/app/modules/shared/components/menu-bar/menu-bar.component";
|
||||
import { SideMenuComponent } from "./components/side-menu/side-menu.component";
|
||||
import {
|
||||
CustomActionDirective,
|
||||
TableComponent,
|
||||
} from "./components/table/table.component";
|
||||
import { BoolPipe } from "src/app/modules/shared/pipes/bool.pipe";
|
||||
import { CustomDatePipe } from "src/app/modules/shared/pipes/customDate.pipe";
|
||||
import { FormPageComponent } from "src/app/modules/shared/components/slidein/form-page.component";
|
||||
import {
|
||||
FormPageContentDirective,
|
||||
FormPageHeaderDirective,
|
||||
} from 'src/app/modules/shared/form';
|
||||
import { ProtectPipe } from './pipes/protect.pipe';
|
||||
import { provideApollo } from 'apollo-angular';
|
||||
import { HttpLink } from 'apollo-angular/http';
|
||||
import { environment } from 'src/environments/environment';
|
||||
import { InMemoryCache } from '@apollo/client/core';
|
||||
import { provideHttpClient, withInterceptors } from '@angular/common/http';
|
||||
import { tokenInterceptor } from 'src/app/core/token.interceptor';
|
||||
} from "src/app/modules/shared/form";
|
||||
import { ProtectPipe } from "./pipes/protect.pipe";
|
||||
import { provideApollo } from "apollo-angular";
|
||||
import { HttpLink } from "apollo-angular/http";
|
||||
import { environment } from "src/environments/environment";
|
||||
import { InMemoryCache } from "@apollo/client/core";
|
||||
import { provideHttpClient, withInterceptors } from "@angular/common/http";
|
||||
import { tokenInterceptor } from "src/app/core/token.interceptor";
|
||||
|
||||
const sharedModules = [
|
||||
StepsModule,
|
||||
@ -114,6 +117,7 @@ const sharedComponents = [
|
||||
FormPageComponent,
|
||||
FormPageHeaderDirective,
|
||||
FormPageContentDirective,
|
||||
CustomActionDirective,
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
@ -131,13 +135,13 @@ const sharedComponents = [
|
||||
|
||||
defaultOptions: {
|
||||
watchQuery: {
|
||||
fetchPolicy: 'no-cache',
|
||||
fetchPolicy: "no-cache",
|
||||
},
|
||||
query: {
|
||||
fetchPolicy: 'no-cache',
|
||||
fetchPolicy: "no-cache",
|
||||
},
|
||||
mutate: {
|
||||
fetchPolicy: 'no-cache',
|
||||
fetchPolicy: "no-cache",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user