diff --git a/application/src/main/java/org/thingsboard/server/controller/AdminController.java b/application/src/main/java/org/thingsboard/server/controller/AdminController.java index 67665ad8c7..ed740f73fb 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AdminController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AdminController.java @@ -191,12 +191,12 @@ public class AdminController extends BaseController { } } - @ApiOperation(value = "Get version control settings (getVersionControlSettings)", - notes = "Get the version control settings object. " + TENANT_AUTHORITY_PARAGRAPH) + @ApiOperation(value = "Get repository settings (getRepositorySettings)", + notes = "Get the repository settings object. " + TENANT_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAuthority('TENANT_ADMIN')") - @GetMapping("/vcSettings") + @GetMapping("/repositorySettings") @ResponseBody - public RepositorySettings getVersionControlSettings() throws ThingsboardException { + public RepositorySettings getRepositorySettings() throws ThingsboardException { try { accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.READ); RepositorySettings versionControlSettings = checkNotNull(versionControlService.getVersionControlSettings(getTenantId())); @@ -209,12 +209,12 @@ public class AdminController extends BaseController { } } - @ApiOperation(value = "Check version control settings exists (versionControlSettingsExists)", - notes = "Check whether the version control settings exists. " + TENANT_AUTHORITY_PARAGRAPH) + @ApiOperation(value = "Check repository settings exists (repositorySettingsExists)", + notes = "Check whether the repository settings exists. " + TENANT_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAuthority('TENANT_ADMIN')") - @GetMapping("/vcSettings/exists") + @GetMapping("/repositorySettings/exists") @ResponseBody - public Boolean versionControlSettingsExists() throws ThingsboardException { + public Boolean repositorySettingsExists() throws ThingsboardException { try { accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.READ); return versionControlService.getVersionControlSettings(getTenantId()) != null; @@ -223,11 +223,11 @@ public class AdminController extends BaseController { } } - @ApiOperation(value = "Creates or Updates the version control settings (saveVersionControlSettings)", - notes = "Creates or Updates the version control settings object. " + TENANT_AUTHORITY_PARAGRAPH) + @ApiOperation(value = "Creates or Updates the repository settings (saveRepositorySettings)", + notes = "Creates or Updates the repository settings object. " + TENANT_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAuthority('TENANT_ADMIN')") - @PostMapping("/vcSettings") - public DeferredResult saveVersionControlSettings(@RequestBody RepositorySettings settings) throws ThingsboardException { + @PostMapping("/repositorySettings") + public DeferredResult saveRepositorySettings(@RequestBody RepositorySettings settings) throws ThingsboardException { accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.WRITE); ListenableFuture future = versionControlService.saveVersionControlSettings(getTenantId(), settings); return wrapFuture(Futures.transform(future, savedSettings -> { @@ -238,13 +238,13 @@ public class AdminController extends BaseController { }, MoreExecutors.directExecutor())); } - @ApiOperation(value = "Delete version control settings (deleteVersionControlSettings)", - notes = "Deletes the version control settings." + @ApiOperation(value = "Delete repository settings (deleteRepositorySettings)", + notes = "Deletes the repository settings." + TENANT_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAuthority('TENANT_ADMIN')") - @RequestMapping(value = "/vcSettings", method = RequestMethod.DELETE) + @RequestMapping(value = "/repositorySettings", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) - public DeferredResult deleteVersionControlSettings() throws ThingsboardException { + public DeferredResult deleteRepositorySettings() throws ThingsboardException { try { accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.DELETE); return wrapFuture(versionControlService.deleteVersionControlSettings(getTenantId())); @@ -253,6 +253,23 @@ public class AdminController extends BaseController { } } + + @ApiOperation(value = "Check repository access (checkRepositoryAccess)", + notes = "Attempts to check repository access. " + TENANT_AUTHORITY_PARAGRAPH) + @PreAuthorize("hasAuthority('TENANT_ADMIN')") + @RequestMapping(value = "/repositorySettings/checkAccess", method = RequestMethod.POST) + public DeferredResult checkRepositoryAccess( + @ApiParam(value = "A JSON value representing the Repository Settings.") + @RequestBody RepositorySettings settings) throws ThingsboardException { + try { + accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.READ); + settings = checkNotNull(settings); + return wrapFuture(versionControlService.checkVersionControlAccess(getTenantId(), settings)); + } catch (Exception e) { + throw handleException(e); + } + } + @ApiOperation(value = "Get auto commit settings (getAutoCommitSettings)", notes = "Get the auto commit settings object. " + TENANT_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @@ -267,8 +284,8 @@ public class AdminController extends BaseController { } } - @ApiOperation(value = "Check version control settings exists (versionControlSettingsExists)", - notes = "Check whether the version control settings exists. " + TENANT_AUTHORITY_PARAGRAPH) + @ApiOperation(value = "Check auto commit settings exists (autoCommitSettingsExists)", + notes = "Check whether the auto commit settings exists. " + TENANT_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @GetMapping("/vc/autoCommitSettings/exists") @ResponseBody @@ -281,8 +298,8 @@ public class AdminController extends BaseController { } } - @ApiOperation(value = "Creates or Updates the version control settings (saveVersionControlSettings)", - notes = "Creates or Updates the version control settings object. " + TENANT_AUTHORITY_PARAGRAPH) + @ApiOperation(value = "Creates or Updates the auto commit settings (saveAutoCommitSettings)", + notes = "Creates or Updates the auto commit settings object. " + TENANT_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @PostMapping("/vc/autoCommitSettings") public AutoCommitSettings saveAutoCommitSettings(@RequestBody AutoCommitSettings settings) throws ThingsboardException { @@ -290,8 +307,8 @@ public class AdminController extends BaseController { return autoCommitSettingsService.save(getTenantId(), settings); } - @ApiOperation(value = "Delete version control settings (deleteVersionControlSettings)", - notes = "Deletes the version control settings." + @ApiOperation(value = "Delete auto commit settings (deleteAutoCommitSettings)", + notes = "Deletes the auto commit settings." + TENANT_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/vc/autoCommitSettings", method = RequestMethod.DELETE) @@ -305,22 +322,6 @@ public class AdminController extends BaseController { } } - @ApiOperation(value = "Check version control access (checkVersionControlAccess)", - notes = "Attempts to check version control access. " + TENANT_AUTHORITY_PARAGRAPH) - @PreAuthorize("hasAuthority('TENANT_ADMIN')") - @RequestMapping(value = "/vcSettings/checkAccess", method = RequestMethod.POST) - public DeferredResult checkVersionControlAccess( - @ApiParam(value = "A JSON value representing the Entities Version Control Settings.") - @RequestBody RepositorySettings settings) throws ThingsboardException { - try { - accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.READ); - settings = checkNotNull(settings); - return wrapFuture(versionControlService.checkVersionControlAccess(getTenantId(), settings)); - } catch (Exception e) { - throw handleException(e); - } - } - @ApiOperation(value = "Check for new Platform Releases (checkUpdates)", notes = "Check notifications about new platform releases. " + SYSTEM_AUTHORITY_PARAGRAPH) diff --git a/application/src/main/java/org/thingsboard/server/service/sync/vc/repository/DefaultTbRepositorySettingsService.java b/application/src/main/java/org/thingsboard/server/service/sync/vc/repository/DefaultTbRepositorySettingsService.java index 608efec870..555490bd06 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/vc/repository/DefaultTbRepositorySettingsService.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/vc/repository/DefaultTbRepositorySettingsService.java @@ -19,7 +19,7 @@ import org.springframework.stereotype.Service; import org.thingsboard.server.cache.TbTransactionalCache; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.sync.vc.RepositorySettings; -import org.thingsboard.server.common.data.sync.vc.VersionControlAuthMethod; +import org.thingsboard.server.common.data.sync.vc.RepositoryAuthMethod; import org.thingsboard.server.dao.settings.AdminSettingsService; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.sync.vc.TbAbstractVersionControlSettingsService; @@ -38,10 +38,10 @@ public class DefaultTbRepositorySettingsService extends TbAbstractVersionControl public RepositorySettings restore(TenantId tenantId, RepositorySettings settings) { RepositorySettings storedSettings = get(tenantId); if (storedSettings != null) { - VersionControlAuthMethod authMethod = settings.getAuthMethod(); - if (VersionControlAuthMethod.USERNAME_PASSWORD.equals(authMethod) && settings.getPassword() == null) { + RepositoryAuthMethod authMethod = settings.getAuthMethod(); + if (RepositoryAuthMethod.USERNAME_PASSWORD.equals(authMethod) && settings.getPassword() == null) { settings.setPassword(storedSettings.getPassword()); - } else if (VersionControlAuthMethod.PRIVATE_KEY.equals(authMethod) && settings.getPrivateKey() == null) { + } else if (RepositoryAuthMethod.PRIVATE_KEY.equals(authMethod) && settings.getPrivateKey() == null) { settings.setPrivateKey(storedSettings.getPrivateKey()); if (settings.getPrivateKeyPassword() == null) { settings.setPrivateKeyPassword(storedSettings.getPrivateKeyPassword()); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/sync/vc/VersionControlAuthMethod.java b/common/data/src/main/java/org/thingsboard/server/common/data/sync/vc/RepositoryAuthMethod.java similarity index 94% rename from common/data/src/main/java/org/thingsboard/server/common/data/sync/vc/VersionControlAuthMethod.java rename to common/data/src/main/java/org/thingsboard/server/common/data/sync/vc/RepositoryAuthMethod.java index 770a1e582c..3c0e5849a3 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/sync/vc/VersionControlAuthMethod.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/sync/vc/RepositoryAuthMethod.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.common.data.sync.vc; -public enum VersionControlAuthMethod { +public enum RepositoryAuthMethod { USERNAME_PASSWORD, PRIVATE_KEY } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/sync/vc/RepositorySettings.java b/common/data/src/main/java/org/thingsboard/server/common/data/sync/vc/RepositorySettings.java index c576f82298..eb1a97ff6c 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/sync/vc/RepositorySettings.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/sync/vc/RepositorySettings.java @@ -17,12 +17,8 @@ package org.thingsboard.server.common.data.sync.vc; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.Data; -import org.thingsboard.server.common.data.EntityType; -import org.thingsboard.server.common.data.sync.vc.request.create.AutoVersionCreateConfig; import java.io.Serializable; -import java.util.HashMap; -import java.util.Map; @Data @JsonIgnoreProperties(ignoreUnknown = true) // temporary to make sure no need to wipe db during development. @@ -30,7 +26,7 @@ public class RepositorySettings implements Serializable { private static final long serialVersionUID = -3211552851889198721L; private String repositoryUri; - private VersionControlAuthMethod authMethod; + private RepositoryAuthMethod authMethod; private String username; private String password; private String privateKeyFileName; diff --git a/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/GitRepository.java b/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/GitRepository.java index dd9a67aed4..2b2802d003 100644 --- a/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/GitRepository.java +++ b/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/GitRepository.java @@ -59,7 +59,7 @@ import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.SortOrder; import org.thingsboard.server.common.data.sync.vc.RepositorySettings; -import org.thingsboard.server.common.data.sync.vc.VersionControlAuthMethod; +import org.thingsboard.server.common.data.sync.vc.RepositoryAuthMethod; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -95,9 +95,9 @@ public class GitRepository { public static GitRepository clone(RepositorySettings settings, File directory) throws GitAPIException { CredentialsProvider credentialsProvider = null; SshdSessionFactory sshSessionFactory = null; - if (VersionControlAuthMethod.USERNAME_PASSWORD.equals(settings.getAuthMethod())) { + if (RepositoryAuthMethod.USERNAME_PASSWORD.equals(settings.getAuthMethod())) { credentialsProvider = newCredentialsProvider(settings.getUsername(), settings.getPassword()); - } else if (VersionControlAuthMethod.PRIVATE_KEY.equals(settings.getAuthMethod())) { + } else if (RepositoryAuthMethod.PRIVATE_KEY.equals(settings.getAuthMethod())) { sshSessionFactory = newSshdSessionFactory(settings.getPrivateKey(), settings.getPrivateKeyPassword(), directory); } CloneCommand cloneCommand = Git.cloneRepository() @@ -113,9 +113,9 @@ public class GitRepository { Git git = Git.open(directory); CredentialsProvider credentialsProvider = null; SshdSessionFactory sshSessionFactory = null; - if (VersionControlAuthMethod.USERNAME_PASSWORD.equals(settings.getAuthMethod())) { + if (RepositoryAuthMethod.USERNAME_PASSWORD.equals(settings.getAuthMethod())) { credentialsProvider = newCredentialsProvider(settings.getUsername(), settings.getPassword()); - } else if (VersionControlAuthMethod.PRIVATE_KEY.equals(settings.getAuthMethod())) { + } else if (RepositoryAuthMethod.PRIVATE_KEY.equals(settings.getAuthMethod())) { sshSessionFactory = newSshdSessionFactory(settings.getPrivateKey(), settings.getPrivateKeyPassword(), directory); } return new GitRepository(git, settings, credentialsProvider, sshSessionFactory, directory.getAbsolutePath()); @@ -124,9 +124,9 @@ public class GitRepository { public static void test(RepositorySettings settings, File directory) throws GitAPIException { CredentialsProvider credentialsProvider = null; SshdSessionFactory sshSessionFactory = null; - if (VersionControlAuthMethod.USERNAME_PASSWORD.equals(settings.getAuthMethod())) { + if (RepositoryAuthMethod.USERNAME_PASSWORD.equals(settings.getAuthMethod())) { credentialsProvider = newCredentialsProvider(settings.getUsername(), settings.getPassword()); - } else if (VersionControlAuthMethod.PRIVATE_KEY.equals(settings.getAuthMethod())) { + } else if (RepositoryAuthMethod.PRIVATE_KEY.equals(settings.getAuthMethod())) { sshSessionFactory = newSshdSessionFactory(settings.getPrivateKey(), settings.getPrivateKeyPassword(), directory); } LsRemoteCommand lsRemoteCommand = Git.lsRemoteRepository().setRemote(settings.getRepositoryUri()); diff --git a/ui-ngx/src/app/core/auth/auth.actions.ts b/ui-ngx/src/app/core/auth/auth.actions.ts index 872607b822..a60720e61d 100644 --- a/ui-ngx/src/app/core/auth/auth.actions.ts +++ b/ui-ngx/src/app/core/auth/auth.actions.ts @@ -24,7 +24,7 @@ export enum AuthActionTypes { LOAD_USER = '[Auth] Load User', UPDATE_USER_DETAILS = '[Auth] Update User Details', UPDATE_LAST_PUBLIC_DASHBOARD_ID = '[Auth] Update Last Public Dashboard Id', - UPDATE_HAS_VERSION_CONTROL = '[Auth] Change Has Version Control' + UPDATE_HAS_REPOSITORY = '[Auth] Change Has Repository' } export class ActionAuthAuthenticated implements Action { @@ -55,11 +55,11 @@ export class ActionAuthUpdateLastPublicDashboardId implements Action { constructor(readonly payload: { lastPublicDashboardId: string }) {} } -export class ActionAuthUpdateHasVersionControl implements Action { - readonly type = AuthActionTypes.UPDATE_HAS_VERSION_CONTROL; +export class ActionAuthUpdateHasRepository implements Action { + readonly type = AuthActionTypes.UPDATE_HAS_REPOSITORY; - constructor(readonly payload: { hasVersionControl: boolean }) {} + constructor(readonly payload: { hasRepository: boolean }) {} } export type AuthActions = ActionAuthAuthenticated | ActionAuthUnauthenticated | - ActionAuthLoadUser | ActionAuthUpdateUserDetails | ActionAuthUpdateLastPublicDashboardId | ActionAuthUpdateHasVersionControl; + ActionAuthLoadUser | ActionAuthUpdateUserDetails | ActionAuthUpdateLastPublicDashboardId | ActionAuthUpdateHasRepository; diff --git a/ui-ngx/src/app/core/auth/auth.models.ts b/ui-ngx/src/app/core/auth/auth.models.ts index a69b783526..33b84945aa 100644 --- a/ui-ngx/src/app/core/auth/auth.models.ts +++ b/ui-ngx/src/app/core/auth/auth.models.ts @@ -20,7 +20,7 @@ export interface SysParamsState { userTokenAccessEnabled: boolean; allowedDashboardIds: string[]; edgesSupportEnabled: boolean; - hasVersionControl: boolean; + hasRepository: boolean; } export interface AuthPayload extends SysParamsState { diff --git a/ui-ngx/src/app/core/auth/auth.reducer.ts b/ui-ngx/src/app/core/auth/auth.reducer.ts index 9d9404524b..cace62660e 100644 --- a/ui-ngx/src/app/core/auth/auth.reducer.ts +++ b/ui-ngx/src/app/core/auth/auth.reducer.ts @@ -24,7 +24,7 @@ const emptyUserAuthState: AuthPayload = { forceFullscreen: false, allowedDashboardIds: [], edgesSupportEnabled: false, - hasVersionControl: false + hasRepository: false }; export const initialState: AuthState = { @@ -55,7 +55,7 @@ export function authReducer( case AuthActionTypes.UPDATE_LAST_PUBLIC_DASHBOARD_ID: return { ...state, ...action.payload}; - case AuthActionTypes.UPDATE_HAS_VERSION_CONTROL: + case AuthActionTypes.UPDATE_HAS_REPOSITORY: return { ...state, ...action.payload}; default: diff --git a/ui-ngx/src/app/core/auth/auth.selectors.ts b/ui-ngx/src/app/core/auth/auth.selectors.ts index 7a099d5acd..4a63dbcbed 100644 --- a/ui-ngx/src/app/core/auth/auth.selectors.ts +++ b/ui-ngx/src/app/core/auth/auth.selectors.ts @@ -55,9 +55,9 @@ export const selectUserTokenAccessEnabled = createSelector( (state: AuthState) => state.userTokenAccessEnabled ); -export const selectHasVersionControl = createSelector( +export const selectHasRepository = createSelector( selectAuthState, - (state: AuthState) => state.hasVersionControl + (state: AuthState) => state.hasRepository ); export function getCurrentAuthState(store: Store): AuthState { diff --git a/ui-ngx/src/app/core/auth/auth.service.ts b/ui-ngx/src/app/core/auth/auth.service.ts index 6fe809955f..74f6689553 100644 --- a/ui-ngx/src/app/core/auth/auth.service.ts +++ b/ui-ngx/src/app/core/auth/auth.service.ts @@ -437,9 +437,9 @@ export class AuthService { return this.http.get('/api/edges/enabled', defaultHttpOptions()); } - private loadHasVersionControl(authUser: AuthUser): Observable { + private loadHasRepository(authUser: AuthUser): Observable { if (authUser.authority === Authority.TENANT_ADMIN) { - return this.http.get('/api/admin/vcSettings/exists', defaultHttpOptions()); + return this.http.get('/api/admin/repositorySettings/exists', defaultHttpOptions()); } else { return of(false); } @@ -449,15 +449,15 @@ export class AuthService { const sources = [this.loadIsUserTokenAccessEnabled(authPayload.authUser), this.fetchAllowedDashboardIds(authPayload), this.loadIsEdgesSupportEnabled(), - this.loadHasVersionControl(authPayload.authUser), + this.loadHasRepository(authPayload.authUser), this.timeService.loadMaxDatapointsLimit()]; return forkJoin(sources) .pipe(map((data) => { const userTokenAccessEnabled: boolean = data[0] as boolean; const allowedDashboardIds: string[] = data[1] as string[]; const edgesSupportEnabled: boolean = data[2] as boolean; - const hasVersionControl: boolean = data[3] as boolean; - return {userTokenAccessEnabled, allowedDashboardIds, edgesSupportEnabled, hasVersionControl}; + const hasRepository: boolean = data[3] as boolean; + return {userTokenAccessEnabled, allowedDashboardIds, edgesSupportEnabled, hasRepository}; }, catchError((err) => { return of({}); }))); diff --git a/ui-ngx/src/app/core/http/admin.service.ts b/ui-ngx/src/app/core/http/admin.service.ts index 7c12bd3a5d..38f18bd598 100644 --- a/ui-ngx/src/app/core/http/admin.service.ts +++ b/ui-ngx/src/app/core/http/admin.service.ts @@ -15,19 +15,21 @@ /// import { Injectable } from '@angular/core'; -import { defaultHttpOptionsFromConfig, RequestConfig } from './http-utils'; -import { Observable } from 'rxjs'; +import { defaultHttpOptions, defaultHttpOptionsFromConfig, RequestConfig } from './http-utils'; +import { Observable, of } from 'rxjs'; import { HttpClient } from '@angular/common/http'; import { AdminSettings, - EntitiesVersionControlSettings, + RepositorySettings, MailServerSettings, SecuritySettings, TestSmsRequest, - UpdateMessage + UpdateMessage, AutoCommitSettings } from '@shared/models/settings.models'; import { EntitiesVersionControlService } from '@core/http/entities-version-control.service'; import { tap } from 'rxjs/operators'; +import { AuthUser } from '@shared/models/user.model'; +import { Authority } from '@shared/models/authority.enum'; @Injectable({ providedIn: 'root' @@ -68,13 +70,13 @@ export class AdminService { defaultHttpOptionsFromConfig(config)); } - public getEntitiesVersionControlSettings(config?: RequestConfig): Observable { - return this.http.get(`/api/admin/vcSettings`, defaultHttpOptionsFromConfig(config)); + public getRepositorySettings(config?: RequestConfig): Observable { + return this.http.get(`/api/admin/repositorySettings`, defaultHttpOptionsFromConfig(config)); } - public saveEntitiesVersionControlSettings(versionControlSettings: EntitiesVersionControlSettings, - config?: RequestConfig): Observable { - return this.http.post('/api/admin/vcSettings', versionControlSettings, + public saveRepositorySettings(repositorySettings: RepositorySettings, + config?: RequestConfig): Observable { + return this.http.post('/api/admin/repositorySettings', repositorySettings, defaultHttpOptionsFromConfig(config)).pipe( tap(() => { this.entitiesVersionControlService.clearBranchList(); @@ -82,17 +84,34 @@ export class AdminService { ); } - public deleteEntitiesVersionControlSettings(config?: RequestConfig) { - return this.http.delete('/api/admin/vcSettings', defaultHttpOptionsFromConfig(config)).pipe( + public deleteRepositorySettings(config?: RequestConfig) { + return this.http.delete('/api/admin/repositorySettings', defaultHttpOptionsFromConfig(config)).pipe( tap(() => { this.entitiesVersionControlService.clearBranchList(); }) ); } - public checkVersionControlAccess(versionControlSettings: EntitiesVersionControlSettings, - config?: RequestConfig): Observable { - return this.http.post('/api/admin/vcSettings/checkAccess', versionControlSettings, defaultHttpOptionsFromConfig(config)); + public checkRepositoryAccess(repositorySettings: RepositorySettings, + config?: RequestConfig): Observable { + return this.http.post('/api/admin/repositorySettings/checkAccess', repositorySettings, defaultHttpOptionsFromConfig(config)); + } + + public getAutoCommitSettings(config?: RequestConfig): Observable { + return this.http.get(`/api/admin/autoCommitSettings`, defaultHttpOptionsFromConfig(config)); + } + + private autoCommitSettingsExists(config?: RequestConfig): Observable { + return this.http.get('/api/admin/autoCommitSettings/exists', defaultHttpOptionsFromConfig(config)); + } + + public saveAutoCommitSettings(autoCommitSettings: AutoCommitSettings, + config?: RequestConfig): Observable { + return this.http.post('/api/admin/autoCommitSettings', autoCommitSettings, defaultHttpOptionsFromConfig(config)); + } + + public deleteAutoCommitSettings(config?: RequestConfig) { + return this.http.delete('/api/admin/autoCommitSettings', defaultHttpOptionsFromConfig(config)); } public checkUpdates(config?: RequestConfig): Observable { diff --git a/ui-ngx/src/app/core/http/entities-version-control.service.ts b/ui-ngx/src/app/core/http/entities-version-control.service.ts index 7578696774..9f6f4f3403 100644 --- a/ui-ngx/src/app/core/http/entities-version-control.service.ts +++ b/ui-ngx/src/app/core/http/entities-version-control.service.ts @@ -17,7 +17,7 @@ import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { defaultHttpOptionsFromConfig, RequestConfig } from '@core/http/http-utils'; -import { combineLatest, Observable, of } from 'rxjs'; +import { Observable, of } from 'rxjs'; import { BranchInfo, EntityDataDiff, EntityVersion, @@ -29,10 +29,10 @@ import { PageLink } from '@shared/models/page/page-link'; import { PageData } from '@shared/models/page/page-data'; import { EntityId } from '@shared/models/id/entity-id'; import { EntityType } from '@shared/models/entity-type.models'; -import { createSelector, select, Store } from '@ngrx/store'; +import { select, Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; -import { selectHasVersionControl, selectIsAuthenticated, selectIsUserLoaded } from '@core/auth/auth.selectors'; -import { catchError, combineAll, tap } from 'rxjs/operators'; +import { selectIsUserLoaded } from '@core/auth/auth.selectors'; +import { catchError, tap } from 'rxjs/operators'; @Injectable({ providedIn: 'root' diff --git a/ui-ngx/src/app/core/services/menu.service.ts b/ui-ngx/src/app/core/services/menu.service.ts index ee81f007ee..50938e5869 100644 --- a/ui-ngx/src/app/core/services/menu.service.ts +++ b/ui-ngx/src/app/core/services/menu.service.ts @@ -388,9 +388,9 @@ export class MenuService { }, { id: guid(), - name: 'admin.git-settings', + name: 'admin.repository-settings', type: 'link', - path: '/settings/vc', + path: '/settings/repository', icon: 'manage_history' } ] @@ -538,9 +538,9 @@ export class MenuService { path: '/settings/resources-library' }, { - name: 'admin.git-settings', + name: 'admin.repository-settings', icon: 'manage_history', - path: '/settings/vc', + path: '/settings/repository', } ] } diff --git a/ui-ngx/src/app/modules/home/components/home-components.module.ts b/ui-ngx/src/app/modules/home/components/home-components.module.ts index e9fc3f8c9a..613f236cf6 100644 --- a/ui-ngx/src/app/modules/home/components/home-components.module.ts +++ b/ui-ngx/src/app/modules/home/components/home-components.module.ts @@ -153,7 +153,7 @@ import { TenantProfileQueuesComponent } from '@home/components/profile/queue/ten import { QueueFormComponent } from '@home/components/queue/queue-form.component'; import { WidgetSettingsModule } from '@home/components/widget/lib/settings/widget-settings.module'; import { WidgetSettingsComponent } from '@home/components/widget/widget-settings.component'; -import { VersionControlSettingsComponent } from '@home/components/vc/version-control-settings.component'; +import { RepositorySettingsComponent } from '@home/components/vc/repository-settings.component'; import { VersionControlComponent } from '@home/components/vc/version-control.component'; import { EntityVersionsTableComponent } from '@home/components/vc/entity-versions-table.component'; import { EntityVersionCreateComponent } from '@home/components/vc/entity-version-create.component'; @@ -163,6 +163,7 @@ import { ComplexVersionCreateComponent } from '@home/components/vc/complex-versi import { EntityTypesVersionCreateComponent } from '@home/components/vc/entity-types-version-create.component'; import { EntityTypesVersionLoadComponent } from '@home/components/vc/entity-types-version-load.component'; import { ComplexVersionLoadComponent } from '@home/components/vc/complex-version-load.component'; +import { RemoveOtherEntitiesConfirmComponent } from '@home/components/vc/remove-other-entities-confirm.component'; @NgModule({ declarations: @@ -287,7 +288,7 @@ import { ComplexVersionLoadComponent } from '@home/components/vc/complex-version DisplayWidgetTypesPanelComponent, TenantProfileQueuesComponent, QueueFormComponent, - VersionControlSettingsComponent, + RepositorySettingsComponent, VersionControlComponent, EntityVersionsTableComponent, EntityVersionCreateComponent, @@ -296,7 +297,8 @@ import { ComplexVersionLoadComponent } from '@home/components/vc/complex-version ComplexVersionCreateComponent, EntityTypesVersionCreateComponent, EntityTypesVersionLoadComponent, - ComplexVersionLoadComponent + ComplexVersionLoadComponent, + RemoveOtherEntitiesConfirmComponent ], imports: [ CommonModule, @@ -415,7 +417,7 @@ import { ComplexVersionLoadComponent } from '@home/components/vc/complex-version DisplayWidgetTypesPanelComponent, TenantProfileQueuesComponent, QueueFormComponent, - VersionControlSettingsComponent, + RepositorySettingsComponent, VersionControlComponent, EntityVersionsTableComponent, EntityVersionCreateComponent, @@ -424,7 +426,8 @@ import { ComplexVersionLoadComponent } from '@home/components/vc/complex-version ComplexVersionCreateComponent, EntityTypesVersionCreateComponent, EntityTypesVersionLoadComponent, - ComplexVersionLoadComponent + ComplexVersionLoadComponent, + RemoveOtherEntitiesConfirmComponent ], providers: [ WidgetComponentService, diff --git a/ui-ngx/src/app/modules/home/components/vc/entity-types-version-create.component.html b/ui-ngx/src/app/modules/home/components/vc/entity-types-version-create.component.html index 9d1192c0c9..3c1dd73117 100644 --- a/ui-ngx/src/app/modules/home/components/vc/entity-types-version-create.component.html +++ b/ui-ngx/src/app/modules/home/components/vc/entity-types-version-create.component.html @@ -53,7 +53,7 @@ [allowedEntityTypes]="allowedEntityTypes(entityTypeFormGroup)">
- + version-control.sync-strategy @@ -64,9 +64,14 @@ - - {{ 'version-control.export-entity-relations' | translate }} - +
+ + {{ 'version-control.export-entity-relations' | translate }} + + + {{ 'version-control.export-entity-attributes' | translate }} + +
-
+
-
- - {{ 'version-control.remove-other-entities' | translate }} - - - {{ 'version-control.load-entities-relations' | translate }} - +
+
+ + {{ 'version-control.remove-other-entities' | translate }} + + + {{ 'version-control.find-existing-entity-by-name' | translate }} + +
+
+ + {{ 'version-control.load-entities-relations' | translate }} + + + {{ 'version-control.load-entities-attributes' | translate }} + +
diff --git a/ui-ngx/src/app/modules/home/components/vc/entity-types-version-load.component.ts b/ui-ngx/src/app/modules/home/components/vc/entity-types-version-load.component.ts index 39709bebe1..40bf9ad869 100644 --- a/ui-ngx/src/app/modules/home/components/vc/entity-types-version-load.component.ts +++ b/ui-ngx/src/app/modules/home/components/vc/entity-types-version-load.component.ts @@ -14,7 +14,7 @@ /// limitations under the License. /// -import { Component, forwardRef, Input, OnInit } from '@angular/core'; +import { Component, forwardRef, Input, OnInit, Renderer2, ViewContainerRef } from '@angular/core'; import { AbstractControl, ControlValueAccessor, @@ -28,11 +28,15 @@ import { Validators } from '@angular/forms'; import { PageComponent } from '@shared/components/page.component'; -import { EntityTypeVersionLoadConfig, exportableEntityTypes } from '@shared/models/vc.models'; +import { EntityTypeVersionLoadConfig, exportableEntityTypes, VersionCreationResult } from '@shared/models/vc.models'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; import { TranslateService } from '@ngx-translate/core'; import { EntityType, entityTypeTranslations } from '@shared/models/entity-type.models'; +import { MatCheckbox } from '@angular/material/checkbox/checkbox'; +import { TbPopoverService } from '@shared/components/popover.service'; +import { EntityVersionCreateComponent } from '@home/components/vc/entity-version-create.component'; +import { RemoveOtherEntitiesConfirmComponent } from '@home/components/vc/remove-other-entities-confirm.component'; @Component({ selector: 'tb-entity-types-version-load', @@ -64,6 +68,9 @@ export class EntityTypesVersionLoadComponent extends PageComponent implements On constructor(protected store: Store, private translate: TranslateService, + private popoverService: TbPopoverService, + private renderer: Renderer2, + private viewContainerRef: ViewContainerRef, private fb: FormBuilder) { super(store); } @@ -124,7 +131,9 @@ export class EntityTypesVersionLoadComponent extends PageComponent implements On entityType: [entityType, [Validators.required]], config: this.fb.group({ loadRelations: [config.loadRelations, []], - removeOtherEntities: [config.removeOtherEntities, []] + loadAttributes: [config.loadAttributes, []], + removeOtherEntities: [config.removeOtherEntities, []], + findExistingEntityByName: [config.findExistingEntityByName, []] }) } ); @@ -156,7 +165,9 @@ export class EntityTypesVersionLoadComponent extends PageComponent implements On const entityTypesArray = this.entityTypesVersionLoadFormGroup.get('entityTypes') as FormArray; const config: EntityTypeVersionLoadConfig = { loadRelations: false, - removeOtherEntities: false + loadAttributes: false, + removeOtherEntities: false, + findExistingEntityByName: false }; const allowed = this.allowedEntityTypes(); let entityType: EntityType = null; @@ -194,6 +205,29 @@ export class EntityTypesVersionLoadComponent extends PageComponent implements On return res; } + onRemoveOtherEntities(removeOtherEntitiesCheckbox: MatCheckbox, entityTypeControl: AbstractControl, $event: Event) { + const removeOtherEntities: boolean = entityTypeControl.get('config.removeOtherEntities').value; + if (!removeOtherEntities) { + $event.preventDefault(); + $event.stopPropagation(); + const trigger = $('.mat-checkbox-frame', removeOtherEntitiesCheckbox._elementRef.nativeElement)[0]; + if (this.popoverService.hasPopover(trigger)) { + this.popoverService.hidePopover(trigger); + } else { + const removeOtherEntitiesConfirmPopover = this.popoverService.displayPopover(trigger, this.renderer, + this.viewContainerRef, RemoveOtherEntitiesConfirmComponent, 'bottom', true, null, + { + onClose: (result: boolean | null) => { + removeOtherEntitiesConfirmPopover.hide(); + if (result) { + entityTypeControl.get('config').get('removeOtherEntities').patchValue(true, {emitEvent: true}); + } + } + }, {}, {}, {}, false); + } + } + } + private updateModel() { const value: [{entityType: string, config: EntityTypeVersionLoadConfig}] = this.entityTypesVersionLoadFormGroup.get('entityTypes').value || []; diff --git a/ui-ngx/src/app/modules/home/components/vc/entity-version-create.component.html b/ui-ngx/src/app/modules/home/components/vc/entity-version-create.component.html index 5c575b93d4..b5f2fb6937 100644 --- a/ui-ngx/src/app/modules/home/components/vc/entity-version-create.component.html +++ b/ui-ngx/src/app/modules/home/components/vc/entity-version-create.component.html @@ -41,6 +41,9 @@ {{ 'version-control.export-entity-relations' | translate }} + + {{ 'version-control.export-entity-attributes' | translate }} +
diff --git a/ui-ngx/src/app/modules/home/components/vc/entity-version-create.component.ts b/ui-ngx/src/app/modules/home/components/vc/entity-version-create.component.ts index 9f998bc2af..2ff8c03227 100644 --- a/ui-ngx/src/app/modules/home/components/vc/entity-version-create.component.ts +++ b/ui-ngx/src/app/modules/home/components/vc/entity-version-create.component.ts @@ -62,7 +62,8 @@ export class EntityVersionCreateComponent extends PageComponent implements OnIni this.createVersionFormGroup = this.fb.group({ branch: [this.branch, [Validators.required]], versionName: [null, [Validators.required]], - saveRelations: [false, []] + saveRelations: [false, []], + saveAttributes: [false, []] }); } @@ -78,7 +79,8 @@ export class EntityVersionCreateComponent extends PageComponent implements OnIni branch: this.createVersionFormGroup.get('branch').value, versionName: this.createVersionFormGroup.get('versionName').value, config: { - saveRelations: this.createVersionFormGroup.get('saveRelations').value + saveRelations: this.createVersionFormGroup.get('saveRelations').value, + saveAttributes: this.createVersionFormGroup.get('saveAttributes').value, }, type: VersionCreateRequestType.SINGLE_ENTITY }; diff --git a/ui-ngx/src/app/modules/home/components/vc/entity-version-restore.component.html b/ui-ngx/src/app/modules/home/components/vc/entity-version-restore.component.html index cb71696b4e..e84beb03dc 100644 --- a/ui-ngx/src/app/modules/home/components/vc/entity-version-restore.component.html +++ b/ui-ngx/src/app/modules/home/components/vc/entity-version-restore.component.html @@ -29,6 +29,9 @@ {{ 'version-control.load-entity-relations' | translate }} + + {{ 'version-control.load-entity-attributes' | translate }} +
diff --git a/ui-ngx/src/app/modules/home/components/vc/entity-version-restore.component.ts b/ui-ngx/src/app/modules/home/components/vc/entity-version-restore.component.ts index 2cc615c011..ea5443e036 100644 --- a/ui-ngx/src/app/modules/home/components/vc/entity-version-restore.component.ts +++ b/ui-ngx/src/app/modules/home/components/vc/entity-version-restore.component.ts @@ -57,7 +57,8 @@ export class EntityVersionRestoreComponent extends PageComponent implements OnIn ngOnInit(): void { this.restoreFormGroup = this.fb.group({ - loadRelations: [false, []] + loadRelations: [false, []], + loadAttributes: [false, []] }); } @@ -73,7 +74,8 @@ export class EntityVersionRestoreComponent extends PageComponent implements OnIn versionId: this.versionId, externalEntityId: this.externalEntityId, config: { - loadRelations: this.restoreFormGroup.get('loadRelations').value + loadRelations: this.restoreFormGroup.get('loadRelations').value, + loadAttributes: this.restoreFormGroup.get('loadAttributes').value }, type: VersionLoadRequestType.SINGLE_ENTITY }; diff --git a/ui-ngx/src/app/modules/home/components/vc/remove-other-entities-confirm.component.html b/ui-ngx/src/app/modules/home/components/vc/remove-other-entities-confirm.component.html new file mode 100644 index 0000000000..14ae91e2f2 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/vc/remove-other-entities-confirm.component.html @@ -0,0 +1,41 @@ + +
+
+
+
+ + + +
+
+
+ + +
+
diff --git a/ui-ngx/src/app/modules/home/components/vc/remove-other-entities-confirm.component.ts b/ui-ngx/src/app/modules/home/components/vc/remove-other-entities-confirm.component.ts new file mode 100644 index 0000000000..f569d96fac --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/vc/remove-other-entities-confirm.component.ts @@ -0,0 +1,66 @@ +/// +/// Copyright © 2016-2022 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { Component, Input, OnInit } from '@angular/core'; +import { PageComponent } from '@shared/components/page.component'; +import { Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; +import { TranslateService } from '@ngx-translate/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; + +@Component({ + selector: 'tb-remove-other-entities-confirm', + templateUrl: './remove-other-entities-confirm.component.html', + styleUrls: [] +}) +export class RemoveOtherEntitiesConfirmComponent extends PageComponent implements OnInit { + + @Input() + onClose: (result: boolean | null) => void; + + confirmFormGroup: FormGroup; + + removeOtherEntitiesConfirmText: SafeHtml; + + removeOtherEntitiesVerificationText = 'remove other entities'; + + constructor(protected store: Store, + private translate: TranslateService, + private sanitizer: DomSanitizer, + private fb: FormBuilder) { + super(store); + this.removeOtherEntitiesConfirmText = this.sanitizer.bypassSecurityTrustHtml(this.translate.instant('version-control.remove-other-entities-confirm-text')); + } + + ngOnInit(): void { + this.confirmFormGroup = this.fb.group({ + verification: [null, []] + }); + } + + cancel(): void { + if (this.onClose) { + this.onClose(null); + } + } + + confirm(): void { + if (this.onClose) { + this.onClose(true); + } + } +} diff --git a/ui-ngx/src/app/modules/home/components/vc/version-control-settings.component.html b/ui-ngx/src/app/modules/home/components/vc/repository-settings.component.html similarity index 78% rename from ui-ngx/src/app/modules/home/components/vc/version-control-settings.component.html rename to ui-ngx/src/app/modules/home/components/vc/repository-settings.component.html index b48162d06f..bdab6c061b 100644 --- a/ui-ngx/src/app/modules/home/components/vc/version-control-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/vc/repository-settings.component.html @@ -16,24 +16,24 @@ -->
- +
- admin.git-repository-settings + admin.repository-settings -
+
-
+
admin.repository-url - + admin.repository-url-required @@ -46,12 +46,12 @@ admin.auth-method - - {{versionControlAuthMethodTranslations.get(method) | translate}} + + {{repositoryAuthMethodTranslations.get(method) | translate}} -
+
common.username
-
+
+ (fileNameChanged)="repositorySettingsForm.get('privateKeyFileName').patchValue($event)"> @@ -96,10 +96,10 @@ -
diff --git a/ui-ngx/src/app/modules/home/components/vc/version-control-settings.component.scss b/ui-ngx/src/app/modules/home/components/vc/repository-settings.component.scss similarity index 96% rename from ui-ngx/src/app/modules/home/components/vc/version-control-settings.component.scss rename to ui-ngx/src/app/modules/home/components/vc/repository-settings.component.scss index d1d55faf19..77ae0ffd8f 100644 --- a/ui-ngx/src/app/modules/home/components/vc/version-control-settings.component.scss +++ b/ui-ngx/src/app/modules/home/components/vc/repository-settings.component.scss @@ -14,7 +14,7 @@ * limitations under the License. */ :host { - mat-card.vc-settings { + mat-card.repository-settings { margin: 8px; } .fields-group { diff --git a/ui-ngx/src/app/modules/home/components/vc/repository-settings.component.ts b/ui-ngx/src/app/modules/home/components/vc/repository-settings.component.ts new file mode 100644 index 0000000000..c73cf0e632 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/vc/repository-settings.component.ts @@ -0,0 +1,216 @@ +/// +/// Copyright © 2016-2022 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { Component, Input, OnInit } from '@angular/core'; +import { PageComponent } from '@shared/components/page.component'; +import { FormBuilder, FormGroup, FormGroupDirective, Validators } from '@angular/forms'; +import { select, Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; +import { AdminService } from '@core/http/admin.service'; +import { + RepositorySettings, + RepositoryAuthMethod, + repositoryAuthMethodTranslationMap +} from '@shared/models/settings.models'; +import { ActionNotificationShow } from '@core/notification/notification.actions'; +import { TranslateService } from '@ngx-translate/core'; +import { isNotEmptyStr } from '@core/utils'; +import { DialogService } from '@core/services/dialog.service'; +import { ActionAuthUpdateHasRepository } from '@core/auth/auth.actions'; +import { selectHasRepository } from '@core/auth/auth.selectors'; +import { catchError, mergeMap, take } from 'rxjs/operators'; +import { of } from 'rxjs'; + +@Component({ + selector: 'tb-repository-settings', + templateUrl: './repository-settings.component.html', + styleUrls: ['./repository-settings.component.scss', './../../pages/admin/settings-card.scss'] +}) +export class RepositorySettingsComponent extends PageComponent implements OnInit { + + @Input() + detailsMode = false; + + repositorySettingsForm: FormGroup; + settings: RepositorySettings = null; + + repositoryAuthMethod = RepositoryAuthMethod; + repositoryAuthMethods = Object.values(RepositoryAuthMethod); + repositoryAuthMethodTranslations = repositoryAuthMethodTranslationMap; + + showChangePassword = false; + changePassword = false; + + showChangePrivateKeyPassword = false; + changePrivateKeyPassword = false; + + constructor(protected store: Store, + private adminService: AdminService, + private dialogService: DialogService, + private translate: TranslateService, + public fb: FormBuilder) { + super(store); + } + + ngOnInit() { + this.repositorySettingsForm = this.fb.group({ + repositoryUri: [null, [Validators.required]], + defaultBranch: ['main', []], + authMethod: [RepositoryAuthMethod.USERNAME_PASSWORD, [Validators.required]], + username: [null, []], + password: [null, []], + privateKeyFileName: [null, [Validators.required]], + privateKey: [null, []], + privateKeyPassword: [null, []] + }); + this.updateValidators(false); + this.repositorySettingsForm.get('authMethod').valueChanges.subscribe(() => { + this.updateValidators(true); + }); + this.repositorySettingsForm.get('privateKeyFileName').valueChanges.subscribe(() => { + this.updateValidators(false); + }); + this.store.pipe( + select(selectHasRepository), + take(1), + mergeMap((hasRepository) => { + if (hasRepository) { + return this.adminService.getRepositorySettings({ignoreErrors: true}).pipe( + catchError(() => of(null)) + ); + } else { + return of(null); + } + }) + ).subscribe( + (settings) => { + this.settings = settings; + if (this.settings != null) { + if (this.settings.authMethod === RepositoryAuthMethod.USERNAME_PASSWORD) { + this.showChangePassword = true; + } else { + this.showChangePrivateKeyPassword = true; + } + this.repositorySettingsForm.reset(this.settings); + this.updateValidators(false); + } + }); + } + + checkAccess(): void { + const settings: RepositorySettings = this.repositorySettingsForm.value; + this.adminService.checkRepositoryAccess(settings).subscribe(() => { + this.store.dispatch(new ActionNotificationShow({ message: this.translate.instant('admin.check-repository-access-success'), + type: 'success' })); + }); + } + + save(): void { + const settings: RepositorySettings = this.repositorySettingsForm.value; + this.adminService.saveRepositorySettings(settings).subscribe( + (savedSettings) => { + this.settings = savedSettings; + if (this.settings.authMethod === RepositoryAuthMethod.USERNAME_PASSWORD) { + this.showChangePassword = true; + this.changePassword = false; + } else { + this.showChangePrivateKeyPassword = true; + this.changePrivateKeyPassword = false; + } + this.repositorySettingsForm.reset(this.settings); + this.updateValidators(false); + this.store.dispatch(new ActionAuthUpdateHasRepository({ hasRepository: true })); + } + ); + } + + delete(formDirective: FormGroupDirective): void { + this.dialogService.confirm( + this.translate.instant('admin.delete-repository-settings-title', ), + this.translate.instant('admin.delete-repository-settings-text'), null, + this.translate.instant('action.delete') + ).subscribe((data) => { + if (data) { + this.adminService.deleteRepositorySettings().subscribe( + () => { + this.settings = null; + this.showChangePassword = false; + this.changePassword = false; + this.showChangePrivateKeyPassword = false; + this.changePrivateKeyPassword = false; + formDirective.resetForm(); + this.repositorySettingsForm.reset({ defaultBranch: 'main', authMethod: RepositoryAuthMethod.USERNAME_PASSWORD }); + this.updateValidators(false); + this.store.dispatch(new ActionAuthUpdateHasRepository({ hasRepository: false })); + } + ); + } + }); + } + + changePasswordChanged() { + if (this.changePassword) { + this.repositorySettingsForm.get('password').patchValue(''); + this.repositorySettingsForm.get('password').markAsDirty(); + } + this.updateValidators(false); + } + + changePrivateKeyPasswordChanged() { + if (this.changePrivateKeyPassword) { + this.repositorySettingsForm.get('privateKeyPassword').patchValue(''); + this.repositorySettingsForm.get('privateKeyPassword').markAsDirty(); + } + this.updateValidators(false); + } + + updateValidators(emitEvent?: boolean): void { + const authMethod: RepositoryAuthMethod = this.repositorySettingsForm.get('authMethod').value; + const privateKeyFileName: string = this.repositorySettingsForm.get('privateKeyFileName').value; + if (authMethod === RepositoryAuthMethod.USERNAME_PASSWORD) { + this.repositorySettingsForm.get('username').enable({emitEvent}); + if (this.changePassword || !this.showChangePassword) { + this.repositorySettingsForm.get('password').enable({emitEvent}); + } else { + this.repositorySettingsForm.get('password').disable({emitEvent}); + } + this.repositorySettingsForm.get('privateKeyFileName').disable({emitEvent}); + this.repositorySettingsForm.get('privateKey').disable({emitEvent}); + this.repositorySettingsForm.get('privateKeyPassword').disable({emitEvent}); + } else { + this.repositorySettingsForm.get('username').disable({emitEvent}); + this.repositorySettingsForm.get('password').disable({emitEvent}); + this.repositorySettingsForm.get('privateKeyFileName').enable({emitEvent}); + this.repositorySettingsForm.get('privateKey').enable({emitEvent}); + if (this.changePrivateKeyPassword || !this.showChangePrivateKeyPassword) { + this.repositorySettingsForm.get('privateKeyPassword').enable({emitEvent}); + } else { + this.repositorySettingsForm.get('privateKeyPassword').disable({emitEvent}); + } + if (isNotEmptyStr(privateKeyFileName)) { + this.repositorySettingsForm.get('privateKey').clearValidators(); + } else { + this.repositorySettingsForm.get('privateKey').setValidators([Validators.required]); + } + } + this.repositorySettingsForm.get('username').updateValueAndValidity({emitEvent: false}); + this.repositorySettingsForm.get('password').updateValueAndValidity({emitEvent: false}); + this.repositorySettingsForm.get('privateKeyFileName').updateValueAndValidity({emitEvent: false}); + this.repositorySettingsForm.get('privateKey').updateValueAndValidity({emitEvent: false}); + this.repositorySettingsForm.get('privateKeyPassword').updateValueAndValidity({emitEvent: false}); + } + +} diff --git a/ui-ngx/src/app/modules/home/components/vc/version-control-settings.component.ts b/ui-ngx/src/app/modules/home/components/vc/version-control-settings.component.ts deleted file mode 100644 index 3462fbb728..0000000000 --- a/ui-ngx/src/app/modules/home/components/vc/version-control-settings.component.ts +++ /dev/null @@ -1,218 +0,0 @@ -/// -/// Copyright © 2016-2022 The Thingsboard Authors -/// -/// Licensed under the Apache License, Version 2.0 (the "License"); -/// you may not use this file except in compliance with the License. -/// You may obtain a copy of the License at -/// -/// http://www.apache.org/licenses/LICENSE-2.0 -/// -/// Unless required by applicable law or agreed to in writing, software -/// distributed under the License is distributed on an "AS IS" BASIS, -/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -/// See the License for the specific language governing permissions and -/// limitations under the License. -/// - -import { Component, Input, OnInit } from '@angular/core'; -import { PageComponent } from '@shared/components/page.component'; -import { HasConfirmForm } from '@core/guards/confirm-on-exit.guard'; -import { FormBuilder, FormGroup, FormGroupDirective, Validators } from '@angular/forms'; -import { select, Store } from '@ngrx/store'; -import { AppState } from '@core/core.state'; -import { AdminService } from '@core/http/admin.service'; -import { - EntitiesVersionControlSettings, - VersionControlAuthMethod, - versionControlAuthMethodTranslationMap -} from '@shared/models/settings.models'; -import { ActionNotificationShow } from '@core/notification/notification.actions'; -import { TranslateService } from '@ngx-translate/core'; -import { isNotEmptyStr } from '@core/utils'; -import { DialogService } from '@core/services/dialog.service'; -import { ActionSettingsChangeLanguage } from '@core/settings/settings.actions'; -import { ActionAuthUpdateHasVersionControl } from '@core/auth/auth.actions'; -import { selectHasVersionControl } from '@core/auth/auth.selectors'; -import { catchError, mergeMap, take } from 'rxjs/operators'; -import { of } from 'rxjs'; - -@Component({ - selector: 'tb-version-control-settings', - templateUrl: './version-control-settings.component.html', - styleUrls: ['./version-control-settings.component.scss', './../../pages/admin/settings-card.scss'] -}) -export class VersionControlSettingsComponent extends PageComponent implements OnInit { - - @Input() - detailsMode = false; - - versionControlSettingsForm: FormGroup; - settings: EntitiesVersionControlSettings = null; - - versionControlAuthMethod = VersionControlAuthMethod; - versionControlAuthMethods = Object.values(VersionControlAuthMethod); - versionControlAuthMethodTranslations = versionControlAuthMethodTranslationMap; - - showChangePassword = false; - changePassword = false; - - showChangePrivateKeyPassword = false; - changePrivateKeyPassword = false; - - constructor(protected store: Store, - private adminService: AdminService, - private dialogService: DialogService, - private translate: TranslateService, - public fb: FormBuilder) { - super(store); - } - - ngOnInit() { - this.versionControlSettingsForm = this.fb.group({ - repositoryUri: [null, [Validators.required]], - defaultBranch: ['main', []], - authMethod: [VersionControlAuthMethod.USERNAME_PASSWORD, [Validators.required]], - username: [null, []], - password: [null, []], - privateKeyFileName: [null, [Validators.required]], - privateKey: [null, []], - privateKeyPassword: [null, []] - }); - this.updateValidators(false); - this.versionControlSettingsForm.get('authMethod').valueChanges.subscribe(() => { - this.updateValidators(true); - }); - this.versionControlSettingsForm.get('privateKeyFileName').valueChanges.subscribe(() => { - this.updateValidators(false); - }); - this.store.pipe( - select(selectHasVersionControl), - take(1), - mergeMap((hasVersionControl) => { - if (hasVersionControl) { - return this.adminService.getEntitiesVersionControlSettings({ignoreErrors: true}).pipe( - catchError(() => of(null)) - ); - } else { - return of(null); - } - }) - ).subscribe( - (settings) => { - this.settings = settings; - if (this.settings != null) { - if (this.settings.authMethod === VersionControlAuthMethod.USERNAME_PASSWORD) { - this.showChangePassword = true; - } else { - this.showChangePrivateKeyPassword = true; - } - this.versionControlSettingsForm.reset(this.settings); - this.updateValidators(false); - } - }); - } - - checkAccess(): void { - const settings: EntitiesVersionControlSettings = this.versionControlSettingsForm.value; - this.adminService.checkVersionControlAccess(settings).subscribe(() => { - this.store.dispatch(new ActionNotificationShow({ message: this.translate.instant('admin.check-vc-access-success'), - type: 'success' })); - }); - } - - save(): void { - const settings: EntitiesVersionControlSettings = this.versionControlSettingsForm.value; - this.adminService.saveEntitiesVersionControlSettings(settings).subscribe( - (savedSettings) => { - this.settings = savedSettings; - if (this.settings.authMethod === VersionControlAuthMethod.USERNAME_PASSWORD) { - this.showChangePassword = true; - this.changePassword = false; - } else { - this.showChangePrivateKeyPassword = true; - this.changePrivateKeyPassword = false; - } - this.versionControlSettingsForm.reset(this.settings); - this.updateValidators(false); - this.store.dispatch(new ActionAuthUpdateHasVersionControl({ hasVersionControl: true })); - } - ); - } - - delete(formDirective: FormGroupDirective): void { - this.dialogService.confirm( - this.translate.instant('admin.delete-git-settings-title', ), - this.translate.instant('admin.delete-git-settings-text'), null, - this.translate.instant('action.delete') - ).subscribe((data) => { - if (data) { - this.adminService.deleteEntitiesVersionControlSettings().subscribe( - () => { - this.settings = null; - this.showChangePassword = false; - this.changePassword = false; - this.showChangePrivateKeyPassword = false; - this.changePrivateKeyPassword = false; - formDirective.resetForm(); - this.versionControlSettingsForm.reset({ defaultBranch: 'main', authMethod: VersionControlAuthMethod.USERNAME_PASSWORD }); - this.updateValidators(false); - this.store.dispatch(new ActionAuthUpdateHasVersionControl({ hasVersionControl: false })); - } - ); - } - }); - } - - changePasswordChanged() { - if (this.changePassword) { - this.versionControlSettingsForm.get('password').patchValue(''); - this.versionControlSettingsForm.get('password').markAsDirty(); - } - this.updateValidators(false); - } - - changePrivateKeyPasswordChanged() { - if (this.changePrivateKeyPassword) { - this.versionControlSettingsForm.get('privateKeyPassword').patchValue(''); - this.versionControlSettingsForm.get('privateKeyPassword').markAsDirty(); - } - this.updateValidators(false); - } - - updateValidators(emitEvent?: boolean): void { - const authMethod: VersionControlAuthMethod = this.versionControlSettingsForm.get('authMethod').value; - const privateKeyFileName: string = this.versionControlSettingsForm.get('privateKeyFileName').value; - if (authMethod === VersionControlAuthMethod.USERNAME_PASSWORD) { - this.versionControlSettingsForm.get('username').enable({emitEvent}); - if (this.changePassword || !this.showChangePassword) { - this.versionControlSettingsForm.get('password').enable({emitEvent}); - } else { - this.versionControlSettingsForm.get('password').disable({emitEvent}); - } - this.versionControlSettingsForm.get('privateKeyFileName').disable({emitEvent}); - this.versionControlSettingsForm.get('privateKey').disable({emitEvent}); - this.versionControlSettingsForm.get('privateKeyPassword').disable({emitEvent}); - } else { - this.versionControlSettingsForm.get('username').disable({emitEvent}); - this.versionControlSettingsForm.get('password').disable({emitEvent}); - this.versionControlSettingsForm.get('privateKeyFileName').enable({emitEvent}); - this.versionControlSettingsForm.get('privateKey').enable({emitEvent}); - if (this.changePrivateKeyPassword || !this.showChangePrivateKeyPassword) { - this.versionControlSettingsForm.get('privateKeyPassword').enable({emitEvent}); - } else { - this.versionControlSettingsForm.get('privateKeyPassword').disable({emitEvent}); - } - if (isNotEmptyStr(privateKeyFileName)) { - this.versionControlSettingsForm.get('privateKey').clearValidators(); - } else { - this.versionControlSettingsForm.get('privateKey').setValidators([Validators.required]); - } - } - this.versionControlSettingsForm.get('username').updateValueAndValidity({emitEvent: false}); - this.versionControlSettingsForm.get('password').updateValueAndValidity({emitEvent: false}); - this.versionControlSettingsForm.get('privateKeyFileName').updateValueAndValidity({emitEvent: false}); - this.versionControlSettingsForm.get('privateKey').updateValueAndValidity({emitEvent: false}); - this.versionControlSettingsForm.get('privateKeyPassword').updateValueAndValidity({emitEvent: false}); - } - -} diff --git a/ui-ngx/src/app/modules/home/components/vc/version-control.component.html b/ui-ngx/src/app/modules/home/components/vc/version-control.component.html index e5e650ac85..3cf10ab168 100644 --- a/ui-ngx/src/app/modules/home/components/vc/version-control.component.html +++ b/ui-ngx/src/app/modules/home/components/vc/version-control.component.html @@ -15,9 +15,9 @@ limitations under the License. --> - - + + (); - hasVersionControl$ = this.store.pipe(select(selectHasVersionControl)); + hasRepository$ = this.store.pipe(select(selectHasRepository)); constructor(private store: Store) { @@ -61,7 +61,7 @@ export class VersionControlComponent implements OnInit, HasConfirmForm { } confirmForm(): FormGroup { - return this.versionControlSettingsComponent?.versionControlSettingsForm; + return this.repositorySettingsComponent?.repositorySettingsForm; } } diff --git a/ui-ngx/src/app/modules/home/pages/admin/admin-routing.module.ts b/ui-ngx/src/app/modules/home/pages/admin/admin-routing.module.ts index 958e7b1c9b..16baa3aa89 100644 --- a/ui-ngx/src/app/modules/home/pages/admin/admin-routing.module.ts +++ b/ui-ngx/src/app/modules/home/pages/admin/admin-routing.module.ts @@ -33,7 +33,7 @@ import { EntityDetailsPageComponent } from '@home/components/entity/entity-detai import { entityDetailsPageBreadcrumbLabelFunction } from '@home/pages/home-pages.models'; import { BreadCrumbConfig } from '@shared/components/breadcrumb'; import { QueuesTableConfigResolver } from '@home/pages/admin/queue/queues-table-config.resolver'; -import { VersionControlAdminSettingsComponent } from '@home/pages/admin/version-control-admin-settings.component'; +import { RepositoryAdminSettingsComponent } from '@home/pages/admin/repository-admin-settings.component'; @Injectable() export class OAuth2LoginProcessingUrlResolver implements Resolve { @@ -225,14 +225,14 @@ const routes: Routes = [ ] }, { - path: 'vc', - component: VersionControlAdminSettingsComponent, + path: 'repository', + component: RepositoryAdminSettingsComponent, canDeactivate: [ConfirmOnExitGuard], data: { auth: [Authority.TENANT_ADMIN], - title: 'admin.git-settings', + title: 'admin.repository-settings', breadcrumb: { - label: 'admin.git-settings', + label: 'admin.repository-settings', icon: 'manage_history' } } diff --git a/ui-ngx/src/app/modules/home/pages/admin/admin.module.ts b/ui-ngx/src/app/modules/home/pages/admin/admin.module.ts index 51612270df..85e3d04767 100644 --- a/ui-ngx/src/app/modules/home/pages/admin/admin.module.ts +++ b/ui-ngx/src/app/modules/home/pages/admin/admin.module.ts @@ -29,7 +29,7 @@ import { SendTestSmsDialogComponent } from '@home/pages/admin/send-test-sms-dial import { HomeSettingsComponent } from '@home/pages/admin/home-settings.component'; import { ResourcesLibraryComponent } from '@home/pages/admin/resource/resources-library.component'; import { QueueComponent} from '@home/pages/admin/queue/queue.component'; -import { VersionControlAdminSettingsComponent } from '@home/pages/admin/version-control-admin-settings.component'; +import { RepositoryAdminSettingsComponent } from '@home/pages/admin/repository-admin-settings.component'; @NgModule({ declarations: @@ -43,7 +43,7 @@ import { VersionControlAdminSettingsComponent } from '@home/pages/admin/version- HomeSettingsComponent, ResourcesLibraryComponent, QueueComponent, - VersionControlAdminSettingsComponent + RepositoryAdminSettingsComponent ], imports: [ CommonModule, diff --git a/ui-ngx/src/app/modules/home/pages/admin/version-control-admin-settings.component.html b/ui-ngx/src/app/modules/home/pages/admin/repository-admin-settings.component.html similarity index 87% rename from ui-ngx/src/app/modules/home/pages/admin/version-control-admin-settings.component.html rename to ui-ngx/src/app/modules/home/pages/admin/repository-admin-settings.component.html index 869067e1fb..7b408fc93a 100644 --- a/ui-ngx/src/app/modules/home/pages/admin/version-control-admin-settings.component.html +++ b/ui-ngx/src/app/modules/home/pages/admin/repository-admin-settings.component.html @@ -15,4 +15,4 @@ limitations under the License. --> - + diff --git a/ui-ngx/src/app/modules/home/pages/admin/version-control-admin-settings.component.ts b/ui-ngx/src/app/modules/home/pages/admin/repository-admin-settings.component.ts similarity index 68% rename from ui-ngx/src/app/modules/home/pages/admin/version-control-admin-settings.component.ts rename to ui-ngx/src/app/modules/home/pages/admin/repository-admin-settings.component.ts index a203f64426..1ee0a7288a 100644 --- a/ui-ngx/src/app/modules/home/pages/admin/version-control-admin-settings.component.ts +++ b/ui-ngx/src/app/modules/home/pages/admin/repository-admin-settings.component.ts @@ -20,16 +20,16 @@ import { HasConfirmForm } from '@core/guards/confirm-on-exit.guard'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; import { FormGroup } from '@angular/forms'; -import { VersionControlSettingsComponent } from '@home/components/vc/version-control-settings.component'; +import { RepositorySettingsComponent } from '@home/components/vc/repository-settings.component'; @Component({ - selector: 'tb-version-control-admin-settings', - templateUrl: './version-control-admin-settings.component.html', + selector: 'tb-repository-admin-settings', + templateUrl: './repository-admin-settings.component.html', styleUrls: [] }) -export class VersionControlAdminSettingsComponent extends PageComponent implements OnInit, HasConfirmForm { +export class RepositoryAdminSettingsComponent extends PageComponent implements OnInit, HasConfirmForm { - @ViewChild('versionControlSettingsComponent') versionControlSettingsComponent: VersionControlSettingsComponent; + @ViewChild('repositorySettingsComponent') repositorySettingsComponent: RepositorySettingsComponent; constructor(protected store: Store) { super(store); @@ -39,6 +39,6 @@ export class VersionControlAdminSettingsComponent extends PageComponent implemen } confirmForm(): FormGroup { - return this.versionControlSettingsComponent?.versionControlSettingsForm; + return this.repositorySettingsComponent?.repositorySettingsForm; } } diff --git a/ui-ngx/src/app/shared/models/constants.ts b/ui-ngx/src/app/shared/models/constants.ts index 6297809522..ff16183509 100644 --- a/ui-ngx/src/app/shared/models/constants.ts +++ b/ui-ngx/src/app/shared/models/constants.ts @@ -135,7 +135,7 @@ export const HelpLinks = { ruleNodePushToCloud: helpBaseUrl + '/docs/user-guide/rule-engine-2-0/action-nodes/#push-to-cloud', ruleNodePushToEdge: helpBaseUrl + '/docs/user-guide/rule-engine-2-0/action-nodes/#push-to-edge', queue: helpBaseUrl + '/docs/user-guide/queue', - versionControlSettings: helpBaseUrl + '/docs/user-guide/ui/version-control-settings' + repositorySettings: helpBaseUrl + '/docs/user-guide/ui/repository-settings' } }; diff --git a/ui-ngx/src/app/shared/models/settings.models.ts b/ui-ngx/src/app/shared/models/settings.models.ts index 8a1b316001..298281da11 100644 --- a/ui-ngx/src/app/shared/models/settings.models.ts +++ b/ui-ngx/src/app/shared/models/settings.models.ts @@ -16,6 +16,7 @@ import { ValidatorFn } from '@angular/forms'; import { isNotEmptyStr, isNumber } from '@core/utils'; +import { VersionCreateConfig } from '@shared/models/vc.models'; export const smtpPortPattern: RegExp = /^([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$/; @@ -397,23 +398,29 @@ export function createSmsProviderConfiguration(type: SmsProviderType): SmsProvid return smsProviderConfiguration; } -export enum VersionControlAuthMethod { +export enum RepositoryAuthMethod { USERNAME_PASSWORD = 'USERNAME_PASSWORD', PRIVATE_KEY = 'PRIVATE_KEY' } -export const versionControlAuthMethodTranslationMap = new Map([ - [VersionControlAuthMethod.USERNAME_PASSWORD, 'admin.auth-method-username-password'], - [VersionControlAuthMethod.PRIVATE_KEY, 'admin.auth-method-private-key'] +export const repositoryAuthMethodTranslationMap = new Map([ + [RepositoryAuthMethod.USERNAME_PASSWORD, 'admin.auth-method-username-password'], + [RepositoryAuthMethod.PRIVATE_KEY, 'admin.auth-method-private-key'] ]); -export interface EntitiesVersionControlSettings { +export interface RepositorySettings { repositoryUri: string; defaultBranch: string; - authMethod: VersionControlAuthMethod; + authMethod: RepositoryAuthMethod; username: string; password: string; privateKeyFileName: string; privateKey: string; privateKeyPassword: string; } + +export interface AutoVersionCreateConfig extends VersionCreateConfig { + branch: string; +} + +export type AutoCommitSettings = {[entityType: string]: AutoVersionCreateConfig}; diff --git a/ui-ngx/src/app/shared/models/vc.models.ts b/ui-ngx/src/app/shared/models/vc.models.ts index 0ad52d2e0b..cd1cba93ed 100644 --- a/ui-ngx/src/app/shared/models/vc.models.ts +++ b/ui-ngx/src/app/shared/models/vc.models.ts @@ -32,6 +32,7 @@ export const exportableEntityTypes: Array = [ export interface VersionCreateConfig { saveRelations: boolean; + saveAttributes: boolean; } export enum VersionCreateRequestType { @@ -81,6 +82,7 @@ export function createDefaultEntityTypesVersionCreate(): {[entityType: string]: res[entityType] = { syncStrategy: null, saveRelations: false, + saveAttributes: false, allEntities: true, entityIds: [] }; @@ -90,6 +92,7 @@ export function createDefaultEntityTypesVersionCreate(): {[entityType: string]: export interface VersionLoadConfig { loadRelations: boolean; + loadAttributes: boolean; } export enum VersionLoadRequestType { @@ -111,6 +114,7 @@ export interface SingleEntityVersionLoadRequest extends VersionLoadRequest { export interface EntityTypeVersionLoadConfig extends VersionLoadConfig { removeOtherEntities: boolean; + findExistingEntityByName: boolean; } export interface EntityTypeVersionLoadRequest extends VersionLoadRequest { @@ -123,7 +127,9 @@ export function createDefaultEntityTypesVersionLoad(): {[entityType: string]: En for (const entityType of exportableEntityTypes) { res[entityType] = { loadRelations: false, - removeOtherEntities: false + loadAttributes: false, + removeOtherEntities: false, + findExistingEntityByName: false }; } return res; @@ -176,18 +182,5 @@ export interface EntityDataDiff { } export function entityExportDataToJsonString(data: EntityExportData): string { - if (!data.relations) { - data.relations = []; - } - const allKeys = new Set(); - JSON.stringify(data, (key, value) => (allKeys.add(key), value)); - return JSON.stringify(data, Array.from(allKeys).sort((key1, key2) => { - if (key1 === 'relations') { - return 1; - } else if (key2 === 'relations') { - return -1; - } else { - return 0; - } - }), 4); + return JSON.stringify(data, null, 4); } diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index 4a4e228cc2..8a2f63cb8f 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -58,7 +58,8 @@ "next-with-label": "Next: {{label}}", "read-more": "Read more", "hide": "Hide", - "restore": "Restore" + "restore": "Restore", + "confirm": "Confirm" }, "aggregation": { "aggregation": "Aggregation", @@ -321,8 +322,7 @@ "queue-submit-strategy": "Submit strategy", "queue-processing-strategy": "Processing strategy", "queue-configuration": "Queue configuration", - "git-settings": "Git settings", - "git-repository-settings": "Git repository settings", + "repository-settings": "Repository settings", "repository-url": "Repository URL", "repository-url-required": "Repository URL is required.", "default-branch": "Default branch name", @@ -338,9 +338,9 @@ "enter-passphrase": "Enter passphrase", "change-passphrase": "Change passphrase", "check-access": "Check access", - "check-vc-access-success": "Git repository access successfully verified!", - "delete-git-settings-title": "Are you sure you want to delete git settings?", - "delete-git-settings-text": "Be careful, after the confirmation the git settings will be removed and git synchronization feature will be unavailable." + "check-repository-access-success": "Repository access successfully verified!", + "delete-repository-settings-title": "Are you sure you want to delete repository settings?", + "delete-repository-settings-text": "Be careful, after the confirmation the repository settings will be removed and version control feature will be unavailable." }, "alarm": { "alarm": "Alarm", @@ -3121,6 +3121,7 @@ "version-name-required": "Version name is required", "author": "Author", "export-entity-relations": "Export entity relations", + "export-entity-attributes": "Export entity attributes", "entity-versions": "Entity versions", "versions": "Versions", "created-time": "Created time", @@ -3133,6 +3134,7 @@ "restore-version": "Restore version", "restore-entity-from-version": "Restore entity from version '{{versionName}}'", "load-entity-relations": "Load entity relations", + "load-entity-attributes": "Load entity attributes", "show-version-diff": "Show version diff", "diff-entity-with-version": "Diff with entity version '{{versionName}}'", "previous-difference": "Previous Difference", @@ -3151,12 +3153,15 @@ "remove-all": "Remove all", "version-create-result": "{ added, plural, 0 {No entities} 1 {1 entity} other {# entities} } added.\n{ modified, plural, 0 {No entities} 1 {1 entity} other {# entities} } modified.\n{ removed, plural, 0 {No entities} 1 {1 entity} other {# entities} } removed.", "load-entities-relations": "Load entities relations", + "load-entities-attributes": "Load entities attributes", "remove-other-entities": "Remove other entities", + "find-existing-entity-by-name": "Find existing entity by name", "restore-entities-from-version": "Restore entities from version '{{versionName}}'", "no-entities-restored": "No entities restored", "created": "{{created}} created", "updated": "{{updated}} updated", - "deleted": "{{deleted}} deleted" + "deleted": "{{deleted}} deleted", + "remove-other-entities-confirm-text": "Be careful! This will permanently delete all current entities
not present in the version you want to restore.

Please type remove other entities to confirm." }, "widget": { "widget-library": "Widgets Library",