Farmbot-Web-App/frontend/route_config.tsx

423 lines
11 KiB
TypeScript
Raw Normal View History

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.
* 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.
* 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:
* * 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)
* 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. =>
* 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
}
}
};
};
}
/** The 404 handler. All unresolved routes end up here. MUST BE LAST ITEM IN
* ROUTE CONFIG!!! */
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-14 13:47:32 -06:00
2018-09-20 17:46:11 -06:00
const getModule = () => import("./farm_designer");
const key = "FarmDesigner";
/** 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.)
*/
export const UNBOUND_ROUTES = [
route({
2018-09-20 17:46:11 -06:00
children: false,
$: "/account",
getModule: () => import("./account"),
2018-09-20 17:46:11 -06:00
key: "Account",
}),
2018-10-15 17:23:58 -06:00
route({
children: false,
$: "/help",
getModule: () => import("./help/help"),
key: "Help",
}),
route({
2018-09-20 17:46:11 -06:00
children: false,
$: "/controls",
getModule: () => import("./controls/controls"),
2018-09-20 17:46:11 -06:00
key: "Controls",
}),
route({
2018-09-20 17:46:11 -06:00
children: false,
$: "/device",
getModule: () => import("./devices/devices"),
2018-09-20 17:46:11 -06:00
key: "Devices",
}),
route({
2018-09-20 17:46:11 -06:00
children: false,
2018-09-18 14:26:13 -06:00
$: "/farmware(/:name)",
getModule: () => import("./farmware"),
2018-09-20 17:46:11 -06:00
key: "FarmwarePage",
}),
route({
2018-09-20 17:46:11 -06:00
children: false,
$: "/logs",
getModule: () => import("./logs"),
2018-09-20 17:46:11 -06:00
key: "Logs",
}),
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)",
getModule: () => import("./regimens"),
2018-09-20 17:46:11 -06:00
key: "Regimens",
}),
route({
2018-09-20 17:46:11 -06:00
children: false,
$: "/sequences(/:sequence)",
getModule: () => import("./sequences/sequences"),
2018-09-20 17:46:11 -06:00
key: "Sequences",
}),
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"
}),
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,
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,
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]);