From 6c4e98fd0cdc0aed59787c3f19a4225835f7ea72 Mon Sep 17 00:00:00 2001 From: martin Date: Tue, 29 May 2018 11:47:09 +0100 Subject: [PATCH] stuff --- test/.gitignore | 147 ++++++++++++++++++++++++++ test/docker-compose.yml | 46 ++++++++ test/setup/postgres/Dockerfile | 0 test/setup/postgres/init.sql | 54 ++++++++++ test/setup/postgres/setup.sh | 4 + test/setup/redis/redis.conf | 0 test/setup/web/Dockerfile | 9 ++ test/setup/web/ecosystem.json | 33 ++++++ test/setup/web/gulp/backbone.js | 38 +++++++ test/setup/web/gulp/build.js | 59 +++++++++++ test/setup/web/gulpfile.js | 7 ++ test/setup/web/package.json | 63 +++++++++++ test/setup/web/server.js | 49 +++++++++ test/setup/web/server/db-connector.js | 22 ++++ test/setup/web/server/db-testdata.js | 40 +++++++ test/setup/web/server/name-gen.js | 61 +++++++++++ test/setup/web/src/css/custom.scss | 137 ++++++++++++++++++++++++ test/setup/web/src/index.html | 44 ++++++++ test/setup/web/src/js/DataList.js | 97 +++++++++++++++++ test/setup/web/src/js/app.js | 19 ++++ 20 files changed, 929 insertions(+) create mode 100644 test/.gitignore create mode 100644 test/docker-compose.yml create mode 100644 test/setup/postgres/Dockerfile create mode 100644 test/setup/postgres/init.sql create mode 100644 test/setup/postgres/setup.sh create mode 100644 test/setup/redis/redis.conf create mode 100644 test/setup/web/Dockerfile create mode 100644 test/setup/web/ecosystem.json create mode 100644 test/setup/web/gulp/backbone.js create mode 100644 test/setup/web/gulp/build.js create mode 100644 test/setup/web/gulpfile.js create mode 100644 test/setup/web/package.json create mode 100644 test/setup/web/server.js create mode 100644 test/setup/web/server/db-connector.js create mode 100644 test/setup/web/server/db-testdata.js create mode 100644 test/setup/web/server/name-gen.js create mode 100644 test/setup/web/src/css/custom.scss create mode 100644 test/setup/web/src/index.html create mode 100644 test/setup/web/src/js/DataList.js create mode 100644 test/setup/web/src/js/app.js diff --git a/test/.gitignore b/test/.gitignore new file mode 100644 index 0000000..3d3e91e --- /dev/null +++ b/test/.gitignore @@ -0,0 +1,147 @@ +# Created by .ignore support plugin (hsz.mobi) +### Node template +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Typescript v1 declaration files +typings/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env + +### macOS template +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk +### JetBrains template +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +.idea/ +# User-specific stuff: +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/dictionaries + +# Sensitive or high-churn files: +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.xml +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml + +# Gradle: +.idea/**/gradle.xml +.idea/**/libraries + +# CMake +cmake-build-debug/ + +# Mongo Explorer plugin: +.idea/**/mongoSettings.xml + +## File-based project format: +*.iws + +## Plugin-specific files: + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Elastic Beanstalk Files +.elasticbeanstalk/* +!.elasticbeanstalk/*.cfg.yml +!.elasticbeanstalk/*.global.yml +/src/bundle.js +/src/bundle.js.map +/setup/web/live/ diff --git a/test/docker-compose.yml b/test/docker-compose.yml new file mode 100644 index 0000000..e3a8c83 --- /dev/null +++ b/test/docker-compose.yml @@ -0,0 +1,46 @@ +version: '3' + +services: + + PostgreSQL: + image: postgres:alpine + ports: + - 5432:5432 + restart: always + env_file: .env + volumes: + - "$ROOT/postgresql:/var/lib/postgresql" + - ./setup/postgres/init.sql:/docker-entrypoint-initdb.d/init.sql + + adminer: + image: adminer + restart: always + depends_on: + - PostgreSQL + ports: + - 8080:8080 + + redis: + image: redis:alpine + restart: always + volumes: + - "$ROOT/redis:/data" + + + web: + build: ./setup/web/. + command: npm run start + volumes: + - .:/user/app + - /usr/app/node_modules + ports: + - 9000:9000 + depends_on: + - PostgreSQL + - redis + environment: + - HOST=${HOST} + - DATABASE=${POSTGRES_DB} + - USER=${POSTGRES_USER} + - PASSWORD=${POSTGRES_PASSWORD} + - DATABASE_URL=${DATABASE_URL} diff --git a/test/setup/postgres/Dockerfile b/test/setup/postgres/Dockerfile new file mode 100644 index 0000000..e69de29 diff --git a/test/setup/postgres/init.sql b/test/setup/postgres/init.sql new file mode 100644 index 0000000..66fb33d --- /dev/null +++ b/test/setup/postgres/init.sql @@ -0,0 +1,54 @@ +-- SEQUENCE: public.test_id_seq + +-- DROP SEQUENCE public.test_id_seq; + +CREATE SEQUENCE public.test_id_seq; + +ALTER SEQUENCE public.test_id_seq + OWNER TO comcardeuser; + + + + + +-- Table: public.test + +-- DROP TABLE public.test; + +CREATE TABLE public.test +( + id integer NOT NULL DEFAULT nextval('test_id_seq'::regclass), + company_name character varying(100) COLLATE pg_catalog."default", + CONSTRAINT test_pkey PRIMARY KEY (id) +) +WITH ( + OIDS = FALSE +) +TABLESPACE pg_default; + +ALTER TABLE public.test + OWNER to comcardeuser; + + + +-- FUNCTION: public.insert_company(character varying) + +-- DROP FUNCTION public.insert_company(character varying); + +CREATE OR REPLACE FUNCTION public.insert_company( + _name character varying) + RETURNS void + LANGUAGE 'plpgsql' + + COST 100 + VOLATILE +AS $BODY$ + +BEGIN + INSERT into test(company_name) Values(_name); +END; + +$BODY$; + +ALTER FUNCTION public.insert_company(character varying) + OWNER TO comcardeuser; diff --git a/test/setup/postgres/setup.sh b/test/setup/postgres/setup.sh new file mode 100644 index 0000000..37b2cf8 --- /dev/null +++ b/test/setup/postgres/setup.sh @@ -0,0 +1,4 @@ +#!/bin/bash +set -e + +echo "Build Postgres" diff --git a/test/setup/redis/redis.conf b/test/setup/redis/redis.conf new file mode 100644 index 0000000..e69de29 diff --git a/test/setup/web/Dockerfile b/test/setup/web/Dockerfile new file mode 100644 index 0000000..3df58fa --- /dev/null +++ b/test/setup/web/Dockerfile @@ -0,0 +1,9 @@ +FROM node:alpine + +WORKDIR /usr/app + +COPY package.json . + +COPY . . + +RUN npm install --unsafe-perm diff --git a/test/setup/web/ecosystem.json b/test/setup/web/ecosystem.json new file mode 100644 index 0000000..6d15fd9 --- /dev/null +++ b/test/setup/web/ecosystem.json @@ -0,0 +1,33 @@ +{ + /** + * Application configuration section + * http://pm2.keymetrics.io/docs/usage/application-declaration/ + */ + apps: [ + // First application + { + "name": "Jubilee", + "script": "server.js", + "cwd": "/home/martind2000/dev/jubilee", + "watch": false, + "ignore_watch" : ["node_modules"], + "merge_logs" : true, + "autorestart" : true, + "restart_delay" : 3500, + "max_memory_restart" : "300M", + env: { + COMMON_VARIABLE: "true" + }, + env_production: { + NODE_ENV: "production" + } + } + ], + /** + * Deployment section + * http://pm2.keymetrics.io/docs/usage/deployment/ + */ + deploy: { + + } +} diff --git a/test/setup/web/gulp/backbone.js b/test/setup/web/gulp/backbone.js new file mode 100644 index 0000000..ea38c71 --- /dev/null +++ b/test/setup/web/gulp/backbone.js @@ -0,0 +1,38 @@ +'use strict'; + +const browserify = require('browserify'); +const gulp = require('gulp'); +const source = require('vinyl-source-stream'); +const buffer = require('vinyl-buffer'); +const uglify = require('gulp-uglify-es').default; +const sourcemaps = require('gulp-sourcemaps'); +const gutil = require('gulp-util'); +const rename = require('gulp-rename'); +const stripDebug = require('gulp-strip-debug'); + + +gulp.task('bundleBackbone', function () { + // set up the browserify instance on a task basis + const b = browserify({ + 'debug': true, + 'entries': './src/js/app.js' + }); + + return b.bundle() + .pipe(source('app.js')) + .pipe(buffer()) + // .pipe(stripDebug()) + .pipe(rename('bundle.js')) + + .pipe(sourcemaps.init({ 'loadMaps': true })) + // Add transformation tasks to the pipeline here. + // .pipe(uglify()) + .on('error', gutil.log) + .pipe(sourcemaps.write('.')) + .pipe(gulp.dest('./live/js')); +}); + +gulp.task('buildBackbone', [ 'bundleBackbone'], function() { + gulp.watch('src/js/**/*.js', [ 'bundleBackbone']); +}); + diff --git a/test/setup/web/gulp/build.js b/test/setup/web/gulp/build.js new file mode 100644 index 0000000..8289d9b --- /dev/null +++ b/test/setup/web/gulp/build.js @@ -0,0 +1,59 @@ +const gulp = require('gulp'), + + autoprefixer = require('gulp-autoprefixer'), + cssnano = require('gulp-cssnano'), + uglify = require('gulp-uglify'), + + rename = require('gulp-rename'), + concat = require('gulp-concat'), + cache = require('gulp-cache'), + htmlmin = require('gulp-htmlmin'), + inject = require('gulp-inject'), + del = require('del'), + htmlreplace = require('gulp-html-replace'); + +const scss = require('gulp-scss'); +const sass = require('gulp-sass'); +const googleWebFonts = require('gulp-google-webfonts'); + +const fontOptions = { }; + +gulp.task('styles', function() { + return gulp.src(['node_modules/backbone.modal/backbone.modal.css', 'node_modules/backbone.modal/backbone.modal.theme.css']) + .pipe(autoprefixer('last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4')) + + /* .pipe(gulp.dest('dist/css'))*/ + /* .pipe(rename({suffix: '.min'}))*/ + .pipe(concat('style.min.css')) + .pipe(cssnano()) + .pipe(gulp.dest('live/css')); +}); + +gulp.task('copy', function() { + gulp.src(['src/img/**/*']).pipe(gulp.dest('live/img')); + gulp.src(['src/gfx/**/*']).pipe(gulp.dest('live/gfx')); + gulp.src(['src/index.html']).pipe(gulp.dest('live')); +}); + +gulp.task('clean', function() { + return del(['live']); +}); + +gulp.task('customMUI', function() { + return gulp.src(['src/css/custom.scss']) + .pipe(sass({ 'outputStyle': 'compressed' }).on('error', sass.logError)) + // .pipe(cssnano()) + .pipe(rename('mui.custom.css')) + // .pipe(gulp.dest(`${dest}/css`)); + .pipe(gulp.dest('live/css')); +}); + +gulp.task('vendor', function() { + return gulp.src([ + 'node_modules/muicss/dist/js/mui.min.js' + ]) + .pipe(concat('vendor.js')) + + /* .pipe(uglify({ 'mangle': false }))*/ + .pipe(gulp.dest(`live/js`)); +}); diff --git a/test/setup/web/gulpfile.js b/test/setup/web/gulpfile.js new file mode 100644 index 0000000..882d48f --- /dev/null +++ b/test/setup/web/gulpfile.js @@ -0,0 +1,7 @@ +const gulp = require('gulp'); + +const requireDir = require('require-dir'); + +requireDir('./gulp'); + +gulp.task('default', ['bundleBackbone', 'styles', 'copy', 'customMUI', 'vendor']); diff --git a/test/setup/web/package.json b/test/setup/web/package.json new file mode 100644 index 0000000..ab66ca2 --- /dev/null +++ b/test/setup/web/package.json @@ -0,0 +1,63 @@ +{ + "name": "pgtest", + "version": "1.0.0", + "description": "", + "main": "server.js", + "scripts": { + "test": "mocha", + "postinstall": "gulp default", + "start": "node server.js" + }, + "author": "", + "license": "ISC", + "dependencies": { + "backbone": "^1.3.3", + "browserify": "^16.1.0", + "eslint": "^4.19.0", + "express": "^4.16.3", + "hh-mm-ss": "^1.2.0", + "jquery": "^3.3.1", + "lodash": "^4.17.5", + "log4js": "^2.5.3", + "memory-cache": "^0.2.0", + "moment": "^2.21.0", + "muicss": "^0.9.38", + "pg-promise": "^8.4.4", + "request-json": "^0.6.3", + "strict-uri-encode": "^2.0.0", + "string": "^3.3.3", + "sugar": "^2.0.4", + "uglifyify": "^4.0.5", + "underscore": "^1.9.0" + }, + "devDependencies": { + "expect.js": "^0.3.1", + "gulp": "^3.9.1", + "gulp-google-webfonts": "^1.0.0", + "gulp-rename": "^1.2.2", + "gulp-sass": "^3.1.0", + "gulp-scss": "^1.4.0", + "gulp-sourcemaps": "^2.6.4", + "gulp-strip-debug": "^3.0.0", + "gulp-uglify-es": "^1.0.1", + "lodash.assign": "^4.2.0", + "mocha": "^5.0.4", + "node-fetch": "^2.1.1", + "require-dir": "^1.0.0", + "requirejs": "^2.3.5", + "sinon": "^4.4.6", + "vinyl-buffer": "^1.0.1", + "vinyl-source-stream": "^2.0.0", + "watchify": "^3.11.0", + "whatwg-fetch": "^2.0.4", + "gulp-autoprefixer": "^5.0.0", + "gulp-bump": "^3.1.0", + "gulp-cache": "^1.0.2", + "gulp-concat": "^2.6.1", + "gulp-cssnano": "^2.1.2", + "gulp-html-replace": "^1.6.2", + "gulp-htmlmin": "^4.0.0", + "gulp-inject": "^4.3.1", + "gulp-uglify": "^3.0.0" + } +} diff --git a/test/setup/web/server.js b/test/setup/web/server.js new file mode 100644 index 0000000..23f66a6 --- /dev/null +++ b/test/setup/web/server.js @@ -0,0 +1,49 @@ +const express = require('express'); +const path = require('path'); +const logger = require('log4js').getLogger('Server'); + + +const db = require('./server/db-connector').dbConnection; +const dbTestdata = require('./server/db-testdata')(db); + +const nameGen = require('./server/name-gen'); + +logger.level = 'debug'; + +const app = express(); +const port = process.env.PORT || 9000; + +const sitePath = 'live'; + +app.use(express.static(path.join(__dirname, sitePath))); + +// app.get('/weather', cache('15 minutes'), (req, res) => { + +const asyncMiddleware = fn => + (req, res, next) => { + Promise.resolve(fn(req, res, next)) + .catch(next); + }; + +app.get('/data', (req, res) => { + dbTestdata.sqlGetSimpleList().then((d) => { + res.send(d); + }).catch((e) => { + logger.error(e); + }); +}); + +app.listen(port, (err) => { + if (err) + return logger.error('Server error:', err); + + logger.info(`Test Server is listening on ${port}`); + + const i = setInterval(()=>{ + dbTestdata.sqlInsertData(nameGen.gen()).then((d) => { + logger.debug(d); + }).catch((e) => { + logger.error(e); + }); + }, 15000) +}); diff --git a/test/setup/web/server/db-connector.js b/test/setup/web/server/db-connector.js new file mode 100644 index 0000000..352c588 --- /dev/null +++ b/test/setup/web/server/db-connector.js @@ -0,0 +1,22 @@ +const pgp = require('pg-promise')(); + +const connectionString = process.env.DATABASE_URL; + + +/*const cn = { + connectionString:connectionString +};*/ + +const cn = { + host: process.env.HOST, + port: 5432, + database: process.env.DATABASE, + user: process.env.USER, + password: process.env.PASSWORD +}; + + + +console.log('>> connectionString', cn); +exports.dbConnection = pgp(cn); + diff --git a/test/setup/web/server/db-testdata.js b/test/setup/web/server/db-testdata.js new file mode 100644 index 0000000..88df3b3 --- /dev/null +++ b/test/setup/web/server/db-testdata.js @@ -0,0 +1,40 @@ +const logger = require('log4js').getLogger('db-testdata'); +logger.level = 'debug'; +module.exports = function(db) { + const module = {}; + + module.sqlGetSimpleList = function(id) { + return new Promise(function(resolve, reject) { + + db.manyOrNone('select * from "test";', [id]) + + .then(function(d) { + // console.log(d); + return resolve(d); + }) + .catch((err)=> { + // console.log(err); + return reject(err); + }); + }); + }; + + + module.sqlInsertData = function(name) { + + logger.info('Insert ', name); + return new Promise(function(resolve, reject) { + db.func('insert_company', + [name]) + .then(()=> { + return resolve('ok'); + }) + .catch((err)=> { + return reject(err); + }); + }); + }; + + + return module; +}; diff --git a/test/setup/web/server/name-gen.js b/test/setup/web/server/name-gen.js new file mode 100644 index 0000000..ec7cfc7 --- /dev/null +++ b/test/setup/web/server/name-gen.js @@ -0,0 +1,61 @@ +/** + * Created by mdonnel on 20/04/2017. + */ + +Array.prototype.random = function () { + return this[Math.floor((Math.random() * this.length))]; +}; + + +const left = ['Alabama', + 'Alaska', + 'Arizona', + 'Maryland', + 'Nevada', + 'Mexico', + 'Texas', + 'Utah', + 'Glasgow', + 'Inverness', + 'Edinburgh', + 'Dumbarton', + 'Balloch', + 'Renton', + 'Cardross', + 'Dundee', + 'Paisley', + 'Hamilton', + 'Greenock', + 'Falkirk', + 'Irvine', + 'Renfrew', + 'Erskine', + 'London', + 'Hammersmith', + 'Islington', + 'Silver', 'Black', 'Yellow', 'Purple', 'White', 'Pink', 'Red', 'Orange', 'Brown', 'Green', 'Blue', + 'Amber', 'Aqua', 'Azure', 'Bronze', 'Coral', 'Copper', 'Crimson', 'Cyan', 'Ginger', 'Gold', 'Indigo', 'Jade' + + ]; + + const right = ['Aganju', 'Cygni', 'Akeron', 'Antares', 'Aragoth', 'Ardus', 'Carpenter', + 'Cooper', 'Dahin', 'Capella', 'Endriago', 'Gallina', 'Fenris', 'Freya', 'Glenn', 'Grissom', + 'Jotunheim', 'Kailaasa', 'Lagarto', 'Muspelheim', 'Nifleheim', 'Primus', 'Vega', 'Ragnarok', + 'Shepard', 'Slayton', 'Tarsis', 'Mercury', 'Venus', 'Mars', 'Earth', 'Terra', 'Jupiter', + 'Saturn', 'Uranus', 'Neptune', 'Pluto', 'Europa', 'Ganymede', 'Callisto', 'Titan', 'Juno', + 'Eridanus', 'Scorpius', 'Crux', 'Cancer', 'Taurus', 'Lyra', 'Andromeda', 'Virgo', 'Aquarius', + 'Cygnus', 'Corvus', 'Taurus', 'Draco', 'Perseus', 'Pegasus', 'Gemini', 'Columbia', 'Bootes', + 'Orion', 'Deneb', 'Merope', 'Agate', 'Amber', 'Beryl', 'Calcite', 'Citrine', 'Coral', 'Diamond', + 'Emerald', 'Garnet', 'Jade', 'Lapis', 'Moonstone', 'Obsidian', 'Onyx', 'Opal', 'Pearl', 'Quartz', + 'Ruby', 'Sapphire', 'Topaz', 'Iron', 'Lead', 'Nickel', 'Copper', 'Zinc', 'Tin', 'Manes', 'Argon', + 'Neon', 'Alpha', 'Bravo', 'Charlie', 'Delta', 'Echo', 'Foxtrot', 'Golf', 'Hotel', 'India', 'Juliett', + 'Kilo', 'Lima', 'Mike', 'November', 'Oscar', 'Papa', 'Quebec', 'Romeo', 'Sierra', 'Tango', 'Uniform', + 'Victor', 'Whisky', 'Xray', 'Yankee', 'Zulu']; + + +function gen(){ + return (`${left.random() } ${ right.random() }`); +} + + +module.exports = {gen}; diff --git a/test/setup/web/src/css/custom.scss b/test/setup/web/src/css/custom.scss new file mode 100644 index 0000000..a6daa85 --- /dev/null +++ b/test/setup/web/src/css/custom.scss @@ -0,0 +1,137 @@ +// import MUI colors +@import "./node_modules/muicss/lib/sass/mui/colors"; + +// customize MUI variables +$mui-primary-color: mui-color('pink', '500'); +$mui-primary-color-dark: mui-color('blue-grey', '700'); +$mui-primary-color-light: mui-color('blue-grey', '100'); + +$mui-accent-color: mui-color('deep-purple', '900'); +$mui-accent-color-dark: mui-color('indigo', 'A100'); +$mui-accent-color-light: mui-color('indigo', 'A400'); + +$mui-base-font-family: 'Roboto', "Helvetica Neue", Helvetica, Arial, Verdana, "Trebuchet MS"; +$mui-base-font-weight: 400; + +$mui-appbar-font-color: mui-color('black') !default; + +$mui-link-font-color: mui-color('pink', '900') !default; + +// import MUI SASS +@import "./node_modules/muicss/lib/sass/mui"; + +body { + background-color: mui-color('grey', '100'); +} + +#header { + position: fixed; + top: 0; + right: 0; + left: 0; + z-index: 2; + transition: left 0.2s; +} + +ul { + margin: 0; + padding: 0; +} + +li { + display: inline; + margin: 0; + padding: 0 4px 0 0; +} + +.dates { + padding: 2px; + border: solid 1px #80007e; + background-color: #ffffff; +} + +#btc, #fx, #trend { + font-size: 85%; +} + +.up, .ontime, .trendUp { + color: mui-color('green') !important; +} + +.down, .delayed, .trendDown { + color: $mui-text-danger !important; +} + +.nochange { + color: #000000; +} + +.password { + border: 1px solid mui-color('grey', '400'); + background-color: mui-color('grey', '200'); + font-family: monospace; + white-space: pre; +} + +.trendUp:before { + content: "▲"; +} + +.trendDown:before { + content: '▼' +} + +.card { + position: relative; + background-color: #fff; + min-height: 48px; + margin: 8px; + border-bottom-color: #666666; + box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12); +} + +.itemRow { + background-color: #fff; + min-height: 48px; + border-bottom-color: mui-color('grey', '200'); + border-bottom-width: 1px; + border-bottom-style: solid; + line-height: 48px; +} + +.cardTitle { + border-bottom-color: mui-color('grey', '200'); + border-bottom-width: 1px; + border-bottom-style: solid; +} + +.entry { + height: 36px; + margin: 6px 0; + vertical-align: middle; +} + +.time { + font-family: 'Roboto'; +} + +.titleBar { + font-family: 'Gotham Light'; + font-size: 125%; +} + + +.tableBody { + transition: all 0.5s; + -webkit-transition: all 0.5s; + +} + +.unsliced { + height: 455px; +} + +.sliced { + height: 300px; + +} diff --git a/test/setup/web/src/index.html b/test/setup/web/src/index.html new file mode 100644 index 0000000..7da1f10 --- /dev/null +++ b/test/setup/web/src/index.html @@ -0,0 +1,44 @@ + + + + + + + PG TEST + + + + + + + + + +
+
+
+ + +
+
+
+
Data
+
+
+
+
+ + + + + + + + + + + diff --git a/test/setup/web/src/js/DataList.js b/test/setup/web/src/js/DataList.js new file mode 100644 index 0000000..da4e8d5 --- /dev/null +++ b/test/setup/web/src/js/DataList.js @@ -0,0 +1,97 @@ +const $ = require('jquery'); +const _ = require('underscore'); +const Backbone = require('backbone'); +const request = require('request'); + +const DataItem = Backbone.Model.extend({ + +}); + +const DataCollection = Backbone.Collection.extend({ + 'model': DataItem +}); + +// const dataCollection = new dataCollection(); + +const DataItemView = Backbone.View.extend({ + 'tagName': 'div', + 'className' : 'mui-row', + 'template': _.template(` +
<%=id%>
+
<%=company_name%>
+ `), + 'initialize': function() { + this.render(); + }, + 'render': function() { + this.$el.html(this.template(this.model.toJSON())); + } +}); + +const DataListModel = Backbone.Model.extend({ + 'defaults' : function (obj) { + // return a new object + return { + 'update' : new Date().getTime() + }; + }, 'initialize': function() { + this.dataCollection = new DataCollection(); + this.listenTo(this, 'change:update', this.onChange); + this.getData(); + }, + 'onChange': function() { + this.getData(); + }, + 'getData': function() { + request({ + 'url': `${window.loc.origin}/data`, + 'method': 'GET', 'qs': { + + } + }, function(err, res, body) { + if (err) + console.error(err); + else { + const fsJSON = JSON.parse(body); + + this.dataCollection.reset(fsJSON); + + this.logUpdate(); + } + }.bind(this)); + }, 'logUpdate': function() { + const time = new Date().getTime() ; + + this.set('time', time); + + this.timerID = setTimeout( + () => this.tick(), + 30 * 1000 + ); + }, + 'tick': function() { + this.set('update', new Date().getTime()); + } + +}); + +const DataListView = Backbone.View.extend({ + 'initialize': function(options) { + this.model.dataCollection.bind('reset', this.render, this); + + }, + 'render' : function() { + + this.$el.empty(); + + this.model.dataCollection.each(function(item) { + const niView = new DataItemView({ 'model': item }); + + this.$el.append(niView.el); + }, this); + + } + +}); + +module.exports = { DataListModel, DataListView }; diff --git a/test/setup/web/src/js/app.js b/test/setup/web/src/js/app.js new file mode 100644 index 0000000..890fd81 --- /dev/null +++ b/test/setup/web/src/js/app.js @@ -0,0 +1,19 @@ +require('muicss'); +const $ = require('jquery'); +const _ = require('underscore'); +const Backbone = require('backbone'); + +const { DataListModel, DataListView } = require('./DataList'); + +var app = app || {}; + +(function () { + + window.loc = new URL(window.location); + + app.dataList = new DataListView({ 'model': new DataListModel(), 'el':'#data' }); + +})(); + + +