From 8a5474ffc491a5e764fe8bd838725525bbbf083f Mon Sep 17 00:00:00 2001 From: ivan Date: Thu, 8 Dec 2016 18:37:41 -0300 Subject: [PATCH 1/4] Max - Create add staff modal [skip ci] --- .../app/admin/panel/staff/add-staff-modal.js | 38 +++++++++++++++++++ .../admin/panel/staff/add-staff-modal.scss | 0 .../panel/staff/admin-panel-staff-members.js | 9 ++++- client/src/data/languages/en.js | 3 ++ 4 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 client/src/app/admin/panel/staff/add-staff-modal.js create mode 100644 client/src/app/admin/panel/staff/add-staff-modal.scss diff --git a/client/src/app/admin/panel/staff/add-staff-modal.js b/client/src/app/admin/panel/staff/add-staff-modal.js new file mode 100644 index 00000000..01ba0268 --- /dev/null +++ b/client/src/app/admin/panel/staff/add-staff-modal.js @@ -0,0 +1,38 @@ +import React from 'react'; + +import i18n from 'lib-app/i18n'; + +import Header from 'core-components/header' +import Form from 'core-components/form'; +import FormField from 'core-components/form-field'; +import SubmitButton from 'core-components/submit-button'; + +class AddStaffModal extends React.Component { + + render() { + return ( +
+
+
+ + + + + + {i18n('SAVE')} + + +
+ ); + } + + onSubmit(form) { + console.log(form); + } + +} + +export default AddStaffModal; \ No newline at end of file diff --git a/client/src/app/admin/panel/staff/add-staff-modal.scss b/client/src/app/admin/panel/staff/add-staff-modal.scss new file mode 100644 index 00000000..e69de29b diff --git a/client/src/app/admin/panel/staff/admin-panel-staff-members.js b/client/src/app/admin/panel/staff/admin-panel-staff-members.js index 2c47a6b3..5d85a0ea 100644 --- a/client/src/app/admin/panel/staff/admin-panel-staff-members.js +++ b/client/src/app/admin/panel/staff/admin-panel-staff-members.js @@ -5,6 +5,9 @@ import i18n from 'lib-app/i18n'; import API from 'lib-app/api-call'; import SessionStore from 'lib-app/session-store'; import PeopleList from 'app-components/people-list'; +import ModalContainer from 'app-components/modal-container'; + +import AddStaffModal from 'app/admin/panel/staff/add-staff-modal'; import Header from 'core-components/header'; import DropDown from 'core-components/drop-down'; @@ -34,7 +37,7 @@ class AdminPanelStaffMembers extends React.Component {
-
@@ -43,6 +46,10 @@ class AdminPanelStaffMembers extends React.Component { ); } + onAddNewStaff() { + ModalContainer.openModal(); + } + getDepartmentDropdownProps() { return { items: this.getDepartments(), diff --git a/client/src/data/languages/en.js b/client/src/data/languages/en.js index f608dcfa..cdd04281 100644 --- a/client/src/data/languages/en.js +++ b/client/src/data/languages/en.js @@ -99,6 +99,8 @@ export default { 'LAST_LOGIN': 'Last login', 'STAFF_MEMBERS': 'Staff members', 'ADD_NEW_STAFF': 'Add new staff', + 'ADD_STAFF': 'Add staff', + 'LEVEL': 'Level', //VIEW DESCRIPTIONS 'CREATE_TICKET_DESCRIPTION': 'This is a form for creating tickets. Fill the form and send us your issues/doubts/suggestions. Our support system will answer it as soon as possible.', @@ -122,6 +124,7 @@ export default { 'LIST_ARTICLES_DESCRIPTION': 'This is a list of articles that includes information about our services.', 'ADD_TOPIC_DESCRIPTION': 'Here you can add a topic that works as a category for articles.', 'STAFF_MEMBERS_DESCRIPTION': 'Here you can see who are your staff members.', + 'ADD_STAFF_DESCRIPTION': 'Here you can add staff members to your teams', //ERRORS 'EMAIL_OR_PASSWORD': 'Email or password invalid', From 77f8976896dcdbaadaba3be2d71516ce4056a9c7 Mon Sep 17 00:00:00 2001 From: ivan Date: Fri, 9 Dec 2016 17:51:30 -0300 Subject: [PATCH 2/4] Ivan - Add Checkbox group component [skip ci] --- client/src/app-components/people-list.js | 2 +- .../app/admin/panel/staff/add-staff-modal.js | 21 ++++--- .../admin/panel/staff/add-staff-modal.scss | 6 ++ client/src/core-components/checkbox-group.js | 57 +++++++++++++++++++ client/src/core-components/checkbox.js | 28 ++++++--- client/src/core-components/drop-down.scss | 13 +++++ client/src/core-components/form-field.js | 18 +++++- client/src/data/languages/en.js | 4 +- 8 files changed, 128 insertions(+), 21 deletions(-) create mode 100644 client/src/core-components/checkbox-group.js diff --git a/client/src/app-components/people-list.js b/client/src/app-components/people-list.js index 1fd18346..604d8967 100644 --- a/client/src/app-components/people-list.js +++ b/client/src/app-components/people-list.js @@ -64,7 +64,7 @@ class PeopleList extends React.Component { renderAnimatedItem(style, index) { return ( -
+
{this.renderItem(index + this.props.pageSize * (this.props.page - 1))}
); diff --git a/client/src/app/admin/panel/staff/add-staff-modal.js b/client/src/app/admin/panel/staff/add-staff-modal.js index 01ba0268..52c2ed63 100644 --- a/client/src/app/admin/panel/staff/add-staff-modal.js +++ b/client/src/app/admin/panel/staff/add-staff-modal.js @@ -1,6 +1,7 @@ import React from 'react'; import i18n from 'lib-app/i18n'; +import SessionStore from 'lib-app/session-store'; import Header from 'core-components/header' import Form from 'core-components/form'; @@ -11,16 +12,19 @@ class AddStaffModal extends React.Component { render() { return ( -
+
- - + +
+ +
+ {i18n('SAVE')} @@ -29,10 +33,13 @@ class AddStaffModal extends React.Component { ); } + getDepartments() { + return SessionStore.getDepartments().map((department) => department.name); + } + onSubmit(form) { console.log(form); } - } export default AddStaffModal; \ No newline at end of file diff --git a/client/src/app/admin/panel/staff/add-staff-modal.scss b/client/src/app/admin/panel/staff/add-staff-modal.scss index e69de29b..e2456788 100644 --- a/client/src/app/admin/panel/staff/add-staff-modal.scss +++ b/client/src/app/admin/panel/staff/add-staff-modal.scss @@ -0,0 +1,6 @@ +.add-staff-modal { + + &__level-selector { + text-align: center; + } +} \ No newline at end of file diff --git a/client/src/core-components/checkbox-group.js b/client/src/core-components/checkbox-group.js new file mode 100644 index 00000000..a5e97e76 --- /dev/null +++ b/client/src/core-components/checkbox-group.js @@ -0,0 +1,57 @@ +import React from 'react'; +import _ from 'lodash'; + +import Checkbox from 'core-components/checkbox'; + +class CheckboxGroup extends React.Component { + static propTypes = { + items: React.PropTypes.array.isRequired, + value: React.PropTypes.arrayOf(React.PropTypes.number), + onChange: React.PropTypes.func + }; + + state = { + value: [] + }; + + render() { + return ( +
    + {this.props.items.map(this.renderItem.bind(this))} +
+ ); + } + + renderItem(label, index) { + const checked = (_.includes(this.getValue(), index)); + + return ( +
  • + +
  • + ); + } + + onCheckboxChange(index) { + let value = _.clone(this.getValue()); + + if(_.includes(value, index)) { + _.pull(value, index); + } else { + value.push(index); + value.sort(); + } + + this.setState({value}); + + if(this.props.onChange) { + this.props.onChange({target: {value}}); + } + } + + getValue() { + return (this.props.value !== undefined) ? this.props.value : this.state.value; + } +} + +export default CheckboxGroup; \ No newline at end of file diff --git a/client/src/core-components/checkbox.js b/client/src/core-components/checkbox.js index c148783a..d269efee 100644 --- a/client/src/core-components/checkbox.js +++ b/client/src/core-components/checkbox.js @@ -11,28 +11,38 @@ class CheckBox extends React.Component { static propTypes = { alignment: React.PropTypes.string, label: React.PropTypes.string, - value: React.PropTypes.bool + value: React.PropTypes.bool, + wrapInLabel: React.PropTypes.bool, + onChange: React.PropTypes.func }; static defaultProps = { + wrapInLabel: false, alignment: 'right' }; - constructor(props) { - super(props); - - this.state = { - checked: false - }; - } + state = { + checked: false + }; render() { + let Wrapper = (this.props.wrapInLabel) ? 'label' : 'span'; + return ( - + {getIcon((this.getValue()) ? 'check-square' : 'square', 'lg') } + {(this.props.label) ? this.renderLabel() : null} + + ); + } + + renderLabel() { + return ( + + {this.props.label} ); } diff --git a/client/src/core-components/drop-down.scss b/client/src/core-components/drop-down.scss index facd5c53..7082e708 100644 --- a/client/src/core-components/drop-down.scss +++ b/client/src/core-components/drop-down.scss @@ -49,4 +49,17 @@ border: 1px solid $light-grey; } } + + &_large { + width: 300px; + + .drop-down__current-item { + border-radius: 4px; + } + + .drop-down__list-container { + width: 300px; + border: 1px solid $light-grey; + } + } } \ No newline at end of file diff --git a/client/src/core-components/form-field.js b/client/src/core-components/form-field.js index ad93729a..78cb9dad 100644 --- a/client/src/core-components/form-field.js +++ b/client/src/core-components/form-field.js @@ -6,6 +6,7 @@ import _ from 'lodash'; import Input from 'core-components/input'; import DropDown from 'core-components/drop-down'; import Checkbox from 'core-components/checkbox'; +import CheckboxGroup from 'core-components/checkbox-group'; import TextEditor from 'core-components/text-editor'; class FormField extends React.Component { @@ -21,7 +22,7 @@ class FormField extends React.Component { required: React.PropTypes.bool, error: React.PropTypes.string, value: React.PropTypes.any, - field: React.PropTypes.oneOf(['input', 'textarea', 'select', 'checkbox']), + field: React.PropTypes.oneOf(['input', 'textarea', 'select', 'checkbox', 'checkbox-group']), fieldProps: React.PropTypes.object }; @@ -36,6 +37,9 @@ class FormField extends React.Component { else if (field === 'checkbox') { return false; } + else if (field === 'checkbox-group') { + return []; + } else if (field === 'textarea') { return RichTextEditor.createEmptyValue(); } @@ -45,7 +49,7 @@ class FormField extends React.Component { } render() { - const Wrapper = (this.props.field === 'textarea') ? 'div' : 'label'; + const Wrapper = (_.includes(this.getDivTypes(), this.props.field)) ? 'div' : 'label'; const fieldContent = [ {this.props.label}, this.renderField(), @@ -67,7 +71,8 @@ class FormField extends React.Component { 'input': Input, 'textarea': TextEditor, 'select': DropDown, - 'checkbox': Checkbox + 'checkbox': Checkbox, + 'checkbox-group': CheckboxGroup }[this.props.field]; if(this.props.decorator) { @@ -122,6 +127,13 @@ class FormField extends React.Component { return props; } + getDivTypes() { + return [ + 'textarea', + 'checkbox-group' + ]; + } + onChange(nativeEvent) { let event = nativeEvent; diff --git a/client/src/data/languages/en.js b/client/src/data/languages/en.js index cdd04281..dc9d268f 100644 --- a/client/src/data/languages/en.js +++ b/client/src/data/languages/en.js @@ -97,10 +97,12 @@ export default { 'ASSIGNED_TICKETS': '{tickets} assigned tickets', 'CLOSED_TICKETS': '{tickets} closed tickets', 'LAST_LOGIN': 'Last login', - 'STAFF_MEMBERS': 'Staff members', 'ADD_NEW_STAFF': 'Add new staff', 'ADD_STAFF': 'Add staff', 'LEVEL': 'Level', + 'LEVEL_1': 'Level 1 (Tickets)', + 'LEVEL_2': 'Level 2 (Tickets + Articles)', + 'LEVEL_3': 'Level 2 (Tickets + Articles + Staff)', //VIEW DESCRIPTIONS 'CREATE_TICKET_DESCRIPTION': 'This is a form for creating tickets. Fill the form and send us your issues/doubts/suggestions. Our support system will answer it as soon as possible.', From 1e69ca3651c21156a0929950bd594b2bca00fdc5 Mon Sep 17 00:00:00 2001 From: ivan Date: Fri, 9 Dec 2016 18:59:26 -0300 Subject: [PATCH 3/4] Ivan - Update checkbox styling, add custom scroll style for chrome [skip ci] --- .../app/admin/panel/staff/add-staff-modal.js | 21 +++++++---- .../admin/panel/staff/add-staff-modal.scss | 17 +++++++++ .../src/core-components/checkbox-group.scss | 11 ++++++ client/src/core-components/checkbox.js | 4 +-- client/src/core-components/checkbox.scss | 10 ++++-- client/src/scss/_vars.scss | 35 ++++++++++++++++++- 6 files changed, 86 insertions(+), 12 deletions(-) create mode 100644 client/src/core-components/checkbox-group.scss diff --git a/client/src/app/admin/panel/staff/add-staff-modal.js b/client/src/app/admin/panel/staff/add-staff-modal.js index 52c2ed63..80d7fb65 100644 --- a/client/src/app/admin/panel/staff/add-staff-modal.js +++ b/client/src/app/admin/panel/staff/add-staff-modal.js @@ -15,16 +15,25 @@ class AddStaffModal extends React.Component {
    - - - -
    - +
    + + + +
    + +
    +
    +
    +
    +
    {i18n('Departments')}
    + +
    +
    - {i18n('SAVE')} diff --git a/client/src/app/admin/panel/staff/add-staff-modal.scss b/client/src/app/admin/panel/staff/add-staff-modal.scss index e2456788..a2dd0d64 100644 --- a/client/src/app/admin/panel/staff/add-staff-modal.scss +++ b/client/src/app/admin/panel/staff/add-staff-modal.scss @@ -1,6 +1,23 @@ +@import "../../../../scss/vars"; + .add-staff-modal { + width: 700px; &__level-selector { text-align: center; } + + &__departments { + @include scrollbars(); + + border: 1px solid $grey; + padding: 20px; + height: 320px; + overflow-y: auto; + } + + &__departments-title { + font-size: $font-size--md; + text-align: center; + } } \ No newline at end of file diff --git a/client/src/core-components/checkbox-group.scss b/client/src/core-components/checkbox-group.scss new file mode 100644 index 00000000..92612c5c --- /dev/null +++ b/client/src/core-components/checkbox-group.scss @@ -0,0 +1,11 @@ +@import "../scss/vars"; + +.checkbox-group { + list-style-type: none; + margin: 0; + padding: 0; + + &__item { + margin: 10px 0; + } +} \ No newline at end of file diff --git a/client/src/core-components/checkbox.js b/client/src/core-components/checkbox.js index d269efee..0dc5efed 100644 --- a/client/src/core-components/checkbox.js +++ b/client/src/core-components/checkbox.js @@ -53,7 +53,7 @@ class CheckBox extends React.Component { props.type = 'checkbox'; props['aria-hidden'] = true; - props.className = 'checkbox--box'; + props.className = 'checkbox__box'; props.checked = this.getValue(); props.onChange = callback(this.handleChange.bind(this), this.props.onChange); @@ -79,7 +79,7 @@ class CheckBox extends React.Component { getIconProps() { return { 'aria-checked': this.getValue(), - className: 'checkbox--icon', + className: 'checkbox__icon', onKeyDown: callback(this.handleIconKeyDown.bind(this), this.props.onKeyDown), role: "checkbox", tabIndex: 0 diff --git a/client/src/core-components/checkbox.scss b/client/src/core-components/checkbox.scss index 9e09a1c5..68d3a18d 100644 --- a/client/src/core-components/checkbox.scss +++ b/client/src/core-components/checkbox.scss @@ -5,11 +5,11 @@ border-radius: 5px; display: inline-block; - &--box { + &__box { display: none; } - &--icon { + &__icon { color: $light-grey; outline: none; @@ -18,8 +18,12 @@ } } + &__label { + margin-left: 10px; + } + &_checked { - .checkbox--icon { + .checkbox__icon { color: $primary-red; &:focus { diff --git a/client/src/scss/_vars.scss b/client/src/scss/_vars.scss index 59793c65..cea6e370 100644 --- a/client/src/scss/_vars.scss +++ b/client/src/scss/_vars.scss @@ -25,4 +25,37 @@ $font-size--sm: 13px; $font-size--md: 16px; $font-size--bg: 19px; $font-size--lg: 24px; -$font-size--xl: 32px; \ No newline at end of file +$font-size--xl: 32px; + +@mixin scrollbars() { + $size: .4em; + $color: $grey; + + &::-webkit-scrollbar { + width: $size; + height: $size; + } + + &::-webkit-scrollbar-thumb { + background: transparent; + } + + &::-webkit-scrollbar-track { + backgroundr: transparent; + } + + &:hover { + &::-webkit-scrollbar { + width: $size; + height: $size; + } + + &::-webkit-scrollbar-thumb { + background: $color; + } + + &::-webkit-scrollbar-track { + background: lighten($color, 50%); + } + } +} From 5ce4fa1f445c3851ddfb24eb16e5dc6925c00499 Mon Sep 17 00:00:00 2001 From: Ivan Diaz Date: Sat, 10 Dec 2016 16:33:49 -0300 Subject: [PATCH 4/4] Ivan - Add API call to add staff modal [skip ci] --- .../app/admin/panel/staff/add-staff-modal.js | 57 ++++++++++++++++++- client/src/data/fixtures/staff-fixtures.js | 13 ++++- 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/client/src/app/admin/panel/staff/add-staff-modal.js b/client/src/app/admin/panel/staff/add-staff-modal.js index 80d7fb65..defd85bd 100644 --- a/client/src/app/admin/panel/staff/add-staff-modal.js +++ b/client/src/app/admin/panel/staff/add-staff-modal.js @@ -1,20 +1,33 @@ import React from 'react'; +import _ from 'lodash'; import i18n from 'lib-app/i18n'; +import API from 'lib-app/api-call'; import SessionStore from 'lib-app/session-store'; import Header from 'core-components/header' import Form from 'core-components/form'; import FormField from 'core-components/form-field'; import SubmitButton from 'core-components/submit-button'; +import Button from 'core-components/button'; class AddStaffModal extends React.Component { + static contextTypes = { + closeModal: React.PropTypes.func + }; + + state = { + loading: false, + errors: {}, + error: null + }; + render() { return (
    - + this.setState({errors})} loading={this.state.loading}>
    @@ -37,17 +50,55 @@ class AddStaffModal extends React.Component { {i18n('SAVE')} +
    ); } getDepartments() { - return SessionStore.getDepartments().map((department) => department.name); + return SessionStore.getDepartments().map(department => department.name); } onSubmit(form) { - console.log(form); + let departments = _.filter(SessionStore.getDepartments(), (department, index) => { + return _.includes(form.departments, index); + }).map(department => department.id); + + this.setState({loading: true}); + + API.call({ + path: '/staff/add', + data: { + name: form.name, + email: form.email, + password: form.password, + level: form.level + 1, + department: JSON.stringify(departments) + } + }).then(this.context.closeModal).catch((result) => { + this.setState({ + loading: false, + error: result.message + }); + }); + } + + onCancelClick(event) { + event.preventDefault(); + this.context.closeModal(); + } + + getErrors() { + let errors = _.extend({}, this.state.errors); + + if (this.state.error === 'ALREADY_A_STAFF') { + errors.email = i18n('EMAIL_EXISTS'); + } + + return errors; } } diff --git a/client/src/data/fixtures/staff-fixtures.js b/client/src/data/fixtures/staff-fixtures.js index 73bbd707..b0180b7b 100644 --- a/client/src/data/fixtures/staff-fixtures.js +++ b/client/src/data/fixtures/staff-fixtures.js @@ -629,6 +629,17 @@ module.exports = [ ] }; } - + }, + { + path: '/staff/add', + time: 100, + response: function () { + return { + status: 'success', + data: { + staffId: 5 + } + }; + } } ]; \ No newline at end of file