Compare commits

..
4 Commits
Author SHA1 Message Date
tanshu 217f636573 Version Bump v15.1.4 2026-09-04 13:44:05 +05:30
tanshu 95ac73bbc4 Updated tracking in template and choose customer fixing. 2026-09-04 08:13:26 +00:00
tanshu 3d86f8706f Version Bump v15.1.3 2026-09-04 09:03:38 +05:30
tanshu 30cbb60efe Choose customer would refresh while fetching customers. 2026-09-04 03:33:17 +00:00
43 changed files with 194 additions and 192 deletions
+2 -2
View File
@@ -29,9 +29,9 @@
"args": [ "args": [
"barker.main:app", "barker.main:app",
"--host", "--host",
"127.0.0.1", "0.0.0.0",
"--port", "--port",
"8000", "9995",
"--reload" "--reload"
], ],
"cwd": "${workspaceFolder}/barker", "cwd": "${workspaceFolder}/barker",
+1 -1
View File
@@ -1 +1 @@
__version__ = "15.1.2" __version__ = "15.1.4"
+1 -1
View File
@@ -1,6 +1,6 @@
[project] [project]
name = "barker" name = "barker"
version = "15.1.2" version = "15.1.4"
description = "Point of Sale for a restaurant" description = "Point of Sale for a restaurant"
requires-python = ">=3.14" requires-python = ">=3.14"
authors = [{ name = "tanshu", email = "git@tanshu.com" }] authors = [{ name = "tanshu", email = "git@tanshu.com" }]
+1 -1
View File
@@ -231,7 +231,7 @@ wheels = [
[[package]] [[package]]
name = "barker" name = "barker"
version = "15.1.2" version = "15.1.4"
source = { editable = "." } source = { editable = "." }
dependencies = [ dependencies = [
{ name = "aiohttp" }, { name = "aiohttp" },
+12 -5
View File
@@ -32,7 +32,9 @@
"input": "public" "input": "public"
} }
], ],
"styles": ["src/styles.sass"], "styles": [
"src/styles.sass"
],
"allowedCommonJsDependencies": [ "allowedCommonJsDependencies": [
"typed-function", "typed-function",
"javascript-natural-sort", "javascript-natural-sort",
@@ -46,8 +48,8 @@
"budgets": [ "budgets": [
{ {
"type": "initial", "type": "initial",
"maximumWarning": "500kb", "maximumWarning": "1000kb",
"maximumError": "1mb" "maximumError": "2mb"
}, },
{ {
"type": "anyComponentStyle", "type": "anyComponentStyle",
@@ -86,14 +88,19 @@
"lint": { "lint": {
"builder": "@angular-eslint/builder:lint", "builder": "@angular-eslint/builder:lint",
"options": { "options": {
"lintFilePatterns": ["src/**/*.ts", "src/**/*.html"] "lintFilePatterns": [
"src/**/*.ts",
"src/**/*.html"
]
} }
} }
} }
} }
}, },
"cli": { "cli": {
"schematicCollections": ["@angular-eslint/schematics"], "schematicCollections": [
"@angular-eslint/schematics"
],
"analytics": false "analytics": false
}, },
"schematics": { "schematics": {
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "bookie", "name": "bookie",
"version": "15.1.2", "version": "15.1.4",
"scripts": { "scripts": {
"ng": "ng", "ng": "ng",
"start": "ng serve", "start": "ng serve",
+1 -1
View File
@@ -1,7 +1,7 @@
export const environment = { export const environment = {
production: true, production: true,
ACCESS_TOKEN_REFRESH_MINUTES: 10, // refresh token 10 minutes before expiry ACCESS_TOKEN_REFRESH_MINUTES: 10, // refresh token 10 minutes before expiry
version: '15.1.2', version: '15.1.4',
}; };
export const dateFormat = { export const dateFormat = {
@@ -42,13 +42,13 @@
<mat-form-field class="flex-auto"> <mat-form-field class="flex-auto">
<mat-label>Sale Category</mat-label> <mat-label>Sale Category</mat-label>
<mat-select [formField]="form.saleCategory"> <mat-select [formField]="form.saleCategory">
@for (sc of saleCategories(); track sc) { @for (sc of saleCategories(); track sc.id) {
<mat-option [value]="sc.id"> <mat-option [value]="sc.id">
{{ sc.name }} {{ sc.name }}
</mat-option> </mat-option>
} }
</mat-select> </mat-select>
@for (error of form.saleCategory().errors(); track error) { @for (error of form.saleCategory().errors(); track $index) {
<mat-error>{{ error.message }}</mat-error> <mat-error>{{ error.message }}</mat-error>
} }
</mat-form-field> </mat-form-field>
@@ -1,39 +1,33 @@
@if (productsResource.isLoading()) { <h1 mat-dialog-title>Edit Bundle Item</h1>
<app-skeleton-loader type="card" [count]="1" />
} @else if (productsResource.error()) {
<app-error-state (retryAction)="productsResource.reload()" />
} @else {
<h1 mat-dialog-title>Edit Bundle Item</h1>
<div mat-dialog-content> <div mat-dialog-content>
<form> <form>
<mat-form-field class="w-full"> <mat-form-field class="w-full">
<mat-label>Item</mat-label> <mat-label>Item</mat-label>
<input matInput type="text" [formField]="form.product" [matAutocomplete]="autoP" /> <input matInput type="text" [formField]="form.product" [matAutocomplete]="autoP" />
<mat-autocomplete #autoP="matAutocomplete" [displayWith]="displayFn"> <mat-autocomplete #autoP="matAutocomplete" [displayWith]="displayFn">
@for (p of products(); track p) { @for (p of products(); track p.id) {
<mat-option [value]="p">{{ p.name }}</mat-option> <mat-option [value]="p">{{ p.name }}</mat-option>
} }
</mat-autocomplete> </mat-autocomplete>
</mat-form-field>
<div class="flex flex-row flex-wrap gap-3">
<mat-form-field class="flex-auto">
<mat-label>Quantity</mat-label>
<input matInput type="number" [formField]="form.quantity" />
</mat-form-field> </mat-form-field>
<div class="flex flex-row flex-wrap gap-3"> <mat-form-field class="flex-auto">
<mat-form-field class="flex-auto"> <mat-label>Sale Price</mat-label>
<mat-label>Quantity</mat-label> <input matInput type="number" [formField]="form.salePrice" />
<input matInput type="number" [formField]="form.quantity" /> </mat-form-field>
</mat-form-field> <mat-checkbox [formField]="form.printInBill" class="flex-auto">Print in Bill?</mat-checkbox>
</div>
</form>
</div>
<mat-form-field class="flex-auto"> <div mat-dialog-actions>
<mat-label>Sale Price</mat-label> <button mat-raised-button color="warn" [mat-dialog-close]="false">Cancel</button>
<input matInput type="number" [formField]="form.salePrice" /> <button type="button" mat-raised-button color="primary" (click)="accept()">Ok</button>
</mat-form-field> </div>
<mat-checkbox [formField]="form.printInBill" class="flex-auto">Print in Bill?</mat-checkbox>
</div>
</form>
</div>
<div mat-dialog-actions>
<button mat-raised-button color="warn" [mat-dialog-close]="false">Cancel</button>
<button type="button" mat-raised-button color="primary" (click)="accept()">Ok</button>
</div>
}
@@ -10,8 +10,6 @@ import { MatInputModule } from '@angular/material/input';
import { ProductQuery } from '../../core/product-query'; import { ProductQuery } from '../../core/product-query';
import { ProductService } from '../../product/product.service'; import { ProductService } from '../../product/product.service';
import { ErrorStateComponent } from '../../shared/error-state/error-state.component';
import { SkeletonLoaderComponent } from '../../shared/skeleton-loader/skeleton-loader.component';
import { BundleItem } from '../bundle'; import { BundleItem } from '../bundle';
export interface BundleDetailDialogFormData { export interface BundleDetailDialogFormData {
@@ -35,8 +33,6 @@ export interface BundleDetailDialogFormData {
MatFormFieldModule, MatFormFieldModule,
MatInputModule, MatInputModule,
FormField, FormField,
ErrorStateComponent,
SkeletonLoaderComponent,
], ],
}) })
export class BundleDetailDialogComponent { export class BundleDetailDialogComponent {
@@ -62,12 +58,15 @@ export class BundleDetailDialogComponent {
return typeof p === 'string' ? p.trim() : ''; return typeof p === 'string' ? p.trim() : '';
}); });
debouncedProduct = debounced(this.productSignal, 150); debouncedProduct = debounced(this.productSignal, 300);
productsResource = this.productSer.query(this.debouncedProduct.value); productsResource = this.productSer.query(this.debouncedProduct.value);
products = computed(() => { products = linkedSignal<ProductQuery[] | undefined, ProductQuery[]>({
if (!this.debouncedProduct.value()) return []; source: () => this.productsResource.value(),
return this.productsResource.value() ?? []; computation: (newVal, previous) => {
if (!this.debouncedProduct.value()) return [];
return newVal ?? previous?.value ?? [];
},
}); });
displayFn(product?: ProductQuery | string): string { displayFn(product?: ProductQuery | string): string {
@@ -28,7 +28,7 @@
<mat-form-field class="flex-auto"> <mat-form-field class="flex-auto">
<mat-label>Menu Category</mat-label> <mat-label>Menu Category</mat-label>
<mat-select [formField]="form.menuCategory"> <mat-select [formField]="form.menuCategory">
@for (mc of menuCategories(); track mc) { @for (mc of menuCategories(); track mc.id) {
<mat-option [value]="mc"> <mat-option [value]="mc">
{{ mc.name }} {{ mc.name }}
</mat-option> </mat-option>
@@ -39,7 +39,7 @@
<mat-form-field class="flex-auto"> <mat-form-field class="flex-auto">
<mat-label>Sale Category</mat-label> <mat-label>Sale Category</mat-label>
<mat-select [formField]="form.saleCategory"> <mat-select [formField]="form.saleCategory">
@for (sc of saleCategories(); track sc) { @for (sc of saleCategories(); track sc.id) {
<mat-option [value]="sc"> <mat-option [value]="sc">
{{ sc.name }} {{ sc.name }}
</mat-option> </mat-option>
@@ -71,7 +71,7 @@
[value]="displayFn(formModel().addRow.sku)" [value]="displayFn(formModel().addRow.sku)"
/> />
<mat-autocomplete #autoItem="matAutocomplete" [displayWith]="displayFn"> <mat-autocomplete #autoItem="matAutocomplete" [displayWith]="displayFn">
@for (p of itemProducts(); track p) { @for (p of itemProducts(); track p.id) {
<mat-option [value]="p">{{ p.name }}</mat-option> <mat-option [value]="p">{{ p.name }}</mat-option>
} }
</mat-autocomplete> </mat-autocomplete>
@@ -109,11 +109,15 @@ export class BundleDetailComponent {
return typeof v === 'string' ? v : null; return typeof v === 'string' ? v : null;
}); });
debouncedItemProduct = debounced(this.itemProductSearch, 150); debouncedItemProduct = debounced(this.itemProductSearch, 300);
itemProductsResource = this.productSer.query(this.debouncedItemProduct.value); itemProductsResource = this.productSer.query(this.debouncedItemProduct.value);
itemProducts = computed(() => { itemProducts = linkedSignal<ProductQuery[] | undefined, ProductQuery[]>({
return this.itemProductsResource.value() ?? []; source: () => this.itemProductsResource.value(),
computation: (newVal, previous) => {
if (!this.debouncedItemProduct.value()) return [];
return newVal ?? previous?.value ?? [];
},
}); });
displayedColumns = ['name', 'quantity', 'salePrice', 'printInBill', 'action']; displayedColumns = ['name', 'quantity', 'salePrice', 'printInBill', 'action'];
@@ -25,7 +25,7 @@
<mat-label>Menu Category</mat-label> <mat-label>Menu Category</mat-label>
<mat-select [formField]="form.menuCategory"> <mat-select [formField]="form.menuCategory">
<mat-option [value]="null">-- All Bundles --</mat-option> <mat-option [value]="null">-- All Bundles --</mat-option>
@for (mc of menuCategoriesResource.value(); track mc) { @for (mc of menuCategoriesResource.value(); track mc.id) {
<mat-option [value]="mc.id"> <mat-option [value]="mc.id">
{{ mc.name }} {{ mc.name }}
</mat-option> </mat-option>
@@ -73,7 +73,7 @@
<mat-header-cell *matHeaderCellDef>Items</mat-header-cell> <mat-header-cell *matHeaderCellDef>Items</mat-header-cell>
<mat-cell *matCellDef="let row"> <mat-cell *matCellDef="let row">
<div class="items-list"> <div class="items-list">
@for (item of row.items; track item) { @for (item of row.items; track item.id) {
<mat-icon> <mat-icon>
{{ item.printInBill ? 'visibility' : 'visibility_off' }} {{ item.printInBill ? 'visibility' : 'visibility_off' }}
</mat-icon> </mat-icon>
@@ -46,7 +46,7 @@
<mat-label>Cashier</mat-label> <mat-label>Cashier</mat-label>
<mat-select [formField]="form.cashier"> <mat-select [formField]="form.cashier">
<mat-option [value]="null">-- Cashier --</mat-option> <mat-option [value]="null">-- Cashier --</mat-option>
@for (ac of cashiers(); track ac) { @for (ac of cashiers(); track ac.id) {
<mat-option [value]="ac.id"> <mat-option [value]="ac.id">
{{ ac.name }} {{ ac.name }}
</mat-option> </mat-option>
@@ -28,7 +28,7 @@
</div> </div>
<mat-divider></mat-divider> <mat-divider></mat-divider>
<div class="discounts"> <div class="discounts">
@for (r of item().discounts; track r; let i = $index) { @for (r of item().discounts; track r.id; let i = $index) {
<div class="row-container"> <div class="row-container">
<mat-form-field class="flex-auto"> <mat-form-field class="flex-auto">
<mat-label>Discount on {{ r.name }}</mat-label> <mat-label>Discount on {{ r.name }}</mat-label>
@@ -50,7 +50,7 @@
<mat-header-cell *matHeaderCellDef>Discounts</mat-header-cell> <mat-header-cell *matHeaderCellDef>Discounts</mat-header-cell>
<mat-cell *matCellDef="let row"> <mat-cell *matCellDef="let row">
<ul> <ul>
@for (discount of row.discounts; track discount) { @for (discount of row.discounts; track discount.id) {
<li>{{ discount.name }} - {{ discount.discount | percent: '1.2-2' }}</li> <li>{{ discount.name }} - {{ discount.discount | percent: '1.2-2' }}</li>
} }
</ul> </ul>
@@ -15,7 +15,7 @@
<mat-form-field class="flex-auto"> <mat-form-field class="flex-auto">
<mat-label>Section</mat-label> <mat-label>Section</mat-label>
<mat-select [formField]="form.section"> <mat-select [formField]="form.section">
@for (s of sections(); track s) { @for (s of sections(); track s.id) {
<mat-option [value]="s.id"> <mat-option [value]="s.id">
{{ s.name }} {{ s.name }}
</mat-option> </mat-option>
@@ -22,7 +22,7 @@
[displayWith]="displayFn" [displayWith]="displayFn"
(optionSelected)="selected($event)" (optionSelected)="selected($event)"
> >
@for (customer of customers(); track customer) { @for (customer of customers(); track customer.id) {
<mat-option [value]="customer">{{ customer.name }} - {{ customer.phone }}</mat-option> <mat-option [value]="customer">{{ customer.name }} - {{ customer.phone }}</mat-option>
} }
</mat-autocomplete> </mat-autocomplete>
@@ -95,12 +95,15 @@ export class GuestBookDetailComponent {
return typeof p === 'string' ? p.trim() : (p as Customer).phone; return typeof p === 'string' ? p.trim() : (p as Customer).phone;
}); });
debouncedPhone = debounced(this.phoneSignal, 150); debouncedPhone = debounced(this.phoneSignal, 300);
customersResource = this.customerService.autocomplete(computed(() => this.debouncedPhone.value())); customersResource = this.customerService.autocomplete(computed(() => this.debouncedPhone.value()));
customers = computed(() => { customers = linkedSignal<Customer[] | undefined, Customer[]>({
if (!this.debouncedPhone.value()) return []; source: () => this.customersResource.value(),
return this.customersResource.value() ?? []; computation: (newVal, previous) => {
if (!this.debouncedPhone.value()) return [];
return newVal ?? previous?.value ?? [];
},
}); });
constructor() { constructor() {
@@ -8,7 +8,7 @@
<mat-form-field class="flex-auto"> <mat-form-field class="flex-auto">
<mat-label>Header / Footer</mat-label> <mat-label>Header / Footer</mat-label>
<mat-select [formField]="form.id" (selectionChange)="show($event)"> <mat-select [formField]="form.id" (selectionChange)="show($event)">
@for (s of list(); track s) { @for (s of list(); track s.id) {
<mat-option [value]="s.id"> <mat-option [value]="s.id">
{{ s.name }} {{ s.name }}
</mat-option> </mat-option>
@@ -47,12 +47,12 @@
<mat-header-cell *matHeaderCellDef>Products</mat-header-cell> <mat-header-cell *matHeaderCellDef>Products</mat-header-cell>
<mat-cell *matCellDef="let row"> <mat-cell *matCellDef="let row">
<ul> <ul>
@for (mc of row.menuCategories; track mc) { @for (mc of row.menuCategories; track mc.id) {
<li> <li>
{{ mc.name }} {{ mc.name }}
@if (!mc.enabled) { @if (!mc.enabled) {
<ul> <ul>
@for (p of mc.skus; track p) { @for (p of mc.skus; track p.id) {
<li>{{ p.name }}</li> <li>{{ p.name }}</li>
} }
</ul> </ul>
@@ -24,13 +24,13 @@
<mat-form-field class="flex-auto"> <mat-form-field class="flex-auto">
<mat-label>Category</mat-label> <mat-label>Category</mat-label>
<mat-select [formField]="form.modifierCategory"> <mat-select [formField]="form.modifierCategory">
@for (mc of modifierCategories(); track mc) { @for (mc of modifierCategories(); track mc.id) {
<mat-option [value]="mc.id"> <mat-option [value]="mc.id">
{{ mc.name }} {{ mc.name }}
</mat-option> </mat-option>
} }
</mat-select> </mat-select>
@for (error of form.modifierCategory().errors(); track error) { @for (error of form.modifierCategory().errors(); track $index) {
<mat-error>{{ error.message }}</mat-error> <mat-error>{{ error.message }}</mat-error>
} }
</mat-form-field> </mat-form-field>
@@ -5,7 +5,7 @@
<mat-form-field class="flex-auto"> <mat-form-field class="flex-auto">
<mat-label>Units</mat-label> <mat-label>Units</mat-label>
<input matInput [formField]="form.units" /> <input matInput [formField]="form.units" />
@for (error of form.units().errors(); track error) { @for (error of form.units().errors(); track $index) {
<mat-error>{{ error.message }}</mat-error> <mat-error>{{ error.message }}</mat-error>
} }
</mat-form-field> </mat-form-field>
@@ -13,7 +13,7 @@
<mat-form-field class="flex-auto"> <mat-form-field class="flex-auto">
<mat-label>Fraction</mat-label> <mat-label>Fraction</mat-label>
<input matInput type="number" [formField]="form.fraction" /> <input matInput type="number" [formField]="form.fraction" />
@for (error of form.fraction().errors(); track error) { @for (error of form.fraction().errors(); track $index) {
<mat-error>{{ error.message }}</mat-error> <mat-error>{{ error.message }}</mat-error>
} }
</mat-form-field> </mat-form-field>
@@ -21,7 +21,7 @@
<mat-form-field class="flex-auto"> <mat-form-field class="flex-auto">
<mat-label>Yield</mat-label> <mat-label>Yield</mat-label>
<input matInput type="number" [formField]="form.productYield" /> <input matInput type="number" [formField]="form.productYield" />
@for (error of form.productYield().errors(); track error) { @for (error of form.productYield().errors(); track $index) {
<mat-error>{{ error.message }}</mat-error> <mat-error>{{ error.message }}</mat-error>
} }
</mat-form-field> </mat-form-field>
@@ -29,7 +29,7 @@
<mat-form-field class="flex-auto"> <mat-form-field class="flex-auto">
<mat-label>Cost Price</mat-label> <mat-label>Cost Price</mat-label>
<input matInput type="number" [formField]="form.costPrice" /> <input matInput type="number" [formField]="form.costPrice" />
@for (error of form.costPrice().errors(); track error) { @for (error of form.costPrice().errors(); track $index) {
<mat-error>{{ error.message }}</mat-error> <mat-error>{{ error.message }}</mat-error>
} }
</mat-form-field> </mat-form-field>
@@ -37,7 +37,7 @@
<mat-form-field class="flex-auto"> <mat-form-field class="flex-auto">
<mat-label>Sale Price</mat-label> <mat-label>Sale Price</mat-label>
<input matInput type="number" [formField]="form.salePrice" /> <input matInput type="number" [formField]="form.salePrice" />
@for (error of form.salePrice().errors(); track error) { @for (error of form.salePrice().errors(); track $index) {
<mat-error>{{ error.message }}</mat-error> <mat-error>{{ error.message }}</mat-error>
} }
</mat-form-field> </mat-form-field>
@@ -45,7 +45,7 @@
<mat-form-field class="flex-auto"> <mat-form-field class="flex-auto">
<mat-label>Menu Category</mat-label> <mat-label>Menu Category</mat-label>
<mat-select [formField]="form.menuCategory"> <mat-select [formField]="form.menuCategory">
@for (mc of menuCategories; track mc) { @for (mc of menuCategories; track mc.id) {
<mat-option [value]="mc.id"> <mat-option [value]="mc.id">
{{ mc.name }} {{ mc.name }}
</mat-option> </mat-option>
@@ -19,7 +19,7 @@
<mat-form-field class="basis-3-4"> <mat-form-field class="basis-3-4">
<mat-label>Sale Category</mat-label> <mat-label>Sale Category</mat-label>
<mat-select [formField]="form.saleCategory"> <mat-select [formField]="form.saleCategory">
@for (sc of saleCategories(); track sc) { @for (sc of saleCategories(); track sc.id) {
<mat-option [value]="sc.id"> <mat-option [value]="sc.id">
{{ sc.name }} {{ sc.name }}
</mat-option> </mat-option>
@@ -35,7 +35,7 @@
<mat-form-field class="flex-auto"> <mat-form-field class="flex-auto">
<mat-label>Units</mat-label> <mat-label>Units</mat-label>
<input matInput [formField]="form.addRow.units" /> <input matInput [formField]="form.addRow.units" />
@for (error of form.addRow.units().errors(); track error) { @for (error of form.addRow.units().errors(); track $index) {
<mat-error>{{ error.message }}</mat-error> <mat-error>{{ error.message }}</mat-error>
} }
</mat-form-field> </mat-form-field>
@@ -43,7 +43,7 @@
<mat-form-field class="flex-auto"> <mat-form-field class="flex-auto">
<mat-label>Fraction</mat-label> <mat-label>Fraction</mat-label>
<input matInput type="number" [formField]="form.addRow.fraction" /> <input matInput type="number" [formField]="form.addRow.fraction" />
@for (error of form.addRow.fraction().errors(); track error) { @for (error of form.addRow.fraction().errors(); track $index) {
<mat-error>{{ error.message }}</mat-error> <mat-error>{{ error.message }}</mat-error>
} }
</mat-form-field> </mat-form-field>
@@ -51,7 +51,7 @@
<mat-form-field class="flex-auto"> <mat-form-field class="flex-auto">
<mat-label>Yield</mat-label> <mat-label>Yield</mat-label>
<input matInput type="number" [formField]="form.addRow.productYield" /> <input matInput type="number" [formField]="form.addRow.productYield" />
@for (error of form.addRow.productYield().errors(); track error) { @for (error of form.addRow.productYield().errors(); track $index) {
<mat-error>{{ error.message }}</mat-error> <mat-error>{{ error.message }}</mat-error>
} }
</mat-form-field> </mat-form-field>
@@ -59,7 +59,7 @@
<mat-form-field class="flex-auto"> <mat-form-field class="flex-auto">
<mat-label>Cost Price</mat-label> <mat-label>Cost Price</mat-label>
<input matInput type="number" [formField]="form.addRow.costPrice" /> <input matInput type="number" [formField]="form.addRow.costPrice" />
@for (error of form.addRow.costPrice().errors(); track error) { @for (error of form.addRow.costPrice().errors(); track $index) {
<mat-error>{{ error.message }}</mat-error> <mat-error>{{ error.message }}</mat-error>
} }
</mat-form-field> </mat-form-field>
@@ -67,7 +67,7 @@
<mat-form-field class="flex-auto"> <mat-form-field class="flex-auto">
<mat-label>Sale Price</mat-label> <mat-label>Sale Price</mat-label>
<input matInput type="number" [formField]="form.addRow.salePrice" /> <input matInput type="number" [formField]="form.addRow.salePrice" />
@for (error of form.addRow.salePrice().errors(); track error) { @for (error of form.addRow.salePrice().errors(); track $index) {
<mat-error>{{ error.message }}</mat-error> <mat-error>{{ error.message }}</mat-error>
} }
</mat-form-field> </mat-form-field>
@@ -75,13 +75,13 @@
<mat-form-field class="flex-auto"> <mat-form-field class="flex-auto">
<mat-label>Menu Category</mat-label> <mat-label>Menu Category</mat-label>
<mat-select [formField]="form.addRow.menuCategory"> <mat-select [formField]="form.addRow.menuCategory">
@for (mc of menuCategories(); track mc) { @for (mc of menuCategories(); track mc.id) {
<mat-option [value]="mc.id"> <mat-option [value]="mc.id">
{{ mc.name }} {{ mc.name }}
</mat-option> </mat-option>
} }
</mat-select> </mat-select>
@for (error of form.addRow.menuCategory().errors(); track error) { @for (error of form.addRow.menuCategory().errors(); track $index) {
<mat-error>{{ error.message }}</mat-error> <mat-error>{{ error.message }}</mat-error>
} }
</mat-form-field> </mat-form-field>
@@ -32,7 +32,7 @@
<mat-label>Menu Category</mat-label> <mat-label>Menu Category</mat-label>
<mat-select [formField]="form.menuCategory"> <mat-select [formField]="form.menuCategory">
<mat-option [value]="null">-- All Products --</mat-option> <mat-option [value]="null">-- All Products --</mat-option>
@for (mc of menuCategoriesResource.value(); track mc) { @for (mc of menuCategoriesResource.value(); track mc.id) {
<mat-option [value]="mc.id"> <mat-option [value]="mc.id">
{{ mc.name }} {{ mc.name }}
</mat-option> </mat-option>
@@ -54,7 +54,7 @@
<mat-header-cell *matHeaderCellDef>Name</mat-header-cell> <mat-header-cell *matHeaderCellDef>Name</mat-header-cell>
<mat-cell *matCellDef="let row"> <mat-cell *matCellDef="let row">
<ul> <ul>
@for (sku of row.skus; track sku) { @for (sku of row.skus; track sku.id) {
<li> <li>
<a [routerLink]="['/products', row.id]">{{ row.name }} ({{ sku.units }})</a> <a [routerLink]="['/products', row.id]">{{ row.name }} ({{ sku.units }})</a>
</li> </li>
@@ -68,7 +68,7 @@
<mat-header-cell *matHeaderCellDef class="right">Price</mat-header-cell> <mat-header-cell *matHeaderCellDef class="right">Price</mat-header-cell>
<mat-cell *matCellDef="let row" class="right"> <mat-cell *matCellDef="let row" class="right">
<ul> <ul>
@for (sku of row.skus; track sku) { @for (sku of row.skus; track sku.id) {
<li> <li>
{{ sku.salePrice | currency: 'INR' }} {{ sku.salePrice | currency: 'INR' }}
</li> </li>
@@ -82,7 +82,7 @@
<mat-header-cell *matHeaderCellDef>Menu Category</mat-header-cell> <mat-header-cell *matHeaderCellDef>Menu Category</mat-header-cell>
<mat-cell *matCellDef="let row"> <mat-cell *matCellDef="let row">
<ul> <ul>
@for (sku of row.skus; track sku) { @for (sku of row.skus; track sku.id) {
<li> <li>
{{ sku.menuCategory.name }} {{ sku.menuCategory.name }}
</li> </li>
@@ -102,7 +102,7 @@
<mat-header-cell *matHeaderCellDef>Details</mat-header-cell> <mat-header-cell *matHeaderCellDef>Details</mat-header-cell>
<mat-cell *matCellDef="let row"> <mat-cell *matCellDef="let row">
<ul> <ul>
@for (sku of row.skus; track sku) { @for (sku of row.skus; track sku.id) {
<li layout="row"> <li layout="row">
<div> <div>
<mat-icon> <mat-icon>
@@ -127,7 +127,7 @@
<mat-header-cell *matHeaderCellDef class="right">Quantity</mat-header-cell> <mat-header-cell *matHeaderCellDef class="right">Quantity</mat-header-cell>
<mat-cell *matCellDef="let row" class="right"> <mat-cell *matCellDef="let row" class="right">
<ul> <ul>
@for (sku of row.skus; track sku) { @for (sku of row.skus; track sku.id) {
<li>{{ sku.fraction | number: '1.2-2' }}{{ row.fractionUnits }}</li> <li>{{ sku.fraction | number: '1.2-2' }}{{ row.fractionUnits }}</li>
} }
</ul> </ul>
@@ -15,7 +15,7 @@
<div class="two-col"> <div class="two-col">
<div class="col"> <div class="col">
<h3>Permissions</h3> <h3>Permissions</h3>
@for (p of form.permissions; track p; let i = $index) { @for (p of form.permissions; track p.id().value() || i; let i = $index) {
<div class="row-container"> <div class="row-container">
<mat-checkbox <mat-checkbox
[formField]="p.enabled" [formField]="p.enabled"
@@ -29,7 +29,7 @@
<div class="col"> <div class="col">
<h3>Includes Roles</h3> <h3>Includes Roles</h3>
@for (r of form.includedRoles; track r; let i = $index) { @for (r of form.includedRoles; track r.id().value() || i; let i = $index) {
<div class="row-container"> <div class="row-container">
<mat-checkbox [formField]="r.enabled" class="flex-auto">{{ r.name().value() }}</mat-checkbox> <mat-checkbox [formField]="r.enabled" class="flex-auto">{{ r.name().value() }}</mat-checkbox>
</div> </div>
@@ -22,7 +22,7 @@
<mat-form-field class="flex-auto"> <mat-form-field class="flex-auto">
<mat-label>Tax</mat-label> <mat-label>Tax</mat-label>
<mat-select [formField]="form.tax"> <mat-select [formField]="form.tax">
@for (t of taxes(); track t) { @for (t of taxes(); track t.id) {
<mat-option [value]="t.id"> <mat-option [value]="t.id">
{{ t.name }} {{ t.name }}
</mat-option> </mat-option>
@@ -4,7 +4,7 @@
<mat-form-field class="flex-auto basis-15"> <mat-form-field class="flex-auto basis-15">
<mat-label>Regime</mat-label> <mat-label>Regime</mat-label>
<mat-select [formField]="form.regime"> <mat-select [formField]="form.regime">
@for (r of regimes; track r) { @for (r of regimes; track r.id) {
<mat-option [value]="r"> <mat-option [value]="r">
{{ r.name }} {{ r.name }}
</mat-option> </mat-option>
@@ -1,63 +1,57 @@
@if (customersResource.isLoading()) { <h2 mat-dialog-title>Customer</h2>
<app-skeleton-loader type="card" [count]="1" /> <mat-dialog-content>
} @else if (customersResource.error()) { <form class="flex-col">
<app-error-state (retryAction)="customersResource.reload()" /> <div class="row-container">
} @else { <mat-form-field class="flex-auto">
<h2 mat-dialog-title>Customer</h2> <mat-label>Phone</mat-label>
<mat-dialog-content> <input
<form class="flex-col"> matInput
<div class="row-container"> type="text"
<mat-form-field class="flex-auto"> [formField]="form.phone"
<mat-label>Phone</mat-label> [matAutocomplete]="auto"
<input autocomplete="off"
matInput cdkFocusInitial
type="text" />
[formField]="form.phone" </mat-form-field>
[matAutocomplete]="auto" <mat-autocomplete
autocomplete="off" #auto="matAutocomplete"
cdkFocusInitial autoActiveFirstOption
/> [displayWith]="displayFn"
</mat-form-field> (optionSelected)="selected($event)"
<mat-autocomplete >
#auto="matAutocomplete" @for (customer of customers(); track customer.id) {
autoActiveFirstOption <mat-option [value]="customer">{{ customer.name }} - {{ customer.phone }}</mat-option>
[displayWith]="displayFn" }
(optionSelected)="selected($event)" </mat-autocomplete>
> </div>
@for (customer of customers(); track customer) { <div class="row-container">
<mat-option [value]="customer">{{ customer.name }} - {{ customer.phone }}</mat-option> <mat-form-field class="flex-auto">
<mat-label>Name</mat-label>
<input matInput [value]="formModel().name" readonly />
</mat-form-field>
</div>
<div class="row-container">
<mat-form-field class="flex-auto">
<mat-label>Address</mat-label>
<textarea matInput [value]="formModel().address" readonly> </textarea>
</mat-form-field>
</div>
<div class="row-container">
<mat-checkbox [checked]="formModel().printInBill" [disabled]="true">Print in Bill?</mat-checkbox>
</div>
<p></p>
<div class="discounts">
<ul>
@for (r of formModel().discounts; track r.id) {
@if (r.discount > 0) {
<li>{{ r.name }} - {{ r.discount | percent: '1.2-2' }}</li>
} }
</mat-autocomplete> }
</div> </ul>
<div class="row-container"> </div>
<mat-form-field class="flex-auto"> </form>
<mat-label>Name</mat-label> </mat-dialog-content>
<input matInput [value]="formModel().name" readonly /> <mat-dialog-actions align="end">
</mat-form-field> <button mat-button [mat-dialog-close]="false">Cancel</button>
</div> <button type="button" mat-raised-button color="primary" (click)="save()">Select</button>
<div class="row-container"> </mat-dialog-actions>
<mat-form-field class="flex-auto">
<mat-label>Address</mat-label>
<textarea matInput [value]="formModel().address" readonly> </textarea>
</mat-form-field>
</div>
<div class="row-container">
<mat-checkbox [checked]="formModel().printInBill" [disabled]="true">Print in Bill?</mat-checkbox>
</div>
<p></p>
<div class="discounts">
<ul>
@for (r of formModel().discounts; track r.id) {
@if (r.discount > 0) {
<li>{{ r.name }} - {{ r.discount | percent: '1.2-2' }}</li>
}
}
</ul>
</div>
</form>
</mat-dialog-content>
<mat-dialog-actions align="end">
<button mat-button [mat-dialog-close]="false">Cancel</button>
<button type="button" mat-raised-button color="primary" (click)="save()">Select</button>
</mat-dialog-actions>
}
@@ -13,8 +13,6 @@ import { MatInputModule } from '@angular/material/input';
import { Customer } from '../../core/customer'; import { Customer } from '../../core/customer';
import { CustomerDiscount } from '../../core/customer-discount'; import { CustomerDiscount } from '../../core/customer-discount';
import { CustomerService } from '../../customers/customer.service'; import { CustomerService } from '../../customers/customer.service';
import { ErrorStateComponent } from '../../shared/error-state/error-state.component';
import { SkeletonLoaderComponent } from '../../shared/skeleton-loader/skeleton-loader.component';
export interface ChooseCustomerFormData { export interface ChooseCustomerFormData {
id: string; id: string;
@@ -40,8 +38,6 @@ export interface ChooseCustomerFormData {
MatOptionModule, MatOptionModule,
PercentPipe, PercentPipe,
FormField, FormField,
ErrorStateComponent,
SkeletonLoaderComponent,
], ],
}) })
export class ChooseCustomerComponent { export class ChooseCustomerComponent {
@@ -66,14 +62,19 @@ export class ChooseCustomerComponent {
form = form(this.formModel); form = form(this.formModel);
phoneSignal = computed(() => { phoneSignal = computed(() => {
return this.formModel().phone; const p = this.formModel().phone;
return typeof p === 'string' ? p.trim() : null;
}); });
debouncedPhone = debounced(this.phoneSignal, 150); debouncedPhone = debounced(this.phoneSignal, 300);
customersResource = this.ser.autocomplete(this.debouncedPhone.value); customersResource = this.ser.autocomplete(this.debouncedPhone.value);
customers = computed(() => { customers = linkedSignal<Customer[] | undefined, Customer[]>({
return this.customersResource.value() ?? []; source: () => this.customersResource.value(),
computation: (newVal, previous) => {
if (!this.debouncedPhone.value()) return [];
return newVal ?? previous?.value ?? [];
},
}); });
save() { save() {
@@ -7,7 +7,7 @@
<mat-card class="flex-col square-button warn" matRipple [routerLink]="['../']" queryParamsHandling="preserve"> <mat-card class="flex-col square-button warn" matRipple [routerLink]="['../']" queryParamsHandling="preserve">
<h3>Back</h3> <h3>Back</h3>
</mat-card> </mat-card>
@for (item of list(); track item) { @for (item of list(); track item.id) {
<mat-card <mat-card
class="primary flex-col square-button" class="primary flex-col square-button"
matRipple matRipple
@@ -12,7 +12,7 @@
> >
<h3>Back</h3> <h3>Back</h3>
</mat-card> </mat-card>
@for (item of list(); track item) { @for (item of list(); track item.id) {
<mat-card <mat-card
class="flex-col square-button" class="flex-col square-button"
matRipple matRipple
@@ -6,7 +6,7 @@
<h2>Running Tables</h2> <h2>Running Tables</h2>
<div class="tables-grid"> <div class="tables-grid">
@for (table of list(); track table) { @for (table of list(); track table.id) {
<mat-card <mat-card
class="flex-col square-button" class="flex-col square-button"
matRipple matRipple
@@ -2,7 +2,7 @@
<mat-dialog-content> <mat-dialog-content>
<form class="flex-col"> <form class="flex-col">
<div> <div>
@for (sc of list(); track sc; let i = $index) { @for (sc of list(); track sc.id; let i = $index) {
<div class="row-container"> <div class="row-container">
<mat-checkbox [formField]="form.saleCategories[i].saleCategory" class="flex-auto">{{ sc.name }}</mat-checkbox> <mat-checkbox [formField]="form.saleCategories[i].saleCategory" class="flex-auto">{{ sc.name }}</mat-checkbox>
</div> </div>
@@ -1,7 +1,7 @@
<h2 mat-dialog-title>Tables</h2> <h2 mat-dialog-title>Tables</h2>
<mat-dialog-content> <mat-dialog-content>
<div class="tables-grid"> <div class="tables-grid">
@for (table of list.value(); track table) { @for (table of list.value(); track table.id) {
<mat-card <mat-card
class="flex-col square-button" class="flex-col square-button"
matRipple matRipple
@@ -9,7 +9,7 @@
<mat-form-field class="flex-auto"> <mat-form-field class="flex-auto">
<mat-label>Section</mat-label> <mat-label>Section</mat-label>
<mat-select [formField]="form.section" (selectionChange)="show($event)"> <mat-select [formField]="form.section" (selectionChange)="show($event)">
@for (s of sections(); track s) { @for (s of sections(); track s.id) {
<mat-option [value]="s.id"> <mat-option [value]="s.id">
{{ s.name }} {{ s.name }}
</mat-option> </mat-option>
@@ -33,7 +33,7 @@
<mat-label>Printer</mat-label> <mat-label>Printer</mat-label>
<mat-select [formField]="form.saleCategories[i].printer"> <mat-select [formField]="form.saleCategories[i].printer">
<mat-option [value]="null">-- Default --</mat-option> <mat-option [value]="null">-- Default --</mat-option>
@for (p of printers(); track p) { @for (p of printers(); track p.id) {
<mat-option [value]="p.id"> <mat-option [value]="p.id">
{{ p.name }} {{ p.name }}
</mat-option> </mat-option>
@@ -15,7 +15,7 @@
<mat-form-field class="flex-auto"> <mat-form-field class="flex-auto">
<mat-label>Voucher Type</mat-label> <mat-label>Voucher Type</mat-label>
<mat-select [formField]="form.voucherType"> <mat-select [formField]="form.voucherType">
@for (vt of voucherTypes; track vt) { @for (vt of voucherTypes; track vt.id) {
<mat-option [value]="vt.id"> <mat-option [value]="vt.id">
{{ vt.name }} {{ vt.name }}
</mat-option> </mat-option>
@@ -25,7 +25,7 @@
<mat-form-field class="flex-auto"> <mat-form-field class="flex-auto">
<mat-label>Reporting Level</mat-label> <mat-label>Reporting Level</mat-label>
<mat-select [formField]="form.reportingLevel"> <mat-select [formField]="form.reportingLevel">
@for (rl of reportingLevel; track rl) { @for (rl of reportingLevel; track rl.id) {
<mat-option [value]="rl.id"> <mat-option [value]="rl.id">
{{ rl.name }} {{ rl.name }}
</mat-option> </mat-option>
@@ -21,7 +21,7 @@
<mat-form-field class="flex-auto"> <mat-form-field class="flex-auto">
<mat-label>Section</mat-label> <mat-label>Section</mat-label>
<mat-select [formField]="form.section"> <mat-select [formField]="form.section">
@for (s of sections(); track s) { @for (s of sections(); track s.id) {
<mat-option [value]="s.id"> <mat-option [value]="s.id">
{{ s.name }} {{ s.name }}
</mat-option> </mat-option>
@@ -23,7 +23,7 @@
<mat-form-field class="flex-auto"> <mat-form-field class="flex-auto">
<mat-label>Regime</mat-label> <mat-label>Regime</mat-label>
<mat-select [formField]="form.regime"> <mat-select [formField]="form.regime">
@for (reg of regimes(); track reg) { @for (reg of regimes(); track reg.id) {
<mat-option [value]="reg.id"> <mat-option [value]="reg.id">
{{ reg.name }} {{ reg.name }}
</mat-option> </mat-option>
@@ -22,7 +22,7 @@
<mat-form-field class="flex-auto"> <mat-form-field class="flex-auto">
<mat-label>Sale Category</mat-label> <mat-label>Sale Category</mat-label>
<mat-select [formField]="productForm.saleCategory"> <mat-select [formField]="productForm.saleCategory">
@for (sc of saleCategories(); track sc) { @for (sc of saleCategories(); track sc.id) {
<mat-option [value]="sc.id"> <mat-option [value]="sc.id">
{{ sc.name }} {{ sc.name }}
</mat-option> </mat-option>
@@ -131,7 +131,7 @@
<mat-form-field class="flex-auto"> <mat-form-field class="flex-auto">
<mat-label>Menu Category</mat-label> <mat-label>Menu Category</mat-label>
<mat-select [formField]="skuForm.menuCategory"> <mat-select [formField]="skuForm.menuCategory">
@for (mc of menuCategories(); track mc) { @for (mc of menuCategories(); track mc.id) {
<mat-option [value]="mc.id"> <mat-option [value]="mc.id">
{{ mc.name }} {{ mc.name }}
</mat-option> </mat-option>
@@ -14,7 +14,7 @@
<mat-label>Menu Category</mat-label> <mat-label>Menu Category</mat-label>
<mat-select [formField]="form.menuCategory"> <mat-select [formField]="form.menuCategory">
<mat-option [value]="null">-- All Products --</mat-option> <mat-option [value]="null">-- All Products --</mat-option>
@for (mc of menuCategoriesResource.value(); track mc) { @for (mc of menuCategoriesResource.value(); track mc.id) {
<mat-option [value]="mc.id"> <mat-option [value]="mc.id">
{{ mc.name }} {{ mc.name }}
</mat-option> </mat-option>
@@ -25,7 +25,7 @@
<mat-label>Sale Category</mat-label> <mat-label>Sale Category</mat-label>
<mat-select [formField]="form.saleCategory"> <mat-select [formField]="form.saleCategory">
<mat-option [value]="null">-- All Products --</mat-option> <mat-option [value]="null">-- All Products --</mat-option>
@for (mc of saleCategoriesResource.value(); track mc) { @for (mc of saleCategoriesResource.value(); track mc.id) {
<mat-option [value]="mc.id"> <mat-option [value]="mc.id">
{{ mc.name }} {{ mc.name }}
</mat-option> </mat-option>
@@ -40,7 +40,7 @@
<mat-header-cell *matHeaderCellDef>Products</mat-header-cell> <mat-header-cell *matHeaderCellDef>Products</mat-header-cell>
<mat-cell *matCellDef="let row"> <mat-cell *matCellDef="let row">
<ul> <ul>
@for (p of row.products; track p) { @for (p of row.products; track p.versionId) {
<li> <li>
<a [routerLink]="['/temporal-products', p.id]"> <a [routerLink]="['/temporal-products', p.id]">
<b>{{ p.name }}</b> <b>{{ p.name }}</b>
@@ -61,7 +61,7 @@
<mat-header-cell *matHeaderCellDef>Skus</mat-header-cell> <mat-header-cell *matHeaderCellDef>Skus</mat-header-cell>
<mat-cell *matCellDef="let row"> <mat-cell *matCellDef="let row">
<ul> <ul>
@for (s of row.skus; track s) { @for (s of row.skus; track s.versionId) {
<li> <li>
{{ s.units }} {{ s.units }}
</li> </li>
@@ -21,7 +21,7 @@
<mat-form-field class="flex-auto basis-2-5"> <mat-form-field class="flex-auto basis-2-5">
<mat-label>Menu Category</mat-label> <mat-label>Menu Category</mat-label>
<mat-select [formField]="form.menuCategory"> <mat-select [formField]="form.menuCategory">
@for (s of menuCategories(); track s) { @for (s of menuCategories(); track s.id) {
<mat-option [value]="s.id"> <mat-option [value]="s.id">
{{ s.name }} {{ s.name }}
</mat-option> </mat-option>
@@ -23,7 +23,7 @@
</div> </div>
<mat-divider></mat-divider> <mat-divider></mat-divider>
<div> <div>
@for (r of form.roles; track r; let i = $index) { @for (r of form.roles; track r.id().value() || i; let i = $index) {
<div class="row-container"> <div class="row-container">
<mat-checkbox [formField]="r.enabled" class="flex-auto">{{ r.name().value() }}</mat-checkbox> <mat-checkbox [formField]="r.enabled" class="flex-auto">{{ r.name().value() }}</mat-checkbox>
</div> </div>