import { Fragment, useContext, useEffect, useState } from 'react'; import './chat-info.scss'; import { OptionsData, SelectChip } from '../../../../components/SelectChip/SelectChip'; import { AutoCategorization, ChatInfoForm, IIntent, IRequestData, IntentRequestCount, ResolutionStatusItem, ResolutionStatusChipColors as ChipColors, ResolutionStatusValues as Statuses, ResolutionStatusLabels as Labels, ResolutionType } from '../../models'; import { List, Views } from '../../../../core/models/core.model'; import { ISelectOption, Select } from '../../../../components/Select/Select'; import { Autocomplete, AutocompleteOption } from '../../../../components/Autocomplete/Autocomplete'; import { AutocompleteRenderInputParams } from '@mui/material'; import RequestDetailsService from '../../services/request-details.service'; import NavigationLink from '../../../../core/components/navigation-link/NavigationLink'; import ChatInfoTitle from './ChatInfoTitle'; import { RequestContext } from '../../../../pages/request-details/Request.context'; import AiseraLoader from '../../../../components/AiseraLoader/AiseraLoader'; import { EntityHighlighterService } from '../../../../modules/request-details/services/entity-highlight-service'; import { TagIcon } from '../../../../components/aisera-icons/custom'; /** * resolutionStatuses: works with request list page in Ticket Intelligence * aligns with collection of resolution statuses */ const resolutionStatuses = [ { value: Statuses.Resolved, label: Labels.Resolved, chipColor: ChipColors.Resolved}, { value: Statuses.Unresolved, label: Labels.Unresolved, chipColor: ChipColors.Unresolved}, { value: Statuses.Unknown, label: Labels.Unknown, chipColor: ChipColors.Unknown}, { value: Statuses.NotHandled, label: Labels.NotHandled, chipColor: ChipColors.NotHandled}, { value: Statuses.Casual, label: Labels.Casual, chipColor: ChipColors.Casual}, { value: Statuses.NotRelevant, label: Labels.NotRelevant, chipColor: ChipColors.NotRelevant}, { value: Statuses.Assisted, label: Labels.Assisted, chipColor: ChipColors.Assisted} ]; const ChatInfo = (props: IChatInfoProps) => { const { botId, botDomain, actions, userId } = useContext(RequestContext); const { request } = props; const [intents, setIntents] = useState(); const [chatInfoForm, setChatInfoForm] = useState(); const [autoCategorizationOptions, setAutoCategorizationOptions] = useState(); const [resolutionTypeOptions, setResolutionTypeOptions] = useState(); const [resolutionStatusOptions, setResolutionStatusOptions] = useState(); const [tags, setTags] = useState(); const [preSelectedTagNames, setPreSelectedTagNames] = useState(); const [highlightedTitle, setHighightedTitle] = useState(); useEffect(() => { const fetchTags = async () => { const tagsData = await RequestDetailsService.fetchAllTags(); const tagsDataList = tagsData.map(({name, id}) => ({label: name, value: id})) setTags(tagsDataList as AutocompleteOption[]); } fetchTags(); }, []); useEffect(() => { if (request) { setHighightedTitle(request.title); const fetchRequestTags = async () => { const intentsWithCounts: IntentRequestCount[] = []; for (const {id, name} of request.intents) { let res = await RequestDetailsService.fetchRequestCountPerIntent(id); if(!res?.length) { res = [{count: 0}]; } intentsWithCounts.push({id, name, ...res[0]}); } setIntents(intentsWithCounts); const requestTagsData = await RequestDetailsService.fetchRequestTags(request.id); const tagsDataList = requestTagsData.map(({listId}: {listId: number}) => listId); setPreSelectedTagNames(requestTagsData.map(({name, listId}) => ({value: listId, label: name} as unknown as AutocompleteOption))); setChatInfoForm({ resolution_status: request.resolution_status, resolution_detail: request.resolution_detail, autotagging_category: request.requestAutocategorization.autotagging_category, tags: tagsDataList }); } fetchRequestTags(); const autoCategorizationTypes = Object.entries(AutoCategorization) .map(([value, label]) => ({ value, label})); setAutoCategorizationOptions(autoCategorizationTypes); const resolutionTypes = Object.entries(ResolutionType) .map(([value, label]) => ({ value, label})); setResolutionTypeOptions(resolutionTypes); setResolutionStatusOptions(resolutionStatuses as ResolutionStatusItem[]); setHighlightedEntityInTitle(); } }, [request]); const setHighlightedEntityInTitle = async () => { const entities = Array.from(EntityHighlighterService.getAddedEntities()); if (entities.length) { const highlightedEntities = await RequestDetailsService.entitiesHighlight([request.title], Array.from(EntityHighlighterService.getAddedEntities()), botId); highlightedEntities?.forEach(highlightOb => { const replacers = {} as any; let highlightInput = highlightOb.input; highlightOb?.values.forEach(({id, spos, epos}) => { const color = EntityHighlighterService.getEntity(id); const substr = highlightOb.input.slice(spos, epos); replacers[substr] = `${substr}`; }); for (const key in replacers) { highlightInput = highlightInput.replace(key, replacers[key]); } setHighightedTitle(highlightInput); }); } } const handleOptionChange = (obj: {[key: string]: string | string[]}) => { const chatInfoFormData = {...chatInfoForm, ...obj as unknown as ChatInfoForm}; setChatInfoForm(chatInfoFormData); updateRequest(chatInfoFormData); } const handleTagOptionChange = async (obj: {[key: string]: string[]}) => { const newTag = obj?.tags?.find(tag => typeof tag === 'string'); if(newTag) { const res = await RequestDetailsService.createNewTag(newTag, userId); if(res) { obj.tags[obj.tags.indexOf(newTag)] = res.id; const allTags = [...tags as AutocompleteOption[], {value: res.id, label: newTag}]; setTags([...tags as AutocompleteOption[], {value: res.id, label: newTag}]); const preselected = allTags.filter(({value}) => obj.tags.includes(value)); setPreSelectedTagNames(preselected); const chatInfoFormData = {...chatInfoForm, ...obj as unknown as ChatInfoForm}; setChatInfoForm(chatInfoFormData); updateRequest(chatInfoFormData); } else { throw 'Could not create new tag'; } } else { handleOptionChange(obj); } } const updateRequest = async (chatInfoFormData: ChatInfoForm) => { await RequestDetailsService.updateRequest(request.id, chatInfoFormData, botId, botDomain, request?.intents?.map((a: IIntent) => a.id)); } const handleIntentClick = (intentId: number) => { actions.handler({type: 'ViewNavigation', data: {viewId: Views.IntentDetails, data : {entityId: intentId}}}); } return (
{request && chatInfoForm ? ( {request.intents?.length ? (
{ intents?.map((intent: IntentRequestCount, index: number) => ( handleIntentClick(intent.id)}/> )) }
) : null} { request?.requestAutocategorization?.autotagging_category && (
{request?.requestAutocategorization?.autotagging_category}
) || null }
handleOptionChange({'resolution_detail': e})} options={resolutionTypeOptions as ISelectOption[]} // readOnly={true} // disabled={true} />
handleOptionChange({'resolution_status': option.value as string})} options={resolutionStatusOptions as ISelectOption[]} // readOnly={true} // disabled={true} />
null} onOptionChange={(e: string[]) => handleTagOptionChange({'tags': e})} options={tags as AutocompleteOption[]} />
) : ( )}
) } export default ChatInfo; export interface IChatInfoProps { request: IRequestData; }