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]
|
||||
|
||||
- [] #3: Save value to recipe
|
||||
- [] #6: display all recipes with materials from csv [material usages with product code]
|
||||
- [] #7: material & menu creation
|
||||
- [] #9: show & edit price
|
||||
|
||||
|
|
@ -19,5 +17,7 @@ Idea, Issue, Work Tracking
|
|||
- [x] #2: Send change value from editing in recipe to machine
|
||||
- [x] #5: revert value on close dialog recipe
|
||||
- [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/stream-extra": "^2.5.3",
|
||||
"animejs": "^4.3.6",
|
||||
"firebase": "^12.11.0",
|
||||
"firebase": "^12.14.0",
|
||||
"idb": "^8.0.3",
|
||||
"mode-watcher": "^1.1.0",
|
||||
"usb": "^2.17.0",
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
import { get, readable, writable } from 'svelte/store';
|
||||
import {
|
||||
currentEditingRecipeProductCode,
|
||||
lastRequestSheetPrice,
|
||||
latestRecipeToppingData,
|
||||
materialFromMachineQuery,
|
||||
materialFromServerQuery,
|
||||
|
|
@ -28,6 +29,8 @@
|
|||
import { addNotification } from '$lib/core/stores/noti';
|
||||
import { env } from '$env/dynamic/public';
|
||||
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 { sendToAndroid } from '$lib/core/stores/adbWriter';
|
||||
import { departmentStore } from '$lib/core/stores/departments';
|
||||
|
|
@ -43,6 +46,10 @@
|
|||
let menuName: string = $state('');
|
||||
let menuCurrentPrice: number = $state(0);
|
||||
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 machineInfoSnapshot: any = $state();
|
||||
|
|
@ -52,6 +59,8 @@
|
|||
|
||||
let toppingSlotState: any = $state([]);
|
||||
|
||||
let unsubSheetPrice: (() => void) | null = null;
|
||||
|
||||
const recipeDetailDispatch = createEventDispatcher();
|
||||
|
||||
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) {
|
||||
// console.log('old', original, 'updated', recipeListMatState);
|
||||
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(() => {
|
||||
machineInfoSnapshot = get(machineInfoStore);
|
||||
|
||||
|
|
@ -231,8 +276,19 @@
|
|||
} 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>
|
||||
|
||||
|
|
@ -265,31 +321,152 @@
|
|||
<Card.Description>Info about this menu</Card.Description>
|
||||
</Card.Header>
|
||||
|
||||
<Card.Content class="grid gap-6">
|
||||
<div class="grid grid-cols-2 gap-6">
|
||||
<div class="grid grid-flow-row gap-3">
|
||||
<Label for="tabs-menu-name">Name</Label>
|
||||
<Input id="tabs-menu-name" value={recipeData['name'] ?? ''} />
|
||||
<!-- Basic Info Card -->
|
||||
<Card.Root class="mb-4">
|
||||
<Card.Header>
|
||||
<Card.Title>Basic Information</Card.Title>
|
||||
</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>
|
||||
</Card.Content>
|
||||
</Card.Root>
|
||||
|
||||
<div class="grid grid-flow-row gap-3">
|
||||
<Label for="tabs-menu-other-name">Other Name</Label>
|
||||
<Input id="tabs-menu-other-name" value={recipeData['otherName'] ?? ''} />
|
||||
<!-- Price Information Card -->
|
||||
<Card.Root class="mb-4">
|
||||
<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>
|
||||
</Card.Content>
|
||||
</Card.Root>
|
||||
|
||||
<div class="grid grid-cols-2 gap-3">
|
||||
<!-- price -->
|
||||
|
||||
<div>
|
||||
<Label for="tabs-menu-price">Price</Label>
|
||||
<Input id="tabs-menu-price" value={menuCurrentPrice} />
|
||||
</div>
|
||||
|
||||
<b> Disabled </b>
|
||||
<Checkbox id="disable-menu-by-price" checked={isMenuHideByPrice} />
|
||||
</div>
|
||||
</Card.Content>
|
||||
<!-- Additional Recipe Data Card -->
|
||||
<Card.Root>
|
||||
<Card.Header>
|
||||
<Card.Title>Additional Recipe Data</Card.Title>
|
||||
</Card.Header>
|
||||
<Card.Content class="space-y-4">
|
||||
{#if recipeData}
|
||||
<div class="space-y-3">
|
||||
<div class="space-y-2">
|
||||
<Label for="tabs-last-change">Last Change</Label>
|
||||
<span id="tabs-last-change" class="text-sm text-muted-foreground block">
|
||||
{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>
|
||||
</Tabs.Content>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue