parent
7075f4a664
commit
29a1a82cfb
12 changed files with 344 additions and 203 deletions
|
|
@ -43,8 +43,16 @@
|
|||
enabledAccessibleCountries = userCurrentPerms
|
||||
.filter((x) => x.startsWith('document.read'))
|
||||
.map((x) => x.split('.')[2]);
|
||||
|
||||
if (enabledAccessibleCountries.length == 1) {
|
||||
onCountrySelected(enabledAccessibleCountries[0]);
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
if (enabledAccessibleCountries.length == 1) {
|
||||
onCountrySelected(enabledAccessibleCountries[0]);
|
||||
}
|
||||
</script>
|
||||
|
||||
<h1 class="m-8 text-4xl font-bold">Country Selection</h1>
|
||||
|
|
|
|||
|
|
@ -1,138 +1,119 @@
|
|||
|
||||
<script lang="ts">
|
||||
import RecipeModuleBtn from '$lib/assets/modules/recipe_btn.png';
|
||||
import MachineInspectBtn from '$lib/assets/modules/monitoring_btn.png';
|
||||
import { animate, JSAnimation, remove as removeAnime, stagger } from 'animejs';
|
||||
import { goto } from '$app/navigation';
|
||||
import Button from '$lib/components/ui/button/button.svelte';
|
||||
|
||||
import RecipeModuleBtn from "$lib/assets/modules/recipe_btn.png";
|
||||
import MachineInspectBtn from "$lib/assets/modules/monitoring_btn.png";
|
||||
import {animate, JSAnimation, remove as removeAnime, stagger} from "animejs";
|
||||
import { goto } from "$app/navigation";
|
||||
import Button from "$lib/components/ui/button/button.svelte";
|
||||
|
||||
import ArrowRight from '@lucide/svelte/icons/arrow-right';
|
||||
import { permission as currentPermissions } from "$lib/core/stores/permissions";
|
||||
import { get } from "svelte/store";
|
||||
import ArrowRight from '@lucide/svelte/icons/arrow-right';
|
||||
import { permission as currentPermissions } from '$lib/core/stores/permissions';
|
||||
import { get } from 'svelte/store';
|
||||
|
||||
let recipeModBtn = $state<HTMLElement | null>(null);
|
||||
let monitorModBtn = $state<HTMLElement | null>(null);
|
||||
let recipeModBtn = $state<HTMLElement | null>(null);
|
||||
let monitorModBtn = $state<HTMLElement | null>(null);
|
||||
|
||||
let gotoDashboardBtn = $state<HTMLElement | null>(null);
|
||||
|
||||
let animationPulseGoto: JSAnimation;
|
||||
let gotoDashboardBtn = $state<HTMLElement | null>(null);
|
||||
|
||||
setInterval(() => {
|
||||
if(gotoDashboardBtn && !animationPulseGoto){
|
||||
animationPulseGoto = animate(gotoDashboardBtn, {
|
||||
opacity: [0.8, 1], // Slight pulse in opacity
|
||||
duration: 800, // Duration of one pulse
|
||||
loop: true, // Repeat forever
|
||||
alternate: true,
|
||||
delay: stagger(100),
|
||||
ease: 'inOutQuad',
|
||||
boxShadow: [
|
||||
'0 0 0px 0 none',
|
||||
'0 0 0px 7px lightblue',
|
||||
],
|
||||
});
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
let perms = get(currentPermissions);
|
||||
let animationPulseGoto: JSAnimation;
|
||||
|
||||
setInterval(() => {
|
||||
if (gotoDashboardBtn && !animationPulseGoto) {
|
||||
animationPulseGoto = animate(gotoDashboardBtn, {
|
||||
opacity: [0.8, 1], // Slight pulse in opacity
|
||||
duration: 800, // Duration of one pulse
|
||||
loop: true, // Repeat forever
|
||||
alternate: true,
|
||||
delay: stagger(100),
|
||||
ease: 'inOutQuad',
|
||||
boxShadow: ['0 0 0px 0 none', '0 0 0px 7px lightblue']
|
||||
});
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
let perms = get(currentPermissions);
|
||||
</script>
|
||||
|
||||
<div class="flex h-screen items-center justify-center">
|
||||
<div class="columns-md place-content-center gap-8">
|
||||
<h1 class="text-center font-bold text-4xl m-8">Module Selection</h1>
|
||||
<div class="columns-md place-content-center gap-8">
|
||||
<h1 class="m-8 text-center text-4xl font-bold">Module Selection</h1>
|
||||
|
||||
|
||||
<div class="flex justify-between items-center">
|
||||
<!-- need permission `document` -->
|
||||
{#if perms.filter((x) => x.startsWith("document.read") || x.startsWith("document.write")).length > 0}
|
||||
<button
|
||||
class="button"
|
||||
id="recipe_mod_btn"
|
||||
bind:this={recipeModBtn}
|
||||
onclick={() => goto('/departments')}
|
||||
onmouseenter={() => {
|
||||
if(recipeModBtn){
|
||||
animate(recipeModBtn, {
|
||||
scale: 1.1,
|
||||
duration: 300,
|
||||
ease: "inOutSine"
|
||||
});
|
||||
}
|
||||
}}
|
||||
onmouseleave={() => {
|
||||
if(recipeModBtn){
|
||||
animate(recipeModBtn, {
|
||||
scale: 1.0,
|
||||
duration: 200,
|
||||
ease: "inOutSine"
|
||||
});
|
||||
}
|
||||
}}>
|
||||
<img
|
||||
src={RecipeModuleBtn}
|
||||
alt="Recipes"
|
||||
loading="lazy"
|
||||
/>
|
||||
</button>
|
||||
{/if}
|
||||
<div class="flex items-center justify-between">
|
||||
<!-- need permission `document` -->
|
||||
{#if perms.filter((x) => x.startsWith('document.read') || x.startsWith('document.write')).length > 0}
|
||||
<button
|
||||
class="button"
|
||||
id="recipe_mod_btn"
|
||||
bind:this={recipeModBtn}
|
||||
onclick={() => goto('/departments')}
|
||||
onmouseenter={() => {
|
||||
if (recipeModBtn) {
|
||||
animate(recipeModBtn, {
|
||||
scale: 1.1,
|
||||
duration: 300,
|
||||
ease: 'inOutSine'
|
||||
});
|
||||
}
|
||||
}}
|
||||
onmouseleave={() => {
|
||||
if (recipeModBtn) {
|
||||
animate(recipeModBtn, {
|
||||
scale: 1.0,
|
||||
duration: 200,
|
||||
ease: 'inOutSine'
|
||||
});
|
||||
}
|
||||
}}
|
||||
>
|
||||
<img src={RecipeModuleBtn} alt="Recipes" loading="lazy" />
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
<!-- need permission `tools` -->
|
||||
{#if perms.filter((x) => x.startsWith("tools")).length > 0}
|
||||
<button
|
||||
class="button"
|
||||
id="monitor_mod_btn"
|
||||
bind:this={monitorModBtn}
|
||||
onclick={() => goto('/tools')}
|
||||
onmouseenter={() => {
|
||||
if(monitorModBtn){
|
||||
animate(monitorModBtn, {
|
||||
scale: 1.1,
|
||||
duration: 300,
|
||||
ease: "inOutSine"
|
||||
});
|
||||
}
|
||||
}}
|
||||
onmouseleave={() => {
|
||||
if(monitorModBtn){
|
||||
animate(monitorModBtn, {
|
||||
scale: 1.0,
|
||||
duration: 200,
|
||||
ease: "inOutSine"
|
||||
});
|
||||
}
|
||||
}}>
|
||||
<img
|
||||
src={MachineInspectBtn}
|
||||
alt="Recipes"
|
||||
loading="lazy"
|
||||
/>
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
<!-- need permission `tools` -->
|
||||
{#if perms.filter((x) => x.startsWith('tools')).length > 0}
|
||||
<button
|
||||
class="button"
|
||||
id="monitor_mod_btn"
|
||||
bind:this={monitorModBtn}
|
||||
onclick={() => goto('/tools')}
|
||||
onmouseenter={() => {
|
||||
if (monitorModBtn) {
|
||||
animate(monitorModBtn, {
|
||||
scale: 1.1,
|
||||
duration: 300,
|
||||
ease: 'inOutSine'
|
||||
});
|
||||
}
|
||||
}}
|
||||
onmouseleave={() => {
|
||||
if (monitorModBtn) {
|
||||
animate(monitorModBtn, {
|
||||
scale: 1.0,
|
||||
duration: 200,
|
||||
ease: 'inOutSine'
|
||||
});
|
||||
}
|
||||
}}
|
||||
>
|
||||
<img src={MachineInspectBtn} alt="Recipes" loading="lazy" />
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{#if perms.filter((x) => x.startsWith("document.read") || x.startsWith("document.write") || x.startsWith("tools")).length == 0}
|
||||
{#if perms.filter((x) => x.startsWith('document.read') || x.startsWith('document.write') || x.startsWith('tools')).length == 0}
|
||||
<p class="m-8 text-center text-2xl">
|
||||
No modules are available. Please check your account with admin.
|
||||
</p>
|
||||
{/if}
|
||||
|
||||
<p class="text-center text-2xl m-8">No modules are available.
|
||||
Please check your account with admin.</p>
|
||||
|
||||
{/if}
|
||||
|
||||
<div class="flex justify-center items-center m-16">
|
||||
<button
|
||||
id="goto_dash_btn"
|
||||
class="focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive inline-flex shrink-0 items-center justify-center gap-2 whitespace-nowrap text-sm font-medium outline-none transition-all focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0 bg-primary text-primary-foreground shadow-xs hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50 rounded-full h-9 px-4 py-2 has-[>svg]:px-3"
|
||||
bind:this={gotoDashboardBtn}
|
||||
onclick={() => goto('/dashboard')}
|
||||
>
|
||||
Go to Dashboard <ArrowRight size={32}/>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="m-16 flex items-center justify-center">
|
||||
<button
|
||||
id="goto_dash_btn"
|
||||
class="inline-flex h-9 shrink-0 items-center justify-center gap-2 rounded-full bg-primary px-4 py-2 text-sm font-medium whitespace-nowrap text-primary-foreground shadow-xs transition-all outline-none hover:bg-accent hover:text-accent-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 has-[>svg]:px-3 aria-disabled:pointer-events-none aria-disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:hover:bg-accent/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
|
||||
bind:this={gotoDashboardBtn}
|
||||
onclick={() => goto('/dashboard')}
|
||||
>
|
||||
Go to Dashboard <ArrowRight size={32} />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { get } from 'svelte/store';
|
|||
|
||||
export async function load({ cookies, params }) {
|
||||
let dep = cookies.get('department');
|
||||
console.log('load recipe ', dep);
|
||||
console.log('load recipe ', dep, params);
|
||||
let recipes = await getRecipes();
|
||||
recipes = get(recipeData);
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,13 @@
|
|||
import DataTable from './data-table.svelte';
|
||||
import { columns, type RecipeOverview } from './columns';
|
||||
import { onDestroy, onMount } from 'svelte';
|
||||
import { loadRecipe, recipeData } from '$lib/core/stores/recipeStore.js';
|
||||
import {
|
||||
loadRecipe,
|
||||
recipeData,
|
||||
recipeFromServerQuery,
|
||||
recipeOverviewData,
|
||||
referenceFromPage
|
||||
} from '$lib/core/stores/recipeStore.js';
|
||||
import { sendMessage } from '$lib/core/handlers/ws_messageSender.js';
|
||||
import { auth } from '$lib/core/stores/auth.js';
|
||||
import { get } from 'svelte/store';
|
||||
|
|
@ -16,7 +22,7 @@
|
|||
recipes: []
|
||||
});
|
||||
|
||||
let unsubRecipeData = recipeData.subscribe((rd) => {
|
||||
let unsubRecipeData = recipeOverviewData.subscribe((rd) => {
|
||||
if (rd) {
|
||||
data.recipes = rd == null ? [] : rd;
|
||||
}
|
||||
|
|
@ -25,6 +31,7 @@
|
|||
onMount(async () => {
|
||||
// do load recipe
|
||||
// loadRecipe();
|
||||
referenceFromPage.set('overview');
|
||||
await getRecipes();
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -10,78 +10,22 @@
|
|||
import { TerminalComponent } from '$lib/components/ui/terminal';
|
||||
import { onMount } from 'svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
import { auth } from '$lib/core/client/firebase';
|
||||
|
||||
import { auth as authStore } from '$lib/core/stores/auth';
|
||||
import { auth } from '$lib/core/client/firebase';
|
||||
import { get } from 'svelte/store';
|
||||
|
||||
// const device = await usb.requestDevice({
|
||||
// filters: [
|
||||
// {
|
||||
// vendorId: 0x18d1
|
||||
// }
|
||||
// ]
|
||||
// });
|
||||
onMount(() => {
|
||||
let existed_account = get(authStore);
|
||||
let current_user_logged = auth.currentUser;
|
||||
console.log(
|
||||
`has acc ${JSON.stringify(existed_account)}, from session: ${JSON.stringify(current_user_logged)}`
|
||||
);
|
||||
|
||||
let recipe: any | undefined = undefined;
|
||||
|
||||
async function test_adb() {
|
||||
try {
|
||||
if (!('usb' in navigator)) {
|
||||
throw new Error('WebUSB not supported, try using fallback');
|
||||
}
|
||||
|
||||
await adb.connnectViaWebUSB();
|
||||
|
||||
let instance = adb.getAdbInstance();
|
||||
|
||||
if (instance) {
|
||||
console.log('create instance ok');
|
||||
let result = await adb.executeCmd(
|
||||
'am start -n com.forthvending.coffeemain/com.forthvending.coffeemain.MainActivity'
|
||||
);
|
||||
console.log(result);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
if (existed_account || current_user_logged) {
|
||||
goto('/entry');
|
||||
}
|
||||
}
|
||||
|
||||
async function test_send_command() {
|
||||
try {
|
||||
if (!('usb' in navigator)) {
|
||||
throw new Error('WebUSB not supported, try using fallback');
|
||||
}
|
||||
|
||||
let instance = adb.getAdbInstance();
|
||||
|
||||
if (instance) {
|
||||
let txt = document.getElementById('cmd-input') as HTMLInputElement;
|
||||
|
||||
console.log('instance existed, ', txt.value);
|
||||
let result = await adb.executeCmd(txt.value ?? '');
|
||||
console.log(result);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
async function test_pull_recipe_dev() {
|
||||
try {
|
||||
if (!('usb' in navigator)) {
|
||||
throw new Error('WebUSB not supported, try using fallback');
|
||||
}
|
||||
let instance = adb.getAdbInstance();
|
||||
if (instance) {
|
||||
let result = await adb.pull('/sdcard/coffeevending/cfg/recipe_branch_dev.json');
|
||||
let payload = JSON.parse(result ?? '');
|
||||
console.log(payload);
|
||||
recipe = payload;
|
||||
alert('pull completed!');
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(`[PULL] ${e}`);
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<!--
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue