diff --git a/gulpfile.js b/gulpfile.js index 424796da..1534c561 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -18,6 +18,11 @@ var concat = require('gulp-concat'); var _ = require('lodash'); var eslint = require('gulp-eslint'); var jest = require('jest-cli'); +var argv = require('yargs').argv; +var server = require('./server.js').app; +var minifyCss = require('gulp-minify-css'); +var uglify = require('gulp-uglify'); + var config = { bootstrapDir: './node_modules/bootstrap-sass', @@ -41,11 +46,14 @@ var config = { } }; -gulp.task('build', function() { +gulp.task('build', ['js:build', 'sass:build', 'copy'], function() { +}); + +gulp.task('js:build', function() { bundle(false); }); - -gulp.task('serve', ['browser-sync', 'sass', 'sass:watch', 'copy'], function() { + +gulp.task('serve', ['browser-sync', 'run-server', 'lint:watch', 'sass:build', 'sass:watch', 'copy'], function() { bundle(true); }); @@ -59,27 +67,30 @@ gulp.task('jest:watch', function(done) { gulp.watch([ config.jestOptions.rootDir + "/**/*.js" ], [ 'jest' ]); }); +gulp.task('run-server', function() { + server.listen(4000); +}); + gulp.task('browser-sync', function() { browserSync({ - server: { - baseDir: '.' - }, - port: process.env.PORT || 3000 + files: ['build/css/*.css', 'build/js/*.js'], + proxy: 'http://localhost:4000', + port: 3000 }); }); -gulp.task('sass', function () { +gulp.task('sass:build', function () { gulp.src('./sass/**/main.scss') - .pipe(sourcemaps.init()) + .pipe(gulpif(!argv.production, sourcemaps.init())) .pipe(sass({ includePaths: [ config.bootstrapDir + '/assets/stylesheets' ] - }) - .on('error', sass.logError)) - .pipe(sourcemaps.write('./maps')) + }).on('error', sass.logError)) + .pipe(gulpif(!argv.production, sourcemaps.write('./maps'))) + .pipe(gulpif(argv.production, minifyCss())) .pipe(gulp.dest('./build/css')) - .pipe(browserSync.stream());; + .pipe(browserSync.stream()); }); gulp.task('sass:watch', function () { @@ -87,13 +98,13 @@ gulp.task('sass:watch', function () { }); gulp.task('copy', function () { - var files = [ + var staticAssets = [ './fonts/**/*', './img/**/*' ]; - gulp.src(files, {base: './'}) - .pipe(gulp.dest('build')); + gulp.src(staticAssets, {base: './'}) + .pipe(gulp.dest('./build')); gulp.src(config.bootstrapDir + '/assets/fonts/**/*') .pipe(gulp.dest('./build/fonts')); @@ -117,6 +128,7 @@ gulp.task('lint:watch', function () { function bundle(watch) { var bro; + if (watch) { bro = watchify(browserify('./js/app.js', // Assigning debug to have sourcemaps @@ -141,13 +153,14 @@ function bundle(watch) { .on('error', notify.onError('Error: <%= error.message %>')) .pipe(source('app.js')) .pipe(buffer()) - .pipe(sourcemaps.init({ + .pipe(gulpif(!argv.production, sourcemaps.init({ loadMaps: true - })) // loads map from browserify file - .pipe(sourcemaps.write()) // writes .map file - .pipe(gulp.dest('./build')) + }))) // loads map from browserify file + .pipe(gulpif(!argv.production, sourcemaps.write())) // writes .map file + .pipe(gulpif(argv.production, uglify({mangle: false}))) + .pipe(gulp.dest('./build/js')) .pipe(browserSync.stream()); } return rebundle(bro); -} \ No newline at end of file +} diff --git a/index.html b/index.html index 320dfa89..852f9027 100644 --- a/index.html +++ b/index.html @@ -6,11 +6,10 @@ ascribe - +
- - + diff --git a/js/actions/global_notification_actions.js b/js/actions/global_notification_actions.js new file mode 100644 index 00000000..b12f7906 --- /dev/null +++ b/js/actions/global_notification_actions.js @@ -0,0 +1,16 @@ +'use strict'; + +import alt from '../alt'; + + +class GlobalNotificationActions { + constructor() { + this.generateActions( + 'appendGlobalNotification', + 'shiftGlobalNotification', + 'emulateEmptyStore' + ); + } +} + +export default alt.createActions(GlobalNotificationActions); diff --git a/js/app.js b/js/app.js index d1215fa3..af92c379 100644 --- a/js/app.js +++ b/js/app.js @@ -26,7 +26,7 @@ fetch.defaults({ } }); -Router.run(routes, Router.HashLocation, (AscribeApp) => { +Router.run(routes, Router.HistoryLocation, (AscribeApp) => { React.render( , document.getElementById('main') diff --git a/js/components/ascribe_app.js b/js/components/ascribe_app.js index 6484976c..ab860893 100644 --- a/js/components/ascribe_app.js +++ b/js/components/ascribe_app.js @@ -3,6 +3,7 @@ import React from 'react'; import Router from 'react-router'; import Header from '../components/header'; +import GlobalNotification from './global_notification'; let Link = Router.Link; let RouteHandler = Router.RouteHandler; @@ -14,6 +15,8 @@ let AscribeApp = React.createClass({
+ +
); } diff --git a/js/components/ascribe_forms/form_piece_extradata.js b/js/components/ascribe_forms/form_piece_extradata.js new file mode 100644 index 00000000..282afcdf --- /dev/null +++ b/js/components/ascribe_forms/form_piece_extradata.js @@ -0,0 +1,43 @@ +'use strict'; + +import React from 'react'; + +import apiUrls from '../../constants/api_urls'; +import FormMixin from '../../mixins/form_mixin'; + +import InputTextAreaToggable from './input_textarea_toggable'; + + +let PersonalNoteForm = React.createClass({ + mixins: [FormMixin], + + url() { + return apiUrls.note_notes; + }, + + getFormData() { + return { + bitcoin_id: this.getBitcoinIds().join(), + note: this.refs.personalNote.state.value + }; + }, + + renderForm() { + + return ( +
+ + + ); + } +}); + +export default PersonalNoteForm; \ No newline at end of file diff --git a/js/components/ascribe_media/media_player.js b/js/components/ascribe_media/media_player.js index 55188568..b0002de0 100644 --- a/js/components/ascribe_media/media_player.js +++ b/js/components/ascribe_media/media_player.js @@ -46,8 +46,8 @@ let Image = React.createClass({ this.inject('http://code.jquery.com/jquery-2.1.4.min.js') .then(() => Promise.all([ - this.inject('node_modules/shmui/shmui.css'), - this.inject('node_modules/shmui/jquery.shmui.js') + this.inject('/static/thirdparty/shmui/shmui.css'), + this.inject('/static/thirdparty/shmui/jquery.shmui.js') ]).then(() => { window.jQuery('.shmui-ascribe').shmui(); })); }, diff --git a/js/components/ascribe_modal/modal_loan.js b/js/components/ascribe_modal/modal_loan.js deleted file mode 100644 index aff34ac0..00000000 --- a/js/components/ascribe_modal/modal_loan.js +++ /dev/null @@ -1,45 +0,0 @@ -'use strict'; - -import React from 'react'; -import Modal from 'react-bootstrap/lib/Modal'; -import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger'; -import ModalTrigger from 'react-bootstrap/lib/ModalTrigger'; -import Tooltip from 'react-bootstrap/lib/Tooltip'; - -import LoanForm from '../ascribe_forms/form_loan'; -import ModalMixin from '../../mixins/modal_mixin'; - -let LoanModalButton = React.createClass({ - render() { - return ( - Loan your artwork for a limited period of time}> - }> -
- LOAN -
-
-
- ); - } -}); - -let LoanModal = React.createClass({ - mixins: [ModalMixin], - - render() { - return ( - -
- -
-
- ); - } -}); - - -export default LoanModalButton; diff --git a/js/components/ascribe_modal/modal_share.js b/js/components/ascribe_modal/modal_share.js deleted file mode 100644 index 2cce53ad..00000000 --- a/js/components/ascribe_modal/modal_share.js +++ /dev/null @@ -1,44 +0,0 @@ -'use strict'; - -import React from 'react'; -import Modal from 'react-bootstrap/lib/Modal'; -import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger'; -import ModalTrigger from 'react-bootstrap/lib/ModalTrigger'; -import Tooltip from 'react-bootstrap/lib/Tooltip'; - -import ModalMixin from '../../mixins/modal_mixin'; -import ShareForm from '../ascribe_forms/form_share_email'; - -let ShareModalButton = React.createClass({ - render() { - return ( - Share the artwork}> - }> -
- -
-
-
- ); - } -}); - -let ShareModal = React.createClass({ - mixins: [ModalMixin], - - render() { - return ( - -
- -
-
- ); - } -}); - - -export default ShareModalButton; diff --git a/js/components/ascribe_modal/modal_unconsign.js b/js/components/ascribe_modal/modal_unconsign.js deleted file mode 100644 index 9bfb2faf..00000000 --- a/js/components/ascribe_modal/modal_unconsign.js +++ /dev/null @@ -1,45 +0,0 @@ -'use strict'; - -import React from 'react'; -import Modal from 'react-bootstrap/lib/Modal'; -import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger'; -import ModalTrigger from 'react-bootstrap/lib/ModalTrigger'; -import Tooltip from 'react-bootstrap/lib/Tooltip'; - -import UnConsignForm from '../ascribe_forms/form_unconsign'; -import ModalMixin from '../../mixins/modal_mixin'; - -let UnConsignModalButton = React.createClass({ - render() { - return ( - Unconsign this artwork}> - }> -
- UNCONSIGN -
-
-
- ); - } -}); - -let UnConsignModal = React.createClass({ - mixins: [ModalMixin], - - render() { - return ( - -
- -
-
- ); - } -}); - - -export default UnConsignModalButton; diff --git a/js/components/ascribe_modal/modal_unconsign_request.js b/js/components/ascribe_modal/modal_unconsign_request.js deleted file mode 100644 index fa0cd19f..00000000 --- a/js/components/ascribe_modal/modal_unconsign_request.js +++ /dev/null @@ -1,45 +0,0 @@ -'use strict'; - -import React from 'react'; -import Modal from 'react-bootstrap/lib/Modal'; -import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger'; -import ModalTrigger from 'react-bootstrap/lib/ModalTrigger'; -import Tooltip from 'react-bootstrap/lib/Tooltip'; - -import UnConsignRequestForm from '../ascribe_forms/form_unconsign_request'; -import ModalMixin from '../../mixins/modal_mixin'; - -let UnConsignRequestModalButton = React.createClass({ - render() { - return ( - Request to unconsign the artwork}> - }> -
- UNCONSIGN REQUEST -
-
-
- ); - } -}); - -let UnConsignRequestModal = React.createClass({ - mixins: [ModalMixin], - - render() { - return ( - -
- -
-
- ); - } -}); - - -export default UnConsignRequestModalButton; diff --git a/js/components/ascribe_piece_list_bulk_modal/piece_list_bulk_modal.js b/js/components/ascribe_piece_list_bulk_modal/piece_list_bulk_modal.js index 2cf32139..48c02221 100644 --- a/js/components/ascribe_piece_list_bulk_modal/piece_list_bulk_modal.js +++ b/js/components/ascribe_piece_list_bulk_modal/piece_list_bulk_modal.js @@ -13,6 +13,7 @@ import UserActions from '../../actions/user_actions'; import PieceListBulkModalSelectedEditionsWidget from './piece_list_bulk_modal_selected_editions_widget'; import AclButtonList from '../ascribe_buttons/acl_button_list'; +import GlobalNotificationActions from '../../actions/global_notification_actions'; let PieceListBulkModal = React.createClass({ propTypes: { @@ -92,7 +93,7 @@ let PieceListBulkModal = React.createClass({ .forEach((pieceId) => { EditionListActions.fetchEditionList(pieceId, this.state.orderBy, this.state.orderAsc); }); - + GlobalNotificationActions.updateGlobalNotification({message: 'Transfer successful'}); EditionListActions.clearAllEditionSelections(); }, diff --git a/js/components/global_notification.js b/js/components/global_notification.js new file mode 100644 index 00000000..82646976 --- /dev/null +++ b/js/components/global_notification.js @@ -0,0 +1,73 @@ +'use strict'; + +import React from 'react'; + +import GlobalNotificationStore from '../stores/global_notification_store'; + +import Row from 'react-bootstrap/lib/Row'; +import Col from 'react-bootstrap/lib/Col'; + +let GlobalNotification = React.createClass({ + + componentDidMount() { + GlobalNotificationStore.listen(this.onChange); + }, + + componentWillUnmount() { + GlobalNotificationStore.unlisten(this.onChange); + }, + + getInititalState() { + return this.extractFirstElem(GlobalNotificationStore.getState().notificationQue); + }, + + extractFirstElem(l) { + return l.length > 0 ? l[0] : null; + }, + + onChange(state) { + let notification = this.extractFirstElem(state.notificationQue); + + if(notification) { + this.setState(notification); + } else { + this.replaceState(null); + } + }, + + render() { + let notificationClass = 'ascribe-global-notification '; + let message = this.state && this.state.message ? this.state.message : null; + + if(message) { + let colors = { + warning: '#f0ad4e', + success: '#5cb85c', + info: 'rgba(2, 182, 163, 1)', + danger: '#d9534f' + }; + + let text = (
{message ? message : null}
); + + return ( + + +
+ {text} +
+ +
+ ); + } else { + return ( + + +
+ + + ); + } + } +}); + +export default GlobalNotification; \ No newline at end of file diff --git a/js/components/header.js b/js/components/header.js index d46dd4b2..3df56afb 100644 --- a/js/components/header.js +++ b/js/components/header.js @@ -38,7 +38,7 @@ let Header = React.createClass({ return (