mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
CB-5790 remove template plugin (#3339)
* CB-5790 remove template plugin * dbeaver/pro#5038 Remove connection template * CB-5790 update yarn lock * CB-5790 fix * CB-5790 remove templates * CB-5790 remove template field from fragment * CB-5790 return access tab --------- Co-authored-by: Ruslan <pupkinvasya7000@gmail.com> Co-authored-by: Evgenia <139753579+EvgeniaBzzz@users.noreply.github.com> Co-authored-by: mr-anton-t <42037741+mr-anton-t@users.noreply.github.com>
This commit is contained in:
co-authored by
Ruslan
Evgenia
mr-anton-t
parent
08346ebc12
commit
d4e8329528
@@ -32,10 +32,8 @@ import java.util.Map;
|
||||
public class WebConnectionConfig {
|
||||
|
||||
private String connectionId;
|
||||
private String templateId;
|
||||
private String driverId;
|
||||
|
||||
private boolean template;
|
||||
private boolean readOnly;
|
||||
|
||||
private String host;
|
||||
@@ -70,14 +68,7 @@ public class WebConnectionConfig {
|
||||
public WebConnectionConfig(Map<String, Object> params) {
|
||||
if (!CommonUtils.isEmpty(params)) {
|
||||
connectionId = JSONUtils.getString(params, "connectionId");
|
||||
templateId = JSONUtils.getString(params, "templateId");
|
||||
String dataSourceId = JSONUtils.getString(params, "dataSourceId");
|
||||
if (CommonUtils.isEmpty(templateId) && !CommonUtils.isEmpty(dataSourceId)) {
|
||||
templateId = dataSourceId;
|
||||
}
|
||||
driverId = JSONUtils.getString(params, "driverId");
|
||||
|
||||
template = JSONUtils.getBoolean(params, "template");
|
||||
readOnly = JSONUtils.getBoolean(params, "readOnly");
|
||||
|
||||
host = JSONUtils.getString(params, "host");
|
||||
@@ -121,21 +112,11 @@ public class WebConnectionConfig {
|
||||
return connectionId;
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getTemplateId() {
|
||||
return templateId;
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getDriverId() {
|
||||
return driverId;
|
||||
}
|
||||
|
||||
@Property
|
||||
public boolean isTemplate() {
|
||||
return template;
|
||||
}
|
||||
|
||||
@Property
|
||||
public boolean isReadOnly() {
|
||||
return readOnly;
|
||||
|
||||
@@ -171,11 +171,6 @@ public class WebConnectionInfo {
|
||||
return dataSourceContainer.isConnected();
|
||||
}
|
||||
|
||||
@Property
|
||||
public boolean isTemplate() {
|
||||
return dataSourceContainer.isTemplate();
|
||||
}
|
||||
|
||||
@Property
|
||||
public boolean isProvided() {
|
||||
return dataSourceContainer.isProvided();
|
||||
|
||||
@@ -357,7 +357,6 @@ type ConnectionInfo {
|
||||
|
||||
properties: Object
|
||||
|
||||
template: Boolean! @deprecated
|
||||
connected: Boolean!
|
||||
provided: Boolean!
|
||||
readOnly: Boolean!
|
||||
@@ -502,8 +501,6 @@ input ConnectionConfig {
|
||||
name: String
|
||||
description: String
|
||||
|
||||
# ID of template connection
|
||||
templateId: ID @deprecated
|
||||
# ID of database driver
|
||||
driverId: ID
|
||||
|
||||
@@ -529,8 +526,6 @@ input ConnectionConfig {
|
||||
# Return auto-commit connection state
|
||||
autocommit: Boolean
|
||||
|
||||
# Return template connection state
|
||||
template: Boolean @deprecated
|
||||
# Return read-only connection state
|
||||
readOnly: Boolean
|
||||
|
||||
@@ -590,9 +585,6 @@ extend type Query {
|
||||
# Return list of user connections
|
||||
userConnections( projectId: ID, id: ID, projectIds: [ID!] ): [ ConnectionInfo! ]!
|
||||
|
||||
# Return list of template connections by project ID
|
||||
templateConnections( projectId: ID ): [ ConnectionInfo! ]! @deprecated
|
||||
|
||||
# List of connection folders
|
||||
connectionFolders( projectId: ID, path: ID ): [ ConnectionFolderInfo! ]!
|
||||
|
||||
@@ -632,9 +624,6 @@ extend type Mutation {
|
||||
# Delete specified connection
|
||||
deleteConnection( id: ID!, projectId: ID ): Boolean!
|
||||
|
||||
# Create new custom connection from template
|
||||
createConnectionFromTemplate( templateId: ID!, projectId: ID!, connectionName: String ): ConnectionInfo! @deprecated
|
||||
|
||||
# Create new folder for connections
|
||||
createConnectionFolder(parentFolderPath: ID, folderName: String!, projectId: ID ): ConnectionFolderInfo!
|
||||
|
||||
|
||||
@@ -109,13 +109,7 @@ public class WebServiceUtils extends WebCommonUtils {
|
||||
@NotNull
|
||||
public static DBPDataSourceContainer createConnectionFromConfig(WebConnectionConfig config, DBPDataSourceRegistry registry) throws DBWebException {
|
||||
DBPDataSourceContainer newDataSource;
|
||||
if (!CommonUtils.isEmpty(config.getTemplateId())) {
|
||||
DBPDataSourceContainer tpl = registry.getDataSource(config.getTemplateId());
|
||||
if (tpl == null) {
|
||||
throw new DBWebException("Template connection '" + config.getTemplateId() + "' not found");
|
||||
}
|
||||
newDataSource = registry.createDataSource(tpl);
|
||||
} else if (!CommonUtils.isEmpty(config.getDriverId())) {
|
||||
if (!CommonUtils.isEmpty(config.getDriverId())) {
|
||||
String driverId = config.getDriverId();
|
||||
if (CommonUtils.isEmpty(driverId)) {
|
||||
throw new DBWebException("Driver not specified");
|
||||
@@ -138,7 +132,6 @@ public class WebServiceUtils extends WebCommonUtils {
|
||||
if (config.getFolder() != null) {
|
||||
newDataSource.setFolder(registry.getFolder(config.getFolder()));
|
||||
}
|
||||
((DataSourceDescriptor)newDataSource).setTemplate(config.isTemplate());
|
||||
|
||||
ServletApplication app = ServletAppUtils.getServletApplication();
|
||||
if (app instanceof WebApplication webApplication) {
|
||||
|
||||
-4
@@ -72,10 +72,6 @@ public class ConnectionControllerCE implements ConnectionController {
|
||||
webSession.addInfoMessage("Create new connection");
|
||||
DBPDataSourceRegistry sessionRegistry = project.getDataSourceRegistry();
|
||||
|
||||
// we don't need to save credentials for templates
|
||||
if (connectionConfig.isTemplate()) {
|
||||
connectionConfig.setSaveCredentials(false);
|
||||
}
|
||||
DBPDataSourceContainer newDataSource = WebServiceUtils.createConnectionFromConfig(connectionConfig,
|
||||
sessionRegistry);
|
||||
if (CommonUtils.isEmpty(newDataSource.getName())) {
|
||||
|
||||
-15
@@ -70,13 +70,6 @@ public interface DBWServiceCore extends DBWService {
|
||||
List<WebConnectionFolderInfo> getConnectionFolders(
|
||||
@NotNull WebSession webSession, @Nullable String projectId, @Nullable String id) throws DBWebException;
|
||||
|
||||
@Deprecated
|
||||
@WebAction
|
||||
List<WebDataSourceConfig> getTemplateDataSources() throws DBWebException;
|
||||
|
||||
@WebAction
|
||||
List<WebConnectionInfo> getTemplateConnections(@NotNull WebSession webSession, @Nullable String projectId) throws DBWebException;
|
||||
|
||||
@WebAction(authRequired = false)
|
||||
String[] getSessionPermissions(@NotNull WebSession webSession) throws DBWebException;
|
||||
|
||||
@@ -151,14 +144,6 @@ public interface DBWServiceCore extends DBWService {
|
||||
@Nullable @WebObjectId String projectId,
|
||||
@NotNull String connectionId) throws DBWebException;
|
||||
|
||||
@WebAction
|
||||
@Deprecated
|
||||
WebConnectionInfo createConnectionFromTemplate(
|
||||
@NotNull WebSession webSession,
|
||||
@NotNull String projectId,
|
||||
@NotNull String templateId,
|
||||
@Nullable String connectionName) throws DBWebException;
|
||||
|
||||
@WebProjectAction(requireProjectPermissions = {RMConstants.PERMISSION_PROJECT_DATASOURCES_EDIT})
|
||||
WebConnectionInfo copyConnectionFromNode(
|
||||
@NotNull WebSession webSession,
|
||||
|
||||
-8
@@ -59,11 +59,8 @@ public class WebServiceBindingCore extends WebServiceBindingBase<DBWServiceCore>
|
||||
.dataFetcher("driverList", env -> getService(env).getDriverList(getWebSession(env), env.getArgument("id")))
|
||||
.dataFetcher("authModels", env -> getService(env).getAuthModels(getWebSession(env)))
|
||||
.dataFetcher("networkHandlers", env -> getService(env).getNetworkHandlers(getWebSession(env)))
|
||||
.dataFetcher("templateDataSources", env -> getService(env).getTemplateDataSources())
|
||||
.dataFetcher("userConnections", env -> getService(env).getUserConnections(
|
||||
getWebSession(env), getProjectReference(env), env.getArgument("id"), env.getArgument("projectIds")))
|
||||
.dataFetcher("templateConnections", env -> getService(env).getTemplateConnections(
|
||||
getWebSession(env), getProjectReference(env)))
|
||||
|
||||
.dataFetcher("connectionFolders", env -> getService(env).getConnectionFolders(
|
||||
getWebSession(env), getProjectReference(env), env.getArgument("path")))
|
||||
@@ -113,11 +110,6 @@ public class WebServiceBindingCore extends WebServiceBindingBase<DBWServiceCore>
|
||||
getWebSession(env), getProjectReference(env), getConnectionConfig(env)))
|
||||
.dataFetcher("deleteConnection", env -> getService(env).deleteConnection(
|
||||
getWebSession(env), getProjectReference(env), env.getArgument("id")))
|
||||
.dataFetcher("createConnectionFromTemplate", env -> getService(env).createConnectionFromTemplate(
|
||||
getWebSession(env),
|
||||
getProjectReference(env),
|
||||
env.getArgument("templateId"),
|
||||
env.getArgument("connectionName")))
|
||||
.dataFetcher("copyConnectionFromNode", env -> getService(env).copyConnectionFromNode(
|
||||
getWebSession(env),
|
||||
getProjectReference(env),
|
||||
|
||||
-90
@@ -132,58 +132,6 @@ public class WebServiceCore implements DBWServiceCore {
|
||||
.toList();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public List<WebDataSourceConfig> getTemplateDataSources() throws DBWebException {
|
||||
|
||||
List<WebDataSourceConfig> result = new ArrayList<>();
|
||||
DBPDataSourceRegistry dsRegistry = WebServiceUtils.getGlobalDataSourceRegistry();
|
||||
|
||||
for (DBPDataSourceContainer ds : dsRegistry.getDataSources()) {
|
||||
if (ds.isTemplate()) {
|
||||
if (WebAppUtils.getWebApplication().getDriverRegistry().getApplicableDrivers().contains(ds.getDriver())) {
|
||||
result.add(new WebDataSourceConfig(ds));
|
||||
} else {
|
||||
log.debug("Template datasource '" + ds.getName() + "' ignored - driver is not applicable");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WebConnectionInfo> getTemplateConnections(
|
||||
@NotNull WebSession webSession, @Nullable String projectId
|
||||
) throws DBWebException {
|
||||
if (webSession.getApplication().isDistributed()) {
|
||||
return List.of();
|
||||
}
|
||||
List<WebConnectionInfo> result = new ArrayList<>();
|
||||
if (projectId == null) {
|
||||
for (WebSessionProjectImpl project : webSession.getAccessibleProjects()) {
|
||||
getTemplateConnectionsFromProject(webSession, project, result);
|
||||
}
|
||||
} else {
|
||||
WebSessionProjectImpl project = getProjectById(webSession, projectId);
|
||||
getTemplateConnectionsFromProject(webSession, project, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void getTemplateConnectionsFromProject(
|
||||
@NotNull WebSession webSession,
|
||||
@NotNull WebSessionProjectImpl project,
|
||||
List<WebConnectionInfo> result
|
||||
) {
|
||||
DBPDataSourceRegistry registry = project.getDataSourceRegistry();
|
||||
for (DBPDataSourceContainer ds : registry.getDataSources()) {
|
||||
if (ds.isTemplate() && WebAppUtils.getWebApplication().getDriverRegistry().getApplicableDrivers().contains(ds.getDriver())) {
|
||||
result.add(new WebConnectionInfo(webSession, ds));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WebConnectionFolderInfo> getConnectionFolders(
|
||||
@NotNull WebSession webSession, @Nullable String projectId, @Nullable String id
|
||||
@@ -401,44 +349,6 @@ public class WebServiceCore implements DBWServiceCore {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public WebConnectionInfo createConnectionFromTemplate(
|
||||
@NotNull WebSession webSession,
|
||||
@NotNull String projectId,
|
||||
@NotNull String templateId,
|
||||
@Nullable String connectionName
|
||||
) throws DBWebException {
|
||||
WebSessionProjectImpl project = getProjectById(webSession, projectId);
|
||||
DBPDataSourceRegistry templateRegistry = project.getDataSourceRegistry();
|
||||
DBPDataSourceContainer dataSourceTemplate = templateRegistry.getDataSource(templateId);
|
||||
if (dataSourceTemplate == null) {
|
||||
throw new DBWebException("Template data source '" + templateId + "' not found");
|
||||
}
|
||||
|
||||
DBPDataSourceRegistry projectRegistry = webSession.getSingletonProject().getDataSourceRegistry();
|
||||
DBPDataSourceContainer newDataSource = projectRegistry.createDataSource(dataSourceTemplate);
|
||||
|
||||
ServletApplication app = ServletAppUtils.getServletApplication();
|
||||
if (app instanceof WebApplication webApplication) {
|
||||
((DataSourceDescriptor) newDataSource).setNavigatorSettings(
|
||||
webApplication.getAppConfiguration().getDefaultNavigatorSettings());
|
||||
}
|
||||
|
||||
if (!CommonUtils.isEmpty(connectionName)) {
|
||||
newDataSource.setName(connectionName);
|
||||
}
|
||||
try {
|
||||
projectRegistry.addDataSource(newDataSource);
|
||||
|
||||
projectRegistry.checkForErrors();
|
||||
} catch (DBException e) {
|
||||
throw new DBWebException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
return project.addConnection(newDataSource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebConnectionInfo copyConnectionFromNode(
|
||||
@NotNull WebSession webSession,
|
||||
|
||||
@@ -255,7 +255,6 @@ export class ConnectionInfoResource extends CachedMapResource<IConnectionInfoPar
|
||||
|
||||
makeObservable<this, 'nodeIdMap'>(this, {
|
||||
nodeIdMap: observable,
|
||||
createFromTemplate: action,
|
||||
create: action,
|
||||
createFromNode: action,
|
||||
add: action,
|
||||
@@ -357,17 +356,6 @@ export class ConnectionInfoResource extends CachedMapResource<IConnectionInfoPar
|
||||
return this.add(connection);
|
||||
}
|
||||
|
||||
async createFromTemplate(projectId: string, templateId: string, connectionName: string): Promise<Connection> {
|
||||
const { connection } = await this.graphQLService.sdk.createConnectionFromTemplate({
|
||||
projectId,
|
||||
templateId,
|
||||
connectionName,
|
||||
...this.getDefaultIncludes(),
|
||||
...this.getIncludesMap(),
|
||||
});
|
||||
return this.add(connection);
|
||||
}
|
||||
|
||||
// addList(connections: Connection[]): Connection[] {
|
||||
// const newConnections = connections.filter(connection => !this.has({
|
||||
// projectId: connection.projectId,
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
export default [
|
||||
['core_connections_connections_settings_group', 'Verbindungen'],
|
||||
['connections_administration_new_connection', 'Neue Verbindung'],
|
||||
['connections_administration_connection_access_empty', 'Keine verfügbaren Benutzer und Teams'],
|
||||
['connections_administration_configuration_wizard_step_title', 'Datenbankverbindungen'],
|
||||
['connections_administration_configuration_wizard_step_description', 'Datenbankverbindungen hinzufügen'],
|
||||
['connections_administration_configuration_wizard_title', 'Datenbankverbindungen hinzufügen'],
|
||||
['connections_administration_connection_no_information', 'Keine Information verfügbar'],
|
||||
['core_connections_new_connection', 'Neue Verbindung'],
|
||||
['core_connections_connection_access_empty', 'Keine verfügbaren Benutzer und Teams'],
|
||||
['core_connections_connection_no_information', 'Keine Information verfügbar'],
|
||||
['connections_administration_delete_confirmation', 'Sie werden diese Verbindungen löschen: '],
|
||||
['connections_administration_tools_delete_tooltip', 'Löschen Sie ausgewählte Verbindungen'],
|
||||
['connections_administration_tools_refresh_success', 'Die Verbindungsliste wurde aktualisiert'],
|
||||
@@ -52,7 +49,6 @@ export default [
|
||||
|
||||
['core_connections_settings_disable', 'Disable'],
|
||||
['core_connections_settings_disable_description', 'Disable the ability to create new connections'],
|
||||
['connections_templates_deprecated_message', 'Template connections are deprecated and will be removed in future releases'],
|
||||
['core_connections_connection_driver_not_installed', 'Driver is not installed'],
|
||||
['core_connections_connection_temporary', 'Temporary connection'],
|
||||
['core_connections_connection_create_success', 'Connection was created'],
|
||||
|
||||
@@ -1,26 +1,12 @@
|
||||
export default [
|
||||
['core_connections_connections_settings_group', 'Connections'],
|
||||
['connections_administration_item', 'Connection Templates'],
|
||||
['connections_administration_connection_create', 'Add Database Template'],
|
||||
['connections_administration_search_database_tip', "Type your hosts here, e.g. 'localhost host1.myhost.com 192.168.0.1' and press Enter"],
|
||||
['connections_administration_new_connection', 'New connection'],
|
||||
['connections_administration_connection_create_error', 'Create connection error'],
|
||||
['connections_administration_connection_save_error', 'Save connection error'],
|
||||
['connections_administration_connection_access_empty', 'No available users and teams'],
|
||||
['connections_administration_configuration_wizard_step_title', 'Database connections'],
|
||||
['connections_administration_configuration_wizard_step_description', 'Add database connections'],
|
||||
['connections_administration_configuration_wizard_title', 'Add database connections'],
|
||||
[
|
||||
'connections_administration_configuration_wizard_message',
|
||||
'Here you can create database connections manually or using a database server search.\nYou can skip this step and configure the connections later.',
|
||||
],
|
||||
['connections_administration_connection_no_information', 'No information available'],
|
||||
['connections_administration_delete_confirmation', "You're going to delete these connections: "],
|
||||
['connections_administration_tools_add_tooltip', 'Add new template'],
|
||||
['connections_administration_tools_refresh_tooltip', 'Refresh connection list'],
|
||||
['connections_administration_tools_delete_tooltip', 'Delete selected connections'],
|
||||
['connections_administration_tools_refresh_success', 'Connection list was refreshed'],
|
||||
['connections_administration_tools_refresh_fail', 'Connection list refresh failed'],
|
||||
['core_connections_search_database_tip', "Type your hosts here, e.g. 'localhost host1.myhost.com 192.168.0.1' and press Enter"],
|
||||
['core_connections_new_connection', 'New connection'],
|
||||
['core_connections_connection_create_error', 'Create connection error'],
|
||||
['core_connections_connection_save_error', 'Save connection error'],
|
||||
['core_connections_connection_access_empty', 'No available users and teams'],
|
||||
['core_connections_connection_no_information', 'No information available'],
|
||||
|
||||
['connections_database_authentication', 'Database Authentication'],
|
||||
['connections_connection_edit_not_own_deny', 'You have no access to edit this connection.'],
|
||||
['connections_connection_connect', 'Connect'],
|
||||
@@ -58,7 +44,6 @@ export default [
|
||||
['connections_connection_configuration', 'Configuration'],
|
||||
['connections_connection_host', 'Host'],
|
||||
['connections_connection_port', 'Port'],
|
||||
['connections_connection_template', 'Template'],
|
||||
['core_connections_connection_create_success', 'Connection was created'],
|
||||
['core_connections_connection_update_success', 'Connection was updated'],
|
||||
['connections_connection_test', 'Test'],
|
||||
@@ -98,7 +83,6 @@ export default [
|
||||
|
||||
['core_connections_settings_disable', 'Disable'],
|
||||
['core_connections_settings_disable_description', 'Disable the ability to create new connections'],
|
||||
['connections_templates_deprecated_message', 'Template connections are deprecated and will be removed in future releases'],
|
||||
['core_connections_connection_driver_not_installed', 'Driver is not installed'],
|
||||
['core_connections_connection_temporary', 'Temporary connection'],
|
||||
];
|
||||
|
||||
@@ -1,29 +1,11 @@
|
||||
export default [
|
||||
['core_connections_connections_settings_group', 'Connexions'],
|
||||
['connections_administration_item', 'Modèles de connexion'],
|
||||
['connections_administration_connection_create', 'Ajouter un modèle de base de données'],
|
||||
[
|
||||
'connections_administration_search_database_tip',
|
||||
"Saisissez vos hôtes ici, par exemple 'localhost host1.myhost.com 192.168.0.1' et appuyez sur Entrée",
|
||||
],
|
||||
['connections_administration_new_connection', 'Nouvelle connexion'],
|
||||
['connections_administration_connection_create_error', 'Erreur de création de connexion'],
|
||||
['connections_administration_connection_save_error', 'Erreur de sauvegarde de connexion'],
|
||||
['connections_administration_connection_access_empty', 'Aucun utilisateur et équipe disponibles'],
|
||||
['connections_administration_configuration_wizard_step_title', 'Connexions de base de données'],
|
||||
['connections_administration_configuration_wizard_step_description', 'Ajouter des connexions de base de données'],
|
||||
['connections_administration_configuration_wizard_title', 'Ajouter des connexions de base de données'],
|
||||
[
|
||||
'connections_administration_configuration_wizard_message',
|
||||
'Ici, vous pouvez créer des connexions de base de données manuellement ou en utilisant une recherche de serveur de base de données.\nVous pouvez passer cette étape et configurer les connexions plus tard.',
|
||||
],
|
||||
['connections_administration_connection_no_information', 'Aucune information disponible'],
|
||||
['connections_administration_delete_confirmation', 'Vous allez supprimer ces connexions : '],
|
||||
['connections_administration_tools_add_tooltip', 'Ajouter un nouveau modèle'],
|
||||
['connections_administration_tools_refresh_tooltip', 'Actualiser la liste des connexions'],
|
||||
['connections_administration_tools_delete_tooltip', 'Supprimer les connexions sélectionnées'],
|
||||
['connections_administration_tools_refresh_success', 'La liste des connexions a été actualisée'],
|
||||
['connections_administration_tools_refresh_fail', "Échec de l'actualisation de la liste des connexions"],
|
||||
['core_connections_search_database_tip', "Saisissez vos hôtes ici, par exemple 'localhost host1.myhost.com 192.168.0.1' et appuyez sur Entrée"],
|
||||
['core_connections_new_connection', 'Nouvelle connexion'],
|
||||
['core_connections_connection_create_error', 'Erreur de création de connexion'],
|
||||
['core_connections_connection_save_error', 'Erreur de sauvegarde de connexion'],
|
||||
['core_connections_connection_access_empty', 'Aucun utilisateur et équipe disponibles'],
|
||||
['core_connections_connection_no_information', 'Aucune information disponible'],
|
||||
['connections_database_authentication', 'Authentification de la base de données'],
|
||||
['connections_connection_edit_not_own_deny', "Vous n'avez pas accès pour modifier cette connexion."],
|
||||
['connections_connection_connect', 'Connecter'],
|
||||
@@ -68,7 +50,6 @@ export default [
|
||||
['connections_connection_host', 'Hôte'],
|
||||
['connections_connection_port', 'Port'],
|
||||
['connections_connection_read_only', 'Read-only connection'],
|
||||
['connections_connection_template', 'Modèle'],
|
||||
['core_connections_connection_create_success', 'Connection was created'],
|
||||
['core_connections_connection_update_success', 'Connection was updated'],
|
||||
['connections_connection_test', 'Tester'],
|
||||
@@ -107,7 +88,6 @@ export default [
|
||||
|
||||
['core_connections_settings_disable', 'Disable'],
|
||||
['core_connections_settings_disable_description', 'Disable the ability to create new connections'],
|
||||
['connections_templates_deprecated_message', 'Template connections are deprecated and will be removed in future releases'],
|
||||
['core_connections_connection_driver_not_installed', 'Driver is not installed'],
|
||||
['core_connections_connection_temporary', 'Temporary connection'],
|
||||
];
|
||||
|
||||
@@ -1,24 +1,10 @@
|
||||
export default [
|
||||
['core_connections_connections_settings_group', 'Connections'],
|
||||
['connections_administration_item', 'Connection Templates'],
|
||||
['connections_administration_connection_create', 'Add Database Template'],
|
||||
['connections_administration_search_database_tip', "Digita gli hosts qui, p.e. 'localhost host1.myhost.com 192.168.0.1' e premi Invio"],
|
||||
['connections_administration_new_connection', 'Nuova Connessione'],
|
||||
['connections_administration_connection_create_error', 'Errore di creazione connessione'],
|
||||
['connections_administration_connection_save_error', 'Errore di salvataggio connessione'],
|
||||
['connections_administration_configuration_wizard_step_title', 'Connessioni ai Database'],
|
||||
['connections_administration_configuration_wizard_step_description', 'Aggiungi connessione al database'],
|
||||
['connections_administration_configuration_wizard_title', 'Aggiungi connessione al database'],
|
||||
[
|
||||
'connections_administration_configuration_wizard_message',
|
||||
'Qui puoi creare connessioni ai database manualmente oppure usando una ricerca di un database server.\nPuoi saltare questo step e configurare le connessioni dopo.',
|
||||
],
|
||||
['connections_administration_connection_no_information', 'Nessuna informazione disponibile'],
|
||||
['connections_administration_tools_add_tooltip', 'Add new template'],
|
||||
['connections_administration_tools_refresh_tooltip', 'Ricarica la lista di connessioni'],
|
||||
['connections_administration_tools_delete_tooltip', 'Elimina le connessioni selezionate'],
|
||||
['connections_administration_tools_refresh_success', 'Lista delle connessioni ricaricata'],
|
||||
['connections_administration_tools_refresh_fail', 'Errore durante la ricarica della lista delle connessioni'],
|
||||
['core_connections_search_database_tip', "Digita gli hosts qui, p.e. 'localhost host1.myhost.com 192.168.0.1' e premi Invio"],
|
||||
['core_connections_new_connection', 'Nuova Connessione'],
|
||||
['core_connections_connection_create_error', 'Errore di creazione connessione'],
|
||||
['core_connections_connection_save_error', 'Errore di salvataggio connessione'],
|
||||
['core_connections_connection_no_information', 'Nessuna informazione disponibile'],
|
||||
['connections_database_authentication', 'Autenticazione al Database'],
|
||||
['connections_connection_edit_not_own_deny', 'Questa connessione è stata creata da un amministratore. Non può essere modificata.'],
|
||||
['connections_connection_connect', 'Collega'],
|
||||
@@ -56,7 +42,6 @@ export default [
|
||||
['connections_connection_configuration', 'Configuration'],
|
||||
['connections_connection_host', 'Host'],
|
||||
['connections_connection_port', 'Porta'],
|
||||
['connections_connection_template', 'Template'],
|
||||
['core_connections_connection_create_success', 'Connection was created'],
|
||||
['core_connections_connection_update_success', 'Connection was updated'],
|
||||
['connections_connection_test', 'Prova la connessione'],
|
||||
@@ -96,7 +81,6 @@ export default [
|
||||
|
||||
['core_connections_settings_disable', 'Disable'],
|
||||
['core_connections_settings_disable_description', 'Disable the ability to create new connections'],
|
||||
['connections_templates_deprecated_message', 'Template connections are deprecated and will be removed in future releases'],
|
||||
['core_connections_connection_driver_not_installed', 'Driver is not installed'],
|
||||
['core_connections_connection_temporary', 'Temporary connection'],
|
||||
];
|
||||
|
||||
@@ -1,20 +1,11 @@
|
||||
export default [
|
||||
['core_connections_connections_settings_group', 'Подключения'],
|
||||
['connections_administration_item', 'Шаблоны подключений'],
|
||||
['connections_administration_connection_create', 'Создание шаблона подключения'],
|
||||
['connections_administration_search_database_tip', "Укажите ваши хосты, например 'localhost host1.myhost.com 192.168.0.1' и нажмите Enter"],
|
||||
['connections_administration_new_connection', 'Создание подключения'],
|
||||
['connections_administration_connection_create_error', 'Ошибка при создании подключения'],
|
||||
['connections_administration_connection_save_error', 'Ошибка при сохранении подключения'],
|
||||
['connections_administration_connection_access_empty', 'Нет доступных пользователей и подключений'],
|
||||
['connections_administration_configuration_wizard_step_title', 'Подключения к базам'],
|
||||
['connections_administration_configuration_wizard_step_description', 'Подключения к базам'],
|
||||
[
|
||||
'connections_administration_configuration_wizard_message',
|
||||
'Here you can create database connections manually or using a database server search.\nYou can skip this step and configure the connections later.',
|
||||
],
|
||||
['connections_administration_connection_no_information', 'Нет доступной информации'],
|
||||
['connections_administration_delete_confirmation', 'Вы собираетесь удалить следующие подключения: '],
|
||||
['core_connections_search_database_tip', "Укажите ваши хосты, например 'localhost host1.myhost.com 192.168.0.1' и нажмите Enter"],
|
||||
['core_connections_new_connection', 'Создание подключения'],
|
||||
['core_connections_connection_create_error', 'Ошибка при создании подключения'],
|
||||
['core_connections_connection_save_error', 'Ошибка при сохранении подключения'],
|
||||
['core_connections_connection_access_empty', 'Нет доступных пользователей и подключений'],
|
||||
['core_connections_connection_no_information', 'Нет доступной информации'],
|
||||
['connections_administration_tools_add_tooltip', 'Добавить новый шаблон подключения'],
|
||||
['connections_administration_tools_refresh_tooltip', 'Обновить список подключений'],
|
||||
['connections_administration_tools_delete_tooltip', 'Удалить выбранные подключения'],
|
||||
@@ -62,7 +53,6 @@ export default [
|
||||
['connections_connection_configuration', 'Конфигурация'],
|
||||
['connections_connection_host', 'Хост'],
|
||||
['connections_connection_port', 'Порт'],
|
||||
['connections_connection_template', 'Шаблон'],
|
||||
['core_connections_connection_create_success', 'Подключение создано'],
|
||||
['core_connections_connection_update_success', 'Подключение обновлено'],
|
||||
['connections_connection_test', 'Тест'],
|
||||
@@ -99,7 +89,6 @@ export default [
|
||||
|
||||
['core_connections_settings_disable', 'Отключить'],
|
||||
['core_connections_settings_disable_description', 'Отключить возможность создания новых подключений'],
|
||||
['connections_templates_deprecated_message', 'Шаблоны подключений больше не поддерживаются и будут удалены в будущих релизах'],
|
||||
['core_connections_connection_driver_not_installed', 'Драйвер не установлен'],
|
||||
['core_connections_connection_temporary', 'Временное подключение'],
|
||||
];
|
||||
|
||||
@@ -1,25 +1,10 @@
|
||||
export default [
|
||||
['core_connections_connections_settings_group', '连接'],
|
||||
['connections_administration_item', '连接模板'],
|
||||
['connections_administration_connection_create', '添加数据库模板'],
|
||||
['connections_administration_search_database_tip', '在此处输入您的主机,例如“localhost host1.myhost.com 192.168.0.1”然后按 Enter'],
|
||||
['connections_administration_new_connection', '新连接'],
|
||||
['connections_administration_connection_create_error', '创建连接失败'],
|
||||
['connections_administration_connection_save_error', '保存链接失败'],
|
||||
['connections_administration_configuration_wizard_step_title', '数据库连接'],
|
||||
['connections_administration_configuration_wizard_step_description', '添加数据库连接'],
|
||||
['connections_administration_configuration_wizard_title', '添加数据库连接'],
|
||||
[
|
||||
'connections_administration_configuration_wizard_message',
|
||||
'您可以在此处手动创建数据库连接或使用数据库服务器搜索。您可以跳过此步骤并稍后配置连接。',
|
||||
],
|
||||
['connections_administration_connection_no_information', '没有可用信息'],
|
||||
['connections_administration_delete_confirmation', '您将删除这些连接:'],
|
||||
['connections_administration_tools_add_tooltip', 'Add new template'],
|
||||
['connections_administration_tools_refresh_tooltip', '刷新连接列表'],
|
||||
['connections_administration_tools_delete_tooltip', '删除选中的连接'],
|
||||
['connections_administration_tools_refresh_success', '连接列表已刷新'],
|
||||
['connections_administration_tools_refresh_fail', '连接列表刷新失败'],
|
||||
['core_connections_search_database_tip', '在此处输入您的主机,例如“localhost host1.myhost.com 192.168.0.1”然后按 Enter'],
|
||||
['core_connections_new_connection', '新连接'],
|
||||
['core_connections_connection_create_error', '创建连接失败'],
|
||||
['core_connections_connection_save_error', '保存链接失败'],
|
||||
['core_connections_connection_no_information', '没有可用信息'],
|
||||
['connections_database_authentication', '数据库认证'],
|
||||
['connections_connection_edit_not_own_deny', '此连接由管理员创建。它无法更新。'],
|
||||
['connections_connection_connect', '连接'],
|
||||
@@ -51,7 +36,6 @@ export default [
|
||||
['connections_connection_configuration', '配置'],
|
||||
['connections_connection_host', '主机'],
|
||||
['connections_connection_port', '端口'],
|
||||
['connections_connection_template', '模板'],
|
||||
['core_connections_connection_create_success', 'Connection was created'],
|
||||
['core_connections_connection_update_success', 'Connection was updated'],
|
||||
['connections_connection_test', '测试连接'],
|
||||
@@ -88,7 +72,6 @@ export default [
|
||||
|
||||
['core_connections_settings_disable', 'Disable'],
|
||||
['core_connections_settings_disable_description', 'Disable the ability to create new connections'],
|
||||
['connections_templates_deprecated_message', 'Template connections are deprecated and will be removed in future releases'],
|
||||
['core_connections_connection_driver_not_installed', 'Driver is not installed'],
|
||||
['core_connections_connection_temporary', 'Temporary connection'],
|
||||
];
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
mutation createConnectionFromTemplate(
|
||||
$projectId: ID!
|
||||
$templateId: ID!
|
||||
$connectionName: String!
|
||||
$includeAuthProperties: Boolean!
|
||||
$includeNetworkHandlersConfig: Boolean!
|
||||
$includeCredentialsSaved: Boolean!
|
||||
$includeAuthNeeded: Boolean!
|
||||
$includeProperties: Boolean!
|
||||
$includeProviderProperties: Boolean!
|
||||
$customIncludeOptions: Boolean!
|
||||
) {
|
||||
connection: createConnectionFromTemplate(projectId: $projectId, templateId: $templateId, connectionName: $connectionName) {
|
||||
...DatabaseConnection
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
query getTemplateConnections(
|
||||
$projectId: ID
|
||||
$includeAuthProperties: Boolean!
|
||||
$includeNetworkHandlersConfig: Boolean!
|
||||
$includeCredentialsSaved: Boolean!
|
||||
$includeAuthNeeded: Boolean!
|
||||
$includeProperties: Boolean!
|
||||
$includeProviderProperties: Boolean!
|
||||
$customIncludeOptions: Boolean!
|
||||
) {
|
||||
connections: templateConnections(projectId: $projectId) {
|
||||
...DatabaseConnection
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,6 @@ fragment DatabaseConnection on ConnectionInfo {
|
||||
keepAliveInterval
|
||||
autocommit
|
||||
|
||||
template
|
||||
connected
|
||||
readOnly
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ fragment DatabaseConnectionCustomOptions on ConnectionInfo {
|
||||
name
|
||||
description
|
||||
folder
|
||||
template
|
||||
driverId
|
||||
keepAliveInterval
|
||||
autocommit
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
* Copyright (C) 2020-2025 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -38,13 +38,13 @@ export const DatabaseList = observer<Props>(function DatabaseList({ databases, h
|
||||
}
|
||||
}, [onSearch]);
|
||||
|
||||
const placeholderMessage = isSearched ? 'connections_not_found' : 'connections_administration_search_database_tip';
|
||||
const placeholderMessage = isSearched ? 'connections_not_found' : 'core_connections_search_database_tip';
|
||||
|
||||
return (
|
||||
<Form ref={focusedRef} className={s(styles, { form: true }, className)} onSubmit={onSearch}>
|
||||
<ItemListSearch
|
||||
value={hosts}
|
||||
placeholder={translate('connections_administration_search_database_tip')}
|
||||
placeholder={translate('core_connections_search_database_tip')}
|
||||
disabled={disabled}
|
||||
permanentSearchIcon
|
||||
onChange={onChange}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
* Copyright (C) 2020-2025 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
# dependencies
|
||||
/node_modules
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# production
|
||||
/lib
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env*
|
||||
|
||||
# debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
@@ -1,49 +0,0 @@
|
||||
{
|
||||
"name": "@cloudbeaver/plugin-connection-template",
|
||||
"type": "module",
|
||||
"sideEffects": [
|
||||
"src/**/*.css",
|
||||
"src/**/*.scss",
|
||||
"public/**/*"
|
||||
],
|
||||
"version": "0.1.0",
|
||||
"description": "",
|
||||
"license": "Apache-2.0",
|
||||
"exports": {
|
||||
".": "./lib/index.js"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc -b",
|
||||
"clean": "rimraf --glob lib",
|
||||
"lint": "eslint ./src/ --ext .ts,.tsx",
|
||||
"validate-dependencies": "core-cli-validate-dependencies"
|
||||
},
|
||||
"dependencies": {
|
||||
"@cloudbeaver/core-authentication": "workspace:*",
|
||||
"@cloudbeaver/core-blocks": "workspace:*",
|
||||
"@cloudbeaver/core-connections": "workspace:*",
|
||||
"@cloudbeaver/core-di": "workspace:*",
|
||||
"@cloudbeaver/core-dialogs": "workspace:*",
|
||||
"@cloudbeaver/core-events": "workspace:*",
|
||||
"@cloudbeaver/core-localization": "workspace:*",
|
||||
"@cloudbeaver/core-projects": "workspace:*",
|
||||
"@cloudbeaver/core-resource": "workspace:*",
|
||||
"@cloudbeaver/core-root": "workspace:*",
|
||||
"@cloudbeaver/core-sdk": "workspace:*",
|
||||
"@cloudbeaver/core-utils": "workspace:*",
|
||||
"@cloudbeaver/core-view": "workspace:*",
|
||||
"@cloudbeaver/plugin-connections": "workspace:*",
|
||||
"mobx": "^6",
|
||||
"mobx-react-lite": "^4",
|
||||
"react": "^19",
|
||||
"react-dom": "^19",
|
||||
"tslib": "^2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@cloudbeaver/core-cli": "workspace:*",
|
||||
"@cloudbeaver/tsconfig": "workspace:*",
|
||||
"@types/react": "^19",
|
||||
"typescript": "^5",
|
||||
"typescript-plugin-css-modules": "^5"
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { createAction } from '@cloudbeaver/core-view';
|
||||
|
||||
export const ACTION_CONNECTION_TEMPLATE = createAction('connection-template', {
|
||||
label: 'plugin_connection_template_action_connection_template_label',
|
||||
});
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
.submittingForm,
|
||||
.center {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
margin: auto;
|
||||
}
|
||||
.center {
|
||||
box-sizing: border-box;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.connectionAuthenticationFormLoader {
|
||||
align-content: center;
|
||||
}
|
||||
.errorMessage {
|
||||
composes: theme-background-secondary theme-text-on-secondary from global;
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { observer } from 'mobx-react-lite';
|
||||
|
||||
import {
|
||||
CommonDialogBody,
|
||||
CommonDialogFooter,
|
||||
CommonDialogHeader,
|
||||
CommonDialogWrapper,
|
||||
ErrorMessage,
|
||||
Form,
|
||||
InfoItem,
|
||||
s,
|
||||
useAdministrationSettings,
|
||||
useErrorDetails,
|
||||
useFocus,
|
||||
useS,
|
||||
useTranslate,
|
||||
} from '@cloudbeaver/core-blocks';
|
||||
import type { DialogComponent } from '@cloudbeaver/core-dialogs';
|
||||
import { ConnectionAuthenticationFormLoader } from '@cloudbeaver/plugin-connections';
|
||||
|
||||
import style from './ConnectionDialog.module.css';
|
||||
import { ConnectionDialogFooter } from './ConnectionDialogFooter.js';
|
||||
import { ConnectionStep } from './EConnectionStep.js';
|
||||
import { TemplateConnectionSelector } from './TemplateConnectionSelector/TemplateConnectionSelector.js';
|
||||
import { useConnectionDialog } from './useConnectionDialog.js';
|
||||
|
||||
export const ConnectionDialog: DialogComponent<null, null> = observer(function ConnectionDialog({ rejectDialog }) {
|
||||
const styles = useS(style);
|
||||
const translate = useTranslate();
|
||||
const [focusedRef] = useFocus<HTMLFormElement>({ focusFirstChild: true });
|
||||
const { credentialsSavingEnabled } = useAdministrationSettings();
|
||||
const dialog = useConnectionDialog(rejectDialog);
|
||||
const errorDetails = useErrorDetails(dialog.connectException);
|
||||
|
||||
const subTitle =
|
||||
dialog.step === ConnectionStep.Connection ? (
|
||||
dialog.template?.name
|
||||
) : (
|
||||
<InfoItem info={translate('connections_templates_deprecated_message')} compact />
|
||||
);
|
||||
|
||||
return (
|
||||
<CommonDialogWrapper size="large" fixedSize={dialog.step === ConnectionStep.ConnectionTemplateSelect}>
|
||||
<CommonDialogHeader
|
||||
title="plugin_connections_new_connection_dialog_title"
|
||||
subTitle={subTitle}
|
||||
icon={dialog.driver?.icon}
|
||||
onReject={rejectDialog}
|
||||
/>
|
||||
<CommonDialogBody noBodyPadding={dialog.step === ConnectionStep.ConnectionTemplateSelect} noOverflow>
|
||||
{dialog.step === ConnectionStep.ConnectionTemplateSelect && <TemplateConnectionSelector onSelect={dialog.selectTemplate} />}
|
||||
{dialog.step === ConnectionStep.Connection &&
|
||||
(!dialog.authModelId ? (
|
||||
<center className={s(styles, { center: true })}>{dialog.processing && translate('plugin_connection_template_connecting_message')}</center>
|
||||
) : (
|
||||
<Form ref={focusedRef} className={s(styles, { submittingForm: true })} onSubmit={dialog.connect}>
|
||||
<ConnectionAuthenticationFormLoader
|
||||
config={dialog.config}
|
||||
authModelId={dialog.authModelId}
|
||||
networkHandlers={dialog.networkHandlers}
|
||||
formId={dialog.template?.id}
|
||||
allowSaveCredentials={credentialsSavingEnabled}
|
||||
disabled={dialog.processing}
|
||||
hideFeatures={['nonSecuredProperty']}
|
||||
projectId={dialog.template?.projectId ?? null}
|
||||
className={s(styles, { connectionAuthenticationFormLoader: true })}
|
||||
/>
|
||||
</Form>
|
||||
))}
|
||||
</CommonDialogBody>
|
||||
{dialog.step === ConnectionStep.Connection && (
|
||||
<CommonDialogFooter>
|
||||
{dialog.connectException && (
|
||||
<ErrorMessage
|
||||
text={errorDetails.message ?? translate('core_blocks_exception_message_error_message')}
|
||||
hasDetails={errorDetails.hasDetails}
|
||||
className={s(styles, { errorMessage: true })}
|
||||
onShowDetails={errorDetails.open}
|
||||
/>
|
||||
)}
|
||||
<ConnectionDialogFooter
|
||||
isConnecting={dialog.processing}
|
||||
onBack={() => dialog.setStep(ConnectionStep.ConnectionTemplateSelect)}
|
||||
onConnect={dialog.connect}
|
||||
/>
|
||||
</CommonDialogFooter>
|
||||
)}
|
||||
</CommonDialogWrapper>
|
||||
);
|
||||
});
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
.controls {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
margin: auto;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.fill {
|
||||
flex: 1;
|
||||
}
|
||||
-34
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { observer } from 'mobx-react-lite';
|
||||
|
||||
import { Button, useS, useTranslate } from '@cloudbeaver/core-blocks';
|
||||
|
||||
import style from './ConnectionDialogFooter.module.css';
|
||||
|
||||
interface Props {
|
||||
isConnecting: boolean;
|
||||
onConnect: () => void;
|
||||
onBack: () => void;
|
||||
}
|
||||
|
||||
export const ConnectionDialogFooter = observer<Props>(function ConnectionDialogFooter({ isConnecting, onConnect, onBack }) {
|
||||
const styles = useS(style);
|
||||
const translate = useTranslate();
|
||||
return (
|
||||
<div className={styles['controls']}>
|
||||
<div className={styles['fill']} />
|
||||
<Button type="button" mod={['outlined']} disabled={isConnecting} onClick={onBack}>
|
||||
{translate('ui_stepper_back')}
|
||||
</Button>
|
||||
<Button type="button" mod={['unelevated']} disabled={isConnecting} onClick={onConnect}>
|
||||
{isConnecting ? translate('ui_processing_connecting') : translate('connections_connection_connect')}
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
@@ -1,11 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
export enum ConnectionStep {
|
||||
ConnectionTemplateSelect,
|
||||
Connection,
|
||||
}
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
.staticImage {
|
||||
box-sizing: border-box;
|
||||
width: 24px;
|
||||
max-height: 24px;
|
||||
}
|
||||
-35
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { ListItem, ListItemDescription, ListItemIcon, ListItemName, s, StaticImage, useS } from '@cloudbeaver/core-blocks';
|
||||
import type { Connection, DBDriver } from '@cloudbeaver/core-connections';
|
||||
|
||||
import styles from './TemplateConnectionItem.module.css';
|
||||
|
||||
interface Props {
|
||||
template: Connection;
|
||||
dbDriver?: DBDriver;
|
||||
onSelect: (connectionId: string) => void;
|
||||
}
|
||||
|
||||
export const TemplateConnectionItem = observer<Props>(function TemplateConnectionItem({ template, dbDriver, onSelect }) {
|
||||
const select = useCallback(() => onSelect(template.id), [template]);
|
||||
const style = useS(styles);
|
||||
|
||||
return (
|
||||
<ListItem onClick={select}>
|
||||
<ListItemIcon>
|
||||
<StaticImage className={s(style, { staticImage: true })} icon={dbDriver?.icon} />
|
||||
</ListItemIcon>
|
||||
<ListItemName>{template.name}</ListItemName>
|
||||
<ListItemDescription title={template.description}>{template.description}</ListItemDescription>
|
||||
</ListItem>
|
||||
);
|
||||
});
|
||||
-57
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { useMemo, useState } from 'react';
|
||||
|
||||
import { ItemList, ItemListSearch, useResource } from '@cloudbeaver/core-blocks';
|
||||
import { DBDriverResource } from '@cloudbeaver/core-connections';
|
||||
import { useService } from '@cloudbeaver/core-di';
|
||||
import { ProjectInfoResource } from '@cloudbeaver/core-projects';
|
||||
import { CachedMapAllKey } from '@cloudbeaver/core-resource';
|
||||
|
||||
import { TemplateConnectionsResource } from '../../TemplateConnectionsResource.js';
|
||||
import { TemplateConnectionsService } from '../../TemplateConnectionsService.js';
|
||||
import { TemplateConnectionItem } from './TemplateConnectionItem.js';
|
||||
|
||||
interface Props {
|
||||
className?: string;
|
||||
onSelect: (dbSourceId: string) => void;
|
||||
}
|
||||
|
||||
export const TemplateConnectionSelector = observer<Props>(function TemplateConnectionSelector({ className, onSelect }) {
|
||||
useResource(TemplateConnectionSelector, ProjectInfoResource, CachedMapAllKey, { forceSuspense: true });
|
||||
useResource(TemplateConnectionSelector, TemplateConnectionsResource, undefined, { forceSuspense: true });
|
||||
const dbDriverResource = useResource(TemplateConnectionSelector, DBDriverResource, CachedMapAllKey);
|
||||
const templateConnectionsService = useService(TemplateConnectionsService);
|
||||
|
||||
const templateConnections = templateConnectionsService.projectTemplates;
|
||||
|
||||
const [search, setSearch] = useState('');
|
||||
const filteredTemplateConnections = useMemo(() => {
|
||||
if (!search) {
|
||||
return templateConnections;
|
||||
}
|
||||
return templateConnections.filter(template => template.name.toUpperCase().includes(search.toUpperCase()));
|
||||
}, [search, templateConnections]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ItemListSearch onChange={setSearch} />
|
||||
<ItemList className={className}>
|
||||
{filteredTemplateConnections.map(template => (
|
||||
<TemplateConnectionItem
|
||||
key={template.id}
|
||||
template={template}
|
||||
dbDriver={dbDriverResource.resource.get(template.driverId)}
|
||||
onSelect={onSelect}
|
||||
/>
|
||||
))}
|
||||
</ItemList>
|
||||
</>
|
||||
);
|
||||
});
|
||||
-208
@@ -1,208 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { action, computed, observable } from 'mobx';
|
||||
|
||||
import { AuthProviderService } from '@cloudbeaver/core-authentication';
|
||||
import { useObservableRef } from '@cloudbeaver/core-blocks';
|
||||
import {
|
||||
type Connection,
|
||||
ConnectionInfoProjectKey,
|
||||
ConnectionInfoResource,
|
||||
type ConnectionInitConfig,
|
||||
createConnectionParam,
|
||||
type DBDriver,
|
||||
DBDriverResource,
|
||||
USER_NAME_PROPERTY_ID,
|
||||
} from '@cloudbeaver/core-connections';
|
||||
import { useService } from '@cloudbeaver/core-di';
|
||||
import { NotificationService } from '@cloudbeaver/core-events';
|
||||
import { ProjectsService } from '@cloudbeaver/core-projects';
|
||||
import { NetworkHandlerAuthType } from '@cloudbeaver/core-sdk';
|
||||
import { getUniqueName } from '@cloudbeaver/core-utils';
|
||||
import type { IConnectionAuthenticationConfig } from '@cloudbeaver/plugin-connections';
|
||||
|
||||
import { TemplateConnectionsService } from '../TemplateConnectionsService.js';
|
||||
import { ConnectionStep } from './EConnectionStep.js';
|
||||
|
||||
interface IState {
|
||||
readonly networkHandlers: string[];
|
||||
readonly authModelId: string | null;
|
||||
step: ConnectionStep;
|
||||
driver: DBDriver | null;
|
||||
template: Connection | null;
|
||||
config: IConnectionAuthenticationConfig;
|
||||
processing: boolean;
|
||||
connectException: Error | null;
|
||||
connect: () => Promise<void>;
|
||||
setStep: (step: ConnectionStep) => void;
|
||||
getConfig: (projectId: string, connectionId: string) => ConnectionInitConfig;
|
||||
selectTemplate: (templateId: string) => Promise<void>;
|
||||
}
|
||||
|
||||
function getDefaultConfig(): IConnectionAuthenticationConfig {
|
||||
return {
|
||||
credentials: {},
|
||||
networkHandlersConfig: [],
|
||||
saveCredentials: false,
|
||||
};
|
||||
}
|
||||
|
||||
export function useConnectionDialog(onConnect?: () => void) {
|
||||
const notificationService = useService(NotificationService);
|
||||
const connectionInfoResource = useService(ConnectionInfoResource);
|
||||
const templateConnectionsService = useService(TemplateConnectionsService);
|
||||
const projectsService = useService(ProjectsService);
|
||||
const authProviderService = useService(AuthProviderService);
|
||||
const dbDriverResource = useService(DBDriverResource);
|
||||
|
||||
const state: IState = useObservableRef(
|
||||
() => ({
|
||||
get networkHandlers() {
|
||||
return this.template?.networkHandlersConfig?.filter(handler => handler.enabled && !handler.savePassword).map(handler => handler.id) || [];
|
||||
},
|
||||
get authModelId() {
|
||||
if (this.template?.authNeeded === false || this.driver?.anonymousAccess === true) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.template?.authModel || this.driver?.defaultAuthModel || null;
|
||||
},
|
||||
step: ConnectionStep.ConnectionTemplateSelect,
|
||||
template: null as Connection | null,
|
||||
driver: null as DBDriver | null,
|
||||
processing: false,
|
||||
connectException: null,
|
||||
config: getDefaultConfig(),
|
||||
async connect() {
|
||||
if (this.processing || !this.template || !this.projectsService.userProject) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
this.connectException = null;
|
||||
this.processing = true;
|
||||
|
||||
const connections = await this.connectionInfoResource.load(ConnectionInfoProjectKey(this.projectsService.userProject.id));
|
||||
const connectionNames = connections.map(connection => connection.name);
|
||||
|
||||
const uniqueConnectionName = getUniqueName(this.template.name || 'Template connection', connectionNames);
|
||||
const connection = await this.connectionInfoResource.createFromTemplate(this.template.projectId, this.template.id, uniqueConnectionName);
|
||||
|
||||
if (connection.requiredAuth) {
|
||||
const state = await this.authProviderService.requireProvider(connection.requiredAuth);
|
||||
|
||||
if (!state) {
|
||||
this.setStep(ConnectionStep.ConnectionTemplateSelect);
|
||||
await this.connectionInfoResource.deleteConnection(createConnectionParam(connection));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
await this.connectionInfoResource.init(this.getConfig(connection.projectId, connection.id));
|
||||
this.notificationService.logSuccess({ title: 'plugin_connection_template_connect_success', message: connection.name });
|
||||
this.onConnect?.();
|
||||
} catch (exception: any) {
|
||||
this.connectException = exception;
|
||||
await this.connectionInfoResource.deleteConnection(createConnectionParam(connection));
|
||||
}
|
||||
} catch (exception: any) {
|
||||
this.connectException = exception;
|
||||
} finally {
|
||||
this.processing = false;
|
||||
}
|
||||
},
|
||||
getConfig(projectId: string, connectionId: string) {
|
||||
const config: ConnectionInitConfig = {
|
||||
projectId,
|
||||
connectionId,
|
||||
};
|
||||
|
||||
if (this.authModelId) {
|
||||
if (Object.keys(this.config.credentials).length > 0) {
|
||||
config.credentials = this.config.credentials;
|
||||
}
|
||||
|
||||
config.saveCredentials = this.config.saveCredentials;
|
||||
}
|
||||
|
||||
if (this.config.networkHandlersConfig.length > 0) {
|
||||
config.networkCredentials = this.config.networkHandlersConfig;
|
||||
}
|
||||
|
||||
return config;
|
||||
},
|
||||
async selectTemplate(templateId: string) {
|
||||
this.template = this.templateConnectionsService.projectTemplates.find(template => template.id === templateId)!;
|
||||
this.driver = await this.dbDriverResource.load(this.template.driverId);
|
||||
this.config = getDefaultConfig();
|
||||
|
||||
if (this.template.authNeeded) {
|
||||
const property = this.template.authProperties?.find(property => property.id === USER_NAME_PROPERTY_ID);
|
||||
|
||||
if (property?.value) {
|
||||
this.config.credentials[USER_NAME_PROPERTY_ID] = property.value;
|
||||
}
|
||||
}
|
||||
|
||||
for (const id of this.networkHandlers) {
|
||||
const handler = this.template.networkHandlersConfig?.find(handler => handler.id === id);
|
||||
|
||||
if (handler && (handler.userName || handler.authType !== NetworkHandlerAuthType.Password)) {
|
||||
this.config.networkHandlersConfig.push({
|
||||
id: handler.id,
|
||||
authType: handler.authType,
|
||||
userName: handler.userName,
|
||||
password: handler.password,
|
||||
savePassword: handler.savePassword,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this.setStep(ConnectionStep.Connection);
|
||||
|
||||
if (!this.authModelId) {
|
||||
this.connect();
|
||||
}
|
||||
},
|
||||
setStep(step: ConnectionStep) {
|
||||
this.step = step;
|
||||
this.connectException = null;
|
||||
|
||||
if (step === ConnectionStep.ConnectionTemplateSelect) {
|
||||
this.template = null;
|
||||
this.driver = null;
|
||||
}
|
||||
},
|
||||
}),
|
||||
{
|
||||
step: observable.ref,
|
||||
config: observable,
|
||||
template: observable.ref,
|
||||
driver: observable.ref,
|
||||
processing: observable.ref,
|
||||
connectException: observable.ref,
|
||||
networkHandlers: computed,
|
||||
authModelId: computed,
|
||||
connect: action.bound,
|
||||
selectTemplate: action.bound,
|
||||
setStep: action.bound,
|
||||
},
|
||||
{
|
||||
templateConnectionsService,
|
||||
projectsService,
|
||||
notificationService,
|
||||
authProviderService,
|
||||
connectionInfoResource,
|
||||
dbDriverResource,
|
||||
onConnect,
|
||||
},
|
||||
);
|
||||
|
||||
return state;
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { Bootstrap, injectable } from '@cloudbeaver/core-di';
|
||||
import { LocalizationService } from '@cloudbeaver/core-localization';
|
||||
|
||||
@injectable()
|
||||
export class LocaleService extends Bootstrap {
|
||||
constructor(private readonly localizationService: LocalizationService) {
|
||||
super();
|
||||
}
|
||||
|
||||
override register(): void {
|
||||
this.localizationService.addProvider(this.provider.bind(this));
|
||||
}
|
||||
|
||||
private async provider(locale: string) {
|
||||
switch (locale) {
|
||||
case 'ru':
|
||||
return (await import('./locales/ru.js')).default;
|
||||
case 'it':
|
||||
return (await import('./locales/it.js')).default;
|
||||
case 'zh':
|
||||
return (await import('./locales/zh.js')).default;
|
||||
case 'fr':
|
||||
return (await import('./locales/fr.js')).default;
|
||||
default:
|
||||
return (await import('./locales/en.js')).default;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { AppAuthService } from '@cloudbeaver/core-authentication';
|
||||
import { importLazyComponent } from '@cloudbeaver/core-blocks';
|
||||
import { Bootstrap, injectable } from '@cloudbeaver/core-di';
|
||||
import { CommonDialogService } from '@cloudbeaver/core-dialogs';
|
||||
import { ProjectInfoResource, ProjectsService } from '@cloudbeaver/core-projects';
|
||||
import { CachedMapAllKey, getCachedDataResourceLoaderState, getCachedMapResourceLoaderState } from '@cloudbeaver/core-resource';
|
||||
import { ActionService, MenuService } from '@cloudbeaver/core-view';
|
||||
import { MENU_CONNECTIONS } from '@cloudbeaver/plugin-connections';
|
||||
|
||||
import { ACTION_CONNECTION_TEMPLATE } from './Actions/ACTION_CONNECTION_TEMPLATE.js';
|
||||
import { TemplateConnectionsResource } from './TemplateConnectionsResource.js';
|
||||
import { TemplateConnectionsService } from './TemplateConnectionsService.js';
|
||||
|
||||
const ConnectionDialog = importLazyComponent(() => import('./ConnectionDialog/ConnectionDialog.js').then(m => m.ConnectionDialog));
|
||||
|
||||
@injectable()
|
||||
export class TemplateConnectionPluginBootstrap extends Bootstrap {
|
||||
constructor(
|
||||
private readonly appAuthService: AppAuthService,
|
||||
private readonly menuService: MenuService,
|
||||
private readonly actionService: ActionService,
|
||||
private readonly projectInfoResource: ProjectInfoResource,
|
||||
private readonly templateConnectionsResource: TemplateConnectionsResource,
|
||||
private readonly commonDialogService: CommonDialogService,
|
||||
private readonly templateConnectionsService: TemplateConnectionsService,
|
||||
private readonly projectsService: ProjectsService,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
override register(): void | Promise<void> {
|
||||
this.menuService.addCreator({
|
||||
menus: [MENU_CONNECTIONS],
|
||||
getItems: (context, items) => [...items, ACTION_CONNECTION_TEMPLATE],
|
||||
});
|
||||
|
||||
this.actionService.addHandler({
|
||||
id: 'connection-template',
|
||||
actions: [ACTION_CONNECTION_TEMPLATE],
|
||||
isHidden: () =>
|
||||
!this.appAuthService.authenticated ||
|
||||
!this.projectsService.userProject?.canEditDataSources ||
|
||||
!this.templateConnectionsService.projectTemplates.length,
|
||||
getLoader: () => [
|
||||
...this.appAuthService.loaders,
|
||||
getCachedMapResourceLoaderState(this.projectInfoResource, () => CachedMapAllKey),
|
||||
getCachedDataResourceLoaderState(
|
||||
this.templateConnectionsResource,
|
||||
() => undefined,
|
||||
() => undefined,
|
||||
),
|
||||
],
|
||||
handler: async (context, action) => {
|
||||
switch (action) {
|
||||
case ACTION_CONNECTION_TEMPLATE: {
|
||||
await this.openConnectionsDialog();
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
private async openConnectionsDialog() {
|
||||
await this.commonDialogService.open(ConnectionDialog, null);
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { AppAuthService } from '@cloudbeaver/core-authentication';
|
||||
import { type Connection, ConnectionInfoResource } from '@cloudbeaver/core-connections';
|
||||
import { injectable } from '@cloudbeaver/core-di';
|
||||
import { CachedDataResource, ResourceKeyUtils } from '@cloudbeaver/core-resource';
|
||||
import { SessionDataResource } from '@cloudbeaver/core-root';
|
||||
import { GraphQLService } from '@cloudbeaver/core-sdk';
|
||||
|
||||
@injectable()
|
||||
export class TemplateConnectionsResource extends CachedDataResource<Connection[]> {
|
||||
constructor(
|
||||
private readonly graphQLService: GraphQLService,
|
||||
connectionInfoResource: ConnectionInfoResource,
|
||||
sessionDataResource: SessionDataResource,
|
||||
appAuthService: AppAuthService,
|
||||
) {
|
||||
super(() => []);
|
||||
|
||||
this.sync(sessionDataResource);
|
||||
|
||||
appAuthService.requireAuthentication(this);
|
||||
|
||||
connectionInfoResource.onConnectionCreate.addHandler(connection => {
|
||||
if (connection.template) {
|
||||
this.markOutdated();
|
||||
}
|
||||
});
|
||||
|
||||
connectionInfoResource.onDataOutdated.addHandler(key => {
|
||||
const keyData = connectionInfoResource.get(key);
|
||||
const connections = Array.isArray(keyData) ? keyData : [keyData];
|
||||
|
||||
if (connections.some(connection => connection?.template)) {
|
||||
this.markOutdated();
|
||||
}
|
||||
});
|
||||
|
||||
connectionInfoResource.onItemUpdate.addHandler(list => {
|
||||
const includesTemplate = connectionInfoResource.get(ResourceKeyUtils.toList(list)).some(connection => connection?.template);
|
||||
|
||||
if (includesTemplate) {
|
||||
this.markOutdated();
|
||||
}
|
||||
});
|
||||
|
||||
connectionInfoResource.onItemDelete.addHandler(list => {
|
||||
const includesTemplate = connectionInfoResource.get(ResourceKeyUtils.toList(list)).some(connection => connection?.template);
|
||||
|
||||
if (includesTemplate) {
|
||||
this.markOutdated();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected async loader(): Promise<Connection[]> {
|
||||
const { connections } = await this.graphQLService.sdk.getTemplateConnections({
|
||||
includeNetworkHandlersConfig: true,
|
||||
includeAuthProperties: true,
|
||||
includeAuthNeeded: true,
|
||||
includeCredentialsSaved: false,
|
||||
includeProperties: false,
|
||||
includeProviderProperties: false,
|
||||
customIncludeOptions: false,
|
||||
});
|
||||
return connections;
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import type { Connection } from '@cloudbeaver/core-connections';
|
||||
import { injectable } from '@cloudbeaver/core-di';
|
||||
import { ProjectsService } from '@cloudbeaver/core-projects';
|
||||
|
||||
import { TemplateConnectionsResource } from './TemplateConnectionsResource.js';
|
||||
|
||||
@injectable()
|
||||
export class TemplateConnectionsService {
|
||||
get projectTemplates(): Connection[] {
|
||||
if (this.projectsService.userProject && this.projectsService.activeProjects.includes(this.projectsService.userProject)) {
|
||||
return this.templateConnectionsResource.data;
|
||||
}
|
||||
|
||||
// return this.templateConnectionsResource.data
|
||||
// .filter(
|
||||
// connection => this.projectsService.activeProjects.some(project => project.id === connection.projectId)
|
||||
// );
|
||||
return [];
|
||||
}
|
||||
constructor(
|
||||
private readonly templateConnectionsResource: TemplateConnectionsResource,
|
||||
private readonly projectsService: ProjectsService,
|
||||
) {}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { connectionTemplate } from './manifest.js';
|
||||
|
||||
export default connectionTemplate;
|
||||
@@ -1,5 +0,0 @@
|
||||
export default [
|
||||
['plugin_connection_template_connecting_message', 'Connecting to database...'],
|
||||
['plugin_connection_template_connect_success', 'Connection is established'],
|
||||
['plugin_connection_template_action_connection_template_label', 'From a Template'],
|
||||
];
|
||||
@@ -1,5 +0,0 @@
|
||||
export default [
|
||||
['plugin_connection_template_connecting_message', 'Connexion à la base de données en cours...'],
|
||||
['plugin_connection_template_connect_success', 'Connexion établie'],
|
||||
['plugin_connection_template_action_connection_template_label', "À partir d'un modèle"],
|
||||
];
|
||||
@@ -1,5 +0,0 @@
|
||||
export default [
|
||||
['plugin_connection_template_connecting_message', 'Collegamento al database...'],
|
||||
['plugin_connection_template_connect_success', 'Connection is established'],
|
||||
['plugin_connection_template_action_connection_template_label', 'Dal Template'],
|
||||
];
|
||||
@@ -1,5 +0,0 @@
|
||||
export default [
|
||||
['plugin_connection_template_connecting_message', 'Подключение к базе...'],
|
||||
['plugin_connection_template_connect_success', 'Подключение установлено'],
|
||||
['plugin_connection_template_action_connection_template_label', 'Из шаблона'],
|
||||
];
|
||||
@@ -1,5 +0,0 @@
|
||||
export default [
|
||||
['plugin_connection_template_connecting_message', '连接数据库...'],
|
||||
['plugin_connection_template_connect_success', '已建立连接'],
|
||||
['plugin_connection_template_action_connection_template_label', '从模板创建'],
|
||||
];
|
||||
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import type { PluginManifest } from '@cloudbeaver/core-di';
|
||||
|
||||
export const connectionTemplate: PluginManifest = {
|
||||
info: {
|
||||
name: 'Template Connections plugin',
|
||||
},
|
||||
|
||||
providers: [
|
||||
() => import('./TemplateConnectionsResource.js').then(m => m.TemplateConnectionsResource),
|
||||
() => import('./LocaleService.js').then(m => m.LocaleService),
|
||||
() => import('./TemplateConnectionPluginBootstrap.js').then(m => m.TemplateConnectionPluginBootstrap),
|
||||
() => import('./TemplateConnectionsService.js').then(m => m.TemplateConnectionsService),
|
||||
],
|
||||
};
|
||||
@@ -1,67 +0,0 @@
|
||||
{
|
||||
"extends": "@cloudbeaver/tsconfig/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "src",
|
||||
"outDir": "lib",
|
||||
"tsBuildInfoFile": "lib/tsconfig.tsbuildinfo",
|
||||
"composite": true
|
||||
},
|
||||
"references": [
|
||||
{
|
||||
"path": "../core-authentication"
|
||||
},
|
||||
{
|
||||
"path": "../core-blocks"
|
||||
},
|
||||
{
|
||||
"path": "../core-cli"
|
||||
},
|
||||
{
|
||||
"path": "../core-connections"
|
||||
},
|
||||
{
|
||||
"path": "../core-di"
|
||||
},
|
||||
{
|
||||
"path": "../core-dialogs"
|
||||
},
|
||||
{
|
||||
"path": "../core-events"
|
||||
},
|
||||
{
|
||||
"path": "../core-localization"
|
||||
},
|
||||
{
|
||||
"path": "../core-projects"
|
||||
},
|
||||
{
|
||||
"path": "../core-resource"
|
||||
},
|
||||
{
|
||||
"path": "../core-root"
|
||||
},
|
||||
{
|
||||
"path": "../core-sdk"
|
||||
},
|
||||
{
|
||||
"path": "../core-utils"
|
||||
},
|
||||
{
|
||||
"path": "../core-view"
|
||||
},
|
||||
{
|
||||
"path": "../plugin-connections"
|
||||
}
|
||||
],
|
||||
"include": [
|
||||
"__custom_mocks__/**/*",
|
||||
"src/**/*",
|
||||
"src/**/*.json",
|
||||
"src/**/*.css",
|
||||
"src/**/*.scss"
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules",
|
||||
"lib/**/*"
|
||||
]
|
||||
}
|
||||
@@ -14,4 +14,4 @@
|
||||
# debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
yarn-error.log*
|
||||
@@ -25,8 +25,6 @@
|
||||
"@cloudbeaver/core-connections": "workspace:*",
|
||||
"@cloudbeaver/core-data-context": "workspace:*",
|
||||
"@cloudbeaver/core-di": "workspace:*",
|
||||
"@cloudbeaver/core-dialogs": "workspace:*",
|
||||
"@cloudbeaver/core-events": "workspace:*",
|
||||
"@cloudbeaver/core-executor": "workspace:*",
|
||||
"@cloudbeaver/core-localization": "workspace:*",
|
||||
"@cloudbeaver/core-projects": "workspace:*",
|
||||
|
||||
-14
@@ -1,14 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
.groupItem {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.error {
|
||||
padding: 24px;
|
||||
}
|
||||
-99
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { observer } from 'mobx-react-lite';
|
||||
|
||||
import type { AdministrationItemContentProps } from '@cloudbeaver/core-administration';
|
||||
import {
|
||||
ColoredContainer,
|
||||
Container,
|
||||
ExceptionMessageStyles,
|
||||
Group,
|
||||
GroupItem,
|
||||
GroupTitle,
|
||||
InfoItem,
|
||||
Loader,
|
||||
s,
|
||||
SContext,
|
||||
type StyleRegistry,
|
||||
ToolsAction,
|
||||
ToolsPanel,
|
||||
useS,
|
||||
useTranslate,
|
||||
} from '@cloudbeaver/core-blocks';
|
||||
|
||||
import ConnectionsAdministrationStyle from './ConnectionsAdministration.module.css';
|
||||
import { ConnectionsTable } from './ConnectionsTable/ConnectionsTable.js';
|
||||
import { useConnectionsTable } from './ConnectionsTable/useConnectionsTable.js';
|
||||
import { CreateConnection } from './CreateConnection/CreateConnection.js';
|
||||
|
||||
const registry: StyleRegistry = [
|
||||
[
|
||||
ExceptionMessageStyles,
|
||||
{
|
||||
mode: 'append',
|
||||
styles: [ConnectionsAdministrationStyle],
|
||||
},
|
||||
],
|
||||
];
|
||||
|
||||
export const ConnectionsAdministration = observer<AdministrationItemContentProps>(function ConnectionsAdministration({
|
||||
sub,
|
||||
param,
|
||||
configurationWizard,
|
||||
}) {
|
||||
const style = useS(ConnectionsAdministrationStyle);
|
||||
const translate = useTranslate();
|
||||
|
||||
const state = useConnectionsTable();
|
||||
|
||||
return (
|
||||
<ColoredContainer vertical wrap parent gap>
|
||||
<Group keepSize dense>
|
||||
<InfoItem info={translate('connections_templates_deprecated_message')} />
|
||||
</Group>
|
||||
<Group box keepSize>
|
||||
<ToolsPanel rounded>
|
||||
<ToolsAction
|
||||
title={translate('connections_administration_tools_refresh_tooltip')}
|
||||
icon="refresh"
|
||||
viewBox="0 0 24 24"
|
||||
disabled={state.loading}
|
||||
onClick={state.update}
|
||||
>
|
||||
{translate('ui_refresh')}
|
||||
</ToolsAction>
|
||||
<ToolsAction
|
||||
title={translate('connections_administration_tools_delete_tooltip')}
|
||||
icon="trash"
|
||||
viewBox="0 0 24 24"
|
||||
disabled={!state.table.itemsSelected || state.loading}
|
||||
onClick={state.delete}
|
||||
>
|
||||
{translate('ui_delete')}
|
||||
</ToolsAction>
|
||||
</ToolsPanel>
|
||||
</Group>
|
||||
<Container overflow gap>
|
||||
{configurationWizard && (
|
||||
<Group gap>
|
||||
<GroupTitle>{translate('connections_administration_configuration_wizard_title')}</GroupTitle>
|
||||
<GroupItem className={s(style, { groupItem: true })}>{translate('connections_administration_configuration_wizard_message')}</GroupItem>
|
||||
</Group>
|
||||
)}
|
||||
{sub && <CreateConnection method={param} configurationWizard={configurationWizard} />}
|
||||
<Group boxNoOverflow>
|
||||
<SContext registry={registry}>
|
||||
<Loader loading={state.loading} overlay>
|
||||
<ConnectionsTable state={state} />
|
||||
</Loader>
|
||||
</SContext>
|
||||
</Group>
|
||||
</Container>
|
||||
</ColoredContainer>
|
||||
);
|
||||
});
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { AdministrationScreenService } from '@cloudbeaver/core-administration';
|
||||
import { injectable } from '@cloudbeaver/core-di';
|
||||
|
||||
@injectable()
|
||||
export class ConnectionsAdministrationNavService {
|
||||
constructor(private readonly administrationScreenService: AdministrationScreenService) {}
|
||||
|
||||
navToRoot() {
|
||||
this.administrationScreenService.navigateToItem('connections');
|
||||
}
|
||||
|
||||
navToCreate(method: string) {
|
||||
this.administrationScreenService.navigateToItemSub('connections', 'create', method);
|
||||
}
|
||||
}
|
||||
-124
@@ -1,124 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2025 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import React from 'react';
|
||||
|
||||
import { AdministrationItemService, AdministrationItemType } from '@cloudbeaver/core-administration';
|
||||
import { ConfirmationDialog, PlaceholderContainer } from '@cloudbeaver/core-blocks';
|
||||
import { type ConnectionInfoOrigin, ConnectionInfoResource, type DatabaseConnection } from '@cloudbeaver/core-connections';
|
||||
import { Bootstrap, injectable } from '@cloudbeaver/core-di';
|
||||
import { CommonDialogService, DialogueStateResult } from '@cloudbeaver/core-dialogs';
|
||||
import { ServerConfigResource } from '@cloudbeaver/core-root';
|
||||
|
||||
import { CreateConnectionService } from './CreateConnectionService.js';
|
||||
import { CachedMapAllKey, getCachedDataResourceLoaderState, getCachedMapResourceLoaderState } from '@cloudbeaver/core-resource';
|
||||
|
||||
export interface IConnectionDetailsPlaceholderProps {
|
||||
connection: DatabaseConnection;
|
||||
connectionOrigin?: ConnectionInfoOrigin;
|
||||
}
|
||||
|
||||
const ConnectionsAdministration = React.lazy(async () => {
|
||||
const { ConnectionsAdministration } = await import('./ConnectionsAdministration.js');
|
||||
return { default: ConnectionsAdministration };
|
||||
});
|
||||
const ConnectionsDrawerItem = React.lazy(async () => {
|
||||
const { ConnectionsDrawerItem } = await import('./ConnectionsDrawerItem.js');
|
||||
return { default: ConnectionsDrawerItem };
|
||||
});
|
||||
const Origin = React.lazy(async () => {
|
||||
const { Origin } = await import('./ConnectionsTable/ConnectionDetailsInfo/Origin.js');
|
||||
return { default: Origin };
|
||||
});
|
||||
const SSH = React.lazy(async () => {
|
||||
const { SSH } = await import('./ConnectionsTable/ConnectionDetailsInfo/SSH.js');
|
||||
return { default: SSH };
|
||||
});
|
||||
|
||||
@injectable()
|
||||
export class ConnectionsAdministrationService extends Bootstrap {
|
||||
readonly connectionDetailsPlaceholder = new PlaceholderContainer<IConnectionDetailsPlaceholderProps>();
|
||||
|
||||
constructor(
|
||||
private readonly administrationItemService: AdministrationItemService,
|
||||
private readonly connectionInfoResource: ConnectionInfoResource,
|
||||
private readonly createConnectionService: CreateConnectionService,
|
||||
private readonly commonDialogService: CommonDialogService,
|
||||
private readonly serverConfigResource: ServerConfigResource,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
override register(): void {
|
||||
this.administrationItemService.create({
|
||||
name: 'connections',
|
||||
type: AdministrationItemType.Administration,
|
||||
order: 5,
|
||||
configurationWizardOptions: {
|
||||
defaultRoute: { sub: 'create' },
|
||||
description: 'connections_administration_configuration_wizard_step_description',
|
||||
},
|
||||
sub: [
|
||||
{
|
||||
name: 'create',
|
||||
onActivate: this.activateCreateMethod.bind(this),
|
||||
onDeActivate: this.deactivateCreateMethod.bind(this),
|
||||
canDeActivate: this.canDeActivateCreate.bind(this),
|
||||
},
|
||||
],
|
||||
getLoader: () => [
|
||||
getCachedDataResourceLoaderState(this.serverConfigResource, () => undefined),
|
||||
getCachedMapResourceLoaderState(this.connectionInfoResource, () => CachedMapAllKey),
|
||||
],
|
||||
isHidden: () => this.serverConfigResource.distributed || !this.connectionInfoResource.values.some(connection => connection.template),
|
||||
getContentComponent: () => ConnectionsAdministration,
|
||||
getDrawerComponent: () => ConnectionsDrawerItem,
|
||||
onDeActivate: this.refreshUserConnections.bind(this),
|
||||
});
|
||||
this.connectionDetailsPlaceholder.add(Origin, 0);
|
||||
this.connectionDetailsPlaceholder.add(SSH, 2);
|
||||
}
|
||||
|
||||
private refreshUserConnections(configuration: boolean, outside: boolean, outsideAdminPage: boolean): void {
|
||||
// TODO: we have to track users' leaving the page
|
||||
if (outside) {
|
||||
this.connectionInfoResource.cleanNewFlags();
|
||||
// const updated = await this.connectionInfoResource.updateSessionConnections();
|
||||
|
||||
// if (updated) {
|
||||
// this.sessionDataResource.markOutdated();
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
private activateCreateMethod(param: string | null) {
|
||||
if (!param) {
|
||||
this.createConnectionService.setCreateMethod();
|
||||
}
|
||||
this.createConnectionService.setCreateMethod(param);
|
||||
}
|
||||
|
||||
private deactivateCreateMethod(param: string | null, configuration: boolean, outside: boolean) {
|
||||
if (outside) {
|
||||
this.createConnectionService.close();
|
||||
}
|
||||
}
|
||||
|
||||
private async canDeActivateCreate() {
|
||||
if (this.createConnectionService.data === null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const result = await this.commonDialogService.open(ConfirmationDialog, {
|
||||
title: 'ui_changes_will_be_lost',
|
||||
message: 'connections_administration_deactivate_message',
|
||||
confirmActionText: 'ui_continue',
|
||||
});
|
||||
|
||||
return result !== DialogueStateResult.Rejected;
|
||||
}
|
||||
}
|
||||
-26
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import type { AdministrationItemDrawerProps } from '@cloudbeaver/core-administration';
|
||||
import { Translate } from '@cloudbeaver/core-blocks';
|
||||
import { TabIcon, Tab, TabTitle } from '@cloudbeaver/core-ui';
|
||||
|
||||
export const ConnectionsDrawerItem: React.FC<AdministrationItemDrawerProps> = function ConnectionsDrawerItem({
|
||||
item,
|
||||
onSelect,
|
||||
disabled,
|
||||
configurationWizard,
|
||||
}) {
|
||||
return (
|
||||
<Tab tabId={item.name} disabled={disabled} onOpen={() => onSelect(item.name)}>
|
||||
<TabIcon icon="/icons/connection.svg" />
|
||||
<TabTitle>
|
||||
<Translate token={configurationWizard ? 'connections_administration_configuration_wizard_step_title' : 'connections_administration_item'} />
|
||||
</TabTitle>
|
||||
</Tab>
|
||||
);
|
||||
};
|
||||
-26
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2025 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
.staticImage {
|
||||
display: flex;
|
||||
width: 24px;
|
||||
min-width: 24px;
|
||||
|
||||
&:not(:last-child) {
|
||||
margin-right: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.tableColumnValueExpand {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.tableItemSelect {
|
||||
margin-left: -10px;
|
||||
margin-right: -10px;
|
||||
}
|
||||
-79
@@ -1,79 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { observer } from 'mobx-react-lite';
|
||||
|
||||
import {
|
||||
Loader,
|
||||
Placeholder,
|
||||
s,
|
||||
StaticImage,
|
||||
TableColumnValue,
|
||||
TableItem,
|
||||
TableItemExpand,
|
||||
TableItemSelect,
|
||||
useResource,
|
||||
useS,
|
||||
} from '@cloudbeaver/core-blocks';
|
||||
import { type ConnectionInfoOrigin, type DatabaseConnection, type IConnectionInfoParams } from '@cloudbeaver/core-connections';
|
||||
import { useService } from '@cloudbeaver/core-di';
|
||||
import { ProjectInfoResource } from '@cloudbeaver/core-projects';
|
||||
|
||||
import { ConnectionsAdministrationService } from '../ConnectionsAdministrationService.js';
|
||||
import styles from './Connection.module.css';
|
||||
import { ConnectionEdit } from './ConnectionEdit.js';
|
||||
|
||||
interface Props {
|
||||
connectionKey: IConnectionInfoParams;
|
||||
connection: DatabaseConnection;
|
||||
shouldDisplayProject: boolean;
|
||||
connectionOrigin?: ConnectionInfoOrigin;
|
||||
icon?: string;
|
||||
}
|
||||
|
||||
export const Connection = observer<Props>(function Connection({ connectionKey, connectionOrigin, connection, shouldDisplayProject, icon }) {
|
||||
const style = useS(styles);
|
||||
const connectionsAdministrationService = useService(ConnectionsAdministrationService);
|
||||
const projectInfoResource = useResource(Connection, ProjectInfoResource, connectionKey.projectId, { active: shouldDisplayProject });
|
||||
|
||||
const projectName = shouldDisplayProject ? (projectInfoResource.data?.name ?? '') : undefined;
|
||||
|
||||
return (
|
||||
<TableItem item={connectionKey} expandElement={ConnectionEdit}>
|
||||
<TableColumnValue centerContent flex>
|
||||
<TableItemSelect className={s(style, { tableItemSelect: true })} />
|
||||
</TableColumnValue>
|
||||
<TableColumnValue className={s(style, { tableColumnValueExpand: true })} centerContent flex expand>
|
||||
<TableItemExpand />
|
||||
</TableColumnValue>
|
||||
<TableColumnValue className={s(style, { tableColumnValueExpand: true })} centerContent flex expand>
|
||||
<StaticImage className={s(style, { staticImage: true })} icon={icon} />
|
||||
</TableColumnValue>
|
||||
<TableColumnValue title={connection.name} className={s(style, { tableColumnValueExpand: true })} expand ellipsis>
|
||||
{connection.name}
|
||||
</TableColumnValue>
|
||||
<TableColumnValue>
|
||||
{connection.host}
|
||||
{connection.host && connection.port && `:${connection.port}`}
|
||||
</TableColumnValue>
|
||||
{projectName !== undefined && (
|
||||
<TableColumnValue title={projectName} className={s(style, { tableColumnValueExpand: true })} expand ellipsis>
|
||||
{projectName}
|
||||
</TableColumnValue>
|
||||
)}
|
||||
<TableColumnValue flex>
|
||||
<Loader suspense small inline hideMessage>
|
||||
<Placeholder
|
||||
container={connectionsAdministrationService.connectionDetailsPlaceholder}
|
||||
connectionOrigin={connectionOrigin}
|
||||
connection={connection}
|
||||
/>
|
||||
</Loader>
|
||||
</TableColumnValue>
|
||||
</TableItem>
|
||||
);
|
||||
});
|
||||
-16
@@ -1,16 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
.staticImage {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
margin-right: 10px;
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { observer } from 'mobx-react-lite';
|
||||
|
||||
import { AUTH_PROVIDER_LOCAL_ID } from '@cloudbeaver/core-authentication';
|
||||
import { type PlaceholderComponent, s, StaticImage, useS } from '@cloudbeaver/core-blocks';
|
||||
|
||||
import type { IConnectionDetailsPlaceholderProps } from '../../ConnectionsAdministrationService.js';
|
||||
import ConnectionDetailsStyles from './ConnectionDetailsStyles.module.css';
|
||||
|
||||
export const Origin: PlaceholderComponent<IConnectionDetailsPlaceholderProps> = observer(function Origin({ connectionOrigin }) {
|
||||
const isLocal = connectionOrigin?.origin?.type === AUTH_PROVIDER_LOCAL_ID;
|
||||
const style = useS(ConnectionDetailsStyles);
|
||||
|
||||
if (!connectionOrigin?.origin || isLocal) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const icon = connectionOrigin.origin.icon;
|
||||
const title = connectionOrigin.origin.displayName;
|
||||
|
||||
return <StaticImage className={s(style, { staticImage: true })} icon={icon} title={title} />;
|
||||
});
|
||||
-34
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { observer } from 'mobx-react-lite';
|
||||
|
||||
import { type PlaceholderComponent, s, StaticImage, useResource, useS, useTranslate } from '@cloudbeaver/core-blocks';
|
||||
import { NetworkHandlerResource, SSH_TUNNEL_ID } from '@cloudbeaver/core-connections';
|
||||
|
||||
import type { IConnectionDetailsPlaceholderProps } from '../../ConnectionsAdministrationService.js';
|
||||
import ConnectionDetailsStyles from './ConnectionDetailsStyles.module.css';
|
||||
|
||||
export const SSH: PlaceholderComponent<IConnectionDetailsPlaceholderProps> = observer(function SSH({ connection }) {
|
||||
const translate = useTranslate();
|
||||
const style = useS(ConnectionDetailsStyles);
|
||||
const sshConfig = connection.networkHandlersConfig?.find(state => state.id === SSH_TUNNEL_ID);
|
||||
const applicable = sshConfig?.enabled === true;
|
||||
const handler = useResource(SSH, NetworkHandlerResource, SSH_TUNNEL_ID, { active: applicable });
|
||||
|
||||
if (!applicable) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<StaticImage
|
||||
className={s(style, { staticImage: true })}
|
||||
icon="/icons/ssh_tunnel.svg"
|
||||
title={translate(handler.data?.label || 'connections_network_handler_ssh_tunnel_title')}
|
||||
/>
|
||||
);
|
||||
});
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { observer } from 'mobx-react-lite';
|
||||
|
||||
import { type PlaceholderComponent, s, StaticImage, useS } from '@cloudbeaver/core-blocks';
|
||||
|
||||
import type { IConnectionDetailsPlaceholderProps } from '../../ConnectionsAdministrationService.js';
|
||||
import ConnectionDetailsStyles from './ConnectionDetailsStyles.module.css';
|
||||
|
||||
export const Template: PlaceholderComponent<IConnectionDetailsPlaceholderProps> = observer(function Template({ connection }) {
|
||||
const style = useS(ConnectionDetailsStyles);
|
||||
if (!connection.template) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <StaticImage className={s(style, { staticImage: true })} icon="/icons/template_connection.svg" title="Template connection" />;
|
||||
});
|
||||
-20
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
.box {
|
||||
composes: theme-background-secondary theme-text-on-secondary from global;
|
||||
box-sizing: border-box;
|
||||
padding-bottom: 24px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 740px;
|
||||
}
|
||||
|
||||
.loader {
|
||||
height: 100%;
|
||||
}
|
||||
-42
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2025 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { observer } from 'mobx-react-lite';
|
||||
|
||||
import { Loader, s, useS } from '@cloudbeaver/core-blocks';
|
||||
import { type IConnectionInfoParams } from '@cloudbeaver/core-connections';
|
||||
import { ConnectionFormLoader, useConnectionFormState } from '@cloudbeaver/plugin-connections';
|
||||
|
||||
import styles from './ConnectionEdit.module.css';
|
||||
import { FormMode } from '@cloudbeaver/core-ui';
|
||||
import { runInAction } from 'mobx';
|
||||
|
||||
interface Props {
|
||||
item: IConnectionInfoParams;
|
||||
}
|
||||
|
||||
export const ConnectionEdit = observer<Props>(function ConnectionEditNew({ item }) {
|
||||
const data = useConnectionFormState(item, state => {
|
||||
state.setMode(FormMode.Edit);
|
||||
|
||||
runInAction(() => {
|
||||
state.state.connectionId = item.connectionId;
|
||||
state.state.projectId = item.projectId;
|
||||
state.state.type = 'admin';
|
||||
});
|
||||
});
|
||||
const style = useS(styles);
|
||||
|
||||
return (
|
||||
<div className={s(style, { box: true })}>
|
||||
<Loader className={s(style, { loader: true })} suspense>
|
||||
<ConnectionFormLoader formState={data} />
|
||||
</Loader>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
-63
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2025 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { observer } from 'mobx-react-lite';
|
||||
|
||||
import { Table, TableBody, TableColumnHeader, TableHeader, TableSelect, useResource, useTranslate } from '@cloudbeaver/core-blocks';
|
||||
import { type ConnectionInfoOrigin, ConnectionInfoOriginResource, DBDriverResource, serializeConnectionParam } from '@cloudbeaver/core-connections';
|
||||
import { useService } from '@cloudbeaver/core-di';
|
||||
import { isGlobalProject, isSharedProject, ProjectsService } from '@cloudbeaver/core-projects';
|
||||
import { CachedMapAllKey } from '@cloudbeaver/core-resource';
|
||||
import { isNotNullDefined } from '@dbeaver/js-helpers';
|
||||
|
||||
import { Connection } from './Connection.js';
|
||||
import { type IConnectionsTableState } from './useConnectionsTable.js';
|
||||
|
||||
interface Props {
|
||||
state: IConnectionsTableState;
|
||||
}
|
||||
|
||||
function getOriginsMap(origins: (ConnectionInfoOrigin | undefined)[]) {
|
||||
return new Map(origins.filter(isNotNullDefined).map(origin => [origin.id, origin]));
|
||||
}
|
||||
|
||||
export const ConnectionsTable = observer<Props>(function ConnectionsTable({ state }) {
|
||||
const translate = useTranslate();
|
||||
const projectService = useService(ProjectsService);
|
||||
const dbDriverResource = useResource(ConnectionsTable, DBDriverResource, CachedMapAllKey);
|
||||
const shouldDisplayProjects = projectService.activeProjects.filter(project => isGlobalProject(project) || isSharedProject(project)).length > 1;
|
||||
const connectionOriginResource = useResource(ConnectionsTable, ConnectionInfoOriginResource, CachedMapAllKey);
|
||||
const connectionOriginsMap = getOriginsMap(connectionOriginResource.data);
|
||||
|
||||
return (
|
||||
<Table keys={state.keys} selectedItems={state.table.selected} expandedItems={state.table.expanded} size="big">
|
||||
<TableHeader fixed>
|
||||
<TableColumnHeader min flex centerContent>
|
||||
<TableSelect />
|
||||
</TableColumnHeader>
|
||||
<TableColumnHeader min />
|
||||
<TableColumnHeader min />
|
||||
<TableColumnHeader>{translate('connections_connection_name')}</TableColumnHeader>
|
||||
<TableColumnHeader>{translate('connections_connection_address')}</TableColumnHeader>
|
||||
{shouldDisplayProjects && <TableColumnHeader>{translate('connections_connection_project')}</TableColumnHeader>}
|
||||
<TableColumnHeader />
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{state.connections.map((connection, i) => (
|
||||
<Connection
|
||||
key={serializeConnectionParam(state.keys[i]!)}
|
||||
connectionKey={state.keys[i]!}
|
||||
connection={connection}
|
||||
connectionOrigin={connectionOriginsMap.get(connection.id)}
|
||||
shouldDisplayProject={shouldDisplayProjects}
|
||||
icon={dbDriverResource.resource.get(connection.driverId)?.icon}
|
||||
/>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
);
|
||||
});
|
||||
-174
@@ -1,174 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2025 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { action, computed, observable } from 'mobx';
|
||||
|
||||
import { ConfirmationDialogDelete, TableState, useObservableRef, useResource, useTable } from '@cloudbeaver/core-blocks';
|
||||
import {
|
||||
compareConnectionsInfo,
|
||||
compareNewConnectionsInfo,
|
||||
type Connection,
|
||||
ConnectionInfoActiveProjectKey,
|
||||
ConnectionInfoResource,
|
||||
createConnectionParam,
|
||||
type IConnectionInfoParams,
|
||||
} from '@cloudbeaver/core-connections';
|
||||
import { useService } from '@cloudbeaver/core-di';
|
||||
import { CommonDialogService, DialogueStateResult } from '@cloudbeaver/core-dialogs';
|
||||
import { NotificationService } from '@cloudbeaver/core-events';
|
||||
import { LocalizationService } from '@cloudbeaver/core-localization';
|
||||
import { isGlobalProject, isSharedProject, ProjectInfoResource, projectInfoSortByName, ProjectsService } from '@cloudbeaver/core-projects';
|
||||
import { CachedMapAllKey, resourceKeyList } from '@cloudbeaver/core-resource';
|
||||
import { isArraysEqual, isObjectsEqual } from '@cloudbeaver/core-utils';
|
||||
import { isDefined } from '@dbeaver/js-helpers';
|
||||
|
||||
export interface IConnectionsTableState {
|
||||
readonly connections: Connection[];
|
||||
readonly keys: IConnectionInfoParams[];
|
||||
table: TableState<IConnectionInfoParams>;
|
||||
loading: boolean;
|
||||
update: () => Promise<void>;
|
||||
delete: () => Promise<void>;
|
||||
}
|
||||
|
||||
export function useConnectionsTable() {
|
||||
const connectionInfoResource = useResource(
|
||||
useConnectionsTable,
|
||||
ConnectionInfoResource,
|
||||
{
|
||||
key: ConnectionInfoActiveProjectKey,
|
||||
includes: ['customIncludeOptions'],
|
||||
},
|
||||
{ forceSuspense: true },
|
||||
);
|
||||
const projectInfoResource = useResource(useConnectionsTable, ProjectInfoResource, CachedMapAllKey, { forceSuspense: true });
|
||||
|
||||
const notificationService = useService(NotificationService);
|
||||
const localizationService = useService(LocalizationService);
|
||||
const commonDialogService = useService(CommonDialogService);
|
||||
const projectService = useService(ProjectsService);
|
||||
|
||||
const table = useTable<IConnectionInfoParams>();
|
||||
|
||||
const state: IConnectionsTableState = useObservableRef(
|
||||
() => ({
|
||||
get connections() {
|
||||
return this.connectionInfoResource.resource
|
||||
.get(ConnectionInfoActiveProjectKey)
|
||||
.filter((connection): connection is Connection => {
|
||||
if (!isDefined(connection)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const project = this.projectInfoResource.resource.get(connection.projectId);
|
||||
|
||||
return connection.template && !!project && (isSharedProject(project) || isGlobalProject(project));
|
||||
})
|
||||
.sort((a, b) => {
|
||||
const compareNew = compareNewConnectionsInfo(a, b);
|
||||
const projectA = this.projectInfoResource.resource.get(a.projectId);
|
||||
const projectB = this.projectInfoResource.resource.get(b.projectId);
|
||||
|
||||
if (compareNew !== 0) {
|
||||
return compareNew;
|
||||
}
|
||||
|
||||
if (projectA && projectB) {
|
||||
const projectSort = projectInfoSortByName(projectA, projectB);
|
||||
|
||||
if (projectSort !== 0) {
|
||||
return projectSort;
|
||||
}
|
||||
}
|
||||
|
||||
return compareConnectionsInfo(a, b);
|
||||
});
|
||||
},
|
||||
get keys() {
|
||||
return this.connections.map(createConnectionParam);
|
||||
},
|
||||
loading: false,
|
||||
async update() {
|
||||
if (this.loading) {
|
||||
return;
|
||||
}
|
||||
this.loading = true;
|
||||
try {
|
||||
await this.connectionInfoResource.resource.refresh(ConnectionInfoActiveProjectKey);
|
||||
this.connectionInfoResource.resource.cleanNewFlags();
|
||||
this.notificationService.logSuccess({ title: 'connections_administration_tools_refresh_success' });
|
||||
} catch (exception: any) {
|
||||
this.notificationService.logException(exception, 'connections_administration_tools_refresh_fail');
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
async delete() {
|
||||
if (this.loading) {
|
||||
return;
|
||||
}
|
||||
|
||||
const deletionList = Array.from(this.table.selected)
|
||||
.filter(([_, value]) => value)
|
||||
.map(([connectionId]) => connectionId);
|
||||
|
||||
if (deletionList.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const connectionNames = deletionList.map(id => this.connectionInfoResource.resource.get(id)?.name).filter(Boolean);
|
||||
const nameList = connectionNames.map(name => `"${name}"`).join(', ');
|
||||
const message = `${this.localizationService.translate(
|
||||
'connections_administration_delete_confirmation',
|
||||
)}${nameList}. ${this.localizationService.translate('ui_are_you_sure')}`;
|
||||
|
||||
const result = await this.commonDialogService.open(ConfirmationDialogDelete, {
|
||||
title: 'ui_data_delete_confirmation',
|
||||
message,
|
||||
confirmActionText: 'ui_delete',
|
||||
});
|
||||
|
||||
if (result === DialogueStateResult.Rejected) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.loading = true;
|
||||
|
||||
try {
|
||||
await this.connectionInfoResource.resource.deleteConnection(resourceKeyList(deletionList));
|
||||
this.table.unselect();
|
||||
|
||||
for (const id of deletionList) {
|
||||
this.table.expand(id, false);
|
||||
}
|
||||
} catch (exception: any) {
|
||||
this.notificationService.logException(exception, 'connections_administration_connection_create_error');
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
}),
|
||||
{
|
||||
connections: computed<Connection[]>({ equals: (a, b) => isArraysEqual(a, b) }),
|
||||
keys: computed<IConnectionInfoParams[]>({ equals: (a, b) => isArraysEqual(a, b, isObjectsEqual) }),
|
||||
loading: observable.ref,
|
||||
update: action.bound,
|
||||
delete: action.bound,
|
||||
},
|
||||
{
|
||||
table,
|
||||
connectionInfoResource,
|
||||
projectInfoResource,
|
||||
notificationService,
|
||||
localizationService,
|
||||
commonDialogService,
|
||||
projectService,
|
||||
},
|
||||
);
|
||||
|
||||
return state;
|
||||
}
|
||||
-112
@@ -1,112 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2025 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { observer } from 'mobx-react-lite';
|
||||
|
||||
import {
|
||||
ActionIconButton,
|
||||
Container,
|
||||
Group,
|
||||
GroupClose,
|
||||
GroupTitle,
|
||||
Loader,
|
||||
s,
|
||||
SContext,
|
||||
StaticImage,
|
||||
type StyleRegistry,
|
||||
useResource,
|
||||
useS,
|
||||
useTranslate,
|
||||
} from '@cloudbeaver/core-blocks';
|
||||
import { DBDriverResource } from '@cloudbeaver/core-connections';
|
||||
import { useService } from '@cloudbeaver/core-di';
|
||||
import { TabListStyles, TabPanelList, TabPanelStyles, TabsState, TabStyles } from '@cloudbeaver/core-ui';
|
||||
import { ConnectionFormLoader, getConnectionFormOptionsPart } from '@cloudbeaver/plugin-connections';
|
||||
|
||||
import { CreateConnectionService } from '../CreateConnectionService.js';
|
||||
import styles from './shared/CreateConnection.module.css';
|
||||
import CreateConnectionTab from './shared/CreateConnectionTab.module.css';
|
||||
import CreateConnectionTabList from './shared/CreateConnectionTabList.module.css';
|
||||
import CreateConnectionTabPanel from './shared/CreateConnectionTabPanel.module.css';
|
||||
|
||||
interface Props {
|
||||
method: string | null | undefined;
|
||||
configurationWizard: boolean;
|
||||
}
|
||||
|
||||
const tabsRegistry: StyleRegistry = [
|
||||
[TabStyles, { mode: 'append', styles: [CreateConnectionTab] }],
|
||||
[TabPanelStyles, { mode: 'append', styles: [CreateConnectionTabPanel] }],
|
||||
[TabListStyles, { mode: 'append', styles: [CreateConnectionTabList] }],
|
||||
];
|
||||
|
||||
export const CreateConnection = observer<Props>(function CreateConnection({ method }) {
|
||||
const style = useS(styles);
|
||||
const createConnectionService = useService(CreateConnectionService);
|
||||
const translate = useTranslate();
|
||||
const optionsPart = createConnectionService.data ? getConnectionFormOptionsPart(createConnectionService.data) : null;
|
||||
const driver = useResource(CreateConnection, DBDriverResource, optionsPart?.state.driverId || null);
|
||||
|
||||
if (createConnectionService.data) {
|
||||
return (
|
||||
<Group className={s(style, { connectionCreate: true })} vertical box boxNoOverflow noWrap>
|
||||
<GroupTitle header keepSize>
|
||||
<Container gap dense noWrap>
|
||||
<Container keepSize>
|
||||
<ActionIconButton
|
||||
name="angle"
|
||||
viewBox="0 0 15 8"
|
||||
className={s(style, { backButton: true })}
|
||||
onClick={createConnectionService.clearConnectionTemplate}
|
||||
/>
|
||||
</Container>
|
||||
<Container keepSize center>
|
||||
{driver.data?.icon && <StaticImage className={s(style, { staticImage: true })} icon={driver.data.icon} />}
|
||||
</Container>
|
||||
<Container keepSize center>
|
||||
{translate('connections_administration_connection_create')}
|
||||
</Container>
|
||||
</Container>
|
||||
<GroupClose onClick={createConnectionService.cancelCreate} />
|
||||
</GroupTitle>
|
||||
<Container overflow>
|
||||
<Loader className={s(style, { loader: true })} suspense>
|
||||
<ConnectionFormLoader
|
||||
formState={createConnectionService.data}
|
||||
onCancel={createConnectionService.clearConnectionTemplate}
|
||||
onSave={createConnectionService.clearConnectionTemplate}
|
||||
/>
|
||||
</Loader>
|
||||
</Container>
|
||||
</Group>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Group className={s(style, { connectionCreate: true })} vertical box boxNoOverflow noWrap>
|
||||
<TabsState
|
||||
currentTabId={method}
|
||||
container={createConnectionService.tabsContainer}
|
||||
manual
|
||||
lazy
|
||||
onChange={({ tabId }) => createConnectionService.setCreateMethod(tabId)}
|
||||
>
|
||||
<GroupTitle keepSize>
|
||||
{translate('connections_administration_connection_create')}
|
||||
<GroupClose onClick={createConnectionService.cancelCreate} />
|
||||
</GroupTitle>
|
||||
<Container overflow>
|
||||
<SContext registry={tabsRegistry}>
|
||||
<TabPanelList />
|
||||
</SContext>
|
||||
{createConnectionService.disabled && <Loader overlay />}
|
||||
</Container>
|
||||
</TabsState>
|
||||
</Group>
|
||||
);
|
||||
});
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import React from 'react';
|
||||
|
||||
import { Bootstrap, injectable } from '@cloudbeaver/core-di';
|
||||
|
||||
import { CreateConnectionService } from '../CreateConnectionService.js';
|
||||
|
||||
const CustomConnection = React.lazy(async () => {
|
||||
const { CustomConnection } = await import('./Manual/CustomConnection.js');
|
||||
return { default: CustomConnection };
|
||||
});
|
||||
|
||||
@injectable()
|
||||
export class CreateConnectionBaseBootstrap extends Bootstrap {
|
||||
constructor(private readonly createConnectionService: CreateConnectionService) {
|
||||
super();
|
||||
}
|
||||
|
||||
override register(): void | Promise<void> {
|
||||
this.createConnectionService.tabsContainer.add({
|
||||
key: 'manual',
|
||||
name: 'connections_connection_create_custom',
|
||||
order: 1,
|
||||
panel: () => CustomConnection,
|
||||
});
|
||||
}
|
||||
}
|
||||
-37
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2025 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { injectable } from '@cloudbeaver/core-di';
|
||||
|
||||
import { CreateConnectionService } from '../../CreateConnectionService.js';
|
||||
|
||||
@injectable()
|
||||
export class ConnectionManualService {
|
||||
get disabled(): boolean {
|
||||
return this.createConnectionService.disabled;
|
||||
}
|
||||
|
||||
set disabled(value: boolean) {
|
||||
this.createConnectionService.disabled = value;
|
||||
}
|
||||
|
||||
constructor(private readonly createConnectionService: CreateConnectionService) {
|
||||
this.select = this.select.bind(this);
|
||||
}
|
||||
|
||||
select(projectId: string, driverId: string): void {
|
||||
this.createConnectionService.setConnectionTemplate(
|
||||
projectId,
|
||||
{
|
||||
template: true,
|
||||
driverId,
|
||||
},
|
||||
[driverId],
|
||||
);
|
||||
}
|
||||
}
|
||||
-52
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { computed } from 'mobx';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import { Loader, useResource } from '@cloudbeaver/core-blocks';
|
||||
import { DBDriverResource } from '@cloudbeaver/core-connections';
|
||||
import { useService } from '@cloudbeaver/core-di';
|
||||
import { NotificationService } from '@cloudbeaver/core-events';
|
||||
import { isSharedProject, ProjectInfoResource, ProjectsService } from '@cloudbeaver/core-projects';
|
||||
import { CachedMapAllKey } from '@cloudbeaver/core-resource';
|
||||
|
||||
import { ConnectionManualService } from './ConnectionManualService.js';
|
||||
import { DriverList } from './DriverList.js';
|
||||
|
||||
export const CustomConnection = observer(function CustomConnection() {
|
||||
const projectsService = useService(ProjectsService);
|
||||
const notificationService = useService(NotificationService);
|
||||
const connectionManualService = useService(ConnectionManualService);
|
||||
const dbDriverResource = useResource(CustomConnection, DBDriverResource, CachedMapAllKey);
|
||||
|
||||
const drivers = useMemo(
|
||||
() => computed(() => dbDriverResource.resource.enabledDrivers.slice().sort(dbDriverResource.resource.compare)),
|
||||
[dbDriverResource],
|
||||
);
|
||||
|
||||
useResource(CustomConnection, ProjectInfoResource, CachedMapAllKey);
|
||||
|
||||
function select(driverId: string) {
|
||||
const shared = projectsService.activeProjects.filter(isSharedProject);
|
||||
|
||||
if (shared.length > 0) {
|
||||
connectionManualService.select(shared[0]!.id, driverId);
|
||||
} else {
|
||||
notificationService.logError({
|
||||
title: 'core_projects_no_default_project',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Loader state={[dbDriverResource]}>
|
||||
<DriverList drivers={drivers.get()} onSelect={select} />
|
||||
</Loader>
|
||||
);
|
||||
});
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
.staticImage {
|
||||
box-sizing: border-box;
|
||||
width: 24px;
|
||||
max-height: 24px;
|
||||
}
|
||||
-34
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { ListItem, ListItemDescription, ListItemIcon, ListItemName, s, StaticImage, useS } from '@cloudbeaver/core-blocks';
|
||||
import type { DBDriver } from '@cloudbeaver/core-connections';
|
||||
|
||||
import style from './Driver.module.css';
|
||||
|
||||
interface Props {
|
||||
driver: DBDriver;
|
||||
onSelect: (driverId: string) => void;
|
||||
}
|
||||
|
||||
export const Driver = observer<Props>(function Driver({ driver, onSelect }) {
|
||||
const select = useCallback(() => onSelect(driver.id), [driver]);
|
||||
const styles = useS(style);
|
||||
|
||||
return (
|
||||
<ListItem onClick={select}>
|
||||
<ListItemIcon>
|
||||
<StaticImage icon={driver.icon} className={s(styles, { staticImage: true })} />
|
||||
</ListItemIcon>
|
||||
<ListItemName>{driver.name}</ListItemName>
|
||||
<ListItemDescription title={driver.description}>{driver.description}</ListItemDescription>
|
||||
</ListItem>
|
||||
);
|
||||
});
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: auto;
|
||||
}
|
||||
-45
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { useMemo, useState } from 'react';
|
||||
|
||||
import { ItemList, ItemListSearch, s, useFocus, useS, useTranslate } from '@cloudbeaver/core-blocks';
|
||||
import type { DBDriver } from '@cloudbeaver/core-connections';
|
||||
|
||||
import { Driver } from './Driver.js';
|
||||
import styles from './DriverList.module.css';
|
||||
|
||||
interface Props {
|
||||
drivers: DBDriver[];
|
||||
className?: string;
|
||||
onSelect: (driverId: string) => void;
|
||||
}
|
||||
|
||||
export const DriverList = observer<Props>(function DriverList({ drivers, className, onSelect }) {
|
||||
const [focusedRef] = useFocus<HTMLDivElement>({ focusFirstChild: true });
|
||||
const translate = useTranslate();
|
||||
const [search, setSearch] = useState('');
|
||||
const style = useS(styles);
|
||||
const filteredDrivers = useMemo(() => {
|
||||
if (!search) {
|
||||
return drivers;
|
||||
}
|
||||
return drivers.filter(driver => driver.name?.toUpperCase().includes(search.toUpperCase()));
|
||||
}, [search, drivers]);
|
||||
|
||||
return (
|
||||
<div ref={focusedRef} className={s(style, { container: true })}>
|
||||
<ItemListSearch value={search} placeholder={translate('connections_driver_search_placeholder')} onChange={setSearch} />
|
||||
<ItemList className={className}>
|
||||
{filteredDrivers.map(driver => (
|
||||
<Driver key={driver.id} driver={driver} onSelect={onSelect} />
|
||||
))}
|
||||
</ItemList>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
.connectionCreate {
|
||||
height: 800px;
|
||||
}
|
||||
|
||||
.loader {
|
||||
z-index: 1;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.staticImage {
|
||||
width: 24px;
|
||||
max-height: 24px;
|
||||
}
|
||||
|
||||
.backButton {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
.tab {
|
||||
composes: theme-background-secondary theme-text-on-secondary from global;
|
||||
}
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
.tabList {
|
||||
composes: theme-border-color-background theme-background-secondary theme-text-on-secondary from global;
|
||||
border-top: solid 1px;
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
align-items: center;
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
border-bottom: solid 2px;
|
||||
border-color: inherit;
|
||||
}
|
||||
}
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
.tabPanel {
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
-147
@@ -1,147 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2025 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { action, makeObservable, observable } from 'mobx';
|
||||
|
||||
import { AdministrationScreenService } from '@cloudbeaver/core-administration';
|
||||
import { injectable, IServiceProvider } from '@cloudbeaver/core-di';
|
||||
import type { ConnectionConfig } from '@cloudbeaver/core-sdk';
|
||||
import { TabsContainer } from '@cloudbeaver/core-ui';
|
||||
import { ConnectionFormService, ConnectionFormState, getConnectionFormOptionsPart } from '@cloudbeaver/plugin-connections';
|
||||
|
||||
import { ConnectionsAdministrationNavService } from './ConnectionsAdministrationNavService.js';
|
||||
|
||||
export interface ICreateMethodOptions {
|
||||
configurationWizard?: {
|
||||
activationPriority?: number;
|
||||
};
|
||||
close?: () => void;
|
||||
}
|
||||
|
||||
@injectable()
|
||||
export class CreateConnectionService {
|
||||
disabled = false;
|
||||
data: ConnectionFormState | null;
|
||||
|
||||
readonly tabsContainer: TabsContainer<void, ICreateMethodOptions>;
|
||||
|
||||
constructor(
|
||||
private readonly connectionsAdministrationNavService: ConnectionsAdministrationNavService,
|
||||
private readonly administrationScreenService: AdministrationScreenService,
|
||||
private readonly serviceProvider: IServiceProvider,
|
||||
private readonly connectionFormService: ConnectionFormService,
|
||||
) {
|
||||
this.data = null;
|
||||
this.tabsContainer = new TabsContainer('Connection Creation mode');
|
||||
|
||||
this.setConnectionTemplate = this.setConnectionTemplate.bind(this);
|
||||
this.clearConnectionTemplate = this.clearConnectionTemplate.bind(this);
|
||||
this.setCreateMethod = this.setCreateMethod.bind(this);
|
||||
this.cancelCreate = this.cancelCreate.bind(this);
|
||||
this.create = this.create.bind(this);
|
||||
|
||||
makeObservable<this, 'activateMethod'>(this, {
|
||||
data: observable,
|
||||
disabled: observable,
|
||||
setCreateMethod: action,
|
||||
cancelCreate: action,
|
||||
create: action,
|
||||
setConnectionTemplate: action,
|
||||
clearConnectionTemplate: action,
|
||||
close: action,
|
||||
activateMethod: action,
|
||||
});
|
||||
}
|
||||
|
||||
getDefault(): string | null {
|
||||
const tabs = this.tabsContainer.getDisplayed();
|
||||
|
||||
if (tabs.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (this.administrationScreenService.isConfigurationMode) {
|
||||
const sorted = tabs.sort((a, b) => {
|
||||
const aPriority = a.options?.configurationWizard?.activationPriority || Number.MAX_SAFE_INTEGER;
|
||||
const bPriority = b.options?.configurationWizard?.activationPriority || Number.MAX_SAFE_INTEGER;
|
||||
|
||||
return aPriority - bPriority;
|
||||
});
|
||||
|
||||
return sorted[0]!.key;
|
||||
}
|
||||
|
||||
return tabs[0]!.key;
|
||||
}
|
||||
|
||||
setCreateMethod(method?: string | null): void {
|
||||
if (!method) {
|
||||
const id = this.getDefault();
|
||||
|
||||
if (!id) {
|
||||
return;
|
||||
}
|
||||
method = id;
|
||||
}
|
||||
this.activateMethod(method);
|
||||
}
|
||||
|
||||
cancelCreate(): void {
|
||||
this.clearConnectionTemplate();
|
||||
this.connectionsAdministrationNavService.navToRoot();
|
||||
}
|
||||
|
||||
create(): void {
|
||||
const defaultId = this.getDefault();
|
||||
if (!defaultId) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.activateMethod(defaultId);
|
||||
}
|
||||
|
||||
private get optionsPart() {
|
||||
return this.data ? getConnectionFormOptionsPart(this.data) : null;
|
||||
}
|
||||
|
||||
async setConnectionTemplate(projectId: string, config: ConnectionConfig, availableDrivers: string[]): Promise<void> {
|
||||
this.clearConnectionTemplate();
|
||||
this.data = new ConnectionFormState(this.serviceProvider, this.connectionFormService, {
|
||||
projectId,
|
||||
availableDrivers,
|
||||
type: 'admin',
|
||||
requiredNetworkHandlersIds: [],
|
||||
connectionId: config.connectionId,
|
||||
});
|
||||
|
||||
await this.optionsPart?.load();
|
||||
await this.optionsPart?.setDriverId(config.driverId);
|
||||
|
||||
Object.assign(this.optionsPart!.state, config);
|
||||
|
||||
this.data.disposeTask.addHandler(this.cancelCreate.bind(this));
|
||||
}
|
||||
|
||||
clearConnectionTemplate(): void {
|
||||
this.data?.dispose();
|
||||
this.data = null;
|
||||
}
|
||||
|
||||
close(): void {
|
||||
this.clearConnectionTemplate();
|
||||
const tabs = this.tabsContainer.getDisplayed();
|
||||
|
||||
for (const method of tabs) {
|
||||
method.options?.close?.();
|
||||
}
|
||||
}
|
||||
|
||||
private activateMethod(method: string) {
|
||||
this.tabsContainer.select(method);
|
||||
this.connectionsAdministrationNavService.navToCreate(method);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
* Copyright (C) 2020-2025 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
+14
-13
@@ -30,12 +30,13 @@ import type { TLocalizationToken } from '@cloudbeaver/core-localization';
|
||||
import { CachedMapAllKey, CachedResourceOffsetPageListKey } from '@cloudbeaver/core-resource';
|
||||
import { FormMode, type TabContainerPanelComponent, useTab } from '@cloudbeaver/core-ui';
|
||||
import { getConnectionFormOptionsPart, type IConnectionFormProps } from '@cloudbeaver/plugin-connections';
|
||||
import styles from './ConnectionAccess.module.css';
|
||||
import { ConnectionAccessGrantedList } from './ConnectionAccessGrantedList.js';
|
||||
import { ConnectionAccessList } from './ConnectionAccessList.js';
|
||||
import { getConnectionFormAccessPart } from './getConnectionFormAccessPart.js';
|
||||
|
||||
export const ConnectionAccess: TabContainerPanelComponent<IConnectionFormProps> = observer(function ConnectionAccess({ tabId, formState }) {
|
||||
import styles from './ConnectionFormAccess.module.css';
|
||||
import { getConnectionFormAccessPart } from './getConnectionFormAccessPart.js';
|
||||
import { ConnectionFormAccessTableGrantedList } from './ConnectionFormAccessTable/ConnectionFormAccessTableGrantedList.js';
|
||||
import { ConnectionFormAccessTableList } from './ConnectionFormAccessTable/ConnectionFormAccessTableList.js';
|
||||
|
||||
export const ConnectionFormAccess: TabContainerPanelComponent<IConnectionFormProps> = observer(function ConnectionFormAccess({ tabId, formState }) {
|
||||
const translate = useTranslate();
|
||||
const style = useS(styles);
|
||||
const state = useObservableRef(
|
||||
@@ -56,12 +57,12 @@ export const ConnectionAccess: TabContainerPanelComponent<IConnectionFormProps>
|
||||
const accessPart = getConnectionFormAccessPart(formState);
|
||||
const [initialFormMode] = useState<FormMode>(formState.mode);
|
||||
|
||||
useAutoLoad(ConnectionAccess, accessPart, selected);
|
||||
useAutoLoad(ConnectionFormAccess, accessPart, selected);
|
||||
|
||||
const users = useResource(ConnectionAccess, UsersResource, CachedResourceOffsetPageListKey(0, 1000).setParent(UsersResourceFilterKey()), {
|
||||
const users = useResource(ConnectionFormAccess, UsersResource, CachedResourceOffsetPageListKey(0, 1000).setParent(UsersResourceFilterKey()), {
|
||||
active: selected,
|
||||
});
|
||||
const teams = useResource(ConnectionAccess, TeamsResource, CachedMapAllKey, { active: selected });
|
||||
const teams = useResource(ConnectionFormAccess, TeamsResource, CachedMapAllKey, { active: selected });
|
||||
|
||||
const grantedUsers = useMemo(
|
||||
() => computed(() => users.resource.values.filter(user => accessPart.state.includes(user.userId))),
|
||||
@@ -75,7 +76,7 @@ export const ConnectionAccess: TabContainerPanelComponent<IConnectionFormProps>
|
||||
|
||||
const optionsPart = getConnectionFormOptionsPart(formState);
|
||||
const connectionInfoResource = useResource(
|
||||
ConnectionAccess,
|
||||
ConnectionFormAccess,
|
||||
ConnectionInfoResource,
|
||||
createConnectionParam(formState.state.projectId, optionsPart.state.connectionId!),
|
||||
{
|
||||
@@ -83,7 +84,7 @@ export const ConnectionAccess: TabContainerPanelComponent<IConnectionFormProps>
|
||||
},
|
||||
);
|
||||
const originInfoResource = useResource(
|
||||
ConnectionAccess,
|
||||
ConnectionFormAccess,
|
||||
ConnectionInfoOriginResource,
|
||||
createConnectionParam(formState.state.projectId, optionsPart.state.connectionId!),
|
||||
{
|
||||
@@ -113,13 +114,13 @@ export const ConnectionAccess: TabContainerPanelComponent<IConnectionFormProps>
|
||||
<ColoredContainer className={s(style, { coloredContainer: true })} parent gap vertical>
|
||||
{!users.resource.values.length && !teams.resource.values.length ? (
|
||||
<Group className={s(style, { group: true })} keepSize large>
|
||||
<TextPlaceholder>{translate('connections_administration_connection_access_empty')}</TextPlaceholder>
|
||||
<TextPlaceholder>{translate('core_connections_connection_access_empty')}</TextPlaceholder>
|
||||
</Group>
|
||||
) : (
|
||||
<>
|
||||
{info && <InfoItem info={info} />}
|
||||
<Container gap overflow>
|
||||
<ConnectionAccessGrantedList
|
||||
<ConnectionFormAccessTableGrantedList
|
||||
grantedUsers={grantedUsers.get()}
|
||||
grantedTeams={grantedTeams.get()}
|
||||
disabled={disabled}
|
||||
@@ -127,7 +128,7 @@ export const ConnectionAccess: TabContainerPanelComponent<IConnectionFormProps>
|
||||
onRevoke={accessPart.revoke}
|
||||
/>
|
||||
{state.editing && (
|
||||
<ConnectionAccessList
|
||||
<ConnectionFormAccessTableList
|
||||
userList={users.resource.values}
|
||||
teamList={teams.resource.values}
|
||||
grantedSubjects={accessPart.state}
|
||||
+1
-1
@@ -77,4 +77,4 @@ export class ConnectionFormAccessPart extends FormPart<string[], IConnectionForm
|
||||
grant(subjectIds: string[]) {
|
||||
this.state.push(...subjectIds);
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
-6
@@ -15,13 +15,13 @@ import { ConnectionFormService, getConnectionFormOptionsPart } from '@cloudbeave
|
||||
import { getConnectionFormAccessPart } from './getConnectionFormAccessPart.js';
|
||||
import { getCachedDataResourceLoaderState, getCachedMapResourceLoaderState } from '@cloudbeaver/core-resource';
|
||||
|
||||
const ConnectionAccess = React.lazy(async () => {
|
||||
const { ConnectionAccess } = await import('./ConnectionAccess.js');
|
||||
return { default: ConnectionAccess };
|
||||
const ConnectionFormAccess = React.lazy(async () => {
|
||||
const { ConnectionFormAccess } = await import('./ConnectionFormAccess.js');
|
||||
return { default: ConnectionFormAccess };
|
||||
});
|
||||
|
||||
@injectable()
|
||||
export class ConnectionAccessTabService extends Bootstrap {
|
||||
export class ConnectionFormAccessTabService extends Bootstrap {
|
||||
private readonly key: string;
|
||||
|
||||
constructor(
|
||||
@@ -52,11 +52,11 @@ export class ConnectionAccessTabService extends Bootstrap {
|
||||
|
||||
return !optionsPart?.state.driverId || this.administrationScreenService.isConfigurationMode;
|
||||
},
|
||||
panel: () => ConnectionAccess,
|
||||
panel: () => ConnectionFormAccess,
|
||||
});
|
||||
}
|
||||
|
||||
private isAccessTabActive(projectId: string | null): boolean {
|
||||
return projectId !== null && isGlobalProject(this.projectInfoResource.get(projectId)) && this.permissionsResource.has(EAdminPermission.admin);
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-5
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
* Copyright (C) 2020-2025 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,10 +26,10 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.tableContainer {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.connectionAccessTableHeader {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.tableContainer {
|
||||
overflow: auto;
|
||||
}
|
||||
+12
-12
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
* Copyright (C) 2020-2025 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -27,11 +27,11 @@ import {
|
||||
import type { TLocalizationToken } from '@cloudbeaver/core-localization';
|
||||
import type { AdminUserInfoFragment } from '@cloudbeaver/core-sdk';
|
||||
|
||||
import styles from './ConnectionAccessGrantedList.module.css';
|
||||
import { ConnectionAccessTableHeader, type IFilterState } from './ConnectionAccessTableHeader/ConnectionAccessTableHeader.js';
|
||||
import { ConnectionAccessTableInnerHeader } from './ConnectionAccessTableHeader/ConnectionAccessTableInnerHeader.js';
|
||||
import { ConnectionAccessTableItem } from './ConnectionAccessTableItem.js';
|
||||
import { getFilteredTeams, getFilteredUsers } from './getFilteredSubjects.js';
|
||||
import styles from './ConnectionFormAccessTableGrantedList.module.css';
|
||||
import { getFilteredUsers, getFilteredTeams } from '../getFilteredSubjects.js';
|
||||
import { ConnectionFormAccessTableHeader, type IFilterState } from './ConnectionFormAccessTableHeader/ConnectionFormAccessTableHeader.js';
|
||||
import { ConnectionFormAccessTableInnerHeader } from './ConnectionFormAccessTableHeader/ConnectionFormAccessTableInnerHeader.js';
|
||||
import { ConnectionFormAccessTableItem } from './ConnectionFormAccessTableItem.js';
|
||||
|
||||
interface Props {
|
||||
grantedUsers: AdminUserInfoFragment[];
|
||||
@@ -41,7 +41,7 @@ interface Props {
|
||||
onEdit: () => void;
|
||||
}
|
||||
|
||||
export const ConnectionAccessGrantedList = observer<Props>(function ConnectionAccessGrantedList({
|
||||
export const ConnectionFormAccessTableGrantedList = observer<Props>(function ConnectionFormAccessTableGrantedList({
|
||||
grantedUsers,
|
||||
grantedTeams,
|
||||
disabled,
|
||||
@@ -77,23 +77,23 @@ export const ConnectionAccessGrantedList = observer<Props>(function ConnectionAc
|
||||
return (
|
||||
<Group className={s(style, { group: true })} box medium overflow>
|
||||
<div className={s(style, { container: true })}>
|
||||
<ConnectionAccessTableHeader className={s(style, { connectionAccessTableHeader: true })} filterState={filterState} disabled={disabled}>
|
||||
<ConnectionFormAccessTableHeader className={s(style, { connectionAccessTableHeader: true })} filterState={filterState} disabled={disabled}>
|
||||
<Button disabled={disabled || !selected} mod={['outlined']} onClick={revoke}>
|
||||
{translate('ui_delete')}
|
||||
</Button>
|
||||
<Button disabled={disabled} mod={['unelevated']} onClick={props.onEdit}>
|
||||
{translate('ui_edit')}
|
||||
</Button>
|
||||
</ConnectionAccessTableHeader>
|
||||
</ConnectionFormAccessTableHeader>
|
||||
<div className={s(style, { tableContainer: true })}>
|
||||
<Table className={s(style, { table: true })} keys={keys} selectedItems={selectedSubjects}>
|
||||
<ConnectionAccessTableInnerHeader disabled={disabled} />
|
||||
<ConnectionFormAccessTableInnerHeader disabled={disabled} />
|
||||
<TableBody>
|
||||
<TableItem item="tableInfo" selectDisabled>
|
||||
<TableColumnValue colSpan={5}>{translate(tableInfoText)}</TableColumnValue>
|
||||
</TableItem>
|
||||
{teams.map(team => (
|
||||
<ConnectionAccessTableItem
|
||||
<ConnectionFormAccessTableItem
|
||||
key={team.teamId}
|
||||
id={team.teamId}
|
||||
name={team.teamName || team.teamId}
|
||||
@@ -105,7 +105,7 @@ export const ConnectionAccessGrantedList = observer<Props>(function ConnectionAc
|
||||
/>
|
||||
))}
|
||||
{users.map(user => (
|
||||
<ConnectionAccessTableItem
|
||||
<ConnectionFormAccessTableItem
|
||||
key={user.userId}
|
||||
id={user.userId}
|
||||
name={user.userId}
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
* Copyright (C) 2020-2025 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
* Copyright (C) 2020-2025 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -9,7 +9,7 @@ import { observer } from 'mobx-react-lite';
|
||||
|
||||
import { Filter, s, useS, useTranslate } from '@cloudbeaver/core-blocks';
|
||||
|
||||
import styles from './ConnectionAccessTableHeader.module.css';
|
||||
import styles from './ConnectionFormAccessTableHeader.module.css';
|
||||
|
||||
export interface IFilterState {
|
||||
filterValue: string;
|
||||
@@ -21,7 +21,7 @@ interface Props {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export const ConnectionAccessTableHeader = observer<React.PropsWithChildren<Props>>(function ConnectionAccessTableHeader({
|
||||
export const ConnectionFormAccessTableHeader = observer<React.PropsWithChildren<Props>>(function ConnectionFormAccessTableHeader({
|
||||
filterState,
|
||||
disabled,
|
||||
className,
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
* Copyright (C) 2020-2025 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -14,7 +14,7 @@ interface Props {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export const ConnectionAccessTableInnerHeader = observer<Props>(function ConnectionAccessTableInnerHeader({ disabled, className }) {
|
||||
export const ConnectionFormAccessTableInnerHeader = observer<Props>(function ConnectionFormAccessTableInnerHeader({ disabled, className }) {
|
||||
const translate = useTranslate();
|
||||
return (
|
||||
<TableHeader className={className} fixed>
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
* Copyright (C) 2020-2025 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
* Copyright (C) 2020-2025 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -9,7 +9,7 @@ import { observer } from 'mobx-react-lite';
|
||||
|
||||
import { s, StaticImage, TableColumnValue, TableItem, TableItemSelect, useS } from '@cloudbeaver/core-blocks';
|
||||
|
||||
import styles from './ConnectionAccessTableItem.module.css';
|
||||
import styles from './ConnectionFormAccessTableItem.module.css';
|
||||
|
||||
interface Props {
|
||||
id: any;
|
||||
@@ -22,7 +22,7 @@ interface Props {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export const ConnectionAccessTableItem = observer<Props>(function ConnectionAccessTableItem({
|
||||
export const ConnectionFormAccessTableItem = observer<Props>(function ConnectionFormAccessTableItem({
|
||||
id,
|
||||
name,
|
||||
description,
|
||||
+5
-5
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
* Copyright (C) 2020-2025 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,10 +26,10 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.connectionAccessTableHeader {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.tableContainer {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.connectionAccessTableHeader {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
+18
-12
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
* Copyright (C) 2020-2025 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,11 +26,11 @@ import {
|
||||
} from '@cloudbeaver/core-blocks';
|
||||
import type { AdminUserInfoFragment } from '@cloudbeaver/core-sdk';
|
||||
|
||||
import styles from './ConnectionAccessList.module.css';
|
||||
import { ConnectionAccessTableHeader, type IFilterState } from './ConnectionAccessTableHeader/ConnectionAccessTableHeader.js';
|
||||
import { ConnectionAccessTableInnerHeader } from './ConnectionAccessTableHeader/ConnectionAccessTableInnerHeader.js';
|
||||
import { ConnectionAccessTableItem } from './ConnectionAccessTableItem.js';
|
||||
import { getFilteredTeams, getFilteredUsers } from './getFilteredSubjects.js';
|
||||
import styles from './ConnectionFormAccessTableList.module.css';
|
||||
import { getFilteredTeams, getFilteredUsers } from '../getFilteredSubjects.js';
|
||||
import { ConnectionFormAccessTableHeader, type IFilterState } from './ConnectionFormAccessTableHeader/ConnectionFormAccessTableHeader.js';
|
||||
import { ConnectionFormAccessTableInnerHeader } from './ConnectionFormAccessTableHeader/ConnectionFormAccessTableInnerHeader.js';
|
||||
import { ConnectionFormAccessTableItem } from './ConnectionFormAccessTableItem.js';
|
||||
|
||||
interface Props {
|
||||
userList: AdminUserInfoFragment[];
|
||||
@@ -40,7 +40,13 @@ interface Props {
|
||||
disabled: boolean;
|
||||
}
|
||||
|
||||
export const ConnectionAccessList = observer<Props>(function ConnectionAccessList({ userList, teamList, grantedSubjects, onGrant, disabled }) {
|
||||
export const ConnectionFormAccessTableList = observer<Props>(function ConnectionFormAccessTableList({
|
||||
userList,
|
||||
teamList,
|
||||
grantedSubjects,
|
||||
onGrant,
|
||||
disabled,
|
||||
}) {
|
||||
const props = useObjectRef({ onGrant });
|
||||
const translate = useTranslate();
|
||||
const style = useS(styles);
|
||||
@@ -61,11 +67,11 @@ export const ConnectionAccessList = observer<Props>(function ConnectionAccessLis
|
||||
return (
|
||||
<Group className={s(style, { group: true })} box medium overflow>
|
||||
<div className={s(style, { container: true })}>
|
||||
<ConnectionAccessTableHeader className={s(style, { connectionAccessTableHeader: true })} filterState={filterState} disabled={disabled}>
|
||||
<ConnectionFormAccessTableHeader className={s(style, { connectionAccessTableHeader: true })} filterState={filterState} disabled={disabled}>
|
||||
<Button disabled={disabled || !selected} mod={['unelevated']} onClick={grant}>
|
||||
{translate('ui_add')}
|
||||
</Button>
|
||||
</ConnectionAccessTableHeader>
|
||||
</ConnectionFormAccessTableHeader>
|
||||
<div className={s(style, { tableContainer: true })}>
|
||||
<Table
|
||||
className={s(style, { table: true })}
|
||||
@@ -73,7 +79,7 @@ export const ConnectionAccessList = observer<Props>(function ConnectionAccessLis
|
||||
selectedItems={selectedSubjects}
|
||||
isItemSelectable={item => !grantedSubjects.includes(item)}
|
||||
>
|
||||
<ConnectionAccessTableInnerHeader disabled={disabled} />
|
||||
<ConnectionFormAccessTableInnerHeader disabled={disabled} />
|
||||
<TableBody>
|
||||
{!keys.length && filterState.filterValue && (
|
||||
<TableItem item="tableInfo" selectDisabled>
|
||||
@@ -81,7 +87,7 @@ export const ConnectionAccessList = observer<Props>(function ConnectionAccessLis
|
||||
</TableItem>
|
||||
)}
|
||||
{teams.map(team => (
|
||||
<ConnectionAccessTableItem
|
||||
<ConnectionFormAccessTableItem
|
||||
key={team.teamId}
|
||||
id={team.teamId}
|
||||
name={team.teamName || team.teamId}
|
||||
@@ -93,7 +99,7 @@ export const ConnectionAccessList = observer<Props>(function ConnectionAccessLis
|
||||
/>
|
||||
))}
|
||||
{users.map(user => (
|
||||
<ConnectionAccessTableItem
|
||||
<ConnectionFormAccessTableItem
|
||||
key={user.userId}
|
||||
id={user.userId}
|
||||
name={user.userId}
|
||||
+3
-3
@@ -1,15 +1,15 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
* Copyright (C) 2020-2025 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
export interface IConnectionAccessTabState {
|
||||
export interface IConnectionFormAccessTabState {
|
||||
loading: boolean;
|
||||
loaded: boolean;
|
||||
grantedSubjects: string[];
|
||||
initialGrantedSubjects: string[];
|
||||
editing: boolean;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -21,4 +21,4 @@ export function getConnectionFormAccessPart(formState: IFormState<IConnectionFor
|
||||
|
||||
return new ConnectionFormAccessPart(formState, connectionInfoResource, optionsPart);
|
||||
});
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
* Copyright (C) 2020-2025 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { Bootstrap, injectable } from '@cloudbeaver/core-di';
|
||||
import { LocalizationService } from '@cloudbeaver/core-localization';
|
||||
|
||||
@injectable()
|
||||
export class LocaleService extends Bootstrap {
|
||||
constructor(private readonly localizationService: LocalizationService) {
|
||||
super();
|
||||
}
|
||||
|
||||
override register(): void {
|
||||
this.localizationService.addProvider(this.provider.bind(this));
|
||||
}
|
||||
|
||||
private async provider(locale: string) {
|
||||
switch (locale) {
|
||||
case 'ru':
|
||||
return (await import('./locales/ru.js')).default;
|
||||
case 'it':
|
||||
return (await import('./locales/it.js')).default;
|
||||
case 'zh':
|
||||
return (await import('./locales/zh.js')).default;
|
||||
case 'fr':
|
||||
return (await import('./locales/fr.js')).default;
|
||||
default:
|
||||
return (await import('./locales/en.js')).default;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,12 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
* Copyright (C) 2020-2025 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { connectionPlugin } from './manifest.js';
|
||||
|
||||
export * from './Administration/Connections/ConnectionsAdministration.js';
|
||||
export * from './Administration/Connections/CreateConnection/Manual/ConnectionManualService.js';
|
||||
export * from './Administration/Connections/ConnectionsAdministrationNavService.js';
|
||||
export * from './Administration/Connections/ConnectionsAdministrationService.js';
|
||||
export * from './Administration/Connections/CreateConnection/CreateConnectionBaseBootstrap.js';
|
||||
export * from './Administration/Connections/CreateConnectionService.js';
|
||||
export * from './ConnectionForm/ConnectionAccess/ConnectionAccessTabService.js';
|
||||
export * from './ConnectionFormAccess/ConnectionFormAccessTabService.js';
|
||||
|
||||
export default connectionPlugin;
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
export default [
|
||||
['plugin_connections_connection_edit_menu_item_title', 'Edit Connection'],
|
||||
['plugin_connections_connection_edit_cancel_title', 'Cancel confirmation'],
|
||||
['plugin_connections_connection_edit_reconnect_title', 'Connection updated'],
|
||||
['plugin_connections_connection_edit_reconnect_message', 'Connection has been updated. Do you want to reconnect?'],
|
||||
['plugin_connections_connection_edit_reconnect_failed', 'Failed to reconnect'],
|
||||
|
||||
['connections_administration_deactivate_message', "Your connection's settings will be lost. Do you want to continue?"],
|
||||
['connections_administration_connection_create_error', 'Failed to create connection'],
|
||||
];
|
||||
@@ -1,10 +0,0 @@
|
||||
export default [
|
||||
['plugin_connections_connection_edit_menu_item_title', 'Modifier la connexion'],
|
||||
['plugin_connections_connection_edit_cancel_title', "Confirmation d'annulation"],
|
||||
['plugin_connections_connection_edit_reconnect_title', 'Connexion mise à jour'],
|
||||
['plugin_connections_connection_edit_reconnect_message', 'La connexion a été mise à jour. Voulez-vous vous reconnecter ?'],
|
||||
['plugin_connections_connection_edit_reconnect_failed', 'Échec de la reconnexion'],
|
||||
|
||||
['connections_administration_deactivate_message', 'Les paramètres de votre connexion seront perdus. Voulez-vous continuer ?'],
|
||||
['connections_administration_connection_create_error', 'Failed to create connection'],
|
||||
];
|
||||
@@ -1,5 +0,0 @@
|
||||
export default [
|
||||
['plugin_connections_connection_edit_menu_item_title', 'Modifica Connessione'],
|
||||
['plugin_connections_connection_edit_cancel_title', "Conferma l'annullamento"],
|
||||
['connections_administration_connection_create_error', 'Failed to create connection'],
|
||||
];
|
||||
@@ -1,10 +0,0 @@
|
||||
export default [
|
||||
['plugin_connections_connection_edit_menu_item_title', 'Изменить подключение'],
|
||||
['plugin_connections_connection_edit_cancel_title', 'Отмена редактирования'],
|
||||
['plugin_connections_connection_edit_reconnect_title', 'Подключение обновлено'],
|
||||
['plugin_connections_connection_edit_reconnect_message', 'Подключение было обновлено. Вы хотите переподключиться?'],
|
||||
['plugin_connections_connection_edit_reconnect_failed', 'Не удалось переподключиться'],
|
||||
|
||||
['connections_administration_deactivate_message', 'Настройки вашего подключения будут потеряны. Вы хотите продолжить?'],
|
||||
['connections_administration_connection_create_error', 'Не удалось создать подключение'],
|
||||
];
|
||||
@@ -1,10 +0,0 @@
|
||||
export default [
|
||||
['plugin_connections_connection_edit_menu_item_title', '编辑连接'],
|
||||
['plugin_connections_connection_edit_cancel_title', '取消确认'],
|
||||
['plugin_connections_connection_edit_reconnect_title', '连接已更新'],
|
||||
['plugin_connections_connection_edit_reconnect_message', '连接已更新。您想重新连接吗?'],
|
||||
['plugin_connections_connection_edit_reconnect_failed', '重新连接失败'],
|
||||
|
||||
['connections_administration_deactivate_message', '您的连接设置将丢失。您要继续吗?'],
|
||||
['connections_administration_connection_create_error', 'Failed to create connection'],
|
||||
];
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
* Copyright (C) 2020-2025 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -12,13 +12,5 @@ export const connectionPlugin: PluginManifest = {
|
||||
name: 'Connections Administration plugin',
|
||||
},
|
||||
|
||||
providers: [
|
||||
() => import('./LocaleService.js').then(m => m.LocaleService),
|
||||
() => import('./Administration/Connections/ConnectionsAdministrationService.js').then(m => m.ConnectionsAdministrationService),
|
||||
() => import('./Administration/Connections/ConnectionsAdministrationNavService.js').then(m => m.ConnectionsAdministrationNavService),
|
||||
() => import('./Administration/Connections/CreateConnectionService.js').then(m => m.CreateConnectionService),
|
||||
() => import('./Administration/Connections/CreateConnection/Manual/ConnectionManualService.js').then(m => m.ConnectionManualService),
|
||||
() => import('./Administration/Connections/CreateConnection/CreateConnectionBaseBootstrap.js').then(m => m.CreateConnectionBaseBootstrap),
|
||||
() => import('./ConnectionForm/ConnectionAccess/ConnectionAccessTabService.js').then(m => m.ConnectionAccessTabService),
|
||||
],
|
||||
providers: [() => import('./ConnectionFormAccess/ConnectionFormAccessTabService.js').then(m => m.ConnectionFormAccessTabService)],
|
||||
};
|
||||
|
||||
@@ -31,12 +31,6 @@
|
||||
{
|
||||
"path": "../core-di"
|
||||
},
|
||||
{
|
||||
"path": "../core-dialogs"
|
||||
},
|
||||
{
|
||||
"path": "../core-events"
|
||||
},
|
||||
{
|
||||
"path": "../core-executor"
|
||||
},
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user