Added base logic to hide columns & added hide columns to levels #79

This commit is contained in:
Sven Heidemann 2023-08-14 23:33:02 +02:00
parent 1fc5ef76a6
commit 4add293186
15 changed files with 347 additions and 66 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "kdb-web", "name": "kdb-web",
"version": "1.1.0", "version": "1.1.dev79_hide_table_attributes",
"scripts": { "scripts": {
"ng": "ng", "ng": "ng",
"update-version": "ts-node-esm update-version.ts", "update-version": "ts-node-esm update-version.ts",

View File

@ -0,0 +1,7 @@
import { ComponentWithTable } from './component-with-table';
describe('ComponentWithTable', () => {
it('should create an instance', () => {
expect(new ComponentWithTable()).toBeTruthy();
});
});

View File

@ -0,0 +1,39 @@
interface Column {
key: string;
name: string;
}
export class ComponentWithTable {
private _hiddenColumns: Column[] = [];
set hiddenColumns(value: Column[]) {
this._hiddenColumns = value;
localStorage.setItem("hiddenColumns", JSON.stringify(value));
}
get hiddenColumns(): Column[] {
return this._hiddenColumns;
}
private name: string = "";
public columns: Column[] = [];
constructor(
name: string,
columns: string[]
) {
this.name = name;
this.columns = columns.map(column => {
return { key: this.getKey(column), name: column };
});
this._hiddenColumns = JSON.parse(localStorage.getItem("hiddenColumns") ?? "");
}
private getKey(column: string): string {
return `${this.name}_${column}`;
}
public isColumnVisible(column: string): boolean {
return !this._hiddenColumns.map(column => column.key).includes(this.getKey(column));
}
}

View File

@ -23,9 +23,10 @@ import { PanelModule } from "primeng/panel";
import { InputNumberModule } from "primeng/inputnumber"; import { InputNumberModule } from "primeng/inputnumber";
import { ImageModule } from "primeng/image"; import { ImageModule } from "primeng/image";
import { SidebarModule } from "primeng/sidebar"; import { SidebarModule } from "primeng/sidebar";
import { HistoryBtnComponent } from './components/history-btn/history-btn.component'; import { HistoryBtnComponent } from "./components/history-btn/history-btn.component";
import { DataViewModule, DataViewLayoutOptions } from 'primeng/dataview'; import { DataViewModule, DataViewLayoutOptions } from "primeng/dataview";
import { ConfigListComponent } from './components/config-list/config-list.component'; import { ConfigListComponent } from "./components/config-list/config-list.component";
import { MultiSelectModule } from "primeng/multiselect";
@NgModule({ @NgModule({
@ -34,7 +35,7 @@ import { ConfigListComponent } from './components/config-list/config-list.compon
IpAddressPipe, IpAddressPipe,
BoolPipe, BoolPipe,
HistoryBtnComponent, HistoryBtnComponent,
ConfigListComponent, ConfigListComponent
], ],
imports: [ imports: [
CommonModule, CommonModule,
@ -60,36 +61,39 @@ import { ConfigListComponent } from './components/config-list/config-list.compon
ImageModule, ImageModule,
SidebarModule, SidebarModule,
DataViewModule, DataViewModule,
MultiSelectModule
], ],
exports: [ exports: [
ButtonModule, ButtonModule,
PasswordModule, PasswordModule,
MenuModule, MenuModule,
DialogModule, DialogModule,
ProgressSpinnerModule, ProgressSpinnerModule,
HttpClientModule, HttpClientModule,
FormsModule, FormsModule,
ReactiveFormsModule, ReactiveFormsModule,
ToastModule, ToastModule,
ConfirmDialogModule, ConfirmDialogModule,
TableModule, TableModule,
InputTextModule, InputTextModule,
CheckboxModule, CheckboxModule,
DropdownModule, DropdownModule,
TranslateModule, TranslateModule,
DynamicDialogModule, DynamicDialogModule,
PanelMenuModule, PanelMenuModule,
PanelModule, PanelModule,
AuthRolePipe, AuthRolePipe,
IpAddressPipe, IpAddressPipe,
BoolPipe, BoolPipe,
InputNumberModule, InputNumberModule,
ImageModule, ImageModule,
SidebarModule, SidebarModule,
HistoryBtnComponent, HistoryBtnComponent,
DataViewModule, DataViewModule,
DataViewLayoutOptions, DataViewLayoutOptions,
ConfigListComponent ConfigListComponent,
] MultiSelectModule
]
}) })
export class SharedModule { } export class SharedModule {
}

