Skip to content
This repository has been archived by the owner on Jan 16, 2025. It is now read-only.

[POC] Edit dashboard #12

Merged
merged 44 commits into from
Apr 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
a208f5e
[POC] edit dashboard
quanvo0213 Mar 19, 2024
02d3bf4
hide unnecessary components
quanvo0213 Mar 20, 2024
904dcbd
Create chart
triquanminh Mar 20, 2024
b25fd2d
Add isKatalonEmbeddedMode to URL after create chart
triquanminh Mar 20, 2024
0696472
hide unuse select button
quanvo0213 Mar 20, 2024
456963a
Fix reflect URL conflicts
triquanminh Mar 20, 2024
8139ea1
Merge branch '3.1.0.katalon' into edit-dashboard-poc
triquanminh Mar 20, 2024
460c596
Add isKatalonEmbeddedMode flag
triquanminh Mar 20, 2024
16856ec
Add custom RA request from Superset FE
triquanminh Mar 20, 2024
52ae943
Fix CORS error
triquanminh Mar 20, 2024
50897b2
Fix CORS error
triquanminh Mar 20, 2024
397cffe
add new params
quanvo0213 Mar 21, 2024
ab5a3fc
Merge remote-tracking branch 'origin/edit-dashboard-poc' into request…
triquanminh Mar 21, 2024
e1701e2
Call API to BFF
triquanminh Mar 21, 2024
27f3d91
convert to x-cookies
quanvo0213 Mar 21, 2024
c6f4646
Add x-cookie to header
triquanminh Mar 21, 2024
9becdd6
Merge pull request #13 from katalon-studio/request-ra-api
quanvo0213 Mar 21, 2024
3c154c4
Remove console.log
triquanminh Mar 21, 2024
c3996d2
Proxy to RA's BFF endpoint
triquanminh Mar 27, 2024
f953a7b
Integrate with RA Proxy's API
triquanminh Mar 28, 2024
0ce26d4
Render edit dashboard button when is not logged in
triquanminh Mar 28, 2024
a14bf95
Merge pull request #14 from katalon-studio/proxy-integration
huynguyen2908 Apr 2, 2024
449c4f4
init MUI 5 for katalon folder
quanvo0213 Apr 3, 2024
46f544d
update libs
quanvo0213 Apr 3, 2024
0865c92
Merge pull request #17 from katalon-studio/mui-5
huynguyen2908 Apr 4, 2024
36e6bc0
Add more filter button
lequangtrai Apr 4, 2024
a354a36
Refactor code
lequangtrai Apr 4, 2024
ab9084f
Merge pull request #18 from katalon-studio/RA-TES-6185
huynguyen2908 Apr 5, 2024
5fa1ca5
init DateRangePicker in superset
quanvo0213 Apr 5, 2024
e0eab62
remove comments
quanvo0213 Apr 5, 2024
fd6c9cb
move popover into component
quanvo0213 Apr 5, 2024
7d2c9fe
init styled-component
quanvo0213 Apr 5, 2024
18b77ec
revert
quanvo0213 Apr 5, 2024
0c4dc17
define propType
quanvo0213 Apr 5, 2024
06278f8
update css
quanvo0213 Apr 8, 2024
db4c10b
refactor
quanvo0213 Apr 8, 2024
7ed378d
refactor
quanvo0213 Apr 8, 2024
31d7c66
Custom Select filter
lequangtrai Apr 8, 2024
078aa8b
Custom Select filter
lequangtrai Apr 8, 2024
633dc80
Merge pull request #20 from katalon-studio/RA-TES-6186
huynguyen2908 Apr 9, 2024
c7ff556
Merge pull request #19 from katalon-studio/RA-TES-6211
huynguyen2908 Apr 9, 2024
5f50176
Update Custom Select filter
lequangtrai Apr 9, 2024
b3ccac9
Merge pull request #22 from katalon-studio/RA-TES-6186
huynguyen2908 Apr 9, 2024
0ce66f5
Config QA's environment
triquanminh Apr 10, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions superset-frontend/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const Config = {
// Local
// supersetClientClass: {
// baseUrl: 'http://localhost:8080/proxy',
// host: 'localhost:8080/proxy',
// port: '8080',
// },
// chartConfig: {
// host: 'localhost',
// path: '/proxy',
// port: '8080',
// },

// QA
supersetClientClass: {
baseUrl: 'https://testops-g3-ra-bff.qa.katalon.com/proxy',
host: 'testops-g3-ra-bff.qa.katalon.com/proxy',
port: '',
},
chartConfig: {
host: 'testops-g3-ra-bff.qa.katalon.com',
path: '/proxy',
port: '',
},
};

