diff --git a/bot/admin/web/src/app/analytics/activity/activity.component.ts b/bot/admin/web/src/app/analytics/activity/activity.component.ts
index b629ab5555..a7d705cf6e 100644
--- a/bot/admin/web/src/app/analytics/activity/activity.component.ts
+++ b/bot/admin/web/src/app/analytics/activity/activity.component.ts
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-import { Component, OnInit } from '@angular/core';
+import { Component, OnDestroy, OnInit } from '@angular/core';
// import * as html2pdf from 'html2pdf.js';
import { StateService } from 'src/app/core-nlp/state.service';
import { BotConfigurationService } from 'src/app/core/bot-configuration.service';
@@ -28,13 +28,15 @@ import { UserAnalyticsQueryResult } from '../users/users';
import { UserFilter } from '../users/users.component';
import { toISOStringWithoutOffset } from '../../shared/utils';
import { SelectBotEvent } from '../../shared/components';
+import { Subject, takeUntil } from 'rxjs';
@Component({
selector: 'tock-activity',
templateUrl: './activity.component.html',
styleUrls: ['./activity.component.css']
})
-export class ActivityComponent implements OnInit {
+export class ActivityComponent implements OnInit, OnDestroy {
+ destroy$ = new Subject();
startDate: Date;
endDate: Date;
selectedConnectorId: string;
@@ -78,7 +80,7 @@ export class ActivityComponent implements OnInit {
variationUsersPercentage: number;
constructor(private state: StateService, private analytics: AnalyticsService, private botConfiguration: BotConfigurationService) {
- this.botConfiguration.configurations.subscribe((configs) => {
+ this.botConfiguration.configurations.pipe(takeUntil(this.destroy$)).subscribe((configs) => {
this.configurations = configs;
});
this.userPreferences = this.analytics.getUserPreferences();
@@ -375,4 +377,9 @@ export class ActivityComponent implements OnInit {
waitAndRefresh() {
setTimeout((_) => this.reload());
}
+
+ ngOnDestroy(): void {
+ this.destroy$.next(true);
+ this.destroy$.complete();
+ }
}
diff --git a/bot/admin/web/src/app/analytics/dialogs/dialogs-list/dialogs-list.component.html b/bot/admin/web/src/app/analytics/dialogs/dialogs-list/dialogs-list.component.html
index 0c18350f21..75402ae8f9 100644
--- a/bot/admin/web/src/app/analytics/dialogs/dialogs-list/dialogs-list.component.html
+++ b/bot/admin/web/src/app/analytics/dialogs/dialogs-list/dialogs-list.component.html
@@ -137,17 +137,18 @@
+
+
+
+
-
- No dialogs found!
-
-
+
-
-
-
-
diff --git a/bot/admin/web/src/app/analytics/dialogs/dialogs-list/dialogs-list.component.scss b/bot/admin/web/src/app/analytics/dialogs/dialogs-list/dialogs-list.component.scss
index 824227d493..01dba2674e 100644
--- a/bot/admin/web/src/app/analytics/dialogs/dialogs-list/dialogs-list.component.scss
+++ b/bot/admin/web/src/app/analytics/dialogs/dialogs-list/dialogs-list.component.scss
@@ -13,3 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+.loader {
+ min-height: 20vh;
+}
diff --git a/bot/admin/web/src/app/analytics/dialogs/dialogs-list/dialogs-list.component.ts b/bot/admin/web/src/app/analytics/dialogs/dialogs-list/dialogs-list.component.ts
index 53eed324b0..61a8564107 100644
--- a/bot/admin/web/src/app/analytics/dialogs/dialogs-list/dialogs-list.component.ts
+++ b/bot/admin/web/src/app/analytics/dialogs/dialogs-list/dialogs-list.component.ts
@@ -69,32 +69,27 @@ export class DialogsListComponent implements OnInit, OnChanges, OnDestroy {
private route: ActivatedRoute,
public botSharedService: BotSharedService,
private router: Router
- ) {
- this.state = state;
-
- this.botConfiguration.configurations.pipe(takeUntil(this.destroy$)).subscribe((configs) => {
- this.isSatisfactionRoute().subscribe((res) => {
- this.botSharedService.getIntentsByApplication(this.state.currentApplication._id).subscribe((intents) => (this.intents = intents));
-
- this.configurationNameList = configs.filter((item) => item.targetConfigurationId == null).map((item) => item.applicationId);
-
- if (res) {
- this.ratingFilter = [1, 2, 3, 4, 5];
- }
- this.refresh();
- });
- });
+ ) {}
+ ngOnInit() {
this.botSharedService
.getConnectorTypes()
.pipe(take(1))
.subscribe((confConf) => {
this.connectorTypes = confConf.map((it) => it.connectorType);
});
- }
- ngOnInit() {
- this.load();
+ this.botConfiguration.configurations.pipe(takeUntil(this.destroy$)).subscribe((configs) => {
+ this.botSharedService.getIntentsByApplication(this.state.currentApplication._id).subscribe((intents) => (this.intents = intents));
+
+ this.configurationNameList = configs
+ .filter((item) => item.targetConfigurationId == null)
+ .map((item) => {
+ return item.applicationId;
+ });
+
+ this.refresh();
+ });
}
ngOnChanges(changes: SimpleChanges) {
diff --git a/bot/admin/web/src/app/analytics/satisfaction/satisfaction.component.html b/bot/admin/web/src/app/analytics/satisfaction/satisfaction.component.html
index d452c40c45..dac0831e90 100644
--- a/bot/admin/web/src/app/analytics/satisfaction/satisfaction.component.html
+++ b/bot/admin/web/src/app/analytics/satisfaction/satisfaction.component.html
@@ -1,11 +1,19 @@
-
+
+
+
Satisfaction
+
+
+
+
+
+
-
-
{{errorMsg}}
+
{{ errorMsg }}
+
diff --git a/bot/admin/web/src/app/analytics/satisfaction/satisfaction.component.ts b/bot/admin/web/src/app/analytics/satisfaction/satisfaction.component.ts
index d279c186db..313e8852fa 100644
--- a/bot/admin/web/src/app/analytics/satisfaction/satisfaction.component.ts
+++ b/bot/admin/web/src/app/analytics/satisfaction/satisfaction.component.ts
@@ -14,42 +14,50 @@
* limitations under the License.
*/
-import {Component, OnInit} from '@angular/core';
-import {AnalyticsService} from "../analytics.service";
-import {StateService} from 'src/app/core-nlp/state.service';
+import { Component, OnDestroy, OnInit } from '@angular/core';
+import { AnalyticsService } from '../analytics.service';
+import { StateService } from 'src/app/core-nlp/state.service';
+import { BotConfigurationService } from '../../core/bot-configuration.service';
+import { Subject, take, takeUntil } from 'rxjs';
+import { BotApplicationConfiguration } from '../../core/model/configuration';
@Component({
selector: 'tock-satisfaction',
templateUrl: './satisfaction.component.html',
styleUrls: ['./satisfaction.component.css']
})
-export class SatisfactionComponent implements OnInit {
+export class SatisfactionComponent implements OnInit, OnDestroy {
+ destroy = new Subject();
+ configurations: BotApplicationConfiguration[];
isStatisfactionActivated: boolean = false;
errorMsg: string;
- public loaded: boolean = false;
+ public loading: boolean = true;
- constructor(
- private analytics: AnalyticsService,
- private state: StateService
- ) {
- }
+ constructor(private analytics: AnalyticsService, private state: StateService, private botConfiguration: BotConfigurationService) {}
ngOnInit(): void {
- this.state.currentIntents.subscribe(() => {
- this.isActiveSatisfaction()
+ this.botConfiguration.configurations.pipe(takeUntil(this.destroy)).subscribe((confs) => {
+ this.configurations = confs;
+
+ if (this.configurations.length) this.isActiveSatisfaction();
+
+ this.loading = false;
});
}
isActiveSatisfaction() {
this.errorMsg = null;
- this.loaded = false;
- this.analytics.isActiveSatisfactionByBot()
- .subscribe((res: boolean) =>
- this.isStatisfactionActivated = res,
- err => this.errorMsg = err,
- () => this.loaded = true);
+ this.analytics
+ .isActiveSatisfactionByBot()
+ .pipe(take(1))
+ .subscribe({
+ next: (res: boolean) => (this.isStatisfactionActivated = res),
+ error: (err) => (this.errorMsg = err)
+ });
}
-
+ ngOnDestroy() {
+ this.destroy.next(true);
+ this.destroy.complete();
+ }
}
-
diff --git a/bot/admin/web/src/app/applications/namespace/namespaces.component.html b/bot/admin/web/src/app/applications/namespace/namespaces.component.html
index 5036d0fa35..53accea90e 100644
--- a/bot/admin/web/src/app/applications/namespace/namespaces.component.html
+++ b/bot/admin/web/src/app/applications/namespace/namespaces.component.html
@@ -34,7 +34,7 @@ Namespaces
diff --git a/bot/admin/web/src/app/applications/namespace/namespaces.component.ts b/bot/admin/web/src/app/applications/namespace/namespaces.component.ts
index 564dd167ba..4c09abc7e4 100644
--- a/bot/admin/web/src/app/applications/namespace/namespaces.component.ts
+++ b/bot/admin/web/src/app/applications/namespace/namespaces.component.ts
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-import { Component, ElementRef, OnDestroy, OnInit, ViewChild } from '@angular/core';
+import { Component, OnDestroy } from '@angular/core';
import { StateService } from '../../core-nlp/state.service';
import { ApplicationService } from '../../core-nlp/applications.service';
import { NamespaceConfiguration, NamespaceSharingConfiguration, UserNamespace } from '../../model/application';
@@ -30,9 +30,8 @@ import { Subject, takeUntil } from 'rxjs';
templateUrl: 'namespaces.component.html',
styleUrls: ['namespaces.component.scss']
})
-export class NamespacesComponent implements OnInit, OnDestroy {
+export class NamespacesComponent implements OnDestroy {
destroy = new Subject();
- namespaces: UserNamespace[];
managedNamespace: string;
managedUsers: UserNamespace[];
@@ -53,22 +52,10 @@ export class NamespacesComponent implements OnInit, OnDestroy {
private nbDialogService: NbDialogService
) {}
- ngOnInit(): void {
- this.state.currentApplicationEmitter.pipe(takeUntil(this.destroy)).subscribe((arg) => {
- this.grabNamespaces();
- });
- this.grabNamespaces();
- }
-
- grabNamespaces(): void {
- this.applicationService.getNamespaces().subscribe((n) => (this.namespaces = n));
- }
-
selectNamespace(namespace: string): void {
this.applicationService.selectNamespace(namespace).subscribe((_) =>
this.authService.loadUser().subscribe((_) => {
- this.applicationService.resetConfiguration;
- this.grabNamespaces();
+ this.applicationService.resetConfiguration();
})
);
}
@@ -85,7 +72,7 @@ export class NamespacesComponent implements OnInit, OnDestroy {
const modal = this.nbDialogService.open(CreateNamespaceComponent);
const validate = modal.componentRef.instance.validate.pipe(takeUntil(this.destroy)).subscribe((result) => {
this.applicationService.createNamespace(result.name.trim()).subscribe((b) => {
- this.ngOnInit();
+ this.applicationService.resetConfiguration();
});
this.closeEdition();
modal.close();
diff --git a/bot/admin/web/src/app/bot/i18n/i18n-filters/i18n-filters.component.ts b/bot/admin/web/src/app/bot/i18n/i18n-filters/i18n-filters.component.ts
index be27faf240..f2381dd242 100644
--- a/bot/admin/web/src/app/bot/i18n/i18n-filters/i18n-filters.component.ts
+++ b/bot/admin/web/src/app/bot/i18n/i18n-filters/i18n-filters.component.ts
@@ -38,7 +38,7 @@ export class I18nFiltersComponent implements OnInit {
constructor(public state: StateService) {}
ngOnInit(): void {
- this.form.valueChanges.pipe(takeUntil(this.destroy$), debounceTime(250)).subscribe(() => this.submitFiltersChange());
+ this.form.valueChanges.pipe(debounceTime(250), takeUntil(this.destroy$)).subscribe(() => this.submitFiltersChange());
}
form = new FormGroup({
diff --git a/bot/admin/web/src/app/bot/story/edit-story/edit-story.component.ts b/bot/admin/web/src/app/bot/story/edit-story/edit-story.component.ts
index 43aa551fcd..b6ff889300 100644
--- a/bot/admin/web/src/app/bot/story/edit-story/edit-story.component.ts
+++ b/bot/admin/web/src/app/bot/story/edit-story/edit-story.component.ts
@@ -1,6 +1,6 @@
import { Component, OnDestroy, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
-import { Subject, take, takeUntil } from 'rxjs';
+import { Subject, take } from 'rxjs';
import { BotService } from '../../bot-service';
import { StoryDefinitionConfiguration } from '../../model/story';
diff --git a/bot/admin/web/src/app/bot/story/search-story/stories-filter/stories-filter.component.ts b/bot/admin/web/src/app/bot/story/search-story/stories-filter/stories-filter.component.ts
index 9939e4b34b..cfe1b44e48 100644
--- a/bot/admin/web/src/app/bot/story/search-story/stories-filter/stories-filter.component.ts
+++ b/bot/admin/web/src/app/bot/story/search-story/stories-filter/stories-filter.component.ts
@@ -49,7 +49,7 @@ export class StoriesFilterComponent implements OnInit, OnDestroy {
}
ngOnInit(): void {
- this.form.valueChanges.pipe(takeUntil(this.destroy$), debounceTime(300)).subscribe(() => {
+ this.form.valueChanges.pipe(debounceTime(300), takeUntil(this.destroy$)).subscribe(() => {
this.onFilter.emit(this.form.value as StoriesFilters);
});
}
diff --git a/bot/admin/web/src/app/configuration/bot-configurations/bot-configuration/bot-configuration.component.html b/bot/admin/web/src/app/configuration/bot-configurations/bot-configuration/bot-configuration.component.html
index 403b1f2499..0ce16624c1 100644
--- a/bot/admin/web/src/app/configuration/bot-configurations/bot-configuration/bot-configuration.component.html
+++ b/bot/admin/web/src/app/configuration/bot-configurations/bot-configuration/bot-configuration.component.html
@@ -15,7 +15,15 @@
-->
-
+
+
+
-
+
diff --git a/bot/admin/web/src/app/configuration/observability-settings/observability-settings.component.ts b/bot/admin/web/src/app/configuration/observability-settings/observability-settings.component.ts
index 6b6508ef2a..fa0193162e 100644
--- a/bot/admin/web/src/app/configuration/observability-settings/observability-settings.component.ts
+++ b/bot/admin/web/src/app/configuration/observability-settings/observability-settings.component.ts
@@ -46,7 +46,7 @@ export class ObservabilitySettingsComponent implements OnInit, OnDestroy {
) {}
ngOnInit(): void {
- this.form.valueChanges.pipe(takeUntil(this.destroy$), debounceTime(200)).subscribe(() => {
+ this.form.valueChanges.pipe(debounceTime(200), takeUntil(this.destroy$)).subscribe(() => {
this.setActivationDisabledState();
});
diff --git a/bot/admin/web/src/app/configuration/sentence-generation-settings/sentence-generation-settings.component.ts b/bot/admin/web/src/app/configuration/sentence-generation-settings/sentence-generation-settings.component.ts
index 70f25c9f07..01d40c8651 100644
--- a/bot/admin/web/src/app/configuration/sentence-generation-settings/sentence-generation-settings.component.ts
+++ b/bot/admin/web/src/app/configuration/sentence-generation-settings/sentence-generation-settings.component.ts
@@ -50,7 +50,7 @@ export class SentenceGenerationSettingsComponent implements OnInit, OnDestroy {
) {}
ngOnInit(): void {
- this.form.valueChanges.pipe(takeUntil(this.destroy$), debounceTime(200)).subscribe(() => {
+ this.form.valueChanges.pipe(debounceTime(200), takeUntil(this.destroy$)).subscribe(() => {
this.setActivationDisabledState();
});
diff --git a/bot/admin/web/src/app/configuration/synchronization/synchronization.component.html b/bot/admin/web/src/app/configuration/synchronization/synchronization.component.html
index 2ff62ca4d5..bab1188fbe 100644
--- a/bot/admin/web/src/app/configuration/synchronization/synchronization.component.html
+++ b/bot/admin/web/src/app/configuration/synchronization/synchronization.component.html
@@ -25,7 +25,7 @@ Synchronize BOTS contents (configuration)
(selectedChange)="selectSourceNamespace(this.sourceNamespace)"
>
{{ namespace.namespace }}
@@ -51,7 +51,7 @@ Synchronize BOTS contents (configuration)
(selectedChange)="selectTargetNamespace(this.targetNamespace)"
>
{{ namespace.namespace }}
diff --git a/bot/admin/web/src/app/configuration/synchronization/synchronization.component.ts b/bot/admin/web/src/app/configuration/synchronization/synchronization.component.ts
index 1544963542..f81371e06d 100644
--- a/bot/admin/web/src/app/configuration/synchronization/synchronization.component.ts
+++ b/bot/admin/web/src/app/configuration/synchronization/synchronization.component.ts
@@ -1,7 +1,6 @@
import { Component, OnInit } from '@angular/core';
import { ApplicationService } from '../../core-nlp/applications.service';
import { Application, UserNamespace } from '../../model/application';
-import { AuthService } from '../../core-nlp/auth/auth.service';
import { StateService } from '../../core-nlp/state.service';
import { BotConfigurationService } from '../../core/bot-configuration.service';
import { DialogService } from '../../core-nlp/dialog.service';
@@ -16,7 +15,6 @@ import { ChoiceDialogComponent } from '../../shared/components';
styleUrls: ['./synchronization.component.css']
})
export class SynchronizationComponent implements OnInit {
- namespaces: UserNamespace[];
sourceNamespace: UserNamespace;
targetNamespace: UserNamespace;
sourceApplications: Application[];
@@ -27,7 +25,6 @@ export class SynchronizationComponent implements OnInit {
constructor(
private applicationService: ApplicationService,
- private authService: AuthService,
public state: StateService,
private botConfigurationService: BotConfigurationService,
private dialog: DialogService,
@@ -36,7 +33,6 @@ export class SynchronizationComponent implements OnInit {
private router: Router
) {}
ngOnInit(): void {
- this.applicationService.getNamespaces().subscribe((n) => (this.namespaces = n));
this.sourceApplications = this.state.applications;
}
@@ -67,7 +63,7 @@ export class SynchronizationComponent implements OnInit {
context: {
title: 'Overwrite configuration?',
subtitle: `During synchronization, configuration will be copied from the source application to the target application (answers, stories, training).
-
+
Please note : ${inboxMessagesCopySubtitle}
The synchronization of both applications will be permanent, and there will be no way to reverse it. Do you want to continue?
diff --git a/bot/admin/web/src/app/configuration/vector-db-settings/vector-db-settings.component.ts b/bot/admin/web/src/app/configuration/vector-db-settings/vector-db-settings.component.ts
index 734bade90e..7d8e17da85 100644
--- a/bot/admin/web/src/app/configuration/vector-db-settings/vector-db-settings.component.ts
+++ b/bot/admin/web/src/app/configuration/vector-db-settings/vector-db-settings.component.ts
@@ -46,7 +46,7 @@ export class VectorDbSettingsComponent implements OnInit {
) {}
ngOnInit(): void {
- this.form.valueChanges.pipe(takeUntil(this.destroy$), debounceTime(200)).subscribe(() => {
+ this.form.valueChanges.pipe(debounceTime(200), takeUntil(this.destroy$)).subscribe(() => {
this.setActivationDisabledState();
});
diff --git a/bot/admin/web/src/app/core-nlp/applications.service.ts b/bot/admin/web/src/app/core-nlp/applications.service.ts
index 172bd2c6f3..6abe15e394 100644
--- a/bot/admin/web/src/app/core-nlp/applications.service.ts
+++ b/bot/admin/web/src/app/core-nlp/applications.service.ts
@@ -62,8 +62,9 @@ export class ApplicationService implements OnDestroy {
}
resetConfiguration() {
- this.locales().subscribe((locales) => (this.state.locales = locales));
- this.nlpEngineTypes().subscribe((engines) => (this.state.supportedNlpEngines = engines));
+ this.getLocales().subscribe((locales) => (this.state.locales = locales));
+ this.getNlpEngineTypes().subscribe((engines) => (this.state.supportedNlpEngines = engines));
+ this.getNamespaces().subscribe((namespaces) => (this.state.namespaces = namespaces));
this.getApplications().subscribe((applications) => {
this.state.applications = applications;
this.state.currentApplication = null;
@@ -79,8 +80,28 @@ export class ApplicationService implements OnDestroy {
return this.getApplicationsPending;
}
- nlpEngineTypes(): Observable {
- return this.rest.getArray('/nlp-engines', NlpEngineType.fromJSONArray);
+ getNamespacesPending: Observable;
+ getNamespaces(): Observable {
+ if (!this.getNamespacesPending) {
+ this.getNamespacesPending = this.rest.get(`/namespaces`, UserNamespace.fromJSONArray).pipe(share());
+ }
+ return this.getNamespacesPending;
+ }
+
+ getLocalesPending: Observable[]>;
+ getLocales(): Observable[]> {
+ if (!this.getLocalesPending) {
+ this.getLocalesPending = this.rest.get(`/locales`, (m) => Entry.fromJSONArray(m)).pipe(share());
+ }
+ return this.getLocalesPending;
+ }
+
+ getNlpEngineTypesPending: Observable;
+ getNlpEngineTypes(): Observable {
+ if (!this.getNlpEngineTypesPending) {
+ this.getNlpEngineTypesPending = this.rest.getArray('/nlp-engines', NlpEngineType.fromJSONArray).pipe(share());
+ }
+ return this.getNlpEngineTypesPending;
}
triggerBuild(application: Application) {
@@ -135,10 +156,6 @@ export class ApplicationService implements OnDestroy {
}
}
- locales(): Observable[]> {
- return this.rest.get(`/locales`, (m) => Entry.fromJSONArray(m));
- }
-
getApplicationDump(application: Application): Observable {
return this.rest.get(`/application/dump/${application._id}`, (r) => new Blob([JSON.stringify(r)], { type: 'application/json' }));
}
@@ -167,10 +184,6 @@ export class ApplicationService implements OnDestroy {
this.rest.setFileUploaderOptions(uploader, url);
}
- getNamespaces(): Observable {
- return this.rest.get(`/namespaces`, UserNamespace.fromJSONArray);
- }
-
getUsersForNamespace(namespace: string): Observable {
return this.rest.get(`/namespaces/${namespace}`, UserNamespace.fromJSONArray);
}
diff --git a/bot/admin/web/src/app/core-nlp/state.service.ts b/bot/admin/web/src/app/core-nlp/state.service.ts
index 2af869deb2..e7f6d76864 100644
--- a/bot/admin/web/src/app/core-nlp/state.service.ts
+++ b/bot/admin/web/src/app/core-nlp/state.service.ts
@@ -16,7 +16,7 @@
import { map } from 'rxjs/operators';
import { EventEmitter, Injectable } from '@angular/core';
-import { Application } from '../model/application';
+import { Application, UserNamespace } from '../model/application';
import { AuthService } from './auth/auth.service';
import { AuthListener } from './auth/auth.listener';
import { User, UserRole } from '../model/auth';
@@ -44,6 +44,7 @@ export class StateService implements AuthListener {
supportedNlpEngines: NlpEngineType[];
user: User;
+ namespaces: UserNamespace[];
applications: Application[];
dateRange = { start: null, end: null, rangeInDays: null };
@@ -265,6 +266,7 @@ export class StateService implements AuthListener {
logout() {
this.user = null;
this.currentApplication = null;
+ this.namespaces = null;
this.applications = null;
}
diff --git a/bot/admin/web/src/app/core/bot-configuration.service.ts b/bot/admin/web/src/app/core/bot-configuration.service.ts
index 38d2d4f92a..7db39dd6d1 100644
--- a/bot/admin/web/src/app/core/bot-configuration.service.ts
+++ b/bot/admin/web/src/app/core/bot-configuration.service.ts
@@ -17,10 +17,10 @@
import { Injectable, OnDestroy } from '@angular/core';
import { RestService } from '../core-nlp/rest/rest.service';
import { StateService } from '../core-nlp/state.service';
-import { BehaviorSubject, Observable, Subscription, forkJoin } from 'rxjs';
+import { BehaviorSubject, Observable, Subscription, forkJoin, share } from 'rxjs';
import { ApplicationScopedQuery } from '../model/commons';
import { BotApplicationConfiguration, BotConfiguration, ConnectorType } from './model/configuration';
-import { SynchronizationConfiguration } from "./model/synchronizationConfiguration";
+import { SynchronizationConfiguration } from './model/synchronizationConfiguration';
@Injectable()
export class BotConfigurationService implements OnDestroy {
@@ -38,8 +38,9 @@ export class BotConfigurationService implements OnDestroy {
readonly bots: BehaviorSubject = new BehaviorSubject([]);
constructor(private rest: RestService, private state: StateService) {
- this.subscription = this.state.configurationChange.subscribe((_) => this.updateConfigurations());
- this.updateConfigurations();
+ this.subscription = this.state.configurationChange.subscribe((_) => {
+ this.updateConfigurations();
+ });
}
ngOnDestroy(): void {
@@ -86,8 +87,12 @@ export class BotConfigurationService implements OnDestroy {
return this.rest.post('/configuration/synchronization', conf);
}
+ getBotsPending: Observable;
private getBots(botId: string): Observable {
- return this.rest.get(`/bots/${botId}`, BotConfiguration.fromJSONArray);
+ if (!this.getBotsPending) {
+ this.getBotsPending = this.rest.get(`/bots/${botId}`, BotConfiguration.fromJSONArray).pipe(share());
+ }
+ return this.getBotsPending;
}
findApplicationConfigurationById(id: string): BotApplicationConfiguration {
@@ -114,9 +119,9 @@ export class BotConfigurationService implements OnDestroy {
findValidPath(connectorType: ConnectorType): string {
const bots = this.bots.getValue();
- const baseTargetPath = `/io/${this.state.user.organization.toLowerCase().replace(/\s/g, '')}/${this.state.currentApplication.name.replace(/\s/g, '_')}/${
- connectorType.id
- }`;
+ const baseTargetPath = `/io/${this.state.user.organization
+ .toLowerCase()
+ .replace(/\s/g, '')}/${this.state.currentApplication.name.replace(/\s/g, '_')}/${connectorType.id}`;
let targetPath = baseTargetPath;
let index = 1;
while (bots.findIndex((b) => b.configurations && b.configurations.findIndex((c) => c.path === targetPath) !== -1) !== -1) {
diff --git a/bot/admin/web/src/app/language-understanding/intents/intents-filters/intents-filters.component.ts b/bot/admin/web/src/app/language-understanding/intents/intents-filters/intents-filters.component.ts
index 0ea5da7188..cba4b41e1a 100644
--- a/bot/admin/web/src/app/language-understanding/intents/intents-filters/intents-filters.component.ts
+++ b/bot/admin/web/src/app/language-understanding/intents/intents-filters/intents-filters.component.ts
@@ -29,7 +29,7 @@ export class IntentsFiltersComponent implements OnInit, OnDestroy {
}
ngOnInit(): void {
- this.form.valueChanges.pipe(takeUntil(this.destroy$), debounceTime(300)).subscribe(() => {
+ this.form.valueChanges.pipe(debounceTime(300), takeUntil(this.destroy$)).subscribe(() => {
this.onFilter.emit(this.form.value as IntentsFilter);
});
}
diff --git a/bot/admin/web/src/app/metrics/indicators/indicators-filters/indicators-filters.component.ts b/bot/admin/web/src/app/metrics/indicators/indicators-filters/indicators-filters.component.ts
index 94101984a1..460afc19ad 100644
--- a/bot/admin/web/src/app/metrics/indicators/indicators-filters/indicators-filters.component.ts
+++ b/bot/admin/web/src/app/metrics/indicators/indicators-filters/indicators-filters.component.ts
@@ -42,7 +42,7 @@ export class IndicatorsFiltersComponent implements OnInit, OnDestroy {
}
ngOnInit() {
- this.form.valueChanges.pipe(takeUntil(this.destroy), debounceTime(500)).subscribe(() => {
+ this.form.valueChanges.pipe(debounceTime(500), takeUntil(this.destroy)).subscribe(() => {
this.onFilter.emit(this.form.value as IndicatorsFilter);
});
}
diff --git a/bot/admin/web/src/app/model-quality/count-stats/count-stats.component.ts b/bot/admin/web/src/app/model-quality/count-stats/count-stats.component.ts
index 88b939689f..459401a4a2 100644
--- a/bot/admin/web/src/app/model-quality/count-stats/count-stats.component.ts
+++ b/bot/admin/web/src/app/model-quality/count-stats/count-stats.component.ts
@@ -33,7 +33,7 @@ export class CountStatsComponent implements OnInit, OnDestroy {
constructor(public state: StateService, private qualityService: QualityService) {}
ngOnInit(): void {
- this.form.valueChanges.pipe(takeUntil(this.destroy), debounceTime(500)).subscribe(() => {
+ this.form.valueChanges.pipe(debounceTime(500), takeUntil(this.destroy)).subscribe(() => {
if (isNaN(parseInt(this.minCount.value))) {
this.minCount.patchValue(1);
}
diff --git a/bot/admin/web/src/app/model-quality/intent-quality/intent-quality.component.ts b/bot/admin/web/src/app/model-quality/intent-quality/intent-quality.component.ts
index 02d22b1a77..162508e3c1 100644
--- a/bot/admin/web/src/app/model-quality/intent-quality/intent-quality.component.ts
+++ b/bot/admin/web/src/app/model-quality/intent-quality/intent-quality.component.ts
@@ -24,7 +24,7 @@ export class IntentQualityComponent implements OnInit, OnDestroy {
constructor(private state: StateService, private quality: QualityService) {}
ngOnInit(): void {
- this.form.valueChanges.pipe(takeUntil(this.destroy), debounceTime(500)).subscribe(() => {
+ this.form.valueChanges.pipe(debounceTime(500), takeUntil(this.destroy)).subscribe(() => {
if (isNaN(parseInt(this.minOccurrences.value))) {
this.minOccurrences.patchValue(1);
}
diff --git a/bot/admin/web/src/app/shared/components/sentence-training/sentence-training-filters/sentence-training-filters.component.ts b/bot/admin/web/src/app/shared/components/sentence-training/sentence-training-filters/sentence-training-filters.component.ts
index 9030e28c30..0803d69fa7 100644
--- a/bot/admin/web/src/app/shared/components/sentence-training/sentence-training-filters/sentence-training-filters.component.ts
+++ b/bot/admin/web/src/app/shared/components/sentence-training/sentence-training-filters/sentence-training-filters.component.ts
@@ -149,7 +149,7 @@ export class SentenceTrainingFiltersComponent implements OnInit, OnDestroy {
this.updateEntitiesFilters();
- this.form.valueChanges.pipe(takeUntil(this.destroy$), debounceTime(500)).subscribe(() => this.submitFiltersChange());
+ this.form.valueChanges.pipe(debounceTime(500), takeUntil(this.destroy$)).subscribe(() => this.submitFiltersChange());
}
submitFiltersChange(): void {
diff --git a/bot/admin/web/src/app/shared/components/sentence-training/sentence-training.component.ts b/bot/admin/web/src/app/shared/components/sentence-training/sentence-training.component.ts
index 159364b2cf..e420c0573e 100644
--- a/bot/admin/web/src/app/shared/components/sentence-training/sentence-training.component.ts
+++ b/bot/admin/web/src/app/shared/components/sentence-training/sentence-training.component.ts
@@ -57,6 +57,7 @@ export class SentenceTrainingComponent implements OnInit, OnDestroy {
@ViewChild('sentenceTrainingFilter') sentenceTrainingFilter: SentenceTrainingFiltersComponent;
loading: boolean = false;
+ unloading: boolean = false;
sentences: SentenceExtended[] = [];
@@ -187,7 +188,7 @@ export class SentenceTrainingComponent implements OnInit, OnDestroy {
): Observable> {
if (showLoadingSpinner) this.loading = true;
- let search = this.search(this.state.createPaginatedQuery(start, size)).pipe(takeUntil(this.destroy$), share());
+ let search = this.search(this.state.createPaginatedQuery(start, size)).pipe(share(), takeUntil(this.destroy$));
search.subscribe({
next: (data: PaginatedResult) => {
@@ -372,6 +373,8 @@ export class SentenceTrainingComponent implements OnInit, OnDestroy {
}
retrieveSentence(sentence: SentenceExtended, tryCount = 0): Subscription | void {
+ if (this.unloading) return;
+
let exists = this.sentences.find((stnce) => {
return stnce.text == sentence.text;
});
@@ -574,6 +577,7 @@ Would you like to translate all the sentences matching the search criteria above
}
ngOnDestroy(): void {
+ this.unloading = true;
this.destroy$.next(true);
this.destroy$.complete();
}
diff --git a/bot/admin/web/src/app/theme/components/header/header.component.html b/bot/admin/web/src/app/theme/components/header/header.component.html
index ee20de4758..97fcb8a2b1 100644
--- a/bot/admin/web/src/app/theme/components/header/header.component.html
+++ b/bot/admin/web/src/app/theme/components/header/header.component.html
@@ -65,7 +65,7 @@
-
+
{{ namespace.namespace }}
diff --git a/bot/admin/web/src/app/theme/components/header/header.component.ts b/bot/admin/web/src/app/theme/components/header/header.component.ts
index 1de1356107..89bcd30a00 100644
--- a/bot/admin/web/src/app/theme/components/header/header.component.ts
+++ b/bot/admin/web/src/app/theme/components/header/header.component.ts
@@ -23,7 +23,6 @@ import { SettingsService } from '../../../core-nlp/settings.service';
import { Subject, take, takeUntil } from 'rxjs';
import { APP_BASE_HREF } from '@angular/common';
import { ApplicationService } from '../../../core-nlp/applications.service';
-import { UserNamespace } from '../../../model/application';
import { BotConfigurationService } from '../../../core/bot-configuration.service';
import { CoreConfig } from '../../../core-nlp/core.config';
import { Router } from '@angular/router';
@@ -40,8 +39,6 @@ export class HeaderComponent implements OnInit, OnDestroy {
currentTheme = 'default';
- namespaces: UserNamespace[];
-
currentApplicationName: string;
constructor(
@@ -69,8 +66,6 @@ export class HeaderComponent implements OnInit, OnDestroy {
}
this.botConfiguration.configurations.pipe(takeUntil(this.destroy)).subscribe((confs) => {
- this.grabNamespaces();
-
this.currentApplicationName = '';
setTimeout(() => {
this.currentApplicationName = this.state?.currentApplication?.name;
@@ -78,12 +73,8 @@ export class HeaderComponent implements OnInit, OnDestroy {
});
}
- grabNamespaces(): void {
- this.applicationService.getNamespaces().subscribe((n) => (this.namespaces = n));
- }
-
get currentNamespaceName() {
- return this.namespaces?.find((n) => n.current).namespace;
+ return this.state.namespaces?.find((n) => n.current).namespace;
}
changeNamespace(namespace: string) {
@@ -93,7 +84,6 @@ export class HeaderComponent implements OnInit, OnDestroy {
.subscribe((_) =>
this.auth.loadUser().subscribe((_) => {
this.applicationService.resetConfiguration();
- this.grabNamespaces();
this.applicationService
.getApplications()
diff --git a/bot/admin/web/src/app/theme/styles/utilities.scss b/bot/admin/web/src/app/theme/styles/utilities.scss
index 591c65e9b4..78968307e8 100644
--- a/bot/admin/web/src/app/theme/styles/utilities.scss
+++ b/bot/admin/web/src/app/theme/styles/utilities.scss
@@ -228,3 +228,8 @@ nb-menu {
border-color: var(--input-basic-disabled-border-color);
color: var(--input-basic-disabled-text-color);
}
+
+.nb-spinner-container {
+ // prevent spinners from being displayed over the application header
+ z-index: 1020;
+}