diff --git a/web/playwright-tests/dashboard-collection.test.ts b/web/playwright-tests/dashboard-collection.test.ts new file mode 100644 index 000000000..99ff032e2 --- /dev/null +++ b/web/playwright-tests/dashboard-collection.test.ts @@ -0,0 +1,36 @@ +import { test, expect } from '@playwright/test'; + +test.skip('Can add dashboard to collection', async ({ page }) => { + await page.goto('http://localhost:3000/app/dashboards/c0855f0f-f50a-424e-9e72-9e53711a7f6a/file'); + + await page.getByTestId('add-to-collection-button').click(); + await expect(page.getByRole('checkbox')).toHaveAttribute('data-state', 'checked'); + + await page.getByRole('checkbox').click(); + await expect(page.getByRole('checkbox')).toHaveAttribute('data-state', 'unchecked'); + await page + .getByRole('menuitemcheckbox', { name: 'Important Things' }) + .getByRole('button') + .click(); + + const url = 'http://localhost:3000/app/collections/0ac43ae2-beda-4007-9574-71a17425da0a'; + await page.waitForTimeout(5000); + await page.waitForLoadState('networkidle'); + await page.waitForLoadState('domcontentloaded'); + await expect(page.url()).toBe(url); + + // Verify that "Important Metrics" text is not on the page + await expect(page.locator('.list-container').getByText('Important Metrics')).not.toBeVisible(); + + await page.goBack(); + await page.getByTestId('add-to-collection-button').click(); + await expect(page.getByRole('checkbox')).toHaveAttribute('data-state', 'unchecked'); + await page + .getByRole('menuitemcheckbox', { name: 'Important Things' }) + .getByRole('button') + .click(); + await page.waitForTimeout(100); + await page.waitForLoadState('networkidle'); + await page.waitForLoadState('domcontentloaded'); + await page.goto('http://localhost:3000/app/dashboards/c0855f0f-f50a-424e-9e72-9e53711a7f6a/file'); +}); diff --git a/web/playwright-tests/dashboard-updates.test.ts b/web/playwright-tests/dashboard-updates.test.ts index fbff2e2cc..b0a0c2cba 100644 --- a/web/playwright-tests/dashboard-updates.test.ts +++ b/web/playwright-tests/dashboard-updates.test.ts @@ -75,8 +75,6 @@ test('Can remove a metric from a dashboard', async ({ page }) => { await page.mouse.up(); await page.waitForTimeout(1000); } catch (e) { - console.log('Drag and drop failed with first approach, trying backup method'); - const sourceBoundingBox = await sourceElement.boundingBox(); const targetBoundingBox = await targetElement.boundingBox(); @@ -156,3 +154,53 @@ test('Can remove a metric from a dashboard', async ({ page }) => { - text: Drag here to create a new row `); }); + +test('Can edit name and description of a dashboard', async ({ page }) => { + await page.goto('http://localhost:3000/app/dashboards/c0855f0f-f50a-424e-9e72-9e53711a7f6a'); + await expect(page.getByRole('textbox', { name: 'Add description...' })).toHaveValue(''); + + await page.getByRole('textbox', { name: 'New dashboard' }).click(); + await page.getByRole('textbox', { name: 'New dashboard' }).fill('Important Metrics NATE RULES'); + await page.getByRole('textbox', { name: 'Add description...' }).click(); + await page.getByRole('textbox', { name: 'Add description...' }).fill('HUH?'); + await expect(page.getByRole('textbox', { name: 'New dashboard' })).toBeVisible(); + await expect(page.getByRole('textbox', { name: 'New dashboard' })).toHaveValue( + 'Important Metrics NATE RULES' + ); + await page.getByRole('button', { name: 'Save' }).click(); + await expect(page.getByRole('textbox', { name: 'New dashboard' })).toHaveValue( + 'Important Metrics NATE RULES' + ); + await page.getByRole('textbox', { name: 'New dashboard' }).click(); + await page.getByRole('textbox', { name: 'New dashboard' }).fill('Important Metrics'); + await page.getByRole('textbox', { name: 'Add description...' }).click(); + await expect(page.getByRole('textbox', { name: 'Add description...' })).toHaveValue('HUH?'); + await page.getByRole('button', { name: 'Save' }).click(); + await page.waitForTimeout(100); + await page.waitForLoadState('networkidle'); + + await expect(page.getByRole('textbox', { name: 'New dashboard' })).toHaveValue( + 'Important Metrics' + ); + await page.getByRole('textbox', { name: 'Add description...' }).fill(''); + await expect(page.getByRole('textbox', { name: 'Add description...' })).toBeEmpty(); + await page.getByRole('textbox', { name: 'New dashboard' }).click(); + await page.getByRole('textbox', { name: 'New dashboard' }).fill('Important Metrics SWAG'); + await page.getByRole('button', { name: 'Save' }).click(); + await page.waitForTimeout(400); + await page.waitForLoadState('networkidle'); + await page.getByTestId('segmented-trigger-file').click(); + await page.getByTestId('segmented-trigger-file').click(); + await page.waitForTimeout(5000); // Wait up to 2 seconds for the text to appear + + await expect(page.getByText('Important Metrics SWAG')).toBeVisible({ timeout: 20000 }); // Wait up to 20 seconds for visibility + await expect(page.locator('.current-line').first()).toBeVisible(); + + await page + .getByRole('textbox', { name: 'Editor content' }) + .fill( + "name: Important Metrics\ndescription: ''\nrows:\n- items:\n - id: 72e445a5-fb08-5b76-8c77-1642adf0cb72\n - id: 45848c7f-0d28-52a0-914e-f3fc1b7d4180\n - id: 117a2fc5-e3e8-5bb0-a29b-bcfa3da3adc0\n - id: b19d2606-6061-5d22-8628-78a4878310d4\n rowHeight: 320\n columnSizes:\n" + ); + await page.getByRole('button', { name: 'Save' }).click(); + await page.getByTestId('segmented-trigger-dashboard').click(); +}); diff --git a/web/src/api/buster_rest/dashboards/queryRequests.ts b/web/src/api/buster_rest/dashboards/queryRequests.ts index 8bc9fe037..de91d1424 100644 --- a/web/src/api/buster_rest/dashboards/queryRequests.ts +++ b/web/src/api/buster_rest/dashboards/queryRequests.ts @@ -109,9 +109,7 @@ export const useSaveDashboard = (params?: { updateOnSave?: boolean }) => { data ); setOriginalDashboard(data.dashboard); - if (variables.update_version) { - onSetLatestDashboardVersion(data.dashboard.id, last(data.versions)?.version_number || 0); - } + onSetLatestDashboardVersion(data.dashboard.id, last(data.versions)?.version_number || 0); } } }); @@ -163,7 +161,8 @@ export const useUpdateDashboard = (params?: { export const useUpdateDashboardConfig = () => { const { mutateAsync } = useUpdateDashboard({ saveToServer: false, - updateVersion: false + updateVersion: false, + updateOnSave: true }); const queryClient = useQueryClient(); const { latestVersionNumber } = useGetDashboardVersionNumber(); diff --git a/web/src/components/ui/charts/BusterChartJS/hooks/useOptions/useTooltipOptions.ts/BusterChartJSTooltip.tsx b/web/src/components/ui/charts/BusterChartJS/hooks/useOptions/useTooltipOptions.ts/BusterChartJSTooltip.tsx index 27f01d09f..77becc98a 100644 --- a/web/src/components/ui/charts/BusterChartJS/hooks/useOptions/useTooltipOptions.ts/BusterChartJSTooltip.tsx +++ b/web/src/components/ui/charts/BusterChartJS/hooks/useOptions/useTooltipOptions.ts/BusterChartJSTooltip.tsx @@ -99,7 +99,6 @@ export const BusterChartJSTooltip: React.FC<{ //I decided to do this because the tooltip really need to be more detailed than the x... // const isAutoDateFormat = // columnLabelFormat?.dateFormat === 'auto' && columnLabelFormat?.style === 'date'; - // console.log(columnLabelFormat); // if (isAutoDateFormat) { // const unit = (chart.scales.x as TimeScale)._unit; diff --git a/web/src/controllers/DashboardController/DashboardViewDashboardController/DashboardEditTitle.tsx b/web/src/controllers/DashboardController/DashboardViewDashboardController/DashboardEditTitle.tsx index 1b1f2ccab..398acd82d 100644 --- a/web/src/controllers/DashboardController/DashboardViewDashboardController/DashboardEditTitle.tsx +++ b/web/src/controllers/DashboardController/DashboardViewDashboardController/DashboardEditTitle.tsx @@ -25,12 +25,13 @@ export const DashboardEditTitles: React.FC<{ }); const onChangeTitle = useMemoizedFn((name: string) => { - if (!readOnly) onUpdateDashboard({ name, id: dashboardId }); + if (!readOnly) onUpdateDashboard({ name, id: dashboardId, description }); }); const onChangeDashboardDescription = useMemoizedFn( (value: React.ChangeEvent) => { - if (!readOnly) onUpdateDashboard({ description: value.target.value, id: dashboardId }); + if (!readOnly) + onUpdateDashboard({ description: value.target.value, id: dashboardId, name: title }); } ); diff --git a/web/src/controllers/DashboardController/DashboardViewDashboardController/DashboardSaveFilePopup.tsx b/web/src/controllers/DashboardController/DashboardViewDashboardController/DashboardSaveFilePopup.tsx index 82ca9a0cb..51e0f47a3 100644 --- a/web/src/controllers/DashboardController/DashboardViewDashboardController/DashboardSaveFilePopup.tsx +++ b/web/src/controllers/DashboardController/DashboardViewDashboardController/DashboardSaveFilePopup.tsx @@ -11,7 +11,6 @@ export const DashboardSaveFilePopup: React.FC<{ dashboardId: string }> = React.m const isFileChanged = useChatIndividualContextSelector((x) => x.isFileChanged); const chatId = useChatLayoutContextSelector((x) => x.chatId); const { data: dashboardResponse } = useGetDashboard({ id: dashboardId }); - const { mutateAsync: onSaveDashboard, isPending: isSaving } = useUpdateDashboard({ saveToServer: true, updateOnSave: true, diff --git a/web/src/controllers/DashboardController/DashboardViewFileController/DashboardViewFileController.tsx b/web/src/controllers/DashboardController/DashboardViewFileController/DashboardViewFileController.tsx index 378d87a56..ca06be550 100644 --- a/web/src/controllers/DashboardController/DashboardViewFileController/DashboardViewFileController.tsx +++ b/web/src/controllers/DashboardController/DashboardViewFileController/DashboardViewFileController.tsx @@ -22,7 +22,8 @@ export const DashboardViewFileController: React.FC<{ error: updateDashboardError } = useUpdateDashboard({ saveToServer: true, - updateVersion: false + updateVersion: false, + updateOnSave: true }); const { isReadOnly } = useIsDashboardReadOnly({