You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@superset.apache.org by "kgabryje (via GitHub)" <gi...@apache.org> on 2024/11/22 11:38:13 UTC
[PR] chore: Refactor dashboard header to func component [superset]
kgabryje opened a new pull request, #31029:
URL: https://github.com/apache/superset/pull/31029
### SUMMARY
Refactor the dashboard Header component from class to function component. No functional changes, just a refactor
### BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
### TESTING INSTRUCTIONS
Everything should work like before
### ADDITIONAL INFORMATION
<!--- Check any relevant boxes with "x" -->
<!--- HINT: Include "Fixes #nnn" if you are fixing an existing issue -->
- [ ] Has associated issue:
- [ ] Required feature flags:
- [ ] Changes UI
- [ ] Includes DB Migration (follow approval process in [SIP-59](https://github.com/apache/superset/issues/13351))
- [ ] Migration is atomic, supports rollback & is backwards-compatible
- [ ] Confirm DB migration upgrade and downgrade tested
- [ ] Runtime estimates and downtime expectations provided
- [ ] Introduces new feature or API
- [ ] Removes existing feature or API
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] chore: Refactor dashboard header to func component [superset]
Posted by "kgabryje (via GitHub)" <gi...@apache.org>.
kgabryje commented on PR #31029:
URL: https://github.com/apache/superset/pull/31029#issuecomment-2494495042
> Maybe it would be nice to use `refactor` instead of `chore` for this type of PR.
good point 🤦 will keep that in mind next time
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] chore: Refactor dashboard header to func component [superset]
Posted by "kgabryje (via GitHub)" <gi...@apache.org>.
kgabryje commented on code in PR #31029:
URL: https://github.com/apache/superset/pull/31029#discussion_r1853864848
##########
superset-frontend/src/dashboard/components/Header/index.jsx:
##########
@@ -170,209 +146,253 @@ const discardBtnStyle = theme => css`
height: ${theme.gridUnit * 8}px;
`;
-class Header extends PureComponent {
- static discardChanges() {
- const url = new URL(window.location.href);
+const discardChanges = () => {
+ const url = new URL(window.location.href);
- url.searchParams.delete('edit');
- window.location.assign(url);
- }
+ url.searchParams.delete('edit');
+ window.location.assign(url);
+};
- constructor(props) {
- super(props);
- this.state = {
- didNotifyMaxUndoHistoryToast: false,
- emphasizeUndo: false,
- emphasizeRedo: false,
- showingPropertiesModal: false,
- isDropdownVisible: false,
- };
+const Header = () => {
+ const dispatch = useDispatch();
+ const [didNotifyMaxUndoHistoryToast, setDidNotifyMaxUndoHistoryToast] =
+ useState(false);
+ const [emphasizeUndo, setEmphasizeUndo] = useState(false);
+ const [emphasizeRedo, setEmphasizeRedo] = useState(false);
+ const [showingPropertiesModal, setShowingPropertiesModal] = useState(false);
+ const [isDropdownVisible, setIsDropdownVisible] = useState(false);
+ const [showingEmbedModal, setShowingEmbedModal] = useState(false);
+ const dashboardInfo = useSelector(state => state.dashboardInfo);
+ const layout = useSelector(state => state.dashboardLayout.present);
+ const undoLength = useSelector(state => state.dashboardLayout.past.length);
+ const redoLength = useSelector(state => state.dashboardLayout.future.length);
+ const dataMask = useSelector(state => state.dataMask);
+ const user = useSelector(state => state.user);
+ const chartIds = useChartIds();
+
+ const {
+ expandedSlices,
+ refreshFrequency,
+ shouldPersistRefreshFrequency,
+ customCss,
+ colorNamespace,
+ colorScheme,
+ isStarred,
+ isPublished,
+ hasUnsavedChanges,
+ maxUndoHistoryExceeded,
+ editMode,
+ lastModifiedTime,
+ } = useSelector(
+ state => ({
+ expandedSlices: state.dashboardState.expandedSlices,
+ refreshFrequency: state.dashboardState.refreshFrequency,
+ shouldPersistRefreshFrequency:
+ !!state.dashboardState.shouldPersistRefreshFrequency,
+ customCss: state.dashboardState.css,
+ colorNamespace: state.dashboardState.colorNamespace,
+ colorScheme: state.dashboardState.colorScheme,
+ isStarred: !!state.dashboardState.isStarred,
+ isPublished: !!state.dashboardState.isPublished,
+ hasUnsavedChanges: !!state.dashboardState.hasUnsavedChanges,
+ maxUndoHistoryExceeded: !!state.dashboardState.maxUndoHistoryExceeded,
+ editMode: !!state.dashboardState.editMode,
+ lastModifiedTime: state.lastModifiedTime,
+ }),
+ shallowEqual,
+ );
+ const isLoading = useSelector(state => isDashboardLoading(state.charts));
+
+ const refreshTimer = useRef(0);
+ const ctrlYTimeout = useRef(0);
+ const ctrlZTimeout = useRef(0);
+
+ const dashboardTitle = layout[DASHBOARD_HEADER_ID]?.meta?.text;
+ const { slug } = dashboardInfo;
+ const actualLastModifiedTime = Math.max(
+ lastModifiedTime,
+ dashboardInfo.last_modified_time,
+ );
+ const boundActionCreators = useMemo(
+ () =>
+ bindActionCreators(
+ {
+ addSuccessToast,
+ addDangerToast,
+ addWarningToast,
+ onUndo: undoLayoutAction,
+ onRedo: redoLayoutAction,
+ setEditMode,
+ setUnsavedChanges,
+ fetchFaveStar,
+ saveFaveStar,
+ savePublished,
+ fetchCharts,
+ updateDashboardTitle,
+ updateCss,
+ onChange,
+ onSave: saveDashboardRequest,
+ setMaxUndoHistoryExceeded,
+ maxUndoHistoryToast,
+ logEvent,
+ setRefreshFrequency,
+ onRefresh,
+ dashboardInfoChanged,
+ dashboardTitleChanged,
+ },
+ dispatch,
+ ),
+ [dispatch],
+ );
+
+ const startPeriodicRender = useCallback(
+ interval => {
+ let intervalMessage;
+
+ if (interval) {
+ const periodicRefreshOptions =
+ dashboardInfo.common?.conf?.DASHBOARD_AUTO_REFRESH_INTERVALS;
Review Comment:
it doesn't change, but _technically_ it could since it's a part of the redux state object, so it should be included in the dependency array - it won't hurt and it won't trigger a lint warning
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] chore: Refactor dashboard header to func component [superset]
Posted by "kgabryje (via GitHub)" <gi...@apache.org>.
kgabryje commented on code in PR #31029:
URL: https://github.com/apache/superset/pull/31029#discussion_r1853860772
##########
superset-frontend/src/dashboard/components/Header/index.jsx:
##########
@@ -383,58 +403,79 @@ class Header extends PureComponent {
certification_details: dashboardInfo.certification_details,
css: customCss,
dashboard_title: dashboardTitle,
- last_modified_time: lastModifiedTime,
+ last_modified_time: actualLastModifiedTime,
owners: dashboardInfo.owners,
roles: dashboardInfo.roles,
slug,
metadata: {
...dashboardInfo?.metadata,
color_namespace: currentColorNamespace,
color_scheme: currentColorScheme,
- positions,
- refresh_frequency: refreshFrequency,
+ positions: layout,
+ refresh_frequency: shouldPersistRefreshFrequency
+ ? refreshFrequency
+ : dashboardInfo.metadata?.refresh_frequency,
},
};
// make sure positions data less than DB storage limitation:
- const positionJSONLength = safeStringify(positions).length;
+ const positionJSONLength = safeStringify(layout).length;
const limit =
- dashboardInfo.common.conf.SUPERSET_DASHBOARD_POSITION_DATA_LIMIT ||
+ dashboardInfo.common?.conf?.SUPERSET_DASHBOARD_POSITION_DATA_LIMIT ||
DASHBOARD_POSITION_DATA_LIMIT;
if (positionJSONLength >= limit) {
- this.props.addDangerToast(
+ boundActionCreators.addDangerToast(
t(
'Your dashboard is too large. Please reduce its size before saving it.',
),
);
} else {
if (positionJSONLength >= limit * 0.9) {
- this.props.addWarningToast('Your dashboard is near the size limit.');
+ boundActionCreators.addWarningToast(
+ 'Your dashboard is near the size limit.',
Review Comment:
nice catch!
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] chore: Refactor dashboard header to func component [superset]
Posted by "Antonio-RiveroMartnez (via GitHub)" <gi...@apache.org>.
Antonio-RiveroMartnez commented on code in PR #31029:
URL: https://github.com/apache/superset/pull/31029#discussion_r1853832007
##########
superset-frontend/src/dashboard/components/Header/index.jsx:
##########
@@ -383,58 +403,79 @@ class Header extends PureComponent {
certification_details: dashboardInfo.certification_details,
css: customCss,
dashboard_title: dashboardTitle,
- last_modified_time: lastModifiedTime,
+ last_modified_time: actualLastModifiedTime,
owners: dashboardInfo.owners,
roles: dashboardInfo.roles,
slug,
metadata: {
...dashboardInfo?.metadata,
color_namespace: currentColorNamespace,
color_scheme: currentColorScheme,
- positions,
- refresh_frequency: refreshFrequency,
+ positions: layout,
+ refresh_frequency: shouldPersistRefreshFrequency
+ ? refreshFrequency
+ : dashboardInfo.metadata?.refresh_frequency,
},
};
// make sure positions data less than DB storage limitation:
- const positionJSONLength = safeStringify(positions).length;
+ const positionJSONLength = safeStringify(layout).length;
const limit =
- dashboardInfo.common.conf.SUPERSET_DASHBOARD_POSITION_DATA_LIMIT ||
+ dashboardInfo.common?.conf?.SUPERSET_DASHBOARD_POSITION_DATA_LIMIT ||
DASHBOARD_POSITION_DATA_LIMIT;
if (positionJSONLength >= limit) {
- this.props.addDangerToast(
+ boundActionCreators.addDangerToast(
t(
'Your dashboard is too large. Please reduce its size before saving it.',
),
);
} else {
if (positionJSONLength >= limit * 0.9) {
- this.props.addWarningToast('Your dashboard is near the size limit.');
+ boundActionCreators.addWarningToast(
+ 'Your dashboard is near the size limit.',
Review Comment:
Should we translate this?
##########
superset-frontend/src/dashboard/components/Header/index.jsx:
##########
@@ -170,209 +146,253 @@ const discardBtnStyle = theme => css`
height: ${theme.gridUnit * 8}px;
`;
-class Header extends PureComponent {
- static discardChanges() {
- const url = new URL(window.location.href);
+const discardChanges = () => {
+ const url = new URL(window.location.href);
- url.searchParams.delete('edit');
- window.location.assign(url);
- }
+ url.searchParams.delete('edit');
+ window.location.assign(url);
+};
- constructor(props) {
- super(props);
- this.state = {
- didNotifyMaxUndoHistoryToast: false,
- emphasizeUndo: false,
- emphasizeRedo: false,
- showingPropertiesModal: false,
- isDropdownVisible: false,
- };
+const Header = () => {
+ const dispatch = useDispatch();
+ const [didNotifyMaxUndoHistoryToast, setDidNotifyMaxUndoHistoryToast] =
+ useState(false);
+ const [emphasizeUndo, setEmphasizeUndo] = useState(false);
+ const [emphasizeRedo, setEmphasizeRedo] = useState(false);
+ const [showingPropertiesModal, setShowingPropertiesModal] = useState(false);
+ const [isDropdownVisible, setIsDropdownVisible] = useState(false);
+ const [showingEmbedModal, setShowingEmbedModal] = useState(false);
+ const dashboardInfo = useSelector(state => state.dashboardInfo);
+ const layout = useSelector(state => state.dashboardLayout.present);
+ const undoLength = useSelector(state => state.dashboardLayout.past.length);
+ const redoLength = useSelector(state => state.dashboardLayout.future.length);
+ const dataMask = useSelector(state => state.dataMask);
+ const user = useSelector(state => state.user);
+ const chartIds = useChartIds();
+
+ const {
+ expandedSlices,
+ refreshFrequency,
+ shouldPersistRefreshFrequency,
+ customCss,
+ colorNamespace,
+ colorScheme,
+ isStarred,
+ isPublished,
+ hasUnsavedChanges,
+ maxUndoHistoryExceeded,
+ editMode,
+ lastModifiedTime,
+ } = useSelector(
+ state => ({
+ expandedSlices: state.dashboardState.expandedSlices,
+ refreshFrequency: state.dashboardState.refreshFrequency,
+ shouldPersistRefreshFrequency:
+ !!state.dashboardState.shouldPersistRefreshFrequency,
+ customCss: state.dashboardState.css,
+ colorNamespace: state.dashboardState.colorNamespace,
+ colorScheme: state.dashboardState.colorScheme,
+ isStarred: !!state.dashboardState.isStarred,
+ isPublished: !!state.dashboardState.isPublished,
+ hasUnsavedChanges: !!state.dashboardState.hasUnsavedChanges,
+ maxUndoHistoryExceeded: !!state.dashboardState.maxUndoHistoryExceeded,
+ editMode: !!state.dashboardState.editMode,
+ lastModifiedTime: state.lastModifiedTime,
+ }),
+ shallowEqual,
+ );
+ const isLoading = useSelector(state => isDashboardLoading(state.charts));
+
+ const refreshTimer = useRef(0);
+ const ctrlYTimeout = useRef(0);
+ const ctrlZTimeout = useRef(0);
+
+ const dashboardTitle = layout[DASHBOARD_HEADER_ID]?.meta?.text;
+ const { slug } = dashboardInfo;
+ const actualLastModifiedTime = Math.max(
+ lastModifiedTime,
+ dashboardInfo.last_modified_time,
+ );
+ const boundActionCreators = useMemo(
+ () =>
+ bindActionCreators(
+ {
+ addSuccessToast,
+ addDangerToast,
+ addWarningToast,
+ onUndo: undoLayoutAction,
+ onRedo: redoLayoutAction,
+ setEditMode,
+ setUnsavedChanges,
+ fetchFaveStar,
+ saveFaveStar,
+ savePublished,
+ fetchCharts,
+ updateDashboardTitle,
+ updateCss,
+ onChange,
+ onSave: saveDashboardRequest,
+ setMaxUndoHistoryExceeded,
+ maxUndoHistoryToast,
+ logEvent,
+ setRefreshFrequency,
+ onRefresh,
+ dashboardInfoChanged,
+ dashboardTitleChanged,
+ },
+ dispatch,
+ ),
+ [dispatch],
+ );
+
+ const startPeriodicRender = useCallback(
+ interval => {
+ let intervalMessage;
+
+ if (interval) {
+ const periodicRefreshOptions =
+ dashboardInfo.common?.conf?.DASHBOARD_AUTO_REFRESH_INTERVALS;
+ const predefinedValue = periodicRefreshOptions.find(
+ option => Number(option[0]) === interval / 1000,
+ );
- this.handleChangeText = this.handleChangeText.bind(this);
- this.handleCtrlZ = this.handleCtrlZ.bind(this);
- this.handleCtrlY = this.handleCtrlY.bind(this);
- this.toggleEditMode = this.toggleEditMode.bind(this);
- this.forceRefresh = this.forceRefresh.bind(this);
- this.startPeriodicRender = this.startPeriodicRender.bind(this);
- this.overwriteDashboard = this.overwriteDashboard.bind(this);
- this.showPropertiesModal = this.showPropertiesModal.bind(this);
- this.hidePropertiesModal = this.hidePropertiesModal.bind(this);
- this.setIsDropdownVisible = this.setIsDropdownVisible.bind(this);
- }
+ if (predefinedValue) {
+ intervalMessage = t(predefinedValue[1]);
+ } else {
+ intervalMessage = moment.duration(interval, 'millisecond').humanize();
+ }
+ }
- componentDidMount() {
- const { refreshFrequency } = this.props;
- this.startPeriodicRender(refreshFrequency * 1000);
- }
+ const periodicRender = () => {
+ const { metadata } = dashboardInfo;
+ const immune = metadata.timed_refresh_immune_slices || [];
+ const affectedCharts = chartIds.filter(
+ chartId => immune.indexOf(chartId) === -1,
+ );
- componentDidUpdate(prevProps) {
- if (this.props.refreshFrequency !== prevProps.refreshFrequency) {
- const { refreshFrequency } = this.props;
- this.startPeriodicRender(refreshFrequency * 1000);
- }
- }
+ boundActionCreators.logEvent(LOG_ACTIONS_PERIODIC_RENDER_DASHBOARD, {
+ interval,
+ chartCount: affectedCharts.length,
+ });
+ boundActionCreators.addWarningToast(
+ t(
+ `This dashboard is currently auto refreshing; the next auto refresh will be in %s.`,
+ intervalMessage,
+ ),
+ );
+ if (
+ dashboardInfo.common?.conf?.DASHBOARD_AUTO_REFRESH_MODE === 'fetch'
+ ) {
+ // force-refresh while auto-refresh in dashboard
+ return boundActionCreators.fetchCharts(
Review Comment:
nit: I know it was like this before this PR, but we could DRY it with a helper function so you can pass the boolean as arg and return the `fetchCharts` call with it here and the one below
##########
superset-frontend/src/dashboard/components/Header/index.jsx:
##########
@@ -170,209 +146,253 @@ const discardBtnStyle = theme => css`
height: ${theme.gridUnit * 8}px;
`;
-class Header extends PureComponent {
- static discardChanges() {
- const url = new URL(window.location.href);
+const discardChanges = () => {
+ const url = new URL(window.location.href);
- url.searchParams.delete('edit');
- window.location.assign(url);
- }
+ url.searchParams.delete('edit');
+ window.location.assign(url);
+};
- constructor(props) {
- super(props);
- this.state = {
- didNotifyMaxUndoHistoryToast: false,
- emphasizeUndo: false,
- emphasizeRedo: false,
- showingPropertiesModal: false,
- isDropdownVisible: false,
- };
+const Header = () => {
+ const dispatch = useDispatch();
+ const [didNotifyMaxUndoHistoryToast, setDidNotifyMaxUndoHistoryToast] =
+ useState(false);
+ const [emphasizeUndo, setEmphasizeUndo] = useState(false);
+ const [emphasizeRedo, setEmphasizeRedo] = useState(false);
+ const [showingPropertiesModal, setShowingPropertiesModal] = useState(false);
+ const [isDropdownVisible, setIsDropdownVisible] = useState(false);
+ const [showingEmbedModal, setShowingEmbedModal] = useState(false);
+ const dashboardInfo = useSelector(state => state.dashboardInfo);
+ const layout = useSelector(state => state.dashboardLayout.present);
+ const undoLength = useSelector(state => state.dashboardLayout.past.length);
+ const redoLength = useSelector(state => state.dashboardLayout.future.length);
+ const dataMask = useSelector(state => state.dataMask);
+ const user = useSelector(state => state.user);
+ const chartIds = useChartIds();
+
+ const {
+ expandedSlices,
+ refreshFrequency,
+ shouldPersistRefreshFrequency,
+ customCss,
+ colorNamespace,
+ colorScheme,
+ isStarred,
+ isPublished,
+ hasUnsavedChanges,
+ maxUndoHistoryExceeded,
+ editMode,
+ lastModifiedTime,
+ } = useSelector(
+ state => ({
+ expandedSlices: state.dashboardState.expandedSlices,
+ refreshFrequency: state.dashboardState.refreshFrequency,
+ shouldPersistRefreshFrequency:
+ !!state.dashboardState.shouldPersistRefreshFrequency,
+ customCss: state.dashboardState.css,
+ colorNamespace: state.dashboardState.colorNamespace,
+ colorScheme: state.dashboardState.colorScheme,
+ isStarred: !!state.dashboardState.isStarred,
+ isPublished: !!state.dashboardState.isPublished,
+ hasUnsavedChanges: !!state.dashboardState.hasUnsavedChanges,
+ maxUndoHistoryExceeded: !!state.dashboardState.maxUndoHistoryExceeded,
+ editMode: !!state.dashboardState.editMode,
+ lastModifiedTime: state.lastModifiedTime,
+ }),
+ shallowEqual,
+ );
+ const isLoading = useSelector(state => isDashboardLoading(state.charts));
+
+ const refreshTimer = useRef(0);
+ const ctrlYTimeout = useRef(0);
+ const ctrlZTimeout = useRef(0);
+
+ const dashboardTitle = layout[DASHBOARD_HEADER_ID]?.meta?.text;
+ const { slug } = dashboardInfo;
+ const actualLastModifiedTime = Math.max(
+ lastModifiedTime,
+ dashboardInfo.last_modified_time,
+ );
+ const boundActionCreators = useMemo(
+ () =>
+ bindActionCreators(
+ {
+ addSuccessToast,
+ addDangerToast,
+ addWarningToast,
+ onUndo: undoLayoutAction,
+ onRedo: redoLayoutAction,
+ setEditMode,
+ setUnsavedChanges,
+ fetchFaveStar,
+ saveFaveStar,
+ savePublished,
+ fetchCharts,
+ updateDashboardTitle,
+ updateCss,
+ onChange,
+ onSave: saveDashboardRequest,
+ setMaxUndoHistoryExceeded,
+ maxUndoHistoryToast,
+ logEvent,
+ setRefreshFrequency,
+ onRefresh,
+ dashboardInfoChanged,
+ dashboardTitleChanged,
+ },
+ dispatch,
+ ),
+ [dispatch],
+ );
+
+ const startPeriodicRender = useCallback(
+ interval => {
+ let intervalMessage;
+
+ if (interval) {
+ const periodicRefreshOptions =
+ dashboardInfo.common?.conf?.DASHBOARD_AUTO_REFRESH_INTERVALS;
Review Comment:
nit: Is this value dynamically changing somewhere or just a static config loaded once? If static, we could move this out the callback.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] chore: Refactor dashboard header to func component [superset]
Posted by "kgabryje (via GitHub)" <gi...@apache.org>.
kgabryje merged PR #31029:
URL: https://github.com/apache/superset/pull/31029
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] chore: Refactor dashboard header to func component [superset]
Posted by "michael-s-molina (via GitHub)" <gi...@apache.org>.
michael-s-molina commented on PR #31029:
URL: https://github.com/apache/superset/pull/31029#issuecomment-2494491426
Maybe it would be nice to use `refactor` instead of `chore` for this type of PR.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org