mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 14:32:10 +01:00
feat: refactor return feature components; remove deprecated files and implement new search bar input
This commit is contained in:
@@ -43,7 +43,7 @@ const meta: Meta<UiSearchBarComponentInputs> = {
|
||||
render: (args) => ({
|
||||
props: { ...args, control: new FormControl(args.value) },
|
||||
template: `<ui-search-bar ${argsToTemplate(args, { exclude: ['placeholder', 'value', 'resetValue'] })}>
|
||||
<input [formControl]="control" type="text" uiSearchBarInput placeholder="${args.placeholder}" />
|
||||
<input [formControl]="control" type="text" placeholder="${args.placeholder}" />
|
||||
<ui-search-bar-clear value="${args.resetValue}"></ui-search-bar-clear>
|
||||
<button type="submit" uiIconButton color="brand">
|
||||
<ng-icon name="isaActionSearch"></ng-icon>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { inject } from '@angular/core';
|
||||
import { ProcessService } from './process.service';
|
||||
|
||||
export function injectActivatedProcess() {
|
||||
return inject(ProcessService).activatedProcess;
|
||||
}
|
||||
|
||||
export function injectActivatedProcessId() {
|
||||
return inject(ProcessService).activatedProcessId;
|
||||
}
|
||||
|
||||
export function injectActivatedProcess() {
|
||||
return inject(ProcessService).activatedProcess;
|
||||
}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
<h1 class="isa-typo-subtitle-1-regualr">Rückgabe starten</h1>
|
||||
<p class="isa-typo-body-regular text-center">
|
||||
Scannen Sie den QR-Code auf der Rechnung oder suchen Sie die Bestellung <br />
|
||||
via Rechnungsnummer, E-Mail-Adresse oder Kundennamen
|
||||
</p>
|
||||
@@ -1,21 +0,0 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { FeatureReturnPagesComponent } from './feature-return-pages.component';
|
||||
|
||||
describe('FeatureReturnPagesComponent', () => {
|
||||
let component: FeatureReturnPagesComponent;
|
||||
let fixture: ComponentFixture<FeatureReturnPagesComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [FeatureReturnPagesComponent],
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(FeatureReturnPagesComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,10 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
@Component({
|
||||
selector: 'lib-feature-return-pages',
|
||||
imports: [CommonModule],
|
||||
templateUrl: './feature-return-pages.component.html',
|
||||
styleUrl: './feature-return-pages.component.css',
|
||||
})
|
||||
export class FeatureReturnPagesComponent {}
|
||||
@@ -0,0 +1,11 @@
|
||||
<h1 class="isa-text-subtitle-1-regular">Rückgabe starten</h1>
|
||||
<p class="isa-text-body-1-regular text-center">
|
||||
Scannen Sie den QR-Code auf der Rechnung oder suchen Sie die Bestellung <br />
|
||||
via Rechnungsnummer, E-Mail-Adresse oder Kundennamen
|
||||
</p>
|
||||
|
||||
<filter-search-bar-input
|
||||
groupName="main"
|
||||
inputKey="qs"
|
||||
(search)="onSearch()"
|
||||
></filter-search-bar-input>
|
||||
@@ -0,0 +1,7 @@
|
||||
:host {
|
||||
display: flex;
|
||||
padding: 3rem 1.5rem 0rem 1.5rem;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 2rem;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
|
||||
import { ReturnSearchService } from '@feature/return/services';
|
||||
import { injectActivatedProcessId } from '@isa/core/process';
|
||||
import { FilterService, SearchBarInputComponent } from '@isa/shared/filter';
|
||||
|
||||
@Component({
|
||||
selector: 'lib-main-page',
|
||||
templateUrl: './main-page.component.html',
|
||||
styleUrls: ['./main-page.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: true,
|
||||
imports: [SearchBarInputComponent],
|
||||
})
|
||||
export class MainPageComponent {
|
||||
processId = injectActivatedProcessId();
|
||||
|
||||
filterService = inject(FilterService);
|
||||
|
||||
returnSearchService = inject(ReturnSearchService);
|
||||
|
||||
onSearch() {
|
||||
this.returnSearchService
|
||||
.search({
|
||||
filter: this.filterService.toParams(),
|
||||
})
|
||||
.subscribe();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import { inject } from '@angular/core';
|
||||
import { ResolveFn } from '@angular/router';
|
||||
import { ReturnSearchService } from '@feature/return/services';
|
||||
import { QuerySettingsDTO } from '@generated/swagger/oms-api';
|
||||
|
||||
export const querySettingsResolverFn: ResolveFn<QuerySettingsDTO> = () =>
|
||||
inject(ReturnSearchService).querySettings();
|
||||
@@ -0,0 +1 @@
|
||||
<router-outlet></router-outlet>
|
||||
@@ -0,0 +1,7 @@
|
||||
:host {
|
||||
display: flex;
|
||||
padding: 3rem 1.5rem 0rem 1.5rem;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 2rem;
|
||||
}
|
||||
12
libs/feature/return/pages/src/lib/return-pages.component.ts
Normal file
12
libs/feature/return/pages/src/lib/return-pages.component.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { Component, inject } from '@angular/core';
|
||||
import { ActivatedRoute, RouterOutlet } from '@angular/router';
|
||||
import { provideQuerySettings } from '@isa/shared/filter';
|
||||
|
||||
@Component({
|
||||
selector: 'lib-return-pages',
|
||||
imports: [RouterOutlet],
|
||||
templateUrl: './return-pages.component.html',
|
||||
styleUrl: './return-pages.component.scss',
|
||||
providers: [provideQuerySettings(() => inject(ActivatedRoute).snapshot.data['querySettings'])],
|
||||
})
|
||||
export class ReturnPagesComponent {}
|
||||
@@ -1,4 +1,13 @@
|
||||
import { Routes } from '@angular/router';
|
||||
import { FeatureReturnPagesComponent } from './feature-return-pages.component';
|
||||
import { ReturnPagesComponent } from './return-pages.component';
|
||||
import { querySettingsResolverFn } from './resolvers/query-settings.resolver-fn';
|
||||
import { MainPageComponent } from './main/main-page.component';
|
||||
|
||||
export const routes: Routes = [{ path: '', component: FeatureReturnPagesComponent }];
|
||||
export const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: ReturnPagesComponent,
|
||||
resolve: { querySettings: querySettingsResolverFn },
|
||||
children: [{ path: '', component: MainPageComponent }],
|
||||
},
|
||||
];
|
||||
|
||||
@@ -1 +1 @@
|
||||
export * from './lib/feature-return-services.component';
|
||||
export * from './lib/return-search.service';
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
<p>FeatureReturnServices works!</p>
|
||||
@@ -1,21 +0,0 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { FeatureReturnServicesComponent } from './feature-return-services.component';
|
||||
|
||||
describe('FeatureReturnServicesComponent', () => {
|
||||
let component: FeatureReturnServicesComponent;
|
||||
let fixture: ComponentFixture<FeatureReturnServicesComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [FeatureReturnServicesComponent],
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(FeatureReturnServicesComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,10 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
@Component({
|
||||
selector: 'lib-feature-return-services',
|
||||
imports: [CommonModule],
|
||||
templateUrl: './feature-return-services.component.html',
|
||||
styleUrl: './feature-return-services.component.css',
|
||||
})
|
||||
export class FeatureReturnServicesComponent {}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
export const QueryTokenSchema = z.object({
|
||||
filter: z.object({
|
||||
qs: z.string().optional(),
|
||||
}),
|
||||
skip: z.number().default(0),
|
||||
take: z.number().default(25),
|
||||
});
|
||||
@@ -0,0 +1,33 @@
|
||||
import { inject, Injectable } from '@angular/core';
|
||||
import { QuerySettingsDTO, QueryTokenDTO, ReceiptService } from '@generated/swagger/oms-api';
|
||||
import { map, Observable, throwError } from 'rxjs';
|
||||
import { z } from 'zod';
|
||||
import * as Schemas from './return-search.schemas';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ReturnSearchService {
|
||||
#receiptService = inject(ReceiptService);
|
||||
|
||||
querySettings(): Observable<QuerySettingsDTO> {
|
||||
return this.#receiptService.ReceiptQueryReceiptSettings().pipe(
|
||||
map((res) => {
|
||||
if (res.error || !res.result) {
|
||||
throw new Error('Failed to fetch query settings');
|
||||
}
|
||||
return res.result;
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
search(queryToken: z.input<typeof Schemas.QueryTokenSchema>): Observable<any> {
|
||||
try {
|
||||
queryToken = Schemas.QueryTokenSchema.parse(queryToken);
|
||||
} catch (error) {
|
||||
return throwError(() => error);
|
||||
}
|
||||
|
||||
return this.#receiptService.ReceiptQueryReceipt({
|
||||
queryToken,
|
||||
});
|
||||
}
|
||||
}
|
||||
22
libs/feature/return/services/src/lib/return-search.store.ts
Normal file
22
libs/feature/return/services/src/lib/return-search.store.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { signalStore, withMethods } from '@ngrx/signals';
|
||||
import {} from '@ngrx/operators';
|
||||
import { withEntities } from '@ngrx/signals/entities';
|
||||
import { pipe } from 'rxjs';
|
||||
|
||||
type ReturnSearuchState = {
|
||||
id: number;
|
||||
params: Record<string, string>;
|
||||
results: string[];
|
||||
hits: number;
|
||||
status: 'idle' | 'pending' | 'success' | 'error';
|
||||
error: string | null;
|
||||
};
|
||||
|
||||
export const ReturnSearchStore = signalStore(
|
||||
{ providedIn: 'root' },
|
||||
withEntities<ReturnSearuchState>(),
|
||||
// withMethods((store) => ({
|
||||
// search: rxMethod<{ id: number; params: Record<string, string> }>(pipe()),
|
||||
// paging: rxMethod<{ id: number }>(pipe()),
|
||||
// })),
|
||||
);
|
||||
7
libs/shared/filter/README.md
Normal file
7
libs/shared/filter/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# shared-filter
|
||||
|
||||
This library was generated with [Nx](https://nx.dev).
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `nx test shared-filter` to execute the unit tests.
|
||||
34
libs/shared/filter/eslint.config.mjs
Normal file
34
libs/shared/filter/eslint.config.mjs
Normal file
@@ -0,0 +1,34 @@
|
||||
import nx from '@nx/eslint-plugin';
|
||||
import baseConfig from '../../../eslint.config.mjs';
|
||||
|
||||
export default [
|
||||
...baseConfig,
|
||||
...nx.configs['flat/angular'],
|
||||
...nx.configs['flat/angular-template'],
|
||||
{
|
||||
files: ['**/*.ts'],
|
||||
rules: {
|
||||
'@angular-eslint/directive-selector': [
|
||||
'error',
|
||||
{
|
||||
type: 'attribute',
|
||||
prefix: 'filter',
|
||||
style: 'camelCase',
|
||||
},
|
||||
],
|
||||
'@angular-eslint/component-selector': [
|
||||
'error',
|
||||
{
|
||||
type: 'element',
|
||||
prefix: 'filter',
|
||||
style: 'kebab-case',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['**/*.html'],
|
||||
// Override or add rules here
|
||||
rules: {},
|
||||
},
|
||||
];
|
||||
21
libs/shared/filter/jest.config.ts
Normal file
21
libs/shared/filter/jest.config.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
export default {
|
||||
displayName: 'shared-filter',
|
||||
preset: '../../../jest.preset.js',
|
||||
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
|
||||
coverageDirectory: '../../../coverage/libs/shared/filter',
|
||||
transform: {
|
||||
'^.+\\.(ts|mjs|js|html)$': [
|
||||
'jest-preset-angular',
|
||||
{
|
||||
tsconfig: '<rootDir>/tsconfig.spec.json',
|
||||
stringifyContentPathRegex: '\\.(html|svg)$',
|
||||
},
|
||||
],
|
||||
},
|
||||
transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'],
|
||||
snapshotSerializers: [
|
||||
'jest-preset-angular/build/serializers/no-ng-attributes',
|
||||
'jest-preset-angular/build/serializers/ng-snapshot',
|
||||
'jest-preset-angular/build/serializers/html-comment',
|
||||
],
|
||||
};
|
||||
20
libs/shared/filter/project.json
Normal file
20
libs/shared/filter/project.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "shared-filter",
|
||||
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "libs/shared/filter/src",
|
||||
"prefix": "shared",
|
||||
"projectType": "library",
|
||||
"tags": [],
|
||||
"targets": {
|
||||
"test": {
|
||||
"executor": "@nx/jest:jest",
|
||||
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
|
||||
"options": {
|
||||
"jestConfig": "libs/shared/filter/jest.config.ts"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint"
|
||||
}
|
||||
}
|
||||
}
|
||||
3
libs/shared/filter/src/index.ts
Normal file
3
libs/shared/filter/src/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export * from './lib/core';
|
||||
export * from './lib/inputs';
|
||||
export * from './lib/types';
|
||||
57
libs/shared/filter/src/lib/core/filter.service.ts
Normal file
57
libs/shared/filter/src/lib/core/filter.service.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import { inject, Injectable, InjectionToken, Provider } from '@angular/core';
|
||||
import { InputType, QuerySettingsDTO } from '../types';
|
||||
import { patchState, signalState } from '@ngrx/signals';
|
||||
import { mapToFilter } from './mappings';
|
||||
|
||||
export const QUERY_SETTINGS = new InjectionToken<QuerySettingsDTO>('QuerySettings');
|
||||
|
||||
export function provideQuerySettings(factory: () => QuerySettingsDTO): Provider[] {
|
||||
return [{ provide: QUERY_SETTINGS, useFactory: factory }, FilterService];
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class FilterService {
|
||||
readonly settings = inject(QUERY_SETTINGS);
|
||||
|
||||
#state = signalState(mapToFilter(this.settings));
|
||||
|
||||
groups = this.#state.groups;
|
||||
|
||||
inputs = this.#state.inputs;
|
||||
|
||||
setInputValue(key: string, value: string | undefined): void {
|
||||
const inputs = this.inputs().map((input) => {
|
||||
if (input.key !== key) {
|
||||
return input;
|
||||
}
|
||||
|
||||
if (input.type === InputType.Text) {
|
||||
return { ...input, value };
|
||||
}
|
||||
|
||||
throw new Error(`Input type not supported: ${input.type}`);
|
||||
});
|
||||
|
||||
patchState(this.#state, { inputs });
|
||||
}
|
||||
|
||||
toParams(): Record<string, string> {
|
||||
const params: Record<string, string> = {};
|
||||
|
||||
for (const input of this.inputs()) {
|
||||
switch (input.type) {
|
||||
case InputType.Text:
|
||||
if (input.value) {
|
||||
params[input.key] = input.value;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
parseParams(params: Record<string, string>): void {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
}
|
||||
3
libs/shared/filter/src/lib/core/index.ts
Normal file
3
libs/shared/filter/src/lib/core/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export * from './filter.service';
|
||||
export * from './mappings';
|
||||
export * from './schemas';
|
||||
102
libs/shared/filter/src/lib/core/mappings.ts
Normal file
102
libs/shared/filter/src/lib/core/mappings.ts
Normal file
@@ -0,0 +1,102 @@
|
||||
import { InputDTO, InputGroupDTO, InputType, OptionDTO, QuerySettingsDTO } from '../types';
|
||||
import {
|
||||
CheckboxFilterInput,
|
||||
CheckboxFilterInputOption,
|
||||
CheckboxFilterInputOptionSchema,
|
||||
CheckboxFilterInputSchema,
|
||||
DateRangeFilterInput,
|
||||
DateRangeFilterInputSchema,
|
||||
Filter,
|
||||
FilterGroup,
|
||||
FilterGroupSchema,
|
||||
FilterInput,
|
||||
TextFilterInput,
|
||||
TextFilterInputSchema,
|
||||
} from './schemas';
|
||||
|
||||
export function mapToFilter(settings: QuerySettingsDTO): Filter {
|
||||
const filter: Filter = {
|
||||
groups: [],
|
||||
inputs: [],
|
||||
};
|
||||
|
||||
const groups = [...settings.filter, ...settings.input];
|
||||
|
||||
for (const group of groups) {
|
||||
filter.groups.push(mapToFilterGroup(group));
|
||||
|
||||
for (const input of group.input) {
|
||||
filter.inputs.push(mapToFilterInput(group.group, input));
|
||||
}
|
||||
}
|
||||
|
||||
return filter;
|
||||
}
|
||||
|
||||
function mapToFilterGroup(group: InputGroupDTO): FilterGroup {
|
||||
return FilterGroupSchema.parse({
|
||||
group: group.group,
|
||||
label: group.label,
|
||||
description: group.description,
|
||||
});
|
||||
}
|
||||
|
||||
function mapToFilterInput(group: string, input: InputDTO): FilterInput {
|
||||
switch (input.type) {
|
||||
case InputType.Text:
|
||||
return mapToTextFilterInput(group, input);
|
||||
case InputType.Checkbox:
|
||||
return mapToCheckboxFilterInput(group, input);
|
||||
case InputType.DateRange:
|
||||
return mapToDateRangeFilterInput(group, input);
|
||||
}
|
||||
throw new Error(`Unknown input type: ${input.type}`);
|
||||
}
|
||||
|
||||
function mapToTextFilterInput(group: string, input: InputDTO): TextFilterInput {
|
||||
return TextFilterInputSchema.parse({
|
||||
group,
|
||||
key: input.key,
|
||||
label: input.label,
|
||||
description: input.description,
|
||||
type: InputType.Text,
|
||||
defaultValue: input.value,
|
||||
value: input.value,
|
||||
placeholder: input.placeholder,
|
||||
});
|
||||
}
|
||||
|
||||
function mapToCheckboxFilterInput(group: string, input: InputDTO): CheckboxFilterInput {
|
||||
return CheckboxFilterInputSchema.parse({
|
||||
group,
|
||||
key: input.key,
|
||||
label: input.label,
|
||||
description: input.description,
|
||||
type: InputType.Checkbox,
|
||||
defaultValue: input.value,
|
||||
maxOptions: input.options?.max,
|
||||
options: input.options?.values?.map(mapToCheckboxOption),
|
||||
selected:
|
||||
input.options?.values?.filter((option) => option.selected).map((option) => option.value) ||
|
||||
[],
|
||||
});
|
||||
}
|
||||
|
||||
function mapToCheckboxOption(option: OptionDTO): CheckboxFilterInputOption {
|
||||
return CheckboxFilterInputOptionSchema.parse({
|
||||
label: option.label,
|
||||
value: option.value,
|
||||
});
|
||||
}
|
||||
|
||||
function mapToDateRangeFilterInput(group: string, input: InputDTO): DateRangeFilterInput {
|
||||
return DateRangeFilterInputSchema.parse({
|
||||
group,
|
||||
key: input.key,
|
||||
label: input.label,
|
||||
description: input.description,
|
||||
type: InputType.DateRange,
|
||||
start: input.options?.values?.[0].value,
|
||||
stop: input.options?.values?.[1].value,
|
||||
});
|
||||
}
|
||||
74
libs/shared/filter/src/lib/core/schemas.ts
Normal file
74
libs/shared/filter/src/lib/core/schemas.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
import { z } from 'zod';
|
||||
import { InputType } from '../types';
|
||||
|
||||
export const FilterGroupSchema = z
|
||||
.object({
|
||||
group: z.string(),
|
||||
label: z.string().optional(),
|
||||
description: z.string().optional(),
|
||||
})
|
||||
.describe('FilterGroup');
|
||||
|
||||
export const CheckboxFilterInputOptionSchema = z
|
||||
.object({
|
||||
label: z.string(),
|
||||
value: z.string(),
|
||||
})
|
||||
.describe('CheckboxFilterInputOption');
|
||||
|
||||
const BaseFilterInputSchema = z
|
||||
.object({
|
||||
group: z.string(),
|
||||
key: z.string(),
|
||||
label: z.string().optional(),
|
||||
description: z.string().optional(),
|
||||
type: z.nativeEnum(InputType),
|
||||
})
|
||||
.describe('BaseFilterInput');
|
||||
|
||||
export const TextFilterInputSchema = BaseFilterInputSchema.extend({
|
||||
type: z.literal(InputType.Text),
|
||||
placeholder: z.string().optional(),
|
||||
defaultValue: z.string().optional(),
|
||||
value: z.string().optional(),
|
||||
}).describe('TextFilterInput');
|
||||
|
||||
export const CheckboxFilterInputSchema = BaseFilterInputSchema.extend({
|
||||
type: z.literal(InputType.Checkbox),
|
||||
maxOptions: z.number().optional(),
|
||||
options: z.array(CheckboxFilterInputOptionSchema),
|
||||
selected: z.array(z.string()),
|
||||
}).describe('CheckboxFilterInput');
|
||||
|
||||
export const DateRangeFilterInputSchema = BaseFilterInputSchema.extend({
|
||||
type: z.literal(InputType.DateRange),
|
||||
start: z.string().optional(),
|
||||
stop: z.string().optional(),
|
||||
}).describe('DateRangeFilterInput');
|
||||
|
||||
export const FilterInputSchema = z.union([
|
||||
TextFilterInputSchema,
|
||||
CheckboxFilterInputSchema,
|
||||
DateRangeFilterInputSchema,
|
||||
]);
|
||||
|
||||
export const FilterSchema = z
|
||||
.object({
|
||||
groups: z.array(FilterGroupSchema),
|
||||
inputs: z.array(FilterInputSchema),
|
||||
})
|
||||
.describe('Filter');
|
||||
|
||||
export type Filter = z.infer<typeof FilterSchema>;
|
||||
|
||||
export type FilterGroup = z.infer<typeof FilterGroupSchema>;
|
||||
|
||||
export type TextFilterInput = z.infer<typeof TextFilterInputSchema>;
|
||||
|
||||
export type CheckboxFilterInput = z.infer<typeof CheckboxFilterInputSchema>;
|
||||
|
||||
export type FilterInput = z.infer<typeof FilterInputSchema>;
|
||||
|
||||
export type CheckboxFilterInputOption = z.infer<typeof CheckboxFilterInputOptionSchema>;
|
||||
|
||||
export type DateRangeFilterInput = z.infer<typeof DateRangeFilterInputSchema>;
|
||||
1
libs/shared/filter/src/lib/inputs/index.ts
Normal file
1
libs/shared/filter/src/lib/inputs/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './search-bar-input';
|
||||
@@ -0,0 +1 @@
|
||||
export * from './search-bar-input.component';
|
||||
@@ -0,0 +1,20 @@
|
||||
@let inp = input();
|
||||
@if (inp) {
|
||||
<ui-search-bar>
|
||||
<input
|
||||
type="text"
|
||||
[formControl]="control"
|
||||
[placeholder]="inp.placeholder"
|
||||
(keydown.enter)="onSearch()"
|
||||
/>
|
||||
<button
|
||||
type="submit"
|
||||
uiIconButton
|
||||
color="brand"
|
||||
[disabled]="control.invalid"
|
||||
(click)="onSearch()"
|
||||
>
|
||||
<ng-icon name="isaActionSearch"></ng-icon>
|
||||
</button>
|
||||
</ui-search-bar>
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import { ChangeDetectionStrategy, Component, computed, inject, input, output } from '@angular/core';
|
||||
import { UiSearchBarComponent } from '@isa/ui/search-bar';
|
||||
import { FormControl, ReactiveFormsModule } from '@angular/forms';
|
||||
import { UiIconButtonComponent } from '@isa/ui/buttons';
|
||||
import { NgIconComponent, provideIcons } from '@ng-icons/core';
|
||||
import { isaActionSearch } from '@isa/icons';
|
||||
import { FilterService, TextFilterInput } from '../../core';
|
||||
import { InputType } from '../../types';
|
||||
|
||||
@Component({
|
||||
selector: 'filter-search-bar-input',
|
||||
templateUrl: './search-bar-input.component.html',
|
||||
styleUrls: ['./search-bar-input.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: true,
|
||||
imports: [UiSearchBarComponent, UiIconButtonComponent, NgIconComponent, ReactiveFormsModule],
|
||||
providers: [provideIcons({ isaActionSearch })],
|
||||
})
|
||||
export class SearchBarInputComponent {
|
||||
readonly filterService = inject(FilterService);
|
||||
|
||||
control = new FormControl();
|
||||
|
||||
inputKey = input.required<string>();
|
||||
|
||||
input = computed<TextFilterInput>(() => {
|
||||
const inputs = this.filterService.inputs();
|
||||
const input = inputs.find(
|
||||
(input) => input.key === this.inputKey() && input.type === InputType.Text,
|
||||
) as TextFilterInput;
|
||||
|
||||
if (!input) {
|
||||
throw new Error(`Input not found for key: ${this.inputKey()}`);
|
||||
}
|
||||
|
||||
this.control.setValue(input.value);
|
||||
|
||||
return input;
|
||||
});
|
||||
|
||||
search = output();
|
||||
|
||||
onSearch() {
|
||||
this.filterService.setInputValue(this.inputKey(), this.control.value);
|
||||
this.search.emit();
|
||||
}
|
||||
}
|
||||
194
libs/shared/filter/src/lib/types.ts
Normal file
194
libs/shared/filter/src/lib/types.ts
Normal file
@@ -0,0 +1,194 @@
|
||||
export enum InputType {
|
||||
Text = 1,
|
||||
Checkbox = 2,
|
||||
DateRange = 128,
|
||||
}
|
||||
|
||||
export interface QuerySettingsDTO {
|
||||
/**
|
||||
* Filter
|
||||
*/
|
||||
filter: Array<InputGroupDTO>;
|
||||
|
||||
/**
|
||||
* Eingabefelder
|
||||
*/
|
||||
input: Array<InputGroupDTO>;
|
||||
|
||||
/**
|
||||
* Sortierung
|
||||
*/
|
||||
orderBy: Array<OrderByDTO>;
|
||||
}
|
||||
|
||||
export interface InputGroupDTO {
|
||||
/**
|
||||
* Beschreibung
|
||||
*/
|
||||
description?: string;
|
||||
|
||||
/**
|
||||
* Group / ID
|
||||
*/
|
||||
group: string;
|
||||
|
||||
/**
|
||||
* Eingabefelder
|
||||
*/
|
||||
input: Array<InputDTO>;
|
||||
|
||||
/**
|
||||
* Label
|
||||
*/
|
||||
label?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sortierwert
|
||||
*/
|
||||
export interface OrderByDTO {
|
||||
/**
|
||||
* Wert
|
||||
*/
|
||||
by?: string;
|
||||
|
||||
/**
|
||||
* Absteigend
|
||||
*/
|
||||
desc?: boolean;
|
||||
|
||||
/**
|
||||
* Label
|
||||
*/
|
||||
label?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Eingabeelement
|
||||
*/
|
||||
export interface InputDTO {
|
||||
/**
|
||||
* Regex-Überprüfung
|
||||
*/
|
||||
constraint?: string;
|
||||
|
||||
/**
|
||||
* Beschreibung
|
||||
*/
|
||||
description?: string;
|
||||
|
||||
/**
|
||||
* Key / ID
|
||||
*/
|
||||
key: string;
|
||||
|
||||
/**
|
||||
* Label
|
||||
*/
|
||||
label?: string;
|
||||
|
||||
/**
|
||||
* Max-Wert (optional)
|
||||
*/
|
||||
maxValue?: string;
|
||||
|
||||
/**
|
||||
* Min-Wert (optional)
|
||||
*/
|
||||
minValue?: string;
|
||||
|
||||
/**
|
||||
* Auswahl
|
||||
*/
|
||||
options?: InputOptionsDTO;
|
||||
|
||||
/**
|
||||
* Wasserzeichen
|
||||
*/
|
||||
placeholder?: string;
|
||||
|
||||
/**
|
||||
* Anwendungsziel
|
||||
*/
|
||||
target?: string;
|
||||
|
||||
/**
|
||||
* Art des Werts
|
||||
*/
|
||||
type: InputType;
|
||||
|
||||
/**
|
||||
* Wert
|
||||
*/
|
||||
value?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Auswahl
|
||||
*/
|
||||
export interface InputOptionsDTO {
|
||||
/**
|
||||
* Maximale Anzahl auswählbarer Elemente (null => alle, 1 = single select)
|
||||
*/
|
||||
max?: number;
|
||||
|
||||
/**
|
||||
* Werte
|
||||
*/
|
||||
values?: Array<OptionDTO>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Auswahlelement
|
||||
*/
|
||||
export interface OptionDTO {
|
||||
/**
|
||||
* Beschreibung
|
||||
*/
|
||||
description?: string;
|
||||
|
||||
/**
|
||||
* Aktiv
|
||||
*/
|
||||
enabled?: boolean;
|
||||
|
||||
/**
|
||||
* Key / ID
|
||||
*/
|
||||
key?: string;
|
||||
|
||||
/**
|
||||
* Label
|
||||
*/
|
||||
label?: string;
|
||||
|
||||
/**
|
||||
* Max-Wert (optional)
|
||||
*/
|
||||
maxValue?: string;
|
||||
|
||||
/**
|
||||
* Min-Wert (optional)
|
||||
*/
|
||||
minValue?: string;
|
||||
|
||||
/**
|
||||
* Wasserzeichen
|
||||
*/
|
||||
placeholder?: string;
|
||||
|
||||
/**
|
||||
* Ausgewählt / Default
|
||||
*/
|
||||
selected?: boolean;
|
||||
|
||||
/**
|
||||
* Wert
|
||||
*/
|
||||
value?: string;
|
||||
|
||||
/**
|
||||
* Unter-Optionen
|
||||
*/
|
||||
values?: Array<OptionDTO>;
|
||||
}
|
||||
6
libs/shared/filter/src/test-setup.ts
Normal file
6
libs/shared/filter/src/test-setup.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone';
|
||||
|
||||
setupZoneTestEnv({
|
||||
errorOnUnknownElements: true,
|
||||
errorOnUnknownProperties: true,
|
||||
});
|
||||
28
libs/shared/filter/tsconfig.json
Normal file
28
libs/shared/filter/tsconfig.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es2022",
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.spec.json"
|
||||
}
|
||||
],
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"angularCompilerOptions": {
|
||||
"enableI18nLegacyMessageIdFormat": false,
|
||||
"strictInjectionParameters": true,
|
||||
"strictInputAccessModifiers": true,
|
||||
"strictTemplates": true
|
||||
}
|
||||
}
|
||||
17
libs/shared/filter/tsconfig.lib.json
Normal file
17
libs/shared/filter/tsconfig.lib.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"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"
|
||||
],
|
||||
"include": ["src/**/*.ts"]
|
||||
}
|
||||
16
libs/shared/filter/tsconfig.spec.json
Normal file
16
libs/shared/filter/tsconfig.spec.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../../dist/out-tsc",
|
||||
"module": "commonjs",
|
||||
"target": "es2016",
|
||||
"types": ["jest", "node"]
|
||||
},
|
||||
"files": ["src/test-setup.ts"],
|
||||
"include": [
|
||||
"jest.config.ts",
|
||||
"src/**/*.test.ts",
|
||||
"src/**/*.spec.ts",
|
||||
"src/**/*.d.ts"
|
||||
]
|
||||
}
|
||||
@@ -1,6 +1,4 @@
|
||||
<ng-content select="[uiSearchBarInput]"></ng-content>
|
||||
|
||||
@let control = inputControl();
|
||||
<ng-content select="input[type=text]"></ng-content>
|
||||
|
||||
<div class="ui-search-bar__actions">
|
||||
<ng-content select="ui-search-bar-clear"></ng-content>
|
||||
|
||||
@@ -5,18 +5,14 @@ import {
|
||||
ElementRef,
|
||||
ViewEncapsulation,
|
||||
} from '@angular/core';
|
||||
import { isaActionClose } from '@isa/icons';
|
||||
import { NgIconComponent, provideIcons } from '@ng-icons/core';
|
||||
import { NgControl } from '@angular/forms';
|
||||
|
||||
@Component({
|
||||
selector: 'ui-search-bar',
|
||||
imports: [NgIconComponent],
|
||||
templateUrl: './search-bar.component.html',
|
||||
styleUrl: './search-bar.component.scss',
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
providers: [provideIcons({ isaActionClose })],
|
||||
host: {
|
||||
'[class]': '["ui-search-bar"]',
|
||||
},
|
||||
|
||||
@@ -1,209 +1,209 @@
|
||||
const plugin = require("tailwindcss/plugin");
|
||||
const plugin = require('tailwindcss/plugin');
|
||||
|
||||
module.exports = plugin(function ({ addBase, addUtilities }) {
|
||||
addBase({
|
||||
".text-h1": { fontSize: "3.375rem", lineHeight: "4.5rem" },
|
||||
".text-h2": { fontSize: "1.625rem", lineHeight: "2.25rem" },
|
||||
".text-h3": { fontSize: "1.375rem", lineHeight: "1.75rem" },
|
||||
".text-p1": { fontSize: "1.125rem", lineHeight: "1.5rem" },
|
||||
".text-p2": { fontSize: "1rem", lineHeight: "1.313rem" },
|
||||
".text-p3": { fontSize: "0.875rem", lineHeight: "1.188rem" },
|
||||
".text-p4": { fontSize: "0.75rem", lineHeight: "1rem" },
|
||||
'.text-h1': { fontSize: '3.375rem', lineHeight: '4.5rem' },
|
||||
'.text-h2': { fontSize: '1.625rem', lineHeight: '2.25rem' },
|
||||
'.text-h3': { fontSize: '1.375rem', lineHeight: '1.75rem' },
|
||||
'.text-p1': { fontSize: '1.125rem', lineHeight: '1.5rem' },
|
||||
'.text-p2': { fontSize: '1rem', lineHeight: '1.313rem' },
|
||||
'.text-p3': { fontSize: '0.875rem', lineHeight: '1.188rem' },
|
||||
'.text-p4': { fontSize: '0.75rem', lineHeight: '1rem' },
|
||||
});
|
||||
|
||||
addUtilities({
|
||||
".isa-text-heading-1-bold": {
|
||||
fontFamily: "Open Sans",
|
||||
fontSize: "3.75rem",
|
||||
fontStyle: "normal",
|
||||
fontWeight: "700",
|
||||
lineHeight: "4.5rem",
|
||||
letterSpacing: "0.02813rem",
|
||||
'.isa-text-heading-1-bold': {
|
||||
fontFamily: 'Open Sans',
|
||||
fontSize: '3.75rem',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '700',
|
||||
lineHeight: '4.5rem',
|
||||
letterSpacing: '0.02813rem',
|
||||
},
|
||||
".isa-text-heading-2-bold": {
|
||||
fontFamily: "Open Sans",
|
||||
fontSize: "3rem",
|
||||
fontStyle: "normal",
|
||||
fontWeight: "700",
|
||||
lineHeight: "4rem",
|
||||
'.isa-text-heading-2-bold': {
|
||||
fontFamily: 'Open Sans',
|
||||
fontSize: '3rem',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '700',
|
||||
lineHeight: '4rem',
|
||||
},
|
||||
".isa-text-heading-3-bold": {
|
||||
fontFamily: "Open Sans",
|
||||
fontSize: "2.5rem",
|
||||
fontStyle: "normal",
|
||||
fontWeight: "700",
|
||||
lineHeight: "3rem",
|
||||
'.isa-text-heading-3-bold': {
|
||||
fontFamily: 'Open Sans',
|
||||
fontSize: '2.5rem',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '700',
|
||||
lineHeight: '3rem',
|
||||
},
|
||||
".isa-text-subtitle-1-regular": {
|
||||
fontFamily: "Open Sans",
|
||||
fontSize: "1.75rem",
|
||||
fontStyle: "normal",
|
||||
fontWeight: "400",
|
||||
lineHeight: "2.5rem",
|
||||
'.isa-text-subtitle-1-regular': {
|
||||
fontFamily: 'Open Sans',
|
||||
fontSize: '1.75rem',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '400',
|
||||
lineHeight: '2.5rem',
|
||||
},
|
||||
".isa-text-subtitle-1-bold": {
|
||||
fontFamily: "Open Sans",
|
||||
fontSize: "1.75rem",
|
||||
fontStyle: "normal",
|
||||
fontWeight: "700",
|
||||
lineHeight: "2.5rem",
|
||||
'.isa-text-subtitle-1-bold': {
|
||||
fontFamily: 'Open Sans',
|
||||
fontSize: '1.75rem',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '700',
|
||||
lineHeight: '2.5rem',
|
||||
},
|
||||
".isa-text-subtitle-2-bold": {
|
||||
fontFamily: "Open Sans",
|
||||
fontSize: "1rem",
|
||||
fontStyle: "normal",
|
||||
fontWeight: "700",
|
||||
lineHeight: "1.5rem",
|
||||
letterSpacing: "0.025rem",
|
||||
textTransform: "uppercase",
|
||||
'.isa-text-subtitle-2-bold': {
|
||||
fontFamily: 'Open Sans',
|
||||
fontSize: '1rem',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '700',
|
||||
lineHeight: '1.5rem',
|
||||
letterSpacing: '0.025rem',
|
||||
textTransform: 'uppercase',
|
||||
},
|
||||
".isa-text-body-1-bold": {
|
||||
fontFamily: "Open Sans",
|
||||
fontSize: "1rem",
|
||||
fontStyle: "normal",
|
||||
fontWeight: "700",
|
||||
lineHeight: "1.5rem",
|
||||
'.isa-text-body-1-bold': {
|
||||
fontFamily: 'Open Sans',
|
||||
fontSize: '1rem',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '700',
|
||||
lineHeight: '1.5rem',
|
||||
},
|
||||
".isa-text-body-1-bold-big": {
|
||||
fontFamily: "Open Sans",
|
||||
fontSize: "1.25rem",
|
||||
fontStyle: "normal",
|
||||
fontWeight: "700",
|
||||
lineHeight: "1.75rem",
|
||||
'.isa-text-body-1-bold-big': {
|
||||
fontFamily: 'Open Sans',
|
||||
fontSize: '1.25rem',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '700',
|
||||
lineHeight: '1.75rem',
|
||||
},
|
||||
".isa-text-body-1-bold-xl": {
|
||||
fontFamily: "Open Sans",
|
||||
fontSize: "1.375rem",
|
||||
fontStyle: "normal",
|
||||
fontWeight: "700",
|
||||
lineHeight: "2.125rem",
|
||||
'.isa-text-body-1-bold-xl': {
|
||||
fontFamily: 'Open Sans',
|
||||
fontSize: '1.375rem',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '700',
|
||||
lineHeight: '2.125rem',
|
||||
},
|
||||
".isa-text-body-1-semibold": {
|
||||
fontFamily: "Open Sans",
|
||||
fontSize: "1rem",
|
||||
fontStyle: "normal",
|
||||
fontWeight: "600",
|
||||
lineHeight: "1.5rem",
|
||||
'.isa-text-body-1-semibold': {
|
||||
fontFamily: 'Open Sans',
|
||||
fontSize: '1rem',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '600',
|
||||
lineHeight: '1.5rem',
|
||||
},
|
||||
".isa-text-body-1-regular": {
|
||||
fontFamily: "Open Sans",
|
||||
fontSize: "1rem",
|
||||
fontStyle: "normal",
|
||||
fontWeight: "400",
|
||||
lineHeight: "1.5rem",
|
||||
'.isa-text-body-1-regular': {
|
||||
fontFamily: 'Open Sans',
|
||||
fontSize: '1rem',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '400',
|
||||
lineHeight: '1.5rem',
|
||||
},
|
||||
".isa-text-body-1-regular-big": {
|
||||
fontFamily: "Open Sans",
|
||||
fontSize: "1.25rem",
|
||||
fontStyle: "normal",
|
||||
fontWeight: "400",
|
||||
lineHeight: "1.75rem",
|
||||
'.isa-text-body-1-regular-big': {
|
||||
fontFamily: 'Open Sans',
|
||||
fontSize: '1.25rem',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '400',
|
||||
lineHeight: '1.75rem',
|
||||
},
|
||||
".isa-text-body-1-regular-xl": {
|
||||
fontFamily: "Open Sans",
|
||||
fontSize: "1.375rem",
|
||||
fontStyle: "normal",
|
||||
fontWeight: "400",
|
||||
lineHeight: "2.125rem",
|
||||
'.isa-text-body-1-regular-xl': {
|
||||
fontFamily: 'Open Sans',
|
||||
fontSize: '1.375rem',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '400',
|
||||
lineHeight: '2.125rem',
|
||||
},
|
||||
".isa-text-body-2-bold": {
|
||||
fontFamily: "Open Sans",
|
||||
fontSize: "0.875rem",
|
||||
fontStyle: "normal",
|
||||
fontWeight: "700",
|
||||
lineHeight: "1.25rem",
|
||||
'.isa-text-body-2-bold': {
|
||||
fontFamily: 'Open Sans',
|
||||
fontSize: '0.875rem',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '700',
|
||||
lineHeight: '1.25rem',
|
||||
},
|
||||
".isa-text-body-2-bold-big": {
|
||||
fontFamily: "Open Sans",
|
||||
fontSize: "1.125rem",
|
||||
fontStyle: "normal",
|
||||
fontWeight: "700",
|
||||
lineHeight: "1.625rem",
|
||||
'.isa-text-body-2-bold-big': {
|
||||
fontFamily: 'Open Sans',
|
||||
fontSize: '1.125rem',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '700',
|
||||
lineHeight: '1.625rem',
|
||||
},
|
||||
".isa-text-body-2-bold-xl": {
|
||||
fontFamily: "Open Sans",
|
||||
fontSize: "1.25rem",
|
||||
fontStyle: "normal",
|
||||
fontWeight: "700",
|
||||
lineHeight: "1.75rem",
|
||||
'.isa-text-body-2-bold-xl': {
|
||||
fontFamily: 'Open Sans',
|
||||
fontSize: '1.25rem',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '700',
|
||||
lineHeight: '1.75rem',
|
||||
},
|
||||
".isa-text-body-2-semibold": {
|
||||
fontFamily: "Open Sans",
|
||||
fontSize: "0.875rem",
|
||||
fontStyle: "normal",
|
||||
fontWeight: "600",
|
||||
lineHeight: "1.25rem",
|
||||
'.isa-text-body-2-semibold': {
|
||||
fontFamily: 'Open Sans',
|
||||
fontSize: '0.875rem',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '600',
|
||||
lineHeight: '1.25rem',
|
||||
},
|
||||
".isa-text-body-2-regular": {
|
||||
fontFamily: "Open Sans",
|
||||
fontSize: "0.875rem",
|
||||
fontStyle: "normal",
|
||||
fontWeight: "400",
|
||||
lineHeight: "1.25rem",
|
||||
'.isa-text-body-2-regular': {
|
||||
fontFamily: 'Open Sans',
|
||||
fontSize: '0.875rem',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '400',
|
||||
lineHeight: '1.25rem',
|
||||
},
|
||||
".isa-text-body-2-regular-big": {
|
||||
fontFamily: "Open Sans",
|
||||
fontSize: "1.125rem",
|
||||
fontStyle: "normal",
|
||||
fontWeight: "400",
|
||||
lineHeight: "1.625rem",
|
||||
'.isa-text-body-2-regular-big': {
|
||||
fontFamily: 'Open Sans',
|
||||
fontSize: '1.125rem',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '400',
|
||||
lineHeight: '1.625rem',
|
||||
},
|
||||
".isa-text-body-2-regular-xl": {
|
||||
fontFamily: "Open Sans",
|
||||
fontSize: "1.125rem",
|
||||
fontStyle: "normal",
|
||||
fontWeight: "400",
|
||||
lineHeight: "1.75rem",
|
||||
'.isa-text-body-2-regular-xl': {
|
||||
fontFamily: 'Open Sans',
|
||||
fontSize: '1.125rem',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '400',
|
||||
lineHeight: '1.75rem',
|
||||
},
|
||||
".isa-text-caption-bold": {
|
||||
fontFamily: "Open Sans",
|
||||
fontSize: "0.75rem",
|
||||
fontStyle: "normal",
|
||||
fontWeight: "700",
|
||||
lineHeight: "1rem",
|
||||
'.isa-text-caption-bold': {
|
||||
fontFamily: 'Open Sans',
|
||||
fontSize: '0.75rem',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '700',
|
||||
lineHeight: '1rem',
|
||||
},
|
||||
".isa-text-caption-bold-big": {
|
||||
fontFamily: "Open Sans",
|
||||
fontSize: "0.875rem",
|
||||
fontStyle: "normal",
|
||||
fontWeight: "700",
|
||||
lineHeight: "1.25rem",
|
||||
'.isa-text-caption-bold-big': {
|
||||
fontFamily: 'Open Sans',
|
||||
fontSize: '0.875rem',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '700',
|
||||
lineHeight: '1.25rem',
|
||||
},
|
||||
".isa-text-caption-bold-xl": {
|
||||
fontFamily: "Open Sans",
|
||||
fontSize: "0.875rem",
|
||||
fontStyle: "normal",
|
||||
fontWeight: "700",
|
||||
lineHeight: "1.25rem",
|
||||
'.isa-text-caption-bold-xl': {
|
||||
fontFamily: 'Open Sans',
|
||||
fontSize: '0.875rem',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '700',
|
||||
lineHeight: '1.25rem',
|
||||
},
|
||||
".isa-text-caption-caps": {
|
||||
fontFamily: "Open Sans",
|
||||
fontSize: "0.75rem",
|
||||
fontStyle: "normal",
|
||||
fontWeight: "700",
|
||||
lineHeight: "1rem",
|
||||
textTransform: "uppercase",
|
||||
'.isa-text-caption-caps': {
|
||||
fontFamily: 'Open Sans',
|
||||
fontSize: '0.75rem',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '700',
|
||||
lineHeight: '1rem',
|
||||
textTransform: 'uppercase',
|
||||
},
|
||||
".isa-text-caption-regular": {
|
||||
fontFamily: "Open Sans",
|
||||
fontSize: "0.75rem",
|
||||
fontStyle: "normal",
|
||||
fontWeight: "400",
|
||||
lineHeight: "1rem",
|
||||
'.isa-text-caption-regular': {
|
||||
fontFamily: 'Open Sans',
|
||||
fontSize: '0.75rem',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '400',
|
||||
lineHeight: '1rem',
|
||||
},
|
||||
".isa-text-caption-regular-big": {
|
||||
fontFamily: "Open Sans",
|
||||
fontSize: "0.875rem",
|
||||
fontStyle: "normal",
|
||||
fontWeight: "400",
|
||||
lineHeight: "1.25rem",
|
||||
'.isa-text-caption-regular-big': {
|
||||
fontFamily: 'Open Sans',
|
||||
fontSize: '0.875rem',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '400',
|
||||
lineHeight: '1.25rem',
|
||||
},
|
||||
".isa-text-caption-regular-xl": {
|
||||
fontFamily: "Open Sans",
|
||||
fontSize: "0.875rem",
|
||||
fontStyle: "normal",
|
||||
fontWeight: "400",
|
||||
lineHeight: "1.25rem",
|
||||
'.isa-text-caption-regular-xl': {
|
||||
fontFamily: 'Open Sans',
|
||||
fontSize: '0.875rem',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '400',
|
||||
lineHeight: '1.25rem',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,7 +2,7 @@ const plugin = require('tailwindcss/plugin');
|
||||
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: ['./apps/**/*.{html,ts}'],
|
||||
content: ['./apps/**/*.{html,ts}', './libs/**/*.{html,ts}'],
|
||||
darkMode: 'media', // or 'media' or 'class',
|
||||
theme: {
|
||||
screens: {
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
"@hub/*": ["apps/isa-app/src/hub/*/index.ts"],
|
||||
"@isa/core/process": ["libs/core/process/src/index.ts"],
|
||||
"@isa/icons": ["libs/icons/src/index.ts"],
|
||||
"@isa/shared/filter": ["libs/shared/filter/src/index.ts"],
|
||||
"@isa/ui/buttons": ["libs/ui/buttons/src/index.ts"],
|
||||
"@isa/ui/input-controls": ["libs/ui/input-controls/src/index.ts"],
|
||||
"@isa/ui/search-bar": ["libs/ui/search-bar/src/index.ts"],
|
||||
|
||||
Reference in New Issue
Block a user