Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add dnd from dimensions to specific position in layout axis #575

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
b7bf465
feat: move dnd context up in hierarchy and create DimensionItems
jenniferarnesen Jan 20, 2020
3ca08ae
feat: working state except for dimensionPanel list placeholder
jenniferarnesen Jan 21, 2020
013f2a6
feat: dim item no longer lost from dim panel
jenniferarnesen Jan 22, 2020
497801a
feat: mostly working dnd from dimension panel
jenniferarnesen Jan 22, 2020
98abc42
feat: fixing
jenniferarnesen Jan 22, 2020
223f089
fix: cleanup
jenniferarnesen Jan 22, 2020
b0ae86b
fix: inbetween step
jenniferarnesen Jan 23, 2020
5fbb65b
fix: some refactoring
jenniferarnesen Jan 24, 2020
8480d7c
fix: step
jenniferarnesen Jan 24, 2020
fd49e39
fix: remove duplicated file
jenniferarnesen Jan 27, 2020
7a96856
Merge branch 'epic/merge-dv-and-pt-apps-DHIS2-7687' into feat/react-d…
jenniferarnesen Jan 27, 2020
f39900f
feat: keep dnd handler in separate component
jenniferarnesen Jan 27, 2020
aa784bc
feat: drag css
jenniferarnesen Jan 27, 2020
06e171a
fix: remove unused props
jenniferarnesen Jan 27, 2020
c8f81cd
fix: comments on the css
jenniferarnesen Jan 27, 2020
68278ea
fix: stuff
jenniferarnesen Jan 28, 2020
b0eb979
fix: small improvement
jenniferarnesen Jan 28, 2020
57d5918
fix: use meaningful names in functions
jenniferarnesen Jan 28, 2020
b8e7a74
Merge branch 'epic/merge-dv-and-pt-apps-DHIS2-7687' into feat/react-d…
jenniferarnesen Jan 28, 2020
17cb649
fix: improve list filtering code
jenniferarnesen Jan 28, 2020
73549fd
fix: validate when adding dimension from panel
jenniferarnesen Jan 28, 2020
737b8f0
fix: check and use index value properly
jenniferarnesen Jan 28, 2020
5f6f95a
fix: update and new tests
jenniferarnesen Jan 28, 2020
a1a2059
fix: use css modules for new components
jenniferarnesen Jan 29, 2020
5700ad3
fix: additional css modules styles
jenniferarnesen Jan 29, 2020
2905265
Merge branch 'epic/merge-dv-and-pt-apps-DHIS2-7687' into feat/react-d…
jenniferarnesen Jan 29, 2020
05e91f6
fix: make dim item id unique
jenniferarnesen Jan 29, 2020
bf3ce20
fix: use itemsByDimension from ui store directly
jenniferarnesen Jan 29, 2020
d3a8c5f
fix: remove use of alias since it is confusing
jenniferarnesen Jan 29, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions packages/app/i18n/en.pot
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ msgid ""
"items. Only the first {{maxNumber}} items will be used and saved."
msgstr ""

msgid "Search dimensions"
msgstr ""

msgid "Download"
msgstr ""

Expand Down
31 changes: 17 additions & 14 deletions packages/app/src/components/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { connect } from 'react-redux'
import PropTypes from 'prop-types'
import i18n from '@dhis2/d2-i18n'

