UNSTABLE BUT FIXES THE ANIMATION ISSUES
parent
37a07747ec
commit
30d18947bf
|
@ -1,8 +1,8 @@
|
|||
import * as React from "react";
|
||||
import { RouteConfig } from "takeme";
|
||||
import { FarmDesigner } from "../farm_designer";
|
||||
// import { connect } from "react-redux";
|
||||
// import { Everything } from "../interfaces";
|
||||
import { connect } from "react-redux";
|
||||
import { Everything } from "../interfaces";
|
||||
import { CowardlyDictionary } from "../util";
|
||||
|
||||
export enum DesignerRouteName {
|
||||
DESIGNER_ROOT = "/designer",
|
||||
|
@ -26,20 +26,89 @@ export enum DesignerRouteName {
|
|||
SAVED_GARDEN_SHOW = "/designer/saved_gardens/:saved_garden_id",
|
||||
}
|
||||
|
||||
export const DESIGNER_ROUTES: DesignerRouteName[] =
|
||||
Object.values(DesignerRouteName);
|
||||
export const BIG_LOOKUP: CowardlyDictionary<() => Promise<React.ComponentType>> = {
|
||||
"/designer":
|
||||
async () => (await import("../farm_designer")).FarmDesigner,
|
||||
"/designer/farm_events": async () => {
|
||||
return (await import("../farm_designer/farm_events/farm_events")).FarmEvents;
|
||||
},
|
||||
"/designer/farm_events/add": async () => {
|
||||
const mod = (await import("../farm_designer/farm_events/add_farm_event"));
|
||||
return mod.AddFarmEvent;
|
||||
},
|
||||
"/designer/farm_events/:farm_event_id": async () => {
|
||||
const mod = await import("../farm_designer/farm_events/edit_farm_event");
|
||||
return mod.EditFarmEvent;
|
||||
},
|
||||
"/designer/plants": async () => {
|
||||
const mod = await import("../farm_designer/plants/plant_inventory");
|
||||
return mod.Plants;
|
||||
},
|
||||
"/designer/plants/move_to": async () => {
|
||||
const mod = await import("../farm_designer/plants/move_to");
|
||||
return mod.MoveTo;
|
||||
},
|
||||
"/designer/plants/saved_gardens": async () => {
|
||||
const mod = await import("../farm_designer/saved_gardens/saved_gardens");
|
||||
return mod.SavedGardens;
|
||||
},
|
||||
"/designer/plants/select": async () => {
|
||||
const mod = await import("../farm_designer/plants/select_plants");
|
||||
return mod.SelectPlants;
|
||||
},
|
||||
"/designer/plants/create_point": async () => {
|
||||
const mod = await import("../farm_designer/plants/create_points");
|
||||
return mod.CreatePoints;
|
||||
},
|
||||
"/designer/plants/crop_search": async () => {
|
||||
const mod = await import("../farm_designer/plants/crop_catalog");
|
||||
return mod.CropCatalog;
|
||||
},
|
||||
"/designer/plants/crop_search/:crop/add": async () => {
|
||||
const mod = await import("../farm_designer/plants/add_plant");
|
||||
return mod.AddPlant;
|
||||
},
|
||||
"/designer/plants/crop_search/:crop": async () => {
|
||||
const mod = await import("../farm_designer/plants/crop_info");
|
||||
return mod.CropInfo;
|
||||
},
|
||||
"/designer/plants/:plant_id/edit": async () => {
|
||||
const mod = await import("../farm_designer/plants/edit_plant_info");
|
||||
return mod.EditPlantInfo;
|
||||
},
|
||||
"/designer/plants/:plant_id": async () => {
|
||||
const mod = await import("../farm_designer/plants/plant_info");
|
||||
return mod.PlantInfo;
|
||||
},
|
||||
"/designer/saved_gardens": async () => {
|
||||
const mod = await import("../farm_designer/saved_gardens/saved_gardens");
|
||||
return mod.SavedGardens;
|
||||
},
|
||||
"/designer/saved_gardens/templates": async () => {
|
||||
const mod = await import("../farm_designer/plants/plant_inventory");
|
||||
return mod.Plants;
|
||||
},
|
||||
"/designer/saved_gardens/templates/:plant_template_id/edit": async () => {
|
||||
const mod = await import("../farm_designer/plants/edit_plant_info");
|
||||
return mod.EditPlantInfo;
|
||||
},
|
||||
"/designer/saved_gardens/templates/:plant_template_id": async () => {
|
||||
const mod = await import("../farm_designer/plants/plant_info");
|
||||
return mod.PlantInfo;
|
||||
},
|
||||
"/designer/saved_gardens/:saved_garden_id": async () => {
|
||||
const mod = await import("../farm_designer/saved_gardens/saved_gardens");
|
||||
return mod.SavedGardens;
|
||||
},
|
||||
};
|
||||
|
||||
interface ExperimentalProps {
|
||||
route: RouteConfig;
|
||||
localConfig: {};
|
||||
}
|
||||
export const DESIGNER_ROUTES: DesignerRouteName[] = Object
|
||||
.values(DesignerRouteName);
|
||||
|
||||
interface ExperimentalState {
|
||||
MapContents: React.ComponentType;
|
||||
}
|
||||
interface ExperimentalProps { route: string | undefined; }
|
||||
interface ExperimentalState { MapContents: React.ComponentType; }
|
||||
|
||||
type P = ExperimentalProps;
|
||||
|
||||
type S = ExperimentalState;
|
||||
|
||||
// @connect()ed components don't need props passed to them.
|
||||
|
@ -47,12 +116,24 @@ type S = ExperimentalState;
|
|||
// Some day, I will migrate to a typescript friendly react-redux alternative.
|
||||
const NOT_TYPE_SAFE: any = {};
|
||||
|
||||
@connect((s: Everything): P => {
|
||||
return { route: s.route.$ };
|
||||
})
|
||||
export class Experimental extends React.Component<P, S> {
|
||||
state: S = { MapContents: () => <div>Loading...</div> };
|
||||
Default = () => <div>
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
Could not load {this.props.route}...
|
||||
</div>;
|
||||
|
||||
render() {
|
||||
return <FarmDesigner {...NOT_TYPE_SAFE}>
|
||||
<this.state.MapContents />
|
||||
<this.Content />
|
||||
</FarmDesigner>;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
import { generateReducer } from "../redux/generate_reducer";
|
||||
import { Actions } from "../constants";
|
||||
|
||||
export interface RouterState { current: string; }
|
||||
export interface RouterState { $: string; }
|
||||
|
||||
export const routeReducerDefaultState: RouterState = {
|
||||
current: "/not_ready"
|
||||
$: "/not_ready"
|
||||
};
|
||||
|
||||
export const routeChange =
|
||||
(payload: string) => ({ type: Actions.ROUTE_CHANGE, payload });
|
||||
|
||||
export const routeReducer = generateReducer<RouterState>(routeReducerDefaultState)
|
||||
.add<string>(Actions.ROUTE_CHANGE,
|
||||
(_, { payload }) => ({ current: payload }));
|
||||
(_, { payload }) => ({ $: payload }));
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import * as React from "react";
|
||||
import { RouteConfig } from "takeme";
|
||||
import { Apology } from "./apology";
|
||||
|
||||
|
@ -8,12 +7,6 @@ interface UnboundRouteConfig<T> {
|
|||
key: keyof T;
|
||||
}
|
||||
|
||||
interface LegacyRouteCfg<T> {
|
||||
$: string;
|
||||
getChild: () => Promise<T>;
|
||||
key: keyof T;
|
||||
}
|
||||
|
||||
/** This is the preferred way to generate a route when there are no legacy
|
||||
* concerns.
|
||||
* PROBLEM:
|
||||
|
@ -56,48 +49,9 @@ function route<T>(i: UnboundRouteConfig<T>) {
|
|||
};
|
||||
}
|
||||
|
||||
/** The FarmDesigner was the only part of the application that used child
|
||||
* routes, a feature of our previous router package. Under the previous scheme,
|
||||
* a child route would be rendered inside of a shared <FarmDesigner/> component
|
||||
* to keep a consistent UI (the FarmDesigner side bar and floating menus, etc..)
|
||||
*
|
||||
* This was accomplished by passing the child route to <FarmDesigner/> via
|
||||
* this.props.children.
|
||||
*
|
||||
* This is not how the current router works. Rather than re-write numerous
|
||||
* FarmDesigner components to not use child routes, we instead have a
|
||||
* `legacyRoute` helper that emulates the child route feature.
|
||||
*
|
||||
* Don't use this for new FarmDesigner pages.
|
||||
* */
|
||||
function legacyRoute<T>(i: LegacyRouteCfg<T>) {
|
||||
return (callback: Function): RouteConfig => {
|
||||
const { $, getChild, key } = i;
|
||||
return {
|
||||
$,
|
||||
enter: async (info) => { // ===========
|
||||
try {
|
||||
// tslint:disable-next-line:no-any
|
||||
const El: any = (await getChild())[key];
|
||||
// ^ Let route() / legacyRoute() catch type issues.
|
||||
|
||||
// tslint:disable-next-line:no-any
|
||||
const stub: any = { children: <El /> };
|
||||
// ^ react-redux will mutate the real props behind the scenes.
|
||||
const { FarmDesigner } = await import("./farm_designer");
|
||||
callback(() => <FarmDesigner {...stub} />, info);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
callback(Apology, info);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
/** The 404 handler. All unresolved routes end up here. MUST BE LAST ITEM IN
|
||||
* ROUTE CONFIG!!! */
|
||||
const NOT_FOUND = route({
|
||||
export const NOT_FOUND_ROUTE = route({
|
||||
$: "*",
|
||||
getModule: () => import("./404"),
|
||||
key: "FourOhFour"
|
||||
|
@ -147,101 +101,4 @@ export const UNBOUND_ROUTES = [
|
|||
getModule: () => import("./tools"),
|
||||
key: "Tools"
|
||||
}),
|
||||
legacyRoute({
|
||||
$: "/designer",
|
||||
getChild: () => import("./farm_designer"),
|
||||
key: "FarmDesigner"
|
||||
}),
|
||||
legacyRoute({
|
||||
$: "/designer/farm_events",
|
||||
getChild: () => import("./farm_designer/farm_events/farm_events"),
|
||||
key: "FarmEvents"
|
||||
}),
|
||||
legacyRoute({
|
||||
$: "/designer/farm_events/add",
|
||||
getChild: () => import("./farm_designer/farm_events/add_farm_event"),
|
||||
key: "AddFarmEvent"
|
||||
}),
|
||||
legacyRoute({
|
||||
$: "/designer/farm_events/:farm_event_id",
|
||||
getChild: () => import("./farm_designer/farm_events/edit_farm_event"),
|
||||
key: "EditFarmEvent"
|
||||
}),
|
||||
// =================== PLANT ROUTES
|
||||
legacyRoute({
|
||||
$: "/designer/plants",
|
||||
getChild: () => import("./farm_designer/plants/plant_inventory"),
|
||||
key: "Plants"
|
||||
}),
|
||||
legacyRoute({
|
||||
$: "/designer/plants/move_to",
|
||||
getChild: () => import("./farm_designer/plants/move_to"),
|
||||
key: "MoveTo"
|
||||
}),
|
||||
legacyRoute({
|
||||
$: "/designer/plants/saved_gardens",
|
||||
getChild: () => import("./farm_designer/saved_gardens/saved_gardens"),
|
||||
key: "SavedGardens"
|
||||
}),
|
||||
legacyRoute({
|
||||
$: "/designer/plants/select",
|
||||
getChild: () => import("./farm_designer/plants/select_plants"),
|
||||
key: "SelectPlants"
|
||||
}),
|
||||
legacyRoute({
|
||||
$: "/designer/plants/create_point",
|
||||
getChild: () => import("./farm_designer/plants/create_points"),
|
||||
key: "CreatePoints"
|
||||
}),
|
||||
legacyRoute({
|
||||
$: "/designer/plants/crop_search",
|
||||
getChild: () => import("./farm_designer/plants/crop_catalog"),
|
||||
key: "CropCatalog"
|
||||
}),
|
||||
legacyRoute({
|
||||
$: "/designer/plants/crop_search/:crop/add",
|
||||
getChild: () => import("./farm_designer/plants/add_plant"),
|
||||
key: "AddPlant"
|
||||
}),
|
||||
legacyRoute({
|
||||
$: "/designer/plants/crop_search/:crop",
|
||||
getChild: () => import("./farm_designer/plants/crop_info"),
|
||||
key: "CropInfo"
|
||||
}),
|
||||
legacyRoute({
|
||||
$: "/designer/plants/:plant_id/edit",
|
||||
getChild: () => import("./farm_designer/plants/edit_plant_info"),
|
||||
key: "EditPlantInfo"
|
||||
}),
|
||||
legacyRoute({
|
||||
$: "/designer/plants/:plant_id",
|
||||
getChild: () => import("./farm_designer/plants/plant_info"),
|
||||
key: "PlantInfo"
|
||||
}),
|
||||
legacyRoute({
|
||||
$: "/designer/saved_gardens",
|
||||
getChild: () => import("./farm_designer/saved_gardens/saved_gardens"),
|
||||
key: "SavedGardens"
|
||||
}),
|
||||
legacyRoute({
|
||||
$: "/designer/saved_gardens/templates",
|
||||
getChild: () => import("./farm_designer/plants/plant_inventory"),
|
||||
key: "Plants"
|
||||
}),
|
||||
legacyRoute({
|
||||
$: "/designer/saved_gardens/templates/:plant_template_id/edit",
|
||||
getChild: () => import("./farm_designer/plants/edit_plant_info"),
|
||||
key: "EditPlantInfo"
|
||||
}),
|
||||
legacyRoute({
|
||||
$: "/designer/saved_gardens/templates/:plant_template_id",
|
||||
getChild: () => import("./farm_designer/plants/plant_info"),
|
||||
key: "PlantInfo"
|
||||
}),
|
||||
legacyRoute({
|
||||
$: "/designer/saved_gardens/:saved_garden_id",
|
||||
getChild: () => import("./farm_designer/saved_gardens/saved_gardens"),
|
||||
key: "SavedGardens"
|
||||
}),
|
||||
|
||||
].concat([NOT_FOUND]);
|
||||
];
|
||||
|
|
|
@ -9,10 +9,12 @@ import { Session } from "./session";
|
|||
import { attachToRoot } from "./util";
|
||||
import { Callback } from "i18next";
|
||||
import { ErrorBoundary } from "./error_boundary";
|
||||
import { Router } from "takeme";
|
||||
import { UNBOUND_ROUTES } from "./route_config";
|
||||
import { Router, RouteConfig } from "takeme";
|
||||
import { UNBOUND_ROUTES, NOT_FOUND_ROUTE } from "./route_config";
|
||||
import { App } from "./app";
|
||||
// import { TransitionGroup, CSSTransition } from "react-transition-group";
|
||||
import { Experimental, DesignerRouteName, BIG_LOOKUP } from "./experimental/experimental";
|
||||
import { routeChange } from "./experimental/reducer";
|
||||
import { FarmDesigner } from "./farm_designer";
|
||||
|
||||
interface RootComponentProps { store: Store; }
|
||||
|
||||
|
@ -23,11 +25,14 @@ export const attachAppToDom: Callback = () => {
|
|||
};
|
||||
|
||||
interface RootComponentState {
|
||||
CurrentRoute: React.ComponentType
|
||||
Route: React.ComponentType;
|
||||
ChildRoute?: React.ComponentType;
|
||||
}
|
||||
|
||||
const FARM_DESIGNER = () => <FarmDesigner {...({} as any)} />;
|
||||
|
||||
export class RootComponent extends React.Component<RootComponentProps, RootComponentState> {
|
||||
state: RootComponentState = { CurrentRoute: () => <div>Loading...</div> };
|
||||
state: RootComponentState = { Route: () => <div>Loading...</div> };
|
||||
|
||||
componentWillMount() {
|
||||
const notLoggedIn = !Session.fetchStoredToken();
|
||||
|
@ -37,22 +42,43 @@ export class RootComponent extends React.Component<RootComponentProps, RootCompo
|
|||
}
|
||||
|
||||
changeRoute =
|
||||
(c: React.ComponentType) => {
|
||||
this.setState({ CurrentRoute: c });
|
||||
}
|
||||
(Route: React.ComponentType, ChildRoute?: React.ComponentType) => {
|
||||
this.setState({ Route: Route, ChildRoute });
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
const routes = UNBOUND_ROUTES.map(bindTo => bindTo(this.changeRoute));
|
||||
new Router(routes).enableHtml5Routing("/app").init();
|
||||
const main_routes = UNBOUND_ROUTES.map(bindTo => bindTo(this.changeRoute));
|
||||
const designer_routes = Object
|
||||
.values(DesignerRouteName)
|
||||
.map(($): RouteConfig => {
|
||||
return {
|
||||
$: $,
|
||||
enter: async () => {
|
||||
_store.dispatch(routeChange($));
|
||||
const fn = BIG_LOOKUP[$];
|
||||
if (fn) {
|
||||
const child = await fn();
|
||||
this.changeRoute(FARM_DESIGNER, child);
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
new Router([
|
||||
...main_routes,
|
||||
...designer_routes,
|
||||
NOT_FOUND_ROUTE(this.changeRoute)
|
||||
]).enableHtml5Routing("/app").init();
|
||||
}
|
||||
|
||||
render() {
|
||||
const { CurrentRoute } = this.state;
|
||||
const { Route } = this.state;
|
||||
const { ChildRoute } = this.state;
|
||||
const props = ChildRoute ? { children: <ChildRoute /> } : {};
|
||||
try {
|
||||
return <ErrorBoundary>
|
||||
<Provider store={_store}>
|
||||
<App {...{} as App["props"]}>
|
||||
<CurrentRoute />
|
||||
<Route {...props} />
|
||||
</App>
|
||||
</Provider>
|
||||
</ErrorBoundary>;
|
||||
|
|
Loading…
Reference in New Issue