2018-09-14 13:47:32 -06:00
|
|
|
import { RouteConfig } from "takeme";
|
|
|
|
import { Apology } from "./apology";
|
|
|
|
|
2018-09-21 06:04:18 -06:00
|
|
|
/** 99% of route configurations will use this interface. */
|
2018-09-20 17:46:11 -06:00
|
|
|
interface UnboundRouteConfigNoChild<T> {
|
|
|
|
children: false,
|
2018-09-14 13:47:32 -06:00
|
|
|
$: string;
|
|
|
|
getModule: () => Promise<T>;
|
|
|
|
key: keyof T;
|
|
|
|
}
|
|
|
|
|
2018-09-21 06:04:18 -06:00
|
|
|
/** A few routes (in the FarmDesigner, mainly) need to use child routes.
|
|
|
|
* If that's the case, set `children: true` and pass in a `getChild`/`childKey`
|
|
|
|
* property.
|
|
|
|
*/
|
2018-09-20 17:46:11 -06:00
|
|
|
interface UnboundRouteConfigChild<T, U> {
|
|
|
|
children: true,
|
|
|
|
$: string;
|
|
|
|
getModule: () => Promise<T>;
|
|
|
|
key: keyof T;
|
|
|
|
getChild: () => Promise<U>;
|
|
|
|
childKey: keyof U;
|
|
|
|
}
|
|
|
|
|
2018-09-21 06:04:18 -06:00
|
|
|
/** The union of both route config types. */
|
2018-09-21 08:09:30 -06:00
|
|
|
export type UnboundRouteConfig<T, U> =
|
2018-09-20 17:46:11 -06:00
|
|
|
UnboundRouteConfigNoChild<T> | UnboundRouteConfigChild<T, U>;
|
2018-09-21 06:04:18 -06:00
|
|
|
/** This is the preferred way to generate a route in the app.
|
2018-09-17 08:25:11 -06:00
|
|
|
* PROBLEM:
|
|
|
|
* 1. We want to lazy load each route's component to shrink the bundle size.
|
2018-09-21 06:04:18 -06:00
|
|
|
* 2. We don't have access to `this.setState()` until runtime because `this`
|
|
|
|
* is a mounted component.
|
2018-09-17 08:25:11 -06:00
|
|
|
* SOLUTION:
|
|
|
|
* Write a helper function that creates a route in multiple steps.
|
2018-09-21 06:04:18 -06:00
|
|
|
* 1. Pass in an object (UnboundRouteConfig<T, U>) that describes:
|
2018-09-17 08:25:11 -06:00
|
|
|
* * the URL
|
|
|
|
* * The module's file location (dynamic `import()` that returns the module
|
|
|
|
* as a promise)
|
2018-09-21 06:04:18 -06:00
|
|
|
* * The specific module that you want to use for the route.
|
|
|
|
* * (optional) a set of child routes (like the FarmDesigner side panel)
|
2018-09-17 08:25:11 -06:00
|
|
|
* 2. Once that information is available, we can create an "unbound route".
|
|
|
|
* An unbound route is a function that has all needed URL / module
|
|
|
|
* information but does NOT yet have a callback to trigger when a route
|
|
|
|
* changes. Such a function is generated later (at runtime, in
|
|
|
|
* componentDidMount) and passed to the "unbound" route to create a "real"
|
|
|
|
* URL route that is needed by the `takeme` routing library.
|
|
|
|
* Workflow:
|
2018-09-21 06:04:18 -06:00
|
|
|
*
|
|
|
|
* Determine how to load the route and children =>
|
|
|
|
* Pass that information to route() =>
|
|
|
|
* Pass the resulting UnboundRoute to `takeme` router. =>
|
2018-09-17 08:25:11 -06:00
|
|
|
* DONE.
|
|
|
|
*/
|
2018-09-20 17:46:11 -06:00
|
|
|
function route<T, U>(info: UnboundRouteConfig<T, U>) {
|
2018-09-14 13:47:32 -06:00
|
|
|
return (callback: Function): RouteConfig => {
|
2018-09-20 17:46:11 -06:00
|
|
|
const { $ } = info;
|
2018-09-14 13:47:32 -06:00
|
|
|
return {
|
|
|
|
$,
|
2019-08-15 13:19:01 -06:00
|
|
|
enter: async () => {
|
2018-09-14 13:47:32 -06:00
|
|
|
try {
|
2018-09-20 17:46:11 -06:00
|
|
|
const comp = (await info.getModule())[info.key];
|
|
|
|
if (info.children) {
|
|
|
|
const child = (await info.getChild())[info.childKey];
|
2018-09-21 08:09:30 -06:00
|
|
|
callback(comp, child, info);
|
2018-09-20 17:46:11 -06:00
|
|
|
} else {
|
2019-03-11 20:34:49 -06:00
|
|
|
callback(comp, undefined, info);
|
2018-09-20 17:46:11 -06:00
|
|
|
}
|
2018-09-14 13:47:32 -06:00
|
|
|
} catch (e) {
|
|
|
|
console.error(e);
|
2018-09-20 17:46:11 -06:00
|
|
|
callback(Apology);
|
2018-09-14 13:47:32 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2018-09-17 08:25:11 -06:00
|
|
|
/** The 404 handler. All unresolved routes end up here. MUST BE LAST ITEM IN
|
|
|
|
* ROUTE CONFIG!!! */
|
2018-09-20 17:09:05 -06:00
|
|
|
export const NOT_FOUND_ROUTE = route({
|
2018-09-20 17:46:11 -06:00
|
|
|
children: false,
|
2018-09-14 13:47:32 -06:00
|
|
|
$: "*",
|
|
|
|
getModule: () => import("./404"),
|
|
|
|
key: "FourOhFour"
|
2018-09-17 08:25:11 -06:00
|
|
|
});
|
2018-09-14 13:47:32 -06:00
|
|
|
|
2018-09-20 17:46:11 -06:00
|
|
|
const getModule = () => import("./farm_designer");
|
|
|
|
const key = "FarmDesigner";
|
|
|
|
|
2018-09-17 08:25:11 -06:00
|
|
|
/** Bind the route to a callback by calling in a function that passes the
|
2018-09-21 06:04:18 -06:00
|
|
|
callback in as the first argument.
|
|
|
|
*
|
2019-03-11 20:34:49 -06:00
|
|
|
* DO NOT RE-ORDER ITEMS FOR READABILITY--they are order-dependent.
|
2018-09-21 06:04:18 -06:00
|
|
|
* Stuff will break if the route order is changed.
|
2019-08-23 15:18:28 -06:00
|
|
|
* (e.g., must be ["a", "a/b", "a/b/:c/d", "a/b/:c", "a/:e"],
|
|
|
|
* 404 must be last, etc.)
|
2018-09-17 08:25:11 -06:00
|
|
|
*/
|
|
|
|
export const UNBOUND_ROUTES = [
|
|
|
|
route({
|
2018-09-20 17:46:11 -06:00
|
|
|
children: false,
|
2018-09-17 08:25:11 -06:00
|
|
|
$: "/account",
|
|
|
|
getModule: () => import("./account"),
|
2018-09-20 17:46:11 -06:00
|
|
|
key: "Account",
|
2018-09-17 08:25:11 -06:00
|
|
|
}),
|
2018-10-15 17:23:58 -06:00
|
|
|
route({
|
|
|
|
children: false,
|
|
|
|
$: "/help",
|
|
|
|
getModule: () => import("./help/help"),
|
|
|
|
key: "Help",
|
|
|
|
}),
|
2018-09-17 08:25:11 -06:00
|
|
|
route({
|
2018-09-20 17:46:11 -06:00
|
|
|
children: false,
|
2018-09-17 08:25:11 -06:00
|
|
|
$: "/controls",
|
|
|
|
getModule: () => import("./controls/controls"),
|
2018-09-20 17:46:11 -06:00
|
|
|
key: "Controls",
|
2018-09-17 08:25:11 -06:00
|
|
|
}),
|
|
|
|
route({
|
2018-09-20 17:46:11 -06:00
|
|
|
children: false,
|
2018-09-17 08:25:11 -06:00
|
|
|
$: "/device",
|
|
|
|
getModule: () => import("./devices/devices"),
|
2018-09-20 17:46:11 -06:00
|
|
|
key: "Devices",
|
2018-09-17 08:25:11 -06:00
|
|
|
}),
|
|
|
|
route({
|
2018-09-20 17:46:11 -06:00
|
|
|
children: false,
|
2018-09-18 14:26:13 -06:00
|
|
|
$: "/farmware(/:name)",
|
2018-09-17 08:25:11 -06:00
|
|
|
getModule: () => import("./farmware"),
|
2018-09-20 17:46:11 -06:00
|
|
|
key: "FarmwarePage",
|
2018-09-17 08:25:11 -06:00
|
|
|
}),
|
|
|
|
route({
|
2018-09-20 17:46:11 -06:00
|
|
|
children: false,
|
2018-09-17 08:25:11 -06:00
|
|
|
$: "/logs",
|
|
|
|
getModule: () => import("./logs"),
|
2018-09-20 17:46:11 -06:00
|
|
|
key: "Logs",
|
2018-09-17 08:25:11 -06:00
|
|
|
}),
|
|
|
|
route({
|
2019-04-16 11:03:44 -06:00
|
|
|
children: false,
|
|
|
|
$: "/messages",
|
|
|
|
getModule: () => import("./messages"),
|
|
|
|
key: "Messages",
|
|
|
|
}),
|
|
|
|
route({
|
2018-09-20 17:46:11 -06:00
|
|
|
children: false,
|
2018-09-18 14:26:13 -06:00
|
|
|
$: "/regimens(/:regimen)",
|
2018-09-17 08:25:11 -06:00
|
|
|
getModule: () => import("./regimens"),
|
2018-09-20 17:46:11 -06:00
|
|
|
key: "Regimens",
|
2018-09-17 08:25:11 -06:00
|
|
|
}),
|
|
|
|
route({
|
2018-09-20 17:46:11 -06:00
|
|
|
children: false,
|
2018-09-17 08:25:11 -06:00
|
|
|
$: "/sequences(/:sequence)",
|
|
|
|
getModule: () => import("./sequences/sequences"),
|
2018-09-20 17:46:11 -06:00
|
|
|
key: "Sequences",
|
2018-09-17 08:25:11 -06:00
|
|
|
}),
|
2018-09-20 17:46:11 -06:00
|
|
|
route({
|
|
|
|
children: false,
|
|
|
|
$: "/designer",
|
|
|
|
getModule: () => import("./farm_designer"),
|
|
|
|
key: "FarmDesigner"
|
|
|
|
}),
|
|
|
|
route({
|
|
|
|
children: true,
|
2019-04-09 19:52:12 -06:00
|
|
|
$: "/designer/events",
|
2018-09-20 17:46:11 -06:00
|
|
|
getModule,
|
|
|
|
key,
|
|
|
|
getChild: () => import("./farm_designer/farm_events/farm_events"),
|
|
|
|
childKey: "FarmEvents"
|
|
|
|
}),
|
|
|
|
route({
|
|
|
|
children: true,
|
2019-04-09 19:52:12 -06:00
|
|
|
$: "/designer/events/add",
|
2018-09-20 17:46:11 -06:00
|
|
|
getModule,
|
|
|
|
key,
|
|
|
|
getChild: () => import("./farm_designer/farm_events/add_farm_event"),
|
|
|
|
childKey: "AddFarmEvent"
|
|
|
|
}),
|
|
|
|
route({
|
|
|
|
children: true,
|
2019-04-09 19:52:12 -06:00
|
|
|
$: "/designer/events/:farm_event_id",
|
2018-09-20 17:46:11 -06:00
|
|
|
getModule,
|
|
|
|
key,
|
|
|
|
getChild: () => import("./farm_designer/farm_events/edit_farm_event"),
|
|
|
|
childKey: "EditFarmEvent"
|
|
|
|
}),
|
|
|
|
route({
|
|
|
|
children: true,
|
|
|
|
$: "/designer/plants",
|
|
|
|
getModule,
|
|
|
|
key,
|
|
|
|
getChild: () => import("./farm_designer/plants/plant_inventory"),
|
|
|
|
childKey: "Plants"
|
|
|
|
}),
|
|
|
|
route({
|
|
|
|
children: true,
|
2019-03-05 11:59:22 -07:00
|
|
|
$: "/designer/move_to",
|
2018-09-20 17:46:11 -06:00
|
|
|
getModule,
|
|
|
|
key,
|
2019-03-05 11:59:22 -07:00
|
|
|
getChild: () => import("./farm_designer/move_to"),
|
2018-09-20 17:46:11 -06:00
|
|
|
childKey: "MoveTo"
|
|
|
|
}),
|
|
|
|
route({
|
|
|
|
children: true,
|
2019-11-06 10:01:05 -07:00
|
|
|
$: "/designer/plants/gardens",
|
2018-09-20 17:46:11 -06:00
|
|
|
getModule,
|
|
|
|
key,
|
|
|
|
getChild: () => import("./farm_designer/saved_gardens/saved_gardens"),
|
|
|
|
childKey: "SavedGardens"
|
|
|
|
}),
|
|
|
|
route({
|
|
|
|
children: true,
|
|
|
|
$: "/designer/plants/select",
|
|
|
|
getModule,
|
|
|
|
key,
|
|
|
|
getChild: () => import("./farm_designer/plants/select_plants"),
|
|
|
|
childKey: "SelectPlants"
|
|
|
|
}),
|
|
|
|
route({
|
|
|
|
children: true,
|
2019-08-23 15:18:28 -06:00
|
|
|
$: "/designer/points",
|
|
|
|
getModule,
|
|
|
|
key,
|
2019-12-10 13:09:52 -07:00
|
|
|
getChild: () => import("./farm_designer/points/point_inventory"),
|
2019-08-23 15:18:28 -06:00
|
|
|
childKey: "Points"
|
|
|
|
}),
|
|
|
|
route({
|
|
|
|
children: true,
|
|
|
|
$: "/designer/points/add",
|
2018-09-20 17:46:11 -06:00
|
|
|
getModule,
|
|
|
|
key,
|
2019-12-10 13:09:52 -07:00
|
|
|
getChild: () => import("./farm_designer/points/create_points"),
|
2018-09-20 17:46:11 -06:00
|
|
|
childKey: "CreatePoints"
|
|
|
|
}),
|
2019-08-23 15:18:28 -06:00
|
|
|
route({
|
|
|
|
children: true,
|
|
|
|
$: "/designer/points/:point_id",
|
|
|
|
getModule,
|
|
|
|
key,
|
2019-12-10 13:09:52 -07:00
|
|
|
getChild: () => import("./farm_designer/points/point_info"),
|
2019-08-23 15:18:28 -06:00
|
|
|
childKey: "EditPoint"
|
|
|
|
}),
|
2018-09-20 17:46:11 -06:00
|
|
|
route({
|
|
|
|
children: true,
|
|
|
|
$: "/designer/plants/crop_search",
|
|
|
|
getModule,
|
|
|
|
key,
|
|
|
|
getChild: () => import("./farm_designer/plants/crop_catalog"),
|
|
|
|
childKey: "CropCatalog"
|
|
|
|
}),
|
|
|
|
route({
|
|
|
|
children: true,
|
|
|
|
$: "/designer/plants/crop_search/:crop/add",
|
|
|
|
getModule,
|
|
|
|
key,
|
|
|
|
getChild: () => import("./farm_designer/plants/add_plant"),
|
|
|
|
childKey: "AddPlant"
|
|
|
|
}),
|
|
|
|
route({
|
|
|
|
children: true,
|
|
|
|
$: "/designer/plants/crop_search/:crop",
|
|
|
|
getModule,
|
|
|
|
key,
|
|
|
|
getChild: () => import("./farm_designer/plants/crop_info"),
|
|
|
|
childKey: "CropInfo"
|
|
|
|
}),
|
|
|
|
route({
|
|
|
|
children: true,
|
|
|
|
$: "/designer/plants/:plant_id",
|
|
|
|
getModule,
|
|
|
|
key,
|
|
|
|
getChild: () => import("./farm_designer/plants/plant_info"),
|
|
|
|
childKey: "PlantInfo"
|
|
|
|
}),
|
|
|
|
route({
|
|
|
|
children: true,
|
2019-11-06 10:01:05 -07:00
|
|
|
$: "/designer/gardens",
|
2018-09-20 17:46:11 -06:00
|
|
|
getModule,
|
|
|
|
key,
|
|
|
|
getChild: () => import("./farm_designer/saved_gardens/saved_gardens"),
|
|
|
|
childKey: "SavedGardens"
|
|
|
|
}),
|
|
|
|
route({
|
|
|
|
children: true,
|
2019-11-06 10:01:05 -07:00
|
|
|
$: "/designer/gardens/templates",
|
2018-09-20 17:46:11 -06:00
|
|
|
getModule,
|
|
|
|
key,
|
|
|
|
getChild: () => import("./farm_designer/plants/plant_inventory"),
|
|
|
|
childKey: "Plants"
|
|
|
|
}),
|
|
|
|
route({
|
|
|
|
children: true,
|
2019-11-06 10:01:05 -07:00
|
|
|
$: "/designer/gardens/templates/:plant_template_id",
|
2018-09-20 17:46:11 -06:00
|
|
|
getModule,
|
|
|
|
key,
|
|
|
|
getChild: () => import("./farm_designer/plants/plant_info"),
|
|
|
|
childKey: "PlantInfo"
|
|
|
|
}),
|
|
|
|
route({
|
|
|
|
children: true,
|
2019-11-06 10:01:05 -07:00
|
|
|
$: "/designer/gardens/add",
|
2018-09-20 17:46:11 -06:00
|
|
|
getModule,
|
|
|
|
key,
|
2019-11-06 10:01:05 -07:00
|
|
|
getChild: () => import("./farm_designer/saved_gardens/garden_add"),
|
|
|
|
childKey: "AddGarden"
|
|
|
|
}),
|
|
|
|
route({
|
|
|
|
children: true,
|
|
|
|
$: "/designer/gardens/:saved_garden_id",
|
|
|
|
getModule,
|
|
|
|
key,
|
|
|
|
getChild: () => import("./farm_designer/saved_gardens/garden_edit"),
|
|
|
|
childKey: "EditGarden"
|
2018-09-17 08:25:11 -06:00
|
|
|
}),
|
2019-06-10 15:43:11 -06:00
|
|
|
route({
|
|
|
|
children: true,
|
|
|
|
$: "/designer/settings",
|
|
|
|
getModule,
|
|
|
|
key,
|
|
|
|
getChild: () => import("./farm_designer/settings"),
|
|
|
|
childKey: "DesignerSettings"
|
|
|
|
}),
|
2019-08-23 15:18:28 -06:00
|
|
|
route({
|
|
|
|
children: true,
|
|
|
|
$: "/designer/tools",
|
|
|
|
getModule,
|
|
|
|
key,
|
|
|
|
getChild: () => import("./farm_designer/tools"),
|
|
|
|
childKey: "Tools"
|
|
|
|
}),
|
|
|
|
route({
|
|
|
|
children: true,
|
|
|
|
$: "/designer/tools/add",
|
|
|
|
getModule,
|
|
|
|
key,
|
|
|
|
getChild: () => import("./farm_designer/tools/add_tool"),
|
|
|
|
childKey: "AddTool"
|
|
|
|
}),
|
|
|
|
route({
|
|
|
|
children: true,
|
|
|
|
$: "/designer/tools/:tool_id",
|
|
|
|
getModule,
|
|
|
|
key,
|
|
|
|
getChild: () => import("./farm_designer/tools/edit_tool"),
|
|
|
|
childKey: "EditTool"
|
|
|
|
}),
|
2019-12-30 09:08:48 -07:00
|
|
|
route({
|
|
|
|
children: true,
|
|
|
|
$: "/designer/tool-slots/add",
|
|
|
|
getModule,
|
|
|
|
key,
|
|
|
|
getChild: () => import("./farm_designer/tools/add_tool_slot"),
|
|
|
|
childKey: "AddToolSlot"
|
|
|
|
}),
|
|
|
|
route({
|
|
|
|
children: true,
|
|
|
|
$: "/designer/tool-slots/:tool_id",
|
|
|
|
getModule,
|
|
|
|
key,
|
|
|
|
getChild: () => import("./farm_designer/tools/edit_tool_slot"),
|
|
|
|
childKey: "EditToolSlot"
|
|
|
|
}),
|
2019-08-06 14:00:58 -06:00
|
|
|
route({
|
|
|
|
children: true,
|
|
|
|
$: "/designer/groups",
|
|
|
|
getModule,
|
|
|
|
key,
|
2019-08-06 14:58:00 -06:00
|
|
|
getChild: () => import("./farm_designer/point_groups/group_list_panel"),
|
2019-08-06 14:00:58 -06:00
|
|
|
childKey: "GroupListPanel"
|
|
|
|
}),
|
2019-08-06 14:58:00 -06:00
|
|
|
route({
|
|
|
|
children: true,
|
|
|
|
$: "/designer/groups/:group_id",
|
|
|
|
getModule,
|
|
|
|
key,
|
|
|
|
getChild: () => import("./farm_designer/point_groups/group_detail"),
|
|
|
|
childKey: "GroupDetail"
|
|
|
|
}),
|
2019-10-23 14:08:38 -06:00
|
|
|
route({
|
|
|
|
children: true,
|
|
|
|
$: "/designer/weeds",
|
|
|
|
getModule,
|
|
|
|
key,
|
2020-04-02 10:53:55 -06:00
|
|
|
getChild: () => import("./farm_designer/weeds/weeds_inventory"),
|
2019-10-23 14:08:38 -06:00
|
|
|
childKey: "Weeds"
|
|
|
|
}),
|
|
|
|
route({
|
|
|
|
children: true,
|
|
|
|
$: "/designer/weeds/add",
|
|
|
|
getModule,
|
|
|
|
key,
|
2019-12-10 13:09:52 -07:00
|
|
|
getChild: () => import("./farm_designer/points/create_points"),
|
2019-11-07 12:17:50 -07:00
|
|
|
childKey: "CreatePoints"
|
2019-10-23 14:08:38 -06:00
|
|
|
}),
|
|
|
|
route({
|
|
|
|
children: true,
|
|
|
|
$: "/designer/weeds/:point_id",
|
|
|
|
getModule,
|
|
|
|
key,
|
2020-04-02 10:53:55 -06:00
|
|
|
getChild: () => import("./farm_designer/weeds/weeds_edit"),
|
2019-10-23 14:08:38 -06:00
|
|
|
childKey: "EditWeed"
|
|
|
|
}),
|
|
|
|
route({
|
|
|
|
children: true,
|
|
|
|
$: "/designer/zones",
|
|
|
|
getModule,
|
|
|
|
key,
|
|
|
|
getChild: () => import("./farm_designer/zones/zones_inventory"),
|
|
|
|
childKey: "Zones"
|
|
|
|
}),
|
|
|
|
route({
|
|
|
|
children: true,
|
|
|
|
$: "/designer/zones/add",
|
|
|
|
getModule,
|
|
|
|
key,
|
|
|
|
getChild: () => import("./farm_designer/zones/add_zone"),
|
|
|
|
childKey: "AddZone"
|
|
|
|
}),
|
|
|
|
route({
|
|
|
|
children: true,
|
|
|
|
$: "/designer/zones/:zone_id",
|
|
|
|
getModule,
|
|
|
|
key,
|
|
|
|
getChild: () => import("./farm_designer/zones/edit_zone"),
|
|
|
|
childKey: "EditZone"
|
|
|
|
}),
|
2018-09-20 17:46:11 -06:00
|
|
|
].concat([NOT_FOUND_ROUTE]);
|