Skip to content

Commit

Permalink
Refactor config-table into its own component
Browse files Browse the repository at this point in the history
  • Loading branch information
PhilippMDoerner committed Dec 14, 2024
1 parent 887e585 commit abb40fc
Show file tree
Hide file tree
Showing 11 changed files with 252 additions and 187 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<app-config-tables
[tableData]="tableData()"
[currentCampaignId]="undefined"
(loadTableEntries)="loadTableEntries($event)"
(deleteTableEntry)="deleteTableEntry($event)"
(createTableEntry)="createTableEntry($event)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { PlayerClass } from 'src/app/_models/playerclass';
import {
ConfigTableData,
ConfigTableKind,
} from 'src/design/templates/_models/config-table';
} from 'src/design/organisms/_model/config-table';
import { ConfigTablesComponent } from '../../../../design/templates/config-tables/config-tables.component';
import { ConfigAdministrationPageStore } from './config-administration-page.store';

Expand Down
24 changes: 24 additions & 0 deletions src/design/organisms/_model/config-table.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { FormlyFieldConfig } from '@ngx-formly/core';
import { Icon } from 'src/design/atoms/_models/icon';

export interface ConfigTable<T extends object> {
name: string;
kind: ConfigTableKind;
entries?: T[];
icon: Icon;
model: Partial<T>;
formFields: FormlyFieldConfig[];
showForm: boolean;
idProp: keyof T;
}

export const CONFIG_TABLE_KINDS = [
'MARKER_TYPE',
'PLAYER_CLASS',
'NODE_LINK_TYPE',
] as const;
export type ConfigTableKind = (typeof CONFIG_TABLE_KINDS)[number];

export type ConfigTableData = {
[key in ConfigTableKind]?: any[] | undefined;
};
98 changes: 98 additions & 0 deletions src/design/organisms/config-table/config-table.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<div class="config-tables__section section">
<!-- Section Heading -->
<div class="section__heading heading">
<h3 class="heading__text">
<app-icon [icon]="table().icon"></app-icon>
{{ table().name }}
</h3>

<!-- Heading Buttons -->
<div class="heading__buttons">
<!-- Add Users -->
<button
btn
[kind]="'DARK'"
[icon]="table().showForm ? 'times' : 'plus'"
[text]="
table().showForm
? 'Cancel ' + table().name + ' creation'
: 'Add ' + table().name
"
(click)="table().showForm = !table().showForm"
></button>

<button
btn
[kind]="'PRIMARY'"
[icon]="'refresh'"
[text]="'Load table data'"
(click)="loadTableEntries.emit()"
></button>
</div>
</div>

<app-separator class="section__separator"></app-separator>

<!-- Section Body -->

@if (!table().showForm) {
@if (table().entries?.length === 0) {
Load entries to see them
}
<div class="section__table-container">
<!-- Table -->

@let entries = table().entries;
@if (entries && entries.length > 0) {
<table class="table table-dark table-striped">
<!-- Table heading -->
<thead>
<tr>
<th scope="col">#</th>
@for (property of entries[0] | keyvalue; track property.key) {
<th scope="col" class="text-uppercase">
{{ property.key }}
</th>
}
</tr>
</thead>
<!-- Table body -->
<tbody>
@for (entry of entries; track entry[table().idProp]) {
<tr>
<th scope="row">{{ entry[table().idProp] }}</th>
@for (property of entry | keyvalue; track property.key) {
<td>
{{ property.value }}
</td>
}
<td>
<app-confirmation-toggle-button
[toggleSize]="'SMALL'"
[confirmationQuestion]="'Delete this Entry?'"
[icon]="'trash'"
(confirm)="deleteTableEntry.emit(entry)"
></app-confirmation-toggle-button>
</td>
</tr>
}
</tbody>
</table>
}
</div>
}

@if (table().showForm) {
<app-card>
<h4>Adding new {{ table().name }}</h4>
<!-- Form -->
<app-form
[model]="table().model"
[fields]="table().formFields"
[cancelButtonType]="'DARK'"
(formlySubmit)="createEntry($event)"
(formlyCancel)="table().showForm = !table().showForm"
></app-form>
</app-card>
}
</div>
37 changes: 37 additions & 0 deletions src/design/organisms/config-table/config-table.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
.config-tables {
&__return-button {
}

&__section {
margin-top: var(--spacer-3);
margin-bottom: var(--spacer-5);
}
}

.section {
&__separator {
--separator-margin-top: var(--spacer-0);
}

&__heading {
}

&__table-container {
overflow-x: auto;
}
}

