mirror of
https://github.com/elastic/kibana.git
synced 2025-04-26 02:37:44 -04:00
👋 Hi all - the biggest breaking change of this PR is around two icon type changes/renames. 1. ⚠️ **The `alert` icon is now named `warning`** - <img width="103" alt="" src="https://user-images.githubusercontent.com/549407/223561599-8913e88c-676f-47cd-aaed-81b64783bd81.png" align="middle"> - This change should have been automatically converted on your behalf by the EUI team, **but if for some reason** we missed making this conversion in this PR and your icon(s) are now broken, please ping us or let us know in this PR (or fix yourself after this PR merges). - In some cases, teams were using this icon for error messages, alongside the `danger` color. In those cases, we opinionatedly changed those icon usages to the new `error` icon instead of using the old alert/warning icon. 2. 🛑 **The `crossInACircleFilled` icon has been removed, and a new `error` icon added** - <img width="84" alt="" src="https://user-images.githubusercontent.com/549407/223561892-4406bdf6-1a55-49ac-85ad-3a11eb7c090d.png" align="middle"> - The conversion for this breaking change was not straightforward. This was the path we used to determine what to change `crossInACircleFilled` usages to: - If the icon was associated with errors or error messages, we changed it to the new `error` icon. - If a "delete" action was associated with this icon, we changed it to the `trash` icon instead. - If a "clear" action was associated with this icon, we changed it to just the `cross` icon, or in some cases `minusInCircleFilled` (if used alongside `plusInCircleFilled`). - Again, if we made a mistake during this conversion or missed your plugin, please feel free to ping us. ## Summary `eui@75.1.2` ⏩ `eui@76.0.2` ## [`76.0.2`](https://github.com/elastic/eui/tree/v76.0.2) **Bug fixes** - Added a legacy `alert` alias for the `warning` `EuiIcon` type ([#6640](https://github.com/elastic/eui/pull/6640)) ## [`76.0.1`](https://github.com/elastic/eui/tree/v76.0.1) **Bug fixes** - Fixed broken icons on all `isInvalid` form controls ([#6629](https://github.com/elastic/eui/pull/6629)) ## [`76.0.0`](https://github.com/elastic/eui/tree/v76.0.0) - Added `pivot` glyph to `EuiIcon` ([#6605](https://github.com/elastic/eui/pull/6605)) - Added the `displayHeaderCellProps` API to `EuiDataGrid`'s columns, which allows passing custom props directly to column header cells ([#6609](https://github.com/elastic/eui/pull/6609)) - Added the new `headerCellProps`/`footerCellProps` APIs to `EuiDataGrid`'s control columns, which allows passing custom props directly to control column header or footer cells ([#6609](https://github.com/elastic/eui/pull/6609)) - Added a new `footerCellRender` API to `EuiDataGrid`'s control columns, which allows completely customizing control column rendering (previously rendered an empty cell) ([#6609](https://github.com/elastic/eui/pull/6609)) - Updated the styling of nested ordered lists in `EuiText` to align with GitHub's list style, which is a popular format used in Markdown or MDX formatting ([#6615](https://github.com/elastic/eui/pull/6615)) - Added a margin-bottom property exclusively to the direct child `ul` and `ol` elements of the `EuiText` component ([#6615](https://github.com/elastic/eui/pull/6615)) - Fix issue with badges appearing within an `EuiBadgeGroup`, where the CSS rule to override the `margin-inline-start` was not being applied correctly due to the order of appearance in the CSS rules ([#6618](https://github.com/elastic/eui/pull/6618)) **Bug fixes** - Fixed `EuiDataGrid` footer control columns rendering with cell expansion popovers when they should not have been ([#6609](https://github.com/elastic/eui/pull/6609)) - Fixed an `EuiSkipLink` bug where main content loading in progressively/dynamically after the skip link rendered was not being correctly focused ([#6613](https://github.com/elastic/eui/pull/6613)) **Breaking changes** - Renamed `EuiIcon`'s `alert` to `warning` ([#6608](https://github.com/elastic/eui/pull/6608)) - Removed `EuiIcon`'s `crossInACircleFilled` in favor of `error` ([#6608](https://github.com/elastic/eui/pull/6608)) --------- Co-authored-by: Davey Holler <daveyholler@hey.com> Co-authored-by: Constance Chen <constance.chen@elastic.co> Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Jon <jon@elastic.co>
190 lines
5.5 KiB
TypeScript
190 lines
5.5 KiB
TypeScript
/*
|
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
* or more contributor license agreements. Licensed under the Elastic License
|
|
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
|
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
|
* Side Public License, v 1.
|
|
*/
|
|
|
|
import React, { useState } from 'react';
|
|
import { useQuery } from '@tanstack/react-query';
|
|
import type { FileJSON } from '@kbn/files-plugin/common';
|
|
import type { FilesClientResponses } from '@kbn/files-plugin/public';
|
|
|
|
import {
|
|
EuiPageTemplate,
|
|
EuiInMemoryTable,
|
|
EuiInMemoryTableProps,
|
|
EuiButton,
|
|
EuiIcon,
|
|
EuiButtonIcon,
|
|
EuiLink,
|
|
} from '@elastic/eui';
|
|
|
|
import { CoreStart } from '@kbn/core/public';
|
|
import { MyFilePicker } from './file_picker';
|
|
import type { MyImageMetadata } from '../../common';
|
|
import type { FileClients } from '../types';
|
|
import { DetailsFlyout } from './details_flyout';
|
|
import { ConfirmButtonIcon } from './confirm_button';
|
|
import { Modal } from './modal';
|
|
|
|
interface FilesExampleAppDeps {
|
|
files: FileClients;
|
|
notifications: CoreStart['notifications'];
|
|
}
|
|
|
|
type ListResponse = FilesClientResponses<MyImageMetadata>['list'];
|
|
|
|
export const FilesExampleApp = ({ files, notifications }: FilesExampleAppDeps) => {
|
|
const { data, isLoading, error, refetch } = useQuery<ListResponse>(
|
|
['files'],
|
|
() => files.example.list(),
|
|
{ refetchOnWindowFocus: false }
|
|
);
|
|
const [showUploadModal, setShowUploadModal] = useState(false);
|
|
const [showFilePickerModal, setShowFilePickerModal] = useState(false);
|
|
const [isDeletingFile, setIsDeletingFile] = useState(false);
|
|
const [selectedItem, setSelectedItem] = useState<undefined | FileJSON<MyImageMetadata>>();
|
|
|
|
const renderToolsRight = () => {
|
|
return [
|
|
<EuiButton
|
|
onClick={() => setShowFilePickerModal(true)}
|
|
isDisabled={isLoading || isDeletingFile}
|
|
iconType="eye"
|
|
>
|
|
Select a file
|
|
</EuiButton>,
|
|
<EuiButton
|
|
onClick={() => setShowUploadModal(true)}
|
|
isDisabled={isLoading || isDeletingFile}
|
|
iconType="exportAction"
|
|
>
|
|
Upload image
|
|
</EuiButton>,
|
|
];
|
|
};
|
|
|
|
const items = [...(data?.files ?? [])].reverse();
|
|
|
|
const columns: EuiInMemoryTableProps<FileJSON<MyImageMetadata>>['columns'] = [
|
|
{
|
|
field: 'name',
|
|
name: 'Name',
|
|
render: (name, item) => (
|
|
<EuiLink disabled={isDeletingFile} onClick={() => setSelectedItem(item)}>
|
|
{name}
|
|
</EuiLink>
|
|
),
|
|
},
|
|
{
|
|
field: 'status',
|
|
name: 'Status',
|
|
render: (status: FileJSON['status']) =>
|
|
status === 'READY' ? (
|
|
<EuiIcon color="success" type="checkInCircleFilled" aria-label={status} />
|
|
) : status === 'AWAITING_UPLOAD' ? (
|
|
<EuiIcon type="clock" aria-label={status} />
|
|
) : (
|
|
<EuiIcon color="danger" type="warning" arial-label={status} />
|
|
),
|
|
},
|
|
{
|
|
name: 'Actions',
|
|
actions: [
|
|
{
|
|
name: 'View',
|
|
description: 'View file',
|
|
isPrimary: true,
|
|
render: (item) => (
|
|
<EuiButtonIcon
|
|
disabled={isDeletingFile}
|
|
aria-label="View file details"
|
|
iconType="eye"
|
|
onClick={() => setSelectedItem(item)}
|
|
/>
|
|
),
|
|
},
|
|
{
|
|
name: 'Delete',
|
|
description: 'Delete this file',
|
|
render: (item) => (
|
|
<ConfirmButtonIcon
|
|
disabled={isDeletingFile}
|
|
label="Delete this file"
|
|
confirmationText="Are you sure you want to delete this file?"
|
|
onConfirm={async () => {
|
|
try {
|
|
setIsDeletingFile(true);
|
|
await files.example.delete({ id: item.id });
|
|
await refetch();
|
|
} finally {
|
|
setIsDeletingFile(false);
|
|
}
|
|
}}
|
|
/>
|
|
),
|
|
},
|
|
],
|
|
},
|
|
];
|
|
|
|
return (
|
|
<>
|
|
<EuiPageTemplate restrictWidth>
|
|
<EuiPageTemplate.Header pageTitle="Files example" />
|
|
<EuiPageTemplate.Section>
|
|
<EuiInMemoryTable
|
|
columns={columns}
|
|
items={items}
|
|
itemId="id"
|
|
loading={isLoading || isDeletingFile}
|
|
error={error ? JSON.stringify(error) : undefined}
|
|
sorting
|
|
search={{
|
|
toolsRight: renderToolsRight(),
|
|
}}
|
|
pagination
|
|
/>
|
|
</EuiPageTemplate.Section>
|
|
</EuiPageTemplate>
|
|
{selectedItem && (
|
|
<DetailsFlyout
|
|
files={files}
|
|
file={selectedItem}
|
|
onDismiss={() => setSelectedItem(undefined)}
|
|
/>
|
|
)}
|
|
{showUploadModal && (
|
|
<Modal
|
|
client={files.unscoped}
|
|
onDismiss={() => setShowUploadModal(false)}
|
|
onUploaded={() => {
|
|
notifications.toasts.addSuccess('Uploaded file!');
|
|
refetch();
|
|
setShowUploadModal(false);
|
|
}}
|
|
/>
|
|
)}
|
|
{showFilePickerModal && (
|
|
<MyFilePicker
|
|
onClose={() => setShowFilePickerModal(false)}
|
|
onUpload={() => {
|
|
notifications.toasts.addSuccess({
|
|
title: 'Uploaded files',
|
|
});
|
|
refetch();
|
|
}}
|
|
onDone={(ids) => {
|
|
notifications.toasts.addSuccess({
|
|
title: 'Selected files!',
|
|
text: 'IDS:' + JSON.stringify(ids, null, 2),
|
|
});
|
|
setShowFilePickerModal(false);
|
|
}}
|
|
/>
|
|
)}
|
|
</>
|
|
);
|
|
};
|