2024-05-28 19:09:04 +05:30
|
|
|
import './GeneralSettings.styles.scss';
|
|
|
|
|
|
|
|
|
|
import { Col, Input, Select, Space, Typography } from 'antd';
|
2023-10-08 23:21:17 +05:30
|
|
|
import { SOMETHING_WENT_WRONG } from 'constants/api';
|
2022-09-09 17:43:25 +05:30
|
|
|
import AddTags from 'container/NewDashboard/DashboardSettings/General/AddTags';
|
2023-10-08 23:21:17 +05:30
|
|
|
import { useUpdateDashboard } from 'hooks/dashboard/useUpdateDashboard';
|
|
|
|
|
import { useNotifications } from 'hooks/useNotifications';
|
2024-05-28 19:09:04 +05:30
|
|
|
import { isEqual } from 'lodash-es';
|
|
|
|
|
import { Check, X } from 'lucide-react';
|
2023-10-08 23:21:17 +05:30
|
|
|
import { useDashboard } from 'providers/Dashboard/Dashboard';
|
2024-05-28 19:09:04 +05:30
|
|
|
import { useEffect, useState } from 'react';
|
2022-09-09 17:43:25 +05:30
|
|
|
import { useTranslation } from 'react-i18next';
|
|
|
|
|
|
|
|
|
|
import { Button } from './styles';
|
2024-05-28 19:09:04 +05:30
|
|
|
import { Base64Icons } from './utils';
|
|
|
|
|
|
|
|
|
|
const { Option } = Select;
|
2022-09-09 17:43:25 +05:30
|
|
|
|
2023-10-08 23:21:17 +05:30
|
|
|
function GeneralDashboardSettings(): JSX.Element {
|
|
|
|
|
const { selectedDashboard, setSelectedDashboard } = useDashboard();
|
|
|
|
|
|
|
|
|
|
const updateDashboardMutation = useUpdateDashboard();
|
|
|
|
|
|
|
|
|
|
const selectedData = selectedDashboard?.data;
|
2022-09-09 17:43:25 +05:30
|
|
|
|
2024-05-28 19:09:04 +05:30
|
|
|
const { title = '', tags = [], description = '', image = Base64Icons[0] } =
|
|
|
|
|
selectedData || {};
|
2022-09-09 17:43:25 +05:30
|
|
|
|
|
|
|
|
const [updatedTitle, setUpdatedTitle] = useState<string>(title);
|
|
|
|
|
const [updatedTags, setUpdatedTags] = useState<string[]>(tags || []);
|
|
|
|
|
const [updatedDescription, setUpdatedDescription] = useState(
|
|
|
|
|
description || '',
|
|
|
|
|
);
|
2024-05-28 19:09:04 +05:30
|
|
|
const [updatedImage, setUpdatedImage] = useState<string>(image);
|
|
|
|
|
const [numberOfUnsavedChanges, setNumberOfUnsavedChanges] = useState<number>(
|
|
|
|
|
0,
|
|
|
|
|
);
|
2022-09-09 17:43:25 +05:30
|
|
|
|
|
|
|
|
const { t } = useTranslation('common');
|
|
|
|
|
|
2023-10-08 23:21:17 +05:30
|
|
|
const { notifications } = useNotifications();
|
|
|
|
|
|
|
|
|
|
const onSaveHandler = (): void => {
|
|
|
|
|
if (!selectedDashboard) return;
|
|
|
|
|
|
|
|
|
|
updateDashboardMutation.mutateAsync(
|
|
|
|
|
{
|
|
|
|
|
...selectedDashboard,
|
2022-09-09 17:43:25 +05:30
|
|
|
data: {
|
2023-10-08 23:21:17 +05:30
|
|
|
...selectedDashboard.data,
|
2022-09-09 17:43:25 +05:30
|
|
|
description: updatedDescription,
|
|
|
|
|
tags: updatedTags,
|
|
|
|
|
title: updatedTitle,
|
2024-05-28 19:09:04 +05:30
|
|
|
image: updatedImage,
|
2022-09-09 17:43:25 +05:30
|
|
|
},
|
|
|
|
|
},
|
2023-10-08 23:21:17 +05:30
|
|
|
{
|
|
|
|
|
onSuccess: (updatedDashboard) => {
|
|
|
|
|
if (updatedDashboard.payload) {
|
|
|
|
|
setSelectedDashboard(updatedDashboard.payload);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
onError: () => {
|
|
|
|
|
notifications.error({
|
|
|
|
|
message: SOMETHING_WENT_WRONG,
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
};
|
2022-09-09 17:43:25 +05:30
|
|
|
|
2024-05-28 19:09:04 +05:30
|
|
|
useEffect(() => {
|
|
|
|
|
let numberOfUnsavedChanges = 0;
|
|
|
|
|
if (!isEqual(updatedTitle, selectedData?.title)) {
|
|
|
|
|
numberOfUnsavedChanges += 1;
|
|
|
|
|
}
|
|
|
|
|
if (!isEqual(updatedDescription, selectedData?.description)) {
|
|
|
|
|
numberOfUnsavedChanges += 1;
|
|
|
|
|
}
|
|
|
|
|
if (!isEqual(updatedTags, selectedData?.tags)) {
|
|
|
|
|
numberOfUnsavedChanges += 1;
|
|
|
|
|
}
|
|
|
|
|
if (!isEqual(updatedImage, selectedData?.image)) {
|
|
|
|
|
numberOfUnsavedChanges += 1;
|
|
|
|
|
}
|
|
|
|
|
setNumberOfUnsavedChanges(numberOfUnsavedChanges);
|
|
|
|
|
}, [
|
|
|
|
|
selectedData?.description,
|
|
|
|
|
selectedData?.image,
|
|
|
|
|
selectedData?.tags,
|
|
|
|
|
selectedData?.title,
|
|
|
|
|
updatedDescription,
|
|
|
|
|
updatedImage,
|
|
|
|
|
updatedTags,
|
|
|
|
|
updatedTitle,
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
const discardHandler = (): void => {
|
|
|
|
|
setUpdatedTitle(title);
|
|
|
|
|
setUpdatedImage(image);
|
|
|
|
|
setUpdatedTags(tags);
|
|
|
|
|
setUpdatedDescription(description);
|
|
|
|
|
};
|
|
|
|
|
|
2022-09-09 17:43:25 +05:30
|
|
|
return (
|
2024-05-28 19:09:04 +05:30
|
|
|
<div className="overview-content">
|
|
|
|
|
<Col className="overview-settings">
|
|
|
|
|
<Space
|
|
|
|
|
direction="vertical"
|
|
|
|
|
style={{
|
|
|
|
|
width: '100%',
|
|
|
|
|
display: 'flex',
|
|
|
|
|
flexDirection: 'column',
|
|
|
|
|
gap: '21px',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<div>
|
|
|
|
|
<Typography style={{ marginBottom: '0.5rem' }} className="dashboard-name">
|
|
|
|
|
Dashboard Name
|
|
|
|
|
</Typography>
|
|
|
|
|
<section className="name-icon-input">
|
|
|
|
|
<Select
|
|
|
|
|
defaultActiveFirstOption
|
|
|
|
|
data-testid="dashboard-image"
|
|
|
|
|
suffixIcon={null}
|
|
|
|
|
rootClassName="dashboard-image-input"
|
|
|
|
|
value={updatedImage}
|
|
|
|
|
onChange={(value: string): void => setUpdatedImage(value)}
|
|
|
|
|
>
|
|
|
|
|
{Base64Icons.map((icon) => (
|
|
|
|
|
<Option value={icon} key={icon}>
|
|
|
|
|
<img src={icon} alt="dashboard-icon" className="list-item-image" />
|
|
|
|
|
</Option>
|
|
|
|
|
))}
|
|
|
|
|
</Select>
|
|
|
|
|
<Input
|
|
|
|
|
data-testid="dashboard-name"
|
|
|
|
|
className="dashboard-name-input"
|
|
|
|
|
value={updatedTitle}
|
|
|
|
|
onChange={(e): void => setUpdatedTitle(e.target.value)}
|
|
|
|
|
/>
|
|
|
|
|
</section>
|
|
|
|
|
</div>
|
2022-09-09 17:43:25 +05:30
|
|
|
|
2024-05-28 19:09:04 +05:30
|
|
|
<div>
|
|
|
|
|
<Typography style={{ marginBottom: '0.5rem' }} className="dashboard-name">
|
|
|
|
|
Description
|
|
|
|
|
</Typography>
|
|
|
|
|
<Input.TextArea
|
|
|
|
|
data-testid="dashboard-desc"
|
|
|
|
|
rows={6}
|
|
|
|
|
value={updatedDescription}
|
|
|
|
|
className="description-text-area"
|
|
|
|
|
onChange={(e): void => setUpdatedDescription(e.target.value)}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
|
|
|
|
<Typography style={{ marginBottom: '0.5rem' }} className="dashboard-name">
|
|
|
|
|
Tags
|
|
|
|
|
</Typography>
|
|
|
|
|
<AddTags tags={updatedTags} setTags={setUpdatedTags} />
|
|
|
|
|
</div>
|
|
|
|
|
</Space>
|
|
|
|
|
</Col>
|
|
|
|
|
{numberOfUnsavedChanges > 0 && (
|
|
|
|
|
<div className="overview-settings-footer">
|
|
|
|
|
<div className="unsaved">
|
|
|
|
|
<div className="unsaved-dot" />
|
|
|
|
|
<Typography.Text className="unsaved-changes">
|
|
|
|
|
{numberOfUnsavedChanges} Unsaved change
|
|
|
|
|
</Typography.Text>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="footer-action-btns">
|
|
|
|
|
<Button
|
|
|
|
|
disabled={updateDashboardMutation.isLoading}
|
|
|
|
|
icon={<X size={14} />}
|
|
|
|
|
onClick={discardHandler}
|
|
|
|
|
type="text"
|
|
|
|
|
className="discard-btn"
|
|
|
|
|
>
|
|
|
|
|
Discard
|
|
|
|
|
</Button>
|
|
|
|
|
<Button
|
|
|
|
|
style={{
|
|
|
|
|
margin: '16px 0',
|
|
|
|
|
}}
|
|
|
|
|
disabled={updateDashboardMutation.isLoading}
|
|
|
|
|
loading={updateDashboardMutation.isLoading}
|
|
|
|
|
icon={<Check size={14} />}
|
|
|
|
|
data-testid="save-dashboard-config"
|
|
|
|
|
onClick={onSaveHandler}
|
|
|
|
|
type="primary"
|
|
|
|
|
className="save-btn"
|
|
|
|
|
>
|
|
|
|
|
{t('save')}
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
2022-09-09 17:43:25 +05:30
|
|
|
</div>
|
2024-05-28 19:09:04 +05:30
|
|
|
)}
|
|
|
|
|
</div>
|
2022-09-09 17:43:25 +05:30
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-08 23:21:17 +05:30
|
|
|
export default GeneralDashboardSettings;
|