mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
Merged PR 2055: feature(ui-label, ahf, warenausgabe, customer-orders): Added and Updated Labe...
feature(ui-label, ahf, warenausgabe, customer-orders): Added and Updated Label Library and Label to the Views, Updated Positioning Ref: #5479
This commit is contained in:
committed by
Lorenz Hilpert
parent
a5bb8b2895
commit
41630d5d7c
83
libs/ui/notice/README.md
Normal file
83
libs/ui/notice/README.md
Normal file
@@ -0,0 +1,83 @@
|
||||
# @isa/ui/notice
|
||||
|
||||
A notice component for displaying prominent notifications and alerts with configurable priority levels.
|
||||
|
||||
## Installation
|
||||
|
||||
```typescript
|
||||
import { NoticeComponent, NoticePriority } from '@isa/ui/notice';
|
||||
```
|
||||
|
||||
## Component
|
||||
|
||||
### NoticeComponent
|
||||
|
||||
**Figma:** [ISA Design System - Notice](https://www.figma.com/design/bK0IW6akzSjHxmMwQfVPRW/ISA-DESIGN-SYSTEM?node-id=2551-4407&m=dev)
|
||||
|
||||
## Priority Levels
|
||||
|
||||
| Priority | Description | Background |
|
||||
| -------- | ---------------- | ---------------- |
|
||||
| `high` | Most prominent | Secondary color |
|
||||
| `medium` | Moderate | Neutral color |
|
||||
| `low` | Subtle (no fill) | Transparent |
|
||||
|
||||
## Usage
|
||||
|
||||
```html
|
||||
<!-- High priority (default) -->
|
||||
<ui-notice>Action Required</ui-notice>
|
||||
|
||||
<!-- Medium priority -->
|
||||
<ui-notice [priority]="NoticePriority.Medium">Secondary message</ui-notice>
|
||||
|
||||
<!-- Low priority -->
|
||||
<ui-notice priority="low">Info message</ui-notice>
|
||||
```
|
||||
|
||||
### Component Example
|
||||
|
||||
```typescript
|
||||
import { Component } from '@angular/core';
|
||||
import { NoticeComponent, NoticePriority } from '@isa/ui/notice';
|
||||
|
||||
@Component({
|
||||
selector: 'app-alert',
|
||||
template: `
|
||||
<ui-notice [priority]="NoticePriority.High">Action Required</ui-notice>
|
||||
<ui-notice [priority]="NoticePriority.Medium">Limited Stock</ui-notice>
|
||||
`,
|
||||
imports: [NoticeComponent],
|
||||
})
|
||||
export class AlertComponent {
|
||||
NoticePriority = NoticePriority;
|
||||
}
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
| Input | Type | Default | Description |
|
||||
| ---------- | ---------------- | -------------------- | --------------------------------- |
|
||||
| `priority` | `NoticePriority` | `NoticePriority.High`| Visual priority level |
|
||||
|
||||
## CSS Classes
|
||||
|
||||
- `.ui-notice` - Base class
|
||||
- `.ui-notice--high` - High priority (secondary background)
|
||||
- `.ui-notice--medium` - Medium priority (neutral background)
|
||||
- `.ui-notice--low` - Low priority (transparent)
|
||||
|
||||
## Accessibility
|
||||
|
||||
- `role="status"` - Indicates status information
|
||||
- E2E testing attributes (`data-what`, `data-which`)
|
||||
|
||||
## E2E Testing
|
||||
|
||||
```typescript
|
||||
// Select all notices
|
||||
page.locator('[data-what="notice"]');
|
||||
|
||||
// Select specific priority
|
||||
page.locator('[data-what="notice"][data-which="priority-high"]');
|
||||
```
|
||||
34
libs/ui/notice/eslint.config.cjs
Normal file
34
libs/ui/notice/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/notice/project.json
Normal file
20
libs/ui/notice/project.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "ui-notice",
|
||||
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "libs/ui/notice/src",
|
||||
"prefix": "ui",
|
||||
"projectType": "library",
|
||||
"tags": ["scope:ui", "type:ui"],
|
||||
"targets": {
|
||||
"test": {
|
||||
"executor": "@nx/vite:test",
|
||||
"outputs": ["{options.reportsDirectory}"],
|
||||
"options": {
|
||||
"reportsDirectory": "../../../coverage/libs/ui/notice"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint"
|
||||
}
|
||||
}
|
||||
}
|
||||
2
libs/ui/notice/src/index.ts
Normal file
2
libs/ui/notice/src/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from './lib/notice/notice.component';
|
||||
export * from './lib/notice/types';
|
||||
16
libs/ui/notice/src/lib/notice/_notice.scss
Normal file
16
libs/ui/notice/src/lib/notice/_notice.scss
Normal file
@@ -0,0 +1,16 @@
|
||||
.ui-notice {
|
||||
@apply inline-flex flex-col items-start;
|
||||
@apply p-2 min-w-48 rounded-lg isa-text-body-2-bold text-isa-neutral-900;
|
||||
}
|
||||
|
||||
.ui-notice--high {
|
||||
@apply bg-isa-secondary-100;
|
||||
}
|
||||
|
||||
.ui-notice--medium {
|
||||
@apply bg-isa-neutral-100;
|
||||
}
|
||||
|
||||
.ui-notice--low {
|
||||
@apply bg-transparent;
|
||||
}
|
||||
1
libs/ui/notice/src/lib/notice/notice.component.html
Normal file
1
libs/ui/notice/src/lib/notice/notice.component.html
Normal file
@@ -0,0 +1 @@
|
||||
<ng-content></ng-content>
|
||||
128
libs/ui/notice/src/lib/notice/notice.component.spec.ts
Normal file
128
libs/ui/notice/src/lib/notice/notice.component.spec.ts
Normal file
@@ -0,0 +1,128 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { NoticeComponent } from './notice.component';
|
||||
import { NoticePriority } from './types';
|
||||
|
||||
describe('NoticeComponent', () => {
|
||||
let component: NoticeComponent;
|
||||
let fixture: ComponentFixture<NoticeComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [NoticeComponent],
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(NoticeComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
describe('Component Setup and Initialization', () => {
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should have default priority as high', () => {
|
||||
expect(component.priority()).toBe(NoticePriority.High);
|
||||
});
|
||||
|
||||
it('should accept medium priority', () => {
|
||||
fixture.componentRef.setInput('priority', NoticePriority.Medium);
|
||||
fixture.detectChanges();
|
||||
expect(component.priority()).toBe(NoticePriority.Medium);
|
||||
});
|
||||
|
||||
it('should accept low priority', () => {
|
||||
fixture.componentRef.setInput('priority', NoticePriority.Low);
|
||||
fixture.detectChanges();
|
||||
expect(component.priority()).toBe(NoticePriority.Low);
|
||||
});
|
||||
|
||||
it('should have correct CSS class for high priority', () => {
|
||||
expect(component.priorityClass()).toBe('ui-notice--high');
|
||||
});
|
||||
|
||||
it('should have correct CSS class for medium priority', () => {
|
||||
fixture.componentRef.setInput('priority', NoticePriority.Medium);
|
||||
fixture.detectChanges();
|
||||
expect(component.priorityClass()).toBe('ui-notice--medium');
|
||||
});
|
||||
|
||||
it('should have correct CSS class for low priority', () => {
|
||||
fixture.componentRef.setInput('priority', NoticePriority.Low);
|
||||
fixture.detectChanges();
|
||||
expect(component.priorityClass()).toBe('ui-notice--low');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Template Rendering', () => {
|
||||
it('should display content with high priority classes', () => {
|
||||
const hostElement = fixture.debugElement.nativeElement;
|
||||
expect(hostElement.classList.contains('ui-notice')).toBe(true);
|
||||
expect(hostElement.classList.contains('ui-notice--high')).toBe(true);
|
||||
});
|
||||
|
||||
it('should display content with medium priority classes', () => {
|
||||
fixture.componentRef.setInput('priority', NoticePriority.Medium);
|
||||
fixture.detectChanges();
|
||||
|
||||
const hostElement = fixture.debugElement.nativeElement;
|
||||
expect(hostElement.classList.contains('ui-notice')).toBe(true);
|
||||
expect(hostElement.classList.contains('ui-notice--medium')).toBe(true);
|
||||
});
|
||||
|
||||
it('should display content with low priority classes', () => {
|
||||
fixture.componentRef.setInput('priority', NoticePriority.Low);
|
||||
fixture.detectChanges();
|
||||
|
||||
const hostElement = fixture.debugElement.nativeElement;
|
||||
expect(hostElement.classList.contains('ui-notice')).toBe(true);
|
||||
expect(hostElement.classList.contains('ui-notice--low')).toBe(true);
|
||||
});
|
||||
|
||||
it('should update classes when priority changes', () => {
|
||||
const hostElement = fixture.debugElement.nativeElement;
|
||||
|
||||
expect(hostElement.classList.contains('ui-notice--high')).toBe(true);
|
||||
expect(hostElement.classList.contains('ui-notice--medium')).toBe(false);
|
||||
|
||||
fixture.componentRef.setInput('priority', NoticePriority.Medium);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(hostElement.classList.contains('ui-notice--high')).toBe(false);
|
||||
expect(hostElement.classList.contains('ui-notice--medium')).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Component Structure', () => {
|
||||
it('should have proper host class binding', () => {
|
||||
const hostElement = fixture.debugElement.nativeElement;
|
||||
expect(hostElement.classList.contains('ui-notice')).toBe(true);
|
||||
});
|
||||
|
||||
it('should have E2E testing attributes', () => {
|
||||
const hostElement = fixture.debugElement.nativeElement;
|
||||
expect(hostElement.getAttribute('data-what')).toBe('notice');
|
||||
expect(hostElement.getAttribute('data-which')).toBe('priority-high');
|
||||
});
|
||||
|
||||
it('should have correct data-which for different priorities', () => {
|
||||
const hostElement = fixture.debugElement.nativeElement;
|
||||
|
||||
expect(hostElement.getAttribute('data-which')).toBe('priority-high');
|
||||
|
||||
fixture.componentRef.setInput('priority', NoticePriority.Medium);
|
||||
fixture.detectChanges();
|
||||
expect(hostElement.getAttribute('data-which')).toBe('priority-medium');
|
||||
|
||||
fixture.componentRef.setInput('priority', NoticePriority.Low);
|
||||
fixture.detectChanges();
|
||||
expect(hostElement.getAttribute('data-which')).toBe('priority-low');
|
||||
});
|
||||
|
||||
it('should have accessibility role', () => {
|
||||
const hostElement = fixture.debugElement.nativeElement;
|
||||
expect(hostElement.getAttribute('role')).toBe('status');
|
||||
});
|
||||
});
|
||||
});
|
||||
41
libs/ui/notice/src/lib/notice/notice.component.ts
Normal file
41
libs/ui/notice/src/lib/notice/notice.component.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
computed,
|
||||
input,
|
||||
ViewEncapsulation,
|
||||
} from '@angular/core';
|
||||
import { NoticePriority } from './types';
|
||||
|
||||
/**
|
||||
* Notice component for displaying prominent notifications and alerts.
|
||||
* Supports high, medium, and low priority variants.
|
||||
*
|
||||
* @example
|
||||
* ```html
|
||||
* <ui-notice>Important message</ui-notice>
|
||||
* <ui-notice [priority]="NoticePriority.Medium">Secondary message</ui-notice>
|
||||
* <ui-notice [priority]="NoticePriority.Low">Info message</ui-notice>
|
||||
* ```
|
||||
*
|
||||
* @see https://www.figma.com/design/bK0IW6akzSjHxmMwQfVPRW/ISA-DESIGN-SYSTEM?node-id=2551-4407&m=dev
|
||||
*/
|
||||
@Component({
|
||||
selector: 'ui-notice',
|
||||
template: '<ng-content></ng-content>',
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
host: {
|
||||
'[class]': '["ui-notice", priorityClass()]',
|
||||
'data-what': 'notice',
|
||||
'[attr.data-which]': '"priority-" + priority()',
|
||||
'role': 'status',
|
||||
},
|
||||
})
|
||||
export class NoticeComponent {
|
||||
/** The priority level of the notice (high, medium, low). */
|
||||
priority = input<NoticePriority>(NoticePriority.High);
|
||||
|
||||
/** A computed CSS class based on the current priority. */
|
||||
priorityClass = computed(() => `ui-notice--${this.priority()}`);
|
||||
}
|
||||
7
libs/ui/notice/src/lib/notice/types.ts
Normal file
7
libs/ui/notice/src/lib/notice/types.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export const NoticePriority = {
|
||||
High: 'high',
|
||||
Medium: 'medium',
|
||||
Low: 'low',
|
||||
} as const;
|
||||
|
||||
export type NoticePriority = (typeof NoticePriority)[keyof typeof NoticePriority];
|
||||
1
libs/ui/notice/src/notice.scss
Normal file
1
libs/ui/notice/src/notice.scss
Normal file
@@ -0,0 +1 @@
|
||||
@use "lib/notice/notice";
|
||||
13
libs/ui/notice/src/test-setup.ts
Normal file
13
libs/ui/notice/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/notice/tsconfig.json
Normal file
30
libs/ui/notice/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/notice/tsconfig.lib.json
Normal file
27
libs/ui/notice/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/notice/tsconfig.spec.json
Normal file
29
libs/ui/notice/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"]
|
||||
}
|
||||
29
libs/ui/notice/vite.config.mts
Normal file
29
libs/ui/notice/vite.config.mts
Normal file
@@ -0,0 +1,29 @@
|
||||
/// <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
|
||||
// @ts-expect-error - Vitest reporter tuple types have complex inference issues
|
||||
defineConfig(() => ({
|
||||
root: __dirname,
|
||||
cacheDir: '../../../node_modules/.vite/libs/ui/notice',
|
||||
plugins: [angular(), nxViteTsPaths(), nxCopyAssetsPlugin(['*.md'])],
|
||||
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',
|
||||
['junit', { outputFile: '../../../testresults/junit-ui-notice.xml' }],
|
||||
],
|
||||
coverage: {
|
||||
reportsDirectory: '../../../coverage/libs/ui/notice',
|
||||
provider: 'v8' as const,
|
||||
reporter: ['text', 'cobertura'],
|
||||
},
|
||||
},
|
||||
}));
|
||||
Reference in New Issue
Block a user