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

UI changes to pause a channel #2373

Merged
merged 3 commits into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 7 additions & 0 deletions assets/css/_global.scss
Original file line number Diff line number Diff line change
Expand Up @@ -833,6 +833,13 @@ i.survey-status {
height: 12px;
}

.channel-paused {
display: block;
color: var(--reference-color12);
width: 24px;
height: 24px;
}

.wizard-content {
> div {
min-height: 110vh;
Expand Down
12 changes: 12 additions & 0 deletions assets/js/actions/channel.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,15 @@ export const changeOutputPattern =
export const deletePattern = (index: number) => (dispatch: Function, getState: () => Store) => {
dispatch(removePattern(index))
}

export const pause = (id: number) => (dispatch: Function) => {
return api
.pauseChannel(id)
.then((response) => dispatch(fetchChannel(id)))
}

export const unpause = (id: number) => (dispatch: Function) => {
return api
.unpauseChannel(id)
.then((response) => dispatch(fetchChannel(id)))
}
8 changes: 8 additions & 0 deletions assets/js/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,14 @@ export const createChannel = (provider, baseUrl, channel) => {
return apiPostJSON(`channels`, channelSchema, { provider, baseUrl, channel })
}

export const pauseChannel = (channelId) => {
return apiPostJSON(`channels/${channelId}/pause`)
}

export const unpauseChannel = (channelId) => {
return apiPostJSON(`channels/${channelId}/unpause`)
}

export const updateQuestionnaire = (projectId, questionnaire) => {
return apiPutJSON(
`projects/${projectId}/questionnaires/${questionnaire.id}`,
Expand Down
16 changes: 10 additions & 6 deletions assets/js/components/channels/ChannelCapacity.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down Expand Up @@ -109,12 +110,15 @@ class ChannelCapacity extends Component {
}

return (
<ChannelCapacityForm
initialValue={channel.settings.capacity || parseInt(config.default_channel_capacity)}
onConfirm={(capacity) => this.onConfirmClick(capacity)}
onCancel={() => this.onCancelClick()}
t={t}
/>
<div className="white">
<ChannelPause />
<ChannelCapacityForm
initialValue={channel.settings.capacity || parseInt(config.default_channel_capacity)}
onConfirm={(capacity) => this.onConfirmClick(capacity)}
onCancel={() => this.onCancelClick()}
t={t}
/>
</div>
)
}
}
Expand Down
9 changes: 6 additions & 3 deletions assets/js/components/channels/ChannelIndex.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -229,7 +229,6 @@ class ChannelIndex extends Component<any> {
</li>
)
}

let providerUIs = []
config.verboice.forEach((_, index) => {
providerUIs.push(verboiceProviderUI(index, multipleVerboice))
Expand All @@ -240,7 +239,7 @@ class ChannelIndex extends Component<any> {

return (
<div>
<AddButton text={t("Add channel")} onClick={(e) => this.addChannel(e)} />
<ActionButton text={t("Add channel")} onClick={(e) => this.addChannel(e)} icon="add" color="green" />
{providerModals}

<Modal card id="add-channel">
Expand Down Expand Up @@ -313,6 +312,10 @@ class ChannelIndex extends Component<any> {
<td className="tdError">
{status == "down" || status == "error" ? (
<span className="questionnaire-error" />
) : status == "paused" ? (
<span className="channel-paused">
<i className="material-icons">pause</i>
</span>
) : null}
</td>
</tr>
Expand Down
2 changes: 2 additions & 0 deletions assets/js/components/channels/ChannelPatterns.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down Expand Up @@ -212,6 +213,7 @@ class ChannelPatterns extends Component {

return (
<div className="white">
<ChannelPause />
<div className="row">
<div className="col s12 m8 push-m2">
<h4>{t("Apply patterns for numbers cleanup")}</h4>
Expand Down
41 changes: 41 additions & 0 deletions assets/js/components/channels/ChannelPause.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { 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) => {
if (pause) {
actions.pause(channel.id)
} else {
actions.unpause(channel.id)
}
}

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))
2 changes: 2 additions & 0 deletions assets/js/components/channels/ChannelShare.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down Expand Up @@ -55,6 +56,7 @@ class ChannelShare extends Component {

return (
<div className="white">
<ChannelPause />
<div className="row">
<div className="col s12 m6 push-m3">
<h4>{t("Share this channel on different projects")}</h4>
Expand Down
15 changes: 9 additions & 6 deletions assets/js/components/channels/DownChannelsStatus.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { PureComponent, PropTypes } from "react"
import TimeAgo from "react-timeago"
import { translate, Trans } from "react-i18next"
import every from "lodash/every"
import map from "lodash/map"

class DownChannelsStatus extends PureComponent {
Expand All @@ -12,7 +13,9 @@ class DownChannelsStatus extends PureComponent {
render() {
const { channels, timestamp } = this.props
const channelNames = map(channels, (channel) => channel.name)
return this.downChannelsDescription(channelNames, timestamp)
const paused = every(channels, (channel) => channel.statusInfo?.status == "paused")
const text = paused ? "paused" : "down"
return this.downChannelsDescription(channelNames, timestamp, text)
}

downChannelsFormatter(number, unit, suffix, date, defaultFormatter) {
Expand All @@ -36,21 +39,21 @@ class DownChannelsStatus extends PureComponent {
}
}

downChannelsDescription(channelNames, timestamp) {
downChannelsDescription(channelNames, timestamp, text) {
const names = channelNames.join(", ")
if (channelNames.length > 1) {
return (
<Trans>
Channels <em>{{ names }}</em> down{" "}
<TimeAgo date={timestamp} formatter={this.bindedDownChannelsFormatter} />
Channels <em>{{ names }}</em> {{text}}{" "}
{timestamp && <TimeAgo date={timestamp} formatter={this.bindedDownChannelsFormatter} />}
</Trans>
)
} else {
const name = channelNames[0]
return (
<Trans>
Channel <em>{{ name }}</em> down{" "}
<TimeAgo date={timestamp} formatter={this.bindedDownChannelsFormatter} />
Channel <em>{{ name }}</em> {{text}}{" "}
{timestamp && <TimeAgo date={timestamp} formatter={this.bindedDownChannelsFormatter} />}
</Trans>
)
}
Expand Down
4 changes: 2 additions & 2 deletions assets/js/components/collaborators/CollaboratorIndex.jsx
Original file line number Diff line number Diff line change
@@ -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"
Expand Down Expand Up @@ -106,7 +106,7 @@ class CollaboratorIndex extends Component {
let addButton = null
if (!readOnly) {
addButton = (
<AddButton text={t("Invite collaborators")} onClick={(e) => this.inviteCollaborator(e)} />
<ActionButton text={t("Invite collaborators")} onClick={(e) => this.inviteCollaborator(e)} icon="add" color="green" />
)
}

Expand Down
6 changes: 4 additions & 2 deletions assets/js/components/integrations/IntegrationIndex.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down Expand Up @@ -168,12 +168,14 @@ class IntegrationIndex extends Component<Props, State> {

return (
<div className="white">
<AddButton
<ActionButton
text="Add integration"
onClick={(e) => {
e.preventDefault()
$("#newIntegration").modal("open")
}}
icon="add"
color="green"
/>
{this.modalNewIntegration()}
<CardTable title="Integrations" tableScroll>
Expand Down
4 changes: 2 additions & 2 deletions assets/js/components/projects/ProjectIndex.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -110,7 +110,7 @@ class ProjectIndex extends Component {
const { archived, t } = this.props
return (
<div>
<AddButton text={t("Add project")} onClick={(e) => this.newProject(e)} />
<ActionButton text={t("Add project")} onClick={(e) => this.newProject(e)} icon="add" color="green" />
<div className="row">
<ArchiveFilter
archived={archived}
Expand Down
4 changes: 2 additions & 2 deletions assets/js/components/questionnaires/QuestionnaireIndex.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import * as questionnaireActions from "../../actions/questionnaire"
import * as userSettingsActions from "../../actions/userSettings"
import * as projectActions from "../../actions/project"
import {
AddButton,
ActionButton,
EmptyPage,
SortableHeader,
CardTable,
Expand Down Expand Up @@ -280,7 +280,7 @@ class QuestionnaireIndex extends Component<any> {
const { archived, t, readOnly } = this.props

const addButton = (
<AddButton text={t("Add questionnaire")} onClick={(e) => this.newQuestionnaire(e)} />
<ActionButton text={t("Add questionnaire")} onClick={(e) => this.newQuestionnaire(e)} icon="add" color="green" />
)

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 = <i className="material-icons">add</i>
export const ActionButton = ({ text, linkPath, onClick, children, icon = "add", color = "green" }) => {
const materialIcon = <i className="material-icons">{icon}</i>

let link
if (linkPath) {
link = (
<Link
className="btn-floating btn-large waves-effect waves-light green right mbottom"
className={`btn-floating btn-large waves-effect waves-light ${color} right mbottom`}
to={linkPath}
>
{icon}
{materialIcon}
</Link>
)
} else if (onClick) {
link = (
<a
className="btn-floating btn-large waves-effect waves-light green right mtop"
className={`btn-floating btn-large waves-effect waves-light ${color} right mtop`}
href="#"
onClick={onClick}
>
{icon}
{materialIcon}
</a>
)
} else {
Expand All @@ -32,9 +32,11 @@ export const AddButton = ({ text, linkPath, onClick, children }) => {
return <Tooltip text={text}>{link}</Tooltip>
}

AddButton.propTypes = {
ActionButton.propTypes = {
text: PropTypes.string.isRequired,
linkPath: PropTypes.string,
onClick: PropTypes.func,
children: PropTypes.node,
icon: PropTypes.string,
color: PropTypes.string,
}
2 changes: 1 addition & 1 deletion assets/js/components/ui/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export * from "./AddButton"
export * from "./ActionButton"
export * from "./Archive"
export * from "./AudioDropzone"
export * from "./Autocomplete"
Expand Down
6 changes: 4 additions & 2 deletions locales/template/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,9 @@
"Changed description of <i>{{surveyName}}</i> survey": "",
"Changes are still being saved. Please wait": "",
"Channel": "",
"Channel <1><0>{{ name }}</0></1> down<3>{\" \"}</3> <5></5>": "Channel <1><0>{{ name }}</0></1> down<3>{\" \"}</3> <5></5>",
"Channel <1><0>{{ name }}</0></1> <3>{{text}}</3><4>{\" \"}</4> {timestamp && <6></6>}": "Channel <1><0>{{ name }}</0></1> <3>{{text}}</3><4>{\" \"}</4> {timestamp && <6></6>}",
"Channels": "",
"Channels <1><0>{{ names }}</0></1> down<3>{\" \"}</3> <5></5>": "Channels <1><0>{{ names }}</0></1> down<3>{\" \"}</3> <5></5>",
"Channels <1><0>{{ names }}</0></1> <3>{{text}}</3><4>{\" \"}</4> {timestamp && <6></6>}": "Channels <1><0>{{ names }}</0></1> <3>{{text}}</3><4>{\" \"}</4> {timestamp && <6></6>}",
"Checking this box will make the survey accept written numbers as valid numeric responses, like \"one\" or \"fifty five\". Written numbers are supported up to one hundred (100).": "",
"Choose a key for each language": "",
"Choose the data you want to be able to access through a public link": "",
Expand Down Expand Up @@ -319,6 +319,7 @@
"Partials": "",
"Pattern must not be blank": "",
"Patterns": "",
"Pause channel": "",
"Percent": "",
"Percent of completes": "",
"Phone call": "",
Expand Down Expand Up @@ -502,6 +503,7 @@
"Unknown role: {{role}}": "",
"Unknown_survey": "",
"Unlocked <i>{{surveyName}}</i> survey": "",
"Unpause channel": "",
"Unresponsive": "",
"Untitled Panel Survey": "",
"Untitled Survey": "",
Expand Down