import React, { useCallback, useEffect, useState } from 'react';
import { defaultSupportedCommandsNameForBroadcastUse, defaultSupportedCommandsNameForSingleUse, defaultSupportedSlackEventActions } from '@growi/slack';
import PropTypes from 'prop-types';
import { useTranslation } from 'react-i18next';
import { apiv3Put } from '~/client/util/apiv3-client';
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 defaultCommandsName = [...defaultSupportedCommandsNameForBroadcastUse, ...defaultSupportedCommandsNameForSingleUse];
// A utility function that returns the new state but identical to the previous state
const getUpdatedChannelsList = (commandPermissionObj, commandName, value) => {
// string to array
const allowedChannelsArray = value.split(',');
// trim whitespace from all elements
const trimedAllowedChannelsArray = allowedChannelsArray.map(channelName => channelName.trim());
commandPermissionObj[commandName] = trimedAllowedChannelsArray;
return commandPermissionObj;
};
// A utility function that returns the new state
const getUpdatedPermissionSettings = (commandPermissionObj, commandName, value) => {
const editedCommandPermissionObj = { ...commandPermissionObj };
switch (value) {
case PermissionTypes.ALLOW_ALL:
editedCommandPermissionObj[commandName] = true;
break;
case PermissionTypes.DENY_ALL:
editedCommandPermissionObj[commandName] = false;
break;
case PermissionTypes.ALLOW_SPECIFIED:
editedCommandPermissionObj[commandName] = [];
break;
default:
logger.error('Not implemented');
break;
}
return editedCommandPermissionObj;
};
const SinglePermissionSettingComponent = ({
commandName, editingCommandPermission, onPermissionTypeClicked, onPermissionListChanged,
}) => {
const { t } = useTranslation();
if (editingCommandPermission == null) {
return null;
}
function permissionTypeClickHandler(e) {
if (onPermissionTypeClicked == null) {
return;
}
onPermissionTypeClicked(e);
}
function onPermissionListChangeHandler(e) {
if (onPermissionListChanged == null) {
return;
}
onPermissionListChanged(e);
}
const permission = editingCommandPermission[commandName];
const hiddenClass = Array.isArray(permission) ? '' : 'd-none';
const textareaDefaultValue = Array.isArray(permission) ? permission.join(',') : '';
return (
{commandName}
);
};
SinglePermissionSettingComponent.propTypes = {
commandName: PropTypes.string,
editingCommandPermission: PropTypes.object,
onPermissionTypeClicked: PropTypes.func,
onPermissionListChanged: PropTypes.func,
};
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
const ManageCommandsProcessWithoutProxy = ({ commandPermission, eventActionsPermission }) => {
const { t } = useTranslation();
const [editingCommandPermission, setEditingCommandPermission] = useState({});
const [editingEventActionsPermission, setEditingEventActionsPermission] = useState({});
useEffect(() => {
if (commandPermission == null) {
return;
}
const updatedState = { ...commandPermission };
setEditingCommandPermission(updatedState);
}, [commandPermission]);
useEffect(() => {
if (eventActionsPermission == null) {
return;
}
const updatedState = { ...eventActionsPermission };
setEditingEventActionsPermission(updatedState);
}, [eventActionsPermission]);
const updatePermissionsCommandsState = useCallback((e) => {
const { target } = e;
const { name: commandName, value } = target;
setEditingCommandPermission(commandPermissionObj => getUpdatedPermissionSettings(commandPermissionObj, commandName, value));
}, []);
const updatePermissionsEventsState = useCallback((e) => {
const { target } = e;
const { name: actionName, value } = target;
setEditingEventActionsPermission(eventActionPermissionObj => getUpdatedPermissionSettings(eventActionPermissionObj, actionName, value));
}, []);
const updateCommandsChannelsListState = useCallback((e) => {
const { target } = e;
const { name: commandName, value } = target;
setEditingCommandPermission(commandPermissionObj => ({ ...getUpdatedChannelsList(commandPermissionObj, commandName, value) }));
}, []);
const updateEventsChannelsListState = useCallback((e) => {
const { target } = e;
const { name: actionName, value } = target;
setEditingEventActionsPermission(eventActionPermissionObj => ({ ...getUpdatedChannelsList(eventActionPermissionObj, actionName, value) }));
}, []);
const updateCommandsHandler = async(e) => {
try {
await apiv3Put('/slack-integration-settings/without-proxy/update-permissions', {
commandPermission: editingCommandPermission,
eventActionsPermission: editingEventActionsPermission,
});
toastSuccess(t('toaster.update_successed', { target: 'the permission for commands' }));
}
catch (err) {
toastError(err);
logger.error(err);
}
};
return (
{t('admin:slack_integration.accordion.growi_commands')}
{ defaultCommandsName.map((commandName) => {
// eslint-disable-next-line max-len
return (
);
})}
Events
{ defaultSupportedSlackEventActions.map(actionName => (
))}
);
};
ManageCommandsProcessWithoutProxy.propTypes = {
commandPermission: PropTypes.object,
eventActionsPermission: PropTypes.object,
};
export default ManageCommandsProcessWithoutProxy;