- reapply proper prettier formatting.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
This commit is contained in:
@@ -1,35 +1,51 @@
|
||||
import { DownCircleFilled } from "@ant-design/icons";
|
||||
import { useApolloClient, useMutation } from "@apollo/client";
|
||||
import { Button, Card, Dropdown, Form, Input, Modal, notification, Popconfirm, Popover, Select, Space } from "antd";
|
||||
import React, { useMemo, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { connect } from "react-redux";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { auth, logImEXEvent } from "../../firebase/firebase.utils";
|
||||
import { CANCEL_APPOINTMENTS_BY_JOB_ID, INSERT_MANUAL_APPT } from "../../graphql/appointments.queries";
|
||||
import { DELETE_JOB, UPDATE_JOB, VOID_JOB } from "../../graphql/jobs.queries";
|
||||
import { insertAuditTrail } from "../../redux/application/application.actions";
|
||||
import { selectJobReadOnly } from "../../redux/application/application.selectors";
|
||||
import { setModalContext } from "../../redux/modals/modals.actions";
|
||||
import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors";
|
||||
import {DownCircleFilled} from "@ant-design/icons";
|
||||
import {useApolloClient, useMutation} from "@apollo/client";
|
||||
import {
|
||||
Button,
|
||||
Card,
|
||||
Dropdown,
|
||||
Form,
|
||||
Input,
|
||||
Modal,
|
||||
notification,
|
||||
Popconfirm,
|
||||
Popover,
|
||||
Select,
|
||||
Space
|
||||
} from "antd";
|
||||
import React, {useMemo, useState} from "react";
|
||||
import {useTranslation} from "react-i18next";
|
||||
import {connect} from "react-redux";
|
||||
import {Link, useNavigate} from "react-router-dom";
|
||||
import {createStructuredSelector} from "reselect";
|
||||
import {auth, logImEXEvent} from "../../firebase/firebase.utils";
|
||||
import {
|
||||
CANCEL_APPOINTMENTS_BY_JOB_ID,
|
||||
INSERT_MANUAL_APPT
|
||||
} from "../../graphql/appointments.queries";
|
||||
import {DELETE_JOB, UPDATE_JOB, VOID_JOB} from "../../graphql/jobs.queries";
|
||||
import {insertAuditTrail} from "../../redux/application/application.actions";
|
||||
import {selectJobReadOnly} from "../../redux/application/application.selectors";
|
||||
import {setModalContext} from "../../redux/modals/modals.actions";
|
||||
import {selectBodyshop, selectCurrentUser} from "../../redux/user/user.selectors";
|
||||
import AuditTrailMapping from "../../utils/AuditTrailMappings";
|
||||
import RbacWrapper from "../rbac-wrapper/rbac-wrapper.component";
|
||||
import AddToProduction from "./jobs-detail-header-actions.addtoproduction.util";
|
||||
import DuplicateJob from "./jobs-detail-header-actions.duplicate.util";
|
||||
import axios from "axios";
|
||||
import { setEmailOptions } from "../../redux/email/email.actions";
|
||||
import { openChatByPhone, setMessage } from "../../redux/messaging/messaging.actions";
|
||||
import { GET_CURRENT_QUESTIONSET_ID, INSERT_CSI } from "../../graphql/csi.queries";
|
||||
import { TemplateList } from "../../utils/TemplateConstants";
|
||||
import {setEmailOptions} from "../../redux/email/email.actions";
|
||||
import {openChatByPhone, setMessage} from "../../redux/messaging/messaging.actions";
|
||||
import {GET_CURRENT_QUESTIONSET_ID, INSERT_CSI} from "../../graphql/csi.queries";
|
||||
import {TemplateList} from "../../utils/TemplateConstants";
|
||||
import parsePhoneNumber from "libphonenumber-js";
|
||||
import { HasFeatureAccess } from "../feature-wrapper/feature-wrapper.component";
|
||||
import { DateTimeFormatter } from "../../utils/DateFormatter";
|
||||
import {HasFeatureAccess} from "../feature-wrapper/feature-wrapper.component";
|
||||
import {DateTimeFormatter} from "../../utils/DateFormatter";
|
||||
import FormDateTimePickerComponent from "../form-date-time-picker/form-date-time-picker.component";
|
||||
import dayjs from "../../utils/day";
|
||||
import { useSplitTreatments } from "@splitsoftware/splitio-react";
|
||||
import {useSplitTreatments} from "@splitsoftware/splitio-react";
|
||||
import InstanceRenderManager from "../../utils/instanceRenderMgr";
|
||||
import JobsDetailHeaderActionsToggleProduction from "./jobs-detail-header-actions.toggle-production";
|
||||
import JobsDetailHeaderActionsToggleProduction
|
||||
from "./jobs-detail-header-actions.toggle-production";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop,
|
||||
@@ -38,38 +54,57 @@ const mapStateToProps = createStructuredSelector({
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
setScheduleContext: (context) => dispatch(setModalContext({ context: context, modal: "schedule" })),
|
||||
setBillEnterContext: (context) => dispatch(setModalContext({ context: context, modal: "billEnter" })),
|
||||
setPaymentContext: (context) => dispatch(setModalContext({ context: context, modal: "payment" })),
|
||||
setJobCostingContext: (context) => dispatch(setModalContext({ context: context, modal: "jobCosting" })),
|
||||
setTimeTicketContext: (context) => dispatch(setModalContext({ context: context, modal: "timeTicket" })),
|
||||
setCardPaymentContext: (context) => dispatch(setModalContext({ context: context, modal: "cardPayment" })),
|
||||
insertAuditTrail: ({ jobid, operation, type }) => dispatch(insertAuditTrail({ jobid, operation, type })),
|
||||
setTimeTicketTaskContext: (context) => dispatch(setModalContext({ context: context, modal: "timeTicketTask" })),
|
||||
setScheduleContext: (context) => dispatch(setModalContext({context: context, modal: "schedule"})),
|
||||
setBillEnterContext: (context) => dispatch(setModalContext({
|
||||
context: context,
|
||||
modal: "billEnter"
|
||||
})),
|
||||
setPaymentContext: (context) => dispatch(setModalContext({context: context, modal: "payment"})),
|
||||
setJobCostingContext: (context) => dispatch(setModalContext({
|
||||
context: context,
|
||||
modal: "jobCosting"
|
||||
})),
|
||||
setTimeTicketContext: (context) => dispatch(setModalContext({
|
||||
context: context,
|
||||
modal: "timeTicket"
|
||||
})),
|
||||
setCardPaymentContext: (context) => dispatch(setModalContext({
|
||||
context: context,
|
||||
modal: "cardPayment"
|
||||
})),
|
||||
insertAuditTrail: ({jobid, operation, type}) => dispatch(insertAuditTrail({
|
||||
jobid,
|
||||
operation,
|
||||
type
|
||||
})),
|
||||
setTimeTicketTaskContext: (context) => dispatch(setModalContext({
|
||||
context: context,
|
||||
modal: "timeTicketTask"
|
||||
})),
|
||||
setEmailOptions: (e) => dispatch(setEmailOptions(e)),
|
||||
openChatByPhone: (phone) => dispatch(openChatByPhone(phone)),
|
||||
setMessage: (text) => dispatch(setMessage(text))
|
||||
});
|
||||
|
||||
export function JobsDetailHeaderActions({
|
||||
job,
|
||||
bodyshop,
|
||||
currentUser,
|
||||
refetch,
|
||||
setScheduleContext,
|
||||
setBillEnterContext,
|
||||
setPaymentContext,
|
||||
setJobCostingContext,
|
||||
jobRO,
|
||||
setTimeTicketContext,
|
||||
setCardPaymentContext,
|
||||
insertAuditTrail,
|
||||
setEmailOptions,
|
||||
openChatByPhone,
|
||||
setMessage,
|
||||
setTimeTicketTaskContext
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
job,
|
||||
bodyshop,
|
||||
currentUser,
|
||||
refetch,
|
||||
setScheduleContext,
|
||||
setBillEnterContext,
|
||||
setPaymentContext,
|
||||
setJobCostingContext,
|
||||
jobRO,
|
||||
setTimeTicketContext,
|
||||
setCardPaymentContext,
|
||||
insertAuditTrail,
|
||||
setEmailOptions,
|
||||
openChatByPhone,
|
||||
setMessage,
|
||||
setTimeTicketTaskContext
|
||||
}) {
|
||||
const {t} = useTranslation();
|
||||
const client = useApolloClient();
|
||||
const history = useNavigate();
|
||||
const [form] = Form.useForm();
|
||||
@@ -83,7 +118,7 @@ export function JobsDetailHeaderActions({
|
||||
const [cancelAllAppointments] = useMutation(CANCEL_APPOINTMENTS_BY_JOB_ID);
|
||||
|
||||
const {
|
||||
treatments: { ImEXPay }
|
||||
treatments: {ImEXPay}
|
||||
} = useSplitTreatments({
|
||||
attributes: {},
|
||||
names: ["ImEXPay"],
|
||||
@@ -117,7 +152,7 @@ export function JobsDetailHeaderActions({
|
||||
DuplicateJob(
|
||||
client,
|
||||
job.id,
|
||||
{ defaultOpenStatus: bodyshop.md_ro_statuses.default_imported },
|
||||
{defaultOpenStatus: bodyshop.md_ro_statuses.default_imported},
|
||||
(newJobId) => {
|
||||
history(`/manage/jobs/${newJobId}`);
|
||||
notification["success"]({
|
||||
@@ -128,7 +163,7 @@ export function JobsDetailHeaderActions({
|
||||
);
|
||||
|
||||
const handleDuplicateConfirm = () =>
|
||||
DuplicateJob(client, job.id, { defaultOpenStatus: bodyshop.md_ro_statuses.default_imported }, (newJobId) => {
|
||||
DuplicateJob(client, job.id, {defaultOpenStatus: bodyshop.md_ro_statuses.default_imported}, (newJobId) => {
|
||||
history(`/manage/jobs/${newJobId}`);
|
||||
notification["success"]({
|
||||
message: t("jobs.successes.duplicated")
|
||||
@@ -142,7 +177,7 @@ export function JobsDetailHeaderActions({
|
||||
try {
|
||||
insertAppointment({
|
||||
variables: {
|
||||
apt: { ...values, isintake: false, jobid: job.id, bodyshopid: bodyshop.id }
|
||||
apt: {...values, isintake: false, jobid: job.id, bodyshopid: bodyshop.id}
|
||||
},
|
||||
refetchQueries: ["QUERY_ALL_ACTIVE_APPOINTMENTS"]
|
||||
});
|
||||
@@ -159,7 +194,7 @@ export function JobsDetailHeaderActions({
|
||||
|
||||
const handleDeleteJob = async () => {
|
||||
//delete the job.
|
||||
const result = await deleteJob({ variables: { id: job.id } });
|
||||
const result = await deleteJob({variables: {id: job.id}});
|
||||
|
||||
if (!!!result.errors) {
|
||||
notification["success"]({
|
||||
@@ -220,7 +255,7 @@ export function JobsDetailHeaderActions({
|
||||
});
|
||||
|
||||
if (!!!result.errors) {
|
||||
notification["success"]({ message: t("csi.successes.created") });
|
||||
notification["success"]({message: t("csi.successes.created")});
|
||||
} else {
|
||||
notification["error"]({
|
||||
message: t("csi.errors.creating", {
|
||||
@@ -375,7 +410,7 @@ export function JobsDetailHeaderActions({
|
||||
try {
|
||||
QbXmlResponse = await axios.post(
|
||||
"/accounting/qbxml/receivables",
|
||||
{ jobIds: [job.id], custDataOnly: true },
|
||||
{jobIds: [job.id], custDataOnly: true},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${await auth.currentUser.getIdToken()}`
|
||||
@@ -484,7 +519,7 @@ export function JobsDetailHeaderActions({
|
||||
setIsCancelScheduleModalVisible(false);
|
||||
};
|
||||
|
||||
const handleLostSaleFinish = async ({ lost_sale_reason }) => {
|
||||
const handleLostSaleFinish = async ({lost_sale_reason}) => {
|
||||
const jobUpdate = await cancelAllAppointments({
|
||||
variables: {
|
||||
jobid: job.id,
|
||||
@@ -524,10 +559,10 @@ export function JobsDetailHeaderActions({
|
||||
}
|
||||
]}
|
||||
>
|
||||
<Input />
|
||||
<Input/>
|
||||
</Form.Item>
|
||||
<Form.Item label={t("appointments.fields.note")} name="note">
|
||||
<Input />
|
||||
<Input/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={t("appointments.fields.start")}
|
||||
@@ -542,7 +577,7 @@ export function JobsDetailHeaderActions({
|
||||
<FormDateTimePickerComponent
|
||||
onBlur={() => {
|
||||
const start = form.getFieldValue("start");
|
||||
form.setFieldsValue({ end: start.add(30, "minutes") });
|
||||
form.setFieldsValue({end: start.add(30, "minutes")});
|
||||
}}
|
||||
/>
|
||||
</Form.Item>
|
||||
@@ -554,10 +589,10 @@ export function JobsDetailHeaderActions({
|
||||
required: true
|
||||
//message: t("general.validation.required"),
|
||||
},
|
||||
({ getFieldValue }) => ({
|
||||
({getFieldValue}) => ({
|
||||
async validator(rule, value) {
|
||||
if (value) {
|
||||
const { start } = form.getFieldsValue();
|
||||
const {start} = form.getFieldsValue();
|
||||
if (dayjs(start).isAfter(dayjs(value))) {
|
||||
return Promise.reject(t("employees.labels.endmustbeafterstart"));
|
||||
} else {
|
||||
@@ -570,7 +605,7 @@ export function JobsDetailHeaderActions({
|
||||
})
|
||||
]}
|
||||
>
|
||||
<FormDateTimePickerComponent />
|
||||
<FormDateTimePickerComponent/>
|
||||
</Form.Item>
|
||||
<Form.Item label={t("appointments.fields.color")} name="color">
|
||||
<Select>
|
||||
@@ -601,7 +636,7 @@ export function JobsDetailHeaderActions({
|
||||
onClick: () => {
|
||||
logImEXEvent("job_header_schedule");
|
||||
setScheduleContext({
|
||||
actions: { refetch: refetch },
|
||||
actions: {refetch: refetch},
|
||||
context: {
|
||||
jobId: job.id,
|
||||
job: job,
|
||||
@@ -645,7 +680,8 @@ export function JobsDetailHeaderActions({
|
||||
{
|
||||
key: "checklist",
|
||||
disabled: !job.converted,
|
||||
label: <Link to={`/manage/jobs/${job.id}/checklist`}>{t("jobs.actions.viewchecklist")}</Link>
|
||||
label: <Link
|
||||
to={`/manage/jobs/${job.id}/checklist`}>{t("jobs.actions.viewchecklist")}</Link>
|
||||
}
|
||||
],
|
||||
rome: "USE_IMEX",
|
||||
@@ -653,35 +689,35 @@ export function JobsDetailHeaderActions({
|
||||
{
|
||||
key: "toggleproduction",
|
||||
disabled: !job.converted || jobRO,
|
||||
label: <JobsDetailHeaderActionsToggleProduction job={job} refetch={refetch} />
|
||||
label: <JobsDetailHeaderActionsToggleProduction job={job} refetch={refetch}/>
|
||||
}
|
||||
]
|
||||
}),
|
||||
...(InstanceRenderManager({
|
||||
imex: true,
|
||||
rome: "USE_IMEX",
|
||||
promanager: HasFeatureAccess({ featureName: "timetickets", bodyshop })
|
||||
promanager: HasFeatureAccess({featureName: "timetickets", bodyshop})
|
||||
})
|
||||
? [
|
||||
{
|
||||
key: "entertimetickets",
|
||||
disabled: !job.converted || (!bodyshop.tt_allow_post_to_invoiced && job.date_invoiced),
|
||||
label: t("timetickets.actions.enter"),
|
||||
onClick: () => {
|
||||
logImEXEvent("job_header_enter_time_ticekts");
|
||||
{
|
||||
key: "entertimetickets",
|
||||
disabled: !job.converted || (!bodyshop.tt_allow_post_to_invoiced && job.date_invoiced),
|
||||
label: t("timetickets.actions.enter"),
|
||||
onClick: () => {
|
||||
logImEXEvent("job_header_enter_time_ticekts");
|
||||
|
||||
setTimeTicketContext({
|
||||
actions: {},
|
||||
context: {
|
||||
jobId: job.id,
|
||||
created_by: currentUser.displayName
|
||||
? currentUser.email.concat(" | ", currentUser.displayName)
|
||||
: currentUser.email
|
||||
}
|
||||
});
|
||||
}
|
||||
setTimeTicketContext({
|
||||
actions: {},
|
||||
context: {
|
||||
jobId: job.id,
|
||||
created_by: currentUser.displayName
|
||||
? currentUser.email.concat(" | ", currentUser.displayName)
|
||||
: currentUser.email
|
||||
}
|
||||
});
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
: [])
|
||||
];
|
||||
|
||||
@@ -692,7 +728,7 @@ export function JobsDetailHeaderActions({
|
||||
onClick: () => {
|
||||
setTimeTicketTaskContext({
|
||||
actions: {},
|
||||
context: { jobid: job.id }
|
||||
context: {jobid: job.id}
|
||||
});
|
||||
},
|
||||
label: t("timetickets.actions.claimtasks")
|
||||
@@ -708,7 +744,7 @@ export function JobsDetailHeaderActions({
|
||||
|
||||
setPaymentContext({
|
||||
actions: {},
|
||||
context: { jobid: job.id }
|
||||
context: {jobid: job.id}
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -723,18 +759,18 @@ export function JobsDetailHeaderActions({
|
||||
|
||||
setCardPaymentContext({
|
||||
actions: {},
|
||||
context: { jobid: job.id }
|
||||
context: {jobid: job.id}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (HasFeatureAccess({ featureName: "courtesycars" })) {
|
||||
if (HasFeatureAccess({featureName: "courtesycars"})) {
|
||||
menuItems.push({
|
||||
key: "cccontract",
|
||||
disabled: jobRO || !job.converted,
|
||||
label: (
|
||||
<Link state={{ jobId: job.id }} to="/manage/courtesycars/contracts/new">
|
||||
<Link state={{jobId: job.id}} to="/manage/courtesycars/contracts/new">
|
||||
{t("menus.jobsactions.newcccontract")}
|
||||
</Link>
|
||||
)
|
||||
@@ -744,17 +780,17 @@ export function JobsDetailHeaderActions({
|
||||
menuItems.push(
|
||||
job.inproduction
|
||||
? {
|
||||
key: "removefromproduction",
|
||||
disabled: !job.converted,
|
||||
label: t("jobs.actions.removefromproduction"),
|
||||
onClick: () => AddToProduction(client, job.id, refetch, true)
|
||||
}
|
||||
key: "removefromproduction",
|
||||
disabled: !job.converted,
|
||||
label: t("jobs.actions.removefromproduction"),
|
||||
onClick: () => AddToProduction(client, job.id, refetch, true)
|
||||
}
|
||||
: {
|
||||
key: "addtoproduction",
|
||||
disabled: !job.converted,
|
||||
label: t("jobs.actions.addtoproduction"),
|
||||
onClick: () => AddToProduction(client, job.id, refetch)
|
||||
}
|
||||
key: "addtoproduction",
|
||||
disabled: !job.converted,
|
||||
label: t("jobs.actions.addtoproduction"),
|
||||
onClick: () => AddToProduction(client, job.id, refetch)
|
||||
}
|
||||
);
|
||||
|
||||
menuItems.push(
|
||||
@@ -810,25 +846,25 @@ export function JobsDetailHeaderActions({
|
||||
...(InstanceRenderManager({
|
||||
imex: true,
|
||||
rome: true,
|
||||
promanager: HasFeatureAccess({ featureName: "bills", bodyshop })
|
||||
promanager: HasFeatureAccess({featureName: "bills", bodyshop})
|
||||
})
|
||||
? [
|
||||
{
|
||||
key: "postbills",
|
||||
disabled: !job.converted,
|
||||
label: t("jobs.actions.postbills"),
|
||||
onClick: () => {
|
||||
logImEXEvent("job_header_enter_bills");
|
||||
{
|
||||
key: "postbills",
|
||||
disabled: !job.converted,
|
||||
label: t("jobs.actions.postbills"),
|
||||
onClick: () => {
|
||||
logImEXEvent("job_header_enter_bills");
|
||||
|
||||
setBillEnterContext({
|
||||
actions: { refetch: refetch },
|
||||
context: {
|
||||
job: job
|
||||
}
|
||||
});
|
||||
}
|
||||
setBillEnterContext({
|
||||
actions: {refetch: refetch},
|
||||
context: {
|
||||
job: job
|
||||
}
|
||||
});
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
: []),
|
||||
|
||||
{
|
||||
@@ -839,7 +875,7 @@ export function JobsDetailHeaderActions({
|
||||
const result = await updateJob({
|
||||
variables: {
|
||||
jobId: job.id,
|
||||
job: { queued_for_parts: true }
|
||||
job: {queued_for_parts: true}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -889,7 +925,7 @@ export function JobsDetailHeaderActions({
|
||||
InstanceRenderManager({
|
||||
imex: true,
|
||||
rome: true,
|
||||
promanager: HasFeatureAccess({ featureName: "export", bodyshop })
|
||||
promanager: HasFeatureAccess({featureName: "export", bodyshop})
|
||||
})
|
||||
) {
|
||||
menuItems.push({
|
||||
@@ -900,7 +936,7 @@ export function JobsDetailHeaderActions({
|
||||
});
|
||||
}
|
||||
|
||||
if (HasFeatureAccess({ featureName: "csi", bodyshop })) {
|
||||
if (HasFeatureAccess({featureName: "csi", bodyshop})) {
|
||||
const children = [
|
||||
{
|
||||
key: "email",
|
||||
@@ -930,20 +966,20 @@ export function JobsDetailHeaderActions({
|
||||
...job.csiinvites.map((item, idx) => {
|
||||
return item.completedon
|
||||
? {
|
||||
key: idx,
|
||||
label: (
|
||||
<Link to={`/manage/shop/csi?responseid=${item.id}`}>
|
||||
<DateTimeFormatter>{item.completedon}</DateTimeFormatter>
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
key: idx,
|
||||
label: (
|
||||
<Link to={`/manage/shop/csi?responseid=${item.id}`}>
|
||||
<DateTimeFormatter>{item.completedon}</DateTimeFormatter>
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
: {
|
||||
key: idx,
|
||||
onClick: () => {
|
||||
navigator.clipboard.writeText(`${window.location.protocol}//${window.location.host}/csi/${item.id}`);
|
||||
},
|
||||
label: t("general.actions.copylink")
|
||||
};
|
||||
key: idx,
|
||||
onClick: () => {
|
||||
navigator.clipboard.writeText(`${window.location.protocol}//${window.location.host}/csi/${item.id}`);
|
||||
},
|
||||
label: t("general.actions.copylink")
|
||||
};
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -963,7 +999,7 @@ export function JobsDetailHeaderActions({
|
||||
logImEXEvent("job_header_job_costing");
|
||||
|
||||
setJobCostingContext({
|
||||
actions: { refetch: refetch },
|
||||
actions: {refetch: refetch},
|
||||
context: {
|
||||
jobId: job.id
|
||||
}
|
||||
@@ -1073,10 +1109,10 @@ export function JobsDetailHeaderActions({
|
||||
<Dropdown menu={menu} trigger={["click"]} key="changestatus">
|
||||
<Button>
|
||||
<span>{t("general.labels.actions")}</span>
|
||||
<DownCircleFilled />
|
||||
<DownCircleFilled/>
|
||||
</Button>
|
||||
</Dropdown>
|
||||
<Popover content={popOverContent} open={visibility} />
|
||||
<Popover content={popOverContent} open={visibility}/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user