Merge branch 'master' of https://github.com/yldio/joyent-portal
This commit is contained in:
commit
cbbc764f30
8
bin/on-changes
Executable file
8
bin/on-changes
Executable file
@ -0,0 +1,8 @@
|
|||||||
|
#! /usr/bin/env bash
|
||||||
|
|
||||||
|
#
|
||||||
|
# Prelude
|
||||||
|
#
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
[[ $(git diff --name-only) == *"$1"* ]]
|
@ -32,7 +32,7 @@ deployment:
|
|||||||
branch: master
|
branch: master
|
||||||
commands:
|
commands:
|
||||||
- ./bin/docker-login
|
- ./bin/docker-login
|
||||||
- make -C ui publish | sed '/NPM_TOKEN/d'
|
- ./bin/on-changes && make -C ui publish | sed '/NPM_TOKEN/d'
|
||||||
- make -j2 build | sed '/NPM_TOKEN/d'
|
- make -j2 build | sed '/NPM_TOKEN/d'
|
||||||
- make -j2 push | sed '/NPM_TOKEN/d'
|
- make -j2 push | sed '/NPM_TOKEN/d'
|
||||||
- ./bin/deploy
|
- ./bin/deploy
|
||||||
|
@ -29,7 +29,7 @@ const plugins = [
|
|||||||
{
|
{
|
||||||
register: understood,
|
register: understood,
|
||||||
options: {
|
options: {
|
||||||
'default': 'en-us',
|
default: 'en-us',
|
||||||
localesDir: path.join(__dirname, '../static/locales')
|
localesDir: path.join(__dirname, '../static/locales')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -39,7 +39,7 @@ const defaultHandler = (request, reply) => {
|
|||||||
const locales = (request.locale || '').toLowerCase().split(/\-/);
|
const locales = (request.locale || '').toLowerCase().split(/\-/);
|
||||||
|
|
||||||
reply(html({
|
reply(html({
|
||||||
locale: locales[1],
|
locale: request.locale,
|
||||||
lang: locales[0]
|
lang: locales[0]
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
@ -5,7 +5,12 @@
|
|||||||
- [x] form values in redux store
|
- [x] form values in redux store
|
||||||
- [x] clear / retain values in store
|
- [x] clear / retain values in store
|
||||||
- [x] pre-populate form
|
- [x] pre-populate form
|
||||||
- [x] validation field / form level
|
- [x] validation on field / form level
|
||||||
- [x] multi page form
|
- [x] multi page form
|
||||||
- [x] custom form fields
|
- [x] custom form components
|
||||||
- [?] requires updates to existing ui components
|
- [ ] requires updates to existing ui components as props to custom components are passed in the following format:
|
||||||
|
|
||||||
|
`"props": { "input": "value": "", "name": "", "onChange": "", "onFocus": "", ... }, "meta": { "valid": "", "error": "", ... }, "anyOtherPropsOnField": "", ... }`
|
||||||
|
|
||||||
|
- [ ] explore proxying props from Field to custom components from above shape to a flat form as expected by custom components
|
||||||
|
- [ ] consider creating component that handles logic and display of label and error which would be reused by form components to avoid code duplication for this functionality
|
||||||
|
15
spikes/fuzzy-search/fuzzy-search-filter/.babelrc
Normal file
15
spikes/fuzzy-search/fuzzy-search-filter/.babelrc
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"sourceMaps": "both",
|
||||||
|
"presets": [
|
||||||
|
"react",
|
||||||
|
"es2015"
|
||||||
|
],
|
||||||
|
"plugins": [
|
||||||
|
"react-hot-loader/babel",
|
||||||
|
"add-module-exports",
|
||||||
|
"syntax-async-functions",
|
||||||
|
["transform-object-rest-spread", {
|
||||||
|
"useBuiltIns": true
|
||||||
|
}]
|
||||||
|
]
|
||||||
|
}
|
42
spikes/fuzzy-search/fuzzy-search-filter/package.json
Normal file
42
spikes/fuzzy-search/fuzzy-search-filter/package.json
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"name": "react-infinite-spike",
|
||||||
|
"private": true,
|
||||||
|
"license": "private",
|
||||||
|
"scripts": {
|
||||||
|
"start": "webpack-dev-server --config webpack/index.js"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"build-array": "^1.0.0",
|
||||||
|
"delay": "^1.3.1",
|
||||||
|
"lodash.debounce": "^4.0.8",
|
||||||
|
"react": "^15.4.0",
|
||||||
|
"react-dom": "^15.4.0",
|
||||||
|
"react-fuzzy-filter": "^2.3.0",
|
||||||
|
"react-hot-loader": "^3.0.0-beta.6",
|
||||||
|
"react-infinite": "^0.10.0",
|
||||||
|
"react-redux": "^4.4.6",
|
||||||
|
"redux": "^3.6.0",
|
||||||
|
"redux-logger": "^2.7.4",
|
||||||
|
"redux-promise-middleware": "^4.1.0",
|
||||||
|
"redux-thunk": "^2.1.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"babel-core": "^6.18.2",
|
||||||
|
"babel-eslint": "^7.1.1",
|
||||||
|
"babel-loader": "^6.2.7",
|
||||||
|
"babel-plugin-add-module-exports": "^0.2.1",
|
||||||
|
"babel-plugin-syntax-async-functions": "^6.13.0",
|
||||||
|
"babel-plugin-transform-object-rest-spread": "^6.19.0",
|
||||||
|
"babel-preset-es2015": "^6.18.0",
|
||||||
|
"babel-preset-react": "^6.16.0",
|
||||||
|
"css-loader": "^0.25.0",
|
||||||
|
"extract-text-webpack-plugin": "^2.0.0-beta.4",
|
||||||
|
"faker": "^3.1.0",
|
||||||
|
"postcss-loader": "^1.0.0",
|
||||||
|
"postcss-modules-values": "^1.2.2",
|
||||||
|
"postcss-nested": "^1.0.0",
|
||||||
|
"style-loader": "^0.13.1",
|
||||||
|
"webpack": "^2.1.0-beta.27",
|
||||||
|
"webpack-dev-server": "^1.16.2"
|
||||||
|
}
|
||||||
|
}
|
5
spikes/fuzzy-search/fuzzy-search-filter/readme.md
Normal file
5
spikes/fuzzy-search/fuzzy-search-filter/readme.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# react-fuzzy-filter
|
||||||
|
|
||||||
|
- https://github.com/jdlehman/react-fuzzy-filter
|
||||||
|
|
||||||
|
- Does not use API endpoint, instead an array of objects needs to be created locally
|
91
spikes/fuzzy-search/fuzzy-search-filter/src/actions.js
Normal file
91
spikes/fuzzy-search/fuzzy-search-filter/src/actions.js
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
const buildArray = require('build-array');
|
||||||
|
const delay = require('delay');
|
||||||
|
const faker = require('faker');
|
||||||
|
|
||||||
|
const actions = {
|
||||||
|
'FETCH_FULFILLED': (state, action) => {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
fetching: false,
|
||||||
|
items: (state.items || []).concat(action.payload)
|
||||||
|
};
|
||||||
|
},
|
||||||
|
'FETCH_PENDING': (state, action) => {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
fetching: true
|
||||||
|
};
|
||||||
|
},
|
||||||
|
'FILTER_PENDING': (state, action) => {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
fetching: true
|
||||||
|
};
|
||||||
|
},
|
||||||
|
'FILTER_FULFILLED': (state, action) => {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
fetching: false,
|
||||||
|
filtered: action.payload.length !== state.items.length
|
||||||
|
? action.payload
|
||||||
|
: null
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetch = () => (dispatch, getState) => {
|
||||||
|
const {
|
||||||
|
filtered
|
||||||
|
} = getState();
|
||||||
|
|
||||||
|
if (filtered) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dispatch({
|
||||||
|
type: 'FETCH',
|
||||||
|
payload: delay(500).then(() => {
|
||||||
|
const {
|
||||||
|
items = []
|
||||||
|
} = getState();
|
||||||
|
|
||||||
|
return buildArray(100000).map((v, i) => {
|
||||||
|
const id = items.length + i;
|
||||||
|
|
||||||
|
return {
|
||||||
|
id,
|
||||||
|
title: `test ${id}`,
|
||||||
|
description: faker.lorem.sentence(),
|
||||||
|
image: faker.image.imageUrl(),
|
||||||
|
date: faker.date.recent()
|
||||||
|
};
|
||||||
|
});
|
||||||
|
})
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const filter = (payload) => (dispatch, getState) => {
|
||||||
|
const regexp = new RegExp(payload);
|
||||||
|
|
||||||
|
return dispatch({
|
||||||
|
type: 'FILTER',
|
||||||
|
payload: delay(500).then(() => {
|
||||||
|
const {
|
||||||
|
items = []
|
||||||
|
} = getState();
|
||||||
|
|
||||||
|
return items.filter((item) => {
|
||||||
|
return regexp.test(item.title);
|
||||||
|
}).sort((a, b) => a.id - b.id);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = (state, action) => {
|
||||||
|
return actions[action.type]
|
||||||
|
? actions[action.type](state, action)
|
||||||
|
: state;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.fetch = fetch;
|
||||||
|
module.exports.filter = filter;
|
18
spikes/fuzzy-search/fuzzy-search-filter/src/index.js
Normal file
18
spikes/fuzzy-search/fuzzy-search-filter/src/index.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
const Store = require('./store');
|
||||||
|
const ReactDOM = require('react-dom');
|
||||||
|
const React = require('react');
|
||||||
|
|
||||||
|
const render = () => {
|
||||||
|
const Root = require('./root');
|
||||||
|
|
||||||
|
ReactDOM.render(
|
||||||
|
<Root store={Store()} />,
|
||||||
|
document.getElementById('root')
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
render();
|
||||||
|
|
||||||
|
if (module.hot) {
|
||||||
|
module.hot.accept('./root', render);
|
||||||
|
}
|
24
spikes/fuzzy-search/fuzzy-search-filter/src/root.js
Normal file
24
spikes/fuzzy-search/fuzzy-search-filter/src/root.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
const ReactRedux = require('react-redux');
|
||||||
|
const ReactHotLoader = require('react-hot-loader');
|
||||||
|
const React = require('react');
|
||||||
|
const Search = require('./search');
|
||||||
|
|
||||||
|
const {
|
||||||
|
AppContainer
|
||||||
|
} = ReactHotLoader;
|
||||||
|
|
||||||
|
const {
|
||||||
|
Provider
|
||||||
|
} = ReactRedux;
|
||||||
|
|
||||||
|
module.exports = ({
|
||||||
|
store
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<AppContainer>
|
||||||
|
<Provider store={store}>
|
||||||
|
<Search />
|
||||||
|
</Provider>
|
||||||
|
</AppContainer>
|
||||||
|
);
|
||||||
|
};
|
62
spikes/fuzzy-search/fuzzy-search-filter/src/search.js
Normal file
62
spikes/fuzzy-search/fuzzy-search-filter/src/search.js
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
const ReactRedux = require('react-redux');
|
||||||
|
const actions = require('./actions');
|
||||||
|
const React = require('react');
|
||||||
|
const users = require('../../users');
|
||||||
|
|
||||||
|
import fuzzyFilterFactory from 'react-fuzzy-filter';
|
||||||
|
|
||||||
|
// these components share state and can even live in different components
|
||||||
|
const {InputFilter, FilterResults} = fuzzyFilterFactory();
|
||||||
|
|
||||||
|
const {
|
||||||
|
connect
|
||||||
|
} = ReactRedux;
|
||||||
|
|
||||||
|
const {
|
||||||
|
fetch,
|
||||||
|
filter
|
||||||
|
} = actions;
|
||||||
|
|
||||||
|
const mapStateToProps = (state) => {
|
||||||
|
return state;
|
||||||
|
};
|
||||||
|
|
||||||
|
const mapDispatchToProps = (dispatch, ownProps) => {
|
||||||
|
return {
|
||||||
|
fetch: () => {
|
||||||
|
return dispatch(fetch());
|
||||||
|
},
|
||||||
|
filter: (payload) => {
|
||||||
|
return dispatch(filter(payload));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const Search = React.createClass({
|
||||||
|
|
||||||
|
renderItem: function(item, index) {
|
||||||
|
return(<div key={index}>{item.name}</div>);
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function() {
|
||||||
|
const fuseConfig = {
|
||||||
|
keys: ['meta', 'tag']
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<InputFilter />
|
||||||
|
<div>Any amount of content between</div>
|
||||||
|
<FilterResults
|
||||||
|
items={users}
|
||||||
|
renderItem={this.renderItem}
|
||||||
|
fuseConfig={fuseConfig}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
module.exports = connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps,
|
||||||
|
)(Search);
|
19
spikes/fuzzy-search/fuzzy-search-filter/src/store.js
Normal file
19
spikes/fuzzy-search/fuzzy-search-filter/src/store.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
const createLogger = require('redux-logger');
|
||||||
|
const promiseMiddleware = require('redux-promise-middleware').default;
|
||||||
|
const thunk = require('redux-thunk').default;
|
||||||
|
const redux = require('redux');
|
||||||
|
const reducer = require('./actions');
|
||||||
|
|
||||||
|
const {
|
||||||
|
createStore,
|
||||||
|
compose,
|
||||||
|
applyMiddleware
|
||||||
|
} = redux;
|
||||||
|
|
||||||
|
module.exports = (state = Object.freeze({})) => {
|
||||||
|
return createStore(reducer, state, applyMiddleware(
|
||||||
|
createLogger(),
|
||||||
|
promiseMiddleware(),
|
||||||
|
thunk
|
||||||
|
));
|
||||||
|
};
|
7
spikes/fuzzy-search/fuzzy-search-filter/static/.gitignore
vendored
Normal file
7
spikes/fuzzy-search/fuzzy-search-filter/static/.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
*
|
||||||
|
!.gitignore
|
||||||
|
!.gitkeep
|
||||||
|
!index.html
|
||||||
|
|
||||||
|
js/*
|
||||||
|
!js/.gitkeep
|
10
spikes/fuzzy-search/fuzzy-search-filter/static/index.html
Normal file
10
spikes/fuzzy-search/fuzzy-search-filter/static/index.html
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang='en-US'>
|
||||||
|
<head>
|
||||||
|
<title>Infinite List</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id='root'></div>
|
||||||
|
<script src='main.js'></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
56
spikes/fuzzy-search/fuzzy-search-filter/webpack/base.js
Normal file
56
spikes/fuzzy-search/fuzzy-search-filter/webpack/base.js
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
const webpack = require('webpack');
|
||||||
|
const path = require('path');
|
||||||
|
const ExtractTextPlugin = require('extract-text-webpack-plugin');
|
||||||
|
|
||||||
|
const plugins = {
|
||||||
|
'no-errors-plugin': new webpack.NoErrorsPlugin(),
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.config = {
|
||||||
|
context: path.join(__dirname, '../'),
|
||||||
|
output: {
|
||||||
|
path: path.join(__dirname, '../static'),
|
||||||
|
publicPath: '/',
|
||||||
|
filename: '[name].js'
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new webpack.NoErrorsPlugin(),
|
||||||
|
new ExtractTextPlugin({
|
||||||
|
filename: 'css/[name].css',
|
||||||
|
allChunks: true
|
||||||
|
}),
|
||||||
|
new webpack.LoaderOptionsPlugin({
|
||||||
|
options: {
|
||||||
|
postcss: {}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
],
|
||||||
|
module: {
|
||||||
|
loaders: [{
|
||||||
|
test: /js?$/,
|
||||||
|
exclude: /node_modules/,
|
||||||
|
include: [
|
||||||
|
path.join(__dirname, '../src')
|
||||||
|
],
|
||||||
|
loader: 'babel-loader'
|
||||||
|
}, {
|
||||||
|
test: /\.css?$/,
|
||||||
|
exclude: /node_modules/,
|
||||||
|
include: [
|
||||||
|
path.join(__dirname, '../src'),
|
||||||
|
path.join(__dirname, '../docs')
|
||||||
|
],
|
||||||
|
loader: ExtractTextPlugin.extract({
|
||||||
|
fallbackLoader: 'style-loader',
|
||||||
|
loader: [
|
||||||
|
'css-loader?',
|
||||||
|
'modules&importLoaders=1&',
|
||||||
|
'localIdentName=[name]__[local]___[hash:base64:5]!',
|
||||||
|
'postcss-loader'
|
||||||
|
].join('')
|
||||||
|
})
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.plugins = plugins;
|
29
spikes/fuzzy-search/fuzzy-search-filter/webpack/index.js
Normal file
29
spikes/fuzzy-search/fuzzy-search-filter/webpack/index.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
const base = require('./base.js');
|
||||||
|
const webpack = require('webpack');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const devServer = {
|
||||||
|
contentBase: [
|
||||||
|
path.join(__dirname, '../static/')
|
||||||
|
],
|
||||||
|
hot: true,
|
||||||
|
compress: true,
|
||||||
|
lazy: false,
|
||||||
|
historyApiFallback: {
|
||||||
|
index: './index.html'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = Object.assign(base.config, {
|
||||||
|
entry: [
|
||||||
|
'react-hot-loader/patch',
|
||||||
|
'webpack-dev-server/client?http://localhost:8080',
|
||||||
|
'webpack/hot/only-dev-server',
|
||||||
|
'./src/index.js'
|
||||||
|
],
|
||||||
|
plugins: base.config.plugins.concat([
|
||||||
|
new webpack.HotModuleReplacementPlugin()
|
||||||
|
]),
|
||||||
|
devtool: 'source-map',
|
||||||
|
devServer
|
||||||
|
});
|
3793
spikes/fuzzy-search/fuzzy-search-filter/yarn.lock
Normal file
3793
spikes/fuzzy-search/fuzzy-search-filter/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
15
spikes/fuzzy-search/react-select/.babelrc
Normal file
15
spikes/fuzzy-search/react-select/.babelrc
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"sourceMaps": "both",
|
||||||
|
"presets": [
|
||||||
|
"react",
|
||||||
|
"es2015"
|
||||||
|
],
|
||||||
|
"plugins": [
|
||||||
|
"react-hot-loader/babel",
|
||||||
|
"add-module-exports",
|
||||||
|
"syntax-async-functions",
|
||||||
|
["transform-object-rest-spread", {
|
||||||
|
"useBuiltIns": true
|
||||||
|
}]
|
||||||
|
]
|
||||||
|
}
|
39
spikes/fuzzy-search/react-select/package.json
Normal file
39
spikes/fuzzy-search/react-select/package.json
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
{
|
||||||
|
"name": "react-infinite-spike",
|
||||||
|
"private": true,
|
||||||
|
"license": "private",
|
||||||
|
"scripts": {
|
||||||
|
"start": "webpack-dev-server --config webpack/index.js"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "^0.15.3",
|
||||||
|
"build-array": "^1.0.0",
|
||||||
|
"delay": "^1.3.1",
|
||||||
|
"lodash.debounce": "^4.0.8",
|
||||||
|
"react": "^15.4.0",
|
||||||
|
"react-dom": "^15.4.0",
|
||||||
|
"react-hot-loader": "^3.0.0-beta.6",
|
||||||
|
"react-infinite": "^0.10.0",
|
||||||
|
"react-redux": "^4.4.6",
|
||||||
|
"react-select": "^1.0.0-rc.2",
|
||||||
|
"redux": "^3.6.0",
|
||||||
|
"redux-logger": "^2.7.4",
|
||||||
|
"redux-promise-middleware": "^4.1.0",
|
||||||
|
"redux-thunk": "^2.1.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"babel-core": "^6.18.2",
|
||||||
|
"babel-eslint": "^7.1.1",
|
||||||
|
"babel-loader": "^6.2.7",
|
||||||
|
"babel-plugin-add-module-exports": "^0.2.1",
|
||||||
|
"babel-plugin-syntax-async-functions": "^6.13.0",
|
||||||
|
"babel-plugin-transform-object-rest-spread": "^6.19.0",
|
||||||
|
"babel-preset-es2015": "^6.18.0",
|
||||||
|
"babel-preset-react": "^6.16.0",
|
||||||
|
"extract-text-webpack-plugin": "^2.0.0-beta.4",
|
||||||
|
"faker": "^3.1.0",
|
||||||
|
"style-loader": "^0.13.1",
|
||||||
|
"webpack": "^2.1.0-beta.27",
|
||||||
|
"webpack-dev-server": "^1.16.2"
|
||||||
|
}
|
||||||
|
}
|
7
spikes/fuzzy-search/react-select/readme.md
Normal file
7
spikes/fuzzy-search/react-select/readme.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# react-select
|
||||||
|
|
||||||
|
- http://jedwatson.github.io/react-select/
|
||||||
|
|
||||||
|
- Has a seperate stylesheet that needs to be included
|
||||||
|
|
||||||
|
- Allows for async option
|
17
spikes/fuzzy-search/react-select/src/index.js
vendored
Normal file
17
spikes/fuzzy-search/react-select/src/index.js
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
const ReactDOM = require('react-dom');
|
||||||
|
const React = require('react');
|
||||||
|
|
||||||
|
const render = () => {
|
||||||
|
const Root = require('./root');
|
||||||
|
|
||||||
|
ReactDOM.render(
|
||||||
|
<Root />,
|
||||||
|
document.getElementById('root')
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
render();
|
||||||
|
|
||||||
|
if (module.hot) {
|
||||||
|
module.hot.accept('./root', render);
|
||||||
|
}
|
27
spikes/fuzzy-search/react-select/src/root.js
vendored
Normal file
27
spikes/fuzzy-search/react-select/src/root.js
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
const ReactRedux = require('react-redux');
|
||||||
|
const ReactHotLoader = require('react-hot-loader');
|
||||||
|
const React = require('react');
|
||||||
|
const Search = require('./search');
|
||||||
|
const SearchAsync = require('./search-async')
|
||||||
|
|
||||||
|
const {
|
||||||
|
AppContainer
|
||||||
|
} = ReactHotLoader;
|
||||||
|
|
||||||
|
const {
|
||||||
|
Provider
|
||||||
|
} = ReactRedux;
|
||||||
|
|
||||||
|
module.exports = ({
|
||||||
|
store
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<AppContainer>
|
||||||
|
<div>
|
||||||
|
<Search multi />
|
||||||
|
<Search />
|
||||||
|
<SearchAsync />
|
||||||
|
</div>
|
||||||
|
</AppContainer>
|
||||||
|
);
|
||||||
|
};
|
56
spikes/fuzzy-search/react-select/src/search-async.js
vendored
Normal file
56
spikes/fuzzy-search/react-select/src/search-async.js
vendored
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
const React = require('react');
|
||||||
|
const Select = require('react-select');
|
||||||
|
const SelectAsync = Select.Async
|
||||||
|
|
||||||
|
|
||||||
|
const SearchAsync = React.createClass({
|
||||||
|
|
||||||
|
getInitialState: function() {
|
||||||
|
return {
|
||||||
|
selectValue: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
updateValue: function(newValue) {
|
||||||
|
console.log('State changed to ' + newValue);
|
||||||
|
this.setState({
|
||||||
|
selectValue: newValue
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
options: function(input, callback) {
|
||||||
|
setTimeout(function() {
|
||||||
|
callback(null, {
|
||||||
|
options: [
|
||||||
|
{ value: 'one', label: 'One' },
|
||||||
|
{ value: 'two', label: 'Two' },
|
||||||
|
{ value: 'three', label: 'Three' },
|
||||||
|
{ value: 'four', label: 'Four' },
|
||||||
|
{ value: 'five', label: 'Five' },
|
||||||
|
{ value: 'six', label: 'Six' },
|
||||||
|
],
|
||||||
|
// CAREFUL! Only set this to true when there are no more options,
|
||||||
|
// or more specific queries will not be sent to the server.
|
||||||
|
complete: true
|
||||||
|
}, 10000);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function () {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h1> Async Search </h1>
|
||||||
|
<SelectAsync
|
||||||
|
ref="stateSelectAsync"
|
||||||
|
loadOptions={this.options}
|
||||||
|
value={this.state.selectValue}
|
||||||
|
onChange={this.updateValue}
|
||||||
|
multi={true}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
module.exports = SearchAsync
|
49
spikes/fuzzy-search/react-select/src/search.js
vendored
Normal file
49
spikes/fuzzy-search/react-select/src/search.js
vendored
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
const React = require('react');
|
||||||
|
const Select = require('react-select');
|
||||||
|
|
||||||
|
|
||||||
|
const Search = React.createClass({
|
||||||
|
|
||||||
|
getInitialState: function() {
|
||||||
|
return {
|
||||||
|
selectValue: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
updateValue: function(newValue) {
|
||||||
|
console.log('State changed to ' + newValue);
|
||||||
|
this.setState({
|
||||||
|
selectValue: newValue
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function () {
|
||||||
|
|
||||||
|
var options = [
|
||||||
|
{ value: 'one', label: 'One' },
|
||||||
|
{ value: 'two', label: 'Two' },
|
||||||
|
{ value: 'three', label: 'Three' },
|
||||||
|
{ value: 'four', label: 'Four' },
|
||||||
|
{ value: 'five', label: 'Five' },
|
||||||
|
{ value: 'six', label: 'Six' },
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h1> {this.props.multi ? 'Multi' : 'Single'} Search </h1>
|
||||||
|
<Select
|
||||||
|
ref="stateSelect"
|
||||||
|
className="is-open"
|
||||||
|
autofocus
|
||||||
|
options={options}
|
||||||
|
name="selected-state"
|
||||||
|
value={this.state.selectValue}
|
||||||
|
onChange={this.updateValue}
|
||||||
|
multi={this.props.multi}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
module.exports = Search
|
7
spikes/fuzzy-search/react-select/static/.gitignore
vendored
Normal file
7
spikes/fuzzy-search/react-select/static/.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
*
|
||||||
|
!.gitignore
|
||||||
|
!.gitkeep
|
||||||
|
!index.html
|
||||||
|
|
||||||
|
js/*
|
||||||
|
!js/.gitkeep
|
13
spikes/fuzzy-search/react-select/static/index.html
Normal file
13
spikes/fuzzy-search/react-select/static/index.html
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang='en-US'>
|
||||||
|
<head>
|
||||||
|
<title>React Select</title>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id='root'></div>
|
||||||
|
<script src='main.js'></script>
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="https://unpkg.com/react-select/dist/react-select.css">
|
||||||
|
</body>
|
||||||
|
</html>
|
56
spikes/fuzzy-search/react-select/webpack/base.js
vendored
Normal file
56
spikes/fuzzy-search/react-select/webpack/base.js
vendored
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
const webpack = require('webpack');
|
||||||
|
const path = require('path');
|
||||||
|
const ExtractTextPlugin = require('extract-text-webpack-plugin');
|
||||||
|
|
||||||
|
const plugins = {
|
||||||
|
'no-errors-plugin': new webpack.NoErrorsPlugin(),
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.config = {
|
||||||
|
context: path.join(__dirname, '../'),
|
||||||
|
output: {
|
||||||
|
path: path.join(__dirname, '../static'),
|
||||||
|
publicPath: '/',
|
||||||
|
filename: '[name].js'
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new webpack.NoErrorsPlugin(),
|
||||||
|
new ExtractTextPlugin({
|
||||||
|
filename: 'css/[name].css',
|
||||||
|
allChunks: true
|
||||||
|
}),
|
||||||
|
new webpack.LoaderOptionsPlugin({
|
||||||
|
options: {
|
||||||
|
postcss: {}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
],
|
||||||
|
module: {
|
||||||
|
loaders: [{
|
||||||
|
test: /js?$/,
|
||||||
|
exclude: /node_modules/,
|
||||||
|
include: [
|
||||||
|
path.join(__dirname, '../src')
|
||||||
|
],
|
||||||
|
loader: 'babel-loader'
|
||||||
|
}, {
|
||||||
|
test: /\.css?$/,
|
||||||
|
exclude: /node_modules/,
|
||||||
|
include: [
|
||||||
|
path.join(__dirname, '../src'),
|
||||||
|
path.join(__dirname, '../docs')
|
||||||
|
],
|
||||||
|
loader: ExtractTextPlugin.extract({
|
||||||
|
fallbackLoader: 'style-loader',
|
||||||
|
loader: [
|
||||||
|
'css-loader?',
|
||||||
|
'modules&importLoaders=1&',
|
||||||
|
'localIdentName=[name]__[local]___[hash:base64:5]!',
|
||||||
|
'postcss-loader'
|
||||||
|
].join('')
|
||||||
|
})
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.plugins = plugins;
|
29
spikes/fuzzy-search/react-select/webpack/index.js
vendored
Normal file
29
spikes/fuzzy-search/react-select/webpack/index.js
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
const base = require('./base.js');
|
||||||
|
const webpack = require('webpack');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const devServer = {
|
||||||
|
contentBase: [
|
||||||
|
path.join(__dirname, '../static/')
|
||||||
|
],
|
||||||
|
hot: true,
|
||||||
|
compress: true,
|
||||||
|
lazy: false,
|
||||||
|
historyApiFallback: {
|
||||||
|
index: './index.html'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = Object.assign(base.config, {
|
||||||
|
entry: [
|
||||||
|
'react-hot-loader/patch',
|
||||||
|
'webpack-dev-server/client?http://localhost:8080',
|
||||||
|
'webpack/hot/only-dev-server',
|
||||||
|
'./src/index.js'
|
||||||
|
],
|
||||||
|
plugins: base.config.plugins.concat([
|
||||||
|
new webpack.HotModuleReplacementPlugin()
|
||||||
|
]),
|
||||||
|
devtool: 'source-map',
|
||||||
|
devServer
|
||||||
|
});
|
3125
spikes/fuzzy-search/react-select/yarn.lock
Normal file
3125
spikes/fuzzy-search/react-select/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
15
spikes/fuzzy-search/react-selectize-stateless/.babelrc
Normal file
15
spikes/fuzzy-search/react-selectize-stateless/.babelrc
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"sourceMaps": "both",
|
||||||
|
"presets": [
|
||||||
|
"react",
|
||||||
|
"es2015"
|
||||||
|
],
|
||||||
|
"plugins": [
|
||||||
|
"react-hot-loader/babel",
|
||||||
|
"add-module-exports",
|
||||||
|
"syntax-async-functions",
|
||||||
|
["transform-object-rest-spread", {
|
||||||
|
"useBuiltIns": true
|
||||||
|
}]
|
||||||
|
]
|
||||||
|
}
|
41
spikes/fuzzy-search/react-selectize-stateless/package.json
Normal file
41
spikes/fuzzy-search/react-selectize-stateless/package.json
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"name": "react-infinite-spike",
|
||||||
|
"private": true,
|
||||||
|
"license": "private",
|
||||||
|
"scripts": {
|
||||||
|
"start": "webpack-dev-server --config webpack/index.js"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "^0.15.3",
|
||||||
|
"build-array": "^1.0.0",
|
||||||
|
"delay": "^1.3.1",
|
||||||
|
"lodash.debounce": "^4.0.8",
|
||||||
|
"react": "^15.4.0",
|
||||||
|
"react-addons-css-transition-group": "^15.4.1",
|
||||||
|
"react-addons-shallow-compare": "^15.4.1",
|
||||||
|
"react-dom": "^15.4.0",
|
||||||
|
"react-hot-loader": "^3.0.0-beta.6",
|
||||||
|
"react-infinite": "^0.10.0",
|
||||||
|
"react-redux": "^4.4.6",
|
||||||
|
"react-selectize": "^2.1.0",
|
||||||
|
"redux": "^3.6.0",
|
||||||
|
"redux-logger": "^2.7.4",
|
||||||
|
"redux-promise-middleware": "^4.1.0",
|
||||||
|
"redux-thunk": "^2.1.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"babel-core": "^6.18.2",
|
||||||
|
"babel-eslint": "^7.1.1",
|
||||||
|
"babel-loader": "^6.2.7",
|
||||||
|
"babel-plugin-add-module-exports": "^0.2.1",
|
||||||
|
"babel-plugin-syntax-async-functions": "^6.13.0",
|
||||||
|
"babel-plugin-transform-object-rest-spread": "^6.19.0",
|
||||||
|
"babel-preset-es2015": "^6.18.0",
|
||||||
|
"babel-preset-react": "^6.16.0",
|
||||||
|
"extract-text-webpack-plugin": "^2.0.0-beta.4",
|
||||||
|
"faker": "^3.1.0",
|
||||||
|
"style-loader": "^0.13.1",
|
||||||
|
"webpack": "^2.1.0-beta.27",
|
||||||
|
"webpack-dev-server": "^1.16.2"
|
||||||
|
}
|
||||||
|
}
|
5
spikes/fuzzy-search/react-selectize-stateless/readme.md
Normal file
5
spikes/fuzzy-search/react-selectize-stateless/readme.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# react-fuzzy-filter
|
||||||
|
|
||||||
|
- https://github.com/jdlehman/react-fuzzy-filter
|
||||||
|
|
||||||
|
- Does not use API endpoint, instead an array of objects needs to be created locally
|
44
spikes/fuzzy-search/react-selectize-stateless/src/actions.js
vendored
Normal file
44
spikes/fuzzy-search/react-selectize-stateless/src/actions.js
vendored
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
const buildArray = require('build-array');
|
||||||
|
const delay = require('delay');
|
||||||
|
const faker = require('faker');
|
||||||
|
|
||||||
|
const actions = {
|
||||||
|
'FETCH': (state, action) => {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
items: (state.items || []).concat(action.payload)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetch = () => (dispatch, getState) => {
|
||||||
|
|
||||||
|
return dispatch({
|
||||||
|
type: 'FETCH',
|
||||||
|
payload: () => {
|
||||||
|
// debugger
|
||||||
|
const {
|
||||||
|
items = []
|
||||||
|
} = getState();
|
||||||
|
|
||||||
|
return buildArray(200).map((v, i) => {
|
||||||
|
const id = items.length + i;
|
||||||
|
|
||||||
|
return {
|
||||||
|
id,
|
||||||
|
name: faker.name.firstName(),
|
||||||
|
meta: `${faker.name.firstName()}|${faker.random.number()}`,
|
||||||
|
key: faker.image.imageUrl()
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = (state, action) => {
|
||||||
|
return actions[action.type]
|
||||||
|
? actions[action.type](state, action)
|
||||||
|
: state;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.fetch = fetch;
|
18
spikes/fuzzy-search/react-selectize-stateless/src/index.js
vendored
Normal file
18
spikes/fuzzy-search/react-selectize-stateless/src/index.js
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
const Store = require('./store');
|
||||||
|
const ReactDOM = require('react-dom');
|
||||||
|
const React = require('react');
|
||||||
|
|
||||||
|
const render = () => {
|
||||||
|
const Root = require('./root');
|
||||||
|
|
||||||
|
ReactDOM.render(
|
||||||
|
<Root store={Store()} />,
|
||||||
|
document.getElementById('root')
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
render();
|
||||||
|
|
||||||
|
if (module.hot) {
|
||||||
|
module.hot.accept('./root', render);
|
||||||
|
}
|
24
spikes/fuzzy-search/react-selectize-stateless/src/root.js
vendored
Normal file
24
spikes/fuzzy-search/react-selectize-stateless/src/root.js
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
const ReactRedux = require('react-redux');
|
||||||
|
const ReactHotLoader = require('react-hot-loader');
|
||||||
|
const React = require('react');
|
||||||
|
const Search = require('./search');
|
||||||
|
|
||||||
|
const {
|
||||||
|
AppContainer
|
||||||
|
} = ReactHotLoader;
|
||||||
|
|
||||||
|
const {
|
||||||
|
Provider
|
||||||
|
} = ReactRedux;
|
||||||
|
|
||||||
|
module.exports = ({
|
||||||
|
store
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<AppContainer>
|
||||||
|
<Provider store={store}>
|
||||||
|
<Search />
|
||||||
|
</Provider>
|
||||||
|
</AppContainer>
|
||||||
|
);
|
||||||
|
};
|
28
spikes/fuzzy-search/react-selectize-stateless/src/search.js
vendored
Normal file
28
spikes/fuzzy-search/react-selectize-stateless/src/search.js
vendored
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
const actions = require('./actions');
|
||||||
|
const React = require('react');
|
||||||
|
const axios = require('axios');
|
||||||
|
const users = require('../../users');
|
||||||
|
|
||||||
|
const ReactSelectize = require("react-selectize");
|
||||||
|
const SimpleSelect = ReactSelectize.SimpleSelect;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const Search = () => {
|
||||||
|
|
||||||
|
let _options = ["apple", "mango", "grapes", "melon", "strawberry"];
|
||||||
|
_options = _options.map(function(fruit){
|
||||||
|
return {label: fruit, value: fruit}
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SimpleSelect
|
||||||
|
options={_options}
|
||||||
|
placeholder="Select a fruit"
|
||||||
|
theme="material"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Search;
|
||||||
|
|
19
spikes/fuzzy-search/react-selectize-stateless/src/store.js
vendored
Normal file
19
spikes/fuzzy-search/react-selectize-stateless/src/store.js
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
const createLogger = require('redux-logger');
|
||||||
|
const promiseMiddleware = require('redux-promise-middleware').default;
|
||||||
|
const thunk = require('redux-thunk').default;
|
||||||
|
const redux = require('redux');
|
||||||
|
const reducer = require('./actions');
|
||||||
|
|
||||||
|
const {
|
||||||
|
createStore,
|
||||||
|
compose,
|
||||||
|
applyMiddleware
|
||||||
|
} = redux;
|
||||||
|
|
||||||
|
module.exports = (state = Object.freeze({})) => {
|
||||||
|
return createStore(reducer, state, applyMiddleware(
|
||||||
|
createLogger(),
|
||||||
|
promiseMiddleware(),
|
||||||
|
thunk
|
||||||
|
));
|
||||||
|
};
|
7
spikes/fuzzy-search/react-selectize-stateless/static/.gitignore
vendored
Normal file
7
spikes/fuzzy-search/react-selectize-stateless/static/.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
*
|
||||||
|
!.gitignore
|
||||||
|
!.gitkeep
|
||||||
|
!index.html
|
||||||
|
|
||||||
|
js/*
|
||||||
|
!js/.gitkeep
|
@ -0,0 +1,10 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang='en-US'>
|
||||||
|
<head>
|
||||||
|
<title>Infinite List</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id='root'></div>
|
||||||
|
<script src='main.js'></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
56
spikes/fuzzy-search/react-selectize-stateless/webpack/base.js
vendored
Normal file
56
spikes/fuzzy-search/react-selectize-stateless/webpack/base.js
vendored
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
const webpack = require('webpack');
|
||||||
|
const path = require('path');
|
||||||
|
const ExtractTextPlugin = require('extract-text-webpack-plugin');
|
||||||
|
|
||||||
|
const plugins = {
|
||||||
|
'no-errors-plugin': new webpack.NoErrorsPlugin(),
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.config = {
|
||||||
|
context: path.join(__dirname, '../'),
|
||||||
|
output: {
|
||||||
|
path: path.join(__dirname, '../static'),
|
||||||
|
publicPath: '/',
|
||||||
|
filename: '[name].js'
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new webpack.NoErrorsPlugin(),
|
||||||
|
new ExtractTextPlugin({
|
||||||
|
filename: 'css/[name].css',
|
||||||
|
allChunks: true
|
||||||
|
}),
|
||||||
|
new webpack.LoaderOptionsPlugin({
|
||||||
|
options: {
|
||||||
|
postcss: {}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
],
|
||||||
|
module: {
|
||||||
|
loaders: [{
|
||||||
|
test: /js?$/,
|
||||||
|
exclude: /node_modules/,
|
||||||
|
include: [
|
||||||
|
path.join(__dirname, '../src')
|
||||||
|
],
|
||||||
|
loader: 'babel-loader'
|
||||||
|
}, {
|
||||||
|
test: /\.css?$/,
|
||||||
|
exclude: /node_modules/,
|
||||||
|
include: [
|
||||||
|
path.join(__dirname, '../src'),
|
||||||
|
path.join(__dirname, '../docs')
|
||||||
|
],
|
||||||
|
loader: ExtractTextPlugin.extract({
|
||||||
|
fallbackLoader: 'style-loader',
|
||||||
|
loader: [
|
||||||
|
'css-loader?',
|
||||||
|
'modules&importLoaders=1&',
|
||||||
|
'localIdentName=[name]__[local]___[hash:base64:5]!',
|
||||||
|
'postcss-loader'
|
||||||
|
].join('')
|
||||||
|
})
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.plugins = plugins;
|
29
spikes/fuzzy-search/react-selectize-stateless/webpack/index.js
vendored
Normal file
29
spikes/fuzzy-search/react-selectize-stateless/webpack/index.js
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
const base = require('./base.js');
|
||||||
|
const webpack = require('webpack');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const devServer = {
|
||||||
|
contentBase: [
|
||||||
|
path.join(__dirname, '../static/')
|
||||||
|
],
|
||||||
|
hot: true,
|
||||||
|
compress: true,
|
||||||
|
lazy: false,
|
||||||
|
historyApiFallback: {
|
||||||
|
index: './index.html'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = Object.assign(base.config, {
|
||||||
|
entry: [
|
||||||
|
'react-hot-loader/patch',
|
||||||
|
'webpack-dev-server/client?http://localhost:8080',
|
||||||
|
'webpack/hot/only-dev-server',
|
||||||
|
'./src/index.js'
|
||||||
|
],
|
||||||
|
plugins: base.config.plugins.concat([
|
||||||
|
new webpack.HotModuleReplacementPlugin()
|
||||||
|
]),
|
||||||
|
devtool: 'source-map',
|
||||||
|
devServer
|
||||||
|
});
|
3140
spikes/fuzzy-search/react-selectize-stateless/yarn.lock
Normal file
3140
spikes/fuzzy-search/react-selectize-stateless/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
15
spikes/fuzzy-search/react-selectize/.babelrc
Normal file
15
spikes/fuzzy-search/react-selectize/.babelrc
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"sourceMaps": "both",
|
||||||
|
"presets": [
|
||||||
|
"react",
|
||||||
|
"es2015"
|
||||||
|
],
|
||||||
|
"plugins": [
|
||||||
|
"react-hot-loader/babel",
|
||||||
|
"add-module-exports",
|
||||||
|
"syntax-async-functions",
|
||||||
|
["transform-object-rest-spread", {
|
||||||
|
"useBuiltIns": true
|
||||||
|
}]
|
||||||
|
]
|
||||||
|
}
|
41
spikes/fuzzy-search/react-selectize/package.json
Normal file
41
spikes/fuzzy-search/react-selectize/package.json
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"name": "react-infinite-spike",
|
||||||
|
"private": true,
|
||||||
|
"license": "private",
|
||||||
|
"scripts": {
|
||||||
|
"start": "webpack-dev-server --config webpack/index.js"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "^0.15.3",
|
||||||
|
"build-array": "^1.0.0",
|
||||||
|
"delay": "^1.3.1",
|
||||||
|
"lodash.debounce": "^4.0.8",
|
||||||
|
"react": "^15.4.0",
|
||||||
|
"react-addons-css-transition-group": "^15.4.1",
|
||||||
|
"react-addons-shallow-compare": "^15.4.1",
|
||||||
|
"react-dom": "^15.4.0",
|
||||||
|
"react-hot-loader": "^3.0.0-beta.6",
|
||||||
|
"react-infinite": "^0.10.0",
|
||||||
|
"react-redux": "^4.4.6",
|
||||||
|
"react-selectize": "^2.1.0",
|
||||||
|
"redux": "^3.6.0",
|
||||||
|
"redux-logger": "^2.7.4",
|
||||||
|
"redux-promise-middleware": "^4.1.0",
|
||||||
|
"redux-thunk": "^2.1.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"babel-core": "^6.18.2",
|
||||||
|
"babel-eslint": "^7.1.1",
|
||||||
|
"babel-loader": "^6.2.7",
|
||||||
|
"babel-plugin-add-module-exports": "^0.2.1",
|
||||||
|
"babel-plugin-syntax-async-functions": "^6.13.0",
|
||||||
|
"babel-plugin-transform-object-rest-spread": "^6.19.0",
|
||||||
|
"babel-preset-es2015": "^6.18.0",
|
||||||
|
"babel-preset-react": "^6.16.0",
|
||||||
|
"extract-text-webpack-plugin": "^2.0.0-beta.4",
|
||||||
|
"faker": "^3.1.0",
|
||||||
|
"style-loader": "^0.13.1",
|
||||||
|
"webpack": "^2.1.0-beta.27",
|
||||||
|
"webpack-dev-server": "^1.16.2"
|
||||||
|
}
|
||||||
|
}
|
7
spikes/fuzzy-search/react-selectize/readme.md
Normal file
7
spikes/fuzzy-search/react-selectize/readme.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# react-fuzzy-filter
|
||||||
|
|
||||||
|
- https://github.com/jdlehman/react-fuzzy-filter
|
||||||
|
|
||||||
|
- Does not use API endpoint, instead an array of objects needs to be created locally
|
||||||
|
- Hard to style - or didn't come easily straight out of the box
|
||||||
|
- Reqiures adding `react-addons-css-transition-group` and `react-addons-shallow-compare`
|
44
spikes/fuzzy-search/react-selectize/src/actions.js
vendored
Normal file
44
spikes/fuzzy-search/react-selectize/src/actions.js
vendored
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
const buildArray = require('build-array');
|
||||||
|
const delay = require('delay');
|
||||||
|
const faker = require('faker');
|
||||||
|
|
||||||
|
const actions = {
|
||||||
|
'FETCH': (state, action) => {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
items: (state.items || []).concat(action.payload)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetch = () => (dispatch, getState) => {
|
||||||
|
|
||||||
|
return dispatch({
|
||||||
|
type: 'FETCH',
|
||||||
|
payload: () => {
|
||||||
|
// debugger
|
||||||
|
const {
|
||||||
|
items = []
|
||||||
|
} = getState();
|
||||||
|
|
||||||
|
return buildArray(200).map((v, i) => {
|
||||||
|
const id = items.length + i;
|
||||||
|
|
||||||
|
return {
|
||||||
|
id,
|
||||||
|
name: faker.name.firstName(),
|
||||||
|
meta: `${faker.name.firstName()}|${faker.random.number()}`,
|
||||||
|
key: faker.image.imageUrl()
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = (state, action) => {
|
||||||
|
return actions[action.type]
|
||||||
|
? actions[action.type](state, action)
|
||||||
|
: state;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.fetch = fetch;
|
18
spikes/fuzzy-search/react-selectize/src/index.js
vendored
Normal file
18
spikes/fuzzy-search/react-selectize/src/index.js
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
const Store = require('./store');
|
||||||
|
const ReactDOM = require('react-dom');
|
||||||
|
const React = require('react');
|
||||||
|
|
||||||
|
const render = () => {
|
||||||
|
const Root = require('./root');
|
||||||
|
|
||||||
|
ReactDOM.render(
|
||||||
|
<Root store={Store()} />,
|
||||||
|
document.getElementById('root')
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
render();
|
||||||
|
|
||||||
|
if (module.hot) {
|
||||||
|
module.hot.accept('./root', render);
|
||||||
|
}
|
23
spikes/fuzzy-search/react-selectize/src/root.js
vendored
Normal file
23
spikes/fuzzy-search/react-selectize/src/root.js
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
const ReactRedux = require('react-redux');
|
||||||
|
const ReactHotLoader = require('react-hot-loader');
|
||||||
|
const React = require('react');
|
||||||
|
const Search = require('./search');
|
||||||
|
const {
|
||||||
|
AppContainer
|
||||||
|
} = ReactHotLoader;
|
||||||
|
|
||||||
|
const {
|
||||||
|
Provider
|
||||||
|
} = ReactRedux;
|
||||||
|
|
||||||
|
module.exports = ({
|
||||||
|
store
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<AppContainer>
|
||||||
|
<Provider store={store}>
|
||||||
|
<Search />
|
||||||
|
</Provider>
|
||||||
|
</AppContainer>
|
||||||
|
);
|
||||||
|
};
|
90
spikes/fuzzy-search/react-selectize/src/search-multi.js
vendored
Normal file
90
spikes/fuzzy-search/react-selectize/src/search-multi.js
vendored
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
const ReactRedux = require('react-redux');
|
||||||
|
const actions = require('./actions');
|
||||||
|
const React = require('react');
|
||||||
|
const axios = require('axios');
|
||||||
|
const users = require('../../users');
|
||||||
|
|
||||||
|
var ReactSelectize = require("react-selectize");
|
||||||
|
var MultiSelect = ReactSelectize.MultiSelect;
|
||||||
|
|
||||||
|
const {
|
||||||
|
connect
|
||||||
|
} = ReactRedux;
|
||||||
|
|
||||||
|
const {
|
||||||
|
fetch
|
||||||
|
} = actions;
|
||||||
|
|
||||||
|
const mapStateToProps = (state) => {
|
||||||
|
return state;
|
||||||
|
};
|
||||||
|
|
||||||
|
const mapDispatchToProps = (dispatch, ownProps) => {
|
||||||
|
return {
|
||||||
|
fetch: () => {
|
||||||
|
return dispatch(fetch());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const SearchMulti = React.createClass({
|
||||||
|
|
||||||
|
getInitialState: function(){
|
||||||
|
return {
|
||||||
|
countries: [],
|
||||||
|
country: undefined
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
componentWillMount: function(){
|
||||||
|
var self = this;
|
||||||
|
this.req = axios.get("http://restverse.com/countries").then(function(countries){
|
||||||
|
self.setState({countries: countries.data}, function(){
|
||||||
|
self.refs.select.highlightFirstSelectableOption();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function(){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
const _onValueChange = (country) => {
|
||||||
|
self.setState({country: country});
|
||||||
|
}
|
||||||
|
|
||||||
|
const _renderNoResultsFound = () => {
|
||||||
|
return (
|
||||||
|
<div className = "no-results-found">
|
||||||
|
{!!self.req ? "loading countries ..." : "No results found"}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h1>Multiple Options</h1>
|
||||||
|
<MultiSelect
|
||||||
|
ref = "select"
|
||||||
|
placeholder = "Select a country"
|
||||||
|
options = {this.state.countries}
|
||||||
|
value = {this.state.country}
|
||||||
|
onValueChange = {_onValueChange}
|
||||||
|
renderNoResultsFound = {_renderNoResultsFound}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{ !!self.state.country ? (
|
||||||
|
<div style = {{margin: 8}}>
|
||||||
|
<span>you selected: </span>
|
||||||
|
<span style = {{fontWeight: "bold"}}>{self.state.country.label}</span>
|
||||||
|
</div>
|
||||||
|
) : null }
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
module.exports = connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps,
|
||||||
|
)(SearchMulti);
|
90
spikes/fuzzy-search/react-selectize/src/search-single.js
vendored
Normal file
90
spikes/fuzzy-search/react-selectize/src/search-single.js
vendored
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
const ReactRedux = require('react-redux');
|
||||||
|
const actions = require('./actions');
|
||||||
|
const React = require('react');
|
||||||
|
const axios = require('axios');
|
||||||
|
const users = require('../../users');
|
||||||
|
|
||||||
|
var ReactSelectize = require("react-selectize");
|
||||||
|
var SimpleSelect = ReactSelectize.SimpleSelect;
|
||||||
|
|
||||||
|
const {
|
||||||
|
connect
|
||||||
|
} = ReactRedux;
|
||||||
|
|
||||||
|
const {
|
||||||
|
fetch
|
||||||
|
} = actions;
|
||||||
|
|
||||||
|
const mapStateToProps = (state) => {
|
||||||
|
return state;
|
||||||
|
};
|
||||||
|
|
||||||
|
const mapDispatchToProps = (dispatch, ownProps) => {
|
||||||
|
return {
|
||||||
|
fetch: () => {
|
||||||
|
return dispatch(fetch());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const Search = React.createClass({
|
||||||
|
|
||||||
|
getInitialState: function(){
|
||||||
|
return {
|
||||||
|
countries: [],
|
||||||
|
country: undefined
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
componentWillMount: function(){
|
||||||
|
var self = this;
|
||||||
|
this.req = axios.get("http://restverse.com/countries").then(function(countries){
|
||||||
|
self.setState({countries: countries.data}, function(){
|
||||||
|
self.refs.select.highlightFirstSelectableOption();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function(){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
const _onValueChange = (country) => {
|
||||||
|
self.setState({country: country});
|
||||||
|
}
|
||||||
|
|
||||||
|
const _renderNoResultsFound = () => {
|
||||||
|
return (
|
||||||
|
<div className = "no-results-found">
|
||||||
|
{!!self.req ? "loading countries ..." : "No results found"}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h1>Single Select</h1>
|
||||||
|
<SimpleSelect
|
||||||
|
ref = "select"
|
||||||
|
placeholder = "Select a country"
|
||||||
|
options = {this.state.countries}
|
||||||
|
value = {this.state.country}
|
||||||
|
onValueChange = {_onValueChange}
|
||||||
|
renderNoResultsFound = {_renderNoResultsFound}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{ !!self.state.country ? (
|
||||||
|
<div style = {{margin: 8}}>
|
||||||
|
<span>you selected: </span>
|
||||||
|
<span style = {{fontWeight: "bold"}}>{self.state.country.label}</span>
|
||||||
|
</div>
|
||||||
|
) : null }
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
module.exports = connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps,
|
||||||
|
)(Search);
|
15
spikes/fuzzy-search/react-selectize/src/search.js
vendored
Normal file
15
spikes/fuzzy-search/react-selectize/src/search.js
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
const React = require('react');
|
||||||
|
const SearchSingle = require('./search-single');
|
||||||
|
const SearchMulti = require('./search-multi')
|
||||||
|
|
||||||
|
const Search = () => {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<SearchSingle />
|
||||||
|
<SearchMulti />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Search
|
19
spikes/fuzzy-search/react-selectize/src/store.js
vendored
Normal file
19
spikes/fuzzy-search/react-selectize/src/store.js
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
const createLogger = require('redux-logger');
|
||||||
|
const promiseMiddleware = require('redux-promise-middleware').default;
|
||||||
|
const thunk = require('redux-thunk').default;
|
||||||
|
const redux = require('redux');
|
||||||
|
const reducer = require('./actions');
|
||||||
|
|
||||||
|
const {
|
||||||
|
createStore,
|
||||||
|
compose,
|
||||||
|
applyMiddleware
|
||||||
|
} = redux;
|
||||||
|
|
||||||
|
module.exports = (state = Object.freeze({})) => {
|
||||||
|
return createStore(reducer, state, applyMiddleware(
|
||||||
|
createLogger(),
|
||||||
|
promiseMiddleware(),
|
||||||
|
thunk
|
||||||
|
));
|
||||||
|
};
|
7
spikes/fuzzy-search/react-selectize/static/.gitignore
vendored
Normal file
7
spikes/fuzzy-search/react-selectize/static/.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
*
|
||||||
|
!.gitignore
|
||||||
|
!.gitkeep
|
||||||
|
!index.html
|
||||||
|
|
||||||
|
js/*
|
||||||
|
!js/.gitkeep
|
10
spikes/fuzzy-search/react-selectize/static/index.html
Normal file
10
spikes/fuzzy-search/react-selectize/static/index.html
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang='en-US'>
|
||||||
|
<head>
|
||||||
|
<title>Multi Select</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id='root'></div>
|
||||||
|
<script src='main.js'></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
56
spikes/fuzzy-search/react-selectize/webpack/base.js
vendored
Normal file
56
spikes/fuzzy-search/react-selectize/webpack/base.js
vendored
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
const webpack = require('webpack');
|
||||||
|
const path = require('path');
|
||||||
|
const ExtractTextPlugin = require('extract-text-webpack-plugin');
|
||||||
|
|
||||||
|
const plugins = {
|
||||||
|
'no-errors-plugin': new webpack.NoErrorsPlugin(),
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.config = {
|
||||||
|
context: path.join(__dirname, '../'),
|
||||||
|
output: {
|
||||||
|
path: path.join(__dirname, '../static'),
|
||||||
|
publicPath: '/',
|
||||||
|
filename: '[name].js'
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new webpack.NoErrorsPlugin(),
|
||||||
|
new ExtractTextPlugin({
|
||||||
|
filename: 'css/[name].css',
|
||||||
|
allChunks: true
|
||||||
|
}),
|
||||||
|
new webpack.LoaderOptionsPlugin({
|
||||||
|
options: {
|
||||||
|
postcss: {}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
],
|
||||||
|
module: {
|
||||||
|
loaders: [{
|
||||||
|
test: /js?$/,
|
||||||
|
exclude: /node_modules/,
|
||||||
|
include: [
|
||||||
|
path.join(__dirname, '../src')
|
||||||
|
],
|
||||||
|
loader: 'babel-loader'
|
||||||
|
}, {
|
||||||
|
test: /\.css?$/,
|
||||||
|
exclude: /node_modules/,
|
||||||
|
include: [
|
||||||
|
path.join(__dirname, '../src'),
|
||||||
|
path.join(__dirname, '../docs')
|
||||||
|
],
|
||||||
|
loader: ExtractTextPlugin.extract({
|
||||||
|
fallbackLoader: 'style-loader',
|
||||||
|
loader: [
|
||||||
|
'css-loader?',
|
||||||
|
'modules&importLoaders=1&',
|
||||||
|
'localIdentName=[name]__[local]___[hash:base64:5]!',
|
||||||
|
'postcss-loader'
|
||||||
|
].join('')
|
||||||
|
})
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.plugins = plugins;
|
29
spikes/fuzzy-search/react-selectize/webpack/index.js
vendored
Normal file
29
spikes/fuzzy-search/react-selectize/webpack/index.js
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
const base = require('./base.js');
|
||||||
|
const webpack = require('webpack');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const devServer = {
|
||||||
|
contentBase: [
|
||||||
|
path.join(__dirname, '../static/')
|
||||||
|
],
|
||||||
|
hot: true,
|
||||||
|
compress: true,
|
||||||
|
lazy: false,
|
||||||
|
historyApiFallback: {
|
||||||
|
index: './index.html'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = Object.assign(base.config, {
|
||||||
|
entry: [
|
||||||
|
'react-hot-loader/patch',
|
||||||
|
'webpack-dev-server/client?http://localhost:8080',
|
||||||
|
'webpack/hot/only-dev-server',
|
||||||
|
'./src/index.js'
|
||||||
|
],
|
||||||
|
plugins: base.config.plugins.concat([
|
||||||
|
new webpack.HotModuleReplacementPlugin()
|
||||||
|
]),
|
||||||
|
devtool: 'source-map',
|
||||||
|
devServer
|
||||||
|
});
|
3140
spikes/fuzzy-search/react-selectize/yarn.lock
Normal file
3140
spikes/fuzzy-search/react-selectize/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
62
spikes/fuzzy-search/users.js
Normal file
62
spikes/fuzzy-search/users.js
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
module.exports = [
|
||||||
|
{
|
||||||
|
"name": "Franks Howe",
|
||||||
|
"integer": 0,
|
||||||
|
"meta": "Franks Howe|0",
|
||||||
|
"tag": "ea"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Lucas Barlow",
|
||||||
|
"integer": 1,
|
||||||
|
"meta": "Lucas Barlow|1",
|
||||||
|
"tag": "dolore"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Black Cote",
|
||||||
|
"integer": 3,
|
||||||
|
"meta": "Black Cote|3",
|
||||||
|
"tag": "eu"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Francisca Pickett",
|
||||||
|
"integer": 10,
|
||||||
|
"meta": "Francisca Pickett|10",
|
||||||
|
"tag": "ipsum"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Debbie Morris",
|
||||||
|
"integer": 2,
|
||||||
|
"meta": "Debbie Morris|2",
|
||||||
|
"tag": "consectetur"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Olga Mclean",
|
||||||
|
"integer": 7,
|
||||||
|
"meta": "Olga Mclean|7",
|
||||||
|
"tag": "laboris"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Wendy Cabrera",
|
||||||
|
"integer": 8,
|
||||||
|
"meta": "Wendy Cabrera|8",
|
||||||
|
"tag": "nisi"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Nell Duncan",
|
||||||
|
"integer": 3,
|
||||||
|
"meta": "Nell Duncan|3",
|
||||||
|
"tag": "qui"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Mendoza Wiggins",
|
||||||
|
"integer": 4,
|
||||||
|
"meta": "Mendoza Wiggins|4",
|
||||||
|
"tag": "Lorem"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Edith Franklin",
|
||||||
|
"integer": 3,
|
||||||
|
"meta": "Edith Franklin|3",
|
||||||
|
"tag": "exercitation"
|
||||||
|
}
|
||||||
|
]
|
1
ui/.storybook/head.html
Normal file
1
ui/.storybook/head.html
Normal file
@ -0,0 +1 @@
|
|||||||
|
<link href="https://fonts.googleapis.com/css?family=Libre+Franklin:400,600" rel="stylesheet">
|
@ -4,7 +4,6 @@ ARG CIRCLE_BUILD_NUM
|
|||||||
ENV NPM_TOKEN ${NPM_TOKEN}
|
ENV NPM_TOKEN ${NPM_TOKEN}
|
||||||
ENV CIRCLE_BUILD_NUM ${CIRCLE_BUILD_NUM}
|
ENV CIRCLE_BUILD_NUM ${CIRCLE_BUILD_NUM}
|
||||||
RUN echo -e "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > .npmrc
|
RUN echo -e "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > .npmrc
|
||||||
RUN make install
|
|
||||||
RUN NODE_ENV=production make compile
|
RUN NODE_ENV=production make compile
|
||||||
RUN npm version 0.0.1-${CIRCLE_BUILD_NUM}
|
RUN npm version 0.0.1-${CIRCLE_BUILD_NUM}
|
||||||
RUN npm publish --tag alpha --access public
|
RUN npm publish --tag alpha --access public
|
||||||
|
@ -28,7 +28,7 @@ install-docs:
|
|||||||
|
|
||||||
.PHONY: install
|
.PHONY: install
|
||||||
install: install-embed-markdown-loader
|
install: install-embed-markdown-loader
|
||||||
yarn install --prefer-offline
|
NODE_ENV=development yarn install --prefer-offline
|
||||||
|
|
||||||
.PHONY: start
|
.PHONY: start
|
||||||
start:
|
start:
|
||||||
|
@ -1,4 +1,14 @@
|
|||||||
const React = require('react');
|
const React = require('react');
|
||||||
|
const Styled = require('styled-components');
|
||||||
|
const constants = require('../../shared/constants');
|
||||||
|
|
||||||
|
const {
|
||||||
|
colors
|
||||||
|
} = constants;
|
||||||
|
|
||||||
|
const {
|
||||||
|
default: styled
|
||||||
|
} = Styled;
|
||||||
|
|
||||||
const buildArray = require('build-array');
|
const buildArray = require('build-array');
|
||||||
const Chart = require('chart.js');
|
const Chart = require('chart.js');
|
||||||
@ -6,6 +16,62 @@ const whisker = require('chartjs-chart-box-plot');
|
|||||||
|
|
||||||
whisker(Chart);
|
whisker(Chart);
|
||||||
|
|
||||||
|
const StyledDiv = styled.div`
|
||||||
|
height: 127px;
|
||||||
|
width: 158px;
|
||||||
|
background-color: ${colors.miniBackground};
|
||||||
|
border: solid 1px ${colors.borderSecondary};
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1;
|
||||||
|
width: 9px;
|
||||||
|
height: 127px;
|
||||||
|
background-image:
|
||||||
|
linear-gradient(to right, rgba(0, 0, 0, 0.1), rgba(216, 216, 216, 0));
|
||||||
|
content: '';
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Devider = styled.div`
|
||||||
|
width: 158px;
|
||||||
|
height: 1px;
|
||||||
|
background-color: ${colors.seperator}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const TextMetric = styled.div`
|
||||||
|
height: 38px;
|
||||||
|
padding: 8px 12px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const InnerTextBox = styled.div`
|
||||||
|
width: 136px;
|
||||||
|
height: 36px;
|
||||||
|
font-family: 'Libre Franklin', sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
font-stretch: normal;
|
||||||
|
line-height: 18px;
|
||||||
|
text-align: right;
|
||||||
|
color: ${colors.regular};
|
||||||
|
|
||||||
|
& p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
& h3 {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1.29;
|
||||||
|
color: ${colors.semibold};
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const StyledCanvas = styled.canvas`
|
||||||
|
`;
|
||||||
|
|
||||||
class MiniMetric extends React.Component {
|
class MiniMetric extends React.Component {
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const {
|
const {
|
||||||
@ -22,13 +88,16 @@ class MiniMetric extends React.Component {
|
|||||||
this._chart = new Chart(this._refs.component, {
|
this._chart = new Chart(this._refs.component, {
|
||||||
type: 'whisker',
|
type: 'whisker',
|
||||||
responsive: true,
|
responsive: true,
|
||||||
|
maintainAspectRatio: true,
|
||||||
options: {
|
options: {
|
||||||
scales: {
|
scales: {
|
||||||
xAxes: [{
|
xAxes: [{
|
||||||
|
display: false,
|
||||||
barPercentage: 1.0,
|
barPercentage: 1.0,
|
||||||
categoryPercentage: 1.0
|
categoryPercentage: 1.0
|
||||||
}],
|
}],
|
||||||
yAxes: [{
|
yAxes: [{
|
||||||
|
display: false,
|
||||||
ticks: {
|
ticks: {
|
||||||
min: min,
|
min: min,
|
||||||
max: max
|
max: max
|
||||||
@ -36,7 +105,7 @@ class MiniMetric extends React.Component {
|
|||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
legend: {
|
legend: {
|
||||||
display: true
|
display: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
@ -63,12 +132,25 @@ class MiniMetric extends React.Component {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
render() {
|
render() {
|
||||||
|
const {
|
||||||
|
name,
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<canvas
|
<StyledDiv>
|
||||||
height='400'
|
<TextMetric>
|
||||||
ref={this.ref('component')}
|
<InnerTextBox>
|
||||||
width='400'
|
<h3>{name}: 54%</h3>
|
||||||
/>
|
<p>(1280/3000 MB)</p>
|
||||||
|
</InnerTextBox>
|
||||||
|
</TextMetric>
|
||||||
|
<Devider />
|
||||||
|
<StyledCanvas
|
||||||
|
height='72'
|
||||||
|
innerRef={this.ref('component')}
|
||||||
|
width='157'
|
||||||
|
/>
|
||||||
|
</StyledDiv>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -78,6 +160,7 @@ MiniMetric.propTypes = {
|
|||||||
labels: React.PropTypes.number,
|
labels: React.PropTypes.number,
|
||||||
max: React.PropTypes.number,
|
max: React.PropTypes.number,
|
||||||
min: React.PropTypes.number,
|
min: React.PropTypes.number,
|
||||||
|
name: React.PropTypes.string,
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = MiniMetric;
|
module.exports = MiniMetric;
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
const fonts = {
|
||||||
|
semibold: '#464646',
|
||||||
|
regular: '#646464'
|
||||||
|
};
|
||||||
|
|
||||||
const brandPrimary = {
|
const brandPrimary = {
|
||||||
brandPrimary: '#3B46CC',
|
brandPrimary: '#3B46CC',
|
||||||
brandPrimaryDark: '#1838C0',
|
brandPrimaryDark: '#1838C0',
|
||||||
@ -32,11 +37,18 @@ const notifications = {
|
|||||||
warningLight: '#FFFAED',
|
warningLight: '#FFFAED',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const metrics = {
|
||||||
|
miniBackground: '#F3F4F9',
|
||||||
|
seperator: '#D9DEF3'
|
||||||
|
};
|
||||||
|
|
||||||
const colors = {
|
const colors = {
|
||||||
...brandPrimary,
|
...brandPrimary,
|
||||||
...brandSecondary,
|
...brandSecondary,
|
||||||
...brandInactive,
|
...brandInactive,
|
||||||
...notifications
|
...notifications,
|
||||||
|
...metrics,
|
||||||
|
...fonts
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = colors;
|
module.exports = colors;
|
||||||
|
@ -306,7 +306,139 @@ storiesOf('Widget', module)
|
|||||||
</Widget>
|
</Widget>
|
||||||
));
|
));
|
||||||
|
|
||||||
|
const colors = {
|
||||||
|
perc: 'rgba(54, 74, 205, 0.2)',
|
||||||
|
alt: 'rgba(245, 93, 93, 0.2)'
|
||||||
|
};
|
||||||
storiesOf('Metrics', module)
|
storiesOf('Metrics', module)
|
||||||
.add('mini', () => (
|
.add('Mini Metric', () => (
|
||||||
<MiniMetric />
|
<MiniMetric
|
||||||
|
datasets={[{
|
||||||
|
backgroundColor: colors['perc'],
|
||||||
|
altBackgroundColor: colors['alt'],
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
firstQuartile: 15,
|
||||||
|
thirdQuartile: 15,
|
||||||
|
median: 15,
|
||||||
|
max: 15,
|
||||||
|
min: 15,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
firstQuartile: 26,
|
||||||
|
thirdQuartile: 26,
|
||||||
|
median: 26,
|
||||||
|
max: 26,
|
||||||
|
min: 26,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
firstQuartile: 17,
|
||||||
|
thirdQuartile: 17,
|
||||||
|
median: 17,
|
||||||
|
max: 17,
|
||||||
|
min: 17,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
firstQuartile: 15,
|
||||||
|
thirdQuartile: 25,
|
||||||
|
median: 19,
|
||||||
|
max: 19,
|
||||||
|
min: 20,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
firstQuartile: 19,
|
||||||
|
thirdQuartile: 25,
|
||||||
|
median: 21,
|
||||||
|
max: 20,
|
||||||
|
min: 25,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
firstQuartile: 24,
|
||||||
|
thirdQuartile: 30,
|
||||||
|
median: 25,
|
||||||
|
max: 26,
|
||||||
|
min: 27,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
firstQuartile: 28,
|
||||||
|
thirdQuartile: 34,
|
||||||
|
median: 30,
|
||||||
|
max: 30,
|
||||||
|
min: 30,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
firstQuartile: 30,
|
||||||
|
thirdQuartile: 45,
|
||||||
|
median: 35,
|
||||||
|
max: 40,
|
||||||
|
min: 40,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
firstQuartile: 20,
|
||||||
|
thirdQuartile: 55,
|
||||||
|
median: 45,
|
||||||
|
max: 44,
|
||||||
|
min: 44,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
firstQuartile: 55,
|
||||||
|
thirdQuartile: 55,
|
||||||
|
median: 55,
|
||||||
|
max: 55,
|
||||||
|
min: 55,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
firstQuartile: 57,
|
||||||
|
thirdQuartile: 56,
|
||||||
|
median: 57,
|
||||||
|
max: 58,
|
||||||
|
min: 57,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
firstQuartile: 57,
|
||||||
|
thirdQuartile: 56,
|
||||||
|
median: 56,
|
||||||
|
max: 56,
|
||||||
|
min: 56,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
firstQuartile: 60,
|
||||||
|
thirdQuartile: 56,
|
||||||
|
median: 60,
|
||||||
|
max: 60,
|
||||||
|
min: 60,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
firstQuartile: 57,
|
||||||
|
thirdQuartile: 57,
|
||||||
|
median: 57,
|
||||||
|
max: 57,
|
||||||
|
min: 57,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
firstQuartile: 57,
|
||||||
|
thirdQuartile: 55,
|
||||||
|
median: 55,
|
||||||
|
max: 55,
|
||||||
|
min: 55,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
firstQuartile: 20,
|
||||||
|
thirdQuartile: 45,
|
||||||
|
median: 45,
|
||||||
|
max: 45,
|
||||||
|
min: 45,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
firstQuartile: 15,
|
||||||
|
thirdQuartile: 40,
|
||||||
|
median: 30,
|
||||||
|
max: 49,
|
||||||
|
min: 30,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}]}
|
||||||
|
labels={17}
|
||||||
|
name='Memory'
|
||||||
|
/>
|
||||||
));
|
));
|
||||||
|
Loading…
Reference in New Issue
Block a user