Introduce pause button

Summary: ..and some earlier reviews comments has been processed + some fine tuning on the ui

Reviewed By: priteshrnandgaonkar

Differential Revision: D26816559

fbshipit-source-id: adf2586763be185ee8e7cc22b2827ecefe4e4cab
This commit is contained in:
Michel Weststrate
2021-03-16 14:54:53 -07:00
committed by Facebook GitHub Bot
parent 525e079284
commit 55981b5259
8 changed files with 81 additions and 47 deletions

View File

@@ -190,7 +190,8 @@ export default class BaseDevice {
if (plugin instanceof _SandyPluginDefinition) { if (plugin instanceof _SandyPluginDefinition) {
return ( return (
plugin.isDevicePlugin && plugin.isDevicePlugin &&
plugin.asDevicePluginModule().supportsDevice(this as any) (plugin.asDevicePluginModule().supportsDevice?.(this as any) ??
false)
); );
} else { } else {
return plugin.supportsDevice(this); return plugin.supportsDevice(this);

View File

@@ -490,6 +490,9 @@ const PluginMenu = styled(Menu)({
overflow: 'hidden', overflow: 'hidden',
textOverflow: 'ellipsis', textOverflow: 'ellipsis',
}, },
'.ant-menu-sub.ant-menu-inline': {
background: theme.backgroundDefault,
},
'.ant-menu-inline .ant-menu-item, .ant-menu-inline .ant-menu-submenu-title ': { '.ant-menu-inline .ant-menu-item, .ant-menu-inline .ant-menu-submenu-title ': {
width: '100%', // reset to remove weird bonus pixel from ANT width: '100%', // reset to remove weird bonus pixel from ANT
}, },
@@ -518,8 +521,9 @@ const PluginMenu = styled(Menu)({
right: 8, right: 8,
}, },
'.ant-badge-count': { '.ant-badge-count': {
color: theme.textColorPrimary, color: theme.textColorSecondary,
background: theme.backgroundTransparentHover, // border: `1px solid ${theme.dividerColor}`,
background: 'transparent',
fontWeight: 'bold', fontWeight: 'bold',
padding: `0 10px`, padding: `0 10px`,
boxShadow: 'none', boxShadow: 'none',

View File

@@ -16,7 +16,7 @@ import {DevicePluginPredicate, DevicePluginFactory} from './DevicePlugin';
*/ */
export type FlipperDevicePluginModule = { export type FlipperDevicePluginModule = {
/** predicate that determines if this plugin applies to the currently selcted device */ /** predicate that determines if this plugin applies to the currently selcted device */
supportsDevice: DevicePluginPredicate; // TODO T84453692: remove this function after some transition period in favor of BaseDevice.supportsPlugin. supportsDevice?: DevicePluginPredicate; // TODO T84453692: remove this function after some transition period in favor of BaseDevice.supportsPlugin.
/** the factory function that initializes a plugin instance */ /** the factory function that initializes a plugin instance */
devicePlugin: DevicePluginFactory; devicePlugin: DevicePluginFactory;
/** the component type that can render this plugin */ /** the component type that can render this plugin */

View File

@@ -145,8 +145,8 @@ export class DataSource<
/** /**
* Returns a defensive copy of the current output. * Returns a defensive copy of the current output.
* Sort, filter, reverse and window are applied, but windowing isn't. * Sort, filter, reverse and are applied.
* Start and end behave like slice, and default to the current window * Start and end behave like slice, and default to the currently active window.
*/ */
public getOutput( public getOutput(
start = this.windowStart, start = this.windowStart,
@@ -308,8 +308,7 @@ export class DataSource<
setReversed(reverse: boolean) { setReversed(reverse: boolean) {
if (this.reverse !== reverse) { if (this.reverse !== reverse) {
this.reverse = reverse; this.reverse = reverse;
// TODO: not needed anymore this.notifyReset(this.output.length);
this.rebuildOutput();
} }
} }
@@ -380,11 +379,11 @@ export class DataSource<
}); });
} }
notifyItemShift(viewIndex: number, delta: number) { notifyItemShift(index: number, delta: number) {
if (!this.outputChangeListener) { if (!this.outputChangeListener) {
return; return;
} }
viewIndex = this.normalizeIndex(viewIndex); let viewIndex = this.normalizeIndex(index);
if (this.reverse && delta < 0) { if (this.reverse && delta < 0) {
viewIndex -= delta; // we need to correct for normalize already using the new length after applying this change viewIndex -= delta; // we need to correct for normalize already using the new length after applying this change
} }
@@ -502,10 +501,7 @@ export class DataSource<
entry.visible = true; entry.visible = true;
}); });
this.output = output; this.output = output;
this.outputChangeListener?.({ this.notifyReset(output.length);
type: 'reset',
newCount: output.length,
});
} }
private sortHelper = (a: Entry<T>) => private sortHelper = (a: Entry<T>) =>

View File

