add breadcrumbs
This commit is contained in:
parent
dfc3afd4a9
commit
b047ecc589
@ -0,0 +1,26 @@
|
|||||||
|
@if (breadcrumbs()?.length) {
|
||||||
|
<div class="breadcrumbs text-sm">
|
||||||
|
<ul>
|
||||||
|
@for (breadcrumb of breadcrumbs(); track breadcrumb; ) {
|
||||||
|
|
||||||
|
<li>
|
||||||
|
@if (breadcrumb.url) {
|
||||||
|
<a [routerLink]="breadcrumb.url">
|
||||||
|
@if (breadcrumb.showIcon !== false) {
|
||||||
|
<span [outerHTML]="(breadcrumb.svgIcon || defaultLinkIcon) | safeHtml"></span>
|
||||||
|
}
|
||||||
|
{{ breadcrumb.text }}
|
||||||
|
</a>
|
||||||
|
} @else {
|
||||||
|
<span class="inline-flex items-center gap-2">
|
||||||
|
@if (breadcrumb.showIcon !== false) {
|
||||||
|
<span [outerHTML]="(breadcrumb.svgIcon || defaultIcon) | safeHtml"></span>
|
||||||
|
}
|
||||||
|
{{ breadcrumb.text }}
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
</li>
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { Breadcrumbs } from './breadcrumbs';
|
||||||
|
|
||||||
|
describe('Breadcrumbs', () => {
|
||||||
|
let component: Breadcrumbs;
|
||||||
|
let fixture: ComponentFixture<Breadcrumbs>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
imports: [Breadcrumbs]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(Breadcrumbs);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,46 @@
|
|||||||
|
import { Component, input } from '@angular/core';
|
||||||
|
import { Breadcrumb } from '../../daisy.types';
|
||||||
|
import { RouterLink } from '@angular/router';
|
||||||
|
import { SafeHtmlPipe } from '../../pipes/safe-html-pipe';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'rs-daisy-breadcrumbs',
|
||||||
|
imports: [
|
||||||
|
RouterLink,
|
||||||
|
SafeHtmlPipe,
|
||||||
|
],
|
||||||
|
templateUrl: './breadcrumbs.html',
|
||||||
|
styleUrl: './breadcrumbs.css',
|
||||||
|
})
|
||||||
|
export class Breadcrumbs {
|
||||||
|
|
||||||
|
breadcrumbs = input<Breadcrumb[]>([]);
|
||||||
|
|
||||||
|
defaultLinkIcon: string = `<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
class="h-4 w-4 stroke-current">
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z"></path>
|
||||||
|
</svg>
|
||||||
|
`;
|
||||||
|
|
||||||
|
defaultIcon: string = `
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
class="h-4 w-4 stroke-current">
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
d="M9 13h6m-3-3v6m5 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
|
||||||
|
</svg>
|
||||||
|
`;
|
||||||
|
|
||||||
|
}
|
||||||
@ -11,3 +11,10 @@ export interface FooterNav{
|
|||||||
export interface FooterConfig{
|
export interface FooterConfig{
|
||||||
navs: FooterNav[]
|
navs: FooterNav[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface Breadcrumb{
|
||||||
|
text: string;
|
||||||
|
url?: string;
|
||||||
|
showIcon?: boolean;
|
||||||
|
svgIcon?: string;
|
||||||
|
}
|
||||||
|
|||||||
@ -0,0 +1,16 @@
|
|||||||
|
import { inject, Pipe, PipeTransform } from '@angular/core';
|
||||||
|
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
|
||||||
|
|
||||||
|
@Pipe({
|
||||||
|
name: 'safeHtml'
|
||||||
|
})
|
||||||
|
export class SafeHtmlPipe implements PipeTransform {
|
||||||
|
|
||||||
|
private sanitized = inject(DomSanitizer);
|
||||||
|
|
||||||
|
transform(value: string | undefined): SafeHtml {
|
||||||
|
if (!value) return '';
|
||||||
|
return this.sanitized.bypassSecurityTrustHtml(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -5,5 +5,6 @@
|
|||||||
export * from './lib/ng-daisyui';
|
export * from './lib/ng-daisyui';
|
||||||
export * from './lib/components/button/button';
|
export * from './lib/components/button/button';
|
||||||
export * from './lib/components/footer/footer';
|
export * from './lib/components/footer/footer';
|
||||||
|
export * from './lib/components/breadcrumbs/breadcrumbs';
|
||||||
export * from './lib/daisy.types';
|
export * from './lib/daisy.types';
|
||||||
export * from './lib/layout/';
|
export * from './lib/layout/';
|
||||||
|
|||||||
@ -1,3 +1,10 @@
|
|||||||
@for (action of actions(); track action){
|
@for (action of actions(); track action){
|
||||||
<a class="btn btn-primary" (click)="onClick($event,action)">{{action.action}}</a>
|
<a class="btn btn-primary" (click)="onClick($event,action)">
|
||||||
|
@if(action.svgIcon){
|
||||||
|
<span [outerHTML]="action.svgIcon | safeHtml"></span>
|
||||||
|
}
|
||||||
|
@if ( action.text !== false){
|
||||||
|
{{action.text || action.action}}
|
||||||
|
}
|
||||||
|
</a>
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,15 +1,19 @@
|
|||||||
import { Component, inject, input, OnInit } from '@angular/core';
|
import { Component, inject, input, OnInit } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
|
import { SafeHtmlPipe } from '../../pipes/safe-html-pipe';
|
||||||
|
|
||||||
export interface ActionDefinition<T> {
|
export interface ActionDefinition<T> {
|
||||||
action: string;
|
action: string;
|
||||||
|
text?: string|false;
|
||||||
generate: (action: string, item?: T) => string;
|
generate: (action: string, item?: T) => string;
|
||||||
handler?: (action: ActionDefinition<T>, item?: T) => void;
|
handler?: (action: ActionDefinition<T>, item?: T) => void;
|
||||||
|
svgIcon?: string; //https://heroicons.com/
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-generic-action-column',
|
selector: 'app-generic-action-column',
|
||||||
imports: [
|
imports: [
|
||||||
|
SafeHtmlPipe,
|
||||||
],
|
],
|
||||||
templateUrl: './generic-action-column.html',
|
templateUrl: './generic-action-column.html',
|
||||||
styleUrl: './generic-action-column.css',
|
styleUrl: './generic-action-column.css',
|
||||||
|
|||||||
@ -1,7 +1,15 @@
|
|||||||
import { Type } from '@angular/core';
|
import { Type } from '@angular/core';
|
||||||
|
import { ColumnDefinition } from './column-definition.interface';
|
||||||
|
|
||||||
|
export interface StyleClassContext<T>{
|
||||||
|
definition: ColumnDefinition<T> ;
|
||||||
|
cellDefinition: CellDefinition<T>;
|
||||||
|
item?: T;
|
||||||
|
}
|
||||||
|
|
||||||
export interface CellDefinition<T> {
|
export interface CellDefinition<T> {
|
||||||
value?: ((item?: T) => any) | string;
|
value?: ((item?: T) => any) | string;
|
||||||
component?: Type<any>;
|
component?: Type<any>;
|
||||||
componentInputs?: (item?: T|null) => { [key: string]: any };
|
componentInputs?: (item?: T|null) => { [key: string]: any };
|
||||||
|
styleClass?: (definition: StyleClassContext<T>) => string;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
<tr [ngClass]="config.rowCssClass ? config.rowCssClass(item) : ''">
|
<tr [ngClass]="config.rowCssClass ? config.rowCssClass(item) : ''">
|
||||||
@for (column of config.columns; track column) {
|
@for (column of config.columns; track column) {
|
||||||
<td [class]="column.attribute">
|
<td [class]="getValueStyleClass(column!,column.valueCell!,item) ">
|
||||||
@if (column.valueCell) {
|
@if (column.valueCell) {
|
||||||
@if (typeof column.valueCell === 'boolean') {
|
@if (typeof column.valueCell === 'boolean') {
|
||||||
{{ resolveValue(item, column) }}
|
{{ resolveValue(item, column) }}
|
||||||
|
|||||||
@ -18,12 +18,11 @@ import { GenericTableSearchForm } from './generic-table-search-form/generic-tabl
|
|||||||
export class GenericTable<T> implements OnInit {
|
export class GenericTable<T> implements OnInit {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Input() config!: GenericTableConfig<T>;
|
@Input() config!: GenericTableConfig<T>;
|
||||||
public data$!: Observable<GetDataResponse<T>>;
|
public data$!: Observable<GetDataResponse<T>>;
|
||||||
|
|
||||||
sanitizer = inject(DomSanitizer);
|
sanitizer = inject(DomSanitizer);
|
||||||
parser = new DOMParser()
|
parser = new DOMParser();
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
|
||||||
@ -31,19 +30,19 @@ export class GenericTable<T> implements OnInit {
|
|||||||
this.config.refresh$,
|
this.config.refresh$,
|
||||||
this.config.filter$.pipe(startWith({})),
|
this.config.filter$.pipe(startWith({})),
|
||||||
this.config.page$.pipe(startWith(1)),
|
this.config.page$.pipe(startWith(1)),
|
||||||
this.config.limit$.pipe(startWith(10))
|
this.config.limit$.pipe(startWith(10)),
|
||||||
]).pipe(
|
]).pipe(
|
||||||
switchMap(([_, filter, page, limit]) => {
|
switchMap(([_, filter, page, limit]) => {
|
||||||
const query = { ...filter, page, limit: 10 };
|
const query = { ...filter, page, limit: 10 };
|
||||||
console.info("filter is", filter)
|
console.info('filter is', filter);
|
||||||
return this.config.dataProvider.getData({
|
return this.config.dataProvider.getData({
|
||||||
params: {
|
params: {
|
||||||
q: filter.term ?? '',
|
q: filter.term ?? '',
|
||||||
page,
|
page,
|
||||||
limit
|
limit,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -84,7 +83,7 @@ export class GenericTable<T> implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected searchTermChanged(searchTerm: any) {
|
protected searchTermChanged(searchTerm: any) {
|
||||||
console.info("searchterm",searchTerm);
|
console.info('searchterm', searchTerm);
|
||||||
this.config.page$.next(1);
|
this.config.page$.next(1);
|
||||||
this.config.filter$.next(searchTerm);
|
this.config.filter$.next(searchTerm);
|
||||||
}
|
}
|
||||||
@ -93,4 +92,16 @@ export class GenericTable<T> implements OnInit {
|
|||||||
this.config.page$.next(1);
|
this.config.page$.next(1);
|
||||||
this.config.limit$.next(+value);
|
this.config.limit$.next(+value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected getValueStyleClass(columnDefinition: ColumnDefinition<T>, cellDefinition: CellDefinition<T> | boolean, item: T) {
|
||||||
|
console.info("co")
|
||||||
|
if ( (cellDefinition as any).hasOwnProperty("styleClass") ){
|
||||||
|
const def = (cellDefinition as CellDefinition<T>);
|
||||||
|
if (def && def.styleClass) {
|
||||||
|
return (columnDefinition.attribute as string) +" "+def.styleClass({definition: columnDefinition, cellDefinition: def, item});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return columnDefinition.attribute;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,28 +2,28 @@
|
|||||||
|
|
||||||
<!-- Generated by the CLI -->
|
<!-- Generated by the CLI -->
|
||||||
<div class="p-4 md:p-8">
|
<div class="p-4 md:p-8">
|
||||||
|
<rs-daisy-breadcrumbs [breadcrumbs]="breadcrumbs"></rs-daisy-breadcrumbs>
|
||||||
<ng-container *ngIf="eventType$ | async as eventType; else loading">
|
<ng-container *ngIf="eventType$ | async as eventType; else loading">
|
||||||
<div class="card bg-base-100 shadow-xl max-w-2xl mx-auto">
|
<div class="card bg-base-100 shadow-xl max-w-2xl mx-auto">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h2 class="card-title text-3xl">EventType Details</h2>
|
<h2 class="card-title text-3xl">Esemény adatai</h2>
|
||||||
|
|
||||||
<div class="overflow-x-auto mt-4">
|
<div class="overflow-x-auto mt-4">
|
||||||
<table class="table w-full">
|
<table class="table w-full">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<th>id</th>
|
<th>Esemény azonosító</th>
|
||||||
<td>{{ eventType.id }}</td>
|
<td>{{ eventType.id }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>name</th>
|
<th>Név</th>
|
||||||
<td>{{ eventType.name }}</td>
|
<td>{{ eventType.name }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>description</th>
|
<th>Leírás</th>
|
||||||
<td>{{ eventType.description }}</td>
|
<td>{{ eventType.description }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>color</th>
|
<th>Szín</th>
|
||||||
<td>{{ eventType.color }}</td>
|
<td>{{ eventType.color }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
@ -31,8 +31,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card-actions justify-end mt-6">
|
<div class="card-actions justify-end mt-6">
|
||||||
<a routerLink="/event-type" class="btn btn-secondary">Back to List</a>
|
<a routerLink="/event-type/{{ eventType.id }}/edit" class="btn btn-primary">Módosítás</a>
|
||||||
<a routerLink="/event-type/{{ eventType.id }}/edit" class="btn btn-primary">Edit</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -5,30 +5,54 @@ import { Component, OnInit } from '@angular/core';
|
|||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { ActivatedRoute, RouterModule } from '@angular/router';
|
import { ActivatedRoute, RouterModule } from '@angular/router';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { switchMap } from 'rxjs/operators';
|
import { switchMap, tap } from 'rxjs/operators';
|
||||||
import { EventType } from '../../models/event-type.model';
|
import { EventType } from '../../models/event-type.model';
|
||||||
import { EventTypeService } from '../../services/event-type.service';
|
import { EventTypeService } from '../../services/event-type.service';
|
||||||
|
import { Breadcrumbs, Breadcrumb } from '@rschneider/ng-daisyui';
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-event-type-details',
|
selector: 'app-event-type-details',
|
||||||
templateUrl: './event-type-details.component.html',
|
templateUrl: './event-type-details.component.html',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
imports: [CommonModule, RouterModule],
|
imports: [CommonModule, RouterModule, Breadcrumbs],
|
||||||
})
|
})
|
||||||
export class EventTypeDetailsComponent implements OnInit {
|
export class EventTypeDetailsComponent implements OnInit {
|
||||||
|
|
||||||
|
static readonly BC_LIST: Breadcrumb = {
|
||||||
|
text: 'Esemény típusok',
|
||||||
|
url: '/event-type/table',
|
||||||
|
};
|
||||||
|
|
||||||
eventType$!: Observable<EventType>;
|
eventType$!: Observable<EventType>;
|
||||||
|
|
||||||
|
protected breadcrumbs: Breadcrumb[] = [
|
||||||
|
EventTypeDetailsComponent.BC_LIST,
|
||||||
|
];
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private eventTypeService: EventTypeService
|
private eventTypeService: EventTypeService,
|
||||||
) {}
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.eventType$ = this.route.params.pipe(
|
this.eventType$ = this.route.params.pipe(
|
||||||
switchMap(params => {
|
switchMap(params => {
|
||||||
const id = params['id'];
|
const id = params['id'];
|
||||||
return this.eventTypeService.findOne(id);
|
return this.eventTypeService.findOne(id);
|
||||||
})
|
|
||||||
|
},
|
||||||
|
),
|
||||||
|
|
||||||
|
tap(value => {
|
||||||
|
this.breadcrumbs = [
|
||||||
|
EventTypeDetailsComponent.BC_LIST,
|
||||||
|
{
|
||||||
|
text: value.name,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,5 +1,5 @@
|
|||||||
<!-- dvbooking-cli/src/templates/angular/form.component.html.tpl -->
|
<!-- dvbooking-cli/src/templates/angular/form.component.html.tpl -->
|
||||||
|
<rs-daisy-breadcrumbs [breadcrumbs]="breadcrumbs"></rs-daisy-breadcrumbs>
|
||||||
<!-- Generated by the CLI -->
|
<!-- Generated by the CLI -->
|
||||||
<div class="p-4 md:p-8">
|
<div class="p-4 md:p-8">
|
||||||
<div class="card bg-base-100 shadow-xl max-w-2xl mx-auto">
|
<div class="card bg-base-100 shadow-xl max-w-2xl mx-auto">
|
||||||
@ -10,14 +10,15 @@
|
|||||||
|
|
||||||
<form [formGroup]="form" (ngSubmit)="onSubmit()" class="space-y-4 mt-4">
|
<form [formGroup]="form" (ngSubmit)="onSubmit()" class="space-y-4 mt-4">
|
||||||
|
|
||||||
<div class="form-control"><label class="label"><span class="label-text">name</span></label>
|
<div class="form-control"><label class="label"><span class="label-text">Esemény típus neve</span></label>
|
||||||
<input type="text" formControlName="name" class="input input-bordered w-full" /></div>
|
<input type="text" formControlName="name" class="input input-bordered w-full" /></div>
|
||||||
|
|
||||||
<div class="form-control"><label class="label"><span class="label-text">description</span></label>
|
<div class="form-control"><label class="label"><span class="label-text">Leírás</span></label>
|
||||||
<input type="text" formControlName="description" class="input input-bordered w-full" /></div>
|
<input type="text" formControlName="description" class="input input-bordered w-full" /></div>
|
||||||
|
|
||||||
<div class="form-control"><label class="label"><span class="label-text">color</span></label>
|
<div class="form-control"><label class="label"><span class="label-text">Szín</span></label>
|
||||||
<input type="text" formControlName="color" class="input input-bordered w-full" /></div>
|
<input type="color" formControlName="color" class="input input-bordered w-full" colorspace="display-p3"
|
||||||
|
alpha /></div>
|
||||||
|
|
||||||
<div class="card-actions justify-end mt-6">
|
<div class="card-actions justify-end mt-6">
|
||||||
<a routerLink="/event-type" class="btn btn-ghost">Cancel</a>
|
<a routerLink="/event-type" class="btn btn-ghost">Cancel</a>
|
||||||
|
|||||||
@ -1,22 +1,34 @@
|
|||||||
// dvbooking-cli/src/templates/angular/form.component.ts.tpl
|
// dvbooking-cli/src/templates/angular/form.component.ts.tpl
|
||||||
|
|
||||||
// Generated by the CLI
|
// Generated by the CLI
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { ChangeDetectorRef, Component, OnInit } from '@angular/core';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { FormBuilder, FormGroup, Validators, ReactiveFormsModule } from '@angular/forms';
|
import { FormBuilder, FormGroup, Validators, ReactiveFormsModule } from '@angular/forms';
|
||||||
import { ActivatedRoute, Router, RouterModule } from '@angular/router';
|
import { ActivatedRoute, Router, RouterModule } from '@angular/router';
|
||||||
import { Observable, of } from 'rxjs';
|
import { delay, Observable, of } from 'rxjs';
|
||||||
import { switchMap, tap } from 'rxjs/operators';
|
import { switchMap, tap } from 'rxjs/operators';
|
||||||
import { EventType } from '../../models/event-type.model';
|
import { EventType } from '../../models/event-type.model';
|
||||||
import { EventTypeService } from '../../services/event-type.service';
|
import { EventTypeService } from '../../services/event-type.service';
|
||||||
|
import { Breadcrumbs, Breadcrumb } from '@rschneider/ng-daisyui';
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-event-type-form',
|
selector: 'app-event-type-form',
|
||||||
templateUrl: './event-type-form.component.html',
|
templateUrl: './event-type-form.component.html',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
imports: [CommonModule, ReactiveFormsModule, RouterModule],
|
imports: [CommonModule, ReactiveFormsModule, RouterModule, Breadcrumbs],
|
||||||
})
|
})
|
||||||
export class EventTypeFormComponent implements OnInit {
|
export class EventTypeFormComponent implements OnInit {
|
||||||
|
|
||||||
|
static readonly BC_LIST: Breadcrumb = {
|
||||||
|
text: 'Esemény típusok',
|
||||||
|
url: '/event-type/table',
|
||||||
|
};
|
||||||
|
|
||||||
|
protected breadcrumbs: Breadcrumb[] = [
|
||||||
|
EventTypeFormComponent.BC_LIST,
|
||||||
|
];
|
||||||
|
|
||||||
form: FormGroup;
|
form: FormGroup;
|
||||||
isEditMode = false;
|
isEditMode = false;
|
||||||
id: number | null = null;
|
id: number | null = null;
|
||||||
@ -27,7 +39,8 @@ export class EventTypeFormComponent implements OnInit {
|
|||||||
private fb: FormBuilder,
|
private fb: FormBuilder,
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private eventTypeService: EventTypeService
|
private eventTypeService: EventTypeService,
|
||||||
|
private cdr: ChangeDetectorRef
|
||||||
) {
|
) {
|
||||||
this.form = this.fb.group({
|
this.form = this.fb.group({
|
||||||
name: [null],
|
name: [null],
|
||||||
@ -49,10 +62,21 @@ export class EventTypeFormComponent implements OnInit {
|
|||||||
return this.eventTypeService.findOne(this.id);
|
return this.eventTypeService.findOne(this.id);
|
||||||
}
|
}
|
||||||
return of(null);
|
return of(null);
|
||||||
})
|
}),
|
||||||
).subscribe(eventType => {
|
).subscribe(eventType => {
|
||||||
|
console.info("Breadcrumb loaded")
|
||||||
if (eventType) {
|
if (eventType) {
|
||||||
this.form.patchValue(eventType);
|
this.form.patchValue(eventType);
|
||||||
|
|
||||||
|
|
||||||
|
this.breadcrumbs = [
|
||||||
|
EventTypeFormComponent.BC_LIST,
|
||||||
|
{
|
||||||
|
text: eventType.name,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
this.cdr.markForCheck();
|
||||||
|
console.info("breadcrumbs", this.breadcrumbs)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,6 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<app-event-type-filter (filterChanged)="onFilterChanged($event)"></app-event-type-filter>
|
<app-event-type-filter (filterChanged)="onFilterChanged($event)"></app-event-type-filter>
|
||||||
|
|
||||||
<ng-container *ngIf="paginatedResponse$ | async as response; else loading">
|
<ng-container *ngIf="paginatedResponse$ | async as response; else loading">
|
||||||
<div class="overflow-x-auto bg-base-100 rounded-lg shadow">
|
<div class="overflow-x-auto bg-base-100 rounded-lg shadow">
|
||||||
<table class="table w-full">
|
<table class="table w-full">
|
||||||
@ -28,9 +27,9 @@
|
|||||||
<td>{{ item.description }}</td>
|
<td>{{ item.description }}</td>
|
||||||
<td>{{ item.color }}</td>
|
<td>{{ item.color }}</td>
|
||||||
<td class="text-right space-x-2">
|
<td class="text-right space-x-2">
|
||||||
<a [routerLink]="['/event-type', item.id]" class="btn btn-sm btn-ghost">View</a>
|
<a [routerLink]="['/event-type', item.id]" class="btn btn-sm btn-ghost">Részletek</a>
|
||||||
<a [routerLink]="['/event-type', item.id, 'edit']" class="btn btn-sm btn-ghost">Edit</a>
|
<a [routerLink]="['/event-type', item.id, 'edit']" class="btn btn-sm btn-ghost">Módosítás</a>
|
||||||
<button (click)="deleteItem(item.id)" class="btn btn-sm btn-error btn-ghost">Delete</button>
|
<button (click)="deleteItem(item.id)" class="btn btn-sm btn-error btn-ghost">Törlés</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr *ngIf="response.data.length === 0">
|
<tr *ngIf="response.data.length === 0">
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import {
|
|||||||
} from '../../../../components/generic-action-column/generic-action-column';
|
} from '../../../../components/generic-action-column/generic-action-column';
|
||||||
import { EventTypeService } from '../../services/event-type.service';
|
import { EventTypeService } from '../../services/event-type.service';
|
||||||
import { BehaviorSubject } from 'rxjs';
|
import { BehaviorSubject } from 'rxjs';
|
||||||
|
import { SvgIcons } from '../../../../svg-icons';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-event-type-table',
|
selector: 'app-event-type-table',
|
||||||
@ -64,7 +65,10 @@ export class EventTypeTableComponent implements OnInit {
|
|||||||
{
|
{
|
||||||
attribute: 'description',
|
attribute: 'description',
|
||||||
headerCell: true,
|
headerCell: true,
|
||||||
valueCell: true,
|
valueCell: {
|
||||||
|
styleClass: ctx => 'w-auto',
|
||||||
|
value: item => item?.description,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
attribute: 'color',
|
attribute: 'color',
|
||||||
@ -79,9 +83,13 @@ export class EventTypeTableComponent implements OnInit {
|
|||||||
componentInputs: item => ({
|
componentInputs: item => ({
|
||||||
item: item,
|
item: item,
|
||||||
actions: [
|
actions: [
|
||||||
{ action: 'view', handler: actionHandler },
|
{ action: 'view', text: false, handler: actionHandler, svgIcon: SvgIcons.heroDocument },
|
||||||
{ action: 'edit', handler: actionHandler },
|
{
|
||||||
{ action: 'delete', handler: actionHandler },
|
action: 'edit', text: false,
|
||||||
|
svgIcon: SvgIcons.heroCog6Tooth,
|
||||||
|
handler: actionHandler,
|
||||||
|
},
|
||||||
|
{ action: 'delete', text: false, handler: actionHandler, svgIcon: SvgIcons.heroTrash },
|
||||||
] as ActionDefinition<EventType>[],
|
] as ActionDefinition<EventType>[],
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
@ -102,7 +110,7 @@ export class EventTypeTableComponent implements OnInit {
|
|||||||
// Explicitly type 'err' to satisfy strict TypeScript rules.
|
// Explicitly type 'err' to satisfy strict TypeScript rules.
|
||||||
error: (err: any) => {
|
error: (err: any) => {
|
||||||
console.error(`Error deleting item with ID ${id}:`, err);
|
console.error(`Error deleting item with ID ${id}:`, err);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
17
admin/src/app/svg-icons.ts
Normal file
17
admin/src/app/svg-icons.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
export class SvgIcons {
|
||||||
|
public static heroDocument = `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m2.25 0H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9Z" />
|
||||||
|
</svg>
|
||||||
|
`;
|
||||||
|
|
||||||
|
public static heroTrash = `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0" />
|
||||||
|
</svg>`;
|
||||||
|
|
||||||
|
public static heroCog6Tooth = `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.325.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 0 1 1.37.49l1.296 2.247a1.125 1.125 0 0 1-.26 1.431l-1.003.827c-.293.241-.438.613-.43.992a7.723 7.723 0 0 1 0 .255c-.008.378.137.75.43.991l1.004.827c.424.35.534.955.26 1.43l-1.298 2.247a1.125 1.125 0 0 1-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.47 6.47 0 0 1-.22.128c-.331.183-.581.495-.644.869l-.213 1.281c-.09.543-.56.94-1.11.94h-2.594c-.55 0-1.019-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 0 1-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 0 1-1.369-.49l-1.297-2.247a1.125 1.125 0 0 1 .26-1.431l1.004-.827c.292-.24.437-.613.43-.991a6.932 6.932 0 0 1 0-.255c.007-.38-.138-.751-.43-.992l-1.004-.827a1.125 1.125 0 0 1-.26-1.43l1.297-2.247a1.125 1.125 0 0 1 1.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.086.22-.128.332-.183.582-.495.644-.869l.214-1.28Z" />
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
|
||||||
|
</svg>
|
||||||
|
`;
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user