feat: migrate recipe editor

- using eventbus in recipe editor
- migrate to logging instead of console log
- fix case swap not saved, value not update after change, topping slot bug

Signed-off-by: pakintada@gmail.com <Pakin>
This commit is contained in:
pakintada@gmail.com 2026-06-19 17:27:28 +07:00
parent 270faf6b34
commit f0619c5a10
65 changed files with 1600 additions and 557 deletions

View file

@ -1,4 +1,5 @@
<script lang="ts">
<script lang="ts">import { logger } from '$lib/core/utils/logger';
import { auth } from '$lib/core/stores/auth';
import { addNotification } from '$lib/core/stores/noti';
import Button from '$lib/components/ui/button/button.svelte';
@ -108,7 +109,7 @@
AdbInstance.instance ? 'INFO:Machine connected' : 'WARN:No machine selected'
);
} catch (error) {
console.error('[Adv] connect error:', error);
logger.error('[Adv] connect error:', error);
addNotification(`ERR:Connect failed: ${error instanceof Error ? error.message : 'unknown'}`);
} finally {
connecting = false;
@ -318,7 +319,7 @@
addNotification(`INFO:Pushed ${success} video(s) to machine (${targetDir})`);
}
} catch (error) {
console.error('[Adv] push to machine error:', error);
logger.error('[Adv] push to machine error:', error);
addNotification(`ERR:Push error: ${error instanceof Error ? error.message : 'unknown'}`);
} finally {
pushingToMachine = false;
@ -389,7 +390,7 @@
} catch (error) {
files[index].status = 'error';
files[index].error = error instanceof Error ? error.message : 'Unknown error';
console.error(`Upload error for ${item.file.name}:`, error);
logger.error(`Upload error for ${item.file.name}:`, error);
}
}
@ -429,7 +430,7 @@
await uploadManifestText(text, uid, displayName, email);
addNotification(`INFO:Manifest uploaded (${active.length} active file(s))`);
} catch (error) {
console.error('[Adv] selected manifest error:', error);
logger.error('[Adv] selected manifest error:', error);
addNotification(`ERR:Manifest failed: ${error instanceof Error ? error.message : 'unknown'}`);
} finally {
generatingManifest = false;
@ -522,7 +523,7 @@
addNotification(`INFO:Machine adv folder synced (${targets.length} file(s))`);
return true;
} catch (error) {
console.error('[Adv] machine sync error:', error);
logger.error('[Adv] machine sync error:', error);
addNotification(`ERR:Machine sync failed: ${error instanceof Error ? error.message : 'unknown'}`);
return false;
} finally {
@ -567,7 +568,7 @@
}
addNotification('INFO:Manifest (from machine) uploaded to server');
} catch (error) {
console.error('[Adv] machine manifest error:', error);
logger.error('[Adv] machine manifest error:', error);
addNotification(`ERR:Machine manifest failed: ${error instanceof Error ? error.message : 'unknown'}`);
} finally {
generatingManifest = false;

View file

@ -1,4 +1,6 @@
<script lang="ts">
import { logger } from '$lib/core/utils/logger';
import Button from '$lib/components/ui/button/button.svelte';
import Spinner from '$lib/components/ui/spinner/spinner.svelte';
import * as Dialog from '$lib/components/ui/dialog/index.js';
@ -71,7 +73,7 @@
// clear out event
GlobalEventBus.on('recipe-event', (d: any) => {
console.log('[recipe-ev] get event: ', d);
logger.info('[recipe-ev] get event: ', d);
if (d?.type == 'load-recipe' && d?.status == 'end') {
addNotification('INFO:Get data, waiting for reloading ...');
// load finish
@ -81,13 +83,13 @@
if (recipeRaw) {
devRecipe = recipeRaw;
// update material & topping
console.log('check dev recipe', devRecipe);
logger.info('check dev recipe', devRecipe);
}
// data.recipes = r01Q.recipe;
buildOverviewForBrewing();
console.log('refresh by m2 mem recipe data done');
logger.info('refresh by m2 mem recipe data done');
recipeLoading = false;
addNotification('INFO:Load recipe from memories success!');
@ -110,7 +112,7 @@
let instance = adb.getAdbInstance();
// recipeFromMachineLoading.set(true);
referenceFromPage.set('brew');
console.log('check instance', instance);
logger.info('check instance', instance);
if (instance) {
recipeLoading = true;
@ -129,7 +131,7 @@
}
} else {
try {
console.log('instance passed!');
logger.info('instance passed!');
const recipePaths = [
`${sourceDir}/cfg/recipe_branch_dev.json`,
`${sourceDir}/coffeethai02.json`
@ -137,7 +139,7 @@
for (const recipePath of recipePaths) {
const dev_recipe = await pullTextWithRetry(recipePath);
console.log('dev recipe pull result', {
logger.info('dev recipe pull result', {
recipePath,
loaded: dev_recipe != undefined,
size: dev_recipe?.length ?? 0
@ -149,7 +151,7 @@
buildOverviewForBrewing();
return;
} catch (error) {
console.error('failed to parse recipe json', recipePath, error);
logger.error('failed to parse recipe json', recipePath, error);
addNotification(`ERROR:Invalid recipe JSON from ${recipePath}`);
}
}
@ -276,7 +278,7 @@
return false;
}
} catch (e) {
console.error('error on auto connect brew page', e);
logger.error('error on auto connect brew page', e);
addNotification('ERROR:Failed to auto connect, please try again');
}
}
@ -349,7 +351,7 @@
}
afterNavigate(async () => {
console.log('after navigate brew');
logger.info('after navigate brew');
await startFetchRecipeFromMachine();
});
@ -577,7 +579,7 @@
)
);
} catch (error) {
console.error('failed to persist staged menus to Android', error);
logger.error('failed to persist staged menus to Android', error);
addNotification('WARN:Failed to save draft menus to Android');
}
}
@ -612,7 +614,7 @@
buildOverviewForBrewing();
return true;
} catch (error) {
console.error('failed to load staged menus from Android', error);
logger.error('failed to load staged menus from Android', error);
addNotification('WARN:Failed to load draft menus from Android');
return false;
}
@ -796,7 +798,18 @@
persistStagedMenus();
clearMenuSaveState(productCode);
addNotification(`INFO:Menu saved: ${productCode}`);
// Sync devRecipe from recipeFromMachine before rebuild —
// the dialog's save handler may have updated recipeFromMachine
// with user edits, and we want buildOverviewForBrewing() to
// use the latest data rather than stale devRecipe.
const latest = get(recipeFromMachine);
if (latest) {
devRecipe = latest;
}
buildOverviewForBrewing();
refresh_counter += 1;
}
onMount(() => {

View file

@ -1,4 +1,5 @@
<script lang="ts">
<script lang="ts">import { logger } from '$lib/core/utils/logger';
import Button from '$lib/components/ui/button/button.svelte';
import Input from '$lib/components/ui/input/input.svelte';
import Label from '$lib/components/ui/label/label.svelte';
@ -338,7 +339,7 @@
addNotification('INFO:Recipe loaded');
return;
} catch (error) {
console.error('failed to parse recipe json', recipePath, error);
logger.error('failed to parse recipe json', recipePath, error);
}
}
@ -364,11 +365,11 @@
// No country file means Thailand
detectedCountry = 'THAI';
}
console.log('[CreateMenu] Detected country:', detectedCountry, '-> prefix:', detectedCountryCode);
logger.info('[CreateMenu] Detected country:', detectedCountry, '-> prefix:', detectedCountryCode);
} catch (error) {
// Error reading file means Thailand (default)
detectedCountry = 'THAI';
console.log('[CreateMenu] Country file not found, defaulting to THAI');
logger.info('[CreateMenu] Country file not found, defaulting to THAI');
} finally {
countryLoading = false;
}
@ -764,7 +765,7 @@
)
);
} catch (error) {
console.error('failed to persist staged menus to Android', error);
logger.error('failed to persist staged menus to Android', error);
addNotification('WARN:Failed to save draft menus to Android');
}
}
@ -798,7 +799,7 @@
}
return true;
} catch (error) {
console.error('failed to load staged menus from Android', error);
logger.error('failed to load staged menus from Android', error);
addNotification('WARN:Failed to load draft menus from Android');
return false;
}
@ -973,7 +974,7 @@
);
return;
}
console.log(
logger.info(
'[Create Menu] save all draft menus',
menus.map((menu) => menu.productCode)
);
@ -1171,7 +1172,7 @@
try {
boxid = (await adb.pull('/sdcard/coffeevending/.bid')) || undefined;
} catch (e) {
console.warn('Failed to get boxid from machine:', e);
logger.warn('Failed to get boxid from machine:', e);
}
}
requestListMenu('tha', boxid);

View file

@ -1,4 +1,5 @@
<script lang="ts">
<script lang="ts">import { logger } from '$lib/core/utils/logger';
import { auth } from '$lib/core/stores/auth';
import { addNotification } from '$lib/core/stores/noti';
import Button from '$lib/components/ui/button/button.svelte';
@ -171,7 +172,7 @@
} catch (error) {
files[index].status = 'error';
files[index].error = error instanceof Error ? error.message : 'Unknown error';
console.error(`Upload error for ${item.file.name}:`, error);
logger.error(`Upload error for ${item.file.name}:`, error);
}
}