Commit 2a6daea1 authored by Laurent Wouters's avatar Laurent Wouters
Browse files

Adding new application framework

parent fb4820a8ad07
type state =
| Loading(list(string))
| Failed
| LoadedInitialSchema(list(string), Hypermedia.schemaType)
| LoadedWithData(
list(string),
Hypermedia.schemaType,
Hypermedia.entityValue,
);
type action =
| LoadingFailed
| LoadedSchema(Hypermedia.schemaType)
| LoadedData(Hypermedia.entityValue)
| Goto(list(string));
type state = Framework.appState;
type action = Framework.appAction;
let component = ReasonReact.reducerComponent("Page");
let goto = (_event, _self, link) => ReasonReact.Router.push(link);
let renderLoadedInitialSchema =
(self: ReasonReact.self(_, _, _), schema: Hypermedia.schemaType) =>
switch (schema) {
| Hypermedia.ArrayType(_) => <div> (ReasonReact.string("Loading")) </div>
| Hypermedia.ObjectType(_) => <div> (ReasonReact.string("Loading")) </div>
| Hypermedia.RootType(rootSchema) =>
Rendering.renderRoot(self, goto, rootSchema)
| Hypermedia.PrimitiveType(ptype) =>
<div> (ReasonReact.string(ptype)) </div>
};
let renderLoadedWithData =
(
self: ReasonReact.self(_, _, _),
schema: Hypermedia.schemaType,
data: Hypermedia.entityValue,
) =>
switch (schema) {
| Hypermedia.ArrayType(arrayType) =>
let values =
switch (data) {
| Hypermedia.ValueArray(x) => x
| _ => []
};
Rendering.renderCollection(self, goto, arrayType, values);
| Hypermedia.ObjectType(objectType) =>
let obj =
switch (data) {
| Hypermedia.ValueObject(x) => x
| _ => {properties: []}
};
Rendering.renderEntity(self, goto, objectType, obj);
| Hypermedia.RootType(rootSchema) =>
Rendering.renderRoot(self, goto, rootSchema)
| Hypermedia.PrimitiveType(ptype) =>
<div> (ReasonReact.string(ptype)) </div>
};
let make = _children => {
...component,
didMount: self => {
let url = ReasonReact.Router.dangerouslyGetInitialUrl();
Hypermedia.Fetch.fetch_shema(
Hypermedia.Fetch.getTarget(url.path),
() => self.send(LoadingFailed),
data => self.send(LoadedSchema(data)),
);
let watcherID =
ReasonReact.Router.watchUrl(url => self.send(Goto(url.path)));
ReasonReact.Router.watchUrl(url =>
self.send(Framework.GoTo(Framework.path_to_str(url.path)))
);
self.onUnmount(() => ReasonReact.Router.unwatchUrl(watcherID));
let url = ReasonReact.Router.dangerouslyGetInitialUrl();
self.send(Framework.GoTo(Framework.path_to_str(url.path)));
},
initialState: () => {
let url = ReasonReact.Router.dangerouslyGetInitialUrl();
Loading(url.path);
let registry = Defaults.defaultRegistry;
Framework.States.initial_state(registry);
},
reducer: (action, state) =>
switch (action) {
| LoadingFailed => ReasonReact.Update(Failed)
| LoadedSchema(schema) =>
switch (state) {
| Loading(path) =>
ReasonReact.Update(LoadedInitialSchema(path, schema))
| _ => ReasonReact.Update(Failed)
}
| LoadedData(value) =>
switch (state) {
| LoadedInitialSchema(path, schema) =>
ReasonReact.Update(LoadedWithData(path, schema, value))
| _ => ReasonReact.Update(Failed)
}
| Goto(path) => ReasonReact.Update(Loading(path))
},
didUpdate: oldNewSelf =>
switch (oldNewSelf.oldSelf.state, oldNewSelf.newSelf.state) {
| (Loading(_), LoadedInitialSchema(path, schema)) =>
switch (schema) {
| Hypermedia.ArrayType(_)
| Hypermedia.ObjectType(_) =>
Hypermedia.Fetch.fetch_data(
Hypermedia.Fetch.getTarget(path),
() => oldNewSelf.newSelf.send(LoadingFailed),
data => oldNewSelf.newSelf.send(LoadedData(data)),
)
| _ => ()
}
| _ => ()
},
render: self =>
switch (self.state) {
| Loading(_) => <div> (ReasonReact.string("Loading")) </div>
| Failed => <div> (ReasonReact.string("Failed")) </div>
| LoadedInitialSchema(_, schema) =>
renderLoadedInitialSchema(self, schema)
| LoadedWithData(_, schema, data) =>
renderLoadedWithData(self, schema, data)
},
reducer: Framework.States.reduce,
didUpdate: oldNewSelf => Framework.States.on_updated(oldNewSelf),
render: self => Framework.Rendering.render(self.state),
};
\ No newline at end of file
......@@ -136,6 +136,13 @@ type appAction =
let follow_link link =
ReasonReact.Router.push link
(* Take a path as a list of segments and convert it to a string *)
let rec path_to_str path =
match path with
| [] -> ""
| [first] -> "/" ^ first
| first :: others -> "/" ^ first ^ (path_to_str others)
(* Module for state management *)
module States : sig
......@@ -334,7 +341,8 @@ end
(* Module for rendering *)
module Rendering : sig
(* Renders an application state *)
val render: appState -> ReasonReact.reactElement
end = struct
(* Select the view if it is appropriate for this kind *)
let best_of_1 (view: view) (kind: viewKind) = match view.specification.kind, kind with
......
......@@ -224,13 +224,6 @@ module Fetch = struct
("Accept", "application/json")
|];;
(* Take a path as a list of segments and convert it to a string *)
let rec getTarget path =
match path with
| [] -> ""
| [first] -> "/" ^ first
| first :: others -> "/" ^ first ^ (getTarget others)
(* Get a promise for fetching a schema for the specified target path *)
let do_fetch_schema target =
let headers = Fetch.HeadersInit.makeWithArray headersForSchema in
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment