447 lines
14 KiB
TypeScript
447 lines
14 KiB
TypeScript
import { useEffect, useState } from "react";
|
||
import { enqueueSnackbar } from "notistack";
|
||
import type { TagKeys, SelectedTags, QuestionKeys, SelectedQuestions, MinifiedData } from "./types";
|
||
import {
|
||
AccountResponse,
|
||
getIntegrationRules,
|
||
getPipelines,
|
||
getSteps,
|
||
getTags,
|
||
getUsers,
|
||
getAccount,
|
||
FieldsRule,
|
||
getFields,
|
||
connectBitrix,
|
||
} from "@/api/bitrixIntegration";
|
||
import { AnyTypedQuizQuestion } from "@frontend/squzanswerer";
|
||
import { UntypedQuizQuestion } from "@/model/questionTypes/shared";
|
||
|
||
const SIZE = 25;
|
||
|
||
interface Props {
|
||
isModalOpen: boolean;
|
||
isTryRemoveAccount: boolean;
|
||
quizID: number;
|
||
questions: (AnyTypedQuizQuestion | UntypedQuizQuestion)[]
|
||
}
|
||
|
||
const FCTranslate = {
|
||
"name": "имя",
|
||
"email": "почта",
|
||
"phone": "телефон",
|
||
"text": "номер",
|
||
"address": "адрес",
|
||
}
|
||
|
||
let isReadyGetPipeline = true;
|
||
let isReadyGetPipelineStep = true;
|
||
let isReadyGetUsers = true;
|
||
let isReadyGetTags = true;
|
||
let isReadyGetFields = true;
|
||
|
||
export const useBitrixIntegration = ({ isModalOpen, isTryRemoveAccount, quizID, questions }: Props) => {
|
||
const [isLoadingPage, setIsLoadingPage] = useState<boolean>(true);
|
||
const [firstRules, setFirstRules] = useState<boolean>(false);
|
||
const [accountInfo, setAccountInfo] = useState<AccountResponse | null>(null);
|
||
|
||
const [leadFlag, setLeadFlag] = useState<boolean>(false);
|
||
|
||
const [arrayOfPipelines, setArrayOfPipelines] = useState<MinifiedData[]>([]);
|
||
const [arrayOfPipelinesSteps, setArrayOfPipelinesSteps] = useState<MinifiedData[]>([]);
|
||
const [fullArrayOfPipelinesSteps, setFullArrayOfPipelinesSteps] = useState<any[]>([]);
|
||
const [arrayOfUsers, setArrayOfUsers] = useState<MinifiedData[]>([]);
|
||
const [arrayOfTags, setArrayOfTags] = useState<MinifiedData[]>([]);
|
||
const [arrayOfFields, setArrayOfFields] = useState<MinifiedData[]>([]);
|
||
|
||
const [selectedPipeline, setSelectedPipeline] = useState<string | null>(null);
|
||
const [selectedPipelineStep, setSelectedPipelineStep] = useState<string | null>(null);
|
||
const [selectedDealUser, setSelectedDealPerformer] = useState<string | null>(null);
|
||
const [selectedCurrentFields, setSelectedCurrentFields] = useState<MinifiedData[]>([]);
|
||
|
||
const [questionsBackend, setQuestionsBackend] = useState<FieldsRule>({} as FieldsRule);
|
||
const [selectedTags, setSelectedTags] = useState<SelectedTags>({
|
||
Lead: [],
|
||
Contact: [],
|
||
Company: [],
|
||
Customer: [],
|
||
});
|
||
const [selectedQuestions, setSelectedQuestions] = useState<SelectedQuestions>({
|
||
lead: [],
|
||
company: [],
|
||
contact: [],
|
||
deal: [],
|
||
CRM_INVOICE: [],
|
||
CRM_SMART_INVOICE: [],
|
||
CRM_QUOTE: [],
|
||
CRM_REQUISITE: [],
|
||
});
|
||
|
||
const [pageOfPipelines, setPageOfPipelines] = useState(1);
|
||
const [pageOfPipelinesSteps, setPageOfPipelinesSteps] = useState(1);
|
||
const [pageOfUsers, setPageOfUsers] = useState(1);
|
||
const [pageOfTags, setPageOfTags] = useState(1);
|
||
const [pageOfFields, setPageOfFields] = useState(1);
|
||
|
||
const leadFlagHC = (s:boolean) => {
|
||
setLeadFlag(s)
|
||
};
|
||
const selectedPipelineHC = (id:string | null) => {
|
||
setSelectedPipeline(id);
|
||
isReadyGetPipelineStep = true;
|
||
setPageOfPipelinesSteps(1);
|
||
}
|
||
|
||
|
||
// useEffect(() => {
|
||
// (async () => {
|
||
// const API_URL = `https://penadigitaltech.bitrix24.ru`;
|
||
// try {
|
||
// const response = await makeRequest<void, { link: string }>({
|
||
// method: "POST",
|
||
// url: `${API_URL}/account`,
|
||
// useToken: true,
|
||
// withCredentials: true,
|
||
// body: {
|
||
// "client_bitrix_url": "penadigitaltech.bitrix24.ru"
|
||
// }
|
||
// });
|
||
// window.open(response.link, "_blank");
|
||
// } catch (nativeError) {
|
||
// return [null, `Не удалось подключить аккаунт. `];
|
||
// }
|
||
// })()
|
||
|
||
// }, [isModalOpen])
|
||
|
||
useEffect(() => {
|
||
const fetchAccountRules = async () => {
|
||
setIsLoadingPage(true);
|
||
const [account, accountError] = await getAccount();
|
||
|
||
if (accountError) {
|
||
if (!accountError.includes("Not Found")) enqueueSnackbar(accountError);
|
||
setAccountInfo(null);
|
||
}
|
||
if (account) {
|
||
setAccountInfo(account);
|
||
}
|
||
const [settingsResponse, rulesError] = await getIntegrationRules(quizID.toString());
|
||
|
||
if (rulesError) {
|
||
if (rulesError === "first") setFirstRules(true);
|
||
if (!rulesError.includes("Not Found") && !rulesError.includes("first")) enqueueSnackbar(rulesError);
|
||
}
|
||
if (settingsResponse) {
|
||
if (settingsResponse.PipelineID) selectedPipelineHC(settingsResponse.PipelineID.toString());
|
||
if (settingsResponse.StepID) setSelectedPipelineStep(settingsResponse.StepID.toString());
|
||
if (settingsResponse.PerformerID) setSelectedDealPerformer(settingsResponse.PerformerID.toString());
|
||
console.log("settingsResponse")
|
||
console.log(settingsResponse)
|
||
setLeadFlag(settingsResponse.LeadFlag)
|
||
|
||
if (Boolean(settingsResponse.FieldsRule) && Object.keys(settingsResponse?.FieldsRule).length > 0) {
|
||
const gottenQuestions = { ...selectedQuestions };
|
||
setQuestionsBackend(settingsResponse.FieldsRule);
|
||
|
||
for (let key in settingsResponse.FieldsRule) {
|
||
if (
|
||
settingsResponse.FieldsRule[key as QuestionKeys] !== null
|
||
) {
|
||
const gottenList = settingsResponse.FieldsRule[key as QuestionKeys];
|
||
|
||
if (gottenList !== null) {
|
||
Object.keys(gottenList.QuestionID).forEach((qId) => {
|
||
const q = questions.find(e => e.backendId === Number(qId)) || {}
|
||
|
||
if (gottenQuestions[key as QuestionKeys] === undefined) gottenQuestions[key as QuestionKeys] = []
|
||
|
||
gottenQuestions[key as QuestionKeys].push({
|
||
id: qId,
|
||
title: q.title,
|
||
entity: key,
|
||
|
||
})
|
||
})
|
||
|
||
}
|
||
|
||
if (key === "Contact") {
|
||
const MAP = settingsResponse.FieldsRule[key as QuestionKeys].ContactRuleMap
|
||
|
||
const list = []
|
||
for (let key in MAP) {
|
||
list.push({
|
||
id: key,
|
||
title: FCTranslate[key],
|
||
entity: "Contact",
|
||
bitrixId: MAP[key].toString(),
|
||
})
|
||
}
|
||
setSelectedCurrentFields(list)
|
||
}
|
||
}
|
||
}
|
||
setSelectedQuestions(gottenQuestions);
|
||
}
|
||
|
||
if (Boolean(settingsResponse.TagsToAdd) && Object.keys(settingsResponse.TagsToAdd).length > 0) {
|
||
const gottenTags = { ...selectedTags };
|
||
|
||
for (let key in settingsResponse.TagsToAdd) {
|
||
const gottenList = settingsResponse.TagsToAdd[key as TagKeys];
|
||
if (gottenList !== null && Array.isArray(gottenList)) {
|
||
gottenTags[key as TagKeys] = gottenList.map((e) => e.toString());
|
||
}
|
||
}
|
||
setSelectedTags(gottenTags);
|
||
}
|
||
setFirstRules(false);
|
||
}
|
||
setIsLoadingPage(false);
|
||
};
|
||
|
||
fetchAccountRules();
|
||
|
||
}, [isModalOpen, isTryRemoveAccount]);
|
||
|
||
|
||
useEffect(() => {
|
||
const transletedQuestions = {...selectedQuestions}
|
||
|
||
Object.keys(selectedQuestions)?.forEach((column) => {
|
||
selectedQuestions[column].forEach((minifiedData) => {
|
||
const q = questions.find(e => e.backendId === Number(minifiedData.id)) || {};
|
||
transletedQuestions[column].push({
|
||
...minifiedData,
|
||
title: q.title || transletedQuestions[column].title
|
||
})
|
||
})
|
||
})
|
||
|
||
setSelectedQuestions(transletedQuestions)
|
||
}, [questions])
|
||
|
||
useEffect(() => {
|
||
if (isReadyGetPipeline) {
|
||
getPipelines({
|
||
page: pageOfPipelines,
|
||
size: SIZE,
|
||
}).then(([response]) => {
|
||
if (response && response.items !== null) {
|
||
const minifiedPipelines: MinifiedData[] = [];
|
||
|
||
response.items.forEach((step) => {
|
||
minifiedPipelines.push({
|
||
id: step.bitrixID.toString(),
|
||
title: step.name || "Нет названия",
|
||
});
|
||
});
|
||
setArrayOfPipelines((prevItems) => [...prevItems, ...minifiedPipelines]);
|
||
setPageOfPipelinesSteps(1);
|
||
} else {
|
||
isReadyGetPipeline = false
|
||
}
|
||
});
|
||
}
|
||
}, [pageOfPipelines]);
|
||
useEffect(() => {
|
||
if (isReadyGetPipelineStep && selectedPipeline !== null) {
|
||
const oldData = pageOfPipelinesSteps === 1 ? [] : arrayOfPipelinesSteps;
|
||
const oldFullData = pageOfPipelinesSteps === 1 ? [] : fullArrayOfPipelinesSteps;
|
||
|
||
getSteps({
|
||
page: pageOfPipelinesSteps,
|
||
size: SIZE,
|
||
pipelineId: Number(selectedPipeline),
|
||
}).then(([response]) => {
|
||
if (response && response.items !== null) {
|
||
// Фильтруем только нужные элементы
|
||
const filteredItems = response.items.filter(item =>
|
||
item.entityID === "STATUS" ||
|
||
item.entityID === "SOURCE" ||
|
||
(typeof item.entityID === 'string' && item.entityID.startsWith("DEAL_STAGE"))
|
||
);
|
||
|
||
// Минифицируем отфильтрованные данные
|
||
const minifiedSteps: MinifiedData[] = filteredItems.map((step) => ({
|
||
id: step.bitrixID.toString(),
|
||
title: step.name,
|
||
entity: step.entityID
|
||
}));
|
||
|
||
// Обновляем массивы
|
||
setArrayOfPipelinesSteps([...oldData, ...minifiedSteps]);
|
||
setFullArrayOfPipelinesSteps([...oldFullData, ...filteredItems]);
|
||
} else {
|
||
// Если нет данных, отключаем дальнейшие запросы
|
||
isReadyGetPipelineStep = false;
|
||
}
|
||
}).catch(error => {
|
||
console.error("Ошибка при получении шагов:", error);
|
||
isReadyGetPipelineStep = false;
|
||
});
|
||
}
|
||
}, [selectedPipeline, pageOfPipelinesSteps]);
|
||
useEffect(() => {
|
||
if (isReadyGetUsers) {
|
||
getUsers({
|
||
page: pageOfUsers,
|
||
size: SIZE,
|
||
}).then(([response]) => {
|
||
if (response && response.items !== null) {
|
||
const minifiedUsers: MinifiedData[] = [];
|
||
|
||
response.items.forEach((step) => {
|
||
minifiedUsers.push({
|
||
id: step.bitrixUserID.toString(),
|
||
title: step.name || "Нет имени",
|
||
});
|
||
});
|
||
setArrayOfUsers((prevItems) => [...prevItems, ...minifiedUsers]);
|
||
} else {
|
||
isReadyGetUsers = false
|
||
}
|
||
});
|
||
}
|
||
}, [pageOfUsers]);
|
||
// useEffect(() => {
|
||
// if (isReadyGetTags) {
|
||
// getTags({
|
||
// page: pageOfTags,
|
||
// size: SIZE,
|
||
// }).then(([response]) => {
|
||
// if (response && response.items !== null) {
|
||
// const minifiedTags: MinifiedData[] = [];
|
||
|
||
// response.items.forEach((step) => {
|
||
// minifiedTags.push({
|
||
// id: step.BitrixID.toString(),
|
||
// title: step.Name,
|
||
// entity:
|
||
// step.Entity === "leads"
|
||
// ? "Lead"
|
||
// : step.Entity === "contacts"
|
||
// ? "Contact"
|
||
// : step.Entity === "companies"
|
||
// ? "Company"
|
||
// : "Customer",
|
||
// });
|
||
// });
|
||
// setArrayOfTags((prevItems) => [...prevItems, ...minifiedTags]);
|
||
// } else {
|
||
// isReadyGetTags = false
|
||
// }
|
||
// });
|
||
// }
|
||
// }, [pageOfTags]);
|
||
useEffect(() => {
|
||
if (isReadyGetFields) {
|
||
getFields({
|
||
page: pageOfFields,
|
||
size: 1000,
|
||
}).then(([response]) => {
|
||
if (response && response.items !== null) {
|
||
const minifiedTags: MinifiedData[] = [];
|
||
|
||
console.log("fields: ")
|
||
console.log(response.items)
|
||
|
||
const entityMap = {
|
||
'CRM_LEAD': 'lead',
|
||
'CRM_DEAL': 'deal',
|
||
'CRM_COMPANY': 'company',
|
||
'CRM_CONTACT': 'contact'
|
||
};
|
||
|
||
response.items.forEach((field) => {
|
||
console.log("поле: ")
|
||
console.log(field)
|
||
|
||
const entity = entityMap[field.entityID];
|
||
|
||
if (entity) {
|
||
minifiedTags.push({
|
||
id: field.bitrixID.toString(),
|
||
title: field.editFromLabel,
|
||
entity: entity,
|
||
});
|
||
}
|
||
});
|
||
|
||
setArrayOfFields((prevItems) => [...prevItems, ...minifiedTags]);
|
||
}
|
||
});
|
||
} else {
|
||
isReadyGetFields = false
|
||
}
|
||
}, [pageOfFields]);
|
||
useEffect(() => () => {
|
||
isReadyGetPipeline = true;
|
||
isReadyGetPipelineStep = true;
|
||
isReadyGetUsers = true;
|
||
isReadyGetTags = true;
|
||
isReadyGetFields = true;
|
||
}, [])
|
||
|
||
return {
|
||
isLoadingPage,
|
||
firstRules,
|
||
accountInfo,
|
||
arrayOfPipelines,
|
||
arrayOfPipelinesSteps,
|
||
arrayOfUsers,
|
||
arrayOfTags,
|
||
arrayOfFields,
|
||
selectedPipeline,
|
||
setSelectedPipeline: selectedPipelineHC,
|
||
selectedCurrentFields,
|
||
selectedPipelineStep,
|
||
setSelectedPipelineStep,
|
||
selectedDealUser,
|
||
setSelectedDealPerformer,
|
||
questionsBackend,
|
||
selectedTags,
|
||
setSelectedTags,
|
||
selectedQuestions,
|
||
setSelectedQuestions,
|
||
setPageOfPipelines: () => setPageOfPipelines(old => old + 1),
|
||
setPageOfPipelinesSteps: () => setPageOfPipelinesSteps(old => old + 1),
|
||
setPageOfUsers: () => setPageOfUsers(old => old + 1),
|
||
setPageOfTags: () => setPageOfTags(old => old + 1),
|
||
setPageOfFields: () => setPageOfFields(old => old + 1),
|
||
setSelectedCurrentFields,
|
||
leadFlag,
|
||
leadFlagHC,
|
||
fullArrayOfPipelinesSteps
|
||
};
|
||
};
|
||
|
||
import { makeRequest } from "@frontend/kitui";
|
||
const API_URL = `${process.env.REACT_APP_DOMAIN}/squiz/bitrix`;
|
||
|
||
export const resetBitrixTagsFields = async () => {
|
||
let success = true
|
||
//Fields
|
||
try {
|
||
await makeRequest({
|
||
method: "PATCH",
|
||
url: `${API_URL}/fields`,
|
||
});
|
||
} catch (nativeError) {
|
||
success = false
|
||
}
|
||
//Tags
|
||
try {
|
||
await makeRequest({
|
||
method: "PATCH",
|
||
url: `${API_URL}/tags`,
|
||
});
|
||
} catch (nativeError) {
|
||
success = false
|
||
}
|
||
if (success) {
|
||
enqueueSnackbar("Данные обновятся через 5-30 минут")
|
||
} else {
|
||
enqueueSnackbar("Не удалось обновить данные")
|
||
}
|
||
} |