wip: add more detail in recipe dialog
Signed-off-by: pakintada@gmail.com <Pakin>
This commit is contained in:
parent
8b0479bf58
commit
be785825fe
4 changed files with 202 additions and 25 deletions
|
|
@ -5,8 +5,6 @@ Idea, Issue, Work Tracking
|
||||||
|
|
||||||
[Pending]
|
[Pending]
|
||||||
|
|
||||||
- [] #3: Save value to recipe
|
|
||||||
- [] #6: display all recipes with materials from csv [material usages with product code]
|
|
||||||
- [] #7: material & menu creation
|
- [] #7: material & menu creation
|
||||||
- [] #9: show & edit price
|
- [] #9: show & edit price
|
||||||
|
|
||||||
|
|
@ -19,5 +17,7 @@ Idea, Issue, Work Tracking
|
||||||
- [x] #2: Send change value from editing in recipe to machine
|
- [x] #2: Send change value from editing in recipe to machine
|
||||||
- [x] #5: revert value on close dialog recipe
|
- [x] #5: revert value on close dialog recipe
|
||||||
- [x] #8: change recipe version
|
- [x] #8: change recipe version
|
||||||
|
- [x] #3: Save value to recipe
|
||||||
|
- [x] #6: display all recipes with materials from csv [material usages with product code]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
BIN
bun.lockb
BIN
bun.lockb
Binary file not shown.
|
|
@ -74,7 +74,7 @@
|
||||||
"@yume-chan/scrcpy": "^2.3.0",
|
"@yume-chan/scrcpy": "^2.3.0",
|
||||||
"@yume-chan/stream-extra": "^2.5.3",
|
"@yume-chan/stream-extra": "^2.5.3",
|
||||||
"animejs": "^4.3.6",
|
"animejs": "^4.3.6",
|
||||||
"firebase": "^12.11.0",
|
"firebase": "^12.14.0",
|
||||||
"idb": "^8.0.3",
|
"idb": "^8.0.3",
|
||||||
"mode-watcher": "^1.1.0",
|
"mode-watcher": "^1.1.0",
|
||||||
"usb": "^2.17.0",
|
"usb": "^2.17.0",
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
import { get, readable, writable } from 'svelte/store';
|
import { get, readable, writable } from 'svelte/store';
|
||||||
import {
|
import {
|
||||||
currentEditingRecipeProductCode,
|
currentEditingRecipeProductCode,
|
||||||
|
lastRequestSheetPrice,
|
||||||
latestRecipeToppingData,
|
latestRecipeToppingData,
|
||||||
materialFromMachineQuery,
|
materialFromMachineQuery,
|
||||||
materialFromServerQuery,
|
materialFromServerQuery,
|
||||||
|
|
@ -28,6 +29,8 @@
|
||||||
import { addNotification } from '$lib/core/stores/noti';
|
import { addNotification } from '$lib/core/stores/noti';
|
||||||
import { env } from '$env/dynamic/public';
|
import { env } from '$env/dynamic/public';
|
||||||
import { sendCommand, sendReset } from '$lib/core/brew/command';
|
import { sendCommand, sendReset } from '$lib/core/brew/command';
|
||||||
|
import { sendCommandRequest } from '$lib/core/handlers/ws_messageSender';
|
||||||
|
import { needPermission } from '$lib/core/handlers/permissionHandler';
|
||||||
import { isAdbWriterAvailable } from '$lib/core/stores/adbWriter';
|
import { isAdbWriterAvailable } from '$lib/core/stores/adbWriter';
|
||||||
import { sendToAndroid } from '$lib/core/stores/adbWriter';
|
import { sendToAndroid } from '$lib/core/stores/adbWriter';
|
||||||
import { departmentStore } from '$lib/core/stores/departments';
|
import { departmentStore } from '$lib/core/stores/departments';
|
||||||
|
|
@ -43,6 +46,10 @@
|
||||||
let menuName: string = $state('');
|
let menuName: string = $state('');
|
||||||
let menuCurrentPrice: number = $state(0);
|
let menuCurrentPrice: number = $state(0);
|
||||||
let isMenuHideByPrice: boolean = $state(false);
|
let isMenuHideByPrice: boolean = $state(false);
|
||||||
|
let sheetPriceValue: number | null = $state(null);
|
||||||
|
let showSheetPrice: boolean = $state(false);
|
||||||
|
let canEditSheetPrice: boolean = $state(false);
|
||||||
|
let sheetPriceRawCell: any = $state(null);
|
||||||
|
|
||||||
let materialSnapshot: any = $state();
|
let materialSnapshot: any = $state();
|
||||||
let machineInfoSnapshot: any = $state();
|
let machineInfoSnapshot: any = $state();
|
||||||
|
|
@ -52,6 +59,8 @@
|
||||||
|
|
||||||
let toppingSlotState: any = $state([]);
|
let toppingSlotState: any = $state([]);
|
||||||
|
|
||||||
|
let unsubSheetPrice: (() => void) | null = null;
|
||||||
|
|
||||||
const recipeDetailDispatch = createEventDispatcher();
|
const recipeDetailDispatch = createEventDispatcher();
|
||||||
|
|
||||||
function remappingToColumn(data: any[]): RecipelistMaterial[] {
|
function remappingToColumn(data: any[]): RecipelistMaterial[] {
|
||||||
|
|
@ -167,6 +176,22 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function saveSheetPrice() {
|
||||||
|
if (!canEditSheetPrice || sheetPriceValue === null) return;
|
||||||
|
sendCommandRequest('sheet', {
|
||||||
|
country: get(departmentStore),
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
product_code: productCode,
|
||||||
|
new_price: sheetPriceValue,
|
||||||
|
cell_coord: sheetPriceRawCell?.coord
|
||||||
|
}
|
||||||
|
],
|
||||||
|
param: 'price',
|
||||||
|
action: 'update'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async function checkChanges(productCode: string, original: any) {
|
async function checkChanges(productCode: string, original: any) {
|
||||||
// console.log('old', original, 'updated', recipeListMatState);
|
// console.log('old', original, 'updated', recipeListMatState);
|
||||||
if (recipeListOriginal.length == 0) {
|
if (recipeListOriginal.length == 0) {
|
||||||
|
|
@ -182,6 +207,26 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateSheetPrice(sheetData: any) {
|
||||||
|
if (!productCode) return;
|
||||||
|
const country = get(departmentStore);
|
||||||
|
if (!country) return;
|
||||||
|
|
||||||
|
const sheetEntry = sheetData[country]?.[productCode];
|
||||||
|
if (sheetEntry && typeof sheetEntry === 'object' && sheetEntry?.value) {
|
||||||
|
sheetPriceRawCell = sheetEntry;
|
||||||
|
const parsed = parseInt(sheetEntry.value);
|
||||||
|
if (!isNaN(parsed) && parsed !== menuCurrentPrice) {
|
||||||
|
sheetPriceValue = parsed;
|
||||||
|
showSheetPrice = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sheetPriceValue = null;
|
||||||
|
showSheetPrice = false;
|
||||||
|
}
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
machineInfoSnapshot = get(machineInfoStore);
|
machineInfoSnapshot = get(machineInfoStore);
|
||||||
|
|
||||||
|
|
@ -231,8 +276,19 @@
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// save old value\
|
// save old value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
canEditSheetPrice = needPermission('document.write.*');
|
||||||
|
|
||||||
|
updateSheetPrice(get(lastRequestSheetPrice));
|
||||||
|
unsubSheetPrice = lastRequestSheetPrice.subscribe((data) => {
|
||||||
|
updateSheetPrice(data);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
onDestroy(() => {
|
||||||
|
if (unsubSheetPrice) unsubSheetPrice();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
@ -265,31 +321,152 @@
|
||||||
<Card.Description>Info about this menu</Card.Description>
|
<Card.Description>Info about this menu</Card.Description>
|
||||||
</Card.Header>
|
</Card.Header>
|
||||||
|
|
||||||
<Card.Content class="grid gap-6">
|
<!-- Basic Info Card -->
|
||||||
<div class="grid grid-cols-2 gap-6">
|
<Card.Root class="mb-4">
|
||||||
<div class="grid grid-flow-row gap-3">
|
<Card.Header>
|
||||||
<Label for="tabs-menu-name">Name</Label>
|
<Card.Title>Basic Information</Card.Title>
|
||||||
<Input id="tabs-menu-name" value={recipeData['name'] ?? ''} />
|
</Card.Header>
|
||||||
|
<Card.Content class="space-y-4">
|
||||||
|
<div class="grid grid-cols-2 gap-4">
|
||||||
|
<div class="space-y-2">
|
||||||
|
<Label for="tabs-menu-name">Name</Label>
|
||||||
|
<Input id="tabs-menu-name" value={recipeData['name'] ?? ''} />
|
||||||
|
</div>
|
||||||
|
<div class="space-y-2">
|
||||||
|
<Label for="tabs-menu-other-name">Other Name</Label>
|
||||||
|
<Input id="tabs-menu-other-name" value={recipeData['otherName'] ?? ''} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</Card.Content>
|
||||||
|
</Card.Root>
|
||||||
|
|
||||||
<div class="grid grid-flow-row gap-3">
|
<!-- Price Information Card -->
|
||||||
<Label for="tabs-menu-other-name">Other Name</Label>
|
<Card.Root class="mb-4">
|
||||||
<Input id="tabs-menu-other-name" value={recipeData['otherName'] ?? ''} />
|
<Card.Header>
|
||||||
|
<Card.Title>Price Information</Card.Title>
|
||||||
|
</Card.Header>
|
||||||
|
<Card.Content class="space-y-4">
|
||||||
|
<div class="space-y-4">
|
||||||
|
<!-- Current Price -->
|
||||||
|
<div class="space-y-2">
|
||||||
|
<Label for="tabs-menu-price">Price</Label>
|
||||||
|
<Input id="tabs-menu-price" value={menuCurrentPrice} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{#if showSheetPrice}
|
||||||
|
<!-- Sheet Price (when different) -->
|
||||||
|
<div class="space-y-2">
|
||||||
|
<Label for="tabs-menu-sheet-price">Price from Sheet</Label>
|
||||||
|
<div class="flex flex-row gap-2">
|
||||||
|
<Input
|
||||||
|
id="tabs-menu-sheet-price"
|
||||||
|
bind:value={sheetPriceValue}
|
||||||
|
disabled={!canEditSheetPrice}
|
||||||
|
/>
|
||||||
|
{#if canEditSheetPrice}
|
||||||
|
<Button onclick={saveSheetPrice} class="btn-sm">
|
||||||
|
Save
|
||||||
|
</Button>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<!-- Disabled by Price -->
|
||||||
|
<div class="space-y-2">
|
||||||
|
<div class="flex flex-row items-center gap-2">
|
||||||
|
<Checkbox
|
||||||
|
id="disable-menu-by-price"
|
||||||
|
checked={isMenuHideByPrice}
|
||||||
|
/>
|
||||||
|
<span>Disabled by Price</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Card.Content>
|
||||||
|
</Card.Root>
|
||||||
|
|
||||||
<div class="grid grid-cols-2 gap-3">
|
<!-- Additional Recipe Data Card -->
|
||||||
<!-- price -->
|
<Card.Root>
|
||||||
|
<Card.Header>
|
||||||
<div>
|
<Card.Title>Additional Recipe Data</Card.Title>
|
||||||
<Label for="tabs-menu-price">Price</Label>
|
</Card.Header>
|
||||||
<Input id="tabs-menu-price" value={menuCurrentPrice} />
|
<Card.Content class="space-y-4">
|
||||||
</div>
|
{#if recipeData}
|
||||||
|
<div class="space-y-3">
|
||||||
<b> Disabled </b>
|
<div class="space-y-2">
|
||||||
<Checkbox id="disable-menu-by-price" checked={isMenuHideByPrice} />
|
<Label for="tabs-last-change">Last Change</Label>
|
||||||
</div>
|
<span id="tabs-last-change" class="text-sm text-muted-foreground block">
|
||||||
</Card.Content>
|
{recipeData.LastChange ?? 'N/A'}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="space-y-2">
|
||||||
|
<Label for="tabs-total-time">Total Time (seconds)</Label>
|
||||||
|
<Input
|
||||||
|
id="tabs-total-time"
|
||||||
|
type="number"
|
||||||
|
value={String(recipeData.total_time ?? '')}
|
||||||
|
oninput={(e) => {
|
||||||
|
const input = e.target as HTMLInputElement | null;
|
||||||
|
if (input && input.value !== '') {
|
||||||
|
const value = parseInt(input.value);
|
||||||
|
if (!isNaN(value)) {
|
||||||
|
recipeData.total_time = value;
|
||||||
|
// Notify parent of change
|
||||||
|
onPendingChange({
|
||||||
|
target: 'recipeData',
|
||||||
|
ref_pd: productCode,
|
||||||
|
value: { ...recipeData, total_time: value }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="space-y-2">
|
||||||
|
<Label class="flex flex-row items-center gap-2">
|
||||||
|
<Checkbox
|
||||||
|
id="tabs-use-gram"
|
||||||
|
checked={recipeData.useGram ?? false}
|
||||||
|
onchange={(e) => {
|
||||||
|
const checkbox = e.target as HTMLInputElement | null;
|
||||||
|
if (checkbox) {
|
||||||
|
recipeData.useGram = checkbox.checked;
|
||||||
|
onPendingChange({
|
||||||
|
target: 'recipeData',
|
||||||
|
ref_pd: productCode,
|
||||||
|
value: { ...recipeData, useGram: checkbox.checked }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<span>Use Gram for Measurement</span>
|
||||||
|
</Label>
|
||||||
|
</div>
|
||||||
|
<div class="space-y-2">
|
||||||
|
<Label for="tabs-uri-data">URI Data</Label>
|
||||||
|
<Input
|
||||||
|
id="tabs-uri-data"
|
||||||
|
value={recipeData.uriData ?? ''}
|
||||||
|
oninput={(e) => {
|
||||||
|
const input = e.target as HTMLInputElement | null;
|
||||||
|
if (input) {
|
||||||
|
recipeData.uriData = input.value;
|
||||||
|
onPendingChange({
|
||||||
|
target: 'recipeData',
|
||||||
|
ref_pd: productCode,
|
||||||
|
value: { ...recipeData, uriData: input.value }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
<p class="text-muted-foreground">No recipe data available</p>
|
||||||
|
{/if}
|
||||||
|
</Card.Content>
|
||||||
|
</Card.Root>
|
||||||
</Card.Root>
|
</Card.Root>
|
||||||
</Tabs.Content>
|
</Tabs.Content>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue