http://git-wip-us.apache.org/repos/asf/asterixdb/blob/a7e8dbe3/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/metadata/input-metadata.component.scss ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/metadata/input-metadata.component.scss b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/metadata/input-metadata.component.scss new file mode 100755 index 0000000..b98080c --- /dev/null +++ b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/metadata/input-metadata.component.scss @@ -0,0 +1,78 @@ +/* +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +$query-spacing-unit: 8px; + +.input-card { + display: flex; + flex-flow: column; + padding: 0; + margin: 0 auto; + margin-top: $query-spacing-unit; + height: 250px; + width: 95%; + overflow: hidden; +} + +.toolbar-icon { + padding: 0 14px 0 0; + margin: 0; +} + +.spacer { + flex: 1 1 auto; +} + +.input-selector { + max-height: 42px; + min-height: 42px; + justify-content: center; + //align-items: center; + font-size: 0.80rem; + font-weight: 500; + background-color: white; + border: 1px solid rgba(54, 147, 209, 0.87); +} + +.content-area { + position: relative; + color: hsla(0,0%,0%,.87); + height: 120px; + padding: 0; + margin: $query-spacing-unit * 2; + overflow: none; +} + +.codemirror-container { + width: 100%; + height: 100%; + padding: 0; + margin: 0; + font-size: 14px; + line-height: 1.8; +} + +.actions { + border-top: 1px solid rgba(0, 0, 0, 0.1); + color: rgba(54, 147, 209, 0.87); + padding: $query-spacing-unit; + margin: 0; +} + +.error-message { + border-bottom: 1px solid rgba(0, 0, 0, 0.1); + color: rgba(209, 54, 54, 0.87); + padding-top: 10px; + padding-left: 20px; + text-overflow: ellipsis; +} \ No newline at end of file
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/a7e8dbe3/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/metadata/input-metadata.component.ts ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/metadata/input-metadata.component.ts b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/metadata/input-metadata.component.ts new file mode 100755 index 0000000..06b9375 --- /dev/null +++ b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/metadata/input-metadata.component.ts @@ -0,0 +1,111 @@ +/* +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +import { Component, ViewChild, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core'; +import { Observable } from 'rxjs/Observable'; +import { Store } from '@ngrx/store'; +import * as sqlQueryActions from '../../shared/actions/query.actions' +import * as dataverseActions from '../../shared/actions/dataverse.actions' +import * as datasetActions from '../../shared/actions/dataset.actions' +import * as datatypeActions from '../../shared/actions/datatype.actions' +import * as indexActions from '../../shared/actions/index.actions' + + +import * as CodeMirror from 'codemirror'; + +/* + * Query metadata component + * has editor (codemirror) for writing some query + */ +@Component({ + moduleId: module.id, + selector: 'awc-query-metadata', + templateUrl:'input-metadata.component.html', + styleUrls: ['input-metadata.component.scss'], +}) + +export class InputQueryMetadataComponent { + private dataverses$: Observable<any>; + private datatypes$: Observable<any>; + private datasets$: Observable<any>; + private indexes$: Observable<any>; + dataverses = []; + datatypes = []; + datasets = []; + indexes = []; + queryMetadataString: string = ""; + loaded$: Observable<any>; + errorMessage: string = ""; + + /** + * Initialize codemirror + */ + codemirrorMetadataConfig = { mode: "asterix", + //lineNumbers: true, + lineWrapping: true, + showCursorWhenSelecting: true, + autofocus: true + }; + + constructor(private store: Store<any>, private changeDetector: ChangeDetectorRef) { + this.store.select("sqlMetadataQuery").subscribe((data: any) => { + if (data.success === false){ + if (data.sqlQueryMetadataError.errors){ + this.errorMessage = "ERROR: " + data.sqlQueryMetadataError.errors[0].msg + this.changeDetector.detectChanges(); + } + } else { + this.errorMessage = "SUCCEED"; + + // Refresh the tables automatically + let stringQuery = data.sqlQueryMetadataString; + stringQuery = stringQuery.toUpperCase(); + + if (stringQuery.includes("CREATE DATAVERSE") || stringQuery.includes("DROP DATAVERSE") ){ + this.store.dispatch(new dataverseActions.SelectDataverses('-')); + } + else if (stringQuery.includes("CREATE DATASET") || stringQuery.includes("DROP DATASET")){ + this.store.dispatch(new datasetActions.SelectDatasets('-')); + } + else if (stringQuery.includes("CREATE TYPE") || stringQuery.includes("DROP TYPE")){ + this.store.dispatch(new datatypeActions.SelectDatatypes('-')); + } + else if (stringQuery.includes("CREATE INDEX") || stringQuery.includes("DROP INDEX")){ + this.store.dispatch(new indexActions.SelectIndexes('-')); + } + + this.changeDetector.detectChanges(); + } + + }) + } + + getQueryResults(queryMetadataString: string) { + this.store.dispatch(new sqlQueryActions.ExecuteMetadataQuery(queryMetadataString)); + } + + executeQuery() { + this.getQueryResults(this.queryMetadataString.replace(/\n/g, " ")); + // Component View Refresh + + } + + onClick() { + this.errorMessage = ""; + } + + /* Cleans up error message */ + cleanUp() { + this.errorMessage = ""; + } +} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/a7e8dbe3/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/metadata/metadata-container.component.html ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/metadata/metadata-container.component.html b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/metadata/metadata-container.component.html new file mode 100755 index 0000000..a2f3a73 --- /dev/null +++ b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/metadata/metadata-container.component.html @@ -0,0 +1,36 @@ +<!--/* +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ --> +<mat-tab-group class="metadata-menu" (selectedTabChange)="tabChange()"> + <mat-tab label="DATAVERSES" class="submenu"> + <div class="dataverses"> + <awc-dataverses #dataverses [message]="message" class="dataverses"></awc-dataverses> + </div> + </mat-tab> + <mat-tab label="DATASETS"> + <div class="datasets"> + <awc-datasets #datasets [message]="message" class="datasets"></awc-datasets> + </div> + </mat-tab> + <mat-tab label="DATATYPES"> + <div class="datatypes"> + <awc-datatypes #datatypes [message]="message" class="datatypes"></awc-datatypes> + </div> + </mat-tab> + <mat-tab label="INDEXES" class="indexes"> + <div class="indexes"> + <awc-indexes #indexes [message]="message" class="indexes"></awc-indexes> + </div> + </mat-tab> +</mat-tab-group> + http://git-wip-us.apache.org/repos/asf/asterixdb/blob/a7e8dbe3/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/metadata/metadata-container.component.scss ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/metadata/metadata-container.component.scss b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/metadata/metadata-container.component.scss new file mode 100755 index 0000000..3857d74 --- /dev/null +++ b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/metadata/metadata-container.component.scss @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + .dataverses { + margin: 0; + min-height: 750px; + max-height: 750px; + width: 100%; + overflow: hidden; + } + +.datasets { + margin: 0; + min-height: 750px; + max-height: 750px; + width: 100%; + overflow: hidden; +} + +.datatypes { + margin: 0; + min-height: 750px; + max-height: 750px; + width: 100%; + overflow: hidden; +} + +.indexes { + margin: 0; + min-height: 750px; + max-height: 750px; + width: 100%; + overflow: hidden; +} + +.metadata-menu { + /deep/ .mat-tab-label { + font-size: 0.80rem !important; + font-weight: 500 !important; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/asterixdb/blob/a7e8dbe3/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/metadata/metadata-container.component.ts ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/metadata/metadata-container.component.ts b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/metadata/metadata-container.component.ts new file mode 100755 index 0000000..c8382cf --- /dev/null +++ b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/metadata/metadata-container.component.ts @@ -0,0 +1,41 @@ +/* +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +import { Component, ViewChild } from '@angular/core'; + +@Component({ + moduleId: module.id, + selector: 'awc-metadata-container', + templateUrl: 'metadata-container.component.html', + styleUrls: ['metadata-container.component.scss'] +}) + +export class MetadataContainerComponent { + + @ViewChild('dataverses') dataverses ; + @ViewChild('datasets') datasets ; + @ViewChild('datatypes') datatypes ; + @ViewChild('indexes') indexes ; + message = ""; + + constructor() {} + + tabChange() { + this.indexes.cleanUp(); + this.datasets.cleanUp(); + this.datatypes.cleanUp(); + this.dataverses.cleanUp(); + } + + +} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/a7e8dbe3/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/codemirror.component.scss ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/codemirror.component.scss b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/codemirror.component.scss new file mode 100755 index 0000000..ba795c2 --- /dev/null +++ b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/codemirror.component.scss @@ -0,0 +1,23 @@ +/* +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +/* -- Place holder for future expansion --> */ +code { + width: 100%; + height: 100%; + padding: 10%; + margin: 0; + overflow-wrap: break-word; + word-break: break-all; + background-color: pink; +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/asterixdb/blob/a7e8dbe3/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/codemirror.component.ts ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/codemirror.component.ts b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/codemirror.component.ts new file mode 100755 index 0000000..91b711d --- /dev/null +++ b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/codemirror.component.ts @@ -0,0 +1,237 @@ +/* +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +/** + * Integrating codemirror (using ng2-codemirror) with our application + * + * component from "https://runkit.com/npm/ng2-codemirror" + * "https://www.npmjs.com/package/ng2-codemirror" + * copy component from /src/codemirror.component.ts + * and modified for custom mode (asterix aql, sql++ code hilighting) + * + * therefore, actually we don't need to "npm install ng2-codemirror" + * + * Because on the outside of this component, + * It was hard to access the codemirror instance that 'ng-codemirror' use + * So, we copied the component in our application and modified it + * + * 'codemirror.js(^5.23.0)' is included in the 'index.html' + * And in this component(codemirror.component.ts) + * add statement like "declare var CodeMirror: any;" + * + * I don't know whether this is right way + * + * ref 1) usage : https://embed.plnkr.co/8e9gxss9u10VeFrv29Zt/ + * ref 2) custom mode : http://jsfiddle.net/TcqAf/99/ + * ref 3) integrating : http://stackoverflow.com/questions/37092142/integrating-codemirror-with-angular2-typescript + * ref 3) integrating : https://medium.com/@s_eschweiler/using-external-libraries-with-angular-2-87e06db8e5d1#.8ok74uvwg + */ + import { + Component, + Input, + Output, + ElementRef, + ViewChild, + EventEmitter, + forwardRef, + AfterViewInit, + OnDestroy + } from '@angular/core'; + import { NG_VALUE_ACCESSOR } from '@angular/forms'; + import * as CodeMirror from 'codemirror'; + +/** + * CodeMirror component + * Usage : + * <codemirror [(ngModel)]="data" [config]="{...}"></codemirror> + */ +@Component({ + moduleId: module.id, + selector: 'codemirror', + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => CodemirrorComponent), + multi: true + } + ], + styleUrls: ['codemirror.component.scss'], + template: `<textarea class="code" #host></textarea>`,//, +}) + +export class CodemirrorComponent implements AfterViewInit, OnDestroy { + @Input() config; + @Output() change = new EventEmitter(); + @Output() focus = new EventEmitter(); + @Output() blur = new EventEmitter(); + @Output() instance = null; + @ViewChild('host') host; + _value = ''; + + /** + * Constructor + */ + constructor(){ + /** + * Custom mode for AsterixDB + */ + CodeMirror.defineMode("asterix", function(){ + var KEYWORD_MATCH = [ + // AQL + "drop", "dataverse", "dataset", + "if", "exists", "create", + "use", "type", "as", "closed", + "primary", "key", "hints", "cardinality", + "index", "on", "btree", "rtree", "keyword", + "for", "in", "Metadata", "Dataset", + "return", "Index", "load", "using", "localfs", "path", "format", + // Query (not perfect) + "from", "in", "with", "group", "by", "select", + "let", "where", "order", "asc", "desc", "limit", + "keeping", "offset", "distinct", "or", "and", + // Built in functions (TODO) + // Built in functions (TODO) + // Built in functions (TODO) + // Asterix Data Model + // Primitive type + "boolean", + "tinyint", "smallint", "integer", "bigint", + "float", "double", + "string", + "binary", "hex", "base64", + "point", "line", "rectangle", "circle", "polygon", + "date", "time", "datetime", "duration", "interval", "uuid", + // Incomplete information type + "null", "missing", + // Derived type + // object {}, array [], multiset {{}} + // SQL++ + "DROP", "DATAVERSE", "IF", "EXISTS", "CREATE", "USE", "TYPE", "AS", "DATASET", "PRIMARY", "KEY", + "INDEX", "SELECT", "VALUE", "INSERT", "INTO", "FROM", "WHERE", "AND", "SOME", "IN", "SATISFIES", "IS", "UNKNOWN", "NOT", "EVERY", + "GROUP", "BY", "ORDER", "DESC", "LIMIT", "OR", "SET", "DELETE", "LOAD", "USING", + ]; + + //"(", ")","{{", "}}", "[", "]", "{", "}", ";", ",", ":","?", "=", + var VAR_MATCH = /[$][a-zA-Z]+(\d*)/; + var DOT_MATCH = /[.](\S)*/; + var DOUBLE_QUOTE_MATCH = /["].*["]/; + var SINGLE_QUOTE_MATCH = /['].*[']/; + var BREAK_POINT = /(\s)/; + + return { + startState: function() {return {inString: false};}, + token: function(stream, state) { + if (state.newLine == undefined)state.newLine = true; + + //match variable reference + if (stream.match(VAR_MATCH)) { + return "variable"; + } + + if (stream.match(DOT_MATCH)) { + return "dot-variable"; + } + + //string variable match + if (stream.match(DOUBLE_QUOTE_MATCH)) { + return "string"; + } + if (stream.match(SINGLE_QUOTE_MATCH)) { + return "string"; + } + + //keyword match + for (var i in KEYWORD_MATCH){ + if (state.newLine && stream.match(KEYWORD_MATCH[i])){ + return "keyword"; + } + } + + if (stream.peek() === " " || stream.peek() === null){ + state.newLine = true; + }else{ + state.newLine = false; + } + stream.next(); + return null; + } + }; + }); + } + + get value() { return this._value; }; + + @Input() set value(v) { + if (v !== this._value) { + this._value = v; + this.onChange(v); + } + } + + /** + * On component destroy + */ + ngOnDestroy() {} + + /** + * On component view init + */ + ngAfterViewInit() { + this.config = this.config || {}; + this.codemirrorInit(this.config); + } + + /** + * Initialize codemirror + */ + codemirrorInit(config){ + this.instance = CodeMirror.fromTextArea(this.host.nativeElement, config); + this.instance.setValue(this._value); + this.instance.setSize(null, 90); + this.instance.on('change', () => { + this.updateValue(this.instance.getValue()); + }); + + this.instance.on('focus', () => { + this.focus.emit(); + }); + + this.instance.on('blur', () => { + this.blur.emit(); + }); + } + + /** + * Value update process + */ + updateValue(value){ + this.value = value; + this.onTouched(); + this.change.emit(value); + } + + /** + * Implements ControlValueAccessor + */ + writeValue(value){ + this._value = value || ''; + if (this.instance) { + this.instance.setValue(this._value); + } + } + + onChange(_) {} + onTouched() {} + registerOnChange(fn){this.onChange = fn;} + registerOnTouched(fn){this.onTouched = fn;} +} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/a7e8dbe3/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/input.component.html ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/input.component.html b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/input.component.html new file mode 100755 index 0000000..2eec6b7 --- /dev/null +++ b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/input.component.html @@ -0,0 +1,28 @@ +<!--/* +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ --> +<mat-card class="input-card"> + <mat-toolbar color="primary" class="input-selector"> + <mat-icon class="toolbar-icon">menu</mat-icon> + <span>INPUT: SQL++</span> + <span class="spacer"></span> + </mat-toolbar> + <mat-card-content class="content-area"> + <div class="codemirror-container"> + <codemirror class="code" #host [(ngModel)]="queryString" [config]="codemirrorConfig"></codemirror> + </div> + </mat-card-content> + <mat-card-actions class="actions"> + <button mat-button class="query-button" (click)="onClick()">RUN</button> + </mat-card-actions> +</mat-card> http://git-wip-us.apache.org/repos/asf/asterixdb/blob/a7e8dbe3/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/input.component.scss ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/input.component.scss b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/input.component.scss new file mode 100755 index 0000000..437ff58 --- /dev/null +++ b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/input.component.scss @@ -0,0 +1,82 @@ +/* +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +$query-spacing-unit: 5px; + +.input-card { + display: flex; + flex-flow: column; + padding: 0; + margin: ($query-spacing-unit * 2); + height: 200px; + width: 100%; + min-height: 150px; + + //background-color: orange; +} + +.toolbar-icon { + padding: 0 14px 0 0; + margin: 0; +} + +.spacer { + flex: 1 1 auto; +} + +.input-selector { + max-height: 42px; + min-height: 42px; + justify-content: center; + //align-items: center; + font-size: 0.80rem; + font-weight: 500; + background-color: white; + border: 1px solid rgba(54, 147, 209, 0.87); +} + +.content-area { + //position: relative; + color: hsla(0,0%,0%,.87); + //height: 102px; + padding: 0; + margin: 0; + overflow: none; + } + +.codemirror-container { + width: 95%; + height: 98%; + padding: 0; // ($query-spacing-unit * 2); + margin: 0 auto; + font-size: 14px; + //letter-spacing: 3px; + line-height: 1.8; + background-color: red; +} + +//.code { +// width: 100%; +// height: 100%; +// padding: 0; +// margin: 0; +// overflow-wrap: break-word; +// word-break: break-all; +//} + +.actions { + border-top: 1px solid rgba(0, 0, 0, 0.1); + color: rgba(54, 147, 209, 0.87); + padding-left: $query-spacing-unit; + margin: 0; +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/asterixdb/blob/a7e8dbe3/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/input.component.ts ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/input.component.ts b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/input.component.ts new file mode 100755 index 0000000..9be9bd9 --- /dev/null +++ b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/input.component.ts @@ -0,0 +1,90 @@ +/* +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +import { Component, ViewChild } from '@angular/core'; +import { Observable } from 'rxjs/Observable'; +import { Store } from '@ngrx/store'; +import * as sqlQueryActions from '../../shared/actions/query.actions' +import * as CodeMirror from 'codemirror'; + +/* + * query component + * has editor (codemirror) for writing some query + */ +@Component({ + moduleId: module.id, + selector: 'awc-query', + templateUrl:'input.component.html', + styleUrls: ['input.component.scss'] +}) + +export class InputQueryComponent { + private guideSelectedDataset$: Observable<any>; + private dataverses$: Observable<any>; + private datatypes$: Observable<any>; + private datasets$: Observable<any>; + private indexes$: Observable<any>; + dataverses = []; + datatypes = []; + datasets = []; + indexes = []; + datasetName = ""; + dataverseName = ""; + queryString: string = "" + + /* Codemirror configuration + */ + codemirrorConfig = { mode: "asterix", + lineWrapping: true, + showCursorWhenSelecting: true, + autofocus: true + } ; + + loaded$: Observable<any> + + constructor(private store: Store<any>) { + // Watching for guide selected or clicked dataset + this.guideSelectedDataset$ = this.store.select(s => s.dataset.guideSelectsDataset); + this.guideSelectedDataset$.subscribe((data: any) => { + if (data) { + this.datasetName = data; + for (let i = 0; i < this.datasets.length; i++) { + if ( this.datasets[i]['DatasetName'] === this.datasetName ) { + this.dataverseName = this.datasets[i]['DataverseName']; + } + } + this.queryString = "USE " + this.dataverseName + "; SELECT * FROM " + this.datasetName; + } + }); + + // Watching for Datatypes + this.dataverses$ = this.store.select(s => s.dataverse.dataverses.results); + this.dataverses$.subscribe((data: any[]) => { + this.dataverses = data; + }); + + // Watching for Datasets + this.datasets$ = this.store.select(s => s.dataset.datasets.results); + this.datasets$.subscribe((data: any[]) => { + this.datasets = data; + }); + } + + getQueryResults(queryString: string) { + this.store.dispatch(new sqlQueryActions.ExecuteQuery(queryString)); + } + + onClick() { + this.getQueryResults(this.queryString.replace(/\n/g, " ")); + } +} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/a7e8dbe3/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/metadata.component.html ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/metadata.component.html b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/metadata.component.html new file mode 100755 index 0000000..4641426 --- /dev/null +++ b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/metadata.component.html @@ -0,0 +1,44 @@ +<!--/* +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ --> +<mat-card class="metadata-card"> + <mat-toolbar color="primary" class="metadata-selector"> + <mat-icon class="example-icon">menu</mat-icon> + <span>METADATA GUIDE</span> + <span class="spacer"></span> + </mat-toolbar> + <div class="metadata-content-area"> + <div class="metadata-tree"> + <div class="metadata-all"> + <p-tree [style]="{'width':'100%', 'border': 'none', 'font-family': 'Roboto Mono', 'font-size': '0.80rem', + 'font-weight': '500'}" selectionMode="single" [value]="nodesAll" (onNodeSelect)="nodeSelectAll($event)"></p-tree> + </div> + <div class="metadata-datasets"> + <p-tree [style]="{'width':'100%', 'border': 'none', 'font-family': 'Roboto Mono', 'font-size': '0.80rem', + 'font-weight': '500'}" selectionMode="single" [value]="nodesDatasets" (onNodeSelect)="nodeSelectDataset($event)"></p-tree> + </div> + <div class="metadata-datatypes"> + <p-tree [style]="{'width':'100%', 'border': 'none', 'font-family': 'Roboto Mono', 'font-size': '0.80rem', + 'font-weight': '500'}" selectionMode="single" [value]="nodesDatatypes"></p-tree> + </div> + <div class="metadata-index"> + <p-tree [style]="{'width':'100%', 'border': 'none', 'font-family': 'Roboto Mono', 'font-size': '0.80rem', + 'font-weight': '500'}" selectionMode="single" [value]="nodesIndexes"></p-tree> + </div> + + </div> + </div> + <!--<mat-card-actions class="actions"> + <button mat-button class="refresh-button" (click)="menuRefresh()">COLLAPSE</button> + </mat-card-actions> --> +</mat-card> http://git-wip-us.apache.org/repos/asf/asterixdb/blob/a7e8dbe3/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/metadata.component.scss ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/metadata.component.scss b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/metadata.component.scss new file mode 100755 index 0000000..4ee2339 --- /dev/null +++ b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/metadata.component.scss @@ -0,0 +1,97 @@ +/* +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +$metadata-spacing-unit: 5px; + +.metadata-card { + display: flex; + flex-flow: column; + padding: 0; + margin: 0 auto; //($metadata-spacing-unit * 2); + margin-top: ($metadata-spacing-unit * 2); + margin-bottom: ($metadata-spacing-unit * 2); + min-height: 150px; + box-shadow: none !important; + width: 92%; + overflow: hidden; +} + +.example-icon { + padding: 0 14px 0 0; + margin: 0; +} + +.spacer { + flex: 1 1 auto; +} + +.metadata-selector { + min-height: 42px; + max-height: 42px; + justify-content: center; + //align-items: center; + font-size: 0.80rem; + font-weight: 500; + background-color: white; + border: 1px solid rgba(54, 147, 209, 0.87); +} + +.metadata-content-area { + padding: ($metadata-spacing-unit * 2); + margin: 0; +} + +.metadata-tree { + min-height: 30px; + font-size: 0.80rem; + font-weight: 500; +} + +.metadata-datasets { + margin-top: ($metadata-spacing-unit * 2); + margin-bottom: ($metadata-spacing-unit * 2); +} + +.metadata-datatypes { + margin-top: ($metadata-spacing-unit * 2); + margin-bottom: ($metadata-spacing-unit * 2); +} + +.metadata-dataindexes { + margin-top: ($metadata-spacing-unit * 2); + margin-bottom: ($metadata-spacing-unit * 2); +} + + +.metadata-tree.ui-tree { + //width: 260px !important; + font-size: 0.80rem; + font-weight: 500; + border: none !important; + background-color: red; +} + +.refresh-button { + float: left; + margin-top: $metadata-spacing-unit; +} + +.actions { + border-top: 1px solid rgba(0, 0, 0, 0.1); + color: rgba(54, 147, 209, 0.87); + padding: $metadata-spacing-unit; + margin: 0; +} + + + http://git-wip-us.apache.org/repos/asf/asterixdb/blob/a7e8dbe3/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/metadata.component.ts ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/metadata.component.ts b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/metadata.component.ts new file mode 100755 index 0000000..e60c9de --- /dev/null +++ b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/metadata.component.ts @@ -0,0 +1,209 @@ +/* +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +import { Component, OnInit, ChangeDetectorRef } from '@angular/core'; +import { Router } from '@angular/router'; +import { Dataverse } from '../../shared/models/asterixDB.model'; +import { Store } from '@ngrx/store'; +import { Observable } from 'rxjs/Observable'; +import * as dataverseActions from '../../shared/actions/dataverse.actions'; +import * as datasetActions from '../../shared/actions/dataset.actions'; +import * as datatypesActions from '../../shared/actions/datatype.actions'; +import * as indexesActions from '../../shared/actions/index.actions'; +import * as metadataActions from '../../shared/actions/metadata.actions'; +import * as datasetsActions from '../../shared/actions/dataset.actions'; +import { ElementRef, ViewChild} from '@angular/core'; +import {DataSource} from '@angular/cdk/collections'; +import {BehaviorSubject} from 'rxjs/BehaviorSubject'; +import 'rxjs/add/operator/startWith'; +import 'rxjs/add/observable/merge'; +import 'rxjs/add/operator/map'; +import 'rxjs/add/operator/debounceTime'; +import 'rxjs/add/operator/distinctUntilChanged'; +import 'rxjs/add/observable/fromEvent'; +import { Subscription } from 'rxjs/Rx'; +import * as fromRoot from '../../shared/reducers/dataverse.reducer'; +import { State } from '../../shared/reducers/dataverse.reducer'; +import { TreeModule, TreeNode} from 'primeng/primeng'; + + +/** + * query component + * has editor (codemirror) for writing some query + */ +@Component({ + moduleId: module.id, + selector: 'awc-metadata', + templateUrl: 'metadata.component.html', + styleUrls: ['metadata.component.scss'] +}) + +export class MetadataComponent implements OnInit { + nodesAll = []; + nodesDatasets = []; + nodesDatatypes = []; + nodesIndexes = []; + + constructor(private store: Store<any>, private changeDetector: ChangeDetectorRef) {} + + ngOnInit(): void { + + // Watching for the metadata tree + this.store.select(s => s.metadata.tree).subscribe((data: any[]) => { + + this.nodesAll = []; + this.nodesDatasets = []; + this.nodesDatatypes = []; + this.nodesIndexes = []; + const indexesMenu = []; + const datatypesMenu = []; + const datasetsMenu = []; + const dataversesRoot = { label: '', children: []}; + dataversesRoot.label = 'DATAVERSES'; + dataversesRoot.children = []; + + for (let i = 0; i < data.length; i++) { + + // Don't want to show metadata system datasets, datatypes or indexes + // if (data[i]['DataverseName'] && data[i]['DataverseName'] !== "Metadata" ) + // { + // Counting dataverses to align the menu identifiers + const dataverse = { label: '', children: [] }; + dataverse.label = data[i]['DataverseName']; + dataversesRoot.children.push(dataverse); + + // Adding the datasets to correspondent dataverse + if (data[i]['Datasets'].length) { + const datasetRoot = { label: '', children: [] }; + datasetRoot.label = 'DATASETS'; + dataverse.children.push(datasetRoot); + for (let j = 0; j < data[i]['Datasets'].length; j++) { + const dataset = { label: '', children: [] }; + dataset.label = data[i]['Datasets'][j]['DatasetName']; + + // + // Adding the datatype to correspondent dataset + // + if (data[i]['Datasets'][j]['Datatype']) { + const datatypeRoot = { label: '', children: [] }; + datatypeRoot.label = 'Datatype: ' + data[i]['Datasets'][j]['Datatype']['DatatypeName']; + // + // Looking for the datatype fields + // + if (data[i]['Datasets'][j]['Datatype']['Derived']) { + if (data[i]['Datasets'][j]['Datatype']['Derived']['Record']) { + const datatypeFieldsRoot = { label: '', leaf: true, expanded: true, children: [] }; + datatypeFieldsRoot.label = 'FIELDS'; + for (let k = 0; k < data[i]['Datasets'][j]['Datatype']['Derived']['Record']['Fields'].length; k++) { + const datatypeField = { label: '', children: [] }; + datatypeField.label = data[i]['Datasets'][j]['Datatype']['Derived']['Record']['Fields'][k]['FieldName'] + ": " + data[i]['Datasets'][j]['Datatype']['Derived']['Record']['Fields'][k]['FieldType']; + datatypeFieldsRoot.children.push(datatypeField); + } + datatypeRoot.children.push(datatypeFieldsRoot); + + } + } + dataset.children.push(datatypeRoot); + + datatypeRoot.label = data[i]['Datasets'][j]['Datatype']['DatatypeName']; + datatypesMenu.push(datatypeRoot); + } + + // + // Adding the indexes to correspondent dataset + // + if (data[i]['Datasets'][j]['Indexes'].length) { + const indexRoot = { label: '', children: [] }; + indexRoot.label = 'INDEXES'; + + for (let k = 0; k < data[i]['Datasets'][j]['Indexes'].length; k++) { + const indexChild = { label: '', children: [] }; + indexChild.label = data[i]['Datasets'][j]['Indexes'][k]['IndexName']; + + // is Primary + const indexIsPrimaryRoot = { label: '', children: [] }; + indexIsPrimaryRoot.label = 'isPrimary' + ': ' + data[i]['Datasets'][j]['Indexes'][k]['IsPrimary']; + indexChild.children.push(indexIsPrimaryRoot); + + // SearchKey + if (data[i]['Datasets'][j]['Indexes'][k]['SearchKey']) { + const indexSearchKeyRoot = { label: '', children: [] }; + indexSearchKeyRoot.label = 'SEARCH KEY'; + for (let l = 0; l < data[i]['Datasets'][j]['Indexes'][k]['SearchKey'].length; l++) { + const indexsearchKeyField = { label: '', children: [] }; + indexsearchKeyField.label = data[i]['Datasets'][j]['Indexes'][k]['SearchKey'][l] + indexSearchKeyRoot.children.push(indexsearchKeyField); + } + + indexChild.children.push(indexSearchKeyRoot); + indexesMenu.push(indexChild); + } + + indexRoot.children.push(indexChild); + } + + dataset.children.push(indexRoot); + datasetRoot.children.push(dataset); + datasetsMenu.push(dataset); + } + } + } + // } + } + + this.nodesAll.push(dataversesRoot); + + /* + * Making the rest of the stand alone submenus + */ + + // Adding the DATASET stand alone submenu + const datasetMenuRoot = { label: '', children: [] }; + datasetMenuRoot.label = 'DATASETS'; + datasetMenuRoot.children = datasetsMenu; + this.nodesDatasets.push(datasetMenuRoot); + + // Adding the DATATYPES stand alone submenu + const datatypeMenuRoot = { label: '', children: [] }; + datatypeMenuRoot.label = 'DATATYPES'; + datatypeMenuRoot.children = datatypesMenu; + this.nodesDatatypes.push(datatypeMenuRoot); + + // Adding the DATATYPE stand alone submenu + const indexesMenuRoot = { label: '', children: [] }; + indexesMenuRoot.label = 'INDEXES'; + indexesMenuRoot.children = indexesMenu; + this.nodesIndexes.push(indexesMenuRoot); + + // Component View Refresh + this.changeDetector.detectChanges(); + }); + } + + /* + * UI helpers to select dataverses from the guide menu + */ + nodeSelectAll(event) { + if (event.node.parent && event.node.parent.label === 'DATASETS') { + const datasetName = event.node.label.replace(/-;-/g); + this.store.dispatch(new datasetsActions.GuideSelectDatasets(datasetName)); + } + } + + nodeSelectDataset(event) { + if (event.node.parent && event.node.parent.label === 'DATASETS') { + const datasetName = event.node.label.replace(/-;-/g); + this.store.dispatch(new datasetsActions.GuideSelectDatasets(datasetName)); + } + } +} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/a7e8dbe3/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/ouput.component.ts ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/ouput.component.ts b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/ouput.component.ts new file mode 100755 index 0000000..fcfc235 --- /dev/null +++ b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/ouput.component.ts @@ -0,0 +1,278 @@ +/* +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +import { Component, OnInit, ViewChild, AfterViewInit, ChangeDetectorRef, Pipe, PipeTransform } from '@angular/core'; +import { Observable } from 'rxjs/Observable'; +import { Store } from '@ngrx/store'; +import * as sqlQueryActions from '../../shared/actions/query.actions' +import { saveAs } from 'file-saver'; +import { DomSanitizer } from '@angular/platform-browser'; +import {TreeModule,TreeNode} from 'primeng/primeng'; + +/** + * query component + * has editor (codemirror) for writing some query + */ + +@Pipe({ name: 'safeHtml'}) +export class SafeHtmlPipe implements PipeTransform { + constructor(private sanitized: DomSanitizer) {} + transform(value) { + return this.sanitized.bypassSecurityTrustHtml(value); + } +} + +@Component({ + moduleId: module.id, + selector: 'awc-results', + templateUrl:'output.component.html', + styleUrls: ['output.component.scss'] +}) + + +export class QueryOutputComponent implements OnInit { + queryMessage: string; + treeData = []; + flattenData = []; + dataColumns = []; + query_message: string; + execution_time: number; + loaded$: Observable<any> + data: any[]; + loading: Boolean; + jsonOutput = ""; + selectedOutputView = "NONE"; + outputQueryString = ""; + toogleExpand = "EXPAND TREE" + + /* Codemirror configuration */ + codemirrorConfig = { mode: "asterix", + lineWrapping: true, + showCursorWhenSelecting: true + }; + + generateTreeMenu(node, rootMenu): any { + + // Check in case the root object is not defined properly + if (rootMenu === undefined) { + rootMenu = { label: '', children: []}; + } + + let nodeArray = []; + + // Going through all the keys in a node looking for objects or array of key values + // and create a sub menu if is an object. + Object.keys(node).map((k) => { + + if (typeof node[k] === 'object') { + let nodeObject = { label: '', children: []}; + nodeObject = { label: '', children: []}; + nodeObject.label = k; + // if this is an object then a new node is created and + // recursive call to find and fill with the nested elements + let newNodeObject = this.generateTreeMenu(node[k], nodeObject); + + // if this is the first node, then will become the root. + if (rootMenu.children) { + rootMenu.children.push(newNodeObject) + } else { + rootMenu = newNodeObject + } + } + else { + // Array of key values converted into a unique string with a : separator + let nodeKeyValue = { label: '', children: []}; + nodeKeyValue.label = k + " : " + node[k] + nodeArray.push(nodeKeyValue); + } + }) + + // The array will be added as value to a parent key. + if (nodeArray.length > 0) { + rootMenu.children = nodeArray.concat(rootMenu.children) + } + + return rootMenu + } + + constructor(private store: Store<any>, private changeDetector: ChangeDetectorRef) { + this.loaded$ = this.store.select(s => s.sqlQuery.loaded); + this.store.select("sqlQuery").subscribe((data: any) => { + // Set the output toolbar query string and default view settings + if (data.loaded) { + this.selectedOutputView = "TABLE"; + this.loading = true; + this.data = data.sqlQueryResult.results; + this.treeData = []; + let stringQuery = data.sqlQueryString; + + // Preparing the toolbar + if (stringQuery.length > 150) { + this.outputQueryString = ": " + stringQuery.slice(0, 150) + " (..)" + } else { + this.outputQueryString = ": " + stringQuery; + } + + // Processing the results + if (data.sqlQueryResult.results && data.sqlQueryResult.results.length > 0 && this.data[0]) { + + /* Removing the root object, disabled for the time being + var resultKeyList = Object.keys(this.data[0]); + var resultKey: string = resultKeyList[0]; + */ + + for (let i = 0; i < this.data.length; i++) { + + /* Removing the root object, disabled for the time being + if (this.data[i][resultKey] instanceof Object) { + this.data[i] = this.data[i][resultKey]; + }*/ + + let nodeContent = { label:"[" + i + "]" , children: []}; + this.treeData.push(this.generateTreeMenu(this.data[i], nodeContent)) + } + + this.loading = false; + } + + // JSON OUTPUT + // Making into a JSON String for JSON String Output + this.jsonOutput = JSON.stringify(data.sqlQueryResult.results, null, 2) + + // TABLE OUTPUT + if (this.data && this.data.length > 0) { + + this.collapseAll(); + // Normalize the data ( removing the first key if is an object ) + // TODO: Move it into a recursive function. + this.dataColumns = []; + + var resultKeyList = Object.keys(this.data[0]); + var resultKey: string = resultKeyList[0]; + if (this.data[0][resultKey] instanceof Object) { + // is a SQL++ Query Results + var nestedKeyList = Object.keys(this.data[0][resultKey]); + for (let i = 0; i < nestedKeyList.length; i++) { + if (typeof this.data[0][resultKey][nestedKeyList[i]] === 'object') { + // Creating a key to display a nested type + this.dataColumns.push({field: 'nestedString' + i, header: nestedKeyList[i]}) + + } else { + this.dataColumns.push({field: nestedKeyList[i], header: nestedKeyList[i] }) + } + + } + } + else { // is a SQL++ Metadata Results and there is an Array + for (let i = 0; i < resultKeyList.length; i++) { + this.dataColumns.push({field: resultKeyList[i], header: resultKeyList[i] }) + } + } + + // Now prepare the data ( SQL++ Query, Metatada Queries no need to change anything ). + // TODO: Move it into a recursive function. + if (this.data[0][resultKey] instanceof Object) { + // is a SQL++ Query Results + for (let i = 0; i < this.data.length; i++) { + + // // is a SQL++ Query Results + var nestedKeyList = Object.keys(this.data[i][resultKey]); + for (let k = 0; k < nestedKeyList.length; k++) { + if ( typeof this.data[i][resultKey][nestedKeyList[k]] === 'object' ){ + // Creating a display value to for a nested type JSON.stringify(jsObj, + var nestedObjectStr = JSON.stringify(this.data[i][resultKey][nestedKeyList[k]], null, '\n'); + var nestedKey = 'nestedString' + k; + this.data[i][resultKey][nestedKey] = nestedObjectStr; + } + } + + this.data[i] = this.data[i][resultKey]; + } + } + } + } + }); + } + + /* + * Subscribing to store values + */ + ngOnInit(): void { + this.loaded$ = this.store.select('sqlQuery'); + this.store.select("sqlQuery").subscribe((data: any) => { + if (data.sqlQueryError.errors){ + this.queryMessage = data.sqlQueryError.errors[0].msg + }else{ + this.queryMessage = "" + } + }) + } + + /* + * Changes view mode [ TABLE, TREE, JSON VIEW ] + */ + onSelect(value: any) { + this.selectedOutputView = value; + } + + /* + * Export to CSV + */ + exportToCSV(){ + var blob = new Blob([this.jsonOutput], {type: "text/csv;charset=utf-8"}); + saveAs(blob, "Asterix-results.csv"); + } + + /* + * Export to plain text + */ + exportToText(){ + var exportOutput = this.jsonOutput; + var blob = new Blob([exportOutput], {type: "text/plain;charset=utf-8"}); + saveAs(blob, "Asterix-results.txt"); + } + + /* + * Expand/Collapse Tree + */ + expandTree(){ + if (this.toogleExpand === "EXPAND TREE"){ + this.expandAll(); + } else { + this.collapseAll(); + } + } + + expandAll(){ + this.toogleExpand = "TREE COLLAPSE"; + this.treeData.forEach( node => { + this.expandRecursive(node, true); + } ); + } + + collapseAll(){ + this.toogleExpand = "EXPAND TREE"; + this.treeData.forEach( node => { + this.expandRecursive(node, false); + } ); + } + + private expandRecursive(node:TreeNode, isExpand:boolean){ + node.expanded = isExpand; + if(node.children){ + node.children.forEach( childNode => { + this.expandRecursive(childNode, isExpand); + } ); + } + } +} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/a7e8dbe3/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/output.component.html ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/output.component.html b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/output.component.html new file mode 100755 index 0000000..f7c4b43 --- /dev/null +++ b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/output.component.html @@ -0,0 +1,68 @@ +<!--/* +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ --> +<mat-card class="sql-results-card"> + <mat-toolbar color="primary" class="results-selector"> + <mat-icon class="toolbar-icon">menu</mat-icon> + <span class="output-query-string">OUTPUT{{outputQueryString}}</span> + <span class="spacer"></span> + </mat-toolbar> + <mat-card-content class="content-area"> + <div *ngIf="loaded$ | async as ld"> + <div *ngIf="selectedOutputView=='TABLE'"> + <p-dataTable [style]="{'width':'100%', 'overflow':'hidden'}" id='review-table' [responsive]="true" [hidden]="loading" [value]="data" [rows]="20" [paginator]="true" [pageLinks]="3" [rowsPerPageOptions]="[5,10,20, 30, 40, 50]" > + <p-column [style]="{'text-align':'left', + 'text-overflow': 'ellipsis', 'word-wrap': 'break-word', 'word-break': 'break-all'}" + + [footerStyle]="{'color':'blue'}" [headerStyleClass]="datatable-header" *ngFor="let node of dataColumns;" [field]="node.field" + [header]="node.header" [sortable]="true"> + </p-column> + </p-dataTable> + </div> + </div> + <div *ngIf="loaded$ | async as ld"> + <div *ngIf="ld.sqlQueryError.metrics" class="queryErrorMessage"> + <span>ERROR:</span> + <span>{{queryMessage}}</span> + </div> + <div [hidden]="selectedOutputView!='TREE'" class="data-viewer-container"> + <button mat-button class="button-expand" (click)="expandTree()">{{toogleExpand}}</button> + <p-tree [style]="{'width':'100%', 'border': 'none', 'font-family': 'Roboto Mono', 'font-size': '0.80rem', + 'font-weight': '500'}" [value]="treeData"></p-tree> + </div> + <div *ngIf="loaded$ | async as ld"> + <div *ngIf="selectedOutputView=='JSON'" class="data-viewer-container"> + <button mat-button class="button-export" (click)="exportToText()">EXPORT</button> + <pre class="json-output">{{jsonOutput}}</pre> + </div> + </div> + </div> + </mat-card-content> + <mat-card-actions class="actions"> + <div *ngIf="loaded$ | async as ld"> + <span *ngIf="ld.sqlQueryResult.metrics" class="metrics"> + <span class="span-results">SUCCESS:</span> + <span class="span-results">Count: {{ld.sqlQueryResult.metrics.resultCount}}</span> + <span class="span-results">Size: {{ld.sqlQueryResult.metrics.resultSize}}</span> + <span class="span-results">Elapsed time: {{ld.sqlQueryResult.metrics.elapsedTime}}</span> + <span class="span-results">Execution time: {{ld.sqlQueryResult.metrics.executionTime}}</span> + <span class="spacer"></span> + <mat-button-toggle-group #group="matButtonToggleGroup" class="output-group" value={{selectedOutput}} (change)="onSelect(group.value)"> + <mat-button-toggle mat-button value="TABLE">TABLE</mat-button-toggle> + <mat-button-toggle mat-button value="TREE">TREE</mat-button-toggle> + <mat-button-toggle mat-button value="JSON">JSON</mat-button-toggle> + </mat-button-toggle-group> + </span> + </div> + </mat-card-actions> +</mat-card> http://git-wip-us.apache.org/repos/asf/asterixdb/blob/a7e8dbe3/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/output.component.scss ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/output.component.scss b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/output.component.scss new file mode 100755 index 0000000..099ca87 --- /dev/null +++ b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/output.component.scss @@ -0,0 +1,169 @@ +/* +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +$results-spacing-unit: 5px; + +.sql-results-card { + display: flex; + flex-flow: column; + padding: 0; + height: 600px; + width: 100%; // 1350px; + margin: ($results-spacing-unit * 2); + min-height: 150px; +} + +.toolbar-icon { + padding: 0 14px 0 0; + margin: 0; +} + +.spacer { + flex: 1 1 auto; +} + +.results-selector { + max-height: 42px; + min-height: 42px; + justify-content: center; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + font-size: 0.80rem; + font-weight: 500; + background-color: white; + border: 1px solid rgba(54, 147, 209, 0.87); + overflow-wrap: break-word; + word-break: break-all; +} + +.content-area { + position: relative; + color: hsla(0,0%,0%,.87); + height: 500px; + padding: 0; + margin: 0; + overflow: auto; + font-size: 0.80rem; + font-weight: 500; + font-family: "Roboto", monospace; +} + +.root-closed { + list-style-type:none; +} + +.root-open { + list-style-type:none; +} + +.leaf-list-open { + list-style-type:none; + // padding-top: ($results-spacing-unit) * 2; + padding-left: 25px; + color: red; +} + +.leaf-list-open.div +//.leaf-list-open.ul +.leaf-list-open.li { + margin-left: ($results-spacing-unit * 10) !important; + color: green; +} + +.leaf { + color: blue; +} + +.leaf-list-closed { + list-style-type:none; + display: none; +} + +ul > .root-closed::before { + content:'+' +} + +ul > .root-open::before { + content:'-' +} + +.queryErrorMessage { + border-bottom: 1px solid rgba(0, 0, 0, 0.1); + color: rgba(209, 54, 54, 0.87); + padding: $results-spacing-unit; + padding-left: ($results-spacing-unit * 2); +} + +.metrics { + display: flex; + color: rgba(54, 147, 209, 0.87); + font-size: 0.80rem; + font-weight: 500; +} + +.span-results { + padding-top: ($results-spacing-unit * 2); + padding-left: ($results-spacing-unit * 2); +} + +.actions { + border-top: 1px solid rgba(0, 0, 0, 0.1); + color: rgba(54, 147, 209, 0.87); + margin: 0; +} + +//someID\:review-table +th { + text-align: left !important; +} + +.datatable-header { + color: red !important; + background-color: blue; +} + +.data-viewer-container { + padding: ($results-spacing-unit * 4); + padding-bottom: ($results-spacing-unit * 8); + height: 100%; + overflow: hidden; +} + +.output-group { + margin-right: ($results-spacing-unit * 4); +} + +.menu-export { + font-size: 0.80rem !important; + font-weight: 500 !important; +} + +.button-export { + margin-right: ($results-spacing-unit * 4); + color: rgba(54, 147, 209, 0.87); +} + +.button-expand { + margin-right: ($results-spacing-unit * 4); + color: rgba(54, 147, 209, 0.87); +} + +.ui-datatable-data> tr> td { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + max-width: 150px; + color: red; +} + http://git-wip-us.apache.org/repos/asf/asterixdb/blob/a7e8dbe3/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/query-container.component.html ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/query-container.component.html b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/query-container.component.html new file mode 100755 index 0000000..6dd3ef3 --- /dev/null +++ b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/query-container.component.html @@ -0,0 +1,24 @@ +<!--/* +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ --> + +<div class="query-container"> + <div class="metadata"> + <awc-metadata class="metadata-card"></awc-metadata> + </div> + <div class="vertical"> + <awc-query class="query-card"></awc-query> + <awc-results class="output-card"></awc-results> + </div> +</div> + http://git-wip-us.apache.org/repos/asf/asterixdb/blob/a7e8dbe3/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/query-container.component.scss ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/query-container.component.scss b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/query-container.component.scss new file mode 100755 index 0000000..d6b530b --- /dev/null +++ b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/query-container.component.scss @@ -0,0 +1,82 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + .query-container { + display: flex; + flex-direction: row; + //background-color: red; + width: 100%; + margin:0; + padding:0; + overflow: hidden; + } + +.metadata { + display: flex; + flex-direction: row; + width: 20%; + // background-color: rgb(0, 255, 42); + margin:0; + padding: 0; + // padding-right: 10px; + border-right: 1px solid hsla(0,0%,0%,.20); +} + +.vertical { + display: flex; + flex-direction: column; + align-items: center; + width: 80%; + overflow: hidden; + margin:0; + padding: 1px0; + // background-color: rgb(38, 0, 255); +} + +.metadata-card { + display: flex; + flex-direction: row; + justify-content: center; + width: 100%; + overflow: hidden; + margin:0; + padding: 0; + // background-color: green; +} + +.query-card { + display: flex; + flex-direction: row; + justify-content: center; + width: 100%; + overflow: hidden; + margin:0; + padding: 0; + //background-color: green; +} + +.output-card { + display: flex; + flex-direction: row; + justify-content: center; + width: 100%; + overflow: hidden; + margin:0; + padding: 0; + //background-color: yellow; +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/asterixdb/blob/a7e8dbe3/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/query-container.component.ts ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/query-container.component.ts b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/query-container.component.ts new file mode 100755 index 0000000..776e184 --- /dev/null +++ b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/dashboard/query/query-container.component.ts @@ -0,0 +1,74 @@ +/* +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +import { Component, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; +import { Dataverse } from '../../shared/models/asterixDB.model' +import { Store } from '@ngrx/store'; +import { Observable } from 'rxjs/Observable'; +import * as dataverseActions from '../../shared/actions/dataverse.actions' +import * as datasetActions from '../../shared/actions/dataset.actions' +import * as datatypesActions from '../../shared/actions/datatype.actions' +import * as indexesActions from '../../shared/actions/index.actions' +import * as metadataActions from '../../shared/actions/metadata.actions' +import { ElementRef, ViewChild} from '@angular/core'; +import {DataSource} from '@angular/cdk/collections'; +import {BehaviorSubject} from 'rxjs/BehaviorSubject'; +import 'rxjs/add/operator/startWith'; +import 'rxjs/add/observable/merge'; +import 'rxjs/add/operator/map'; +import 'rxjs/add/operator/debounceTime'; +import 'rxjs/add/operator/distinctUntilChanged'; +import 'rxjs/add/observable/fromEvent'; +import { Subscription } from "rxjs/Rx"; +import * as fromRoot from '../../shared/reducers/dataverse.reducer'; +import { State } from '../../shared/reducers/dataverse.reducer'; +import * as sqlQueryActions from '../../shared/actions/query.actions' +/* + * query component + * has editor (codemirror) for writing some query + */ +@Component({ + moduleId: module.id, + selector: 'awc-query-container', + templateUrl:'query-container.component.html', + styleUrls: ['query-container.component.scss'] +}) + +export class QueryContainerComponent { + nodes = [] + constructor(private store: Store<any>) { + + this.store.select(s => s.metadata.tree).subscribe((data: any[]) => { + this.nodes = [] + for (let i = 0; i < data.length; i++) { + if (data[i]['DataverseName']) { + let node = { id: 0, name:"", children:[] }; + node.id = i; + node.name = data[i]['DataverseName']; + for (let j = 0; j < data[i]['Datasets'].length; j++) { + let children = { id: 0, name:"", children:[] }; + children.id = j + children.name = data[i]['Datasets'][j]['DatasetName']; + node.children.push(children) + } + this.nodes.push(node) + } + } + }); + } + + treeCalc() { + this.store.dispatch(new metadataActions.UpdateMetadataTree()); + } +} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/a7e8dbe3/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/db.ts ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/db.ts b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/db.ts new file mode 100755 index 0000000..8f51b00 --- /dev/null +++ b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/db.ts @@ -0,0 +1,23 @@ +/* +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +import { DBSchema } from '@ngrx/db'; + +/* +* Persistent storage capability to the dashboard in case is needed. +*/ +export const schema: DBSchema = { + version: 1, + name: 'asterixDB_app', + stores: {}, +}; http://git-wip-us.apache.org/repos/asf/asterixdb/blob/a7e8dbe3/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/material.module.ts ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/material.module.ts b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/material.module.ts new file mode 100755 index 0000000..3bb67d9 --- /dev/null +++ b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/material.module.ts @@ -0,0 +1,105 @@ +/* +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +import {NgModule} from '@angular/core'; +import { + MatAutocompleteModule, + MatButtonModule, + MatButtonToggleModule, + MatCardModule, + MatCheckboxModule, + MatChipsModule, + MatDatepickerModule, + MatDialogModule, + MatExpansionModule, + MatFormFieldModule, + MatGridListModule, + MatIconModule, + MatInputModule, + MatListModule, + MatMenuModule, + MatPaginatorModule, + MatProgressBarModule, + MatProgressSpinnerModule, + MatRadioModule, + MatSelectModule, + MatSidenavModule, + MatSliderModule, + MatSlideToggleModule, + MatSnackBarModule, + MatSortModule, + MatTableModule, + MatTabsModule, + MatToolbarModule, + MatTooltipModule, + MatStepperModule, +} from '@angular/material'; +import {MatNativeDateModule, MatRippleModule} from '@angular/material'; +import {CdkTableModule} from '@angular/cdk/table'; +//import {CdkAccordionModule} from '@angular/cdk/accordion'; +import {A11yModule} from '@angular/cdk/a11y'; +import {BidiModule} from '@angular/cdk/bidi'; +import {OverlayModule} from '@angular/cdk/overlay'; +import {PlatformModule} from '@angular/cdk/platform'; +import {ObserversModule} from '@angular/cdk/observers'; +import {PortalModule} from '@angular/cdk/portal'; + +/* +* NgModule that includes all Material modules that are required to +* serve AsterixDB Dashboard +*/ +@NgModule({ + exports: [ + MatAutocompleteModule, + MatButtonModule, + MatButtonToggleModule, + MatCardModule, + MatCheckboxModule, + MatChipsModule, + MatTableModule, + MatDatepickerModule, + MatDialogModule, + MatExpansionModule, + MatFormFieldModule, + MatGridListModule, + MatIconModule, + MatInputModule, + MatListModule, + MatMenuModule, + MatPaginatorModule, + MatProgressBarModule, + MatProgressSpinnerModule, + MatRadioModule, + MatRippleModule, + MatSelectModule, + MatSidenavModule, + MatSlideToggleModule, + MatSliderModule, + MatSnackBarModule, + MatSortModule, + MatStepperModule, + MatTabsModule, + MatToolbarModule, + MatTooltipModule, + MatNativeDateModule, + CdkTableModule, + A11yModule, + BidiModule, + // CdkAccordionModule, + ObserversModule, + OverlayModule, + PlatformModule, + PortalModule, + ] +}) +export class MaterialModule {} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/a7e8dbe3/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/shared/actions/app.actions.ts ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/shared/actions/app.actions.ts b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/shared/actions/app.actions.ts new file mode 100755 index 0000000..29da05f --- /dev/null +++ b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/shared/actions/app.actions.ts @@ -0,0 +1,33 @@ +/* +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +import { Action } from '@ngrx/store'; +import { AsterixDBQueryMessage, Dataset } from '../models/asterixDB.model'; + +/* +* Definition of App Actions +*/ +export const APP_MODE_CHANGE = '[App State] App Mode Change'; + +/* +* Guide Select Datasets for UI Helpers +*/ +export class ChangeMode implements Action { + readonly type = APP_MODE_CHANGE; + constructor(public payload: string) {} +} + +/* +* Exports of datasets actions +*/ +export type All = ChangeMode; http://git-wip-us.apache.org/repos/asf/asterixdb/blob/a7e8dbe3/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/shared/actions/dataset.actions.ts ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/shared/actions/dataset.actions.ts b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/shared/actions/dataset.actions.ts new file mode 100755 index 0000000..a49e07c --- /dev/null +++ b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/shared/actions/dataset.actions.ts @@ -0,0 +1,130 @@ +/* +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +import { Action } from '@ngrx/store'; +import { AsterixDBQueryMessage, Dataset } from '../models/asterixDB.model'; + +/* +* Definition of Datasets Actions +*/ +export const SELECT_DATASETS = '[Dataset Collection] Select Dataset'; +export const SELECT_DATASETS_SUCCESS = '[Dataset Collection] Select Dataset Success'; +export const SELECT_DATASETS_FAIL = '[Dataset Collection] Select Dataset Fail'; +export const CREATE_DATASET = '[Dataset Collection] Create Dataset'; +export const CREATE_DATASET_SUCCESS = '[Dataset Collection] Create Dataset Success'; +export const CREATE_DATASET_FAIL = '[Dataset Collection] Create Dataset Fail'; +export const UPDATE_DATASET = '[Dataset Collection] Update Dataset'; +export const UPDATE_DATASET_SUCCESS = '[Dataset Collection] Update Dataset Success'; +export const UPDATE_DATASET_FAIL = '[Dataset Collection] Update Dataset Fail'; +export const DROP_DATASET = '[Dataset Collection] Drop Dataset'; +export const DROP_DATASET_SUCCESS = '[Dataset Collection] Drop Dataset Success'; +export const DROP_DATASET_FAIL = '[Dataset Collection] Drop Dataset Fail'; +export const GUIDE_SELECT_DATASET = '[Dataset Collection] Guide Select Dataset'; + + +/* +* Guide Select Datasets for UI Helpers +*/ +export class GuideSelectDatasets implements Action { + readonly type = GUIDE_SELECT_DATASET; + constructor(public payload: string) {} +} + +/* +* Select Datasets +*/ +export class SelectDatasets implements Action { + readonly type = SELECT_DATASETS; + constructor(public payload: string) {} +} + +export class SelectDatasetsSuccess implements Action { + readonly type = SELECT_DATASETS_SUCCESS; + constructor(public payload: AsterixDBQueryMessage[]) {} +} + +export class SelectDatasetsFail implements Action { + readonly type = SELECT_DATASETS_FAIL; + constructor(public payload: AsterixDBQueryMessage[]) {} +} + +/* +* Create Dataset +*/ +export class CreateDataset implements Action { + readonly type = CREATE_DATASET; + constructor(public payload: string) {} +} + +export class CreateDatasetSuccess implements Action { + readonly type = CREATE_DATASET_SUCCESS; + constructor(public payload: Dataset[]) {} +} + +export class CreateDatasetFail implements Action { + readonly type = CREATE_DATASET_FAIL; + constructor(public payload: Dataset) {} +} + +/* +* Update Dataset +*/ +export class UpdateDataset implements Action { + readonly type = UPDATE_DATASET; + constructor(public payload: Dataset) {} +} + +export class UpdateDatasetSuccess implements Action { + readonly type = UPDATE_DATASET_SUCCESS; + constructor(public payload: Dataset[]) {} +} + +export class UpdateDatasetFail implements Action { + readonly type = UPDATE_DATASET_FAIL; + constructor(public payload: Dataset) {} +} + +/* +* Drop Dataset +*/ +export class DropDataset implements Action { + readonly type = DROP_DATASET; + constructor(public payload: string) {} +} + +export class DropDatasetSuccess implements Action { + readonly type = DROP_DATASET_SUCCESS; + constructor(public payload: Dataset[]) {} +} + +export class DropDatasetFail implements Action { + readonly type = DROP_DATASET_FAIL; + constructor(public payload: Dataset) {} +} + +/* +* Exports of datasets actions +*/ +export type All = SelectDatasets | + SelectDatasetsSuccess | + SelectDatasetsFail | + CreateDataset | + CreateDatasetSuccess | + CreateDatasetFail | + UpdateDataset | + UpdateDatasetSuccess | + UpdateDatasetFail | + DropDataset | + DropDatasetSuccess | + DropDatasetFail | + GuideSelectDatasets; http://git-wip-us.apache.org/repos/asf/asterixdb/blob/a7e8dbe3/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/shared/actions/datatype.actions.ts ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/shared/actions/datatype.actions.ts b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/shared/actions/datatype.actions.ts new file mode 100755 index 0000000..5543a7a --- /dev/null +++ b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/shared/actions/datatype.actions.ts @@ -0,0 +1,122 @@ +/* +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +import { Action } from '@ngrx/store'; +import { AsterixDBQueryMessage, Datatype } from '../models/asterixDB.model'; + +/* +* Definition of Datatypes Actions +*/ +export const SELECT_DATATYPES = '[Datatype Collection] Select Datatypes'; +export const SELECT_DATATYPES_SUCCESS = '[Datatype Collection] Select Datatypes Success'; +export const SELECT_DATATYPES_FAIL = '[Datatype Collection] Select Datatypes Fail'; +export const CREATE_DATATYPE = '[Datatype Collection] Create Datatypes'; +export const CREATE_DATATYPE_SUCCESS = '[Datatype Collection] Create Datatypes Success'; +export const CREATE_DATATYPE_FAIL = '[Datatype Collection] Create Datatypes Fail'; +export const UPDATE_DATATYPE = '[Datatype Collection] Update Datatype'; +export const UPDATE_DATATYPE_SUCCESS = '[Datatype Collection] Update Datatype Success'; +export const UPDATE_DATATYPE_FAIL = '[Datatype Collection] Update Datatype Fail'; +export const DROP_DATATYPE = '[Datatype Collection] Drop Datatypes'; +export const DROP_DATATYPE_SUCCESS = '[Datatype Collection] Drop Datatypes Success'; +export const DROP_DATATYPE_FAIL = '[Datatype Collection] Drop Datatypes Fail'; + +/* +* Select Datatypes +*/ +export class SelectDatatypes implements Action { + readonly type = SELECT_DATATYPES; + constructor(public payload: string) {} +} + +export class SelectDatatypesSuccess implements Action { + readonly type = SELECT_DATATYPES_SUCCESS; + constructor(public payload: AsterixDBQueryMessage[]) {} +} + +export class SelectDatatypesFail implements Action { + readonly type = SELECT_DATATYPES_FAIL; + constructor(public payload: AsterixDBQueryMessage[]) {} +} + +/* +* Create Datatype +*/ +export class CreateDatatype implements Action { + readonly type = CREATE_DATATYPE; + constructor(public payload: string) {} +} + +export class CreateDatatypeSuccess implements Action { + readonly type = CREATE_DATATYPE_SUCCESS; + constructor(public payload: Datatype[]) {} +} + +export class CreateDatatypeFail implements Action { + readonly type = CREATE_DATATYPE_FAIL; + constructor(public payload: Datatype) {} +} + +/* +* Update Datatype +*/ +export class UpdateDatatype implements Action { + readonly type = UPDATE_DATATYPE; + constructor(public payload: Datatype) {} +} + +export class UpdateDatatypeSuccess implements Action { + readonly type = UPDATE_DATATYPE_SUCCESS; + constructor(public payload: Datatype[]) {} +} + +export class UpdateDatatypeFail implements Action { + readonly type = UPDATE_DATATYPE_FAIL; + constructor(public payload: Datatype) {} +} + +/* +* Drop Datatype +*/ +export class DropDatatype implements Action { + readonly type = DROP_DATATYPE; + + constructor(public payload: string) {} +} + +export class DropDatatypeSuccess implements Action { + readonly type = DROP_DATATYPE_SUCCESS; + + constructor(public payload: Datatype[]) {} +} + +export class DropDatatypeFail implements Action { + readonly type = DROP_DATATYPE_FAIL; + + constructor(public payload: Datatype) {} +} + +/* +* Exports of datastypes actions +*/ +export type All = SelectDatatypes | + SelectDatatypesSuccess | + SelectDatatypesFail | + CreateDatatype | + CreateDatatypeSuccess | + CreateDatatypeFail | + UpdateDatatype | + UpdateDatatypeSuccess | + UpdateDatatypeFail | + DropDatatype | + DropDatatypeSuccess | + DropDatatypeFail; http://git-wip-us.apache.org/repos/asf/asterixdb/blob/a7e8dbe3/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/shared/actions/dataverse.actions.ts ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/shared/actions/dataverse.actions.ts b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/shared/actions/dataverse.actions.ts new file mode 100755 index 0000000..dc33c0a --- /dev/null +++ b/asterixdb/asterix-dashboard/src/main/resources/dashboard/src/app/shared/actions/dataverse.actions.ts @@ -0,0 +1,119 @@ +/* +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +import { Action } from '@ngrx/store'; +import { AsterixDBQueryMessage, Dataverse } from '../models/asterixDB.model'; + +/* +* Definition of Dataverses Actions +*/ +export const SELECT_DATAVERSES = '[Dataverse Collection] Select Dataverses'; +export const SELECT_DATAVERSES_SUCCESS = '[Dataverse Collection] Select Dataverses Success'; +export const SELECT_DATAVERSES_FAIL = '[Dataverse Collection] Select Dataverses Fail'; +export const CREATE_DATAVERSE = '[Dataverse Collection] Create Dataverse'; +export const CREATE_DATAVERSE_SUCCESS = '[Dataverse Collection] Create Dataverse Success'; +export const CREATE_DATAVERSE_FAIL = '[Dataverse Collection] Create Dataverse Fail'; +export const UPDATE_DATAVERSE = '[Dataverse Collection] Update Dataverse'; +export const UPDATE_DATAVERSE_SUCCESS = '[Dataverse Collection] Update Dataverse Success'; +export const UPDATE_DATAVERSE_FAIL = '[Dataverse Collection] Update Dataverse Fail'; +export const DROP_DATAVERSE = '[Dataverse Collection] Drop Dataverses'; +export const DROP_DATAVERSE_SUCCESS = '[Dataverse Collection] Drop Dataverses Success'; +export const DROP_DATAVERSE_FAIL = '[Dataverse Collection] Drop Dataverses Fail'; + +/* +* Select Dataverses +*/ +export class SelectDataverses implements Action { + readonly type = SELECT_DATAVERSES; + constructor(public payload: string) {} +} + +export class SelectDataversesSuccess implements Action { + readonly type = SELECT_DATAVERSES_SUCCESS; + constructor(public payload: AsterixDBQueryMessage[]) {} +} + +export class SelectDataversesFail implements Action { + readonly type = SELECT_DATAVERSES_FAIL; + constructor(public payload: AsterixDBQueryMessage[]) {} +} + +/* +* Create Dataverse +*/ +export class CreateDataverse implements Action { + readonly type = CREATE_DATAVERSE; + constructor(public payload: string) {} +} + +export class CreateDataverseSuccess implements Action { + readonly type = CREATE_DATAVERSE_SUCCESS; + constructor(public payload: Dataverse[]) {} +} + +export class CreateDataverseFail implements Action { + readonly type = CREATE_DATAVERSE_FAIL; + constructor(public payload: Dataverse) {} +} + +/* +* Update Dataverse +*/ +export class UpdateDataverse implements Action { + readonly type = UPDATE_DATAVERSE; + constructor(public payload: Dataverse) {} +} + +export class UpdateDataverseSuccess implements Action { + readonly type = UPDATE_DATAVERSE_SUCCESS; + constructor(public payload: Dataverse[]) {} +} + +export class UpdateDataverseFail implements Action { + readonly type = UPDATE_DATAVERSE_FAIL; + constructor(public payload: Dataverse) {} +} + +/* +* Drop Dataverse +*/ +export class DropDataverse implements Action { + readonly type = DROP_DATAVERSE; + constructor(public payload: string) {} +} + +export class DropDataverseSuccess implements Action { + readonly type = DROP_DATAVERSE_SUCCESS; + constructor(public payload: Dataverse[]) {} +} + +export class DropDataverseFail implements Action { + readonly type = DROP_DATAVERSE_FAIL; + constructor(public payload: Dataverse) {} +} + +/* +* Exports of datasverses actions +*/ +export type All = SelectDataverses | + SelectDataversesSuccess | + SelectDataversesFail | + CreateDataverse | + CreateDataverseSuccess | + CreateDataverseFail | + UpdateDataverse | + UpdateDataverseSuccess | + UpdateDataverseFail | + DropDataverse | + DropDataverseSuccess | + DropDataverseFail;
