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

[Share Modal Redesign] Reporting modals with licensing using link/embed tabbed modal component #179206

Closed
wants to merge 97 commits into from

Conversation

rshen91
Copy link
Contributor

@rshen91 rshen91 commented Mar 22, 2024

Summary

This PR is focused on the redesign in terms of the export modals. Test refactoring will be done in a separate PR.
Partially closes https://github.com/elastic/kibana-team/issues/753

  • Need to refactor this PR to include @eokoneyo's general modal component
  • Lens needs to have Export with all three report type options - to avoid circular dependencies move the Lens CSV stuff into the reporting plugin vs having it in Lens
  • Canvas should not be affected by these changes (so the old share/reporting code has to stay for canvas)
    [Discover] Unsaved work error on CSV reports for read-only user #151523 to keep in mind for the redesign

Failed tests will be covered in this PR #179694

To test:

Add share.new_version.enabled: true to your kibana.dev.yml

Checklist

Any text added follows EUI's writing guidelines, uses sentence case text and includes i18n support

@rshen91 rshen91 self-assigned this Mar 22, 2024
@rshen91
Copy link
Contributor Author

rshen91 commented Mar 29, 2024

/ci

@kibana-ci
Copy link
Collaborator

kibana-ci commented Mar 29, 2024

💔 Build Failed

Failed CI Steps

Test Failures

  • [job] [logs] FTR Configs #75 / Alerts and alerts index related logic - Basic License/Essentials Tier Alert status APIs @ess @serverless change alert status endpoints validation checks update by ids should not give errors when querying and the alerts index does not exist yet
  • [job] [logs] FTR Configs #70 / dashboard Reporting Dashboard Reporting Screenshots Print PDF button is available if new
  • [job] [logs] FTR Configs #70 / dashboard Reporting Dashboard Reporting Screenshots Print PDF button is available if new
  • [job] [logs] FTR Configs #17 / discover Discover CSV Export Generate CSV: new search generates a report with single timefilter
  • [job] [logs] FTR Configs #18 / discover Discover CSV Export Generate CSV: new search generates a report with single timefilter
  • [job] [logs] FTR Configs #25 / discover Discover CSV Export Generate CSV: new search generates a report with single timefilter
  • [job] [logs] FTR Configs #33 / discover Discover CSV Export Generate CSV: new search generates a report with single timefilter
  • [job] [logs] FTR Configs #33 / discover Discover CSV Export Generate CSV: new search generates a report with single timefilter
  • [job] [logs] FTR Configs #18 / discover Discover CSV Export Generate CSV: new search generates a report with single timefilter
  • [job] [logs] FTR Configs #17 / discover Discover CSV Export Generate CSV: new search generates a report with single timefilter
  • [job] [logs] FTR Configs #25 / discover Discover CSV Export Generate CSV: new search generates a report with single timefilter
  • [job] [logs] FTR Configs #36 / lens app - group 1 lens ad hoc data view tests should be possible to share a URL of a visualization with adhoc dataViews
  • [job] [logs] FTR Configs #36 / lens app - group 1 lens ad hoc data view tests should be possible to share a URL of a visualization with adhoc dataViews
  • [job] [logs] FTR Configs #57 / lens app - group 4 lens share tests should enable both download and URL sharing for valid configuration
  • [job] [logs] FTR Configs #57 / lens app - group 4 lens share tests should enable both download and URL sharing for valid configuration
  • [job] [logs] FTR Configs #32 / lens app - group 6 lens reporting should not cause PDF reports to fail
  • [job] [logs] FTR Configs #32 / lens app - group 6 lens reporting should not cause PDF reports to fail
  • [job] [logs] FTR Configs #38 / maps app dashboard reporting: creates a map report PNG file matches the baseline image, using sample geo data
  • [job] [logs] FTR Configs #38 / maps app dashboard reporting: creates a map report PNG file matches the baseline image, using sample geo data
  • [job] [logs] FTR Configs #88 / reporting examples Captures PNG file matches the baseline image
  • [job] [logs] FTR Configs #88 / reporting examples Captures PNG file matches the baseline image
  • [job] [logs] FTR Configs #69 / Reporting Functional Tests with Deprecated Security configuration enabled Security with reporting_user built-in role Dashboard: Generate Screenshot does not allow user that does not have reporting_user role
  • [job] [logs] FTR Configs #69 / Reporting Functional Tests with Deprecated Security configuration enabled Security with reporting_user built-in role Dashboard: Generate Screenshot does not allow user that does not have reporting_user role
  • [job] [logs] FTR Configs #27 / Reporting Functional Tests with Security enabled Security with reporting_user built-in role Dashboard: Generate Screenshot does allow PDF generation user with reporting privileges
  • [job] [logs] FTR Configs #27 / Reporting Functional Tests with Security enabled Security with reporting_user built-in role Dashboard: Generate Screenshot does allow PDF generation user with reporting privileges
  • [job] [logs] FTR Configs #96 / Visualize Visualize Reporting Screenshots Print PDF button is available if new
  • [job] [logs] FTR Configs #96 / Visualize Visualize Reporting Screenshots Print PDF button is available if new

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
reporting 122 130 +8
share 85 95 +10
total +18

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
lens 1.4MB 1.4MB +32.0B
reporting 71.2KB 67.8KB -3.3KB
share 6.1KB 3.6KB -2.4KB
total -5.7KB

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
lens 46.4KB 46.5KB +153.0B
reporting 47.8KB 62.4KB +14.7KB
share 55.0KB 66.4KB +11.4KB
total +26.2KB

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

