Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 32
POC - Client-Side Dash Apps #7
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| 'use strict'; | ||
| var partial = require('webpack-partial').default; | ||
| module.exports = function (config) { | ||
| return partial(config, { | ||
| entry: {bundle: [ | ||
| 'whatwg-fetch', | ||
| './local.js' | ||
| ]} | ||
| }); | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| 'use strict'; | ||
| var path = require('path'); | ||
| var partial = require('webpack-partial').default; | ||
| var ROOT = process.cwd(); | ||
| var BUILD = path.join(ROOT, 'dash_renderer'); | ||
| module.exports = function (config) { | ||
| return partial(config, { | ||
| output: { | ||
| path: BUILD, | ||
| publicPath: '/dash_renderer/', | ||
| // TODO: Bundle filename should be hashed (#10) | ||
| filename: 'local.js' | ||
| } | ||
| }); | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| 'use strict'; | ||
| var compose = require('ramda').compose; | ||
| var babel = require('./partials/babel'); | ||
| var defineEnv = require('./partials/defineEnv'); | ||
| var entryLocal = require('./partials/entryLocal'); | ||
| var outputLocal = require('./partials/outputLocal'); | ||
| var baseConfig = require('./webpack.config'); | ||
| // TODO: support locally served source maps in production (#11) | ||
| module.exports = compose( | ||
| babel, | ||
| defineEnv, | ||
| entryLocal, | ||
| outputLocal | ||
| )(baseConfig); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,185 @@ | ||
| /*eslint-env browser */ | ||
| import React from 'react'; | ||
| import ReactDOM from 'react-dom'; | ||
| require('es6-promise').polyfill(); | ||
| import {combineReducers} from 'redux'; | ||
| import {connect, Provider} from 'react-redux' | ||
| import {createStore, applyMiddleware} from 'redux'; | ||
| import thunk from 'redux-thunk'; | ||
| import createLogger from 'redux-logger'; | ||
| import {pluck, reduce} from 'ramda'; | ||
| // Actions | ||
| import { | ||
| computeGraphs, | ||
| computePaths, | ||
| setLayout, | ||
| triggerDefaultState | ||
| } from './actions/index'; | ||
| // Render the app | ||
| import renderTree from './renderTree'; | ||
| // Stores | ||
| import layout from './reducers/layout'; | ||
| import graphs from './reducers/dependencyGraph'; | ||
| import paths from './reducers/paths'; | ||
| import requestQueue from './reducers/requestQueue'; | ||
| import * as API from './reducers/api'; | ||
| /* | ||
| * Change the path here to try out different examples. | ||
| * Examples need to export appLayout and mapInputsToOutputs | ||
| * objects. | ||
| */ | ||
| import {appLayout, mapInputsToOutputs} from './local_examples/example_1_input_to_div'; | ||
| /* | ||
| * You shouldn't have to edit anything below here | ||
| * This block below does a few things: | ||
| * - it transforms the API calls into | ||
| * some promises that call the `transform` method | ||
| * for the appropriate input-output pair. | ||
| * - it initializes the app without the API controller | ||
| */ | ||
| const dependenciesRequest = { | ||
| content: mapInputsToOutputs.map(object => { | ||
| object.events = []; | ||
| object.state = []; | ||
| return object; | ||
| }), | ||
| status: 200 | ||
| }; | ||
| window.fetch = function(url, options) { | ||
| const payload = JSON.parse(options.body); | ||
| return new Promise(resolveResonse => { | ||
| const inputOutputPair = mapInputsToOutputs.find(pair => | ||
| (pair.output.id === payload.output.id) && | ||
| (pair.output.property === payload.output.property) | ||
| ); | ||
| resolveResonse({ | ||
| status: 200, | ||
| json: () => new Promise(resolveJson => { | ||
| resolveJson({ | ||
| response: { | ||
| props: { | ||
| 'id': inputOutputPair.output.id, | ||
| [inputOutputPair.output.property]: ( | ||
| inputOutputPair.output.transform( | ||
| reduce( | ||
| (acc, input) => { | ||
| acc[`${input.id}.${input.property}`] = input.value; | ||
| return acc | ||
| }, | ||
| {}, | ||
| payload.inputs | ||
| ) | ||
| ) | ||
| ) | ||
| } | ||
| } | ||
| }) | ||
| }) | ||
| }) | ||
| }); | ||
| } | ||
| // Initialize a store | ||
| const reducer = combineReducers({ | ||
| layout, | ||
| graphs, | ||
| paths, | ||
| requestQueue, | ||
| dependenciesRequest: API.dependenciesRequest | ||
| }); | ||
| const logger = createLogger() | ||
| let store; | ||
| const initializeStore = () => { | ||
| if (store) { | ||
| return store; | ||
| } | ||
| store = createStore( | ||
| reducer, | ||
| applyMiddleware(thunk, logger) | ||
| ); | ||
| window.store = store; /* global window:true */ | ||
| return store; | ||
| }; | ||
| store = initializeStore(); | ||
| store.dispatch({ | ||
| type: 'dependenciesRequest', | ||
| payload: dependenciesRequest | ||
| }); | ||
| store.dispatch(setLayout(appLayout)); | ||
| store.dispatch(computePaths({subTree: appLayout, startingPath: []})); | ||
| store.dispatch(computeGraphs(dependenciesRequest.content)); | ||
| store.dispatch(triggerDefaultState); | ||
| const ConnectedApp = connect(state => ({ | ||
| layout: state.layout, | ||
| dependenciesRequest: state.dependenciesRequest | ||
| }))( | ||
| props => { | ||
| return ( | ||
| <div> | ||
| {renderTree(props.layout, props.dependenciesRequest.content)} | ||
| </div> | ||
| ) | ||
| } | ||
| ); | ||
| ReactDOM.render( | ||
| <Provider store={store}> | ||
| <ConnectedApp/> | ||
| </Provider>, | ||
| document.getElementById('react-entry-point') | ||
| ); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| export const appLayout = { | ||
MemberAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. MemberAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the super simple example to get started. | ||
| 'type': 'Div', | ||
| 'namespace': 'dash_html_components', | ||
| 'props': { | ||
| 'content': [ | ||
| { | ||
| 'type': 'Input', | ||
| 'namespace': 'dash_core_components', | ||
| 'props': { | ||
| 'id': 'my-input', | ||
| 'value': 'Initial value' | ||
| } | ||
| }, | ||
| { | ||
| 'type': 'Div', | ||
| 'namespace': 'dash_html_components', | ||
| 'props': { | ||
| 'id': 'my-div' | ||
| } | ||
| } | ||
| ] | ||
| } | ||
| }; | ||
MemberAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This
| ||
| export const mapInputsToOutputs = [ | ||
| { | ||
| inputs: [ | ||
| { | ||
| id: 'my-input', | ||
| property: 'value' | ||
| } | ||
| ], | ||
MemberAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
| ||
| output: { | ||
| id: 'my-div', | ||
| property: 'content', | ||
| /* | ||
| * Of course, we can't have functions in the actual spec, | ||
| * but we could introduce a lightweight transformation | ||
| * language for modifying strings, accessing values in | ||
| * objects or arrays, arithmetic, etc. | ||
MemberAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Important point here! ^^ | ||
| */ | ||
| transform: inputArguments => { | ||
| return `You've entered: ${inputArguments['my-input.value']}`; | ||
MemberAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
| ||
| } | ||
| } | ||
| } | ||
| ]; | ||
Uh oh!
There was an error while loading. Please reload this page.

There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To create a new example, just change this import. And make sure that the examples that you write export an
appLayoutand amapInputsToOutputsobject.