Chore: Migrate LivechatEditView to Typescript (#3499)
* Chore: Migrate LivechatEditView to Typescript * refactor: minor tweak * refactor: fix the interfaces for input * refactor: fix lint erros * minor tweak with new navigation types * function * iroom tweak * livechateditview tweak * TextInput tweak * refactor: update new types and interfaces for use ISubscription * refactor to default useState type * change the component name in SearchBox * changed state type Co-authored-by: AlexAlexandre <alexalexandrejr@gmail.com> Co-authored-by: Gerzon Z <gerzonc@icloud.com> Co-authored-by: Diego Mello <diegolmello@gmail.com>
This commit is contained in:
parent
6933278fd5
commit
0289ba716d
|
@ -1,5 +1,13 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { NativeSyntheticEvent, StyleSheet, Text, TextInputFocusEventData, TextInputProps, View } from 'react-native';
|
import {
|
||||||
|
NativeSyntheticEvent,
|
||||||
|
StyleSheet,
|
||||||
|
TextInput as RNTextInput,
|
||||||
|
Text,
|
||||||
|
TextInputFocusEventData,
|
||||||
|
TextInputProps,
|
||||||
|
View
|
||||||
|
} from 'react-native';
|
||||||
import Touchable from 'react-native-platform-touchable';
|
import Touchable from 'react-native-platform-touchable';
|
||||||
|
|
||||||
import TextInput from '../presentation/TextInput';
|
import TextInput from '../presentation/TextInput';
|
||||||
|
@ -51,7 +59,7 @@ interface ISearchBox {
|
||||||
hasCancel?: boolean;
|
hasCancel?: boolean;
|
||||||
onCancelPress?: Function;
|
onCancelPress?: Function;
|
||||||
theme?: string;
|
theme?: string;
|
||||||
inputRef?: React.Ref<unknown>;
|
inputRef?: React.Ref<RNTextInput>;
|
||||||
testID?: string;
|
testID?: string;
|
||||||
onFocus?: (e: NativeSyntheticEvent<TextInputFocusEventData>) => void;
|
onFocus?: (e: NativeSyntheticEvent<TextInputFocusEventData>) => void;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { StyleProp, StyleSheet, Text, TextInputProps, TextStyle, View, ViewStyle } from 'react-native';
|
import { StyleProp, StyleSheet, Text, TextInputProps, TextInput as RNTextInput, TextStyle, View, ViewStyle } from 'react-native';
|
||||||
import Touchable from 'react-native-platform-touchable';
|
import Touchable from 'react-native-platform-touchable';
|
||||||
|
|
||||||
import sharedStyles from '../views/Styles';
|
import sharedStyles from '../views/Styles';
|
||||||
|
@ -59,7 +59,7 @@ export interface IRCTextInputProps extends TextInputProps {
|
||||||
loading?: boolean;
|
loading?: boolean;
|
||||||
containerStyle?: StyleProp<ViewStyle>;
|
containerStyle?: StyleProp<ViewStyle>;
|
||||||
inputStyle?: StyleProp<TextStyle>;
|
inputStyle?: StyleProp<TextStyle>;
|
||||||
inputRef?: React.Ref<unknown>;
|
inputRef?: React.Ref<RNTextInput>;
|
||||||
testID?: string;
|
testID?: string;
|
||||||
iconLeft?: string;
|
iconLeft?: string;
|
||||||
iconRight?: string;
|
iconRight?: string;
|
||||||
|
|
|
@ -22,8 +22,8 @@ interface IMultiSelect {
|
||||||
context?: number;
|
context?: number;
|
||||||
loading?: boolean;
|
loading?: boolean;
|
||||||
multiselect?: boolean;
|
multiselect?: boolean;
|
||||||
onSearch: Function;
|
onSearch?: () => void;
|
||||||
onClose: Function;
|
onClose?: () => void;
|
||||||
inputStyle: object;
|
inputStyle: object;
|
||||||
value?: any[];
|
value?: any[];
|
||||||
disabled?: boolean | object;
|
disabled?: boolean | object;
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
export interface ITagsOmnichannel {
|
||||||
|
_id: string;
|
||||||
|
name: string;
|
||||||
|
departments: string[];
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
export interface IVisitorEmail {
|
||||||
|
address: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IVisitorPhone {
|
||||||
|
phoneNumber: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IVisitor {
|
||||||
|
_id?: string;
|
||||||
|
token: string;
|
||||||
|
username: string;
|
||||||
|
updatedAt?: Date;
|
||||||
|
name: string;
|
||||||
|
department?: string;
|
||||||
|
phone?: IVisitorPhone[];
|
||||||
|
visitorEmails?: IVisitorEmail[];
|
||||||
|
customFields?: {
|
||||||
|
[key: string]: any;
|
||||||
|
};
|
||||||
|
livechatData: {
|
||||||
|
[key: string]: any;
|
||||||
|
};
|
||||||
|
}
|
|
@ -15,7 +15,7 @@ interface IThemedTextInput extends IRCTextInputProps {
|
||||||
theme: string;
|
theme: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ThemedTextInput = React.forwardRef(({ style, theme, ...props }: IThemedTextInput, ref: any) => (
|
const ThemedTextInput = React.forwardRef<TextInput, IThemedTextInput>(({ style, theme, ...props }, ref) => (
|
||||||
<TextInput
|
<TextInput
|
||||||
ref={ref}
|
ref={ref}
|
||||||
style={[{ color: themes[theme].titleText }, style, styles.input]}
|
style={[{ color: themes[theme].titleText }, style, styles.input]}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { StackNavigationOptions } from '@react-navigation/stack';
|
import { StackNavigationOptions } from '@react-navigation/stack';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { ScrollView, StyleSheet, Text } from 'react-native';
|
import { ScrollView, StyleSheet, Text, TextInput as RNTextInput } from 'react-native';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import { encryptionDecodeKey } from '../actions/encryption';
|
import { encryptionDecodeKey } from '../actions/encryption';
|
||||||
|
@ -37,7 +37,7 @@ interface IE2EEnterYourPasswordViewState {
|
||||||
type TE2EEnterYourPasswordViewProps = IBaseScreen<E2EEnterYourPasswordStackParamList, 'E2EEnterYourPasswordView'>;
|
type TE2EEnterYourPasswordViewProps = IBaseScreen<E2EEnterYourPasswordStackParamList, 'E2EEnterYourPasswordView'>;
|
||||||
|
|
||||||
class E2EEnterYourPasswordView extends React.Component<TE2EEnterYourPasswordViewProps, IE2EEnterYourPasswordViewState> {
|
class E2EEnterYourPasswordView extends React.Component<TE2EEnterYourPasswordViewProps, IE2EEnterYourPasswordViewState> {
|
||||||
private passwordInput?: TextInput;
|
private passwordInput?: RNTextInput;
|
||||||
|
|
||||||
static navigationOptions = ({ navigation }: Pick<TE2EEnterYourPasswordViewProps, 'navigation'>): StackNavigationOptions => ({
|
static navigationOptions = ({ navigation }: Pick<TE2EEnterYourPasswordViewProps, 'navigation'>): StackNavigationOptions => ({
|
||||||
headerLeft: () => <HeaderButton.CloseModal navigation={navigation} testID='e2e-enter-your-password-view-close' />,
|
headerLeft: () => <HeaderButton.CloseModal navigation={navigation} testID='e2e-enter-your-password-view-close' />,
|
||||||
|
@ -76,7 +76,7 @@ class E2EEnterYourPasswordView extends React.Component<TE2EEnterYourPasswordView
|
||||||
style={[styles.container, { backgroundColor: themes[theme].backgroundColor }]}
|
style={[styles.container, { backgroundColor: themes[theme].backgroundColor }]}
|
||||||
testID='e2e-enter-your-password-view'>
|
testID='e2e-enter-your-password-view'>
|
||||||
<TextInput
|
<TextInput
|
||||||
inputRef={(e: TextInput) => {
|
inputRef={(e: RNTextInput) => {
|
||||||
this.passwordInput = e;
|
this.passwordInput = e;
|
||||||
}}
|
}}
|
||||||
placeholder={I18n.t('Password')}
|
placeholder={I18n.t('Password')}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import { StackNavigationProp } from '@react-navigation/stack';
|
||||||
import { ScrollView, StyleSheet, Text } from 'react-native';
|
import { RouteProp } from '@react-navigation/native';
|
||||||
|
import { ScrollView, StyleSheet, Text, TextInput as RNTextInput } from 'react-native';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { BLOCK_CONTEXT } from '@rocket.chat/ui-kit';
|
import { BLOCK_CONTEXT } from '@rocket.chat/ui-kit';
|
||||||
|
|
||||||
|
@ -10,7 +11,6 @@ import TextInput from '../containers/TextInput';
|
||||||
import KeyboardView from '../presentation/KeyboardView';
|
import KeyboardView from '../presentation/KeyboardView';
|
||||||
import RocketChat from '../lib/rocketchat';
|
import RocketChat from '../lib/rocketchat';
|
||||||
import I18n from '../i18n';
|
import I18n from '../i18n';
|
||||||
|
|
||||||
import { LISTENER } from '../containers/Toast';
|
import { LISTENER } from '../containers/Toast';
|
||||||
import EventEmitter from '../utils/events';
|
import EventEmitter from '../utils/events';
|
||||||
import scrollPersistTaps from '../utils/scrollPersistTaps';
|
import scrollPersistTaps from '../utils/scrollPersistTaps';
|
||||||
|
@ -18,6 +18,10 @@ import { getUserSelector } from '../selectors/login';
|
||||||
import Button from '../containers/Button';
|
import Button from '../containers/Button';
|
||||||
import SafeAreaView from '../containers/SafeAreaView';
|
import SafeAreaView from '../containers/SafeAreaView';
|
||||||
import { MultiSelect } from '../containers/UIKit/MultiSelect';
|
import { MultiSelect } from '../containers/UIKit/MultiSelect';
|
||||||
|
import { IVisitor } from '../definitions/IVisitor';
|
||||||
|
import { ITagsOmnichannel } from '../definitions/ITagsOmnichannel';
|
||||||
|
import { IApplicationState, ISubscription } from '../definitions';
|
||||||
|
import { ChatsStackParamList } from '../stacks/types';
|
||||||
import sharedStyles from './Styles';
|
import sharedStyles from './Styles';
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
|
@ -39,36 +43,87 @@ const styles = StyleSheet.create({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const Title = ({ title, theme }) =>
|
interface ITitle {
|
||||||
title ? <Text style={[styles.title, { color: themes[theme].titleText }]}>{title}</Text> : null;
|
title: string;
|
||||||
Title.propTypes = {
|
theme: string;
|
||||||
title: PropTypes.string,
|
}
|
||||||
theme: PropTypes.string
|
|
||||||
};
|
|
||||||
|
|
||||||
const LivechatEditView = ({ user, navigation, route, theme, editOmnichannelContact, editLivechatRoomCustomfields }) => {
|
interface IField {
|
||||||
const [customFields, setCustomFields] = useState({});
|
_id: string;
|
||||||
const [availableUserTags, setAvailableUserTags] = useState([]);
|
visibility: string;
|
||||||
|
scope: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IInputs {
|
||||||
|
[key: string]: string | string[] | undefined;
|
||||||
|
name: string;
|
||||||
|
email: string;
|
||||||
|
phone?: string;
|
||||||
|
topic: string;
|
||||||
|
tag: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
type TParams = IVisitor & IInputs;
|
||||||
|
|
||||||
|
interface ILivechat extends ISubscription {
|
||||||
|
// Param dynamic depends on server
|
||||||
|
sms?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IInputsRefs {
|
||||||
|
[index: string]: RNTextInput | null;
|
||||||
|
name: RNTextInput | null;
|
||||||
|
phone: RNTextInput | null;
|
||||||
|
topic: RNTextInput | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ICustomFields {
|
||||||
|
visitor?: { [key: string]: string };
|
||||||
|
livechat?: { [key: string]: string };
|
||||||
|
}
|
||||||
|
interface ILivechatEditViewProps {
|
||||||
|
// TODO: Refactor when migrate models
|
||||||
|
user: any;
|
||||||
|
navigation: StackNavigationProp<ChatsStackParamList, 'LivechatEditView'>;
|
||||||
|
route: RouteProp<ChatsStackParamList, 'LivechatEditView'>;
|
||||||
|
theme: string;
|
||||||
|
editOmnichannelContact: string[];
|
||||||
|
editLivechatRoomCustomfields: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
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 [customFields, setCustomFields] = useState<ICustomFields>({});
|
||||||
|
const [availableUserTags, setAvailableUserTags] = useState<string[]>([]);
|
||||||
const [permissions, setPermissions] = useState([]);
|
const [permissions, setPermissions] = useState([]);
|
||||||
|
|
||||||
const params = {};
|
const params = {} as TParams;
|
||||||
const inputs = {};
|
const inputs = {} as IInputsRefs;
|
||||||
|
|
||||||
const livechat = route.params?.room ?? {};
|
const livechat = (route.params?.room ?? {}) as ILivechat;
|
||||||
const visitor = route.params?.roomUser ?? {};
|
const visitor = route.params?.roomUser ?? {};
|
||||||
|
|
||||||
const getCustomFields = async () => {
|
const getCustomFields = async () => {
|
||||||
const result = await RocketChat.getCustomFields();
|
const result = await RocketChat.getCustomFields();
|
||||||
if (result.success && result.customFields?.length) {
|
if (result.success && result.customFields?.length) {
|
||||||
const visitorCustomFields = result.customFields
|
const visitorCustomFields = result.customFields
|
||||||
.filter(field => field.visibility !== 'hidden' && field.scope === 'visitor')
|
.filter((field: IField) => field.visibility !== 'hidden' && field.scope === 'visitor')
|
||||||
.map(field => ({ [field._id]: (visitor.livechatData && visitor.livechatData[field._id]) || '' }))
|
.map((field: IField) => ({ [field._id]: (visitor.livechatData && visitor.livechatData[field._id]) || '' }))
|
||||||
.reduce((ret, field) => ({ ...field, ...ret }));
|
.reduce((ret: IField, field: IField) => ({ ...field, ...ret }));
|
||||||
|
|
||||||
const livechatCustomFields = result.customFields
|
const livechatCustomFields = result.customFields
|
||||||
.filter(field => field.visibility !== 'hidden' && field.scope === 'room')
|
.filter((field: IField) => field.visibility !== 'hidden' && field.scope === 'room')
|
||||||
.map(field => ({ [field._id]: (livechat.livechatData && livechat.livechatData[field._id]) || '' }))
|
.map((field: IField) => ({ [field._id]: (livechat.livechatData && livechat.livechatData[field._id]) || '' }))
|
||||||
.reduce((ret, field) => ({ ...field, ...ret }));
|
.reduce((ret: IField, field: IField) => ({ ...field, ...ret }));
|
||||||
|
|
||||||
return setCustomFields({ visitor: visitorCustomFields, livechat: livechatCustomFields });
|
return setCustomFields({ visitor: visitorCustomFields, livechat: livechatCustomFields });
|
||||||
}
|
}
|
||||||
|
@ -83,8 +138,8 @@ const LivechatEditView = ({ user, navigation, route, theme, editOmnichannelConta
|
||||||
setTags(uniqueArray);
|
setTags(uniqueArray);
|
||||||
}, [availableUserTags]);
|
}, [availableUserTags]);
|
||||||
|
|
||||||
const getTagsList = async agentDepartments => {
|
const getTagsList = async (agentDepartments: string[]) => {
|
||||||
const tags = await RocketChat.getTagsList();
|
const tags: ITagsOmnichannel[] = await RocketChat.getTagsList();
|
||||||
const isAdmin = ['admin', 'livechat-manager'].find(role => user.roles.includes(role));
|
const isAdmin = ['admin', 'livechat-manager'].find(role => user.roles.includes(role));
|
||||||
const availableTags = tags
|
const availableTags = tags
|
||||||
.filter(({ departments }) => isAdmin || departments.length === 0 || departments.some(i => agentDepartments.indexOf(i) > -1))
|
.filter(({ departments }) => isAdmin || departments.length === 0 || departments.some(i => agentDepartments.indexOf(i) > -1))
|
||||||
|
@ -95,16 +150,18 @@ const LivechatEditView = ({ user, navigation, route, theme, editOmnichannelConta
|
||||||
const getAgentDepartments = async () => {
|
const getAgentDepartments = async () => {
|
||||||
const result = await RocketChat.getAgentDepartments(visitor?._id);
|
const result = await RocketChat.getAgentDepartments(visitor?._id);
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
const agentDepartments = result.departments.map(dept => dept.departmentId);
|
const agentDepartments = result.departments.map((dept: { departmentId: string }) => dept.departmentId);
|
||||||
getTagsList(agentDepartments);
|
getTagsList(agentDepartments);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const submit = async () => {
|
const submit = async () => {
|
||||||
const userData = { _id: visitor?._id };
|
const userData = { _id: visitor?._id } as TParams;
|
||||||
|
|
||||||
const { rid, sms } = livechat;
|
const { rid } = livechat;
|
||||||
const roomData = { _id: rid };
|
const sms = livechat?.sms;
|
||||||
|
|
||||||
|
const roomData = { _id: rid } as TParams;
|
||||||
|
|
||||||
if (params.name) {
|
if (params.name) {
|
||||||
userData.name = params.name;
|
userData.name = params.name;
|
||||||
|
@ -149,7 +206,7 @@ const LivechatEditView = ({ user, navigation, route, theme, editOmnichannelConta
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const onChangeText = (key, text) => {
|
const onChangeText = (key: string, text: string) => {
|
||||||
params[key] = text;
|
params[key] = text;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -159,6 +216,9 @@ const LivechatEditView = ({ user, navigation, route, theme, editOmnichannelConta
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
navigation.setOptions({
|
||||||
|
title: I18n.t('Edit')
|
||||||
|
});
|
||||||
getAgentDepartments();
|
getAgentDepartments();
|
||||||
getCustomFields();
|
getCustomFields();
|
||||||
getPermissions();
|
getPermissions();
|
||||||
|
@ -177,7 +237,7 @@ const LivechatEditView = ({ user, navigation, route, theme, editOmnichannelConta
|
||||||
defaultValue={visitor?.name}
|
defaultValue={visitor?.name}
|
||||||
onChangeText={text => onChangeText('name', text)}
|
onChangeText={text => onChangeText('name', text)}
|
||||||
onSubmitEditing={() => {
|
onSubmitEditing={() => {
|
||||||
inputs.name.focus();
|
inputs.name?.focus();
|
||||||
}}
|
}}
|
||||||
theme={theme}
|
theme={theme}
|
||||||
editable={!!permissions[0]}
|
editable={!!permissions[0]}
|
||||||
|
@ -190,7 +250,7 @@ const LivechatEditView = ({ user, navigation, route, theme, editOmnichannelConta
|
||||||
defaultValue={visitor?.visitorEmails && visitor?.visitorEmails[0]?.address}
|
defaultValue={visitor?.visitorEmails && visitor?.visitorEmails[0]?.address}
|
||||||
onChangeText={text => onChangeText('email', text)}
|
onChangeText={text => onChangeText('email', text)}
|
||||||
onSubmitEditing={() => {
|
onSubmitEditing={() => {
|
||||||
inputs.phone.focus();
|
inputs.phone?.focus();
|
||||||
}}
|
}}
|
||||||
theme={theme}
|
theme={theme}
|
||||||
editable={!!permissions[0]}
|
editable={!!permissions[0]}
|
||||||
|
@ -206,9 +266,9 @@ const LivechatEditView = ({ user, navigation, route, theme, editOmnichannelConta
|
||||||
const keys = Object.keys(customFields?.visitor || {});
|
const keys = Object.keys(customFields?.visitor || {});
|
||||||
if (keys.length > 0) {
|
if (keys.length > 0) {
|
||||||
const key = keys[0];
|
const key = keys[0];
|
||||||
inputs[key].focus();
|
inputs[key]?.focus();
|
||||||
} else {
|
} else {
|
||||||
inputs.topic.focus();
|
inputs.topic?.focus();
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
theme={theme}
|
theme={theme}
|
||||||
|
@ -224,9 +284,9 @@ const LivechatEditView = ({ user, navigation, route, theme, editOmnichannelConta
|
||||||
onChangeText={text => onChangeText(key, text)}
|
onChangeText={text => onChangeText(key, text)}
|
||||||
onSubmitEditing={() => {
|
onSubmitEditing={() => {
|
||||||
if (array.length - 1 > index) {
|
if (array.length - 1 > index) {
|
||||||
return inputs[array[index + 1][0]].focus();
|
return inputs[array[index + 1][0]]?.focus();
|
||||||
}
|
}
|
||||||
inputs.topic.focus();
|
inputs.topic?.focus();
|
||||||
}}
|
}}
|
||||||
theme={theme}
|
theme={theme}
|
||||||
editable={!!permissions[0]}
|
editable={!!permissions[0]}
|
||||||
|
@ -240,15 +300,14 @@ const LivechatEditView = ({ user, navigation, route, theme, editOmnichannelConta
|
||||||
}}
|
}}
|
||||||
defaultValue={livechat?.topic}
|
defaultValue={livechat?.topic}
|
||||||
onChangeText={text => onChangeText('topic', text)}
|
onChangeText={text => onChangeText('topic', text)}
|
||||||
onSubmitEditing={() => inputs.tags.focus()}
|
|
||||||
theme={theme}
|
theme={theme}
|
||||||
editable={!!permissions[1]}
|
editable={!!permissions[1]}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Text style={[styles.label, { color: themes[theme].titleText }]}>{I18n.t('Tags')}</Text>
|
<Text style={[styles.label, { color: themes[theme].titleText }]}>{I18n.t('Tags')}</Text>
|
||||||
<MultiSelect
|
<MultiSelect
|
||||||
options={tagParam.map(tag => ({ text: { text: tag }, value: tag }))}
|
options={tagParam.map((tag: string) => ({ text: { text: tag }, value: tag }))}
|
||||||
onChange={({ value }) => {
|
onChange={({ value }: { value: string[] }) => {
|
||||||
setTagParamSelected([...value]);
|
setTagParamSelected([...value]);
|
||||||
}}
|
}}
|
||||||
placeholder={{ text: I18n.t('Tags') }}
|
placeholder={{ text: I18n.t('Tags') }}
|
||||||
|
@ -260,7 +319,7 @@ const LivechatEditView = ({ user, navigation, route, theme, editOmnichannelConta
|
||||||
inputStyle={styles.multiSelect}
|
inputStyle={styles.multiSelect}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{Object.entries(customFields?.livechat || {}).map(([key, value], index, array) => (
|
{Object.entries(customFields?.livechat || {}).map(([key, value], index, array: any) => (
|
||||||
<TextInput
|
<TextInput
|
||||||
label={key}
|
label={key}
|
||||||
defaultValue={value}
|
defaultValue={value}
|
||||||
|
@ -270,7 +329,7 @@ const LivechatEditView = ({ user, navigation, route, theme, editOmnichannelConta
|
||||||
onChangeText={text => onChangeText(key, text)}
|
onChangeText={text => onChangeText(key, text)}
|
||||||
onSubmitEditing={() => {
|
onSubmitEditing={() => {
|
||||||
if (array.length - 1 > index) {
|
if (array.length - 1 > index) {
|
||||||
return inputs[array[index + 1]].focus();
|
return inputs[array[index + 1]]?.focus();
|
||||||
}
|
}
|
||||||
submit();
|
submit();
|
||||||
}}
|
}}
|
||||||
|
@ -285,19 +344,8 @@ const LivechatEditView = ({ user, navigation, route, theme, editOmnichannelConta
|
||||||
</KeyboardView>
|
</KeyboardView>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
LivechatEditView.propTypes = {
|
|
||||||
user: PropTypes.object,
|
|
||||||
navigation: PropTypes.object,
|
|
||||||
route: PropTypes.object,
|
|
||||||
theme: PropTypes.string,
|
|
||||||
editOmnichannelContact: PropTypes.array,
|
|
||||||
editLivechatRoomCustomfields: PropTypes.array
|
|
||||||
};
|
|
||||||
LivechatEditView.navigationOptions = {
|
|
||||||
title: I18n.t('Edit')
|
|
||||||
};
|
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = (state: IApplicationState) => ({
|
||||||
server: state.server.server,
|
server: state.server.server,
|
||||||
user: getUserSelector(state),
|
user: getUserSelector(state),
|
||||||
editOmnichannelContact: state.permissions['edit-omnichannel-contact'],
|
editOmnichannelContact: state.permissions['edit-omnichannel-contact'],
|
Loading…
Reference in New Issue