Add toggle for block client.
Screenshots: https://imgur.com/a/w0UT3wQ
Change-Id: I986b73999969c4bf8f4a471d6fda85ecba1aaf39
diff --git a/ui/src/assets/record.scss b/ui/src/assets/record.scss
index 02dab44..5714119 100644
--- a/ui/src/assets/record.scss
+++ b/ui/src/assets/record.scss
@@ -506,6 +506,81 @@
}
} // probe
+ .toggle {
+ transition: color 0.2s ease;
+ padding-top: var(--record-section-padding);
+ padding-bottom: var(--record-section-padding);
+
+ &:hover {
+ >img { opacity: 1; }
+ >label {
+ color: #333;
+ input[type=checkbox]::after {
+ background: hsl(207, 60%, 60%);
+ }
+ }
+ } // :hover
+
+ >label {
+ cursor: pointer;
+ font-size: 14px;
+ color: var(--record-text-color);
+
+ // The per-probe on-off switch.
+ input[type=checkbox] {
+ -moz-appearance: none;
+ -webkit-appearance: none;
+ cursor: pointer;
+ margin: 0 12px 0 2px;
+ position: relative;
+ display: inline-block;
+ height: 10px;
+ width: 22px;
+ background: #89898966;
+ border-radius: 100px;
+ transition: all 0.3s ease;
+ overflow: visible;
+ vertical-align: middle;
+
+ &:focus {
+ outline: none;
+ }
+
+ &::after {
+ position: absolute;
+ left: -5px;
+ top: -5px;
+ display: block;
+ width: 20px;
+ height: 20px;
+ border-radius: 100px;
+ background: #f5f5f5;
+ box-shadow: 0px 3px 3px rgba(0,0,0,0.15);
+ content: '';
+ transition: all 0.3s ease;
+ }
+ &:checked {
+ background: #8398b7;
+ }
+ &:focus::after {
+ background: hsl(207, 60%, 60%);
+ }
+ &:checked::after {
+ left: 12px;
+ background: #27303d;
+ }
+ } // checkbox
+ } // label
+
+ // The content of the toggle section.
+ >div.descr {
+ font-size: 12px;
+ min-height: 50px;
+ color: #666;
+ line-height: 20px;
+ }
+ } // toggle
+
// The three "Stop when full", "Ring buffer", "Long trace" buttons.
.record-mode {
display: grid;
diff --git a/ui/src/common/state.ts b/ui/src/common/state.ts
index 97ee845..6d4ba72 100644
--- a/ui/src/common/state.ts
+++ b/ui/src/common/state.ts
@@ -416,6 +416,7 @@
hpContinuousDumpsPhase: number;
hpContinuousDumpsInterval: number;
hpSharedMemoryBuffer: number;
+ hpBlockClient: boolean;
javaHeapDump: boolean;
jpProcesses: string;
@@ -479,6 +480,7 @@
hpContinuousDumpsPhase: 0,
hpContinuousDumpsInterval: 0,
hpSharedMemoryBuffer: 8 * 1048576,
+ hpBlockClient: true,
javaHeapDump: false,
jpProcesses: '',
diff --git a/ui/src/controller/record_controller.ts b/ui/src/controller/record_controller.ts
index d6aa111..5525778 100644
--- a/ui/src/controller/record_controller.ts
+++ b/ui/src/controller/record_controller.ts
@@ -269,8 +269,7 @@
cdc.dumpPhaseMs = uiCfg.hpContinuousDumpsPhase;
}
}
- // TODO(fmayer): Add a toggle for this to the UI?
- cfg.blockClient = true;
+ cfg.blockClient = uiCfg.hpBlockClient;
heapprofd = cfg;
}
diff --git a/ui/src/frontend/record_page.ts b/ui/src/frontend/record_page.ts
index 05b46a1..6769e65 100644
--- a/ui/src/frontend/record_page.ts
+++ b/ui/src/frontend/record_page.ts
@@ -44,7 +44,9 @@
Slider,
SliderAttrs,
Textarea,
- TextareaAttrs
+ TextareaAttrs,
+ Toggle,
+ ToggleAttrs
} from './record_widgets';
import {Router} from './router';
@@ -388,7 +390,14 @@
min: 0,
set: (cfg, val) => cfg.hpSharedMemoryBuffer = val,
get: (cfg) => cfg.hpSharedMemoryBuffer
- } as SliderAttrs)
+ } as SliderAttrs),
+ m(Toggle, {
+ title: 'Block client',
+ cssClass: '.thin',
+ descr: `Slow down target application if profiler cannot keep up.`,
+ setEnabled: (cfg, val) => cfg.hpBlockClient = val,
+ isEnabled: (cfg) => cfg.hpBlockClient
+ } as ToggleAttrs)
// TODO(taylori): Add advanced options.
);
}
diff --git a/ui/src/frontend/record_widgets.ts b/ui/src/frontend/record_widgets.ts
index c31545e..2e6db1f 100644
--- a/ui/src/frontend/record_widgets.ts
+++ b/ui/src/frontend/record_widgets.ts
@@ -85,6 +85,43 @@
}
}
+// +-------------------------------------------------------------+
+// | Toggle: an on/off switch.
+// +-------------------------------------------------------------+
+
+export interface ToggleAttrs {
+ title: string;
+ descr: string;
+ cssClass?: string;
+ isEnabled: Getter<boolean>;
+ setEnabled: Setter<boolean>;
+}
+
+export class Toggle implements m.ClassComponent<ToggleAttrs> {
+ view({attrs}: m.CVnode<ToggleAttrs>) {
+ const onToggle = (enabled: boolean) => {
+ const traceCfg = produce(globals.state.recordConfig, draft => {
+ attrs.setEnabled(draft, enabled);
+ });
+ globals.dispatch(Actions.setRecordConfig({config: traceCfg}));
+ };
+
+ const enabled = attrs.isEnabled(globals.state.recordConfig);
+
+ return m(
+ `.toggle${enabled ? '.enabled' : ''}${attrs.cssClass || ''}`,
+ m('label',
+ m(`input[type=checkbox]`, {
+ checked: enabled,
+ oninput: (e: InputEvent) => {
+ onToggle((e.target as HTMLInputElement).checked);
+ },
+ }),
+ m('span', attrs.title)),
+ m('.descr', attrs.descr));
+ }
+}
+
// +---------------------------------------------------------------------------+
// | Slider: draggable horizontal slider with numeric spinner. |
// +---------------------------------------------------------------------------+