From 0214df86fddd1a6191a5a4be91829f1ec4cba336 Mon Sep 17 00:00:00 2001 From: balaji-jr Date: Thu, 3 Oct 2024 16:47:28 +0530 Subject: [PATCH] support for tile duplication --- src/pages/Dashboards/Dashboard.tsx | 79 ++++++++++++++++++- src/pages/Dashboards/Tile.tsx | 13 ++- .../providers/DashboardsProvider.ts | 17 +++- 3 files changed, 102 insertions(+), 7 deletions(-) diff --git a/src/pages/Dashboards/Dashboard.tsx b/src/pages/Dashboards/Dashboard.tsx index f33b8882..9abc277a 100644 --- a/src/pages/Dashboards/Dashboard.tsx +++ b/src/pages/Dashboards/Dashboard.tsx @@ -1,4 +1,4 @@ -import { Box, Button, Divider, FileInput, Modal, Stack, Text } from '@mantine/core'; +import { Box, Button, Divider, FileInput, Modal, Stack, Text, TextInput } from '@mantine/core'; import Toolbar from './Toolbar'; import 'react-grid-layout/css/styles.css'; import 'react-resizable/css/styles.css'; @@ -20,10 +20,10 @@ import { useDashboardsQuery } from '@/hooks/useDashboards'; import Tile from './Tile'; import { Layout } from 'react-grid-layout'; import { useAppStore } from '@/layouts/MainLayout/providers/AppProvider'; -import { ImportDashboardType } from '@/@types/parseable/api/dashboards'; +import { EditTileType, ImportDashboardType, Tile as TileType } from '@/@types/parseable/api/dashboards'; import { templates } from './assets/templates'; -const { toggleCreateDashboardModal, toggleCreateTileModal, toggleDeleteTileModal, handlePaging, toggleImportDashboardModal } = +const { toggleCreateDashboardModal, toggleCreateTileModal, toggleDuplicateTileModal, toggleDeleteTileModal, handlePaging, toggleImportDashboardModal } = dashboardsStoreReducers; const TilesView = (props: { onLayoutChange: (layout: Layout[]) => void }) => { @@ -319,6 +319,78 @@ const NoTilesView = () => { ); }; +const findTileByTileId = (tiles: TileType[], tileId: string | null) => { + return _.find(tiles, tile => tile.tile_id === tileId) +} + +const DuplicateTileModal = () => { + const [duplicateTileModalOpen, setDashboardsStore] = useDashboardsStore(store => store.duplicateTileModalOpen) + const [editTileId] = useDashboardsStore(store => store.editTileId); + const [activeDashboard] = useDashboardsStore(store => store.activeDashboard) + const [inputValue, setInputValue] = useState(''); + const onClose = useCallback(() => { + setDashboardsStore((store) => toggleDuplicateTileModal(store, false, null)); + }, []); + + const handleInputChange = useCallback((e: React.ChangeEvent) => { + setInputValue(e.target.value); + }, []); + const { updateDashboard, isUpdatingDashboard } = useDashboardsQuery({}); + + const handleSubmit = useCallback(() => { + const currentTile = findTileByTileId(activeDashboard?.tiles || [], editTileId); + if (currentTile && activeDashboard) { + const currentOrder = currentTile.order; + const tempTiles = [...activeDashboard.tiles] as EditTileType[]; + const duplicatedTile = _.omit({ ...currentTile, name: inputValue }, 'tile_id'); + tempTiles.splice(currentOrder, 0, duplicatedTile); + const updatedTilesWithOrder = assignOrderToTiles(tempTiles); + return updateDashboard({ + dashboard: { ...activeDashboard, tiles: updatedTilesWithOrder }, + onSuccess: () => { + onClose(); + }, + }); + } + }, [inputValue, editTileId, activeDashboard]); + + useEffect(() => { + const currentTile = findTileByTileId(activeDashboard?.tiles || [], editTileId); + if (currentTile) { + setInputValue(currentTile?.name); + } + }, [editTileId]); + + return ( + Duplicate Tile}> + + + + + + + + + + + + + + + ); +}; + const Dashboard = () => { const [dashboards] = useDashboardsStore((store) => store.dashboards); const layoutRef = useRef([]); @@ -333,6 +405,7 @@ const Dashboard = () => { return ( + diff --git a/src/pages/Dashboards/Tile.tsx b/src/pages/Dashboards/Tile.tsx index 483b0692..2b3f6953 100644 --- a/src/pages/Dashboards/Tile.tsx +++ b/src/pages/Dashboards/Tile.tsx @@ -3,6 +3,7 @@ import classes from './styles/tile.module.css'; import { IconAlertTriangle, IconBraces, + IconCopyPlus, IconDotsVertical, IconGripVertical, IconPencil, @@ -71,7 +72,7 @@ const ParseableLogo = () => ( ); -const { toggleCreateTileModal, toggleDeleteTileModal } = dashboardsStoreReducers; +const { toggleCreateTileModal, toggleDeleteTileModal, toggleDuplicateTileModal } = dashboardsStoreReducers; const NoDataView = () => { return ( @@ -171,6 +172,10 @@ function TileControls(props: { tile: TileType; data: TileQueryResponse }) { setDashboardsStore((store) => toggleCreateTileModal(store, true, tile_id)); }, []); + const openDuplicateTileModal = useCallback(() => { + setDashboardsStore((store) => toggleDuplicateTileModal(store, true, tile_id)); + }, []); + const openDeleteModal = useCallback(() => { setDashboardsStore((store) => toggleDeleteTileModal(store, true, tile_id)); }, []); @@ -197,6 +202,12 @@ function TileControls(props: { tile: TileType; data: TileQueryResponse }) { leftSection={}> Edit + }> + Duplicate + { return _.chain(idsByOrder) @@ -15,7 +15,7 @@ export const sortTilesByOrder = (tiles: Tile[], idsByOrder: string[]): Tile[] => .value(); }; -export const assignOrderToTiles = (tiles: Tile[]) => { +export const assignOrderToTiles = (tiles: Tile[] | EditTileType[]) => { return _.map(tiles, (tile, index) => { return { ...tile, order: index + 1 }; }); @@ -77,6 +77,7 @@ type DashboardsStore = { editDashboardModalOpen: boolean; deleteDashboardModalOpen: boolean; createTileFormOpen: boolean; + duplicateTileModalOpen: boolean; vizEditorModalOpen: boolean; allowDrag: boolean; editTileId: string | null; @@ -99,6 +100,7 @@ const initialState: DashboardsStore = { deleteDashboardModalOpen: false, createTileFormOpen: false, vizEditorModalOpen: false, + duplicateTileModalOpen: false, allowDrag: false, editTileId: null, tilesData: {}, @@ -118,6 +120,7 @@ type DashboardsStoreReducers = { toggleEditDashboardModal: (store: DashboardsStore, val: boolean) => ReducerOutput; selectDashboard: (store: DashboardsStore, dashboardId?: string | null, dashboard?: Dashboard) => ReducerOutput; toggleCreateTileModal: (store: DashboardsStore, val: boolean, tileId?: string | null) => ReducerOutput; + toggleDuplicateTileModal: (store: DashboardsStore, val: boolean, tileId?: string | null) => ReducerOutput; toggleVizEditorModal: (store: DashboardsStore, val: boolean) => ReducerOutput; toggleAllowDrag: (store: DashboardsStore) => ReducerOutput; toggleDeleteDashboardModal: (store: DashboardsStore, val: boolean) => ReducerOutput; @@ -148,6 +151,13 @@ const toggleCreateTileModal = (_store: DashboardsStore, val: boolean, tileId: st }; }; +const toggleDuplicateTileModal = (_store: DashboardsStore, val: boolean, tileId: string | null = null) => { + return { + duplicateTileModalOpen: val, + editTileId: tileId, + }; +}; + const toggleVizEditorModal = (_store: DashboardsStore, val: boolean) => { return { vizEditorModalOpen: val, @@ -275,6 +285,7 @@ const dashboardsStoreReducers: DashboardsStoreReducers = { toggleImportTileModal, toggleImportDashboardModal, handlePaging, + toggleDuplicateTileModal }; export { DashbaordsProvider, useDashboardsStore, dashboardsStoreReducers };