@bigfishtv/cockpit
Version:
123 lines (113 loc) • 4.32 kB
JavaScript
/**
* Prompt Utilities
* @module Utilities/promptUtils
*/
import React from 'react'
import { post } from '../api/xhrUtils'
import PromptModal from '../components/prompt/PromptModal'
import PromptInputModal from '../components/prompt/PromptInputModal'
import ConfirmCancel from '../components/prompt/ConfirmCancel'
import { modalHandler } from '../components/modal/ModalHost'
/**
* Shows prompt modal, customizable by props provided
* @param {Object} props - Object of prompt props
* @param {String} props.title
* @param {String} props.message
* @param {React.Component} props.Buttons
* @param {Function} props.callback
* @param {String} props.style - e.g. succes, error, warning, primary etc.
*/
export function showPrompt(props) {
launchModal(
props.title || null,
props.message || null,
props.Buttons || ConfirmCancel,
props.callback ? props.callback : () => console.warn('No callback for prompt'),
props.style || null
)
}
/**
* Launches modal with props validated by showPrompt function
* @param {String} title
* @param {String} message
* @param {React.Component} Buttons
* @param {Function} callback
* @param {String} style
*/
function launchModal(title = null, message = null, Buttons = null, callback = null, style = null) {
modalHandler.add({
Component: PromptModal,
props: {
title,
message,
Buttons,
callback,
style,
},
})
}
const defaultRenderListItem = item => item.name || item.title || item.id || null
/**
* Shows a prompt to delete items based on data array and selectedIds, along with other props
* @param {Object} props - Object of delete prompt props
* @param {String} props.model - Model reference, will be smarly constructed from subject prop if provided
* @param {String} props.queryUrl - Url to post delete request to, will be smartly constructed if model prop is provided
* @param {String} props.subject - Subject string to use in notifications, will be smarly constructed from model prop if provided
* @param {String} props.title - Alternate title string to default "Are you sure you want to delete (x)?"
* @param {Array} props.data - Array of data
* @param {Array} props.selectedIds - Array of selected ids, can be used to collate a list from the data prop
* @param {Function} props.renderListItem - Function returning jsx/string based on data row
* @param {Function} props.callback - Callback on delete success, takes one argument: new data rray
*/
export function showDeletePrompt(props) {
const { data, selectedIds } = props
const defaultTitle = 'Are you sure you want to delete ' + (props.subject || 'item') + '(s)?'
const model = props.model ? props.model : props.subject ? props.subject.toLowerCase().replace(' ', '_') + 's' : null
const subject = props.subject ? props.subject : props.model ? props.model.replace('_', ' ').slice(0, -1) : 'item'
const renderListItem = props.renderListItem || defaultRenderListItem
const url = props.queryUrl ? props.queryUrl : model ? '/admin/' + model + '/delete.json' : null
showPrompt({
style: 'error',
title: props.title || defaultTitle,
message: (
<ul>
{data.map((item, i) => (
<li key={i}>{renderListItem(item)}</li>
))}
</ul>
),
callback: response => {
if (response === true) {
post({
url,
data: selectedIds,
subject: props.subject,
failureMessage: 'Failed to delete ' + subject + '(s)!',
successMessage: 'Deleted ' + subject + '(s) successfully!',
callback: _deletedIds => {
const deletedIds = Object.keys(_deletedIds).reduce(
(ids, id) => (_deletedIds[parseInt(id)] === true ? [...ids, parseInt(id)] : ids),
[]
)
const newData = data.filter(item => deletedIds.indexOf(item.id) >= 0)
props.callback(newData)
},
})
}
},
})
}
/**
* Shows an input prompt
* @param {Object} props - Object of input prompt props
* @param {String} props.title - Prompt modal title
* @param {String/ReactNode} props.message - Message to display above input
* @param {String} props.defaultValue - Default input text
* @param {Function} props.callback - Called on confirm/cancel with one arg the value
*/
export function showInputPrompt(props) {
modalHandler.add({
Component: PromptInputModal,
props,
})
}