import React, { useCallback, useState } from 'react'; import PropTypes from 'prop-types'; import { useTranslation } from 'react-i18next'; import { defaultSupportedCommandsNameForBroadcastUse, defaultSupportedCommandsNameForSingleUse } from '@growi/slack'; import loggerFactory from '~/utils/logger'; import { toastSuccess, toastError } from '../../../client/util/apiNotification'; const logger = loggerFactory('growi:SlackIntegration:ManageCommandsProcess'); const PermissionTypes = { ALLOW_ALL: 'allowAll', DENY_ALL: 'denyAll', ALLOW_SPECIFIED: 'allowSpecified', }; const CommandUsageTypes = { BROADCAST_USE: 'broadcastUse', SINGLE_USE: 'singleUse', }; // A utility function that returns the new state const getUpdatedChannelsList = (prevState, commandName, value) => { const newState = { ...prevState }; // string to array const allowedChannelsArray = value.split(','); // trim whitespace from all elements const trimedAllowedChannelsArray = allowedChannelsArray.map(channelName => channelName.trim()); prevState[commandName] = trimedAllowedChannelsArray; return newState; }; // A utility function that returns the new state const getUpdatedPermissionSettings = (prevState, commandName, value) => { const newState = { ...prevState }; switch (value) { case PermissionTypes.ALLOW_ALL: newState[commandName] = true; break; case PermissionTypes.DENY_ALL: newState[commandName] = false; break; case PermissionTypes.ALLOW_SPECIFIED: newState[commandName] = []; break; default: logger.error('Not implemented'); break; } return newState; }; // A utility function that returns the permission type from the permission value const getPermissionTypeFromValue = (value) => { if (Array.isArray(value)) { return PermissionTypes.ALLOW_SPECIFIED; } if (typeof value === 'boolean') { return value ? PermissionTypes.ALLOW_ALL : PermissionTypes.DENY_ALL; } logger.error('The value type must be boolean or string[]'); }; // TODO: Add permittedChannelsForEachCommand to use data from server (props must have it) GW-7006 const ManageCommandsProcess = ({ apiv3Put, slackAppIntegrationId, permissionsForBroadcastUseCommands, permissionsForSingleUseCommands, }) => { const { t } = useTranslation(); // TODO: use data from server GW-7006 const [permissionsForBroadcastUseCommandsState, setPermissionsForBroadcastUseCommandsState] = useState({ search: true, }); const [permissionsForSingleUseCommandsState, setPermissionsForSingleUseCommandsState] = useState({ create: false, togetter: [], }); const [currentPermissionTypes, setCurrentPermissionTypes] = useState(() => { const initialState = {}; Object.entries(permissionsForBroadcastUseCommandsState).forEach((entry) => { const [commandName, value] = entry; initialState[commandName] = getPermissionTypeFromValue(value); }); Object.entries(permissionsForSingleUseCommandsState).forEach((entry) => { const [commandName, value] = entry; initialState[commandName] = getPermissionTypeFromValue(value); }); return initialState; }); const updatePermissionsForBroadcastUseCommandsState = useCallback((e) => { const { target } = e; const { name: commandName, value } = target; // update state setPermissionsForBroadcastUseCommandsState((prevState) => { return getUpdatedPermissionSettings(prevState, commandName, value); }); setCurrentPermissionTypes((prevState) => { const newState = { ...prevState }; newState[commandName] = value; return newState; }); }, []); const updatePermissionsForSingleUseCommandsState = useCallback((e) => { const { target } = e; const { name: commandName, value } = target; // update state setPermissionsForSingleUseCommandsState((prevState) => { return getUpdatedPermissionSettings(prevState, commandName, value); }); setCurrentPermissionTypes((prevState) => { const newState = { ...prevState }; newState[commandName] = value; return newState; }); }, []); const updateChannelsListForBroadcastUseCommandsState = useCallback((e) => { const { target } = e; const { name: commandName, value } = target; // update state setPermissionsForBroadcastUseCommandsState((prevState) => { return getUpdatedChannelsList(prevState, commandName, value); }); }, []); const updateChannelsListForSingleUseCommandsState = useCallback((e) => { const { target } = e; const { name: commandName, value } = target; // update state setPermissionsForSingleUseCommandsState((prevState) => { return getUpdatedChannelsList(prevState, commandName, value); }); }, []); // TODO: UPDATE API AND REWRITE HERE GW-7006 const updateCommandsHandler = async() => { try { await apiv3Put(`/slack-integration-settings/${slackAppIntegrationId}/supported-commands`, { permissionsForBroadcastUseCommands: ['REWRITE'], permissionsForSingleUseCommands: ['REWRITE'], }); toastSuccess(t('toaster.update_successed', { target: 'Token' })); } catch (err) { toastError(err); logger.error(err); } }; const PermissionSettingForEachCommandComponent = ({ commandName, commandUsageType }) => { const hiddenClass = currentPermissionTypes[commandName] === PermissionTypes.ALLOW_SPECIFIED ? '' : 'd-none'; const isCommandBroadcastUse = commandUsageType === CommandUsageTypes.BROADCAST_USE; const permissionSettings = isCommandBroadcastUse ? permissionsForBroadcastUseCommandsState : permissionsForSingleUseCommandsState; const permission = permissionSettings[commandName]; if (permission === undefined) logger.error('Must be implemented'); const textareaDefaultValue = Array.isArray(permission) ? permission.join(',') : ''; return (
{commandName}
{t('admin:slack_integration.accordion.allowed_channels_description', { commandName })}
{isCommandBroadcastUse ? 'Multiple GROWI' : 'Single GROWI'}
{isCommandBroadcastUse ? t('admin:slack_integration.accordion.multiple_growi_command') : t('admin:slack_integration.accordion.single_growi_command')}
{t('admin:slack_integration.accordion.manage_commands')}