mirror of
https://github.com/balena-io/etcher.git
synced 2025-07-23 11:16:39 +00:00
Use drive-selector's table for flash errors table
Change-type: patch Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzothunder.ambrosi@gmail.com>
This commit is contained in:
parent
e74dc9eb60
commit
31409c61ca
@ -18,15 +18,7 @@ import ExclamationTriangleSvg from '@fortawesome/fontawesome-free/svgs/solid/exc
|
|||||||
import ChevronDownSvg from '@fortawesome/fontawesome-free/svgs/solid/chevron-down.svg';
|
import ChevronDownSvg from '@fortawesome/fontawesome-free/svgs/solid/chevron-down.svg';
|
||||||
import * as sourceDestination from 'etcher-sdk/build/source-destination/';
|
import * as sourceDestination from 'etcher-sdk/build/source-destination/';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {
|
import { Flex, ModalProps, Txt, Badge, Link, TableColumn } from 'rendition';
|
||||||
Flex,
|
|
||||||
ModalProps,
|
|
||||||
Txt,
|
|
||||||
Badge,
|
|
||||||
Link,
|
|
||||||
Table,
|
|
||||||
TableColumn,
|
|
||||||
} from 'rendition';
|
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -43,7 +35,12 @@ import { getImage, isDriveSelected } from '../../models/selection-state';
|
|||||||
import { store } from '../../models/store';
|
import { store } from '../../models/store';
|
||||||
import { logEvent, logException } from '../../modules/analytics';
|
import { logEvent, logException } from '../../modules/analytics';
|
||||||
import { open as openExternal } from '../../os/open-external/services/open-external';
|
import { open as openExternal } from '../../os/open-external/services/open-external';
|
||||||
import { Alert, Modal, ScrollableFlex } from '../../styled-components';
|
import {
|
||||||
|
Alert,
|
||||||
|
GenericTableProps,
|
||||||
|
Modal,
|
||||||
|
Table,
|
||||||
|
} from '../../styled-components';
|
||||||
|
|
||||||
import DriveSVGIcon from '../../../assets/tgt.svg';
|
import DriveSVGIcon from '../../../assets/tgt.svg';
|
||||||
import { SourceMetadata } from '../source-selector/source-selector';
|
import { SourceMetadata } from '../source-selector/source-selector';
|
||||||
@ -75,27 +72,12 @@ function isDrivelistDrive(drive: Drive): drive is DrivelistDrive {
|
|||||||
return typeof (drive as DrivelistDrive).size === 'number';
|
return typeof (drive as DrivelistDrive).size === 'number';
|
||||||
}
|
}
|
||||||
|
|
||||||
const DrivesTable = styled(({ refFn, ...props }) => (
|
const DrivesTable = styled((props: GenericTableProps<Drive>) => (
|
||||||
<div>
|
<Table<Drive> {...props} />
|
||||||
<Table<Drive> ref={refFn} {...props} />
|
|
||||||
</div>
|
|
||||||
))`
|
))`
|
||||||
[data-display='table-head']
|
[data-display='table-head'],
|
||||||
> [data-display='table-row']
|
[data-display='table-body'] {
|
||||||
> [data-display='table-cell'] {
|
> [data-display='table-row'] > [data-display='table-cell'] {
|
||||||
position: sticky;
|
|
||||||
top: 0;
|
|
||||||
background-color: ${(props) => props.theme.colors.quartenary.light};
|
|
||||||
|
|
||||||
input[type='checkbox'] + div {
|
|
||||||
display: ${({ multipleSelection }) =>
|
|
||||||
multipleSelection ? 'flex' : 'none'};
|
|
||||||
}
|
|
||||||
|
|
||||||
&:first-child {
|
|
||||||
padding-left: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(2) {
|
&:nth-child(2) {
|
||||||
width: 38%;
|
width: 38%;
|
||||||
}
|
}
|
||||||
@ -112,36 +94,6 @@ const DrivesTable = styled(({ refFn, ...props }) => (
|
|||||||
width: 32%;
|
width: 32%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-display='table-body'] > [data-display='table-row'] {
|
|
||||||
> [data-display='table-cell']:first-child {
|
|
||||||
padding-left: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
> [data-display='table-cell']:last-child {
|
|
||||||
padding-right: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&[data-highlight='true'] {
|
|
||||||
&.system {
|
|
||||||
background-color: ${(props) =>
|
|
||||||
props.showWarnings ? '#fff5e6' : '#e8f5fc'};
|
|
||||||
}
|
|
||||||
|
|
||||||
> [data-display='table-cell']:first-child {
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&& [data-display='table-row'] > [data-display='table-cell'] {
|
|
||||||
padding: 6px 8px;
|
|
||||||
color: #2a506f;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type='checkbox'] + div {
|
|
||||||
border-radius: ${({ multipleSelection }) =>
|
|
||||||
multipleSelection ? '4px' : '50%'};
|
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@ -453,7 +405,6 @@ export class DriveSelector extends React.Component<
|
|||||||
}}
|
}}
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
<Flex width="100%" height="90%">
|
|
||||||
{!hasAvailableDrives() ? (
|
{!hasAvailableDrives() ? (
|
||||||
<Flex
|
<Flex
|
||||||
flexDirection="column"
|
flexDirection="column"
|
||||||
@ -465,9 +416,9 @@ export class DriveSelector extends React.Component<
|
|||||||
<b>{this.props.emptyListLabel}</b>
|
<b>{this.props.emptyListLabel}</b>
|
||||||
</Flex>
|
</Flex>
|
||||||
) : (
|
) : (
|
||||||
<ScrollableFlex flexDirection="column" width="100%">
|
<>
|
||||||
<DrivesTable
|
<DrivesTable
|
||||||
refFn={(t: Table<Drive>) => {
|
refFn={(t) => {
|
||||||
if (t !== null) {
|
if (t !== null) {
|
||||||
t.setRowSelection(selectedList);
|
t.setRowSelection(selectedList);
|
||||||
}
|
}
|
||||||
@ -533,15 +484,13 @@ export class DriveSelector extends React.Component<
|
|||||||
</Flex>
|
</Flex>
|
||||||
</Link>
|
</Link>
|
||||||
)}
|
)}
|
||||||
</ScrollableFlex>
|
</>
|
||||||
)}
|
)}
|
||||||
{this.props.showWarnings && hasSystemDrives ? (
|
{this.props.showWarnings && hasSystemDrives ? (
|
||||||
<Alert className="system-drive-alert" style={{ width: '67%' }}>
|
<Alert className="system-drive-alert" style={{ width: '67%' }}>
|
||||||
Selecting your system drive is dangerous and will erase your
|
Selecting your system drive is dangerous and will erase your drive!
|
||||||
drive!
|
|
||||||
</Alert>
|
</Alert>
|
||||||
) : null}
|
) : null}
|
||||||
</Flex>
|
|
||||||
|
|
||||||
{missingDriversModal.drive !== undefined && (
|
{missingDriversModal.drive !== undefined && (
|
||||||
<Modal
|
<Modal
|
||||||
|
@ -20,7 +20,7 @@ import TimesCircleSvg from '@fortawesome/fontawesome-free/svgs/solid/times-circl
|
|||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import outdent from 'outdent';
|
import outdent from 'outdent';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { Flex, FlexProps, Link, Table, TableColumn, Txt } from 'rendition';
|
import { Flex, FlexProps, Link, TableColumn, Txt } from 'rendition';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
|
||||||
import { progress } from '../../../../shared/messages';
|
import { progress } from '../../../../shared/messages';
|
||||||
@ -31,7 +31,7 @@ import { getDrives } from '../../models/available-drives';
|
|||||||
import { resetState } from '../../models/flash-state';
|
import { resetState } from '../../models/flash-state';
|
||||||
import * as selection from '../../models/selection-state';
|
import * as selection from '../../models/selection-state';
|
||||||
import { middleEllipsis } from '../../utils/middle-ellipsis';
|
import { middleEllipsis } from '../../utils/middle-ellipsis';
|
||||||
import { Modal } from '../../styled-components';
|
import { Modal, Table } from '../../styled-components';
|
||||||
|
|
||||||
const ErrorsTable = styled((props) => <Table<FlashError> {...props} />)`
|
const ErrorsTable = styled((props) => <Table<FlashError> {...props} />)`
|
||||||
&&& [data-display='table-head'],
|
&&& [data-display='table-head'],
|
||||||
@ -99,7 +99,7 @@ const columns: Array<TableColumn<FlashError>> = [
|
|||||||
field: 'message',
|
field: 'message',
|
||||||
label: 'Error',
|
label: 'Error',
|
||||||
render: (message: string, { code }: FlashError) => {
|
render: (message: string, { code }: FlashError) => {
|
||||||
return message ? message : code;
|
return message ?? code;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@ -152,7 +152,7 @@ export function FlashResults({
|
|||||||
allFailed={allFailed}
|
allFailed={allFailed}
|
||||||
color={allFailed || someFailed ? '#c6c8c9' : '#1ac135'}
|
color={allFailed || someFailed ? '#c6c8c9' : '#1ac135'}
|
||||||
/>
|
/>
|
||||||
<Txt>{middleEllipsis(image, 16)}</Txt>
|
<Txt>{middleEllipsis(image, 24)}</Txt>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Txt fontSize={24} color="#fff" mb="17px">
|
<Txt fontSize={24} color="#fff" mb="17px">
|
||||||
Flash Complete!
|
Flash Complete!
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import * as _ from 'lodash';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {
|
import {
|
||||||
Alert as AlertBase,
|
Alert as AlertBase,
|
||||||
@ -23,27 +24,16 @@ import {
|
|||||||
ButtonProps,
|
ButtonProps,
|
||||||
Modal as ModalBase,
|
Modal as ModalBase,
|
||||||
Provider,
|
Provider,
|
||||||
|
Table as BaseTable,
|
||||||
|
TableProps as BaseTableProps,
|
||||||
Txt,
|
Txt,
|
||||||
Theme as renditionTheme,
|
|
||||||
} from 'rendition';
|
} from 'rendition';
|
||||||
import styled, { css } from 'styled-components';
|
import styled, { css } from 'styled-components';
|
||||||
|
|
||||||
import { colors, theme } from './theme';
|
import { colors, theme } from './theme';
|
||||||
|
|
||||||
const defaultTheme = {
|
|
||||||
...renditionTheme,
|
|
||||||
...theme,
|
|
||||||
layer: {
|
|
||||||
extend: () => `
|
|
||||||
> div:first-child {
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export const ThemedProvider = (props: any) => (
|
export const ThemedProvider = (props: any) => (
|
||||||
<Provider theme={defaultTheme} {...props}></Provider>
|
<Provider theme={theme} {...props}></Provider>
|
||||||
);
|
);
|
||||||
|
|
||||||
export const BaseButton = styled(Button)`
|
export const BaseButton = styled(Button)`
|
||||||
@ -134,25 +124,8 @@ const modalFooterShadowCss = css`
|
|||||||
background-attachment: local, local, scroll, scroll;
|
background-attachment: local, local, scroll, scroll;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const Modal = styled(({ style, ...props }) => {
|
export const Modal = styled(({ style, children, ...props }) => {
|
||||||
return (
|
return (
|
||||||
<Provider
|
|
||||||
theme={{
|
|
||||||
...defaultTheme,
|
|
||||||
header: {
|
|
||||||
height: '50px',
|
|
||||||
},
|
|
||||||
layer: {
|
|
||||||
extend: () => `
|
|
||||||
${defaultTheme.layer.extend()}
|
|
||||||
|
|
||||||
> div:last-child {
|
|
||||||
top: 0;
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<ModalBase
|
<ModalBase
|
||||||
position="top"
|
position="top"
|
||||||
width="97vw"
|
width="97vw"
|
||||||
@ -167,8 +140,11 @@ export const Modal = styled(({ style, ...props }) => {
|
|||||||
...style,
|
...style,
|
||||||
}}
|
}}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
>
|
||||||
</Provider>
|
<ScrollableFlex flexDirection="column" width="100%" height="90%">
|
||||||
|
{...children}
|
||||||
|
</ScrollableFlex>
|
||||||
|
</ModalBase>
|
||||||
);
|
);
|
||||||
})`
|
})`
|
||||||
> div {
|
> div {
|
||||||
@ -188,12 +164,9 @@ export const Modal = styled(({ style, ...props }) => {
|
|||||||
|
|
||||||
> div:nth-child(2) {
|
> div:nth-child(2) {
|
||||||
height: 61%;
|
height: 61%;
|
||||||
|
|
||||||
> div:not(.system-drive-alert) {
|
|
||||||
padding: 0 30px;
|
padding: 0 30px;
|
||||||
${modalFooterShadowCss}
|
${modalFooterShadowCss}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
> div:last-child {
|
> div:last-child {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@ -249,3 +222,82 @@ export const Alert = styled((props) => (
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export interface GenericTableProps<T> extends BaseTableProps<T> {
|
||||||
|
refFn: (t: BaseTable<T>) => void;
|
||||||
|
multipleSelection: boolean;
|
||||||
|
showWarnings?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const GenericTable: <T>(
|
||||||
|
props: GenericTableProps<T>,
|
||||||
|
) => React.ReactElement<GenericTableProps<T>> = <T extends {}>({
|
||||||
|
refFn,
|
||||||
|
...props
|
||||||
|
}: GenericTableProps<T>) => (
|
||||||
|
<div>
|
||||||
|
<BaseTable<T> ref={refFn} {...props} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
function StyledTable<T>() {
|
||||||
|
return styled((props: GenericTableProps<T>) => (
|
||||||
|
<GenericTable<T> {...props} />
|
||||||
|
))`
|
||||||
|
[data-display='table-head']
|
||||||
|
> [data-display='table-row']
|
||||||
|
> [data-display='table-cell'] {
|
||||||
|
position: sticky;
|
||||||
|
background-color: #f8f9fd;
|
||||||
|
top: 0;
|
||||||
|
z-index: 1;
|
||||||
|
|
||||||
|
input[type='checkbox'] + div {
|
||||||
|
display: ${(props) => (props.multipleSelection ? 'flex' : 'none')};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-display='table-head'] > [data-display='table-row'],
|
||||||
|
[data-display='table-body'] > [data-display='table-row'] {
|
||||||
|
> [data-display='table-cell']:first-child {
|
||||||
|
padding-left: 15px;
|
||||||
|
width: 6%;
|
||||||
|
}
|
||||||
|
|
||||||
|
> [data-display='table-cell']:last-child {
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-display='table-body'] > [data-display='table-row'] {
|
||||||
|
&:nth-of-type(2n) {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
&[data-highlight='true'] {
|
||||||
|
&.system {
|
||||||
|
background-color: ${(props) =>
|
||||||
|
props.showWarnings ? '#fff5e6' : '#e8f5fc'};
|
||||||
|
}
|
||||||
|
|
||||||
|
> [data-display='table-cell']:first-child {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&& [data-display='table-row'] > [data-display='table-cell'] {
|
||||||
|
padding: 6px 8px;
|
||||||
|
color: #2a506f;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type='checkbox'] + div {
|
||||||
|
border-radius: ${(props) => (props.multipleSelection ? '4px' : '50%')};
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Table = <T extends {}>(props: GenericTableProps<T>) => {
|
||||||
|
const TypedStyledFunctional = StyledTable<T>();
|
||||||
|
return <TypedStyledFunctional {...props} />;
|
||||||
|
};
|
||||||
|
@ -115,4 +115,11 @@ export const theme = _.merge({}, Theme, {
|
|||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
|
layer: {
|
||||||
|
extend: () => `
|
||||||
|
> div:first-child {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user