Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions src/environments/environment.dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/

// This file can be replaced during build by using the `fileReplacements` array.
// `ng build` replaces `environment.ts` with `environment.prod.ts`.
// The list of file replacements can be found in `angular.json`.
import { Environment } from "./typings";

export const environment = {
export const environment: Environment = {
env: "development",
cloudUrl: "https://cloud.typedb.dev",
};

/*
Expand All @@ -19,4 +18,4 @@ export const environment = {
* This import should be commented out in production mode because it will have a negative impact
* on performance if an error is thrown.
*/
import 'zone.js/plugins/zone-error'; // Included with Angular CLI.
import 'zone.js/plugins/zone-error';
5 changes: 4 additions & 1 deletion src/environments/environment.prod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/

export const environment = {
import { Environment } from "./typings";

export const environment: Environment = {
env: "production",
cloudUrl: "https://cloud.typedb.com",
};
11 changes: 9 additions & 2 deletions src/environments/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,15 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/

export const environment = {
// This file can be replaced during build by using the `fileReplacements` array.
// `ng build` replaces `environment.ts` with `environment.prod.ts`.
// The list of file replacements can be found in `angular.json`.

import { Environment } from "./typings";

export const environment: Environment = {
env: "local",
cloudUrl: "http://localhost:8080",
};

/*
Expand All @@ -15,4 +22,4 @@ export const environment = {
* This import should be commented out in production mode because it will have a negative impact
* on performance if an error is thrown.
*/
import 'zone.js/plugins/zone-error'; // Included with Angular CLI.
import 'zone.js/plugins/zone-error';
5 changes: 3 additions & 2 deletions src/typings.d.ts → src/environments/typings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/

interface Window {
gtag: (arg0: string, arg1: string, arg2: object) => unknown;
export interface Environment {
env: string;
cloudUrl: string;
}
11 changes: 6 additions & 5 deletions src/framework/code-snippet/code-snippet.component.html
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
<div class="cs-root text-code" #rootElement (mouseenter)="showOverlay.set(true)" (mouseleave)="showOverlay.set(false)">
<div class="cs-root text-code" #rootElement>
<!-- Copy overlay - outside the scrollable area -->
<div class="copy-overlay" [class.visible]="showOverlay()" matTooltip="Copy" matTooltipPosition="below" (click)="copyCode()">
<i class="fas" [class.fa-copy]="!copied()" [class.fa-check]="copied()"></i>
</div>

<!-- Scrollable container for both line numbers and code -->
<div class="cs-scrollable-content">
Expand All @@ -18,5 +15,9 @@
<div class="cs-code-area">
<pre><code [class]="snippet.language ? 'language-' + snippet.language : undefined" [innerHTML]="snippet.code"></code></pre>
</div>

<div class="copy-overlay visible" (click)="copyCode()">
<i [class]="copied() ? 'fal fa-check' : 'fal fa-copy'"></i>
</div>
</div>
</div>
</div>
11 changes: 7 additions & 4 deletions src/framework/code-snippet/code-snippet.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@
:host {
display: block;
height: 100%;
/* Remove overflow: auto */
border: shapes.$border;
}

.cs-root {
min-height: 100%;
width: 100%;
position: relative;
height: 100%;
background: var(--body-background);
}

.cs-scrollable-content {
Expand All @@ -27,12 +27,15 @@
padding: 4px;
height: 100%;
overflow: auto; /* Move overflow here */
position: relative;
scrollbar-width: thin;
}

.cs-line-numbers {
flex-shrink: 0;
padding: 0 7px;
color: #66637f;
user-select: none;
}

.cs-code-area {
Expand All @@ -47,7 +50,7 @@
.copy-overlay {
position: absolute;
top: 12px;
right: 24px;
right: 12px;
display: flex;
align-items: center;
justify-content: center;
Expand Down Expand Up @@ -82,7 +85,7 @@
}

.copy-overlay:hover {
background: rgba(255, 255, 255, 0.15);
background: rgba(255, 255, 255, 0.1);
border-color: colors.$secondary-mid-deep-grey;
color: rgba(255, 255, 255, 1);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
Expand Down
19 changes: 8 additions & 11 deletions src/framework/code-snippet/code-snippet.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ import { AfterViewInit, ChangeDetectionStrategy, Component, ElementRef, Input, N

import Prism from "prismjs";
import { initCustomScrollbars } from "typedb-web-common/lib";
import { MatTooltipModule } from "@angular/material/tooltip";

const DEFAULT_MIN_LINES = { desktop: 33, mobile: 13 };
import { MatTooltip, MatTooltipModule } from "@angular/material/tooltip";

@Component({
selector: "tp-code-snippet",
Expand All @@ -26,17 +24,16 @@ export class CodeSnippetComponent implements AfterViewInit, OnChanges {
@ViewChild("scrollbarY") scrollbarY!: ElementRef<HTMLElement>;
@ViewChild("rootElement") rootElement!: ElementRef<HTMLElement>;

showOverlay = signal(false);
copied = signal(false);

get lineNumbers() {
return [...Array(Math.max(
(this.snippet.code.match(/\n/g) || []).length + 2,
DEFAULT_MIN_LINES.desktop,
)).keys()].map((n) => n + 1)
return [...Array(
(this.snippet.code.match(/\n/g) || []).length + 1,
).keys()].map((n) => n + 1)
}

constructor(private ngZone: NgZone, private elementRef: ElementRef) { }
constructor(private ngZone: NgZone, private elementRef: ElementRef) {
}

ngAfterViewInit() {
this.maybeInitScrollbarsAndHighlighting();
Expand All @@ -57,10 +54,10 @@ export class CodeSnippetComponent implements AfterViewInit, OnChanges {
await navigator.clipboard.writeText(this.snippet.code);
this.copied.set(true);

// Reset copied state after 2 seconds
// Reset copied state after 3 seconds
setTimeout(() => {
this.copied.set(false);
}, 2000);
}, 3000);
} catch (err) {
console.error('Failed to copy code:', err);
}
Expand Down
2 changes: 1 addition & 1 deletion src/framework/util/observable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ import { INTERNAL_ERROR } from "./strings";

export function requireValue<T>(behaviorSubject: BehaviorSubject<T | null>): T {
const value = behaviorSubject.value;
if (!value) throw INTERNAL_ERROR;
if (!value) throw new Error(INTERNAL_ERROR);
return value;
}
59 changes: 59 additions & 0 deletions src/module/agentic/ai-assist-tool-window.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<div class="card-header">
<i class="fa-light fa-message-dots"></i>
<h3>Chat</h3>
</div>
<div class="chat-container">
<div class="messages" #messagesContainer>
@for (msg of state.messages$ | async; track msg) {
<div class="message" [class.user]="msg.sender === 'user'" [class.ai]="msg.sender === 'ai'">
<div class="message-content">
@if (msg.isProcessing) {
<div class="typing-indicator">
<tp-spinner [size]="20"/>
</div>
} @else if (msg.sender === 'user' || msg.error || msg.content.startsWith('ERROR')) {
<div class="message-text">{{ msg.content }}@if (msg.error) {<div class="error-message"><i class="fa-solid fa-triangle-exclamation"></i>{{ msg.error }}</div>}</div>
} @else {
<tp-code-snippet [snippet]="{ language: 'typeql', code: msg.content }"/>
}
</div>
</div>
}

@if ((state.messages$ | async)?.length === 0) {
<div class="welcome-content">
<i class="fa-thin fa-sparkles"></i>
<h3>Query with agent mode.</h3>
<aside class="text-muted">AI responses may be inaccurate.</aside>
</div>
}
</div>

<div class="input-container">
<form (submit)="onSubmit($event)" class="message-form">
<div class="input-wrapper">
<mat-form-field appearance="outline">
<textarea matInput
[formControl]="state.promptControl"
[disabled]="(state.isProcessing$ | async) || true"
placeholder="e.g. Get all users and their attributes"
rows="3"
cdkTextareaAutosize
cdkAutosizeMinRows="1"
cdkAutosizeMaxRows="6"
(keydown.enter)="onInputKeyDownEnter($any($event))">
</textarea>
<button matSuffix
type="submit"
matIconButton
matTooltip="Send"
matTooltipShowDelay="500"
[disabled]="!state.promptControl.value || !(driver.database$ | async) || (state.isProcessing$ | async)"
[class.processing]="state.isProcessing$ | async">
<i class="fa-light fa-paper-plane-top"></i>
</button>
</mat-form-field>
</div>
</form>
</div>
</div>
Loading