// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. import React, {useCallback, useMemo} from 'react'; import {View} from 'react-native'; import AutocompleteSelector from '@components/autocomplete_selector'; import Markdown from '@components/markdown'; import BoolSetting from '@components/settings/bool_setting'; import TextSetting from '@components/settings/text_setting'; import {View as ViewConstants} from '@constants'; import {AppFieldTypes, SelectableAppFieldTypes} from '@constants/apps'; import {useTheme} from '@context/theme'; import {selectKeyboardType} from '@utils/integrations'; import {getMarkdownBlockStyles, getMarkdownTextStyles} from '@utils/markdown'; import {makeStyleSheetFromTheme} from '@utils/theme'; const TEXT_DEFAULT_MAX_LENGTH = 150; const TEXTAREA_DEFAULT_MAX_LENGTH = 3000; export type Props = { field: AppField; name: string; errorText?: string; value: AppFormValue; onChange: (name: string, value: AppFormValue) => void; performLookup: (name: string, userInput: string) => Promise; } const dialogOptionToAppSelectOption = (option: DialogOption): AppSelectOption => ({ label: option.text, value: option.value, }); const appSelectOptionToDialogOption = (option: AppSelectOption): DialogOption => ({ text: option.label, value: option.value, }); const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => { return { markdownFieldContainer: { marginTop: 15, marginBottom: 10, marginLeft: 15, }, markdownFieldText: { fontSize: 14, color: theme.centerChannelColor, }, }; }); function selectDataSource(fieldType: string): string { switch (fieldType) { case AppFieldTypes.USER: return ViewConstants.DATA_SOURCE_USERS; case AppFieldTypes.CHANNEL: return ViewConstants.DATA_SOURCE_CHANNELS; case AppFieldTypes.DYNAMIC_SELECT: return ViewConstants.DATA_SOURCE_DYNAMIC; default: return ''; } } function AppsFormField({ field, name, errorText, value, onChange, performLookup, }: Props) { const theme = useTheme(); const style = getStyleSheet(theme); const testID = `AppFormElement.${name}`; const placeholder = field.hint || ''; const displayName = field.modal_label || field.label || ''; const handleChange = useCallback((newValue: string | boolean) => { onChange(name, newValue); }, [name]); const handleSelect = useCallback((newValue: SelectedDialogOption) => { if (!newValue) { const emptyValue = field.multiselect ? [] : null; onChange(name, emptyValue); return; } if (Array.isArray(newValue)) { const selectedOptions = newValue.map(dialogOptionToAppSelectOption); onChange(name, selectedOptions); return; } onChange(name, dialogOptionToAppSelectOption(newValue)); }, [onChange, field, name]); const getDynamicOptions = useCallback(async (userInput = ''): Promise => { const options = await performLookup(field.name, userInput); return options.map(appSelectOptionToDialogOption); }, [performLookup, field]); const options = useMemo(() => { if (field.type === AppFieldTypes.STATIC_SELECT) { return field.options?.map(appSelectOptionToDialogOption); } if (field.type === AppFieldTypes.DYNAMIC_SELECT) { if (!value) { return undefined; } if (Array.isArray(value)) { return value.map(appSelectOptionToDialogOption); } const selectedOption = value as AppSelectOption; return [appSelectOptionToDialogOption(selectedOption)]; } return undefined; }, [field, value]); const selectedValue = useMemo(() => { if (!value || !SelectableAppFieldTypes.includes(field.type)) { return undefined; } if (!value) { return undefined; } if (Array.isArray(value)) { return value.map((v) => v.value); } return value as string; }, [field, value]); switch (field.type) { case AppFieldTypes.TEXT: { return ( ); } case AppFieldTypes.USER: case AppFieldTypes.CHANNEL: case AppFieldTypes.STATIC_SELECT: case AppFieldTypes.DYNAMIC_SELECT: { return ( ); } case AppFieldTypes.BOOL: { return ( ); } case AppFieldTypes.MARKDOWN: { if (!field.description) { return null; } return ( ); } } return null; } export default AppsFormField;