diff --git a/src/i18n/locale-en.json b/src/i18n/locale-en.json index 1c28090aa..730c1239f 100644 --- a/src/i18n/locale-en.json +++ b/src/i18n/locale-en.json @@ -280,6 +280,14 @@ "messages": { "answer_copy_successful": "The answer was successfully copied to the clipboard.", "answer_copy_failed": "Failed to copy the answer to the clipboard." + }, + "dialog": { + "confirm_repository_change_before_open_similarity": { + "body": "If you proceed with creating the similarity index, GraphDB will open in a new tab and switch to the {{repositoryId}} repository." + }, + "confirm_repository_change_before_open_connectors": { + "body": "If you proceed with creating the ChatGPT retrieval connector, GraphDB will open in a new tab and switch to the {{repositoryId}} repository." + } } }, "agent": { @@ -323,7 +331,7 @@ }, "fts_search": { "label": "Full-text search", - "fts_disabled_message": "To use this method, you must enable the full-text search (FTS) index on chosen repository and then restart it.
Enable the index: here", + "fts_disabled_message": "You must enable the full-text search (FTS) index to use this method.", "missing_repository_id": "Repository ID must be selected" }, "sparql_search": { @@ -342,14 +350,22 @@ "similarity_index": { "label": "Similarity index name", "loading_indexes": "Loading similarity indexes...", - "no_similarity_index_message": "To use this method, you must have a similarity index created.
Create similarity text index here." + "no_similarity_index": { + "message_1": "You must", + "message_2": "create a similarity index", + "message_3": "to use this method" + } }, "similarity_threshold": { "label": "Similarity threshold" }, "retrieval_search": { "label": "ChatGPT retrieval connector", - "no_retrieval_connectors_message": "No connector instances.
Create ChatGPT retrieval connector here." + "no_retrieval_connectors": { + "message_1": "You must", + "message_2": "create ChatGPT retrieval connector", + "message_3": "to use this method" + } }, "connector_id": { "label": "ChatGPT retrieval connector" diff --git a/src/i18n/locale-fr.json b/src/i18n/locale-fr.json index f4b8e7a1c..491cfb803 100644 --- a/src/i18n/locale-fr.json +++ b/src/i18n/locale-fr.json @@ -281,6 +281,14 @@ "messages": { "answer_copy_successful": "La réponse a été copiée avec succès dans le presse-papiers.", "answer_copy_failed": "Échec de la copie de la réponse dans le presse-papiers." + }, + "dialog": { + "confirm_repository_change_before_open_similarity": { + "body": "Si vous continuez à créer l'index de similarité, GraphDB s'ouvrira dans un nouvel onglet et passera au dépôt {{repositoryId}}." + }, + "confirm_repository_change_before_open_connectors": { + "body": "Si vous continuez à créer le connecteur de récupération ChatGPT, GraphDB s'ouvrira dans un nouvel onglet et passera au dépôt {{repositoryId}}." + } } }, "agent": { @@ -324,7 +332,7 @@ }, "fts_search": { "label": "Recherche en texte intégral", - "fts_disabled_message": "Pour utiliser cette méthode, vous devez activer l'index de recherche en texte intégral (FTS) sur le référentiel choisi, puis le redémarrer.
Activez l'index ici.", + "fts_disabled_message": "Vous devez activer l'index de recherche en texte intégral (FTS) pour utiliser cette méthode.", "missing_repository_id": "L'ID du référentiel doit être sélectionné" }, "sparql_search": { @@ -343,14 +351,22 @@ "similarity_index": { "label": "Nom de l'index de similarité", "loading_indexes": "Chargement des indices de similarité...", - "no_similarity_index_message": "Pour utiliser cette méthode, vous devez avoir créé un index de similarité.
Créez un index de texte de similarité ici." + "no_similarity_index": { + "message_1": "Vous devez", + "message_2": "créer un index de similarité", + "message_3": "pour utiliser cette méthode" + } }, "similarity_threshold": { "label": "Seuil de similarité" }, "retrieval_search": { "label": "Connecteur de récupération ChatGPT", - "no_retrieval_connectors_message": "Aucune instance de connecteur.
Créez un connecteur de récupération ChatGPT ici." + "no_retrieval_connectors": { + "message_1": "Vous devez", + "message_2": "créer un connecteur de récupération ChatGPT", + "message_3": "pour utiliser cette méthode" + } }, "connector_id": { "label": "Connecteur de récupération ChatGPT" diff --git a/src/js/angular/core/services/repositories.service.js b/src/js/angular/core/services/repositories.service.js index a3ea3ab7f..141dd1e5f 100644 --- a/src/js/angular/core/services/repositories.service.js +++ b/src/js/angular/core/services/repositories.service.js @@ -255,6 +255,16 @@ repositories.service('$repositories', ['toastr', '$rootScope', '$timeout', '$loc return repos; }; + /** + * Gets repository by id. + * + * @param {string} repositoryId + * @return {*} + */ + this.getRepository = function (repositoryId) { + return this.getRepositories().find((repository) => repository.id === repositoryId); + }; + this.getReadableRepositories = function () { return _.filter(this.getRepositories(), function (repo) { return $jwtAuth.canReadRepo(repo); diff --git a/src/js/angular/ttyg/controllers/agent-settings-modal.controller.js b/src/js/angular/ttyg/controllers/agent-settings-modal.controller.js index 5ef99e3c1..7f177f08e 100644 --- a/src/js/angular/ttyg/controllers/agent-settings-modal.controller.js +++ b/src/js/angular/ttyg/controllers/agent-settings-modal.controller.js @@ -4,6 +4,7 @@ import 'angular/core/services/similarity.service'; import 'angular/core/services/connectors.service'; import 'angular/rest/repositories.rest.service'; import {REPOSITORY_PARAMS} from "../../models/repository/repository"; +import {TTYGEventName} from "../services/ttyg-context.service"; angular .module('graphdb.framework.ttyg.controllers.agent-settings-modal', [ @@ -13,9 +14,31 @@ angular ]) .controller('AgentSettingsModalController', AgentSettingsModalController); -AgentSettingsModalController.$inject = ['$scope', '$uibModalInstance', 'SimilarityService', 'ConnectorsService', 'RepositoriesRestService', '$sce', 'toastr', 'UriUtils', '$translate', 'dialogModel']; - -function AgentSettingsModalController($scope, $uibModalInstance, SimilarityService, ConnectorsService, RepositoriesRestService, $sce, toastr, UriUtils, $translate, dialogModel) { +AgentSettingsModalController.$inject = [ + '$scope', + '$uibModalInstance', + 'SimilarityService', + 'ConnectorsService', + 'RepositoriesRestService', + '$sce', + 'toastr', + 'UriUtils', + '$translate', + 'dialogModel', + 'TTYGContextService']; + +function AgentSettingsModalController( + $scope, + $uibModalInstance, + SimilarityService, + ConnectorsService, + RepositoriesRestService, + $sce, + toastr, + UriUtils, + $translate, + dialogModel, + TTYGContextService) { // ========================= // Private variables @@ -132,42 +155,24 @@ function AgentSettingsModalController($scope, $uibModalInstance, SimilarityServi const message = decodeHTML( $translate.instant( 'ttyg.agent.create_agent_modal.form.fts_search.fts_disabled_message', - {repositoryEditPage: '#/repository/edit/' + $scope.activeRepositoryInfo.id} + {repositoryEditPage: '#/repository/edit/' + $scope.agentFormModel.repositoryId} ) ); return $sce.trustAsHtml(message); }; /** - * Resolves the hint for the missing similarity index message. This is needed because the hint contains a html link - * that should be properly rendered. - * @return {*} + * Opens the 'Create Similarity' view in a new tab. */ - $scope.getNoSimilarityIndexHelpMessage = () => { - // The hint contains a html link which should be properly rendered. - const message = decodeHTML( - $translate.instant( - 'ttyg.agent.create_agent_modal.form.similarity_index.no_similarity_index_message', - {similarityIndexPage: '#/similarity'} - ) - ); - return $sce.trustAsHtml(message); + $scope.goToCreateSimilarityView = () => { + TTYGContextService.emit(TTYGEventName.GO_TO_CREATE_SIMILARITY_VIEW, {repositoryId: $scope.agentFormModel.repositoryId}); }; /** - * Resolves the hint for the missing retrieval connector message. This is needed because the hint contains a html - * link that should be properly rendered. - * @return {*} + * Opens the 'Connectors' view in a new tab. */ - $scope.getNoRetrievalConnectorHelpMessage = () => { - // The hint contains a html link which should be properly rendered. - const message = decodeHTML( - $translate.instant( - 'ttyg.agent.create_agent_modal.form.retrieval_search.no_retrieval_connectors_message', - {retrievalConnectorPage: '#/connectors'} - ) - ); - return $sce.trustAsHtml(message); + $scope.goToConnectorsView = () => { + TTYGContextService.emit(TTYGEventName.GO_TO_CONNECTORS_VIEW, {repositoryId: $scope.agentFormModel.repositoryId}); }; /** diff --git a/src/js/angular/ttyg/controllers/ttyg-view.controller.js b/src/js/angular/ttyg/controllers/ttyg-view.controller.js index be94e6f79..2211c3c8e 100644 --- a/src/js/angular/ttyg/controllers/ttyg-view.controller.js +++ b/src/js/angular/ttyg/controllers/ttyg-view.controller.js @@ -15,6 +15,7 @@ import {agentFormModelMapper, newAgentFormModelProvider} from "../services/agent import {SelectMenuOptionsModel} from "../../models/form-fields"; import {repositoryInfoMapper} from "../../rest/mappers/repositories-mapper"; import {saveAs} from 'lib/FileSaver-patch'; +import {decodeHTML} from "../../../../app"; const modules = [ 'toastr', @@ -34,9 +35,37 @@ angular .module('graphdb.framework.ttyg.controllers.ttyg-view', modules) .controller('TTYGViewCtrl', TTYGViewCtrl); -TTYGViewCtrl.$inject = ['$rootScope', '$scope', '$http', '$timeout', '$translate', '$uibModal', '$repositories', 'toastr', 'ModalService', 'LocalStorageAdapter', 'TTYGService', 'TTYGContextService', 'TTYGStorageService']; - -function TTYGViewCtrl($rootScope, $scope, $http, $timeout, $translate, $uibModal, $repositories, toastr, ModalService, LocalStorageAdapter, TTYGService, TTYGContextService, TTYGStorageService) { +TTYGViewCtrl.$inject = [ + '$window', + '$rootScope', + '$scope', + '$http', + '$timeout', + '$translate', + '$uibModal', + '$repositories', + 'toastr', + 'ModalService', + 'LocalStorageAdapter', + 'TTYGService', + 'TTYGContextService', + 'TTYGStorageService']; + +function TTYGViewCtrl( + $window, + $rootScope, + $scope, + $http, + $timeout, + $translate, + $uibModal, + $repositories, + toastr, + ModalService, + LocalStorageAdapter, + TTYGService, + TTYGContextService, + TTYGStorageService) { // ========================= // Private variables @@ -598,6 +627,64 @@ function TTYGViewCtrl($rootScope, $scope, $http, $timeout, $translate, $uibModal }); }; + /** + * Opens the create similarity view. It checks if the passed repository ID matches the one selected by the workbench. + * If they do not match, a confirmation dialog is shown to inform the user that the selected repository + * will be automatically changed upon confirmation. + * + * @param {{repositoryId: string}} payload - The payload containing the repository ID. + */ + const onGoToCreateSimilarityView = (payload) => { + if (payload.repositoryId !== $repositories.getActiveRepository()) { + const repository = $repositories.getRepository(payload.repositoryId); + if (repository) { + ModalService.openConfirmation( + $translate.instant('common.confirm'), + decodeHTML($translate.instant('ttyg.chat_panel.dialog.confirm_repository_change_before_open_similarity.body', {repositoryId: repository.id})), + () => { + $repositories.setRepository(repository); + openCreateSimilarityView(); + }); + } + + } else { + openCreateSimilarityView(); + } + }; + + const openCreateSimilarityView = () => { + $window.open('/similarity/index/create', '_blank'); + }; + + /** + * Opens the connectors view. It checks if the passed repository ID matches the one selected by the workbench. + * If they do not match, a confirmation dialog is shown to inform the user that the selected repository + * will be automatically changed upon confirmation. + * + * @param {{repositoryId: string}} payload - The payload containing the repository ID. + */ + const onGoToConnectorsView = (payload) => { + if (payload.repositoryId !== $repositories.getActiveRepository()) { + const repository = $repositories.getRepository(payload.repositoryId); + if (repository) { + ModalService.openConfirmation( + $translate.instant('common.confirm'), + decodeHTML($translate.instant('ttyg.chat_panel.dialog.confirm_repository_change_before_open_connectors.body', {repositoryId: repository.id})), + () => { + $repositories.setRepository(repository); + openConnectorsView(); + }); + } + + } else { + openConnectorsView(); + } + }; + + const openConnectorsView = () => { + $window.open('/connectors', '_blank'); + }; + /** * Loads a chat using the chat ID stored in the local storage and selects it. */ @@ -651,6 +738,8 @@ function TTYGViewCtrl($rootScope, $scope, $http, $timeout, $translate, $uibModal subscriptions.push(TTYGContextService.subscribe(TTYGEventName.AGENT_SELECTED, onAgentSelected)); subscriptions.push(TTYGContextService.subscribe(TTYGEventName.SELECT_CHAT, onChatSelected)); subscriptions.push(TTYGContextService.subscribe(TTYGEventName.COPY_ANSWER_TO_CLIPBOARD, onCopiedAnswerToClipboard)); + subscriptions.push(TTYGContextService.subscribe(TTYGEventName.GO_TO_CREATE_SIMILARITY_VIEW, onGoToCreateSimilarityView)); + subscriptions.push(TTYGContextService.subscribe(TTYGEventName.GO_TO_CONNECTORS_VIEW, onGoToConnectorsView)); subscriptions.push($rootScope.$on('$translateChangeSuccess', updateLabels)); $scope.$on('$destroy', removeAllListeners); diff --git a/src/js/angular/ttyg/services/ttyg-context.service.js b/src/js/angular/ttyg/services/ttyg-context.service.js index 2c47c4349..139a17837 100644 --- a/src/js/angular/ttyg/services/ttyg-context.service.js +++ b/src/js/angular/ttyg/services/ttyg-context.service.js @@ -329,5 +329,15 @@ export const TTYGEventName = { /** * This event will be emitted when copying an answer to the clipboard fails. */ - COPY_ANSWER_TO_CLIPBOARD_FAILURE: 'copyAnswerToClipboardFailure' + COPY_ANSWER_TO_CLIPBOARD_FAILURE: 'copyAnswerToClipboardFailure', + + /** + * This event will trigger the opening of the similarity view. + */ + GO_TO_CREATE_SIMILARITY_VIEW: "goToCreateSimilarityView", + + /** + * This event will trigger the opening of the connectors view. + */ + GO_TO_CONNECTORS_VIEW: "goToConnectorsView" }; diff --git a/src/js/angular/ttyg/templates/modal/agent-settings-modal.html b/src/js/angular/ttyg/templates/modal/agent-settings-modal.html index effc5a2be..136ab52a8 100644 --- a/src/js/angular/ttyg/templates/modal/agent-settings-modal.html +++ b/src/js/angular/ttyg/templates/modal/agent-settings-modal.html @@ -134,8 +134,12 @@