diff --git a/vscode/package.json b/vscode/package.json index ad6178c..621cceb 100644 --- a/vscode/package.json +++ b/vscode/package.json @@ -131,7 +131,7 @@ }, { "command": "auxon.modality.log", - "when": "view == auxon.segments || view == auxon.timelines", + "when": "view == auxon.segments || view == auxon.timelines || (view == auxon.events && viewItem == event)", "group": "inline" }, { @@ -174,6 +174,10 @@ "command": "auxon.events.createEventAttrNotebook", "when": "view == auxon.events && viewItem == eventAttribute" }, + { + "command": "auxon.events.logSelected", + "when": "view == auxon.events && listMultiSelection && viewItem == event" + }, { "command": "auxon.specs.showLatest", "when": "view == auxon.specs && viewItem == spec && !listMultiSelection", @@ -466,6 +470,10 @@ "command": "auxon.events.createEventAttrNotebook", "title": "View Attribute Plots in a Jupyter Notebook" }, + { + "command": "auxon.events.logSelected", + "title": "Log Selected Events" + }, { "command": "auxon.specs.refresh", "title": "Refresh Spec List", @@ -597,7 +605,7 @@ }, { "command": "auxon.modality.log", - "title": "View log", + "title": "View Log", "icon": "$(open-preview)" } ], diff --git a/vscode/src/events.ts b/vscode/src/events.ts index 68be30d..36831cf 100644 --- a/vscode/src/events.ts +++ b/vscode/src/events.ts @@ -5,6 +5,7 @@ import * as commonNotebookCells from "../templates/common.json"; import * as eventTimingNotebookCells from "../templates/eventTiming.json"; import * as eventAttributeValuesNotebookCells from "../templates/eventAttributeValues.json"; import * as eventMultiAttributeValuesNotebookCells from "../templates/eventMultiAttributeValues.json"; +import * as modalityLog from "./modalityLog"; export class EventsTreeDataProvider implements vscode.TreeDataProvider { selectedTimelineId?: api.TimelineId = undefined; @@ -30,6 +31,7 @@ export class EventsTreeDataProvider implements vscode.TreeDataProvider this.refresh()), + vscode.commands.registerCommand("auxon.events.logSelected", () => this.logSelectedCommand()), vscode.commands.registerCommand("auxon.events.setSelectedTimeline", (timelineId, timelineName) => this.setSelectedTimeline(timelineId, timelineName) ), @@ -73,7 +75,7 @@ export class EventsTreeDataProvider implements vscode.TreeDataProvider a.eventName.localeCompare(b.eventName)); @@ -95,6 +97,19 @@ export class EventsTreeDataProvider implements vscode.TreeDataProvider data.eventName); // Add the item the command was executed on, it may not be in the selection @@ -225,7 +240,19 @@ export type EventsTreeItemData = EventNameTreeItemData | EventAttributeTreeItemD export type EventsTreeItem = EventNameTreeItem | EventAttributeTreeItem; export class EventNameTreeItemData { - constructor(public eventName: string, public numInstances: number, public attributes: string[]) {} + constructor( + public eventName: string, + public numInstances: number, + public attributes: string[], + public timelineId: api.TimelineId + ) {} + + getModalityLogCommandArgs(): modalityLog.ModalityLogCommandArgs { + const literalTimelineId = "%" + this.timelineId.replace(/-/g, ""); + return new modalityLog.ModalityLogCommandArgs({ + thingToLog: `${this.eventName}@*(_.timeline.id=${literalTimelineId})`, + }); + } } class EventNameTreeItem extends vscode.TreeItem { diff --git a/vscode/src/segments.ts b/vscode/src/segments.ts index 4da811a..0ee8d30 100644 --- a/vscode/src/segments.ts +++ b/vscode/src/segments.ts @@ -100,6 +100,16 @@ export class SegmentsTreeDataProvider implements vscode.TreeDataProvider { + if (a === null || a.name === null) { + return 1; + } + if (b === null || b.name === null) { + return -1; + } + return a.segment.latest_receive_time - b.segment.latest_receive_time; + }); + if ( !isDeepStrictEqual(usedSegmentConfig, this.usedSegmentConfig) || !isDeepStrictEqual(activeSegmentIds, this.activeSegmentIds) diff --git a/vscode/src/specCoverage.ts b/vscode/src/specCoverage.ts index 2779a15..398e87f 100644 --- a/vscode/src/specCoverage.ts +++ b/vscode/src/specCoverage.ts @@ -145,7 +145,7 @@ function specViewModel(sc: api.SpecCoverage): SpecViewModel { } for (const [_c_name, caseCoverage] of Object.entries(behaviorCoverage.case_coverage)) { numSpecCases += 1; - if (caseCoverage.ever_matched) { + if (caseCoverage.ever_matched || (caseCoverage.case_type == "Prohibited" && !caseCoverage.ever_matched)) { numSpecCasesCovered += 1; } } @@ -223,7 +223,7 @@ function caseViewModel(cCov: api.CaseCoverage): CaseViewModel { let status: Status = "not-executed"; if (cCov.case_type == "Prohibited") { - if (!cCov.ever_matched || cCov.matched_n_times > 0) { + if (cCov.ever_matched || cCov.matched_n_times > 0) { status = "failed"; } else { status = "passed"; diff --git a/vscode/src/timelines.ts b/vscode/src/timelines.ts index 396d41b..22b24ec 100644 --- a/vscode/src/timelines.ts +++ b/vscode/src/timelines.ts @@ -433,7 +433,15 @@ export class TimelineGroupTreeItemData extends TimelineTreeItemData { } override children(): TimelineTreeItemData[] { - const timelines = this.timeline_group.timelines.sort(); + const timelines = this.timeline_group.timelines.sort((a, b) => { + if (a === null || a.name === null) { + return 1; + } + if (b === null || b.name === null) { + return -1; + } + return a.name.localeCompare(b.name); + }); return timelines.map((timeline_overview) => new TimelineLeafTreeItemData(timeline_overview)); } }