Merge pull request #12139 from vvlladd28/improvement/mobile-center/minor-bug
Fixed and imporvements mobile center
This commit is contained in:
		
						commit
						9bb2239938
					
				@ -114,6 +114,8 @@ export class MobileAppTableConfigResolver  {
 | 
			
		||||
    this.config.entitiesFetchFunction = pageLink => this.mobileAppService.getTenantMobileAppInfos(pageLink);
 | 
			
		||||
    this.config.loadEntity = id => this.mobileAppService.getMobileAppInfoById(id.id);
 | 
			
		||||
    this.config.saveEntity = (mobileApp) => this.mobileAppService.saveMobileApp(mobileApp);
 | 
			
		||||
    this.config.deleteEntityTitle = (mobileApp) => this.translate.instant('mobile.delete-application-title-short', {name: mobileApp.name});
 | 
			
		||||
    this.config.deleteEntityContent = () => this.translate.instant('mobile.delete-application-text-short');
 | 
			
		||||
    this.config.deleteEntity = id => this.mobileAppService.deleteMobileApp(id.id);
 | 
			
		||||
 | 
			
		||||
    this.config.cellActionDescriptors = this.configureCellActions();
 | 
			
		||||
@ -138,19 +140,23 @@ export class MobileAppTableConfigResolver  {
 | 
			
		||||
    if ($event) {
 | 
			
		||||
      $event.stopPropagation();
 | 
			
		||||
    }
 | 
			
		||||
    this.dialog.open<RemoveAppDialogComponent, MobileAppDeleteDialogData,
 | 
			
		||||
      MobileAppBundleInfo>(RemoveAppDialogComponent, {
 | 
			
		||||
      disableClose: true,
 | 
			
		||||
      panelClass: ['tb-dialog', 'tb-fullscreen-dialog'],
 | 
			
		||||
      data: {
 | 
			
		||||
        id: entity.id.id
 | 
			
		||||
      }
 | 
			
		||||
    }).afterClosed()
 | 
			
		||||
      .subscribe((res) => {
 | 
			
		||||
        if (res) {
 | 
			
		||||
          this.config.updateData();
 | 
			
		||||
    if(entity.status === MobileAppStatus.PUBLISHED) {
 | 
			
		||||
      this.dialog.open<RemoveAppDialogComponent, MobileAppDeleteDialogData,
 | 
			
		||||
        MobileAppBundleInfo>(RemoveAppDialogComponent, {
 | 
			
		||||
        disableClose: true,
 | 
			
		||||
        panelClass: ['tb-dialog', 'tb-fullscreen-dialog'],
 | 
			
		||||
        data: {
 | 
			
		||||
          id: entity.id.id
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
      }).afterClosed()
 | 
			
		||||
        .subscribe((res) => {
 | 
			
		||||
          if (res) {
 | 
			
		||||
            this.config.updateData();
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
    } else {
 | 
			
		||||
      this.config.getTable().deleteEntity($event, entity);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private mobileStatus(status: MobileAppStatus): string {
 | 
			
		||||
 | 
			
		||||
@ -148,7 +148,7 @@
 | 
			
		||||
      </mat-form-field>
 | 
			
		||||
      <mat-form-field appearance="outline" *ngIf="entityForm.get('platformType').value === PlatformType.ANDROID">
 | 
			
		||||
        <mat-label translate>mobile.sha256-certificate-fingerprints</mat-label>
 | 
			
		||||
        <input matInput [required]="entityForm.get('status').value === MobileAppStatus.PUBLISHED" formControlName="sha256CertFingerprints">
 | 
			
		||||
        <input matInput [required]="entityForm.get('status').value !== MobileAppStatus.DRAFT" formControlName="sha256CertFingerprints">
 | 
			
		||||
        <tb-copy-button
 | 
			
		||||
          matSuffix
 | 
			
		||||
          miniButton="false"
 | 
			
		||||
@ -166,7 +166,7 @@
 | 
			
		||||
      </mat-form-field>
 | 
			
		||||
      <mat-form-field appearance="outline" *ngIf="entityForm.get('platformType').value === PlatformType.IOS">
 | 
			
		||||
        <mat-label translate>mobile.app-id</mat-label>
 | 
			
		||||
        <input matInput [required]="entityForm.get('status').value === MobileAppStatus.PUBLISHED" formControlName="appId">
 | 
			
		||||
        <input matInput [required]="entityForm.get('status').value !== MobileAppStatus.DRAFT" formControlName="appId">
 | 
			
		||||
        <tb-copy-button
 | 
			
		||||
          matSuffix
 | 
			
		||||
          miniButton="false"
 | 
			
		||||
 | 
			
		||||
@ -79,7 +79,7 @@ export class MobileAppComponent extends EntityComponent<MobileApp> {
 | 
			
		||||
          Validators.pattern(/^https?:\/\/play\.google\.com\/store\/apps\/details\?id=[a-zA-Z0-9._]+$/)],
 | 
			
		||||
        sha256CertFingerprints: [entity?.storeInfo?.sha256CertFingerprints ? entity.storeInfo.sha256CertFingerprints : '',
 | 
			
		||||
          Validators.pattern(/^[A-Fa-f0-9]{2}(:[A-Fa-f0-9]{2}){1,31}$/)],
 | 
			
		||||
        appId: [entity?.storeInfo?.appId ? entity.storeInfo.appId : '', Validators.pattern(/^\d{7,10}$/)],
 | 
			
		||||
        appId: [entity?.storeInfo?.appId ? entity.storeInfo.appId : '', Validators.pattern(/^[A-Z0-9]{10}\.[a-zA-Z0-9]+(\.[a-zA-Z0-9]+)*$/)],
 | 
			
		||||
      }),
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
@ -126,7 +126,8 @@ export class MobileAppComponent extends EntityComponent<MobileApp> {
 | 
			
		||||
  override updateFormState(): void {
 | 
			
		||||
    super.updateFormState();
 | 
			
		||||
    if (this.isEdit && this.entityForm && !this.isAdd) {
 | 
			
		||||
      this.entityForm.get('status').updateValueAndValidity({onlySelf: false});
 | 
			
		||||
      this.entityForm.get('status').updateValueAndValidity({onlySelf: true});
 | 
			
		||||
      this.entityForm.get('platformType').updateValueAndValidity({onlySelf: true});
 | 
			
		||||
      this.entityForm.get('platformType').disable({emitEvent: false});
 | 
			
		||||
      if (this.entityForm.get('platformType').value === PlatformType.ANDROID) {
 | 
			
		||||
        this.entityForm.get('storeInfo.appId').disable({emitEvent: false});
 | 
			
		||||
 | 
			
		||||
@ -36,7 +36,7 @@
 | 
			
		||||
  <button mat-button color="primary"
 | 
			
		||||
          type="button"
 | 
			
		||||
          [disabled]="(isLoading$ | async)"
 | 
			
		||||
          (click)="cancel()" cdkFocusInitial>
 | 
			
		||||
          (click)="suspend()" cdkFocusInitial>
 | 
			
		||||
    {{ 'action.suspend' | translate }}
 | 
			
		||||
  </button>
 | 
			
		||||
  <button mat-button mat-raised-button color="warn"
 | 
			
		||||
 | 
			
		||||
@ -24,6 +24,8 @@ import { TranslateService } from '@ngx-translate/core';
 | 
			
		||||
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
 | 
			
		||||
import { FormBuilder } from '@angular/forms';
 | 
			
		||||
import { MobileAppService } from '@core/http/mobile-app.service';
 | 
			
		||||
import { mergeMap } from 'rxjs';
 | 
			
		||||
import { MobileAppStatus } from '@shared/models/mobile-app.models';
 | 
			
		||||
 | 
			
		||||
export interface MobileAppDeleteDialogData {
 | 
			
		||||
  id: string;
 | 
			
		||||
@ -60,6 +62,17 @@ export class RemoveAppDialogComponent extends DialogComponent<RemoveAppDialogCom
 | 
			
		||||
    this.dialogRef.close(false);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  suspend(): void {
 | 
			
		||||
    this.mobileAppService.getMobileAppInfoById(this.data.id).pipe(
 | 
			
		||||
      mergeMap(value => {
 | 
			
		||||
        value.status = MobileAppStatus.SUSPENDED;
 | 
			
		||||
        return this.mobileAppService.saveMobileApp(value)
 | 
			
		||||
      })
 | 
			
		||||
    ).subscribe(() => {
 | 
			
		||||
      this.dialogRef.close(true);
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  delete(): void {
 | 
			
		||||
    this.mobileAppService.deleteMobileApp(this.data.id).subscribe(() => {
 | 
			
		||||
      this.dialogRef.close(true);
 | 
			
		||||
 | 
			
		||||
@ -62,7 +62,7 @@ export class CustomMobilePageComponent implements ControlValueAccessor, Validato
 | 
			
		||||
    icon: ['star'],
 | 
			
		||||
    label: ['', Validators.required],
 | 
			
		||||
    type: [MobilePageType.DASHBOARD],
 | 
			
		||||
    dashboardId: ['', Validators.required],
 | 
			
		||||
    dashboardId: this.fb.control<string>(null, Validators.required),
 | 
			
		||||
    url: [{value:'', disabled: true}, [Validators.required, Validators.pattern(/^(https?:\/\/)?(localhost|([\w\-]+\.)+[\w\-]+)(:\d+)?(\/[\w\-._~:\/?#[\]@!$&'()*+,;=%]*)?$/)]],
 | 
			
		||||
    path: [{value:'', disabled: true}, [Validators.required, Validators.pattern(/^(\/[\w\-._~:\/?#[\]@!$&'()*+,;=%]*)?$/)]]
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@ -51,6 +51,16 @@
 | 
			
		||||
    <tb-markdown usePlainMarkdown containerClass="tb-command-code"
 | 
			
		||||
                 [data]=createMarkDownCommand(configureApi)></tb-markdown>
 | 
			
		||||
  </div>
 | 
			
		||||
  <div class="tb-form-panel stroked" *ngIf="setApplication">
 | 
			
		||||
    <div class="tb-form-panel-title" translate>mobile.configuration-step.configure-package-title</div>
 | 
			
		||||
    <div translate>mobile.configuration-step.configure-package-text</div>
 | 
			
		||||
    <div translate>mobile.configuration-step.configure-package-text-install</div>
 | 
			
		||||
    <tb-markdown usePlainMarkdown containerClass="tb-command-code"
 | 
			
		||||
                 [data]=createMarkDownCommand(flutterInstallRenameCommand)></tb-markdown>
 | 
			
		||||
    <div translate>mobile.configuration-step.configure-package-run-commands</div>
 | 
			
		||||
    <tb-markdown usePlainMarkdown containerClass="tb-command-code"
 | 
			
		||||
                 [data]=createMarkDownCommand(renameCommands)></tb-markdown>
 | 
			
		||||
  </div>
 | 
			
		||||
  <div class="tb-form-panel stroked">
 | 
			
		||||
    <div class="tb-form-panel-title" translate>mobile.configuration-step.run-app-title</div>
 | 
			
		||||
    <div translate>mobile.configuration-step.run-app-text</div>
 | 
			
		||||
@ -62,7 +72,7 @@
 | 
			
		||||
      <div class="flex-1" translate>mobile.configuration-step.more-information</div>
 | 
			
		||||
      <a mat-stroked-button
 | 
			
		||||
         color="primary"
 | 
			
		||||
         href="https://docs.flutter.dev/get-started/install"
 | 
			
		||||
         href="https://docs.flutter.dev/learn-flutter"
 | 
			
		||||
         target="_blank">
 | 
			
		||||
        <mat-icon class="tb-mat-24">rocket_launch</mat-icon>{{ 'mobile.configuration-step.getting-started' | translate }}
 | 
			
		||||
      </a>
 | 
			
		||||
 | 
			
		||||
@ -40,7 +40,8 @@
 | 
			
		||||
          background: #F3F6FA;
 | 
			
		||||
          border-color: $tb-primary-color;
 | 
			
		||||
          padding-right: 38px;
 | 
			
		||||
          overflow: scroll;
 | 
			
		||||
          overflow: hidden;
 | 
			
		||||
          overflow-x: auto;
 | 
			
		||||
          padding-bottom: 4px;
 | 
			
		||||
          min-height: 42px;
 | 
			
		||||
          scrollbar-width: thin;
 | 
			
		||||
@ -51,7 +52,7 @@
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      button.clipboard-btn {
 | 
			
		||||
      button.clipboard-btn, button.clipboard-btn.multiline {
 | 
			
		||||
        right: -2px;
 | 
			
		||||
        p {
 | 
			
		||||
          color: $tb-primary-color;
 | 
			
		||||
@ -70,8 +71,8 @@
 | 
			
		||||
            width: 18px;
 | 
			
		||||
            height: 18px;
 | 
			
		||||
            background: $tb-primary-color;
 | 
			
		||||
            mask-image: url(/src/assets/copy-code-icon.svg);
 | 
			
		||||
            -webkit-mask-image: url(/src/assets/copy-code-icon.svg);
 | 
			
		||||
            mask-image: url(/assets/copy-code-icon.svg);
 | 
			
		||||
            -webkit-mask-image: url(/assets/copy-code-icon.svg);
 | 
			
		||||
            mask-repeat: no-repeat;
 | 
			
		||||
            -webkit-mask-repeat: no-repeat;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
@ -21,10 +21,12 @@ 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';
 | 
			
		||||
 | 
			
		||||
export interface MobileAppConfigurationDialogData {
 | 
			
		||||
  afterAdd: boolean;
 | 
			
		||||
  appSecret: string;
 | 
			
		||||
  androidApp: MobileApp;
 | 
			
		||||
  iosApp: MobileApp;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
@ -35,14 +37,18 @@ export interface MobileAppConfigurationDialogData {
 | 
			
		||||
export class MobileAppConfigurationDialogComponent extends DialogComponent<MobileAppConfigurationDialogComponent> {
 | 
			
		||||
 | 
			
		||||
  notShowAgain = false;
 | 
			
		||||
  setApplication = 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[] = [];
 | 
			
		||||
  configureApi: string;
 | 
			
		||||
 | 
			
		||||
  renameCommands: string[] = [];
 | 
			
		||||
 | 
			
		||||
  constructor(protected store: Store<AppState>,
 | 
			
		||||
              protected router: Router,
 | 
			
		||||
@ -53,8 +59,30 @@ export class MobileAppConfigurationDialogComponent extends DialogComponent<Mobil
 | 
			
		||||
 | 
			
		||||
    this.showDontShowAgain = this.data.afterAdd;
 | 
			
		||||
 | 
			
		||||
    this.configureApi.push(`static const thingsBoardApiEndpoint = '${window.location.origin}';`);
 | 
			
		||||
    this.configureApi.push(`static const thingsboardOAuth2AppSecret = '${this.data.appSecret}';`);
 | 
			
		||||
    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 {
 | 
			
		||||
 | 
			
		||||
@ -188,7 +188,8 @@ export class MobileBundleTableConfigResolver {
 | 
			
		||||
        panelClass: ['tb-dialog', 'tb-fullscreen-dialog'],
 | 
			
		||||
        data: {
 | 
			
		||||
          afterAdd,
 | 
			
		||||
          appSecret: data.androidApp?.appSecret || data.iosApp?.appSecret
 | 
			
		||||
          androidApp: data.androidApp,
 | 
			
		||||
          iosApp: data.iosApp
 | 
			
		||||
        }
 | 
			
		||||
      }).afterClosed()
 | 
			
		||||
        .subscribe(() => {
 | 
			
		||||
 | 
			
		||||
@ -28,6 +28,7 @@
 | 
			
		||||
    <button mat-raised-button
 | 
			
		||||
            color="primary"
 | 
			
		||||
            type="button"
 | 
			
		||||
            *ngIf="!disabled"
 | 
			
		||||
            (click)="apply()"
 | 
			
		||||
            [disabled]="editorControl.invalid || !editorControl.dirty">
 | 
			
		||||
      {{ 'action.apply' | translate }}
 | 
			
		||||
 | 
			
		||||
@ -54,7 +54,8 @@ export class EditorPanelComponent implements OnInit {
 | 
			
		||||
    height: 400,
 | 
			
		||||
    autofocus: false,
 | 
			
		||||
    branding: false,
 | 
			
		||||
    promotion: false
 | 
			
		||||
    promotion: false,
 | 
			
		||||
    resize: false
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  constructor(private fb: FormBuilder) {
 | 
			
		||||
@ -64,6 +65,9 @@ export class EditorPanelComponent implements OnInit {
 | 
			
		||||
    this.editorControl = this.fb.control(this.content);
 | 
			
		||||
    if (this.disabled) {
 | 
			
		||||
      this.editorControl.disable({emitEvent: false});
 | 
			
		||||
      this.tinyMceOptions.toolbar = false;
 | 
			
		||||
      this.tinyMceOptions.menubar = false;
 | 
			
		||||
      this.tinyMceOptions.statusbar = false;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -3443,6 +3443,8 @@
 | 
			
		||||
        "delete-application": "Delete application",
 | 
			
		||||
        "delete-application-button-text": "I understand consequences, delete application",
 | 
			
		||||
        "delete-application-text": "This action can not be undone. This will permanently delete your application.<br/>If you don’t want to delete it permanently you can <b>suspend</b> application temporary.<br/><b>To delete</b> the application anyway please type <b>\"{{phrase}}\"</b> to confirm.",
 | 
			
		||||
        "delete-application-title-short": "Are you sure you want to delete the application '{{name}}'?",
 | 
			
		||||
        "delete-application-text-short": "Be careful, after the confirmation the applications and all related data will become unrecoverable.",
 | 
			
		||||
        "delete-application-phrase": "delete application",
 | 
			
		||||
        "delete-applications-bundle-text": "Be careful, after the confirmation the mobile bundle and all related data will become unrecoverable.",
 | 
			
		||||
        "delete-applications-bundle-title": "Are you sure you want to delete the mobile bundle '{{bundleName}}'?",
 | 
			
		||||
@ -3542,7 +3544,11 @@
 | 
			
		||||
            "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"
 | 
			
		||||
            "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:"
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    "notification": {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user