View File

@ -110,7 +110,7 @@ export class ConfigComponent implements OnInit {
return throwError(err); return throwError(err);
})).subscribe(result => { })).subscribe(result => {
this.spinner.hideSpinner(); this.spinner.hideSpinner();
this.toastService.success(this.translate.instant("view.server.config.message.server_config_create"), this.translate.instant("view.server.config.message.server_config_create_d")); this.toastService.success(this.translate.instant("view.server.config.message.server#_config_create"), this.translate.instant("view.server.config.message.server_config_create_d"));
}); });
} }
} }

View File

@ -9,11 +9,21 @@
<ng-template pTemplate="caption"> <ng-template pTemplate="caption">
<div class="table-caption"> <div class="table-caption">
<div class="table-caption-text"> <div class="table-caption-table-info">
<ng-container *ngIf="!loading">{{levels.length}} {{'common.of' | translate}} <div class="table-caption-text">
{{dt.totalRecords}} <ng-container *ngIf="!loading">{{levels.length}} {{'common.of' | translate}}
</ng-container> {{dt.totalRecords}}
{{'view.server.levels.levels' | translate}} </ng-container>
{{'view.server.levels.levels' | translate}}
</div>
<div class="table-caption-column-select">
<p-multiSelect [options]="columns" [(ngModel)]="hiddenColumns" optionLabel="name" placeholder="{{'common.hidden_columns' | translate}}" [filter]=false>
<ng-template let-item pTemplate="item">
<div>{{'view.server.levels.headers.' + item.name | translate}}</div>
</ng-template>
</p-multiSelect>
</div>
</div> </div>
<div class="table-caption-btn-wrapper btn-wrapper"> <div class="table-caption-btn-wrapper btn-wrapper">
@ -36,28 +46,28 @@
</div> </div>
</th> </th>
<th pSortableColumn="name"> <th *ngIf="isColumnVisible('name')" pSortableColumn="name">
<div class="table-header-label"> <div class="table-header-label">
<div class="table-header-text">{{'view.server.levels.headers.name' | translate}}</div> <div class="table-header-text">{{'view.server.levels.headers.name' | translate}}</div>
<p-sortIcon field="name" class="table-header-icon"></p-sortIcon> <p-sortIcon field="name" class="table-header-icon"></p-sortIcon>
</div> </div>
</th> </th>
<th pSortableColumn="color"> <th *ngIf="isColumnVisible('color')" pSortableColumn="color">
<div class="table-header-label"> <div class="table-header-label">
<div class="table-header-text">{{'view.server.levels.headers.color' | translate}}</div> <div class="table-header-text">{{'view.server.levels.headers.color' | translate}}</div>
<p-sortIcon field="color" class="table-header-icon"></p-sortIcon> <p-sortIcon field="color" class="table-header-icon"></p-sortIcon>
</div> </div>
</th> </th>
<th pSortableColumn="minXp"> <th *ngIf="isColumnVisible('min_xp')" pSortableColumn="minXp">
<div class="table-header-label"> <div class="table-header-label">
<div class="table-header-text">{{'view.server.levels.headers.min_xp' | translate}}</div> <div class="table-header-text">{{'view.server.levels.headers.min_xp' | translate}}</div>
<p-sortIcon field="minXp" class="table-header-icon"></p-sortIcon> <p-sortIcon field="minXp" class="table-header-icon"></p-sortIcon>
</div> </div>
</th> </th>
<th pSortableColumn="permissions"> <th *ngIf="isColumnVisible('permissions')" pSortableColumn="permissions">
<div class="table-header-label"> <div class="table-header-label">
<div class="table-header-text">{{'view.server.levels.headers.permissions' | translate}}</div> <div class="table-header-text">{{'view.server.levels.headers.permissions' | translate}}</div>
<p-sortIcon field="permissions" class="table-header-icon"></p-sortIcon> <p-sortIcon field="permissions" class="table-header-icon"></p-sortIcon>
@ -90,15 +100,15 @@
placeholder="{{'common.id' | translate}}"> placeholder="{{'common.id' | translate}}">
</form> </form>
</th> </th>
<th> <th *ngIf="isColumnVisible('name')">
<form [formGroup]="filterForm"> <form [formGroup]="filterForm">
<input type="text" pInputText formControlName="name" <input type="text" pInputText formControlName="name"
placeholder="{{'view.server.levels.headers.name' | translate}}"> placeholder="{{'view.server.levels.headers.name' | translate}}">
</form> </form>
</th> </th>
<th></th> <th *ngIf="isColumnVisible('color')"></th>
<th></th> <th *ngIf="isColumnVisible('min_xp')"></th>
<th></th> <th *ngIf="isColumnVisible('permissions')"></th>
<th class="table-header-small-dropdown"></th> <th class="table-header-small-dropdown"></th>
<th class="table-header-small-dropdown"></th> <th class="table-header-small-dropdown"></th>
<th class="table-header-actions"></th> <th class="table-header-actions"></th>
@ -118,7 +128,7 @@
</p-cellEditor> </p-cellEditor>
</td> </td>
<td> <td *ngIf="isColumnVisible('name')">
<p-cellEditor> <p-cellEditor>
<ng-template pTemplate="input"> <ng-template pTemplate="input">
<input class="table-edit-input" pInputText type="text" [(ngModel)]="level.name"> <input class="table-edit-input" pInputText type="text" [(ngModel)]="level.name">
@ -129,7 +139,7 @@
</p-cellEditor> </p-cellEditor>
</td> </td>
<td> <td *ngIf="isColumnVisible('color')">
<p-cellEditor> <p-cellEditor>
<ng-template pTemplate="input"> <ng-template pTemplate="input">
<input class="table-edit-input" pInputText type="text" [(ngModel)]="level.color"> <input class="table-edit-input" pInputText type="text" [(ngModel)]="level.color">
@ -140,7 +150,7 @@
</p-cellEditor> </p-cellEditor>
</td> </td>
<td> <td *ngIf="isColumnVisible('min_xp')">
<p-cellEditor> <p-cellEditor>
<ng-template pTemplate="input"> <ng-template pTemplate="input">
<input class="table-edit-input" pInputText min="0" type="number" [(ngModel)]="level.minXp"> <input class="table-edit-input" pInputText min="0" type="number" [(ngModel)]="level.minXp">
@ -151,7 +161,7 @@
</p-cellEditor> </p-cellEditor>
</td> </td>
<td> <td *ngIf="isColumnVisible('permissions')">
<p-cellEditor> <p-cellEditor>
<ng-template pTemplate="input"> <ng-template pTemplate="input">
<input class="table-edit-input" pInputText min="0" type="text" [(ngModel)]="level.permissions"> <input class="table-edit-input" pInputText min="0" type="text" [(ngModel)]="level.permissions">

