mirror of
https://github.com/morten-olsen/bob-the-algorithm.git
synced 2026-02-08 00:46:25 +01:00
v3
This commit is contained in:
@@ -1,15 +1,18 @@
|
||||
import { createContext } from 'react';
|
||||
import { createDataContext } from '#/utils/data-context';
|
||||
import { Strategies } from "./algorithm/build-graph";
|
||||
|
||||
type PlannerOptions = {
|
||||
strategy: Strategies;
|
||||
}
|
||||
type PlannerContextValue = {
|
||||
options: PlannerOptions;
|
||||
setOptions: (options: Partial<PlannerOptions>) => void;
|
||||
}
|
||||
|
||||
const PlannerContext = createContext<PlannerContextValue>(undefined as any);
|
||||
const {
|
||||
Context: PlannerContext,
|
||||
Provider: PlannerProvider,
|
||||
} = createDataContext<PlannerOptions>({
|
||||
createDefault: () => ({
|
||||
strategy: Strategies.firstComplet,
|
||||
}),
|
||||
});
|
||||
|
||||
export type { PlannerContextValue, PlannerOptions };
|
||||
export { PlannerContext };
|
||||
export type { PlannerOptions };
|
||||
export { PlannerContext, PlannerProvider };
|
||||
|
||||
@@ -1,14 +1,8 @@
|
||||
import { useGetTransition } from "#/features/location";
|
||||
import { buildGraph, Status, Strategies } from "./algorithm/build-graph";
|
||||
import { constructDay } from "./algorithm/construct-day";
|
||||
import { useAsyncCallback } from "#/hooks/async";
|
||||
import { UserLocation } from "#/types/location";
|
||||
import { useDate } from "../calendar";
|
||||
import { useTasksWithContext } from "../agenda-context";
|
||||
import { useContext, useMemo, useState } from "react";
|
||||
import { useContext } from "react";
|
||||
import { PlanItem } from "#/types/plans";
|
||||
import { Task } from "#/types/task";
|
||||
import { PlannerContext } from "./context";
|
||||
import { Task, UserLocation } from "../data";
|
||||
|
||||
export type UsePlanOptions = {
|
||||
location: UserLocation;
|
||||
@@ -25,53 +19,16 @@ export type UsePlan = [
|
||||
]
|
||||
|
||||
export const usePlanOptions = () => {
|
||||
const { options } = useContext(PlannerContext);
|
||||
return options;
|
||||
const { data } = useContext(PlannerContext);
|
||||
return data;
|
||||
}
|
||||
|
||||
export const useSetPlanOptions = () => {
|
||||
const { setOptions } = useContext(PlannerContext);
|
||||
return setOptions;
|
||||
const { setData } = useContext(PlannerContext);
|
||||
return setData;
|
||||
}
|
||||
|
||||
export const usePlan = ({
|
||||
location,
|
||||
}: UsePlanOptions): UsePlan => {
|
||||
const today = useDate();
|
||||
const planOptions = usePlanOptions();
|
||||
const [status, setStatus] = useState<Status>();
|
||||
const all = useTasksWithContext();
|
||||
const enabled = useMemo(() => all.filter(f => f.enabled), [all])
|
||||
const getTransition = useGetTransition();
|
||||
const [invoke, options] = useAsyncCallback(
|
||||
async (start?: Date) => {
|
||||
const graph = await buildGraph({
|
||||
location,
|
||||
time: start || today,
|
||||
tasks: enabled,
|
||||
strategy: planOptions.strategy,
|
||||
context: {
|
||||
getTransition,
|
||||
},
|
||||
callback: setStatus,
|
||||
});
|
||||
const valid = graph.filter(a => !a.status.dead && a.status.completed).sort((a, b) => b.score - a.score);
|
||||
const day = constructDay(valid[0]);
|
||||
return {
|
||||
impossible: valid[0].impossibeTasks,
|
||||
agenda: day,
|
||||
};
|
||||
},
|
||||
[today, location, all, setStatus, planOptions],
|
||||
);
|
||||
|
||||
return [
|
||||
invoke,
|
||||
{
|
||||
result: options.result,
|
||||
loading: options.loading,
|
||||
error: options.error,
|
||||
status: status,
|
||||
}
|
||||
];
|
||||
export const usePlan = () => {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
export { PlannerProvider } from './provider';
|
||||
export type { PlannerOptions } from './context';
|
||||
export { PlannerProvider, PlannerOptions } from './context';
|
||||
export { Strategies } from './algorithm/build-graph';
|
||||
export * from './hooks';
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
import { ReactNode, useCallback, useState } from 'react';
|
||||
import { Strategies } from './algorithm/build-graph';
|
||||
import { PlannerContext, PlannerOptions } from './context';
|
||||
|
||||
type PlannerProviderProps = {
|
||||
children: ReactNode;
|
||||
};
|
||||
|
||||
const PlannerProvider: React.FC<PlannerProviderProps> = ({ children }) => {
|
||||
const [options, setOwnOptions] = useState<PlannerOptions>({
|
||||
strategy: Strategies.firstComplet,
|
||||
})
|
||||
|
||||
const setOptions = useCallback(
|
||||
(next: Partial<PlannerOptions>) => {
|
||||
setOwnOptions(current => ({
|
||||
...current,
|
||||
...next,
|
||||
}))
|
||||
},
|
||||
[setOwnOptions],
|
||||
);
|
||||
|
||||
return (
|
||||
<PlannerContext.Provider value={{ options, setOptions }}>
|
||||
{children}
|
||||
</PlannerContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export type { PlannerProviderProps };
|
||||
export { PlannerProvider };
|
||||
45
src/features/planner/types.ts
Normal file
45
src/features/planner/types.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
|
||||
type Context = {
|
||||
getTransition: GetTransition;
|
||||
};
|
||||
|
||||
export type PlannedTask = {
|
||||
type: 'task';
|
||||
name: string;
|
||||
start: Date;
|
||||
external?: boolean;
|
||||
end: Date;
|
||||
score: number;
|
||||
}
|
||||
|
||||
export type PlannedTransition = {
|
||||
type: 'transition';
|
||||
start: Date;
|
||||
end: Date;
|
||||
from: UserLocation;
|
||||
to: UserLocation;
|
||||
};
|
||||
|
||||
type GraphNode = {
|
||||
location: UserLocation;
|
||||
task?: Task;
|
||||
transition?: Transition;
|
||||
parent?: GraphNode;
|
||||
remainingTasks: Task[];
|
||||
impossibeTasks: Task[];
|
||||
score: number;
|
||||
time: {
|
||||
start: Date;
|
||||
end: Date;
|
||||
};
|
||||
status: {
|
||||
dead: boolean;
|
||||
completed: boolean;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
export type {
|
||||
GraphNode,
|
||||
Context,
|
||||
};
|
||||
Reference in New Issue
Block a user