Merge branch 'dev' into 'staging'

Dev

See merge request frontend/squiz!341
This commit is contained in:
Nastya 2024-06-11 11:50:50 +00:00
commit 80dd693ea9
9 changed files with 117 additions and 49 deletions

@ -239,10 +239,10 @@ export type IntegrationRules = {
StepID: number; StepID: number;
UTMs: number[]; UTMs: number[];
FieldsRule: { FieldsRule: {
lead: { QuestionID: number }[]; Lead: { QuestionID: number }[];
contact: { ContactRuleMap: string }[]; Contact: { ContactRuleMap: string }[];
company: { QuestionID: number }[]; Company: { QuestionID: number }[];
customer: { QuestionID: number }[]; Customer: { QuestionID: number }[];
}; };
Deleted: boolean; Deleted: boolean;
CreatedAt: number; CreatedAt: number;
@ -258,6 +258,7 @@ export const getIntegrationRules = async (
}); });
return [settingsResponse || null]; return [settingsResponse || null];
} catch (nativeError) { } catch (nativeError) {
if (nativeError.response.status === 404) return [null, "first"];
const [error] = parseAxiosError(nativeError); const [error] = parseAxiosError(nativeError);
return [null, `Не удалось получить настройки интеграции. ${error}`]; return [null, `Не удалось получить настройки интеграции. ${error}`];
} }
@ -278,6 +279,22 @@ export type IntegrationRulesUpdate = {
}; };
}; };
export const setIntegrationRules = async (
quizID: string,
settings: IntegrationRulesUpdate,
): Promise<[string | null, string?]> => {
try {
const updateResponse = await makeRequest<IntegrationRulesUpdate, string>({
method: "POST",
url: `${API_URL}/rules/${quizID}`,
body: settings,
});
return [updateResponse];
} catch (nativeError) {
const [error] = parseAxiosError(nativeError);
return [null, `Failed to update integration settings. ${error}`];
}
};
export const updateIntegrationRules = async ( export const updateIntegrationRules = async (
quizID: string, quizID: string,
settings: IntegrationRulesUpdate, settings: IntegrationRulesUpdate,

@ -139,11 +139,11 @@ export const CustomRadioGroup: FC<CustomRadioGroupProps> = ({
borderRadius: "12px", borderRadius: "12px",
margin: 0, margin: 0,
backgroundColor: backgroundColor:
currentValue === item.AmoID.toString() currentValue === Number(item.AmoID)
? theme.palette.background.default ? theme.palette.background.default
: theme.palette.common.white, : theme.palette.common.white,
}} }}
value={item.AmoID.toString()} value={Number(item.AmoID)}
control={ control={
<Radio <Radio
checkedIcon={ checkedIcon={
@ -185,7 +185,7 @@ export const CustomRadioGroup: FC<CustomRadioGroupProps> = ({
? theme.palette.background.default ? theme.palette.background.default
: theme.palette.common.white, : theme.palette.common.white,
}} }}
value={step.Name} value={step.AmoID}
control={ control={
<Radio <Radio
checkedIcon={ checkedIcon={
@ -256,7 +256,7 @@ export const CustomRadioGroup: FC<CustomRadioGroupProps> = ({
borderRadius: "12px", borderRadius: "12px",
margin: 0, margin: 0,
backgroundColor: backgroundColor:
currentValue === backendId currentValue === Number(backendId)
? theme.palette.background.default ? theme.palette.background.default
: theme.palette.common.white, : theme.palette.common.white,
"&.MuiFormControlLabel-root > .MuiTypography-root": { "&.MuiFormControlLabel-root > .MuiTypography-root": {
@ -265,7 +265,7 @@ export const CustomRadioGroup: FC<CustomRadioGroupProps> = ({
textOverflow: "ellipsis" textOverflow: "ellipsis"
} }
}} }}
value={backendId} value={Number(backendId)}
control={ control={
<Radio <Radio
checkedIcon={ checkedIcon={
@ -314,7 +314,12 @@ export const CustomRadioGroup: FC<CustomRadioGroupProps> = ({
aria-labelledby="demo-controlled-radio-buttons-group" aria-labelledby="demo-controlled-radio-buttons-group"
name="controlled-radio-buttons-group" name="controlled-radio-buttons-group"
value={currentValue} value={currentValue}
onChange={handleChange} onChange={(e) => {
console.log("klick")
console.log(e.target.value)
console.log(typeof e.target.value)
handleChange(e)
}}
> >
{formControlLabels} {formControlLabels}
</RadioGroup> </RadioGroup>

@ -95,7 +95,7 @@ export const CustomSelect: FC<CustomSelectProps> = ({
return users.map((user) => ( return users.map((user) => (
<MenuItem <MenuItem
key={user.ID} key={user.ID}
value={user.Name} value={user.AmocrmID}
sx={{ sx={{
padding: "6px 0", padding: "6px 0",
zIndex: 2, zIndex: 2,

@ -18,18 +18,18 @@ import { AmoStep7 } from "./IntegrationStep7/AmoStep7";
import { AmoModalTitle } from "./AmoModalTitle/AmoModalTitle"; import { AmoModalTitle } from "./AmoModalTitle/AmoModalTitle";
import { AmoSettingsBlock } from "./SettingsBlock/AmoSettingsBlock"; import { AmoSettingsBlock } from "./SettingsBlock/AmoSettingsBlock";
import { AmoAccountInfo } from "./AmoAccountInfo/AmoAccountInfo"; import { AmoAccountInfo } from "./AmoAccountInfo/AmoAccountInfo";
import { AccountResponse, IntegrationRules, getAccount, getIntegrationRules } from "@api/integration"; import { AccountResponse, IntegrationRules, getAccount, getIntegrationRules, setIntegrationRules, updateIntegrationRules } from "@api/integration";
import { useQuestions } from "@/stores/questions/hooks"; import { useQuestions } from "@/stores/questions/hooks";
import { redirect } from "react-router-dom"; import { redirect } from "react-router-dom";
import { enqueueSnackbar } from "notistack"; import { enqueueSnackbar } from "notistack";
export type TitleKeys = "contacts" | "company" | "deal" | "buyers"; export type TitleKeys = "Contact" | "Company" | "Lead" | "Customer";
export type TagQuestionObject = { export type TagQuestionObject = {
backendId: string; backendId: string;
title: string; title: string;
}; };
export type TQuestionEntity = Record<TitleKeys, string[] | []>; export type TQuestionEntity = Record<TitleKeys, number[] | []>;
type IntegrationsModalProps = { type IntegrationsModalProps = {
isModalOpen: boolean; isModalOpen: boolean;
handleCloseModal: () => void; handleCloseModal: () => void;
@ -37,8 +37,8 @@ type IntegrationsModalProps = {
quizID: number | undefined; quizID: number | undefined;
}; };
export type TagKeys = "contact" | "company" | "deal" | "buyer"; export type TagKeys = "Contact" | "Company" | "Lead" | "Customer";
export type TTags = Record<TagKeys, string[] | []>; export type TTags = Record<TagKeys, number[] | []>;
export const AmoCRMModal: FC<IntegrationsModalProps> = ({ export const AmoCRMModal: FC<IntegrationsModalProps> = ({
isModalOpen, isModalOpen,
@ -56,8 +56,9 @@ export const AmoCRMModal: FC<IntegrationsModalProps> = ({
const [isSettingsBlock, setIsSettingsBlock] = useState<boolean>(false); const [isSettingsBlock, setIsSettingsBlock] = useState<boolean>(false);
const [isRemoveAccount, setIsRemoveAccount] = useState<boolean>(false); const [isRemoveAccount, setIsRemoveAccount] = useState<boolean>(false);
const [firstRules, setFirstRules] = useState<boolean>(false);
const [accountInfo, setAccountInfo] = useState<AccountResponse | null>(null); const [accountInfo, setAccountInfo] = useState<AccountResponse | null>(null);
const [integrationRules, setIntegrationRules] = useState<IntegrationRules | null>(null);
const [selectedPipelinePerformer, setSelectedPipelinePerformer] = useState< const [selectedPipelinePerformer, setSelectedPipelinePerformer] = useState<
string | null string | null
>(null); >(null);
@ -70,16 +71,16 @@ export const AmoCRMModal: FC<IntegrationsModalProps> = ({
string | null string | null
>(null); >(null);
const [questionEntity, setQuestionEntity] = useState<TQuestionEntity>({ const [questionEntity, setQuestionEntity] = useState<TQuestionEntity>({
deal: [], Lead: [],
contacts: [], Contact: [],
company: [], Company: [],
buyers: [], Customer: [],
}); });
const [tags, setTags] = useState<TTags>({ const [tags, setTags] = useState<TTags>({
deal: [], Lead: [],
contact: [], Contact: [],
company: [], Company: [],
buyer: [], Customer: [],
}); });
console.log(questionEntity) console.log(questionEntity)
console.log(tags) console.log(tags)
@ -101,12 +102,14 @@ export const AmoCRMModal: FC<IntegrationsModalProps> = ({
const [settingsResponse, error] = await getIntegrationRules(quizID.toString()); const [settingsResponse, error] = await getIntegrationRules(quizID.toString());
if (error) { if (error) {
if (!error.includes("Not Found")) enqueueSnackbar(error) if (error === "first") setFirstRules(true);
setIntegrationRules(null); if (!error.includes("Not Found") && !error.includes("first")) enqueueSnackbar(error);
} }
if (settingsResponse) { if (settingsResponse) {
setIntegrationRules(settingsResponse); console.log(settingsResponse);
setFirstRules(false);
} }
}; };
fetchAccount(); fetchAccount();
@ -121,8 +124,53 @@ export const AmoCRMModal: FC<IntegrationsModalProps> = ({
setStep((prevState) => prevState - 1); setStep((prevState) => prevState - 1);
}; };
const handleSave = () => { const handleSave = () => {
handleCloseModal(); console.log("На отправку")
setStep(1); console.log({
PerformerID: selectedDealPerformer,
PipelineID: selectedPipeline,
StepID: selectedStep,
Fieldsrule: {
...questionEntity
},
TagsToAdd: {
...tags
}
})
if (quizID === undefined) return
if (selectedPipeline?.toString().length === 0) return enqueueSnackbar("Выберите воронку")
if (selectedPipeline?.toString().length === 0) return enqueueSnackbar("Выберите этап воронки")
if (firstRules) {
setIntegrationRules(quizID.toString(), {
PerformerID: Number(selectedDealPerformer),
PipelineID: Number(selectedPipeline),
StepID: Number(selectedStep),
Fieldsrule: {
...questionEntity
},
TagsToAdd: {
...tags
}
})
} else {
const body = {
Fieldsrule: {
...questionEntity
},
TagsToAdd: {
...tags
}
};
if (selectedDealPerformer?.toString() > 0) body.PerformerID = Number(selectedDealPerformer)
if (selectedPipeline?.toString() > 0) body.PipelineID = Number(selectedPipeline)
if (selectedStep?.toString() > 0) body.StepID = Number(selectedStep)
updateIntegrationRules(quizID.toString(), body)
}
// handleCloseModal();
// setStep(1);
}; };
const steps = useMemo( const steps = useMemo(
() => [ () => [
@ -147,8 +195,9 @@ export const AmoCRMModal: FC<IntegrationsModalProps> = ({
<AmoStep2 <AmoStep2
handlePrevStep={handlePrevStep} handlePrevStep={handlePrevStep}
handleNextStep={handleNextStep} handleNextStep={handleNextStep}
selectedPipelinePerformer={selectedPipelinePerformer} selectedPipelinePerformer={selectedDealPerformer}
setSelectedPipelinePerformer={setSelectedPipelinePerformer} setSelectedPipelinePerformer={setSelectedDealPerformer}
setSelectedDealPerformer={setSelectedDealPerformer}
selectedPipeline={selectedPipeline} selectedPipeline={selectedPipeline}
setSelectedPipeline={setSelectedPipeline} setSelectedPipeline={setSelectedPipeline}
/> />
@ -161,8 +210,8 @@ export const AmoCRMModal: FC<IntegrationsModalProps> = ({
<AmoStep3 <AmoStep3
handlePrevStep={handlePrevStep} handlePrevStep={handlePrevStep}
handleNextStep={handleNextStep} handleNextStep={handleNextStep}
selectedStepsPerformer={selectedStepsPerformer} selectedStepsPerformer={selectedDealPerformer}
setSelectedStepsPerformer={setSelectedStepsPerformer} setSelectedStepsPerformer={setSelectedDealPerformer}
selectedStep={selectedStep} selectedStep={selectedStep}
setSelectedStep={setSelectedStep} setSelectedStep={setSelectedStep}
pipelineId={selectedPipeline} pipelineId={selectedPipeline}
@ -186,7 +235,7 @@ export const AmoCRMModal: FC<IntegrationsModalProps> = ({
isSettingsAvailable: true, isSettingsAvailable: true,
component: ( component: (
<AmoStep6 <AmoStep6
tagsNames={tags} tagsNames={tags}
handlePrevStep={handlePrevStep} handlePrevStep={handlePrevStep}
handleNextStep={handleNextStep} handleNextStep={handleNextStep}
setTagsNames={setTags} setTagsNames={setTags}
@ -289,8 +338,8 @@ export const AmoCRMModal: FC<IntegrationsModalProps> = ({
startRemoveAccount={() => setIsRemoveAccount(true)} startRemoveAccount={() => setIsRemoveAccount(true)}
/> />
{isRemoveAccount && ( {isRemoveAccount && (
<AmoRemoveAccount <AmoRemoveAccount
stopThisPage={() => setIsRemoveAccount(false)} stopThisPage={() => setIsRemoveAccount(false)}
/> />
)} )}
{isSettingsBlock && ( {isSettingsBlock && (

@ -11,6 +11,7 @@ type AmoStep2Props = {
setSelectedPipelinePerformer: (value: string | null) => void; setSelectedPipelinePerformer: (value: string | null) => void;
selectedPipeline: string | null; selectedPipeline: string | null;
setSelectedPipeline: (value: string | null) => void; setSelectedPipeline: (value: string | null) => void;
}; };
export const AmoStep2: FC<AmoStep2Props> = ({ export const AmoStep2: FC<AmoStep2Props> = ({

@ -38,7 +38,7 @@ export const AmoStep6: FC<Props> = ({
setTagsNames((prevState) => ({ setTagsNames((prevState) => ({
...prevState, ...prevState,
[activeItem]: [...prevState[activeItem as TagKeys], selectedValue], [activeItem]: [...prevState[activeItem as TagKeys], Number(selectedValue)],
})); }));
}, [activeItem, setTagsNames, selectedValue]); }, [activeItem, setTagsNames, selectedValue]);

@ -40,7 +40,7 @@ export const AmoStep7: FC<Props> = ({
setQuestionEntity((prevState) => ({ setQuestionEntity((prevState) => ({
...prevState, ...prevState,
[activeItem]: [...prevState[activeItem as TitleKeys], selectedValue], [activeItem]: [...prevState[activeItem as TitleKeys], Number(selectedValue)],
})); }));
}, [activeItem, setQuestionEntity, selectedValue]); }, [activeItem, setQuestionEntity, selectedValue]);
@ -50,7 +50,7 @@ export const AmoStep7: FC<Props> = ({
type !== "result" type !== "result"
&& type !== null) && type !== null)
.map(({ backendId, title }) => ({ .map(({ backendId, title }) => ({
backendId: backendId.toString(), backendId: backendId,
title title
})), })),
[], [],
@ -59,7 +59,6 @@ export const AmoStep7: FC<Props> = ({
const translated = {} as TQuestionEntity; const translated = {} as TQuestionEntity;
for (let key in questionEntity) { for (let key in questionEntity) {
// /* ... делать что-то с obj[key] ... */
translated[key] = questionEntity[key].map((id) => translated[key] = questionEntity[key].map((id) =>
questions.find((q) => q.backendId === Number(id))?.title || id questions.find((q) => q.backendId === Number(id))?.title || id
) )

@ -15,13 +15,10 @@ export const Item: FC<ItemProps> = ({ title, onAddBtnClick, data }) => {
console.log("title") console.log("title")
console.log(data) console.log(data)
const titleDictionary = { const titleDictionary = {
contact: "Контакт", Company: "Компания",
company: "Компания", Lead: "Сделка",
deal: "Сделка", Contact: "Контакты",
buyer: "Покупатель", Customer: "Покупатели",
contacts: "Контакты",
users: "Пользователи",
buyers: "Покупатели",
}; };
const translatedTitle = titleDictionary[title]; const translatedTitle = titleDictionary[title];

@ -4,7 +4,7 @@ import { StepButtonsBlock } from "../../StepButtonsBlock/StepButtonsBlock";
import { FC } from "react"; import { FC } from "react";
import { TQuestionEntity } from "../../AmoCRMModal"; import { TQuestionEntity } from "../../AmoCRMModal";
type TitleKeys = "contacts" | "company" | "deal" | "buyers"; type TitleKeys = "Contact" | "Company" | "Lead" | "Customer";
type ItemDetailsViewProps = { type ItemDetailsViewProps = {
setIsSelection: (value: boolean) => void; setIsSelection: (value: boolean) => void;