export default Config;
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
ParseMethod,
} from './types';
import { DEFAULT_FETCH_RETRY_OPTIONS, DEFAULT_BASE_URL } from './constants';
import Config from '../../../../config';

const defaultUnauthorizedHandler = () => {
if (!window.location.pathname.startsWith('/login')) {
Expand Down Expand Up @@ -72,7 +73,7 @@ export default class SupersetClientClass {
protocol,
headers = {},
fetchRetryOptions = {},
mode = 'same-origin',
mode = 'cors',
timeout,
credentials = undefined,
csrfToken = undefined,
Expand All @@ -88,8 +89,10 @@ export default class SupersetClientClass {
// as the base of baseUrl
window.location.href,
);
this.baseUrl = url.href.replace(/\/+$/, ''); // always strip trailing slash
this.host = url.host;
// this.baseUrl = url.href.replace(/\/+$/, ''); // always strip trailing slash
this.baseUrl = Config.supersetClientClass.baseUrl;
// this.host = url.host;
this.host = Config.supersetClientClass.host;
this.protocol = url.protocol as Protocol;
this.headers = { Accept: 'application/json', ...headers }; // defaulting accept to json
this.mode = mode;
Expand Down Expand Up @@ -198,13 +201,24 @@ export default class SupersetClientClass {
ignoreUnauthorized = false,
...rest
}: RequestConfig & { parseMethod?: T }) {
await this.ensureAuth();
// await this.ensureAuth();

const urlParams = new URLSearchParams(window.location.search);
const projectId = urlParams.get('projectId');
const accessToken = urlParams.get('accessToken');
const combinedHeaders = {
...this.headers,
...headers,
...(projectId && { 'x-project-id': projectId }),
...(accessToken && { Authorization: `Bearer ${accessToken}` }),
};
triquanminh marked this conversation as resolved.
Show resolved Hide resolved

return callApiAndParseWithTimeout({
...rest,
credentials: credentials ?? this.credentials,
mode: mode ?? this.mode,
url: this.getUrl({ endpoint, host, url }),
headers: { ...this.headers, ...headers },
headers: combinedHeaders,
timeout: timeout ?? this.timeout,
fetchRetryOptions: fetchRetryOptions ?? this.fetchRetryOptions,
}).catch(res => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export default async function callApi({
fetchRetryOptions,
headers,
method = 'GET',
mode = 'same-origin',
mode = 'cors',
postPayload,
triquanminh marked this conversation as resolved.
Show resolved Hide resolved
jsonPayload,
redirect = 'follow',
Expand Down
27 changes: 18 additions & 9 deletions superset-frontend/src/components/PageHeaderWithActions/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import React, { ReactNode, ReactElement } from 'react';
import { css, SupersetTheme, t, useTheme } from '@superset-ui/core';
import { AntdDropdown, AntdDropdownProps } from 'src/components';
import { TooltipPlacement } from 'src/components/Tooltip';
import { getUrlParam } from 'src/utils/urlUtils';
import { URL_PARAMS } from 'src/constants';
import {
DynamicEditableTitle,
DynamicEditableTitleProps,
Expand Down Expand Up @@ -134,24 +136,31 @@ export const PageHeaderWithActions = ({
tooltipProps,
}: PageHeaderWithActionsProps) => {
const theme = useTheme();
const isKatalonEmbeddedDashboard = getUrlParam(
URL_PARAMS.isKatalonEmbeddedMode,
);
triquanminh marked this conversation as resolved.
Show resolved Hide resolved
return (
<div css={headerStyles} className="header-with-actions">
<div className="title-panel">
<DynamicEditableTitle {...editableTitleProps} />
{showTitlePanelItems && (
<div css={buttonsStyles}>
{certificatiedBadgeProps?.certifiedBy && (
<CertifiedBadge {...certificatiedBadgeProps} />
{!isKatalonEmbeddedDashboard && (
<>
<DynamicEditableTitle {...editableTitleProps} />
{showTitlePanelItems && (
<div css={buttonsStyles}>
{certificatiedBadgeProps?.certifiedBy && (
<CertifiedBadge {...certificatiedBadgeProps} />
)}
{showFaveStar && <FaveStar {...faveStarProps} />}
{titlePanelAdditionalItems}
</div>
triquanminh marked this conversation as resolved.
Show resolved Hide resolved
)}
{showFaveStar && <FaveStar {...faveStarProps} />}
{titlePanelAdditionalItems}
</div>
</>
)}
</div>
<div className="right-button-panel">
{rightPanelAdditionalItems}
<div css={additionalActionsContainerStyles}>
{showMenuDropdown && (
{!isKatalonEmbeddedDashboard && showMenuDropdown && (
<AntdDropdown
trigger={['click']}
overlay={additionalActionsMenu}
triquanminh marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
12 changes: 12 additions & 0 deletions superset-frontend/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,18 @@ export const URL_PARAMS = {
name: 'focused_chart',
type: 'number',
},
isKatalonEmbeddedMode: {
name: 'isKatalonEmbeddedMode',
type: 'boolean',
},
projectId: {
name: 'projectId',
type: 'string',
},
accessToken: {
name: 'accessToken',
type: 'string',
},
triquanminh marked this conversation as resolved.
Show resolved Hide resolved
} as const;

export const RESERVED_CHART_URL_PARAMS: string[] = [
Expand Down
13 changes: 12 additions & 1 deletion superset-frontend/src/dashboard/actions/dashboardState.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ import { getActiveFilters } from 'src/dashboard/util/activeDashboardFilters';
import { safeStringify } from 'src/utils/safeStringify';
import { logEvent } from 'src/logger/actions';
import { LOG_ACTIONS_CONFIRM_OVERWRITE_DASHBOARD_METADATA } from 'src/logger/LogUtils';
import { getUrlParam } from 'src/utils/urlUtils';
import { URL_PARAMS } from 'src/constants';
import { UPDATE_COMPONENTS_PARENTS_LIST } from './dashboardLayout';
import {
saveChartConfiguration,
Expand Down Expand Up @@ -342,11 +344,20 @@ export function saveDashboardRequest(data, id, saveType) {
dispatch(saveDashboardRequestSuccess(lastModifiedTime));
}
dispatch(saveDashboardFinished());

const isKatalonEmbeddedDashboard = getUrlParam(
URL_PARAMS.isKatalonEmbeddedMode,
);
const projectId = getUrlParam(URL_PARAMS.projectId);
const accessToken = getUrlParam(URL_PARAMS.accessToken);
triquanminh marked this conversation as resolved.
Show resolved Hide resolved

// redirect to the new slug or id
window.history.pushState(
{ event: 'dashboard_properties_changed' },
'',
`/superset/dashboard/${slug || id}/`,
`/superset/dashboard/${
slug || id
}/?isKatalonEmbeddedMode=${isKatalonEmbeddedDashboard}&projectId=${projectId}&accessToken=${accessToken}`,
triquanminh marked this conversation as resolved.
Show resolved Hide resolved
triquanminh marked this conversation as resolved.
Show resolved Hide resolved
);

dispatch(addSuccessToast(t('This dashboard was saved successfully.')));
Expand Down
9 changes: 6 additions & 3 deletions superset-frontend/src/dashboard/components/Header/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
t,
getSharedLabelColor,
getExtensionsRegistry,
SupersetClient,

Check failure on line 31 in superset-frontend/src/dashboard/components/Header/index.jsx

View workflow job for this annotation

GitHub Actions / frontend-build

'SupersetClient' is defined but never used

Check failure on line 31 in superset-frontend/src/dashboard/components/Header/index.jsx

View workflow job for this annotation

GitHub Actions / frontend-build

'SupersetClient' is defined but never used
} from '@superset-ui/core';
import { Global } from '@emotion/react';
import {
Expand Down Expand Up @@ -466,10 +467,12 @@
logEvent,
} = this.props;

const userCanEdit =
dashboardInfo.dash_edit_perm && !dashboardInfo.is_managed_externally;
// const userCanEdit =
// dashboardInfo.dash_edit_perm && !dashboardInfo.is_managed_externally;
const userCanEdit = true;
const userCanShare = dashboardInfo.dash_share_perm;
const userCanSaveAs = dashboardInfo.dash_save_perm;
// const userCanSaveAs = dashboardInfo.dash_save_perm;
const userCanSaveAs = true;
triquanminh marked this conversation as resolved.
Show resolved Hide resolved
triquanminh marked this conversation as resolved.
Show resolved Hide resolved
const userCanCurate =
isFeatureEnabled(FeatureFlag.EMBEDDED_SUPERSET) &&
findPermission('can_set_embedded', 'Dashboard', user.roles);
Expand Down
28 changes: 21 additions & 7 deletions superset-frontend/src/dashboard/components/SliceAdder.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ import { slicePropShape } from 'src/dashboard/util/propShapes';
import { debounce, pickBy } from 'lodash';
import Checkbox from 'src/components/Checkbox';
import { InfoTooltipWithTrigger } from '@superset-ui/chart-controls';
import { getUrlParam } from 'src/utils/urlUtils';
import { URL_PARAMS } from 'src/constants';
triquanminh marked this conversation as resolved.
Show resolved Hide resolved
import AddSliceCard from './AddSliceCard';
import AddSliceDragPreview from './dnd/AddSliceDragPreview';
import DragDroppable from './dnd/DragDroppable';
Expand Down Expand Up @@ -331,13 +333,25 @@ class SliceAdder extends React.Component {
<NewChartButton
buttonStyle="link"
buttonSize="xsmall"
onClick={() =>
window.open(
`/chart/add?dashboard_id=${this.props.dashboardId}`,
'_blank',
'noopener noreferrer',
)
}
onClick={() => {
const isKatalonEmbeddedDashboard = getUrlParam(
URL_PARAMS.isKatalonEmbeddedMode,
);
const projectId = getUrlParam(URL_PARAMS.projectId);
const accessToken = getUrlParam(URL_PARAMS.accessToken);

if (isKatalonEmbeddedDashboard) {
window.location.assign(
`/explore/?dashboard_id=${this.props.dashboardId}&isKatalonEmbeddedMode=true&projectId=${projectId}&accessToken=${accessToken}`,
triquanminh marked this conversation as resolved.
Show resolved Hide resolved
triquanminh marked this conversation as resolved.
Show resolved Hide resolved
);
} else {
window.open(
`/chart/add?dashboard_id=${this.props.dashboardId}`,
'_blank',
'noopener noreferrer',
);
}
}}
triquanminh marked this conversation as resolved.
Show resolved Hide resolved
>
<Icons.PlusSmall />
{t('Create new chart')}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ import Icons from 'src/components/Icons';
import { RootState } from 'src/dashboard/types';
import { getSliceHeaderTooltip } from 'src/dashboard/util/getSliceHeaderTooltip';
import { DashboardPageIdContext } from 'src/dashboard/containers/DashboardPage';
import { getUrlParam } from 'src/utils/urlUtils';
import { URL_PARAMS } from 'src/constants';
triquanminh marked this conversation as resolved.
Show resolved Hide resolved

const extensionsRegistry = getExtensionsRegistry();

Expand Down Expand Up @@ -195,6 +197,8 @@ const SliceHeader: FC<SliceHeaderProps> = ({

const exploreUrl = `/explore/?dashboard_page_id=${dashboardPageId}&slice_id=${slice.slice_id}`;

const isKatalonEmbeddedMode = getUrlParam(URL_PARAMS.isKatalonEmbeddedMode);
triquanminh marked this conversation as resolved.
Show resolved Hide resolved

return (
<ChartHeaderStyles data-test="slice-header" ref={innerRef}>
<div className="header-title" ref={headerRef}>
Expand Down Expand Up @@ -258,10 +262,10 @@ const SliceHeader: FC<SliceHeaderProps> = ({
<CrossFilterIcon iconSize="m" />
</Tooltip>
)}
{!uiConfig.hideChartControls && (
{!isKatalonEmbeddedMode && !uiConfig.hideChartControls && (
triquanminh marked this conversation as resolved.
Show resolved Hide resolved
<FiltersBadge chartId={slice.slice_id} />
)}
{!uiConfig.hideChartControls && (
{!isKatalonEmbeddedMode && !uiConfig.hideChartControls && (
triquanminh marked this conversation as resolved.
Show resolved Hide resolved
<SliceHeaderControls
slice={slice}
triquanminh marked this conversation as resolved.
Show resolved Hide resolved
isCached={isCached}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import DropdownContainer, {
Ref as DropdownContainerRef,
} from 'src/components/DropdownContainer';
import Icons from 'src/components/Icons';
import FilterExtension from 'src/katalon/CustomFilter/FilterExtension';
triquanminh marked this conversation as resolved.
Show resolved Hide resolved
import { FiltersOutOfScopeCollapsible } from '../FiltersOutOfScopeCollapsible';
import { useFilterControlFactory } from '../useFilterControlFactory';
import { FiltersDropdownContent } from '../FiltersDropdownContent';
Expand Down Expand Up @@ -215,6 +216,7 @@ const FilterControls: FC<FilterControlsProps> = ({
if (isFeatureEnabled(FeatureFlag.DASHBOARD_NATIVE_FILTERS)) {
const nativeFiltersInScope = filtersInScope.map((filter, index) => ({
id: filter.id,
name: filter.name,
triquanminh marked this conversation as resolved.
Show resolved Hide resolved
element: (
<div
className="filter-item-wrapper"
Expand Down Expand Up @@ -316,6 +318,8 @@ const FilterControls: FC<FilterControlsProps> = ({
}
}, [outlinedFilterId, lastUpdated, popoverRef, overflowedIds]);

const renderFilterExtension = () => <FilterExtension items={items} />;
triquanminh marked this conversation as resolved.
Show resolved Hide resolved

return (
<>
{portalNodes
Expand All @@ -332,7 +336,9 @@ const FilterControls: FC<FilterControlsProps> = ({
{filterBarOrientation === FilterBarOrientation.VERTICAL &&
renderVerticalContent()}
{filterBarOrientation === FilterBarOrientation.HORIZONTAL &&
renderHorizontalContent()}
renderFilterExtension()}
{/* {filterBarOrientation === FilterBarOrientation.HORIZONTAL &&
renderHorizontalContent()} */}
triquanminh marked this conversation as resolved.
Show resolved Hide resolved
</>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import { logEvent } from 'src/logger/actions';
import { LOG_ACTIONS_CHANGE_DASHBOARD_FILTER } from 'src/logger/LogUtils';
import { FilterBarOrientation, RootState } from 'src/dashboard/types';
import { UserWithPermissionsAndRoles } from 'src/types/bootstrapTypes';
import KatalonHorizontal from 'src/katalon/CustomFilter/KatalonHorizontal';
triquanminh marked this conversation as resolved.
Show resolved Hide resolved
import { checkIsApplyDisabled } from './utils';
import { FiltersBarProps } from './types';
import {
Expand Down Expand Up @@ -287,7 +288,7 @@ const FilterBar: React.FC<FiltersBarProps> = ({

const filterBarComponent =
orientation === FilterBarOrientation.HORIZONTAL ? (
<Horizontal
<KatalonHorizontal
triquanminh marked this conversation as resolved.
Show resolved Hide resolved
actions={actions}
canEdit={canEdit}
dashboardId={dashboardId}
Expand Down
2 changes: 2 additions & 0 deletions superset-frontend/src/explore/actions/saveModalActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import { SupersetClient, t } from '@superset-ui/core';
import { addSuccessToast } from 'src/components/MessageToasts/actions';
import { isEmpty } from 'lodash';
triquanminh marked this conversation as resolved.
Show resolved Hide resolved
import { getUrlParam } from 'src/utils/urlUtils';

Check failure on line 23 in superset-frontend/src/explore/actions/saveModalActions.js

View workflow job for this annotation

GitHub Actions / frontend-build

'getUrlParam' is defined but never used

Check failure on line 23 in superset-frontend/src/explore/actions/saveModalActions.js

View workflow job for this annotation

GitHub Actions / frontend-build

'getUrlParam' is defined but never used
triquanminh marked this conversation as resolved.
Show resolved Hide resolved
import { URL_PARAMS } from 'src/constants';

Check failure on line 24 in superset-frontend/src/explore/actions/saveModalActions.js

View workflow job for this annotation

GitHub Actions / frontend-build

'URL_PARAMS' is defined but never used

Check failure on line 24 in superset-frontend/src/explore/actions/saveModalActions.js

View workflow job for this annotation

GitHub Actions / frontend-build

'URL_PARAMS' is defined but never used
triquanminh marked this conversation as resolved.
Show resolved Hide resolved
import { buildV1ChartDataPayload } from '../exploreUtils';
import { Operators } from '../constants';

Expand Down
Loading
Loading