From 18c4c0ea82d3a803d539061df2cf3371245700bf Mon Sep 17 00:00:00 2001 From: Federico Madoery Date: Tue, 8 Jan 2019 17:43:36 -0300 Subject: [PATCH] [WIP] Issue #22 Code Cleanup Alphabetical ordering of imports and actions (in redux) Implementation of BlockList to manage and render the Set Blocks, to improve the readability of Schedule Page by reducing your code length Enable Submit now is managed through redux UI Polish Fix alignment for Setblocks scheduled within the same day and make sure the setblock dots (on both the sidebar and the main page are perfect squares instead of rectangles - Was Fixed some commits ago in PR "Close Issue #9" Fix alignment on the empty state UI "This user hasn't committed..." - Was Fixed some commits ago in PR "Close Issue #9" --- config/paths.js | 4 +- web/components/BlockList.jsx | 87 ++++++++++++++++++++++++++++++--- web/components/CommitBlock.jsx | 2 +- web/components/DayBlock.jsx | 5 +- web/components/NavigationBar.js | 2 +- web/components/SchedulePage.jsx | 76 +++++++--------------------- web/components/SetBlock.jsx | 6 +-- web/components/SideBar.jsx | 2 +- web/components/TeamMember.jsx | 5 +- web/reducers/environment.js | 60 ++++++++++++++--------- 10 files changed, 151 insertions(+), 98 deletions(-) diff --git a/config/paths.js b/config/paths.js index 9c7c793..146fd0c 100644 --- a/config/paths.js +++ b/config/paths.js @@ -1,5 +1,5 @@ -var path = require('path') -var fs = require('fs') +const path = require('path') +const fs = require('fs') const projectDirectory = fs.realpathSync(process.cwd()) const resolve = relativePath => path.resolve(projectDirectory, relativePath) diff --git a/web/components/BlockList.jsx b/web/components/BlockList.jsx index 4bcc434..b47ea26 100644 --- a/web/components/BlockList.jsx +++ b/web/components/BlockList.jsx @@ -1,12 +1,87 @@ import React from 'react'; +import { connect } from 'react-redux'; +import moment from 'moment'; +import { cloneDeep } from 'lodash'; + +import SetBlock from './SetBlock'; +import Text from './Text'; +import { DEFAULT_SETBLOCKS } from '../constants'; + +import { + setEnableSubmit, updateUnsavedSetblocks, +} from '../reducers/environment'; + +class BlockList extends React.Component { + + completeWithEmptySetBlocks(setBlocks) { + const defaultSetBlocks = cloneDeep(DEFAULT_SETBLOCKS); + let replacedBlocks = 0; + setBlocks = _.orderBy(setBlocks, ['blockTime'], ['asc']); // Use Lodash to sort array by 'name' + setBlocks = _.uniqBy(setBlocks, 'blockTime'); // Use Lodash to delete repeated blockTimes + if (setBlocks && setBlocks.length > 0) { // To avoid iterate if the array is empty, return default + defaultSetBlocks.forEach((setBlock, index, theArray) => { + if (setBlocks && replacedBlocks < setBlocks.length && setBlock.blockTime === setBlocks[replacedBlocks].blockTime) { + theArray[index] = setBlocks[replacedBlocks]; + replacedBlocks++; + } + }); + } + return defaultSetBlocks + } + + updateUnsavedSetBlock(selectedDay, index, editedSetBlock ) { + const { unsavedSetBlocks } = this.props + let dayEdited = unsavedSetBlocks[selectedDay]; + dayEdited[index] = editedSetBlock; // index 0 = SetBlock with blockTime 1 + this.props.updateUnsavedSetblocks({ + ...unsavedSetBlocks, + [selectedDay]: dayEdited + }) + this.props.setEnableSubmit(true) + } -export default class BlockList extends React.Component { render() { - return ( -
-
BlockList
-
- ); + const { + editModeSchedule, currentWeeklySetblocks, unsavedSetBlocks, selectedDay + } = this.props; + const selectedDayFormatted = moment(selectedDay).format('YYYY-MM-DD') + let setBlocksByDate = _.groupBy(currentWeeklySetblocks, 'date'); + let setBlocks = setBlocksByDate[selectedDayFormatted]; + + if (editModeSchedule && unsavedSetBlocks ) { + // As it is your schedule, you can see the empty blocks, to complete then, that's why it is completed with the missing ones + return this.completeWithEmptySetBlocks(setBlocks).map((setBlock, index) => { + return ( + this.updateUnsavedSetBlock(selectedDayFormatted, index, editedSetBlock )} + /> + ) + }) + } else if (!editModeSchedule && setBlocks) { + return setBlocks.map((setBlock, index) => { + return + }) + } else { + return ( + This user hasn't committed any Setblocks for this day + ) + } } } +const mapStateToProps = ({ environment }) => { + return { + ...environment + }; +}; + +const mapDispatchToProps = (dispatch) => { + return { + setEnableSubmit: (enableSubmit) => dispatch(setEnableSubmit(enableSubmit)), + updateUnsavedSetblocks: (unsavedSetBlocks) => dispatch(updateUnsavedSetblocks(unsavedSetBlocks)) + }; +}; +export default connect(mapStateToProps, mapDispatchToProps)(BlockList); \ No newline at end of file diff --git a/web/components/CommitBlock.jsx b/web/components/CommitBlock.jsx index a2bdfee..79b68a2 100644 --- a/web/components/CommitBlock.jsx +++ b/web/components/CommitBlock.jsx @@ -3,9 +3,9 @@ import moment from 'moment'; import { connect } from 'react-redux'; import { Check } from 'styled-icons/feather/Check.cjs' -import Text from './Text'; import Card from './Card'; import Flex from './Flex'; +import Text from './Text'; import { createSetBlock, setEditModeSchedule, updateSetBlock } from '../reducers/environment'; diff --git a/web/components/DayBlock.jsx b/web/components/DayBlock.jsx index 5b9203a..5db3f7b 100644 --- a/web/components/DayBlock.jsx +++ b/web/components/DayBlock.jsx @@ -1,10 +1,11 @@ +import React from 'react'; import { connect } from 'react-redux'; import moment from 'moment'; -import React from 'react'; + +import Card from './Card'; import Flex from './Flex'; import Text from './Text'; -import Card from './Card'; class DayBlock extends React.Component { diff --git a/web/components/NavigationBar.js b/web/components/NavigationBar.js index 39722ba..fdc2e53 100644 --- a/web/components/NavigationBar.js +++ b/web/components/NavigationBar.js @@ -1,6 +1,6 @@ import React from 'react'; import { connect } from 'react-redux'; -var _ = require('lodash'); +import _ from 'lodash' import NavLinkItem from './NavLinkItem'; diff --git a/web/components/SchedulePage.jsx b/web/components/SchedulePage.jsx index e913d75..13398a7 100644 --- a/web/components/SchedulePage.jsx +++ b/web/components/SchedulePage.jsx @@ -3,18 +3,20 @@ import moment from 'moment'; import { connect } from 'react-redux'; import { cloneDeep } from 'lodash'; +import BlockList from './BlockList'; +import CommitBlock from './CommitBlock'; +import Flex from './Flex'; +import LoadingDots from './Loading'; import ScheduleHeader from './ScheduleHeader'; import SideBar from './SideBar'; -import Flex from './Flex'; -import SetBlock from './SetBlock'; import Text from './Text'; -import LoadingDots from './Loading'; -import CommitBlock from './CommitBlock'; -import { DEFAULT_SETBLOCKS } from '../constants/index'; + +import { DEFAULT_SETBLOCKS } from '../constants'; import { fetchCurrentTeamMemberById, setEditModeSchedule, + setEnableSubmit, setSelectedDay, updateUnsavedSetblocks } from '../reducers/environment'; @@ -23,7 +25,6 @@ import { class SchedulePage extends React.Component { state = { daysOfWeek: [], - enableSubmit: false, } componentDidMount() { @@ -69,7 +70,7 @@ class SchedulePage extends React.Component { // This only take effect if change the currentTeamMember if ((editModeSchedule && currentTeamMember !== nextProps.currentTeamMember) || selectedDay !== nextProps.selectedDay) { this.makeSetBlocksForEdit(nextProps.currentWeeklySetblocks); - this.setState({ enableSubmit: false }) + this.props.setEnableSubmit(false) } } @@ -86,61 +87,21 @@ class SchedulePage extends React.Component { let replacedBlocks = 0; setBlocks = _.orderBy(setBlocks, ['blockTime'], ['asc']); // Use Lodash to sort array by 'name' setBlocks = _.uniqBy(setBlocks, 'blockTime'); // Use Lodash to delete repeated blockTimes - defaultSetBlocks.forEach((setBlock, index, theArray) => { - if (setBlocks && replacedBlocks < setBlocks.length && setBlock.blockTime === setBlocks[replacedBlocks].blockTime) { - theArray[index] = setBlocks[replacedBlocks]; - replacedBlocks++; - } - }); - return defaultSetBlocks - } - - updateUnsavedSetBlock(selectedDay, index, editedSetBlock ) { - const { unsavedSetBlocks } = this.props - let dayEdited = unsavedSetBlocks[selectedDay]; - dayEdited[index] = editedSetBlock; // index 0 = SetBlock with blockTime 1 - this.props.updateUnsavedSetblocks({ - ...unsavedSetBlocks, - [selectedDay]: dayEdited - }) - this.setState({ enableSubmit: true }) - } - - renderSetBlocks = (selectedDay) => { - const { editModeSchedule, currentWeeklySetblocks, unsavedSetBlocks } = this.props; - selectedDay = moment(selectedDay).format('YYYY-MM-DD') - const setBlocksByDate = _.groupBy(currentWeeklySetblocks, 'date') - let setBlocks = setBlocksByDate[selectedDay]; - - if (editModeSchedule && unsavedSetBlocks) { - // If the match.params don't have a teamMemberId are u seeing your schedule - // As it is your schedule, you can see the empty blocks, to complete then, that's why it is completed with the missing ones - return this.completeWithEmptySetBlocks(setBlocks).map((setBlock, index) => { - return ( - this.updateUnsavedSetBlock(selectedDay, index, editedSetBlock )} - /> - ) - }) - } else if (!editModeSchedule && setBlocks) { - return setBlocks.map((setBlock, index) => { - return - }) - } else { - return ( - This user hasn't committed any Setblocks for this day - ) + if (setBlocks && setBlocks.length > 0) { // To avoid iterate if the array is empty, return default + defaultSetBlocks.forEach((setBlock, index, theArray) => { + if (setBlocks && replacedBlocks < setBlocks.length && setBlock.blockTime === setBlocks[replacedBlocks].blockTime) { + theArray[index] = setBlocks[replacedBlocks]; + replacedBlocks++; + } + }); } + return defaultSetBlocks } renderIfItReady() { const { - match, currentTeamMember, fetchingData, selectedDay, editModeSchedule + match, currentTeamMember, fetchingData, editModeSchedule, enableSubmit } = this.props - const { enableSubmit } = this.state if (fetchingData) { return ( // If you are waiting for the API to respond, render a loading @@ -161,7 +122,7 @@ class SchedulePage extends React.Component { {match.params.teamMemberId ? currentTeamMember.name : 'Your'} {' Schedule\'s Page'} - {this.renderSetBlocks(selectedDay)} + {editModeSchedule && ()} ) @@ -212,6 +173,7 @@ const mapDispatchToProps = (dispatch) => { fetchCurrentTeamMemberById: (params) => dispatch(fetchCurrentTeamMemberById(params)), setSelectedDay: (selectedDay) => dispatch(setSelectedDay(selectedDay)), setEditModeSchedule: (editMode) => dispatch(setEditModeSchedule(editMode)), + setEnableSubmit: (enableSubmit) => dispatch(setEnableSubmit(enableSubmit)), updateUnsavedSetblocks: (unsavedSetBlocks) => dispatch(updateUnsavedSetblocks(unsavedSetBlocks)) }; }; diff --git a/web/components/SetBlock.jsx b/web/components/SetBlock.jsx index 184c3fa..a92e0ae 100644 --- a/web/components/SetBlock.jsx +++ b/web/components/SetBlock.jsx @@ -2,12 +2,12 @@ import React from 'react'; import { connect } from 'react-redux'; import { Edit3 } from 'styled-icons/feather/Edit3.cjs' -import Flex from './Flex'; -import Text from './Text'; +import Box from './Box'; import Card from './Card'; +import Flex from './Flex'; import Modal from './Modal'; -import Box from './Box'; import Input from './Input'; +import Text from './Text'; class SetBlock extends React.Component { diff --git a/web/components/SideBar.jsx b/web/components/SideBar.jsx index ec13389..3c696b8 100644 --- a/web/components/SideBar.jsx +++ b/web/components/SideBar.jsx @@ -2,8 +2,8 @@ import React from 'react'; import { withRouter } from 'react-router-dom'; import { connect } from 'react-redux'; -import Flex from './Flex'; import DayBlock from './DayBlock'; +import Flex from './Flex'; import { setEditModeSchedule, setSelectedDay } from '../reducers/environment'; diff --git a/web/components/TeamMember.jsx b/web/components/TeamMember.jsx index 49d8b9d..c59ff4e 100644 --- a/web/components/TeamMember.jsx +++ b/web/components/TeamMember.jsx @@ -1,9 +1,10 @@ import React from 'react'; -import Flex from './Flex'; -import Text from './Text'; import Card from './Card'; +import Flex from './Flex'; import Image from './Image'; +import Text from './Text'; + export default class TeamMember extends React.Component { render() { diff --git a/web/reducers/environment.js b/web/reducers/environment.js index 7bc1bfe..76dcc72 100644 --- a/web/reducers/environment.js +++ b/web/reducers/environment.js @@ -1,59 +1,71 @@ -import moment from 'moment'; - import api from 'scripts/api' +import moment from 'moment'; // Index of Action Types -const RECEIVE_TEAM_MEMBERS = 'RECEIVE_TEAM_MEMBERS' +const CREATE_SET_BLOCK = 'CREATE_SET_BLOCK' +const EDIT_MODE_SCHEDULE = 'EDIT_MODE_SCHEDULE' +const ENABLE_SUBMIT = 'ENABLE_SUBMIT' +const FETCHING_DATA = 'FETCHING_DATA' const RECEIVE_TEAM_MEMBER = 'RECEIVE_TEAM_MEMBER' +const RECEIVE_TEAM_MEMBERS = 'RECEIVE_TEAM_MEMBERS' const SET_SELECTED_DAY = 'SET_SELECTED_DAY' -const FETCHING_DATA = 'FETCHING_DATA' -const EDIT_MODE_SCHEDULE = 'EDIT_MODE_SCHEDULE' const UPDATE_BLOCK_FRACTION = 'UPDATE_BLOCK_FRACTION' -const CREATE_SET_BLOCK = 'CREATE_SET_BLOCK' const UPDATE_SET_BLOCK = 'UPDATE_SET_BLOCK' const UPDATE_UNSAVED_SET_BLOCKS = 'UPDATE_UNSAVED_SET_BLOCKS' // Reducer const initialState = { - teamMembers: [], currentTeamMember: { id: '', name: '' }, currentWeeklySetblocks: [], - selectedDay: moment.now(), - fetchingData: false, editModeSchedule: false, + enableSubmit: false, + fetchingData: false, + teamMembers: [], + selectedDay: moment.now(), unsavedSetBlocks: [], } export default function reducer(state = initialState, action) { switch (action.type) { - case RECEIVE_TEAM_MEMBERS: + case CREATE_SET_BLOCK: return { ...state, - teamMembers: action.members + + currentWeeklySetblocks: action.teamMember.weeklySetblocks } - case RECEIVE_TEAM_MEMBER: + case EDIT_MODE_SCHEDULE: return { ...state, - currentTeamMember: { id: action.member.id, name: action.member.name }, - currentWeeklySetblocks: action.member.weeklySetblocks + editModeSchedule: action.editModeSchedule } - case SET_SELECTED_DAY: + case ENABLE_SUBMIT: return { ...state, - selectedDay: action.selectedDay + enableSubmit: action.enableSubmit } case FETCHING_DATA: return { ...state, fetchingData: action.fetchingData } - case EDIT_MODE_SCHEDULE: + case RECEIVE_TEAM_MEMBER: return { ...state, - editModeSchedule: action.editModeSchedule + currentTeamMember: { id: action.member.id, name: action.member.name }, + currentWeeklySetblocks: action.member.weeklySetblocks + } + case RECEIVE_TEAM_MEMBERS: + return { + ...state, + teamMembers: action.members + } + case SET_SELECTED_DAY: + return { + ...state, + selectedDay: action.selectedDay } case UPDATE_BLOCK_FRACTION: return { @@ -62,11 +74,6 @@ export default function reducer(state = initialState, action) { (setBlock) => setBlock.id === action.blockId ? { ...setBlock, blockFraction: action.blockFraction } : setBlock ) } - case CREATE_SET_BLOCK: - return { - ...state, - currentWeeklySetblocks: action.teamMember.weeklySetblocks - } case UPDATE_SET_BLOCK: return { ...state, @@ -234,6 +241,13 @@ export function setEditModeSchedule(editModeSchedule) { } } +export function setEnableSubmit(enableSubmit) { + return { + type: ENABLE_SUBMIT, + enableSubmit + } +} + export function updateBlockFraction(blockId, blockFraction) { return { type: UPDATE_BLOCK_FRACTION,