mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
Merged PR 1879: Warenbegleitschein Übersicht und Details
Related work items: #5137, #5138
This commit is contained in:
7
libs/ui/bullet-list/README.md
Normal file
7
libs/ui/bullet-list/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# ui-bullet-list
|
||||
|
||||
This library was generated with [Nx](https://nx.dev).
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `nx test ui-bullet-list` to execute the unit tests.
|
||||
34
libs/ui/bullet-list/eslint.config.cjs
Normal file
34
libs/ui/bullet-list/eslint.config.cjs
Normal file
@@ -0,0 +1,34 @@
|
||||
const nx = require('@nx/eslint-plugin');
|
||||
const baseConfig = require('../../../eslint.config.js');
|
||||
|
||||
module.exports = [
|
||||
...baseConfig,
|
||||
...nx.configs['flat/angular'],
|
||||
...nx.configs['flat/angular-template'],
|
||||
{
|
||||
files: ['**/*.ts'],
|
||||
rules: {
|
||||
'@angular-eslint/directive-selector': [
|
||||
'error',
|
||||
{
|
||||
type: 'attribute',
|
||||
prefix: 'ui',
|
||||
style: 'camelCase',
|
||||
},
|
||||
],
|
||||
'@angular-eslint/component-selector': [
|
||||
'error',
|
||||
{
|
||||
type: 'element',
|
||||
prefix: 'ui',
|
||||
style: 'kebab-case',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['**/*.html'],
|
||||
// Override or add rules here
|
||||
rules: {},
|
||||
},
|
||||
];
|
||||
20
libs/ui/bullet-list/project.json
Normal file
20
libs/ui/bullet-list/project.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "ui-bullet-list",
|
||||
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "libs/ui/bullet-list/src",
|
||||
"prefix": "ui",
|
||||
"projectType": "library",
|
||||
"tags": [],
|
||||
"targets": {
|
||||
"test": {
|
||||
"executor": "@nx/vite:test",
|
||||
"outputs": ["{options.reportsDirectory}"],
|
||||
"options": {
|
||||
"reportsDirectory": "../../../coverage/libs/ui/bullet-list"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint"
|
||||
}
|
||||
}
|
||||
}
|
||||
11
libs/ui/bullet-list/src/bullet-list.scss
Normal file
11
libs/ui/bullet-list/src/bullet-list.scss
Normal file
@@ -0,0 +1,11 @@
|
||||
.ui-bullet-list {
|
||||
@apply flex flex-col gap-2 items-start shrink-0;
|
||||
}
|
||||
|
||||
.ui-bullet-list-item {
|
||||
@apply text-isa-secondary-900 isa-text-body-2-bold flex items-center gap-1;
|
||||
|
||||
ng-icon {
|
||||
@apply text-isa-neutral-900;
|
||||
}
|
||||
}
|
||||
6
libs/ui/bullet-list/src/index.ts
Normal file
6
libs/ui/bullet-list/src/index.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { BulletListComponent } from './lib/bullet-list.component';
|
||||
import { BulletListItemComponent } from './lib/bullet-list-item.component';
|
||||
|
||||
export const UiBulletList = [BulletListComponent, BulletListItemComponent];
|
||||
|
||||
export { BulletListComponent, BulletListItemComponent };
|
||||
30
libs/ui/bullet-list/src/lib/bullet-list-item.component.ts
Normal file
30
libs/ui/bullet-list/src/lib/bullet-list-item.component.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
computed,
|
||||
inject,
|
||||
input,
|
||||
} from '@angular/core';
|
||||
import { NgIcon } from '@ng-icons/core';
|
||||
import { BulletListComponent } from './bullet-list.component';
|
||||
|
||||
@Component({
|
||||
selector: 'ui-bullet-list-item',
|
||||
template: `<ng-icon [name]="iconName()" size="1.5rem"></ng-icon>
|
||||
<ng-content></ng-content>`,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: true,
|
||||
imports: [NgIcon],
|
||||
host: {
|
||||
class: 'ui-bullet-list-item',
|
||||
},
|
||||
})
|
||||
export class BulletListItemComponent {
|
||||
#bulletList = inject(BulletListComponent, { optional: true, host: true });
|
||||
|
||||
icon = input<string | undefined>();
|
||||
|
||||
iconName = computed(() => {
|
||||
return this.icon() ?? this.#bulletList?.icon();
|
||||
});
|
||||
}
|
||||
18
libs/ui/bullet-list/src/lib/bullet-list.component.ts
Normal file
18
libs/ui/bullet-list/src/lib/bullet-list.component.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { ChangeDetectionStrategy, Component, input } from '@angular/core';
|
||||
import { provideIcons } from '@ng-icons/core';
|
||||
import { isaActionChevronRight } from '@isa/icons';
|
||||
|
||||
@Component({
|
||||
selector: 'ui-bullet-list',
|
||||
template: `<ng-content></ng-content>`,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: true,
|
||||
imports: [],
|
||||
providers: [provideIcons({ isaActionChevronRight })],
|
||||
host: {
|
||||
class: 'ui-bullet-list',
|
||||
},
|
||||
})
|
||||
export class BulletListComponent {
|
||||
icon = input<string>('isaActionChevronRight');
|
||||
}
|
||||
13
libs/ui/bullet-list/src/test-setup.ts
Normal file
13
libs/ui/bullet-list/src/test-setup.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import '@angular/compiler';
|
||||
import '@analogjs/vitest-angular/setup-zone';
|
||||
|
||||
import {
|
||||
BrowserTestingModule,
|
||||
platformBrowserTesting,
|
||||
} from '@angular/platform-browser/testing';
|
||||
import { getTestBed } from '@angular/core/testing';
|
||||
|
||||
getTestBed().initTestEnvironment(
|
||||
BrowserTestingModule,
|
||||
platformBrowserTesting(),
|
||||
);
|
||||
30
libs/ui/bullet-list/tsconfig.json
Normal file
30
libs/ui/bullet-list/tsconfig.json
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"importHelpers": true,
|
||||
"moduleResolution": "bundler",
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"module": "preserve"
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"enableI18nLegacyMessageIdFormat": false,
|
||||
"strictInjectionParameters": true,
|
||||
"strictInputAccessModifiers": true,
|
||||
"typeCheckHostBindings": true,
|
||||
"strictTemplates": true
|
||||
},
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.spec.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
27
libs/ui/bullet-list/tsconfig.lib.json
Normal file
27
libs/ui/bullet-list/tsconfig.lib.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../../dist/out-tsc",
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"inlineSources": true,
|
||||
"types": []
|
||||
},
|
||||
"exclude": [
|
||||
"src/**/*.spec.ts",
|
||||
"src/test-setup.ts",
|
||||
"jest.config.ts",
|
||||
"src/**/*.test.ts",
|
||||
"vite.config.ts",
|
||||
"vite.config.mts",
|
||||
"vitest.config.ts",
|
||||
"vitest.config.mts",
|
||||
"src/**/*.test.tsx",
|
||||
"src/**/*.spec.tsx",
|
||||
"src/**/*.test.js",
|
||||
"src/**/*.spec.js",
|
||||
"src/**/*.test.jsx",
|
||||
"src/**/*.spec.jsx"
|
||||
],
|
||||
"include": ["src/**/*.ts"]
|
||||
}
|
||||
29
libs/ui/bullet-list/tsconfig.spec.json
Normal file
29
libs/ui/bullet-list/tsconfig.spec.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../../dist/out-tsc",
|
||||
"types": [
|
||||
"vitest/globals",
|
||||
"vitest/importMeta",
|
||||
"vite/client",
|
||||
"node",
|
||||
"vitest"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"vite.config.ts",
|
||||
"vite.config.mts",
|
||||
"vitest.config.ts",
|
||||
"vitest.config.mts",
|
||||
"src/**/*.test.ts",
|
||||
"src/**/*.spec.ts",
|
||||
"src/**/*.test.tsx",
|
||||
"src/**/*.spec.tsx",
|
||||
"src/**/*.test.js",
|
||||
"src/**/*.spec.js",
|
||||
"src/**/*.test.jsx",
|
||||
"src/**/*.spec.jsx",
|
||||
"src/**/*.d.ts"
|
||||
],
|
||||
"files": ["src/test-setup.ts"]
|
||||
}
|
||||
27
libs/ui/bullet-list/vite.config.mts
Normal file
27
libs/ui/bullet-list/vite.config.mts
Normal file
@@ -0,0 +1,27 @@
|
||||
/// <reference types='vitest' />
|
||||
import { defineConfig } from 'vite';
|
||||
import angular from '@analogjs/vite-plugin-angular';
|
||||
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
|
||||
import { nxCopyAssetsPlugin } from '@nx/vite/plugins/nx-copy-assets.plugin';
|
||||
|
||||
export default defineConfig(() => ({
|
||||
root: __dirname,
|
||||
cacheDir: '../../../node_modules/.vite/libs/ui/bullet-list',
|
||||
plugins: [angular(), nxViteTsPaths(), nxCopyAssetsPlugin(['*.md'])],
|
||||
// Uncomment this if you are using workers.
|
||||
// worker: {
|
||||
// plugins: [ nxViteTsPaths() ],
|
||||
// },
|
||||
test: {
|
||||
watch: false,
|
||||
globals: true,
|
||||
environment: 'jsdom',
|
||||
include: ['{src,tests}/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
||||
setupFiles: ['src/test-setup.ts'],
|
||||
reporters: ['default'],
|
||||
coverage: {
|
||||
reportsDirectory: '../../../coverage/libs/ui/bullet-list',
|
||||
provider: 'v8' as const,
|
||||
},
|
||||
},
|
||||
}));
|
||||
@@ -1,81 +1,81 @@
|
||||
import {
|
||||
Directive,
|
||||
ViewContainerRef,
|
||||
TemplateRef,
|
||||
inject,
|
||||
input,
|
||||
effect,
|
||||
ComponentRef,
|
||||
untracked,
|
||||
EmbeddedViewRef,
|
||||
} from '@angular/core';
|
||||
import { SkeletonLoaderComponent } from './skeleton-loader.component';
|
||||
|
||||
/**
|
||||
* Structural directive that conditionally replaces its content with a skeleton loader.
|
||||
*
|
||||
* @example
|
||||
* <div *uiSkeletonLoader="isLoading">Content to hide while loading</div>
|
||||
*
|
||||
* @example
|
||||
* <div *uiSkeletonLoader="isLoading; width: '100px'; height: '20px'">Content</div>
|
||||
*/
|
||||
@Directive({
|
||||
selector: '[uiSkeletonLoader]',
|
||||
})
|
||||
export class SkeletonLoaderDirective {
|
||||
#viewContainerRef = inject(ViewContainerRef);
|
||||
#templateRef = inject(TemplateRef);
|
||||
|
||||
private componentRef: ComponentRef<SkeletonLoaderComponent> | null = null;
|
||||
private embeddedViewRef: EmbeddedViewRef<unknown> | null = null;
|
||||
|
||||
uiSkeletonLoader = input<boolean>(false);
|
||||
|
||||
uiSkeletonLoaderWidth = input<string | undefined>(undefined);
|
||||
|
||||
uiSkeletonLoaderHeight = input<string | undefined>(undefined);
|
||||
|
||||
render = effect(() => {
|
||||
const condition = this.uiSkeletonLoader();
|
||||
|
||||
if (condition && !this.componentRef) {
|
||||
// Create the skeleton loader when condition is true and view isn't created
|
||||
this.#viewContainerRef.clear();
|
||||
this.componentRef = this.#viewContainerRef.createComponent(
|
||||
SkeletonLoaderComponent,
|
||||
);
|
||||
|
||||
untracked(() => {
|
||||
this.applyStyles();
|
||||
});
|
||||
|
||||
this.embeddedViewRef = null; // Clear the embedded view reference
|
||||
} else if (!condition && !this.embeddedViewRef) {
|
||||
// Show original content when condition is false
|
||||
this.#viewContainerRef.clear();
|
||||
this.embeddedViewRef = this.#viewContainerRef.createEmbeddedView(
|
||||
this.#templateRef,
|
||||
);
|
||||
|
||||
this.componentRef = null; // Clear the component reference
|
||||
}
|
||||
});
|
||||
|
||||
updateStyles = effect(() => {
|
||||
this.applyStyles();
|
||||
});
|
||||
|
||||
applyStyles() {
|
||||
if (this.componentRef) {
|
||||
const width = this.uiSkeletonLoaderWidth() || '100%';
|
||||
const height = this.uiSkeletonLoaderHeight() || '100%';
|
||||
const element: HTMLElement | undefined =
|
||||
this.componentRef?.location?.nativeElement;
|
||||
if (element) {
|
||||
element.style.width = width;
|
||||
element.style.height = height;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
import {
|
||||
Directive,
|
||||
ViewContainerRef,
|
||||
TemplateRef,
|
||||
inject,
|
||||
input,
|
||||
effect,
|
||||
ComponentRef,
|
||||
untracked,
|
||||
EmbeddedViewRef,
|
||||
} from '@angular/core';
|
||||
import { SkeletonLoaderComponent } from './skeleton-loader.component';
|
||||
|
||||
/**
|
||||
* Structural directive that conditionally replaces its content with a skeleton loader.
|
||||
*
|
||||
* @example
|
||||
* <div *uiSkeletonLoader="isLoading">Content to hide while loading</div>
|
||||
*
|
||||
* @example
|
||||
* <div *uiSkeletonLoader="isLoading; width: '100px'; height: '20px'">Content</div>
|
||||
*/
|
||||
@Directive({
|
||||
selector: '[uiSkeletonLoader]',
|
||||
})
|
||||
export class SkeletonLoaderDirective {
|
||||
#viewContainerRef = inject(ViewContainerRef);
|
||||
#templateRef = inject(TemplateRef);
|
||||
|
||||
private componentRef: ComponentRef<SkeletonLoaderComponent> | null = null;
|
||||
private embeddedViewRef: EmbeddedViewRef<unknown> | null = null;
|
||||
|
||||
uiSkeletonLoader = input<boolean>(false);
|
||||
|
||||
uiSkeletonLoaderWidth = input<string | undefined>(undefined);
|
||||
|
||||
uiSkeletonLoaderHeight = input<string | undefined>(undefined);
|
||||
|
||||
render = effect(() => {
|
||||
const condition = this.uiSkeletonLoader();
|
||||
|
||||
if (condition && !this.componentRef) {
|
||||
// Create the skeleton loader when condition is true and view isn't created
|
||||
this.#viewContainerRef.clear();
|
||||
this.componentRef = this.#viewContainerRef.createComponent(
|
||||
SkeletonLoaderComponent,
|
||||
);
|
||||
|
||||
untracked(() => {
|
||||
this.applyStyles();
|
||||
});
|
||||
|
||||
this.embeddedViewRef = null; // Clear the embedded view reference
|
||||
} else if (!condition && !this.embeddedViewRef) {
|
||||
// Show original content when condition is false
|
||||
this.#viewContainerRef.clear();
|
||||
this.embeddedViewRef = this.#viewContainerRef.createEmbeddedView(
|
||||
this.#templateRef,
|
||||
);
|
||||
|
||||
this.componentRef = null; // Clear the component reference
|
||||
}
|
||||
});
|
||||
|
||||
updateStyles = effect(() => {
|
||||
this.applyStyles();
|
||||
});
|
||||
|
||||
applyStyles() {
|
||||
if (this.componentRef) {
|
||||
const width = this.uiSkeletonLoaderWidth() || 'inherit';
|
||||
const height = this.uiSkeletonLoaderHeight() || 'inherit';
|
||||
const element: HTMLElement | undefined =
|
||||
this.componentRef?.location?.nativeElement;
|
||||
if (element) {
|
||||
element.style.width = width;
|
||||
element.style.height = height;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user