From e3668cf3059843856dc96fbe2273d1b96e0dc259 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Genevi=C3=A8ve=20Bastien?= Date: Mon, 9 Nov 2020 13:46:49 -0500 Subject: [PATCH] Split viewer-prototype in packages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In prevision of the development of a vscode extension, the code in the viewer-prototype has been mostly moved to 2 new packages: * @trace-viewer/base: Queries the trace server for traces, experiments and possible outputs * @trace-viewer/react-components: Contains the various types of visualization for trace data, queries the trace server for output data to display Those 2 packages can eventually be published to npm. In the viewer-prototype directory only remains the theia specific module contributions. So the application still works as before using theia, it's just that most of the classes used by the trace-viewer have been moved to new npm packages. Signed-off-by: Geneviève Bastien --- README.md | 3 +- browser-app/package.json | 2 +- configs/base.eslintrc.json | 1 - electron-app/package.json | 2 +- package.json | 6 +- packages/base/.eslintrc.js | 26 ++++ packages/base/package.json | 35 +++++ .../base/src}/experiment-manager.ts | 42 +++--- packages/base/src/message-manager.ts | 39 ++++++ packages/base/src/signal-manager.ts | 32 +++++ .../base/src}/trace-manager.ts | 58 +++------ .../base/src}/utils/time-range.ts | 0 .../base/src}/utils/value-hash.ts | 0 packages/base/tsconfig.json | 16 +++ packages/react-components/.eslintrc.js | 39 ++++++ .../react-components}/jest.config.json | 0 .../react-components}/jestSetup.ts | 0 packages/react-components/package.json | 66 ++++++++++ .../components/abstract-output-component.tsx | 7 +- .../abstract-tree-output-component.tsx | 0 .../data-providers/style-provider.ts | 0 .../data-providers/tsp-data-provider.ts | 0 .../src}/components/null-output-component.tsx | 0 .../components/table-output-component.tsx | 0 .../components/timegraph-output-component.tsx | 6 +- .../components/trace-context-component.tsx | 33 +++-- .../__snapshots__/entry-tree.test.tsx.snap | 0 .../__snapshots__/table-row.test.tsx.snap | 0 .../__tests__/entry-tree.test.tsx | 0 .../filtrer-tree/__tests__/table-row.test.tsx | 0 .../filtrer-tree/__tests__/utils.test.tsx | 0 .../utils/filtrer-tree/checkbox-component.tsx | 0 .../utils/filtrer-tree/column-header.tsx | 0 .../utils/filtrer-tree/entry-tree.tsx | 0 .../components/utils/filtrer-tree/filter.tsx | 0 .../components/utils/filtrer-tree/icons.tsx | 0 .../components/utils/filtrer-tree/message.tsx | 0 .../components/utils/filtrer-tree/sort.tsx | 0 .../utils/filtrer-tree/table-body.tsx | 0 .../utils/filtrer-tree/table-cell.tsx | 0 .../utils/filtrer-tree/table-header.tsx | 0 .../utils/filtrer-tree/table-row.tsx | 0 .../components/utils/filtrer-tree/table.tsx | 0 .../utils/filtrer-tree/tree-node.tsx | 0 .../components/utils/filtrer-tree/tree.tsx | 0 .../components/utils/filtrer-tree/utils.tsx | 0 .../utils/output-component-style.ts | 0 .../components/utils/time-axis-component.tsx | 0 .../utils/time-navigator-component.tsx | 0 .../utils/timegraph-container-component.tsx | 0 .../src}/components/xy-output-component.tsx | 0 packages/react-components/src/index.tsx | 3 + .../src}/style/chart-line-solid.svg | 0 .../src}/style/output-components-style.css | 0 .../src}/style/status-bar.css | 0 .../src}/style/trace-context-style.css | 0 .../src}/style/trace-explorer.css | 0 .../src}/style/trace-viewer.css | 0 packages/react-components/tsconfig.json | 25 ++++ viewer-prototype/.eslintrc.js | 2 +- viewer-prototype/README.md | 23 ---- viewer-prototype/package.json | 123 +++++++----------- .../src/browser/theia-message-manager.ts | 24 ++++ .../trace-explorer/trace-explorer-widget.tsx | 28 +++- .../trace-viewer-frontend-module.ts | 12 +- .../src/browser/trace-viewer/trace-viewer.tsx | 28 ++-- .../src/browser/tsp-client-provider.ts | 16 +++ .../src/common/redux_store_prototype.json | 50 ------- viewer-prototype/src/common/signal-manager.ts | 24 ---- viewer-prototype/tsconfig.json | 2 +- 70 files changed, 482 insertions(+), 291 deletions(-) create mode 100644 packages/base/.eslintrc.js create mode 100644 packages/base/package.json rename {viewer-prototype/src/common => packages/base/src}/experiment-manager.ts (78%) create mode 100644 packages/base/src/message-manager.ts create mode 100644 packages/base/src/signal-manager.ts rename {viewer-prototype/src/common => packages/base/src}/trace-manager.ts (72%) rename {viewer-prototype/src/common => packages/base/src}/utils/time-range.ts (100%) rename {viewer-prototype/src/common => packages/base/src}/utils/value-hash.ts (100%) create mode 100644 packages/base/tsconfig.json create mode 100644 packages/react-components/.eslintrc.js rename {viewer-prototype => packages/react-components}/jest.config.json (100%) rename {viewer-prototype => packages/react-components}/jestSetup.ts (100%) create mode 100644 packages/react-components/package.json rename {viewer-prototype/src/browser/trace-viewer => packages/react-components/src}/components/abstract-output-component.tsx (95%) rename {viewer-prototype/src/browser/trace-viewer => packages/react-components/src}/components/abstract-tree-output-component.tsx (100%) rename {viewer-prototype/src/browser/trace-viewer => packages/react-components/src}/components/data-providers/style-provider.ts (100%) rename {viewer-prototype/src/browser/trace-viewer => packages/react-components/src}/components/data-providers/tsp-data-provider.ts (100%) rename {viewer-prototype/src/browser/trace-viewer => packages/react-components/src}/components/null-output-component.tsx (100%) rename {viewer-prototype/src/browser/trace-viewer => packages/react-components/src}/components/table-output-component.tsx (100%) rename {viewer-prototype/src/browser/trace-viewer => packages/react-components/src}/components/timegraph-output-component.tsx (98%) rename {viewer-prototype/src/browser/trace-viewer => packages/react-components/src}/components/trace-context-component.tsx (91%) rename {viewer-prototype/src/browser/trace-viewer => packages/react-components/src}/components/utils/filtrer-tree/__tests__/__snapshots__/entry-tree.test.tsx.snap (100%) rename {viewer-prototype/src/browser/trace-viewer => packages/react-components/src}/components/utils/filtrer-tree/__tests__/__snapshots__/table-row.test.tsx.snap (100%) rename {viewer-prototype/src/browser/trace-viewer => packages/react-components/src}/components/utils/filtrer-tree/__tests__/entry-tree.test.tsx (100%) rename {viewer-prototype/src/browser/trace-viewer => packages/react-components/src}/components/utils/filtrer-tree/__tests__/table-row.test.tsx (100%) rename {viewer-prototype/src/browser/trace-viewer => packages/react-components/src}/components/utils/filtrer-tree/__tests__/utils.test.tsx (100%) rename {viewer-prototype/src/browser/trace-viewer => packages/react-components/src}/components/utils/filtrer-tree/checkbox-component.tsx (100%) rename {viewer-prototype/src/browser/trace-viewer => packages/react-components/src}/components/utils/filtrer-tree/column-header.tsx (100%) rename {viewer-prototype/src/browser/trace-viewer => packages/react-components/src}/components/utils/filtrer-tree/entry-tree.tsx (100%) rename {viewer-prototype/src/browser/trace-viewer => packages/react-components/src}/components/utils/filtrer-tree/filter.tsx (100%) rename {viewer-prototype/src/browser/trace-viewer => packages/react-components/src}/components/utils/filtrer-tree/icons.tsx (100%) rename {viewer-prototype/src/browser/trace-viewer => packages/react-components/src}/components/utils/filtrer-tree/message.tsx (100%) rename {viewer-prototype/src/browser/trace-viewer => packages/react-components/src}/components/utils/filtrer-tree/sort.tsx (100%) rename {viewer-prototype/src/browser/trace-viewer => packages/react-components/src}/components/utils/filtrer-tree/table-body.tsx (100%) rename {viewer-prototype/src/browser/trace-viewer => packages/react-components/src}/components/utils/filtrer-tree/table-cell.tsx (100%) rename {viewer-prototype/src/browser/trace-viewer => packages/react-components/src}/components/utils/filtrer-tree/table-header.tsx (100%) rename {viewer-prototype/src/browser/trace-viewer => packages/react-components/src}/components/utils/filtrer-tree/table-row.tsx (100%) rename {viewer-prototype/src/browser/trace-viewer => packages/react-components/src}/components/utils/filtrer-tree/table.tsx (100%) rename {viewer-prototype/src/browser/trace-viewer => packages/react-components/src}/components/utils/filtrer-tree/tree-node.tsx (100%) rename {viewer-prototype/src/browser/trace-viewer => packages/react-components/src}/components/utils/filtrer-tree/tree.tsx (100%) rename {viewer-prototype/src/browser/trace-viewer => packages/react-components/src}/components/utils/filtrer-tree/utils.tsx (100%) rename {viewer-prototype/src/browser/trace-viewer => packages/react-components/src}/components/utils/output-component-style.ts (100%) rename {viewer-prototype/src/browser/trace-viewer => packages/react-components/src}/components/utils/time-axis-component.tsx (100%) rename {viewer-prototype/src/browser/trace-viewer => packages/react-components/src}/components/utils/time-navigator-component.tsx (100%) rename {viewer-prototype/src/browser/trace-viewer => packages/react-components/src}/components/utils/timegraph-container-component.tsx (100%) rename {viewer-prototype/src/browser/trace-viewer => packages/react-components/src}/components/xy-output-component.tsx (100%) create mode 100644 packages/react-components/src/index.tsx rename {viewer-prototype/src/browser => packages/react-components/src}/style/chart-line-solid.svg (100%) rename {viewer-prototype/src/browser => packages/react-components/src}/style/output-components-style.css (100%) rename {viewer-prototype/src/browser => packages/react-components/src}/style/status-bar.css (100%) rename {viewer-prototype/src/browser => packages/react-components/src}/style/trace-context-style.css (100%) rename {viewer-prototype/src/browser => packages/react-components/src}/style/trace-explorer.css (100%) rename {viewer-prototype/src/browser => packages/react-components/src}/style/trace-viewer.css (100%) create mode 100644 packages/react-components/tsconfig.json delete mode 100644 viewer-prototype/README.md create mode 100644 viewer-prototype/src/browser/theia-message-manager.ts delete mode 100644 viewer-prototype/src/common/redux_store_prototype.json delete mode 100644 viewer-prototype/src/common/signal-manager.ts diff --git a/README.md b/README.md index be452c8f6..4690e05b6 100644 --- a/README.md +++ b/README.md @@ -110,5 +110,4 @@ Now, you will see 3 sections: **Opened experiments**, **Available analysis** and There is only a limited number of such operations and they are only implemented in the Time Graph views (the ones looking like Gantt charts). For Zoom-in/out use CTRL+mouse wheel. Or use left mouse drag on time axis on top. Navigating the trace you can use the scrollbar at the bottom of the experiment container. ### Time Graph Tooltip -Currently, the **Time Graph Tooltip** is populated when selecting a state in a Time Graph view. - +Currently, the **Time Graph Tooltip** is populated when selecting a state in a Time Graph view. \ No newline at end of file diff --git a/browser-app/package.json b/browser-app/package.json index af8e33ef4..b3b2b3440 100644 --- a/browser-app/package.json +++ b/browser-app/package.json @@ -29,7 +29,7 @@ "@theia/vsx-registry": "latest", "@theia/keymaps": "latest", "@theia/getting-started": "latest", - "trace-viewer": "0.0.0" + "theia-trace-viewer": "0.0.0" }, "devDependencies": { "@theia/cli": "latest" diff --git a/configs/base.eslintrc.json b/configs/base.eslintrc.json index 4bd94b952..f639b7266 100644 --- a/configs/base.eslintrc.json +++ b/configs/base.eslintrc.json @@ -14,7 +14,6 @@ ], "env": { "browser": true, - "mocha": true, "node": true }, "ignorePatterns": [ diff --git a/electron-app/package.json b/electron-app/package.json index ade5d5516..cc4b70041 100644 --- a/electron-app/package.json +++ b/electron-app/package.json @@ -38,7 +38,7 @@ "@theia/keymaps": "latest", "@theia/getting-started": "latest", "@theia/electron": "latest", - "trace-viewer": "0.0.0" + "theia-trace-viewer": "0.0.0" }, "devDependencies": { "@theia/cli": "latest", diff --git a/package.json b/package.json index 4c429ba41..8e54e4de6 100644 --- a/package.json +++ b/package.json @@ -11,13 +11,15 @@ "start:server": "./trace-compass-server/tracecompass-server", "start-all:browser": "yarn start:server & yarn start:browser", "start-all:electron": "yarn start:server & yarn start:electron", - "lint": "yarn workspace trace-viewer run lint", - "test": "yarn workspace trace-viewer run test" + "lint": "lerna run lint", + "test": "lerna run test" }, "devDependencies": { "lerna": "2.4.0" }, "workspaces": [ + "packages/base", + "packages/react-components", "viewer-prototype", "browser-app", "electron-app" diff --git a/packages/base/.eslintrc.js b/packages/base/.eslintrc.js new file mode 100644 index 000000000..a6115b869 --- /dev/null +++ b/packages/base/.eslintrc.js @@ -0,0 +1,26 @@ +/** @type {import('eslint').Linter.Config} */ +module.exports = { + root: true, + parser: "@typescript-eslint/parser", // Specifies the ESLint parser + parserOptions: { + ecmaVersion: 2020, // Allows for the parsing of modern ECMAScript features + sourceType: "module", // Allows for the use of imports + tsconfigRootDir: __dirname, + project: 'tsconfig.json', + projectFolderIgnoreList: [ + '/lib/' + ] + }, + extends: [ + 'plugin:@typescript-eslint/recommended', + '../../configs/base.eslintrc.json', + '../../configs/warnings.eslintrc.json', + '../../configs/errors.eslintrc.json' + ], + ignorePatterns: [ + 'node_modules', + 'lib', + '.eslintrc.js', + 'plugins' + ] +}; diff --git a/packages/base/package.json b/packages/base/package.json new file mode 100644 index 000000000..c1c60661d --- /dev/null +++ b/packages/base/package.json @@ -0,0 +1,35 @@ +{ + "name": "@trace-viewer/base", + "version": "0.0.0", + "description": "Trace Compass base package, contains trace management utilities", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/theia-ide/theia-trace-extension" + }, + "files": [ + "lib", + "src" + ], + "dependencies": { + "tsp-typescript-client": "next" + }, + "devDependencies": { + "@typescript-eslint/eslint-plugin": "^3.4.0", + "@typescript-eslint/parser": "^3.4.0", + "eslint": "^7.3.0", + "eslint-plugin-import": "^2.21.2", + "eslint-plugin-no-null": "^1.0.2", + "eslint-plugin-react": "^7.20.0", + "rimraf": "latest", + "typescript": "latest" + }, + "scripts": { + "build": "tsc", + "clean": "rimraf lib", + "lint": "eslint .", + "prepare": "yarn clean && yarn build", + "test": "echo 'test'", + "watch": "tsc -w" + } +} \ No newline at end of file diff --git a/viewer-prototype/src/common/experiment-manager.ts b/packages/base/src/experiment-manager.ts similarity index 78% rename from viewer-prototype/src/common/experiment-manager.ts rename to packages/base/src/experiment-manager.ts index fee1ddf57..3260d37a9 100644 --- a/viewer-prototype/src/common/experiment-manager.ts +++ b/packages/base/src/experiment-manager.ts @@ -1,32 +1,20 @@ import { Trace } from 'tsp-typescript-client/lib/models/trace'; -import { Emitter } from '@theia/core'; import { TspClient } from 'tsp-typescript-client/lib/protocol/tsp-client'; -import { TspClientProvider } from '../browser/tsp-client-provider'; import { Query } from 'tsp-typescript-client/lib/models/query/query'; -import { injectable, inject } from 'inversify'; import { OutputDescriptor } from 'tsp-typescript-client/lib/models/output-descriptor'; import { Experiment } from 'tsp-typescript-client/lib/models/experiment'; import { TspClientResponse } from 'tsp-typescript-client/lib/protocol/tsp-client-response'; +import { signalManager, Signals } from './signal-manager'; -@injectable() export class ExperimentManager { - // Open signal - private experimentOpenedEmitter = new Emitter(); - public experimentOpenedSignal = this.experimentOpenedEmitter.event; - - // Close signal - private experimentClosedEmitter = new Emitter(); - public experimentClosedSignal = this.experimentClosedEmitter.event; private fOpenExperiments: Map = new Map(); + private fTspClient: TspClient; - private tspClient: TspClient; - - private constructor( - @inject(TspClientProvider) private tspClientProvider: TspClientProvider + constructor( + tspClient: TspClient ) { - this.tspClient = this.tspClientProvider.getTspClient(); - this.tspClientProvider.addTspClientChangeListener(tspClient => this.tspClient = tspClient); + this.fTspClient = tspClient; } /** @@ -36,7 +24,7 @@ export class ExperimentManager { async getOpenedExperiments(): Promise { const openedExperiments: Array = []; // Look on the server for opened experiments - const experimentResponse = await this.tspClient.fetchExperiments(); + const experimentResponse = await this.fTspClient.fetchExperiments(); if (experimentResponse.isOk()) { openedExperiments.push(...experimentResponse.getModel()); } @@ -53,7 +41,7 @@ export class ExperimentManager { // If the experiment is undefined, check on the server if (!experiment) { - const experimentResponse = await this.tspClient.fetchExperiment(experimentUUID); + const experimentResponse = await this.fTspClient.fetchExperiment(experimentUUID); if (experimentResponse.isOk()) { experiment = experimentResponse.getModel(); } @@ -69,7 +57,7 @@ export class ExperimentManager { // Check if the experiment is opened const experiment = this.fOpenExperiments.get(experimentUUID); if (experiment) { - const outputsResponse = await this.tspClient.experimentOutputs(experiment.UUID); + const outputsResponse = await this.fTspClient.experimentOutputs(experiment.UUID); return outputsResponse.getModel(); } return undefined; @@ -89,14 +77,14 @@ export class ExperimentManager { traceURIs.push(traces[i].UUID); } - const experimentResponse = await this.tspClient.createExperiment(new Query({ + const experimentResponse = await this.fTspClient.createExperiment(new Query({ 'name': name, 'traces': traceURIs })); const opendExperiment = experimentResponse.getModel(); if (opendExperiment && experimentResponse.isOk()) { this.addExperiment(opendExperiment); - this.experimentOpenedEmitter.fire(opendExperiment); + signalManager().emit(Signals.EXPERIMENT_OPENED, {experiment: opendExperiment}); return opendExperiment; } else if (opendExperiment && experimentResponse.getStatusCode() === 409) { // Repost with a suffix as long as there are conflicts @@ -110,13 +98,13 @@ export class ExperimentManager { let conflictResolutionResponse = experimentResponse; let i = 1; while (conflictResolutionResponse.getStatusCode() === 409) { - conflictResolutionResponse = await handleConflict(this.tspClient, i); + conflictResolutionResponse = await handleConflict(this.fTspClient, i); i++; } const experiment = conflictResolutionResponse.getModel(); if (experiment && conflictResolutionResponse.isOk()) { this.addExperiment(experiment); - this.experimentOpenedEmitter.fire(experiment); + signalManager().emit(Signals.EXPERIMENT_OPENED, {experiment: experiment}); return experiment; } } @@ -132,7 +120,7 @@ export class ExperimentManager { async updateExperiment(experimentUUID: string): Promise { const currentExperiment = this.fOpenExperiments.get(experimentUUID); if (currentExperiment) { - const experimentResponse = await this.tspClient.fetchExperiment(currentExperiment.UUID); + const experimentResponse = await this.fTspClient.fetchExperiment(currentExperiment.UUID); const experiment = experimentResponse.getModel(); if (experiment && experimentResponse.isOk) { this.fOpenExperiments.set(experimentUUID, experiment); @@ -150,10 +138,10 @@ export class ExperimentManager { async closeExperiment(experimentUUID: string): Promise { const experimentToClose = this.fOpenExperiments.get(experimentUUID); if (experimentToClose) { - await this.tspClient.deleteExperiment(experimentUUID); + await this.fTspClient.deleteExperiment(experimentUUID); const deletedExperiment = this.removeExperiment(experimentUUID); if (deletedExperiment) { - this.experimentClosedEmitter.fire(deletedExperiment); + signalManager().emit(Signals.EXPERIMENT_CLOSED, {experiment: deletedExperiment}); } } } diff --git a/packages/base/src/message-manager.ts b/packages/base/src/message-manager.ts new file mode 100644 index 000000000..7778b013b --- /dev/null +++ b/packages/base/src/message-manager.ts @@ -0,0 +1,39 @@ +export enum MessageCategory { + TRACE_CONTEXT, + SERVER_MESSAGE, + SERVER_STATUS, +} + +export enum MessageSeverity { + ERROR, + WARNING, + INFO, + DEBUG +} + +export interface StatusMessage { + text: string; + category?: MessageCategory; + severity?: MessageSeverity; +} + +export declare interface MessageManager { + + addStatusMessage(messageKey: string, message: StatusMessage): void; + removeStatusMessage(messageKey: string): void; + +} + +export class MessageManager implements MessageManager { + + addStatusMessage(messageKey: string, {text, + category = MessageCategory.SERVER_MESSAGE, + severity = MessageSeverity.INFO }: StatusMessage): void { + console.log('New status message', messageKey, text, category, severity); + } + + removeStatusMessage(messageKey: string): void { + console.log('Removing status message status message', messageKey); + } + +} diff --git a/packages/base/src/signal-manager.ts b/packages/base/src/signal-manager.ts new file mode 100644 index 000000000..6be9afe74 --- /dev/null +++ b/packages/base/src/signal-manager.ts @@ -0,0 +1,32 @@ +import { EventEmitter } from 'events'; + +export declare interface SignalManager { + + fireTooltipSignal(tooltip: { [key: string]: string }): void; + +} + +export const Signals = { + TRACE_OPENED : 'trace opened', + TRACE_CLOSED : 'trace closed', + EXPERIMENT_OPENED: 'experiment opened', + EXPERIMENT_CLOSED: 'experiment closed', + EXPERIMENT_SELECTED: 'experiment selected', + TOOLTIP_UPDATED: 'tooltip updated' +}; + +export class SignalManager extends EventEmitter implements SignalManager { + + fireTooltipSignal(tooltip: { [key: string]: string; }): void { + this.emit(Signals.TOOLTIP_UPDATED, {tooltip}); + } + +} + +let instance: SignalManager = new SignalManager(); + +export const setSignalManagerInstance = (sm: SignalManager) => { + instance = sm; +}; + +export const signalManager = (): SignalManager => instance; diff --git a/viewer-prototype/src/common/trace-manager.ts b/packages/base/src/trace-manager.ts similarity index 72% rename from viewer-prototype/src/common/trace-manager.ts rename to packages/base/src/trace-manager.ts index b5a0b1e2b..287232d17 100644 --- a/viewer-prototype/src/common/trace-manager.ts +++ b/packages/base/src/trace-manager.ts @@ -1,31 +1,20 @@ + import { Trace } from 'tsp-typescript-client/lib/models/trace'; -import { Path, Emitter } from '@theia/core'; import { TspClient } from 'tsp-typescript-client/lib/protocol/tsp-client'; -import { TspClientProvider } from '../browser/tsp-client-provider'; import { Query } from 'tsp-typescript-client/lib/models/query/query'; -import { injectable, inject } from 'inversify'; import { OutputDescriptor } from 'tsp-typescript-client/lib/models/output-descriptor'; import { TspClientResponse } from 'tsp-typescript-client/lib/protocol/tsp-client-response'; +import { signalManager, Signals } from './signal-manager'; -@injectable() export class TraceManager { - // Open signal - private traceOpenedEmitter = new Emitter(); - public traceOpenedSignal = this.traceOpenedEmitter.event; - - // Close signal - private traceClosedEmitter = new Emitter(); - public traceClosedSignal = this.traceClosedEmitter.event; private fOpenTraces: Map = new Map(); + private fTspClient: TspClient; - private tspClient: TspClient; - - private constructor( - @inject(TspClientProvider) private tspClientProvider: TspClientProvider + constructor( + tspClient: TspClient ) { - this.tspClient = this.tspClientProvider.getTspClient(); - this.tspClientProvider.addTspClientChangeListener(tspClient => this.tspClient = tspClient); + this.fTspClient = tspClient; } /** @@ -35,7 +24,7 @@ export class TraceManager { async getOpenedTraces(): Promise { const openedTraces: Array = []; // Look on the server for opened trace - const tracesResponse = await this.tspClient.fetchTraces(); + const tracesResponse = await this.fTspClient.fetchTraces(); if (tracesResponse.isOk()) { openedTraces.push(...tracesResponse.getModel()); } @@ -52,7 +41,7 @@ export class TraceManager { // If the trace is undefined, check on the server if (!trace) { - const traceResponse = await this.tspClient.fetchTrace(traceUUID); + const traceResponse = await this.fTspClient.fetchTrace(traceUUID); if (traceResponse.isOk()) { trace = traceResponse.getModel(); } @@ -68,7 +57,7 @@ export class TraceManager { // Check if the trace is opened const trace = this.fOpenTraces.get(traceUUID); if (trace) { - const outputsResponse = await this.tspClient.experimentOutputs(trace.UUID); + const outputsResponse = await this.fTspClient.experimentOutputs(trace.UUID); return outputsResponse.getModel(); } return undefined; @@ -80,21 +69,16 @@ export class TraceManager { * @param traceName Optional name for the trace. If not specified the URI name is used * @returns The opened trace */ - async openTrace(traceURI: Path, traceName?: string): Promise { - let name = traceURI.name; - if (traceName) { - name = traceName; - } - - const tracePath = traceURI.toString(); - const traceResponse = await this.tspClient.openTrace(new Query({ - 'name': name, - 'uri': tracePath + async openTrace(traceURI: string, traceName?: string): Promise { + const traceResponse = await this.fTspClient.openTrace(new Query({ + 'name': traceName, + 'uri': traceURI })); + const openedTrace = traceResponse.getModel(); if (openedTrace && traceResponse.isOk()) { this.addTrace(openedTrace); - this.traceOpenedEmitter.fire(openedTrace); + signalManager().emit(Signals.TRACE_OPENED, {trace: openedTrace}); return openedTrace; } else if (openedTrace && traceResponse.getStatusCode() === 409) { // Repost with a suffix as long as there are conflicts @@ -102,19 +86,19 @@ export class TraceManager { const suffix = '(' + tryNb + ')'; return tspClient.openTrace(new Query({ 'name': name + suffix, - 'uri': tracePath + 'uri': traceURI })); }; let conflictResolutionResponse = traceResponse; let i = 1; while (conflictResolutionResponse.getStatusCode() === 409) { - conflictResolutionResponse = await handleConflict(this.tspClient, i); + conflictResolutionResponse = await handleConflict(this.fTspClient, i); i++; } const trace = conflictResolutionResponse.getModel(); if (trace && conflictResolutionResponse.isOk()) { this.addTrace(trace); - this.traceOpenedEmitter.fire(trace); + signalManager().emit(Signals.TRACE_OPENED, {trace: openedTrace}); return trace; } } @@ -130,7 +114,7 @@ export class TraceManager { async updateTrace(traceUUID: string): Promise { const currentTrace = this.fOpenTraces.get(traceUUID); if (currentTrace) { - const traceResponse = await this.tspClient.fetchTrace(currentTrace.UUID); + const traceResponse = await this.fTspClient.fetchTrace(currentTrace.UUID); const trace = traceResponse.getModel(); if (trace && traceResponse.isOk) { this.fOpenTraces.set(traceUUID, trace); @@ -148,10 +132,10 @@ export class TraceManager { async closeTrace(traceUUID: string): Promise { const traceToClose = this.fOpenTraces.get(traceUUID); if (traceToClose) { - await this.tspClient.deleteTrace(traceUUID); + await this.fTspClient.deleteTrace(traceUUID); const deletedTrace = this.removeTrace(traceUUID); if (deletedTrace) { - this.traceClosedEmitter.fire(deletedTrace); + signalManager().emit(Signals.TRACE_CLOSED, {trace: deletedTrace}); } } } diff --git a/viewer-prototype/src/common/utils/time-range.ts b/packages/base/src/utils/time-range.ts similarity index 100% rename from viewer-prototype/src/common/utils/time-range.ts rename to packages/base/src/utils/time-range.ts diff --git a/viewer-prototype/src/common/utils/value-hash.ts b/packages/base/src/utils/value-hash.ts similarity index 100% rename from viewer-prototype/src/common/utils/value-hash.ts rename to packages/base/src/utils/value-hash.ts diff --git a/packages/base/tsconfig.json b/packages/base/tsconfig.json new file mode 100644 index 000000000..5a0969723 --- /dev/null +++ b/packages/base/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "strict": true, + "sourceMap": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "module": "commonjs", + "target": "ES2020", + "outDir": "lib", + "declaration": true, + "skipLibCheck": true + }, + "include": [ + "src" + ] +} \ No newline at end of file diff --git a/packages/react-components/.eslintrc.js b/packages/react-components/.eslintrc.js new file mode 100644 index 000000000..af4297895 --- /dev/null +++ b/packages/react-components/.eslintrc.js @@ -0,0 +1,39 @@ +/** @type {import('eslint').Linter.Config} */ +module.exports = { + root: true, + parser: "@typescript-eslint/parser", // Specifies the ESLint parser + parserOptions: { + ecmaVersion: 2020, // Allows for the parsing of modern ECMAScript features + sourceType: "module", // Allows for the use of imports + ecmaFeatures: { + jsx: true // Allows for the parsing of JSX + } + }, + settings: { + react: { + version: "detect" // Tells eslint-plugin-react to automatically detect the version of React to use + } + }, + extends: [ + 'plugin:react/recommended', + 'plugin:@typescript-eslint/recommended', + '../../configs/base.eslintrc.json', + '../../configs/warnings.eslintrc.json', + '../../configs/errors.eslintrc.json' + ], + ignorePatterns: [ + 'node_modules', + 'lib', + '.eslintrc.js', + 'plugins', + '**/*/__tests__', + 'jestSetup.ts' + ], + parserOptions: { + tsconfigRootDir: __dirname, + project: 'tsconfig.json', + projectFolderIgnoreList: [ + '/lib/' + ] + } +}; diff --git a/viewer-prototype/jest.config.json b/packages/react-components/jest.config.json similarity index 100% rename from viewer-prototype/jest.config.json rename to packages/react-components/jest.config.json diff --git a/viewer-prototype/jestSetup.ts b/packages/react-components/jestSetup.ts similarity index 100% rename from viewer-prototype/jestSetup.ts rename to packages/react-components/jestSetup.ts diff --git a/packages/react-components/package.json b/packages/react-components/package.json new file mode 100644 index 000000000..37ced0156 --- /dev/null +++ b/packages/react-components/package.json @@ -0,0 +1,66 @@ +{ + "name": "@trace-viewer/react-components", + "version": "0.0.0", + "description": "Trace Compass react components", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/theia-ide/theia-trace-extension" + }, + "files": [ + "lib", + "src" + ], + "dependencies": { + "@fortawesome/fontawesome-svg-core": "^1.2.17", + "@fortawesome/free-solid-svg-icons": "^5.8.1", + "@fortawesome/react-fontawesome": "^0.1.4", + "@trace-viewer/base": "0.0.0", + "ag-grid-community": "^20.2.0", + "ag-grid-react": "^20.2.0", + "chart.js": "^2.8.0", + "lodash": "^4.17.15", + "react-chartjs-2": "^2.7.6", + "react-grid-layout": "^1.1.0", + "react-modal": "^3.8.1", + "react-virtualized": "^9.21.0", + "semantic-ui-css": "^2.4.1", + "semantic-ui-react": "^0.86.0", + "timeline-chart": "next", + "tsp-typescript-client": "next" + }, + "devDependencies": { + "@testing-library/react": "^10.4.6", + "@types/chart.js": "^2.7.52", + "@types/enzyme": "^3.10.5", + "@types/enzyme-adapter-react-16": "^1.0.6", + "@types/jest": "^26.0.4", + "@types/lodash": "^4.14.142", + "@types/react-grid-layout": "^0.16.7", + "@types/react-modal": "^3.8.2", + "@types/react-test-renderer": "^16.9.2", + "@types/react-virtualized": "^9.21.1", + "@typescript-eslint/eslint-plugin": "^3.4.0", + "@typescript-eslint/parser": "^3.4.0", + "enzyme": "^3.11.0", + "enzyme-adapter-react-16": "^1.15.2", + "eslint": "^7.3.0", + "eslint-plugin-import": "^2.21.2", + "eslint-plugin-no-null": "^1.0.2", + "eslint-plugin-react": "^7.20.0", + "jest": "^26.1.0", + "react-test-renderer": "^16.13.1", + "rimraf": "latest", + "ts-jest": "^26.3.0", + "typescript": "latest" + }, + "scripts": { + "assets": "mkdir -p ./lib/style && cp -r ./src/style/* ./lib/style", + "build": "tsc && yarn run assets", + "clean": "rimraf lib", + "lint": "eslint .", + "prepare": "yarn clean && yarn build", + "test": "jest --config jest.config.json", + "watch": "tsc -w" + } +} diff --git a/viewer-prototype/src/browser/trace-viewer/components/abstract-output-component.tsx b/packages/react-components/src/components/abstract-output-component.tsx similarity index 95% rename from viewer-prototype/src/browser/trace-viewer/components/abstract-output-component.tsx rename to packages/react-components/src/components/abstract-output-component.tsx index 5e21992b4..5286a8055 100644 --- a/viewer-prototype/src/browser/trace-viewer/components/abstract-output-component.tsx +++ b/packages/react-components/src/components/abstract-output-component.tsx @@ -4,7 +4,7 @@ import { TspClient } from 'tsp-typescript-client/lib/protocol/tsp-client'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faTimes } from '@fortawesome/free-solid-svg-icons'; import { TimeGraphUnitController } from 'timeline-chart/lib/time-graph-unit-controller'; -import { TimeRange } from '../../../common/utils/time-range'; +import { TimeRange } from '@trace-viewer/base/lib/utils/time-range'; import { OutputComponentStyle } from './utils/output-component-style'; import { OutputStyleModel } from 'tsp-typescript-client/lib/models/styles'; @@ -46,10 +46,11 @@ export abstract class AbstractOutputComponent

; } - renderTitleBar(): React.ReactNode { + private renderTitleBar(): React.ReactNode { const outputName = this.props.outputDescriptor.name; return