Files
flipper/desktop/plugins/logs/LogWatcher.tsx
Anton Nikolaev 10d990c32c Move plugins to "sonar/desktop/plugins"
Summary:
Plugins moved from "sonar/desktop/src/plugins" to "sonar/desktop/plugins".

Fixed all the paths after moving.

New "desktop" folder structure:
- `src` - Flipper desktop app JS code executing in Electron Renderer (Chrome) process.
- `static` - Flipper desktop app JS code executing in Electron Main (Node.js) process.
- `plugins` - Flipper desktop JS plugins.
- `pkg` - Flipper packaging lib and CLI tool.
- `doctor` - Flipper diagnostics lib and CLI tool.
- `scripts` - Build scripts for Flipper desktop app.
- `headless` - Headless version of Flipper desktop app.
- `headless-tests` - Integration tests running agains Flipper headless version.

Reviewed By: mweststrate

Differential Revision: D20344186

fbshipit-source-id: d020da970b2ea1e001f9061a8782bfeb54e31ba0
2020-03-14 14:35:18 -07:00

229 lines
4.8 KiB
TypeScript

/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
import {TableBodyRow} from 'flipper';
import {
PureComponent,
FlexColumn,
Panel,
Input,
Toolbar,
Text,
ManagedTable,
Button,
colors,
styled,
} from 'flipper';
import React from 'react';
export type Counter = {
readonly expression: RegExp;
readonly count: number;
readonly notify: boolean;
readonly label: string;
};
type Props = {
readonly onChange: (counters: ReadonlyArray<Counter>) => void;
readonly counters: ReadonlyArray<Counter>;
};
type State = {
readonly input: string;
readonly highlightedRow: string | null;
};
const ColumnSizes = {
expression: '70%',
count: '15%',
notify: 'flex',
};
const Columns = {
expression: {
value: 'Expression',
resizable: false,
},
count: {
value: 'Count',
resizable: false,
},
notify: {
value: 'Notify',
resizable: false,
},
};
const Count = styled(Text)({
alignSelf: 'center',
background: colors.macOSHighlightActive,
color: colors.white,
fontSize: 12,
fontWeight: 500,
textAlign: 'center',
borderRadius: '999em',
padding: '4px 9px 3px',
lineHeight: '100%',
marginLeft: 'auto',
});
const Checkbox = styled(Input)({
lineHeight: '100%',
padding: 0,
margin: 0,
height: 'auto',
alignSelf: 'center',
});
const ExpressionInput = styled(Input)({
flexGrow: 1,
});
const WatcherPanel = styled(Panel)({
minHeight: 200,
});
export default class LogWatcher extends PureComponent<Props, State> {
state = {
input: '',
highlightedRow: null,
};
_inputRef: HTMLInputElement | undefined;
onAdd = () => {
if (
this.props.counters.findIndex(({label}) => label === this.state.input) >
-1 ||
this.state.input.length === 0
) {
// prevent duplicates
return;
}
this.props.onChange([
...this.props.counters,
{
label: this.state.input,
expression: new RegExp(this.state.input, 'gi'),
notify: false,
count: 0,
},
]);
this.setState({input: ''});
};
onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
this.setState({
input: e.target.value,
});
};
resetCount = (index: number) => {
const newCounters = [...this.props.counters];
newCounters[index] = {
...newCounters[index],
count: 0,
};
this.props.onChange(newCounters);
};
buildRows = (): Array<TableBodyRow> => {
return this.props.counters.map(({label, count, notify}, i) => ({
columns: {
expression: {
value: <Text code={true}>{label}</Text>,
},
count: {
value: <Count onClick={() => this.resetCount(i)}>{count}</Count>,
},
notify: {
value: (
<Checkbox
type="checkbox"
checked={notify}
onChange={() => this.setNotification(i, !notify)}
/>
),
},
},
key: label,
}));
};
setNotification = (index: number, notify: boolean) => {
const newCounters: Array<Counter> = [...this.props.counters];
newCounters[index] = {
...newCounters[index],
notify,
};
this.props.onChange(newCounters);
};
onRowHighlighted = (rows: Array<string>) => {
this.setState({
highlightedRow: rows.length === 1 ? rows[0] : null,
});
};
onKeyDown = (e: React.KeyboardEvent) => {
if (
(e.key === 'Delete' || e.key === 'Backspace') &&
this.state.highlightedRow != null
) {
this.props.onChange(
this.props.counters.filter(
({label}) => label !== this.state.highlightedRow,
),
);
}
};
onSubmit = (e: React.KeyboardEvent) => {
if (e.key === 'Enter') {
this.onAdd();
}
};
render() {
return (
<FlexColumn grow={true} tabIndex={-1} onKeyDown={this.onKeyDown}>
<WatcherPanel
heading="Expression Watcher"
floating={false}
collapsable={true}
padded={false}>
<Toolbar>
<ExpressionInput
value={this.state.input}
placeholder="Expression..."
onChange={this.onChange}
onKeyDown={this.onSubmit}
/>
<Button
onClick={this.onAdd}
disabled={this.state.input.length === 0}>
Add counter
</Button>
</Toolbar>
<ManagedTable
onRowHighlighted={this.onRowHighlighted}
columnSizes={ColumnSizes}
columns={Columns}
rows={this.buildRows()}
autoHeight={true}
floating={false}
zebra={false}
/>
</WatcherPanel>
</FlexColumn>
);
}
}