feat(stores): sync vehicles
This commit is contained in:
@ -10,10 +10,9 @@
|
|||||||
} from "@lucide/svelte";
|
} from "@lucide/svelte";
|
||||||
import Button, { buttonVariants } from "../ui/button/button.svelte";
|
import Button, { buttonVariants } from "../ui/button/button.svelte";
|
||||||
import {
|
import {
|
||||||
|
addVehicle,
|
||||||
isValidFuel,
|
isValidFuel,
|
||||||
selectVehicle,
|
selectVehicle,
|
||||||
setVehicles,
|
|
||||||
vehicles,
|
|
||||||
type Vehicle,
|
type Vehicle,
|
||||||
type VehicleType,
|
type VehicleType,
|
||||||
} from "$lib/vehicles/vehicles.svelte";
|
} from "$lib/vehicles/vehicles.svelte";
|
||||||
@ -183,9 +182,10 @@
|
|||||||
alert(m["vehicles.add.errors.select-fuel"]());
|
alert(m["vehicles.add.errors.select-fuel"]());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setVehicles([...vehicles, vehicle]);
|
// setVehicles([...vehicles.current, vehicle]);
|
||||||
|
addVehicle(vehicle);
|
||||||
selectVehicle(vehicle);
|
selectVehicle(vehicle);
|
||||||
location.reload(); // TODO
|
// location.reload(); // TODO
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<SaveIcon />
|
<SaveIcon />
|
||||||
|
|||||||
@ -55,18 +55,18 @@
|
|||||||
>
|
>
|
||||||
</Drawer.Header>
|
</Drawer.Header>
|
||||||
<div class="p-4 pt-0 flex flex-col gap-2">
|
<div class="p-4 pt-0 flex flex-col gap-2">
|
||||||
{#each vehicles as vehicle (vehicle.name)}
|
{#each vehicles.current as vehicle (vehicle.name)}
|
||||||
<Button
|
<Button
|
||||||
variant={selectedVehicle() === vehicle ? "default" : "secondary"}
|
variant={selectedVehicle() === vehicle.data ? "default" : "secondary"}
|
||||||
class="w-full p-5"
|
class="w-full p-5"
|
||||||
onclick={() => {
|
onclick={() => {
|
||||||
selectVehicle(vehicle);
|
selectVehicle(vehicle.data);
|
||||||
open = false;
|
open = false;
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{@const Icon = getVehicleIcon(vehicle.type)}
|
{@const Icon = getVehicleIcon(vehicle.data.type)}
|
||||||
<Icon />
|
<Icon />
|
||||||
{vehicle.name}
|
{vehicle.data.name}
|
||||||
</Button>
|
</Button>
|
||||||
{/each}
|
{/each}
|
||||||
|
|
||||||
|
|||||||
@ -17,6 +17,12 @@ export interface StoreInfo {
|
|||||||
name: string;
|
name: string;
|
||||||
type: StoreType;
|
type: StoreType;
|
||||||
}
|
}
|
||||||
|
export interface WrappedValue<T> {
|
||||||
|
current: T;
|
||||||
|
}
|
||||||
|
export type StoreValue<T> = {
|
||||||
|
data: T;
|
||||||
|
} & Omit<Store, "data">;
|
||||||
|
|
||||||
interface TCDB extends DBSchema {
|
interface TCDB extends DBSchema {
|
||||||
stores: {
|
stores: {
|
||||||
@ -145,25 +151,25 @@ export async function updateStore(info: StoreInfo, data: object | null) {
|
|||||||
// return state;
|
// return state;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
export function stores<T extends object>(type: StoreType) {
|
export function stores<T extends object>(type: StoreType): WrappedValue<StoreValue<T>[]> {
|
||||||
const state = $state<T[]>([]);
|
const state = $state<StoreValue<T>[]>([]);
|
||||||
eventTarget.addEventListener("store-updated", async (event) => {
|
eventTarget.addEventListener("store-updated", async (event) => {
|
||||||
const customEvent = event as CustomEvent;
|
const customEvent = event as CustomEvent;
|
||||||
const updatedStore = customEvent.detail as Store;
|
const updatedStore = customEvent.detail as Store;
|
||||||
if(updatedStore.type === type) {
|
if(updatedStore.type === type) {
|
||||||
const stores = await db.getAllFromIndex("stores", "by-type", type);
|
const stores = await db.getAllFromIndex("stores", "by-type", type);
|
||||||
state.splice(0, state.length, ...(stores.map(store => JSON.parse(store.data) as T).filter(store => store !== null)));
|
state.splice(0, state.length, ...(stores.map(store => ({ ...store, data: JSON.parse(store.data) as T })).filter(store => store.data !== null)));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
(async () => {
|
(async () => {
|
||||||
const stores = await db.getAllFromIndex("stores", "by-type", type);
|
const stores = await db.getAllFromIndex("stores", "by-type", type);
|
||||||
state.splice(0, state.length, ...(stores.map(store => JSON.parse(store.data) as T).filter(store => store !== null)));
|
state.splice(0, state.length, ...(stores.map(store => ({ ...store, data: JSON.parse(store.data) as T })).filter(store => store.data !== null)));
|
||||||
})();
|
})();
|
||||||
return {
|
return {
|
||||||
get current() {
|
get current() {
|
||||||
return state;
|
return state;
|
||||||
},
|
},
|
||||||
set current(newValue: T[]) {
|
set current(newValue: StoreValue<T>[]) {
|
||||||
state.splice(0, state.length, ...newValue);
|
state.splice(0, state.length, ...newValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { m } from "$lang/messages";
|
import { m } from "$lang/messages";
|
||||||
|
import { stores, updateStore, type StoreValue, type WrappedValue } from "$lib/services/stores.svelte";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Valhalla costing:
|
Valhalla costing:
|
||||||
@ -71,11 +72,7 @@ export const DefaultVehicle: Vehicle = {
|
|||||||
interface StateValue<T> {
|
interface StateValue<T> {
|
||||||
v: T;
|
v: T;
|
||||||
}
|
}
|
||||||
export const vehicles: Vehicle[] = $state(
|
export const vehicles: WrappedValue<StoreValue<Vehicle>[]> = stores("vehicle");
|
||||||
localStorage.getItem("vehicles")
|
|
||||||
? JSON.parse(localStorage.getItem("vehicles")!)
|
|
||||||
: [],
|
|
||||||
);
|
|
||||||
export const selectedVehicleIdx: StateValue<number | null> = $state({
|
export const selectedVehicleIdx: StateValue<number | null> = $state({
|
||||||
v: localStorage.getItem("selectedVehicle")
|
v: localStorage.getItem("selectedVehicle")
|
||||||
? parseInt(localStorage.getItem("selectedVehicle")!)
|
? parseInt(localStorage.getItem("selectedVehicle")!)
|
||||||
@ -83,23 +80,27 @@ export const selectedVehicleIdx: StateValue<number | null> = $state({
|
|||||||
});
|
});
|
||||||
export const selectedVehicle: () => Vehicle | null = () => {
|
export const selectedVehicle: () => Vehicle | null = () => {
|
||||||
return (
|
return (
|
||||||
vehicles[selectedVehicleIdx.v !== null ? selectedVehicleIdx.v : 0] || null
|
vehicles.current[selectedVehicleIdx.v !== null ? selectedVehicleIdx.v : 0]?.data ?? null
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export function setVehicles(_vehicles: Vehicle[]) {
|
// export function setVehicles(_vehicles: Vehicle[]) {
|
||||||
// vehicles = _vehicles;
|
// // vehicles = _vehicles;
|
||||||
// Hack to update without reassigning the array
|
// // Hack to update without reassigning the array
|
||||||
vehicles.length = 0;
|
// vehicles.current.length = 0;
|
||||||
_vehicles.forEach((vehicle) => vehicles.push(vehicle));
|
// // _vehicles.forEach((vehicle) => vehicles.current.push({ data: vehicle }));
|
||||||
localStorage.setItem("vehicles", JSON.stringify(vehicles));
|
// // localStorage.setItem("vehicles", JSON.stringify(vehicles));
|
||||||
|
// }
|
||||||
|
|
||||||
|
export async function addVehicle(vehicle: Vehicle) {
|
||||||
|
await updateStore({ name: vehicle.name, type: "vehicle" }, vehicle);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function selectVehicle(vehicle: Vehicle | null) {
|
export function selectVehicle(vehicle: Vehicle | null) {
|
||||||
if (vehicle == null) {
|
if (vehicle == null) {
|
||||||
selectedVehicleIdx.v = null;
|
selectedVehicleIdx.v = null;
|
||||||
} else {
|
} else {
|
||||||
selectedVehicleIdx.v = vehicles.findIndex((v) => v.name === vehicle.name);
|
selectedVehicleIdx.v = vehicles.current.findIndex((v) => v.name === vehicle.name);
|
||||||
if (selectedVehicleIdx.v === -1) {
|
if (selectedVehicleIdx.v === -1) {
|
||||||
selectedVehicleIdx.v = null;
|
selectedVehicleIdx.v = null;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user