Browse Source

UI: Chang order mobile center pagss; Add validation in mobile app fields; Add mobile layout show hidden pages; Move config to bundle

pull/11835/head
Vladyslav_Prykhodko 2 years ago
parent
commit
5fc412d728
  1. 6
      ui-ngx/src/app/core/services/menu.models.ts
  2. 4
      ui-ngx/src/app/modules/home/pages/mobile/applications/applications.module.ts
  3. 54
      ui-ngx/src/app/modules/home/pages/mobile/applications/mobile-app-table-config.resolver.ts
  4. 23
      ui-ngx/src/app/modules/home/pages/mobile/applications/mobile-app.component.html
  5. 23
      ui-ngx/src/app/modules/home/pages/mobile/applications/mobile-app.component.ts
  6. 5
      ui-ngx/src/app/modules/home/pages/mobile/bundes/bundles.module.ts
  7. 1
      ui-ngx/src/app/modules/home/pages/mobile/bundes/layout/mobile-layout.component.html
  8. 13
      ui-ngx/src/app/modules/home/pages/mobile/bundes/layout/mobile-layout.component.ts
  9. 0
      ui-ngx/src/app/modules/home/pages/mobile/bundes/mobile-app-configuration-dialog.component.html
  10. 4
      ui-ngx/src/app/modules/home/pages/mobile/bundes/mobile-app-configuration-dialog.component.scss
  11. 2
      ui-ngx/src/app/modules/home/pages/mobile/bundes/mobile-app-configuration-dialog.component.ts
  12. 63
      ui-ngx/src/app/modules/home/pages/mobile/bundes/mobile-bundle-table-config.resolve.ts
  13. 2
      ui-ngx/src/app/modules/home/pages/mobile/mobile-routing.module.ts
  14. 2
      ui-ngx/src/app/shared/models/user-settings.models.ts
  15. 7
      ui-ngx/src/assets/locale/locale.constant-en_US.json

6
ui-ngx/src/app/core/services/menu.models.ts

