Chore: Hooks - create usePermissions (#4190)
* Chore: Hooks - create custom hook usePermissions * minor tweak * Change usage of usePermissiosn on LivechatEditView * Create getPermissionsSelector * Simplify selector * Simplify userRoles * First render with permissions array length of false * Move roles state closer to each other * useSubscription (not working, but looking cool) * at least it's working now * working * cleanup * solve ts return * Change it to useSubscriptionRoles only and check for diff on the state * Remove IAppState * Minor tweak to work properly useSubscriptionRoles Co-authored-by: Diego Mello <diegolmello@gmail.com>
This commit is contained in:
parent
a16c271f1f
commit
fa90e4d456
|
@ -1 +1,2 @@
|
|||
export * from './useAppSelector';
|
||||
export * from './usePermissions';
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
import { useState, useEffect } from 'react';
|
||||
import { dequal } from 'dequal';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { createSelector } from 'reselect';
|
||||
import { shallowEqual } from 'react-redux';
|
||||
|
||||
import { TSupportedPermissions } from '../../reducers/permissions';
|
||||
import { IApplicationState, TSubscriptionModel } from '../../definitions';
|
||||
import { getUserSelector } from '../../selectors/login';
|
||||
import { useAppSelector } from './useAppSelector';
|
||||
import { getSubscriptionByRoomId } from '../database/services/Subscription';
|
||||
|
||||
const getPermissionsSelector = createSelector(
|
||||
[(state: IApplicationState) => state.permissions, (_state: any, permissionsArray: TSupportedPermissions[]) => permissionsArray],
|
||||
(permissions, permissionsArray) => permissionsArray.map(p => permissions[p])
|
||||
);
|
||||
|
||||
const useSubscriptionRoles = (rid?: string): TSubscriptionModel['roles'] => {
|
||||
const [subscriptionRoles, setSubscriptionRoles] = useState<TSubscriptionModel['roles']>([]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!rid) {
|
||||
return;
|
||||
}
|
||||
let subSubscription: Subscription;
|
||||
getSubscriptionByRoomId(rid).then(sub => {
|
||||
if (!sub) {
|
||||
return;
|
||||
}
|
||||
const observable = sub.observe();
|
||||
subSubscription = observable.subscribe(s => {
|
||||
if (!dequal(subscriptionRoles, s.roles)) {
|
||||
setSubscriptionRoles(s.roles);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return () => {
|
||||
if (subSubscription && subSubscription?.unsubscribe) subSubscription.unsubscribe();
|
||||
};
|
||||
}, [subscriptionRoles]);
|
||||
|
||||
return subscriptionRoles;
|
||||
};
|
||||
|
||||
export function usePermissions(permissions: TSupportedPermissions[], rid?: string): boolean[] {
|
||||
const userRoles = useAppSelector(state => getUserSelector(state).roles || [], shallowEqual);
|
||||
const permissionsRedux = useAppSelector(state => getPermissionsSelector(state, permissions), shallowEqual);
|
||||
const subscriptionRoles = useSubscriptionRoles(rid);
|
||||
|
||||
const mergedRoles = [...new Set([...(subscriptionRoles || []), ...userRoles])];
|
||||
return permissionsRedux.map(permission => (permission ?? []).some(r => mergedRoles.includes(r)));
|
||||
}
|
|
@ -21,8 +21,8 @@ import { ICustomFields, IInputsRefs, TParams, ITitle, ILivechat } from '../defin
|
|||
import { IApplicationState, IUser } from '../definitions';
|
||||
import { ChatsStackParamList } from '../stacks/types';
|
||||
import sharedStyles from './Styles';
|
||||
import { hasPermission } from '../lib/methods/helpers';
|
||||
import { Services } from '../lib/services';
|
||||
import { usePermissions } from '../lib/hooks';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
|
@ -55,17 +55,9 @@ interface ILivechatEditViewProps {
|
|||
const Title = ({ title, theme }: ITitle) =>
|
||||
title ? <Text style={[styles.title, { color: themes[theme].titleText }]}>{title}</Text> : null;
|
||||
|
||||
const LivechatEditView = ({
|
||||
user,
|
||||
navigation,
|
||||
route,
|
||||
theme,
|
||||
editOmnichannelContact,
|
||||
editLivechatRoomCustomfields
|
||||
}: ILivechatEditViewProps) => {
|
||||
const LivechatEditView = ({ user, navigation, route, theme }: ILivechatEditViewProps) => {
|
||||
const [customFields, setCustomFields] = useState<ICustomFields>({});
|
||||
const [availableUserTags, setAvailableUserTags] = useState<string[]>([]);
|
||||
const [permissions, setPermissions] = useState<boolean[]>([]);
|
||||
|
||||
const params = {} as TParams;
|
||||
const inputs = {} as IInputsRefs;
|
||||
|
@ -73,6 +65,11 @@ const LivechatEditView = ({
|
|||
const livechat = (route.params?.room ?? {}) as ILivechat;
|
||||
const visitor = route.params?.roomUser ?? {};
|
||||
|
||||
const [editOmnichannelContactPermission, editLivechatRoomCustomFieldsPermission] = usePermissions(
|
||||
['edit-omnichannel-contact', 'edit-livechat-room-customfields'],
|
||||
livechat.rid
|
||||
);
|
||||
|
||||
const getCustomFields = async () => {
|
||||
const result = await Services.getCustomFields();
|
||||
if (result.success && result.customFields?.length) {
|
||||
|
@ -171,18 +168,12 @@ const LivechatEditView = ({
|
|||
params[key] = text;
|
||||
};
|
||||
|
||||
const getPermissions = async () => {
|
||||
const permissionsArray = await hasPermission([editOmnichannelContact, editLivechatRoomCustomfields], livechat.rid);
|
||||
setPermissions(permissionsArray);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
navigation.setOptions({
|
||||
title: I18n.t('Edit')
|
||||
});
|
||||
handleGetAgentDepartments();
|
||||
getCustomFields();
|
||||
getPermissions();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
|
@ -201,7 +192,7 @@ const LivechatEditView = ({
|
|||
inputs.name?.focus();
|
||||
}}
|
||||
theme={theme}
|
||||
editable={!!permissions[0]}
|
||||
editable={!!editOmnichannelContactPermission}
|
||||
/>
|
||||
<FormTextInput
|
||||
label={I18n.t('Email')}
|
||||
|
@ -214,7 +205,7 @@ const LivechatEditView = ({
|
|||
inputs.phone?.focus();
|
||||
}}
|
||||
theme={theme}
|
||||
editable={!!permissions[0]}
|
||||
editable={!!editOmnichannelContactPermission}
|
||||
/>
|
||||
<FormTextInput
|
||||
label={I18n.t('Phone')}
|
||||
|
@ -233,7 +224,7 @@ const LivechatEditView = ({
|
|||
}
|
||||
}}
|
||||
theme={theme}
|
||||
editable={!!permissions[0]}
|
||||
editable={!!editOmnichannelContactPermission}
|
||||
/>
|
||||
{Object.entries(customFields?.visitor || {}).map(([key, value], index, array) => (
|
||||
<FormTextInput
|
||||
|
@ -250,7 +241,7 @@ const LivechatEditView = ({
|
|||
inputs.topic?.focus();
|
||||
}}
|
||||
theme={theme}
|
||||
editable={!!permissions[0]}
|
||||
editable={!!editOmnichannelContactPermission}
|
||||
/>
|
||||
))}
|
||||
<Title title={I18n.t('Conversation')} theme={theme} />
|
||||
|
@ -262,7 +253,7 @@ const LivechatEditView = ({
|
|||
defaultValue={livechat?.topic}
|
||||
onChangeText={text => onChangeText('topic', text)}
|
||||
theme={theme}
|
||||
editable={!!permissions[1]}
|
||||
editable={!!editLivechatRoomCustomFieldsPermission}
|
||||
/>
|
||||
|
||||
<Text style={[styles.label, { color: themes[theme].titleText }]}>{I18n.t('Tags')}</Text>
|
||||
|
@ -275,7 +266,7 @@ const LivechatEditView = ({
|
|||
value={tagParamSelected}
|
||||
context={BlockContext.FORM}
|
||||
multiselect
|
||||
disabled={!permissions[1]}
|
||||
disabled={!editLivechatRoomCustomFieldsPermission}
|
||||
inputStyle={styles.multiSelect}
|
||||
/>
|
||||
|
||||
|
@ -294,7 +285,7 @@ const LivechatEditView = ({
|
|||
submit();
|
||||
}}
|
||||
theme={theme}
|
||||
editable={!!permissions[1]}
|
||||
editable={!!editLivechatRoomCustomFieldsPermission}
|
||||
/>
|
||||
))}
|
||||
|
||||
|
@ -307,9 +298,7 @@ const LivechatEditView = ({
|
|||
|
||||
const mapStateToProps = (state: IApplicationState) => ({
|
||||
server: state.server.server,
|
||||
user: getUserSelector(state),
|
||||
editOmnichannelContact: state.permissions['edit-omnichannel-contact'],
|
||||
editLivechatRoomCustomfields: state.permissions['edit-livechat-room-customfields']
|
||||
user: getUserSelector(state)
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(withTheme(LivechatEditView));
|
||||
|
|
Loading…
Reference in New Issue