;
+ }.bind(this)
+ );
}
return (
diff --git a/js/mixins/modal_mixin.js b/js/mixins/modal_mixin.js
new file mode 100644
index 00000000..7dee243b
--- /dev/null
+++ b/js/mixins/modal_mixin.js
@@ -0,0 +1,11 @@
+import React from 'react';
+
+let ModalMixin = {
+ onRequestHide(e){
+ if (e)
+ e.preventDefault();
+ this.props.onRequestHide();
+ }
+};
+
+export default ModalMixin;
\ No newline at end of file
diff --git a/js/mixins/table_column_mixin.js b/js/mixins/table_column_mixin.js
index d74214e1..eac266b6 100644
--- a/js/mixins/table_column_mixin.js
+++ b/js/mixins/table_column_mixin.js
@@ -1,6 +1,6 @@
import React from 'react';
-import GeneralUtils from '../utils/general_utils';
+import { sumNumList } from '../utils/general_utils';
let TableColumnMixin = {
/**
@@ -11,7 +11,7 @@ let TableColumnMixin = {
let bootstrapClasses = ['col-xs-', 'col-sm-', 'col-md-', 'col-lg-'];
let listOfRowValues = list.map((column) => column.rowWidth );
- let numOfUsedColumns = GeneralUtils.sumNumList(listOfRowValues);
+ 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.')
diff --git a/js/stores/edition_store.js b/js/stores/edition_store.js
index 9859ec7c..b33e248f 100644
--- a/js/stores/edition_store.js
+++ b/js/stores/edition_store.js
@@ -1,11 +1,11 @@
import alt from '../alt';
-import EditionAction from '../actions/edition_actions';
+import EditionActions from '../actions/edition_actions';
class EditionStore {
constructor() {
this.edition = {};
- this.bindActions(EditionAction);
+ this.bindActions(EditionActions);
}
onUpdateEdition(edition) {
diff --git a/js/stores/piece_list_store.js b/js/stores/piece_list_store.js
index 97e3f4a4..7ca96c87 100644
--- a/js/stores/piece_list_store.js
+++ b/js/stores/piece_list_store.js
@@ -24,6 +24,19 @@ class PieceListStore {
this.bindActions(PieceListActions);
}
+ onShowEditionList(pieceId) {
+ this.pieceList
+ .forEach((piece) => {
+ if(piece.id === pieceId) {
+ if(piece.show) {
+ piece.show = false;
+ } else {
+ piece.show = true;
+ }
+ }
+ });
+ }
+
onUpdatePieceList({ page, pageSize, search, pieceList, orderBy, orderAsc, pieceListCount }) {
this.page = page;
this.pageSize = pageSize;
diff --git a/js/stores/user_store.js b/js/stores/user_store.js
index 45fbec57..6ae631c9 100644
--- a/js/stores/user_store.js
+++ b/js/stores/user_store.js
@@ -4,13 +4,13 @@ import UserAction from '../actions/user_actions';
class UserStore{
constructor() {
- this.currentUser = {}
+ this.currentUser = {};
this.bindActions(UserAction);
}
onUpdateCurrentUser(user) {
this.currentUser = user;
}
-};
+}
export default alt.createStore(UserStore);
diff --git a/js/utils/fetch.js b/js/utils/fetch.js
index a9fa1c02..f7e12f43 100644
--- a/js/utils/fetch.js
+++ b/js/utils/fetch.js
@@ -1,5 +1,6 @@
import { default as _fetch } from 'isomorphic-fetch';
-import FetchApiUtils from '../utils/fetch_api_utils';
+
+import { argsToQueryParams } from '../utils/fetch_api_utils';
class UrlMapError extends Error {};
@@ -66,7 +67,7 @@ class Fetch {
});
if (attachParamsToQuery && params && Object.keys(params).length > 0) {
- newUrl += FetchApiUtils.argsToQueryParams(params);
+ newUrl += argsToQueryParams(params);
}
return newUrl;
diff --git a/js/utils/fetch_api_utils.js b/js/utils/fetch_api_utils.js
index 47b52e66..bf66a45c 100644
--- a/js/utils/fetch_api_utils.js
+++ b/js/utils/fetch_api_utils.js
@@ -1,8 +1,6 @@
-import GeneralUtils from './general_utils';
-
+import { sanitize } from './general_utils';
// TODO: Create Unittests that test all functions
-let FetchApiUtils = {
/**
* Takes a key-value object of this form:
@@ -20,48 +18,45 @@ let FetchApiUtils = {
* CamelCase gets converted to snake_case!
*
*/
- argsToQueryParams(obj) {
+export function argsToQueryParams(obj) {
- obj = GeneralUtils.sanitize(obj);
+ obj = sanitize(obj);
- return Object
- .keys(obj)
- .map((key, i) => {
- let s = '';
+ return Object
+ .keys(obj)
+ .map((key, i) => {
+ let s = '';
- if(i === 0) {
- s += '?';
- } else {
- s += '&';
- }
+ if(i === 0) {
+ s += '?';
+ } else {
+ s += '&';
+ }
- let snakeCaseKey = key.replace(/[A-Z]/, (match) => '_' + match.toLowerCase());
+ let snakeCaseKey = key.replace(/[A-Z]/, (match) => '_' + match.toLowerCase());
- return s + snakeCaseKey + '=' + encodeURIComponent(obj[key]);
- })
- .join('');
- },
-
- /**
- * Takes a string and a boolean and generates a string query parameter for
- * an API call.
- */
- generateOrderingQueryParams(orderBy, orderAsc) {
- let interpolation = '';
-
- if(!orderAsc) {
- interpolation += '-';
- }
-
- return interpolation + orderBy;
- },
-
- status(response) {
- if (response.status >= 200 && response.status < 300) {
- return response
- }
- throw new Error(response.json())
- }
+ return s + snakeCaseKey + '=' + encodeURIComponent(obj[key]);
+ })
+ .join('');
};
-export default FetchApiUtils;
+/**
+ * Takes a string and a boolean and generates a string query parameter for
+ * an API call.
+ */
+export function generateOrderingQueryParams(orderBy, orderAsc) {
+ let interpolation = '';
+
+ if(!orderAsc) {
+ interpolation += '-';
+ }
+
+ return interpolation + orderBy;
+};
+
+export function status(response) {
+ if (response.status >= 200 && response.status < 300) {
+ return response
+ }
+ throw new Error(response.json())
+};
diff --git a/js/utils/general_utils.js b/js/utils/general_utils.js
index 7ab180fa..96f56c1e 100644
--- a/js/utils/general_utils.js
+++ b/js/utils/general_utils.js
@@ -1,41 +1,63 @@
// TODO: Create Unittests that test all functions
-let GeneralUtils = {
- /**
- * Removes undefined and null values from an key-value object.
- */
- sanitize(obj) {
- Object
- .keys(obj)
- .map((key) => {
- // By matching null with a double equal, we can match undefined and null
- // http://stackoverflow.com/a/15992131
- if(obj[key] == null || obj[key] === '') {
- delete obj[key];
- }
- });
-
- return obj;
- },
-
- /**
- * Returns the values of an object.
- */
- valuesOfObject(obj) {
- return Object
- .keys(obj)
- .map(key => obj[key]);
- },
-
- /**
- * Sums up a list of numbers. Like a Epsilon-math-kinda-sum...
- */
- sumNumList(l) {
- let sum = 0;
- l.forEach((num) => sum += parseFloat(num) || 0);
- return sum;
- }
+export function sanitize(obj) {
+ Object
+ .keys(obj)
+ .map((key) => {
+ // By matching null with a double equal, we can match undefined and null
+ // http://stackoverflow.com/a/15992131
+ if(obj[key] == null || obj[key] === '') {
+ delete obj[key];
+ }
+ });
+ return obj;
};
-export default GeneralUtils;
+/**
+ * Returns the values of an object.
+ */
+export function valuesOfObject(obj) {
+ return Object
+ .keys(obj)
+ .map(key => obj[key]);
+};
+
+/**
+ * Sums up a list of numbers. Like a Epsilon-math-kinda-sum...
+ */
+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
+*/
+export function formatText() {
+ var args = arguments,
+ string = args[0],
+ i = 1;
+ return string.replace(/%((%)|s|d)/g, function (m) {
+ // m is the matched format, e.g. %s, %d
+ var val = null;
+ if (m[2]) {
+ val = m[2];
+ } else {
+ val = args[i];
+ // A switch statement so that the formatter can be extended. Default is %s
+ switch (m) {
+ case '%d':
+ val = parseFloat(val);
+ if (isNaN(val)) {
+ val = 0;
+ }
+ break;
+ }
+ i++;
+ }
+ return val;
+ });
+};
diff --git a/js/utils/lang_utils.js b/js/utils/lang_utils.js
new file mode 100644
index 00000000..7eb4b6f3
--- /dev/null
+++ b/js/utils/lang_utils.js
@@ -0,0 +1,30 @@
+import languages from '../constants/languages';
+
+import { formatText } from './general_utils';
+
+/**
+ * Is used to translate strings to another language. Basically can be used with C's string format method.
+ * @param {string} s The string you want to translate
+ * @param {array} args An array of arguments (essentially JavaScript's this.arguments) that can be used to substitute digits and other strings
+ * @return {string} The formated string
+ */
+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';
+ try {
+ if(lang in languages) {
+ return formatText(languages[lang][s], args);
+ } else {
+ // just use the english language
+ return formatText(languages['en-US'][s], args);
+ }
+ } catch(err) {
+ if(!(s in languages[lang])) {
+ console.error(new Error('Language-string is not in constants file. Add: "' + s + '" to the "' + lang + '" language file.'));
+ } else {
+ console.error(err);
+ }
+
+ }
+};
diff --git a/package.json b/package.json
index 3fc2112b..99f8f431 100644
--- a/package.json
+++ b/package.json
@@ -36,7 +36,9 @@
"react": "^0.13.2",
"react-bootstrap": "~0.22.6",
"react-router": "^0.13.3",
- "uglifyjs": "^2.4.10"
+ "uglifyjs": "^2.4.10",
+ "react-bootstrap": "~0.22.6",
+ "react-datepicker": "~0.8.0"
},
"jest": {
"scriptPreprocessor": "node_modules/babel-jest",
diff --git a/sass/ascribe-accordion_list.scss b/sass/ascribe_accordion_list.scss
similarity index 100%
rename from sass/ascribe-accordion_list.scss
rename to sass/ascribe_accordion_list.scss
diff --git a/sass/ascribe-piece-list-toolbar.scss b/sass/ascribe_piece_list_bulk_modal.scss
similarity index 85%
rename from sass/ascribe-piece-list-toolbar.scss
rename to sass/ascribe_piece_list_bulk_modal.scss
index 6093aed9..4a6b98d7 100644
--- a/sass/ascribe-piece-list-toolbar.scss
+++ b/sass/ascribe_piece_list_bulk_modal.scss
@@ -1,4 +1,4 @@
-.ascribe-piece-list-toolbar {
+.ascribe-piece-list-bulk-modal {
position: fixed;
top:0;
width:1170px;
@@ -14,7 +14,7 @@
z-index:9999;
}
-.piece-list-toolbar-clear-all {
+.piece-list-bulk-modal-clear-all {
text-decoration: underline;
cursor:pointer;
}
\ No newline at end of file
diff --git a/sass/ascribe_piece_list_toolbar.scss b/sass/ascribe_piece_list_toolbar.scss
new file mode 100644
index 00000000..73c0bc94
--- /dev/null
+++ b/sass/ascribe_piece_list_toolbar.scss
@@ -0,0 +1,3 @@
+.ascribe-piece-list-toolbar {
+ margin-bottom: 1.5em;
+}
\ No newline at end of file
diff --git a/sass/ascribe-variables.scss b/sass/ascribe_variables.scss
similarity index 100%
rename from sass/ascribe-variables.scss
rename to sass/ascribe_variables.scss
diff --git a/sass/main.scss b/sass/main.scss
index 471a6124..2fe60cac 100644
--- a/sass/main.scss
+++ b/sass/main.scss
@@ -1,12 +1,15 @@
// If you import a new .scss file, make sure to restart gulp
// otherwise it will not be included
@import 'variables';
-@import 'ascribe-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';
-@import 'ascribe-piece-list-toolbar';
+@import 'ascribe_accordion_list';
+@import 'ascribe_piece_list_bulk_modal';
+@import 'ascribe_piece_list_toolbar';
+@import 'offset_right';
.hidden {
display: none;
@@ -15,10 +18,10 @@
.navbar-default {
border-left:0;
border-right:0;
- margin-bottom: 3em;
+ margin-bottom: 1.5em;
}
-.clear-margins-and-paddings {
+.clear-paddings {
padding-left:0;
padding-right:0;
}
@@ -162,7 +165,8 @@
text-transform: uppercase;
}
-.input-text-ascribe {
+.input-text-ascribe,
+.datepicker__input {
border-bottom: 1px solid black;
border-top: 0;
border-left: 0;
@@ -176,6 +180,14 @@
height: 13em !important;
}
+.input-checkbox-ascribe {
+ text-align: left;
+ line-height: 1.6;
+ width: 90%;
+ margin-left: auto;
+ margin-right: auto;
+}
+
/* columns of same height styles */
/* http://www.minimit.com/articles/solutions-tutorials/bootstrap-3-responsive-columns-of-same-height */
.row-full-height {
@@ -232,4 +244,4 @@
.col-bottom {
vertical-align: bottom;
-}
\ No newline at end of file
+}
diff --git a/sass/offset_right.scss b/sass/offset_right.scss
new file mode 100644
index 00000000..f844ce20
--- /dev/null
+++ b/sass/offset_right.scss
@@ -0,0 +1,164 @@
+/* Taken from: http://stackoverflow.com/a/27501063/1263876 */
+
+.col-xs-offset-right-12 {
+ margin-right: 100%;
+}
+.col-xs-offset-right-11 {
+ margin-right: 91.66666667%;
+}
+.col-xs-offset-right-10 {
+ margin-right: 83.33333333%;
+}
+.col-xs-offset-right-9 {
+ margin-right: 75%;
+}
+.col-xs-offset-right-8 {
+ margin-right: 66.66666667%;
+}
+.col-xs-offset-right-7 {
+ margin-right: 58.33333333%;
+}
+.col-xs-offset-right-6 {
+ margin-right: 50%;
+}
+.col-xs-offset-right-5 {
+ margin-right: 41.66666667%;
+}
+.col-xs-offset-right-4 {
+ margin-right: 33.33333333%;
+}
+.col-xs-offset-right-3 {
+ margin-right: 25%;
+}
+.col-xs-offset-right-2 {
+ margin-right: 16.66666667%;
+}
+.col-xs-offset-right-1 {
+ margin-right: 8.33333333%;
+}
+.col-xs-offset-right-0 {
+ margin-right: 0;
+}
+@media (min-width: 768px) {
+ .col-sm-offset-right-12 {
+ margin-right: 100%;
+ }
+ .col-sm-offset-right-11 {
+ margin-right: 91.66666667%;
+ }
+ .col-sm-offset-right-10 {
+ margin-right: 83.33333333%;
+ }
+ .col-sm-offset-right-9 {
+ margin-right: 75%;
+ }
+ .col-sm-offset-right-8 {
+ margin-right: 66.66666667%;
+ }
+ .col-sm-offset-right-7 {
+ margin-right: 58.33333333%;
+ }
+ .col-sm-offset-right-6 {
+ margin-right: 50%;
+ }
+ .col-sm-offset-right-5 {
+ margin-right: 41.66666667%;
+ }
+ .col-sm-offset-right-4 {
+ margin-right: 33.33333333%;
+ }
+ .col-sm-offset-right-3 {
+ margin-right: 25%;
+ }
+ .col-sm-offset-right-2 {
+ margin-right: 16.66666667%;
+ }
+ .col-sm-offset-right-1 {
+ margin-right: 8.33333333%;
+ }
+ .col-sm-offset-right-0 {
+ margin-right: 0;
+ }
+}
+@media (min-width: 992px) {
+ .col-md-offset-right-12 {
+ margin-right: 100%;
+ }
+ .col-md-offset-right-11 {
+ margin-right: 91.66666667%;
+ }
+ .col-md-offset-right-10 {
+ margin-right: 83.33333333%;
+ }
+ .col-md-offset-right-9 {
+ margin-right: 75%;
+ }
+ .col-md-offset-right-8 {
+ margin-right: 66.66666667%;
+ }
+ .col-md-offset-right-7 {
+ margin-right: 58.33333333%;
+ }
+ .col-md-offset-right-6 {
+ margin-right: 50%;
+ }
+ .col-md-offset-right-5 {
+ margin-right: 41.66666667%;
+ }
+ .col-md-offset-right-4 {
+ margin-right: 33.33333333%;
+ }
+ .col-md-offset-right-3 {
+ margin-right: 25%;
+ }
+ .col-md-offset-right-2 {
+ margin-right: 16.66666667%;
+ }
+ .col-md-offset-right-1 {
+ margin-right: 8.33333333%;
+ }
+ .col-md-offset-right-0 {
+ margin-right: 0;
+ }
+}
+@media (min-width: 1200px) {
+ .col-lg-offset-right-12 {
+ margin-right: 100%;
+ }
+ .col-lg-offset-right-11 {
+ margin-right: 91.66666667%;
+ }
+ .col-lg-offset-right-10 {
+ margin-right: 83.33333333%;
+ }
+ .col-lg-offset-right-9 {
+ margin-right: 75%;
+ }
+ .col-lg-offset-right-8 {
+ margin-right: 66.66666667%;
+ }
+ .col-lg-offset-right-7 {
+ margin-right: 58.33333333%;
+ }
+ .col-lg-offset-right-6 {
+ margin-right: 50%;
+ }
+ .col-lg-offset-right-5 {
+ margin-right: 41.66666667%;
+ }
+ .col-lg-offset-right-4 {
+ margin-right: 33.33333333%;
+ }
+ .col-lg-offset-right-3 {
+ margin-right: 25%;
+ }
+ .col-lg-offset-right-2 {
+ margin-right: 16.66666667%;
+ }
+ .col-lg-offset-right-1 {
+ margin-right: 8.33333333%;
+ }
+ .col-lg-offset-right-0 {
+ margin-right: 0;
+ }
+}
\ No newline at end of file