From 2e4ccac9f6ef7d5fd01799e62f49091cad6c57eb Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Fri, 4 Jul 2025 12:11:18 +0300 Subject: [PATCH 1/5] UI: Improved mobile configuration dialog to single file --- ...le-app-configuration-dialog.component.html | 25 +++----- ...bile-app-configuration-dialog.component.ts | 64 +++++++------------ .../import-export/import-export.service.ts | 2 +- .../assets/locale/locale.constant-en_US.json | 12 ++-- 4 files changed, 35 insertions(+), 68 deletions(-) diff --git a/ui-ngx/src/app/modules/home/pages/mobile/bundes/mobile-app-configuration-dialog.component.html b/ui-ngx/src/app/modules/home/pages/mobile/bundes/mobile-app-configuration-dialog.component.html index 3c11be8930..afaa0da3c1 100644 --- a/ui-ngx/src/app/modules/home/pages/mobile/bundes/mobile-app-configuration-dialog.component.html +++ b/ui-ngx/src/app/modules/home/pages/mobile/bundes/mobile-app-configuration-dialog.component.html @@ -43,23 +43,14 @@ [data]=createMarkDownCommand(gitRepositoryLink)>
-
mobile.configuration-step.configure-api-title
-
mobile.configuration-step.configure-api-text
- -
mobile.configuration-step.configure-api-hint
- -
-
-
mobile.configuration-step.configure-package-title
-
mobile.configuration-step.configure-package-text
-
mobile.configuration-step.configure-package-text-install
- -
mobile.configuration-step.configure-package-run-commands
- +
mobile.configuration-step.configure-app-settings-title
+
+
mobile.configuration-step.configure-app-settings-text
+ +
mobile.configuration-step.run-app-title
diff --git a/ui-ngx/src/app/modules/home/pages/mobile/bundes/mobile-app-configuration-dialog.component.ts b/ui-ngx/src/app/modules/home/pages/mobile/bundes/mobile-app-configuration-dialog.component.ts index 9168f14245..5e7d384383 100644 --- a/ui-ngx/src/app/modules/home/pages/mobile/bundes/mobile-app-configuration-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/pages/mobile/bundes/mobile-app-configuration-dialog.component.ts @@ -22,6 +22,7 @@ import { Router } from '@angular/router'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { ActionPreferencesPutUserSettings } from '@core/auth/auth.actions'; import { MobileApp } from '@shared/models/mobile-app.models'; +import { ImportExportService } from '@shared/import-export/import-export.service'; export interface MobileAppConfigurationDialogData { afterAdd: boolean; @@ -36,53 +37,22 @@ export interface MobileAppConfigurationDialogData { }) export class MobileAppConfigurationDialogComponent extends DialogComponent { - notShowAgain = false; - setApplication = false; + private fileName = 'configs.json'; + notShowAgain = false; showDontShowAgain: boolean; gitRepositoryLink = 'git clone -b master https://github.com/thingsboard/flutter_thingsboard_app.git'; - pathToConstants = 'lib/constants/app_constants.dart'; - flutterRunCommand = 'flutter run'; - flutterInstallRenameCommand = 'flutter pub global activate rename'; - - configureApi: string; - - renameCommands: string[] = []; + flutterRunCommand = `flutter run --dart-define-from-file ${this.fileName}`; constructor(protected store: Store, protected router: Router, @Inject(MAT_DIALOG_DATA) private data: MobileAppConfigurationDialogData, protected dialogRef: MatDialogRef, + private importExportService: ImportExportService, ) { super(store, router, dialogRef); - this.showDontShowAgain = this.data.afterAdd; - - this.setApplication = !!this.data.androidApp || !!this.data.iosApp; - - this.configureApi = `static const thingsBoardApiEndpoint = '${window.location.origin}';`; - if (this.setApplication) { - this.configureApi += '\n'; - if (!!this.data.androidApp) { - this.configureApi += `\nstatic const thingsboardAndroidAppSecret = '${this.data.androidApp.appSecret}';`; - } - if (!!this.data.iosApp) { - this.configureApi += `\nstatic const thingsboardIOSAppSecret = '${this.data.iosApp.appSecret}';`; - } - } - if (this.setApplication) { - if (this.data.androidApp?.pkgName === this.data.iosApp?.pkgName) { - this.renameCommands.push(`rename setBundleId --targets android, ios --value "${this.data.androidApp.pkgName}"`); - } else { - if (!!this.data.androidApp) { - this.renameCommands.push(`rename setBundleId --targets android --value "${this.data.androidApp.pkgName}"`); - } - if (!!this.data.iosApp) { - this.renameCommands.push(`rename setBundleId --targets ios --value "${this.data.iosApp.pkgName}"`); - } - } - } } close(): void { @@ -94,14 +64,24 @@ export class MobileAppConfigurationDialogComponent extends DialogComponent = []; - commands.forEach(command => formatCommands.push(this.createMarkDownSingleCommand(command))); - return formatCommands.join(`\n
\n\n`); - } else { - return this.createMarkDownSingleCommand(commands); + createMarkDownCommand(commands: string): string { + return this.createMarkDownSingleCommand(commands); + } + + downloadSettings(): void { + const settings: any = { + thingsBoardApiEndpoint: window.location.origin + }; + if (!!this.data.androidApp) { + settings.androidApplicationId = this.data.androidApp.pkgName; + settings.thingsboardOAuth2CallbackUrlScheme = this.data.androidApp.pkgName + '.auth'; + settings.thingsboardAndroidAppSecret = this.data.androidApp.appSecret; + } + if (!!this.data.iosApp) { + settings.iosApplicationId = this.data.iosApp.pkgName; + settings.thingsboardIOSAppSecret = this.data.iosApp.appSecret; } + this.importExportService.exportJson(settings, this.fileName); } private createMarkDownSingleCommand(command: string): string { diff --git a/ui-ngx/src/app/shared/import-export/import-export.service.ts b/ui-ngx/src/app/shared/import-export/import-export.service.ts index 2ad60f0139..94960cb838 100644 --- a/ui-ngx/src/app/shared/import-export/import-export.service.ts +++ b/ui-ngx/src/app/shared/import-export/import-export.service.ts @@ -1188,7 +1188,7 @@ export class ImportExportService { this.exportJson(data, filename); } - private exportJson(data: any, filename: string) { + public exportJson(data: any, filename: string) { if (isObject(data)) { data = JSON.stringify(data, null, 2); } 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 963bf769ee..14395f3b95 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -3850,17 +3850,13 @@ "prepare-environment-text": "Flutter ThingsBoard Mobile Application requires Flutter SDK. Follow instructions to set up Flutter SDK.", "get-source-code-title": "Get app source code", "get-source-code-text": "You can get Flutter ThingsBoard Mobile Application source code by cloning it from the GitHub repository:", - "configure-api-title": "Configure ThingsBoard API endpoint", - "configure-api-text": "Open the flutter_thingsboard_app project in your editor/IDE. Edit:", - "configure-api-hint": "Set the value of the thingsBoardApiEndpoint constant to match the API endpoint of your ThingsBoard server instance. Do not use “localhost” or “127.0.0.1” hostnames.", + "configure-app-settings-title": "Configure app settings", + "configure-app-settings-text": "Download the configuration file and place it into the root directory of the project you cloned in the previous step.", + "download-file": "Download file", "run-app-title": "Run the app", "run-app-text": "Run the app as described in your IDE.\nIf using the terminal, run the app with the following command:", "more-information": "Detailed information may be found in our Getting Started documentation.", - "getting-started": "Getting Started", - "configure-package-title": "Configure application package", - "configure-package-text": "You can manually change the Application Package or use third party CLI tool.", - "configure-package-text-install": "To install the Rename CLI Tool, execute the following command:", - "configure-package-run-commands": "Run these commands in the root directory of your project:" + "getting-started": "Getting Started" } }, "notification": { From 5a848477fc26292a47a8ac8f8545e8b340605c0e Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Wed, 16 Jul 2025 11:37:33 +0300 Subject: [PATCH 2/5] Add support mobile application title in predefined config --- application/src/main/data/upgrade/basic/schema_update.sql | 2 ++ .../server/common/data/mobile/app/MobileApp.java | 4 ++++ .../org/thingsboard/server/dao/model/ModelConstants.java | 1 + .../thingsboard/server/dao/model/sql/MobileAppEntity.java | 5 +++++ dao/src/main/resources/sql/schema-entities.sql | 1 + .../applications/mobile-app-table-config.resolver.ts | 1 + .../pages/mobile/applications/mobile-app.component.html | 8 ++++++++ .../pages/mobile/applications/mobile-app.component.ts | 5 +++-- .../bundes/mobile-app-configuration-dialog.component.ts | 7 +++++-- .../mobile/bundes/mobile-bundle-table-config.resolve.ts | 3 ++- ui-ngx/src/app/shared/models/mobile-app.models.ts | 1 + ui-ngx/src/assets/locale/locale.constant-en_US.json | 2 ++ 12 files changed, 35 insertions(+), 5 deletions(-) diff --git a/application/src/main/data/upgrade/basic/schema_update.sql b/application/src/main/data/upgrade/basic/schema_update.sql index c959cfd6c1..ec1bb862fd 100644 --- a/application/src/main/data/upgrade/basic/schema_update.sql +++ b/application/src/main/data/upgrade/basic/schema_update.sql @@ -35,3 +35,5 @@ DROP INDEX IF EXISTS idx_customer_external_id; DROP INDEX IF EXISTS idx_widgets_bundle_external_id; -- DROP INDEXES THAT DUPLICATE UNIQUE CONSTRAINT END + +ALTER TABLE mobile_app ADD COLUMN IF NOT EXISTS pkg_title varchar(255); \ No newline at end of file diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/mobile/app/MobileApp.java b/common/data/src/main/java/org/thingsboard/server/common/data/mobile/app/MobileApp.java index e5fefd6072..b2b848c3ba 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/mobile/app/MobileApp.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/mobile/app/MobileApp.java @@ -43,6 +43,9 @@ public class MobileApp extends BaseData implements HasTenantId, Has @NotBlank @Length(fieldName = "pkgName") private String pkgName; + @Schema(description = "Application package title") + @Length(fieldName = "pkgTitle") + private String pkgTitle; @Schema(description = "Application secret. The length must be at least 16 characters", requiredMode = Schema.RequiredMode.REQUIRED) @NotEmpty @Length(fieldName = "appSecret", min = 16, max = 2048, message = "must be at least 16 and max 2048 characters") @@ -72,6 +75,7 @@ public class MobileApp extends BaseData implements HasTenantId, Has super(mobile); this.tenantId = mobile.tenantId; this.pkgName = mobile.pkgName; + this.pkgTitle = mobile.pkgTitle; this.appSecret = mobile.appSecret; this.platformType = mobile.platformType; this.status = mobile.status; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java index 23324eccb5..da1c2d3ca4 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java @@ -457,6 +457,7 @@ public class ModelConstants { */ public static final String MOBILE_APP_TABLE_NAME = "mobile_app"; public static final String MOBILE_APP_PKG_NAME_PROPERTY = "pkg_name"; + public static final String MOBILE_APP_PKG_TITLE_PROPERTY = "pkg_title"; public static final String MOBILE_APP_APP_SECRET_PROPERTY = "app_secret"; public static final String MOBILE_APP_PLATFORM_TYPE_PROPERTY = "platform_type"; public static final String MOBILE_APP_STATUS_PROPERTY = "status"; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/MobileAppEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/MobileAppEntity.java index 70f711750d..34d8869004 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/MobileAppEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/MobileAppEntity.java @@ -53,6 +53,9 @@ public class MobileAppEntity extends BaseSqlEntity { @Column(name = ModelConstants.MOBILE_APP_PKG_NAME_PROPERTY) private String pkgName; + @Column(name = ModelConstants.MOBILE_APP_PKG_TITLE_PROPERTY) + private String pkgTitle; + @Column(name = ModelConstants.MOBILE_APP_APP_SECRET_PROPERTY) private String appSecret; @@ -82,6 +85,7 @@ public class MobileAppEntity extends BaseSqlEntity { this.tenantId = mobile.getTenantId().getId(); } this.pkgName = mobile.getPkgName(); + this.pkgTitle = mobile.getPkgTitle(); this.appSecret = mobile.getAppSecret(); this.platformType = mobile.getPlatformType(); this.status = mobile.getStatus(); @@ -98,6 +102,7 @@ public class MobileAppEntity extends BaseSqlEntity { } mobile.setCreatedTime(createdTime); mobile.setPkgName(pkgName); + mobile.setPkgTitle(pkgTitle); mobile.setAppSecret(appSecret); mobile.setPlatformType(platformType); mobile.setStatus(status); diff --git a/dao/src/main/resources/sql/schema-entities.sql b/dao/src/main/resources/sql/schema-entities.sql index 2cc8cbad0e..6b3753e96d 100644 --- a/dao/src/main/resources/sql/schema-entities.sql +++ b/dao/src/main/resources/sql/schema-entities.sql @@ -626,6 +626,7 @@ CREATE TABLE IF NOT EXISTS mobile_app ( created_time bigint NOT NULL, tenant_id uuid, pkg_name varchar(255), + pkg_title varchar(255), app_secret varchar(2048), platform_type varchar(32), status varchar(32), diff --git a/ui-ngx/src/app/modules/home/pages/mobile/applications/mobile-app-table-config.resolver.ts b/ui-ngx/src/app/modules/home/pages/mobile/applications/mobile-app-table-config.resolver.ts index 0a0732362e..4508f97efc 100644 --- a/ui-ngx/src/app/modules/home/pages/mobile/applications/mobile-app-table-config.resolver.ts +++ b/ui-ngx/src/app/modules/home/pages/mobile/applications/mobile-app-table-config.resolver.ts @@ -83,6 +83,7 @@ export class MobileAppTableConfigResolver { onAction: (_$event, entity) => entity.pkgName, type: CellActionDescriptorType.COPY_BUTTON }), + new EntityTableColumn('pkgTitle', 'mobile.mobile-package-title', '20%'), new EntityTableColumn('appSecret', 'mobile.application-secret', '15%', (entity) => this.truncatePipe.transform(entity.appSecret, true, 10, '…'), () => ({}), true, () => ({}), () => undefined, false, diff --git a/ui-ngx/src/app/modules/home/pages/mobile/applications/mobile-app.component.html b/ui-ngx/src/app/modules/home/pages/mobile/applications/mobile-app.component.html index daad184b9e..7316f0a5d8 100644 --- a/ui-ngx/src/app/modules/home/pages/mobile/applications/mobile-app.component.html +++ b/ui-ngx/src/app/modules/home/pages/mobile/applications/mobile-app.component.html @@ -38,6 +38,14 @@ {{ 'mobile.mobile-package-pattern' | translate }} + + mobile.mobile-package-title + + + + {{ 'mobile.mobile-package-title-max-length' | translate }} + + mobile.platform-type diff --git a/ui-ngx/src/app/modules/home/pages/mobile/applications/mobile-app.component.ts b/ui-ngx/src/app/modules/home/pages/mobile/applications/mobile-app.component.ts index eceda5ac9a..592470f2b2 100644 --- a/ui-ngx/src/app/modules/home/pages/mobile/applications/mobile-app.component.ts +++ b/ui-ngx/src/app/modules/home/pages/mobile/applications/mobile-app.component.ts @@ -63,9 +63,10 @@ export class MobileAppComponent extends EntityComponent { buildForm(entity: MobileApp): FormGroup { const form = this.fb.group({ - pkgName: [entity?.pkgName ? entity.pkgName : '', [Validators.required, Validators.maxLength(255), + pkgName: [entity?.pkgName ?? '', [Validators.required, Validators.maxLength(255), Validators.pattern(/^[a-zA-Z][a-zA-Z\d_]*(?:\.[a-zA-Z][a-zA-Z\d_]*)+$/)]], - platformType: [entity?.platformType ? entity.platformType : PlatformType.ANDROID], + pkgTitle: [entity?.pkgTitle ?? '', [Validators.maxLength(255)]], + platformType: [entity?.platformType ?? PlatformType.ANDROID], appSecret: [entity?.appSecret ? entity.appSecret : btoa(randomAlphanumeric(64)), [Validators.required, this.base64Format]], status: [entity?.status ? entity.status : MobileAppStatus.DRAFT], versionInfo: this.fb.group({ diff --git a/ui-ngx/src/app/modules/home/pages/mobile/bundes/mobile-app-configuration-dialog.component.ts b/ui-ngx/src/app/modules/home/pages/mobile/bundes/mobile-app-configuration-dialog.component.ts index 5e7d384383..aefe7374f3 100644 --- a/ui-ngx/src/app/modules/home/pages/mobile/bundes/mobile-app-configuration-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/pages/mobile/bundes/mobile-app-configuration-dialog.component.ts @@ -28,6 +28,7 @@ export interface MobileAppConfigurationDialogData { afterAdd: boolean; androidApp: MobileApp; iosApp: MobileApp; + bundleTitle: string; } @Component({ @@ -37,13 +38,13 @@ export interface MobileAppConfigurationDialogData { }) export class MobileAppConfigurationDialogComponent extends DialogComponent { - private fileName = 'configs.json'; + private fileName = 'configs'; notShowAgain = false; showDontShowAgain: boolean; gitRepositoryLink = 'git clone -b master https://github.com/thingsboard/flutter_thingsboard_app.git'; - flutterRunCommand = `flutter run --dart-define-from-file ${this.fileName}`; + flutterRunCommand = `flutter run --dart-define-from-file ${this.fileName}.json`; constructor(protected store: Store, protected router: Router, @@ -74,11 +75,13 @@ export class MobileAppConfigurationDialogComponent extends DialogComponent, HasTenantId { pkgName: string; + pkgTitle?: string; appSecret: string; platformType: PlatformType; status: MobileAppStatus; 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 14395f3b95..7e81a45839 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -3767,6 +3767,8 @@ "mobile-package-max-length": "Application package should be less than 256", "mobile-package-required": "Application package is required.", "mobile-package-pattern": "Application package invalid format", + "mobile-package-title": "Application title", + "mobile-package-title-max-length": "Application title should be less than 256", "no-application": "No applications found", "no-bundles": "No bundles found", "platform-type": "Platform type", From 3a441567d9198d5d7779f53fbb2785317f0315f6 Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Wed, 16 Jul 2025 12:56:29 +0300 Subject: [PATCH 3/5] Rename pkgTitle to title --- application/src/main/data/upgrade/basic/schema_update.sql | 2 +- .../server/common/data/mobile/app/MobileApp.java | 6 +++--- .../org/thingsboard/server/dao/model/ModelConstants.java | 2 +- .../thingsboard/server/dao/model/sql/MobileAppEntity.java | 8 ++++---- dao/src/main/resources/sql/schema-entities.sql | 2 +- .../applications/mobile-app-table-config.resolver.ts | 2 +- .../pages/mobile/applications/mobile-app.component.html | 4 ++-- .../pages/mobile/applications/mobile-app.component.ts | 2 +- .../bundes/mobile-app-configuration-dialog.component.ts | 5 +++-- ui-ngx/src/app/shared/models/mobile-app.models.ts | 2 +- 10 files changed, 18 insertions(+), 17 deletions(-) diff --git a/application/src/main/data/upgrade/basic/schema_update.sql b/application/src/main/data/upgrade/basic/schema_update.sql index ec1bb862fd..d614f4b8ea 100644 --- a/application/src/main/data/upgrade/basic/schema_update.sql +++ b/application/src/main/data/upgrade/basic/schema_update.sql @@ -36,4 +36,4 @@ DROP INDEX IF EXISTS idx_widgets_bundle_external_id; -- DROP INDEXES THAT DUPLICATE UNIQUE CONSTRAINT END -ALTER TABLE mobile_app ADD COLUMN IF NOT EXISTS pkg_title varchar(255); \ No newline at end of file +ALTER TABLE mobile_app ADD COLUMN IF NOT EXISTS title varchar(255); \ No newline at end of file diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/mobile/app/MobileApp.java b/common/data/src/main/java/org/thingsboard/server/common/data/mobile/app/MobileApp.java index b2b848c3ba..e05932e324 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/mobile/app/MobileApp.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/mobile/app/MobileApp.java @@ -44,8 +44,8 @@ public class MobileApp extends BaseData implements HasTenantId, Has @Length(fieldName = "pkgName") private String pkgName; @Schema(description = "Application package title") - @Length(fieldName = "pkgTitle") - private String pkgTitle; + @Length(fieldName = "title") + private String title; @Schema(description = "Application secret. The length must be at least 16 characters", requiredMode = Schema.RequiredMode.REQUIRED) @NotEmpty @Length(fieldName = "appSecret", min = 16, max = 2048, message = "must be at least 16 and max 2048 characters") @@ -75,7 +75,7 @@ public class MobileApp extends BaseData implements HasTenantId, Has super(mobile); this.tenantId = mobile.tenantId; this.pkgName = mobile.pkgName; - this.pkgTitle = mobile.pkgTitle; + this.title = mobile.title; this.appSecret = mobile.appSecret; this.platformType = mobile.platformType; this.status = mobile.status; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java index da1c2d3ca4..66b8842597 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java @@ -457,7 +457,7 @@ public class ModelConstants { */ public static final String MOBILE_APP_TABLE_NAME = "mobile_app"; public static final String MOBILE_APP_PKG_NAME_PROPERTY = "pkg_name"; - public static final String MOBILE_APP_PKG_TITLE_PROPERTY = "pkg_title"; + public static final String MOBILE_APP_TITLE_PROPERTY = "title"; public static final String MOBILE_APP_APP_SECRET_PROPERTY = "app_secret"; public static final String MOBILE_APP_PLATFORM_TYPE_PROPERTY = "platform_type"; public static final String MOBILE_APP_STATUS_PROPERTY = "status"; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/MobileAppEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/MobileAppEntity.java index 34d8869004..d9c22c6e9b 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/MobileAppEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/MobileAppEntity.java @@ -53,8 +53,8 @@ public class MobileAppEntity extends BaseSqlEntity { @Column(name = ModelConstants.MOBILE_APP_PKG_NAME_PROPERTY) private String pkgName; - @Column(name = ModelConstants.MOBILE_APP_PKG_TITLE_PROPERTY) - private String pkgTitle; + @Column(name = ModelConstants.MOBILE_APP_TITLE_PROPERTY) + private String title; @Column(name = ModelConstants.MOBILE_APP_APP_SECRET_PROPERTY) private String appSecret; @@ -85,7 +85,7 @@ public class MobileAppEntity extends BaseSqlEntity { this.tenantId = mobile.getTenantId().getId(); } this.pkgName = mobile.getPkgName(); - this.pkgTitle = mobile.getPkgTitle(); + this.title = mobile.getTitle(); this.appSecret = mobile.getAppSecret(); this.platformType = mobile.getPlatformType(); this.status = mobile.getStatus(); @@ -102,7 +102,7 @@ public class MobileAppEntity extends BaseSqlEntity { } mobile.setCreatedTime(createdTime); mobile.setPkgName(pkgName); - mobile.setPkgTitle(pkgTitle); + mobile.setTitle(title); mobile.setAppSecret(appSecret); mobile.setPlatformType(platformType); mobile.setStatus(status); diff --git a/dao/src/main/resources/sql/schema-entities.sql b/dao/src/main/resources/sql/schema-entities.sql index 6b3753e96d..0e30dde613 100644 --- a/dao/src/main/resources/sql/schema-entities.sql +++ b/dao/src/main/resources/sql/schema-entities.sql @@ -626,7 +626,7 @@ CREATE TABLE IF NOT EXISTS mobile_app ( created_time bigint NOT NULL, tenant_id uuid, pkg_name varchar(255), - pkg_title varchar(255), + title varchar(255), app_secret varchar(2048), platform_type varchar(32), status varchar(32), diff --git a/ui-ngx/src/app/modules/home/pages/mobile/applications/mobile-app-table-config.resolver.ts b/ui-ngx/src/app/modules/home/pages/mobile/applications/mobile-app-table-config.resolver.ts index 4508f97efc..6a05558905 100644 --- a/ui-ngx/src/app/modules/home/pages/mobile/applications/mobile-app-table-config.resolver.ts +++ b/ui-ngx/src/app/modules/home/pages/mobile/applications/mobile-app-table-config.resolver.ts @@ -83,7 +83,7 @@ export class MobileAppTableConfigResolver { onAction: (_$event, entity) => entity.pkgName, type: CellActionDescriptorType.COPY_BUTTON }), - new EntityTableColumn('pkgTitle', 'mobile.mobile-package-title', '20%'), + new EntityTableColumn('title', 'mobile.mobile-package-title', '20%'), new EntityTableColumn('appSecret', 'mobile.application-secret', '15%', (entity) => this.truncatePipe.transform(entity.appSecret, true, 10, '…'), () => ({}), true, () => ({}), () => undefined, false, diff --git a/ui-ngx/src/app/modules/home/pages/mobile/applications/mobile-app.component.html b/ui-ngx/src/app/modules/home/pages/mobile/applications/mobile-app.component.html index 7316f0a5d8..667da4927c 100644 --- a/ui-ngx/src/app/modules/home/pages/mobile/applications/mobile-app.component.html +++ b/ui-ngx/src/app/modules/home/pages/mobile/applications/mobile-app.component.html @@ -40,9 +40,9 @@ mobile.mobile-package-title - + - + {{ 'mobile.mobile-package-title-max-length' | translate }} diff --git a/ui-ngx/src/app/modules/home/pages/mobile/applications/mobile-app.component.ts b/ui-ngx/src/app/modules/home/pages/mobile/applications/mobile-app.component.ts index 592470f2b2..141c274422 100644 --- a/ui-ngx/src/app/modules/home/pages/mobile/applications/mobile-app.component.ts +++ b/ui-ngx/src/app/modules/home/pages/mobile/applications/mobile-app.component.ts @@ -65,7 +65,7 @@ export class MobileAppComponent extends EntityComponent { const form = this.fb.group({ pkgName: [entity?.pkgName ?? '', [Validators.required, Validators.maxLength(255), Validators.pattern(/^[a-zA-Z][a-zA-Z\d_]*(?:\.[a-zA-Z][a-zA-Z\d_]*)+$/)]], - pkgTitle: [entity?.pkgTitle ?? '', [Validators.maxLength(255)]], + title: [entity?.title ?? '', [Validators.maxLength(255)]], platformType: [entity?.platformType ?? PlatformType.ANDROID], appSecret: [entity?.appSecret ? entity.appSecret : btoa(randomAlphanumeric(64)), [Validators.required, this.base64Format]], status: [entity?.status ? entity.status : MobileAppStatus.DRAFT], diff --git a/ui-ngx/src/app/modules/home/pages/mobile/bundes/mobile-app-configuration-dialog.component.ts b/ui-ngx/src/app/modules/home/pages/mobile/bundes/mobile-app-configuration-dialog.component.ts index aefe7374f3..f11a556ff2 100644 --- a/ui-ngx/src/app/modules/home/pages/mobile/bundes/mobile-app-configuration-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/pages/mobile/bundes/mobile-app-configuration-dialog.component.ts @@ -23,6 +23,7 @@ import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { ActionPreferencesPutUserSettings } from '@core/auth/auth.actions'; import { MobileApp } from '@shared/models/mobile-app.models'; import { ImportExportService } from '@shared/import-export/import-export.service'; +import { isNotEmptyStr } from '@core/utils'; export interface MobileAppConfigurationDialogData { afterAdd: boolean; @@ -75,13 +76,13 @@ export class MobileAppConfigurationDialogComponent extends DialogComponent, HasTenantId { pkgName: string; - pkgTitle?: string; + title?: string; appSecret: string; platformType: PlatformType; status: MobileAppStatus; From 1f9351100b0e789b279aa579497df18380aee828 Mon Sep 17 00:00:00 2001 From: Viacheslav Klimov Date: Wed, 16 Jul 2025 13:14:26 +0300 Subject: [PATCH 4/5] Change mobile app title Swagger description --- .../thingsboard/server/common/data/mobile/app/MobileApp.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/mobile/app/MobileApp.java b/common/data/src/main/java/org/thingsboard/server/common/data/mobile/app/MobileApp.java index e05932e324..ef1580c0e3 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/mobile/app/MobileApp.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/mobile/app/MobileApp.java @@ -43,7 +43,7 @@ public class MobileApp extends BaseData implements HasTenantId, Has @NotBlank @Length(fieldName = "pkgName") private String pkgName; - @Schema(description = "Application package title") + @Schema(description = "Application title") @Length(fieldName = "title") private String title; @Schema(description = "Application secret. The length must be at least 16 characters", requiredMode = Schema.RequiredMode.REQUIRED) From d7d936af7650eda516f888e33c1e3461a2886fca Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Thu, 17 Jul 2025 11:13:18 +0300 Subject: [PATCH 5/5] UI: Fixed typo in mobile; Add app link constants --- .../mobile-app-configuration-dialog.component.ts | 14 ++++++++------ .../bundes/mobile-bundle-table-config.resolve.ts | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/ui-ngx/src/app/modules/home/pages/mobile/bundes/mobile-app-configuration-dialog.component.ts b/ui-ngx/src/app/modules/home/pages/mobile/bundes/mobile-app-configuration-dialog.component.ts index f11a556ff2..5644620b27 100644 --- a/ui-ngx/src/app/modules/home/pages/mobile/bundes/mobile-app-configuration-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/pages/mobile/bundes/mobile-app-configuration-dialog.component.ts @@ -21,7 +21,7 @@ import { AppState } from '@core/core.state'; import { Router } from '@angular/router'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { ActionPreferencesPutUserSettings } from '@core/auth/auth.actions'; -import { MobileApp } from '@shared/models/mobile-app.models'; +import { MobileApp, MobileAppBundleInfo } from '@shared/models/mobile-app.models'; import { ImportExportService } from '@shared/import-export/import-export.service'; import { isNotEmptyStr } from '@core/utils'; @@ -29,7 +29,7 @@ export interface MobileAppConfigurationDialogData { afterAdd: boolean; androidApp: MobileApp; iosApp: MobileApp; - bundleTitle: string; + bundle: MobileAppBundleInfo; } @Component({ @@ -72,18 +72,20 @@ export class MobileAppConfigurationDialogComponent extends DialogComponent