From 48508d5756f96774c0ee7edd6b7ee1dad01f4bd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Wed, 16 Sep 2015 21:21:30 +0200 Subject: [PATCH 01/18] Implement filter display for piece list --- .../ascribe_accordion_list/accordion_list.js | 2 +- js/components/piece_list.js | 8 ++-- js/components/piece_list_filter_display.js | 45 +++++++++++++++++++ sass/ascribe_accordion_list.scss | 4 ++ sass/main.scss | 20 +++++++++ 5 files changed, 75 insertions(+), 4 deletions(-) create mode 100644 js/components/piece_list_filter_display.js diff --git a/js/components/ascribe_accordion_list/accordion_list.js b/js/components/ascribe_accordion_list/accordion_list.js index 471ba9d5..fe300702 100644 --- a/js/components/ascribe_accordion_list/accordion_list.js +++ b/js/components/ascribe_accordion_list/accordion_list.js @@ -21,7 +21,7 @@ let AccordionList = React.createClass({ ); } else if(this.props.count === 0) { return ( -
+

{getLangText('We could not find any works related to you...')}

{getLangText('To register one, click')} {getLangText('here')}!

diff --git a/js/components/piece_list.js b/js/components/piece_list.js index 71304a63..c7cab0f4 100644 --- a/js/components/piece_list.js +++ b/js/components/piece_list.js @@ -15,6 +15,8 @@ import AccordionListItemTableEditions from './ascribe_accordion_list/accordion_l import Pagination from './ascribe_pagination/pagination'; +import PieceListFilterDisplay from './piece_list_filter_display'; + import GlobalAction from './global_action'; import PieceListBulkModal from './ascribe_piece_list_bulk_modal/piece_list_bulk_modal'; import PieceListToolbar from './ascribe_piece_list_toolbar/piece_list_toolbar'; @@ -22,6 +24,8 @@ import PieceListToolbar from './ascribe_piece_list_toolbar/piece_list_toolbar'; import AppConstants from '../constants/application_constants'; import { mergeOptions } from '../utils/general_utils'; +import { getLangText } from '../utils/lang_utils'; + let PieceList = React.createClass({ propTypes: { @@ -149,9 +153,6 @@ let PieceList = React.createClass({ let loadingElement = (); let AccordionListItemType = this.props.accordionListItemType; - // - - return (
+ filter.split('acl_')[1]).join(', '); + + // there are acls, like acl_create_editions that still have underscores in them, + // therefore we need to replace all underscores with spaces + return filterText.replace(/_/g, ' '); + }, + + render() { + let { filterBy } = this.props; + + // do not show the FilterDisplay if there are no filters applied + if(filterBy && Object.keys(filterBy).length === 0) { + return null; + } else { + return ( +
+
+ {this.getFilterText()} +
+
+
+ ); + } + } +}); + +export default PieceListFilterDisplay; \ No newline at end of file diff --git a/sass/ascribe_accordion_list.scss b/sass/ascribe_accordion_list.scss index 6412a598..86a519b5 100644 --- a/sass/ascribe_accordion_list.scss +++ b/sass/ascribe_accordion_list.scss @@ -5,6 +5,10 @@ $ascribe-accordion-list-item-height: 8em; padding-right: 15px; } +.ascribe-accordion-list-placeholder { + margin-top: 1em; +} + .ascribe-accordion-list-item { background-color: white; border: 1px solid black; diff --git a/sass/main.scss b/sass/main.scss index 5f5c0f23..39ea78bd 100644 --- a/sass/main.scss +++ b/sass/main.scss @@ -487,3 +487,23 @@ hr { .ascribe-progress-bar-xs { height: 12px; } + + +.ascribe-piece-list-filter-display { + padding-left: 0; + padding-right: 0; + + > span { + font-size: 1.1em; + font-weight: 600; + color: #616161; + + padding-left: .3em; + } + + > hr { + margin-top: .15em; + margin-bottom: .1em; + border-color: #ccc; + } +} \ No newline at end of file From a96aa1005fba0db7dd770ef2f0872e897adbcc83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Wed, 16 Sep 2015 23:36:21 +0200 Subject: [PATCH 02/18] Make PieceListToolbar filters generic --- .../piece_list_toolbar.js | 7 +- .../piece_list_toolbar_filter_widget.js | 71 +++++++++++-------- js/components/piece_list.js | 18 +++-- js/components/piece_list_filter_display.js | 66 ++++++++++++++--- sass/ascribe_piece_list_toolbar.scss | 10 ++- sass/main.scss | 4 +- 6 files changed, 126 insertions(+), 50 deletions(-) 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 233f4089..ea609155 100644 --- a/js/components/ascribe_piece_list_toolbar/piece_list_toolbar.js +++ b/js/components/ascribe_piece_list_toolbar/piece_list_toolbar.js @@ -14,7 +14,12 @@ let PieceListToolbar = React.createClass({ propTypes: { className: React.PropTypes.string, searchFor: React.PropTypes.func, - filterParams: React.PropTypes.array, + filterParams: React.PropTypes.arrayOf( + React.PropTypes.shape({ + label: React.PropTypes.string, + items: React.PropTypes.array + }) + ), filterBy: React.PropTypes.object, applyFilterBy: React.PropTypes.func, orderParams: React.PropTypes.array, 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 2520c499..9591f970 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 @@ -16,7 +16,12 @@ let PieceListToolbarFilterWidgetFilter = React.createClass({ // label: // } // - filterParams: React.PropTypes.arrayOf(React.PropTypes.any).isRequired, + filterParams: React.PropTypes.arrayOf( + React.PropTypes.shape({ + label: React.PropTypes.string, + items: React.PropTypes.array + }) + ).isRequired, filterBy: React.PropTypes.object, applyFilterBy: React.PropTypes.func }, @@ -79,35 +84,43 @@ let PieceListToolbarFilterWidgetFilter = React.createClass({ -
  • - {getLangText('Show works I can')}: -
  • - {this.props.filterParams.map((param, i) => { - let label; - - if(typeof param !== 'string') { - label = param.label; - param = param.key; - } else { - param = param; - label = param.split('_')[1]; - } - + {this.props.filterParams.map(({ label, items }, i) => { return ( - -
    - - {getLangText(label)} - - -
    -
    +
    +
  • + {label}: +
  • + {items.map((param, j) => { + let label; + + if(typeof param !== 'string') { + label = param.label; + param = param.key; + } else { + param = param; + label = param.split('_')[1]; + } + + return ( +
  • +
    + + {getLangText(label)} + + +
    +
  • + ); + })} +
    ); })}
    diff --git a/js/components/piece_list.js b/js/components/piece_list.js index c7cab0f4..dd8ee91e 100644 --- a/js/components/piece_list.js +++ b/js/components/piece_list.js @@ -35,7 +35,6 @@ let PieceList = React.createClass({ filterParams: React.PropTypes.array, orderParams: React.PropTypes.array, orderBy: React.PropTypes.string - }, mixins: [Router.Navigation, Router.State], @@ -44,13 +43,20 @@ let PieceList = React.createClass({ return { accordionListItemType: AccordionListItemWallet, orderParams: ['artist_name', 'title'], - filterParams: [ + filterParams: [{ + label: getLangText('Show works I can'), + items: [ 'acl_transfer', 'acl_consign', { key: 'acl_create_editions', label: 'create editions' }] + }, + { + label: getLangText('Show works I have'), + items: ['acl_loaned'] + }] }; }, getInitialState() { @@ -95,8 +101,8 @@ let PieceList = React.createClass({ // the site should go to the top document.body.scrollTop = document.documentElement.scrollTop = 0; PieceListActions.fetchPieceList(page, this.state.pageSize, this.state.search, - this.state.orderBy, this.state.orderAsc, - this.state.filterBy); + this.state.orderBy, this.state.orderAsc, + this.state.filterBy); }; }, @@ -167,7 +173,9 @@ let PieceList = React.createClass({ {this.props.customSubmitButton}
    - + filter.split('acl_')[1]).join(', '); + return filterParams.map((filterParam) => { + return { + label: filterParam.label, + items: filterParam.items.map((item) => { + if(typeof item !== 'string' && typeof item.key === 'string' && typeof item.label === 'string') { + return { + key: item.key, + label: item.label, + value: filterBy[item.key] ? filterBy[item.key] : false + }; + } else { + return { + key: item, + label: item.split('acl_')[1].replace(/_/g, ' '), + value: filterBy[item] ? filterBy[item] : false + } + } + }) + } + }); + }, - // there are acls, like acl_create_editions that still have underscores in them, - // therefore we need to replace all underscores with spaces - return filterText.replace(/_/g, ' '); + getFilterText(filtersWithLabel) { + let filterTextList = filtersWithLabel + .map((filterWithLabel) => { + let activeFilterWithLabel = filterWithLabel + .items + .map((filter) => { + if(filter.value) { + return filter.label; + } + }) + .filter((filterName) => !!filterName) + .join(', '); + + if(activeFilterWithLabel) { + return filterWithLabel.label + ': ' + activeFilterWithLabel + } + }) + .filter((filterText) => !!filterText) + // if there are multiple sentences, capitalize the first one and lowercase the others + .map((filterText, i) => i === 0 ? filterText.charAt(0).toUpperCase() + filterText.substr(1) : filterText.charAt(0).toLowerCase() + filterText.substr(1)) + .join(' and '); + + return filterTextList; }, render() { let { filterBy } = this.props; + let filtersWithLabel = this.transformFilterParamsItemsToBools(); // do not show the FilterDisplay if there are no filters applied if(filterBy && Object.keys(filterBy).length === 0) { @@ -33,7 +77,7 @@ let PieceListFilterDisplay = React.createClass({ return (
    - {this.getFilterText()} + {this.getFilterText(filtersWithLabel)}
    diff --git a/sass/ascribe_piece_list_toolbar.scss b/sass/ascribe_piece_list_toolbar.scss index aeec1bff..dde7f2f0 100644 --- a/sass/ascribe_piece_list_toolbar.scss +++ b/sass/ascribe_piece_list_toolbar.scss @@ -54,8 +54,7 @@ } .filter-widget-item { - - > a { + a { padding-left: 0; padding-right: 0; } @@ -64,6 +63,13 @@ .checkbox-line { height: 25px; position: relative; + color: #333333; + + /* Fuck you react-bootstrap */ + &:hover { + background-color: $dropdown-link-hover-bg; + cursor: pointer; + } span { cursor: pointer; diff --git a/sass/main.scss b/sass/main.scss index 39ea78bd..e7170b6d 100644 --- a/sass/main.scss +++ b/sass/main.scss @@ -490,8 +490,8 @@ hr { .ascribe-piece-list-filter-display { - padding-left: 0; - padding-right: 0; + padding-left: 10px; + padding-right: 10px; > span { font-size: 1.1em; From 67e0b3464089ac4f7586690f10aaf1290951cbad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Thu, 17 Sep 2015 10:06:47 +0200 Subject: [PATCH 03/18] integrate filtering into IkonoTv and Cyland whitelabel --- js/components/piece_list.js | 4 ---- .../wallet/components/cyland/cyland_piece_list.js | 9 +++++++++ .../wallet/components/ikonotv/ikonotv_piece_list.js | 11 ++++++++++- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/js/components/piece_list.js b/js/components/piece_list.js index dd8ee91e..7ecbd0f0 100644 --- a/js/components/piece_list.js +++ b/js/components/piece_list.js @@ -52,10 +52,6 @@ let PieceList = React.createClass({ key: 'acl_create_editions', label: 'create editions' }] - }, - { - label: getLangText('Show works I have'), - items: ['acl_loaned'] }] }; }, diff --git a/js/components/whitelabel/wallet/components/cyland/cyland_piece_list.js b/js/components/whitelabel/wallet/components/cyland/cyland_piece_list.js index 018a3e55..3b1c70c0 100644 --- a/js/components/whitelabel/wallet/components/cyland/cyland_piece_list.js +++ b/js/components/whitelabel/wallet/components/cyland/cyland_piece_list.js @@ -8,6 +8,8 @@ import UserStore from '../../../../../stores/user_store'; import CylandAccordionListItem from './ascribe_accordion_list/cyland_accordion_list_item'; +import { getLangText } from '../../../../../utils/lang_utils'; + let CylandPieceList = React.createClass({ getInitialState() { @@ -33,6 +35,13 @@ let CylandPieceList = React.createClass({
    ); diff --git a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_piece_list.js b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_piece_list.js index 4c8766e4..33478fbf 100644 --- a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_piece_list.js +++ b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_piece_list.js @@ -8,6 +8,9 @@ import UserStore from '../../../../../stores/user_store'; import IkonotvAccordionListItem from './ascribe_accordion_list/ikonotv_accordion_list_item'; +import { getLangText } from '../../../../../utils/lang_utils'; + + let IkonotvPieceList = React.createClass({ getInitialState() { return UserStore.getState(); @@ -32,7 +35,13 @@ let IkonotvPieceList = React.createClass({ + filterParams={[{ + label: getLangText('Show works I have'), + items: [{ + key: 'acl_loaned', + label: getLangText('loaned to IkonoTV') + }] + }]}/>
    ); } From ace465afad0b403206dc329ace1964475c954ed0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Thu, 17 Sep 2015 10:20:35 +0200 Subject: [PATCH 04/18] Improve PropTypes for PieceListToolbarFilterWidget --- .../piece_list_toolbar.js | 10 ++++++++- .../piece_list_toolbar_filter_widget.js | 21 +++++++++---------- js/components/piece_list_filter_display.js | 18 ++++++++++------ 3 files changed, 31 insertions(+), 18 deletions(-) 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 ea609155..0890db00 100644 --- a/js/components/ascribe_piece_list_toolbar/piece_list_toolbar.js +++ b/js/components/ascribe_piece_list_toolbar/piece_list_toolbar.js @@ -17,7 +17,15 @@ let PieceListToolbar = React.createClass({ filterParams: React.PropTypes.arrayOf( React.PropTypes.shape({ label: React.PropTypes.string, - items: React.PropTypes.array + items: React.PropTypes.arrayOf( + React.PropTypes.oneOfType([ + React.PropTypes.string, + React.PropTypes.shape({ + key: React.PropTypes.string, + label: React.PropTypes.string + }) + ]) + ) }) ), filterBy: React.PropTypes.object, 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 9591f970..eb36bbd5 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 @@ -3,23 +3,24 @@ import React from 'react'; import DropdownButton from 'react-bootstrap/lib/DropdownButton'; -import MenuItem from 'react-bootstrap/lib/MenuItem'; import { getLangText } from '../../utils/lang_utils.js'; + let PieceListToolbarFilterWidgetFilter = React.createClass({ propTypes: { - // An array of either strings (which represent acl enums) or objects of the form - // - // { - // key: , - // label: - // } - // filterParams: React.PropTypes.arrayOf( React.PropTypes.shape({ label: React.PropTypes.string, - items: React.PropTypes.array + items: React.PropTypes.arrayOf( + React.PropTypes.oneOfType([ + React.PropTypes.string, + React.PropTypes.shape({ + key: React.PropTypes.string, + label: React.PropTypes.string + }) + ]) + ) }) ).isRequired, filterBy: React.PropTypes.object, @@ -93,8 +94,6 @@ let PieceListToolbarFilterWidgetFilter = React.createClass({ {label}: {items.map((param, j) => { - let label; - if(typeof param !== 'string') { label = param.label; param = param.key; diff --git a/js/components/piece_list_filter_display.js b/js/components/piece_list_filter_display.js index 971adb82..e1cbf9bd 100644 --- a/js/components/piece_list_filter_display.js +++ b/js/components/piece_list_filter_display.js @@ -2,8 +2,6 @@ import React from 'react'; -import { getLangText } from '../utils/lang_utils'; - let PieceListFilterDisplay = React.createClass({ propTypes: { @@ -11,7 +9,15 @@ let PieceListFilterDisplay = React.createClass({ filterParams: React.PropTypes.arrayOf( React.PropTypes.shape({ label: React.PropTypes.string, - items: React.PropTypes.array + items: React.PropTypes.arrayOf( + React.PropTypes.oneOfType([ + React.PropTypes.string, + React.PropTypes.shape({ + key: React.PropTypes.string, + label: React.PropTypes.string + }) + ]) + ) }) ) }, @@ -34,10 +40,10 @@ let PieceListFilterDisplay = React.createClass({ key: item, label: item.split('acl_')[1].replace(/_/g, ' '), value: filterBy[item] ? filterBy[item] : false - } + }; } }) - } + }; }); }, @@ -55,7 +61,7 @@ let PieceListFilterDisplay = React.createClass({ .join(', '); if(activeFilterWithLabel) { - return filterWithLabel.label + ': ' + activeFilterWithLabel + return filterWithLabel.label + ': ' + activeFilterWithLabel; } }) .filter((filterText) => !!filterText) From ac09c721ca1fb2204478a231ee9a02df7ad0e669 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Thu, 17 Sep 2015 10:41:23 +0200 Subject: [PATCH 05/18] Document PieceListToolbarFilterWidget and PieceListFilterDisplay --- .../piece_list_toolbar_filter_widget.js | 12 ++++++++++ js/components/piece_list_filter_display.js | 23 +++++++++++++++++++ 2 files changed, 35 insertions(+) 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 eb36bbd5..07f66cd1 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 @@ -85,6 +85,8 @@ let PieceListToolbarFilterWidgetFilter = React.createClass({ + {/* We iterate over filterParams, to receive the label and then for each + label also iterate over its items, to get all filterable options */} {this.props.filterParams.map(({ label, items }, i) => { return (
    @@ -94,6 +96,16 @@ let PieceListToolbarFilterWidgetFilter = React.createClass({ {label}: {items.map((param, j) => { + + // As can be seen in the PropTypes, a param can either + // be a string or an object of the shape: + // + // { + // key: , + // label: + // } + // + // This is why we need to distinguish between both here. if(typeof param !== 'string') { label = param.label; param = param.key; diff --git a/js/components/piece_list_filter_display.js b/js/components/piece_list_filter_display.js index e1cbf9bd..e1c19bdd 100644 --- a/js/components/piece_list_filter_display.js +++ b/js/components/piece_list_filter_display.js @@ -22,6 +22,12 @@ let PieceListFilterDisplay = React.createClass({ ) }, + /** + * Takes the above described filterParams prop, + * assigns it it's true filterBy value that is derived from the filterBy prop + * and also - if there wasn't already one defined - generates a label + * @return {object} + */ transformFilterParamsItemsToBools() { let { filterParams, filterBy } = this.props; @@ -47,23 +53,40 @@ let PieceListFilterDisplay = React.createClass({ }); }, + /** + * Takes the list of filters generated in transformFilterParamsItemsToBools and + * transforms them into human readable text. + * @param {Object} filtersWithLabel An object of the shape {key: , label: , value: } + * @return {string} A human readable string + */ getFilterText(filtersWithLabel) { let filterTextList = filtersWithLabel + // Iterate over all provided filterLabels and generate a list + // of human readable strings .map((filterWithLabel) => { let activeFilterWithLabel = filterWithLabel .items + // If the filter is active (which it is when its value is true), + // we're going to include it's label into a list, + // otherwise we'll just return nothing .map((filter) => { if(filter.value) { return filter.label; } }) + // if nothing is returned, that index is 'undefined'. + // As we only want active filter, we filter out all falsy values e.g. undefined .filter((filterName) => !!filterName) + // and join the result to a string .join(', '); + // If this actually didn't generate an empty string, + // we take the label and concat it to the result. if(activeFilterWithLabel) { return filterWithLabel.label + ': ' + activeFilterWithLabel; } }) + // filter out strings that are undefined, as their filter's were not activated .filter((filterText) => !!filterText) // if there are multiple sentences, capitalize the first one and lowercase the others .map((filterText, i) => i === 0 ? filterText.charAt(0).toUpperCase() + filterText.substr(1) : filterText.charAt(0).toLowerCase() + filterText.substr(1)) From cf39b1e708e7787ad89245c0314867871b64e9fd Mon Sep 17 00:00:00 2001 From: Cevo Date: Thu, 17 Sep 2015 11:17:47 +0200 Subject: [PATCH 06/18] min year changed to 1 --- js/components/ascribe_forms/form_register_piece.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/components/ascribe_forms/form_register_piece.js b/js/components/ascribe_forms/form_register_piece.js index 8f2666c0..541840c0 100644 --- a/js/components/ascribe_forms/form_register_piece.js +++ b/js/components/ascribe_forms/form_register_piece.js @@ -128,7 +128,7 @@ let RegisterPieceForm = React.createClass({ {this.props.children} From 32f38428f19e81a153addc6c1a06927725e98399 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Thu, 17 Sep 2015 11:39:45 +0200 Subject: [PATCH 07/18] PR Feedback: Fix replacement of underscores in filterParams --- .../piece_list_toolbar_filter_widget.js | 2 +- js/components/piece_list.js | 10 ++++------ 2 files changed, 5 insertions(+), 7 deletions(-) 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 07f66cd1..9cb8b94f 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 @@ -111,7 +111,7 @@ let PieceListToolbarFilterWidgetFilter = React.createClass({ param = param.key; } else { param = param; - label = param.split('_')[1]; + label = param.split('acl_')[1].replace(/_/g, ' '); } return ( diff --git a/js/components/piece_list.js b/js/components/piece_list.js index 7ecbd0f0..7978ffde 100644 --- a/js/components/piece_list.js +++ b/js/components/piece_list.js @@ -46,12 +46,10 @@ let PieceList = React.createClass({ filterParams: [{ label: getLangText('Show works I can'), items: [ - 'acl_transfer', - 'acl_consign', - { - key: 'acl_create_editions', - label: 'create editions' - }] + 'acl_transfer', + 'acl_consign', + 'acl_create_editions' + ] }] }; }, From 297d30f21f3027e9e0cc0e44b5682b7ec518f7d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Thu, 17 Sep 2015 13:52:51 +0200 Subject: [PATCH 08/18] PR Feeback: Simplify statements --- js/components/piece_list_filter_display.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/components/piece_list_filter_display.js b/js/components/piece_list_filter_display.js index e1c19bdd..6ca5207a 100644 --- a/js/components/piece_list_filter_display.js +++ b/js/components/piece_list_filter_display.js @@ -39,13 +39,13 @@ let PieceListFilterDisplay = React.createClass({ return { key: item.key, label: item.label, - value: filterBy[item.key] ? filterBy[item.key] : false + value: filterBy[item.key] || false }; } else { return { key: item, label: item.split('acl_')[1].replace(/_/g, ' '), - value: filterBy[item] ? filterBy[item] : false + value: filterBy[item] || false }; } }) From 7bccb26d82d02405b936fc81cc3ace16ebe6f16a Mon Sep 17 00:00:00 2001 From: diminator Date: Fri, 18 Sep 2015 09:46:37 +0200 Subject: [PATCH 09/18] acl on contract settings --- .../ascribe_settings/account_settings.js | 33 +--- .../ascribe_settings/contract_settings.js | 155 ++++++++++-------- .../ascribe_settings/settings_container.js | 28 +++- .../wallet/constants/wallet_api_urls.js | 3 +- 4 files changed, 122 insertions(+), 97 deletions(-) diff --git a/js/components/ascribe_settings/account_settings.js b/js/components/ascribe_settings/account_settings.js index b4d46b2d..0591b350 100644 --- a/js/components/ascribe_settings/account_settings.js +++ b/js/components/ascribe_settings/account_settings.js @@ -2,9 +2,6 @@ import React from 'react'; -import UserStore from '../../stores/user_store'; -import UserActions from '../../actions/user_actions'; - import GlobalNotificationModel from '../../models/global_notification_model'; import GlobalNotificationActions from '../../actions/global_notification_actions'; @@ -19,38 +16,26 @@ import AppConstants from '../../constants/application_constants'; import { getLangText } from '../../utils/lang_utils'; let AccountSettings = React.createClass({ - getInitialState() { - return UserStore.getState(); - }, - - componentDidMount() { - UserStore.listen(this.onChange); - UserActions.fetchCurrentUser(); - }, - - componentWillUnmount() { - UserStore.unlisten(this.onChange); - }, - - onChange(state) { - this.setState(state); + propTypes: { + currentUser: React.PropTypes.object.required, + loadUser: React.PropTypes.func.required }, handleSuccess(){ - UserActions.fetchCurrentUser(); + this.props.loadUser(); let notification = new GlobalNotificationModel(getLangText('Settings succesfully updated'), 'success', 5000); GlobalNotificationActions.appendGlobalNotification(notification); }, getFormDataProfile(){ - return {'email': this.state.currentUser.email}; + return {'email': this.props.currentUser.email}; }, render() { let content = ; let profile = null; - if (this.state.currentUser.username) { + if (this.props.currentUser.username) { content = (
    @@ -70,7 +55,7 @@ let AccountSettings = React.createClass({ editable={false}> @@ -87,7 +72,7 @@ let AccountSettings = React.createClass({ className="ascribe-settings-property-collapsible-toggle" style={{paddingBottom: 0}}> + defaultChecked={this.props.currentUser.profile.hash_locally}> {' ' + getLangText('Enable hash option, e.g. slow connections or to keep piece private')} diff --git a/js/components/ascribe_settings/contract_settings.js b/js/components/ascribe_settings/contract_settings.js index c7abc682..889932af 100644 --- a/js/components/ascribe_settings/contract_settings.js +++ b/js/components/ascribe_settings/contract_settings.js @@ -14,11 +14,14 @@ import ContractSettingsUpdateButton from './contract_settings_update_button'; import GlobalNotificationModel from '../../models/global_notification_model'; import GlobalNotificationActions from '../../actions/global_notification_actions'; +import AclProxy from '../acl_proxy'; + import { getLangText } from '../../utils/lang_utils'; let ContractSettings = React.createClass({ propTypes: { + currentUser: React.PropTypes.object, defaultExpanded: React.PropTypes.bool }, @@ -79,80 +82,92 @@ let ContractSettings = React.createClass({ } return ( - + - {createPublicContractForm} - {publicContracts.map((contract, i) => { - return ( - - - - {getLangText('PREVIEW')} - - -
    - } - leftColumnWidth="40%" - rightColumnWidth="60%"/> - ); - })} + + + {createPublicContractForm} + {publicContracts.map((contract, i) => { + return ( + + + + {getLangText('PREVIEW')} + + + + } + leftColumnWidth="40%" + rightColumnWidth="60%"/> + ); + })} + + + + + + {privateContracts.map((contract, i) => { + return ( + + + + {getLangText('PREVIEW')} + + + + } + leftColumnWidth="40%" + rightColumnWidth="60%"/> + ); + })} + + - - - {privateContracts.map((contract, i) => { - return ( - - - - {getLangText('PREVIEW')} - - - - } - leftColumnWidth="40%" - rightColumnWidth="60%"/> - ); - })} - - + ); } }); diff --git a/js/components/ascribe_settings/settings_container.js b/js/components/ascribe_settings/settings_container.js index 2d2440bf..9b08af43 100644 --- a/js/components/ascribe_settings/settings_container.js +++ b/js/components/ascribe_settings/settings_container.js @@ -3,6 +3,9 @@ import React from 'react'; import Router from 'react-router'; +import UserStore from '../../stores/user_store'; +import UserActions from '../../actions/user_actions'; + import AccountSettings from './account_settings'; import BitcoinWalletSettings from './bitcoin_wallet_settings'; import ContractSettings from './contract_settings'; @@ -18,14 +21,35 @@ let SettingsContainer = React.createClass({ mixins: [Router.Navigation], + getInitialState() { + return UserStore.getState(); + }, + + componentDidMount() { + UserStore.listen(this.onChange); + UserActions.fetchCurrentUser(); + }, + + componentWillUnmount() { + UserStore.unlisten(this.onChange); + }, + + loadUser(){ + UserActions.fetchCurrentUser(); + }, + + onChange(state) { + this.setState(state); + }, + render() { return (
    - + {this.props.children} - +
    ); } diff --git a/js/components/whitelabel/wallet/constants/wallet_api_urls.js b/js/components/whitelabel/wallet/constants/wallet_api_urls.js index e0d8a862..2cdc0054 100644 --- a/js/components/whitelabel/wallet/constants/wallet_api_urls.js +++ b/js/components/whitelabel/wallet/constants/wallet_api_urls.js @@ -8,7 +8,8 @@ function getWalletApiUrls(subdomain) { return { 'pieces_list': walletConstants.walletApiEndpoint + subdomain + '/pieces/', 'piece': walletConstants.walletApiEndpoint + subdomain + '/pieces/${piece_id}/', - 'piece_extradata': walletConstants.walletApiEndpoint + subdomain + '/pieces/${piece_id}/extradata/' + 'piece_extradata': walletConstants.walletApiEndpoint + subdomain + '/pieces/${piece_id}/extradata/', + 'user': walletConstants.walletApiEndpoint + subdomain + '/users/' }; } else if (subdomain === 'ikonotv'){ From b76ffcde73cd941d0f8137c92818a1e373ba7602 Mon Sep 17 00:00:00 2001 From: vrde Date: Fri, 18 Sep 2015 13:46:15 +0200 Subject: [PATCH 10/18] Finish styling for landing page --- js/components/whitelabel/prize/prize_app.js | 2 +- .../components/ikonotv/ikonotv_landing.js | 14 +++--- js/components/whitelabel/wallet/wallet_app.js | 5 ++- .../wallet/ikonotv/ikonotv_landing.scss | 43 ++++++++++++++++--- 4 files changed, 50 insertions(+), 14 deletions(-) diff --git a/js/components/whitelabel/prize/prize_app.js b/js/components/whitelabel/prize/prize_app.js index 29763ab3..f187dd1c 100644 --- a/js/components/whitelabel/prize/prize_app.js +++ b/js/components/whitelabel/prize/prize_app.js @@ -27,7 +27,7 @@ let PrizeApp = React.createClass({ } return ( -
    +
    {header} diff --git a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_landing.js b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_landing.js index 1e2d3803..293eecdd 100644 --- a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_landing.js +++ b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_landing.js @@ -32,13 +32,13 @@ let IkonotvLanding = React.createClass({ if(this.state.currentUser && this.state.currentUser.email) { return ( - {getLangText('ENTER')} + {getLangText('ENTER TO START')} ); } else { return ( - {getLangText('ENTER')} + {getLangText('ENTER TO START')} ); } @@ -51,11 +51,13 @@ let IkonotvLanding = React.createClass({

    PROTECT

    - +
    +
    +
    +

    & SHARE

    -

    Welcome to the ikonoTV

    -

    Registration Page

    +

    Welcome to the ikonoTV
    Registration Page

    @@ -102,4 +104,4 @@ let IkonotvLanding = React.createClass({ } }); -export default IkonotvLanding; \ No newline at end of file +export default IkonotvLanding; diff --git a/js/components/whitelabel/wallet/wallet_app.js b/js/components/whitelabel/wallet/wallet_app.js index 06bac15f..8aa15f59 100644 --- a/js/components/whitelabel/wallet/wallet_app.js +++ b/js/components/whitelabel/wallet/wallet_app.js @@ -8,9 +8,12 @@ import Footer from '../../footer'; import GlobalNotification from '../../global_notification'; import getRoutes from './wallet_routes'; +import classNames from 'classnames'; + let RouteHandler = Router.RouteHandler; + let WalletApp = React.createClass({ mixins: [Router.State], @@ -28,7 +31,7 @@ let WalletApp = React.createClass({ } return ( -
    +
    {header} diff --git a/sass/whitelabel/wallet/ikonotv/ikonotv_landing.scss b/sass/whitelabel/wallet/ikonotv/ikonotv_landing.scss index b0d60983..7a54f20a 100644 --- a/sass/whitelabel/wallet/ikonotv/ikonotv_landing.scss +++ b/sass/whitelabel/wallet/ikonotv/ikonotv_landing.scss @@ -1,11 +1,20 @@ +.client--ikonotv.page--landing { + background-color: #c40050; + margin: 0; + width: 100%; + padding: 5em 1em; +} + + +.client--ikonotv.page--landing .ascribe-footer { + display: none; +} + .ikonotv-landing { /* center all text on the page */ text-align: center; - background-color: #c40050; color: white; - padding: 5em 5em 5em 5em; - header { /* center all images on the page */ img { @@ -16,7 +25,7 @@ /* Ikonotv logo */ img:first-child { - width: 200px; + max-width: 200px; } > .tagline { @@ -29,12 +38,30 @@ margin-top: 10px; margin-bottom: 10px; + + @media only screen and (max-width: 600px) { + font-size: 4em; + } + } + + > .poster { + max-width: 600px; + margin: 0 auto; + > .content { + width: 100%; + padding-bottom: 56.25%; + height: 0; + background-color: #ffff00; + } } } > h2 { font-weight: 600; font-size: 2.75em; + @media only screen and (max-width: 600px) { + font-size: 1.75em; + } } > h2 + h2 { @@ -44,7 +71,8 @@ article { > section { - width: 65%; + width: 100%; + max-width: 60em; margin: 3em auto 1em auto; > h1 { @@ -57,6 +85,9 @@ text-align: left; font-size: 1.3em; line-height: 1.8; + @media only screen and (max-width: 600px) { + font-size: 1.1em; + } } } } @@ -78,4 +109,4 @@ font-weight: 500; } } -} \ No newline at end of file +} From c99c3492fbb67a0b50609b89e0374577a5b20e97 Mon Sep 17 00:00:00 2001 From: vrde Date: Fri, 18 Sep 2015 14:02:31 +0200 Subject: [PATCH 11/18] Add margin top to ascribe-wallet-app class --- sass/whitelabel/index.scss | 3 ++- sass/whitelabel/wallet/index.scss | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 sass/whitelabel/wallet/index.scss diff --git a/sass/whitelabel/index.scss b/sass/whitelabel/index.scss index 9fa1b68f..fc7a6b3b 100644 --- a/sass/whitelabel/index.scss +++ b/sass/whitelabel/index.scss @@ -1,2 +1,3 @@ @import 'prize/index'; -@import 'wallet/ikonotv/ikonotv_landing'; \ No newline at end of file +@import 'wallet/index'; +@import 'wallet/ikonotv/ikonotv_landing'; diff --git a/sass/whitelabel/wallet/index.scss b/sass/whitelabel/wallet/index.scss new file mode 100644 index 00000000..4ec76076 --- /dev/null +++ b/sass/whitelabel/wallet/index.scss @@ -0,0 +1,5 @@ +.ascribe-wallet-app { + border-radius: 0; + padding-top: 70px; + min-height: 100vh; +} From 03803ca61a5e7220df5eb61a543ef1323315c9d4 Mon Sep 17 00:00:00 2001 From: vrde Date: Fri, 18 Sep 2015 14:25:31 +0200 Subject: [PATCH 12/18] Add active routes as css classes --- js/components/whitelabel/wallet/wallet_app.js | 3 ++- sass/whitelabel/wallet/ikonotv/ikonotv_landing.scss | 7 +++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/js/components/whitelabel/wallet/wallet_app.js b/js/components/whitelabel/wallet/wallet_app.js index 8aa15f59..cb2a79d5 100644 --- a/js/components/whitelabel/wallet/wallet_app.js +++ b/js/components/whitelabel/wallet/wallet_app.js @@ -20,6 +20,7 @@ let WalletApp = React.createClass({ render() { let subdomain = window.location.host.split('.')[0]; let ROUTES = getRoutes(null, subdomain); + let activeRoutes = this.getRoutes().map(elem => 'route--' + elem.name); let header = null; if ((this.isActive('landing') || this.isActive('login') || this.isActive('signup')) @@ -31,7 +32,7 @@ let WalletApp = React.createClass({ } return ( -
    +
    {header} diff --git a/sass/whitelabel/wallet/ikonotv/ikonotv_landing.scss b/sass/whitelabel/wallet/ikonotv/ikonotv_landing.scss index 7a54f20a..0dc69a84 100644 --- a/sass/whitelabel/wallet/ikonotv/ikonotv_landing.scss +++ b/sass/whitelabel/wallet/ikonotv/ikonotv_landing.scss @@ -1,12 +1,15 @@ -.client--ikonotv.page--landing { +.client--ikonotv.route--landing { background-color: #c40050; margin: 0; width: 100%; padding: 5em 1em; } +.client--ikonotv .ascribe-login-wrapper { -.client--ikonotv.page--landing .ascribe-footer { +} + +.client--ikonotv.route--landing .ascribe-footer { display: none; } From 63b375ade6013f6eda8811b536387a92c777ea66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Fri, 18 Sep 2015 15:17:24 +0200 Subject: [PATCH 13/18] fix separation --- .../ascribe_settings/contract_settings.js | 28 ++++++++----------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/js/components/ascribe_settings/contract_settings.js b/js/components/ascribe_settings/contract_settings.js index 889932af..34966304 100644 --- a/js/components/ascribe_settings/contract_settings.js +++ b/js/components/ascribe_settings/contract_settings.js @@ -75,8 +75,8 @@ let ContractSettings = React.createClass({ ); } @@ -92,10 +92,7 @@ let ContractSettings = React.createClass({ - +
    {createPublicContractForm} {publicContracts.map((contract, i) => { return ( @@ -123,21 +120,18 @@ let ContractSettings = React.createClass({ rightColumnWidth="60%"/> ); })} - +
    - +
    + isPublic={false} + fileClassToUpload={{ + singular: getLangText('new contract'), + plural: getLangText('new contracts') + }}/> {privateContracts.map((contract, i) => { return ( ); })} - +
    From eb43b18167f1bf39c3be4b2c3e4d375f522d0699 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Fri, 18 Sep 2015 15:22:57 +0200 Subject: [PATCH 14/18] make remove in ContractSettings a secondary action --- js/components/ascribe_settings/contract_settings.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/components/ascribe_settings/contract_settings.js b/js/components/ascribe_settings/contract_settings.js index 34966304..f85db29e 100644 --- a/js/components/ascribe_settings/contract_settings.js +++ b/js/components/ascribe_settings/contract_settings.js @@ -110,7 +110,7 @@ let ContractSettings = React.createClass({ {getLangText('PREVIEW')} @@ -148,7 +148,7 @@ let ContractSettings = React.createClass({ {getLangText('PREVIEW')} From 7be3c8b46920e9e66206deefaae4d3c84dec0a7d Mon Sep 17 00:00:00 2001 From: vrde Date: Fri, 18 Sep 2015 15:36:01 +0200 Subject: [PATCH 15/18] Add style for signup and login --- js/components/whitelabel/wallet/wallet_app.js | 14 ++-- .../wallet/ikonotv/ikonotv_landing.scss | 83 ++++++++++++++++++- 2 files changed, 89 insertions(+), 8 deletions(-) diff --git a/js/components/whitelabel/wallet/wallet_app.js b/js/components/whitelabel/wallet/wallet_app.js index cb2a79d5..b92656e2 100644 --- a/js/components/whitelabel/wallet/wallet_app.js +++ b/js/components/whitelabel/wallet/wallet_app.js @@ -32,12 +32,14 @@ let WalletApp = React.createClass({ } return ( -
    - {header} - - - -