.heading {
display: flex;
justify-content: space-between;

&__text {
margin-bottom: var(--spacer-0);
}

&__buttons {
align-self: flex-end;
position: relative;
top: 1px;
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { ConfigTablesComponent } from './config-tables.component';
import { ConfigTableComponent } from './config-table.component';

describe('ConfigTablesComponent', () => {
let component: ConfigTablesComponent;
let fixture: ComponentFixture<ConfigTablesComponent>;
describe('ConfigTableComponent', () => {
let component: ConfigTableComponent;
let fixture: ComponentFixture<ConfigTableComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [ConfigTablesComponent]
})
imports: [ConfigTableComponent]
})
.compileComponents();

fixture = TestBed.createComponent(ConfigTablesComponent);
fixture = TestBed.createComponent(ConfigTableComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
Expand Down
42 changes: 42 additions & 0 deletions src/design/organisms/config-table/config-table.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { KeyValuePipe } from '@angular/common';
import {
ChangeDetectionStrategy,
Component,
input,
output,
} from '@angular/core';
import { ButtonComponent } from 'src/design/atoms/button/button.component';
import { CardComponent } from '../../atoms/card/card.component';
import { IconComponent } from '../../atoms/icon/icon.component';
import { SeparatorComponent } from '../../atoms/separator/separator.component';
import { ConfirmationToggleButtonComponent } from '../../molecules/confirmation-toggle-button/confirmation-toggle-button.component';
import { FormComponent } from '../../molecules/form/form.component';
import { ConfigTable } from '../_model/config-table';

@Component({
selector: 'app-config-table',
standalone: true,
imports: [
IconComponent,
SeparatorComponent,
ConfirmationToggleButtonComponent,
FormComponent,
CardComponent,
ButtonComponent,
KeyValuePipe,
],
templateUrl: './config-table.component.html',
styleUrl: './config-table.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ConfigTableComponent<T extends object> {
table = input.required<ConfigTable<T>>();

loadTableEntries = output<void>();
deleteTableEntry = output<T>();
createTableEntry = output<T>();

createEntry(entry: Partial<T>): void {
this.createTableEntry.emit(entry as T);
}
}
9 changes: 0 additions & 9 deletions src/design/templates/_models/config-table.ts

This file was deleted.

109 changes: 8 additions & 101 deletions src/design/templates/config-tables/config-tables.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,107 +11,14 @@

<!-- Sections -->
@for (table of tables(); track table.kind) {
<div class="config-tables__section section">
<!-- Section Heading -->
<div class="section__heading heading">
<h3 class="heading__text">
<app-icon [icon]="table.icon"></app-icon>
{{ table.name }}
</h3>

<!-- Heading Buttons -->
<div class="heading__buttons">
<!-- Add Users -->
<button
btn
[kind]="'DARK'"
[icon]="table.showForm ? 'times' : 'plus'"
[text]="
table.showForm
? 'Cancel ' + table.name + ' creation'
: 'Add ' + table.name
"
(click)="table.showForm = !table.showForm"
></button>

<button
btn
[kind]="'PRIMARY'"
[icon]="'refresh'"
[text]="'Load table data'"
(click)="loadTableEntries.emit(table.kind)"
></button>
</div>
</div>

<app-separator class="section__separator"></app-separator>

<!-- Section Body -->

@if (!table.showForm) {
@if (table.entries?.length === 0) {
Load entries to see them
}
<div class="section__table-container">
<!-- Table -->
@if (table.entries && table.entries.length > 0) {
<table class="table table-dark table-striped">
<!-- Table heading -->
<thead>
<tr>
<th scope="col">#</th>
@for (
property of table.entries[0] | keyvalue;
track property.key
) {
<th scope="col" class="text-uppercase">
{{ property.key }}
</th>
}
</tr>
</thead>
<!-- Table body -->
<tbody>
@for (entry of table.entries; track entry.pk) {
<tr>
<th scope="row">{{ entry.id }} {{ entry.pk }}</th>
@for (property of entry | keyvalue; track property.key) {
<td>
{{ property.value }}
</td>
}
<td>
<app-confirmation-toggle-button
[toggleSize]="'SMALL'"
[confirmationQuestion]="'Delete this Entry?'"
[icon]="'trash'"
(confirm)="
deleteTableEntry.emit({ table: table.kind, entry })
"
></app-confirmation-toggle-button>
</td>
</tr>
}
</tbody>
</table>
}
</div>
}

@if (table.showForm) {
<app-card>
<h4>Adding new {{ table.name }}</h4>
<!-- Form -->
<app-form
[model]="table.model"
[fields]="table.formFields"
[cancelButtonType]="'DARK'"
(formlySubmit)="createEntry(table.kind, table.model)"
(formlyCancel)="table.showForm = !table.showForm"
></app-form>
</app-card>
}
</div>
<app-config-table
[table]="table"
(loadTableEntries)="loadTableEntries.emit(table.kind)"
(createTableEntry)="createEntry(table.kind, $event)"
(deleteTableEntry)="
deleteTableEntry.emit({ table: table.kind, entry: $event })
"
></app-config-table>
}

<a class="config-tables__return-button" [routerLink]="campaignOverviewUrl">
Expand Down
Loading

0 comments on commit abb40fc

Please sign in to comment.