From 47dd322cff7bcde10f0e7111ded67f385ee29737 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Fri, 22 May 2015 14:15:12 +0200 Subject: [PATCH 1/3] Add dynamically injectable TableItems to Table Component --- js/components/ascribe_table/table.js | 8 +++++--- js/components/piece_list.js | 4 +++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/js/components/ascribe_table/table.js b/js/components/ascribe_table/table.js index d95ea4c7..71c97658 100644 --- a/js/components/ascribe_table/table.js +++ b/js/components/ascribe_table/table.js @@ -1,17 +1,19 @@ import React from 'react'; -import TableItem from './table_item'; import TableHeader from './table_header'; - import TableColumnModel from '../../models/table_column_model'; let Table = React.createClass({ + propTypes: { columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(TableColumnModel)), - changeOrder: React.PropTypes.func.isRequired + changeOrder: React.PropTypes.func.isRequired, + tableItem: React.PropTypes.any.isRequired // Optimally, this should check if tableItem is an instance of React.Component or something like that }, + render() { + let TableItem = this.props.tableItem; if(this.props.itemList && this.props.itemList.length > 0) { return ( diff --git a/js/components/piece_list.js b/js/components/piece_list.js index be3bfbe3..6c04b499 100644 --- a/js/components/piece_list.js +++ b/js/components/piece_list.js @@ -5,6 +5,7 @@ import PieceListStore from '../stores/piece_list_store'; import PieceListActions from '../actions/piece_list_actions'; import Table from './ascribe_table/table'; +import TableItem from './ascribe_table/table_item'; import TableItemImg from './ascribe_table/table_item_img'; import TableItemText from './ascribe_table/table_item_text'; @@ -56,7 +57,8 @@ let PieceList = React.createClass({ 'pageSize': props.pageSize } }}> - +
+
); From 4c0e7992f48f2063b02e9b3d6e3e8311ad990ed9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Fri, 22 May 2015 16:51:08 +0200 Subject: [PATCH 2/3] Inject elements-to-transclude in the table --- css/main.css | 5 ++ js/actions/edition_list_actions.js | 6 +- js/components/ascribe_table/table.js | 31 ++++++---- js/components/ascribe_table/table_header.js | 4 +- js/components/ascribe_table/table_item.js | 13 +--- .../ascribe_table/table_item_subtable.js | 61 +++++++++++++++++++ .../table_item_subtable_button.js | 20 ++++++ js/components/edition_list.js | 32 ---------- js/components/piece_list.js | 24 +++++--- js/fetchers/edition_list_fetcher.js | 4 +- ...model.js => table_column_content_model.js} | 5 +- js/stores/edition_list_store.js | 6 +- 12 files changed, 135 insertions(+), 76 deletions(-) create mode 100644 js/components/ascribe_table/table_item_subtable.js create mode 100644 js/components/ascribe_table/table_item_subtable_button.js delete mode 100644 js/components/edition_list.js rename js/models/{table_column_model.js => table_column_content_model.js} (68%) diff --git a/css/main.css b/css/main.css index 30ea36cc..5e19671b 100644 --- a/css/main.css +++ b/css/main.css @@ -51,3 +51,8 @@ display:table-cell; vertical-align: middle; } + +.btn-ascribe, .btn-ascribe:hover, .btn-ascribe:active, .btn-ascribe:focus { + background-color: rgba(2, 182, 163, 0.5); + border-color: rgba(2, 182, 163, 0.5); +} \ No newline at end of file diff --git a/js/actions/edition_list_actions.js b/js/actions/edition_list_actions.js index 35c43764..21c84017 100644 --- a/js/actions/edition_list_actions.js +++ b/js/actions/edition_list_actions.js @@ -9,11 +9,11 @@ class EditionListActions { ); } - fetchList() { + fetchList(pieceId) { EditionListFetcher - .fetch() + .fetch(pieceId) .then((res) => { - this.actions.updateEditionList(res.pieces); + this.actions.updateEditionList(res.editions); }) .catch((err) => { console.log(err); diff --git a/js/components/ascribe_table/table.js b/js/components/ascribe_table/table.js index 71c97658..550cf1a4 100644 --- a/js/components/ascribe_table/table.js +++ b/js/components/ascribe_table/table.js @@ -1,32 +1,39 @@ import React from 'react'; +import ReactAddons from 'react/addons'; import TableHeader from './table_header'; -import TableColumnModel from '../../models/table_column_model'; +import TableColumnContentModel from '../../models/table_column_content_model'; let Table = React.createClass({ propTypes: { - columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(TableColumnModel)), - changeOrder: React.PropTypes.func.isRequired, - tableItem: React.PropTypes.any.isRequired // Optimally, this should check if tableItem is an instance of React.Component or something like that + columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(TableColumnContentModel)), + changeOrder: React.PropTypes.func.isRequired + }, + + renderChildren() { + var that = this; + return ReactAddons.Children.map(this.props.children, (child) => { + return that.props.itemList.map((item, i) => { + return ReactAddons.addons.cloneWithProps(child, { + columnList: this.props.columnList, + columnContent: item, + key: i + }); + }); + }); }, render() { - let TableItem = this.props.tableItem; - + if(this.props.itemList && this.props.itemList.length > 0) { return (
- {this.props.itemList.map((item, i) => { - return ( - - ); - })} + {this.renderChildren()}
); - } else { return (

Loading

diff --git a/js/components/ascribe_table/table_header.js b/js/components/ascribe_table/table_header.js index 853990bf..564f7725 100644 --- a/js/components/ascribe_table/table_header.js +++ b/js/components/ascribe_table/table_header.js @@ -4,13 +4,13 @@ import TableColumnMixin from '../../mixins/table_column_mixin'; import GeneralUtils from '../../utils/general_utils'; import TableHeaderItem from './table_header_item'; -import TableColumnModel from '../../models/table_column_model'; +import TableColumnContentModel from '../../models/table_column_content_model'; let TableHeader = React.createClass({ mixins: [TableColumnMixin], propTypes: { - columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(TableColumnModel)), + columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(TableColumnContentModel)), itemList: React.PropTypes.array.isRequired, changeOrder: React.PropTypes.func.isRequired, orderAsc: React.PropTypes.bool.isRequired, diff --git a/js/components/ascribe_table/table_item.js b/js/components/ascribe_table/table_item.js index 05f9942a..23f91201 100644 --- a/js/components/ascribe_table/table_item.js +++ b/js/components/ascribe_table/table_item.js @@ -1,26 +1,19 @@ import React from 'react'; import TableColumnMixin from '../../mixins/table_column_mixin'; -import TableItemImg from './table_item_img'; -import TableItemText from './table_item_text'; -import TableColumnModel from '../../models/table_column_model'; +import TableColumnContentModel from '../../models/table_column_content_model'; let TableItem = React.createClass({ mixins: [TableColumnMixin], propTypes: { - columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(TableColumnModel)), - columnContent: React.PropTypes.object.isRequired + columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(TableColumnContentModel)), + columnContent: React.PropTypes.object }, render() { - - /** - * An element in the Table can have a certain display_type. - * A display_type is just - */ let calcColumnElementContent = () => { return this.props.columnList.map((column, i) => { diff --git a/js/components/ascribe_table/table_item_subtable.js b/js/components/ascribe_table/table_item_subtable.js new file mode 100644 index 00000000..453b0c06 --- /dev/null +++ b/js/components/ascribe_table/table_item_subtable.js @@ -0,0 +1,61 @@ +import React from 'react'; + +import TableColumnContentModel from '../../models/table_column_content_model'; + +// ToDo: Create Table-specific Utils to not lock it to projects utilities +import GeneralUtils from '../../utils/general_utils'; + +import TableItemSubtableButton from './table_item_subtable_button'; + + +let TableItemSubtable = React.createClass({ + propTypes: { + columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(TableColumnContentModel)), + columnContent: React.PropTypes.object + }, + + calcColumnClasses(list, i) { + let bootstrapClasses = ['col-xs-', 'col-sm-', 'col-md-', 'col-lg-']; + + let listOfRowValues = list.map((column) => column.rowWidth ); + let numOfColumns = GeneralUtils.sumNumList(listOfRowValues); + + if(numOfColumns > 10) { + throw new Error('Bootstrap has only 12 columns to assign. You defined ' + numOfColumns + '. Change this in the columnMap you\'re passing to the table.') + } else { + return bootstrapClasses.join( listOfRowValues[i] + ' ') + listOfRowValues[i]; + } + }, + + render() { + + let calcColumnElementContent = () => { + return this.props.columnList.map((column, i) => { + + let TypeElement = column.displayType; + let columnClass = this.calcColumnClasses(this.props.columnList, i); + + return ( +
+ +
+ ); + + }); + }; + + return ( +
+
+ {calcColumnElementContent()} +
+ + +
+
+
+ ); + } +}); + +export default TableItemSubtable; diff --git a/js/components/ascribe_table/table_item_subtable_button.js b/js/components/ascribe_table/table_item_subtable_button.js new file mode 100644 index 00000000..c2579ea8 --- /dev/null +++ b/js/components/ascribe_table/table_item_subtable_button.js @@ -0,0 +1,20 @@ +import React from 'react'; + +let TableItemSubtableButton = React.createClass({ + + propTypes: { + content: React.PropTypes.string.isRequired + }, + + render() { + return ( + + + + ); + } +}); + +export default TableItemSubtableButton; \ No newline at end of file diff --git a/js/components/edition_list.js b/js/components/edition_list.js deleted file mode 100644 index f1325eb4..00000000 --- a/js/components/edition_list.js +++ /dev/null @@ -1,32 +0,0 @@ -import React from 'react'; -import AltContainer from 'alt/AltContainer'; - -import EditionListStore from '../stores/edition_list_store'; -import EditionListActions from '../actions/edition_list_actions'; - -import Table from './ascribe_table/table'; -import TableItemText from './ascribe_table/table_item_text'; - -import TableColumnModel from '../models/table_column_model'; - -let EditionList = React.createClass({ - - getInitialState() { - return EditionListStore.getState(); - }, - - componentDidMount() { - EditionListActions.fetchList(); - }, - - render() { - return ( - -
-
- ); - } - -}); - -export default EditionList; \ No newline at end of file diff --git a/js/components/piece_list.js b/js/components/piece_list.js index 6c04b499..b89df670 100644 --- a/js/components/piece_list.js +++ b/js/components/piece_list.js @@ -4,12 +4,17 @@ import AltContainer from 'alt/AltContainer'; import PieceListStore from '../stores/piece_list_store'; import PieceListActions from '../actions/piece_list_actions'; +import EditionListStore from '../stores/edition_list_store'; +import EditionListActions from '../actions/edition_list_actions'; + import Table from './ascribe_table/table'; import TableItem from './ascribe_table/table_item'; import TableItemImg from './ascribe_table/table_item_img'; import TableItemText from './ascribe_table/table_item_text'; +import TableItemSubtable from './ascribe_table/table_item_subtable'; +import TableItemSubtableButton from './ascribe_table/table_item_subtable_button'; -import TableColumnModel from '../models/table_column_model'; +import TableColumnContentModel from '../models/table_column_content_model'; import Pagination from './pagination' @@ -22,8 +27,7 @@ let PieceList = React.createClass({ componentDidMount() { let page = this.props.query.page || this.state.page; - PieceListActions.fetchPieceList(page, this.state.pageSize, this.state.search, - this.state.orderBy, this.state.orderAsc); + PieceListActions.fetchPieceList(page, this.state.pageSize, this.state.search, this.state.orderBy, this.state.orderAsc); }, paginationGoToPage(page) { @@ -36,16 +40,15 @@ let PieceList = React.createClass({ render() { let columnList = [ - new TableColumnModel('thumbnail', '', TableItemImg, 2, false), - new TableColumnModel('artist_name', 'Artist', TableItemText, 4, true), - new TableColumnModel('title', 'Title', TableItemText, 4, true) + new TableColumnContentModel('thumbnail', '', TableItemImg, 2, false), + new TableColumnContentModel('artist_name', 'Artist', TableItemText, 4, true), + new TableColumnContentModel('title', 'Title', TableItemText, 4, true) ]; // Could wrap this altContainer potentially once again. return ( { return { 'itemList': props.pieceList, @@ -54,10 +57,11 @@ let PieceList = React.createClass({ 'orderAsc': props.orderAsc, 'search': props.search, 'page': props.page, - 'pageSize': props.pageSize + 'pageSize': props.pageSize, } }}> - +
+
diff --git a/js/fetchers/edition_list_fetcher.js b/js/fetchers/edition_list_fetcher.js index 353915c6..2cf4bd35 100644 --- a/js/fetchers/edition_list_fetcher.js +++ b/js/fetchers/edition_list_fetcher.js @@ -7,9 +7,9 @@ let EditionListFetcher = { /** * Fetches a list of editions from the API. */ - fetch() { + fetch(pieceId) { - return fetch(AppConstants.baseUrl + 'pieces/', { + return fetch(AppConstants.baseUrl + 'pieces/' + pieceId + '/editions/', { headers: { 'Authorization': 'Basic ' + AppConstants.debugCredentialBase64 } diff --git a/js/models/table_column_model.js b/js/models/table_column_content_model.js similarity index 68% rename from js/models/table_column_model.js rename to js/models/table_column_content_model.js index 770be6d1..4084fb4a 100644 --- a/js/models/table_column_model.js +++ b/js/models/table_column_content_model.js @@ -1,4 +1,5 @@ -class TableColumnItem { +class TableColumnContentModel { + // ToDo: Add validation for all passed-in parameters constructor(columnName, displayName, displayType, rowWidth, canBeOrdered) { this.columnName = columnName; this.displayName = displayName; @@ -8,4 +9,4 @@ class TableColumnItem { } } -export default TableColumnItem; \ No newline at end of file +export default TableColumnContentModel; \ No newline at end of file diff --git a/js/stores/edition_list_store.js b/js/stores/edition_list_store.js index c8034465..0412122b 100644 --- a/js/stores/edition_list_store.js +++ b/js/stores/edition_list_store.js @@ -3,12 +3,12 @@ import EditionsListActions from '../actions/edition_list_actions'; class EditionListStore { constructor() { - this.itemList = []; + this.editionList = []; this.bindActions(EditionsListActions); } - onUpdateEditionList(itemList) { - this.itemList = itemList; + onUpdateEditionList(editionList) { + this.editionList = editionList; } }; From 0927d021c975efd6779ee08bfa050b754686f290 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Fri, 22 May 2015 18:41:15 +0200 Subject: [PATCH 3/3] put architecture for transcluding TableItem in place --- js/actions/edition_list_actions.js | 2 +- js/components/ascribe_table/table.js | 2 +- .../ascribe_table/table_item_subtable.js | 21 ++++++++++++++++++- js/components/piece_list.js | 2 +- 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/js/actions/edition_list_actions.js b/js/actions/edition_list_actions.js index 21c84017..e8381b53 100644 --- a/js/actions/edition_list_actions.js +++ b/js/actions/edition_list_actions.js @@ -9,7 +9,7 @@ class EditionListActions { ); } - fetchList(pieceId) { + fetchEditionList(pieceId) { EditionListFetcher .fetch(pieceId) .then((res) => { diff --git a/js/components/ascribe_table/table.js b/js/components/ascribe_table/table.js index 550cf1a4..c5ef0fbb 100644 --- a/js/components/ascribe_table/table.js +++ b/js/components/ascribe_table/table.js @@ -9,7 +9,7 @@ let Table = React.createClass({ propTypes: { columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(TableColumnContentModel)), - changeOrder: React.PropTypes.func.isRequired + changeOrder: React.PropTypes.func // turn isRequired on again after editions order implemented }, renderChildren() { diff --git a/js/components/ascribe_table/table_item_subtable.js b/js/components/ascribe_table/table_item_subtable.js index 453b0c06..b2ca4349 100644 --- a/js/components/ascribe_table/table_item_subtable.js +++ b/js/components/ascribe_table/table_item_subtable.js @@ -14,6 +14,25 @@ let TableItemSubtable = React.createClass({ columnContent: React.PropTypes.object }, + getInitialState() { + return { + 'open': false + }; + }, + + onChange(state) { + this.setState(state); + }, + + componentDidMount() { + this.props.store.listen(this.onChange); + }, + + loadEditionList() { + console.log(this.props); + //this.props.actions.actions.fetchEditionList(); + }, + calcColumnClasses(list, i) { let bootstrapClasses = ['col-xs-', 'col-sm-', 'col-md-', 'col-lg-']; @@ -49,7 +68,7 @@ let TableItemSubtable = React.createClass({
{calcColumnElementContent()}
- +
diff --git a/js/components/piece_list.js b/js/components/piece_list.js index b89df670..54b56382 100644 --- a/js/components/piece_list.js +++ b/js/components/piece_list.js @@ -61,7 +61,7 @@ let PieceList = React.createClass({ } }}> - +