feat(inventories): implement inventory movement list and transfer functionality
- Added InventoryMovementListComponent to display stock movements with filtering options. - Created InventoriesTransferFormComponent for transferring stock between inventories. - Implemented product cardex view to show detailed inventory movements for specific products. - Enhanced product listing with loading states and improved UI components. - Introduced Jalali date formatting directive for better date representation. - Added utility functions for Jalali date conversions and comparisons. - Created reusable details info card component for displaying inventory details. - Updated movement reference types and tags for better categorization of inventory movements.
This commit is contained in:
@@ -2,6 +2,7 @@ export * from './copy/copy.component';
|
||||
export * from './datepicker/datepicker.component';
|
||||
export * from './duration-picker/duration-picker.component';
|
||||
export * from './paginator.component';
|
||||
export * from './uikit-counter.component';
|
||||
export * from './uikit-emptystate.component';
|
||||
export * from './uikit-field.component';
|
||||
export * from './uikit-label.component';
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
<div class="flex items-center border rounded overflow-hidden bg-white" [class.opacity-60]="disabled">
|
||||
<button
|
||||
type="button"
|
||||
pButton
|
||||
class="p-button p-component flex items-center justify-center px-3"
|
||||
(click)="decrease()"
|
||||
[disabled]="disabled"
|
||||
aria-label="decrease"
|
||||
>
|
||||
-
|
||||
</button>
|
||||
|
||||
<input
|
||||
class="text-center w-16 px-2 py-1 outline-none"
|
||||
type="number"
|
||||
[value]="value"
|
||||
(input)="onInput($event)"
|
||||
[min]="min ?? undefined"
|
||||
[max]="max ?? undefined"
|
||||
[step]="step"
|
||||
[disabled]="disabled"
|
||||
aria-label="quantity"
|
||||
/>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
pButton
|
||||
class="p-button p-component flex items-center justify-center px-3"
|
||||
(click)="increase()"
|
||||
[disabled]="disabled"
|
||||
aria-label="increase"
|
||||
>
|
||||
+
|
||||
</button>
|
||||
</div>
|
||||
@@ -0,0 +1,14 @@
|
||||
:host {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/* Tailwind handles the main layout. Keep a couple of small overrides for cross-browser input appearance. */
|
||||
.uikit-counter__input {
|
||||
-moz-appearance: textfield;
|
||||
}
|
||||
|
||||
.uikit-counter__input::-webkit-outer-spin-button,
|
||||
.uikit-counter__input::-webkit-inner-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { ButtonModule } from 'primeng/button';
|
||||
|
||||
@Component({
|
||||
selector: 'app-uikit-counter',
|
||||
templateUrl: './uikit-counter.component.html',
|
||||
styleUrls: ['./uikit-counter.component.scss'],
|
||||
standalone: true,
|
||||
imports: [CommonModule, ButtonModule],
|
||||
})
|
||||
export class UikitCounterComponent {
|
||||
@Input() value = 0;
|
||||
@Input() min: number | null = null;
|
||||
@Input() max: number | null = null;
|
||||
@Input() step = 1;
|
||||
@Input() disabled = false;
|
||||
|
||||
@Output() valueChange = new EventEmitter<number>();
|
||||
|
||||
clamp(v: number): number {
|
||||
if (this.min !== null && v < this.min) return this.min;
|
||||
if (this.max !== null && v > this.max) return this.max;
|
||||
return v;
|
||||
}
|
||||
|
||||
setValue(v: number) {
|
||||
const clamped = this.clamp(v);
|
||||
if (clamped !== this.value) {
|
||||
this.value = clamped;
|
||||
this.valueChange.emit(this.value);
|
||||
}
|
||||
}
|
||||
|
||||
increase() {
|
||||
if (this.disabled) return;
|
||||
this.setValue(this.value + this.step);
|
||||
}
|
||||
|
||||
decrease() {
|
||||
if (this.disabled) return;
|
||||
this.setValue(this.value - this.step);
|
||||
}
|
||||
|
||||
onInput(e: Event) {
|
||||
const v = (e.target as HTMLInputElement).value;
|
||||
const n = Number(v);
|
||||
if (!Number.isNaN(n)) {
|
||||
this.setValue(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user