Skip to content

Commit

Permalink
[Reporting] Reporting info panel touch ups (#120617)
Browse files Browse the repository at this point in the history
* changed info -> summary and combined maximum attempts and attempts field

* added spaceId if it is there to job info

* moved space id to job details section

* moved processing and job info into a single array

* wip, introduced a new structure to the flyout for easier visual parsing. still need to re-introduce errors and deprecated report types in the new structure

* remove unnecessary div

* added warnings and errors to callout and cleaned up comments

* remove unused functionality and introduce date formatting per advanced settings format

* remove unused import

* remove unused i18n

* refactor check for info.max_attempts in flyout content

Co-authored-by: Tim Sullivan <[email protected]>

* update info.lyout.dimensions.height to be Math.ceiled

Co-authored-by: Tim Sullivan <[email protected]>

* update info.lyout.dimensions.width to be Math.ceiled

Co-authored-by: Tim Sullivan <[email protected]>

* lint and remove bad suggestion commit

* added actions button to flyout, in flyout footer

* create a little bit more breathing room for the section titles

* added logic to disable the action buttons in the flyout when the actions are not ready

* update copy per feedback

* added basic tests for the actions menu in the flyout

Co-authored-by: Kibana Machine <[email protected]>
Co-authored-by: Tim Sullivan <[email protected]>
  • Loading branch information
3 people authored Dec 15, 2021
1 parent 692f224 commit d213263
Show file tree
Hide file tree
Showing 11 changed files with 331 additions and 169 deletions.
7 changes: 6 additions & 1 deletion x-pack/plugins/reporting/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,12 @@ export const CSV_SEARCHSOURCE_IMMEDIATE_TYPE = 'csv_searchsource_immediate';
export const CSV_REPORT_TYPE_DEPRECATED = 'CSV';
export const CSV_JOB_TYPE_DEPRECATED = 'csv';

export const USES_HEADLESS_JOB_TYPES = [PDF_JOB_TYPE, PNG_JOB_TYPE];
export const USES_HEADLESS_JOB_TYPES = [
PDF_JOB_TYPE,
PNG_JOB_TYPE,
PDF_JOB_TYPE_V2,
PNG_JOB_TYPE_V2,
];

export const DEPRECATED_JOB_TYPES = [CSV_JOB_TYPE_DEPRECATED];

Expand Down
49 changes: 24 additions & 25 deletions x-pack/plugins/reporting/public/lib/job.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

import { EuiText, EuiTextColor } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import moment from 'moment';
import React from 'react';
import { JOB_STATUSES } from '../../common/constants';
Expand Down Expand Up @@ -38,6 +37,7 @@ export class Job {
public spaceId: ReportPayload['spaceId'];
public browserTimezone?: ReportPayload['browserTimezone'];
public layout: ReportPayload['layout'];
public version: ReportPayload['version'];

public jobtype: ReportSource['jobtype'];
public created_by: ReportSource['created_by'];
Expand Down Expand Up @@ -68,6 +68,7 @@ export class Job {
this.objectType = report.payload.objectType;
this.title = report.payload.title;
this.layout = report.payload.layout;
this.version = report.payload.version;
this.created_by = report.created_by;
this.created_at = report.created_at;
this.started_at = report.started_at;
Expand Down Expand Up @@ -141,34 +142,32 @@ export class Job {
return null;
}

getStatus() {
const statusLabel = jobStatusLabelsMap.get(this.status) as string;
const statusTimestamp = this.getStatusTimestamp();
public get prettyStatus(): string {
return (
jobStatusLabelsMap.get(this.status) ??
i18n.translate('xpack.reporting.jobStatusDetail.unknownText', { defaultMessage: 'Unknown' })
);
}

if (statusTimestamp) {
return (
<FormattedMessage
id="xpack.reporting.jobStatusDetail.statusTimestampText"
defaultMessage="{statusLabel} at {statusTimestamp}"
values={{
statusLabel,
statusTimestamp: (
<span className="eui-textNoWrap">{this.formatDate(statusTimestamp)}</span>
),
}}
/>
);
}
public get canLinkToKibanaApp(): boolean {
return Boolean(this.locatorParams);
}

return statusLabel;
public get isDownloadReady(): boolean {
return this.status === JOB_STATUSES.COMPLETED || this.status === JOB_STATUSES.WARNINGS;
}

getStatusLabel() {
return (
<>
{this.getStatus()} {this.getStatusMessage()}
</>
);
public get prettyTimeout(): string {
if (this.timeout == null) {
return i18n.translate('xpack.reporting.jobStatusDetail.timeoutSecondsUnknown', {
defaultMessage: 'Unknown',
});
}
const seconds = this.timeout / 1000;
return i18n.translate('xpack.reporting.jobStatusDetail.timeoutSeconds', {
defaultMessage: '{timeout} seconds',
values: { timeout: seconds },
});
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export interface TestDependencies {
urlService: SharePluginSetup['url'];
toasts: NotificationsSetup['toasts'];
ilmLocator: LocatorPublic<SerializableRecord>;
uiSettings: ReturnType<typeof coreMock.createSetup>['uiSettings'];
}

const mockPollConfig = {
Expand Down Expand Up @@ -74,9 +75,10 @@ const createTestBed = registerTestBed(
license$: l$,
urlService,
toasts,
uiSettings,
...rest
}: Partial<Props> & TestDependencies) => (
<KibanaContextProvider services={{ http, application }}>
<KibanaContextProvider services={{ http, application, uiSettings }}>
<InternalApiClientProvider apiClient={reportingAPIClient}>
<IlmPolicyStatusContextProvider>
<ReportListing
Expand Down Expand Up @@ -119,6 +121,7 @@ export const setup = async (props?: Partial<Props>) => {
license$,
reportingAPIClient,
ilmLocator,
uiSettings: uiSettingsClient,
urlService: {
locators: {
get: () => ilmLocator,
Expand All @@ -130,13 +133,29 @@ export const setup = async (props?: Partial<Props>) => {

const { find, exists, component } = testBed;

return {
const api = {
...testBed,
testDependencies,
actions: {
findListTable: () => find('reportJobListing'),
hasIlmMigrationBanner: () => exists('migrateReportingIndicesPolicyCallOut'),
hasIlmPolicyLink: () => exists('ilmPolicyLink'),
flyout: {
open: async (jobId: string) => {
await act(async () => {
find(`viewReportingLink${jobId}`).simulate('click');
});
component.update();
},
openActionsMenu: () => {
act(() => {
find('reportInfoFlyoutActionsButton').simulate('click');
});
component.update();
},
findDownloadButton: () => find('reportInfoFlyoutDownloadButton'),
findOpenInAppButton: () => find('reportInfoFlyoutOpenInKibanaButton'),
},
migrateIndices: async () => {
await act(async () => {
find('migrateReportingIndicesButton').simulate('click');
Expand All @@ -145,4 +164,6 @@ export const setup = async (props?: Partial<Props>) => {
},
},
};

return api;
};
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,17 @@ import {
EuiFlyout,
EuiFlyoutBody,
EuiFlyoutHeader,
EuiFlyoutFooter,
EuiPortal,
EuiText,
EuiFlexGroup,
EuiFlexItem,
EuiButtonEmpty,
EuiButton,
EuiTitle,
EuiLoadingSpinner,
EuiPopover,
EuiContextMenuItem,
EuiContextMenuPanel,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';

Expand All @@ -31,10 +38,13 @@ interface Props {
export const ReportInfoFlyout: FunctionComponent<Props> = ({ onClose, job }) => {
const [isLoading, setIsLoading] = useState<boolean>(true);
const [loadingError, setLoadingError] = useState<undefined | Error>();
const [isActionsPopoverOpen, setIsActionsPopoverOpen] = useState<boolean>(false);
const [info, setInfo] = useState<undefined | Job>();
const isMounted = useMountedState();
const { apiClient } = useInternalApiClient();

const closePopover = () => setIsActionsPopoverOpen(false);

useEffect(() => {
(async function loadInfo() {
if (isLoading) {
Expand All @@ -56,6 +66,48 @@ export const ReportInfoFlyout: FunctionComponent<Props> = ({ onClose, job }) =>
})();
}, [isLoading, apiClient, job.id, isMounted]);

const actionsButton = (
<EuiButton
data-test-subj="reportInfoFlyoutActionsButton"
iconType="arrowUp"
onClick={() => setIsActionsPopoverOpen((isOpen) => !isOpen)}
>
{i18n.translate('xpack.reporting.reportInfoFlyout.actionsButtonLabel', {
defaultMessage: 'Actions',
})}
</EuiButton>
);

const actionItems = [
<EuiContextMenuItem
data-test-subj="reportInfoFlyoutDownloadButton"
key="download"
icon="download"
disabled={!job.isDownloadReady}
onClick={() => {
apiClient.downloadReport(job.id);
}}
>
{i18n.translate('xpack.reporting.reportInfoFlyout.downloadButtonLabel', {
defaultMessage: 'Download',
})}
</EuiContextMenuItem>,
<EuiContextMenuItem
data-test-subj="reportInfoFlyoutOpenInKibanaButton"
disabled={!job.canLinkToKibanaApp}
key="openInKibanaApp"
icon="popout"
onClick={() => {
window.open(apiClient.getKibanaAppHref(job), '_blank');
window.focus();
}}
>
{i18n.translate('xpack.reporting.reportInfoFlyout.openInKibanaAppButtonLabel', {
defaultMessage: 'Open in Kibana',
})}
</EuiContextMenuItem>,
];

return (
<EuiPortal>
<EuiFlyout
Expand All @@ -72,8 +124,9 @@ export const ReportInfoFlyout: FunctionComponent<Props> = ({ onClose, job }) =>
? i18n.translate('xpack.reporting.listing.table.reportInfoUnableToFetch', {
defaultMessage: 'Unable to fetch report info.',
})
: i18n.translate('xpack.reporting.listing.table.reportCalloutTitle', {
defaultMessage: 'Report info',
: info?.title ??
i18n.translate('xpack.reporting.listing.table.untitledReport', {
defaultMessage: 'Untitled report',
})}
</h2>
</EuiTitle>
Expand All @@ -82,11 +135,33 @@ export const ReportInfoFlyout: FunctionComponent<Props> = ({ onClose, job }) =>
{isLoading ? (
<EuiLoadingSpinner />
) : loadingError ? undefined : !!info ? (
<EuiText>
<ReportInfoFlyoutContent info={info} />
</EuiText>
<ReportInfoFlyoutContent info={info} />
) : undefined}
</EuiFlyoutBody>
{!isLoading && (
<EuiFlyoutFooter>
<EuiFlexGroup gutterSize="none" justifyContent="spaceBetween">
<EuiFlexItem grow={false}>
<EuiButtonEmpty iconType="cross" flush="left" onClick={onClose}>
{i18n.translate('xpack.reporting.listing.flyout.closeButtonLabel', {
defaultMessage: 'Close',
})}
</EuiButtonEmpty>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiPopover
id="reportInfoFlyoutActionsPopover"
button={actionsButton}
isOpen={isActionsPopoverOpen}
closePopover={closePopover}
panelPaddingSize="none"
>
<EuiContextMenuPanel items={actionItems} />
</EuiPopover>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlyoutFooter>
)}
</EuiFlyout>
</EuiPortal>
);
Expand Down
Loading

0 comments on commit d213263

Please sign in to comment.