View File

@ -22,14 +22,14 @@ import { Mutations } from "../../../../../../models/graphql/mutations.model";
import { Subject, throwError } from "rxjs"; import { Subject, throwError } from "rxjs";
import { Server } from "../../../../../../models/data/server.model"; import { Server } from "../../../../../../models/data/server.model";
import { UserDTO } from "../../../../../../models/auth/auth-user.dto"; import { UserDTO } from "../../../../../../models/auth/auth-user.dto";
import { ComponentWithTable } from "../../../../../../base/component-with-table";
@Component({ @Component({
selector: "app-levels", selector: "app-levels",
templateUrl: "./levels.component.html", templateUrl: "./levels.component.html",
styleUrls: ["./levels.component.scss"] styleUrls: ["./levels.component.scss"]
}) })
export class LevelsComponent implements OnInit, OnDestroy { export class LevelsComponent extends ComponentWithTable implements OnInit, OnDestroy {
public levels: Level[] = []; public levels: Level[] = [];
public loading = true; public loading = true;
@ -72,7 +72,9 @@ export class LevelsComponent implements OnInit, OnDestroy {
private translate: TranslateService, private translate: TranslateService,
private data: DataService, private data: DataService,
private sidebar: SidebarService, private sidebar: SidebarService,
private route: ActivatedRoute) { private route: ActivatedRoute
) {
super("level", ["name", "color", "min_xp", "permissions"]);
} }
public ngOnInit(): void { public ngOnInit(): void {
@ -96,8 +98,8 @@ export class LevelsComponent implements OnInit, OnDestroy {
serverId: this.server.id, filter: this.filter, page: this.page, sort: this.sort serverId: this.server.id, filter: this.filter, page: this.page, sort: this.sort
}, },
(data: Query) => { (data: Query) => {
return data.servers[0]; return data.servers[0];
} }
).subscribe(data => { ).subscribe(data => {
this.totalRecords = data.levelCount; this.totalRecords = data.levelCount;
this.levels = data.levels; this.levels = data.levels;

View File

@ -142,6 +142,7 @@
"discord_id": "Discord Id", "discord_id": "Discord Id",
"email": "E-Mail", "email": "E-Mail",
"error": "Fehler", "error": "Fehler",
"hidden_columns": "Ausgeblendete Spalten",
"history": { "history": {
"attribute": "Attribut", "attribute": "Attribut",
"autoRole": "Auto Rolle", "autoRole": "Auto Rolle",

View File

@ -142,6 +142,7 @@
"discord_id": "Discord Id", "discord_id": "Discord Id",
"email": "E-Mail", "email": "E-Mail",
"error": "Error", "error": "Error",
"hidden_columns": "Hidden columns",
"history": { "history": {
"attribute": "Attribute", "attribute": "Attribute",
"autoRole": "Auto role", "autoRole": "Auto role",

View File

@ -2,6 +2,6 @@
"WebVersion": { "WebVersion": {
"Major": "1", "Major": "1",
"Minor": "1", "Minor": "1",
"Micro": "0" "Micro": "dev79_hide_table_attributes"
} }
} }

View File

@ -241,9 +241,22 @@ header {
.table-caption { .table-caption {
display: flex; display: flex;
.table-caption-text { .table-caption-table-info {
display: flex;
flex: 1; flex: 1;
font-weight: 400; flex-direction: row;
gap: 25px;
.table-caption-text {
display: flex;
align-items: center;
font-weight: 400;
}
.table-caption-column-select {
flex: 1;
}
} }
.table-caption-search { .table-caption-search {

View File

@ -386,7 +386,12 @@
color: $primaryTextColor !important; color: $primaryTextColor !important;
.table-caption { .table-caption {
.table-caption-text { .table-caption-table-info {
.table-caption-text {
}
.table-caption-column-select {
}
} }
.table-caption-search-wrapper { .table-caption-search-wrapper {
@ -611,4 +616,50 @@
} }
} }
} }
.p-multiselect {
background-color: $primaryBackgroundColor !important;
color: $primaryTextColor !important;
&:focus,
&.p-focus,
&:not(.p-disabled):hover {
border-color: $primaryHeaderColor !important;
box-shadow: none !important;
}
.p-multiselect-panel {
.p-multiselect-header {
background-color: $primaryBackgroundColor !important;
}
.p-multiselect-items,
.p-multiselect-item {
background-color: $secondaryBackgroundColor !important;
}
.p-multiselect-item {
color: $primaryTextColor !important;
border: 1px solid transparent !important;
&:hover {
border: 1px solid $primaryHeaderColor !important;
color: $primaryHeaderColor !important;
}
&:focus {
box-shadow: none !important;
}
}
.p-checkbox .p-checkbox-box.p-highlight {
border-color: $primaryHeaderColor !important;
background: $primaryHeaderColor !important;
}
.p-checkbox:not(.p-checkbox-disabled) .p-checkbox-box:hover {
border-color: $primaryHeaderColor !important;
}
}
}
} }

View File

@ -386,7 +386,12 @@
color: $primaryTextColor !important; color: $primaryTextColor !important;
.table-caption { .table-caption {
.table-caption-text { .table-caption-table-info {
.table-caption-text {
}
.table-caption-column-select {
}
} }
.table-caption-search-wrapper { .table-caption-search-wrapper {
@ -611,4 +616,50 @@
} }
} }
} }
.p-multiselect {
background-color: $primaryBackgroundColor !important;
color: $primaryTextColor !important;
&:focus,
&.p-focus,
&:not(.p-disabled):hover {
border-color: $primaryHeaderColor !important;
box-shadow: none !important;
}
.p-multiselect-panel {
.p-multiselect-header {
background-color: $secondaryBackgroundColor !important;
}
.p-multiselect-items,
.p-multiselect-item {
background-color: $primaryBackgroundColor !important;
}
.p-multiselect-item {
color: $primaryTextColor !important;
border: 1px solid transparent !important;
&:hover {
border: 1px solid $primaryHeaderColor !important;
color: $primaryHeaderColor !important;
}
&:focus {
box-shadow: none !important;
}
}
.p-checkbox .p-checkbox-box.p-highlight {
border-color: $primaryHeaderColor !important;
background: $primaryHeaderColor !important;
}
.p-checkbox:not(.p-checkbox-disabled) .p-checkbox-box:hover {
border-color: $primaryHeaderColor !important;
}
}
}
} }

View File

@ -390,7 +390,12 @@
color: $primaryTextColor !important; color: $primaryTextColor !important;
.table-caption { .table-caption {
.table-caption-text { .table-caption-table-info {
.table-caption-text {
}
.table-caption-column-select {
}
} }
.table-caption-search-wrapper { .table-caption-search-wrapper {
@ -619,4 +624,50 @@
} }
} }
} }
.p-multiselect {
background-color: $primaryBackgroundColor !important;
color: $primaryTextColor !important;
&:focus,
&.p-focus,
&:not(.p-disabled):hover {
border-color: $primaryHeaderColor !important;
box-shadow: none !important;
}
.p-multiselect-panel {
.p-multiselect-header {
background-color: $primaryBackgroundColor !important;
}
.p-multiselect-items,
.p-multiselect-item {
background-color: $secondaryBackgroundColor !important;
}
.p-multiselect-item {
color: $primaryTextColor !important;
border: 1px solid transparent !important;
&:hover {
border: 1px solid $primaryHeaderColor !important;
color: $primaryHeaderColor !important;
}
&:focus {
box-shadow: none !important;
}
}
.p-checkbox .p-checkbox-box.p-highlight {
border-color: $primaryHeaderColor !important;
background: $primaryHeaderColor !important;
}
.p-checkbox:not(.p-checkbox-disabled) .p-checkbox-box:hover {
border-color: $primaryHeaderColor !important;
}
}
}
} }

