mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
Merge branch 'develop' of ssh.dev.azure.com:v3/hugendubel/ISA/ISA-Frontend into develop
This commit is contained in:
@@ -1,11 +1,22 @@
|
||||
import { argsToTemplate, type Meta, type StoryObj, moduleMetadata } from '@storybook/angular';
|
||||
import { UiSearchBarClearComponent, UiSearchBarComponent } from '@isa/ui/search-bar';
|
||||
import {
|
||||
argsToTemplate,
|
||||
type Meta,
|
||||
type StoryObj,
|
||||
moduleMetadata,
|
||||
} from '@storybook/angular';
|
||||
import {
|
||||
UiSearchBarClearComponent,
|
||||
UiSearchBarComponent,
|
||||
} from '@isa/ui/search-bar';
|
||||
import { NgIconComponent, provideIcons } from '@ng-icons/core';
|
||||
import { isaActionSearch } from '@isa/icons';
|
||||
import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { IconButtonComponent } from '@isa/ui/buttons';
|
||||
|
||||
type Appearance = 'main' | 'results';
|
||||
|
||||
export interface UiSearchBarComponentInputs {
|
||||
appearance: Appearance;
|
||||
placeholder: string;
|
||||
value: string;
|
||||
resetValue: string;
|
||||
@@ -36,20 +47,37 @@ const meta: Meta<UiSearchBarComponentInputs> = {
|
||||
resetValue: {
|
||||
control: 'text',
|
||||
},
|
||||
appearance: {
|
||||
control: {
|
||||
type: 'select',
|
||||
options: ['main', 'results'] as Appearance[],
|
||||
},
|
||||
},
|
||||
},
|
||||
args: {
|
||||
placeholder: 'Rechnungsnummer, E-Mail, Kundenkarte, Name...',
|
||||
appearance: 'main',
|
||||
},
|
||||
render: (args) => {
|
||||
let button = '';
|
||||
|
||||
if (args.appearance === 'main') {
|
||||
button =
|
||||
'<button type="submit" uiIconButton color="brand"><ng-icon name="isaActionSearch"></ng-icon></button>';
|
||||
} else if (args.appearance === 'results') {
|
||||
button =
|
||||
'<button type="submit" uiIconButton prefix color="neutral"><ng-icon name="isaActionSearch"></ng-icon></button>';
|
||||
}
|
||||
|
||||
return {
|
||||
props: { ...args, control: new FormControl(args.value) },
|
||||
template: `<ui-search-bar class="flex items-center shrink-0 h-[3.75rem] pr-2 pl-6" ${argsToTemplate(args, { exclude: ['placeholder', 'value', 'resetValue', 'appearance'] })}>
|
||||
<input [formControl]="control" type="text" placeholder="${args.placeholder}" />
|
||||
<ui-search-bar-clear [class.pr-4]="${args.appearance === 'results'}" value="${args.resetValue}"></ui-search-bar-clear>
|
||||
${button}
|
||||
</ui-search-bar>`,
|
||||
};
|
||||
},
|
||||
render: (args) => ({
|
||||
props: { ...args, control: new FormControl(args.value) },
|
||||
template: `<ui-search-bar ${argsToTemplate(args, { exclude: ['placeholder', 'value', 'resetValue'] })}>
|
||||
<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>
|
||||
</button>
|
||||
</ui-search-bar>`,
|
||||
}),
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
|
||||
@@ -1,14 +1,8 @@
|
||||
@if (isMobileDevice) {
|
||||
<ui-icon-button (click)="onOpenOrderByDialog()">
|
||||
<ng-icon name="isaActionSort"></ng-icon>
|
||||
</ui-icon-button>
|
||||
} @else {
|
||||
<ui-toolbar>
|
||||
<span class="text-isa-neutral-600 isa-text-body-2-regular">Sortieren</span>
|
||||
<div class="flex-grow"></div>
|
||||
<button (click)="onClick('Belegdatum')" uiTextButton>Belegdatum</button>
|
||||
<button (click)="onClick('Email')" uiTextButton>Email</button>
|
||||
<button (click)="onClick('Name')" uiTextButton>Name</button>
|
||||
<button (click)="onClick('PLZ')" uiTextButton>PLZ</button>
|
||||
</ui-toolbar>
|
||||
}
|
||||
<ui-toolbar>
|
||||
<span class="text-isa-neutral-600 isa-text-body-2-regular">Sortieren</span>
|
||||
<div class="flex-grow"></div>
|
||||
<button (click)="onClick('Belegdatum')" uiTextButton>Belegdatum</button>
|
||||
<button (click)="onClick('Email')" uiTextButton>Email</button>
|
||||
<button (click)="onClick('Name')" uiTextButton>Name</button>
|
||||
<button (click)="onClick('PLZ')" uiTextButton>PLZ</button>
|
||||
</ui-toolbar>
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import { Platform } from '@angular/cdk/platform';
|
||||
import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
|
||||
import { isaActionSort } from '@isa/icons';
|
||||
import { IconButtonComponent, TextButtonComponent } from '@isa/ui/buttons';
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
|
||||
import { TextButtonComponent } from '@isa/ui/buttons';
|
||||
import { ToolbarComponent } from '@isa/ui/toolbar';
|
||||
import { NgIconComponent, provideIcons } from '@ng-icons/core';
|
||||
|
||||
@Component({
|
||||
selector: 'lib-return-order-by-list',
|
||||
@@ -11,21 +9,10 @@ import { NgIconComponent, provideIcons } from '@ng-icons/core';
|
||||
styleUrls: ['./return-order-by-list.component.css'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: true,
|
||||
imports: [
|
||||
ToolbarComponent,
|
||||
TextButtonComponent,
|
||||
NgIconComponent,
|
||||
IconButtonComponent,
|
||||
],
|
||||
providers: [provideIcons({ isaActionSort })],
|
||||
imports: [ToolbarComponent, TextButtonComponent],
|
||||
})
|
||||
export class ReturnOrderByListComponent {
|
||||
#platform = inject(Platform);
|
||||
isMobileDevice = this.#platform.ANDROID || this.#platform.IOS;
|
||||
onClick(label: string) {
|
||||
console.log('Order By click -', label);
|
||||
}
|
||||
onOpenOrderByDialog() {
|
||||
console.log('Open Order By dialog');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,33 @@
|
||||
<div class="w-full flex flex-row justify-between items-start">
|
||||
<div class="flex flex-col gap-5 justify-start">
|
||||
<filter-search-bar-input
|
||||
class="flex flex-row gap-4 h-12"
|
||||
[appearance]="'results'"
|
||||
inputKey="qs"
|
||||
(search)="onSearch()"
|
||||
></filter-search-bar-input>
|
||||
<span class="text-isa-neutral-900 isa-text-body-2-regular">
|
||||
{{ entityHits() }} Einträge
|
||||
</span>
|
||||
</div>
|
||||
<filter-search-bar-input
|
||||
class="flex flex-row gap-4 h-12"
|
||||
[appearance]="'results'"
|
||||
inputKey="qs"
|
||||
(search)="onSearch()"
|
||||
></filter-search-bar-input>
|
||||
|
||||
<div class="flex flex-row gap-4 items-center">
|
||||
<lib-return-results-filter-list></lib-return-results-filter-list>
|
||||
<lib-return-order-by-list></lib-return-order-by-list>
|
||||
@if (isMobileDevice()) {
|
||||
<ui-icon-button
|
||||
(click)="toggleOrderByToolbar.set(!toggleOrderByToolbar())"
|
||||
>
|
||||
<ng-icon name="isaActionSort"></ng-icon>
|
||||
</ui-icon-button>
|
||||
} @else {
|
||||
<lib-return-order-by-list></lib-return-order-by-list>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if (isMobileDevice() && toggleOrderByToolbar()) {
|
||||
<lib-return-order-by-list class="w-full"></lib-return-order-by-list>
|
||||
}
|
||||
|
||||
<span class="text-isa-neutral-900 isa-text-body-2-regular self-start">
|
||||
{{ entityHits() }} Einträge
|
||||
</span>
|
||||
|
||||
@let items = entityItems();
|
||||
@if (items.length > 0) {
|
||||
<div class="flex flex-col gap-4 w-full items-center justify-center">
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
effect,
|
||||
inject,
|
||||
QueryList,
|
||||
signal,
|
||||
untracked,
|
||||
viewChildren,
|
||||
} from '@angular/core';
|
||||
@@ -24,6 +25,9 @@ import { FilterService, SearchBarInputComponent } from '@isa/shared/filter';
|
||||
import { IconButtonComponent } from '@isa/ui/buttons';
|
||||
import { EmptyStateComponent } from '@isa/ui/empty-state';
|
||||
import { restoreScrollPosition } from '@isa/core/scroll-position';
|
||||
import { Platform } from '@angular/cdk/platform';
|
||||
import { NgIconComponent, provideIcons } from '@ng-icons/core';
|
||||
import { isaActionSort } from '@isa/icons';
|
||||
|
||||
type EmptyState = {
|
||||
title: string;
|
||||
@@ -44,11 +48,14 @@ type EmptyState = {
|
||||
IconButtonComponent,
|
||||
SearchBarInputComponent,
|
||||
EmptyStateComponent,
|
||||
NgIconComponent,
|
||||
],
|
||||
providers: [provideIcons({ isaActionSort })],
|
||||
})
|
||||
export class ResultsPageComponent {
|
||||
#route = inject(ActivatedRoute);
|
||||
#router = inject(Router);
|
||||
#platform = inject(Platform);
|
||||
|
||||
private _processId = injectActivatedProcessId();
|
||||
private _returnSearchStore = inject(ReturnSearchStore);
|
||||
@@ -85,6 +92,9 @@ export class ResultsPageComponent {
|
||||
|
||||
listElements = viewChildren<QueryList<ReturnResultsItemListComponent>>('listElement');
|
||||
|
||||
isMobileDevice = signal(this.#platform.ANDROID || this.#platform.IOS);
|
||||
toggleOrderByToolbar = signal(false);
|
||||
|
||||
searchEffectFn = () =>
|
||||
effect(() => {
|
||||
const processId = this._processId();
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
import { debounceTime, distinctUntilChanged, pipe, switchMap, tap } from 'rxjs';
|
||||
import { ReturnSearchService } from './return-search.service';
|
||||
import { tapResponse } from '@ngrx/operators';
|
||||
import { inject, input } from '@angular/core';
|
||||
import { inject } from '@angular/core';
|
||||
import { ReceiptListItem, QueryTokenSchema, ListResponseArgs } from './schemas';
|
||||
|
||||
export enum ReturnSearchStatus {
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
export const FilterSchema = z.record(z.any());
|
||||
|
||||
export const InputSchema = z.object({
|
||||
qs: z.string().optional(),
|
||||
});
|
||||
|
||||
export const OrderBySchema = z.object({
|
||||
by: z.string().optional(),
|
||||
label: z.string().optional(),
|
||||
@@ -14,8 +8,8 @@ export const OrderBySchema = z.object({
|
||||
});
|
||||
|
||||
export const QueryTokenSchema = z.object({
|
||||
filter: FilterSchema.default({}),
|
||||
input: InputSchema.default({}),
|
||||
filter: z.record(z.any()).default({}),
|
||||
input: z.record(z.any()).default({}),
|
||||
orderBy: z.array(OrderBySchema).default([]),
|
||||
skip: z.number().default(0),
|
||||
take: z.number().default(25),
|
||||
|
||||
Reference in New Issue
Block a user