From bfd4f39100c99db882a7f8bfcf6d88103cacaa48 Mon Sep 17 00:00:00 2001 From: Ismael Bejarano Date: Mon, 28 Oct 2024 23:02:43 -0300 Subject: [PATCH] * Rename AddButton to ActionButton * Allow icon and color props for ActionButton * Add ChannelPause button * Add actions to pause a channel --- assets/js/actions/channel.js | 12 ++++++ assets/js/api.js | 8 ++++ .../components/channels/ChannelCapacity.jsx | 16 ++++--- .../js/components/channels/ChannelIndex.jsx | 24 +++++++++-- .../components/channels/ChannelPatterns.jsx | 2 + .../js/components/channels/ChannelPause.jsx | 42 +++++++++++++++++++ .../js/components/channels/ChannelShare.jsx | 2 + .../collaborators/CollaboratorIndex.jsx | 4 +- .../integrations/IntegrationIndex.jsx | 6 ++- .../js/components/projects/ProjectIndex.jsx | 4 +- .../questionnaires/QuestionnaireIndex.jsx | 4 +- .../ui/{AddButton.jsx => ActionButton.jsx} | 16 +++---- assets/js/components/ui/index.js | 2 +- locales/template/translation.json | 2 + 14 files changed, 118 insertions(+), 26 deletions(-) create mode 100644 assets/js/components/channels/ChannelPause.jsx rename assets/js/components/ui/{AddButton.jsx => ActionButton.jsx} (52%) diff --git a/assets/js/actions/channel.js b/assets/js/actions/channel.js index e479cb0bc..c5e3c38e3 100644 --- a/assets/js/actions/channel.js +++ b/assets/js/actions/channel.js @@ -129,3 +129,15 @@ export const changeOutputPattern = export const deletePattern = (index: number) => (dispatch: Function, getState: () => Store) => { dispatch(removePattern(index)) } + +export const pause = (channel: Channel) => (dispatch) => { + return api + .pauseChannel(channel) + .then((response) => dispatch(fetchChannel(channel.id))) +} + +export const unpause = (channel: Channel) => (dispatch) => { + return api + .unpauseChannel(channel) + .then((response) => dispatch(fetchChannel(channel.id))) +} diff --git a/assets/js/api.js b/assets/js/api.js index c0d716f49..5713ab74b 100644 --- a/assets/js/api.js +++ b/assets/js/api.js @@ -368,6 +368,14 @@ export const createChannel = (provider, baseUrl, channel) => { return apiPostJSON(`channels`, channelSchema, { provider, baseUrl, channel }) } +export const pauseChannel = (channel) => { + return apiPostJSON(`channels/${channel.id}/pause`, channelSchema) +} + +export const unpauseChannel = (channel) => { + return apiPostJSON(`channels/${channel.id}/unpause`, channelSchema) +} + export const updateQuestionnaire = (projectId, questionnaire) => { return apiPutJSON( `projects/${projectId}/questionnaires/${questionnaire.id}`, diff --git a/assets/js/components/channels/ChannelCapacity.jsx b/assets/js/components/channels/ChannelCapacity.jsx index 86d92fb1b..5f0b0e46e 100644 --- a/assets/js/components/channels/ChannelCapacity.jsx +++ b/assets/js/components/channels/ChannelCapacity.jsx @@ -6,6 +6,7 @@ import * as actions from "../../actions/channel" import * as routes from "../../routes" import { translate } from "react-i18next" import { config } from "../../config" +import ChannelPause from "./ChannelPause" class ChannelCapacityForm extends Component { static propTypes = { @@ -109,12 +110,15 @@ class ChannelCapacity extends Component { } return ( - this.onConfirmClick(capacity)} - onCancel={() => this.onCancelClick()} - t={t} - /> +
+ + this.onConfirmClick(capacity)} + onCancel={() => this.onCancelClick()} + t={t} + /> +
) } } diff --git a/assets/js/components/channels/ChannelIndex.jsx b/assets/js/components/channels/ChannelIndex.jsx index 80a87409b..26cb3b602 100644 --- a/assets/js/components/channels/ChannelIndex.jsx +++ b/assets/js/components/channels/ChannelIndex.jsx @@ -9,7 +9,7 @@ import * as actions from "../../actions/channels" import range from "lodash/range" import * as authActions from "../../actions/authorizations" import { - AddButton, + ActionButton, EmptyPage, CardTable, UntitledIfEmpty, @@ -18,6 +18,7 @@ import { ConfirmationModal, PagingFooter, channelFriendlyName, + Tooltip, } from "../ui" import { Preloader } from "react-materialize" import { config } from "../../config" @@ -230,6 +231,21 @@ class ChannelIndex extends Component { ) } + const pauseIconForChannel = (channel) => { + const { statusInfo } = channel + console.log({statusInfo, label: "1--------"}) + const { t } = this.props + return ( + + + this.pause(e, channel)}> + pause + + + + ) + } + let providerUIs = [] config.verboice.forEach((_, index) => { providerUIs.push(verboiceProviderUI(index, multipleVerboice)) @@ -240,7 +256,7 @@ class ChannelIndex extends Component { return (
- this.addChannel(e)} /> + this.addChannel(e)} icon="add" color="green" /> {providerModals} @@ -297,7 +313,7 @@ class ChannelIndex extends Component { if (!channel) return ( - + ) @@ -311,7 +327,7 @@ class ChannelIndex extends Component { {`${channel.provider}${channelFriendlyName(channel)}`} - {status == "down" || status == "error" ? ( + {status == "down" || status == "error" || status == "paused" ? ( ) : null} diff --git a/assets/js/components/channels/ChannelPatterns.jsx b/assets/js/components/channels/ChannelPatterns.jsx index ef8ac6544..c608371bf 100644 --- a/assets/js/components/channels/ChannelPatterns.jsx +++ b/assets/js/components/channels/ChannelPatterns.jsx @@ -4,6 +4,7 @@ import { translate } from "react-i18next" import { bindActionCreators } from "redux" import * as routes from "../../routes" import * as actions from "../../actions/channel" +import ChannelPause from "./ChannelPause" class Pattern extends Component { static propTypes = { @@ -212,6 +213,7 @@ class ChannelPatterns extends Component { return (
+

{t("Apply patterns for numbers cleanup")}

diff --git a/assets/js/components/channels/ChannelPause.jsx b/assets/js/components/channels/ChannelPause.jsx new file mode 100644 index 000000000..87d3875bc --- /dev/null +++ b/assets/js/components/channels/ChannelPause.jsx @@ -0,0 +1,42 @@ +import React, { PropTypes } from "react" +import { bindActionCreators } from "redux" +import { connect } from "react-redux" +import { translate } from "react-i18next" +import { ActionButton } from "../ui" +import * as actions from "../../actions/channel" + +const ChannelPause = ({ channel, t, actions }) => { + if (!channel) return null + const { statusInfo } = channel + const paused = statusInfo != null && statusInfo.status == "paused" + const text = paused ? t("Unpause channel") : t("Pause channel") + const icon = paused ? "play_arrow" : "pause" + const color = paused ? "green" : "red" + + const pauseChannel = (channel, pause) => { + console.log(`About to ${pause ? "pause" : "unpause"} channel ${channel.id}`) + if (pause) { + actions.pause(channel) + } else { + actions.unpause(channel) + } + } + + return ActionButton({ text, onClick: (e) => pauseChannel(channel, !paused), icon, color }) +} + +ChannelPause.propTypes = { + t: PropTypes.func, + channel: PropTypes.object, + actions: PropTypes.object.isRequired, +} + +const mapStateToProps = (state, ownProps) => ({ + channel: state.channel.data, +}) + +const mapDispatchToProps = (dispatch) => ({ + actions: bindActionCreators(actions, dispatch), +}) + +export default translate()(connect(mapStateToProps, mapDispatchToProps)(ChannelPause)) diff --git a/assets/js/components/channels/ChannelShare.jsx b/assets/js/components/channels/ChannelShare.jsx index aa1a45bf7..65b298893 100644 --- a/assets/js/components/channels/ChannelShare.jsx +++ b/assets/js/components/channels/ChannelShare.jsx @@ -6,6 +6,7 @@ import * as actions from "../../actions/channel" import * as projectsActions from "../../actions/projects" import * as routes from "../../routes" import { translate } from "react-i18next" +import ChannelPause from "./ChannelPause" class ChannelShare extends Component { static propTypes = { @@ -55,6 +56,7 @@ class ChannelShare extends Component { return (
+

{t("Share this channel on different projects")}

diff --git a/assets/js/components/collaborators/CollaboratorIndex.jsx b/assets/js/components/collaborators/CollaboratorIndex.jsx index d68d8bb5e..6196cdb5b 100644 --- a/assets/js/components/collaborators/CollaboratorIndex.jsx +++ b/assets/js/components/collaborators/CollaboratorIndex.jsx @@ -1,7 +1,7 @@ import React, { Component, PropTypes } from "react" import { bindActionCreators } from "redux" import { connect } from "react-redux" -import { CardTable, AddButton, Tooltip, roleDisplayName } from "../ui" +import { CardTable, ActionButton, Tooltip, roleDisplayName } from "../ui" import { Input } from "react-materialize" import InviteModal from "../collaborators/InviteModal" import * as actions from "../../actions/collaborators" @@ -106,7 +106,7 @@ class CollaboratorIndex extends Component { let addButton = null if (!readOnly) { addButton = ( - this.inviteCollaborator(e)} /> + this.inviteCollaborator(e)} icon="add" color="green" /> ) } diff --git a/assets/js/components/integrations/IntegrationIndex.jsx b/assets/js/components/integrations/IntegrationIndex.jsx index 18a176a70..f4c1c7378 100644 --- a/assets/js/components/integrations/IntegrationIndex.jsx +++ b/assets/js/components/integrations/IntegrationIndex.jsx @@ -6,7 +6,7 @@ import * as actions from "../../actions/integrations" import * as surveyActions from "../../actions/survey" import * as projectActions from "../../actions/project" import values from "lodash/values" -import { AddButton, CardTable, InputWithLabel, Modal } from "../ui" +import { ActionButton, CardTable, InputWithLabel, Modal } from "../ui" import IntegrationRow from "./IntegrationRow" type Props = { @@ -168,12 +168,14 @@ class IntegrationIndex extends Component { return (
- { e.preventDefault() $("#newIntegration").modal("open") }} + icon="add" + color="green" /> {this.modalNewIntegration()} diff --git a/assets/js/components/projects/ProjectIndex.jsx b/assets/js/components/projects/ProjectIndex.jsx index 475e8b103..b66d60922 100644 --- a/assets/js/components/projects/ProjectIndex.jsx +++ b/assets/js/components/projects/ProjectIndex.jsx @@ -6,7 +6,7 @@ import { createProject } from "../../api" import * as actions from "../../actions/projects" import * as projectActions from "../../actions/project" import { - AddButton, + ActionButton, EmptyPage, CardTable, SortableHeader, @@ -110,7 +110,7 @@ class ProjectIndex extends Component { const { archived, t } = this.props return (
- this.newProject(e)} /> + this.newProject(e)} icon="add" color="green" />
{ const { archived, t, readOnly } = this.props const addButton = ( - this.newQuestionnaire(e)} /> + this.newQuestionnaire(e)} icon="add" color="green" /> ) return ( diff --git a/assets/js/components/ui/AddButton.jsx b/assets/js/components/ui/ActionButton.jsx similarity index 52% rename from assets/js/components/ui/AddButton.jsx rename to assets/js/components/ui/ActionButton.jsx index 99d72f483..5307f4dc2 100644 --- a/assets/js/components/ui/AddButton.jsx +++ b/assets/js/components/ui/ActionButton.jsx @@ -2,27 +2,27 @@ import React, { PropTypes } from "react" import { Link } from "react-router" import { Tooltip } from "." -export const AddButton = ({ text, linkPath, onClick, children }) => { - const icon = add +export const ActionButton = ({ text, linkPath, onClick, children, icon = "add", color = "green" }) => { + const materialIcon = {icon} let link if (linkPath) { link = ( - {icon} + {materialIcon} ) } else if (onClick) { link = ( - {icon} + {materialIcon} ) } else { @@ -32,9 +32,11 @@ export const AddButton = ({ text, linkPath, onClick, children }) => { return {link} } -AddButton.propTypes = { +ActionButton.propTypes = { text: PropTypes.string.isRequired, linkPath: PropTypes.string, onClick: PropTypes.func, children: PropTypes.node, + icon: PropTypes.string, + color: PropTypes.string, } diff --git a/assets/js/components/ui/index.js b/assets/js/components/ui/index.js index 4bde6afa5..04cf55d2f 100644 --- a/assets/js/components/ui/index.js +++ b/assets/js/components/ui/index.js @@ -1,4 +1,4 @@ -export * from "./AddButton" +export * from "./ActionButton" export * from "./Archive" export * from "./AudioDropzone" export * from "./Autocomplete" diff --git a/locales/template/translation.json b/locales/template/translation.json index f92f211f9..2048132d4 100644 --- a/locales/template/translation.json +++ b/locales/template/translation.json @@ -319,6 +319,7 @@ "Partials": "", "Pattern must not be blank": "", "Patterns": "", + "Pause channel": "", "Percent": "", "Percent of completes": "", "Phone call": "", @@ -502,6 +503,7 @@ "Unknown role: {{role}}": "", "Unknown_survey": "", "Unlocked {{surveyName}} survey": "", + "Unpause channel": "", "Unresponsive": "", "Untitled Panel Survey": "", "Untitled Survey": "",