NameableGraph Dropdown now contains an active Delete button (#1058)
* Dropdown now contains an active Delete button * Prefer `filter` over `findIndex` => `slice`pull/1061/head
parent
01ec21b483
commit
148140effa
|
@ -3,6 +3,7 @@ import {
|
||||||
updateDashboard as updateDashboardAJAX,
|
updateDashboard as updateDashboardAJAX,
|
||||||
updateDashboardCell as updateDashboardCellAJAX,
|
updateDashboardCell as updateDashboardCellAJAX,
|
||||||
addDashboardCell as addDashboardCellAJAX,
|
addDashboardCell as addDashboardCellAJAX,
|
||||||
|
deleteDashboardCell as deleteDashboardCellAJAX,
|
||||||
} from 'src/dashboards/apis'
|
} from 'src/dashboards/apis'
|
||||||
|
|
||||||
import {NEW_DEFAULT_DASHBOARD_CELL} from 'src/dashboards/constants'
|
import {NEW_DEFAULT_DASHBOARD_CELL} from 'src/dashboards/constants'
|
||||||
|
@ -86,6 +87,13 @@ export const renameDashboardCell = (x, y, name) => ({
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const deleteDashboardCell = (cell) => ({
|
||||||
|
type: 'DELETE_DASHBOARD_CELL',
|
||||||
|
payload: {
|
||||||
|
cell,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
// Async Action Creators
|
// Async Action Creators
|
||||||
|
|
||||||
export const getDashboards = (dashboardID) => (dispatch) => {
|
export const getDashboards = (dashboardID) => (dispatch) => {
|
||||||
|
@ -117,3 +125,13 @@ export const addDashboardCellAsync = (dashboard) => async (dispatch) => {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const deleteDashboardCellAsync = (cell) => async (dispatch) => {
|
||||||
|
try {
|
||||||
|
await deleteDashboardCellAJAX(cell)
|
||||||
|
dispatch(deleteDashboardCell(cell))
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -48,3 +48,15 @@ export const addDashboardCell = async (dashboard, cell) => {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const deleteDashboardCell = async (cell) => {
|
||||||
|
try {
|
||||||
|
return await AJAX({
|
||||||
|
method: 'DELETE',
|
||||||
|
url: cell.links.self,
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ const Dashboard = ({
|
||||||
onEditCell,
|
onEditCell,
|
||||||
onRenameCell,
|
onRenameCell,
|
||||||
onUpdateCell,
|
onUpdateCell,
|
||||||
|
onDeleteCell,
|
||||||
onSummonOverlayTechnologies,
|
onSummonOverlayTechnologies,
|
||||||
source,
|
source,
|
||||||
autoRefresh,
|
autoRefresh,
|
||||||
|
@ -25,13 +26,13 @@ const Dashboard = ({
|
||||||
<div className={classnames({'page-contents': true, 'presentation-mode': inPresentationMode})}>
|
<div className={classnames({'page-contents': true, 'presentation-mode': inPresentationMode})}>
|
||||||
<div className={classnames('container-fluid full-width dashboard', {'dashboard-edit': isEditMode})}>
|
<div className={classnames('container-fluid full-width dashboard', {'dashboard-edit': isEditMode})}>
|
||||||
{isEditMode ? <Visualizations/> : null}
|
{isEditMode ? <Visualizations/> : null}
|
||||||
{Dashboard.renderDashboard(dashboard, autoRefresh, timeRange, source, onPositionChange, onEditCell, onRenameCell, onUpdateCell, onSummonOverlayTechnologies)}
|
{Dashboard.renderDashboard(dashboard, autoRefresh, timeRange, source, onPositionChange, onEditCell, onRenameCell, onUpdateCell, onDeleteCell, onSummonOverlayTechnologies)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
Dashboard.renderDashboard = (dashboard, autoRefresh, timeRange, source, onPositionChange, onEditCell, onRenameCell, onUpdateCell, onSummonOverlayTechnologies) => {
|
Dashboard.renderDashboard = (dashboard, autoRefresh, timeRange, source, onPositionChange, onEditCell, onRenameCell, onUpdateCell, onDeleteCell, onSummonOverlayTechnologies) => {
|
||||||
const cells = dashboard.cells.map((cell, i) => {
|
const cells = dashboard.cells.map((cell, i) => {
|
||||||
i = `${i}`
|
i = `${i}`
|
||||||
const dashboardCell = {...cell, i}
|
const dashboardCell = {...cell, i}
|
||||||
|
@ -58,6 +59,7 @@ Dashboard.renderDashboard = (dashboard, autoRefresh, timeRange, source, onPositi
|
||||||
onEditCell={onEditCell}
|
onEditCell={onEditCell}
|
||||||
onRenameCell={onRenameCell}
|
onRenameCell={onRenameCell}
|
||||||
onUpdateCell={onUpdateCell}
|
onUpdateCell={onUpdateCell}
|
||||||
|
onDeleteCell={onDeleteCell}
|
||||||
onSummonOverlayTechnologies={onSummonOverlayTechnologies}
|
onSummonOverlayTechnologies={onSummonOverlayTechnologies}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
@ -79,6 +81,7 @@ Dashboard.propTypes = {
|
||||||
onEditCell: func,
|
onEditCell: func,
|
||||||
onRenameCell: func,
|
onRenameCell: func,
|
||||||
onUpdateCell: func,
|
onUpdateCell: func,
|
||||||
|
onDeleteCell: func,
|
||||||
onSummonOverlayTechnologies: func,
|
onSummonOverlayTechnologies: func,
|
||||||
source: shape({
|
source: shape({
|
||||||
links: shape({
|
links: shape({
|
||||||
|
|
|
@ -154,6 +154,10 @@ const DashboardPage = React.createClass({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
handleDeleteDashboardCell(cell) {
|
||||||
|
this.props.dashboardActions.deleteDashboardCellAsync(cell)
|
||||||
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
dashboards,
|
dashboards,
|
||||||
|
@ -223,6 +227,7 @@ const DashboardPage = React.createClass({
|
||||||
onEditCell={this.handleEditDashboardCell}
|
onEditCell={this.handleEditDashboardCell}
|
||||||
onRenameCell={this.handleRenameDashboardCell}
|
onRenameCell={this.handleRenameDashboardCell}
|
||||||
onUpdateCell={this.handleUpdateDashboardCell}
|
onUpdateCell={this.handleUpdateDashboardCell}
|
||||||
|
onDeleteCell={this.handleDeleteDashboardCell}
|
||||||
onSummonOverlayTechnologies={this.handleSummonOverlayTechnologies}
|
onSummonOverlayTechnologies={this.handleSummonOverlayTechnologies}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -109,6 +109,23 @@ export default function ui(state = initialState, action) {
|
||||||
return {...state, ...newState}
|
return {...state, ...newState}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'DELETE_DASHBOARD_CELL': {
|
||||||
|
const {cell} = action.payload
|
||||||
|
const {dashboard} = state
|
||||||
|
|
||||||
|
const newCells = dashboard.cells.filter((c) => !(c.x === cell.x && c.y === cell.y))
|
||||||
|
const newDashboard = {
|
||||||
|
...dashboard,
|
||||||
|
cells: newCells,
|
||||||
|
}
|
||||||
|
const newState = {
|
||||||
|
dashboard: newDashboard,
|
||||||
|
dashboards: state.dashboards.map((d) => d.id === dashboard.id ? newDashboard : d),
|
||||||
|
}
|
||||||
|
|
||||||
|
return {...state, ...newState}
|
||||||
|
}
|
||||||
|
|
||||||
case 'SYNC_DASHBOARD_CELL': {
|
case 'SYNC_DASHBOARD_CELL': {
|
||||||
const {cell} = action.payload
|
const {cell} = action.payload
|
||||||
const {dashboard} = state
|
const {dashboard} = state
|
||||||
|
|
|
@ -50,6 +50,7 @@ export const LayoutRenderer = React.createClass({
|
||||||
onEditCell: func,
|
onEditCell: func,
|
||||||
onRenameCell: func,
|
onRenameCell: func,
|
||||||
onUpdateCell: func,
|
onUpdateCell: func,
|
||||||
|
onDeleteCell: func,
|
||||||
onSummonOverlayTechnologies: func,
|
onSummonOverlayTechnologies: func,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -86,7 +87,7 @@ export const LayoutRenderer = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
generateVisualizations() {
|
generateVisualizations() {
|
||||||
const {autoRefresh, source, cells, onEditCell, onRenameCell, onUpdateCell, onSummonOverlayTechnologies} = this.props;
|
const {autoRefresh, source, cells, onEditCell, onRenameCell, onUpdateCell, onDeleteCell, onSummonOverlayTechnologies} = this.props;
|
||||||
|
|
||||||
return cells.map((cell) => {
|
return cells.map((cell) => {
|
||||||
const qs = cell.queries.map((query) => {
|
const qs = cell.queries.map((query) => {
|
||||||
|
@ -103,6 +104,7 @@ export const LayoutRenderer = React.createClass({
|
||||||
onEditCell={onEditCell}
|
onEditCell={onEditCell}
|
||||||
onRenameCell={onRenameCell}
|
onRenameCell={onRenameCell}
|
||||||
onUpdateCell={onUpdateCell}
|
onUpdateCell={onUpdateCell}
|
||||||
|
onDeleteCell={onDeleteCell}
|
||||||
onSummonOverlayTechnologies={onSummonOverlayTechnologies}
|
onSummonOverlayTechnologies={onSummonOverlayTechnologies}
|
||||||
cell={cell}
|
cell={cell}
|
||||||
>
|
>
|
||||||
|
@ -123,6 +125,7 @@ export const LayoutRenderer = React.createClass({
|
||||||
onEditCell={onEditCell}
|
onEditCell={onEditCell}
|
||||||
onRenameCell={onRenameCell}
|
onRenameCell={onRenameCell}
|
||||||
onUpdateCell={onUpdateCell}
|
onUpdateCell={onUpdateCell}
|
||||||
|
onDeleteCell={onDeleteCell}
|
||||||
onSummonOverlayTechnologies={onSummonOverlayTechnologies}
|
onSummonOverlayTechnologies={onSummonOverlayTechnologies}
|
||||||
cell={cell}
|
cell={cell}
|
||||||
>
|
>
|
||||||
|
|
|
@ -23,6 +23,7 @@ const NameableGraph = React.createClass({
|
||||||
onEditCell: func,
|
onEditCell: func,
|
||||||
onRenameCell: func,
|
onRenameCell: func,
|
||||||
onUpdateCell: func,
|
onUpdateCell: func,
|
||||||
|
onDeleteCell: func,
|
||||||
onSummonOverlayTechnologies: func,
|
onSummonOverlayTechnologies: func,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -56,6 +57,7 @@ const NameableGraph = React.createClass({
|
||||||
onEditCell,
|
onEditCell,
|
||||||
onRenameCell,
|
onRenameCell,
|
||||||
onUpdateCell,
|
onUpdateCell,
|
||||||
|
onDeleteCell,
|
||||||
onSummonOverlayTechnologies,
|
onSummonOverlayTechnologies,
|
||||||
children,
|
children,
|
||||||
} = this.props
|
} = this.props
|
||||||
|
@ -96,7 +98,7 @@ const NameableGraph = React.createClass({
|
||||||
<div className="dash-graph">
|
<div className="dash-graph">
|
||||||
<div className="dash-graph--heading">
|
<div className="dash-graph--heading">
|
||||||
<div onClick={onClickHandler(x, y, isEditing)}>{nameOrField}</div>
|
<div onClick={onClickHandler(x, y, isEditing)}>{nameOrField}</div>
|
||||||
<ContextMenu isOpen={this.state.isMenuOpen} toggleMenu={this.toggleMenu} onEdit={onSummonOverlayTechnologies} cell={cell} handleClickOutside={this.closeMenu}/>
|
<ContextMenu isOpen={this.state.isMenuOpen} toggleMenu={this.toggleMenu} onEdit={onSummonOverlayTechnologies} onDelete={onDeleteCell} cell={cell} handleClickOutside={this.closeMenu}/>
|
||||||
</div>
|
</div>
|
||||||
<div className="dash-graph--container">
|
<div className="dash-graph--container">
|
||||||
{children}
|
{children}
|
||||||
|
@ -106,13 +108,14 @@ const NameableGraph = React.createClass({
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const ContextMenu = OnClickOutside(({isOpen, toggleMenu, onEdit, cell}) => (
|
const ContextMenu = OnClickOutside(({isOpen, toggleMenu, onEdit, onDelete, cell}) => (
|
||||||
<div className={classnames("dash-graph--options", {"dash-graph--options-show": isOpen})} onClick={toggleMenu}>
|
<div className={classnames("dash-graph--options", {"dash-graph--options-show": isOpen})} onClick={toggleMenu}>
|
||||||
<button className="btn btn-info btn-xs">
|
<button className="btn btn-info btn-xs">
|
||||||
<span className="icon caret-down"></span>
|
<span className="icon caret-down"></span>
|
||||||
</button>
|
</button>
|
||||||
<ul className="dash-graph--options-menu">
|
<ul className="dash-graph--options-menu">
|
||||||
<li onClick={() => onEdit(cell)}>Edit</li>
|
<li onClick={() => onEdit(cell)}>Edit</li>
|
||||||
|
<li onClick={() => onDelete(cell)}>Delete</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
))
|
))
|
||||||
|
|
Loading…
Reference in New Issue