@ -723,8 +723,8 @@ const defaultUserMenuMap = new Map<Authority, MenuReference[]>([
{ {
id: MenuId.mobile_center, id: MenuId.mobile_center,
pages: [ pages: [
{id: MenuId.mobile_apps},
{id: MenuId.mobile_bundles}, {id: MenuId.mobile_bundles},
{id: MenuId.mobile_apps},
{id: MenuId.mobile_qr_code_widget} {id: MenuId.mobile_qr_code_widget}
] ]
}, },
@ -819,8 +819,8 @@ const defaultUserMenuMap = new Map<Authority, MenuReference[]>([
{ {
id: MenuId.mobile_center, id: MenuId.mobile_center,
pages: [ pages: [
{id: MenuId.mobile_apps}, {id: MenuId.mobile_bundles},
{id: MenuId.mobile_bundles} {id: MenuId.mobile_apps}
] ]
}, },
{id: MenuId.api_usage}, {id: MenuId.api_usage},

4
ui-ngx/src/app/modules/home/pages/mobile/applications/applications.module.ts

@ -23,9 +23,6 @@ import { HomeComponentsModule } from '@home/components/home-components.module';
import { ApplicationsRoutingModule } from '@home/pages/mobile/applications/applications-routing.module'; import { ApplicationsRoutingModule } from '@home/pages/mobile/applications/applications-routing.module';
import { MobileAppDialogComponent } from '@home/pages/mobile/applications/mobile-app-dialog.component'; import { MobileAppDialogComponent } from '@home/pages/mobile/applications/mobile-app-dialog.component';
import { RemoveAppDialogComponent } from '@home/pages/mobile/applications/remove-app-dialog.component'; import { RemoveAppDialogComponent } from '@home/pages/mobile/applications/remove-app-dialog.component';
import {
MobileAppConfigurationDialogComponent
} from '@home/pages/mobile/applications/mobile-app-configuration-dialog.component';
import { CommonMobileModule } from '@home/pages/mobile/common/common-mobile.module'; import { CommonMobileModule } from '@home/pages/mobile/common/common-mobile.module';
@NgModule({ @NgModule({
@ -34,7 +31,6 @@ import { CommonMobileModule } from '@home/pages/mobile/common/common-mobile.modu
MobileAppTableHeaderComponent, MobileAppTableHeaderComponent,
MobileAppDialogComponent, MobileAppDialogComponent,
RemoveAppDialogComponent, RemoveAppDialogComponent,
MobileAppConfigurationDialogComponent,
], ],
imports: [ imports: [
CommonModule, CommonModule,

54
ui-ngx/src/app/modules/home/pages/mobile/applications/mobile-app-table-config.resolver.ts

@ -38,24 +38,11 @@ import {
} from '@shared/models/mobile-app.models'; } from '@shared/models/mobile-app.models';
import { platformTypeTranslations } from '@shared/models/oauth2.models'; import { platformTypeTranslations } from '@shared/models/oauth2.models';
import { TruncatePipe } from '@shared/pipe/truncate.pipe'; import { TruncatePipe } from '@shared/pipe/truncate.pipe';
import { NotificationTemplate } from '@shared/models/notification.models';
import { BaseData, HasId } from '@shared/models/base-data';
import {
MobileBundleDialogComponent,
MobileBundleDialogData
} from '@home/pages/mobile/bundes/mobile-bundle-dialog.component';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
import { import {
MobileAppDeleteDialogData, MobileAppDeleteDialogData,
RemoveAppDialogComponent RemoveAppDialogComponent
} from '@home/pages/mobile/applications/remove-app-dialog.component'; } from '@home/pages/mobile/applications/remove-app-dialog.component';
import {
MobileAppConfigurationDialogComponent, MobileAppConfigurationDialogData
} from '@home/pages/mobile/applications/mobile-app-configuration-dialog.component';
import { select, Store } from '@ngrx/store';
import { selectUserSettingsProperty } from '@core/auth/auth.selectors';
import { take } from 'rxjs/operators';
import { AppState } from '@core/core.state';
@Injectable() @Injectable()
export class MobileAppTableConfigResolver { export class MobileAppTableConfigResolver {
@ -66,8 +53,7 @@ export class MobileAppTableConfigResolver {
private datePipe: DatePipe, private datePipe: DatePipe,
private mobileAppService: MobileAppService, private mobileAppService: MobileAppService,
private truncatePipe: TruncatePipe, private truncatePipe: TruncatePipe,
private dialog: MatDialog, private dialog: MatDialog
private store: Store<AppState>,
) { ) {
this.config.selectionEnabled = false; this.config.selectionEnabled = false;
this.config.entityType = EntityType.MOBILE_APP; this.config.entityType = EntityType.MOBILE_APP;
@ -130,18 +116,6 @@ export class MobileAppTableConfigResolver {
this.config.saveEntity = (mobileApp) => this.mobileAppService.saveMobileApp(mobileApp); this.config.saveEntity = (mobileApp) => this.mobileAppService.saveMobileApp(mobileApp);
this.config.deleteEntity = id => this.mobileAppService.deleteMobileApp(id.id); this.config.deleteEntity = id => this.mobileAppService.deleteMobileApp(id.id);
this.config.entityAdded = (mobileApp) => {
this.store.pipe(select(selectUserSettingsProperty( 'notDisplayConfigurationAfterAddMobileApp'))).pipe(
take(1)
).subscribe((settings: boolean) => {
if(!settings) {
this.configurationApp(null, mobileApp, true);
} else {
this.config.updateData();
}
});
}
this.config.cellActionDescriptors = this.configureCellActions(); this.config.cellActionDescriptors = this.configureCellActions();
} }
@ -151,12 +125,6 @@ export class MobileAppTableConfigResolver {
private configureCellActions(): Array<CellActionDescriptor<MobileApp>> { private configureCellActions(): Array<CellActionDescriptor<MobileApp>> {
return [ return [
{
name: this.translate.instant('mobile.configuration-app'),
icon: 'code',
isEnabled: () => true,
onAction: ($event, entity) => this.configurationApp($event, entity)
},
{ {
name: this.translate.instant('action.delete'), name: this.translate.instant('action.delete'),
icon: 'delete', icon: 'delete',
@ -185,26 +153,6 @@ export class MobileAppTableConfigResolver {
}); });
} }
private configurationApp($event: Event, entity: MobileApp, afterAdd = false) {
if ($event) {
$event.stopPropagation();
}
this.dialog.open<MobileAppConfigurationDialogComponent, MobileAppConfigurationDialogData,
MobileAppBundleInfo>(MobileAppConfigurationDialogComponent, {
disableClose: true,
panelClass: ['tb-dialog', 'tb-fullscreen-dialog'],
data: {
afterAdd,
appSecret: entity.appSecret
}
}).afterClosed()
.subscribe(() => {
if (afterAdd) {
this.config.updateData();
}
});
}
private mobileStatus(status: MobileAppStatus): string { private mobileStatus(status: MobileAppStatus): string {
const translateKey = mobileAppStatusTranslations.get(status); const translateKey = mobileAppStatusTranslations.get(status);
let backgroundColor = 'rgba(25, 128, 56, 0.06)'; let backgroundColor = 'rgba(25, 128, 56, 0.06)';

23
ui-ngx/src/app/modules/home/pages/mobile/applications/mobile-app.component.html

@ -35,7 +35,7 @@
{{ 'mobile.mobile-package-max-length' | translate }} {{ 'mobile.mobile-package-max-length' | translate }}
</mat-error> </mat-error>
<mat-error *ngIf="entityForm.get('pkgName').hasError('pattern')"> <mat-error *ngIf="entityForm.get('pkgName').hasError('pattern')">
{{ 'mobile.mobile-package-spaces' | translate }} {{ 'mobile.mobile-package-pattern' | translate }}
</mat-error> </mat-error>
</mat-form-field> </mat-form-field>
<mat-form-field appearance="outline" class="flex"> <mat-form-field appearance="outline" class="flex">
@ -84,9 +84,13 @@
<div class="tb-form-panel-title" translate>mobile.version-information</div> <div class="tb-form-panel-title" translate>mobile.version-information</div>
<section class="flex flex-col"> <section class="flex flex-col">
<section class="flex flex-row"> <section class="flex flex-row">
<mat-form-field class="flex-1" appearance="outline"> <mat-form-field class="flex-1" appearance="outline" subscriptSizing="dynamic">
<mat-label translate>mobile.min-version</mat-label> <mat-label translate>mobile.min-version</mat-label>
<input matInput formControlName="minVersion"> <input matInput formControlName="minVersion">
<mat-hint> </mat-hint>
<mat-error *ngIf="entityForm.get('versionInfo.minVersion').hasError('pattern')">
{{ 'mobile.invalid-version-pattern' | translate }}
</mat-error>
</mat-form-field> </mat-form-field>
<button mat-icon-button <button mat-icon-button
style="margin-top: 4px; color:#00000061" style="margin-top: 4px; color:#00000061"
@ -99,9 +103,13 @@
</button> </button>
</section> </section>
<section class="flex flex-row"> <section class="flex flex-row">
<mat-form-field class="flex-1" appearance="outline"> <mat-form-field class="flex-1" appearance="outline" subscriptSizing="dynamic">
<mat-label translate>mobile.latest-version</mat-label> <mat-label translate>mobile.latest-version</mat-label>
<input matInput formControlName="latestVersion"> <input matInput formControlName="latestVersion">
<mat-hint> </mat-hint>
<mat-error *ngIf="entityForm.get('versionInfo.minVersion').hasError('pattern')">
{{ 'mobile.invalid-version-pattern' | translate }}
</mat-error>
</mat-form-field> </mat-form-field>
<button mat-icon-button <button mat-icon-button
style="margin-top: 4px; color:#00000061" style="margin-top: 4px; color:#00000061"
@ -134,6 +142,9 @@
<mat-error *ngIf="entityForm.get('storeInfo.storeLink').hasError('required')"> <mat-error *ngIf="entityForm.get('storeInfo.storeLink').hasError('required')">
{{ (entityForm.get('platformType').value === PlatformType.ANDROID ? 'mobile.google-play-link-required' : 'mobile.app-store-link-required') | translate }} {{ (entityForm.get('platformType').value === PlatformType.ANDROID ? 'mobile.google-play-link-required' : 'mobile.app-store-link-required') | translate }}
</mat-error> </mat-error>
<mat-error *ngIf="entityForm.get('storeInfo.storeLink').hasError('pattern')">
{{ 'mobile.invalid-store-link' | translate }}
</mat-error>
</mat-form-field> </mat-form-field>
<mat-form-field appearance="outline" *ngIf="entityForm.get('platformType').value === PlatformType.ANDROID"> <mat-form-field appearance="outline" *ngIf="entityForm.get('platformType').value === PlatformType.ANDROID">
<mat-label translate>mobile.sha256-certificate-fingerprints</mat-label> <mat-label translate>mobile.sha256-certificate-fingerprints</mat-label>
@ -149,6 +160,9 @@
<mat-error *ngIf="entityForm.get('storeInfo.sha256CertFingerprints').hasError('required')"> <mat-error *ngIf="entityForm.get('storeInfo.sha256CertFingerprints').hasError('required')">
{{ 'mobile.sha256-certificate-fingerprints-required' | translate }} {{ 'mobile.sha256-certificate-fingerprints-required' | translate }}
</mat-error> </mat-error>
<mat-error *ngIf="entityForm.get('storeInfo.sha256CertFingerprints').hasError('pattern')">
{{ 'mobile.sha256-certificate-fingerprints-pattern' | translate }}
</mat-error>
</mat-form-field> </mat-form-field>
<mat-form-field appearance="outline" *ngIf="entityForm.get('platformType').value === PlatformType.IOS"> <mat-form-field appearance="outline" *ngIf="entityForm.get('platformType').value === PlatformType.IOS">
<mat-label translate>mobile.app-id</mat-label> <mat-label translate>mobile.app-id</mat-label>
@ -164,6 +178,9 @@
<mat-error *ngIf="entityForm.get('storeInfo.appId').hasError('required')"> <mat-error *ngIf="entityForm.get('storeInfo.appId').hasError('required')">
{{ 'mobile.app-id-required' | translate }} {{ 'mobile.app-id-required' | translate }}
</mat-error> </mat-error>
<mat-error *ngIf="entityForm.get('storeInfo.appId').hasError('pattern')">
{{ 'mobile.app-id-pattern' | translate }}
</mat-error>
</mat-form-field> </mat-form-field>
</section> </section>
</section> </section>

23
ui-ngx/src/app/modules/home/pages/mobile/applications/mobile-app.component.ts

@ -64,20 +64,22 @@ export class MobileAppComponent extends EntityComponent<MobileApp> {
buildForm(entity: MobileApp): FormGroup { buildForm(entity: MobileApp): FormGroup {
const form = this.fb.group({ const form = this.fb.group({
pkgName: [entity?.pkgName ? entity.pkgName : '', [Validators.required, Validators.maxLength(255), pkgName: [entity?.pkgName ? entity.pkgName : '', [Validators.required, Validators.maxLength(255),
Validators.pattern(/^\S+$/)]], Validators.pattern(/^[a-zA-Z][a-zA-Z\d_]*(?:\.[a-zA-Z][a-zA-Z\d_]*)+$/)]],
platformType: [entity?.platformType ? entity.platformType : PlatformType.ANDROID], platformType: [entity?.platformType ? entity.platformType : PlatformType.ANDROID],
appSecret: [entity?.appSecret ? entity.appSecret : btoa(randomAlphanumeric(64)), [Validators.required, this.base64Format]], appSecret: [entity?.appSecret ? entity.appSecret : btoa(randomAlphanumeric(64)), [Validators.required, this.base64Format]],
status: [entity?.status ? entity.status : MobileAppStatus.DRAFT], status: [entity?.status ? entity.status : MobileAppStatus.DRAFT],
versionInfo: this.fb.group({ versionInfo: this.fb.group({
minVersion: [entity?.versionInfo?.minVersion ? entity.versionInfo.minVersion : ''], minVersion: [entity?.versionInfo?.minVersion ? entity.versionInfo.minVersion : '', Validators.pattern(/^\d+\.\d+\.\d+(-[a-zA-Z\d-.]+)?(\+[a-zA-Z\d-.]+)?$/)],
minVersionReleaseNotes: [entity?.versionInfo?.minVersionReleaseNotes ? entity.versionInfo.minVersionReleaseNotes : ''], minVersionReleaseNotes: [entity?.versionInfo?.minVersionReleaseNotes ? entity.versionInfo.minVersionReleaseNotes : ''],
latestVersion: [entity?.versionInfo?.latestVersion ? entity.versionInfo.latestVersion : ''], latestVersion: [entity?.versionInfo?.latestVersion ? entity.versionInfo.latestVersion : '', Validators.pattern(/^\d+\.\d+\.\d+(-[a-zA-Z\d-.]+)?(\+[a-zA-Z\d-.]+)?$/)],
latestVersionReleaseNotes: [entity?.versionInfo?.latestVersionReleaseNotes ? entity.versionInfo.latestVersionReleaseNotes : ''], latestVersionReleaseNotes: [entity?.versionInfo?.latestVersionReleaseNotes ? entity.versionInfo.latestVersionReleaseNotes : ''],
}), }),
storeInfo: this.fb.group({ storeInfo: this.fb.group({
storeLink: [entity?.storeInfo?.storeLink ? entity.storeInfo.storeLink : ''], storeLink: [entity?.storeInfo?.storeLink ? entity.storeInfo.storeLink : '',
sha256CertFingerprints: [entity?.storeInfo?.sha256CertFingerprints ? entity.storeInfo.sha256CertFingerprints : ''], Validators.pattern(/^https?:\/\/play\.google\.com\/store\/apps\/details\?id=[a-zA-Z0-9._]+$/)],
appId: [entity?.storeInfo?.appId ? entity.storeInfo.appId : ''], 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}$/)],
}), }),
}); });
@ -87,9 +89,11 @@ export class MobileAppComponent extends EntityComponent<MobileApp> {
if (value === PlatformType.ANDROID) { if (value === PlatformType.ANDROID) {
form.get('storeInfo.sha256CertFingerprints').enable({emitEvent: false}); form.get('storeInfo.sha256CertFingerprints').enable({emitEvent: false});
form.get('storeInfo.appId').disable({emitEvent: false}); form.get('storeInfo.appId').disable({emitEvent: false});
form.get('storeInfo.storeLink').setValidators(Validators.pattern(/^https?:\/\/play\.google\.com\/store\/apps\/details\?id=[a-zA-Z0-9._]+$/));
} else if (value === PlatformType.IOS) { } else if (value === PlatformType.IOS) {
form.get('storeInfo.sha256CertFingerprints').disable({emitEvent: false}); form.get('storeInfo.sha256CertFingerprints').disable({emitEvent: false});
form.get('storeInfo.appId').enable({emitEvent: false}); form.get('storeInfo.appId').enable({emitEvent: false});
form.get('storeInfo.storeLink').setValidators(Validators.pattern(/^https?:\/\/apps\.apple\.com\/[a-z]{2}\/app\/[\w-]+\/id\d{7,10}$/));
} }
form.get('storeInfo.storeLink').setValue('', {emitEvent: false}); form.get('storeInfo.storeLink').setValue('', {emitEvent: false});
}); });
@ -99,12 +103,13 @@ export class MobileAppComponent extends EntityComponent<MobileApp> {
).subscribe((value: MobileAppStatus) => { ).subscribe((value: MobileAppStatus) => {
if (value !== MobileAppStatus.DRAFT) { if (value !== MobileAppStatus.DRAFT) {
form.get('storeInfo.storeLink').addValidators(Validators.required); form.get('storeInfo.storeLink').addValidators(Validators.required);
form.get('storeInfo.sha256CertFingerprints').addValidators(Validators.required); form.get('storeInfo.sha256CertFingerprints')
.addValidators(Validators.required);
form.get('storeInfo.appId').addValidators(Validators.required); form.get('storeInfo.appId').addValidators(Validators.required);
} else { } else {
form.get('storeInfo.storeLink').clearValidators(); form.get('storeInfo.storeLink').clearValidators();
form.get('storeInfo.sha256CertFingerprints').clearValidators(); form.get('storeInfo.sha256CertFingerprints').removeValidators(Validators.required);
form.get('storeInfo.appId').clearValidators(); form.get('storeInfo.appId').removeValidators(Validators.required);
} }
form.get('storeInfo.storeLink').updateValueAndValidity({emitEvent: false}); form.get('storeInfo.storeLink').updateValueAndValidity({emitEvent: false});
form.get('storeInfo.sha256CertFingerprints').updateValueAndValidity({emitEvent: false}); form.get('storeInfo.sha256CertFingerprints').updateValueAndValidity({emitEvent: false});

5
ui-ngx/src/app/modules/home/pages/mobile/bundes/bundles.module.ts

@ -27,6 +27,10 @@ import { AddMobilePageDialogComponent } from '@home/pages/mobile/bundes/layout/a
import { CustomMobilePageComponent } from '@home/pages/mobile/bundes/layout/custom-mobile-page.component'; import { CustomMobilePageComponent } from '@home/pages/mobile/bundes/layout/custom-mobile-page.component';
import { CustomMobilePagePanelComponent } from '@home/pages/mobile/bundes/layout/custom-mobile-page-panel.component'; import { CustomMobilePagePanelComponent } from '@home/pages/mobile/bundes/layout/custom-mobile-page-panel.component';
import { DefaultMobilePagePanelComponent } from '@home/pages/mobile/bundes/layout/default-mobile-page-panel.component'; import { DefaultMobilePagePanelComponent } from '@home/pages/mobile/bundes/layout/default-mobile-page-panel.component';
import {
MobileAppConfigurationDialogComponent
} from '@home/pages/mobile/bundes/mobile-app-configuration-dialog.component';
@NgModule({ @NgModule({
declarations: [ declarations: [
@ -38,6 +42,7 @@ import { DefaultMobilePagePanelComponent } from '@home/pages/mobile/bundes/layou
CustomMobilePageComponent, CustomMobilePageComponent,
CustomMobilePagePanelComponent, CustomMobilePagePanelComponent,
DefaultMobilePagePanelComponent, DefaultMobilePagePanelComponent,
MobileAppConfigurationDialogComponent,
], ],
imports: [ imports: [
CommonModule, CommonModule,

1
ui-ngx/src/app/modules/home/pages/mobile/bundes/layout/mobile-layout.component.html

@ -19,6 +19,7 @@
<div class="header flex items-center gap-2"> <div class="header flex items-center gap-2">
<div class="title-section"> <div class="title-section">
<span tbTruncateWithTooltip class="title-container" translate>mobile.pages</span> <span tbTruncateWithTooltip class="title-container" translate>mobile.pages</span>
<mat-slide-toggle class="whitespace-nowrap xs:!hidden" [formControl]="showHiddenPages">{{ 'mobile.show-hidden-pages' | translate }}</mat-slide-toggle>
</div> </div>
<span class="flex-1"></span> <span class="flex-1"></span>
<button *ngIf="!readonly" class="tb-mobile-layout-button lt-lg:!hidden" <button *ngIf="!readonly" class="tb-mobile-layout-button lt-lg:!hidden"

13
ui-ngx/src/app/modules/home/pages/mobile/bundes/layout/mobile-layout.component.ts

@ -69,11 +69,13 @@ export class MobileLayoutComponent implements ControlValueAccessor, Validator {
mobilePagesContainer: ElementRef<HTMLElement>; mobilePagesContainer: ElementRef<HTMLElement>;
pagesForm = this.fb.group({ pagesForm = this.fb.group({
pages: this.fb.array([]) pages: this.fb.array<MobilePage>([])
}); });
maxIconNameBlockWidth = 256; maxIconNameBlockWidth = 256;
showHiddenPages = new FormControl(true);
private hideItemsSubject = new Subject<void>(); private hideItemsSubject = new Subject<void>();
hideItems$ = this.hideItemsSubject.asObservable(); hideItems$ = this.hideItemsSubject.asObservable();
@ -129,6 +131,9 @@ export class MobileLayoutComponent implements ControlValueAccessor, Validator {
hideAll() { hideAll() {
this.hideItemsSubject.next(); this.hideItemsSubject.next();
if (this.showHiddenPages.value) {
this.showHiddenPages.setValue(false);
}
} }
resetToDefault() { resetToDefault() {
@ -143,7 +148,7 @@ export class MobileLayoutComponent implements ControlValueAccessor, Validator {
} }
visibleMobilePagesControls(): Array<AbstractControl> { visibleMobilePagesControls(): Array<AbstractControl> {
return this.pagesFormArray().controls; return this.pagesFormArray().controls.filter(c => this.showHiddenPages.value || c.value.visible);
} }
mobileItemDrop(event: CdkDragDrop<string[]>) { mobileItemDrop(event: CdkDragDrop<string[]>) {
@ -215,8 +220,8 @@ export class MobileLayoutComponent implements ControlValueAccessor, Validator {
return layout.pages; return layout.pages;
} }
private prepareMobilePagesFormArray(items: MobilePage[]): FormArray { private prepareMobilePagesFormArray(items: MobilePage[]): FormArray<FormControl<MobilePage>> {
const menuItemsControls: Array<AbstractControl> = []; const menuItemsControls: Array<FormControl<MobilePage>> = [];
items.forEach((item) => { items.forEach((item) => {
menuItemsControls.push(this.fb.control(deepClone(item))); menuItemsControls.push(this.fb.control(deepClone(item)));
}); });

0
ui-ngx/src/app/modules/home/pages/mobile/applications/mobile-app-configuration-dialog.component.html → ui-ngx/src/app/modules/home/pages/mobile/bundes/mobile-app-configuration-dialog.component.html

4
ui-ngx/src/app/modules/home/pages/mobile/applications/mobile-app-configuration-dialog.component.scss → ui-ngx/src/app/modules/home/pages/mobile/bundes/mobile-app-configuration-dialog.component.scss

@ -70,8 +70,8 @@
width: 18px; width: 18px;
height: 18px; height: 18px;
background: $tb-primary-color; background: $tb-primary-color;
mask-image: url(/assets/copy-code-icon.svg); mask-image: url(/src/assets/copy-code-icon.svg);
-webkit-mask-image: url(/assets/copy-code-icon.svg); -webkit-mask-image: url(/src/assets/copy-code-icon.svg);
mask-repeat: no-repeat; mask-repeat: no-repeat;
-webkit-mask-repeat: no-repeat; -webkit-mask-repeat: no-repeat;
} }

2
ui-ngx/src/app/modules/home/pages/mobile/applications/mobile-app-configuration-dialog.component.ts → ui-ngx/src/app/modules/home/pages/mobile/bundes/mobile-app-configuration-dialog.component.ts

@ -59,7 +59,7 @@ export class MobileAppConfigurationDialogComponent extends DialogComponent<Mobil
close(): void { close(): void {
if (this.notShowAgain && this.showDontShowAgain) { if (this.notShowAgain && this.showDontShowAgain) {
this.store.dispatch(new ActionPreferencesPutUserSettings({ notDisplayConfigurationAfterAddMobileApp: true })); this.store.dispatch(new ActionPreferencesPutUserSettings({ notDisplayConfigurationAfterAddMobileBundle: true }));
this.dialogRef.close(null); this.dialogRef.close(null);
} else { } else {
this.dialogRef.close(null); this.dialogRef.close(null);

63
ui-ngx/src/app/modules/home/pages/mobile/bundes/mobile-bundle-table-config.resolve.ts

@ -30,7 +30,7 @@ import { Direction } from '@shared/models/page/sort-order';
import { MobileBundleTableHeaderComponent } from '@home/pages/mobile/bundes/mobile-bundle-table-header.component'; import { MobileBundleTableHeaderComponent } from '@home/pages/mobile/bundes/mobile-bundle-table-header.component';
import { DatePipe } from '@angular/common'; import { DatePipe } from '@angular/common';
import { MobileAppService } from '@core/http/mobile-app.service'; import { MobileAppService } from '@core/http/mobile-app.service';
import { map } from 'rxjs/operators'; import { map, take } from 'rxjs/operators';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { EntityAction } from '@home/models/entity/entity-component.models'; import { EntityAction } from '@home/models/entity/entity-component.models';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
@ -38,7 +38,14 @@ import {
MobileBundleDialogComponent, MobileBundleDialogComponent,
MobileBundleDialogData MobileBundleDialogData
} from '@home/pages/mobile/bundes/mobile-bundle-dialog.component'; } from '@home/pages/mobile/bundes/mobile-bundle-dialog.component';
import { NotificationTemplate } from '@shared/models/notification.models'; import {
MobileAppConfigurationDialogComponent,
MobileAppConfigurationDialogData
} from '@home/pages/mobile/bundes/mobile-app-configuration-dialog.component';
import { select, Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { selectUserSettingsProperty } from '@core/auth/auth.selectors';
import { forkJoin, of } from 'rxjs';
@Injectable() @Injectable()
export class MobileBundleTableConfigResolver { export class MobileBundleTableConfigResolver {
@ -50,6 +57,7 @@ export class MobileBundleTableConfigResolver {
private mobileAppService: MobileAppService, private mobileAppService: MobileAppService,
private translate : TranslateService, private translate : TranslateService,
private dialog: MatDialog, private dialog: MatDialog,
private store: Store<AppState>
) { ) {
this.config.selectionEnabled = false; this.config.selectionEnabled = false;
this.config.entityType = EntityType.MOBILE_APP_BUNDLE; this.config.entityType = EntityType.MOBILE_APP_BUNDLE;
@ -105,12 +113,25 @@ export class MobileBundleTableConfigResolver {
}) })
return true; return true;
}; };
this.config.cellActionDescriptors = this.configureCellActions();
} }
resolve(_route: ActivatedRouteSnapshot): EntityTableConfig<MobileAppBundleInfo> { resolve(_route: ActivatedRouteSnapshot): EntityTableConfig<MobileAppBundleInfo> {
return this.config; return this.config;
} }
private configureCellActions(): Array<CellActionDescriptor<MobileAppBundleInfo>> {
return [
{
name: this.translate.instant('mobile.configuration-app'),
icon: 'code',
isEnabled: () => true,
onAction: ($event, entity) => this.configurationApp($event, entity)
}
];
}
private editBundle($event: Event, bundle: MobileAppBundleInfo, isAdd = false) { private editBundle($event: Event, bundle: MobileAppBundleInfo, isAdd = false) {
if ($event) { if ($event) {
$event.stopPropagation(); $event.stopPropagation();
@ -125,8 +146,18 @@ export class MobileBundleTableConfigResolver {
} }
}).afterClosed() }).afterClosed()
.subscribe((res) => { .subscribe((res) => {
if (res) { if (res && !isAdd) {
this.config.updateData(); this.config.updateData();
} else {
this.store.pipe(select(selectUserSettingsProperty('notDisplayConfigurationAfterAddMobileBundle'))).pipe(
take(1)
).subscribe((settings: boolean) => {
if (!settings) {
this.configurationApp(null, res, true);
} else {
this.config.updateData();
}
});
} }
}); });
} }
@ -139,4 +170,30 @@ export class MobileBundleTableConfigResolver {
} }
return false; return false;
} }
private configurationApp($event: Event, entity: MobileAppBundleInfo, afterAdd = false) {
if ($event) {
$event.stopPropagation();
}
const task = {
androidApp: entity.androidAppId ? this.mobileAppService.getMobileAppInfoById(entity.androidAppId.id) : of(null),
iosApp: entity.iosAppId ? this.mobileAppService.getMobileAppInfoById(entity.iosAppId.id) : of(null)
};
forkJoin(task).subscribe(data => {
this.dialog.open<MobileAppConfigurationDialogComponent, MobileAppConfigurationDialogData,
MobileAppBundleInfo>(MobileAppConfigurationDialogComponent, {
disableClose: true,
panelClass: ['tb-dialog', 'tb-fullscreen-dialog'],
data: {
afterAdd,
appSecret: data.androidApp?.appSecret || data.iosApp?.appSecret
}
}).afterClosed()
.subscribe(() => {
if (afterAdd) {
this.config.updateData();
}
});
})
}
} }

2
ui-ngx/src/app/modules/home/pages/mobile/mobile-routing.module.ts

@ -39,7 +39,7 @@ const routes: Routes = [
children: [], children: [],
data: { data: {
auth: [Authority.TENANT_ADMIN, Authority.CUSTOMER_USER, Authority.SYS_ADMIN], auth: [Authority.TENANT_ADMIN, Authority.CUSTOMER_USER, Authority.SYS_ADMIN],
redirectTo: '/mobile-center/applications' redirectTo: '/mobile-center/bundles'
} }
}, },
...applicationsRoutes, ...applicationsRoutes,

2
ui-ngx/src/app/shared/models/user-settings.models.ts

@ -18,7 +18,7 @@ export interface UserSettings {
openedMenuSections?: string[]; openedMenuSections?: string[];
notDisplayConnectivityAfterAddDevice?: boolean; notDisplayConnectivityAfterAddDevice?: boolean;
notDisplayInstructionsAfterAddEdge?: boolean; notDisplayInstructionsAfterAddEdge?: boolean;
notDisplayConfigurationAfterAddMobileApp?: boolean; notDisplayConfigurationAfterAddMobileBundle?: boolean;
includeBundleWidgetsInExport?: boolean; includeBundleWidgetsInExport?: boolean;
} }

7
ui-ngx/src/assets/locale/locale.constant-en_US.json

@ -3382,6 +3382,7 @@
"add-application": "Add application", "add-application": "Add application",
"app-id": "App ID", "app-id": "App ID",
"app-id-required": "App ID is required", "app-id-required": "App ID is required",
"app-id-pattern": "Invalid format App ID",
"app-store-link": "App Store link", "app-store-link": "App Store link",
"app-store-link-required": "App Store link is required", "app-store-link-required": "App Store link is required",
"application-details": "Application details", "application-details": "Application details",
@ -3407,11 +3408,12 @@
"google-play-link-required": "Google Play link is required", "google-play-link-required": "Google Play link is required",
"latest-version": "Latest version", "latest-version": "Latest version",
"min-version": "Min version", "min-version": "Min version",
"invalid-version-pattern": "Invalid version format. Please use the format: major.minor.patch (e.g., 1.0.0).",
"mobile-center": "Mobile center", "mobile-center": "Mobile center",
"mobile-package": "Application package", "mobile-package": "Application package",
"mobile-package-max-length": "Application package should be less than 256", "mobile-package-max-length": "Application package should be less than 256",
"mobile-package-required": "Application package is required.", "mobile-package-required": "Application package is required.",
"mobile-package-spaces": "Application package should not contain spaces", "mobile-package-pattern": "Application package invalid format",
"no-application": "No applications found", "no-application": "No applications found",
"no-bundles": "No bundles found", "no-bundles": "No bundles found",
"platform-type": "Platform type", "platform-type": "Platform type",
@ -3420,6 +3422,8 @@
"set": "Set", "set": "Set",
"sha256-certificate-fingerprints": "SHA256 certificate fingerprints", "sha256-certificate-fingerprints": "SHA256 certificate fingerprints",
"sha256-certificate-fingerprints-required": "SHA256 certificate fingerprints is required", "sha256-certificate-fingerprints-required": "SHA256 certificate fingerprints is required",
"sha256-certificate-fingerprints-pattern": "Invalid format SHA256 certificate fingerprint",
"show-hidden-pages": "Show hidden pages",
"status": "Status", "status": "Status",
"status-type": { "status-type": {
"deprecated": "Deprecated", "deprecated": "Deprecated",
@ -3441,6 +3445,7 @@
"android-application": "Android Application", "android-application": "Android Application",
"ios-app": "iOS App", "ios-app": "iOS App",
"ios-application": "iOS Application", "ios-application": "iOS Application",
"invalid-store-link": "Invalid store link",
"enable-oauth" : "Enable OAuth 2.0", "enable-oauth" : "Enable OAuth 2.0",
"enable-self-registration": "Enable Self registration", "enable-self-registration": "Enable Self registration",
"edit-bundle": "Edit bundle", "edit-bundle": "Edit bundle",

Loading…
Cancel
Save