diff --git a/core/amber/src/main/scala/edu/uci/ics/texera/web/service/JobResultService.scala b/core/amber/src/main/scala/edu/uci/ics/texera/web/service/JobResultService.scala
index a5b8168b3ae..d0c367faa69 100644
--- a/core/amber/src/main/scala/edu/uci/ics/texera/web/service/JobResultService.scala
+++ b/core/amber/src/main/scala/edu/uci/ics/texera/web/service/JobResultService.scala
@@ -31,7 +31,7 @@ import scala.concurrent.duration.DurationInt
object JobResultService {
- val defaultPageSize: Int = 10
+ val defaultPageSize: Int = 5
// convert Tuple from engine's format to JSON format
def webDataFromTuple(
diff --git a/core/new-gui/angular.json b/core/new-gui/angular.json
index 935108a0e26..438c4490ba1 100644
--- a/core/new-gui/angular.json
+++ b/core/new-gui/angular.json
@@ -29,6 +29,7 @@
}
],
"styles": [
+ "node_modules/jquery-contextmenu/dist/jquery.contextMenu.min.css",
"node_modules/ng-zorro-antd/ng-zorro-antd.min.css",
"node_modules/jointjs/css/layout.css",
"node_modules/jointjs/css/themes/material.css",
@@ -37,6 +38,9 @@
"src/styles.scss"
],
"scripts": [
+ "node_modules/jquery/dist/jquery.min.js",
+ "node_modules/jquery-contextmenu/dist/jquery.contextMenu.min.js",
+ "node_modules/jquery-contextmenu/dist/jquery.ui.position.min.js",
"./node_modules/ngx-monaco-editor/assets/monaco/vs/loader.js"
],
"allowedCommonJsDependencies": [
diff --git a/core/new-gui/package.json b/core/new-gui/package.json
index 5df270c6fc7..8a7c423fbbd 100644
--- a/core/new-gui/package.json
+++ b/core/new-gui/package.json
@@ -61,6 +61,7 @@
"jointjs": "~3.5.4",
"jquery": "~3.6.0",
"jquery-ui-dist": "~1.13.1",
+ "jquery-contextmenu": "^2.9.2",
"js-abbreviation-number": "~1.4.0",
"jwt-decode": "~3.1.2",
"lodash-es": "~4.17.21",
@@ -109,6 +110,7 @@
"@types/jasminewd2": "~2.0.10",
"@types/jquery": "~3.5.14",
"@types/jqueryui": "1.12.10",
+ "@types/jquery.contextmenu": "1.7.35",
"@types/json-schema": "~7.0.9",
"@types/lodash": "~4.14.179",
"@types/uuid": "~8.3.4",
diff --git a/core/new-gui/src/app/workspace/component/result-panel/result-panel.component.html b/core/new-gui/src/app/workspace/component/result-panel/result-panel.component.html
index 88ba14308f0..406b84d9cce 100644
--- a/core/new-gui/src/app/workspace/component/result-panel/result-panel.component.html
+++ b/core/new-gui/src/app/workspace/component/result-panel/result-panel.component.html
@@ -1,5 +1,13 @@
+
+
+
+
No results available to display.
+
+
+
+
+ Empty result set.
+
-
-
-
- | {{ column.header }} |
-
-
-
-
- |
- {{ column.getCell(row) }}
- |
-
-
-
+
+
+
+
+ |
+ {{ column.header }}
+ |
+
+
+
+
+ |
+ {{ column.getCell(row) }}
+ |
+
+
+
+
diff --git a/core/new-gui/src/app/workspace/component/result-panel/result-table-frame/result-table-frame.component.scss b/core/new-gui/src/app/workspace/component/result-panel/result-table-frame/result-table-frame.component.scss
index e69de29bb2d..2fa38e9fea1 100644
--- a/core/new-gui/src/app/workspace/component/result-panel/result-table-frame/result-table-frame.component.scss
+++ b/core/new-gui/src/app/workspace/component/result-panel/result-table-frame/result-table-frame.component.scss
@@ -0,0 +1,33 @@
+:host ::ng-deep .ant-table-wrapper {
+ width: 500px;
+}
+
+:host ::ng-deep .ant-table-pagination.ant-pagination {
+ margin: 10px;
+}
+
+:host ::ng-deep .ant-table-pagination-right {
+ justify-content: left;
+}
+:host ::ng-deep .ant-table-header {
+ width: 200vw;
+}
+
+:host ::ng-deep .ant-table-body {
+ width: 200vw;
+}
+
+div.scroll {
+ margin: 0px, 0px;
+ padding: 0px;
+ width: 100%;
+ overflow-x: scroll;
+}
+
+td.data-size {
+ font-size: 9px;
+}
+
+th.header-size {
+ font-size: 10px;
+}
diff --git a/core/new-gui/src/app/workspace/component/workflow-editor/workflow-editor.component.ts b/core/new-gui/src/app/workspace/component/workflow-editor/workflow-editor.component.ts
index c4f3ed485c6..e08bbe14c90 100644
--- a/core/new-gui/src/app/workspace/component/workflow-editor/workflow-editor.component.ts
+++ b/core/new-gui/src/app/workspace/component/workflow-editor/workflow-editor.component.ts
@@ -75,6 +75,7 @@ export const WORKFLOW_EDITOR_JOINTJS_ID = "texera-workflow-editor-jointjs-body-i
* @author Henry Chen
*
*/
+
@UntilDestroy()
@Component({
selector: "texera-workflow-editor",
@@ -160,6 +161,8 @@ export class WorkflowEditorComponent implements AfterViewInit, OnDestroy {
this.handleOperatorSuggestionHighlightEvent();
this.dragDropService.registerWorkflowEditorDrop(this.WORKFLOW_EDITOR_JOINTJS_ID);
+ this.rightClickContextMenu();
+
this.handleElementDelete();
this.handleElementSelectAll();
this.handleElementCopy();
@@ -602,6 +605,104 @@ export class WorkflowEditorComponent implements AfterViewInit, OnDestroy {
});
}
+ private rightClickContextMenu(): void {
+ const highlightedOperatorIDs = this.workflowActionService.getJointGraphWrapper().getCurrentHighlightedOperatorIDs();
+
+ const highlightedGroupIDs = this.workflowActionService.getJointGraphWrapper().getCurrentHighlightedGroupIDs();
+
+ var isVisible = function (key: any, opt: { $trigger: { nodeName: string } }) {
+ if (highlightedOperatorIDs.length > 0 || highlightedGroupIDs.length > 0) {
+ return true;
+ } else {
+ return false;
+ }
+ };
+
+ jQuery(() => {
+ jQuery.contextMenu({
+ selector: ".texera-workspace-workflow-editor-body",
+
+ callback: (key: any, options: any) => {
+ if (key == "copy") {
+ this.clearCopiedElements();
+ this.saveHighlighedElements();
+ } else if (key == "paste") {
+ if (this.copiedOperators.size > 0 || this.copiedGroups.size > 0) {
+ const operatorsAndPositions: { op: OperatorPredicate; pos: Point }[] = [];
+ const links: OperatorLink[] = [];
+ const groups: Group[] = [];
+ const positions: Point[] = [];
+
+ this.copiedOperators = new Map(
+ Array.from(this.copiedOperators).sort((first, second) => first[1].layer - second[1].layer)
+ );
+
+ this.copiedOperators.forEach((copiedOperator: { operator: any }, operatorID: any) => {
+ const newOperator = this.copyOperator(copiedOperator.operator);
+ const newOperatorPosition = this.calcOperatorPosition(newOperator.operatorID, operatorID, positions);
+ operatorsAndPositions.push({
+ op: newOperator,
+ pos: newOperatorPosition,
+ });
+ positions.push(newOperatorPosition);
+ });
+
+ this.copiedGroups.forEach((copiedGroup: { group: any; position: any }, groupID: any) => {
+ const newGroup = this.copyGroup(copiedGroup.group);
+
+ const oldPosition = copiedGroup.position;
+ const newPosition = this.calcGroupPosition(newGroup.groupID, groupID, positions);
+ positions.push(newPosition);
+
+ const delta = {
+ x: newPosition.x - oldPosition.x,
+ y: newPosition.y - oldPosition.y,
+ };
+
+ newGroup.operators.forEach(
+ (operatorInfo: { position: { x: number; y: number }; operator: any }, operatorID: any) => {
+ operatorInfo.position.x += delta.x;
+ operatorInfo.position.y += delta.x;
+
+ operatorsAndPositions.push({
+ op: operatorInfo.operator,
+ pos: operatorInfo.position,
+ });
+ }
+ );
+
+ newGroup.links.forEach((linkInfo: { link: OperatorLink }, operatorID: any) => {
+ links.push(linkInfo.link);
+ });
+
+ groups.push(newGroup);
+ });
+
+ this.workflowActionService.addOperatorsAndLinks(operatorsAndPositions, links, groups, new Map());
+ }
+ } else if (key == "cut") {
+ this.clearCopiedElements();
+ this.saveHighlighedElements();
+ this.workflowActionService.deleteOperatorsAndLinks(highlightedOperatorIDs, [], highlightedGroupIDs);
+ } else if (key == "delete") {
+ this.workflowActionService.deleteOperatorsAndLinks(highlightedOperatorIDs, [], highlightedGroupIDs);
+ }
+ if (highlightedOperatorIDs.length == 0 || highlightedGroupIDs.length == 0) {
+ }
+ //var m = "clicked: " + key;
+ //alert(m); '
+ return true;
+ },
+ items: {
+ copy: { name: "Copy", icon: "copy", visible: isVisible },
+ paste: { name: "Paste", icon: "paste" },
+ cut: { name: "Cut", icon: "cut", visible: isVisible },
+ delete: { name: "Delete", icon: "delete", visible: isVisible },
+ },
+ });
+ });
+ }
+
private handleHighlightMouseDBClickInput(): void {
fromJointPaperEvent(this.getJointPaper(), "cell:pointerdblclick")
.pipe(untilDestroyed(this))
@@ -854,6 +955,7 @@ export class WorkflowEditorComponent implements AfterViewInit, OnDestroy {
}
/**
+ *
* Handles the event where the Delete button is clicked for a Link,
* and call workflowAction to delete the corresponding link.
*
diff --git a/core/new-gui/src/app/workspace/component/workspace.component.scss b/core/new-gui/src/app/workspace/component/workspace.component.scss
index d9e167c63f3..4c754e36b17 100644
--- a/core/new-gui/src/app/workspace/component/workspace.component.scss
+++ b/core/new-gui/src/app/workspace/component/workspace.component.scss
@@ -46,10 +46,10 @@
grid-template-columns: 200px auto 350px;
grid-template-rows:
var(--header-height)
- calc((100% - var(--header-height) - var(--resultbar-height)) * 0.6)
+ calc((100% - var(--header-height) - var(--resultbar-height)) * 0.4)
0px
var(--resultbar-height)
- calc((100% - var(--header-height) - var(--resultbar-height)) * 0.4);
+ calc((100% - var(--header-height) - var(--resultbar-height)) * 0.6);
position: relative;
}
@@ -129,8 +129,7 @@
.texera-result-panel-grid-container {
grid-column: 2/3;
grid-row: 5/6;
- overflow: auto;
- transition: height 1s;
+ transition: height 2s;
}
.texera-result-panel-toggle-grid-container {
diff --git a/core/new-gui/src/app/workspace/service/workflow-result/workflow-result.service.ts b/core/new-gui/src/app/workspace/service/workflow-result/workflow-result.service.ts
index df1f27b9862..5befdc46ffb 100644
--- a/core/new-gui/src/app/workspace/service/workflow-result/workflow-result.service.ts
+++ b/core/new-gui/src/app/workspace/service/workflow-result/workflow-result.service.ts
@@ -13,9 +13,9 @@ import { Observable, of, Subject } from "rxjs";
import { v4 as uuid } from "uuid";
import { ChartType } from "../../types/visualization.interface";
-export const DEFAULT_PAGE_SIZE = 10;
+export const DEFAULT_PAGE_SIZE = 5;
-/**
+/*
* WorkflowResultService manages the result data of a workflow execution.
*/
@Injectable({
diff --git a/core/new-gui/src/environments/environment.default.ts b/core/new-gui/src/environments/environment.default.ts
index ac9a51ba010..c42c40b6880 100644
--- a/core/new-gui/src/environments/environment.default.ts
+++ b/core/new-gui/src/environments/environment.default.ts
@@ -14,7 +14,7 @@ export const defaultEnvironment = {
* whether fetching available source tables is enabled
* see SourceTablesService for details
*/
- sourceTableEnabled: false,
+ sourceTableEnabled: true,
/**
* whether operator schema propagation and autocomplete feature is enabled,
* see SchemaPropagationService for details
@@ -36,7 +36,7 @@ export const defaultEnvironment = {
/**
* whether user system is enabled
*/
- userSystemEnabled: false,
+ userSystemEnabled: true,
/**
* whether user preset feature is enabled, requires user system to be enabled
diff --git a/core/new-gui/src/tsconfig.app.json b/core/new-gui/src/tsconfig.app.json
index 26727d8c999..4a93fd74166 100644
--- a/core/new-gui/src/tsconfig.app.json
+++ b/core/new-gui/src/tsconfig.app.json
@@ -3,7 +3,7 @@
"compilerOptions": {
"outDir": "../out-tsc/app",
// include jqueryui type definition here because Angular does not include it if it's not imported
- "types": ["jqueryui", "gapi.auth2", "gapi"]
+ "types": ["jqueryui", "jquery.contextmenu", "gapi.auth2", "gapi"]
},
// ask Angular to check template error during the compilation process
"angularCompilerOptions": {
diff --git a/core/new-gui/yarn.lock b/core/new-gui/yarn.lock
index 06ae4a46b44..1418850c329 100644
--- a/core/new-gui/yarn.lock
+++ b/core/new-gui/yarn.lock
@@ -3339,6 +3339,13 @@
dependencies:
"@types/jasmine" "*"
+"@types/jquery.contextmenu@1.7.35":
+ version "1.7.35"
+ resolved "https://registry.yarnpkg.com/@types/jquery.contextmenu/-/jquery.contextmenu-1.7.35.tgz#f7fc43f0c5529c48bd687ef5aaf858a3090cca2f"
+ integrity sha512-0KmOOYgU6ySqOcglRYxFz8KyoFyOeN5YJ0ykg8IL1SJmmLTkeplVixqspcSmFtpLRORPl46a893An5YbuLr6rw==
+ dependencies:
+ "@types/jquery" "*"
+
"@types/jquery@*", "@types/jquery@~3.5.14":
version "3.5.14"
resolved "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.14.tgz"
@@ -8902,6 +8909,13 @@ jointjs@~3.5.4:
jquery "~3.6.0"
lodash "~4.17.21"
+jquery-contextmenu@^2.9.2:
+ version "2.9.2"
+ resolved "https://registry.yarnpkg.com/jquery-contextmenu/-/jquery-contextmenu-2.9.2.tgz#f9dc362e45871dda2e50fa45de2243e917446ced"
+ integrity sha512-6S6sH/08owDStC/7zNwcN366yR0ydX6PmMB0RnjLRQOp7Nc/rqwEHglshfHrrw2kdTev97GXwRXrayDUmToIOw==
+ dependencies:
+ jquery "^3.5.0"
+
jquery-ui-dist@~1.13.1:
version "1.13.1"
resolved "https://registry.npmjs.org/jquery-ui-dist/-/jquery-ui-dist-1.13.1.tgz"
@@ -8909,7 +8923,7 @@ jquery-ui-dist@~1.13.1:
dependencies:
jquery ">=1.8.0 <4.0.0"
-"jquery@>=1.8.0 <4.0.0", jquery@~3.6.0:
+"jquery@>=1.8.0 <4.0.0", jquery@^3.5.0, jquery@~3.6.0:
version "3.6.0"
resolved "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz"
integrity sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw==