mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
- feat(remission-data-access,remission-list,remission-return-receipt-details): improve remission list UX and persist store state - feat(remission-list, remission-data-access): implement resource-based receipt data fetching - Merge branch 'develop' into feature/5230-Feedback-Remi-Starten - feat(remission-data-access, remission-list, ui-dialog, remission-start-dialog): consolidate remission workflow and enhance dialog system - feat(remission-list-item): extract selection logic into dedicated component Refs: #5230 #5233
This commit is contained in:
committed by
Lorenz Hilpert
parent
f4b541c7c0
commit
c5182809ac
@@ -13,9 +13,4 @@
|
||||
@apply overflow-y-auto overflow-x-hidden;
|
||||
@apply min-h-0;
|
||||
}
|
||||
|
||||
&:has(ui-feedback-dialog),
|
||||
&:has(remi-remission-start-dialog) {
|
||||
@apply gap-0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { createComponentFactory, Spectator } from '@ngneat/spectator/jest';
|
||||
import { DialogComponent } from './dialog.component';
|
||||
import { DialogContentDirective } from './dialog-content.directive';
|
||||
import { DIALOG_CONTENT, DIALOG_TITLE } from './tokens';
|
||||
import { DIALOG_CLASS_LIST, DIALOG_CONTENT, DIALOG_TITLE } from './tokens';
|
||||
import { Component } from '@angular/core';
|
||||
import { DialogRef, DIALOG_DATA } from '@angular/cdk/dialog';
|
||||
import { NgComponentOutlet } from '@angular/common';
|
||||
@@ -12,13 +12,18 @@ import { NgComponentOutlet } from '@angular/common';
|
||||
template: '<div>Mock Content</div>',
|
||||
standalone: true,
|
||||
})
|
||||
class MockDialogContentComponent extends DialogContentDirective<unknown, unknown> {}
|
||||
class MockDialogContentComponent extends DialogContentDirective<
|
||||
unknown,
|
||||
unknown
|
||||
> {}
|
||||
|
||||
describe('DialogComponent', () => {
|
||||
let spectator: Spectator<DialogComponent<unknown, unknown, MockDialogContentComponent>>;
|
||||
let spectator: Spectator<
|
||||
DialogComponent<unknown, unknown, MockDialogContentComponent>
|
||||
>;
|
||||
const mockTitle = 'Test Dialog Title';
|
||||
const mockDialogRef = { close: jest.fn() };
|
||||
|
||||
|
||||
const createComponent = createComponentFactory({
|
||||
component: DialogComponent,
|
||||
imports: [NgComponentOutlet, MockDialogContentComponent], // Use imports instead of declarations for standalone components
|
||||
@@ -26,7 +31,8 @@ describe('DialogComponent', () => {
|
||||
{ provide: DIALOG_TITLE, useValue: mockTitle },
|
||||
{ provide: DIALOG_CONTENT, useValue: MockDialogContentComponent },
|
||||
{ provide: DialogRef, useValue: mockDialogRef },
|
||||
{ provide: DIALOG_DATA, useValue: {} }
|
||||
{ provide: DIALOG_DATA, useValue: {} },
|
||||
{ provide: DIALOG_CLASS_LIST, useValue: [] },
|
||||
],
|
||||
});
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
computed,
|
||||
inject,
|
||||
signal,
|
||||
} from '@angular/core';
|
||||
import { DialogContentDirective } from './dialog-content.directive';
|
||||
import { DIALOG_CONTENT, DIALOG_TITLE } from './tokens';
|
||||
import { DIALOG_CLASS_LIST, DIALOG_CONTENT, DIALOG_TITLE } from './tokens';
|
||||
import { ComponentType } from '@angular/cdk/portal';
|
||||
import { NgComponentOutlet } from '@angular/common';
|
||||
|
||||
@@ -23,7 +24,7 @@ import { NgComponentOutlet } from '@angular/common';
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
imports: [NgComponentOutlet],
|
||||
host: {
|
||||
'[class]': '["ui-dialog"]',
|
||||
'[class]': 'classes()',
|
||||
},
|
||||
})
|
||||
export class DialogComponent<D, R, C extends DialogContentDirective<D, R>> {
|
||||
@@ -32,4 +33,18 @@ export class DialogComponent<D, R, C extends DialogContentDirective<D, R>> {
|
||||
|
||||
/** The component type to instantiate as the dialog content */
|
||||
readonly component = inject(DIALOG_CONTENT) as ComponentType<C>;
|
||||
|
||||
/** Additional CSS classes provided via injection */
|
||||
private readonly classList =
|
||||
inject(DIALOG_CLASS_LIST, { optional: true }) ?? [];
|
||||
|
||||
/**
|
||||
* Computed property that combines the base dialog class with any additional classes
|
||||
* This allows for dynamic styling of the dialog based on external configuration
|
||||
*
|
||||
* @return An array of CSS class names to apply to the dialog element
|
||||
*/
|
||||
classes = computed(() => {
|
||||
return ['ui-dialog', ...this.classList];
|
||||
});
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
injectFeedbackDialog,
|
||||
injectMessageDialog,
|
||||
injectTextInputDialog,
|
||||
injectNumberInputDialog,
|
||||
} from './injects';
|
||||
import { MessageDialogComponent } from './message-dialog/message-dialog.component';
|
||||
import { DialogComponent } from './dialog.component';
|
||||
@@ -13,6 +14,7 @@ import { Component } from '@angular/core';
|
||||
import { DialogContentDirective } from './dialog-content.directive';
|
||||
import { TextInputDialogComponent } from './text-input-dialog/text-input-dialog.component';
|
||||
import { FeedbackDialogComponent } from './feedback-dialog/feedback-dialog.component';
|
||||
import { NumberInputDialogComponent } from './number-input-dialog/number-input-dialog.component';
|
||||
|
||||
// Test component extending DialogContentDirective for testing
|
||||
@Component({ template: '' })
|
||||
@@ -177,6 +179,27 @@ describe('Dialog Injects', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('injectNumberInputDialog', () => {
|
||||
it('should create a dialog injector for NumberInputDialogComponent', () => {
|
||||
// Act
|
||||
const openNumberInputDialog = TestBed.runInInjectionContext(() =>
|
||||
injectNumberInputDialog(),
|
||||
);
|
||||
openNumberInputDialog({
|
||||
data: {
|
||||
message: 'Test message',
|
||||
inputLabel: 'Enter value',
|
||||
inputDefaultValue: 0,
|
||||
},
|
||||
});
|
||||
|
||||
// Assert
|
||||
const callOptions = mockDialogOpen.mock.calls[0][1];
|
||||
const injector = callOptions.injector;
|
||||
expect(injector.get(DIALOG_CONTENT)).toBe(NumberInputDialogComponent);
|
||||
});
|
||||
});
|
||||
|
||||
describe('injectFeedbackDialog', () => {
|
||||
it('should create a dialog injector for FeedbackDialogComponent', () => {
|
||||
// Act
|
||||
|
||||
@@ -4,9 +4,10 @@ import { ComponentType } from '@angular/cdk/portal';
|
||||
import { inject, Injector } from '@angular/core';
|
||||
import { DialogContentDirective } from './dialog-content.directive';
|
||||
import { DialogComponent } from './dialog.component';
|
||||
import { DIALOG_CONTENT, DIALOG_TITLE } from './tokens';
|
||||
import { DIALOG_CLASS_LIST, DIALOG_CONTENT, DIALOG_TITLE } from './tokens';
|
||||
import { MessageDialogComponent } from './message-dialog/message-dialog.component';
|
||||
import { TextInputDialogComponent } from './text-input-dialog/text-input-dialog.component';
|
||||
import { NumberInputDialogComponent } from './number-input-dialog/number-input-dialog.component';
|
||||
import {
|
||||
FeedbackDialogComponent,
|
||||
FeedbackDialogData,
|
||||
@@ -16,6 +17,9 @@ export interface InjectDialogOptions {
|
||||
/** Optional title override for the dialog */
|
||||
title?: string;
|
||||
|
||||
/** Optional additional CSS classes to apply to the dialog */
|
||||
classList?: string[];
|
||||
|
||||
/** Optional width for the dialog */
|
||||
width?: string;
|
||||
|
||||
@@ -81,6 +85,10 @@ export function injectDialog<C extends DialogContentDirective<any, any>>(
|
||||
provide: DIALOG_TITLE,
|
||||
useValue: openOptions?.title ?? injectOptions?.title,
|
||||
},
|
||||
{
|
||||
provide: DIALOG_CLASS_LIST,
|
||||
useValue: openOptions?.classList ?? injectOptions?.classList ?? [],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
@@ -119,6 +127,13 @@ export const injectMessageDialog = () => injectDialog(MessageDialogComponent);
|
||||
export const injectTextInputDialog = () =>
|
||||
injectDialog(TextInputDialogComponent);
|
||||
|
||||
/**
|
||||
* Convenience function that returns a pre-configured NumberInputDialog injector
|
||||
* @returns A function to open a number input dialog
|
||||
*/
|
||||
export const injectNumberInputDialog = () =>
|
||||
injectDialog(NumberInputDialogComponent);
|
||||
|
||||
/**
|
||||
* Convenience function that returns a pre-configured FeedbackDialog injector
|
||||
* @returns A function to open a feedback dialog
|
||||
@@ -129,5 +144,6 @@ export const injectFeedbackDialog = (
|
||||
injectDialog(FeedbackDialogComponent, {
|
||||
disableClose: false,
|
||||
minWidth: '20rem',
|
||||
classList: ['gap-0'],
|
||||
...options,
|
||||
});
|
||||
|
||||
@@ -16,3 +16,11 @@ export const DIALOG_TITLE = new InjectionToken<string | undefined>(
|
||||
export const DIALOG_CONTENT = new InjectionToken<ComponentType<unknown>>(
|
||||
'DIALOG_CONTENT',
|
||||
);
|
||||
|
||||
/**
|
||||
* Injection token for providing additional CSS classes to the dialog
|
||||
* Allows customization of dialog appearance through external styles
|
||||
*/
|
||||
export const DIALOG_CLASS_LIST = new InjectionToken<string[]>(
|
||||
'DIALOG_CLASS_LIST',
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user