import DndContext from './DndContext'
import Snackbar from '../components/Snackbar/Snackbar'
import MenuBar from './MenuBar/MenuBar'
import TitleBar from './TitleBar/TitleBar'
Expand Down Expand Up @@ -169,22 +170,24 @@ export class App extends Component {
</div>
</div>
<div className="section-main flex-grow-1 flex-ct">
<div className="main-left">
<DimensionsPanel />
</div>
<div className="main-center flex-grow-1 flex-basis-0 flex-ct flex-dir-col">
<div className="main-center-layout">
<Layout />
</div>
<div className="main-center-titlebar">
<TitleBar />
<DndContext>
<div className="main-left">
<DimensionsPanel />
</div>
<div className="main-center-canvas flex-grow-1">
{this.state.initialLoadIsComplete && (
<Visualization />
)}
<div className="main-center flex-grow-1 flex-basis-0 flex-ct flex-dir-col">
<div className="main-center-layout">
<Layout />
</div>
<div className="main-center-titlebar">
<TitleBar />
</div>
<div className="main-center-canvas flex-grow-1">
{this.state.initialLoadIsComplete && (
<Visualization />
)}
</div>
</div>
</div>
</DndContext>
{this.props.ui.rightSidebarOpen && this.props.current && (
<div className="main-right">
<Interpretations
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export class AddToLayoutButton extends Component {

onUpdate = axisId => {
this.props.onAddDimension({
[this.props.dialogId]: axisId,
[this.props.dialogId]: { axisId },
})

this.props.onClick()
Expand Down
71 changes: 10 additions & 61 deletions packages/app/src/components/DimensionsPanel/DimensionsPanel.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
import React, { Component } from 'react'
import { connect } from 'react-redux'
import {
DimensionsPanel,
DimensionMenu,
getDisallowedDimensions,
getAllLockedDimensionIds,
DIMENSION_ID_ASSIGNED_CATEGORIES,
} from '@dhis2/analytics'
import PropTypes from 'prop-types'

import DialogManager from './Dialogs/DialogManager'
import { SOURCE_DIMENSIONS } from '../../modules/layout'
import { setDataTransfer } from '../../modules/dnd'
import DndDimensionsPanel from './DndDimensionsPanel'
import * as fromReducers from '../../reducers'
import * as fromActions from '../../actions'

import { styles } from './styles/DimensionsPanel.style'
import { AXIS_SETUP_DIALOG_ID } from '../AxisSetup/AxisSetup'
Expand All @@ -22,59 +17,36 @@ import {
acAddUiLayoutDimensions,
acRemoveUiLayoutDimensions,
} from '../../actions/ui'
import { sGetUiType } from '../../reducers/ui'
import { createSelector } from 'reselect'

export class Dimensions extends Component {
state = {
dimensionMenuAnchorEl: null,
dimensionId: null,
}

onDimensionOptionsClick = (event, id) => {
openOptionsMenuForDimension = (event, id) => {
event.stopPropagation()

// set anchor for options menu
// open menu
this.setState({
dimensionMenuAnchorEl: event.currentTarget,
dimensionId: id,
})
}

onDimensionOptionsClose = () =>
closeOptionsMenuForDimension = () =>
this.setState({
dimensionMenuAnchorEl: null,
dimensionId: null,
})

onDimensionDragStart = e => {
setDataTransfer(e, SOURCE_DIMENSIONS)
}

disabledDimension = dimensionId =>
this.props.disallowedDimensions.includes(dimensionId)

lockedDimension = dimensionId =>
this.props.lockedDimensions.includes(dimensionId)

getNumberOfDimensionItems = () =>
(this.props.itemsByDimension[this.state.dimensionId] || []).length

render() {
return (
<div style={styles.divContainer}>
<DimensionsPanel
dimensions={Object.values(this.props.dimensions)}
selectedIds={this.props.selectedIds}
disabledDimension={this.disabledDimension}
lockedDimension={this.lockedDimension}
recommendedDimension={dimensionId =>
this.props.recommendedIds.includes(dimensionId)
}
onDimensionOptionsClick={this.onDimensionOptionsClick}
onDimensionDragStart={this.onDimensionDragStart}
onDimensionClick={this.props.onDimensionClick}
<DndDimensionsPanel
onDimensionOptionsClick={this.openOptionsMenuForDimension}
/>
<DimensionMenu
dimensionId={this.state.dimensionId}
Expand All @@ -96,48 +68,30 @@ export class Dimensions extends Component {
axisItemHandler={this.props.axisItemHandler}
removeItemHandler={this.props.removeItemHandler}
anchorEl={this.state.dimensionMenuAnchorEl}
onClose={this.onDimensionOptionsClose}
onClose={this.closeOptionsMenuForDimension}
/>
<DialogManager />
</div>
)
}
}

const getDisallowedDimensionsMemo = createSelector([sGetUiType], type =>
getDisallowedDimensions(type)
)

const getLockedDimensionsMemo = createSelector([sGetUiType], type =>
getAllLockedDimensionIds(type)
)

Dimensions.propTypes = {
assignedCategoriesItemHandler: PropTypes.func,
axisItemHandler: PropTypes.func,
dimensions: PropTypes.object,
disallowedDimensions: PropTypes.array,
dualAxisItemHandler: PropTypes.func,
getCurrentAxisId: PropTypes.func,
itemsByDimension: PropTypes.object,
layoutHasAssignedCategories: PropTypes.bool,
lockedDimensions: PropTypes.array,
recommendedIds: PropTypes.array,
removeItemHandler: PropTypes.func,
selectedIds: PropTypes.array,
ui: PropTypes.object,
onDimensionClick: PropTypes.func,
}

const mapStateToProps = state => ({
ui: fromReducers.fromUi.sGetUi(state),
dimensions: fromReducers.fromDimensions.sGetDimensions(state),
selectedIds: fromReducers.fromUi.sGetDimensionIdsFromLayout(state),
recommendedIds: fromReducers.fromRecommendedIds.sGetRecommendedIds(state),
layout: fromReducers.fromUi.sGetUiLayout(state),
itemsByDimension: fromReducers.fromUi.sGetUiItems(state),
disallowedDimensions: getDisallowedDimensionsMemo(state),
lockedDimensions: getLockedDimensionsMemo(state),
layoutHasAssignedCategories: fromReducers.fromUi.sLayoutHasAssignedCategories(
state
),
Expand All @@ -146,12 +100,10 @@ const mapStateToProps = state => ({
})

const mapDispatchToProps = dispatch => ({
onDimensionClick: id =>
dispatch(fromActions.fromUi.acSetUiActiveModalDialog(id)),
dualAxisItemHandler: () =>
dispatch(acSetUiActiveModalDialog(AXIS_SETUP_DIALOG_ID)),
axisItemHandler: (dimensionId, targetAxisId, numberOfDimensionItems) => {
dispatch(acAddUiLayoutDimensions({ [dimensionId]: targetAxisId }))
axisItemHandler: (dimensionId, axisId, numberOfDimensionItems) => {
dispatch(acAddUiLayoutDimensions({ [dimensionId]: { axisId } }))

if (numberOfDimensionItems > 0) {
dispatch(acSetUiActiveModalDialog(dimensionId))
Expand All @@ -160,15 +112,12 @@ const mapDispatchToProps = dispatch => ({
removeItemHandler: dimensionId => {
dispatch(acRemoveUiLayoutDimensions(dimensionId))
},
assignedCategoriesItemHandler: (
layoutHasAssignedCategories,
destination
) => {
assignedCategoriesItemHandler: (layoutHasAssignedCategories, axisId) => {
dispatch(
layoutHasAssignedCategories
? acRemoveUiLayoutDimensions(DIMENSION_ID_ASSIGNED_CATEGORIES)
: acAddUiLayoutDimensions({
[DIMENSION_ID_ASSIGNED_CATEGORIES]: destination,
[DIMENSION_ID_ASSIGNED_CATEGORIES]: { axisId },
})
)
},
Expand Down
76 changes: 76 additions & 0 deletions packages/app/src/components/DimensionsPanel/DndDimensionItem.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { Draggable } from 'react-beautiful-dnd'
import { DimensionItem } from '@dhis2/analytics'

import styles from './styles/DndDimensionItem.module.css'

export class DndDimensionItem extends Component {
render = () => {
const {
id,
index,
name,
isSelected,
isLocked,
isDeactivated,
isRecommended,
onClick,
onOptionsClick,
} = this.props

const itemCommonProps = {
name,
isSelected,
isLocked,
isDeactivated,
isRecommended,
}

return (
<Draggable
draggableId={id}
index={index}
isDragDisabled={isSelected || isDeactivated || isLocked}
>
{(provided, snapshot) => (
<>
<DimensionItem
innerRef={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
id={id}
className={
snapshot.isDragging ? styles.dragging : null
}
onClick={onClick}
onOptionsClick={onOptionsClick}
{...itemCommonProps}
/>
{snapshot.isDragging && (
<DimensionItem
id={`dimension-item-clone-${id}`}
className={styles.dimensionItemClone}
{...itemCommonProps}
/>
)}
</>
)}
</Draggable>
)
}
}

DndDimensionItem.propTypes = {
id: PropTypes.string,
index: PropTypes.number,
isDeactivated: PropTypes.bool,
isLocked: PropTypes.bool,
isRecommended: PropTypes.bool,
isSelected: PropTypes.bool,
name: PropTypes.string,
onClick: PropTypes.func,
onOptionsClick: PropTypes.func,
}

export default DndDimensionItem
Loading