From b4076aeef75f1b7e2b42f6fb5e5d999305bff06e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Wed, 3 Jun 2015 10:45:23 +0200 Subject: [PATCH 01/21] code styling --- index.html | 1 - .../accordion_list_item_table_editions.js | 51 +++++++++++++++++-- .../piece_list_bulk_modal.js | 10 +--- .../ascribe_table/table_item_acl_filtered.js | 4 +- sass/main.scss | 1 + 5 files changed, 52 insertions(+), 15 deletions(-) diff --git a/index.html b/index.html index 066b36cc..8d16b099 100644 --- a/index.html +++ b/index.html @@ -5,7 +5,6 @@ ascribe - diff --git a/js/components/ascribe_accordion_list/accordion_list_item_table_editions.js b/js/components/ascribe_accordion_list/accordion_list_item_table_editions.js index 1d8daa45..13225c59 100644 --- a/js/components/ascribe_accordion_list/accordion_list_item_table_editions.js +++ b/js/components/ascribe_accordion_list/accordion_list_item_table_editions.js @@ -53,10 +53,53 @@ let AccordionListItemTableEditions = React.createClass({ render() { let columnList = [ - new TableColumnContentModel((item) => { return { 'editionId': item.id, 'pieceId': this.props.parentId, 'selectItem': this.selectItem, 'selected': item.selected }}, '', '', TableItemCheckbox, 1, false), - new TableColumnContentModel((item) => { return { 'content': item.edition_number }}, 'num_editions', '#', TableItemText, 1, false), - new TableColumnContentModel((item) => { return { 'content': item.bitcoin_id }}, 'bitcoin_id', getLangText('Bitcoin Address'), TableItemText, 5, false), - new TableColumnContentModel((item) => { return { 'content': item.acl }}, 'acl', getLangText('Actions'), TableItemAclFiltered, 4, false) + new TableColumnContentModel( + (item) => { + return { + 'editionId': item.id, + 'pieceId': this.props.parentId, + 'selectItem': this.selectItem, + 'selected': item.selected + }}, + '', + '', + TableItemCheckbox, + 1, + false + ), + new TableColumnContentModel( + (item) => { + return { + 'content': item.edition_number + }}, + 'num_editions', + '#', + TableItemText, + 1, + false + ), + new TableColumnContentModel( + (item) => { + return { + 'content': item.bitcoin_id + }}, + 'bitcoin_id', + getLangText('Bitcoin Address'), + TableItemText, + 5, + false + ), + new TableColumnContentModel( + (item) => { + return { + 'content': item.acl + }}, + 'acl', + getLangText('Actions'), + TableItemAclFiltered, + 4, + false + ) ]; return ( 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 f229ef07..896882df 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 @@ -33,17 +33,13 @@ let PieceListBulkModal = React.createClass({ UserStore.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); + let filteredEditionsForPiece = this.state.editionList[key].filter((edition) => edition.selected); selectedEditionList = selectedEditionList.concat(filteredEditionsForPiece); }); @@ -54,10 +50,6 @@ let PieceListBulkModal = React.createClass({ return a.filter((val) => b.indexOf(val) > -1); }, - bulk(action) { - console.log(action); - }, - getAvailableAcls() { let availableAcls = []; let selectedEditionList = this.fetchSelectedEditionList(); diff --git a/js/components/ascribe_table/table_item_acl_filtered.js b/js/components/ascribe_table/table_item_acl_filtered.js index dada05ab..6fd8e9fe 100644 --- a/js/components/ascribe_table/table_item_acl_filtered.js +++ b/js/components/ascribe_table/table_item_acl_filtered.js @@ -7,8 +7,10 @@ let TableItemAclFiltered = React.createClass({ }, render() { + var availableAcls = ['consign', 'loan', 'transfer', 'view']; + let filteredAcls = this.props.content.filter((v) => { - return v === 'consign' || v === 'loan' || v === 'transfer' || v === 'view'; + return availableAcls.indexOf(v) > -1; }); return ( diff --git a/sass/main.scss b/sass/main.scss index 1a00481b..2fe60cac 100644 --- a/sass/main.scss +++ b/sass/main.scss @@ -3,6 +3,7 @@ @import 'variables'; @import 'ascribe_variables'; @import '../node_modules/bootstrap-sass/assets/stylesheets/bootstrap'; +@import '../node_modules/react-datepicker/dist/react-datepicker'; @import './ascribe-fonts/style'; @import './ascribe-fonts/ascribe-fonts'; @import 'ascribe_accordion_list'; From e3c3afcefaf40b0540c2e2f3e6308dcfd828ab82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Wed, 3 Jun 2015 16:34:32 +0200 Subject: [PATCH 02/21] add year to accordion-list-item --- js/components/ascribe_accordion_list/accordion_list_item.js | 2 ++ js/utils/lang_utils.js | 2 +- sass/ascribe_accordion_list.scss | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/js/components/ascribe_accordion_list/accordion_list_item.js b/js/components/ascribe_accordion_list/accordion_list_item.js index e9bb8742..fc8715a7 100644 --- a/js/components/ascribe_accordion_list/accordion_list_item.js +++ b/js/components/ascribe_accordion_list/accordion_list_item.js @@ -11,6 +11,7 @@ let AccordionListItem = React.createClass({ }, render() { + console.log(this.props.content); return (
@@ -21,6 +22,7 @@ let AccordionListItem = React.createClass({

{this.props.content.title}

{getLangText('by %s', this.props.content.artist_name)}

+

{this.props.content.date_created.split('-')[0]}

diff --git a/js/utils/lang_utils.js b/js/utils/lang_utils.js index 7eb4b6f3..d1ea5fd5 100644 --- a/js/utils/lang_utils.js +++ b/js/utils/lang_utils.js @@ -11,7 +11,7 @@ import { formatText } from './general_utils'; export function getLangText(s, ...args) { let lang = navigator.language || navigator.userLanguage; // this is just for testing, as changing the navigator.language wasn't possible - lang = 'de'; + //lang = 'de'; try { if(lang in languages) { return formatText(languages[lang][s], args); diff --git a/sass/ascribe_accordion_list.scss b/sass/ascribe_accordion_list.scss index 43b77fa9..13023d0f 100644 --- a/sass/ascribe_accordion_list.scss +++ b/sass/ascribe_accordion_list.scss @@ -36,8 +36,8 @@ $ascribe-accordion-list-font: 'Source Sans Pro'; float:left; font-family: $ascribe-accordion-list-font; margin-left: 2em; - padding-top: .75em; h1 { + margin-top: .5em; font-size: 2.25em; } h3 { From 8d560fb664a347d8109b04e2b515c466b817cd6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Wed, 3 Jun 2015 16:48:31 +0200 Subject: [PATCH 03/21] thumbnail is not croped anymore --- .../accordion_list_item.js | 5 ++-- sass/ascribe_accordion_list.scss | 27 +++++++------------ 2 files changed, 11 insertions(+), 21 deletions(-) diff --git a/js/components/ascribe_accordion_list/accordion_list_item.js b/js/components/ascribe_accordion_list/accordion_list_item.js index fc8715a7..53739f3a 100644 --- a/js/components/ascribe_accordion_list/accordion_list_item.js +++ b/js/components/ascribe_accordion_list/accordion_list_item.js @@ -11,15 +11,14 @@ let AccordionListItem = React.createClass({ }, render() { - console.log(this.props.content); return (
-
+
-
+

{this.props.content.title}

{getLangText('by %s', this.props.content.artist_name)}

{this.props.content.date_created.split('-')[0]}

diff --git a/sass/ascribe_accordion_list.scss b/sass/ascribe_accordion_list.scss index 13023d0f..fefba59c 100644 --- a/sass/ascribe_accordion_list.scss +++ b/sass/ascribe_accordion_list.scss @@ -21,29 +21,20 @@ $ascribe-accordion-list-font: 'Source Sans Pro'; height:100%; // ToDo: Include media queries for thumbnail .thumbnail-wrapper { - float:left; - height:100%; - width:$ascribe-accordion-list-item-height; - overflow:hidden; + margin-left:0; padding-left:0; - padding-right:0; - img { + display:block; height: $ascribe-accordion-list-item-height; } } - .info-wrapper { - float:left; - font-family: $ascribe-accordion-list-font; - margin-left: 2em; - h1 { - margin-top: .5em; - font-size: 2.25em; - } - h3 { - font-size: 1.1em; - margin: .7em 0 0 0; - } + h1 { + margin-top: .3em; + font-size: 2.25em; + } + h3 { + font-size: 1.1em; + margin: .7em 0 0 0; } } } From ef6662e8592c7239f05c9f71b7a60d108b3bf7b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Thu, 4 Jun 2015 09:16:30 +0200 Subject: [PATCH 04/21] add ordering functionality to editionlist table --- js/actions/edition_list_actions.js | 8 +++++--- .../accordion_list_item_table.js | 10 ++++++++-- .../accordion_list_item_table_editions.js | 17 ++++++++++++----- js/components/ascribe_table/table.js | 13 +++++++------ js/fetchers/edition_list_fetcher.js | 7 +++++-- js/stores/edition_list_store.js | 6 +++++- 6 files changed, 42 insertions(+), 19 deletions(-) diff --git a/js/actions/edition_list_actions.js b/js/actions/edition_list_actions.js index 78cc0eeb..f07d7d18 100644 --- a/js/actions/edition_list_actions.js +++ b/js/actions/edition_list_actions.js @@ -11,13 +11,15 @@ class EditionListActions { ); } - fetchEditionList(pieceId) { + fetchEditionList(pieceId, orderBy, orderAsc) { EditionListFetcher - .fetch(pieceId) + .fetch(pieceId, orderBy, orderAsc) .then((res) => { this.actions.updateEditionList({ 'editionListOfPiece': res.editions, - pieceId + pieceId, + orderBy, + orderAsc }); }) .catch((err) => { diff --git a/js/components/ascribe_accordion_list/accordion_list_item_table.js b/js/components/ascribe_accordion_list/accordion_list_item_table.js index 1cf410df..82b9a23a 100644 --- a/js/components/ascribe_accordion_list/accordion_list_item_table.js +++ b/js/components/ascribe_accordion_list/accordion_list_item_table.js @@ -14,7 +14,10 @@ let AccordionListItemTable = React.createClass({ itemList: React.PropTypes.array, columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(TableColumnContentModel)), numOfTableItems: React.PropTypes.number, - show: React.PropTypes.bool + show: React.PropTypes.bool, + changeOrder: React.PropTypes.func, + orderBy: React.PropTypes.string, + orderAsc: React.PropTypes.bool }, render() { @@ -23,7 +26,10 @@ let AccordionListItemTable = React.createClass({
+ itemList={this.props.itemList} + changeOrder={this.props.changeOrder} + orderBy={this.props.orderBy} + orderAsc={this.props.orderAsc}> {this.props.itemList.map((item, i) => { return ( { @@ -87,7 +91,7 @@ let AccordionListItemTableEditions = React.createClass({ getLangText('Bitcoin Address'), TableItemText, 5, - false + true ), new TableColumnContentModel( (item) => { @@ -110,7 +114,10 @@ let AccordionListItemTableEditions = React.createClass({ itemList={this.state.editionList[this.props.parentId]} columnList={columnList} numOfTableItems={this.props.numOfEditions} - show={this.props.show}> + show={this.props.show} + orderBy={this.state.orderBy} + orderAsc={this.state.orderAsc} + changeOrder={this.changeEditionListOrder}>
{this.renderChildren()} diff --git a/js/fetchers/edition_list_fetcher.js b/js/fetchers/edition_list_fetcher.js index 07e52d87..2cec37a7 100644 --- a/js/fetchers/edition_list_fetcher.js +++ b/js/fetchers/edition_list_fetcher.js @@ -1,5 +1,7 @@ import fetch from '../utils/fetch'; +import { generateOrderingQueryParams } from '../utils/fetch_api_utils'; + import AppConstants from '../constants/application_constants'; @@ -7,8 +9,9 @@ let EditionListFetcher = { /** * Fetches a list of editions from the API. */ - fetch(pieceId) { - return fetch.get('editions_list', { 'piece_id': pieceId }); + fetch(pieceId, orderBy, orderAsc) { + let ordering = generateOrderingQueryParams(orderBy, orderAsc); + return fetch.get('editions_list', { 'piece_id': pieceId, ordering }); } }; diff --git a/js/stores/edition_list_store.js b/js/stores/edition_list_store.js index b8855896..4c93fd5c 100644 --- a/js/stores/edition_list_store.js +++ b/js/stores/edition_list_store.js @@ -6,10 +6,12 @@ import EditionsListActions from '../actions/edition_list_actions'; class EditionListStore { constructor() { this.editionList = {}; + this.orderBy = 'edition_number'; + this.orderAsc = true; this.bindActions(EditionsListActions); } - onUpdateEditionList({pieceId, editionListOfPiece}) { + onUpdateEditionList({pieceId, editionListOfPiece, orderBy, orderAsc}) { if(this.editionList[pieceId]) { this.editionList[pieceId].forEach((edition, i) => { // This uses the index of the new editionList for determining the edition. @@ -18,6 +20,8 @@ class EditionListStore { }) } this.editionList[pieceId] = editionListOfPiece; + this.orderBy = orderBy; + this.orderAsc = orderAsc; } onSelectEdition({pieceId, editionId}) { From 4fe5766bc453d0ffc4f3ad969c2967dc3bdb9b2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Thu, 4 Jun 2015 10:11:18 +0200 Subject: [PATCH 05/21] add select all functionality for edition list table --- .../accordion_list_item_table_editions.js | 30 ++++++++++++++++++- ...t_item_table_select_all_editions_toggle.js | 21 +++++++++++++ .../ascribe_table/table_header_item.js | 5 +++- js/stores/piece_list_store.js | 1 + js/utils/lang_utils.js | 2 +- 5 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 js/components/ascribe_accordion_list/accordion_list_item_table_select_all_editions_toggle.js diff --git a/js/components/ascribe_accordion_list/accordion_list_item_table_editions.js b/js/components/ascribe_accordion_list/accordion_list_item_table_editions.js index afe9eb5d..97bc7659 100644 --- a/js/components/ascribe_accordion_list/accordion_list_item_table_editions.js +++ b/js/components/ascribe_accordion_list/accordion_list_item_table_editions.js @@ -7,6 +7,7 @@ import PieceListActions from '../../actions/piece_list_actions'; import AccordionListItemTable from './accordion_list_item_table'; import AccordionListItemTableToggle from './accordion_list_item_table_toggle'; +import AccordionListItemTableSelectAllEditionsToggle from './accordion_list_item_table_select_all_editions_toggle'; import TableColumnContentModel from '../../models/table_column_content_model'; @@ -46,6 +47,19 @@ let AccordionListItemTableEditions = React.createClass({ EditionListActions.selectEdition({pieceId, editionId}); }, + selectAllItems() { + this.state.editionList[this.props.parentId] + .forEach((edition) => { + this.selectItem(this.props.parentId, edition.id); + }); + }, + + filterSelectedEditions() { + let selectedEditions = this.state.editionList[this.props.parentId] + .filter((edition) => edition.selected); + return selectedEditions; + }, + toggleTable() { PieceListActions.showEditionList(this.props.parentId); EditionListActions.fetchEditionList(this.props.parentId, this.state.orderBy, this.state.orderAsc); @@ -56,6 +70,17 @@ let AccordionListItemTableEditions = React.createClass({ }, render() { + let selectedEditionsCount = 0; + let allEditionsCount = 0; + + // here we need to check if all editions of a specific + // piece are already defined. Otherwise .length will throw an error and we'll not + // be notified about it. + if(this.state.editionList[this.props.parentId]) { + selectedEditionsCount = this.filterSelectedEditions().length; + allEditionsCount = this.state.editionList[this.props.parentId].length; + } + let columnList = [ new TableColumnContentModel( (item) => { @@ -66,7 +91,10 @@ let AccordionListItemTableEditions = React.createClass({ 'selected': item.selected }}, '', - '', + , TableItemCheckbox, 1, false diff --git a/js/components/ascribe_accordion_list/accordion_list_item_table_select_all_editions_toggle.js b/js/components/ascribe_accordion_list/accordion_list_item_table_select_all_editions_toggle.js new file mode 100644 index 00000000..37af9edb --- /dev/null +++ b/js/components/ascribe_accordion_list/accordion_list_item_table_select_all_editions_toggle.js @@ -0,0 +1,21 @@ +import React from 'react'; + + +let AccordionListItemTableSelectAllEditionsToggle = React.createClass({ + + propTypes: { + onChange: React.PropTypes.func.isRequired, + numOfSelectedEditions: React.PropTypes.number.isRequired, + numOfAllEditions: React.PropTypes.number.isRequired + }, + + render() { + return ( + + ); + } +}); + +export default AccordionListItemTableSelectAllEditionsToggle; \ No newline at end of file diff --git a/js/components/ascribe_table/table_header_item.js b/js/components/ascribe_table/table_header_item.js index dce2261e..598edada 100644 --- a/js/components/ascribe_table/table_header_item.js +++ b/js/components/ascribe_table/table_header_item.js @@ -6,7 +6,10 @@ let TableHeaderItem = React.createClass({ propTypes: { columnClasses: React.PropTypes.string.isRequired, - displayName: React.PropTypes.string.isRequired, + displayName: React.PropTypes.oneOfType([ + React.PropTypes.string, + React.PropTypes.element + ]).isRequired, columnName: React.PropTypes.string.isRequired, canBeOrdered: React.PropTypes.bool, changeOrder: React.PropTypes.func, diff --git a/js/stores/piece_list_store.js b/js/stores/piece_list_store.js index 7ca96c87..b70f8fc3 100644 --- a/js/stores/piece_list_store.js +++ b/js/stores/piece_list_store.js @@ -35,6 +35,7 @@ class PieceListStore { } } }); + console.log(this.pieceList, pieceId); } onUpdatePieceList({ page, pageSize, search, pieceList, orderBy, orderAsc, pieceListCount }) { diff --git a/js/utils/lang_utils.js b/js/utils/lang_utils.js index 7eb4b6f3..d1ea5fd5 100644 --- a/js/utils/lang_utils.js +++ b/js/utils/lang_utils.js @@ -11,7 +11,7 @@ import { formatText } from './general_utils'; export function getLangText(s, ...args) { let lang = navigator.language || navigator.userLanguage; // this is just for testing, as changing the navigator.language wasn't possible - lang = 'de'; + //lang = 'de'; try { if(lang in languages) { return formatText(languages[lang][s], args); From 0747c89a35811dc54d3f3cbb9b936d44ca4b0e42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Thu, 4 Jun 2015 10:25:31 +0200 Subject: [PATCH 06/21] documenting known issue with open/close state of edition list table --- js/stores/piece_list_store.js | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/js/stores/piece_list_store.js b/js/stores/piece_list_store.js index b70f8fc3..3b3fd94e 100644 --- a/js/stores/piece_list_store.js +++ b/js/stores/piece_list_store.js @@ -35,17 +35,31 @@ class PieceListStore { } } }); - console.log(this.pieceList, pieceId); } - + onUpdatePieceList({ page, pageSize, search, pieceList, orderBy, orderAsc, pieceListCount }) { this.page = page; this.pageSize = pageSize; this.search = search; this.orderAsc = orderAsc; this.orderBy = orderBy; - this.pieceList = pieceList; this.pieceListCount = pieceListCount; + + /** + * The piece list store currently stores the open/close state of a piece list item. + * + * Once a new page is requested, this.pieceList will be overwritten, which means that the + * open/close state of a specific list item will be thrown away. + * + * This means that when opening an editionListTable on a piece, and continuing + * clicking next or back in the pagination, the editionListTable will return to its + * default value, which is "close". + * + * We did not implement this, as we're going to add pagination to pieceList at some + * point anyway. Then, this problem is automatically resolved. + * + */ + this.pieceList = pieceList; } }; From 302f05b68eb29a5beec50bd97bed8104135b1407 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Thu, 4 Jun 2015 11:41:56 +0200 Subject: [PATCH 07/21] add link functionality --- .../accordion_list_item.js | 3 +++ .../accordion_list_item_table_editions.js | 12 +++++++--- .../ascribe_media/resource_viewer.js | 2 +- .../ascribe_table/table_item_wrapper.js | 24 +++++++++++++++++-- js/models/table_column_content_model.js | 3 ++- 5 files changed, 37 insertions(+), 7 deletions(-) diff --git a/js/components/ascribe_accordion_list/accordion_list_item.js b/js/components/ascribe_accordion_list/accordion_list_item.js index e9bb8742..c52f7e55 100644 --- a/js/components/ascribe_accordion_list/accordion_list_item.js +++ b/js/components/ascribe_accordion_list/accordion_list_item.js @@ -1,9 +1,12 @@ import React from 'react'; +import Router from 'react-router'; import AccordionListItemTable from './accordion_list_item_table'; import { getLangText } from '../../utils/lang_utils'; +let Link = Router.Link; + let AccordionListItem = React.createClass({ propTypes: { className: React.PropTypes.string, diff --git a/js/components/ascribe_accordion_list/accordion_list_item_table_editions.js b/js/components/ascribe_accordion_list/accordion_list_item_table_editions.js index 97bc7659..70391e2d 100644 --- a/js/components/ascribe_accordion_list/accordion_list_item_table_editions.js +++ b/js/components/ascribe_accordion_list/accordion_list_item_table_editions.js @@ -1,4 +1,5 @@ import React from 'react'; +import Router from 'react-router'; import EditionListStore from '../../stores/edition_list_store'; import EditionListActions from '../../actions/edition_list_actions'; @@ -18,6 +19,8 @@ import TableItemAclFiltered from '../ascribe_table/table_item_acl_filtered'; import { getLangText } from '../../utils/lang_utils'; +let Link = Router.Link; + let AccordionListItemTableEditions = React.createClass({ propTypes: { @@ -108,7 +111,8 @@ let AccordionListItemTableEditions = React.createClass({ '#', TableItemText, 1, - true + true, + {to: 'edition', paramsKey: 'editionId', contentKey: 'bitcoin_id'} ), new TableColumnContentModel( (item) => { @@ -119,7 +123,8 @@ let AccordionListItemTableEditions = React.createClass({ getLangText('Bitcoin Address'), TableItemText, 5, - true + true, + {to: 'edition', paramsKey: 'editionId', contentKey: 'bitcoin_id'} ), new TableColumnContentModel( (item) => { @@ -130,7 +135,8 @@ let AccordionListItemTableEditions = React.createClass({ getLangText('Actions'), TableItemAclFiltered, 4, - false + false, + {to: 'edition', paramsKey: 'editionId', contentKey: 'bitcoin_id'} ) ]; diff --git a/js/components/ascribe_media/resource_viewer.js b/js/components/ascribe_media/resource_viewer.js index 4519bcb7..519b6cec 100644 --- a/js/components/ascribe_media/resource_viewer.js +++ b/js/components/ascribe_media/resource_viewer.js @@ -25,7 +25,7 @@ let ResourceViewer = React.createClass({ mixins: [InjectInHeadMixin], componentDidMount() { - this.inject('http://antani.com'); + //this.inject('http://antani.com'); }, render() { diff --git a/js/components/ascribe_table/table_item_wrapper.js b/js/components/ascribe_table/table_item_wrapper.js index c6251c4b..a6ffa36b 100644 --- a/js/components/ascribe_table/table_item_wrapper.js +++ b/js/components/ascribe_table/table_item_wrapper.js @@ -1,16 +1,31 @@ import React from 'react'; +import Router from 'react-router'; import TableColumnContentModel from '../../models/table_column_content_model'; import TableColumnMixin from '../../mixins/table_column_mixin'; let TableItemWrapper = React.createClass({ - mixins: [TableColumnMixin], + mixins: [TableColumnMixin, Router.Navigation], propTypes: { columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(TableColumnContentModel)), columnContent: React.PropTypes.object, columnWidth: React.PropTypes.number.isRequired }, + /** + * If a link is defined in columnContent, then we can use + * Router.Navigation.transitionTo to redirect the user + * programmatically + */ + transition(column) { + if(column.link) { + let params = {}; + params[column.link.paramsKey] = this.props.columnContent[column.link.contentKey]; + + this.transitionTo(column.link.to, params); + } + }, + render() { return (
@@ -21,8 +36,13 @@ let TableItemWrapper = React.createClass({ let columnClass = this.calcColumnClasses(this.props.columnList, i, this.props.columnWidth); + let transition = this.transition.bind(this, column); + return ( -
+
); diff --git a/js/models/table_column_content_model.js b/js/models/table_column_content_model.js index 5e93cce4..ecaa0748 100644 --- a/js/models/table_column_content_model.js +++ b/js/models/table_column_content_model.js @@ -1,12 +1,13 @@ class TableColumnContentModel { // ToDo: Add validation for all passed-in parameters - constructor(transformFn, columnName, displayName, displayType, rowWidth, canBeOrdered) { + constructor(transformFn, columnName, displayName, displayType, rowWidth, canBeOrdered, link) { this.transformFn = transformFn; this.columnName = columnName; this.displayName = displayName; this.displayType = displayType; this.rowWidth = rowWidth; this.canBeOrdered = canBeOrdered; + this.link = link; } } From ccbf411168a198b01dcf7aa47a646ed747b4a62c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Thu, 4 Jun 2015 13:16:19 +0200 Subject: [PATCH 08/21] fixed store bindings --- js/app.js | 20 ++++++++++++++++++ .../piece_list_bulk_modal.js | 21 +++++++++---------- .../ascribe_table/table_item_wrapper.js | 1 - js/components/edition_container.js | 20 ++++++++++-------- js/components/header.js | 4 ++++ js/components/piece_list.js | 2 +- 6 files changed, 46 insertions(+), 22 deletions(-) diff --git a/js/app.js b/js/app.js index d37e1a62..30d2f486 100644 --- a/js/app.js +++ b/js/app.js @@ -14,6 +14,26 @@ import alt from './alt'; import fetch from './utils/fetch'; import AlertDismissable from './components/ascribe_forms/alert'; +/* + Taken from + http://stackoverflow.com/questions/30613447/how-to-debug-reactjss-setstate?noredirect=1#comment49301874_30613447 + + + +*/ + +var warn = console.warn; +console.warn = function(warning) { + if (/(setState)/.test(warning)) { + throw new Error(warning); + } + warn.apply(console, arguments); +}; + +/* + + + */ fetch.defaults({ urlMap: ApiUrls, 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 896882df..75695058 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 @@ -15,7 +15,10 @@ let PieceListBulkModal = React.createClass({ }, getInitialState() { - return EditionListStore.getState(); + return { + editions: EditionListStore.getState(), + user: UserStore.getState() + }; }, onChange(state) { @@ -37,9 +40,9 @@ let PieceListBulkModal = React.createClass({ let selectedEditionList = []; Object - .keys(this.state.editionList) + .keys(this.state.editions.editionList) .forEach((key) => { - let filteredEditionsForPiece = this.state.editionList[key].filter((edition) => edition.selected); + let filteredEditionsForPiece = this.state.editions.editionList[key].filter((edition) => edition.selected); selectedEditionList = selectedEditionList.concat(filteredEditionsForPiece); }); @@ -73,10 +76,6 @@ let PieceListBulkModal = React.createClass({ EditionListActions.clearAllEditionSelections(); }, - handleSuccess(){ - - }, - render() { let availableAcls = this.getAvailableAcls(); let selectedEditions = this.fetchSelectedEditionList(); @@ -104,25 +103,25 @@ let PieceListBulkModal = React.createClass({ availableAcls={availableAcls} action="transfer" editions={selectedEditions} - currentUser={this.state.currentUser} + currentUser={this.state.user.currentUser} handleSuccess={this.handleSuccess} />
diff --git a/js/components/ascribe_table/table_item_wrapper.js b/js/components/ascribe_table/table_item_wrapper.js index a6ffa36b..62778174 100644 --- a/js/components/ascribe_table/table_item_wrapper.js +++ b/js/components/ascribe_table/table_item_wrapper.js @@ -21,7 +21,6 @@ let TableItemWrapper = React.createClass({ if(column.link) { let params = {}; params[column.link.paramsKey] = this.props.columnContent[column.link.contentKey]; - this.transitionTo(column.link.to, params); } }, diff --git a/js/components/edition_container.js b/js/components/edition_container.js index 6887fd20..7b8b6151 100644 --- a/js/components/edition_container.js +++ b/js/components/edition_container.js @@ -11,10 +11,11 @@ import Edition from './edition'; * This is the component that implements resource/data specific functionality */ let EditionContainer = React.createClass({ - getInitialState() { - return {'user': UserStore.getState(), - 'edition': EditionStore.getState()} + return { + 'user': UserStore.getState(), + 'edition': EditionStore.getState() + }; }, onChange(state) { @@ -22,10 +23,11 @@ let EditionContainer = React.createClass({ }, componentDidMount() { - EditionActions.fetchOne(this.props.params.editionId); EditionStore.listen(this.onChange); - UserActions.fetchCurrentUser(); UserStore.listen(this.onChange); + + UserActions.fetchCurrentUser(); + EditionActions.fetchOne(this.props.params.editionId); }, componentDidUnmount() { EditionStore.unlisten(this.onChange); @@ -33,18 +35,18 @@ let EditionContainer = React.createClass({ }, render() { - if('title' in this.state.edition) { return ( - + + ); } else { return (

Loading

); } - - } }); diff --git a/js/components/header.js b/js/components/header.js index b7a412e0..1c0116db 100644 --- a/js/components/header.js +++ b/js/components/header.js @@ -26,6 +26,10 @@ let Header = React.createClass({ UserActions.fetchCurrentUser(); }, + componentDidUnmount() { + UserStore.unlisten(this.onChange); + }, + onChange(state) { this.setState(state); }, diff --git a/js/components/piece_list.js b/js/components/piece_list.js index e6735a27..9d6ad26e 100644 --- a/js/components/piece_list.js +++ b/js/components/piece_list.js @@ -26,7 +26,7 @@ let PieceList = React.createClass({ PieceListActions.fetchPieceList(page, this.state.pageSize, this.state.search, this.state.orderBy, this.state.orderAsc); }, - componentWillUnmount() { + componentDidUnmount() { PieceListStore.unlisten(this.onChange); }, From c19a05ca50f7661409e97f15bbd80a5acb9bd441 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Thu, 4 Jun 2015 13:17:59 +0200 Subject: [PATCH 09/21] fix setState bug by renaming componentDidUnmount to componentWillUnmount --- .../accordion_list_item_table_editions.js | 2 +- .../ascribe_piece_list_bulk_modal/piece_list_bulk_modal.js | 2 +- js/components/ascribe_piece_list_toolbar/piece_list_toolbar.js | 2 +- js/components/edition_container.js | 2 +- js/components/header.js | 2 +- js/components/piece_list.js | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/js/components/ascribe_accordion_list/accordion_list_item_table_editions.js b/js/components/ascribe_accordion_list/accordion_list_item_table_editions.js index 70391e2d..f40587cb 100644 --- a/js/components/ascribe_accordion_list/accordion_list_item_table_editions.js +++ b/js/components/ascribe_accordion_list/accordion_list_item_table_editions.js @@ -42,7 +42,7 @@ let AccordionListItemTableEditions = React.createClass({ EditionListStore.listen(this.onChange); }, - componentDidUnmount() { + componentWillUnmount() { EditionListStore.unlisten(this.onChange); }, 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 75695058..280af762 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 @@ -31,7 +31,7 @@ let PieceListBulkModal = React.createClass({ UserStore.listen(this.onChange); }, - componentDidUnmount() { + componentWillUnmount() { EditionListStore.unlisten(this.onChange); UserStore.unlisten(this.onChange); }, 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 ce9150b1..84681b55 100644 --- a/js/components/ascribe_piece_list_toolbar/piece_list_toolbar.js +++ b/js/components/ascribe_piece_list_toolbar/piece_list_toolbar.js @@ -22,7 +22,7 @@ let PieceListToolbar = React.createClass({ PieceListStore.listen(this.onChange); }, - componentDidUnmount() { + componentWillUnmount() { PieceListStore.unlisten(this.onChange); }, diff --git a/js/components/edition_container.js b/js/components/edition_container.js index 7b8b6151..8a2a8487 100644 --- a/js/components/edition_container.js +++ b/js/components/edition_container.js @@ -29,7 +29,7 @@ let EditionContainer = React.createClass({ UserActions.fetchCurrentUser(); EditionActions.fetchOne(this.props.params.editionId); }, - componentDidUnmount() { + componentWillUnmount() { EditionStore.unlisten(this.onChange); UserStore.unlisten(this.onChange); }, diff --git a/js/components/header.js b/js/components/header.js index 1c0116db..a53b628e 100644 --- a/js/components/header.js +++ b/js/components/header.js @@ -26,7 +26,7 @@ let Header = React.createClass({ UserActions.fetchCurrentUser(); }, - componentDidUnmount() { + componentWillUnmount() { UserStore.unlisten(this.onChange); }, diff --git a/js/components/piece_list.js b/js/components/piece_list.js index 9d6ad26e..e6735a27 100644 --- a/js/components/piece_list.js +++ b/js/components/piece_list.js @@ -26,7 +26,7 @@ let PieceList = React.createClass({ PieceListActions.fetchPieceList(page, this.state.pageSize, this.state.search, this.state.orderBy, this.state.orderAsc); }, - componentDidUnmount() { + componentWillUnmount() { PieceListStore.unlisten(this.onChange); }, From a93634f01017b908957c7382b3f4c207726faa06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Thu, 4 Jun 2015 13:48:07 +0200 Subject: [PATCH 10/21] add transition model and callback for closing the edition list of a piece after changing route --- js/actions/piece_list_actions.js | 3 +- .../accordion_list_item_table.js | 4 +-- .../accordion_list_item_table_editions.js | 18 +++++----- .../piece_list_bulk_modal.js | 4 +++ .../ascribe_table/models/table_models.js | 34 +++++++++++++++++++ js/components/ascribe_table/table.js | 4 +-- js/components/ascribe_table/table_header.js | 4 +-- js/components/ascribe_table/table_item.js | 4 +-- .../ascribe_table/table_item_selectable.js | 4 +-- .../ascribe_table/table_item_subtable.js | 10 +++--- .../ascribe_table/table_item_wrapper.js | 16 +++++---- js/models/table_column_content_model.js | 14 -------- js/stores/piece_list_store.js | 7 ++++ sass/main.scss | 4 +++ 14 files changed, 86 insertions(+), 44 deletions(-) create mode 100644 js/components/ascribe_table/models/table_models.js delete mode 100644 js/models/table_column_content_model.js diff --git a/js/actions/piece_list_actions.js b/js/actions/piece_list_actions.js index 0105ff06..1bb44c1f 100644 --- a/js/actions/piece_list_actions.js +++ b/js/actions/piece_list_actions.js @@ -7,7 +7,8 @@ class PieceListActions { constructor() { this.generateActions( 'updatePieceList', - 'showEditionList' + 'showEditionList', + 'closeAllEditionLists' ); } diff --git a/js/components/ascribe_accordion_list/accordion_list_item_table.js b/js/components/ascribe_accordion_list/accordion_list_item_table.js index 82b9a23a..fb8f85b2 100644 --- a/js/components/ascribe_accordion_list/accordion_list_item_table.js +++ b/js/components/ascribe_accordion_list/accordion_list_item_table.js @@ -3,7 +3,7 @@ import React from 'react'; import Table from '../ascribe_table/table'; import TableItem from '../ascribe_table/table_item'; -import TableColumnContentModel from '../../models/table_column_content_model'; +import { ColumnModel } from '../ascribe_table/models/table_models'; import { getLangText } from '../../utils/lang_utils'; @@ -12,7 +12,7 @@ let AccordionListItemTable = React.createClass({ className: React.PropTypes.string, parentId: React.PropTypes.number, itemList: React.PropTypes.array, - columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(TableColumnContentModel)), + columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(ColumnModel)), numOfTableItems: React.PropTypes.number, show: React.PropTypes.bool, changeOrder: React.PropTypes.func, diff --git a/js/components/ascribe_accordion_list/accordion_list_item_table_editions.js b/js/components/ascribe_accordion_list/accordion_list_item_table_editions.js index f40587cb..9edc4e8a 100644 --- a/js/components/ascribe_accordion_list/accordion_list_item_table_editions.js +++ b/js/components/ascribe_accordion_list/accordion_list_item_table_editions.js @@ -10,7 +10,7 @@ import AccordionListItemTable from './accordion_list_item_table'; import AccordionListItemTableToggle from './accordion_list_item_table_toggle'; import AccordionListItemTableSelectAllEditionsToggle from './accordion_list_item_table_select_all_editions_toggle'; -import TableColumnContentModel from '../../models/table_column_content_model'; +import { ColumnModel, TransitionModel } from '../ascribe_table/models/table_models'; import TableItemImg from '../ascribe_table/table_item_img'; import TableItemText from '../ascribe_table/table_item_text'; @@ -84,8 +84,10 @@ let AccordionListItemTableEditions = React.createClass({ allEditionsCount = this.state.editionList[this.props.parentId].length; } + let transition = new TransitionModel('edition', 'editionId', 'bitcoin_id', PieceListActions.closeAllEditionLists); + let columnList = [ - new TableColumnContentModel( + new ColumnModel( (item) => { return { 'editionId': item.id, @@ -102,7 +104,7 @@ let AccordionListItemTableEditions = React.createClass({ 1, false ), - new TableColumnContentModel( + new ColumnModel( (item) => { return { 'content': item.edition_number @@ -112,9 +114,9 @@ let AccordionListItemTableEditions = React.createClass({ TableItemText, 1, true, - {to: 'edition', paramsKey: 'editionId', contentKey: 'bitcoin_id'} + transition ), - new TableColumnContentModel( + new ColumnModel( (item) => { return { 'content': item.bitcoin_id @@ -124,9 +126,9 @@ let AccordionListItemTableEditions = React.createClass({ TableItemText, 5, true, - {to: 'edition', paramsKey: 'editionId', contentKey: 'bitcoin_id'} + transition ), - new TableColumnContentModel( + new ColumnModel( (item) => { return { 'content': item.acl @@ -136,7 +138,7 @@ let AccordionListItemTableEditions = React.createClass({ TableItemAclFiltered, 4, false, - {to: 'edition', paramsKey: 'editionId', contentKey: 'bitcoin_id'} + transition ) ]; 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 280af762..4d4a5e2d 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 @@ -76,6 +76,10 @@ let PieceListBulkModal = React.createClass({ EditionListActions.clearAllEditionSelections(); }, + handleSuccess() { + + }, + render() { let availableAcls = this.getAvailableAcls(); let selectedEditions = this.fetchSelectedEditionList(); diff --git a/js/components/ascribe_table/models/table_models.js b/js/components/ascribe_table/models/table_models.js new file mode 100644 index 00000000..8bf57358 --- /dev/null +++ b/js/components/ascribe_table/models/table_models.js @@ -0,0 +1,34 @@ +export class ColumnModel { + // ToDo: Add validation for all passed-in parameters + constructor(transformFn, columnName, displayName, displayType, rowWidth, canBeOrdered, transition) { + this.transformFn = transformFn; + this.columnName = columnName; + this.displayName = displayName; + this.displayType = displayType; + this.rowWidth = rowWidth; + this.canBeOrdered = canBeOrdered; + this.transition = transition; + } +} + +/** + * If a user opens an editionList of a piece and clicks on a specific edition to go to the + * piece detail page, all previously opened editionLists are still saved as show = true in the + * pieceList store. + * + * So if the user now comes back to this view the old data will still be in this store, + * since the browser wasn't able to load the new data (only containing show = undefined = false). + * + * This means that without closing all pieces after a transition, we'll get this flickering of editionLists. + * + * Since react-router does not implement a callback function for its transitionTo method, we have to do it + * our selfes, using this TransitionModel. + */ +export class TransitionModel { + constructor(to, queryKey, valueKey, callback) { + this.to = to; + this.queryKey = queryKey; + this.valueKey = valueKey; + this.callback = callback; + } +} \ No newline at end of file diff --git a/js/components/ascribe_table/table.js b/js/components/ascribe_table/table.js index 9339a00a..08e4e642 100644 --- a/js/components/ascribe_table/table.js +++ b/js/components/ascribe_table/table.js @@ -2,13 +2,13 @@ import React from 'react'; import ReactAddons from 'react/addons'; import TableHeader from './table_header'; -import TableColumnContentModel from '../../models/table_column_content_model'; +import { ColumnModel } from './models/table_models'; let Table = React.createClass({ propTypes: { - columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(TableColumnContentModel)), + columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(ColumnModel)), changeOrder: React.PropTypes.func, orderBy: React.PropTypes.string, orderAsc: React.PropTypes.bool, diff --git a/js/components/ascribe_table/table_header.js b/js/components/ascribe_table/table_header.js index 44594394..00521a40 100644 --- a/js/components/ascribe_table/table_header.js +++ b/js/components/ascribe_table/table_header.js @@ -3,13 +3,13 @@ import React from 'react'; import TableColumnMixin from '../../mixins/table_column_mixin'; import TableHeaderItem from './table_header_item'; -import TableColumnContentModel from '../../models/table_column_content_model'; +import { ColumnModel } from './models/table_models'; let TableHeader = React.createClass({ mixins: [TableColumnMixin], propTypes: { - columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(TableColumnContentModel)), + columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(ColumnModel)), itemList: React.PropTypes.array.isRequired, changeOrder: React.PropTypes.func, orderAsc: React.PropTypes.bool, diff --git a/js/components/ascribe_table/table_item.js b/js/components/ascribe_table/table_item.js index dffb7fa9..0357b86b 100644 --- a/js/components/ascribe_table/table_item.js +++ b/js/components/ascribe_table/table_item.js @@ -1,6 +1,6 @@ import React from 'react'; -import TableColumnContentModel from '../../models/table_column_content_model'; +import { ColumnModel } from './models/table_models'; import TableItemWrapper from './table_item_wrapper'; @@ -8,7 +8,7 @@ import TableItemWrapper from './table_item_wrapper'; let TableItem = React.createClass({ propTypes: { - columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(TableColumnContentModel)), + columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(ColumnModel)), columnContent: React.PropTypes.object, onClick: React.PropTypes.func, // See: https://facebook.github.io/react/tips/expose-component-functions.html className: React.PropTypes.string diff --git a/js/components/ascribe_table/table_item_selectable.js b/js/components/ascribe_table/table_item_selectable.js index 711e42b6..f151373e 100644 --- a/js/components/ascribe_table/table_item_selectable.js +++ b/js/components/ascribe_table/table_item_selectable.js @@ -1,7 +1,7 @@ import React from 'react'; import classNames from 'classnames'; -import TableColumnContentModel from '../../models/table_column_content_model'; +import { ColumnModel } from './models/table_models'; import TableItem from './table_item'; @@ -9,7 +9,7 @@ import TableItem from './table_item'; let TableItemSelectable = React.createClass({ propTypes: { - columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(TableColumnContentModel)), + columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(ColumnModel)), columnContent: React.PropTypes.object, parentId: React.PropTypes.number, className: React.PropTypes.string diff --git a/js/components/ascribe_table/table_item_subtable.js b/js/components/ascribe_table/table_item_subtable.js index dcd3da0f..231bb74b 100644 --- a/js/components/ascribe_table/table_item_subtable.js +++ b/js/components/ascribe_table/table_item_subtable.js @@ -1,6 +1,6 @@ import React from 'react'; -import TableColumnContentModel from '../../models/table_column_content_model'; +import { ColumnModel } from './models/table_models'; import EditionListStore from '../../stores/edition_list_store'; import EditionListActions from '../../actions/edition_list_actions'; @@ -16,7 +16,7 @@ import TableItemSubtableButton from './table_item_subtable_button'; let TableItemSubtable = React.createClass({ propTypes: { - columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(TableColumnContentModel)), + columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(ColumnModel)), columnContent: React.PropTypes.object }, @@ -61,9 +61,9 @@ let TableItemSubtable = React.createClass({ let renderEditionListTable = () => { let columnList = [ - new TableColumnContentModel('edition_number', 'Number', TableItemText, 2, false), - new TableColumnContentModel('user_registered', 'User', TableItemText, 4, true), - new TableColumnContentModel('acl', 'Actions', TableItemAcl, 4, true) + new ColumnModel('edition_number', 'Number', TableItemText, 2, false), + new ColumnModel('user_registered', 'User', TableItemText, 4, true), + new ColumnModel('acl', 'Actions', TableItemAcl, 4, true) ]; if(this.state.open && this.state.editionList[this.props.columnContent.id] && this.state.editionList[this.props.columnContent.id].length) { diff --git a/js/components/ascribe_table/table_item_wrapper.js b/js/components/ascribe_table/table_item_wrapper.js index 62778174..33e72c67 100644 --- a/js/components/ascribe_table/table_item_wrapper.js +++ b/js/components/ascribe_table/table_item_wrapper.js @@ -1,27 +1,31 @@ import React from 'react'; import Router from 'react-router'; -import TableColumnContentModel from '../../models/table_column_content_model'; +import { ColumnModel } from './models/table_models'; import TableColumnMixin from '../../mixins/table_column_mixin'; let TableItemWrapper = React.createClass({ mixins: [TableColumnMixin, Router.Navigation], propTypes: { - columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(TableColumnContentModel)), + columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(ColumnModel)), columnContent: React.PropTypes.object, columnWidth: React.PropTypes.number.isRequired }, /** - * If a link is defined in columnContent, then we can use + * If a transition is defined in columnContent, then we can use * Router.Navigation.transitionTo to redirect the user * programmatically */ transition(column) { - if(column.link) { + if(column.transition) { let params = {}; - params[column.link.paramsKey] = this.props.columnContent[column.link.contentKey]; - this.transitionTo(column.link.to, params); + params[column.transition.queryKey] = this.props.columnContent[column.transition.valueKey]; + this.transitionTo(column.transition.to, params); + + if(column.transition.callback) { + column.transition.callback(); + } } }, diff --git a/js/models/table_column_content_model.js b/js/models/table_column_content_model.js deleted file mode 100644 index ecaa0748..00000000 --- a/js/models/table_column_content_model.js +++ /dev/null @@ -1,14 +0,0 @@ -class TableColumnContentModel { - // ToDo: Add validation for all passed-in parameters - constructor(transformFn, columnName, displayName, displayType, rowWidth, canBeOrdered, link) { - this.transformFn = transformFn; - this.columnName = columnName; - this.displayName = displayName; - this.displayType = displayType; - this.rowWidth = rowWidth; - this.canBeOrdered = canBeOrdered; - this.link = link; - } -} - -export default TableColumnContentModel; \ No newline at end of file diff --git a/js/stores/piece_list_store.js b/js/stores/piece_list_store.js index 3b3fd94e..bc1c0e5b 100644 --- a/js/stores/piece_list_store.js +++ b/js/stores/piece_list_store.js @@ -36,6 +36,13 @@ class PieceListStore { } }); } + + onCloseAllEditionLists() { + this.pieceList + .forEach((piece) => { + piece.show = false; + }); + } onUpdatePieceList({ page, pageSize, search, pieceList, orderBy, orderAsc, pieceListCount }) { this.page = page; diff --git a/sass/main.scss b/sass/main.scss index 2fe60cac..cc7ae4e3 100644 --- a/sass/main.scss +++ b/sass/main.scss @@ -73,6 +73,10 @@ font-family: 'Source Sans Pro'; font-size: .8em; height:3em; + + &:not(:first-child) { + cursor: pointer; + } } .ascribe-table-item-column > * { From 1230ae7192077ef709bca47fbf61ab23353eccca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Thu, 4 Jun 2015 15:30:21 +0200 Subject: [PATCH 11/21] add handle success functionality to piece list and implement onject merger for components with multiple stores --- .../piece_list_bulk_modal.js | 37 +++++++++++++------ js/stores/piece_list_store.js | 7 +++- js/utils/general_utils.js | 30 +++++++++++++++ 3 files changed, 61 insertions(+), 13 deletions(-) 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 4d4a5e2d..ca6d03cb 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 @@ -1,5 +1,7 @@ import React from 'react'; +import { mergeOptionList } from '../../utils/general_utils'; + import EditionListStore from '../../stores/edition_list_store'; import EditionListActions from '../../actions/edition_list_actions'; @@ -15,10 +17,7 @@ let PieceListBulkModal = React.createClass({ }, getInitialState() { - return { - editions: EditionListStore.getState(), - user: UserStore.getState() - }; + return mergeOptionList([EditionListStore.getState(), UserStore.getState()]); }, onChange(state) { @@ -26,9 +25,9 @@ let PieceListBulkModal = React.createClass({ }, componentDidMount() { - UserActions.fetchCurrentUser(); EditionListStore.listen(this.onChange); UserStore.listen(this.onChange); + UserActions.fetchCurrentUser(); }, componentWillUnmount() { @@ -36,13 +35,22 @@ let PieceListBulkModal = React.createClass({ UserStore.unlisten(this.onChange); }, + fetchSelectedPieceEditionList() { + let filteredPieceIdList = Object.keys(this.state.editionList) + .filter((pieceId) => { + return this.state.editions.editionList[pieceId] + .filter((edition) => edition.selected).length > 0; + }); + return filteredPieceIdList; + }, + fetchSelectedEditionList() { let selectedEditionList = []; Object - .keys(this.state.editions.editionList) - .forEach((key) => { - let filteredEditionsForPiece = this.state.editions.editionList[key].filter((edition) => edition.selected); + .keys(this.state.editionList) + .forEach((pieceId) => { + let filteredEditionsForPiece = this.state.editionList[pieceId].filter((edition) => edition.selected); selectedEditionList = selectedEditionList.concat(filteredEditionsForPiece); }); @@ -77,7 +85,12 @@ let PieceListBulkModal = React.createClass({ }, handleSuccess() { + this.fetchSelectedPieceEditionList() + .forEach((pieceId) => { + EditionListActions.fetchEditionList(pieceId, this.state.orderBy, this.state.orderAsc); + }); + EditionListActions.clearAllEditionSelections(); }, render() { @@ -107,25 +120,25 @@ let PieceListBulkModal = React.createClass({ availableAcls={availableAcls} action="transfer" editions={selectedEditions} - currentUser={this.state.user.currentUser} + currentUser={this.state.currentUser} handleSuccess={this.handleSuccess} />
diff --git a/js/stores/piece_list_store.js b/js/stores/piece_list_store.js index bc1c0e5b..493ebfc4 100644 --- a/js/stores/piece_list_store.js +++ b/js/stores/piece_list_store.js @@ -1,4 +1,6 @@ +import React from 'react'; import alt from '../alt'; + import PieceListActions from '../actions/piece_list_actions'; @@ -53,6 +55,10 @@ class PieceListStore { this.pieceListCount = pieceListCount; /** + * Pagination - Known Issue: + * ######################### + * + * * The piece list store currently stores the open/close state of a piece list item. * * Once a new page is requested, this.pieceList will be overwritten, which means that the @@ -64,7 +70,6 @@ class PieceListStore { * * We did not implement this, as we're going to add pagination to pieceList at some * point anyway. Then, this problem is automatically resolved. - * */ this.pieceList = pieceList; } diff --git a/js/utils/general_utils.js b/js/utils/general_utils.js index 96f56c1e..9400ebfb 100644 --- a/js/utils/general_utils.js +++ b/js/utils/general_utils.js @@ -61,3 +61,33 @@ export function formatText() { return val; }); }; + +/** + * Takes a list of object and merges their keys to one object. + * Uses mergeOptions for two objects. + * @param {[type]} l [description] + * @return {[type]} [description] + */ +export function mergeOptionList(l) { + let newObj = {}; + + for(let i = 1; i < l.length; i++) { + newObj = mergeOptions(newObj, mergeOptions(l[i-1], l[i])); + } + + return newObj; +}; + +/** + * Overwrites obj1's values with obj2's and adds obj2's if non existent in obj1 + * @param obj1 + * @param obj2 + * @returns obj3 a new object based on obj1 and obj2 + * Taken from: http://stackoverflow.com/a/171256/1263876 + */ +function mergeOptions(obj1,obj2){ + var obj3 = {}; + for (var attrname in obj1) { obj3[attrname] = obj1[attrname]; } + for (var attrname in obj2) { obj3[attrname] = obj2[attrname]; } + return obj3; +}; From 8a3ff445ef0c5f63ae27604e420e0f15a79a2cab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Thu, 4 Jun 2015 15:33:59 +0200 Subject: [PATCH 12/21] use mergeOptionsList on all react components --- js/components/edition_container.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/js/components/edition_container.js b/js/components/edition_container.js index 8a2a8487..551b8686 100644 --- a/js/components/edition_container.js +++ b/js/components/edition_container.js @@ -1,5 +1,7 @@ import React from 'react'; +import { mergeOptionList } from '../utils/general_utils'; + import EditionActions from '../actions/edition_actions'; import EditionStore from '../stores/edition_store'; import UserActions from '../actions/user_actions'; @@ -12,10 +14,7 @@ import Edition from './edition'; */ let EditionContainer = React.createClass({ getInitialState() { - return { - 'user': UserStore.getState(), - 'edition': EditionStore.getState() - }; + return mergeOptionList([UserStore.getState(), EditionStore.getState()]); }, onChange(state) { From 6da18e9a8515bec5c73fc8d0b3e4e03e8eca91ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Thu, 4 Jun 2015 15:38:15 +0200 Subject: [PATCH 13/21] rename mergeOptions --- .../ascribe_piece_list_bulk_modal/piece_list_bulk_modal.js | 4 ++-- js/components/edition_container.js | 4 ++-- js/utils/general_utils.js | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) 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 ca6d03cb..c2ccfbc1 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 @@ -1,6 +1,6 @@ import React from 'react'; -import { mergeOptionList } from '../../utils/general_utils'; +import { mergeOptions } from '../../utils/general_utils'; import EditionListStore from '../../stores/edition_list_store'; import EditionListActions from '../../actions/edition_list_actions'; @@ -17,7 +17,7 @@ let PieceListBulkModal = React.createClass({ }, getInitialState() { - return mergeOptionList([EditionListStore.getState(), UserStore.getState()]); + return mergeOptions(EditionListStore.getState(), UserStore.getState()); }, onChange(state) { diff --git a/js/components/edition_container.js b/js/components/edition_container.js index 551b8686..ca56bda7 100644 --- a/js/components/edition_container.js +++ b/js/components/edition_container.js @@ -1,6 +1,6 @@ import React from 'react'; -import { mergeOptionList } from '../utils/general_utils'; +import { mergeOptions } from '../utils/general_utils'; import EditionActions from '../actions/edition_actions'; import EditionStore from '../stores/edition_store'; @@ -14,7 +14,7 @@ import Edition from './edition'; */ let EditionContainer = React.createClass({ getInitialState() { - return mergeOptionList([UserStore.getState(), EditionStore.getState()]); + return mergeOptions(UserStore.getState(), EditionStore.getState()); }, onChange(state) { diff --git a/js/utils/general_utils.js b/js/utils/general_utils.js index 9400ebfb..2eedc1af 100644 --- a/js/utils/general_utils.js +++ b/js/utils/general_utils.js @@ -68,11 +68,11 @@ export function formatText() { * @param {[type]} l [description] * @return {[type]} [description] */ -export function mergeOptionList(l) { +export function mergeOptions(...l) { let newObj = {}; for(let i = 1; i < l.length; i++) { - newObj = mergeOptions(newObj, mergeOptions(l[i-1], l[i])); + newObj = _mergeOptions(newObj, _mergeOptions(l[i-1], l[i])); } return newObj; @@ -85,7 +85,7 @@ export function mergeOptionList(l) { * @returns obj3 a new object based on obj1 and obj2 * Taken from: http://stackoverflow.com/a/171256/1263876 */ -function mergeOptions(obj1,obj2){ +function _mergeOptions(obj1,obj2){ var obj3 = {}; for (var attrname in obj1) { obj3[attrname] = obj1[attrname]; } for (var attrname in obj2) { obj3[attrname] = obj2[attrname]; } From 4fd5cdcdb52c0f13a6c6bda7151661e70fc77a21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Thu, 4 Jun 2015 16:07:37 +0200 Subject: [PATCH 14/21] add real href to edition list --- .../ascribe_table/models/table_models.js | 11 ++++ .../ascribe_table/table_item_wrapper.js | 55 ++++++++++--------- sass/main.scss | 4 -- 3 files changed, 40 insertions(+), 30 deletions(-) diff --git a/js/components/ascribe_table/models/table_models.js b/js/components/ascribe_table/models/table_models.js index 8bf57358..245a2310 100644 --- a/js/components/ascribe_table/models/table_models.js +++ b/js/components/ascribe_table/models/table_models.js @@ -31,4 +31,15 @@ export class TransitionModel { this.valueKey = valueKey; this.callback = callback; } + + toReactRouterLinkProps(queryValue) { + let props = { + to: this.to, + params: {} + }; + + props.params[this.queryKey] = queryValue; + + return props; + } } \ No newline at end of file diff --git a/js/components/ascribe_table/table_item_wrapper.js b/js/components/ascribe_table/table_item_wrapper.js index 33e72c67..7f503c88 100644 --- a/js/components/ascribe_table/table_item_wrapper.js +++ b/js/components/ascribe_table/table_item_wrapper.js @@ -4,6 +4,8 @@ import Router from 'react-router'; import { ColumnModel } from './models/table_models'; import TableColumnMixin from '../../mixins/table_column_mixin'; +let Link = Router.Link; + let TableItemWrapper = React.createClass({ mixins: [TableColumnMixin, Router.Navigation], propTypes: { @@ -12,23 +14,6 @@ let TableItemWrapper = React.createClass({ columnWidth: React.PropTypes.number.isRequired }, - /** - * If a transition is defined in columnContent, then we can use - * Router.Navigation.transitionTo to redirect the user - * programmatically - */ - transition(column) { - if(column.transition) { - let params = {}; - params[column.transition.queryKey] = this.props.columnContent[column.transition.valueKey]; - this.transitionTo(column.transition.to, params); - - if(column.transition.callback) { - column.transition.callback(); - } - } - }, - render() { return (
@@ -39,17 +24,35 @@ let TableItemWrapper = React.createClass({ let columnClass = this.calcColumnClasses(this.props.columnList, i, this.props.columnWidth); - let transition = this.transition.bind(this, column); + // + - return ( -
- -
- ); + if(!column.transition) { + return ( +
+ +
+ ); + } else { + let linkProps = column.transition.toReactRouterLinkProps(this.props.columnContent[column.transition.valueKey]); + /** + * If a transition is defined in columnContent, then we can use + * Router.Navigation.transitionTo to redirect the user + * programmatically + */ + return ( + + + + ); + } })}
); diff --git a/sass/main.scss b/sass/main.scss index cc7ae4e3..2fe60cac 100644 --- a/sass/main.scss +++ b/sass/main.scss @@ -73,10 +73,6 @@ font-family: 'Source Sans Pro'; font-size: .8em; height:3em; - - &:not(:first-child) { - cursor: pointer; - } } .ascribe-table-item-column > * { From eaefd253d556c0a858ea5993e40eb358981e247a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Thu, 4 Jun 2015 16:13:10 +0200 Subject: [PATCH 15/21] fixing AD-393 --- sass/ascribe_piece_list_bulk_modal.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sass/ascribe_piece_list_bulk_modal.scss b/sass/ascribe_piece_list_bulk_modal.scss index 4a6b98d7..d2c72113 100644 --- a/sass/ascribe_piece_list_bulk_modal.scss +++ b/sass/ascribe_piece_list_bulk_modal.scss @@ -11,7 +11,7 @@ border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; border-bottom: 0.2em solid #E0E0E0; - z-index:9999; + z-index:1000; } .piece-list-bulk-modal-clear-all { From 6aa74d6b423965efce4721f856adad2e254f72f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Thu, 4 Jun 2015 16:41:14 +0200 Subject: [PATCH 16/21] fix separation of orderings in edtionLists --- js/actions/edition_list_actions.js | 5 +++++ .../accordion_list_item_table_editions.js | 10 +++++++--- js/stores/edition_list_store.js | 13 +++++++++---- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/js/actions/edition_list_actions.js b/js/actions/edition_list_actions.js index f07d7d18..e967793c 100644 --- a/js/actions/edition_list_actions.js +++ b/js/actions/edition_list_actions.js @@ -12,6 +12,11 @@ class EditionListActions { } fetchEditionList(pieceId, orderBy, orderAsc) { + if(!orderBy && typeof orderAsc == "undefined") { + orderBy = 'edition_number'; + orderAsc = true; + } + EditionListFetcher .fetch(pieceId, orderBy, orderAsc) .then((res) => { diff --git a/js/components/ascribe_accordion_list/accordion_list_item_table_editions.js b/js/components/ascribe_accordion_list/accordion_list_item_table_editions.js index 9edc4e8a..3e81574a 100644 --- a/js/components/ascribe_accordion_list/accordion_list_item_table_editions.js +++ b/js/components/ascribe_accordion_list/accordion_list_item_table_editions.js @@ -65,7 +65,7 @@ let AccordionListItemTableEditions = React.createClass({ toggleTable() { PieceListActions.showEditionList(this.props.parentId); - EditionListActions.fetchEditionList(this.props.parentId, this.state.orderBy, this.state.orderAsc); + EditionListActions.fetchEditionList(this.props.parentId); }, changeEditionListOrder(orderBy, orderAsc) { @@ -75,6 +75,8 @@ let AccordionListItemTableEditions = React.createClass({ render() { let selectedEditionsCount = 0; let allEditionsCount = 0; + let orderBy; + let orderAsc; // here we need to check if all editions of a specific // piece are already defined. Otherwise .length will throw an error and we'll not @@ -82,6 +84,8 @@ let AccordionListItemTableEditions = React.createClass({ if(this.state.editionList[this.props.parentId]) { selectedEditionsCount = this.filterSelectedEditions().length; allEditionsCount = this.state.editionList[this.props.parentId].length; + orderBy = this.state.editionList[this.props.parentId].orderBy + orderAsc = this.state.editionList[this.props.parentId].orderAsc; } let transition = new TransitionModel('edition', 'editionId', 'bitcoin_id', PieceListActions.closeAllEditionLists); @@ -151,8 +155,8 @@ let AccordionListItemTableEditions = React.createClass({ columnList={columnList} numOfTableItems={this.props.numOfEditions} show={this.props.show} - orderBy={this.state.orderBy} - orderAsc={this.state.orderAsc} + orderBy={orderBy} + orderAsc={orderAsc} changeOrder={this.changeEditionListOrder}> Date: Thu, 4 Jun 2015 17:21:38 +0200 Subject: [PATCH 17/21] refactor table to bootstrap table --- .../accordion_list_item.js | 4 +-- .../accordion_list_item_table.js | 11 ++++---- js/components/ascribe_table/table.js | 9 +++--- js/components/ascribe_table/table_header.js | 8 +++--- .../ascribe_table/table_header_item.js | 16 +++++------ js/components/ascribe_table/table_item.js | 16 ++++------- .../ascribe_table/table_item_wrapper.js | 28 +++++++++---------- sass/ascribe_accordion_list.scss | 2 +- sass/main.scss | 21 ++------------ 9 files changed, 47 insertions(+), 68 deletions(-) diff --git a/js/components/ascribe_accordion_list/accordion_list_item.js b/js/components/ascribe_accordion_list/accordion_list_item.js index d749b890..9828ea30 100644 --- a/js/components/ascribe_accordion_list/accordion_list_item.js +++ b/js/components/ascribe_accordion_list/accordion_list_item.js @@ -18,10 +18,10 @@ let AccordionListItem = React.createClass({
-
+
-
+

{this.props.content.title}

{getLangText('by %s', this.props.content.artist_name)}

{this.props.content.date_created.split('-')[0]}

diff --git a/js/components/ascribe_accordion_list/accordion_list_item_table.js b/js/components/ascribe_accordion_list/accordion_list_item_table.js index fb8f85b2..5e22bf05 100644 --- a/js/components/ascribe_accordion_list/accordion_list_item_table.js +++ b/js/components/ascribe_accordion_list/accordion_list_item_table.js @@ -25,11 +25,12 @@ let AccordionListItemTable = React.createClass({ return (
+ className="ascribe-table" + columnList={this.props.columnList} + itemList={this.props.itemList} + changeOrder={this.props.changeOrder} + orderBy={this.props.orderBy} + orderAsc={this.props.orderAsc}> {this.props.itemList.map((item, i) => { return ( +
-
+
{this.renderChildren()} - - + +
); } }); diff --git a/js/components/ascribe_table/table_header.js b/js/components/ascribe_table/table_header.js index 00521a40..3892dffa 100644 --- a/js/components/ascribe_table/table_header.js +++ b/js/components/ascribe_table/table_header.js @@ -18,8 +18,8 @@ let TableHeader = React.createClass({ render() { return ( -
-
+ + {this.props.columnList.map((val, i) => { let columnClasses = this.calcColumnClasses(this.props.columnList, i, 12); @@ -39,8 +39,8 @@ let TableHeader = React.createClass({ ); })} -
-
+ + ); } diff --git a/js/components/ascribe_table/table_header_item.js b/js/components/ascribe_table/table_header_item.js index 598edada..d55347a6 100644 --- a/js/components/ascribe_table/table_header_item.js +++ b/js/components/ascribe_table/table_header_item.js @@ -25,28 +25,28 @@ let TableHeaderItem = React.createClass({ if(this.props.canBeOrdered && this.props.changeOrder && this.props.orderAsc != null && this.props.orderBy) { if(this.props.columnName === this.props.orderBy) { return ( -
{this.props.displayName} -
+ ); } else { return ( -
{this.props.displayName} -
+ ); } } else { return ( -
+ {this.props.displayName} -
+ ); } } diff --git a/js/components/ascribe_table/table_item.js b/js/components/ascribe_table/table_item.js index 0357b86b..f96839c4 100644 --- a/js/components/ascribe_table/table_item.js +++ b/js/components/ascribe_table/table_item.js @@ -10,22 +10,16 @@ let TableItem = React.createClass({ propTypes: { columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(ColumnModel)), columnContent: React.PropTypes.object, - onClick: React.PropTypes.func, // See: https://facebook.github.io/react/tips/expose-component-functions.html className: React.PropTypes.string }, render() { return ( -
-
- - -
-
+ + ); } }); diff --git a/js/components/ascribe_table/table_item_wrapper.js b/js/components/ascribe_table/table_item_wrapper.js index 7f503c88..f052084e 100644 --- a/js/components/ascribe_table/table_item_wrapper.js +++ b/js/components/ascribe_table/table_item_wrapper.js @@ -16,7 +16,7 @@ let TableItemWrapper = React.createClass({ render() { return ( -
+ {this.props.columnList.map((column, i) => { let TypeElement = column.displayType; @@ -24,16 +24,13 @@ let TableItemWrapper = React.createClass({ let columnClass = this.calcColumnClasses(this.props.columnList, i, this.props.columnWidth); - // - - if(!column.transition) { return ( -
-
+ ); } else { @@ -44,17 +41,18 @@ let TableItemWrapper = React.createClass({ * programmatically */ return ( - - - + + + + + ); } })} -
+ ); } }); diff --git a/sass/ascribe_accordion_list.scss b/sass/ascribe_accordion_list.scss index fefba59c..21236488 100644 --- a/sass/ascribe_accordion_list.scss +++ b/sass/ascribe_accordion_list.scss @@ -1,4 +1,4 @@ -$ascribe-accordion-list-item-height: 9em; +$ascribe-accordion-list-item-height: 8em; $ascribe-accordion-list-font: 'Source Sans Pro'; .ascribe-accordion-list-item { diff --git a/sass/main.scss b/sass/main.scss index 2fe60cac..1ff12fc5 100644 --- a/sass/main.scss +++ b/sass/main.scss @@ -37,15 +37,8 @@ float: none; } -.ascribe-table-header-row { - border-bottom: 2px solid #E0E0E0; - padding: 0; -} - -.ascribe-table-header-column { - display: table; - height:3em; - padding: 0; +.ascribe-table { + margin-bottom:0; } .ascribe-table-header-column > span { @@ -59,14 +52,6 @@ .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; -}*/ .ascribe-table-item-column { display: table; @@ -78,9 +63,9 @@ .ascribe-table-item-column > * { display: table-cell; vertical-align: middle; - text-overflow: ellipsis; white-space: nowrap; overflow: hidden; + text-overflow: ellipsis; } .ascribe-table-item-selected { From c177b95f45430a4b71dca3abee3cb43305a5cfd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Thu, 4 Jun 2015 17:28:14 +0200 Subject: [PATCH 18/21] responsive table --- js/components/piece_list.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/components/piece_list.js b/js/components/piece_list.js index e6735a27..22a115e1 100644 --- a/js/components/piece_list.js +++ b/js/components/piece_list.js @@ -69,7 +69,7 @@ let PieceList = React.createClass({ content={item} key={i}> From ae4428795d11ea055fa729a46b910680b790e669 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Fri, 5 Jun 2015 09:17:41 +0200 Subject: [PATCH 19/21] integrate es6lint --- .eslintrc | 37 +++++++++++++++++++++++++++++++++++++ gulpfile.js | 16 +++++++++++++++- package.json | 8 +++++++- 3 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 .eslintrc diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 00000000..4d0cfbed --- /dev/null +++ b/.eslintrc @@ -0,0 +1,37 @@ +{ + "parser": "babel-eslint", + "env": { + "browser": true, + "es6": true + }, + "rules": { + "quotes": [2, "single"], + "eol-last": [0], + "no-mixed-requires": [0], + "no-underscore-dangle": [0], + "react/display-name": 1, + "react/jsx-boolean-value": 1, + "react/jsx-no-undef": 1, + "react/jsx-quotes": 1, + "react/jsx-sort-prop-types": 1, + "react/jsx-sort-props": 1, + "react/jsx-uses-react": 1, + "react/jsx-uses-vars": 1, + "react/no-did-mount-set-state": 1, + "react/no-did-update-set-state": 1, + "react/no-multi-comp": 1, + "react/no-unknown-property": 1, + "react/prop-types": 1, + "react/react-in-jsx-scope": 1, + "react/self-closing-comp": 1, + "react/sort-comp": 1, + "react/wrap-multilines": 1 + }, + "plugins": [ + "react" + ], + "ecmaFeatures": { + "jsx": true, + "modules": true + } +} \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js index a685ea56..1790e3ff 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -12,6 +12,7 @@ var notify = require('gulp-notify'); var sass = require('gulp-sass'); var concat = require('gulp-concat'); var _ = require('lodash'); +var eslint = require('gulp-eslint'); var config = { bootstrapDir: './node_modules/bootstrap-sass' @@ -21,7 +22,7 @@ gulp.task('build', function() { bundle(false); }); -gulp.task('serve', ['browser-sync', 'sass', 'sass:watch', 'copy'], function() { +gulp.task('serve', ['browser-sync', 'sass', 'sass:watch', 'copy', 'lint'], function() { bundle(true); }); @@ -64,6 +65,19 @@ gulp.task('copy', function () { .pipe(gulp.dest('./build/fonts')); }); +gulp.task('lint', function () { + return gulp.src(['js/**/*.js']) + // eslint() attaches the lint output to the eslint property + // of the file object so it can be used by other modules. + .pipe(eslint()) + // eslint.format() outputs the lint results to the console. + // Alternatively use eslint.formatEach() (see Docs). + .pipe(eslint.format()) + // To have the process exit with an error code (1) on + // lint error, return the stream and pipe to failOnError last. + .pipe(eslint.failOnError()); +}); + function bundle(watch) { var bro; diff --git a/package.json b/package.json index 99f8f431..5de03b4e 100644 --- a/package.json +++ b/package.json @@ -3,18 +3,25 @@ "version": "0.0.1", "description": "Das neue web client for Ascribe", "main": "js/app.js", + "scripts": { + "lint": "eslint ./js" + }, "author": "Ascribe", "license": "Copyright", "private": true, "devDependencies": { + "babel-eslint": "^3.1.11", "babel-jest": "^4.0.0", "babelify": "^6.1.2", "bootstrap-sass": "^3.3.4", "browser-sync": "^2.7.5", "browserify": "^9.0.8", "envify": "^3.4.0", + "eslint": "^0.22.1", + "eslint-plugin-react": "^2.5.0", "gulp": "^3.8.11", "gulp-concat": "^2.5.2", + "gulp-eslint": "^0.13.2", "gulp-if": "^1.2.5", "gulp-notify": "^2.2.0", "gulp-sass": "^2.0.1", @@ -37,7 +44,6 @@ "react-bootstrap": "~0.22.6", "react-router": "^0.13.3", "uglifyjs": "^2.4.10", - "react-bootstrap": "~0.22.6", "react-datepicker": "~0.8.0" }, "jest": { From f987bce7cc644806750fba6bfc8432ff226d1d2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Fri, 5 Jun 2015 11:06:36 +0200 Subject: [PATCH 20/21] add es6lint to build process and fix most (not really) errors and warnings --- .eslintrc | 29 ++++++++--- gulpfile.js | 8 ++- js/actions/edition_actions.js | 2 + js/actions/edition_list_actions.js | 4 +- js/actions/piece_actions.js | 2 + js/actions/piece_list_actions.js | 4 +- js/actions/user_actions.js | 8 +-- js/alt.js | 2 + js/app.js | 7 +-- js/components/acl_button.js | 36 +++++++------ .../ascribe_accordion_list/accordion_list.js | 3 +- .../accordion_list_item.js | 7 +-- .../accordion_list_item_table.js | 9 ++-- .../accordion_list_item_table_editions.js | 28 +++++----- ...t_item_table_select_all_editions_toggle.js | 6 ++- .../accordion_list_item_table_toggle.js | 4 +- js/components/ascribe_app.js | 4 +- js/components/ascribe_forms/alert.js | 5 ++ .../ascribe_forms/button_submit_close.js | 10 +++- js/components/ascribe_forms/form_consign.js | 9 ++-- js/components/ascribe_forms/form_loan.js | 51 +++++++++++-------- .../ascribe_forms/form_share_email.js | 10 ++-- js/components/ascribe_forms/form_transfer.js | 11 ++-- js/components/ascribe_forms/form_unconsign.js | 8 +-- .../ascribe_forms/form_unconsign_request.js | 9 ++-- js/components/ascribe_forms/input_checkbox.js | 13 +++-- js/components/ascribe_forms/input_date.js | 19 ++++--- js/components/ascribe_forms/input_hidden.js | 6 ++- js/components/ascribe_forms/input_text.js | 10 ++-- js/components/ascribe_forms/input_textarea.js | 13 +++-- .../ascribe_media/resource_viewer.js | 4 +- js/components/ascribe_modal/modal_loan.js | 12 +++-- js/components/ascribe_modal/modal_share.js | 14 ++--- .../ascribe_modal/modal_unconsign.js | 12 +++-- .../ascribe_modal/modal_unconsign_request.js | 12 +++-- js/components/ascribe_modal/modal_wrapper.js | 15 ++++-- .../ascribe_pagination/pagination.js | 16 +++--- .../ascribe_pagination/pagination_button.js | 2 + .../piece_list_bulk_modal.js | 6 ++- ...ist_bulk_modal_selected_editions_widget.js | 2 + .../piece_list_toolbar.js | 16 +++--- .../piece_list_toolbar_filter_widget.js | 2 + .../ascribe_table/models/table_models.js | 4 +- js/components/ascribe_table/table.js | 8 ++- js/components/ascribe_table/table_header.js | 19 +++---- .../ascribe_table/table_header_item.js | 6 ++- .../ascribe_table/table_header_item_carret.js | 2 + js/components/ascribe_table/table_item.js | 5 +- js/components/ascribe_table/table_item_acl.js | 2 + .../ascribe_table/table_item_acl_filtered.js | 2 + .../ascribe_table/table_item_checkbox.js | 2 + js/components/ascribe_table/table_item_img.js | 4 +- .../ascribe_table/table_item_selectable.js | 10 ++-- .../ascribe_table/table_item_subtable.js | 27 +++++----- .../table_item_subtable_button.js | 2 + .../ascribe_table/table_item_text.js | 2 + .../ascribe_table/table_item_wrapper.js | 11 ++-- js/components/edition.js | 38 +++++++++++--- js/components/edition_container.js | 10 ++-- js/components/fatal_error.js | 0 js/components/header.js | 6 +-- js/components/piece_list.js | 21 ++++---- js/constants/api_urls.js | 14 ++--- js/constants/application_constants.js | 2 + js/constants/languages.js | 2 + js/fetchers/edition_fetcher.js | 6 +-- js/fetchers/edition_list_fetcher.js | 4 +- js/fetchers/ownership_fetcher.js | 4 +- js/fetchers/piece_fetcher.js | 7 ++- js/fetchers/piece_list_fetcher.js | 3 +- js/fetchers/user_fetcher.js | 5 +- js/mixins/alert_mixin.js | 12 +++-- js/mixins/form_mixin.js | 27 +++++----- js/mixins/inject_in_head_mixin.js | 12 +++-- js/mixins/modal_mixin.js | 5 +- js/mixins/table_column_mixin.js | 4 +- js/routes.js | 9 ++-- js/stores/edition_list_store.js | 8 +-- js/stores/edition_store.js | 2 + js/stores/piece_list_store.js | 17 ++++--- js/stores/piece_store.js | 2 + js/stores/user_store.js | 2 + js/utils/fetch.js | 18 ++++--- js/utils/fetch_api_utils.js | 16 +++--- js/utils/general_utils.js | 27 ++++++---- js/utils/lang_utils.js | 4 +- 86 files changed, 525 insertions(+), 318 deletions(-) delete mode 100644 js/components/fatal_error.js diff --git a/.eslintrc b/.eslintrc index 4d0cfbed..869e2d3d 100644 --- a/.eslintrc +++ b/.eslintrc @@ -9,17 +9,21 @@ "eol-last": [0], "no-mixed-requires": [0], "no-underscore-dangle": [0], - "react/display-name": 1, + "global-strict": [2, "always"], + "no-trailing-spaces": [2, { skipBlankLines: true }], + "no-console": 0, + "camelcase": [2, {"properties": "never"}], + "react/display-name": 0, "react/jsx-boolean-value": 1, "react/jsx-no-undef": 1, "react/jsx-quotes": 1, - "react/jsx-sort-prop-types": 1, - "react/jsx-sort-props": 1, + "react/jsx-sort-prop-types": 0, + "react/jsx-sort-props": 0, "react/jsx-uses-react": 1, "react/jsx-uses-vars": 1, "react/no-did-mount-set-state": 1, "react/no-did-update-set-state": 1, - "react/no-multi-comp": 1, + "react/no-multi-comp": 0, "react/no-unknown-property": 1, "react/prop-types": 1, "react/react-in-jsx-scope": 1, @@ -31,7 +35,20 @@ "react" ], "ecmaFeatures": { - "jsx": true, - "modules": true + "jsx": 1, + "modules": 1, + "arrowFunctions", + "classes": 1, + "blockBindings": 1, + "defaultParams": 1, + "destructuring": 1, + "objectLiteralComputedProperties": 1, + "objectLiteralDuplicateProperties": 0, + "objectLiteralShorthandMethods": 1, + "objectLiteralShorthandProperties": 1, + "restParams": 1, + "spread": 1, + "superInFunctions": 1, + "templateStrings": 1 } } \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js index 1790e3ff..6e5697bb 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,3 +1,5 @@ +'use strict'; + var gulp = require('gulp'); var gulpif = require('gulp-if'); var sourcemaps = require('gulp-sourcemaps'); @@ -22,7 +24,7 @@ gulp.task('build', function() { bundle(false); }); -gulp.task('serve', ['browser-sync', 'sass', 'sass:watch', 'copy', 'lint'], function() { +gulp.task('serve', ['browser-sync', 'lint:watch', 'sass', 'sass:watch', 'copy'], function() { bundle(true); }); @@ -78,6 +80,10 @@ gulp.task('lint', function () { .pipe(eslint.failOnError()); }); +gulp.task('lint:watch', function () { + gulp.watch('js/**/*.js', ['lint']); +}); + function bundle(watch) { var bro; diff --git a/js/actions/edition_actions.js b/js/actions/edition_actions.js index a39c330a..07fcab1d 100644 --- a/js/actions/edition_actions.js +++ b/js/actions/edition_actions.js @@ -1,3 +1,5 @@ +'use strict'; + import alt from '../alt'; import EditionFetcher from '../fetchers/edition_fetcher'; diff --git a/js/actions/edition_list_actions.js b/js/actions/edition_list_actions.js index e967793c..83b9abfe 100644 --- a/js/actions/edition_list_actions.js +++ b/js/actions/edition_list_actions.js @@ -1,3 +1,5 @@ +'use strict'; + import alt from '../alt'; import EditionListFetcher from '../fetchers/edition_list_fetcher.js'; @@ -12,7 +14,7 @@ class EditionListActions { } fetchEditionList(pieceId, orderBy, orderAsc) { - if(!orderBy && typeof orderAsc == "undefined") { + if(!orderBy && typeof orderAsc == 'undefined') { orderBy = 'edition_number'; orderAsc = true; } diff --git a/js/actions/piece_actions.js b/js/actions/piece_actions.js index 274ef458..cd78569d 100644 --- a/js/actions/piece_actions.js +++ b/js/actions/piece_actions.js @@ -1,3 +1,5 @@ +'use strict'; + import alt from '../alt'; import PieceFetcher from '../fetchers/piece_fetcher'; diff --git a/js/actions/piece_list_actions.js b/js/actions/piece_list_actions.js index 1bb44c1f..938cb195 100644 --- a/js/actions/piece_list_actions.js +++ b/js/actions/piece_list_actions.js @@ -1,3 +1,5 @@ +'use strict'; + import alt from '../alt'; import PieceListFetcher from '../fetchers/piece_list_fetcher'; @@ -28,6 +30,6 @@ class PieceListActions { }); } -}; +} export default alt.createActions(PieceListActions); diff --git a/js/actions/user_actions.js b/js/actions/user_actions.js index 34e80f52..90e931b1 100644 --- a/js/actions/user_actions.js +++ b/js/actions/user_actions.js @@ -1,3 +1,5 @@ +'use strict'; + import alt from '../alt'; import UserFetcher from '../fetchers/user_fetcher'; @@ -12,12 +14,12 @@ class UserActions { fetchCurrentUser() { UserFetcher.fetchOne() .then((res) => { - this.actions.updateCurrentUser(res['users'][0]); + this.actions.updateCurrentUser(res.users[0]); }) .catch((err) => { - console.log(err); + console.log(err); }); } -}; +} export default alt.createActions(UserActions); diff --git a/js/alt.js b/js/alt.js index ad49b9b5..94786185 100644 --- a/js/alt.js +++ b/js/alt.js @@ -1,3 +1,5 @@ +'use strict'; + import Alt from 'alt'; export default new Alt(); diff --git a/js/app.js b/js/app.js index 30d2f486..ca2df1c6 100644 --- a/js/app.js +++ b/js/app.js @@ -6,16 +6,13 @@ import promise from 'es6-promise'; promise.polyfill(); -import AscribeApp from './components/ascribe_app'; import AppConstants from './constants/application_constants'; import ApiUrls from './constants/api_urls'; import routes from './routes'; -import alt from './alt'; import fetch from './utils/fetch'; -import AlertDismissable from './components/ascribe_forms/alert'; -/* - Taken from +/* + Taken from http://stackoverflow.com/questions/30613447/how-to-debug-reactjss-setstate?noredirect=1#comment49301874_30613447 diff --git a/js/components/acl_button.js b/js/components/acl_button.js index 5f2a0708..9607384b 100644 --- a/js/components/acl_button.js +++ b/js/components/acl_button.js @@ -1,3 +1,5 @@ +'use strict'; + import React from 'react'; import ConsignForm from './ascribe_forms/form_consign'; @@ -17,31 +19,33 @@ let AclButton = React.createClass({ }, actionProperties(){ - if (this.props.action == 'consign'){ + if (this.props.action === 'consign'){ return { - title: "Consign artwork", - tooltip: "Have someone else sell the artwork", + title: 'Consign artwork', + tooltip: 'Have someone else sell the artwork', form: - } + }; } - else if (this.props.action == 'transfer') { + else if (this.props.action === 'transfer') { return { - title: "Transfer artwork", - tooltip: "Transfer the ownership of the artwork", + title: 'Transfer artwork', + tooltip: 'Transfer the ownership of the artwork', form: - } + }; } - else if (this.props.action == 'loan'){ + else if (this.props.action === 'loan'){ return { - title: "Loan artwork", - tooltip: "Loan your artwork for a limited period of time", - form: } + title: 'Loan artwork', + tooltip: 'Loan your artwork for a limited period of time', + form: + }; } - else if (this.props.action == 'share'){ + else if (this.props.action === 'share'){ return { - title: "Share artwork", - tooltip: "Share the artwork", - form: } + title: 'Share artwork', + tooltip: 'Share the artwork', + form: + }; } }, render() { diff --git a/js/components/ascribe_accordion_list/accordion_list.js b/js/components/ascribe_accordion_list/accordion_list.js index 9eb484b7..a17aed36 100644 --- a/js/components/ascribe_accordion_list/accordion_list.js +++ b/js/components/ascribe_accordion_list/accordion_list.js @@ -1,5 +1,6 @@ +'use strict'; + import React from 'react'; -import ReactAddons from 'react/addons'; let AccordionList = React.createClass({ diff --git a/js/components/ascribe_accordion_list/accordion_list_item.js b/js/components/ascribe_accordion_list/accordion_list_item.js index 9828ea30..e822b5c6 100644 --- a/js/components/ascribe_accordion_list/accordion_list_item.js +++ b/js/components/ascribe_accordion_list/accordion_list_item.js @@ -1,8 +1,8 @@ +'use strict'; + import React from 'react'; import Router from 'react-router'; -import AccordionListItemTable from './accordion_list_item_table'; - import { getLangText } from '../../utils/lang_utils'; let Link = Router.Link; @@ -10,7 +10,8 @@ let Link = Router.Link; let AccordionListItem = React.createClass({ propTypes: { className: React.PropTypes.string, - content: React.PropTypes.object + content: React.PropTypes.object, + children: React.PropTypes.object }, render() { diff --git a/js/components/ascribe_accordion_list/accordion_list_item_table.js b/js/components/ascribe_accordion_list/accordion_list_item_table.js index 5e22bf05..4ead1eeb 100644 --- a/js/components/ascribe_accordion_list/accordion_list_item_table.js +++ b/js/components/ascribe_accordion_list/accordion_list_item_table.js @@ -1,3 +1,5 @@ +'use strict'; + import React from 'react'; import Table from '../ascribe_table/table'; @@ -5,8 +7,6 @@ import TableItem from '../ascribe_table/table_item'; import { ColumnModel } from '../ascribe_table/models/table_models'; -import { getLangText } from '../../utils/lang_utils'; - let AccordionListItemTable = React.createClass({ propTypes: { className: React.PropTypes.string, @@ -26,7 +26,7 @@ let AccordionListItemTable = React.createClass({
- + key={i} /> ); })}
diff --git a/js/components/ascribe_accordion_list/accordion_list_item_table_editions.js b/js/components/ascribe_accordion_list/accordion_list_item_table_editions.js index 3e81574a..c975500e 100644 --- a/js/components/ascribe_accordion_list/accordion_list_item_table_editions.js +++ b/js/components/ascribe_accordion_list/accordion_list_item_table_editions.js @@ -1,9 +1,10 @@ +'use strict'; + import React from 'react'; import Router from 'react-router'; import EditionListStore from '../../stores/edition_list_store'; import EditionListActions from '../../actions/edition_list_actions'; -import PieceListStore from '../../stores/piece_list_store'; import PieceListActions from '../../actions/piece_list_actions'; import AccordionListItemTable from './accordion_list_item_table'; @@ -12,7 +13,6 @@ import AccordionListItemTableSelectAllEditionsToggle from './accordion_list_item import { ColumnModel, TransitionModel } from '../ascribe_table/models/table_models'; -import TableItemImg from '../ascribe_table/table_item_img'; import TableItemText from '../ascribe_table/table_item_text'; import TableItemCheckbox from '../ascribe_table/table_item_checkbox'; import TableItemAclFiltered from '../ascribe_table/table_item_acl_filtered'; @@ -34,10 +34,6 @@ let AccordionListItemTableEditions = React.createClass({ return EditionListStore.getState(); }, - onChange(state) { - this.setState(state); - }, - componentDidMount() { EditionListStore.listen(this.onChange); }, @@ -46,6 +42,10 @@ let AccordionListItemTableEditions = React.createClass({ EditionListStore.unlisten(this.onChange); }, + onChange(state) { + this.setState(state); + }, + selectItem(pieceId, editionId) { EditionListActions.selectEdition({pieceId, editionId}); }, @@ -84,7 +84,7 @@ let AccordionListItemTableEditions = React.createClass({ if(this.state.editionList[this.props.parentId]) { selectedEditionsCount = this.filterSelectedEditions().length; allEditionsCount = this.state.editionList[this.props.parentId].length; - orderBy = this.state.editionList[this.props.parentId].orderBy + orderBy = this.state.editionList[this.props.parentId].orderBy; orderAsc = this.state.editionList[this.props.parentId].orderAsc; } @@ -98,7 +98,7 @@ let AccordionListItemTableEditions = React.createClass({ 'pieceId': this.props.parentId, 'selectItem': this.selectItem, 'selected': item.selected - }}, + }; }, '', { + (item) => { return { 'content': item.edition_number - }}, + }; }, 'edition_number', '#', TableItemText, @@ -124,7 +124,7 @@ let AccordionListItemTableEditions = React.createClass({ (item) => { return { 'content': item.bitcoin_id - }}, + }; }, 'bitcoin_id', getLangText('Bitcoin Address'), TableItemText, @@ -133,10 +133,10 @@ let AccordionListItemTableEditions = React.createClass({ transition ), new ColumnModel( - (item) => { + (item) => { return { 'content': item.acl - }}, + }; }, 'acl', getLangText('Actions'), TableItemAclFiltered, @@ -159,7 +159,7 @@ let AccordionListItemTableEditions = React.createClass({ orderAsc={orderAsc} changeOrder={this.changeEditionListOrder}> diff --git a/js/components/ascribe_accordion_list/accordion_list_item_table_select_all_editions_toggle.js b/js/components/ascribe_accordion_list/accordion_list_item_table_select_all_editions_toggle.js index 37af9edb..0fe71c35 100644 --- a/js/components/ascribe_accordion_list/accordion_list_item_table_select_all_editions_toggle.js +++ b/js/components/ascribe_accordion_list/accordion_list_item_table_select_all_editions_toggle.js @@ -1,3 +1,5 @@ +'use strict'; + import React from 'react'; @@ -11,8 +13,8 @@ let AccordionListItemTableSelectAllEditionsToggle = React.createClass({ render() { return ( - ); } diff --git a/js/components/ascribe_accordion_list/accordion_list_item_table_toggle.js b/js/components/ascribe_accordion_list/accordion_list_item_table_toggle.js index a3431b04..1f05de4b 100644 --- a/js/components/ascribe_accordion_list/accordion_list_item_table_toggle.js +++ b/js/components/ascribe_accordion_list/accordion_list_item_table_toggle.js @@ -1,3 +1,5 @@ +'use strict'; + import React from 'react'; let AccordionListItemTableToggle = React.createClass({ @@ -10,7 +12,7 @@ let AccordionListItemTableToggle = React.createClass({ render() { return ( - {this.props.show ? 'Hide all ' + this.props.numOfTableItems + ' Editions' : 'Show all ' + this.props.numOfTableItems + ' Editions'} diff --git a/js/components/ascribe_app.js b/js/components/ascribe_app.js index bab7de97..6484976c 100644 --- a/js/components/ascribe_app.js +++ b/js/components/ascribe_app.js @@ -1,3 +1,5 @@ +'use strict'; + import React from 'react'; import Router from 'react-router'; import Header from '../components/header'; @@ -12,7 +14,7 @@ let AscribeApp = React.createClass({
-
+
); } }); diff --git a/js/components/ascribe_forms/alert.js b/js/components/ascribe_forms/alert.js index 482afdfe..4d5bae64 100644 --- a/js/components/ascribe_forms/alert.js +++ b/js/components/ascribe_forms/alert.js @@ -1,3 +1,5 @@ +'use strict'; + import React from 'react'; import Alert from 'react-bootstrap/lib/Alert'; @@ -7,12 +9,15 @@ let AlertDismissable = React.createClass({ alertVisible: true }; }, + show() { this.setState({alertVisible: true}); }, + hide() { this.setState({alertVisible: false}); }, + render() { if (this.state.alertVisible) { let key = this.props.error; diff --git a/js/components/ascribe_forms/button_submit_close.js b/js/components/ascribe_forms/button_submit_close.js index e811cab5..7430f484 100644 --- a/js/components/ascribe_forms/button_submit_close.js +++ b/js/components/ascribe_forms/button_submit_close.js @@ -1,5 +1,13 @@ +'use strict'; + import React from 'react'; + +/* + Is this even used somewhere? + Deprecate? 5.6.15 - Tim + + */ let ButtonSubmitOrClose = React.createClass({ render() { if (this.props.submitted){ @@ -14,7 +22,7 @@ let ButtonSubmitOrClose = React.createClass({
- ) + ); } }); diff --git a/js/components/ascribe_forms/form_consign.js b/js/components/ascribe_forms/form_consign.js index dbb1eee0..85c21467 100644 --- a/js/components/ascribe_forms/form_consign.js +++ b/js/components/ascribe_forms/form_consign.js @@ -1,4 +1,4 @@ -import fetch from 'isomorphic-fetch'; +'use strict'; import React from 'react'; @@ -12,19 +12,20 @@ let ConsignForm = React.createClass({ mixins: [FormMixin], url() { - return ApiUrls.ownership_consigns + return ApiUrls.ownership_consigns; }, + getFormData() { return { bitcoin_id: this.getBitcoinIds().join(), consignee: this.refs.consignee.state.value, consign_message: this.refs.consign_message.state.value, password: this.refs.password.state.value - } + }; }, renderForm() { - let title = this.getTitlesString().join(""); + let title = this.getTitlesString().join(''); let username = this.props.currentUser.username; let message = `Hi, diff --git a/js/components/ascribe_forms/form_loan.js b/js/components/ascribe_forms/form_loan.js index 483d0f0a..3b9dc5e3 100644 --- a/js/components/ascribe_forms/form_loan.js +++ b/js/components/ascribe_forms/form_loan.js @@ -1,4 +1,4 @@ -import fetch from 'isomorphic-fetch'; +'use strict'; import React from 'react'; @@ -9,39 +9,47 @@ import InputHidden from './input_hidden'; import InputCheckbox from './input_checkbox'; import InputDate from './input_date'; import InputTextArea from './input_textarea'; -import OwnershipFetcher from '../../fetchers/ownership_fetcher' +import OwnershipFetcher from '../../fetchers/ownership_fetcher'; import ButtonSubmitOrClose from './button_submit_close'; let LoanForm = React.createClass({ + + getInitialState() { + this.setState({ + contract_key: null, + contract_url: null, + loaneeHasContract: false + }); + }, + mixins: [FormMixin], url() { - return ApiUrls.ownership_loans - }, - componentDidMount(){ - this.setState({contract_key: null, - contract_url: null, - loaneeHasContract: false}); + return ApiUrls.ownership_loans; }, + getFormData() { return { bitcoin_id: this.getBitcoinIds().join(), loanee: this.refs.loanee.state.value, gallery_name: this.refs.gallery_name.state.value, - startdate: this.refs.startdate.state.value.format("YYYY-MM-DD"), - enddate: this.refs.enddate.state.value.format("YYYY-MM-DD"), + startdate: this.refs.startdate.state.value.format('YYYY-MM-DD'), + enddate: this.refs.enddate.state.value.format('YYYY-MM-DD'), loan_message: this.refs.loan_message.state.value, password: this.refs.password.state.value, terms: this.refs.terms.state.value - } + }; }, - handleLoanEmailBlur(e){ + + handleLoanEmailBlur(){ OwnershipFetcher.fetchLoanContract(this.refs.loanee.state.value) .then((res) => { if (res && res.length > 0) { - this.setState({contract_key: res[0].s3Key, - contract_url: res[0].s3Url, - loaneeHasContract: true}); + this.setState({ + contract_key: res[0].s3Key, + contract_url: res[0].s3Url, + loaneeHasContract: true + }); } else{ this.resetLoanContract(); @@ -52,14 +60,16 @@ let LoanForm = React.createClass({ this.resetLoanContract(); }); }, + resetLoanContract(){ this.setState({contract_key: null, contract_url: null, loaneeHasContract: false }); }, + renderForm() { - let title = this.getTitlesString().join(""); + let title = this.getTitlesString().join(''); let username = this.props.currentUser.username; let message = `Hi, @@ -72,18 +82,19 @@ ${username}`; let contract = ; if (this.state.loaneeHasContract){ - let label =
+ let label = (; - contract = ); + contract = ( + />); } + return (
diff --git a/js/components/ascribe_forms/form_share_email.js b/js/components/ascribe_forms/form_share_email.js index cbcfc7a1..5728e03b 100644 --- a/js/components/ascribe_forms/form_share_email.js +++ b/js/components/ascribe_forms/form_share_email.js @@ -1,4 +1,4 @@ -import fetch from 'isomorphic-fetch'; +'use strict'; import React from 'react'; @@ -12,17 +12,19 @@ let ShareForm = React.createClass({ mixins: [FormMixin], url() { - return ApiUrls.ownership_shares_mail + return ApiUrls.ownership_shares_mail; }, + getFormData() { return { bitcoin_id: this.getBitcoinIds().join(), share_emails: this.refs.share_emails.state.value, share_message: this.refs.share_message.state.value - } + }; }, + renderForm() { - let title = this.getTitlesString().join(""); + let title = this.getTitlesString().join(''); let username = this.props.currentUser.username; let message = `Hi, diff --git a/js/components/ascribe_forms/form_transfer.js b/js/components/ascribe_forms/form_transfer.js index c724edd0..bb20c8a6 100644 --- a/js/components/ascribe_forms/form_transfer.js +++ b/js/components/ascribe_forms/form_transfer.js @@ -1,4 +1,4 @@ -import fetch from 'isomorphic-fetch'; +'use strict'; import React from 'react'; @@ -9,23 +9,24 @@ import InputTextArea from './input_textarea'; import ButtonSubmitOrClose from './button_submit_close'; - let TransferForm = React.createClass({ mixins: [FormMixin], url() { - return ApiUrls.ownership_transfers + return ApiUrls.ownership_transfers; }, + getFormData() { return { bitcoin_id: this.getBitcoinIds().join(), transferee: this.refs.transferee.state.value, transfer_message: this.refs.transfer_message.state.value, password: this.refs.password.state.value - } + }; }, + renderForm() { - let title = this.getTitlesString().join(""); + let title = this.getTitlesString().join(''); let username = this.props.currentUser.username; let message = `Hi, diff --git a/js/components/ascribe_forms/form_unconsign.js b/js/components/ascribe_forms/form_unconsign.js index 60112334..01a6e7b9 100644 --- a/js/components/ascribe_forms/form_unconsign.js +++ b/js/components/ascribe_forms/form_unconsign.js @@ -1,4 +1,4 @@ -import fetch from 'isomorphic-fetch'; +'use strict'; import React from 'react'; @@ -12,15 +12,17 @@ let UnConsignForm = React.createClass({ mixins: [FormMixin], url() { - return ApiUrls.ownership_unconsigns + return ApiUrls.ownership_unconsigns; }, + getFormData() { return { bitcoin_id: this.props.edition.bitcoin_id, unconsign_message: this.refs.unconsign_message.state.value, password: this.refs.password.state.value - } + }; }, + renderForm() { let title = this.props.edition.title; let username = this.props.currentUser.username; diff --git a/js/components/ascribe_forms/form_unconsign_request.js b/js/components/ascribe_forms/form_unconsign_request.js index f572a287..4857164e 100644 --- a/js/components/ascribe_forms/form_unconsign_request.js +++ b/js/components/ascribe_forms/form_unconsign_request.js @@ -1,10 +1,9 @@ -import fetch from 'isomorphic-fetch'; +'use strict'; import React from 'react'; import ApiUrls from '../../constants/api_urls'; import FormMixin from '../../mixins/form_mixin'; -import InputText from './input_text'; import InputTextArea from './input_textarea'; import ButtonSubmitOrClose from './button_submit_close'; @@ -12,14 +11,16 @@ let UnConsignRequestForm = React.createClass({ mixins: [FormMixin], url() { - return ApiUrls.ownership_unconsigns_request + return ApiUrls.ownership_unconsigns_request; }, + getFormData() { return { bitcoin_id: this.props.edition.bitcoin_id, unconsign_request_message: this.refs.unconsign_request_message.state.value - } + }; }, + renderForm() { let title = this.props.edition.title; let username = this.props.currentUser.username; diff --git a/js/components/ascribe_forms/input_checkbox.js b/js/components/ascribe_forms/input_checkbox.js index c1ecda1a..187a1acf 100644 --- a/js/components/ascribe_forms/input_checkbox.js +++ b/js/components/ascribe_forms/input_checkbox.js @@ -1,19 +1,24 @@ +'use strict'; + import React from 'react'; -import AlertMixin from '../../mixins/alert_mixin' +import AlertMixin from '../../mixins/alert_mixin'; let InputCheckbox = React.createClass({ - mixins : [AlertMixin], + mixins: [AlertMixin], getInitialState() { - return {value: null, - alerts: null // needed in AlertMixin + return { + value: null, + alerts: null // needed in AlertMixin }; }, + handleChange(event) { this.setState({value: event.target.value}); }, + render() { let alerts = (this.props.submitted) ? null : this.state.alerts; return ( diff --git a/js/components/ascribe_forms/input_date.js b/js/components/ascribe_forms/input_date.js index 98422c72..a3be6633 100644 --- a/js/components/ascribe_forms/input_date.js +++ b/js/components/ascribe_forms/input_date.js @@ -1,15 +1,18 @@ +'use strict'; + import React from 'react'; -import AlertMixin from '../../mixins/alert_mixin' -import DatePicker from 'react-datepicker/dist/react-datepicker' +import AlertMixin from '../../mixins/alert_mixin'; +import DatePicker from 'react-datepicker/dist/react-datepicker'; let InputDate = React.createClass({ - mixins : [AlertMixin], + mixins: [AlertMixin], getInitialState() { - return {value: null, - alerts: null // needed in AlertMixin + return { + value: null, + alerts: null // needed in AlertMixin }; }, @@ -18,7 +21,7 @@ let InputDate = React.createClass({ }, render: function () { - let className = "form-control input-text-ascribe"; + let className = 'form-control input-text-ascribe'; let alerts = (this.props.submitted) ? null : this.state.alerts; return ( ); + // CAN THIS BE REMOVED??? + // + // - Tim? + // //return ( //
diff --git a/js/components/ascribe_forms/input_textarea.js b/js/components/ascribe_forms/input_textarea.js index cf5cfc4a..1d7af441 100644 --- a/js/components/ascribe_forms/input_textarea.js +++ b/js/components/ascribe_forms/input_textarea.js @@ -1,21 +1,24 @@ +'use strict'; + import React from 'react'; -import AlertMixin from '../../mixins/alert_mixin' +import AlertMixin from '../../mixins/alert_mixin'; let InputTextArea = React.createClass({ - mixins : [AlertMixin], + mixins: [AlertMixin], getInitialState() { - return {value: this.props.defaultValue, - alerts: null // needed in AlertMixin + return { + value: this.props.defaultValue, + alerts: null // needed in AlertMixin }; }, handleChange(event) { this.setState({value: event.target.value}); }, render() { - let className = "form-control input-text-ascribe textarea-ascribe-message"; + let className = 'form-control input-text-ascribe textarea-ascribe-message'; let alerts = (this.props.submitted) ? null : this.state.alerts; return ( diff --git a/js/components/ascribe_media/resource_viewer.js b/js/components/ascribe_media/resource_viewer.js index 519b6cec..012228c6 100644 --- a/js/components/ascribe_media/resource_viewer.js +++ b/js/components/ascribe_media/resource_viewer.js @@ -1,3 +1,5 @@ +'use strict'; + import React from 'react'; import InjectInHeadMixin from '../../mixins/inject_in_head_mixin'; @@ -14,7 +16,7 @@ import InjectInHeadMixin from '../../mixins/inject_in_head_mixin'; let resourceMap = { 'image': 1 -} +}; let ResourceViewer = React.createClass({ propTypes: { diff --git a/js/components/ascribe_modal/modal_loan.js b/js/components/ascribe_modal/modal_loan.js index aed475b1..aff34ac0 100644 --- a/js/components/ascribe_modal/modal_loan.js +++ b/js/components/ascribe_modal/modal_loan.js @@ -1,11 +1,13 @@ +'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' +import LoanForm from '../ascribe_forms/form_loan'; +import ModalMixin from '../../mixins/modal_mixin'; let LoanModalButton = React.createClass({ render() { @@ -19,12 +21,12 @@ let LoanModalButton = React.createClass({
- ) + ); } }); let LoanModal = React.createClass({ - mixins : [ModalMixin], + mixins: [ModalMixin], render() { return ( @@ -35,7 +37,7 @@ let LoanModal = React.createClass({ onRequestHide={this.onRequestHide}/>
- ) + ); } }); diff --git a/js/components/ascribe_modal/modal_share.js b/js/components/ascribe_modal/modal_share.js index 4ada244c..2cce53ad 100644 --- a/js/components/ascribe_modal/modal_share.js +++ b/js/components/ascribe_modal/modal_share.js @@ -1,13 +1,13 @@ +'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' +import ModalMixin from '../../mixins/modal_mixin'; +import ShareForm from '../ascribe_forms/form_share_email'; let ShareModalButton = React.createClass({ render() { @@ -20,12 +20,12 @@ let ShareModalButton = React.createClass({
- ) + ); } }); let ShareModal = React.createClass({ - mixins : [ModalMixin], + mixins: [ModalMixin], render() { return ( @@ -36,7 +36,7 @@ let ShareModal = React.createClass({ onRequestHide={this.onRequestHide}/>
- ) + ); } }); diff --git a/js/components/ascribe_modal/modal_unconsign.js b/js/components/ascribe_modal/modal_unconsign.js index 1245fc01..9bfb2faf 100644 --- a/js/components/ascribe_modal/modal_unconsign.js +++ b/js/components/ascribe_modal/modal_unconsign.js @@ -1,11 +1,13 @@ +'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' +import UnConsignForm from '../ascribe_forms/form_unconsign'; +import ModalMixin from '../../mixins/modal_mixin'; let UnConsignModalButton = React.createClass({ render() { @@ -19,12 +21,12 @@ let UnConsignModalButton = React.createClass({
- ) + ); } }); let UnConsignModal = React.createClass({ - mixins : [ModalMixin], + mixins: [ModalMixin], render() { return ( @@ -35,7 +37,7 @@ let UnConsignModal = React.createClass({ onRequestHide={this.onRequestHide}/>
- ) + ); } }); diff --git a/js/components/ascribe_modal/modal_unconsign_request.js b/js/components/ascribe_modal/modal_unconsign_request.js index c74e637b..fa0cd19f 100644 --- a/js/components/ascribe_modal/modal_unconsign_request.js +++ b/js/components/ascribe_modal/modal_unconsign_request.js @@ -1,11 +1,13 @@ +'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' +import UnConsignRequestForm from '../ascribe_forms/form_unconsign_request'; +import ModalMixin from '../../mixins/modal_mixin'; let UnConsignRequestModalButton = React.createClass({ render() { @@ -19,12 +21,12 @@ let UnConsignRequestModalButton = React.createClass({
- ) + ); } }); let UnConsignRequestModal = React.createClass({ - mixins : [ModalMixin], + mixins: [ModalMixin], render() { return ( @@ -35,7 +37,7 @@ let UnConsignRequestModal = React.createClass({ onRequestHide={this.onRequestHide}/>
- ) + ); } }); diff --git a/js/components/ascribe_modal/modal_wrapper.js b/js/components/ascribe_modal/modal_wrapper.js index a5d20389..43aecbe0 100644 --- a/js/components/ascribe_modal/modal_wrapper.js +++ b/js/components/ascribe_modal/modal_wrapper.js @@ -1,3 +1,5 @@ +'use strict'; + import React from 'react'; import ReactAddons from 'react/addons'; @@ -6,7 +8,7 @@ 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 ModalMixin from '../../mixins/modal_mixin'; let ModalWrapper = React.createClass({ @@ -27,20 +29,22 @@ let ModalWrapper = React.createClass({ {this.props.button} - ) + ); } }); // let ModalBody = React.createClass({ - mixins : [ModalMixin], + + mixins: [ModalMixin], handleSuccess(){ this.props.handleSuccess(); this.props.onRequestHide(); }, + renderChildren() { - return ReactAddons.Children.map(this.props.children, (child, i) => { + return ReactAddons.Children.map(this.props.children, (child) => { return ReactAddons.addons.cloneWithProps(child, { editions: this.props.editions, currentUser: this.props.currentUser, @@ -49,6 +53,7 @@ let ModalBody = React.createClass({ }); }); }, + render() { return ( @@ -56,7 +61,7 @@ let ModalBody = React.createClass({ {this.renderChildren()}
- ) + ); } }); diff --git a/js/components/ascribe_pagination/pagination.js b/js/components/ascribe_pagination/pagination.js index e99f8e4e..6b55f119 100644 --- a/js/components/ascribe_pagination/pagination.js +++ b/js/components/ascribe_pagination/pagination.js @@ -1,3 +1,5 @@ +'use strict'; + import React from 'react'; import PaginationButton from './pagination_button'; @@ -7,25 +9,23 @@ let Pagination = React.createClass({ goToPage: React.PropTypes.func.isRequired, currentPage: React.PropTypes.number.isRequired, totalPages: React.PropTypes.number.isRequired - //itemListCount: React.PropTypes.number.isRequired + //itemListCount: React.PropTypes.number.isRequired }, render() { - return( + return ( ); diff --git a/js/components/ascribe_pagination/pagination_button.js b/js/components/ascribe_pagination/pagination_button.js index bbb2a789..3adf0b50 100644 --- a/js/components/ascribe_pagination/pagination_button.js +++ b/js/components/ascribe_pagination/pagination_button.js @@ -1,3 +1,5 @@ +'use strict'; + import React from 'react'; import Router from 'react-router'; 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 c2ccfbc1..039d6aad 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 @@ -1,3 +1,5 @@ +'use strict'; + import React from 'react'; import { mergeOptions } from '../../utils/general_utils'; @@ -108,7 +110,7 @@ let PieceListBulkModal = React.createClass({           - clear all @@ -148,7 +150,7 @@ let PieceListBulkModal = React.createClass({ ); } else { return null; - } + } } }); diff --git a/js/components/ascribe_piece_list_bulk_modal/piece_list_bulk_modal_selected_editions_widget.js b/js/components/ascribe_piece_list_bulk_modal/piece_list_bulk_modal_selected_editions_widget.js index 22b35a4a..99ede112 100644 --- a/js/components/ascribe_piece_list_bulk_modal/piece_list_bulk_modal_selected_editions_widget.js +++ b/js/components/ascribe_piece_list_bulk_modal/piece_list_bulk_modal_selected_editions_widget.js @@ -1,3 +1,5 @@ +'use strict'; + import React from 'react'; let PieceListBulkModalSelectedEditionsWidget = React.createClass({ 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 84681b55..a3c8c219 100644 --- a/js/components/ascribe_piece_list_toolbar/piece_list_toolbar.js +++ b/js/components/ascribe_piece_list_toolbar/piece_list_toolbar.js @@ -1,3 +1,5 @@ +'use strict'; + import React from 'react'; import PieceListStore from '../../stores/piece_list_store'; @@ -6,18 +8,16 @@ import PieceListActions from '../../actions/piece_list_actions'; import Input from 'react-bootstrap/lib/Input'; import Glyphicon from 'react-bootstrap/lib/Glyphicon'; -import PieceListToolbarFilterWidgetFilter from './piece_list_toolbar_filter_widget'; - let PieceListToolbar = React.createClass({ + propTypes: { + className: React.PropTypes.string + }, + getInitialState() { return PieceListStore.getState(); }, - onChange(state) { - this.setState(state); - }, - componentDidMount() { PieceListStore.listen(this.onChange); }, @@ -26,6 +26,10 @@ let PieceListToolbar = React.createClass({ PieceListStore.unlisten(this.onChange); }, + onChange(state) { + this.setState(state); + }, + searchFor() { let searchTerm = this.refs.search.getInputDOMNode().value; PieceListActions.fetchPieceList(this.state.page, this.pageSize, searchTerm, this.state.orderBy, this.state.orderAsc); diff --git a/js/components/ascribe_piece_list_toolbar/piece_list_toolbar_filter_widget.js b/js/components/ascribe_piece_list_toolbar/piece_list_toolbar_filter_widget.js index 7aaf9dd8..d9d2b172 100644 --- a/js/components/ascribe_piece_list_toolbar/piece_list_toolbar_filter_widget.js +++ b/js/components/ascribe_piece_list_toolbar/piece_list_toolbar_filter_widget.js @@ -1,3 +1,5 @@ +'use strict'; + import React from 'react'; import Glyphicon from 'react-bootstrap/lib/Glyphicon'; diff --git a/js/components/ascribe_table/models/table_models.js b/js/components/ascribe_table/models/table_models.js index 245a2310..e5fad805 100644 --- a/js/components/ascribe_table/models/table_models.js +++ b/js/components/ascribe_table/models/table_models.js @@ -1,3 +1,5 @@ +'use strict'; + export class ColumnModel { // ToDo: Add validation for all passed-in parameters constructor(transformFn, columnName, displayName, displayType, rowWidth, canBeOrdered, transition) { @@ -12,7 +14,7 @@ export class ColumnModel { } /** - * If a user opens an editionList of a piece and clicks on a specific edition to go to the + * If a user opens an editionList of a piece and clicks on a specific edition to go to the * piece detail page, all previously opened editionLists are still saved as show = true in the * pieceList store. * diff --git a/js/components/ascribe_table/table.js b/js/components/ascribe_table/table.js index 9fe77195..6a8f0c93 100644 --- a/js/components/ascribe_table/table.js +++ b/js/components/ascribe_table/table.js @@ -1,3 +1,5 @@ +'use strict'; + import React from 'react'; import ReactAddons from 'react/addons'; @@ -12,7 +14,9 @@ let Table = React.createClass({ changeOrder: React.PropTypes.func, orderBy: React.PropTypes.string, orderAsc: React.PropTypes.bool, - className: React.PropTypes.string + className: React.PropTypes.string, + children: React.PropTypes.object, + itemList: React.PropTypes.array }, renderChildren() { @@ -29,7 +33,7 @@ let Table = React.createClass({ render() { return ( - @@ -29,20 +32,18 @@ let TableHeader = React.createClass({ return ( - + changeOrder={this.props.changeOrder} /> ); })} - + ); - } }); diff --git a/js/components/ascribe_table/table_header_item.js b/js/components/ascribe_table/table_header_item.js index d55347a6..56b5c16c 100644 --- a/js/components/ascribe_table/table_header_item.js +++ b/js/components/ascribe_table/table_header_item.js @@ -1,3 +1,5 @@ +'use strict'; + import React from 'react'; import TableHeaderItemCarret from './table_header_item_carret'; @@ -25,7 +27,7 @@ let TableHeaderItem = React.createClass({ if(this.props.canBeOrdered && this.props.changeOrder && this.props.orderAsc != null && this.props.orderBy) { if(this.props.columnName === this.props.orderBy) { return ( -
{this.props.displayName} @@ -33,7 +35,7 @@ let TableHeaderItem = React.createClass({ ); } else { return ( - {this.props.displayName} diff --git a/js/components/ascribe_table/table_header_item_carret.js b/js/components/ascribe_table/table_header_item_carret.js index 628ead11..d597e8c5 100644 --- a/js/components/ascribe_table/table_header_item_carret.js +++ b/js/components/ascribe_table/table_header_item_carret.js @@ -1,3 +1,5 @@ +'use strict'; + import React from 'react'; let TableHeaderItemCarret = React.createClass({ diff --git a/js/components/ascribe_table/table_item.js b/js/components/ascribe_table/table_item.js index f96839c4..a0e6e852 100644 --- a/js/components/ascribe_table/table_item.js +++ b/js/components/ascribe_table/table_item.js @@ -1,3 +1,5 @@ +'use strict'; + import React from 'react'; import { ColumnModel } from './models/table_models'; @@ -18,8 +20,7 @@ let TableItem = React.createClass({ - + columnWidth={12} /> ); } }); diff --git a/js/components/ascribe_table/table_item_acl.js b/js/components/ascribe_table/table_item_acl.js index 87e14761..1f66fd81 100644 --- a/js/components/ascribe_table/table_item_acl.js +++ b/js/components/ascribe_table/table_item_acl.js @@ -1,3 +1,5 @@ +'use strict'; + import React from 'react'; diff --git a/js/components/ascribe_table/table_item_acl_filtered.js b/js/components/ascribe_table/table_item_acl_filtered.js index 6fd8e9fe..10a419f0 100644 --- a/js/components/ascribe_table/table_item_acl_filtered.js +++ b/js/components/ascribe_table/table_item_acl_filtered.js @@ -1,3 +1,5 @@ +'use strict'; + import React from 'react'; diff --git a/js/components/ascribe_table/table_item_checkbox.js b/js/components/ascribe_table/table_item_checkbox.js index 02357fa3..131f7427 100644 --- a/js/components/ascribe_table/table_item_checkbox.js +++ b/js/components/ascribe_table/table_item_checkbox.js @@ -1,3 +1,5 @@ +'use strict'; + import React from 'react'; diff --git a/js/components/ascribe_table/table_item_img.js b/js/components/ascribe_table/table_item_img.js index c082e85a..d7670524 100644 --- a/js/components/ascribe_table/table_item_img.js +++ b/js/components/ascribe_table/table_item_img.js @@ -1,3 +1,5 @@ +'use strict'; + import React from 'react'; /** @@ -5,7 +7,7 @@ import React from 'react'; */ let TableItemImg = React.createClass({ propTypes: { - content: React.PropTypes.string.isRequired, + content: React.PropTypes.string.isRequired }, render() { diff --git a/js/components/ascribe_table/table_item_selectable.js b/js/components/ascribe_table/table_item_selectable.js index f151373e..cc53c5f0 100644 --- a/js/components/ascribe_table/table_item_selectable.js +++ b/js/components/ascribe_table/table_item_selectable.js @@ -1,3 +1,5 @@ +'use strict'; + import React from 'react'; import classNames from 'classnames'; @@ -12,7 +14,8 @@ let TableItemSelectable = React.createClass({ columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(ColumnModel)), columnContent: React.PropTypes.object, parentId: React.PropTypes.number, - className: React.PropTypes.string + className: React.PropTypes.string, + selectItem: React.PropTypes.func }, selectItem() { @@ -25,12 +28,11 @@ let TableItemSelectable = React.createClass({ }); return ( - - + onClick={this.selectItem} /> ); } diff --git a/js/components/ascribe_table/table_item_subtable.js b/js/components/ascribe_table/table_item_subtable.js index 231bb74b..56b22fa0 100644 --- a/js/components/ascribe_table/table_item_subtable.js +++ b/js/components/ascribe_table/table_item_subtable.js @@ -1,3 +1,5 @@ +'use strict'; + import React from 'react'; import { ColumnModel } from './models/table_models'; @@ -26,14 +28,18 @@ let TableItemSubtable = React.createClass({ }; }, - onChange(state) { - this.setState(state); - }, - componentDidMount() { EditionListStore.listen(this.onChange); }, + componentWillUnmount() { + EditionListStore.unlisten(this.onChange); + }, + + onChange(state) { + this.setState(state); + }, + loadEditionList() { if(this.state.open) { this.setState({ @@ -77,10 +83,9 @@ let TableItemSubtable = React.createClass({ className="ascribe-table-item-selectable" selectItem={this.selectItem} parentId={this.props.columnContent.id} - key={i}> - + key={i} /> ); - })} + })}
@@ -94,15 +99,13 @@ let TableItemSubtable = React.createClass({ - + columnWidth={12} />
- - +
{renderEditionListTable()} - + ); } }); diff --git a/js/components/ascribe_table/table_item_subtable_button.js b/js/components/ascribe_table/table_item_subtable_button.js index 8c5431d8..75aeba7f 100644 --- a/js/components/ascribe_table/table_item_subtable_button.js +++ b/js/components/ascribe_table/table_item_subtable_button.js @@ -1,3 +1,5 @@ +'use strict'; + import React from 'react'; let TableItemSubtableButton = React.createClass({ diff --git a/js/components/ascribe_table/table_item_text.js b/js/components/ascribe_table/table_item_text.js index 0e90a2d5..96dd1f16 100644 --- a/js/components/ascribe_table/table_item_text.js +++ b/js/components/ascribe_table/table_item_text.js @@ -1,3 +1,5 @@ +'use strict'; + import React from 'react'; diff --git a/js/components/ascribe_table/table_item_wrapper.js b/js/components/ascribe_table/table_item_wrapper.js index f052084e..9e1696f4 100644 --- a/js/components/ascribe_table/table_item_wrapper.js +++ b/js/components/ascribe_table/table_item_wrapper.js @@ -1,3 +1,5 @@ +'use strict'; + import React from 'react'; import Router from 'react-router'; @@ -7,13 +9,14 @@ import TableColumnMixin from '../../mixins/table_column_mixin'; let Link = Router.Link; let TableItemWrapper = React.createClass({ - mixins: [TableColumnMixin, Router.Navigation], propTypes: { columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(ColumnModel)), columnContent: React.PropTypes.object, columnWidth: React.PropTypes.number.isRequired }, + mixins: [TableColumnMixin, Router.Navigation], + render() { return ( @@ -27,7 +30,7 @@ let TableItemWrapper = React.createClass({ if(!column.transition) { return ( @@ -42,8 +45,8 @@ let TableItemWrapper = React.createClass({ */ return ( - diff --git a/js/components/edition.js b/js/components/edition.js index ee305ca1..ebd0f176 100644 --- a/js/components/edition.js +++ b/js/components/edition.js @@ -1,14 +1,21 @@ +'use strict'; + import React from 'react'; import ResourceViewer from './ascribe_media/resource_viewer'; -import EditionActions from '../actions/edition_actions' -import AclButton from './acl_button' +import EditionActions from '../actions/edition_actions'; +import AclButton from './acl_button'; /** * This is the component that implements display-specific functionality */ let Edition = React.createClass({ + propTypes: { + edition: React.PropTypes.object, + currentUser: React.PropTypes.object + }, + render() { let thumbnail = this.props.edition.thumbnail; let mimetype = this.props.edition.digital_work.mime; @@ -31,13 +38,17 @@ let Edition = React.createClass({ }); let EditionHeader = React.createClass({ + propTypes: { + edition: React.PropTypes.object + }, + render() { - var title_html =
{this.props.edition.title}
; + var titleHtml =
{this.props.edition.title}
; return (
- + - +
); @@ -45,26 +56,32 @@ let EditionHeader = React.createClass({ }); let EditionDetails = React.createClass({ + propTypes: { + edition: React.PropTypes.object, + currentUser: React.PropTypes.object + }, + handleSuccess(){ EditionActions.fetchOne(this.props.edition.id); }, + render() { return (
+ value={this.props.edition.edition_number + ' of ' + this.props.edition.num_editions} />
diff --git a/js/components/edition_container.js b/js/components/edition_container.js index ca56bda7..09009248 100644 --- a/js/components/edition_container.js +++ b/js/components/edition_container.js @@ -1,3 +1,5 @@ +'use strict'; + import React from 'react'; import { mergeOptions } from '../utils/general_utils'; @@ -28,6 +30,7 @@ let EditionContainer = React.createClass({ UserActions.fetchCurrentUser(); EditionActions.fetchOne(this.props.params.editionId); }, + componentWillUnmount() { EditionStore.unlisten(this.onChange); UserStore.unlisten(this.onChange); @@ -36,10 +39,9 @@ let EditionContainer = React.createClass({ render() { if('title' in this.state.edition) { return ( - - + ); } else { return ( diff --git a/js/components/fatal_error.js b/js/components/fatal_error.js deleted file mode 100644 index e69de29b..00000000 diff --git a/js/components/header.js b/js/components/header.js index a53b628e..e26553a3 100644 --- a/js/components/header.js +++ b/js/components/header.js @@ -1,13 +1,13 @@ +'use strict'; + import React from 'react'; import Router from 'react-router'; -import AltContainer from 'alt/AltContainer'; import UserActions from '../actions/user_actions'; import UserStore from '../stores/user_store'; import Nav from 'react-bootstrap/lib/Nav'; import Navbar from 'react-bootstrap/lib/Navbar'; -import NavItem from 'react-bootstrap/lib/NavItem'; import DropdownButton from 'react-bootstrap/lib/DropdownButton'; import MenuItem from 'react-bootstrap/lib/MenuItem'; @@ -22,7 +22,7 @@ let Header = React.createClass({ }, componentDidMount() { - UserStore.listen(this.onChange) + UserStore.listen(this.onChange); UserActions.fetchCurrentUser(); }, diff --git a/js/components/piece_list.js b/js/components/piece_list.js index 22a115e1..479b9c3f 100644 --- a/js/components/piece_list.js +++ b/js/components/piece_list.js @@ -1,5 +1,6 @@ +'use strict'; + import React from 'react'; -import AltContainer from 'alt/AltContainer'; import PieceListStore from '../stores/piece_list_store'; import PieceListActions from '../actions/piece_list_actions'; @@ -15,7 +16,10 @@ import PieceListToolbar from './ascribe_piece_list_toolbar/piece_list_toolbar'; let PieceList = React.createClass({ - + propTypes: { + query: React.PropTypes.object + }, + getInitialState() { return PieceListStore.getState(); }, @@ -35,7 +39,7 @@ let PieceList = React.createClass({ }, paginationGoToPage(page) { - return (e) => PieceListActions.fetchPieceList(page, this.state.pageSize, + return () => PieceListActions.fetchPieceList(page, this.state.pageSize, this.state.search, this.state.orderBy, this.state.orderAsc); }, @@ -47,8 +51,8 @@ let PieceList = React.createClass({ render() { let currentPage = parseInt(this.props.query.page, 10) || 1; - let totalPages = Math.ceil(this.state.pieceListCount / this.state.pageSize) - + let totalPages = Math.ceil(this.state.pieceListCount / this.state.pageSize); + return (
@@ -64,11 +68,11 @@ let PieceList = React.createClass({ pageSize={this.state.pageSize}> {this.state.pieceList.map((item, i) => { return ( - - - + goToPage={this.paginationGoToPage} />
); } diff --git a/js/constants/api_urls.js b/js/constants/api_urls.js index db846a72..7d466561 100644 --- a/js/constants/api_urls.js +++ b/js/constants/api_urls.js @@ -1,17 +1,19 @@ +'use strict'; + import AppConstants from './application_constants'; let apiUrls = { - 'ownership_shares_mail' : AppConstants.baseUrl + 'ownership/shares/mail/', - 'ownership_transfers' : AppConstants.baseUrl + 'ownership/transfers/', + 'ownership_shares_mail': AppConstants.baseUrl + 'ownership/shares/mail/', + 'ownership_transfers': AppConstants.baseUrl + 'ownership/transfers/', 'user': AppConstants.baseUrl + 'users/', 'pieces_list': AppConstants.baseUrl + 'pieces/', 'piece': AppConstants.baseUrl + 'pieces/${piece_id}', 'edition': AppConstants.baseUrl + 'editions/${bitcoin_id}/', 'editions_list': AppConstants.baseUrl + 'pieces/${piece_id}/editions/', - 'ownership_loans' : AppConstants.baseUrl + 'ownership/loans/', - 'ownership_consigns' : AppConstants.baseUrl + 'ownership/consigns/', - 'ownership_unconsigns' : AppConstants.baseUrl + 'ownership/unconsigns/', - 'ownership_unconsigns_request' : AppConstants.baseUrl + 'ownership/unconsigns/request/' + 'ownership_loans': AppConstants.baseUrl + 'ownership/loans/', + 'ownership_consigns': AppConstants.baseUrl + 'ownership/consigns/', + 'ownership_unconsigns': AppConstants.baseUrl + 'ownership/unconsigns/', + 'ownership_unconsigns_request': AppConstants.baseUrl + 'ownership/unconsigns/request/' }; export default apiUrls; diff --git a/js/constants/application_constants.js b/js/constants/application_constants.js index b235d1d4..25486919 100644 --- a/js/constants/application_constants.js +++ b/js/constants/application_constants.js @@ -1,3 +1,5 @@ +'use strict'; + let constants = { //'baseUrl': 'http://localhost:8000/api/', 'baseUrl': 'http://staging.ascribe.io/api/', diff --git a/js/constants/languages.js b/js/constants/languages.js index 47e29ee0..f673083d 100644 --- a/js/constants/languages.js +++ b/js/constants/languages.js @@ -1,3 +1,5 @@ +'use strict'; + const languages = { 'en-US': { 'Bitcoin Address': 'Bitcoin Address', diff --git a/js/fetchers/edition_fetcher.js b/js/fetchers/edition_fetcher.js index 46cdf1b7..bb995523 100644 --- a/js/fetchers/edition_fetcher.js +++ b/js/fetchers/edition_fetcher.js @@ -1,13 +1,11 @@ +'use strict'; + import fetch from '../utils/fetch'; -import AppConstants from '../constants/application_constants'; - - let EditionFetcher = { /** * Fetch one user from the API. * If no arg is supplied, load the current user - * */ fetchOne(editionId) { return fetch.get('edition', {'bitcoin_id': editionId}); diff --git a/js/fetchers/edition_list_fetcher.js b/js/fetchers/edition_list_fetcher.js index 2cec37a7..21ebee58 100644 --- a/js/fetchers/edition_list_fetcher.js +++ b/js/fetchers/edition_list_fetcher.js @@ -1,9 +1,9 @@ +'use strict'; + import fetch from '../utils/fetch'; import { generateOrderingQueryParams } from '../utils/fetch_api_utils'; -import AppConstants from '../constants/application_constants'; - let EditionListFetcher = { /** diff --git a/js/fetchers/ownership_fetcher.js b/js/fetchers/ownership_fetcher.js index 94050860..57cef4b9 100644 --- a/js/fetchers/ownership_fetcher.js +++ b/js/fetchers/ownership_fetcher.js @@ -1,14 +1,14 @@ +'use strict'; + import fetch from 'isomorphic-fetch'; import AppConstants from '../constants/application_constants'; -import FetchApiUtils from '../utils/fetch_api_utils'; let OwnershipFetcher = { /** * Fetch one user from the API. * If no arg is supplied, load the current user - * */ fetchLoanContract(email) { return fetch(AppConstants.baseUrl + 'ownership/loans/contract/?loanee=' + email, { diff --git a/js/fetchers/piece_fetcher.js b/js/fetchers/piece_fetcher.js index cf37c4d3..a5317e5f 100644 --- a/js/fetchers/piece_fetcher.js +++ b/js/fetchers/piece_fetcher.js @@ -1,15 +1,14 @@ -import fetch from '../utils/fetch'; +'use strict'; -import AppConstants from '../constants/application_constants'; +import fetch from '../utils/fetch'; let PieceFetcher = { /** * Fetch one user from the API. * If no arg is supplied, load the current user - * */ - fetchOne(pieceId) { + fetchOne() { return fetch.get('piece'); } }; diff --git a/js/fetchers/piece_list_fetcher.js b/js/fetchers/piece_list_fetcher.js index ed867253..2f706e15 100644 --- a/js/fetchers/piece_list_fetcher.js +++ b/js/fetchers/piece_list_fetcher.js @@ -1,4 +1,5 @@ -import AppConstants from '../constants/application_constants'; +'use strict'; + import { generateOrderingQueryParams } from '../utils/fetch_api_utils'; import fetch from '../utils/fetch'; diff --git a/js/fetchers/user_fetcher.js b/js/fetchers/user_fetcher.js index df3e887e..c57c93d9 100644 --- a/js/fetchers/user_fetcher.js +++ b/js/fetchers/user_fetcher.js @@ -1,13 +1,12 @@ -import fetch from '../utils/fetch'; +'use strict'; -import AppConstants from '../constants/application_constants'; +import fetch from '../utils/fetch'; let UserFetcher = { /** * Fetch one user from the API. * If no arg is supplied, load the current user - * */ fetchOne() { return fetch.get('user'); diff --git a/js/mixins/alert_mixin.js b/js/mixins/alert_mixin.js index f52890c7..2b9b5158 100644 --- a/js/mixins/alert_mixin.js +++ b/js/mixins/alert_mixin.js @@ -1,15 +1,17 @@ +'use strict'; + import React from 'react'; import AlertDismissable from '../components/ascribe_forms/alert'; let AlertMixin = { setAlerts(errors){ - let alerts = errors.map( - function(error) { - return ; - }.bind(this) - ); + let alerts = errors.map((error) => { + return ; + }); + this.setState({alerts: alerts}); }, + clearAlerts(){ this.setState({alerts: null}); } diff --git a/js/mixins/form_mixin.js b/js/mixins/form_mixin.js index 4e2c7045..fa398390 100644 --- a/js/mixins/form_mixin.js +++ b/js/mixins/form_mixin.js @@ -1,8 +1,9 @@ +'use strict'; + import fetch from '../utils/fetch'; import React from 'react'; -import AppConstants from '../constants/application_constants' -import AlertDismissable from '../components/ascribe_forms/alert' +import AlertDismissable from '../components/ascribe_forms/alert'; export const FormMixin = { getInitialState() { @@ -10,7 +11,7 @@ export const FormMixin = { submitted: false , status: null , errors: [] - } + }; }, submit(e) { @@ -18,7 +19,7 @@ export const FormMixin = { this.setState({submitted: true}); fetch .post(this.url(), { body: this.getFormData() }) - .then(response => { this.props.handleSuccess(); }) + .then(() => { this.props.handleSuccess(); }) .catch(this.handleError); }, @@ -40,31 +41,29 @@ export const FormMixin = { getBitcoinIds(){ return this.props.editions.map(function(edition){ - return edition.bitcoin_id - }) + return edition.bitcoin_id; + }); }, getTitlesString(){ return this.props.editions.map(function(edition){ - return '- \"' + edition.title + ', edition ' + edition.edition_number + '\"\n' - }) + return '- \"' + edition.title + ', edition ' + edition.edition_number + '\"\n'; + }); }, render(){ let alert = null; if (this.state.errors.length > 0){ - alert = this.state.errors.map( - function(error) { - return ; - }.bind(this) - ); + alert = this.state.errors.map((error) => { + return ; + }); } return (
{alert} {this.renderForm()}
- ) + ); } }; diff --git a/js/mixins/inject_in_head_mixin.js b/js/mixins/inject_in_head_mixin.js index 72ecdfe1..f88fa035 100644 --- a/js/mixins/inject_in_head_mixin.js +++ b/js/mixins/inject_in_head_mixin.js @@ -1,12 +1,14 @@ +'use strict'; + let mapAttr = { link: 'href', source: 'src' -} +}; let mapExt = { js: 'source', css: 'link' -} +}; let InjectInHeadMixin = { @@ -23,9 +25,9 @@ let InjectInHeadMixin = { }, injectTag(tag, src){ - console.log(this.foobar); - if (InjectInHeadMixin.isPresent(tag, src)) + if (InjectInHeadMixin.isPresent(tag, src)) { return; + } let attr = mapAttr[tag]; let element = document.createElement(tag); @@ -49,6 +51,8 @@ let InjectInHeadMixin = { } catch (e) { throw new Error(`Cannot inject ${src} in the DOM, cannot guess the tag name from extension ${ext}. Valid extensions are "js" and "css".`); } + // ES6Lint says tag is not defined, pls fix + // - Tim InjectInHeadMixin.injectTag(tag, src); } diff --git a/js/mixins/modal_mixin.js b/js/mixins/modal_mixin.js index 7dee243b..6087f32c 100644 --- a/js/mixins/modal_mixin.js +++ b/js/mixins/modal_mixin.js @@ -1,9 +1,10 @@ -import React from 'react'; +'use strict'; let ModalMixin = { onRequestHide(e){ - if (e) + if (e) { e.preventDefault(); + } this.props.onRequestHide(); } }; diff --git a/js/mixins/table_column_mixin.js b/js/mixins/table_column_mixin.js index eac266b6..b8813433 100644 --- a/js/mixins/table_column_mixin.js +++ b/js/mixins/table_column_mixin.js @@ -1,4 +1,4 @@ -import React from 'react'; +'use strict'; import { sumNumList } from '../utils/general_utils'; @@ -14,7 +14,7 @@ let TableColumnMixin = { let numOfUsedColumns = sumNumList(listOfRowValues); 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.') + 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]; } diff --git a/js/routes.js b/js/routes.js index ab515462..eeadc564 100644 --- a/js/routes.js +++ b/js/routes.js @@ -1,3 +1,5 @@ +'use strict'; + import React from 'react'; import Router from 'react-router'; @@ -10,11 +12,8 @@ let Route = Router.Route; let routes = ( - - - - - + + ); diff --git a/js/stores/edition_list_store.js b/js/stores/edition_list_store.js index 3121744e..67993ff9 100644 --- a/js/stores/edition_list_store.js +++ b/js/stores/edition_list_store.js @@ -1,3 +1,5 @@ +'use strict'; + import React from 'react'; import alt from '../alt'; @@ -15,7 +17,7 @@ class EditionListStore { // 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; @@ -26,7 +28,7 @@ class EditionListStore { * Default values for both are set in the editon_list-actions. */ this.editionList[pieceId].orderBy = orderBy; - this.editionList[pieceId].orderAsc = orderAsc + this.editionList[pieceId].orderAsc = orderAsc; } onSelectEdition({pieceId, editionId}) { @@ -55,6 +57,6 @@ class EditionListStore { }); }); } -}; +} export default alt.createStore(EditionListStore); \ No newline at end of file diff --git a/js/stores/edition_store.js b/js/stores/edition_store.js index b33e248f..7579c8d8 100644 --- a/js/stores/edition_store.js +++ b/js/stores/edition_store.js @@ -1,3 +1,5 @@ +'use strict'; + import alt from '../alt'; import EditionActions from '../actions/edition_actions'; diff --git a/js/stores/piece_list_store.js b/js/stores/piece_list_store.js index 493ebfc4..d61d6c07 100644 --- a/js/stores/piece_list_store.js +++ b/js/stores/piece_list_store.js @@ -1,4 +1,5 @@ -import React from 'react'; +'use strict'; + import alt from '../alt'; import PieceListActions from '../actions/piece_list_actions'; @@ -7,7 +8,7 @@ import PieceListActions from '../actions/piece_list_actions'; class PieceListStore { constructor() { /** - * The store manages the state that is introduced by fetching + * The store manages the state that is introduced by fetching * the resource with certain parameters. * * This means that pieceList for example only contains pageSize-many items. @@ -20,8 +21,8 @@ class PieceListStore { this.pieceListCount = 0; this.page = 1; this.pageSize = 10; - this.search = ""; - this.orderBy = "artist_name"; + this.search = ''; + this.orderBy = 'artist_name'; this.orderAsc = true; this.bindActions(PieceListActions); } @@ -58,13 +59,13 @@ class PieceListStore { * Pagination - Known Issue: * ######################### * - * + * * The piece list store currently stores the open/close state of a piece list item. * - * Once a new page is requested, this.pieceList will be overwritten, which means that the + * Once a new page is requested, this.pieceList will be overwritten, which means that the * open/close state of a specific list item will be thrown away. * - * This means that when opening an editionListTable on a piece, and continuing + * This means that when opening an editionListTable on a piece, and continuing * clicking next or back in the pagination, the editionListTable will return to its * default value, which is "close". * @@ -73,6 +74,6 @@ class PieceListStore { */ this.pieceList = pieceList; } -}; +} export default alt.createStore(PieceListStore); diff --git a/js/stores/piece_store.js b/js/stores/piece_store.js index 35e8c229..f9693564 100644 --- a/js/stores/piece_store.js +++ b/js/stores/piece_store.js @@ -1,3 +1,5 @@ +'use strict'; + import alt from '../alt'; import PieceAction from '../actions/piece_actions'; diff --git a/js/stores/user_store.js b/js/stores/user_store.js index 6ae631c9..e1b4dd29 100644 --- a/js/stores/user_store.js +++ b/js/stores/user_store.js @@ -1,3 +1,5 @@ +'use strict'; + import alt from '../alt'; import UserAction from '../actions/user_actions'; diff --git a/js/utils/fetch.js b/js/utils/fetch.js index f7e12f43..ec674935 100644 --- a/js/utils/fetch.js +++ b/js/utils/fetch.js @@ -1,11 +1,13 @@ +'use strict'; + import { default as _fetch } from 'isomorphic-fetch'; import { argsToQueryParams } from '../utils/fetch_api_utils'; -class UrlMapError extends Error {}; -class ServerError extends Error {}; -class APIError extends Error {}; +class UrlMapError extends Error {} +class ServerError extends Error {} +class APIError extends Error {} class Fetch { @@ -33,7 +35,7 @@ class Fetch { } handleAPIError(json) { - if (!json['success']) { + if (!json.success) { let error = new APIError(); error.json = json; throw error; @@ -58,7 +60,7 @@ class Fetch { let re = /\${(\w+)}/g; newUrl = newUrl.replace(re, (match, key) => { - let val = params[key] + let val = params[key]; if (!val) { throw new Error(`Cannot find param ${key}`); } @@ -76,7 +78,7 @@ class Fetch { request(verb, url, options) { options = options || {}; let merged = this._merge(this.httpOptions, options); - merged['method'] = verb; + merged.method = verb; return _fetch(url, merged) .then(this.unpackResponse) .then(JSON.parse) @@ -95,8 +97,8 @@ class Fetch { let newUrl = this.prepareUrl(url, params); let body = null; - if (params['body']) { - body = JSON.stringify(params['body']) + if (params.body) { + body = JSON.stringify(params.body); } return this.request('post', url, { body }); } diff --git a/js/utils/fetch_api_utils.js b/js/utils/fetch_api_utils.js index bf66a45c..272e29f3 100644 --- a/js/utils/fetch_api_utils.js +++ b/js/utils/fetch_api_utils.js @@ -1,3 +1,5 @@ +'use strict'; + import { sanitize } from './general_utils'; // TODO: Create Unittests that test all functions @@ -16,7 +18,7 @@ import { sanitize } from './general_utils'; * ?page=1&page_size=10 * * CamelCase gets converted to snake_case! - * + * */ export function argsToQueryParams(obj) { @@ -38,10 +40,10 @@ export function argsToQueryParams(obj) { return s + snakeCaseKey + '=' + encodeURIComponent(obj[key]); }) .join(''); -}; +} /** - * Takes a string and a boolean and generates a string query parameter for + * Takes a string and a boolean and generates a string query parameter for * an API call. */ export function generateOrderingQueryParams(orderBy, orderAsc) { @@ -52,11 +54,11 @@ export function generateOrderingQueryParams(orderBy, orderAsc) { } return interpolation + orderBy; -}; +} export function status(response) { if (response.status >= 200 && response.status < 300) { - return response + return response; } - throw new Error(response.json()) -}; + throw new Error(response.json()); +} diff --git a/js/utils/general_utils.js b/js/utils/general_utils.js index 2eedc1af..4caf3d15 100644 --- a/js/utils/general_utils.js +++ b/js/utils/general_utils.js @@ -1,3 +1,5 @@ +'use strict'; + // TODO: Create Unittests that test all functions export function sanitize(obj) { @@ -12,7 +14,7 @@ export function sanitize(obj) { }); return obj; -}; +} /** * Returns the values of an object. @@ -21,7 +23,7 @@ export function valuesOfObject(obj) { return Object .keys(obj) .map(key => obj[key]); -}; +} /** * Sums up a list of numbers. Like a Epsilon-math-kinda-sum... @@ -30,11 +32,14 @@ export function sumNumList(l) { let sum = 0; l.forEach((num) => sum += parseFloat(num) || 0); return sum; -}; +} /* Taken from http://stackoverflow.com/a/4795914/1263876 Behaves like C's format string function + + REFACTOR TO ES6 (let instead of var) + */ export function formatText() { var args = arguments, @@ -60,7 +65,7 @@ export function formatText() { } return val; }); -}; +} /** * Takes a list of object and merges their keys to one object. @@ -72,11 +77,11 @@ export function mergeOptions(...l) { let newObj = {}; for(let i = 1; i < l.length; i++) { - newObj = _mergeOptions(newObj, _mergeOptions(l[i-1], l[i])); + newObj = _mergeOptions(newObj, _mergeOptions(l[i - 1], l[i])); } return newObj; -}; +} /** * Overwrites obj1's values with obj2's and adds obj2's if non existent in obj1 @@ -85,9 +90,9 @@ export function mergeOptions(...l) { * @returns obj3 a new object based on obj1 and obj2 * Taken from: http://stackoverflow.com/a/171256/1263876 */ -function _mergeOptions(obj1,obj2){ - var obj3 = {}; - for (var attrname in obj1) { obj3[attrname] = obj1[attrname]; } - for (var attrname in obj2) { obj3[attrname] = obj2[attrname]; } +function _mergeOptions(obj1, obj2){ + let obj3 = {}; + for (let attrname in obj1) { obj3[attrname] = obj1[attrname]; } + for (let attrname in obj2) { obj3[attrname] = obj2[attrname]; } return obj3; -}; +} diff --git a/js/utils/lang_utils.js b/js/utils/lang_utils.js index d1ea5fd5..bf842efa 100644 --- a/js/utils/lang_utils.js +++ b/js/utils/lang_utils.js @@ -1,3 +1,5 @@ +'use strict'; + import languages from '../constants/languages'; import { formatText } from './general_utils'; @@ -27,4 +29,4 @@ export function getLangText(s, ...args) { } } -}; +} From 18a2806fb1cfa51aa7d79f662d7a2e49501e0791 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Fri, 5 Jun 2015 11:32:10 +0200 Subject: [PATCH 21/21] minor fixes --- js/components/ascribe_table/table.js | 2 +- js/components/edition.js | 5 ++++- js/mixins/inject_in_head_mixin.js | 1 - 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/js/components/ascribe_table/table.js b/js/components/ascribe_table/table.js index 6a8f0c93..44ba5d61 100644 --- a/js/components/ascribe_table/table.js +++ b/js/components/ascribe_table/table.js @@ -15,7 +15,7 @@ let Table = React.createClass({ orderBy: React.PropTypes.string, orderAsc: React.PropTypes.bool, className: React.PropTypes.string, - children: React.PropTypes.object, + children: React.PropTypes.array, itemList: React.PropTypes.array }, diff --git a/js/components/edition.js b/js/components/edition.js index ebd0f176..9094e20b 100644 --- a/js/components/edition.js +++ b/js/components/edition.js @@ -97,7 +97,10 @@ let EditionDetails = React.createClass({ let EditionDetailProperty = React.createClass({ propTypes: { label: React.PropTypes.string, - value: React.PropTypes.string + value: React.PropTypes.oneOfType([ + React.PropTypes.string, + React.PropTypes.element + ]) }, render() { diff --git a/js/mixins/inject_in_head_mixin.js b/js/mixins/inject_in_head_mixin.js index f88fa035..42e3b6dc 100644 --- a/js/mixins/inject_in_head_mixin.js +++ b/js/mixins/inject_in_head_mixin.js @@ -44,7 +44,6 @@ let InjectInHeadMixin = { }, inject(src) { - //debugger; let ext = src.split('.').pop(); try { let tag = mapAttr(src);