cc @rshen91

downloadCsvShareProvider({
uiSettings: core.uiSettings,
formatFactoryFn: () => startServices().plugins.fieldFormats.deserialize,
license,
Copy link
Member

Choose a reason for hiding this comment

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

It looks like the CSV Download option is getting removed unless the license type is at least Gold. It would be better to handle that here, and use the license type as a condition to suppress registration of the option completely.

       const startServices$ = from(getStartServices());
       startServices$.subscribe(([, { licensing }]) => {
         licensing?.license$.subscribe((license) => {
-          return share.register(
-            downloadCsvShareProvider({
-              uiSettings: core.uiSettings,
-              formatFactoryFn: () => startServices().plugins.fieldFormats.deserialize,
-              license,
-            })
-          );
+          const atLeastGold = license.hasAtLeast('gold');
+          if (atLeastGold) {
+            share.register(
+              downloadCsvShareProvider({
+                uiSettings: core.uiSettings,
+                formatFactoryFn: () => startServices().plugins.fieldFormats.deserialize,
+              })
+            );
+          }
         });
       });

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oh I love this thank you

? [
{ id: 'printablePdfV2', label: 'PDF' },
{ id: 'pngV2', label: 'PNG', 'data-test-subj': 'pngReportOption' },
{ id: 'csv', label: 'CSV', 'data-test-subj': 'lensCSVReport' },
Copy link
Member

Choose a reason for hiding this comment

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

Lens CSV Report doesn't belong here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok so I think I'm following based on the comment #179206 (comment) and keeping in mind the designs in the figma, I would want to set up the modal to have the registerModalOption(exportCsv, exportPdf, exportPng)? Because Lens will have to have all three types in the same export...For the other cases I think I'm following. Thanks!

// needed for canvas
getJobParams?: JobAppParamsPDFV2;
objectType: string;
downloadCsvFromLens: () => void;
Copy link
Member

Choose a reason for hiding this comment

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

"Download CSV From Lens" doesn't belong here


export type Props = ReportingModalProps & { intl: InjectedIntl };

type AllowedImageExportType = 'pngV2' | 'printablePdfV2' | 'printablePdf' | 'csv';
Copy link
Member

Choose a reason for hiding this comment

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

  • csv isn't an image type
    *printablePdf is deprecated, so is only available via API, not the UI
Suggested change
type AllowedImageExportType = 'pngV2' | 'printablePdfV2' | 'printablePdf' | 'csv';
type AllowedImageExportType = 'pngV2' | 'printablePdfV2';

@tsullivan
Copy link
Member

tsullivan commented Apr 1, 2024

The PR needs to support everything the way it was by default, when share.new_version.enabled: false is set. To achieve that, I recommend creating new methods in the Share plugin setup contract, to use for the new experience, instead of re-using the register method for both experiences. This is because the way modal options are shown doesn't overlap with the old way: the new has options belonging to specific tabs, which have to be declared when the option gets registered.

With share.new_version.enabled: true, use a new, distinct method:
With share.new_version.enabled: false, use the old method:

const { share: shareSetup } = somethingPluginSetupDeps;
if (isNewVersionEnabled) {
  shareSetup.registerModalOption(somethingShareModalOptionProvider()); // new functionality
} else {
  shareSetup.register(somethingShareProvider()); // existing functionality
}

In the modal, each sharing tab is responsible for showing certain kinds of options. This doesn't overlap with the old way, where the sharing menu shows all the components that get registered. In the new way, the objects that get registered should describe a component and that component will have to be brought to life in the sharing tab. I recommend defining a new type of object (ShareModalOption) that describes which tab it belongs to, and a model for how the user selects the option, and what happens when the user selects the option.

interface ShareModalOption {
  /*
   * Define which tab the option belongs to
   */
  tabType: 'links' | 'export';

  /*
   * When the option is selected, the header shows intro about the option.
   * If there is a single option, the header is static.
   */
  headerWhenSelected: string;

  /*
   * When the option is selected, the footer shows a primary button and optionally a secondary button
   * If there is a single option, the footer is static.
   */
  footerWhenSelected: Array<{ type: 'primaryBtn' | 'secondaryBtn'; text: string }>;

  /*
   * Control the actions that happen when the option is selected, such as copy the link, download the CSV, or
   * send a request to generate a report. Make sure the action calls a close() method if the modal should be
   * closed after the action happens.
   */
  action: Function;

  /*
   * The sharable link option is "single"
   * The export options use "radio"
   */
  optionType: 'single' | 'radio';

  /*
   * If there are radio options in the tab, use this to show the label above the options
   */
  radioType?: 'fileType';

  /*
   * The Sharing Link option will be a JSX.Element showing the link text
   * The Export options will be a string, such as "PDF", "PNG", "CSV"
   */
  content: string | JSX.Element;
}

/*
 * built-in to share plugin?
 */
const copyLink: ShareModalOption = {
  tabType: 'links',
  headerWhenSelected: 'Share a direct link to this lens.',
  footerWhenSelected: [{ type: 'primaryBtn', text: 'Copy link' }],
  action: () => {
    /* call the copy-to-clipboard code */
  },
  optionType: 'single',
  content: <>{/* component to show the text with copyable link */}</>,
};
shareSetup.registerModalOption(copyLink);

/*
 * lens/public/plugin.ts
 */
const downloadCsv: ShareModalOption = {
  tabType: 'export',
  headerWhenSelected: 'Download the data displayed in the visualization.',
  footerWhenSelected: [{ type: 'primaryBtn', text: 'Download CSV' }],
  action: () => {
    /* call the download CSV code */
  },
  optionType: 'radio',
  radioType: 'fileType',
  content: <>CSV</>,
};
shareSetup.registerModalOption(downloadCsv);

/*
 * reporting/public/plugin.ts
 */
const exportPdf: ShareModalOption = {
  tabType: 'export',
  headerWhenSelected: 'Exports can take a few minutes to generate.',
  footerWhenSelected: [
    { type: 'secondaryBtn', text: 'Copy POST URL' },
    { type: 'primaryBtn', text: 'Generate report' },
  ],
  action: () => {
    /* call the generate PDF code */
  },
  optionType: 'radio',
  radioType: 'fileType',
  content: <>PDF</>,
};

const exportPng: ShareModalOption = {
  tabType: 'export',
  headerWhenSelected: 'Exports can take a few minutes to generate.',
  footerWhenSelected: [
    { type: 'secondaryBtn', text: 'Copy POST URL' },
    { type: 'primaryBtn', text: 'Generate report' },
  ],
  action: () => {
    /* call the generate PNG code */
  },
  optionType: 'radio',
  radioType: 'fileType',
  content: <>PNG</>,
};
shareSetup.registerModalOption(exportPdf);
shareSetup.registerModalOption(exportPng);

When these types of objects are registered, the Sharing Modal has the job retrieve them and "bring them to life" in the tab, by picking the options that belong to the tab, showing the content, updating things based on the selected option, and calling the action when the buttons are clicked.

This interface is just a starting point. You might need more fields, such as an action function for "secondary buttons," and for fine-tuning things like the ordering of radio options, putting in icons, etc. I hope this helps!

@rshen91
Copy link
Contributor Author

rshen91 commented Apr 4, 2024

Closing in favor of PR #180009

@rshen91 rshen91 closed this Apr 4, 2024
rshen91 added a commit that referenced this pull request Apr 16, 2024
## Summary

This PR refactors #179206 to have
each export type be registered in Reporting and then passed into the
share plugin.

This PR is focused on the redesign in terms of the export modals. Test
refactoring will be done in a separate PR.
Partially closes elastic/kibana-team#753

- [x] Need to refactor this PR to include @eokoneyo's general modal
component
- [x] Lens needs to have Export with all three report type options - to
avoid circular dependencies move the Lens CSV stuff into the reporting
plugin vs having it in Lens
- [x] Canvas should not be affected by these changes (so the old
share/reporting code has to stay for canvas)
#151523 to keep in mind for the
redesign

Failed tests will be covered in this PR
#180406


### TO TEST 

Mark `share.new_version.enabled: true` in your kibana.dev.yml


### Checklist

- [x] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)
- [x] Any UI touched in this PR is usable by keyboard only (learn more
about [keyboard accessibility](https://webaim.org/techniques/keyboard/))

---------

Co-authored-by: Eyo Okon Eyo <eyo.eyo@elastic.co>
Co-authored-by: Tim Sullivan <tsullivan@users.noreply.github.com>
Co-authored-by: Marco Liberati <dej611@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants