From b5f0180cd668d6290d7d5bcdac0cc249f0e4ddae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Tue, 26 May 2015 14:05:34 +0200 Subject: [PATCH 01/14] Orderable Resource not a requirement for table anymore --- .DS_Store | Bin 0 -> 6148 bytes js/.DS_Store | Bin 0 -> 6148 bytes js/components/.DS_Store | Bin 0 -> 6148 bytes js/components/ascribe_table/.DS_Store | Bin 0 -> 6148 bytes js/components/ascribe_table/table_header.js | 6 +++--- js/components/ascribe_table/table_header_item.js | 10 +++++----- .../ascribe_table/table_item_subtable.js | 15 ++------------- 7 files changed, 10 insertions(+), 21 deletions(-) create mode 100644 .DS_Store create mode 100644 js/.DS_Store create mode 100644 js/components/.DS_Store create mode 100644 js/components/ascribe_table/.DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..36dd3e247a289deecc66728285e3a7ea7d7717b6 GIT binary patch literal 6148 zcmeHK%}T>S5Z+P^h$sN=-a$z7bqU9g&Rja6nL- zd9BC;`^{^&@w_(#a=INe?GrBSzUeMnThP=)U=hGnZ?JRn>ndAqh2*} zlWtscJ4b3J{lGJJ#Z8(Y_CXZ2hPLa~WYBBa3%gO6xH1enpF)r8GW4TfDe8uPd|cJ< zt4lv=HtfYpCpd@DiW>$s8B0&LWO8BU@M+jf{r<*wAukH+YlFP#7q^Oev0W$*2KK9E zEw60u>>suVmsi&}w|Dmsk5BppI3|rUuVFYo4=pl?0b+m{7;6U1HE7L_b(WMIF+dFb zh5@`E1Sq0oFx9B84j5Dm0GI{060otCz!+iBF_>zE6%ejN0d*)hEe6-&;1_0}V=&dI z!x=Zt2RC2lrbFTC>+pV|wlnT%q>&gP2EH;dp{F+1|Gl64|F1zbBL;|pv0{K{%hhrT zQZlu5Bsr|L0`wFV1^1;Ihaq67QVe^s6fc1)0lz>4&@q^51P=)P2q+q8AO`-Ffp_vr BUR(eG literal 0 HcmV?d00001 diff --git a/js/.DS_Store b/js/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..8f65424352bd69f2c70480fcd4428c0396c70faa GIT binary patch literal 6148 zcmeHK%}N6?5Kd~ebp-@porS7^54bXxHU=*LGjz2Cm{lSbX1tG0u42(7wduqR{b$)-#$tQ@wwJ>ToCZWIfmxU$?Yh+b*E zR1h1*QonD%TGqni+UCwdtABZQeRF$v|M2*vZ-gTWC^H%c{qw*ggBTzNh=Gw}z&v}_ z)JUC*4nqtO1HZulz7GNv(J`26R8I$VsssScf?EmLSW94xFz6UeHNp%C*P(zql$#QR z>u~T3v(7P?YSiJ3o8p6;FLP6&aP@WAU#R7bI~u7c28e;L42l2s L8mJ=%{*-}tJttr# literal 0 HcmV?d00001 diff --git a/js/components/.DS_Store b/js/components/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..a817a720381c8c59c4e07b04f0dfaa5d3526c674 GIT binary patch literal 6148 zcmeHK&1%~~5T141MouWGq=i5)dky#y_b>RSy6!PxaIpzVaJ7}d3qmrM921N|=R8J} z{=7$M-=UAtN9e6HyBibZCGh*hO9nGxRZ(&yh0HQUC8UQ{3c&LPx8k#$V-jl9K z#YF@nD$b!nK@0;ZAY94j!2ieq?cF2XtsFkWcxnF>BoM1$E$}rrjbeCV49yADfYmV&(i!SPXCc_gR)K{806DJRSH?-ezeL z>NFnTDn04zG|Hx}Y?4O#N!QNT*HJMX_)k0I_zX)sVH)>zu9Z%7aqiXV8Th-i*~^1Q zT{d1kpV#HA`MOz`2aV=@?*H<{wXX9}ABi zW`G%B2G)cDci?&3YqB0*1~b46{5=Nfe2}Pwfy2_GIXcjo767q|VI$~MFF`fZVc@W| zh;LAYEk(4Y!nGK}mSbGHyue{;(Uya7&4+Mb7Oq1P=Ic1WH0dA$i)@(zW?-3t4LkJd z{(pCW|G!+sBW8dZSStoZwcTyEa7pfNU0EF6wG#CMDhcJ478fPxn5!6b=_=kuHG*+T X4r1W2w1^QD{t+-Vuwe%NDFc51NIqci literal 0 HcmV?d00001 diff --git a/js/components/ascribe_table/.DS_Store b/js/components/ascribe_table/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 column.rowWidth ); - let numOfColumns = GeneralUtils.sumNumList(listOfRowValues); - - if(numOfColumns > 10) { - throw new Error('Bootstrap has only 12 columns to assign. You defined ' + numOfColumns + '. Change this in the columnMap you\'re passing to the table.') - } else { - return bootstrapClasses.join( listOfRowValues[i] + ' ') + listOfRowValues[i]; - } - }, - render() { let calcColumnElementContent = () => { From 65ccaf10cfc43dcded2a92534728b1ce261c3c31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Tue, 26 May 2015 14:32:28 +0200 Subject: [PATCH 02/14] remove all .DS_Store and add to gitignore --- .DS_Store | Bin 6148 -> 0 bytes .gitignore | 2 ++ js/.DS_Store | Bin 6148 -> 0 bytes js/components/.DS_Store | Bin 6148 -> 0 bytes js/components/ascribe_table/.DS_Store | Bin 6148 -> 0 bytes 5 files changed, 2 insertions(+) delete mode 100644 .DS_Store delete mode 100644 js/.DS_Store delete mode 100644 js/components/.DS_Store delete mode 100644 js/components/ascribe_table/.DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 36dd3e247a289deecc66728285e3a7ea7d7717b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK%}T>S5Z+P^h$sN=-a$z7bqU9g&Rja6nL- zd9BC;`^{^&@w_(#a=INe?GrBSzUeMnThP=)U=hGnZ?JRn>ndAqh2*} zlWtscJ4b3J{lGJJ#Z8(Y_CXZ2hPLa~WYBBa3%gO6xH1enpF)r8GW4TfDe8uPd|cJ< zt4lv=HtfYpCpd@DiW>$s8B0&LWO8BU@M+jf{r<*wAukH+YlFP#7q^Oev0W$*2KK9E zEw60u>>suVmsi&}w|Dmsk5BppI3|rUuVFYo4=pl?0b+m{7;6U1HE7L_b(WMIF+dFb zh5@`E1Sq0oFx9B84j5Dm0GI{060otCz!+iBF_>zE6%ejN0d*)hEe6-&;1_0}V=&dI z!x=Zt2RC2lrbFTC>+pV|wlnT%q>&gP2EH;dp{F+1|Gl64|F1zbBL;|pv0{K{%hhrT zQZlu5Bsr|L0`wFV1^1;Ihaq67QVe^s6fc1)0lz>4&@q^51P=)P2q+q8AO`-Ffp_vr BUR(eG diff --git a/.gitignore b/.gitignore index 580f3863..31b4a8c5 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,5 @@ node_modules npm-debug.log build/app.js + +.DS_Store \ No newline at end of file diff --git a/js/.DS_Store b/js/.DS_Store deleted file mode 100644 index 8f65424352bd69f2c70480fcd4428c0396c70faa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK%}N6?5Kd~ebp-@porS7^54bXxHU=*LGjz2Cm{lSbX1tG0u42(7wduqR{b$)-#$tQ@wwJ>ToCZWIfmxU$?Yh+b*E zR1h1*QonD%TGqni+UCwdtABZQeRF$v|M2*vZ-gTWC^H%c{qw*ggBTzNh=Gw}z&v}_ z)JUC*4nqtO1HZulz7GNv(J`26R8I$VsssScf?EmLSW94xFz6UeHNp%C*P(zql$#QR z>u~T3v(7P?YSiJ3o8p6;FLP6&aP@WAU#R7bI~u7c28e;L42l2s L8mJ=%{*-}tJttr# diff --git a/js/components/.DS_Store b/js/components/.DS_Store deleted file mode 100644 index a817a720381c8c59c4e07b04f0dfaa5d3526c674..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK&1%~~5T141MouWGq=i5)dky#y_b>RSy6!PxaIpzVaJ7}d3qmrM921N|=R8J} z{=7$M-=UAtN9e6HyBibZCGh*hO9nGxRZ(&yh0HQUC8UQ{3c&LPx8k#$V-jl9K z#YF@nD$b!nK@0;ZAY94j!2ieq?cF2XtsFkWcxnF>BoM1$E$}rrjbeCV49yADfYmV&(i!SPXCc_gR)K{806DJRSH?-ezeL z>NFnTDn04zG|Hx}Y?4O#N!QNT*HJMX_)k0I_zX)sVH)>zu9Z%7aqiXV8Th-i*~^1Q zT{d1kpV#HA`MOz`2aV=@?*H<{wXX9}ABi zW`G%B2G)cDci?&3YqB0*1~b46{5=Nfe2}Pwfy2_GIXcjo767q|VI$~MFF`fZVc@W| zh;LAYEk(4Y!nGK}mSbGHyue{;(Uya7&4+Mb7Oq1P=Ic1WH0dA$i)@(zW?-3t4LkJd z{(pCW|G!+sBW8dZSStoZwcTyEa7pfNU0EF6wG#CMDhcJ478fPxn5!6b=_=kuHG*+T X4r1W2w1^QD{t+-Vuwe%NDFc51NIqci diff --git a/js/components/ascribe_table/.DS_Store b/js/components/ascribe_table/.DS_Store deleted file mode 100644 index 5008ddfcf53c02e82d7eee2e57c38e5672ef89f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 Date: Tue, 26 May 2015 14:57:32 +0200 Subject: [PATCH 03/14] Refactor TableColumnMixin --- js/components/ascribe_table/table_header.js | 2 +- js/components/ascribe_table/table_item.js | 2 +- js/components/ascribe_table/table_item_subtable.js | 2 +- js/mixins/table_column_mixin.js | 8 ++++---- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/js/components/ascribe_table/table_header.js b/js/components/ascribe_table/table_header.js index a4e68879..8176ad31 100644 --- a/js/components/ascribe_table/table_header.js +++ b/js/components/ascribe_table/table_header.js @@ -23,7 +23,7 @@ let TableHeader = React.createClass({
{this.props.columnList.map((val, i) => { - let columnClasses = this.calcColumnClasses(this.props.columnList, i); + let columnClasses = this.calcColumnClasses(this.props.columnList, i, 12); let columnName = this.props.columnList[i].columnName; let canBeOrdered = this.props.columnList[i].canBeOrdered; diff --git a/js/components/ascribe_table/table_item.js b/js/components/ascribe_table/table_item.js index 23f91201..89e9fbbe 100644 --- a/js/components/ascribe_table/table_item.js +++ b/js/components/ascribe_table/table_item.js @@ -18,7 +18,7 @@ let TableItem = React.createClass({ return this.props.columnList.map((column, i) => { let TypeElement = column.displayType; - let columnClass = this.calcColumnClasses(this.props.columnList, i); + let columnClass = this.calcColumnClasses(this.props.columnList, i, 12); return (
diff --git a/js/components/ascribe_table/table_item_subtable.js b/js/components/ascribe_table/table_item_subtable.js index 70f8fbee..a4643d3e 100644 --- a/js/components/ascribe_table/table_item_subtable.js +++ b/js/components/ascribe_table/table_item_subtable.js @@ -56,7 +56,7 @@ let TableItemSubtable = React.createClass({ return this.props.columnList.map((column, i) => { let TypeElement = column.displayType; - let columnClass = this.calcColumnClasses(this.props.columnList, i); + let columnClass = this.calcColumnClasses(this.props.columnList, i, 12); return (
diff --git a/js/mixins/table_column_mixin.js b/js/mixins/table_column_mixin.js index 5904389d..d74214e1 100644 --- a/js/mixins/table_column_mixin.js +++ b/js/mixins/table_column_mixin.js @@ -7,14 +7,14 @@ let TableColumnMixin = { * Generates the bootstrap grid column declarations automatically using * the columnMap. */ - calcColumnClasses(list, i) { + calcColumnClasses(list, i, numOfColumns) { let bootstrapClasses = ['col-xs-', 'col-sm-', 'col-md-', 'col-lg-']; let listOfRowValues = list.map((column) => column.rowWidth ); - let numOfColumns = GeneralUtils.sumNumList(listOfRowValues); + let numOfUsedColumns = GeneralUtils.sumNumList(listOfRowValues); - if(numOfColumns > 12) { - throw new Error('Bootstrap has only 12 columns to assign. You defined ' + numOfColumns + '. Change this in the columnMap you\'re passing to the table.') + if(numOfUsedColumns > numOfColumns) { + throw new Error('This table has only ' + numOfColumns + ' columns to assign. You defined ' + numOfUsedColumns + '. Change this in the columnMap you\'re passing to the table.') } else { return bootstrapClasses.join( listOfRowValues[i] + ' ') + listOfRowValues[i]; } From 92be6a63e8d90b247f97c0bbf31946a492fd5184 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Tue, 26 May 2015 16:48:48 +0200 Subject: [PATCH 04/14] select state is saved in the store --- css/main.css | 8 +++-- js/actions/edition_list_actions.js | 5 +-- js/components/ascribe_table/table_item.js | 8 +++-- .../ascribe_table/table_item_selectable.js | 36 +++++++++++++++++++ .../ascribe_table/table_item_subtable.js | 15 ++++++-- js/stores/edition_list_store.js | 18 ++++++++-- 6 files changed, 79 insertions(+), 11 deletions(-) create mode 100644 js/components/ascribe_table/table_item_selectable.js diff --git a/css/main.css b/css/main.css index cac29beb..de85b7fc 100644 --- a/css/main.css +++ b/css/main.css @@ -31,10 +31,10 @@ .ascribe-table-header-column > span > .glyphicon { font-size: .5em; } - +/* .ascribe-table-item:nth-child(even) { background-color: #F5F5F5; -} +}*/ /*.ascribe-table-item:hover { background-color: #EEEEEE; @@ -55,4 +55,8 @@ .btn-ascribe, .btn-ascribe:hover, .btn-ascribe:active, .btn-ascribe:focus { background-color: rgba(2, 182, 163, 0.5); border-color: rgba(2, 182, 163, 0.5); +} + +.ascribe-table-item-selected { + background-color: rgba(2, 182, 163, 0.5); } \ No newline at end of file diff --git a/js/actions/edition_list_actions.js b/js/actions/edition_list_actions.js index 055ef2a5..10e1d66c 100644 --- a/js/actions/edition_list_actions.js +++ b/js/actions/edition_list_actions.js @@ -5,7 +5,8 @@ import EditionListFetcher from '../fetchers/edition_list_fetcher.js'; class EditionListActions { constructor() { this.generateActions( - 'updateEditionList' + 'updateEditionList', + 'selectEdition' ); } @@ -14,7 +15,7 @@ class EditionListActions { .fetch(pieceId) .then((res) => { this.actions.updateEditionList({ - 'editionList': res.editions, + 'editionListOfPiece': res.editions, pieceId }); }) diff --git a/js/components/ascribe_table/table_item.js b/js/components/ascribe_table/table_item.js index 89e9fbbe..6b7b62f8 100644 --- a/js/components/ascribe_table/table_item.js +++ b/js/components/ascribe_table/table_item.js @@ -10,7 +10,9 @@ let TableItem = React.createClass({ propTypes: { columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(TableColumnContentModel)), - columnContent: React.PropTypes.object + columnContent: React.PropTypes.object, + onClick: React.PropTypes.func, // See: https://facebook.github.io/react/tips/expose-component-functions.html + classNames: React.PropTypes.string }, render() { @@ -30,7 +32,9 @@ let TableItem = React.createClass({ }; return ( -
+
{calcColumnElementContent()}
diff --git a/js/components/ascribe_table/table_item_selectable.js b/js/components/ascribe_table/table_item_selectable.js new file mode 100644 index 00000000..8e48b816 --- /dev/null +++ b/js/components/ascribe_table/table_item_selectable.js @@ -0,0 +1,36 @@ +import React from 'react'; +import classNames from 'classnames'; + +import TableColumnContentModel from '../../models/table_column_content_model'; + +import TableItem from './table_item'; + +// This Component is implemented as recommended here: http://stackoverflow.com/a/25723635/1263876 +let TableItemSelectable = React.createClass({ + + propTypes: { + parentId: React.PropTypes.number + }, + + propTypes: { + columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(TableColumnContentModel)), + columnContent: React.PropTypes.object + }, + + render() { + let tableItemClasses = classNames({ + 'ascribe-table-item-selected': this.props.columnContent.selected + }); + let boundSelectItem = this.props.selectItem.bind(this, this.props.parentId, this.props.columnContent.edition_number); + + return ( + + + ); + } +}); + +export default TableItemSelectable; diff --git a/js/components/ascribe_table/table_item_subtable.js b/js/components/ascribe_table/table_item_subtable.js index a4643d3e..66faee49 100644 --- a/js/components/ascribe_table/table_item_subtable.js +++ b/js/components/ascribe_table/table_item_subtable.js @@ -10,7 +10,7 @@ import EditionListActions from '../../actions/edition_list_actions'; import GeneralUtils from '../../utils/general_utils'; import Table from './table'; -import TableItem from './table_item'; +import TableItemSelectable from './table_item_selectable'; import TableItemText from './table_item_text'; import TableItemSubtableButton from './table_item_subtable_button'; @@ -50,6 +50,13 @@ let TableItemSubtable = React.createClass({ } }, + selectItem(parentId, itemId) { + EditionListActions.selectEdition({ + 'pieceId': parentId, + 'editionId': itemId + }); + }, + render() { let calcColumnElementContent = () => { @@ -83,9 +90,11 @@ let TableItemSubtable = React.createClass({ {this.state.editionList[this.props.columnContent.id].map((edition, i) => { return ( - - + ); })}
diff --git a/js/stores/edition_list_store.js b/js/stores/edition_list_store.js index 4158e74c..0edad1dc 100644 --- a/js/stores/edition_list_store.js +++ b/js/stores/edition_list_store.js @@ -7,8 +7,22 @@ class EditionListStore { this.bindActions(EditionsListActions); } - onUpdateEditionList({pieceId, editionList}) { - this.editionList[pieceId] = editionList; + onUpdateEditionList({pieceId, editionListOfPiece}) { + this.editionList[pieceId] = editionListOfPiece; + } + + onSelectEdition({pieceId, editionId}) { + + this.editionList[pieceId].forEach((edition) => { + if(edition.edition_number === editionId) { + if(edition.selected) { + edition.selected = false; + } else { + edition.selected = true; + } + } + }); + } }; From d71e6baa19a5f3ec95ee2c4530b6e2a141cfe053 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Tue, 26 May 2015 17:25:03 +0200 Subject: [PATCH 05/14] add persistent selected rows --- js/components/ascribe_table/table_item_subtable.js | 1 + js/stores/edition_list_store.js | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/js/components/ascribe_table/table_item_subtable.js b/js/components/ascribe_table/table_item_subtable.js index 66faee49..f3d65407 100644 --- a/js/components/ascribe_table/table_item_subtable.js +++ b/js/components/ascribe_table/table_item_subtable.js @@ -42,6 +42,7 @@ let TableItemSubtable = React.createClass({ 'open': false }); } else { + EditionListActions.fetchEditionList(this.props.columnContent.id); this.setState({ 'open': true, diff --git a/js/stores/edition_list_store.js b/js/stores/edition_list_store.js index 0edad1dc..feb0ba2a 100644 --- a/js/stores/edition_list_store.js +++ b/js/stores/edition_list_store.js @@ -1,3 +1,5 @@ +import React from 'react'; + import alt from '../alt'; import EditionsListActions from '../actions/edition_list_actions'; @@ -8,6 +10,13 @@ class EditionListStore { } onUpdateEditionList({pieceId, editionListOfPiece}) { + if(this.editionList[pieceId]) { + this.editionList[pieceId].forEach((edition, i) => { + // This uses the index of the new editionList for determining the edition. + // If the list of editions can be sorted in the future, this needs to be changed! + editionListOfPiece[i] = React.addons.update(edition, {$merge: editionListOfPiece[i]}); + }) + } this.editionList[pieceId] = editionListOfPiece; } From 64793cd90b847096b4ad2f764fd0238f2deef91e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Tue, 26 May 2015 19:16:30 +0200 Subject: [PATCH 06/14] remove npm start scripts, add gulp for build and watch, add source maps --- README.md | 4 +--- gulpfile.js | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 22 ++++++++--------- 3 files changed, 78 insertions(+), 15 deletions(-) create mode 100644 gulpfile.js diff --git a/README.md b/README.md index 21c85c0c..c4391d52 100644 --- a/README.md +++ b/README.md @@ -18,9 +18,7 @@ Install some nice extensions for Chrom(e|ium): git clone git@bitbucket.org:ascribe/onion.git cd onion npm install -npm run watch - -python -mSimpleHTTPServer +gulp serve ``` diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 00000000..3b42e4de --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,67 @@ +var gulp = require('gulp'); +var gulpif = require('gulp-if'); +var sourcemaps = require('gulp-sourcemaps'); +var util = require('gulp-util'); +var source = require('vinyl-source-stream'); +var buffer = require('vinyl-buffer'); +var watchify = require('watchify'); +var browserify = require('browserify'); +var browserSync = require('browser-sync'); +var babelify = require('babelify'); +var notify = require('gulp-notify'); +var _ = require('lodash'); + +gulp.task('build', function() { + bundle(false); +}); + +gulp.task('serve', ['browser-sync'], function() { + bundle(true); +}); + +gulp.task('browser-sync', function() { + browserSync({ + server: { + baseDir: "." + }, + port: process.env.PORT || 3000 + }); +}); + +function bundle(watch) { + var bro; + + if (watch) { + bro = watchify(browserify('./js/app.js', + // Assigning debug to have sourcemaps + _.assign(watchify.args, { + debug: true + }))); + bro.on('update', function() { + rebundle(bro, true); + }); + } else { + bro = browserify('./js/app.js', { + debug: true + }); + } + + bro.transform(babelify.configure({ + compact: false + })); + + function rebundle(bundler, watch) { + return bundler.bundle() + .on('error', notify.onError('Error: <%= error.message %>')) + .pipe(source('app.js')) + .pipe(buffer()) + .pipe(sourcemaps.init({ + loadMaps: true + })) // loads map from browserify file + .pipe(sourcemaps.write()) // writes .map file + .pipe(gulp.dest('./build')) + .pipe(browserSync.stream()); + } + + return rebundle(bro); +} \ No newline at end of file diff --git a/package.json b/package.json index a7b45c6c..2313c305 100644 --- a/package.json +++ b/package.json @@ -3,26 +3,24 @@ "version": "0.0.1", "description": "Das neue web client for Ascribe", "main": "js/app.js", - "scripts": { - "watch": "watchify -o build/app.js -v -d js/app.js", - "build": "browserify . -t [envify --NODE_ENV production] | uglifyjs -cm > build/app.js", - "test": "jest" - }, "author": "Ascribe", "license": "Copyright", - "browserify": { - "transform": [ - "babelify", - "envify" - ] - }, "devDependencies": { "babel-jest": "^4.0.0", - "babelify": "^6.0.2", + "babelify": "^6.1.2", + "browser-sync": "^2.7.5", "browserify": "^9.0.8", "envify": "^3.4.0", + "gulp": "^3.8.11", + "gulp-if": "^1.2.5", + "gulp-notify": "^2.2.0", + "gulp-sourcemaps": "^1.5.2", + "gulp-util": "^3.0.4", "jest-cli": "^0.4.0", + "lodash": "^3.9.3", "reactify": "^1.1.0", + "vinyl-buffer": "^1.0.0", + "vinyl-source-stream": "^1.1.0", "watchify": "^3.1.2" }, "dependencies": { From 9c017ac993f3c685b485f71098b4a76a02c1ffbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Tue, 26 May 2015 19:50:18 +0200 Subject: [PATCH 07/14] Fix bind warning --- js/components/ascribe_table/table_item_selectable.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/js/components/ascribe_table/table_item_selectable.js b/js/components/ascribe_table/table_item_selectable.js index 8e48b816..974c5453 100644 --- a/js/components/ascribe_table/table_item_selectable.js +++ b/js/components/ascribe_table/table_item_selectable.js @@ -17,17 +17,20 @@ let TableItemSelectable = React.createClass({ columnContent: React.PropTypes.object }, + selectItem() { + this.props.selectItem(this.props.parentId, this.props.columnContent.edition_number); + }, + render() { let tableItemClasses = classNames({ 'ascribe-table-item-selected': this.props.columnContent.selected }); - let boundSelectItem = this.props.selectItem.bind(this, this.props.parentId, this.props.columnContent.edition_number); return ( + onClick={this.selectItem}> ); } From abac948dd1a285eb98c71a1a23d522820924d894 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Tue, 26 May 2015 19:59:37 +0200 Subject: [PATCH 08/14] Add ACL display for table --- js/components/ascribe_table/table_item_acl.js | 18 ++++++++++++++++++ .../ascribe_table/table_item_subtable.js | 5 +++-- 2 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 js/components/ascribe_table/table_item_acl.js diff --git a/js/components/ascribe_table/table_item_acl.js b/js/components/ascribe_table/table_item_acl.js new file mode 100644 index 00000000..87e14761 --- /dev/null +++ b/js/components/ascribe_table/table_item_acl.js @@ -0,0 +1,18 @@ +import React from 'react'; + + +let TableItemAcl = React.createClass({ + propTypes: { + content: React.PropTypes.array.isRequired + }, + + render() { + return ( + + {this.props.content.join('/')} + + ); + } +}); + +export default TableItemAcl; diff --git a/js/components/ascribe_table/table_item_subtable.js b/js/components/ascribe_table/table_item_subtable.js index f3d65407..85e361fe 100644 --- a/js/components/ascribe_table/table_item_subtable.js +++ b/js/components/ascribe_table/table_item_subtable.js @@ -10,8 +10,9 @@ import EditionListActions from '../../actions/edition_list_actions'; import GeneralUtils from '../../utils/general_utils'; import Table from './table'; -import TableItemSelectable from './table_item_selectable'; import TableItemText from './table_item_text'; +import TableItemAcl from './table_item_acl'; +import TableItemSelectable from './table_item_selectable'; import TableItemSubtableButton from './table_item_subtable_button'; @@ -81,7 +82,7 @@ let TableItemSubtable = React.createClass({ let columnList = [ new TableColumnContentModel('edition_number', 'Edition Number', TableItemText, 2, false), new TableColumnContentModel('user_registered', 'User', TableItemText, 4, true), - new TableColumnContentModel('bitcoin_id', 'Bitcoin Address', TableItemText, 4, true) + new TableColumnContentModel('acl', 'Actions', TableItemAcl, 4, true) ]; if(this.state.open && this.state.editionList[this.props.columnContent.id] && this.state.editionList[this.props.columnContent.id].length) { From b875a9817cc128a8aadb2ec898272f6009cba895 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Tue, 26 May 2015 20:20:17 +0200 Subject: [PATCH 09/14] Refactor table_item logic --- js/components/ascribe_table/table_item.js | 26 ++++---------- .../ascribe_table/table_item_subtable.js | 26 +++----------- .../ascribe_table/table_item_wrapper.js | 34 +++++++++++++++++++ 3 files changed, 46 insertions(+), 40 deletions(-) create mode 100644 js/components/ascribe_table/table_item_wrapper.js diff --git a/js/components/ascribe_table/table_item.js b/js/components/ascribe_table/table_item.js index 6b7b62f8..1827253f 100644 --- a/js/components/ascribe_table/table_item.js +++ b/js/components/ascribe_table/table_item.js @@ -1,12 +1,11 @@ import React from 'react'; -import TableColumnMixin from '../../mixins/table_column_mixin'; - import TableColumnContentModel from '../../models/table_column_content_model'; +import TableItemWrapper from './table_item_wrapper'; + let TableItem = React.createClass({ - mixins: [TableColumnMixin], propTypes: { columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(TableColumnContentModel)), @@ -16,27 +15,16 @@ let TableItem = React.createClass({ }, render() { - let calcColumnElementContent = () => { - return this.props.columnList.map((column, i) => { - - let TypeElement = column.displayType; - let columnClass = this.calcColumnClasses(this.props.columnList, i, 12); - - return ( -
- -
- ); - - }); - }; - return (
- {calcColumnElementContent()} + +
); diff --git a/js/components/ascribe_table/table_item_subtable.js b/js/components/ascribe_table/table_item_subtable.js index 85e361fe..00c456ce 100644 --- a/js/components/ascribe_table/table_item_subtable.js +++ b/js/components/ascribe_table/table_item_subtable.js @@ -1,15 +1,13 @@ import React from 'react'; import TableColumnContentModel from '../../models/table_column_content_model'; -import TableColumnMixin from '../../mixins/table_column_mixin'; import EditionListStore from '../../stores/edition_list_store'; import EditionListActions from '../../actions/edition_list_actions'; -// ToDo: Create Table-specific Utils to not lock it to projects utilities -import GeneralUtils from '../../utils/general_utils'; import Table from './table'; +import TableItemWrapper from './table_item_wrapper'; import TableItemText from './table_item_text'; import TableItemAcl from './table_item_acl'; import TableItemSelectable from './table_item_selectable'; @@ -17,7 +15,6 @@ import TableItemSubtableButton from './table_item_subtable_button'; let TableItemSubtable = React.createClass({ - mixins: [TableColumnMixin], propTypes: { columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(TableColumnContentModel)), columnContent: React.PropTypes.object @@ -61,22 +58,6 @@ let TableItemSubtable = React.createClass({ render() { - let calcColumnElementContent = () => { - return this.props.columnList.map((column, i) => { - - let TypeElement = column.displayType; - let columnClass = this.calcColumnClasses(this.props.columnList, i, 12); - - return ( -
- -
- ); - - }); - }; - - let renderEditionListTable = () => { let columnList = [ @@ -109,7 +90,10 @@ let TableItemSubtable = React.createClass({ return (
- {calcColumnElementContent()} +
diff --git a/js/components/ascribe_table/table_item_wrapper.js b/js/components/ascribe_table/table_item_wrapper.js new file mode 100644 index 00000000..2f9f4c7e --- /dev/null +++ b/js/components/ascribe_table/table_item_wrapper.js @@ -0,0 +1,34 @@ +import React from 'react'; + +import TableColumnContentModel from '../../models/table_column_content_model'; +import TableColumnMixin from '../../mixins/table_column_mixin'; + +let TableItemWrapper = React.createClass({ + mixins: [TableColumnMixin], + propTypes: { + columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(TableColumnContentModel)), + columnContent: React.PropTypes.object, + columnWidth: React.PropTypes.number.isRequired + }, + + render() { + return ( +
+ {this.props.columnList.map((column, i) => { + + let TypeElement = column.displayType; + let columnClass = this.calcColumnClasses(this.props.columnList, i, this.props.columnWidth); + + return ( +
+ +
+ ); + + })} +
+ ); + } +}); + +export default TableItemWrapper; \ No newline at end of file From f6dab18cba7a4b53cf8f7219d332b21a09c2b657 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Wed, 27 May 2015 08:24:13 +0200 Subject: [PATCH 10/14] small refactor --- js/components/ascribe_table/table.js | 8 +++++++- js/components/ascribe_table/table_item_selectable.js | 5 +++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/js/components/ascribe_table/table.js b/js/components/ascribe_table/table.js index 90067be6..06af7b89 100644 --- a/js/components/ascribe_table/table.js +++ b/js/components/ascribe_table/table.js @@ -27,7 +27,13 @@ let Table = React.createClass({ if(this.props.itemList && this.props.itemList.length > 0) { return (
- + {this.renderChildren()}
); diff --git a/js/components/ascribe_table/table_item_selectable.js b/js/components/ascribe_table/table_item_selectable.js index 974c5453..7b03618c 100644 --- a/js/components/ascribe_table/table_item_selectable.js +++ b/js/components/ascribe_table/table_item_selectable.js @@ -5,7 +5,7 @@ import TableColumnContentModel from '../../models/table_column_content_model'; import TableItem from './table_item'; -// This Component is implemented as recommended here: http://stackoverflow.com/a/25723635/1263876 +// This component is implemented as recommended here: http://stackoverflow.com/a/25723635/1263876 let TableItemSelectable = React.createClass({ propTypes: { @@ -27,7 +27,8 @@ let TableItemSelectable = React.createClass({ }); return ( - From aa75b7d8bdd9c26b40b0e5c07af5c0e189daa1a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Wed, 27 May 2015 09:05:39 +0200 Subject: [PATCH 11/14] fix small bug --- js/components/ascribe_table/table_item_selectable.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/js/components/ascribe_table/table_item_selectable.js b/js/components/ascribe_table/table_item_selectable.js index 7b03618c..bc508a7c 100644 --- a/js/components/ascribe_table/table_item_selectable.js +++ b/js/components/ascribe_table/table_item_selectable.js @@ -8,13 +8,10 @@ import TableItem from './table_item'; // This component is implemented as recommended here: http://stackoverflow.com/a/25723635/1263876 let TableItemSelectable = React.createClass({ - propTypes: { - parentId: React.PropTypes.number - }, - propTypes: { columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(TableColumnContentModel)), - columnContent: React.PropTypes.object + columnContent: React.PropTypes.object, + parentId: React.PropTypes.number }, selectItem() { From 58e284cbdf03c6ce125319cce2b97dbfd504b73c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Wed, 27 May 2015 09:56:26 +0200 Subject: [PATCH 12/14] refactor edition-button --- css/main.css | 13 ++++++------- .../ascribe_table/table_item_selectable.js | 5 +++-- js/components/ascribe_table/table_item_subtable.js | 8 +++++--- .../ascribe_table/table_item_subtable_button.js | 2 +- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/css/main.css b/css/main.css index de85b7fc..9188fe42 100644 --- a/css/main.css +++ b/css/main.css @@ -16,7 +16,7 @@ .ascribe-table-header-column { display: table; - height:4em; + height:3em; } .ascribe-table-header-column > span { @@ -44,7 +44,7 @@ display: table; font-family: 'Source Sans Pro'; font-size: 1.2em; - height:4em; + height:3em; } .ascribe-table-item-column > * { @@ -52,11 +52,10 @@ vertical-align: middle; } -.btn-ascribe, .btn-ascribe:hover, .btn-ascribe:active, .btn-ascribe:focus { - background-color: rgba(2, 182, 163, 0.5); - border-color: rgba(2, 182, 163, 0.5); -} - .ascribe-table-item-selected { background-color: rgba(2, 182, 163, 0.5); +} + +.ascribe-table-item-selectable { + cursor: default; } \ No newline at end of file diff --git a/js/components/ascribe_table/table_item_selectable.js b/js/components/ascribe_table/table_item_selectable.js index bc508a7c..d62f8d04 100644 --- a/js/components/ascribe_table/table_item_selectable.js +++ b/js/components/ascribe_table/table_item_selectable.js @@ -11,7 +11,8 @@ let TableItemSelectable = React.createClass({ propTypes: { columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(TableColumnContentModel)), columnContent: React.PropTypes.object, - parentId: React.PropTypes.number + parentId: React.PropTypes.number, + className: React.PropTypes.string }, selectItem() { @@ -25,7 +26,7 @@ let TableItemSelectable = React.createClass({ return ( diff --git a/js/components/ascribe_table/table_item_subtable.js b/js/components/ascribe_table/table_item_subtable.js index 00c456ce..9db1930c 100644 --- a/js/components/ascribe_table/table_item_subtable.js +++ b/js/components/ascribe_table/table_item_subtable.js @@ -74,6 +74,7 @@ let TableItemSubtable = React.createClass({ {this.state.editionList[this.props.columnContent.id].map((edition, i) => { return ( @@ -93,9 +94,10 @@ let TableItemSubtable = React.createClass({ -
- + columnWidth={12}> + +
+
diff --git a/js/components/ascribe_table/table_item_subtable_button.js b/js/components/ascribe_table/table_item_subtable_button.js index 7638dc13..8c5431d8 100644 --- a/js/components/ascribe_table/table_item_subtable_button.js +++ b/js/components/ascribe_table/table_item_subtable_button.js @@ -10,7 +10,7 @@ let TableItemSubtableButton = React.createClass({ render() { return ( - From f85d4fd1067043eab0f001d5548c270800a0c57d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Wed, 27 May 2015 13:57:11 +0200 Subject: [PATCH 13/14] implement intersection logic for acls --- css/main.css | 11 +++ .../piece_list_toolbar.js | 81 +++++++++++++++++++ js/components/piece_list.js | 5 +- 3 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 js/components/ascribe_piece_list_toolbar/piece_list_toolbar.js diff --git a/css/main.css b/css/main.css index 9188fe42..d76c9773 100644 --- a/css/main.css +++ b/css/main.css @@ -12,11 +12,13 @@ .ascribe-table-header-row { border-bottom: 2px solid rgba(2, 182, 163, 0.5); border-top: 2px solid rgba(2, 182, 163, 0.5); + padding: 0; } .ascribe-table-header-column { display: table; height:3em; + padding: 0; } .ascribe-table-header-column > span { @@ -58,4 +60,13 @@ .ascribe-table-item-selectable { cursor: default; +} + +.piece-list-toolbar { + height:3em; +} + +.no-margin { + margin-right: 0; + margin-left: 0; } \ No newline at end of file diff --git a/js/components/ascribe_piece_list_toolbar/piece_list_toolbar.js b/js/components/ascribe_piece_list_toolbar/piece_list_toolbar.js new file mode 100644 index 00000000..a45e7b9d --- /dev/null +++ b/js/components/ascribe_piece_list_toolbar/piece_list_toolbar.js @@ -0,0 +1,81 @@ +import React from 'react'; + +import EditionListStore from '../../stores/edition_list_store'; + +let PieceListToolbar = React.createClass({ + getInitialState() { + return EditionListStore.getState(); + }, + + onChange(state) { + this.setState(state); + }, + + componentDidMount() { + EditionListStore.listen(this.onChange) + }, + + componentDidUnmount() { + EditionListStore.unlisten(this.onChange) + }, + + filterForSelected(edition) { + return edition.selected; + }, + + fetchSelectedEditionList() { + let selectedEditionList = []; + + Object + .keys(this.state.editionList) + .forEach((key) => { + let filteredEditionsForPiece = this.state.editionList[key] + .filter(this.filterForSelected); + selectedEditionList = selectedEditionList.concat(filteredEditionsForPiece); + }); + + return selectedEditionList; + }, + + intersectAcls(a, b) { + //console.log(a, b); + return a.filter((val) => b.indexOf(val) > -1); + }, + + getAvailableAcls() { + let availableAcls = []; + let selectedEditionList = this.fetchSelectedEditionList(); + + // If no edition has been selected, availableActions is empty + // If only one edition has been selected, their actions are available + if(selectedEditionList.length >= 1) { + availableAcls = selectedEditionList[0].acl; + } + if(selectedEditionList.length >= 2) { + for(let i = 1; i < selectedEditionList.length; i++) { + availableAcls = this.intersectAcls(availableAcls, selectedEditionList[i].acl); + } + } + + return availableAcls; + }, + + render() { + this.getAvailableAcls(); + + return ( +
+
+
+ + + + +
+
+
+ ); + } +}); + +export default PieceListToolbar; \ No newline at end of file diff --git a/js/components/piece_list.js b/js/components/piece_list.js index 13927164..f9ffddc3 100644 --- a/js/components/piece_list.js +++ b/js/components/piece_list.js @@ -13,7 +13,9 @@ import TableItemSubtableButton from './ascribe_table/table_item_subtable_button' import TableColumnContentModel from '../models/table_column_content_model'; -import Pagination from './ascribe_pagination/pagination' +import Pagination from './ascribe_pagination/pagination'; + +import PieceListToolbar from './ascribe_piece_list_toolbar/piece_list_toolbar'; let PieceList = React.createClass({ @@ -62,6 +64,7 @@ let PieceList = React.createClass({ if(this.state.pieceList && this.state.pieceList.length > 0) { return (
+ Date: Wed, 27 May 2015 14:35:33 +0200 Subject: [PATCH 14/14] add acl buttons for selection --- js/components/acl_button.js | 32 +++++++++++++++++++ .../piece_list_toolbar.js | 17 +++++----- js/constants/application_constants.js | 3 +- 3 files changed, 43 insertions(+), 9 deletions(-) create mode 100644 js/components/acl_button.js diff --git a/js/components/acl_button.js b/js/components/acl_button.js new file mode 100644 index 00000000..9d52a09a --- /dev/null +++ b/js/components/acl_button.js @@ -0,0 +1,32 @@ +import React from 'react'; + +import AppConstants from '../constants/application_constants'; + +let AclButton = React.createClass({ + propTypes: { + action: React.PropTypes.oneOf(AppConstants.aclList).isRequired, + availableAcls: React.PropTypes.array.isRequired + }, + + render() { + let shouldDisplay = this.props.availableAcls.indexOf(this.props.action) > -1; + let styles = {}; + + if(shouldDisplay) { + styles.display = 'inline-block'; + } else { + styles.display = 'none'; + } + + return ( + + ); + } +}); + +export default AclButton; \ No newline at end of file diff --git a/js/components/ascribe_piece_list_toolbar/piece_list_toolbar.js b/js/components/ascribe_piece_list_toolbar/piece_list_toolbar.js index a45e7b9d..1ce4d744 100644 --- a/js/components/ascribe_piece_list_toolbar/piece_list_toolbar.js +++ b/js/components/ascribe_piece_list_toolbar/piece_list_toolbar.js @@ -2,6 +2,8 @@ import React from 'react'; import EditionListStore from '../../stores/edition_list_store'; +import AclButton from '../acl_button'; + let PieceListToolbar = React.createClass({ getInitialState() { return EditionListStore.getState(); @@ -29,8 +31,7 @@ let PieceListToolbar = React.createClass({ Object .keys(this.state.editionList) .forEach((key) => { - let filteredEditionsForPiece = this.state.editionList[key] - .filter(this.filterForSelected); + let filteredEditionsForPiece = this.state.editionList[key].filter(this.filterForSelected); selectedEditionList = selectedEditionList.concat(filteredEditionsForPiece); }); @@ -38,7 +39,6 @@ let PieceListToolbar = React.createClass({ }, intersectAcls(a, b) { - //console.log(a, b); return a.filter((val) => b.indexOf(val) > -1); }, @@ -48,6 +48,7 @@ let PieceListToolbar = React.createClass({ // If no edition has been selected, availableActions is empty // If only one edition has been selected, their actions are available + // If more than one editions have been selected, their acl properties are intersected if(selectedEditionList.length >= 1) { availableAcls = selectedEditionList[0].acl; } @@ -61,16 +62,16 @@ let PieceListToolbar = React.createClass({ }, render() { - this.getAvailableAcls(); + let availableAcls = this.getAvailableAcls(); return (
- - - - + + + +
diff --git a/js/constants/application_constants.js b/js/constants/application_constants.js index 8efb7196..7d706d8c 100644 --- a/js/constants/application_constants.js +++ b/js/constants/application_constants.js @@ -1,6 +1,7 @@ let constants = { 'baseUrl': 'http://staging.ascribe.io/api/', - 'debugCredentialBase64': 'ZGltaUBtYWlsaW5hdG9yLmNvbTowMDAwMDAwMDAw' // dimi@mailinator:0000000000 + 'debugCredentialBase64': 'ZGltaUBtYWlsaW5hdG9yLmNvbTowMDAwMDAwMDAw', // dimi@mailinator:0000000000 + 'aclList': ['edit', 'consign', 'transfer', 'loan', 'share', 'download', 'view', 'delete', 'del_from_collection', 'add_to_collection'] }; export default constants; \ No newline at end of file