Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(dashboard): confirm overwrite to prevent unintended changes #21819

Conversation

justinpark
Copy link
Member

@justinpark justinpark commented Oct 14, 2022

SUMMARY

At Airbnb, there's reasonable amount of reporting about unintended overwritten of filter scopes settings.
We believe there must be unknown overwriting on json_metadata by other authors during editing. (json_metadata can be easily overwritten since it passes all attributes including unchanged values.)
This commit introduces the inspection step for this high volatility value changes and then proceed to update with the user's confirmation. (the inspection items are defined here)
This commit also adds the logging for the user confirmation.

BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

review-overwrite-values.mov

TESTING INSTRUCTIONS

  • set ENABLE_CONFIRM_OVERWRITE_DASHBOARD_METADATA feature flag to true
  • go to any dashboard page
  • update css or/and filter scopes
  • click save to confirm the overwrite values

ADDITIONAL INFORMATION

  • Has associated issue:
  • Required feature flags: ENABLE_CONFIRM_OVERWRITE_DASHBOARD_METADATA
  • Changes UI
  • Includes DB Migration (follow approval process in SIP-59)
    • 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

cc: @ktmud @john-bodley

@codecov
Copy link

codecov bot commented Oct 15, 2022

Codecov Report

Merging #21819 (c6e9b24) into master (72598a5) will increase coverage by 1.22%.
The diff coverage is 87.67%.

❗ Current head c6e9b24 differs from pull request most recent head 0ca291d. Consider uploading reports for the commit 0ca291d to get more accurate results

@@            Coverage Diff             @@
##           master   #21819      +/-   ##
==========================================
+ Coverage   65.72%   66.94%   +1.22%     
==========================================
  Files        1809     1809              
  Lines       69335    69178     -157     
  Branches     7413     7401      -12     
