Skip to content

Commit

Permalink
Kamu UI 434 ux resizable query input (#441)
Browse files Browse the repository at this point in the history
  • Loading branch information
dmitriy-borzenko authored Oct 7, 2024
1 parent 2883332 commit 13a1719
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 22 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## Unreleased
### Added
- Added the ability to resize the monaco editor vertically

## [0.27.1] - 2024-10-04
### Fixed
- Lineage graph: redirect to another dataset
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<span *ngIf="!isAdmin">Logs tab coming soon</span>
<ng-container *ngIf="isAdmin && grafanaTaskDetailsURL">
<p class="position-relative my-4 box p-4" data-test-id="grafana-logs-section">
You can <a [href]="grafanaTaskLogsUrl(this.grafanaTaskDetailsURL)">see logs in Grafana</a>
You can <a [href]="grafanaTaskLogsUrl(this.grafanaTaskDetailsURL)" target="_blank">see logs in Grafana</a>
<mat-icon class="admin-view text-muted"> admin_panel_settings</mat-icon>
</p>
</ng-container>
Original file line number Diff line number Diff line change
Expand Up @@ -141,18 +141,18 @@ <h2 class="box-title align-items-center pb-3 m-0">Query:</h2>
</div>
</div>

<div class="position-relative">
<div class="position-relative mt-4">
<ng-container *ngIf="!this.editorLoaded || sqlLoading">
<mat-progress-bar data-test-id="editor-progress-bar" class="position-absolute" mode="indeterminate" />
</ng-container>
<div class="border border-1 rounded-2 px-2 py-4 position-relative mt-2">
<app-sql-editor
[(template)]="sqlRequestCode"
[error]="sqlErrorMarker$ | async"
(onRunSql)="runSql()"
(onEditorLoaded)="hideProgressBar()"
/>
</div>

<app-sql-editor
[(template)]="sqlRequestCode"
[error]="sqlErrorMarker$ | async"
(onRunSql)="runSql()"
(onEditorLoaded)="hideProgressBar()"
/>

<div class="mt-3 text-end">
<app-request-timer
class="badge"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
</button>
</div>
</div>
<div class="mt-4 container-monaco py-4">
<div class="mt-4 container-monaco">
<app-sql-editor [(template)]="queries[i].query" height="300px" data-test-id="monaco-editor-modal" />
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { EditorError } from "../../models/error.model";
export abstract class BaseEditorComponent implements OnChanges {
@Input({ required: true }) public template = "";
@Input() public error: MaybeNull<string>;
@Input() public height: MaybeUndefined<string>;
@Input() public height: string = "220px";
@Input() public width: MaybeUndefined<string>;

@Output() public templateChange = new EventEmitter<string>();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
<ngx-monaco-editor
[ngStyle]="{ height: height, width: width }"
(onInit)="onInitEditor($event)"
[options]="EDITOR_OPTIONS"
[(ngModel)]="template"
(ngModelChange)="modelChange()"
/>
<div class="resizable pt-4">
<ngx-monaco-editor
[ngStyle]="{ height: height, width: width }"
(onInit)="onInitEditor($event)"
[options]="EDITOR_OPTIONS"
[(ngModel)]="template"
(ngModelChange)="modelChange()"
/>
<div class="cell-border-bottom"></div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
@import "var";

.resizable {
position: relative;
border-radius: 3px;
border: 1px solid $app-color-border-default;
}

.cell-border-bottom {
content: "";
position: absolute;
bottom: 0;
cursor: s-resize;
height: 9px;
width: 100%;
border-top: 1px solid #f1f1f1;
overflow: hidden;
background-color: #eff0f1;
background-image: url("https://cdn.sstatic.net/Sites/stackoverflow/img/sprites.svg"), none;
background-position: calc(100% / 2) -364px;
background-size: initial;
background-repeat: no-repeat;
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
import { ChangeDetectionStrategy, Component, EventEmitter, Output } from "@angular/core";
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
EventEmitter,
inject,
OnDestroy,
OnInit,
Output,
} from "@angular/core";
import * as monaco from "monaco-editor";

import { getMonacoNamespace } from "../../services/monaco.service";
import { BaseEditorComponent } from "../base-editor/base-editor.component";
import { getSqlError } from "../../helpers/editor-error-formatter";
import { fromEvent, filter, take, Subscription, takeWhile } from "rxjs";

const SQL_EDITOR_OPTIONS: monaco.editor.IStandaloneEditorConstructionOptions = {
theme: "vs",
Expand All @@ -12,21 +22,84 @@ const SQL_EDITOR_OPTIONS: monaco.editor.IStandaloneEditorConstructionOptions = {
minimap: {
enabled: false,
},
scrollPredominantAxis: true,
scrollBeyondLastLine: false,
tabSize: 2,
automaticLayout: true,
scrollbar: {
verticalHasArrows: true,
useShadows: false,
},
};

@Component({
selector: "app-sql-editor",
templateUrl: "./sql-editor.component.html",
styleUrls: ["./sql-editor.component.scss"],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class SqlEditorComponent extends BaseEditorComponent {
export class SqlEditorComponent extends BaseEditorComponent implements OnInit, OnDestroy {
public readonly EDITOR_OPTIONS: monaco.editor.IStandaloneEditorConstructionOptions = SQL_EDITOR_OPTIONS;
public getErrorDetails = getSqlError;

@Output() public onRunSql = new EventEmitter<null>();

private cdr = inject(ChangeDetectorRef);
private readonly INITIAL_EDITOR_HEIGHT = 200;
private readonly EDITOR_VERTICAL_PADDINGS = 30;

rectOld: DOMRect | undefined;
origin: {
x: number;
y: number;
};
moveSubscription: Subscription | undefined;
div: HTMLElement | null;
alive: boolean = true;

ngOnInit(): void {
/* istanbul ignore next */
fromEvent(document, "mousedown")
.pipe(
takeWhile(() => this.alive),
filter((event) => {
const className = (event.target as HTMLDivElement).className;
if (className && typeof className === "string") {
return className == "cell-border-bottom";
}
return false;
}),
)
.subscribe((event) => {
const mouseEvent = event as MouseEvent;
this.div = (event.target as HTMLDivElement).parentElement;
this.rectOld = this.div?.getBoundingClientRect();
this.origin = { x: mouseEvent.screenX, y: mouseEvent.screenY };
fromEvent(document, "mouseup")
.pipe(take(1))
.subscribe(() => {
if (this.moveSubscription) {
this.moveSubscription.unsubscribe();
this.moveSubscription = undefined;
}
});
if (!this.moveSubscription && this.div) {
this.moveSubscription = fromEvent(document, "mousemove").subscribe((moveEvent) => {
const incrTop = (moveEvent as MouseEvent).screenY - this.origin.y;
if (this.rectOld && this.div) {
const heigth = this.rectOld.height + incrTop;
this.div.style.height =
(heigth < this.INITIAL_EDITOR_HEIGHT ? this.INITIAL_EDITOR_HEIGHT : heigth) + "px";
this.height =
(heigth < this.INITIAL_EDITOR_HEIGHT
? this.INITIAL_EDITOR_HEIGHT - this.EDITOR_VERTICAL_PADDINGS
: heigth - this.EDITOR_VERTICAL_PADDINGS) + "px";
this.cdr.detectChanges();
}
});
}
});
}

public onInitEditor(editor: monaco.editor.IStandaloneCodeEditor): void {
super.onInitEditor(editor);

Expand All @@ -52,4 +125,8 @@ export class SqlEditorComponent extends BaseEditorComponent {
});
}
}

ngOnDestroy() {
this.alive = false;
}
}

0 comments on commit 13a1719

Please sign in to comment.