View File

@ -386,7 +386,12 @@
color: $primaryTextColor !important; color: $primaryTextColor !important;
.table-caption { .table-caption {
.table-caption-text { .table-caption-table-info {
.table-caption-text {
}
.table-caption-column-select {
}
} }
.table-caption-search-wrapper { .table-caption-search-wrapper {
@ -611,4 +616,50 @@
} }
} }
} }
.p-multiselect {
background-color: $primaryBackgroundColor !important;
color: $primaryTextColor !important;
&:focus,
&.p-focus,
&:not(.p-disabled):hover {
border-color: $primaryHeaderColor !important;
box-shadow: none !important;
}
.p-multiselect-panel {
.p-multiselect-header {
background-color: $secondaryBackgroundColor !important;
}
.p-multiselect-items,
.p-multiselect-item {
background-color: $primaryBackgroundColor !important;
}
.p-multiselect-item {
color: $primaryTextColor !important;
border: 1px solid transparent !important;
&:hover {
border: 1px solid $primaryHeaderColor !important;
color: $primaryHeaderColor !important;
}
&:focus {
box-shadow: none !important;
}
}
.p-checkbox .p-checkbox-box.p-highlight {
border-color: $primaryHeaderColor !important;
background: $primaryHeaderColor !important;
}
.p-checkbox:not(.p-checkbox-disabled) .p-checkbox-box:hover {
border-color: $primaryHeaderColor !important;
}
}
}
} }