==========================================
+ Hits        45571    46313     +742     
+ Misses      21853    20952     -901     
- Partials     1911     1913       +2     
Flag Coverage Δ
javascript 53.43% <87.67%> (+0.02%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
...ackages/superset-ui-core/src/utils/featureFlags.ts 100.00% <ø> (ø)
...frontend/src/dashboard/components/Header/index.jsx 59.85% <ø> (+0.86%) ⬆️
...-frontend/src/dashboard/reducers/dashboardState.js 74.46% <ø> (-1.62%) ⬇️
...ponents/OverwriteConfirm/OverwriteConfirmModal.tsx 82.14% <82.14%> (ø)
...t-frontend/src/dashboard/actions/dashboardState.js 52.94% <88.00%> (+15.84%) ⬆️
...t-frontend/src/dashboard/util/getOverwriteItems.ts 90.90% <90.90%> (ø)
...rc/dashboard/components/OverwriteConfirm/index.tsx 100.00% <100.00%> (ø)
superset-frontend/src/dashboard/constants.ts 100.00% <100.00%> (ø)
superset-frontend/src/dashboard/util/constants.ts 100.00% <100.00%> (ø)
superset-frontend/src/logger/LogUtils.ts 96.15% <100.00%> (ø)
... and 160 more

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

{
keyPath: 'json_metadata.filter_scopes',
oldValue:
'{\n "122": {\n "ethnic_minority": {\n "scope": [\n "ROOT_ID"\n ],\n "immune": []\n },\n "gender": {\n "scope": [\n "ROOT_ID"\n ],\n "immune": []\n },\n "developer_type": {\n "scope": [\n "ROOT_ID"\n ],\n "immune": []\n },\n "lang_at_home": {\n "scope": [\n "ROOT_ID"\n ],\n "immune": []\n },\n "country_live": {\n "scope": [\n "ROOT_ID"\n ],\n "immune": []\n }\n }\n}',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add \t here and/or compare the old/new without the formatting, i.e., as a parsed JSON blob?

@michael-s-molina
Copy link
Member

Thanks for this exciting feature @justinpark! Some first-pass comments:

1 - Can we rename the feature flag to a shorter name like DASHBOARD_METADATA_DIFF or anything else?

2 - Can you add the new feature flag to RESOURCES/FEATURE_FLAGS.md?

3 - Can we set a min/max width/height to the modal to avoid the situation where it takes the whole screen?

4 - Can we make the modal appear only when there's a change to the scope or CSS? Unrelated changes shouldn't present it.

5 - Is it possible to make the scope changes more user-friendly? It's showing ID diffs that are not traceable to the screen. Maybe add the chart names to the diff or use a different kind of scope representation when comparing.

Copy link
Member

@ktmud ktmud left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

++ to @michael-s-molina 's comments.

A diff modal is a useful add when some of the updates may be implicit but I agree more visual diffs would be nice. I'm also wondering if in the long run we should strive for not requiring diff confirmation as we get more confident that the updates would not accidentally make unwanted changes.

If this is only meant to be temporary---which I'd assume is the case since it's in a feature flag, I think it'd be okay to just show JSON diffs.

@@ -48,6 +48,7 @@ export enum FeatureFlag {
ENABLE_JAVASCRIPT_CONTROLS = 'ENABLE_JAVASCRIPT_CONTROLS',
ENABLE_TEMPLATE_PROCESSING = 'ENABLE_TEMPLATE_PROCESSING',
ENABLE_TEMPLATE_REMOVE_FILTERS = 'ENABLE_TEMPLATE_REMOVE_FILTERS',
ENABLE_CONFIRM_OVERWRITE_DASHBOARD_METADATA = 'ENABLE_CONFIRM_OVERWRITE_DASHBOARD_METADATA',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ENABLE_CONFIRM_OVERWRITE_DASHBOARD_METADATA = 'ENABLE_CONFIRM_OVERWRITE_DASHBOARD_METADATA',
CONFIRM_DASHBOARD_DIFF = 'CONFIRM_DASHBOARD_DIFF',

keyPath: 'css',
oldValue: '',
newValue:
".navbar {\n transition: opacity 0.5s ease;\n opacity: 0.05;\n}\n.navbar:hover {\n opacity: 1;\n}\n.chart-header .header{\n font-weight: @font-weight-normal;\n font-size: 12px;\n}\n/*\nvar bnbColors = [\n //rausch hackb kazan babu lima beach tirol\n '#ff5a5f', '#7b0051', '#007A87', '#00d1c1', '#8ce071', '#ffb400', '#b4a76c',\n '#ff8083', '#cc0086', '#00a1b3', '#00ffeb', '#bbedab', '#ffd266', '#cbc29a',\n '#ff3339', '#ff1ab1', '#005c66', '#00b3a5', '#55d12e', '#b37e00', '#988b4e',\n ];\n*/\n",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this file is manually generated, could we use template literals to display multiline strings instead?

Comment on lines 36 to 37
latestUpdatedAt: '2022-10-07T16:35:30.924212',
latestUpdatedBy: 'Superset Admin',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
latestUpdatedAt: '2022-10-07T16:35:30.924212',
latestUpdatedBy: 'Superset Admin',
updatedAt: '2022-10-07T16:35:30.924212',
updatedBy: 'Superset Admin'

Nit: I think this is clear enough.


return SupersetClient.put({
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this dispatch function returns a promise, can we just rewrite it with async/await?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be better to have a separate PR for the async/await migration.

}
onHide={onHide}
>
<>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this fragment needed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch. removed

title={t('Confirm overwrite')}
footer={
<>
{t('* Scroll down to the bottom to complete the review. ')}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
{t('* Scroll down to the bottom to complete the review. ')}
{t('Scroll down to the bottom to complete the review. ')}

Not sure if * is needed.

cta
buttonStyle="primary"
onClick={onConfirmOverwrite}
disabled={!hasReviewed}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a tooltip to explain the disabled state?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The following description should be enough to explain the disabled state.

my_new_dashboard

`}
`;

const StackableHeader = styled(Button)<{ top: number }>`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This header is currently rendered as all caps (probably inherited style from Button). Is that what we want?

@justinpark
Copy link
Member Author

1 - Can we rename the feature flag to a shorter name like DASHBOARD_METADATA_DIFF or anything else?

I updated to CONFIRM_DASHBOARD_DIFF

2 - Can you add the new feature flag to RESOURCES/FEATURE_FLAGS.md?

Yes. updated.

3 - Can we set a min/max width/height to the modal to avoid the situation where it takes the whole screen?

Yes I added the maxWidth using responsive. (its size up to 1024px)

4 - Can we make the modal appear only when there's a change to the scope or CSS? Unrelated changes shouldn't present it.

Sure. The modal only pops up when the following values are changed.

export const OVERWRITE_INSPECT_FIELDS = ['css', 'json_metadata.filter_scopes'];

5 - Is it possible to make the scope changes more user-friendly? It's showing ID diffs that are not traceable to the screen. Maybe add the chart names to the diff or use a different kind of scope representation when comparing.

as @ktmud commented, it becomes complicated to access the scope labels and its hierarchy. I'll follow up this improvement in the next step.

@justinpark justinpark force-pushed the feat--dashboard-confirm-overwrite-unintended-changes branch from c6e9b24 to 0ca291d Compare November 1, 2022 23:02
@justinpark
Copy link
Member Author

1 - Can we rename the feature flag to a shorter name like DASHBOARD_METADATA_DIFF or anything else?

I updated to CONFIRM_DASHBOARD_DIFF

2 - Can you add the new feature flag to RESOURCES/FEATURE_FLAGS.md?

Yes. updated.

3 - Can we set a min/max width/height to the modal to avoid the situation where it takes the whole screen?

Yes I added the maxWidth using responsive. (its size up to 1024px)

4 - Can we make the modal appear only when there's a change to the scope or CSS? Unrelated changes shouldn't present it.

Sure. The modal only pops up when the following values are changed.

export const OVERWRITE_INSPECT_FIELDS = ['css', 'json_metadata.filter_scopes'];

5 - Is it possible to make the scope changes more user-friendly? It's showing ID diffs that are not traceable to the screen. Maybe add the chart names to the diff or use a different kind of scope representation when comparing.

as ktmud commented, it becomes complicated to access the scope labels and its hierarchy. I'll follow up this improvement in the next step.

@michael-s-molina do you have any objections with the approach? We'd like to kick off the feature with JSON diffs first. (and then will follow up the improved labels version)

@michael-s-molina
Copy link
Member

@michael-s-molina do you have any objections with the approach? We'd like to kick off the feature with JSON diffs first. (and then will follow up the improved labels version)

No problem 👍🏼

@justinpark
Copy link
Member Author

@michael-s-molina do you have any objections with the approach? We'd like to kick off the feature with JSON diffs first. (and then will follow up the improved labels version)

No problem 👍🏼

Great! can you approve the change? (it's blocked by the reviewers)

@john-bodley john-bodley merged commit ef6b9a9 into apache:master Nov 8, 2022
john-bodley pushed a commit to airbnb/superset-fork that referenced this pull request Nov 8, 2022
@mistercrunch mistercrunch added 🏷️ bot A label used by `supersetbot` to keep track of which PR where auto-tagged with release labels 🚢 2.1.0 labels Mar 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🏷️ bot A label used by `supersetbot` to keep track of which PR where auto-tagged with release labels size/XL 🚢 2.1.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants