Repository: lightdash/lightdash
Pull request #14488: feat: transfer to modal
Author: login: IrakliJani
Labels: name: released
Created: 2025-04-22T12:18:04Z | Merged: 2025-04-23T08:53:59Z

<!-- Thanks so much for your PR, your contribution is appreciated! ❤️ -->

Partially implements: https://github.com/lightdash/lightdash/issues/14420

### Description:


[CleanShot 2025-04-22 at 16.12.13.mp4 <span class="graphite__hidden">(uploaded via Graphite)</span> <img class="graphite__hidden" src="https://app.graphite.dev/api/v1/graphite/video/thumbnail/cOL6QbQzyaUdOs5psinD/e140beef-6f91-4737-bd72-41253f90bef1.mp4" />](https://app.graphite.dev/media/video/cOL6QbQzyaUdOs5psinD/e140beef-6f91-4737-bd72-41253f90bef1.mp4)

### Reviewer actions

- [ ] I have manually tested the changes in the preview environment
- [ ] I have reviewed the code
- [ ] I understand that "request changes" will block this PR from merging



Diff:
diff --git a/packages/frontend/src/components/common/MantineModal/index.tsx b/packages/frontend/src/components/common/MantineModal/index.tsx
index f62129463a8a3..31c95fd9d1989 100644
--- a/packages/frontend/src/components/common/MantineModal/index.tsx
+++ b/packages/frontend/src/components/common/MantineModal/index.tsx
@@ -20,7 +20,7 @@ const modalSizes = {
     lg: 480,
 } as const;
 
-type MantineModalProps = {
+export type MantineModalProps = {
     opened: boolean;
     onClose: () => void;
     title: string;
@@ -96,7 +96,7 @@ const MantineModal: React.FC<MantineModalProps> = ({
                     })}
                     {...modalBodyProps}
                 >
-                    <Stack p="xl" spacing="md">
+                    <Stack px="xl" py="md" spacing="md">
                         {children}
                     </Stack>
                 </Modal.Body>
diff --git a/packages/frontend/src/components/common/ResourceView/ResourceActionHandlers.tsx b/packages/frontend/src/components/common/ResourceView/ResourceActionHandlers.tsx
index cdf30b0e0043f..3d219ee4733e9 100644
--- a/packages/frontend/src/components/common/ResourceView/ResourceActionHandlers.tsx
+++ b/packages/frontend/src/components/common/ResourceView/ResourceActionHandlers.tsx
@@ -21,9 +21,11 @@ import { useChartPinningMutation } from '../../../hooks/pinning/useChartPinningM
 import { useDashboardPinningMutation } from '../../../hooks/pinning/useDashboardPinningMutation';
 import { useSpacePinningMutation } from '../../../hooks/pinning/useSpaceMutation';
 import { useMoveChartMutation } from '../../../hooks/useSavedQuery';
+import { useSpaceSummaries } from '../../../hooks/useSpaces';
 import AddTilesToDashboardModal from '../../SavedDashboards/AddTilesToDashboardModal';
 import SpaceActionModal from '../SpaceActionModal';
 import { ActionType } from '../SpaceActionModal/types';
+import TransferItemsModal from '../TransferItemsModal/TransferItemsModal';
 import ChartDeleteModal from '../modal/ChartDeleteModal';
 import ChartDuplicateModal from '../modal/ChartDuplicateModal';
 import ChartUpdateModal from '../modal/ChartUpdateModal';
@@ -45,6 +47,7 @@ const ResourceActionHandlers: FC<ResourceActionHandlersProps> = ({
     onAction,
 }) => {
     const { projectUuid } = useParams<{ projectUuid: string }>();
+    const { data: spaces } = useSpaceSummaries(projectUuid, true, {});
 
     const { mutate: moveChart } = useMoveChartMutation();
     const { mutate: updateSqlChart } = useUpdateSqlChartMutation(
@@ -299,6 +302,20 @@ const ResourceActionHandlers: FC<ResourceActionHandlersProps> = ({
                     );
             }
 
+        case ResourceViewItemAction.TRANSFER_TO_SPACE:
+            return (
+                <TransferItemsModal
+                    opened
+                    onClose={handleReset}
+                    items={[action.item]}
+                    spaces={spaces ?? []}
+                    onConfirm={(spaceUuid) => {
+                        moveToSpace(action.item, spaceUuid);
+                        handleReset();
+                    }}
+                />
+            );
+
         case ResourceViewItemAction.CLOSE:
         case ResourceViewItemAction.MOVE_TO_SPACE:
         case ResourceViewItemAction.PIN_TO_HOMEPAGE:
diff --git a/packages/frontend/src/components/common/ResourceView/ResourceActionMenu.tsx b/packages/frontend/src/components/common/ResourceView/ResourceActionMenu.tsx
index 67065b571d143..045387e48446b 100644
--- a/packages/frontend/src/components/common/ResourceView/ResourceActionMenu.tsx
+++ b/packages/frontend/src/components/common/ResourceView/ResourceActionMenu.tsx
@@ -1,8 +1,9 @@
 import { subject } from '@casl/ability';
 import {
+    assertUnreachable,
     ChartSourceType,
+    FeatureFlags,
     ResourceViewItemType,
-    assertUnreachable,
     type ResourceViewItem,
 } from '@lightdash/common';
 import { ActionIcon, Box, Menu, Tooltip } from '@mantine/core';
@@ -14,6 +15,7 @@ import {
     IconDots,
     IconEdit,
     IconFolders,
+    IconFolderSymlink,
     IconLayoutGridAdd,
     IconPin,
     IconPinnedOff,
@@ -31,6 +33,7 @@ import {
     usePromoteDashboardDiffMutation,
     usePromoteDashboardMutation,
 } from '../../../features/promotion/hooks/usePromoteDashboard';
+import { useFeatureFlagEnabled } from '../../../hooks/useFeatureFlagEnabled';
 import { useProject } from '../../../hooks/useProject';
 import { useSpaceSummaries } from '../../../hooks/useSpaces';
 import { Can } from '../../../providers/Ability';
@@ -72,6 +75,10 @@ const ResourceViewActionMenu: FC<ResourceViewActionMenuProps> = ({
     onClose,
     onAction,
 }) => {
+    const areNestedSpacesEnabled = useFeatureFlagEnabled(
+        FeatureFlags.NestedSpaces,
+    );
+
     const { user } = useApp();
     const location = useLocation();
     const { projectUuid } = useParams<{ projectUuid: string }>();
@@ -365,144 +372,165 @@ const ResourceViewActionMenu: FC<ResourceViewActionMenuProps> = ({
                                 display={isSqlChart ? 'none' : 'block'}
                             />
 
-                            <Menu
-                                withinPortal
-                                trigger="hover"
-                                offset={0}
-                                position="right"
-                                shadow="md"
-                                closeOnItemClick
-                            >
-                                <Menu.Target>
-                                    <Menu.Item
-                                        component="button"
-                                        role="menuitem"
-                                        icon={<IconFolders size={18} />}
-                                        rightSection={
-                                            <Box w={18} h={18} ml="lg">
-                                                <IconChevronRight size={18} />
-                                            </Box>
-                                        }
-                                    >
-                                        Move to Space
-                                    </Menu.Item>
-                                </Menu.Target>
-
-                                <Menu.Dropdown
-                                    maw={320}
-                                    mah={400}
-                                    style={{
-                                        overflowY: 'auto',
+                            {areNestedSpacesEnabled ? (
+                                <Menu.Item
+                                    component="button"
+                                    role="menuitem"
+                                    icon={<IconFolderSymlink size={18} />}
+                                    onClick={() => {
+                                        onAction({
+                                            type: ResourceViewItemAction.TRANSFER_TO_SPACE,
+                                            item,
+                                        });
                                     }}
                                 >
-                                    {[
-                                        SpaceType.SharedWithMe,
-                                        SpaceType.AdminContentView,
-                                    ].map((spaceType) => (
-                                        <Fragment key={spaceType}>
-                                            {spacesByType[spaceType].length >
-                                            0 ? (
-                                                <>
-                                                    {spaceType ===
-                                                        SpaceType.AdminContentView &&
-                                                    spacesByType[
-                                                        SpaceType.SharedWithMe
-                                                    ].length > 0 ? (
-                                                        <Menu.Divider />
-                                                    ) : null}
+                                    Transfer to space
+                                </Menu.Item>
+                            ) : (
+                                <Menu
+                                    withinPortal
+                                    trigger="hover"
+                                    offset={0}
+                                    position="right"
+                                    shadow="md"
+                                    closeOnItemClick
+                                >
+                                    <Menu.Target>
+                                        <Menu.Item
+                                            component="button"
+                                            role="menuitem"
+                                            icon={<IconFolders size={18} />}
+                                            rightSection={
+                                                <Box w={18} h={18} ml="lg">
+                                                    <IconChevronRight
+                                                        size={18}
+                                                    />
+                                                </Box>
+                                            }
+                                        >
+                                            Move to Space
+                                        </Menu.Item>
+                                    </Menu.Target>
 
-                                                    <Menu.Label>
-                                                        {
-                                                            SpaceTypeLabels[
-                                                                spaceType
-                                                            ]
-                                                        }
-                                                    </Menu.Label>
-                                                </>
-                                            ) : null}
+                                    <Menu.Dropdown
+                                        maw={320}
+                                        mah={400}
+                                        style={{
+                                            overflowY: 'auto',
+                                        }}
+                                    >
+                                        {[
+                                            SpaceType.SharedWithMe,
+                                            SpaceType.AdminContentView,
+                                        ].map((spaceType) => (
+                                            <Fragment key={spaceType}>
+                                                {spacesByType[spaceType]
+                                                    .length > 0 ? (
+                                                    <>
+                                                        {spaceType ===
+                                                            SpaceType.AdminContentView &&
+                                                        spacesByType[
+                                                            SpaceType
+                                                                .SharedWithMe
+                                                        ].length > 0 ? (
+                                                            <Menu.Divider />
+                                                        ) : null}
+
+                                                        <Menu.Label>
+                                                            {
+                                                                SpaceTypeLabels[
+                                                                    spaceType
+                                                                ]
+                                                            }
+                                                        </Menu.Label>
+                                                    </>
+                                                ) : null}
 
-                                            {spacesByType[spaceType].map(
-                                                (space) => (
-                                                    <Menu.Item
-                                                        key={space.uuid}
-                                                        role="menuitem"
-                                                        disabled={
-                                                            item.data
-                                                                .spaceUuid ===
-                                                            space.uuid
-                                                        }
-                                                        icon={
-                                                            item.data
-                                                                .spaceUuid ===
-                                                            space.uuid ? (
-                                                                <IconCheck
-                                                                    size={18}
-                                                                />
-                                                            ) : (
-                                                                <Box
-                                                                    w={18}
-                                                                    h={18}
-                                                                />
-                                                            )
-                                                        }
-                                                        component="button"
-                                                        onClick={() => {
-                                                            if (
+                                                {spacesByType[spaceType].map(
+                                                    (space) => (
+                                                        <Menu.Item
+                                                            key={space.uuid}
+                                                            role="menuitem"
+                                                            disabled={
                                                                 item.data
-                                                                    .spaceUuid !==
+                                                                    .spaceUuid ===
                                                                 space.uuid
-                                                            ) {
-                                                                onAction({
-                                                                    type: ResourceViewItemAction.MOVE_TO_SPACE,
-                                                                    item,
-                                                                    data: {
-                                                                        ...item.data,
-                                                                        spaceUuid:
-                                                                            space.uuid,
-                                                                    },
-                                                                });
                                                             }
-                                                        }}
-                                                    >
-                                                        {space.name}
-                                                    </Menu.Item>
-                                                ),
-                                            )}
-                                        </Fragment>
-                                    ))}
+                                                            icon={
+                                                                item.data
+                                                                    .spaceUuid ===
+                                                                space.uuid ? (
+                                                                    <IconCheck
+                                                                        size={
+                                                                            18
+                                                                        }
+                                                                    />
+                                                                ) : (
+                                                                    <Box
+                                                                        w={18}
+                                                                        h={18}
+                                                                    />
+                                                                )
+                                                            }
+                                                            component="button"
+                                                            onClick={() => {
+                                                                if (
+                                                                    item.data
+                                                                        .spaceUuid !==
+                                                                    space.uuid
+                                                                ) {
+                                                                    onAction({
+                                                                        type: ResourceViewItemAction.MOVE_TO_SPACE,
+                                                                        item,
+                                                                        data: {
+                                                                            ...item.data,
+                                                                            spaceUuid:
+                                                                                space.uuid,
+                                                                        },
+                                                                    });
+                                                                }
+                                                            }}
+                                                        >
+                                                            {space.name}
+                                                        </Menu.Item>
+                                                    ),
+                                                )}
+                                            </Fragment>
+                                        ))}
 
-                                    <Can
-                                        I="create"
-                                        this={subject('Space', {
-                                            organizationUuid:
-                                                user.data?.organizationUuid,
-                                            projectUuid,
-                                        })}
-                                    >
-                                        {spaces.length > 0 ? (
-                                            <Menu.Divider />
-                                        ) : null}
-                                        <Menu.Item
-                                            component="button"
-                                            role="menuitem"
-                                            icon={
-                                                <MantineIcon
-                                                    icon={IconPlus}
-                                                    size={18}
-                                                />
-                                            }
-                                            onClick={() => {
-                                                onAction({
-                                                    type: ResourceViewItemAction.CREATE_SPACE,
-                                                    item,
-                                                });
-                                            }}
+                                        <Can
+                                            I="create"
+                                            this={subject('Space', {
+                                                organizationUuid:
+                                                    user.data?.organizationUuid,
+                                                projectUuid,
+                                            })}
                                         >
-                                            Create new space
-                                        </Menu.Item>
-                                    </Can>
-                                </Menu.Dropdown>
-                            </Menu>
+                                            {spaces.length > 0 ? (
+                                                <Menu.Divider />
+                                            ) : null}
+                                            <Menu.Item
+                                                component="button"
+                                                role="menuitem"
+                                                icon={
+                                                    <MantineIcon
+                                                        icon={IconPlus}
+                                                        size={18}
+                                                    />
+                                                }
+                                                onClick={() => {
+                                                    onAction({
+                                                        type: ResourceViewItemAction.CREATE_SPACE,
+                                                        item,
+                                                    });
+                                                }}
+                                            >
+                                                Create new space
+                                            </Menu.Item>
+                                        </Can>
+                                    </Menu.Dropdown>
+                                </Menu>
+                            )}
                         </>
                     ) : null}
 
diff --git a/packages/frontend/src/components/common/ResourceView/index.tsx b/packages/frontend/src/components/common/ResourceView/index.tsx
index aca2c867ed8cb..eba2a104aa007 100644
--- a/packages/frontend/src/components/common/ResourceView/index.tsx
+++ b/packages/frontend/src/components/common/ResourceView/index.tsx
@@ -11,7 +11,7 @@ import {
     useMantineTheme,
 } from '@mantine/core';
 import { IconInfoCircle } from '@tabler/icons-react';
-import React, { useCallback, useMemo, useState, type FC } from 'react';
+import { useCallback, useMemo, useState, type FC } from 'react';
 import { useTableTabStyles } from '../../../hooks/styles/useTableTabStyles';
 import MantineIcon from '../MantineIcon';
 import ResourceActionHandlers from './ResourceActionHandlers';
diff --git a/packages/frontend/src/components/common/ResourceView/types.ts b/packages/frontend/src/components/common/ResourceView/types.ts
index 73ac9dec9b9f2..de2eddd9cf6d4 100644
--- a/packages/frontend/src/components/common/ResourceView/types.ts
+++ b/packages/frontend/src/components/common/ResourceView/types.ts
@@ -12,8 +12,9 @@ export enum ResourceViewItemAction {
     DUPLICATE,
     ADD_TO_DASHBOARD,
     CREATE_SPACE,
-    MOVE_TO_SPACE,
     PIN_TO_HOMEPAGE,
+    TRANSFER_TO_SPACE,
+    MOVE_TO_SPACE, // TODO: remove these once we shift to the new nested spaces
 }
 
 export enum ResourceViewType {
@@ -27,7 +28,9 @@ export enum ResourceSortDirection {
 }
 
 export type ResourceViewItemActionState =
-    | { type: ResourceViewItemAction.CLOSE }
+    | {
+          type: ResourceViewItemAction.CLOSE;
+      }
     | {
           type: ResourceViewItemAction.UPDATE;
           item: ResourceViewItem;
@@ -56,6 +59,10 @@ export type ResourceViewItemActionState =
           type: ResourceViewItemAction.MOVE_TO_SPACE;
           item: ResourceViewChartItem | ResourceViewDashboardItem;
           data: { spaceUuid: string };
+      }
+    | {
+          type: ResourceViewItemAction.TRANSFER_TO_SPACE;
+          item: ResourceViewChartItem | ResourceViewDashboardItem; // TODO: implement spaces
       };
 
 type TabType = {
diff --git a/packages/frontend/src/components/common/TransferItemsModal/TransferItemsModal.tsx b/packages/frontend/src/components/common/TransferItemsModal/TransferItemsModal.tsx
new file mode 100644
index 0000000000000..4043460ea96f1
--- /dev/null
+++ b/packages/frontend/src/components/common/TransferItemsModal/TransferItemsModal.tsx
@@ -0,0 +1,100 @@
+import {
+    Alert,
+    Box,
+    Button,
+    Group,
+    Paper,
+    ScrollArea,
+    Text,
+} from '@mantine/core';
+import { useMemo, useState } from 'react';
+import MantineModal, { type MantineModalProps } from '../MantineModal';
+import Tree from '../Tree/Tree';
+import { type NestableItem } from '../Tree/types';
+
+type Props<T, U> = Pick<MantineModalProps, 'opened' | 'onClose'> & {
+    items: T;
+    spaces: U;
+    onConfirm: (spaceUuid: string) => void;
+};
+
+const TransferItemsModal = <
+    T extends Array<unknown>,
+    U extends Array<NestableItem>,
+>({
+    opened,
+    onClose,
+    items,
+    spaces,
+    onConfirm,
+}: Props<T, U>) => {
+    const [spaceUuid, setSpaceUuid] = useState<string | null>(null);
+
+    const selectedSpaceLabel = useMemo(() => {
+        if (!spaceUuid) return null;
+        return spaces.find((space) => space.uuid === spaceUuid)?.name;
+    }, [spaceUuid, spaces]);
+
+    return (
+        <MantineModal
+            title={`Transfer ${items.length > 1 ? 'items' : 'item'}`}
+            opened={opened}
+            onClose={onClose}
+            actions={
+                <Group position="apart" w="100%">
+                    {/* <Button variant="subtle">New Space</Button> */}
+                    <Box />
+
+                    <Group>
+                        <Button variant="default" onClick={onClose}>
+                            Cancel
+                        </Button>
+                        <Button
+                            disabled={!spaceUuid}
+                            onClick={() => {
+                                if (spaceUuid) {
+                                    onConfirm(spaceUuid);
+                                }
+                            }}
+                        >
+                            Confirm
+                        </Button>
+                    </Group>
+                </Group>
+            }
+        >
+            <Text fz="sm" fw={500}>
+                Select a space to transfer {items.length > 1 ? 'items' : 'item'}{' '}
+                to:
+            </Text>
+
+            <Paper
+                component={ScrollArea}
+                w="100%"
+                h="320px"
+                withBorder
+                px="sm"
+                py="xs"
+            >
+                <Tree
+                    data={spaces}
+                    value={spaceUuid}
+                    onChange={setSpaceUuid}
+                    topLevelLabel="Spaces"
+                />
+            </Paper>
+
+            {selectedSpaceLabel ? (
+                <Alert color="gray">
+                    <Text fw={500}>
+                        Transfer {items.length}{' '}
+                        {items.length > 1 ? 'items' : 'item'} to{' '}
+                        {selectedSpaceLabel}.
+                    </Text>
+                </Alert>
+            ) : null}
+        </MantineModal>
+    );
+};
+
+export default TransferItemsModal;


Reviews:
user: login: joaoviana
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-22T17:47:10Z
user: login: joaoviana
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-22T17:48:42Z
user: login: joaoviana
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-22T17:48:44Z
user: login: IrakliJani
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-23T07:05:20Z

Review comments:
diff_hunk: @@ -0,0 +1,100 @@
+import {
+    Alert,
+    Box,
+    Button,
+    Group,
+    Paper,
+    ScrollArea,
+    Text,
+} from '@mantine/core';
+import { useMemo, useState } from 'react';
+import MantineModal, { type MantineModalProps } from '../MantineModal';
+import Tree from '../Tree/Tree';
+import { type NestableItem } from '../Tree/types';
+
+type Props<T, U> = Pick<MantineModalProps, 'opened' | 'onClose'> & {
+    items: T;
+    spaces: U;
+    onConfirm: (spaceUuid: string) => void;
+};
+
+const TransferItemsModal = <
+    T extends Array<unknown>,
+    U extends Array<NestableItem>,
+>({
+    opened,
+    onClose,
+    items,
+    spaces,
+    onConfirm,
+}: Props<T, U>) => {
+    const [spaceUuid, setSpaceUuid] = useState<string | null>(null);
+
+    const selectedSpaceLabel = useMemo(() => {
+        if (!spaceUuid) return null;
+        return spaces.find((space) => space.uuid === spaceUuid)?.name;
+    }, [spaceUuid, spaces]);
+
+    return (
+        <MantineModal
+            title={`Transfer ${items.length > 1 ? 'items' : 'item'}`}
+            opened={opened}
+            onClose={onClose}
+            actions={
+                <Group position="apart" w="100%">
+                    {/* <Button variant="subtle">New Space</Button> */}
path: packages/frontend/src/components/common/TransferItemsModal/TransferItemsModal.tsx
user: login: joaoviana
body: to check if this is removed after merging stack into this
created_at: 2025-04-22T17:47:10Z
author_association: CONTRIBUTOR
diff_hunk: @@ -45,6 +47,7 @@ const ResourceActionHandlers: FC<ResourceActionHandlersProps> = ({
     onAction,
 }) => {
     const { projectUuid } = useParams<{ projectUuid: string }>();
+    const { data: spaces } = useSpaceSummaries(projectUuid, true, {});
path: packages/frontend/src/components/common/ResourceView/ResourceActionHandlers.tsx
user: login: joaoviana
body: now that we include private spaces (if the user has the ability) do we want to have 2 separate views or a visual indicator like you've mentioned internally? 
created_at: 2025-04-22T17:48:42Z
author_association: CONTRIBUTOR
diff_hunk: @@ -45,6 +47,7 @@ const ResourceActionHandlers: FC<ResourceActionHandlersProps> = ({
     onAction,
 }) => {
     const { projectUuid } = useParams<{ projectUuid: string }>();
+    const { data: spaces } = useSpaceSummaries(projectUuid, true, {});
path: packages/frontend/src/components/common/ResourceView/ResourceActionHandlers.tsx
user: login: IrakliJani
body: yes, definitely! I'll create a sub-ticket for that. thanks for reminding me
created_at: 2025-04-23T07:05:20Z
author_association: CONTRIBUTOR

PR comments:
user: login: IrakliJani
created_at: 2025-04-22T12:18:20Z
body: * **#14489** <a href="https://app.graphite.dev/github/pr/lightdash/lightdash/14489?utm_source=stack-comment-icon" target="_blank"><img src="https://static.graphite.dev/graphite-32x32-black.png" alt="Graphite" width="10px" height="10px"/></a>: 2  dependent PRs ([#14490](https://github.com/lightdash/lightdash/pull/14490) <a href="https://app.graphite.dev/github/pr/lightdash/lightdash/14490?utm_source=stack-comment-icon" target="_blank"><img src="https://static.graphite.dev/graphite-32x32-black.png" alt="Graphite" width="10px" height="10px"/></a>, [#14492](https://github.com/lightdash/lightdash/pull/14492) <a href="https://app.graphite.dev/github/pr/lightdash/lightdash/14492?utm_source=stack-comment-icon" target="_blank"><img src="https://static.graphite.dev/graphite-32x32-black.png" alt="Graphite" width="10px" height="10px"/></a>)
* **#14488** <a href="https://app.graphite.dev/github/pr/lightdash/lightdash/14488?utm_source=stack-comment-icon" target="_blank"><img src="https://static.graphite.dev/graphite-32x32-black.png" alt="Graphite" width="10px" height="10px"/></a> 👈 <a href="https://app.graphite.dev/github/pr/lightdash/lightdash/14488?utm_source=stack-comment-view-in-graphite" target="_blank">(View in Graphite)</a>
* `main`


<h2></h2>

This stack of pull requests is managed by <a href="https://graphite.dev?utm-source=stack-comment"><b>Graphite</b></a>. Learn more about <a href="https://stacking.dev/?utm_source=stack-comment">stacking</a>.
<!-- Current dependencies on/for this PR: -->
author_association: CONTRIBUTOR
user: login: IrakliJani
created_at: 2025-04-23T08:53:47Z
body: ### Merge activity

* **Apr 23, 4:53 AM EDT**: A user started a stack merge that includes this pull request via [Graphite](https://app.graphite.dev/github/pr/lightdash/lightdash/14488).
* **Apr 23, 4:54 AM EDT**: A user merged this pull request with [Graphite](https://app.graphite.dev/github/pr/lightdash/lightdash/14488).

author_association: CONTRIBUTOR
user: login: lightdash-bot
created_at: 2025-04-23T08:57:57Z
body: :tada: This PR is included in version 0.1593.0 :tada:

The release is available on:
- `0.1593.0`
- [GitHub release](https://github.com/lightdash/lightdash/releases/tag/0.1593.0)

Your **[semantic-release](https://github.com/semantic-release/semantic-release)** bot :package::rocket:
author_association: COLLABORATOR