Skip to content

Commit 253394c

Browse files
authored
Move plots webview message sending into webview messages (#2033)
1 parent ed35e17 commit 253394c

File tree

4 files changed

+133
-130
lines changed

4 files changed

+133
-130
lines changed

extension/src/plots/index.ts

Lines changed: 14 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
11
import { join } from 'path'
22
import { Event, EventEmitter, Memento } from 'vscode'
3-
import isEmpty from 'lodash.isempty'
4-
import {
5-
ComparisonPlot,
6-
ComparisonRevisionData,
7-
PlotsData as TPlotsData,
8-
Section
9-
} from './webview/contract'
3+
import { PlotsData as TPlotsData } from './webview/contract'
104
import { WebviewMessages } from './webview/messages'
115
import { PlotsData } from './data'
126
import { PlotsModel } from './model'
@@ -20,7 +14,7 @@ import { Resource } from '../resourceLocator'
2014
import { InternalCommands } from '../commands/internal'
2115
import { definedAndNonEmpty } from '../util/array'
2216
import { ExperimentsOutput, TEMP_PLOTS_DIR } from '../cli/reader'
23-
import { getModifiedTime, removeDir } from '../fileSystem'
17+
import { removeDir } from '../fileSystem'
2418
import { Toast } from '../vscode/toast'
2519
import { pickPaths } from '../path/selection/quickPick'
2620

@@ -41,6 +35,8 @@ export class Plots extends BaseRepository<TPlotsData> {
4135
private readonly data: PlotsData
4236
private readonly workspaceState: Memento
4337

38+
private webviewMessages?: WebviewMessages
39+
4440
constructor(
4541
dvcRoot: string,
4642
internalCommands: InternalCommands,
@@ -82,7 +78,11 @@ export class Plots extends BaseRepository<TPlotsData> {
8278
new PathsModel(this.dvcRoot, this.workspaceState)
8379
)
8480

85-
this.handleMessageFromWebview(this.paths, this.plots, this.experiments)
81+
this.webviewMessages = this.createWebviewMessageHandler(
82+
this.paths,
83+
this.plots,
84+
this.experiments
85+
)
8686

8787
this.data.setModel(this.plots)
8888

@@ -144,98 +144,21 @@ export class Plots extends BaseRepository<TPlotsData> {
144144
this.fetchMissingOrSendPlots()
145145
}
146146

147-
private sendCheckpointPlotsData() {
148-
this.webview?.show({
149-
checkpoint: this.getCheckpointPlots()
150-
})
151-
}
152-
153-
private getCheckpointPlots() {
154-
return this.plots?.getCheckpointPlots() || null
155-
}
156-
157147
private async fetchMissingOrSendPlots() {
158148
await this.isReady()
159149

160150
if (
161151
this.paths?.hasPaths() &&
162152
definedAndNonEmpty(this.plots?.getUnfetchedRevisions())
163153
) {
164-
this.sendCheckpointPlotsData()
154+
this.webviewMessages?.sendCheckpointPlotsMessage()
165155
return this.data.managedUpdate()
166156
}
167157

168-
return this.sendPlots()
158+
return this.webviewMessages?.sendWebviewMessage()
169159
}
170160

171-
private sendPlots() {
172-
this.webview?.show({
173-
checkpoint: this.getCheckpointPlots(),
174-
comparison: this.getComparisonPlots(),
175-
hasPlots: !!this.paths?.hasPaths(),
176-
hasSelectedPlots: definedAndNonEmpty(this.paths?.getSelected()),
177-
sectionCollapsed: this.plots?.getSectionCollapsed(),
178-
selectedRevisions: this.plots?.getSelectedRevisionDetails(),
179-
template: this.getTemplatePlots()
180-
})
181-
}
182-
183-
private getTemplatePlots() {
184-
const paths = this.paths?.getTemplateOrder()
185-
const plots = this.plots?.getTemplatePlots(paths)
186-
187-
if (!this.plots || !plots || isEmpty(plots)) {
188-
return null
189-
}
190-
191-
return {
192-
plots,
193-
size: this.plots.getPlotSize(Section.TEMPLATE_PLOTS)
194-
}
195-
}
196-
197-
private getComparisonPlots() {
198-
const paths = this.paths?.getComparisonPaths()
199-
const comparison = this.plots?.getComparisonPlots(paths)
200-
if (!this.plots || !comparison || isEmpty(comparison)) {
201-
return null
202-
}
203-
204-
return {
205-
plots: comparison.map(({ path, revisions }) => {
206-
return { path, revisions: this.getRevisionsWithCorrectUrls(revisions) }
207-
}),
208-
size: this.plots.getPlotSize(Section.COMPARISON_TABLE)
209-
}
210-
}
211-
212-
private getRevisionsWithCorrectUrls(revisions: ComparisonRevisionData) {
213-
const acc: ComparisonRevisionData = {}
214-
215-
for (const [revision, plot] of Object.entries(revisions)) {
216-
const updatedPlot = this.addCorrectUrl(plot)
217-
if (!updatedPlot) {
218-
continue
219-
}
220-
acc[revision] = updatedPlot
221-
}
222-
return acc
223-
}
224-
225-
private addCorrectUrl(plot: ComparisonPlot) {
226-
if (this.webview) {
227-
return {
228-
...plot,
229-
url: plot.url
230-
? `${this.webview.getWebviewUri(plot.url)}?${getModifiedTime(
231-
plot.url
232-
)}`
233-
: undefined
234-
}
235-
}
236-
}
237-
238-
private handleMessageFromWebview(
161+
private createWebviewMessageHandler(
239162
paths: PathsModel,
240163
plots: PlotsModel,
241164
experiments: Experiments
@@ -244,10 +167,7 @@ export class Plots extends BaseRepository<TPlotsData> {
244167
paths,
245168
plots,
246169
experiments,
247-
() => this.sendSectionCollapsed(),
248-
() => this.sendTemplatePlots(),
249-
() => this.sendComparisonPlots(),
250-
() => this.sendCheckpointPlotsData(),
170+
() => this.getWebview(),
251171
() => this.selectPlots(),
252172
() => this.data.update()
253173
)
@@ -256,25 +176,7 @@ export class Plots extends BaseRepository<TPlotsData> {
256176
webviewMessages.handleMessageFromWebview(message)
257177
)
258178
)
259-
}
260-
261-
private sendSectionCollapsed() {
262-
this.webview?.show({
263-
sectionCollapsed: this.plots?.getSectionCollapsed()
264-
})
265-
}
266-
267-
private sendComparisonPlots() {
268-
this.webview?.show({
269-
comparison: this.getComparisonPlots(),
270-
selectedRevisions: this.plots?.getSelectedRevisionDetails()
271-
})
272-
}
273-
274-
private sendTemplatePlots() {
275-
this.webview?.show({
276-
template: this.getTemplatePlots()
277-
})
179+
return webviewMessages
278180
}
279181

280182
private waitForInitialData(experiments: Experiments) {

extension/src/plots/webview/messages.ts

Lines changed: 111 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
1-
import { PlotSize, Section, SectionCollapsed } from './contract'
1+
import isEmpty from 'lodash.isempty'
2+
import {
3+
ComparisonPlot,
4+
ComparisonRevisionData,
5+
PlotsData as TPlotsData,
6+
PlotSize,
7+
Section,
8+
SectionCollapsed
9+
} from './contract'
210
import { Logger } from '../../common/logger'
311
import { Experiments } from '../../experiments'
412
import { sendTelemetryEvent } from '../../telemetry'
@@ -11,41 +19,53 @@ import {
1119
} from '../../webview/contract'
1220
import { PlotsModel } from '../model'
1321
import { PathsModel } from '../paths/model'
22+
import { BaseWebview } from '../../webview'
23+
import { getModifiedTime } from '../../fileSystem'
24+
import { definedAndNonEmpty } from '../../util/array'
1425

1526
export class WebviewMessages {
1627
private readonly paths: PathsModel
1728
private readonly plots: PlotsModel
1829
private readonly experiments: Experiments
1930

20-
private readonly sendSectionCollapsed: () => void
21-
private readonly sendTemplatePlots: () => void
22-
private readonly sendComparisonPlots: () => void
23-
private readonly sendCheckpointPlotsData: () => void
31+
private readonly getWebview: () => BaseWebview<TPlotsData> | undefined
2432
private readonly selectPlots: () => void
2533
private readonly updateData: () => void
2634

2735
constructor(
2836
paths: PathsModel,
2937
plots: PlotsModel,
3038
experiments: Experiments,
31-
sendSectionCollapsed: () => void,
32-
sendTemplatePlots: () => void,
33-
sendComparisonPlots: () => void,
34-
sendCheckpointPlotsData: () => void,
39+
getWebview: () => BaseWebview<TPlotsData> | undefined,
3540
selectPlots: () => void,
3641
updateData: () => void
3742
) {
3843
this.paths = paths
3944
this.plots = plots
4045
this.experiments = experiments
41-
this.sendSectionCollapsed = sendSectionCollapsed
42-
this.sendTemplatePlots = sendTemplatePlots
43-
this.sendComparisonPlots = sendComparisonPlots
44-
this.sendCheckpointPlotsData = sendCheckpointPlotsData
46+
this.getWebview = getWebview
4547
this.selectPlots = selectPlots
4648
this.updateData = updateData
4749
}
4850

51+
public sendWebviewMessage() {
52+
this.getWebview()?.show({
53+
checkpoint: this.getCheckpointPlots(),
54+
comparison: this.getComparisonPlots(),
55+
hasPlots: !!this.paths?.hasPaths(),
56+
hasSelectedPlots: definedAndNonEmpty(this.paths.getSelected()),
57+
sectionCollapsed: this.plots.getSectionCollapsed(),
58+
selectedRevisions: this.plots.getSelectedRevisionDetails(),
59+
template: this.getTemplatePlots()
60+
})
61+
}
62+
63+
public sendCheckpointPlotsMessage() {
64+
this.getWebview()?.show({
65+
checkpoint: this.getCheckpointPlots()
66+
})
67+
}
68+
4969
public handleMessageFromWebview(message: MessageFromWebview) {
5070
switch (message.type) {
5171
case MessageFromWebviewType.TOGGLE_METRIC:
@@ -176,7 +196,84 @@ export class WebviewMessages {
176196
| typeof EventName.VIEWS_REORDER_PLOTS_METRICS
177197
| typeof EventName.VIEWS_PLOTS_METRICS_SELECTED
178198
) {
179-
this.sendCheckpointPlotsData()
199+
this.sendCheckpointPlotsMessage()
180200
sendTelemetryEvent(event, undefined, undefined)
181201
}
202+
203+
private sendSectionCollapsed() {
204+
this.getWebview()?.show({
205+
sectionCollapsed: this.plots?.getSectionCollapsed()
206+
})
207+
}
208+
209+
private sendComparisonPlots() {
210+
this.getWebview()?.show({
211+
comparison: this.getComparisonPlots(),
212+
selectedRevisions: this.plots?.getSelectedRevisionDetails()
213+
})
214+
}
215+
216+
private sendTemplatePlots() {
217+
this.getWebview()?.show({
218+
template: this.getTemplatePlots()
219+
})
220+
}
221+
222+
private getTemplatePlots() {
223+
const paths = this.paths?.getTemplateOrder()
224+
const plots = this.plots?.getTemplatePlots(paths)
225+
226+
if (!this.plots || !plots || isEmpty(plots)) {
227+
return null
228+
}
229+
230+
return {
231+
plots,
232+
size: this.plots.getPlotSize(Section.TEMPLATE_PLOTS)
233+
}
234+
}
235+
236+
private getComparisonPlots() {
237+
const paths = this.paths.getComparisonPaths()
238+
const comparison = this.plots.getComparisonPlots(paths)
239+
if (!this.plots || !comparison || isEmpty(comparison)) {
240+
return null
241+
}
242+
243+
return {
244+
plots: comparison.map(({ path, revisions }) => {
245+
return { path, revisions: this.getRevisionsWithCorrectUrls(revisions) }
246+
}),
247+
size: this.plots.getPlotSize(Section.COMPARISON_TABLE)
248+
}
249+
}
250+
251+
private getRevisionsWithCorrectUrls(revisions: ComparisonRevisionData) {
252+
const acc: ComparisonRevisionData = {}
253+
254+
for (const [revision, plot] of Object.entries(revisions)) {
255+
const updatedPlot = this.addCorrectUrl(plot)
256+
if (!updatedPlot) {
257+
continue
258+
}
259+
acc[revision] = updatedPlot
260+
}
261+
return acc
262+
}
263+
264+
private addCorrectUrl(plot: ComparisonPlot) {
265+
const webview = this.getWebview()
266+
if (webview) {
267+
return {
268+
...plot,
269+
url: plot.url
270+
? `${webview.getWebviewUri(plot.url)}?${getModifiedTime(plot.url)}`
271+
: undefined
272+
}
273+
}
274+
}
275+
276+
private getCheckpointPlots() {
277+
return this.plots?.getCheckpointPlots() || null
278+
}
182279
}

extension/src/test/suite/plots/index.test.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,12 +167,11 @@ suite('Plots Test Suite', () => {
167167

168168
it('should re-fetch data when moving between branches', async () => {
169169
const mockNow = getMockNow()
170-
const { data, experiments, mockPlotsDiff, plots, plotsModel } =
170+
const { data, experiments, mockPlotsDiff, plotsModel, webviewMessages } =
171171
await buildPlots(disposable, plotsDiffFixture)
172172
mockPlotsDiff.resetHistory()
173173

174-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
175-
const mockSendPlots = stub(plots as any, 'sendPlots')
174+
const mockSendPlots = stub(webviewMessages, 'sendWebviewMessage')
176175

177176
mockPlotsDiff
178177
.onFirstCall()

extension/src/test/suite/plots/util.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { MOCK_IMAGE_MTIME } from '../../fixtures/plotsDiff'
1818
import { PathsModel } from '../../../plots/paths/model'
1919
import { Color } from '../../../experiments/model/status/colors'
2020
import { BaseWorkspaceWebviews } from '../../../webview/workspace'
21+
import { WebviewMessages } from '../../../plots/webview/messages'
2122

2223
export const buildPlots = async (
2324
disposer: Disposer,
@@ -78,6 +79,9 @@ export const buildPlots = async (
7879
// eslint-disable-next-line @typescript-eslint/no-explicit-any
7980
const pathsModel: PathsModel = (plots as any).paths
8081

82+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
83+
const webviewMessages: WebviewMessages = (plots as any).webviewMessages
84+
8185
return {
8286
data,
8387
experiments,
@@ -87,7 +91,8 @@ export const buildPlots = async (
8791
mockRemoveDir,
8892
pathsModel,
8993
plots,
90-
plotsModel
94+
plotsModel,
95+
webviewMessages
9196
}
9297
}
9398

0 commit comments

Comments
 (0)