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:
committed by
Facebook GitHub Bot
parent
525e079284
commit
55981b5259
@@ -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);
|
||||||
|
|||||||
@@ -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',
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
@@ -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>) =>
|
||||||
|
|||||||
@@ -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 (
|
||||||
|
<div>
|
||||||
<Dropdown overlay={menu} trigger={['click']}>
|
<Dropdown overlay={menu} trigger={['click']}>
|
||||||
<Button
|
<FilterButton isActive={isActive}>
|
||||||
size="small"
|
|
||||||
type="text"
|
|
||||||
style={{
|
|
||||||
backgroundColor: theme.backgroundWash,
|
|
||||||
borderRadius: 0,
|
|
||||||
visibility: isActive ? 'visible' : 'hidden',
|
|
||||||
color: isActive ? theme.primaryColor : theme.disabledColor,
|
|
||||||
}}>
|
|
||||||
<FilterFilled />
|
<FilterFilled />
|
||||||
</Button>
|
</FilterButton>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|||||||
@@ -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}>
|
||||||
|
|||||||
@@ -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',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|||||||
@@ -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)
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user