@@ -8,12 +8,13 @@
*/ */
import {useMemo, useState} from 'react'; import {useMemo, useState} from 'react';
import styled from '@emotion/styled';
import React from 'react'; import React from 'react';
import {theme} from '../theme';
import type {DataTableColumn} from './DataTable';
import {Button, Checkbox, Dropdown, Menu, Typography, Input} from 'antd'; import {Button, Checkbox, Dropdown, Menu, Typography, Input} from 'antd';
import {FilterFilled, MinusCircleOutlined} from '@ant-design/icons'; import {FilterFilled, MinusCircleOutlined} from '@ant-design/icons';
import {theme} from '../theme';
import type {DataTableColumn} from './DataTable';
import {Layout} from '../Layout'; import {Layout} from '../Layout';
const {Text} = Typography; const {Text} = Typography;
@@ -127,18 +128,25 @@ export function FilterIcon({
); );
return ( return (
<Dropdown overlay={menu} trigger={['click']}> <div>
<Button <Dropdown overlay={menu} trigger={['click']}>
size="small" <FilterButton isActive={isActive}>
type="text" <FilterFilled />
style={{ </FilterButton>
backgroundColor: theme.backgroundWash, </Dropdown>
borderRadius: 0, </div>
visibility: isActive ? 'visible' : 'hidden',
color: isActive ? theme.primaryColor : theme.disabledColor,
}}>
<FilterFilled />
</Button>
</Dropdown>
); );
} }
export const FilterButton = styled.div<{isActive?: boolean}>(({isActive}) => ({
backgroundColor: theme.backgroundWash,
visibility: isActive ? 'visible' : 'hidden',
color: isActive ? theme.primaryColor : theme.disabledColor,
cursor: 'pointer',
marginRight: 4,
zIndex: 1,
'&:hover': {
color: theme.primaryColor,
backgroundColor: theme.backgroundWash,
},
}));

View File

@@ -24,7 +24,7 @@ import {Typography} from 'antd';
import {CaretDownFilled, CaretUpFilled} from '@ant-design/icons'; import {CaretDownFilled, CaretUpFilled} from '@ant-design/icons';
import {Layout} from '../Layout'; import {Layout} from '../Layout';
import {Sorting, OnColumnResize, SortDirection} from './useDataTableManager'; import {Sorting, OnColumnResize, SortDirection} from './useDataTableManager';
import {ColumnFilterHandlers, FilterIcon} from './ColumnFilter'; import {ColumnFilterHandlers, FilterButton, FilterIcon} from './ColumnFilter';
const {Text} = Typography; const {Text} = Typography;
@@ -98,8 +98,8 @@ const TableHeadColumnContainer = styled.div<{
[`:hover ${SortIconsContainer}`]: { [`:hover ${SortIconsContainer}`]: {
visibility: 'visible', visibility: 'visible',
}, },
[`&:hover button`]: { [`&:hover ${FilterButton}`]: {
visibility: 'visible !important' as any, visibility: 'visible',
}, },
})); }));
TableHeadColumnContainer.displayName = 'TableHead:TableHeadColumnContainer'; TableHeadColumnContainer.displayName = 'TableHead:TableHeadColumnContainer';
@@ -166,10 +166,13 @@ function TableHeadColumn({
<div <div
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
onSort( const newDirection =
column.key, sorted === undefined
sorted === 'asc' ? 'desc' : sorted === 'desc' ? undefined : 'asc', ? 'asc'
); : sorted === 'asc'
? 'desc'
: undefined;
onSort(column.key, newDirection);
}} }}
role="button" role="button"
tabIndex={0}> tabIndex={0}>

View File

@@ -9,9 +9,13 @@
import {MenuOutlined} from '@ant-design/icons'; import {MenuOutlined} from '@ant-design/icons';
import {Button, Dropdown, Input} from 'antd'; import {Button, Dropdown, Input} from 'antd';
import React, {memo} from 'react'; import React, {memo, useState} from 'react';
import styled from '@emotion/styled';
import {Layout} from '../Layout'; import {Layout} from '../Layout';
import {theme} from '../theme'; import {theme} from '../theme';
import {debounce} from 'lodash';
import {useAssertStableRef} from '../../utils/useAssertStableRef';
export const TableSearch = memo(function TableSearch({ export const TableSearch = memo(function TableSearch({
onSearch, onSearch,
@@ -23,14 +27,23 @@ export const TableSearch = memo(function TableSearch({
hasSelection?: boolean; hasSelection?: boolean;
contextMenu?: React.ReactElement; contextMenu?: React.ReactElement;
}) { }) {
useAssertStableRef(onSearch, 'onSearch');
const [search, setSearch] = useState('');
const [performSearch] = useState(() =>
debounce(onSearch, 200, {leading: true}),
);
return ( return (
<Layout.Horizontal <Searchbar gap>
gap <Input.Search
style={{ allowClear
backgroundColor: theme.backgroundWash, placeholder="Search..."
padding: theme.space.small, onSearch={performSearch}
}}> value={search}
<Input.Search allowClear placeholder="Search..." onSearch={onSearch} /> onChange={(e) => {
setSearch(e.target.value);
performSearch(e.target.value);
}}
/>
{extraActions} {extraActions}
{contextMenu && ( {contextMenu && (
<Dropdown overlay={contextMenu} placement="bottomRight"> <Dropdown overlay={contextMenu} placement="bottomRight">
@@ -39,6 +52,15 @@ export const TableSearch = memo(function TableSearch({
</Button> </Button>
</Dropdown> </Dropdown>
)} )}
</Layout.Horizontal> </Searchbar>
); );
}); });
const Searchbar = styled(Layout.Horizontal)({
backgroundColor: theme.backgroundWash,
padding: theme.space.small,
'.ant-btn': {
padding: `${theme.space.tiny}px ${theme.space.small}px`,
background: 'transparent',
},
});

View File

@@ -10,7 +10,7 @@
import {useRef} from 'react'; import {useRef} from 'react';
/** /**
* This hook will throw in development builds if the value passed in is stable. * This hook will throw in development builds if the value passed in is unstable.
* Use this if to make sure consumers aren't creating or changing certain props over time * Use this if to make sure consumers aren't creating or changing certain props over time
* (intentionally or accidentally) * (intentionally or accidentally)
*/ */