From e66a3e08dc879437d9105eaec0364e8727bc520d Mon Sep 17 00:00:00 2001 From: Filip Barl Date: Mon, 25 Feb 2019 16:41:15 +0100 Subject: [PATCH] Add a confirmation dialog for deleting a pod. --- .../node-details-control-button.js | 7 ++-- .../node-details/node-details-controls.js | 13 ++++--- probe/kubernetes/reporter.go | 9 ++--- render/detailed/node.go | 35 ++++++++++--------- report/controls.go | 9 ++--- 5 files changed, 42 insertions(+), 31 deletions(-) diff --git a/client/app/scripts/components/node-details/node-details-control-button.js b/client/app/scripts/components/node-details/node-details-control-button.js index 23323f575..8bca5fbb3 100644 --- a/client/app/scripts/components/node-details/node-details-control-button.js +++ b/client/app/scripts/components/node-details/node-details-control-button.js @@ -1,5 +1,6 @@ import React from 'react'; import { connect } from 'react-redux'; +import { isEmpty } from 'lodash'; import classNames from 'classnames'; import { trackAnalyticsEvent } from '../../utils/tracking-utils'; @@ -25,9 +26,11 @@ class NodeDetailsControlButton extends React.Component { handleClick(ev) { ev.preventDefault(); - const { id, human } = this.props.control; + const { id, human, confirmation } = this.props.control; trackAnalyticsEvent('scope.node.control.click', { id, title: human }); - this.props.dispatch(doControl(this.props.nodeId, this.props.control)); + if (isEmpty(confirmation) || window.confirm(confirmation)) { // eslint-disable-line no-alert + this.props.dispatch(doControl(this.props.nodeId, this.props.control)); + } } } diff --git a/client/app/scripts/components/node-details/node-details-controls.js b/client/app/scripts/components/node-details/node-details-controls.js index edb9029ec..41e08794f 100644 --- a/client/app/scripts/components/node-details/node-details-controls.js +++ b/client/app/scripts/components/node-details/node-details-controls.js @@ -22,11 +22,14 @@ export default function NodeDetailsControls({ } - {sortBy(controls, 'rank').map(control => ())} + {sortBy(controls, 'rank').map(control => ( + + ))} {controls && } diff --git a/probe/kubernetes/reporter.go b/probe/kubernetes/reporter.go index 2be582e08..e56b3ad0c 100644 --- a/probe/kubernetes/reporter.go +++ b/probe/kubernetes/reporter.go @@ -538,10 +538,11 @@ func (r *Reporter) podTopology(services []Service, deployments []Deployment, dae Rank: 0, }) pods.Controls.AddControl(report.Control{ - ID: DeletePod, - Human: "Delete", - Icon: "far fa-trash-alt", - Rank: 1, + ID: DeletePod, + Human: "Delete", + Icon: "far fa-trash-alt", + Confirmation: "Are you sure you want to delete this pod?", + Rank: 1, }) for _, service := range services { selectors = append(selectors, match( diff --git a/render/detailed/node.go b/render/detailed/node.go index 459cc593f..7b8b29164 100644 --- a/render/detailed/node.go +++ b/render/detailed/node.go @@ -41,24 +41,26 @@ func (*ControlInstance) UnmarshalJSON(b []byte) error { } type wiredControlInstance struct { - ProbeID string `json:"probeId"` - NodeID string `json:"nodeId"` - ID string `json:"id"` - Human string `json:"human"` - Icon string `json:"icon"` - Rank int `json:"rank"` + ProbeID string `json:"probeId"` + NodeID string `json:"nodeId"` + ID string `json:"id"` + Human string `json:"human"` + Icon string `json:"icon"` + Confirmation string `json:"confirmation,omitempty"` + Rank int `json:"rank"` } // CodecEncodeSelf marshals this ControlInstance. It takes the basic Metric // rendering, then adds some row-specific fields. func (c *ControlInstance) CodecEncodeSelf(encoder *codec.Encoder) { encoder.Encode(wiredControlInstance{ - ProbeID: c.ProbeID, - NodeID: c.NodeID, - ID: c.Control.ID, - Human: c.Control.Human, - Icon: c.Control.Icon, - Rank: c.Control.Rank, + ProbeID: c.ProbeID, + NodeID: c.NodeID, + ID: c.Control.ID, + Human: c.Control.Human, + Icon: c.Control.Icon, + Confirmation: c.Control.Confirmation, + Rank: c.Control.Rank, }) } @@ -70,10 +72,11 @@ func (c *ControlInstance) CodecDecodeSelf(decoder *codec.Decoder) { ProbeID: in.ProbeID, NodeID: in.NodeID, Control: report.Control{ - ID: in.ID, - Human: in.Human, - Icon: in.Icon, - Rank: in.Rank, + ID: in.ID, + Human: in.Human, + Icon: in.Icon, + Confirmation: in.Confirmation, + Rank: in.Rank, }, } } diff --git a/report/controls.go b/report/controls.go index f534de5dd..dcf5cb3a6 100644 --- a/report/controls.go +++ b/report/controls.go @@ -12,10 +12,11 @@ type Controls map[string]Control // A Control basically describes an RPC type Control struct { - ID string `json:"id"` - Human string `json:"human"` - Icon string `json:"icon"` // from https://fortawesome.github.io/Font-Awesome/cheatsheet/ please - Rank int `json:"rank"` + ID string `json:"id"` + Human string `json:"human"` + Icon string `json:"icon"` // from https://fortawesome.github.io/Font-Awesome/cheatsheet/ please + Confirmation string `json:"confirmation,omitempty"` + Rank int `json:"rank"` } // Merge merges other with cs, returning a fresh Controls.