summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/commands/site/export.py38
-rw-r--r--frontend/common/index.js3
-rw-r--r--frontend/common/loader.component.js16
-rw-r--r--frontend/common/miscellaneous.component.js11
-rw-r--r--frontend/site/site/site.actions.js20
-rw-r--r--frontend/site/viewer/viewer.container.js2
-rw-r--r--frontend/views/page/components/tile.handle.js2
-rw-r--r--frontend/views/page/cursors.css15
-rw-r--r--frontend/views/page/page.container.js1
-rw-r--r--frontend/views/page/page.css15
-rw-r--r--static/site.css129
-rw-r--r--static/site.html1
-rw-r--r--webpack.config.prod.js5
-rw-r--r--webpack.config.site.js55
14 files changed, 244 insertions, 69 deletions
diff --git a/cli/commands/site/export.py b/cli/commands/site/export.py
index cf6be7b..d715c6c 100644
--- a/cli/commands/site/export.py
+++ b/cli/commands/site/export.py
@@ -3,6 +3,7 @@ import click
from app.settings import app_cfg
from app.utils.file_utils import load_text, write_json, write_text
from os.path import join
+import os
@click.command('info')
@click.option('-g', '--graph', 'opt_graph_path', required=True,
@@ -17,6 +18,7 @@ def cli(ctx, opt_graph_path, opt_output_dir):
# imports
from app.sql.common import db, Session, Graph, Page, Tile
+ from distutils.dir_util import copy_tree
# ------------------------------------------------
# generate HTML for index and all pages
@@ -27,16 +29,30 @@ def cli(ctx, opt_graph_path, opt_output_dir):
print(f"Not a graph: {opt_graph_path}")
return
- print(f"Output site to {opt_output_dir}")
+ # build everything here
+ graph_dir = join(opt_output_dir, graph.path)
+ # load site index
+ index_html = load_text(join(app_cfg.DIR_STATIC, 'site.html'), split=False)
+ index_html = index_html.replace('SITE_PATH', '/' + graph.path)
+
+ # write site JSON data
site_data = { 'graph': sanitize_graph(graph.toSiteJSON()) }
+ write_json(site_data, join(graph_dir, 'index.json'), default=str)
- index_html = load_text(join(app_cfg.DIR_STATIC, 'site.html'), split=False)
- write_json(site_data, join(opt_output_dir, graph.path, 'index.json'), default=str)
- # write_index(graph, None, index_html, join(opt_output_dir, graph.path, 'index.html'))
+ # import custom css
+ site_css = load_text(join(app_cfg.DIR_STATIC, 'site.css'), split=False)
+ site_css = site_css.replace('SITE_PATH', '/' + graph.path)
+ write_text(site_css, join(graph_dir, 'site.css'))
+ copy_tree(join(app_cfg.DIR_STATIC, 'fonts'), join(graph_dir, 'static/fonts'))
+ copy_tree(join(app_cfg.DIR_STATIC, 'img'), join(graph_dir, 'static/img'))
+ # write index file, redirects to homepage
home_page = site_data['graph']['home_page']
- write_text(f'<meta http-equiv="refresh" content="0; url={home_page}">', join(opt_output_dir, graph.path, 'index.html'))
+ if home_page is None:
+ print("Homepage not set! Shift-click a page on the graph to make it the homepage.")
+ return
+ write_text(f'<meta http-equiv="refresh" content="0; url={home_page}">', join(graph_dir, 'index.html'))
index_path = ""
for page in graph.pages:
@@ -46,12 +62,18 @@ def cli(ctx, opt_graph_path, opt_output_dir):
print(f'/{page_path} [index]')
else:
print(f'/{page_path}')
- write_index(graph, page, index_html, join(opt_output_dir, graph.path, page.path, 'index.html'))
+ write_index(graph, page, index_html, join(graph_dir, page.path, 'index.html'))
# ------------------------------------------------
- # generate javascript...
+ # build javascript
+
+ print("Building javascript...")
+ print(f'NODE_ENV=production webpack --config ./webpack.config.site.js -o {graph_dir}/bundle.js')
+ os.chdir(app_cfg.DIR_PROJECT_ROOT)
+ os.system(f'NODE_ENV=production webpack --config ./webpack.config.site.js -o {graph_dir}/bundle.js')
- # NODE_ENV=production webpack --config ./webpack.config.site.js -o ./data_store/exports/asdf/bundle.js
+ print("Site export complete!")
+ print(f"Graph exported to: {graph_dir}")
def write_index(graph, page, index_html, fp_out):
if page is None:
diff --git a/frontend/common/index.js b/frontend/common/index.js
index 3647203..5c0dc50 100644
--- a/frontend/common/index.js
+++ b/frontend/common/index.js
@@ -8,9 +8,10 @@ export {
LabelDescription, ColorInput,
} from './form.component'
export {
- Loader, Swatch, Dot, Columns, Statistic, Detections, Progress
+ Swatch, Dot, Columns, Statistic, Detections, Progress
} from './miscellaneous.component'
export { default as TableIndex } from './tableIndex.component'
+export { Loader } from './loader.component'
export {
TableObject, TableArray, TableTuples,
TableRow, TableCell
diff --git a/frontend/common/loader.component.js b/frontend/common/loader.component.js
new file mode 100644
index 0000000..f0a0c69
--- /dev/null
+++ b/frontend/common/loader.component.js
@@ -0,0 +1,16 @@
+import React, { Component } from 'react';
+
+import './loader.css'
+
+const Loader = () => (
+ <div>
+ <div className='circular-loader color'>
+ <div className="stroke">
+ <div className="stroke-left"></div>
+ <div className="stroke-right"></div>
+ </div>
+ </div>
+ </div>
+)
+
+export { Loader }
diff --git a/frontend/common/miscellaneous.component.js b/frontend/common/miscellaneous.component.js
index 4eb23f1..cf12ef5 100644
--- a/frontend/common/miscellaneous.component.js
+++ b/frontend/common/miscellaneous.component.js
@@ -2,17 +2,6 @@ import React, { Component } from 'react';
import { Link } from 'react-router-dom'
import { clamp, percent } from '../util'
-export const Loader = () => (
- <div>
- <div className='circular-loader color'>
- <div className="stroke">
- <div className="stroke-left"></div>
- <div className="stroke-right"></div>
- </div>
- </div>
- </div>
-)
-
export const Swatch = ({ color }) => (
<div
className='swatch'
diff --git a/frontend/site/site/site.actions.js b/frontend/site/site/site.actions.js
index 2362e5f..5724df8 100644
--- a/frontend/site/site/site.actions.js
+++ b/frontend/site/site/site.actions.js
@@ -11,14 +11,14 @@ export const setSiteTitle = title => dispatch => {
export const loadSite = (graph_name, path_name) => dispatch => (
api(dispatch, types.site, 'site', '/' + graph_name + '/index.json')
- .then(res => {
- const { graph } = res.data
- // console.log(graph)
- // console.log(graph.home_page)
- const first_path = ["", graph_name, path_name].join("/")
- if (!path_name || !(first_path in graph.pages)) {
- // console.log(graph.home_page)
- window.location.href = graph.home_page
- }
- })
+ // .then(res => {
+ // const { graph } = res.data
+ // // console.log(graph)
+ // // console.log(graph.home_page)
+ // const first_path = ["", graph_name, path_name].join("/")
+ // if (!path_name || !(first_path in graph.pages)) {
+ // // console.log(graph.home_page)
+ // window.location.href = graph.home_page
+ // }
+ // })
)
diff --git a/frontend/site/viewer/viewer.container.js b/frontend/site/viewer/viewer.container.js
index 68088d2..da81551 100644
--- a/frontend/site/viewer/viewer.container.js
+++ b/frontend/site/viewer/viewer.container.js
@@ -4,7 +4,7 @@ import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import actions from '../actions'
-import { Loader } from '../../common'
+import { Loader } from '../../common/loader.component'
import TileHandle from '../../views/page/components/tile.handle'
import '../../views/page/page.css'
diff --git a/frontend/views/page/components/tile.handle.js b/frontend/views/page/components/tile.handle.js
index f3a700b..bd47ae9 100644
--- a/frontend/views/page/components/tile.handle.js
+++ b/frontend/views/page/components/tile.handle.js
@@ -11,7 +11,7 @@ const TileHandle = ({ tile, bounds, box, viewing, onMouseDown, onDoubleClick })
// console.log(generateTransform(tile))
let content;
let className = ['tile', tile.type].join(' ')
- if (tile.target_page_id) {
+ if (tile.target_page_id || (viewing && tile.href)) {
className += ' ' + (tile.settings.cursor || 'hand_up')
}
// console.log(tile.settings)
diff --git a/frontend/views/page/cursors.css b/frontend/views/page/cursors.css
new file mode 100644
index 0000000..5f90dd1
--- /dev/null
+++ b/frontend/views/page/cursors.css
@@ -0,0 +1,15 @@
+/* cursors */
+/* keep in separate file so they don't conflict. a copy of this lives in site.css */
+
+.tile.hand_up {
+ cursor: url(/static/img/hand_up.png) 40 10, pointer;
+}
+.tile.hand_right {
+ cursor: url(/static/img/hand_right.png) 90 40, pointer;
+}
+.tile.hand_down {
+ cursor: url(/static/img/hand_down.png) 60 90, pointer;
+}
+.tile.hand_left {
+ cursor: url(/static/img/hand_left.png) 10 60, pointer;
+}
diff --git a/frontend/views/page/page.container.js b/frontend/views/page/page.container.js
index 5da41d6..26bed30 100644
--- a/frontend/views/page/page.container.js
+++ b/frontend/views/page/page.container.js
@@ -4,6 +4,7 @@ import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import './page.css'
+import './cursors.css'
import actions from '../../actions'
import { Loader } from '../../common'
diff --git a/frontend/views/page/page.css b/frontend/views/page/page.css
index c29aff2..ec41241 100644
--- a/frontend/views/page/page.css
+++ b/frontend/views/page/page.css
@@ -168,18 +168,3 @@
width: 6rem;
max-width: 6rem;
}
-
-/* cursors */
-
-.tile.hand_up {
- cursor: url(/static/img/hand_up.png) 40 10, pointer;
-}
-.tile.hand_right {
- cursor: url(/static/img/hand_right.png) 90 40, pointer;
-}
-.tile.hand_down {
- cursor: url(/static/img/hand_down.png) 60 90, pointer;
-}
-.tile.hand_left {
- cursor: url(/static/img/hand_left.png) 10 60, pointer;
-}
diff --git a/static/site.css b/static/site.css
new file mode 100644
index 0000000..7f4a733
--- /dev/null
+++ b/static/site.css
@@ -0,0 +1,129 @@
+
+* { box-sizing: border-box; }
+html, body {
+ margin: 0;
+ padding: 0;
+ width: 100%;
+ height: 100%;
+}
+body {
+ background: #000;
+ color: #ddd;
+ overflow: hidden;
+ font-family: 'Roboto', sans-serif;
+ font-size: 0.875rem;
+ height: 100%;
+ width: 100%;
+}
+.gray {
+ color: #888;
+}
+
+/* layout */
+
+.container {
+ height: 100%;
+ width: 100%;
+}
+.app {
+ /*display: flex;*/
+ height: 100%;
+ width: 100%;
+}
+.app > div {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ width: 100%;
+}
+.app .body {
+ display: flex;
+ flex-direction: column;
+ flex-grow: 1;
+ position: relative;
+ height: 100%;
+ width: 100%;
+}
+
+.row {
+ display: flex;
+ flex-direction: row;
+ justify-content: flex-start;
+ align-items: flex-start;
+}
+.row > div {
+ margin-right: 1.5rem;
+}
+.row > div:last-child {
+ margin-right: 0;
+}
+
+@font-face {
+ font-family: 'Roboto';
+ src: url('SITE_PATH/static/fonts/Roboto-Bold.ttf') format('truetype');
+ font-weight: bold;
+}
+@font-face {
+ font-family: 'Roboto';
+ src: url('SITE_PATH/static/fonts/Roboto-BoldItalic.ttf') format('truetype');
+ font-weight: bold;
+ font-style: italic;
+}
+/*
+@font-face {
+ font-family: 'Roboto';
+ src: url('SITE_PATH/static/fonts/Roboto-Light.ttf') format('truetype');
+ font-weight: 100;
+}
+@font-face {
+ font-family: 'Roboto';
+ src: url('SITE_PATH/static/fonts/Roboto-LightItalic.ttf') format('truetype');
+ font-weight: 100;
+}
+*/
+@font-face {
+ font-family: 'Roboto';
+ src: url('SITE_PATH/static/fonts/Roboto-Medium.ttf') format('truetype');
+ font-weight: 300;
+}
+@font-face {
+ font-family: 'Roboto';
+ src: url('SITE_PATH/static/fonts/Roboto-MediumItalic.ttf') format('truetype');
+ font-style: italic;
+ font-weight: 300;
+}
+@font-face {
+ font-family: 'Roboto';
+ src: url('SITE_PATH/static/fonts/Roboto-Regular.ttf') format('truetype');
+}
+@font-face {
+ font-family: 'Roboto';
+ src: url('SITE_PATH/static/fonts/Roboto-Italic.ttf') format('truetype');
+ font-style: italic;
+}
+/*
+@font-face {
+ font-family: 'Roboto';
+ src: url('SITE_PATH/static/fonts/Roboto-Thin.ttf') format('truetype');
+ font-weight: 100;
+}
+@font-face {
+ font-family: 'Roboto';
+ src: url('SITE_PATH/static/fonts/Roboto-ThinItalic.ttf') format('truetype');
+ font-weight: 100;
+}
+*/
+
+
+.tile.hand_up {
+ cursor: url(SITE_PATH/static/img/hand_up.png) 40 10, pointer;
+}
+.tile.hand_right {
+ cursor: url(SITE_PATH/static/img/hand_right.png) 90 40, pointer;
+}
+.tile.hand_down {
+ cursor: url(SITE_PATH/static/img/hand_down.png) 60 90, pointer;
+}
+.tile.hand_left {
+ cursor: url(SITE_PATH/static/img/hand_left.png) 10 60, pointer;
+}
diff --git a/static/site.html b/static/site.html
index 18bd0d0..e19847b 100644
--- a/static/site.html
+++ b/static/site.html
@@ -4,6 +4,7 @@
<meta charset="UTF-8">
<title>PAGE_TITLE</title>
<meta name="viewport" content="width=device-width,initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="SITE_PATH/site.css" />
<style>
html { background: #000; }
</style>
diff --git a/webpack.config.prod.js b/webpack.config.prod.js
index b57c765..6e9f404 100644
--- a/webpack.config.prod.js
+++ b/webpack.config.prod.js
@@ -18,8 +18,9 @@ module.exports = {
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify("production"),
- 'process.env.S3_HOST': JSON.stringify(process.env.S3_HOST || ""),
- 'process.env.API_HOST': JSON.stringify(process.env.API_HOST || ""),
+ // 'process.env.S3_HOST': JSON.stringify(process.env.S3_HOST || ""),
+ // 'process.env.API_HOST': JSON.stringify(process.env.API_HOST || ""),
+ '__REACT_DEVTOOLS_GLOBAL_HOOK__': '({ isDisabled: true })'
}),
new TerserPlugin(),
new webpack.optimize.AggressiveMergingPlugin(),
diff --git a/webpack.config.site.js b/webpack.config.site.js
index 8a62c75..07a48c8 100644
--- a/webpack.config.site.js
+++ b/webpack.config.site.js
@@ -2,12 +2,12 @@ require('dotenv').config()
const webpack = require('webpack')
const path = require('path')
+const TerserPlugin = require('terser-webpack-plugin')
+
-// print stack-trace of deprecations in webpack plugins, if something causes this
-// process.traceDeprecation = true
module.exports = {
- mode: "development",
+ mode: "production",
entry: {
main: './frontend/site/index.js'
},
@@ -15,7 +15,29 @@ module.exports = {
path: path.resolve(__dirname, 'static/js/dist'),
filename: 'bundle.js'
},
- devtool: 'cheap-module-eval-source-map',
+ plugins: [
+ new webpack.DefinePlugin({
+ 'process.env.NODE_ENV': JSON.stringify("production"),
+ // 'process.env.S3_HOST': JSON.stringify(process.env.S3_HOST || ""),
+ // 'process.env.API_HOST': JSON.stringify(process.env.API_HOST || ""),
+ '__REACT_DEVTOOLS_GLOBAL_HOOK__': '({ isDisabled: true })'
+ }),
+ new TerserPlugin(),
+ new webpack.optimize.AggressiveMergingPlugin(),
+ // new Visualizer({
+ // filename: './statistics.html'
+ // })
+ ],
+ optimization: {
+ minimize: true,
+ minimizer: [new TerserPlugin({
+ terserOptions: {
+ compress: {
+ // drop_console: true,
+ }
+ }
+ })],
+ },
resolve: {
alias: {
// "react": "preact/compat",
@@ -23,12 +45,7 @@ module.exports = {
// "react-dom": "preact/compat",
}
},
- plugins: [
- new webpack.DefinePlugin({
- 'process.env.NODE_ENV': '"development"',
- '__REACT_DEVTOOLS_GLOBAL_HOOK__': '({ isDisabled: true })'
- }),
- ],
+ devtool: 'cheap-module-source-map',
module: {
rules: [
{
@@ -39,16 +56,14 @@ module.exports = {
test: /\.js$/,
// include: path.resolve(__dirname, 'client'),
exclude: /(node_modules|bower_components|build)/,
- use: {
- loader: 'babel-loader',
- options: {
- presets: ['@babel/preset-env'],
- plugins: [
- "@babel/plugin-transform-runtime",
- ],
- }
+ loader: 'babel-loader',
+ options: {
+ presets: ['@babel/preset-react'],
+ plugins: [
+ "@babel/plugin-transform-runtime",
+ ],
}
}
]
- }
-}
+ },
+};