bitrix
This commit is contained in:
parent
e734e8b28b
commit
4997179b75
@ -1,3 +1,4 @@
|
|||||||
|
1.0.15 _ 2025-12-03 _ Merge branch 'pin' into staging
|
||||||
1.0.14 _ 2025-10-20 _ логика overtime для публички
|
1.0.14 _ 2025-10-20 _ логика overtime для публички
|
||||||
1.0.13 _ 2025-10-18 _ Визуал utm + логика
|
1.0.13 _ 2025-10-18 _ Визуал utm + логика
|
||||||
1.0.12 _ 2025-10-12 _ ютм с дизайном и беком, но без логики
|
1.0.12 _ 2025-10-12 _ ютм с дизайном и беком, но без логики
|
||||||
|
|||||||
@ -16,13 +16,10 @@ const API_URL = `${process.env.REACT_APP_DOMAIN}/squiz/bitrix`;
|
|||||||
export type AccountResponse = {
|
export type AccountResponse = {
|
||||||
id: number;
|
id: number;
|
||||||
accountID: string;
|
accountID: string;
|
||||||
amoID: number;
|
bitrixID: number;
|
||||||
name: string;
|
|
||||||
deleted: boolean;
|
deleted: boolean;
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
subdomain: string;
|
subdomain: string;
|
||||||
country: string;
|
|
||||||
driveURL: string;
|
|
||||||
stale: boolean;
|
stale: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -56,10 +53,13 @@ export function useBitrixAccount() {
|
|||||||
|
|
||||||
export const connectBitrix = async (): Promise<[string | null, string?]> => {
|
export const connectBitrix = async (): Promise<[string | null, string?]> => {
|
||||||
try {
|
try {
|
||||||
const response = await makeRequest<void, { link: string }>({
|
const response = await makeRequest<{client_bitrix_url: string}, { link: string }>({
|
||||||
method: "POST",
|
method: "POST",
|
||||||
url: `${API_URL}/account`,
|
url: `${API_URL}/account`,
|
||||||
useToken: true,
|
useToken: true,
|
||||||
|
body: {
|
||||||
|
client_bitrix_url: 'penadigitaltech.bitrix24.ru'
|
||||||
|
},
|
||||||
withCredentials: true,
|
withCredentials: true,
|
||||||
});
|
});
|
||||||
return [response.link];
|
return [response.link];
|
||||||
@ -125,16 +125,18 @@ export const getTags = async ({ page, size }: PaginationRequest): Promise<[TagsR
|
|||||||
|
|
||||||
export type User = {
|
export type User = {
|
||||||
id: number;
|
id: number;
|
||||||
amoID: number;
|
accountID: string;
|
||||||
|
bitrixUserID: string;
|
||||||
name: string;
|
name: string;
|
||||||
|
lastName: string;
|
||||||
|
secondName: string;
|
||||||
|
title: string;
|
||||||
email: string;
|
email: string;
|
||||||
role: number;
|
uf_department: [ number ];
|
||||||
group: number;
|
|
||||||
deleted: boolean;
|
deleted: boolean;
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
amoUserID: number;
|
workPosition: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type UsersResponse = {
|
export type UsersResponse = {
|
||||||
count: number;
|
count: number;
|
||||||
items: User[];
|
items: User[];
|
||||||
@ -157,13 +159,16 @@ export const getUsers = async ({ page, size }: PaginationRequest): Promise<[User
|
|||||||
|
|
||||||
export type Step = {
|
export type Step = {
|
||||||
ID: number;
|
ID: number;
|
||||||
AmoID: number;
|
accountID: string;
|
||||||
PipelineID: number;
|
bitrixID: string;
|
||||||
AccountID: number;
|
entityID: string;
|
||||||
Name: string;
|
statusID: string;
|
||||||
Color: string;
|
name: string;
|
||||||
Deleted: boolean;
|
nameInit: string;
|
||||||
CreatedAt: number;
|
color: string;
|
||||||
|
pipelineID: number;
|
||||||
|
deleted: boolean;
|
||||||
|
createdAt: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type StepsResponse = {
|
export type StepsResponse = {
|
||||||
@ -192,12 +197,12 @@ export const getSteps = async ({
|
|||||||
|
|
||||||
export type Pipeline = {
|
export type Pipeline = {
|
||||||
ID: number;
|
ID: number;
|
||||||
AmoID: number;
|
bitrixID: number;
|
||||||
AccountID: number;
|
accountID: number;
|
||||||
Name: string;
|
name: string;
|
||||||
IsArchive: boolean;
|
entityTypeId: boolean;
|
||||||
Deleted: boolean;
|
deleted: boolean;
|
||||||
CreatedAt: number;
|
createdAt: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type PipelinesResponse = {
|
export type PipelinesResponse = {
|
||||||
@ -310,15 +315,16 @@ export type CustomField = {
|
|||||||
};
|
};
|
||||||
export type Field = {
|
export type Field = {
|
||||||
ID: number;
|
ID: number;
|
||||||
AmoID: number;
|
accountID: string;
|
||||||
Code: string;
|
bitrixID: string;
|
||||||
AccountID: number;
|
entityID: string;
|
||||||
Name: string;
|
fieldName: string;
|
||||||
Entity: string;
|
editFromLabel: string;
|
||||||
Type: string;
|
fieldType: string;
|
||||||
Deleted: boolean;
|
deleted: boolean;
|
||||||
CreatedAt: number;
|
createdAt: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type CustomFieldsResponse = {
|
export type CustomFieldsResponse = {
|
||||||
count: number;
|
count: number;
|
||||||
items: CustomField[];
|
items: CustomField[];
|
||||||
|
|||||||
@ -24,6 +24,8 @@ export const CustomRadioGroup: FC<CustomRadioGroupProps> = ({
|
|||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
||||||
|
|
||||||
|
console.log("CustomRadioGroup")
|
||||||
|
console.log(items)
|
||||||
const currentItem =
|
const currentItem =
|
||||||
(selectedItemId !== null && selectedItemId.length > 0) ?
|
(selectedItemId !== null && selectedItemId.length > 0) ?
|
||||||
items.find((item) => item.id === selectedItemId) || null
|
items.find((item) => item.id === selectedItemId) || null
|
||||||
|
|||||||
@ -26,6 +26,7 @@ export const CustomSelect: FC<CustomSelectProps> = ({ items, selectedItemId, set
|
|||||||
|
|
||||||
const currentItem = useMemo(() => items.find((item) => item.id === selectedItemId) || null, [selectedItemId, items]);
|
const currentItem = useMemo(() => items.find((item) => item.id === selectedItemId) || null, [selectedItemId, items]);
|
||||||
|
|
||||||
|
|
||||||
const menuItems = useMemo(() => {
|
const menuItems = useMemo(() => {
|
||||||
if (items.length !== 0) {
|
if (items.length !== 0) {
|
||||||
return items.map((item) => (
|
return items.map((item) => (
|
||||||
|
|||||||
@ -113,21 +113,23 @@ export const useAmoIntegration = ({ isModalOpen, isTryRemoveAccount, quizID, que
|
|||||||
) {
|
) {
|
||||||
const gottenList = settingsResponse.FieldsRule[key as QuestionKeys];
|
const gottenList = settingsResponse.FieldsRule[key as QuestionKeys];
|
||||||
|
|
||||||
if (gottenList !== null) {
|
console.log("gottenList-----")
|
||||||
Object.keys(gottenList.QuestionID).forEach((qId) => {
|
console.log(gottenList)
|
||||||
const q = questions.find(e => e.backendId === Number(qId)) || {}
|
// 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] = []
|
// if (gottenQuestions[key as QuestionKeys] === undefined) gottenQuestions[key as QuestionKeys] = []
|
||||||
|
|
||||||
gottenQuestions[key as QuestionKeys].push({
|
// gottenQuestions[key as QuestionKeys].push({
|
||||||
id: qId,
|
// id: qId,
|
||||||
title: q.title,
|
// title: q.title,
|
||||||
entity: key,
|
// entity: key,
|
||||||
|
|
||||||
})
|
// })
|
||||||
})
|
// })
|
||||||
|
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (key === "Contact") {
|
if (key === "Contact") {
|
||||||
const MAP = settingsResponse.FieldsRule[key as QuestionKeys].ContactRuleMap
|
const MAP = settingsResponse.FieldsRule[key as QuestionKeys].ContactRuleMap
|
||||||
|
|||||||
@ -4,13 +4,13 @@ import { FC } from "react";
|
|||||||
import { AccountResponse } from "@/api/bitrixIntegration";
|
import { AccountResponse } from "@/api/bitrixIntegration";
|
||||||
import AccountSetting from "@icons/AccountSetting";
|
import AccountSetting from "@icons/AccountSetting";
|
||||||
|
|
||||||
type AmoAccountInfoProps = {
|
type BitrixAccountInfoProps = {
|
||||||
handleNextStep: () => void;
|
handleNextStep: () => void;
|
||||||
accountInfo: AccountResponse | null;
|
accountInfo: AccountResponse | null;
|
||||||
toChangeAccount: () => void;
|
toChangeAccount: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const AccountInfo: FC<AmoAccountInfoProps> = ({ handleNextStep, accountInfo, toChangeAccount }) => {
|
export const AccountInfo: FC<BitrixAccountInfoProps> = ({ handleNextStep, accountInfo, toChangeAccount }) => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
||||||
|
|
||||||
@ -119,11 +119,9 @@ export const AccountInfo: FC<AmoAccountInfoProps> = ({ handleNextStep, accountIn
|
|||||||
>
|
>
|
||||||
1 шаг
|
1 шаг
|
||||||
</Typography>
|
</Typography>
|
||||||
{infoItem("Amo ID", accountInfo?.amoID)}
|
{infoItem("Bitrix ID", accountInfo?.bitrixID)}
|
||||||
{infoItem("Имя аккаунта", accountInfo?.name)}
|
{/* {infoItemLink("ЛК в bitrix", `https://${accountInfo?.subdomain}/dashboard/`)}
|
||||||
{infoItemLink("ЛК в amo", `https://${accountInfo?.subdomain}/dashboard/`)}
|
{infoItemLink("Профиль пользователя в bitrix", `https://${accountInfo?.subdomain}/settings/users/`)} */}
|
||||||
{infoItemLink("Профиль пользователя в amo", `https://${accountInfo?.subdomain}/settings/users/`)}
|
|
||||||
{infoItem("Страна пользователя", accountInfo?.country)}
|
|
||||||
</Box>
|
</Box>
|
||||||
<Box>
|
<Box>
|
||||||
|
|
||||||
|
|||||||
@ -22,7 +22,7 @@ type IntegrationStep1Props = {
|
|||||||
// password: string().required("Поле обязательно").min(8, "Минимум 8 символов"),
|
// password: string().required("Поле обязательно").min(8, "Минимум 8 символов"),
|
||||||
// });
|
// });
|
||||||
|
|
||||||
export const AmoLogin: FC<IntegrationStep1Props> = ({ handleNextStep }) => {
|
export const BitrixLogin: FC<IntegrationStep1Props> = ({ handleNextStep }) => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
||||||
|
|
||||||
@ -1,5 +1,5 @@
|
|||||||
import { connectBitrix } from "@/api/bitrixIntegration";
|
import { connectBitrix } from "@/api/bitrixIntegration";
|
||||||
import { setTryShowAmoTokenExpiredDialog } from "@/stores/uiTools/actions";
|
import { setTryShowBitrixTokenExpiredDialog } from "@/stores/uiTools/actions";
|
||||||
import { useUiTools } from "@/stores/uiTools/store";
|
import { useUiTools } from "@/stores/uiTools/store";
|
||||||
import CustomCheckbox from "@/ui_kit/CustomCheckbox";
|
import CustomCheckbox from "@/ui_kit/CustomCheckbox";
|
||||||
import { Box, Button, Dialog, Typography, useTheme } from "@mui/material";
|
import { Box, Button, Dialog, Typography, useTheme } from "@mui/material";
|
||||||
@ -9,17 +9,17 @@ import { useLocation } from "react-router-dom";
|
|||||||
const HIDE_DIALOG_EXPIRATION_PERIOD = 24 * 60 * 60 * 1000;
|
const HIDE_DIALOG_EXPIRATION_PERIOD = 24 * 60 * 60 * 1000;
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
isAmoTokenExpired: boolean;
|
isBitrixTokenExpired: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function AmoTokenExpiredDialog({ isAmoTokenExpired }: Props) {
|
export default function BitrixTokenExpiredDialog({ isBitrixTokenExpired }: Props) {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const tryShowAmoTokenExpiredDialog = useUiTools((state) => state.tryShowAmoTokenExpiredDialog);
|
const tryShowBitrixTokenExpiredDialog = useUiTools((state) => state.tryShowBitrixTokenExpiredDialog);
|
||||||
const [isHideDialogForADayChecked, setIsHideDialogForADayChecked] = useState<boolean>(false);
|
const [isHideDialogForADayChecked, setIsHideDialogForADayChecked] = useState<boolean>(false);
|
||||||
// const { hash, pathname, search } = useLocation();
|
// const { hash, pathname, search } = useLocation();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
|
||||||
const onAmoClick = async () => {
|
const onBitrixClick = async () => {
|
||||||
const [url, error] = await connectBitrix();
|
const [url, error] = await connectBitrix();
|
||||||
if (url && !error) {
|
if (url && !error) {
|
||||||
window.open(url, "_blank");
|
window.open(url, "_blank");
|
||||||
@ -29,19 +29,19 @@ export default function AmoTokenExpiredDialog({ isAmoTokenExpired }: Props) {
|
|||||||
function handleDialogClose() {
|
function handleDialogClose() {
|
||||||
if (isHideDialogForADayChecked) {
|
if (isHideDialogForADayChecked) {
|
||||||
const expirationDate = Date.now() + HIDE_DIALOG_EXPIRATION_PERIOD;
|
const expirationDate = Date.now() + HIDE_DIALOG_EXPIRATION_PERIOD;
|
||||||
localStorage.setItem("hideAmoTokenExpiredDialogExpirationTime", expirationDate.toString());
|
localStorage.setItem("hideBitrixTokenExpiredDialogExpirationTime", expirationDate.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
setTryShowAmoTokenExpiredDialog(false);
|
setTryShowBitrixTokenExpiredDialog(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setTryShowAmoTokenExpiredDialog(true);
|
setTryShowBitrixTokenExpiredDialog(true);
|
||||||
}, [location]);
|
}, [location]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
open={isAmoTokenExpired && tryShowAmoTokenExpiredDialog && location.pathname !== "/"}
|
open={isBitrixTokenExpired && tryShowBitrixTokenExpiredDialog && location.pathname !== "/"}
|
||||||
onClose={handleDialogClose}
|
onClose={handleDialogClose}
|
||||||
PaperProps={{
|
PaperProps={{
|
||||||
sx: {
|
sx: {
|
||||||
@ -96,7 +96,7 @@ export default function AmoTokenExpiredDialog({ isAmoTokenExpired }: Props) {
|
|||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
variant="contained"
|
variant="contained"
|
||||||
onClick={onAmoClick}
|
onClick={onBitrixClick}
|
||||||
sx={{
|
sx={{
|
||||||
flex: "1 0 0",
|
flex: "1 0 0",
|
||||||
}}
|
}}
|
||||||
@ -17,7 +17,7 @@ type Props = {
|
|||||||
title: string;
|
title: string;
|
||||||
desc: string;
|
desc: string;
|
||||||
toSettings: () => void;
|
toSettings: () => void;
|
||||||
}
|
};
|
||||||
onScrollUsers: () => void;
|
onScrollUsers: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -36,39 +36,37 @@ export const DealPerformers: FC<Props> = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
alignItems: "center",
|
|
||||||
height: "100%",
|
|
||||||
overflow: "auto",
|
|
||||||
flexGrow: 1,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Box sx={{ width: "100%", zIndex: 3 }}>
|
|
||||||
<ModalTitle
|
|
||||||
{...titleProps}
|
|
||||||
/>
|
|
||||||
<CustomSelect
|
|
||||||
items={users}
|
|
||||||
selectedItemId={selectedDealUser}
|
|
||||||
setSelectedItem={setSelectedDealPerformer}
|
|
||||||
handleScroll={onScrollUsers}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
marginTop: "auto",
|
display: "flex",
|
||||||
alignSelf: "end",
|
flexDirection: "column",
|
||||||
|
alignItems: "center",
|
||||||
|
height: "100%",
|
||||||
|
overflow: "auto",
|
||||||
|
flexGrow: 1,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<StepButtonsBlock
|
<Box sx={{ width: "100%", zIndex: 3 }}>
|
||||||
onLargeBtnClick={handleNextStep}
|
<ModalTitle {...titleProps} />
|
||||||
onSmallBtnClick={handlePrevStep}
|
<CustomSelect
|
||||||
/>
|
items={users}
|
||||||
|
selectedItemId={selectedDealUser}
|
||||||
|
setSelectedItem={setSelectedDealPerformer}
|
||||||
|
handleScroll={onScrollUsers}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
marginTop: "auto",
|
||||||
|
alignSelf: "end",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<StepButtonsBlock
|
||||||
|
onLargeBtnClick={handleNextStep}
|
||||||
|
onSmallBtnClick={handlePrevStep}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -15,13 +15,14 @@ type Props = {
|
|||||||
setSelectedDealPerformer: (value: string | null) => void;
|
setSelectedDealPerformer: (value: string | null) => void;
|
||||||
selectedStep: string | null;
|
selectedStep: string | null;
|
||||||
setSelectedStep: (value: string | null) => void;
|
setSelectedStep: (value: string | null) => void;
|
||||||
|
leadFlag: boolean;
|
||||||
|
|
||||||
titleProps: {
|
titleProps: {
|
||||||
step: number;
|
step: number;
|
||||||
title: string;
|
title: string;
|
||||||
desc: string;
|
desc: string;
|
||||||
toSettings: () => void;
|
toSettings: () => void;
|
||||||
}
|
};
|
||||||
onScroll: () => void;
|
onScroll: () => void;
|
||||||
onScrollUsers: () => void;
|
onScrollUsers: () => void;
|
||||||
};
|
};
|
||||||
@ -36,17 +37,18 @@ export const PipelineSteps: FC<Props> = ({
|
|||||||
setSelectedStep,
|
setSelectedStep,
|
||||||
onScroll,
|
onScroll,
|
||||||
onScrollUsers,
|
onScrollUsers,
|
||||||
|
leadFlag,
|
||||||
|
|
||||||
handlePrevStep,
|
handlePrevStep,
|
||||||
handleNextStep,
|
handleNextStep,
|
||||||
|
|
||||||
titleProps
|
titleProps,
|
||||||
}) => {
|
}) => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
||||||
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
||||||
|
console.log("leadFlag")
|
||||||
|
console.log(leadFlag)
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Box
|
<Box
|
||||||
@ -65,11 +67,10 @@ export const PipelineSteps: FC<Props> = ({
|
|||||||
overflow: "auto",
|
overflow: "auto",
|
||||||
zIndex: 3,
|
zIndex: 3,
|
||||||
width: "100%",
|
width: "100%",
|
||||||
}}>
|
}}
|
||||||
|
>
|
||||||
<Box sx={{ width: "100%", zIndex: 3 }}>
|
<Box sx={{ width: "100%", zIndex: 3 }}>
|
||||||
<ModalTitle
|
<ModalTitle {...titleProps} />
|
||||||
{...titleProps}
|
|
||||||
/>
|
|
||||||
<CustomSelect
|
<CustomSelect
|
||||||
items={users}
|
items={users}
|
||||||
selectedItemId={selectedDealUser}
|
selectedItemId={selectedDealUser}
|
||||||
@ -85,7 +86,7 @@ export const PipelineSteps: FC<Props> = ({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<CustomRadioGroup
|
<CustomRadioGroup
|
||||||
items={steps}
|
items={leadFlag ? steps : steps.filter(step => step.entity !== "STATUS")}
|
||||||
selectedItemId={selectedStep}
|
selectedItemId={selectedStep}
|
||||||
setSelectedItem={setSelectedStep}
|
setSelectedItem={setSelectedStep}
|
||||||
handleScroll={onScroll}
|
handleScroll={onScroll}
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import { diffArr } from "..";
|
|||||||
import { DataConstrictor } from "../Components/DataConstrictor";
|
import { DataConstrictor } from "../Components/DataConstrictor";
|
||||||
import { ModalTitle } from "../ModalTitle";
|
import { ModalTitle } from "../ModalTitle";
|
||||||
import { StepButtonsBlock } from "../StepButtonsBlock";
|
import { StepButtonsBlock } from "../StepButtonsBlock";
|
||||||
import { resetBitrixTagsFields } from "../useAmoIntegration";
|
import { resetBitrixTagsFields } from "../useBitrixIntegration";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
selectedCurrentFields: MinifiedData[] | [];
|
selectedCurrentFields: MinifiedData[] | [];
|
||||||
@ -39,11 +39,11 @@ const FCTranslate = {
|
|||||||
"text": "номер",
|
"text": "номер",
|
||||||
"address": "адрес",
|
"address": "адрес",
|
||||||
}
|
}
|
||||||
export const AmoQuestions: FC<Props> = ({
|
export const BitrixQuestions: FC<Props> = ({
|
||||||
selectedCurrentFields,
|
selectedCurrentFields,
|
||||||
questionsItems,
|
questionsItems,
|
||||||
fieldsItems,
|
fieldsItems,
|
||||||
selectedQuestions = [],
|
selectedQuestions = {},
|
||||||
handleAddQuestion,
|
handleAddQuestion,
|
||||||
handlePrevStep,
|
handlePrevStep,
|
||||||
handleNextStep,
|
handleNextStep,
|
||||||
@ -53,17 +53,54 @@ export const AmoQuestions: FC<Props> = ({
|
|||||||
onScroll,
|
onScroll,
|
||||||
titleProps,
|
titleProps,
|
||||||
}) => {
|
}) => {
|
||||||
if (!selectedQuestions.hasOwnProperty('Contact')) {
|
console.log("---------------------------------------------------------------------")
|
||||||
selectedQuestions.Contact = []
|
console.log(
|
||||||
|
{
|
||||||
|
selectedCurrentFields,
|
||||||
|
questionsItems,
|
||||||
|
fieldsItems,
|
||||||
|
selectedQuestions,
|
||||||
|
handleAddQuestion,
|
||||||
|
handlePrevStep,
|
||||||
|
handleNextStep,
|
||||||
|
openDelete,
|
||||||
|
FieldsAllowedFC,
|
||||||
|
setSelectedCurrentFields,
|
||||||
|
onScroll,
|
||||||
|
titleProps,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
// "lead": "Лид",
|
||||||
|
// "company": "Компания",
|
||||||
|
// "contact": "Контакт",
|
||||||
|
// "deal": "Сделка",
|
||||||
|
// "CRM_INVOICE": "Счёт (старый)",
|
||||||
|
// "CRM_SMART_INVOICE": "Cчёт (новый)",
|
||||||
|
// "CRM_QUOTE": "Предложение",
|
||||||
|
// "CRM_REQUISITE": "Реквизит"
|
||||||
|
if (!selectedQuestions.hasOwnProperty('lead')) {
|
||||||
|
selectedQuestions.lead = []
|
||||||
}
|
}
|
||||||
if (!selectedQuestions.hasOwnProperty('Customer')) {
|
if (!selectedQuestions.hasOwnProperty('company')) {
|
||||||
selectedQuestions.Customer = []
|
selectedQuestions.company = []
|
||||||
}
|
}
|
||||||
if (!selectedQuestions.hasOwnProperty('Company')) {
|
if (!selectedQuestions.hasOwnProperty('contact')) {
|
||||||
selectedQuestions.Company = []
|
selectedQuestions.contact = []
|
||||||
}
|
}
|
||||||
if (!selectedQuestions.hasOwnProperty('Lead')) {
|
if (!selectedQuestions.hasOwnProperty('deal')) {
|
||||||
selectedQuestions.Lead = []
|
selectedQuestions.deal = []
|
||||||
|
}
|
||||||
|
if (!selectedQuestions.hasOwnProperty('CRM_INVOICE')) {
|
||||||
|
selectedQuestions.CRM_INVOICE = []
|
||||||
|
}
|
||||||
|
if (!selectedQuestions.hasOwnProperty('CRM_SMART_INVOICE')) {
|
||||||
|
selectedQuestions.CRM_SMART_INVOICE = []
|
||||||
|
}
|
||||||
|
if (!selectedQuestions.hasOwnProperty('CRM_QUOTE')) {
|
||||||
|
selectedQuestions.CRM_QUOTE = []
|
||||||
|
}
|
||||||
|
if (!selectedQuestions.hasOwnProperty('CRM_REQUISITE')) {
|
||||||
|
selectedQuestions.CRM_REQUISITE = []
|
||||||
}
|
}
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
||||||
@ -95,7 +132,7 @@ export const AmoQuestions: FC<Props> = ({
|
|||||||
id: selectedQuestion,
|
id: selectedQuestion,
|
||||||
title: questionsItems.find(e => e.id === selectedQuestion)?.title || FCTranslate[selectedQuestion],
|
title: questionsItems.find(e => e.id === selectedQuestion)?.title || FCTranslate[selectedQuestion],
|
||||||
entity: activeScope,
|
entity: activeScope,
|
||||||
amoId: selectedField,
|
bitrixId: selectedField,
|
||||||
})
|
})
|
||||||
setSelectedCurrentFields(newArray);
|
setSelectedCurrentFields(newArray);
|
||||||
};
|
};
|
||||||
@ -117,10 +154,14 @@ export const AmoQuestions: FC<Props> = ({
|
|||||||
};
|
};
|
||||||
const SCFworld = (() => {
|
const SCFworld = (() => {
|
||||||
const obj = {
|
const obj = {
|
||||||
Lead: [],
|
lead: [],
|
||||||
Company: [],
|
company: [],
|
||||||
Customer: [],
|
contact: [],
|
||||||
Contact: []
|
deal: [],
|
||||||
|
// CRM_INVOICE: [],
|
||||||
|
// CRM_SMART_INVOICE: [],
|
||||||
|
// CRM_QUOTE: [],
|
||||||
|
// CRM_REQUISITE: [],
|
||||||
}
|
}
|
||||||
selectedCurrentFields.forEach((e) => {
|
selectedCurrentFields.forEach((e) => {
|
||||||
if (!obj[e.entity]?.includes(e.id)) {
|
if (!obj[e.entity]?.includes(e.id)) {
|
||||||
@ -216,10 +257,14 @@ export const AmoQuestions: FC<Props> = ({
|
|||||||
items={[...questionsItems, ...FieldsAllowedFC]}
|
items={[...questionsItems, ...FieldsAllowedFC]}
|
||||||
setActiveScope={setActiveScope}
|
setActiveScope={setActiveScope}
|
||||||
selectedQuestions={{
|
selectedQuestions={{
|
||||||
Lead: [...selectedQuestions.Lead, ...SCFworld.Lead],
|
lead: [...selectedQuestions.lead, ...SCFworld.lead],
|
||||||
Company: [...selectedQuestions.Company, ...SCFworld.Company],
|
company: [...selectedQuestions.company, ...SCFworld.company],
|
||||||
Customer: [...selectedQuestions.Customer, ...SCFworld.Customer],
|
contact: [...selectedQuestions.contact, ...SCFworld.contact],
|
||||||
Contact: [...selectedQuestions.Contact, ...SCFworld.Contact]
|
deal: [...selectedQuestions.deal, ...SCFworld.deal],
|
||||||
|
// CRM_INVOICE: [...selectedQuestions.CRM_INVOICE, ...SCFworld.CRM_INVOICE],
|
||||||
|
// CRM_SMART_INVOICE: [...selectedQuestions.CRM_SMART_INVOICE, ...SCFworld.CRM_SMART_INVOICE],
|
||||||
|
// CRM_QUOTE: [...selectedQuestions.CRM_QUOTE, ...SCFworld.CRM_QUOTE],
|
||||||
|
// CRM_REQUISITE: [...selectedQuestions.CRM_REQUISITE, ...SCFworld.CRM_REQUISITE]
|
||||||
}}
|
}}
|
||||||
setIsSelection={setIsSelection}
|
setIsSelection={setIsSelection}
|
||||||
deleteHC={handleDelete}
|
deleteHC={handleDelete}
|
||||||
@ -4,7 +4,7 @@ import { FC, useState } from "react";
|
|||||||
import { MinifiedData, TagKeys } from "../types";
|
import { MinifiedData, TagKeys } from "../types";
|
||||||
import { CurrentFields } from "./CurrentFields";
|
import { CurrentFields } from "./CurrentFields";
|
||||||
import { NewFields } from "./NewFields";
|
import { NewFields } from "./NewFields";
|
||||||
import { QuestionPair } from "./AmoQuestions";
|
import { QuestionPair } from "./BitrixQuestions";
|
||||||
import { diffArr } from "..";
|
import { diffArr } from "..";
|
||||||
|
|
||||||
type ItemsSelectionViewProps = {
|
type ItemsSelectionViewProps = {
|
||||||
|
|||||||
@ -15,12 +15,20 @@ export const ItemForQuestions: FC<ItemProps> = ({ items, title, onAddBtnClick, d
|
|||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
const titleDictionary = {
|
const titleDictionary = {
|
||||||
Company: "Компания",
|
"lead": "Лид",
|
||||||
Lead: "Сделка",
|
"company": "Компания",
|
||||||
Contact: "Контакты",
|
"contact": "Контакт",
|
||||||
Customer: "Покупатели",
|
"deal": "Сделка",
|
||||||
|
// "CRM_INVOICE": "Счёт (старый)",
|
||||||
|
// "CRM_SMART_INVOICE": "Счёт (новый)",
|
||||||
|
// "CRM_QUOTE": "Предложение",
|
||||||
|
// "CRM_REQUISITE": "Реквизит"
|
||||||
|
// Company: "Компания",
|
||||||
|
// Lead: "Сделка",
|
||||||
|
// Contact: "Контакты",
|
||||||
|
// Customer: "Покупатели",
|
||||||
};
|
};
|
||||||
|
console.log("title: " + title)
|
||||||
const translatedTitle = titleDictionary[title];
|
const translatedTitle = titleDictionary[title];
|
||||||
const selectedOptions = data[title];
|
const selectedOptions = data[title];
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -16,7 +16,7 @@ type SettingItemProps = {
|
|||||||
selectedDealUser: string | null;
|
selectedDealUser: string | null;
|
||||||
selectedStage: string | null;
|
selectedStage: string | null;
|
||||||
selectedQuestions: SelectedQuestions;
|
selectedQuestions: SelectedQuestions;
|
||||||
selectedTags: SelectedTags;
|
leadFlag: boolean
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SettingItem: FC<SettingItemProps> = ({
|
export const SettingItem: FC<SettingItemProps> = ({
|
||||||
@ -29,7 +29,7 @@ export const SettingItem: FC<SettingItemProps> = ({
|
|||||||
selectedDealUser,
|
selectedDealUser,
|
||||||
selectedStage,
|
selectedStage,
|
||||||
selectedQuestions,
|
selectedQuestions,
|
||||||
selectedTags,
|
leadFlag
|
||||||
}) => {
|
}) => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
||||||
@ -42,31 +42,7 @@ export const SettingItem: FC<SettingItemProps> = ({
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ResponsiblePerson performer={selectedDealUser} />
|
<ResponsiblePerson performer={selectedDealUser} />
|
||||||
<SelectedParameter parameter={selectedFunnel} />
|
<Box>
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (step === 2) {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<ResponsiblePerson performer={selectedDealUser} />
|
|
||||||
<SelectedParameter parameter={selectedStage} />
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (step === 3) {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<ResponsiblePerson performer={selectedDealUser} />
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (step === 4) {
|
|
||||||
const isFilled = Object.values(selectedTags).some((array) => array.length > 0);
|
|
||||||
const status = isFilled ? "Заполнено" : "Не заполнено";
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Typography
|
<Typography
|
||||||
sx={{
|
sx={{
|
||||||
color: theme.palette.grey2.main,
|
color: theme.palette.grey2.main,
|
||||||
@ -76,7 +52,7 @@ export const SettingItem: FC<SettingItemProps> = ({
|
|||||||
}}
|
}}
|
||||||
display={"inline-block"}
|
display={"inline-block"}
|
||||||
>
|
>
|
||||||
Статус:
|
Выбранный этап сделки
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography
|
<Typography
|
||||||
sx={{
|
sx={{
|
||||||
@ -86,8 +62,33 @@ export const SettingItem: FC<SettingItemProps> = ({
|
|||||||
}}
|
}}
|
||||||
display={"inline"}
|
display={"inline"}
|
||||||
>
|
>
|
||||||
{status}
|
{leadFlag ? "Лид сделки" : "Дил сделки"}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
|
</Box>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (step === 2) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ResponsiblePerson performer={selectedDealUser} />
|
||||||
|
<SelectedParameter parameter={selectedFunnel} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (step === 3) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ResponsiblePerson performer={selectedDealUser} />
|
||||||
|
<SelectedParameter parameter={selectedStage} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (step === 4) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ResponsiblePerson performer={selectedDealUser} />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -130,7 +131,6 @@ export const SettingItem: FC<SettingItemProps> = ({
|
|||||||
selectedDealUser,
|
selectedDealUser,
|
||||||
selectedStage,
|
selectedStage,
|
||||||
selectedQuestions,
|
selectedQuestions,
|
||||||
selectedTags,
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -10,9 +10,9 @@ type AmoSettingsBlockProps = {
|
|||||||
selectedStage: string | null;
|
selectedStage: string | null;
|
||||||
selectedDealUser: string | null;
|
selectedDealUser: string | null;
|
||||||
selectedQuestions: SelectedQuestions;
|
selectedQuestions: SelectedQuestions;
|
||||||
selectedTags: SelectedTags;
|
|
||||||
toBack: () => void
|
toBack: () => void
|
||||||
setStep: (step: number) => void
|
setStep: (step: number) => void
|
||||||
|
leadFlag: boolean
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SettingsBlock: FC<AmoSettingsBlockProps> = ({
|
export const SettingsBlock: FC<AmoSettingsBlockProps> = ({
|
||||||
@ -21,9 +21,10 @@ export const SettingsBlock: FC<AmoSettingsBlockProps> = ({
|
|||||||
selectedDealUser,
|
selectedDealUser,
|
||||||
selectedStage,
|
selectedStage,
|
||||||
selectedQuestions,
|
selectedQuestions,
|
||||||
selectedTags,
|
// selectedTags,
|
||||||
toBack,
|
toBack,
|
||||||
setStep,
|
setStep,
|
||||||
|
leadFlag,
|
||||||
}) => {
|
}) => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
||||||
@ -64,13 +65,13 @@ export const SettingsBlock: FC<AmoSettingsBlockProps> = ({
|
|||||||
{stepTitles &&
|
{stepTitles &&
|
||||||
stepTitles.map((title, index) => (
|
stepTitles.map((title, index) => (
|
||||||
<SettingItem
|
<SettingItem
|
||||||
|
leadFlag={leadFlag}
|
||||||
step={index+1}
|
step={index+1}
|
||||||
title={title}
|
title={title}
|
||||||
selectedDealUser={selectedDealUser}
|
selectedDealUser={selectedDealUser}
|
||||||
selectedFunnel={selectedFunnel}
|
selectedFunnel={selectedFunnel}
|
||||||
selectedStage={selectedStage}
|
selectedStage={selectedStage}
|
||||||
selectedQuestions={selectedQuestions}
|
selectedQuestions={selectedQuestions}
|
||||||
selectedTags={selectedTags}
|
|
||||||
|
|
||||||
setStep={setStep}
|
setStep={setStep}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { useMemo, useState } from "react"
|
import { useMemo, useState } from "react";
|
||||||
import { Dialog, IconButton, Typography, useMediaQuery, useTheme, Box, Skeleton } from "@mui/material";
|
import { Dialog, IconButton, Typography, useMediaQuery, useTheme, Box, Skeleton } from "@mui/material";
|
||||||
import { useQuestions } from "@/stores/questions/hooks";
|
import { useQuestions } from "@/stores/questions/hooks";
|
||||||
import { redirect } from "react-router-dom";
|
import { redirect } from "react-router-dom";
|
||||||
@ -8,28 +8,28 @@ import CloseIcon from "@mui/icons-material/Close";
|
|||||||
|
|
||||||
import { RemoveAccount } from "./RemoveAccount";
|
import { RemoveAccount } from "./RemoveAccount";
|
||||||
import { DeleteTagQuestion } from "./DeleteTagQuestion";
|
import { DeleteTagQuestion } from "./DeleteTagQuestion";
|
||||||
import { AmoLogin } from "./AmoLogin";
|
import { BitrixLogin } from "./BitrixLogin";
|
||||||
import { Pipelines } from "./Pipelines";
|
import { Pipelines } from "./Pipelines";
|
||||||
import { PipelineSteps } from "./PipelineSteps";
|
import { PipelineSteps } from "./PipelineSteps";
|
||||||
import { DealPerformers } from "./DealPerformers";
|
import { DealPerformers } from "./DealPerformers";
|
||||||
import { AmoTags } from "./Tags/AmoTags";
|
import { СhoosePerson } from "./СhoosePerson";
|
||||||
import { AmoQuestions } from "./Questions/AmoQuestions";
|
import { BitrixQuestions } from "./Questions/BitrixQuestions";
|
||||||
import { ModalTitle } from "./ModalTitle";
|
import { ModalTitle } from "./ModalTitle";
|
||||||
import { SettingsBlock } from "./SettingsBlock/SettingsBlock";
|
import { SettingsBlock } from "./SettingsBlock/SettingsBlock";
|
||||||
import { AccountInfo } from "./AccountInfo";
|
import { AccountInfo } from "./AccountInfo";
|
||||||
import { MinifiedData, QuestionKeys, TagKeys, TagQuestionHC } from "./types";
|
import { MinifiedData, QuestionKeys, TagKeys, TagQuestionHC } from "./types";
|
||||||
import { Quiz } from "@/model/quiz/quiz";
|
import { Quiz } from "@/model/quiz/quiz";
|
||||||
import { AccountResponse, setIntegrationRules, updateIntegrationRules } from "@/api/integration";
|
import { AccountResponse, setIntegrationRules, updateIntegrationRules } from "@/api/bitrixIntegration";
|
||||||
import { AnyTypedQuizQuestion } from "@frontend/squzanswerer";
|
import { AnyTypedQuizQuestion } from "@frontend/squzanswerer";
|
||||||
import { UntypedQuizQuestion } from "@/model/questionTypes/shared";
|
import { UntypedQuizQuestion } from "@/model/questionTypes/shared";
|
||||||
|
|
||||||
const FCTranslate = {
|
const FCTranslate = {
|
||||||
"name": "имя",
|
name: "имя",
|
||||||
"email": "почта",
|
email: "почта",
|
||||||
"phone": "телефон",
|
phone: "телефон",
|
||||||
"text": "номер",
|
text: "номер",
|
||||||
"address": "адрес",
|
address: "адрес",
|
||||||
}
|
};
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
quiz: Quiz;
|
quiz: Quiz;
|
||||||
@ -59,6 +59,8 @@ interface Props {
|
|||||||
setPageOfFields: () => void;
|
setPageOfFields: () => void;
|
||||||
setSelectedCurrentFields: any;
|
setSelectedCurrentFields: any;
|
||||||
handleCloseModal: any;
|
handleCloseModal: any;
|
||||||
|
leadFlag: boolean;
|
||||||
|
leadFlagHC: (s: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SwitchPages = ({
|
export const SwitchPages = ({
|
||||||
@ -89,16 +91,20 @@ export const SwitchPages = ({
|
|||||||
setPageOfFields,
|
setPageOfFields,
|
||||||
setSelectedCurrentFields,
|
setSelectedCurrentFields,
|
||||||
handleCloseModal,
|
handleCloseModal,
|
||||||
|
leadFlag,
|
||||||
|
leadFlagHC,
|
||||||
|
fullArrayOfPipelinesSteps,
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
const [step, setStep] = useState(0)
|
const [step, setStep] = useState(0);
|
||||||
const [specialPage, setSpecialPage] = useState<"deleteCell" | "removeAccount" | "settingsBlock" | "accountInfo" | "amoLogin" | "">(accountInfo ? "accountInfo" : "amoLogin")
|
const [specialPage, setSpecialPage] = useState<
|
||||||
|
"deleteCell" | "removeAccount" | "settingsBlock" | "accountInfo" | "bitrixLogin" | ""
|
||||||
|
>(accountInfo ? "accountInfo" : "bitrixLogin");
|
||||||
const [openDelete, setOpenDelete] = useState<TagQuestionHC | null>(null);
|
const [openDelete, setOpenDelete] = useState<TagQuestionHC | null>(null);
|
||||||
|
|
||||||
|
|
||||||
const startDeleteTagQuestion = (itemForDelete) => {
|
const startDeleteTagQuestion = (itemForDelete) => {
|
||||||
setOpenDelete(itemForDelete)
|
setOpenDelete(itemForDelete);
|
||||||
setSpecialPage("deleteCell")
|
setSpecialPage("deleteCell");
|
||||||
}
|
};
|
||||||
|
|
||||||
const minifiedQuestions = useMemo(
|
const minifiedQuestions = useMemo(
|
||||||
() =>
|
() =>
|
||||||
@ -110,47 +116,50 @@ export const SwitchPages = ({
|
|||||||
})),
|
})),
|
||||||
[questions]
|
[questions]
|
||||||
);
|
);
|
||||||
const FieldsAllowedFC = useMemo(
|
const FieldsAllowedFC = useMemo(() => {
|
||||||
() => {
|
const list: MinifiedData[] = [];
|
||||||
const list: MinifiedData[] = []
|
if (quiz.config.showfc) {
|
||||||
if (quiz.config.showfc) {
|
const fields = quiz.config.formContact.fields;
|
||||||
const fields = quiz.config.formContact.fields
|
for (let key in fields) {
|
||||||
for (let key in fields) {
|
if (fields[key].used)
|
||||||
if (fields[key].used) list.push({
|
list.push({
|
||||||
id: key,
|
id: key,
|
||||||
title: FCTranslate[key],
|
title: FCTranslate[key],
|
||||||
entity: "Contact",
|
entity: "Contact",
|
||||||
})
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return list;
|
}
|
||||||
},
|
return list;
|
||||||
[quiz]
|
}, [quiz]);
|
||||||
);
|
|
||||||
const handleAddTagQuestion = (scope: QuestionKeys | TagKeys, id: string, type: "question" | "tag") => {
|
const handleAddTagQuestion = (scope: QuestionKeys | TagKeys, id: string, type: "question" | "tag") => {
|
||||||
if (!scope || !id) return;
|
if (!scope || !id) return;
|
||||||
|
|
||||||
if (type === "tag") {
|
if (type === "tag") {
|
||||||
setSelectedTags((prevState) => {
|
setSelectedTags((prevState) => {
|
||||||
return({
|
return {
|
||||||
...prevState,
|
...prevState,
|
||||||
[scope]: [...prevState[scope as TagKeys], id],
|
[scope]: [...prevState[scope as TagKeys], id],
|
||||||
})});
|
};
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type === "question") {
|
if (type === "question") {
|
||||||
const q = questions.find(e => e.backendId === Number(id))
|
const q = questions.find((e) => e.backendId === Number(id));
|
||||||
setSelectedQuestions((prevState) => {
|
setSelectedQuestions((prevState) => {
|
||||||
return ({
|
return {
|
||||||
...prevState,
|
...prevState,
|
||||||
[scope]: [...prevState[scope as QuestionKeys], {
|
[scope]: [
|
||||||
id,
|
...prevState[scope as QuestionKeys],
|
||||||
title: q?.title || "вопрос",
|
{
|
||||||
entity: scope,
|
id,
|
||||||
}],
|
title: q?.title || "вопрос",
|
||||||
})});
|
entity: scope,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
const handleDeleteTagQuestion = () => {
|
const handleDeleteTagQuestion = () => {
|
||||||
if (openDelete === null || !openDelete.scope || !openDelete.id || !openDelete.type) return;
|
if (openDelete === null || !openDelete.scope || !openDelete.id || !openDelete.type) return;
|
||||||
@ -166,15 +175,16 @@ export const SwitchPages = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (openDelete.type === "question") {
|
if (openDelete.type === "question") {
|
||||||
let newArray = selectedQuestions
|
let newArray = selectedQuestions;
|
||||||
newArray[openDelete.scope as QuestionKeys] = newArray[openDelete.scope as QuestionKeys].filter(e => e.id !== openDelete.id)
|
newArray[openDelete.scope as QuestionKeys] = newArray[openDelete.scope as QuestionKeys].filter(
|
||||||
|
(e) => e.id !== openDelete.id
|
||||||
|
);
|
||||||
setSelectedQuestions(newArray);
|
setSelectedQuestions(newArray);
|
||||||
setSelectedCurrentFields(selectedCurrentFields.filter(e => e.id !== openDelete.id));
|
setSelectedCurrentFields(selectedCurrentFields.filter((e) => e.id !== openDelete.id));
|
||||||
|
|
||||||
}
|
}
|
||||||
setOpenDelete(null);
|
setOpenDelete(null);
|
||||||
closeSpecialPage();
|
closeSpecialPage();
|
||||||
}
|
};
|
||||||
|
|
||||||
const handleNextStep = () => {
|
const handleNextStep = () => {
|
||||||
setStep((prevState) => prevState + 1);
|
setStep((prevState) => prevState + 1);
|
||||||
@ -190,20 +200,39 @@ export const SwitchPages = ({
|
|||||||
const body = {
|
const body = {
|
||||||
PipelineID: Number(selectedPipeline),
|
PipelineID: Number(selectedPipeline),
|
||||||
StepID: Number(selectedPipelineStep),
|
StepID: Number(selectedPipelineStep),
|
||||||
PerformerID: Number(selectedDealUser),
|
PerformerID: selectedDealUser,
|
||||||
|
LeadFlag: leadFlag,
|
||||||
|
|
||||||
|
StageID: "",
|
||||||
|
SourceID: "",
|
||||||
|
StatusID: "",
|
||||||
// FieldsRule: questionsBackend,
|
// FieldsRule: questionsBackend,
|
||||||
TagsToAdd: selectedTags,
|
// TagsToAdd: selectedTags,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const step = fullArrayOfPipelinesSteps.find((step) => step.bitrixID === selectedPipelineStep);
|
||||||
|
console.log("CURRENT step CURRENT step CURRENT step CURRENT step CURRENT step CURRENT step CURRENT step ");
|
||||||
|
console.log(step);
|
||||||
|
console.log(step.entityID);
|
||||||
|
console.log(step.entityID === "STATUS");
|
||||||
|
|
||||||
|
// if (step.entityId === undefined) return
|
||||||
|
if (step.entityID === "SOURCE") body.SourceID = step.statusID;
|
||||||
|
if (step.entityID === "STATUS") body.StatusID = step.statusID;
|
||||||
|
if (step.entityID.startsWith("DEAL_STAGE") && leadFlag) body.StageID = step.statusID;
|
||||||
|
|
||||||
const FieldsRule = {
|
const FieldsRule = {
|
||||||
Company: { QuestionID: {} },
|
lead: { QuestionID: {} },
|
||||||
Lead: { QuestionID: {} },
|
deal: { QuestionID: {} },
|
||||||
Customer: { QuestionID: {} },
|
company: { QuestionID: {} },
|
||||||
Contact: {
|
contact: {
|
||||||
QuestionID: {},
|
QuestionID: {},
|
||||||
ContactRuleMap: {
|
ContactRuleMap: {},
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
// CRM_INVOICE: { QuestionID: {} },
|
||||||
|
// CRM_SMART_INVOICE: { QuestionID: {} },
|
||||||
|
// CRM_QUOTE: { QuestionID: {} },
|
||||||
|
// CRM_REQUISITE: { QuestionID: {} },
|
||||||
};
|
};
|
||||||
|
|
||||||
for (let key in FieldsRule) {
|
for (let key in FieldsRule) {
|
||||||
@ -213,13 +242,12 @@ export const SwitchPages = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
selectedCurrentFields.forEach((data) => {
|
selectedCurrentFields.forEach((data) => {
|
||||||
if (data.entity === "Contact") {
|
if (data.entity === "contact") {
|
||||||
FieldsRule.Contact.ContactRuleMap[data.id] = Number(data.amoId)
|
FieldsRule.contact.ContactRuleMap[data.id] = Number(data.bitrixId);
|
||||||
} else {
|
} else {
|
||||||
FieldsRule[data.entity].QuestionID[data.id] = Number(data.amoId) || 0
|
FieldsRule[data.entity].QuestionID[data.id] = Number(data.bitrixId) || 0;
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
|
|
||||||
for (let key in body.TagsToAdd) {
|
for (let key in body.TagsToAdd) {
|
||||||
body.TagsToAdd[key as TagKeys] = body.TagsToAdd[key as TagKeys].map((id) => Number(id));
|
body.TagsToAdd[key as TagKeys] = body.TagsToAdd[key as TagKeys].map((id) => Number(id));
|
||||||
@ -235,17 +263,33 @@ export const SwitchPages = ({
|
|||||||
handleCloseModal();
|
handleCloseModal();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const closeSpecialPage = () => setSpecialPage("");
|
||||||
const closeSpecialPage = () => setSpecialPage("")
|
|
||||||
|
|
||||||
const steps = [
|
const steps = [
|
||||||
|
{
|
||||||
|
isSettingsAvailable: true,
|
||||||
|
component: (
|
||||||
|
<СhoosePerson
|
||||||
|
leadFlag={leadFlag}
|
||||||
|
leadFlagHC={leadFlagHC}
|
||||||
|
handlePrevStep={() => setSpecialPage("accountInfo")}
|
||||||
|
handleNextStep={handleNextStep}
|
||||||
|
titleProps={{
|
||||||
|
step: step + 2,
|
||||||
|
title: "Выбор этапа взаимодействия",
|
||||||
|
desc: "",
|
||||||
|
toSettings: () => setSpecialPage("settingsBlock"),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
isSettingsAvailable: true,
|
isSettingsAvailable: true,
|
||||||
component: (
|
component: (
|
||||||
<Pipelines
|
<Pipelines
|
||||||
users={arrayOfUsers}
|
users={arrayOfUsers}
|
||||||
pipelines={arrayOfPipelines}
|
pipelines={arrayOfPipelines}
|
||||||
handlePrevStep={() => setSpecialPage("accountInfo")}
|
handlePrevStep={handlePrevStep}
|
||||||
handleNextStep={handleNextStep}
|
handleNextStep={handleNextStep}
|
||||||
selectedDealUser={selectedDealUser}
|
selectedDealUser={selectedDealUser}
|
||||||
setSelectedDealPerformer={setSelectedDealPerformer}
|
setSelectedDealPerformer={setSelectedDealPerformer}
|
||||||
@ -255,7 +299,7 @@ export const SwitchPages = ({
|
|||||||
step: step + 2,
|
step: step + 2,
|
||||||
title: "Выбор воронки",
|
title: "Выбор воронки",
|
||||||
desc: "На этом этапе вы можете выбрать нужную воронку и ответственного за сделку",
|
desc: "На этом этапе вы можете выбрать нужную воронку и ответственного за сделку",
|
||||||
toSettings: () => setSpecialPage("settingsBlock")
|
toSettings: () => setSpecialPage("settingsBlock"),
|
||||||
}}
|
}}
|
||||||
onScroll={setPageOfPipelines}
|
onScroll={setPageOfPipelines}
|
||||||
onScrollUsers={setPageOfUsers}
|
onScrollUsers={setPageOfUsers}
|
||||||
@ -278,10 +322,11 @@ export const SwitchPages = ({
|
|||||||
step: step + 2,
|
step: step + 2,
|
||||||
title: "Выбор этапа воронки",
|
title: "Выбор этапа воронки",
|
||||||
desc: "На этом этапе вы можете выбрать нужный этап и ответственного за сделку",
|
desc: "На этом этапе вы можете выбрать нужный этап и ответственного за сделку",
|
||||||
toSettings: () => setSpecialPage("settingsBlock")
|
toSettings: () => setSpecialPage("settingsBlock"),
|
||||||
}}
|
}}
|
||||||
onScroll={setPageOfPipelinesSteps}
|
onScroll={setPageOfPipelinesSteps}
|
||||||
onScrollUsers={setPageOfUsers}
|
onScrollUsers={setPageOfUsers}
|
||||||
|
leadFlag={leadFlag}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@ -298,36 +343,36 @@ export const SwitchPages = ({
|
|||||||
step: step + 2,
|
step: step + 2,
|
||||||
title: "Сделка",
|
title: "Сделка",
|
||||||
desc: "На этом этапе вы можете выбрать ответственного за сделку",
|
desc: "На этом этапе вы можете выбрать ответственного за сделку",
|
||||||
toSettings: () => setSpecialPage("settingsBlock")
|
toSettings: () => setSpecialPage("settingsBlock"),
|
||||||
}}
|
}}
|
||||||
onScrollUsers={setPageOfUsers}
|
onScrollUsers={setPageOfUsers}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
// {
|
||||||
|
// isSettingsAvailable: true,
|
||||||
|
// component: (
|
||||||
|
// <BitrixTags
|
||||||
|
// tagsItems={arrayOfTags}
|
||||||
|
// selectedTags={selectedTags}
|
||||||
|
// openDelete={startDeleteTagQuestion}
|
||||||
|
// handleAddTag={handleAddTagQuestion}
|
||||||
|
// handlePrevStep={handlePrevStep}
|
||||||
|
// handleNextStep={handleNextStep}
|
||||||
|
// titleProps={{
|
||||||
|
// step: step + 2,
|
||||||
|
// title: "Добавление тегов",
|
||||||
|
// desc: "На этом этапе вы можете добавить теги с результатами",
|
||||||
|
// toSettings: () => setSpecialPage("settingsBlock")
|
||||||
|
// }}
|
||||||
|
// onScroll={setPageOfTags}
|
||||||
|
// />
|
||||||
|
// ),
|
||||||
|
// },
|
||||||
{
|
{
|
||||||
isSettingsAvailable: true,
|
isSettingsAvailable: true,
|
||||||
component: (
|
component: (
|
||||||
<AmoTags
|
<BitrixQuestions
|
||||||
tagsItems={arrayOfTags}
|
|
||||||
selectedTags={selectedTags}
|
|
||||||
openDelete={startDeleteTagQuestion}
|
|
||||||
handleAddTag={handleAddTagQuestion}
|
|
||||||
handlePrevStep={handlePrevStep}
|
|
||||||
handleNextStep={handleNextStep}
|
|
||||||
titleProps={{
|
|
||||||
step: step + 2,
|
|
||||||
title: "Добавление тегов",
|
|
||||||
desc: "На этом этапе вы можете добавить теги с результатами",
|
|
||||||
toSettings: () => setSpecialPage("settingsBlock")
|
|
||||||
}}
|
|
||||||
onScroll={setPageOfTags}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
isSettingsAvailable: true,
|
|
||||||
component: (
|
|
||||||
<AmoQuestions
|
|
||||||
setSelectedCurrentFields={setSelectedCurrentFields}
|
setSelectedCurrentFields={setSelectedCurrentFields}
|
||||||
fieldsItems={arrayOfFields}
|
fieldsItems={arrayOfFields}
|
||||||
selectedCurrentFields={selectedCurrentFields}
|
selectedCurrentFields={selectedCurrentFields}
|
||||||
@ -341,56 +386,71 @@ export const SwitchPages = ({
|
|||||||
titleProps={{
|
titleProps={{
|
||||||
step: step + 2,
|
step: step + 2,
|
||||||
title: "Соотнесение вопросов и сущностей",
|
title: "Соотнесение вопросов и сущностей",
|
||||||
toSettings: () => setSpecialPage("settingsBlock")
|
toSettings: () => setSpecialPage("settingsBlock"),
|
||||||
}}
|
}}
|
||||||
onScroll={setPageOfFields}
|
onScroll={setPageOfFields}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
]
|
];
|
||||||
|
|
||||||
const stepTitles = steps.map((step) => step.title);
|
const stepTitles = steps.map((step) => step.title);
|
||||||
|
|
||||||
switch (specialPage) {
|
switch (specialPage) {
|
||||||
case "deleteCell":
|
case "deleteCell":
|
||||||
return <DeleteTagQuestion
|
return (
|
||||||
close={closeSpecialPage}
|
<DeleteTagQuestion
|
||||||
deleteItem={handleDeleteTagQuestion}
|
close={closeSpecialPage}
|
||||||
/>
|
deleteItem={handleDeleteTagQuestion}
|
||||||
|
/>
|
||||||
|
);
|
||||||
case "removeAccount":
|
case "removeAccount":
|
||||||
return <RemoveAccount
|
return (
|
||||||
handleCloseModal={handleCloseModal}
|
<RemoveAccount
|
||||||
stopThisPage={closeSpecialPage}
|
handleCloseModal={handleCloseModal}
|
||||||
/>
|
stopThisPage={closeSpecialPage}
|
||||||
|
/>
|
||||||
|
);
|
||||||
case "settingsBlock":
|
case "settingsBlock":
|
||||||
return <SettingsBlock
|
return (
|
||||||
stepTitles={stepTitles}
|
<SettingsBlock
|
||||||
selectedDealUser={arrayOfUsers.find((u) => u.id === selectedDealUser)?.title || "не указан"}
|
stepTitles={stepTitles}
|
||||||
selectedFunnel={arrayOfPipelines.find((p) => p.id === selectedPipeline)?.title || "нет данных"}
|
selectedDealUser={arrayOfUsers.find((u) => u.id === selectedDealUser)?.title || "не указан"}
|
||||||
selectedStage={
|
selectedFunnel={arrayOfPipelines.find((p) => p.id === selectedPipeline)?.title || "нет данных"}
|
||||||
arrayOfPipelinesSteps.find((s) => s.id === selectedPipelineStep)?.title || "нет данных"
|
selectedStage={arrayOfPipelinesSteps.find((s) => s.id === selectedPipelineStep)?.title || "нет данных"}
|
||||||
}
|
selectedQuestions={selectedQuestions}
|
||||||
selectedQuestions={selectedQuestions}
|
selectedTags={selectedTags}
|
||||||
selectedTags={selectedTags}
|
toBack={() => closeSpecialPage()}
|
||||||
toBack={() => closeSpecialPage()}
|
setStep={(step: number) => {
|
||||||
setStep={(step: number) => {
|
closeSpecialPage();
|
||||||
closeSpecialPage()
|
setStep(step - 1);
|
||||||
setStep(step - 1)
|
}}
|
||||||
}}
|
leadFlag={leadFlag}
|
||||||
/>
|
/>
|
||||||
case "amoLogin": return <AmoLogin handleNextStep={handleNextStep} />
|
);
|
||||||
case "accountInfo": return <AccountInfo
|
case "bitrixLogin":
|
||||||
handleNextStep={() => closeSpecialPage()}
|
return <BitrixLogin handleNextStep={handleNextStep} />;
|
||||||
accountInfo={accountInfo}
|
case "accountInfo":
|
||||||
toChangeAccount={() => setSpecialPage("removeAccount")}
|
return (
|
||||||
/>
|
<AccountInfo
|
||||||
|
handleNextStep={() => closeSpecialPage()}
|
||||||
|
accountInfo={accountInfo}
|
||||||
|
toChangeAccount={() => setSpecialPage("removeAccount")}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
default:
|
||||||
default: return <Box sx={{
|
return (
|
||||||
flexGrow: 1,
|
<Box
|
||||||
width: "100%",
|
sx={{
|
||||||
height: "100%",
|
flexGrow: 1,
|
||||||
overflow: "auto"
|
width: "100%",
|
||||||
}}>{steps[step].component}</Box>
|
height: "100%",
|
||||||
|
overflow: "auto",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{steps[step].component}
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import { MinifiedData, QuestionKeys, SelectedTags, TagKeys, TagQuestionHC } from
|
|||||||
import { DataConstrictor } from "../Components/DataConstrictor";
|
import { DataConstrictor } from "../Components/DataConstrictor";
|
||||||
import { ModalTitle } from "../ModalTitle";
|
import { ModalTitle } from "../ModalTitle";
|
||||||
import { StepButtonsBlock } from "../StepButtonsBlock";
|
import { StepButtonsBlock } from "../StepButtonsBlock";
|
||||||
import { resetBitrixTagsFields } from "../useAmoIntegration";
|
import { resetBitrixTagsFields } from "../useBitrixIntegration";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
tagsItems: MinifiedData[] | [];
|
tagsItems: MinifiedData[] | [];
|
||||||
@ -25,7 +25,7 @@ type Props = {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const AmoTags: FC<Props> = ({
|
export const BitrixTags: FC<Props> = ({
|
||||||
tagsItems,
|
tagsItems,
|
||||||
selectedTags,
|
selectedTags,
|
||||||
handleAddTag,
|
handleAddTag,
|
||||||
@ -5,7 +5,7 @@ import { redirect } from "react-router-dom";
|
|||||||
|
|
||||||
import CloseIcon from "@mui/icons-material/Close";
|
import CloseIcon from "@mui/icons-material/Close";
|
||||||
|
|
||||||
import { useBitrixIntegration } from "./useAmoIntegration";
|
import { useBitrixIntegration } from "./useBitrixIntegration";
|
||||||
import { MinifiedData } from "./types";
|
import { MinifiedData } from "./types";
|
||||||
import { Quiz } from "@/model/quiz/quiz";
|
import { Quiz } from "@/model/quiz/quiz";
|
||||||
import { SwitchPages } from "./SwitchPages";
|
import { SwitchPages } from "./SwitchPages";
|
||||||
@ -60,11 +60,14 @@ export const BitrixModal: FC<IntegrationsModalProps> = ({ isModalOpen, handleClo
|
|||||||
setPageOfTags,
|
setPageOfTags,
|
||||||
setPageOfFields,
|
setPageOfFields,
|
||||||
setSelectedCurrentFields,
|
setSelectedCurrentFields,
|
||||||
|
leadFlag,
|
||||||
|
leadFlagHC,
|
||||||
|
fullArrayOfPipelinesSteps
|
||||||
} = useBitrixIntegration({
|
} = useBitrixIntegration({
|
||||||
quizID: quiz.backendId,
|
quizID: quiz.backendId,
|
||||||
isModalOpen,
|
isModalOpen,
|
||||||
isTryRemoveAccount,
|
isTryRemoveAccount,
|
||||||
questions,
|
questions
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -160,6 +163,9 @@ export const BitrixModal: FC<IntegrationsModalProps> = ({ isModalOpen, handleClo
|
|||||||
setPageOfFields={setPageOfFields}
|
setPageOfFields={setPageOfFields}
|
||||||
setSelectedCurrentFields={setSelectedCurrentFields}
|
setSelectedCurrentFields={setSelectedCurrentFields}
|
||||||
handleCloseModal={handleCloseModal}
|
handleCloseModal={handleCloseModal}
|
||||||
|
leadFlag={leadFlag}
|
||||||
|
leadFlagHC={leadFlagHC}
|
||||||
|
fullArrayOfPipelinesSteps={fullArrayOfPipelinesSteps}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@ -1,7 +1,22 @@
|
|||||||
export type TagKeys = "Company" | "Lead" | "Customer" | "Contact";
|
export type TagKeys = "lead"
|
||||||
|
| "company"
|
||||||
|
| "contact"
|
||||||
|
| "deal"
|
||||||
|
| "CRM_INVOICE"
|
||||||
|
| "CRM_SMART_INVOICE"
|
||||||
|
| "CRM_QUOTE"
|
||||||
|
| "CRM_REQUISITE";
|
||||||
|
|
||||||
export type SelectedTags = Record<TagKeys, number[]>;
|
export type SelectedTags = Record<TagKeys, number[]>;
|
||||||
|
|
||||||
export type QuestionKeys = "Company" | "Lead" | "Customer" | "Contact";
|
export type QuestionKeys = "lead"
|
||||||
|
| "company"
|
||||||
|
| "contact"
|
||||||
|
| "deal"
|
||||||
|
| "CRM_INVOICE"
|
||||||
|
| "CRM_SMART_INVOICE"
|
||||||
|
| "CRM_QUOTE"
|
||||||
|
| "CRM_REQUISITE";
|
||||||
export type SelectedQuestions = Record<QuestionKeys, MinifiedData[]>;
|
export type SelectedQuestions = Record<QuestionKeys, MinifiedData[]>;
|
||||||
|
|
||||||
export type MinifiedData = {
|
export type MinifiedData = {
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import {
|
|||||||
getAccount,
|
getAccount,
|
||||||
FieldsRule,
|
FieldsRule,
|
||||||
getFields,
|
getFields,
|
||||||
|
connectBitrix,
|
||||||
} from "@/api/bitrixIntegration";
|
} from "@/api/bitrixIntegration";
|
||||||
import { AnyTypedQuizQuestion } from "@frontend/squzanswerer";
|
import { AnyTypedQuizQuestion } from "@frontend/squzanswerer";
|
||||||
import { UntypedQuizQuestion } from "@/model/questionTypes/shared";
|
import { UntypedQuizQuestion } from "@/model/questionTypes/shared";
|
||||||
@ -43,8 +44,11 @@ export const useBitrixIntegration = ({ isModalOpen, isTryRemoveAccount, quizID,
|
|||||||
const [firstRules, setFirstRules] = useState<boolean>(false);
|
const [firstRules, setFirstRules] = useState<boolean>(false);
|
||||||
const [accountInfo, setAccountInfo] = useState<AccountResponse | null>(null);
|
const [accountInfo, setAccountInfo] = useState<AccountResponse | null>(null);
|
||||||
|
|
||||||
|
const [leadFlag, setLeadFlag] = useState<boolean>(false);
|
||||||
|
|
||||||
const [arrayOfPipelines, setArrayOfPipelines] = useState<MinifiedData[]>([]);
|
const [arrayOfPipelines, setArrayOfPipelines] = useState<MinifiedData[]>([]);
|
||||||
const [arrayOfPipelinesSteps, setArrayOfPipelinesSteps] = useState<MinifiedData[]>([]);
|
const [arrayOfPipelinesSteps, setArrayOfPipelinesSteps] = useState<MinifiedData[]>([]);
|
||||||
|
const [fullArrayOfPipelinesSteps, setFullArrayOfPipelinesSteps] = useState<any[]>([]);
|
||||||
const [arrayOfUsers, setArrayOfUsers] = useState<MinifiedData[]>([]);
|
const [arrayOfUsers, setArrayOfUsers] = useState<MinifiedData[]>([]);
|
||||||
const [arrayOfTags, setArrayOfTags] = useState<MinifiedData[]>([]);
|
const [arrayOfTags, setArrayOfTags] = useState<MinifiedData[]>([]);
|
||||||
const [arrayOfFields, setArrayOfFields] = useState<MinifiedData[]>([]);
|
const [arrayOfFields, setArrayOfFields] = useState<MinifiedData[]>([]);
|
||||||
@ -62,10 +66,14 @@ export const useBitrixIntegration = ({ isModalOpen, isTryRemoveAccount, quizID,
|
|||||||
Customer: [],
|
Customer: [],
|
||||||
});
|
});
|
||||||
const [selectedQuestions, setSelectedQuestions] = useState<SelectedQuestions>({
|
const [selectedQuestions, setSelectedQuestions] = useState<SelectedQuestions>({
|
||||||
Lead: [],
|
lead: [],
|
||||||
Company: [],
|
company: [],
|
||||||
Customer: [],
|
contact: [],
|
||||||
Contact: []
|
deal: [],
|
||||||
|
CRM_INVOICE: [],
|
||||||
|
CRM_SMART_INVOICE: [],
|
||||||
|
CRM_QUOTE: [],
|
||||||
|
CRM_REQUISITE: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
const [pageOfPipelines, setPageOfPipelines] = useState(1);
|
const [pageOfPipelines, setPageOfPipelines] = useState(1);
|
||||||
@ -74,12 +82,37 @@ export const useBitrixIntegration = ({ isModalOpen, isTryRemoveAccount, quizID,
|
|||||||
const [pageOfTags, setPageOfTags] = useState(1);
|
const [pageOfTags, setPageOfTags] = useState(1);
|
||||||
const [pageOfFields, setPageOfFields] = useState(1);
|
const [pageOfFields, setPageOfFields] = useState(1);
|
||||||
|
|
||||||
|
const leadFlagHC = (s:boolean) => {
|
||||||
|
setLeadFlag(s)
|
||||||
|
};
|
||||||
const selectedPipelineHC = (id:string | null) => {
|
const selectedPipelineHC = (id:string | null) => {
|
||||||
setSelectedPipeline(id);
|
setSelectedPipeline(id);
|
||||||
isReadyGetPipelineStep = true;
|
isReadyGetPipelineStep = true;
|
||||||
setPageOfPipelinesSteps(1);
|
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(() => {
|
useEffect(() => {
|
||||||
const fetchAccountRules = async () => {
|
const fetchAccountRules = async () => {
|
||||||
setIsLoadingPage(true);
|
setIsLoadingPage(true);
|
||||||
@ -138,7 +171,7 @@ export const useBitrixIntegration = ({ isModalOpen, isTryRemoveAccount, quizID,
|
|||||||
id: key,
|
id: key,
|
||||||
title: FCTranslate[key],
|
title: FCTranslate[key],
|
||||||
entity: "Contact",
|
entity: "Contact",
|
||||||
amoId: MAP[key].toString(),
|
bitrixId: MAP[key].toString(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
setSelectedCurrentFields(list)
|
setSelectedCurrentFields(list)
|
||||||
@ -196,8 +229,8 @@ export const useBitrixIntegration = ({ isModalOpen, isTryRemoveAccount, quizID,
|
|||||||
|
|
||||||
response.items.forEach((step) => {
|
response.items.forEach((step) => {
|
||||||
minifiedPipelines.push({
|
minifiedPipelines.push({
|
||||||
id: step.AmoID.toString(),
|
id: step.bitrixID.toString(),
|
||||||
title: step.Name,
|
title: step.name || "Нет названия",
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
setArrayOfPipelines((prevItems) => [...prevItems, ...minifiedPipelines]);
|
setArrayOfPipelines((prevItems) => [...prevItems, ...minifiedPipelines]);
|
||||||
@ -208,31 +241,44 @@ export const useBitrixIntegration = ({ isModalOpen, isTryRemoveAccount, quizID,
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [pageOfPipelines]);
|
}, [pageOfPipelines]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isReadyGetPipelineStep) {
|
if (isReadyGetPipelineStep && selectedPipeline !== null) {
|
||||||
const oldData = pageOfPipelinesSteps === 1 ? [] : arrayOfPipelinesSteps;
|
const oldData = pageOfPipelinesSteps === 1 ? [] : arrayOfPipelinesSteps;
|
||||||
if (selectedPipeline !== null)
|
const oldFullData = pageOfPipelinesSteps === 1 ? [] : fullArrayOfPipelinesSteps;
|
||||||
getSteps({
|
|
||||||
page: pageOfPipelinesSteps,
|
|
||||||
size: SIZE,
|
|
||||||
pipelineId: Number(selectedPipeline),
|
|
||||||
}).then(([response]) => {
|
|
||||||
if (response && response.items !== null) {
|
|
||||||
const minifiedSteps: MinifiedData[] = [];
|
|
||||||
|
|
||||||
response.items.forEach((step) => {
|
getSteps({
|
||||||
minifiedSteps.push({
|
page: pageOfPipelinesSteps,
|
||||||
id: step.AmoID.toString(),
|
size: SIZE,
|
||||||
title: step.Name,
|
pipelineId: Number(selectedPipeline),
|
||||||
});
|
}).then(([response]) => {
|
||||||
});
|
if (response && response.items !== null) {
|
||||||
setArrayOfPipelinesSteps([...oldData, ...minifiedSteps]);
|
// Фильтруем только нужные элементы
|
||||||
} else {
|
const filteredItems = response.items.filter(item =>
|
||||||
isReadyGetPipelineStep = false
|
item.entityID === "STATUS" ||
|
||||||
}
|
item.entityID === "SOURCE" ||
|
||||||
});
|
(typeof item.entityID === 'string' && item.entityID.startsWith("DEAL_STAGE"))
|
||||||
}
|
);
|
||||||
}, [selectedPipeline, pageOfPipelinesSteps]);
|
|
||||||
|
// Минифицируем отфильтрованные данные
|
||||||
|
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(() => {
|
useEffect(() => {
|
||||||
if (isReadyGetUsers) {
|
if (isReadyGetUsers) {
|
||||||
getUsers({
|
getUsers({
|
||||||
@ -244,8 +290,8 @@ export const useBitrixIntegration = ({ isModalOpen, isTryRemoveAccount, quizID,
|
|||||||
|
|
||||||
response.items.forEach((step) => {
|
response.items.forEach((step) => {
|
||||||
minifiedUsers.push({
|
minifiedUsers.push({
|
||||||
id: step.amoUserID.toString(),
|
id: step.bitrixUserID.toString(),
|
||||||
title: step.name,
|
title: step.name || "Нет имени",
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
setArrayOfUsers((prevItems) => [...prevItems, ...minifiedUsers]);
|
setArrayOfUsers((prevItems) => [...prevItems, ...minifiedUsers]);
|
||||||
@ -255,66 +301,77 @@ export const useBitrixIntegration = ({ isModalOpen, isTryRemoveAccount, quizID,
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [pageOfUsers]);
|
}, [pageOfUsers]);
|
||||||
useEffect(() => {
|
// useEffect(() => {
|
||||||
if (isReadyGetTags) {
|
// if (isReadyGetTags) {
|
||||||
getTags({
|
// getTags({
|
||||||
page: pageOfTags,
|
// page: pageOfTags,
|
||||||
size: SIZE,
|
// size: SIZE,
|
||||||
}).then(([response]) => {
|
// }).then(([response]) => {
|
||||||
if (response && response.items !== null) {
|
// if (response && response.items !== null) {
|
||||||
const minifiedTags: MinifiedData[] = [];
|
// const minifiedTags: MinifiedData[] = [];
|
||||||
|
|
||||||
response.items.forEach((step) => {
|
// response.items.forEach((step) => {
|
||||||
minifiedTags.push({
|
// minifiedTags.push({
|
||||||
id: step.AmoID.toString(),
|
// id: step.BitrixID.toString(),
|
||||||
title: step.Name,
|
// title: step.Name,
|
||||||
entity:
|
// entity:
|
||||||
step.Entity === "leads"
|
// step.Entity === "leads"
|
||||||
? "Lead"
|
// ? "Lead"
|
||||||
: step.Entity === "contacts"
|
// : step.Entity === "contacts"
|
||||||
? "Contact"
|
// ? "Contact"
|
||||||
: step.Entity === "companies"
|
// : step.Entity === "companies"
|
||||||
? "Company"
|
// ? "Company"
|
||||||
: "Customer",
|
// : "Customer",
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
setArrayOfTags((prevItems) => [...prevItems, ...minifiedTags]);
|
// setArrayOfTags((prevItems) => [...prevItems, ...minifiedTags]);
|
||||||
} else {
|
// } else {
|
||||||
isReadyGetTags = false
|
// isReadyGetTags = false
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
}, [pageOfTags]);
|
// }, [pageOfTags]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isReadyGetFields) {
|
if (isReadyGetFields) {
|
||||||
getFields({
|
getFields({
|
||||||
page: pageOfFields,
|
page: pageOfFields,
|
||||||
size: 1000,
|
size: 1000,
|
||||||
}).then(([response]) => {
|
}).then(([response]) => {
|
||||||
if (response && response.items !== null) {
|
if (response && response.items !== null) {
|
||||||
const minifiedTags: MinifiedData[] = [];
|
const minifiedTags: MinifiedData[] = [];
|
||||||
|
|
||||||
response.items.forEach((field) => {
|
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({
|
minifiedTags.push({
|
||||||
id: field.AmoID.toString(),
|
id: field.bitrixID.toString(),
|
||||||
title: field.Name,
|
title: field.editFromLabel,
|
||||||
entity:
|
entity: entity,
|
||||||
field.Entity === "leads"
|
|
||||||
? "Lead"
|
|
||||||
: field.Entity === "contacts"
|
|
||||||
? "Contact"
|
|
||||||
: field.Entity === "companies"
|
|
||||||
? "Company"
|
|
||||||
: "Customer",
|
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
setArrayOfFields((prevItems) => [...prevItems, ...minifiedTags]);
|
});
|
||||||
}
|
|
||||||
});
|
setArrayOfFields((prevItems) => [...prevItems, ...minifiedTags]);
|
||||||
} else {
|
}
|
||||||
isReadyGetFields = false
|
});
|
||||||
}
|
} else {
|
||||||
}, [pageOfFields]);
|
isReadyGetFields = false
|
||||||
|
}
|
||||||
|
}, [pageOfFields]);
|
||||||
useEffect(() => () => {
|
useEffect(() => () => {
|
||||||
isReadyGetPipeline = true;
|
isReadyGetPipeline = true;
|
||||||
isReadyGetPipelineStep = true;
|
isReadyGetPipelineStep = true;
|
||||||
@ -350,6 +407,9 @@ export const useBitrixIntegration = ({ isModalOpen, isTryRemoveAccount, quizID,
|
|||||||
setPageOfTags: () => setPageOfTags(old => old + 1),
|
setPageOfTags: () => setPageOfTags(old => old + 1),
|
||||||
setPageOfFields: () => setPageOfFields(old => old + 1),
|
setPageOfFields: () => setPageOfFields(old => old + 1),
|
||||||
setSelectedCurrentFields,
|
setSelectedCurrentFields,
|
||||||
|
leadFlag,
|
||||||
|
leadFlagHC,
|
||||||
|
fullArrayOfPipelinesSteps
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -0,0 +1,136 @@
|
|||||||
|
import { Box, FormControl, FormControlLabel, Radio, RadioGroup, useMediaQuery, useTheme } from "@mui/material";
|
||||||
|
import { FC } from "react";
|
||||||
|
import { StepButtonsBlock } from "./StepButtonsBlock";
|
||||||
|
import CheckboxIcon from "@/assets/icons/Checkbox";
|
||||||
|
import { ModalTitle } from "./ModalTitle";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
leadFlag: boolean;
|
||||||
|
leadFlagHC: (a: boolean) => void;
|
||||||
|
handlePrevStep: () => void;
|
||||||
|
handleNextStep: () => void;
|
||||||
|
|
||||||
|
titleProps: {
|
||||||
|
step: number;
|
||||||
|
title: string;
|
||||||
|
desc: string;
|
||||||
|
toSettings: () => void;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const СhoosePerson: FC<Props> = ({
|
||||||
|
leadFlag,
|
||||||
|
leadFlagHC,
|
||||||
|
|
||||||
|
handlePrevStep,
|
||||||
|
handleNextStep,
|
||||||
|
|
||||||
|
titleProps,
|
||||||
|
}) => {
|
||||||
|
const theme = useTheme();
|
||||||
|
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
||||||
|
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
alignItems: "center",
|
||||||
|
height: "100%",
|
||||||
|
overflow: "auto",
|
||||||
|
flexGrow: 1,
|
||||||
|
justifyContent: "space-between",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box sx={{ width: "100%", zIndex: 3 }}>
|
||||||
|
<ModalTitle {...titleProps} />
|
||||||
|
</Box>
|
||||||
|
<Box>
|
||||||
|
<FormControl component="fieldset">
|
||||||
|
<RadioGroup
|
||||||
|
row
|
||||||
|
aria-label="тип сделки"
|
||||||
|
name="dealType"
|
||||||
|
value={leadFlag ? "lead" : "deal"}
|
||||||
|
onChange={(e) => leadFlagHC(e.target.value === "lead")}
|
||||||
|
sx={{ gap: 3 }}
|
||||||
|
>
|
||||||
|
<FormControlLabel
|
||||||
|
value="lead"
|
||||||
|
control={
|
||||||
|
<Radio
|
||||||
|
checkedIcon={
|
||||||
|
<CheckboxIcon
|
||||||
|
checked
|
||||||
|
isRounded
|
||||||
|
color={theme.palette.brightPurple.main}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
icon={<CheckboxIcon isRounded />}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
label="Лид сделки"
|
||||||
|
sx={{
|
||||||
|
color: "black",
|
||||||
|
padding: "15px",
|
||||||
|
border: `1px solid ${theme.palette.background.default}`,
|
||||||
|
borderRadius: "12px",
|
||||||
|
margin: 0,
|
||||||
|
backgroundColor: "#eff0f5",
|
||||||
|
"&.MuiFormControlLabel-root > .MuiTypography-root": {
|
||||||
|
width: isMobile ? "150px" : "200px",
|
||||||
|
overflow: "hidden",
|
||||||
|
textOverflow: "ellipsis",
|
||||||
|
whiteSpace: "nowrap",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<FormControlLabel
|
||||||
|
value="deal"
|
||||||
|
control={
|
||||||
|
<Radio
|
||||||
|
checkedIcon={
|
||||||
|
<CheckboxIcon
|
||||||
|
checked
|
||||||
|
isRounded
|
||||||
|
color={theme.palette.brightPurple.main}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
icon={<CheckboxIcon isRounded />}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
label="Дил сделки"
|
||||||
|
sx={{
|
||||||
|
color: "black",
|
||||||
|
padding: "15px",
|
||||||
|
border: `1px solid ${theme.palette.background.default}`,
|
||||||
|
borderRadius: "12px",
|
||||||
|
margin: 0,
|
||||||
|
backgroundColor: "#eff0f5",
|
||||||
|
"&.MuiFormControlLabel-root > .MuiTypography-root": {
|
||||||
|
width: isMobile ? "150px" : "200px",
|
||||||
|
overflow: "hidden",
|
||||||
|
textOverflow: "ellipsis",
|
||||||
|
whiteSpace: "nowrap",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</RadioGroup>
|
||||||
|
</FormControl>
|
||||||
|
</Box>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
alignSelf: "end",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<StepButtonsBlock
|
||||||
|
onLargeBtnClick={handleNextStep}
|
||||||
|
onSmallBtnClick={handlePrevStep}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
@ -7,6 +7,7 @@ import { useNavigate } from "react-router-dom";
|
|||||||
import { PartnersBoard } from "./PartnersBoard/PartnersBoard";
|
import { PartnersBoard } from "./PartnersBoard/PartnersBoard";
|
||||||
import { getLeadTargetsByQuiz, LeadTargetModel } from "@/api/leadtarget";
|
import { getLeadTargetsByQuiz, LeadTargetModel } from "@/api/leadtarget";
|
||||||
import { QuizMetricType } from "@model/quizSettings";
|
import { QuizMetricType } from "@model/quizSettings";
|
||||||
|
import { makeRequest } from "@frontend/kitui";
|
||||||
|
|
||||||
interface IntegrationsPageProps {
|
interface IntegrationsPageProps {
|
||||||
heightSidebar: number;
|
heightSidebar: number;
|
||||||
@ -56,6 +57,24 @@ export const IntegrationsPage = ({
|
|||||||
load();
|
load();
|
||||||
}, [leadTargetsLoaded, quiz?.id]);
|
}, [leadTargetsLoaded, quiz?.id]);
|
||||||
|
|
||||||
|
// useEffect(() => {
|
||||||
|
// (async () => {
|
||||||
|
// const API_URL = `${process.env.REACT_APP_DOMAIN}/squiz/yclients`;
|
||||||
|
// try {
|
||||||
|
// const response = await makeRequest<void, { link: string }>({
|
||||||
|
// method: "POST",
|
||||||
|
// url: `${API_URL}/account`,
|
||||||
|
// useToken: true,
|
||||||
|
// withCredentials: true,
|
||||||
|
// });
|
||||||
|
// window.open(response.link, "_blank");
|
||||||
|
// } catch (nativeError) {
|
||||||
|
// return [null, `Не удалось подключить аккаунт. `];
|
||||||
|
// }
|
||||||
|
// })()
|
||||||
|
|
||||||
|
// }, [])
|
||||||
|
|
||||||
const refreshLeadTargets = async () => {
|
const refreshLeadTargets = async () => {
|
||||||
if (!quiz?.id) return;
|
if (!quiz?.id) return;
|
||||||
const [items] = await getLeadTargetsByQuiz(quiz.backendId);
|
const [items] = await getLeadTargetsByQuiz(quiz.backendId);
|
||||||
|
|||||||
@ -140,7 +140,7 @@ export const PartnersBoard: FC<PartnersBoardProps> = ({
|
|||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Typography variant="h6" sx={sectionTitleStyles}>
|
<Typography variant="h6" sx={sectionTitleStyles}>
|
||||||
Автоматизация
|
Автоматизация
|
||||||
</Typography>
|
</Typography>
|
||||||
<Box sx={containerStyles}>
|
<Box sx={containerStyles}>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user