mirror of
https://github.com/ascribe/onion.git
synced 2025-01-03 10:25:08 +01:00
Merge remote-tracking branch 'origin/master' into piece-detail-mediaplayer
Conflicts: js/components/ascribe_media/resource_viewer.js
This commit is contained in:
commit
d44cf295f0
@ -11,13 +11,15 @@ class EditionListActions {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchEditionList(pieceId) {
|
fetchEditionList(pieceId, orderBy, orderAsc) {
|
||||||
EditionListFetcher
|
EditionListFetcher
|
||||||
.fetch(pieceId)
|
.fetch(pieceId, orderBy, orderAsc)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.actions.updateEditionList({
|
this.actions.updateEditionList({
|
||||||
'editionListOfPiece': res.editions,
|
'editionListOfPiece': res.editions,
|
||||||
pieceId
|
pieceId,
|
||||||
|
orderBy,
|
||||||
|
orderAsc
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import Router from 'react-router';
|
||||||
|
|
||||||
import AccordionListItemTable from './accordion_list_item_table';
|
import AccordionListItemTable from './accordion_list_item_table';
|
||||||
|
|
||||||
import { getLangText } from '../../utils/lang_utils';
|
import { getLangText } from '../../utils/lang_utils';
|
||||||
|
|
||||||
|
let Link = Router.Link;
|
||||||
|
|
||||||
let AccordionListItem = React.createClass({
|
let AccordionListItem = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
className: React.PropTypes.string,
|
className: React.PropTypes.string,
|
||||||
|
@ -14,7 +14,10 @@ let AccordionListItemTable = React.createClass({
|
|||||||
itemList: React.PropTypes.array,
|
itemList: React.PropTypes.array,
|
||||||
columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(TableColumnContentModel)),
|
columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(TableColumnContentModel)),
|
||||||
numOfTableItems: React.PropTypes.number,
|
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() {
|
render() {
|
||||||
@ -23,7 +26,10 @@ let AccordionListItemTable = React.createClass({
|
|||||||
<div className={this.props.className}>
|
<div className={this.props.className}>
|
||||||
<Table
|
<Table
|
||||||
columnList={this.props.columnList}
|
columnList={this.props.columnList}
|
||||||
itemList={this.props.itemList}>
|
itemList={this.props.itemList}
|
||||||
|
changeOrder={this.props.changeOrder}
|
||||||
|
orderBy={this.props.orderBy}
|
||||||
|
orderAsc={this.props.orderAsc}>
|
||||||
{this.props.itemList.map((item, i) => {
|
{this.props.itemList.map((item, i) => {
|
||||||
return (
|
return (
|
||||||
<TableItem
|
<TableItem
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import Router from 'react-router';
|
||||||
|
|
||||||
import EditionListStore from '../../stores/edition_list_store';
|
import EditionListStore from '../../stores/edition_list_store';
|
||||||
import EditionListActions from '../../actions/edition_list_actions';
|
import EditionListActions from '../../actions/edition_list_actions';
|
||||||
@ -7,6 +8,7 @@ import PieceListActions from '../../actions/piece_list_actions';
|
|||||||
|
|
||||||
import AccordionListItemTable from './accordion_list_item_table';
|
import AccordionListItemTable from './accordion_list_item_table';
|
||||||
import AccordionListItemTableToggle from './accordion_list_item_table_toggle';
|
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 TableColumnContentModel from '../../models/table_column_content_model';
|
||||||
|
|
||||||
@ -17,6 +19,8 @@ import TableItemAclFiltered from '../ascribe_table/table_item_acl_filtered';
|
|||||||
|
|
||||||
import { getLangText } from '../../utils/lang_utils';
|
import { getLangText } from '../../utils/lang_utils';
|
||||||
|
|
||||||
|
let Link = Router.Link;
|
||||||
|
|
||||||
let AccordionListItemTableEditions = React.createClass({
|
let AccordionListItemTableEditions = React.createClass({
|
||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
@ -46,12 +50,40 @@ let AccordionListItemTableEditions = React.createClass({
|
|||||||
EditionListActions.selectEdition({pieceId, editionId});
|
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() {
|
toggleTable() {
|
||||||
PieceListActions.showEditionList(this.props.parentId);
|
PieceListActions.showEditionList(this.props.parentId);
|
||||||
EditionListActions.fetchEditionList(this.props.parentId);
|
EditionListActions.fetchEditionList(this.props.parentId, this.state.orderBy, this.state.orderAsc);
|
||||||
|
},
|
||||||
|
|
||||||
|
changeEditionListOrder(orderBy, orderAsc) {
|
||||||
|
EditionListActions.fetchEditionList(this.props.parentId, orderBy, orderAsc);
|
||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
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 = [
|
let columnList = [
|
||||||
new TableColumnContentModel(
|
new TableColumnContentModel(
|
||||||
(item) => {
|
(item) => {
|
||||||
@ -62,7 +94,10 @@ let AccordionListItemTableEditions = React.createClass({
|
|||||||
'selected': item.selected
|
'selected': item.selected
|
||||||
}},
|
}},
|
||||||
'',
|
'',
|
||||||
'',
|
<AccordionListItemTableSelectAllEditionsToggle
|
||||||
|
onChange={this.selectAllItems}
|
||||||
|
numOfSelectedEditions={selectedEditionsCount}
|
||||||
|
numOfAllEditions={allEditionsCount}/>,
|
||||||
TableItemCheckbox,
|
TableItemCheckbox,
|
||||||
1,
|
1,
|
||||||
false
|
false
|
||||||
@ -72,11 +107,12 @@ let AccordionListItemTableEditions = React.createClass({
|
|||||||
return {
|
return {
|
||||||
'content': item.edition_number
|
'content': item.edition_number
|
||||||
}},
|
}},
|
||||||
'num_editions',
|
'edition_number',
|
||||||
'#',
|
'#',
|
||||||
TableItemText,
|
TableItemText,
|
||||||
1,
|
1,
|
||||||
false
|
true,
|
||||||
|
{to: 'edition', paramsKey: 'editionId', contentKey: 'bitcoin_id'}
|
||||||
),
|
),
|
||||||
new TableColumnContentModel(
|
new TableColumnContentModel(
|
||||||
(item) => {
|
(item) => {
|
||||||
@ -87,7 +123,8 @@ let AccordionListItemTableEditions = React.createClass({
|
|||||||
getLangText('Bitcoin Address'),
|
getLangText('Bitcoin Address'),
|
||||||
TableItemText,
|
TableItemText,
|
||||||
5,
|
5,
|
||||||
false
|
true,
|
||||||
|
{to: 'edition', paramsKey: 'editionId', contentKey: 'bitcoin_id'}
|
||||||
),
|
),
|
||||||
new TableColumnContentModel(
|
new TableColumnContentModel(
|
||||||
(item) => {
|
(item) => {
|
||||||
@ -98,7 +135,8 @@ let AccordionListItemTableEditions = React.createClass({
|
|||||||
getLangText('Actions'),
|
getLangText('Actions'),
|
||||||
TableItemAclFiltered,
|
TableItemAclFiltered,
|
||||||
4,
|
4,
|
||||||
false
|
false,
|
||||||
|
{to: 'edition', paramsKey: 'editionId', contentKey: 'bitcoin_id'}
|
||||||
)
|
)
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -110,7 +148,10 @@ let AccordionListItemTableEditions = React.createClass({
|
|||||||
itemList={this.state.editionList[this.props.parentId]}
|
itemList={this.state.editionList[this.props.parentId]}
|
||||||
columnList={columnList}
|
columnList={columnList}
|
||||||
numOfTableItems={this.props.numOfEditions}
|
numOfTableItems={this.props.numOfEditions}
|
||||||
show={this.props.show}>
|
show={this.props.show}
|
||||||
|
orderBy={this.state.orderBy}
|
||||||
|
orderAsc={this.state.orderAsc}
|
||||||
|
changeOrder={this.changeEditionListOrder}>
|
||||||
<AccordionListItemTableToggle
|
<AccordionListItemTableToggle
|
||||||
className="ascribe-accordion-list-table-toggle"
|
className="ascribe-accordion-list-table-toggle"
|
||||||
onClick={this.toggleTable}
|
onClick={this.toggleTable}
|
||||||
|
@ -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 (
|
||||||
|
<input type="checkbox"
|
||||||
|
onChange={this.props.onChange}
|
||||||
|
checked={this.props.numOfAllEditions === this.props.numOfSelectedEditions} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default AccordionListItemTableSelectAllEditionsToggle;
|
@ -9,7 +9,9 @@ let Table = React.createClass({
|
|||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(TableColumnContentModel)),
|
columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(TableColumnContentModel)),
|
||||||
changeOrder: React.PropTypes.func
|
changeOrder: React.PropTypes.func,
|
||||||
|
orderBy: React.PropTypes.string,
|
||||||
|
orderAsc: React.PropTypes.bool,
|
||||||
},
|
},
|
||||||
|
|
||||||
renderChildren() {
|
renderChildren() {
|
||||||
@ -29,7 +31,6 @@ let Table = React.createClass({
|
|||||||
<TableHeader
|
<TableHeader
|
||||||
columnList={this.props.columnList}
|
columnList={this.props.columnList}
|
||||||
itemList={this.props.itemList}
|
itemList={this.props.itemList}
|
||||||
fetchList={this.props.fetchList}
|
|
||||||
changeOrder={this.props.changeOrder}
|
changeOrder={this.props.changeOrder}
|
||||||
orderAsc={this.props.orderAsc}
|
orderAsc={this.props.orderAsc}
|
||||||
orderBy={this.props.orderBy} />
|
orderBy={this.props.orderBy} />
|
||||||
|
@ -6,7 +6,10 @@ let TableHeaderItem = React.createClass({
|
|||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
columnClasses: React.PropTypes.string.isRequired,
|
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,
|
columnName: React.PropTypes.string.isRequired,
|
||||||
canBeOrdered: React.PropTypes.bool,
|
canBeOrdered: React.PropTypes.bool,
|
||||||
changeOrder: React.PropTypes.func,
|
changeOrder: React.PropTypes.func,
|
||||||
|
@ -1,16 +1,31 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import Router from 'react-router';
|
||||||
|
|
||||||
import TableColumnContentModel from '../../models/table_column_content_model';
|
import TableColumnContentModel from '../../models/table_column_content_model';
|
||||||
import TableColumnMixin from '../../mixins/table_column_mixin';
|
import TableColumnMixin from '../../mixins/table_column_mixin';
|
||||||
|
|
||||||
let TableItemWrapper = React.createClass({
|
let TableItemWrapper = React.createClass({
|
||||||
mixins: [TableColumnMixin],
|
mixins: [TableColumnMixin, Router.Navigation],
|
||||||
propTypes: {
|
propTypes: {
|
||||||
columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(TableColumnContentModel)),
|
columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(TableColumnContentModel)),
|
||||||
columnContent: React.PropTypes.object,
|
columnContent: React.PropTypes.object,
|
||||||
columnWidth: React.PropTypes.number.isRequired
|
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() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
@ -21,8 +36,13 @@ let TableItemWrapper = React.createClass({
|
|||||||
|
|
||||||
let columnClass = this.calcColumnClasses(this.props.columnList, i, this.props.columnWidth);
|
let columnClass = this.calcColumnClasses(this.props.columnList, i, this.props.columnWidth);
|
||||||
|
|
||||||
|
let transition = this.transition.bind(this, column);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={columnClass + ' ascribe-table-item-column'} key={i}>
|
<div
|
||||||
|
className={columnClass + ' ascribe-table-item-column'}
|
||||||
|
key={i}
|
||||||
|
onClick={transition}>
|
||||||
<TypeElement {...typeElementProps} />
|
<TypeElement {...typeElementProps} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import fetch from '../utils/fetch';
|
import fetch from '../utils/fetch';
|
||||||
|
|
||||||
|
import { generateOrderingQueryParams } from '../utils/fetch_api_utils';
|
||||||
|
|
||||||
import AppConstants from '../constants/application_constants';
|
import AppConstants from '../constants/application_constants';
|
||||||
|
|
||||||
|
|
||||||
@ -7,8 +9,9 @@ let EditionListFetcher = {
|
|||||||
/**
|
/**
|
||||||
* Fetches a list of editions from the API.
|
* Fetches a list of editions from the API.
|
||||||
*/
|
*/
|
||||||
fetch(pieceId) {
|
fetch(pieceId, orderBy, orderAsc) {
|
||||||
return fetch.get('editions_list', { 'piece_id': pieceId });
|
let ordering = generateOrderingQueryParams(orderBy, orderAsc);
|
||||||
|
return fetch.get('editions_list', { 'piece_id': pieceId, ordering });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
class TableColumnContentModel {
|
class TableColumnContentModel {
|
||||||
// ToDo: Add validation for all passed-in parameters
|
// 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.transformFn = transformFn;
|
||||||
this.columnName = columnName;
|
this.columnName = columnName;
|
||||||
this.displayName = displayName;
|
this.displayName = displayName;
|
||||||
this.displayType = displayType;
|
this.displayType = displayType;
|
||||||
this.rowWidth = rowWidth;
|
this.rowWidth = rowWidth;
|
||||||
this.canBeOrdered = canBeOrdered;
|
this.canBeOrdered = canBeOrdered;
|
||||||
|
this.link = link;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,10 +6,12 @@ import EditionsListActions from '../actions/edition_list_actions';
|
|||||||
class EditionListStore {
|
class EditionListStore {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.editionList = {};
|
this.editionList = {};
|
||||||
|
this.orderBy = 'edition_number';
|
||||||
|
this.orderAsc = true;
|
||||||
this.bindActions(EditionsListActions);
|
this.bindActions(EditionsListActions);
|
||||||
}
|
}
|
||||||
|
|
||||||
onUpdateEditionList({pieceId, editionListOfPiece}) {
|
onUpdateEditionList({pieceId, editionListOfPiece, orderBy, orderAsc}) {
|
||||||
if(this.editionList[pieceId]) {
|
if(this.editionList[pieceId]) {
|
||||||
this.editionList[pieceId].forEach((edition, i) => {
|
this.editionList[pieceId].forEach((edition, i) => {
|
||||||
// This uses the index of the new editionList for determining the edition.
|
// This uses the index of the new editionList for determining the edition.
|
||||||
@ -18,6 +20,8 @@ class EditionListStore {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
this.editionList[pieceId] = editionListOfPiece;
|
this.editionList[pieceId] = editionListOfPiece;
|
||||||
|
this.orderBy = orderBy;
|
||||||
|
this.orderAsc = orderAsc;
|
||||||
}
|
}
|
||||||
|
|
||||||
onSelectEdition({pieceId, editionId}) {
|
onSelectEdition({pieceId, editionId}) {
|
||||||
|
@ -43,8 +43,23 @@ class PieceListStore {
|
|||||||
this.search = search;
|
this.search = search;
|
||||||
this.orderAsc = orderAsc;
|
this.orderAsc = orderAsc;
|
||||||
this.orderBy = orderBy;
|
this.orderBy = orderBy;
|
||||||
this.pieceList = pieceList;
|
|
||||||
this.pieceListCount = pieceListCount;
|
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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ import { formatText } from './general_utils';
|
|||||||
export function getLangText(s, ...args) {
|
export function getLangText(s, ...args) {
|
||||||
let lang = navigator.language || navigator.userLanguage;
|
let lang = navigator.language || navigator.userLanguage;
|
||||||
// this is just for testing, as changing the navigator.language wasn't possible
|
// this is just for testing, as changing the navigator.language wasn't possible
|
||||||
lang = 'de';
|
//lang = 'de';
|
||||||
try {
|
try {
|
||||||
if(lang in languages) {
|
if(lang in languages) {
|
||||||
return formatText(languages[lang][s], args);
|
return formatText(languages[lang][s], args);
|
||||||
|
Loading…
Reference in New Issue
Block a user