Initial Commit ...
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { AdminGuard } from 'x-mabsut-api-sdk';
|
||||
import { LoginPage } from './login/login.page';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { LogoutPage } from './logout/logout.page';
|
||||
import { ProfilePage } from './profile/profile.page';
|
||||
import { XCanDeactivateGuard } from 'x-framework-core';
|
||||
import { ViewsModule } from 'src/app/views/public-api';
|
||||
import { RegisterPage } from './register/register.page';
|
||||
import { BaseRoutes } from 'src/app/config/page.config';
|
||||
import { AuthGuard, NotAuthGuard } from 'x-framework-identity-sdk';
|
||||
import { AccountRoutes } from 'src/app/views/account/account.configs';
|
||||
import { EmailConfirmPage } from './email-confirm/email-confirm.page';
|
||||
import { PhoneConfirmPage } from './phone-confirm/phone-confirm.page';
|
||||
import { ResetPasswordPage } from './reset-password/reset-password.page';
|
||||
import { ChangePasswordPage } from './change-password/change-password.page';
|
||||
import { SearchProfilesPage } from './search-profiles/search-profiles.page';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
LoginPage,
|
||||
LogoutPage,
|
||||
ProfilePage,
|
||||
RegisterPage,
|
||||
PhoneConfirmPage,
|
||||
EmailConfirmPage,
|
||||
ResetPasswordPage,
|
||||
ChangePasswordPage,
|
||||
SearchProfilesPage,
|
||||
],
|
||||
imports: [
|
||||
ViewsModule,
|
||||
RouterModule.forChild([
|
||||
{
|
||||
path: BaseRoutes.Default,
|
||||
redirectTo: AccountRoutes.Profile,
|
||||
pathMatch: 'full',
|
||||
},
|
||||
//
|
||||
// Login ...
|
||||
{
|
||||
path: AccountRoutes.Login,
|
||||
component: LoginPage,
|
||||
canActivate: [NotAuthGuard],
|
||||
canDeactivate: [XCanDeactivateGuard],
|
||||
},
|
||||
//
|
||||
// Logout ...
|
||||
{
|
||||
path: AccountRoutes.Logout,
|
||||
component: LogoutPage,
|
||||
canActivate: [AuthGuard],
|
||||
canDeactivate: [XCanDeactivateGuard],
|
||||
},
|
||||
//
|
||||
// Profile ...
|
||||
{
|
||||
path: AccountRoutes.Profile,
|
||||
component: ProfilePage,
|
||||
canActivate: [AuthGuard],
|
||||
canDeactivate: [XCanDeactivateGuard],
|
||||
},
|
||||
//
|
||||
// Register ...
|
||||
{
|
||||
path: AccountRoutes.Register,
|
||||
component: RegisterPage,
|
||||
canActivate: [NotAuthGuard],
|
||||
canDeactivate: [XCanDeactivateGuard],
|
||||
},
|
||||
//
|
||||
// Email Confirm ...
|
||||
{
|
||||
path: AccountRoutes.EmailConfirm,
|
||||
component: EmailConfirmPage,
|
||||
canActivate: [NotAuthGuard],
|
||||
canDeactivate: [XCanDeactivateGuard],
|
||||
},
|
||||
//
|
||||
// Phone Confirm ...
|
||||
{
|
||||
path: AccountRoutes.PhoneConfirm,
|
||||
component: PhoneConfirmPage,
|
||||
canActivate: [NotAuthGuard],
|
||||
canDeactivate: [XCanDeactivateGuard],
|
||||
},
|
||||
//
|
||||
// Reset Password ...
|
||||
{
|
||||
path: AccountRoutes.ResetPassword,
|
||||
component: ResetPasswordPage,
|
||||
canActivate: [NotAuthGuard],
|
||||
canDeactivate: [XCanDeactivateGuard],
|
||||
},
|
||||
//
|
||||
// Change Password ...
|
||||
{
|
||||
path: AccountRoutes.ChangePassword,
|
||||
component: ChangePasswordPage,
|
||||
canActivate: [AuthGuard],
|
||||
canDeactivate: [XCanDeactivateGuard],
|
||||
},
|
||||
//
|
||||
// Search Profiles ...
|
||||
{
|
||||
path: AccountRoutes.SearchProfiles,
|
||||
component: SearchProfilesPage,
|
||||
canActivate: [AuthGuard],
|
||||
canDeactivate: [XCanDeactivateGuard],
|
||||
},
|
||||
{
|
||||
path: BaseRoutes.Unknown,
|
||||
pathMatch: 'full',
|
||||
redirectTo: AccountRoutes.Default,
|
||||
},
|
||||
]),
|
||||
],
|
||||
exports: [
|
||||
//
|
||||
ViewsModule,
|
||||
RouterModule,
|
||||
//
|
||||
LoginPage,
|
||||
LogoutPage,
|
||||
ProfilePage,
|
||||
RegisterPage,
|
||||
PhoneConfirmPage,
|
||||
EmailConfirmPage,
|
||||
ResetPasswordPage,
|
||||
ChangePasswordPage,
|
||||
SearchProfilesPage,
|
||||
],
|
||||
})
|
||||
export class AccountPageModule {}
|
||||
@@ -0,0 +1,5 @@
|
||||
export const LoginTasks = {
|
||||
Login: 'login',
|
||||
RequestResetPassword: 'request_reset_password',
|
||||
ResendEmailVerificationLink: 'resend_email_verification_link',
|
||||
};
|
||||
@@ -0,0 +1,14 @@
|
||||
<!-- -->
|
||||
<!-- Page Presenter -->
|
||||
<!-- -->
|
||||
<v-page-presenter
|
||||
[loading]="loading"
|
||||
[containerBase]="this"
|
||||
[uiDisabled]="uiDisabled"
|
||||
[contentTemplate]="contentTemplate"
|
||||
></v-page-presenter>
|
||||
|
||||
<!-- -->
|
||||
<!-- Page Content -->
|
||||
<!-- -->
|
||||
<ng-template #contentTemplate> Change Password ... </ng-template>
|
||||
@@ -0,0 +1,20 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { VPageComponent } from 'src/app/views/v-page/v-page.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-change-password',
|
||||
templateUrl: './change-password.page.html',
|
||||
styleUrls: ['./change-password.page.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class ChangePasswordPage extends VPageComponent {
|
||||
//
|
||||
//#region Props ...
|
||||
hasSide = true;
|
||||
toolbarShowSubTitle = true;
|
||||
showToolbarEndSlot = true;
|
||||
showToolbarContent = false;
|
||||
titleRes = this.AppResourceIDs.change_password_page_title;
|
||||
toolbarSubTitle = this.resourceProvider(this.titleRes);
|
||||
//#endregion
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<!-- -->
|
||||
<!-- Page Presenter -->
|
||||
<!-- -->
|
||||
<v-page-presenter
|
||||
[loading]="loading"
|
||||
[containerBase]="this"
|
||||
[uiDisabled]="uiDisabled"
|
||||
[contentTemplate]="contentTemplate"
|
||||
></v-page-presenter>
|
||||
|
||||
<!-- -->
|
||||
<!-- Page Content -->
|
||||
<!-- -->
|
||||
<ng-template #contentTemplate> Email Confirm ... </ng-template>
|
||||
@@ -0,0 +1,27 @@
|
||||
import { XSideType } from 'x-framework-components';
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { VPageComponent } from 'src/app/views/v-page/v-page.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-email-confirm',
|
||||
templateUrl: './email-confirm.page.html',
|
||||
styleUrls: ['./email-confirm.page.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class EmailConfirmPage extends VPageComponent {
|
||||
//
|
||||
//#region Props ...
|
||||
hasSide = true;
|
||||
toolbarShowSubTitle = true;
|
||||
showToolbarEndSlot = true;
|
||||
showToolbarContent = false;
|
||||
titleRes = this.AppResourceIDs.email_confirm_page_title;
|
||||
toolbarSubTitle = this.resourceProvider(this.titleRes);
|
||||
|
||||
/**
|
||||
* use this for Menu always Visible ...
|
||||
*/
|
||||
toggleMenuWhen = '';
|
||||
sideType = XSideType.Overlay;
|
||||
//#endregion
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<!-- -->
|
||||
<!-- Page Presenter -->
|
||||
<!-- -->
|
||||
<v-page-presenter
|
||||
[loading]="loading"
|
||||
[containerBase]="this"
|
||||
[uiDisabled]="uiDisabled"
|
||||
[contentTemplate]="contentTemplate"
|
||||
></v-page-presenter>
|
||||
|
||||
<!-- -->
|
||||
<!-- Page Content -->
|
||||
<!-- -->
|
||||
<ng-template #contentTemplate>
|
||||
<v-login
|
||||
[model]="model"
|
||||
[loading]="loading"
|
||||
(login)="handleLogin()"
|
||||
[uiDisabled]="loading || uiDisabled"
|
||||
(lockNotifier)="handleLockStateChanged($event)"
|
||||
(changeNotifier)="handleModelStateChange($event)"
|
||||
></v-login>
|
||||
</ng-template>
|
||||
@@ -0,0 +1,350 @@
|
||||
import {
|
||||
XTask,
|
||||
XParam,
|
||||
getTaskName,
|
||||
isNullOrUndefined,
|
||||
} from 'x-framework-core';
|
||||
import { filter } from 'rxjs/operators';
|
||||
import { LoginTasks } from '../account.typings';
|
||||
import { Pages } from 'src/app/config/page.config';
|
||||
import { XSideType } from 'x-framework-components';
|
||||
import { XLoginRequestDto } from 'x-framework-identity-sdk';
|
||||
import { VModelState } from 'src/app/views/v-dto/v-dto.typings';
|
||||
import { Component, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { VPageComponent } from 'src/app/views/v-page/v-page.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-login',
|
||||
templateUrl: './login.page.html',
|
||||
styleUrls: ['./login.page.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
// tslint:disable-next-line:component-class-suffix
|
||||
export class LoginPage extends VPageComponent {
|
||||
//
|
||||
//#region Props ...
|
||||
//
|
||||
hasSide = true;
|
||||
toolbarShowSubTitle = true;
|
||||
showToolbarEndSlot = true;
|
||||
showToolbarContent = false;
|
||||
titleRes = this.AppResourceIDs.login_page_title;
|
||||
toolbarSubTitle = this.resourceProvider(this.titleRes);
|
||||
|
||||
/**
|
||||
* use this for Menu always Visible ...
|
||||
*/
|
||||
toggleMenuWhen = '';
|
||||
sideType = XSideType.Overlay;
|
||||
|
||||
//
|
||||
showEmailConfirm = false;
|
||||
showResetPassword = false;
|
||||
|
||||
//
|
||||
model: XLoginRequestDto = {
|
||||
userSelectBy: '',
|
||||
password: '',
|
||||
};
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Constructor ...
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region LifeCycles ...
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Register Handlers ...
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Task Handlers ...
|
||||
async onTaskStart(name: string, task: XTask<any>) {
|
||||
super.onTaskStart(name, task);
|
||||
|
||||
//
|
||||
// Prevent Moving Forward ...
|
||||
if (!this.isPageTask(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Set Loading State ...
|
||||
await this.setLoadingState(true);
|
||||
|
||||
//
|
||||
// Handle Flags for Confirm Email and Reset Password ...
|
||||
// TODO: Complete this ...
|
||||
|
||||
//
|
||||
if (name === LoginTasks.ResendEmailVerificationLink) {
|
||||
this.showEmailConfirm = false;
|
||||
}
|
||||
|
||||
//
|
||||
if (name === LoginTasks.RequestResetPassword) {
|
||||
this.showResetPassword = false;
|
||||
}
|
||||
|
||||
//
|
||||
// Apply Changes ...
|
||||
this.detectChanges();
|
||||
}
|
||||
|
||||
async onTaskFinished(name: string, task: XTask<any>) {
|
||||
super.onTaskFinished(name, task);
|
||||
|
||||
//
|
||||
// Prevent Moving Forward ...
|
||||
if (!this.isPageTask(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Set Loading State ...
|
||||
await this.setLoadingState(false);
|
||||
|
||||
//
|
||||
// Handle User Authenticated ...
|
||||
if (name === LoginTasks.Login) {
|
||||
this.handleUserAuthenticated();
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// If Email Verification is Passed ...
|
||||
if (
|
||||
name === LoginTasks.ResendEmailVerificationLink ||
|
||||
name === LoginTasks.RequestResetPassword
|
||||
) {
|
||||
//
|
||||
await this.managerService.notificationService.presentSuccessNotification({
|
||||
message: this.resourceProvider(this.AppResourceIDs.check_mail),
|
||||
dissmissable: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async onTaskFailed(name: string, task: XTask<any>) {
|
||||
super.onTaskFailed(name, task);
|
||||
|
||||
//
|
||||
// Prevent Moving Forward ...
|
||||
if (!this.isPageTask(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Set Loading State ...
|
||||
await this.setLoadingState(false);
|
||||
|
||||
//
|
||||
// Retrieve Exception ...
|
||||
const exception = task.error;
|
||||
await this.handleErrorState(exception, true);
|
||||
|
||||
//
|
||||
// Handle Email Verification Error ...
|
||||
if (task.name === LoginTasks.ResendEmailVerificationLink) {
|
||||
//
|
||||
this.uiDisabled = true;
|
||||
this.showEmailConfirm = true;
|
||||
|
||||
//
|
||||
this.detectChanges();
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Request Reset Password Error ...
|
||||
if (task.name === LoginTasks.RequestResetPassword) {
|
||||
//
|
||||
this.uiDisabled = true;
|
||||
this.showResetPassword = true;
|
||||
|
||||
//
|
||||
this.detectChanges();
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Other Errors ...
|
||||
switch (exception.id) {
|
||||
//
|
||||
// Email Not Confirmed ...
|
||||
case 135:
|
||||
//
|
||||
this.uiDisabled = true;
|
||||
this.showEmailConfirm = true;
|
||||
break;
|
||||
|
||||
//
|
||||
// User Disabled ...
|
||||
case 117:
|
||||
//
|
||||
this.uiDisabled = true;
|
||||
this.showEmailConfirm = true;
|
||||
break;
|
||||
//
|
||||
// Login Failed (Username is Ok ... Password Mistmatch ...) ...
|
||||
case 106:
|
||||
//
|
||||
this.uiDisabled = true;
|
||||
this.showResetPassword = true;
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Apply Changes ...
|
||||
this.detectChanges();
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region UI Providers ...
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region UI Handlers ...
|
||||
/**
|
||||
* Handle Login ...
|
||||
*/
|
||||
async handleLogin() {
|
||||
//
|
||||
// Prevent Moving Forward when Context is Busy ...
|
||||
if (this.loading || this.uiDisabled || isNullOrUndefined(this.model)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
if (this.lock) {
|
||||
this.lock = false;
|
||||
}
|
||||
|
||||
//
|
||||
// Prepare User Select By ...
|
||||
const model = {
|
||||
...this.model,
|
||||
userSelectBy: this.model.userSelectBy.toLowerCase(),
|
||||
};
|
||||
|
||||
//
|
||||
// Prepare Task Requirements ...
|
||||
const mTaskName = LoginTasks.Login;
|
||||
const mTask = this.sharedService.authService.login(model);
|
||||
|
||||
//
|
||||
// Add or Update Task to Queue ...
|
||||
await this.addOrUpdateTask({
|
||||
name: mTaskName,
|
||||
priority: 0,
|
||||
affectLoading: true,
|
||||
task: mTask,
|
||||
});
|
||||
|
||||
//
|
||||
// Dispatch Task ...
|
||||
await this.dispatchTask(mTaskName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update Model ...
|
||||
*
|
||||
* @param state
|
||||
*/
|
||||
async handleModelStateChange(state: VModelState<XLoginRequestDto>) {
|
||||
//
|
||||
// Update Model Fields ...
|
||||
this.model.device = state.model.device;
|
||||
this.model.language = state.model.language;
|
||||
this.model.password = state.model.password;
|
||||
this.model.userSelectBy = state.model.userSelectBy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handling Lock State ...
|
||||
*
|
||||
* @param event
|
||||
* @returns
|
||||
*/
|
||||
handleLockStateChanged(event: { id: string; state: boolean }) {
|
||||
//
|
||||
if (isNullOrUndefined(event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
this.lock = event.state;
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Actions ...
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Private Actions ...
|
||||
//
|
||||
//#region Task Providers ...
|
||||
private getTaskNames() {
|
||||
return [
|
||||
//
|
||||
LoginTasks.Login,
|
||||
LoginTasks.RequestResetPassword,
|
||||
LoginTasks.ResendEmailVerificationLink,
|
||||
];
|
||||
}
|
||||
|
||||
private async isPageTask(key: string | any) {
|
||||
//
|
||||
const pageTasks = this.getTaskNames();
|
||||
const mTaskKey = getTaskName(key);
|
||||
const result = pageTasks.includes(mTaskKey);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Task Handlers ...
|
||||
private handleUserAuthenticated() {
|
||||
//
|
||||
const hasAfterLoginRedirectPage = !isNullOrUndefined(
|
||||
this.config.afterLoginRedirectPage
|
||||
);
|
||||
|
||||
//
|
||||
const url = this.managerService.isContainQueryParam(XParam.ReturnUrl)
|
||||
? this.managerService.getQueryParamValOfType<string>(XParam.ReturnUrl)
|
||||
: hasAfterLoginRedirectPage
|
||||
? this.managerService.getPageRoute(this.config.afterLoginRedirectPage)
|
||||
: this.managerService.getPageRoute(Pages.Home);
|
||||
|
||||
//
|
||||
const mSubscription = this.sharedService.state$
|
||||
.asObservable()
|
||||
.pipe(filter((res) => !isNullOrUndefined(res) && res.isLoggedIn === true))
|
||||
// tslint:disable-next-line: deprecation
|
||||
.subscribe(async () => {
|
||||
//
|
||||
this.runTimedOut(async () => {
|
||||
//
|
||||
if (this.lock) {
|
||||
this.lock = false;
|
||||
}
|
||||
|
||||
//
|
||||
await this.managerService.navigateByUrlReplace(url);
|
||||
});
|
||||
|
||||
//
|
||||
mSubscription.unsubscribe();
|
||||
});
|
||||
}
|
||||
//#endregion
|
||||
//#endregion
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<!-- -->
|
||||
<!-- Page Presenter -->
|
||||
<!-- -->
|
||||
<v-page-presenter
|
||||
[containerBase]="this"
|
||||
[contentTemplate]="contentTemplate"
|
||||
></v-page-presenter>
|
||||
|
||||
<!-- -->
|
||||
<!-- Page Content -->
|
||||
<!-- -->
|
||||
<ng-template #contentTemplate>
|
||||
</ng-template>
|
||||
@@ -0,0 +1,74 @@
|
||||
import { Pages } from 'src/app/config/page.config';
|
||||
import { XSideType } from 'x-framework-components';
|
||||
import { Component, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { VPageComponent } from 'src/app/views/v-page/v-page.component';
|
||||
|
||||
const LogoutKeys = {
|
||||
LoggingOutID: 'logging_out',
|
||||
};
|
||||
|
||||
@Component({
|
||||
selector: 'app-logout',
|
||||
templateUrl: './logout.page.html',
|
||||
styleUrls: ['./logout.page.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
// tslint:disable-next-line:component-class-suffix
|
||||
export class LogoutPage extends VPageComponent {
|
||||
//
|
||||
//#region Props ...
|
||||
hasSide = true;
|
||||
toolbarShowSubTitle = true;
|
||||
showToolbarEndSlot = false;
|
||||
showToolbarContent = false;
|
||||
titleRes = this.AppResourceIDs.logout_page_title;
|
||||
toolbarSubTitle = this.resourceProvider(this.titleRes);
|
||||
|
||||
/**
|
||||
* use this for Menu always Visible ...
|
||||
*/
|
||||
toggleMenuWhen = '';
|
||||
sideType = XSideType.Overlay;
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Constructor ...
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region LifeCycles ...
|
||||
async afterViewInit() {
|
||||
super.afterViewInit();
|
||||
|
||||
//
|
||||
await this.handleLogoutAction();
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Private Actions ...
|
||||
private async handleLogoutAction() {
|
||||
//
|
||||
await this.managerService.dialogService.presentLoading({
|
||||
id: LogoutKeys.LoggingOutID,
|
||||
message: this.resourceProvider(this.AppResourceIDs.logging_out),
|
||||
});
|
||||
|
||||
//
|
||||
this.loading = true;
|
||||
|
||||
//
|
||||
await this.sharedService.authService.logout();
|
||||
this.managerService.settingsService.restart();
|
||||
|
||||
//
|
||||
this.loading = false;
|
||||
this.managerService.dialogService.loadingController.dismiss(
|
||||
LogoutKeys.LoggingOutID
|
||||
);
|
||||
|
||||
//
|
||||
await this.managerService.navigateByPageReplace(Pages.Startup);
|
||||
}
|
||||
//#endregion
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<!-- -->
|
||||
<!-- Page Presenter -->
|
||||
<!-- -->
|
||||
<v-page-presenter
|
||||
[loading]="loading"
|
||||
[containerBase]="this"
|
||||
[uiDisabled]="uiDisabled"
|
||||
[contentTemplate]="contentTemplate"
|
||||
></v-page-presenter>
|
||||
|
||||
<!-- -->
|
||||
<!-- Page Content -->
|
||||
<!-- -->
|
||||
<ng-template #contentTemplate> Phone Confirm ... </ng-template>
|
||||
@@ -0,0 +1,27 @@
|
||||
import { XSideType } from 'x-framework-components';
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { VPageComponent } from 'src/app/views/v-page/v-page.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-phone-confirm',
|
||||
templateUrl: './phone-confirm.page.html',
|
||||
styleUrls: ['./phone-confirm.page.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class PhoneConfirmPage extends VPageComponent {
|
||||
//
|
||||
//#region Props ...
|
||||
hasSide = true;
|
||||
toolbarShowSubTitle = true;
|
||||
showToolbarEndSlot = true;
|
||||
showToolbarContent = false;
|
||||
titleRes = this.AppResourceIDs.phone_confirm_page_title;
|
||||
toolbarSubTitle = this.resourceProvider(this.titleRes);
|
||||
|
||||
/**
|
||||
* use this for Menu always Visible ...
|
||||
*/
|
||||
toggleMenuWhen = '';
|
||||
sideType = XSideType.Overlay;
|
||||
//#endregion
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<!-- -->
|
||||
<!-- Page Presenter -->
|
||||
<!-- -->
|
||||
<v-page-presenter
|
||||
[loading]="loading"
|
||||
[containerBase]="this"
|
||||
[uiDisabled]="uiDisabled"
|
||||
[contentTemplate]="contentTemplate"
|
||||
></v-page-presenter>
|
||||
|
||||
<!-- -->
|
||||
<!-- Page Content -->
|
||||
<!-- -->
|
||||
<ng-template #contentTemplate> Profile ... </ng-template>
|
||||
@@ -0,0 +1,20 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { VPageComponent } from 'src/app/views/v-page/v-page.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-profile',
|
||||
templateUrl: './profile.page.html',
|
||||
styleUrls: ['./profile.page.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class ProfilePage extends VPageComponent {
|
||||
//
|
||||
//#region Props ...
|
||||
hasSide = true;
|
||||
toolbarShowSubTitle = true;
|
||||
showToolbarEndSlot = true;
|
||||
showToolbarContent = false;
|
||||
titleRes = this.AppResourceIDs.profile_page_title;
|
||||
toolbarSubTitle = this.resourceProvider(this.titleRes);
|
||||
//#endregion
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<!-- -->
|
||||
<!-- Page Presenter -->
|
||||
<!-- -->
|
||||
<v-page-presenter
|
||||
[loading]="loading"
|
||||
[containerBase]="this"
|
||||
[uiDisabled]="uiDisabled"
|
||||
[contentTemplate]="contentTemplate"
|
||||
></v-page-presenter>
|
||||
|
||||
<!-- -->
|
||||
<!-- Page Content -->
|
||||
<!-- -->
|
||||
<ng-template #contentTemplate>
|
||||
<!-- Register -->
|
||||
<v-register
|
||||
[isInPage]="true"
|
||||
[wrapWithCard]="true"
|
||||
[cardTitle]="AppResourceIDs.register"
|
||||
></v-register>
|
||||
</ng-template>
|
||||
@@ -0,0 +1,62 @@
|
||||
import { XSideType } from 'x-framework-components';
|
||||
import { VPageComponent } from 'src/app/views/public-api';
|
||||
import { Component, ChangeDetectionStrategy } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-register',
|
||||
templateUrl: './register.page.html',
|
||||
styleUrls: ['./register.page.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
// tslint:disable-next-line: component-class-suffix
|
||||
export class RegisterPage extends VPageComponent {
|
||||
//
|
||||
//#region Props ...
|
||||
hasSide = true;
|
||||
toolbarShowSubTitle = true;
|
||||
titleRes = this.AppResourceIDs.register_page_title;
|
||||
toolbarSubTitle = this.resourceProvider(this.titleRes);
|
||||
|
||||
/**
|
||||
* use this for Menu always Visible ...
|
||||
*/
|
||||
toggleMenuWhen = '';
|
||||
sideType = XSideType.Overlay;
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Constructor ...
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region LifeCycles ...
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Constructor ...
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Register Handlers ...
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Task Handlers ...
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region UI Providers ...
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region UI Handlers ...
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Actions ...
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Private ...
|
||||
//#endregion
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<!-- -->
|
||||
<!-- Page Presenter -->
|
||||
<!-- -->
|
||||
<v-page-presenter
|
||||
[loading]="loading"
|
||||
[containerBase]="this"
|
||||
[uiDisabled]="uiDisabled"
|
||||
[contentTemplate]="contentTemplate"
|
||||
></v-page-presenter>
|
||||
|
||||
<!-- -->
|
||||
<!-- Page Content -->
|
||||
<!-- -->
|
||||
<ng-template #contentTemplate> Reset Password ... </ng-template>
|
||||
@@ -0,0 +1,27 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { VPageComponent } from 'src/app/views/v-page/v-page.component';
|
||||
import { XSideType } from 'x-framework-components';
|
||||
|
||||
@Component({
|
||||
selector: 'app-reset-password',
|
||||
templateUrl: './reset-password.page.html',
|
||||
styleUrls: ['./reset-password.page.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class ResetPasswordPage extends VPageComponent {
|
||||
//
|
||||
//#region Props ...
|
||||
hasSide = true;
|
||||
toolbarShowSubTitle = true;
|
||||
showToolbarEndSlot = true;
|
||||
showToolbarContent = false;
|
||||
titleRes = this.AppResourceIDs.reset_password_page_title;
|
||||
toolbarSubTitle = this.resourceProvider(this.titleRes);
|
||||
|
||||
/**
|
||||
* use this for Menu always Visible ...
|
||||
*/
|
||||
toggleMenuWhen = '';
|
||||
sideType = XSideType.Overlay;
|
||||
//#endregion
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<!-- -->
|
||||
<!-- Page Presenter -->
|
||||
<!-- -->
|
||||
<v-page-presenter
|
||||
[loading]="loading"
|
||||
[containerBase]="this"
|
||||
[uiDisabled]="uiDisabled"
|
||||
[contentTemplate]="contentTemplate"
|
||||
></v-page-presenter>
|
||||
|
||||
<!-- -->
|
||||
<!-- Page Content -->
|
||||
<!-- -->
|
||||
<ng-template #contentTemplate> Search Profiles ... </ng-template>
|
||||
@@ -0,0 +1,20 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { VPageComponent } from 'src/app/views/v-page/v-page.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-search-profiles',
|
||||
templateUrl: './search-profiles.page.html',
|
||||
styleUrls: ['./search-profiles.page.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class SearchProfilesPage extends VPageComponent {
|
||||
//
|
||||
//#region Props ...
|
||||
hasSide = true;
|
||||
toolbarShowSubTitle = true;
|
||||
showToolbarEndSlot = true;
|
||||
showToolbarContent = false;
|
||||
titleRes = this.AppResourceIDs.search_profiles_page_title;
|
||||
toolbarSubTitle = this.resourceProvider(this.titleRes);
|
||||
//#endregion
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<!-- -->
|
||||
<!-- Page Presenter -->
|
||||
<!-- -->
|
||||
<v-page-presenter
|
||||
[containerBase]="this"
|
||||
[contentTemplate]="contentTemplate"
|
||||
></v-page-presenter>
|
||||
|
||||
<!-- -->
|
||||
<!-- Page Content -->
|
||||
<!-- -->
|
||||
<ng-template #contentTemplate>
|
||||
<v-error
|
||||
[isInPage]="true"
|
||||
[errorTitle]="''"
|
||||
[wrapWithCard]="true"
|
||||
*ngIf="hasChildValue(errors) | async"
|
||||
[errors]="getArrayValue(errors) | async"
|
||||
[cardTitle]="AppResourceIDs.error_page_title"
|
||||
>
|
||||
</v-error>
|
||||
</ng-template>
|
||||
@@ -0,0 +1,79 @@
|
||||
import { Pages } from 'src/app/config/page.config';
|
||||
import { XButtonType } from 'x-framework-components';
|
||||
import { Component, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { VPageComponent } from 'src/app/views/v-page/v-page.component';
|
||||
import { toArray, XOneOrManyType, XParam } from 'x-framework-core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-error',
|
||||
templateUrl: './error.page.html',
|
||||
styleUrls: ['./error.page.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
// tslint:disable-next-line: component-class-suffix
|
||||
export class ErrorPage extends VPageComponent {
|
||||
//
|
||||
//#region Props ...
|
||||
hasSide = false;
|
||||
toolbarHasBack = true;
|
||||
toolbarShowBack = true;
|
||||
showToolbarEndSlot = false;
|
||||
showToolbarContent = false;
|
||||
toolbarShowSubTitle = true;
|
||||
titleRes = this.AppResourceIDs.error_page_title;
|
||||
toolbarSubTitle = this.resourceProvider(this.titleRes);
|
||||
|
||||
//
|
||||
errors: XOneOrManyType<string>;
|
||||
returnUrl = this.managerService.getPageRoute(Pages.Startup);
|
||||
|
||||
//
|
||||
toolbarBackHandler = () => {
|
||||
this.managerService.navigateByUrlReplace(this.returnUrl);
|
||||
};
|
||||
|
||||
//
|
||||
//#region Private/ReadOnly ...
|
||||
readonly ButtonTypes = Object.assign({}, XButtonType);
|
||||
//#endregion
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Constructor ...
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region LifeCycle ...
|
||||
parseParams(): void {
|
||||
super.parseParams();
|
||||
|
||||
//
|
||||
this.errors = [
|
||||
...toArray(
|
||||
this.managerService.getStateValOfType<XOneOrManyType<string>>(
|
||||
XParam.Errors
|
||||
)
|
||||
),
|
||||
];
|
||||
|
||||
//
|
||||
const isContainsReturnUrl = this.managerService.isContainState(
|
||||
XParam.ReturnUrl
|
||||
);
|
||||
if (isContainsReturnUrl) {
|
||||
this.returnUrl = this.managerService.getStateValOfType<string>(
|
||||
XParam.ReturnUrl
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
if (this.hasChild(this.errors)) {
|
||||
this.detectChanges();
|
||||
}
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Action Handlers ...
|
||||
//#endregion
|
||||
}
|
||||
@@ -0,0 +1,266 @@
|
||||
<!-- -->
|
||||
<!-- Page Presenter -->
|
||||
<!-- -->
|
||||
<v-page-presenter
|
||||
#pagePresenter
|
||||
[loading]="loading"
|
||||
[containerBase]="this"
|
||||
[uiDisabled]="uiDisabled"
|
||||
[contentTemplate]="contentTemplate"
|
||||
(xOnEscapeGlobal)="handleGlobalEscapePressed($event)"
|
||||
></v-page-presenter>
|
||||
|
||||
<!-- -->
|
||||
<!-- Page Content -->
|
||||
<!-- -->
|
||||
<ng-template #contentTemplate>
|
||||
<!-- Query Presenter -->
|
||||
<v-query-presenter
|
||||
[loading]="loading"
|
||||
[tabsLock]="tabsLock"
|
||||
[tabsColor]="tabsColor"
|
||||
[showEmpty]="showEmpty"
|
||||
[emptyColor]="emptyColor"
|
||||
[addTabTitle]="addTabTitle"
|
||||
[itemTemplate]="itemTemplate"
|
||||
[emptyMessage]="emptyMessage"
|
||||
[tabsCssClass]="tabsCssClass"
|
||||
[tabsLoopTabs]="tabsLoopTabs"
|
||||
[tabsSwipable]="tabsSwipable"
|
||||
[listTabTitle]="listTabTitle"
|
||||
[emptyCssClass]="emptyCssClass"
|
||||
[showPaginator]="showPaginator"
|
||||
[tabsAlignTabs]="tabsAlignTabs"
|
||||
[showSearchBar]="showSearchBar"
|
||||
[searchBarType]="searchBarType"
|
||||
[searchBarValue]="searchBarValue"
|
||||
[searchBarTitle]="searchBarTitle"
|
||||
[searchBarColor]="searchBarColor"
|
||||
[updateTabTitle]="updateTabTitle"
|
||||
[paginatorColor]="paginatorColor"
|
||||
[tabsShowHeader]="tabsShowHeader"
|
||||
[addItemTemplate]="addItemTemplate"
|
||||
[emptyHasRefresh]="emptyHasRefresh"
|
||||
[detailsTabTitle]="detailsTabTitle"
|
||||
[tabsHeaderColor]="tabsHeaderColor"
|
||||
[showItemsAsList]="showItemsAsList"
|
||||
[modelIdentifier]="modelIdentifier"
|
||||
[uiDisabled]="loading || uiDisabled"
|
||||
[listItemTemplate]="listItemTemplate"
|
||||
[listTabCardTitle]="listTabCardTitle"
|
||||
[listTabCardColor]="listTabCardColor"
|
||||
[emptyRefreshIcon]="emptyRefreshIcon"
|
||||
[emptyMessageColor]="emptyMessageColor"
|
||||
[paginatorPosition]="paginatorPosition"
|
||||
[tabsSelectedIndex]="tabsSelectedIndex"
|
||||
[tabsDynamicHeight]="tabsDynamicHeight"
|
||||
[tabsDisableRipple]="tabsDisableRipple"
|
||||
[searchBarDebounce]="searchBarDebounce"
|
||||
[searchBarCssClass]="searchBarCssClass"
|
||||
[updateItemTemplate]="updateItemTemplate"
|
||||
[tabsHeaderPosition]="tabsHeaderPosition"
|
||||
[tabsActiveTabColor]="tabsActiveTabColor"
|
||||
[searchBarSpellcheck]="searchBarSpellcheck"
|
||||
[detailsItemTemplate]="detailsItemTemplate"
|
||||
[wrapListTabWithCard]="wrapListTabWithCard"
|
||||
[listTabCardIsInPage]="listTabCardIsInPage"
|
||||
[listTabCardSubTitle]="listTabCardSubTitle"
|
||||
[emptyForegroundColor]="emptyForegroundColor"
|
||||
[actionProvider]="queryPresenterActionProvider"
|
||||
[tabsDisablePagination]="tabsDisablePagination"
|
||||
[tabsAnimationDuration]="tabsAnimationDuration"
|
||||
[tabsTabIndicatorColor]="tabsTabIndicatorColor"
|
||||
[tabsTabPaginatorColor]="tabsTabPaginatorColor"
|
||||
[searchBarKeyboardType]="searchBarKeyboardType"
|
||||
[searchBarEnterKeyHint]="searchBarEnterKeyHint"
|
||||
[emptyRefreshButtonColor]="emptyRefreshButtonColor"
|
||||
[searchBarForegroundColor]="searchBarForegroundColor"
|
||||
[searchBarShowClearButton]="searchBarShowClearButton"
|
||||
[searchBarClearButtonIcon]="searchBarClearButtonIcon"
|
||||
[searchBarCancelButtonIcon]="searchBarCancelButtonIcon"
|
||||
[searchBarSearchButtonIcon]="searchBarSearchButtonIcon"
|
||||
[searchBarSearchInputColor]="searchBarSearchInputColor"
|
||||
[searchBarShowCancelButton]="searchBarShowCancelButton"
|
||||
[searchBarCancelButtonTitle]="searchBarCancelButtonTitle"
|
||||
[emptyForegroundMessageColor]="emptyForegroundMessageColor"
|
||||
[searchBarClearButtonIconColor]="searchBarClearButtonIconColor"
|
||||
[searchBarCancelButtonIconColor]="searchBarCancelButtonIconColor"
|
||||
[searchBarSearchButtonIconColor]="searchBarSearchButtonIconColor"
|
||||
[emptyForegroundRefreshButtonColor]="emptyForegroundRefreshButtonColor"
|
||||
[searchBarForegroundSearchInputColor]="searchBarForegroundSearchInputColor"
|
||||
>
|
||||
</v-query-presenter>
|
||||
</ng-template>
|
||||
|
||||
<!-- -->
|
||||
<!-- Item Template -->
|
||||
<!-- -->
|
||||
<ng-template #itemTemplate let-item="item">
|
||||
<v-file
|
||||
[model]="item"
|
||||
class="v-item"
|
||||
[loading]="loading"
|
||||
[uiDisabled]="loading || uiDisabled"
|
||||
[cardTitle]="getModelCardTitle(item)"
|
||||
[presentType]="BasePresentTypes.AsView"
|
||||
[actionProvider]="listItemActionProvider"
|
||||
*ngIf="notNullOrUndefinedValue(item) | async"
|
||||
[providedFieldDescriptors]="listItemViewFieldDescriptors"
|
||||
>
|
||||
<div actions *ngIf="(notNullOrUndefinedValue(item) | async)">
|
||||
<ng-container *ngIf="itemsActions.has(item.id)">
|
||||
<!-- Slotting Actions -->
|
||||
<x-slotter [hasCenterSlot]="false" [layout]="SlotLayouts.HORIZONTAL">
|
||||
<!-- START -->
|
||||
<x-slot [name]="SlotNames.START" [cssClass]="'ion-text-start'">
|
||||
<ng-container
|
||||
*ngFor="let action of getSlottedItemActions(SlotNames.START, item)"
|
||||
>
|
||||
<!-- Present Action -->
|
||||
<ng-container
|
||||
*ngTemplateOutlet="itemActionTemplate; context: {action: action, data: item}"
|
||||
></ng-container>
|
||||
</ng-container>
|
||||
</x-slot>
|
||||
|
||||
<!-- END -->
|
||||
<x-slot [name]="SlotNames.END" [cssClass]="'ion-text-end'">
|
||||
<ng-container
|
||||
*ngFor="let action of getSlottedItemActions(SlotNames.END, item)"
|
||||
>
|
||||
<!-- Present Action -->
|
||||
<ng-container
|
||||
*ngTemplateOutlet="itemActionTemplate; context: {action: action, data: item}"
|
||||
></ng-container>
|
||||
</ng-container>
|
||||
</x-slot>
|
||||
</x-slotter>
|
||||
</ng-container>
|
||||
</div>
|
||||
</v-file>
|
||||
</ng-template>
|
||||
|
||||
<!-- Item Action Presenter -->
|
||||
<ng-template #itemActionTemplate let-action="action" let-data="data">
|
||||
<!-- Validate -->
|
||||
<ng-container
|
||||
*ngIf="(notNullOrUndefinedValue(data) | async) && (notNullOrUndefinedValue(action) | async)"
|
||||
>
|
||||
<!-- Present Action -->
|
||||
<x-button
|
||||
[loading]="loading"
|
||||
[icon]="action.icon"
|
||||
[title]="action.title"
|
||||
[color]="action.color"
|
||||
[foregroundColor]="true"
|
||||
[type]="ButtonTypes.Icon"
|
||||
[iconColor]="ColorNames.Transparent"
|
||||
(clicked)="handleItemAction(action.id, data)"
|
||||
[uiDisabled]="loading || uiDisabled || action.disabled"
|
||||
>
|
||||
</x-button>
|
||||
</ng-container>
|
||||
</ng-template>
|
||||
|
||||
<!-- -->
|
||||
<!-- List Item Template -->
|
||||
<!-- -->
|
||||
<ng-template #listItemTemplate let-item="item">
|
||||
<v-file
|
||||
class="v-list-item"
|
||||
[model]="item.data"
|
||||
[loading]="loading"
|
||||
[uiDisabled]="loading || uiDisabled"
|
||||
[presentType]="FilePresentTypes.AsItem"
|
||||
[actionProvider]="listItemActionProvider"
|
||||
*ngIf="notNullOrUndefinedValue(item) | async"
|
||||
[providedFieldDescriptors]="listItemViewFieldDescriptors"
|
||||
></v-file>
|
||||
</ng-template>
|
||||
|
||||
<!-- Owner Name in Lists Template -->
|
||||
<ng-template
|
||||
#listOwnerRef
|
||||
let-key="key"
|
||||
let-index="index"
|
||||
let-value="value"
|
||||
let-props="props"
|
||||
>
|
||||
{{ getOwnerFullName(value) }}
|
||||
</ng-template>
|
||||
|
||||
<!-- -->
|
||||
<!-- Add Item Template -->
|
||||
<!-- -->
|
||||
<ng-template #addItemTemplate>
|
||||
<v-file
|
||||
[model]="addModel"
|
||||
[loading]="loading"
|
||||
class="v-input-item"
|
||||
[showValidationErrors]="true"
|
||||
[cardTitle]="ResourceIDs.upload"
|
||||
[uiDisabled]="uiDisabled || loading"
|
||||
[actionProvider]="addItemActionProvider"
|
||||
[presentType]="FilePresentTypes.AsFileUpload"
|
||||
*ngIf="notNullOrUndefinedValue(addModel) | async"
|
||||
(lockNotifier)="handleAddViewLockNotifier($event)"
|
||||
(fileUploadActionFired)="handleFileUploadActionFired($event)"
|
||||
(fileUploadFilesChanged)="handleFileUploadFilesChanged($event)"
|
||||
>
|
||||
</v-file>
|
||||
</ng-template>
|
||||
|
||||
<!-- -->
|
||||
<!-- Update Item Template -->
|
||||
<!-- -->
|
||||
<ng-template #updateItemTemplate>
|
||||
<v-file
|
||||
[loading]="loading"
|
||||
class="v-input-item"
|
||||
[model]="updateModel"
|
||||
[showValidationErrors]="true"
|
||||
[cardTitle]="ResourceIDs.update"
|
||||
[uiDisabled]="uiDisabled || loading"
|
||||
[presentType]="BasePresentTypes.AsForm"
|
||||
[actionProvider]="updateItemActionProvider"
|
||||
*ngIf="notNullOrUndefinedValue(updateModel) | async"
|
||||
(lockNotifier)="handleUpdateViewLockNotifier($event)"
|
||||
(dtoModelActionFired)="handleUpdateViewActionFired($event)"
|
||||
[providedFieldDescriptors]="updateModelViewFieldDescriptors"
|
||||
>
|
||||
</v-file>
|
||||
</ng-template>
|
||||
|
||||
<!-- -->
|
||||
<!-- Details Item Template -->
|
||||
<!-- -->
|
||||
<ng-template #detailsItemTemplate>
|
||||
<v-file
|
||||
[loading]="loading"
|
||||
class="v-detail-item"
|
||||
[model]="detailsModel"
|
||||
[showValidationErrors]="false"
|
||||
[uiDisabled]="uiDisabled || loading"
|
||||
[presentType]="BasePresentTypes.AsView"
|
||||
[actionProvider]="detailsItemActionProvider"
|
||||
[cardTitle]="getModelCardTitle(detailsModel)"
|
||||
*ngIf="notNullOrUndefinedValue(detailsModel) | async"
|
||||
[providedFieldDescriptors]="detailsModelViewFieldDescriptors"
|
||||
>
|
||||
</v-file>
|
||||
</ng-template>
|
||||
|
||||
<!-- Detail File Name Template -->
|
||||
<ng-template
|
||||
#fileNameRef
|
||||
let-key="key"
|
||||
let-index="index"
|
||||
let-value="value"
|
||||
let-props="props"
|
||||
>
|
||||
<v-media
|
||||
[src]="value"
|
||||
style="--thumbnail-size: 128px;"
|
||||
[presentType]="MediaPresentTypes.AsThumbnail"
|
||||
></v-media>
|
||||
</ng-template>
|
||||
@@ -0,0 +1,20 @@
|
||||
.v-item,
|
||||
.v-list-item,
|
||||
.v-input-item,
|
||||
.v-detail-item {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.v-media-thumbnail-present {
|
||||
margin: {
|
||||
left: auto;
|
||||
right: auto;
|
||||
}
|
||||
}
|
||||
|
||||
:host ::ng-deep .v-media-thumbnail-present {
|
||||
margin: {
|
||||
left: auto !important;
|
||||
right: auto !important;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1 @@
|
||||
@import '../files-base//files-base.provider.page.scss';
|
||||
@@ -0,0 +1,42 @@
|
||||
import { Observable } from 'rxjs';
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { XQueryDto, XQueryResultDto } from 'x-framework-identity-sdk';
|
||||
import { FilesBaseProviderPage } from '../files-base/files-base.provider.page';
|
||||
|
||||
@Component({
|
||||
selector: 'files-explorer',
|
||||
styleUrls: ['./files-explorer.page.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
templateUrl: '../files-base/files-base.provider.page.html',
|
||||
})
|
||||
export class FilesExplorerPage extends FilesBaseProviderPage {
|
||||
//
|
||||
//#region Props ...
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region LifeCycles ...
|
||||
onInit(): void {
|
||||
super.onInit();
|
||||
|
||||
//
|
||||
this.configureAsExplorerPage();
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Abstractions ...
|
||||
getModelTask(identifier: string): Observable<any> {
|
||||
//
|
||||
return this.sharedService.mabsutAPIService.files.fileProviderService.get(
|
||||
identifier
|
||||
);
|
||||
}
|
||||
|
||||
queryModelTask(query: XQueryDto): Observable<XQueryResultDto<any>> {
|
||||
return this.sharedService.mabsutAPIService.files.fileProviderService.query(
|
||||
query
|
||||
);
|
||||
}
|
||||
//#endregion
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
@import '../files-base//files-base.provider.page.scss';
|
||||
@@ -0,0 +1,42 @@
|
||||
import { Observable } from 'rxjs';
|
||||
import { Component, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { XQueryDto, XQueryResultDto } from 'x-framework-identity-sdk';
|
||||
import { FilesBaseProviderPage } from '../files-base/files-base.provider.page';
|
||||
|
||||
@Component({
|
||||
selector: 'files-management',
|
||||
styleUrls: ['./files-management.page.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
templateUrl: '../files-base/files-base.provider.page.html',
|
||||
})
|
||||
export class FilesManagementPage extends FilesBaseProviderPage {
|
||||
//
|
||||
//#region Props ...
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region LifeCycles ...
|
||||
onInit(): void {
|
||||
super.onInit();
|
||||
|
||||
//
|
||||
this.configureAsManagementPage();
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Abstractions ...
|
||||
getModelTask(identifier: string): Observable<any> {
|
||||
//
|
||||
return this.sharedService.mabsutAPIService.files.fileProviderService.get(
|
||||
identifier
|
||||
);
|
||||
}
|
||||
|
||||
queryModelTask(query: XQueryDto): Observable<XQueryResultDto<any>> {
|
||||
return this.sharedService.mabsutAPIService.files.fileProviderService.query(
|
||||
query
|
||||
);
|
||||
}
|
||||
//#endregion
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { AuthGuard } from 'x-framework-identity-sdk';
|
||||
import { XCanDeactivateGuard } from 'x-framework-core';
|
||||
import { BaseRoutes } from 'src/app/config/page.config';
|
||||
import { ViewsModule } from 'src/app/views/views.module';
|
||||
import { FileRoutes } from 'src/app/views/files/v-file.configs';
|
||||
import { FilesExplorerPage } from './files-explorer/files-explorer.page';
|
||||
import { FilesManagementPage } from './files-management/files-management.page';
|
||||
|
||||
@NgModule({
|
||||
declarations: [FilesExplorerPage, FilesManagementPage],
|
||||
imports: [
|
||||
ViewsModule,
|
||||
RouterModule.forChild([
|
||||
{
|
||||
pathMatch: 'full',
|
||||
path: BaseRoutes.Default,
|
||||
redirectTo: FileRoutes.FilesExplorer,
|
||||
},
|
||||
//
|
||||
// Explorer ...
|
||||
{
|
||||
canActivate: [AuthGuard],
|
||||
component: FilesExplorerPage,
|
||||
canDeactivate: [XCanDeactivateGuard],
|
||||
path: FileRoutes.FilesExplorer,
|
||||
},
|
||||
//
|
||||
// Management ...
|
||||
{
|
||||
canActivate: [AuthGuard],
|
||||
component: FilesManagementPage,
|
||||
canDeactivate: [XCanDeactivateGuard],
|
||||
path: FileRoutes.FilesManagement,
|
||||
},
|
||||
{
|
||||
pathMatch: 'full',
|
||||
path: BaseRoutes.Unknown,
|
||||
redirectTo: FileRoutes.Default,
|
||||
},
|
||||
]),
|
||||
],
|
||||
exports: [ViewsModule, RouterModule, FilesExplorerPage, FilesManagementPage],
|
||||
})
|
||||
export class FilesPageModule {}
|
||||
@@ -0,0 +1,13 @@
|
||||
<!-- -->
|
||||
<!-- Page Presenter -->
|
||||
<!-- -->
|
||||
<v-page-presenter
|
||||
[containerBase]="this"
|
||||
[contentTemplate]="contentTemplate"
|
||||
></v-page-presenter>
|
||||
|
||||
<!-- -->
|
||||
<!-- Page Content -->
|
||||
<!-- -->
|
||||
<ng-template #contentTemplate>
|
||||
</ng-template>
|
||||
@@ -0,0 +1,56 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { VPageComponent } from 'src/app/views/v-page/v-page.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-components-home',
|
||||
templateUrl: './home.page.html',
|
||||
styleUrls: ['./home.page.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
// tslint:disable-next-line:component-class-suffix
|
||||
export class HomePage extends VPageComponent {
|
||||
//
|
||||
//#region Props ...
|
||||
toolbarShowTitle = true;
|
||||
toolbarShowSubTitle = true;
|
||||
titleRes = this.ResourceIDs.app_name;
|
||||
toolbarSubTitle = this.resourceProvider(this.AppResourceIDs.home_page_title);
|
||||
toolbarTitle = this.resourceProvider(this.titleRes);
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Constructor ...
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region LifeCycles ...
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Register Handlers ...
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Task Handlers ...
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region UI Providers ...
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region UI Handlers ...
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Actions ...
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Abstracts ...
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Private ...
|
||||
//#endregion
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<!-- -->
|
||||
<!-- Page Presenter -->
|
||||
<!-- -->
|
||||
<v-page-presenter
|
||||
[containerBase]="this"
|
||||
[contentTemplate]="contentTemplate"
|
||||
></v-page-presenter>
|
||||
|
||||
<!-- -->
|
||||
<!-- Page Content -->
|
||||
<!-- -->
|
||||
<ng-template #contentTemplate>
|
||||
</ng-template>
|
||||
@@ -0,0 +1,67 @@
|
||||
import { XStandardType } from 'x-framework-core';
|
||||
import { XSideType } from 'x-framework-components';
|
||||
import { Component, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { VPageComponent } from 'src/app/views/v-page/v-page.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-landing',
|
||||
templateUrl: './landing.page.html',
|
||||
styleUrls: ['./landing.page.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
// tslint:disable-next-line: component-class-suffix
|
||||
export class LandingPage extends VPageComponent {
|
||||
//
|
||||
//#region Props ...
|
||||
hasSide = true;
|
||||
showFooter = true;
|
||||
toolbarShowSubTitle = true;
|
||||
titleRes = this.AppResourceIDs.landing_page_title;
|
||||
toolbarSubTitle = this.resourceProvider(
|
||||
this.AppResourceIDs.landing_page_description
|
||||
);
|
||||
toolbarTitle = this.resourceProvider(this.titleRes);
|
||||
|
||||
/**
|
||||
* use this for Menu always Visible ...
|
||||
*/
|
||||
toggleMenuWhen = '';
|
||||
sideType: XStandardType<string> = XSideType.Overlay;
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Constructor ...
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region LifeCycles ...
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Register Handlers ...
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Handlers ...
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Task Handlers ...
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region UI Providers ...
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region UI Handlers ...
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Actions ...
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Private ...
|
||||
//#endregion
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<!-- -->
|
||||
<!-- Page Presenter -->
|
||||
<!-- -->
|
||||
<v-page-presenter
|
||||
[containerBase]="this"
|
||||
[contentTemplate]="contentTemplate"
|
||||
></v-page-presenter>
|
||||
|
||||
<!-- -->
|
||||
<!-- Page Content -->
|
||||
<!-- -->
|
||||
<ng-template #contentTemplate>
|
||||
</ng-template>
|
||||
@@ -0,0 +1,35 @@
|
||||
import { Pages } from 'src/app/config/page.config';
|
||||
import { Component, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { VPageComponent } from 'src/app/views/v-page/v-page.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-not-authorized',
|
||||
templateUrl: './not-authorized.page.html',
|
||||
styleUrls: ['./not-authorized.page.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
// tslint:disable-next-line: component-class-suffix
|
||||
export class NotAuthorizedPage extends VPageComponent {
|
||||
//
|
||||
//#region Page Props ...
|
||||
hasSide = false;
|
||||
toolbarHasBack = true;
|
||||
toolbarShowBack = true;
|
||||
showToolbarEndSlot = false;
|
||||
showToolbarContent = false;
|
||||
toolbarShowSubTitle = true;
|
||||
toolbarSubTitle = this.resourceProvider(this.titleRes);
|
||||
titleRes = this.AppResourceIDs.not_authorized_page_title;
|
||||
|
||||
//
|
||||
toolbarBackHandler = () => {
|
||||
//
|
||||
// TODO: Fix this ...
|
||||
// this.managerService.navigateByPageReplace(Pages.);
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Constructor ...
|
||||
//#endregion
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<!-- -->
|
||||
<!-- Page Presenter -->
|
||||
<!-- -->
|
||||
<v-page-presenter
|
||||
[containerBase]="this"
|
||||
[contentTemplate]="contentTemplate"
|
||||
></v-page-presenter>
|
||||
|
||||
<!-- -->
|
||||
<!-- Page Content -->
|
||||
<!-- -->
|
||||
<ng-template #contentTemplate>
|
||||
</ng-template>
|
||||
@@ -0,0 +1,180 @@
|
||||
import {
|
||||
XPage,
|
||||
XExceptionIDs,
|
||||
isNullOrUndefined,
|
||||
} from 'x-framework-core';
|
||||
import { Pages } from 'src/app/config/page.config';
|
||||
import { VPageComponent } from 'src/app/views/v-page/v-page.component';
|
||||
import { Component, ChangeDetectionStrategy } from '@angular/core';
|
||||
|
||||
const StartupKeys = {
|
||||
AuthLoadingID: 'auth_loading',
|
||||
};
|
||||
|
||||
@Component({
|
||||
selector: 'app-startup',
|
||||
templateUrl: './startup.page.html',
|
||||
styleUrls: ['./startup.page.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
// tslint:disable-next-line: component-class-suffix
|
||||
export class StartupPage extends VPageComponent {
|
||||
//
|
||||
//#region Configuration Props ...
|
||||
//
|
||||
hasSide = false;
|
||||
showToolbarEndSlot = false;
|
||||
showToolbarContent = false;
|
||||
|
||||
//
|
||||
hasBlogPage = !isNullOrUndefined(this.config.defaultBlogPage);
|
||||
hasLandingPage = !isNullOrUndefined(this.config.defaultLandingPage);
|
||||
|
||||
//
|
||||
private loadingModal: HTMLIonLoadingElement;
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Constructor ...
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region LifeCycle ...
|
||||
async onInit() {
|
||||
super.onInit();
|
||||
|
||||
//
|
||||
await this.handleStartUp();
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Private ...
|
||||
private async handleStartUp() {
|
||||
//
|
||||
await this.presentLoading(
|
||||
StartupKeys.AuthLoadingID,
|
||||
this.resourceProvider(this.AppResourceIDs.default_loading)
|
||||
);
|
||||
|
||||
//
|
||||
// Retrieve Account State ...
|
||||
const xAccountState = await this.sharedService.authService.currentState();
|
||||
const isAuthenticated = xAccountState ? xAccountState.isLoggedIn : false;
|
||||
if (!isAuthenticated) {
|
||||
//
|
||||
if (!this.hasBlogPage && !this.hasLandingPage) {
|
||||
//
|
||||
await this.dismissLoading(StartupKeys.AuthLoadingID);
|
||||
this.showError(XExceptionIDs.NotAuthorized);
|
||||
}
|
||||
|
||||
//
|
||||
await this.finishAction(Pages.Login);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Token Expiration ...
|
||||
const isExpiredToken = await this.sharedService.authService.isExpired();
|
||||
if (isExpiredToken) {
|
||||
//
|
||||
try {
|
||||
//
|
||||
const mTask = this.sharedService.authService.refreshTokens();
|
||||
|
||||
//
|
||||
const newTokens = await this.getValueAsync(mTask);
|
||||
|
||||
//
|
||||
await this.sharedService.authService.updateUserTokens(
|
||||
xAccountState,
|
||||
newTokens
|
||||
);
|
||||
|
||||
//
|
||||
await this.finishAction(Pages.Home);
|
||||
} catch {
|
||||
//
|
||||
if (!this.hasBlogPage && !this.hasLandingPage) {
|
||||
await this.handleErrorState(XExceptionIDs.LoginFailed, true);
|
||||
}
|
||||
|
||||
//
|
||||
await this.sharedService.authService.logout();
|
||||
await this.finishAction(Pages.Login);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
if (!this.hasBlogPage && !this.hasLandingPage) {
|
||||
//
|
||||
await this.finishAction(Pages.Login);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
await this.finishAction(Pages.Home);
|
||||
return;
|
||||
}
|
||||
|
||||
private async finishAction(dest?: XPage) {
|
||||
//
|
||||
await this.dismissLoading(StartupKeys.AuthLoadingID);
|
||||
|
||||
//
|
||||
if (this.hasBlogPage && !this.hasLandingPage) {
|
||||
//
|
||||
await this.managerService.navigateByPageReplace(
|
||||
this.config.defaultBlogPage
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
if (this.hasLandingPage) {
|
||||
//
|
||||
await this.managerService.navigateByPageReplace(
|
||||
this.config.defaultLandingPage
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
if (!isNullOrUndefined(dest)) {
|
||||
await this.managerService.navigateByPageReplace(dest);
|
||||
}
|
||||
}
|
||||
|
||||
private async presentLoading(id: string, message: string) {
|
||||
//
|
||||
if (!isNullOrUndefined(this.loadingModal) && this.loadingModal) {
|
||||
await this.dismissLoading(StartupKeys.AuthLoadingID);
|
||||
}
|
||||
|
||||
//
|
||||
this.loadingModal = await this.managerService.dialogService.presentLoading({
|
||||
id,
|
||||
message,
|
||||
});
|
||||
}
|
||||
|
||||
private async dismissLoading(id: string) {
|
||||
//
|
||||
if (isNullOrUndefined(this.loadingModal)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
const result =
|
||||
await this.managerService.dialogService.loadingController.dismiss(id);
|
||||
if (!!result) {
|
||||
this.loadingModal = undefined;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
//#endregion
|
||||
}
|
||||
@@ -0,0 +1,240 @@
|
||||
<!-- -->
|
||||
<!-- Page Presenter -->
|
||||
<!-- -->
|
||||
<v-page-presenter
|
||||
#pagePresenter
|
||||
[loading]="loading"
|
||||
[containerBase]="this"
|
||||
[uiDisabled]="uiDisabled"
|
||||
[contentTemplate]="contentTemplate"
|
||||
(xOnEscapeGlobal)="handleGlobalEscapePressed($event)"
|
||||
></v-page-presenter>
|
||||
|
||||
<!-- -->
|
||||
<!-- Page Content -->
|
||||
<!-- -->
|
||||
<ng-template #contentTemplate>
|
||||
<!-- Query Presenter -->
|
||||
<v-query-presenter
|
||||
[loading]="loading"
|
||||
[tabsLock]="tabsLock"
|
||||
[tabsColor]="tabsColor"
|
||||
[showEmpty]="showEmpty"
|
||||
[emptyColor]="emptyColor"
|
||||
[addTabTitle]="addTabTitle"
|
||||
[itemTemplate]="itemTemplate"
|
||||
[emptyMessage]="emptyMessage"
|
||||
[tabsCssClass]="tabsCssClass"
|
||||
[tabsLoopTabs]="tabsLoopTabs"
|
||||
[tabsSwipable]="tabsSwipable"
|
||||
[listTabTitle]="listTabTitle"
|
||||
[emptyCssClass]="emptyCssClass"
|
||||
[showPaginator]="showPaginator"
|
||||
[tabsAlignTabs]="tabsAlignTabs"
|
||||
[showSearchBar]="showSearchBar"
|
||||
[searchBarType]="searchBarType"
|
||||
[searchBarValue]="searchBarValue"
|
||||
[searchBarTitle]="searchBarTitle"
|
||||
[searchBarColor]="searchBarColor"
|
||||
[updateTabTitle]="updateTabTitle"
|
||||
[paginatorColor]="paginatorColor"
|
||||
[tabsShowHeader]="tabsShowHeader"
|
||||
[addItemTemplate]="addItemTemplate"
|
||||
[emptyHasRefresh]="emptyHasRefresh"
|
||||
[detailsTabTitle]="detailsTabTitle"
|
||||
[tabsHeaderColor]="tabsHeaderColor"
|
||||
[showItemsAsList]="showItemsAsList"
|
||||
[modelIdentifier]="modelIdentifier"
|
||||
[uiDisabled]="loading || uiDisabled"
|
||||
[listItemTemplate]="listItemTemplate"
|
||||
[listTabCardTitle]="listTabCardTitle"
|
||||
[listTabCardColor]="listTabCardColor"
|
||||
[emptyRefreshIcon]="emptyRefreshIcon"
|
||||
[emptyMessageColor]="emptyMessageColor"
|
||||
[paginatorPosition]="paginatorPosition"
|
||||
[tabsSelectedIndex]="tabsSelectedIndex"
|
||||
[tabsDynamicHeight]="tabsDynamicHeight"
|
||||
[tabsDisableRipple]="tabsDisableRipple"
|
||||
[searchBarDebounce]="searchBarDebounce"
|
||||
[searchBarCssClass]="searchBarCssClass"
|
||||
[updateItemTemplate]="updateItemTemplate"
|
||||
[tabsHeaderPosition]="tabsHeaderPosition"
|
||||
[tabsActiveTabColor]="tabsActiveTabColor"
|
||||
[searchBarSpellcheck]="searchBarSpellcheck"
|
||||
[detailsItemTemplate]="detailsItemTemplate"
|
||||
[wrapListTabWithCard]="wrapListTabWithCard"
|
||||
[listTabCardIsInPage]="listTabCardIsInPage"
|
||||
[listTabCardSubTitle]="listTabCardSubTitle"
|
||||
[emptyForegroundColor]="emptyForegroundColor"
|
||||
[actionProvider]="queryPresenterActionProvider"
|
||||
[tabsDisablePagination]="tabsDisablePagination"
|
||||
[tabsAnimationDuration]="tabsAnimationDuration"
|
||||
[tabsTabIndicatorColor]="tabsTabIndicatorColor"
|
||||
[tabsTabPaginatorColor]="tabsTabPaginatorColor"
|
||||
[searchBarKeyboardType]="searchBarKeyboardType"
|
||||
[searchBarEnterKeyHint]="searchBarEnterKeyHint"
|
||||
[emptyRefreshButtonColor]="emptyRefreshButtonColor"
|
||||
[searchBarForegroundColor]="searchBarForegroundColor"
|
||||
[searchBarShowClearButton]="searchBarShowClearButton"
|
||||
[searchBarClearButtonIcon]="searchBarClearButtonIcon"
|
||||
[searchBarCancelButtonIcon]="searchBarCancelButtonIcon"
|
||||
[searchBarSearchButtonIcon]="searchBarSearchButtonIcon"
|
||||
[searchBarSearchInputColor]="searchBarSearchInputColor"
|
||||
[searchBarShowCancelButton]="searchBarShowCancelButton"
|
||||
[searchBarCancelButtonTitle]="searchBarCancelButtonTitle"
|
||||
[emptyForegroundMessageColor]="emptyForegroundMessageColor"
|
||||
[searchBarClearButtonIconColor]="searchBarClearButtonIconColor"
|
||||
[searchBarCancelButtonIconColor]="searchBarCancelButtonIconColor"
|
||||
[searchBarSearchButtonIconColor]="searchBarSearchButtonIconColor"
|
||||
[emptyForegroundRefreshButtonColor]="emptyForegroundRefreshButtonColor"
|
||||
[searchBarForegroundSearchInputColor]="searchBarForegroundSearchInputColor"
|
||||
>
|
||||
</v-query-presenter>
|
||||
</ng-template>
|
||||
|
||||
<!-- -->
|
||||
<!-- Item Template -->
|
||||
<!-- -->
|
||||
<ng-template #itemTemplate let-item="item">
|
||||
<v-tag
|
||||
[model]="item"
|
||||
class="v-item"
|
||||
[loading]="loading"
|
||||
[uiDisabled]="loading || uiDisabled"
|
||||
[cardTitle]="getModelCardTitle(item)"
|
||||
[presentType]="BasePresentTypes.AsView"
|
||||
[actionProvider]="listItemActionProvider"
|
||||
*ngIf="notNullOrUndefinedValue(item) | async"
|
||||
[providedFieldDescriptors]="listItemViewFieldDescriptors"
|
||||
>
|
||||
<div actions *ngIf="(notNullOrUndefinedValue(item) | async)">
|
||||
<ng-container *ngIf="itemsActions.has(item.id.toString())">
|
||||
<!-- Slotting Actions -->
|
||||
<x-slotter [hasCenterSlot]="false" [layout]="SlotLayouts.HORIZONTAL">
|
||||
<!-- START -->
|
||||
<x-slot [name]="SlotNames.START" [cssClass]="'ion-text-start'">
|
||||
<ng-container
|
||||
*ngFor="let action of getSlottedItemActions(SlotNames.START, item)"
|
||||
>
|
||||
<!-- Present Action -->
|
||||
<ng-container
|
||||
*ngTemplateOutlet="itemActionTemplate; context: {action: action, data: item}"
|
||||
></ng-container>
|
||||
</ng-container>
|
||||
</x-slot>
|
||||
|
||||
<!-- END -->
|
||||
<x-slot [name]="SlotNames.END" [cssClass]="'ion-text-end'">
|
||||
<ng-container
|
||||
*ngFor="let action of getSlottedItemActions(SlotNames.END, item)"
|
||||
>
|
||||
<!-- Present Action -->
|
||||
<ng-container
|
||||
*ngTemplateOutlet="itemActionTemplate; context: {action: action, data: item}"
|
||||
></ng-container>
|
||||
</ng-container>
|
||||
</x-slot>
|
||||
</x-slotter>
|
||||
</ng-container>
|
||||
</div>
|
||||
</v-tag>
|
||||
</ng-template>
|
||||
|
||||
<!-- Item Action Presenter -->
|
||||
<ng-template #itemActionTemplate let-action="action" let-data="data">
|
||||
<!-- Validate -->
|
||||
<ng-container
|
||||
*ngIf="(notNullOrUndefinedValue(data) | async) && (notNullOrUndefinedValue(action) | async)"
|
||||
>
|
||||
<!-- Present Action -->
|
||||
<x-button
|
||||
[loading]="loading"
|
||||
[icon]="action.icon"
|
||||
[title]="action.title"
|
||||
[color]="action.color"
|
||||
[foregroundColor]="true"
|
||||
[type]="ButtonTypes.Icon"
|
||||
[iconColor]="ColorNames.Transparent"
|
||||
(clicked)="handleItemAction(action.id, data)"
|
||||
[uiDisabled]="loading || uiDisabled || action.disabled"
|
||||
>
|
||||
</x-button>
|
||||
</ng-container>
|
||||
</ng-template>
|
||||
|
||||
<!-- -->
|
||||
<!-- List Item Template -->
|
||||
<!-- -->
|
||||
<ng-template #listItemTemplate let-item="item">
|
||||
<v-tag
|
||||
class="v-list-item"
|
||||
[model]="item.data"
|
||||
[loading]="loading"
|
||||
[uiDisabled]="loading || uiDisabled"
|
||||
[presentType]="TagPresentTypes.AsView"
|
||||
[actionProvider]="listItemActionProvider"
|
||||
*ngIf="notNullOrUndefinedValue(item) | async"
|
||||
[providedFieldDescriptors]="listItemViewFieldDescriptors"
|
||||
></v-tag>
|
||||
</ng-template>
|
||||
|
||||
<!-- -->
|
||||
<!-- Add Item Template -->
|
||||
<!-- -->
|
||||
<ng-template #addItemTemplate>
|
||||
<v-tag
|
||||
[model]="addModel"
|
||||
[loading]="loading"
|
||||
class="v-input-item"
|
||||
[showValidationErrors]="true"
|
||||
[cardTitle]="ResourceIDs.add"
|
||||
[uiDisabled]="uiDisabled || loading"
|
||||
[presentType]="BasePresentTypes.AsForm"
|
||||
[actionProvider]="addItemActionProvider"
|
||||
*ngIf="notNullOrUndefinedValue(addModel) | async"
|
||||
(lockNotifier)="handleAddViewLockNotifier($event)"
|
||||
(dtoModelActionFired)="handleAddViewActionFired($event)"
|
||||
[providedFieldDescriptors]="addModelViewFieldDescriptors"
|
||||
>
|
||||
</v-tag>
|
||||
</ng-template>
|
||||
|
||||
<!-- -->
|
||||
<!-- Update Item Template -->
|
||||
<!-- -->
|
||||
<ng-template #updateItemTemplate>
|
||||
<v-tag
|
||||
[loading]="loading"
|
||||
class="v-input-item"
|
||||
[model]="updateModel"
|
||||
[showValidationErrors]="true"
|
||||
[cardTitle]="ResourceIDs.update"
|
||||
[uiDisabled]="uiDisabled || loading"
|
||||
[presentType]="BasePresentTypes.AsForm"
|
||||
[actionProvider]="updateItemActionProvider"
|
||||
*ngIf="notNullOrUndefinedValue(updateModel) | async"
|
||||
(lockNotifier)="handleUpdateViewLockNotifier($event)"
|
||||
(dtoModelActionFired)="handleUpdateViewActionFired($event)"
|
||||
[providedFieldDescriptors]="updateModelViewFieldDescriptors"
|
||||
>
|
||||
</v-tag>
|
||||
</ng-template>
|
||||
|
||||
<!-- -->
|
||||
<!-- Details Item Template -->
|
||||
<!-- -->
|
||||
<ng-template #detailsItemTemplate>
|
||||
<v-tag
|
||||
[loading]="loading"
|
||||
class="v-detail-item"
|
||||
[model]="detailsModel"
|
||||
[showValidationErrors]="false"
|
||||
[uiDisabled]="uiDisabled || loading"
|
||||
[presentType]="BasePresentTypes.AsView"
|
||||
[actionProvider]="detailsItemActionProvider"
|
||||
[cardTitle]="getModelCardTitle(detailsModel)"
|
||||
*ngIf="notNullOrUndefinedValue(detailsModel) | async"
|
||||
[providedFieldDescriptors]="detailsModelViewFieldDescriptors"
|
||||
>
|
||||
</v-tag>
|
||||
</ng-template>
|
||||
@@ -0,0 +1,7 @@
|
||||
.v-item,
|
||||
.v-list-item,
|
||||
.v-input-item,
|
||||
.v-detail-item
|
||||
{
|
||||
width: 100%;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1 @@
|
||||
@import '../tags-base/tags-base.provider.page.scss';
|
||||
@@ -0,0 +1,42 @@
|
||||
import { Observable } from 'rxjs';
|
||||
import { toNumber } from 'x-framework-core';
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { XQueryDto, XQueryResultDto } from 'x-framework-identity-sdk';
|
||||
import { TagsBaseProviderPage } from '../tags-base/tags-base.provider.page';
|
||||
|
||||
@Component({
|
||||
selector: 'tags-explorer',
|
||||
styleUrls: ['./tags-explorer.page.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
templateUrl: '../tags-base/tags-base.provider.page.html',
|
||||
})
|
||||
export class TagsExplorerPage extends TagsBaseProviderPage {
|
||||
//
|
||||
//#region Props ...
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region LifeCycles ...
|
||||
onInit(): void {
|
||||
super.onInit();
|
||||
|
||||
//
|
||||
this.configureAsExplorerPage();
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Abstractions ...
|
||||
getModelTask(identifier: string): Observable<any> {
|
||||
//
|
||||
return this.sharedService.mabsutAPIService.tags.tagProviderService
|
||||
.get(toNumber(identifier));
|
||||
}
|
||||
|
||||
queryModelTask(query: XQueryDto): Observable<XQueryResultDto<any>> {
|
||||
return this.sharedService.mabsutAPIService.tags.tagProviderService.query(
|
||||
query
|
||||
);
|
||||
}
|
||||
//#endregion
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
@import '../tags-base/tags-base.provider.page.scss';
|
||||
@@ -0,0 +1,43 @@
|
||||
import { Observable } from 'rxjs';
|
||||
import { toNumber } from 'x-framework-core';
|
||||
import { Component, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { XQueryDto, XQueryResultDto } from 'x-framework-identity-sdk';
|
||||
import { TagsBaseProviderPage } from '../tags-base/tags-base.provider.page';
|
||||
|
||||
@Component({
|
||||
selector: 'tags-management',
|
||||
styleUrls: ['./tags-management.page.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
templateUrl: '../tags-base/tags-base.provider.page.html',
|
||||
})
|
||||
export class TagsManagementPage extends TagsBaseProviderPage {
|
||||
//
|
||||
//#region Props ...
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region LifeCycles ...
|
||||
onInit(): void {
|
||||
super.onInit();
|
||||
|
||||
//
|
||||
this.configureAsManagementPage();
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Abstractions ...
|
||||
getModelTask(identifier: string): Observable<any> {
|
||||
//
|
||||
return this.sharedService.mabsutAPIService.tags.tagProviderService.get(
|
||||
toNumber(identifier)
|
||||
);
|
||||
}
|
||||
|
||||
queryModelTask(query: XQueryDto): Observable<XQueryResultDto<any>> {
|
||||
return this.sharedService.mabsutAPIService.tags.tagProviderService.query(
|
||||
query
|
||||
);
|
||||
}
|
||||
//#endregion
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { AuthGuard } from 'x-framework-identity-sdk';
|
||||
import { XCanDeactivateGuard } from 'x-framework-core';
|
||||
import { BaseRoutes } from 'src/app/config/page.config';
|
||||
import { ViewsModule } from 'src/app/views/views.module';
|
||||
import { TagRoutes } from 'src/app/views/tags/v-tag.configs';
|
||||
import { TagsExplorerPage } from './tags-explorer/tags-explorer.page';
|
||||
import { TagsManagementPage } from './tags-management/tags-management.page';
|
||||
|
||||
@NgModule({
|
||||
declarations: [TagsExplorerPage, TagsManagementPage],
|
||||
imports: [
|
||||
ViewsModule,
|
||||
RouterModule.forChild([
|
||||
{
|
||||
pathMatch: 'full',
|
||||
path: BaseRoutes.Default,
|
||||
redirectTo: TagRoutes.TagsExplorer,
|
||||
},
|
||||
//
|
||||
// Tags Explorer ...
|
||||
{
|
||||
canActivate: [AuthGuard],
|
||||
component: TagsExplorerPage,
|
||||
canDeactivate: [XCanDeactivateGuard],
|
||||
path: TagRoutes.TagsExplorer,
|
||||
},
|
||||
//
|
||||
// Tags Management ...
|
||||
{
|
||||
canActivate: [AuthGuard],
|
||||
component: TagsManagementPage,
|
||||
canDeactivate: [XCanDeactivateGuard],
|
||||
path: TagRoutes.TagsManagement,
|
||||
},
|
||||
{
|
||||
pathMatch: 'full',
|
||||
path: BaseRoutes.Unknown,
|
||||
redirectTo: TagRoutes.Default,
|
||||
},
|
||||
]),
|
||||
],
|
||||
exports: [ViewsModule, RouterModule, TagsExplorerPage, TagsManagementPage],
|
||||
})
|
||||
export class TagsPageModule {}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { XLocale } from 'x-framework-core';
|
||||
import { AppResourceIDs } from 'src/app/config/localization.config';
|
||||
|
||||
export function getLocaleResourceID(locale: XLocale) {
|
||||
//
|
||||
if (locale === 'en-US') {
|
||||
return AppResourceIDs.english;
|
||||
} else if (locale === 'fa-IR') {
|
||||
return AppResourceIDs.persian;
|
||||
}
|
||||
|
||||
//
|
||||
return locale;
|
||||
}
|
||||
@@ -0,0 +1,268 @@
|
||||
<!-- -->
|
||||
<!-- Page Presenter -->
|
||||
<!-- -->
|
||||
<v-page-presenter
|
||||
#pagePresenter
|
||||
[loading]="loading"
|
||||
[containerBase]="this"
|
||||
[uiDisabled]="uiDisabled"
|
||||
[contentTemplate]="contentTemplate"
|
||||
(xOnEscapeGlobal)="handleGlobalEscapePressed($event)"
|
||||
></v-page-presenter>
|
||||
|
||||
<!-- -->
|
||||
<!-- Page Content -->
|
||||
<!-- -->
|
||||
<ng-template #contentTemplate>
|
||||
<!-- Item List -->
|
||||
<v-query-presenter
|
||||
[loading]="loading"
|
||||
[tabsLock]="tabsLock"
|
||||
[tabsColor]="tabsColor"
|
||||
[showEmpty]="showEmpty"
|
||||
[emptyColor]="emptyColor"
|
||||
[addTabTitle]="addTabTitle"
|
||||
[itemTemplate]="itemTemplate"
|
||||
[emptyMessage]="emptyMessage"
|
||||
[tabsCssClass]="tabsCssClass"
|
||||
[tabsLoopTabs]="tabsLoopTabs"
|
||||
[tabsSwipable]="tabsSwipable"
|
||||
[listTabTitle]="listTabTitle"
|
||||
[emptyCssClass]="emptyCssClass"
|
||||
[showPaginator]="showPaginator"
|
||||
[tabsAlignTabs]="tabsAlignTabs"
|
||||
[showSearchBar]="showSearchBar"
|
||||
[searchBarType]="searchBarType"
|
||||
[searchBarValue]="searchBarValue"
|
||||
[searchBarTitle]="searchBarTitle"
|
||||
[searchBarColor]="searchBarColor"
|
||||
[updateTabTitle]="updateTabTitle"
|
||||
[paginatorColor]="paginatorColor"
|
||||
[tabsShowHeader]="tabsShowHeader"
|
||||
[addItemTemplate]="addItemTemplate"
|
||||
[emptyHasRefresh]="emptyHasRefresh"
|
||||
[detailsTabTitle]="detailsTabTitle"
|
||||
[tabsHeaderColor]="tabsHeaderColor"
|
||||
[showItemsAsList]="showItemsAsList"
|
||||
[modelIdentifier]="modelIdentifier"
|
||||
[uiDisabled]="loading || uiDisabled"
|
||||
[listItemTemplate]="listItemTemplate"
|
||||
[listTabCardTitle]="listTabCardTitle"
|
||||
[listTabCardColor]="listTabCardColor"
|
||||
[emptyRefreshIcon]="emptyRefreshIcon"
|
||||
[emptyMessageColor]="emptyMessageColor"
|
||||
[paginatorPosition]="paginatorPosition"
|
||||
[tabsSelectedIndex]="tabsSelectedIndex"
|
||||
[tabsDynamicHeight]="tabsDynamicHeight"
|
||||
[tabsDisableRipple]="tabsDisableRipple"
|
||||
[searchBarDebounce]="searchBarDebounce"
|
||||
[searchBarCssClass]="searchBarCssClass"
|
||||
[updateItemTemplate]="updateItemTemplate"
|
||||
[tabsHeaderPosition]="tabsHeaderPosition"
|
||||
[tabsActiveTabColor]="tabsActiveTabColor"
|
||||
[searchBarSpellcheck]="searchBarSpellcheck"
|
||||
[detailsItemTemplate]="detailsItemTemplate"
|
||||
[wrapListTabWithCard]="wrapListTabWithCard"
|
||||
[listTabCardIsInPage]="listTabCardIsInPage"
|
||||
[listTabCardSubTitle]="listTabCardSubTitle"
|
||||
[emptyForegroundColor]="emptyForegroundColor"
|
||||
[actionProvider]="queryPresenterActionProvider"
|
||||
[tabsDisablePagination]="tabsDisablePagination"
|
||||
[tabsAnimationDuration]="tabsAnimationDuration"
|
||||
[tabsTabIndicatorColor]="tabsTabIndicatorColor"
|
||||
[tabsTabPaginatorColor]="tabsTabPaginatorColor"
|
||||
[searchBarKeyboardType]="searchBarKeyboardType"
|
||||
[searchBarEnterKeyHint]="searchBarEnterKeyHint"
|
||||
[emptyRefreshButtonColor]="emptyRefreshButtonColor"
|
||||
[searchBarForegroundColor]="searchBarForegroundColor"
|
||||
[searchBarShowClearButton]="searchBarShowClearButton"
|
||||
[searchBarClearButtonIcon]="searchBarClearButtonIcon"
|
||||
[searchBarCancelButtonIcon]="searchBarCancelButtonIcon"
|
||||
[searchBarSearchButtonIcon]="searchBarSearchButtonIcon"
|
||||
[searchBarSearchInputColor]="searchBarSearchInputColor"
|
||||
[searchBarShowCancelButton]="searchBarShowCancelButton"
|
||||
[searchBarCancelButtonTitle]="searchBarCancelButtonTitle"
|
||||
[emptyForegroundMessageColor]="emptyForegroundMessageColor"
|
||||
[searchBarClearButtonIconColor]="searchBarClearButtonIconColor"
|
||||
[searchBarCancelButtonIconColor]="searchBarCancelButtonIconColor"
|
||||
[searchBarSearchButtonIconColor]="searchBarSearchButtonIconColor"
|
||||
[emptyForegroundRefreshButtonColor]="emptyForegroundRefreshButtonColor"
|
||||
[searchBarForegroundSearchInputColor]="searchBarForegroundSearchInputColor"
|
||||
>
|
||||
</v-query-presenter>
|
||||
</ng-template>
|
||||
|
||||
<!-- -->
|
||||
<!-- Item Template -->
|
||||
<!-- -->
|
||||
<ng-template #itemTemplate let-item="item">
|
||||
<v-webinar-view
|
||||
[model]="item"
|
||||
[showTags]="false"
|
||||
[loading]="loading"
|
||||
[uiDisabled]="loading || uiDisabled"
|
||||
[cardTitle]="getModelCardTitle(item)"
|
||||
[presentType]="BasePresentTypes.AsView"
|
||||
[actionProvider]="listItemActionProvider"
|
||||
*ngIf="notNullOrUndefinedValue(item) | async"
|
||||
[providedFieldDescriptors]="listItemViewFieldDescriptors"
|
||||
>
|
||||
<div actions *ngIf="(notNullOrUndefinedValue(item) | async)">
|
||||
<ng-container *ngIf="itemsActions.has(item.id)">
|
||||
<!-- Slotting Actions -->
|
||||
<x-slotter [hasCenterSlot]="false" [layout]="SlotLayouts.HORIZONTAL">
|
||||
<!-- START -->
|
||||
<x-slot [name]="SlotNames.START" [cssClass]="'ion-text-start'">
|
||||
<ng-container
|
||||
*ngFor="let action of getSlottedItemActions(SlotNames.START, item)"
|
||||
>
|
||||
<!-- Present Action -->
|
||||
<ng-container
|
||||
*ngTemplateOutlet="itemActionTemplate; context: {action: action, data: item}"
|
||||
></ng-container>
|
||||
</ng-container>
|
||||
</x-slot>
|
||||
|
||||
<!-- END -->
|
||||
<x-slot [name]="SlotNames.END" [cssClass]="'ion-text-end'">
|
||||
<ng-container
|
||||
*ngFor="let action of getSlottedItemActions(SlotNames.END, item)"
|
||||
>
|
||||
<!-- Present Action -->
|
||||
<ng-container
|
||||
*ngTemplateOutlet="itemActionTemplate; context: {action: action, data: item}"
|
||||
></ng-container>
|
||||
</ng-container>
|
||||
</x-slot>
|
||||
</x-slotter>
|
||||
</ng-container>
|
||||
</div>
|
||||
</v-webinar-view>
|
||||
</ng-template>
|
||||
|
||||
<!-- Item Action Presenter -->
|
||||
<ng-template #itemActionTemplate let-action="action" let-data="data">
|
||||
<!-- Validate -->
|
||||
<ng-container
|
||||
*ngIf="(notNullOrUndefinedValue(data) | async) && (notNullOrUndefinedValue(action) | async)"
|
||||
>
|
||||
<!-- Present Action -->
|
||||
<x-button
|
||||
[loading]="loading"
|
||||
[icon]="action.icon"
|
||||
[title]="action.title"
|
||||
[color]="action.color"
|
||||
[foregroundColor]="true"
|
||||
[type]="ButtonTypes.Icon"
|
||||
[iconColor]="ColorNames.Transparent"
|
||||
(clicked)="handleItemAction(action.id, data)"
|
||||
[uiDisabled]="loading || uiDisabled || action.disabled"
|
||||
>
|
||||
</x-button>
|
||||
</ng-container>
|
||||
</ng-template>
|
||||
|
||||
<!-- -->
|
||||
<!-- List Item Template -->
|
||||
<!-- -->
|
||||
<ng-template #listItemTemplate let-item="item">
|
||||
<v-webinar-view
|
||||
[showTags]="false"
|
||||
[model]="item.data"
|
||||
[loading]="loading"
|
||||
[uiDisabled]="loading || uiDisabled"
|
||||
[presentType]="BasePresentTypes.AsView"
|
||||
[actionProvider]="listItemActionProvider"
|
||||
*ngIf="notNullOrUndefinedValue(item) | async"
|
||||
[providedFieldDescriptors]="listItemViewFieldDescriptors"
|
||||
></v-webinar-view>
|
||||
</ng-template>
|
||||
|
||||
<!-- Webinar Owner Name in Lists Template -->
|
||||
<ng-template
|
||||
#listOwnerRef
|
||||
let-key="key"
|
||||
let-index="index"
|
||||
let-value="value"
|
||||
let-props="props"
|
||||
>
|
||||
{{ getOwnerFullName(value) }}
|
||||
</ng-template>
|
||||
|
||||
<!-- -->
|
||||
<!-- Add Item Template -->
|
||||
<!-- -->
|
||||
<ng-template #addItemTemplate>
|
||||
<v-webinar-view
|
||||
[showTags]="true"
|
||||
[showFiles]="true"
|
||||
[model]="addModel"
|
||||
[loading]="loading"
|
||||
[showTagsLabel]="true"
|
||||
[showFilesLabel]="true"
|
||||
[showValidationErrors]="true"
|
||||
[cardTitle]="ResourceIDs.add"
|
||||
[uiDisabled]="uiDisabled || loading"
|
||||
[presentType]="BasePresentTypes.AsForm"
|
||||
[actionProvider]="addItemActionProvider"
|
||||
*ngIf="notNullOrUndefinedValue(addModel) | async"
|
||||
(lockNotifier)="handleAddViewLockNotifier($event)"
|
||||
(tagsStateChanged)="handleTagsStateChanged($event)"
|
||||
(filesStateChanged)="handleFilesStateChanged($event)"
|
||||
(dtoModelActionFired)="handleAddViewActionFired($event)"
|
||||
[providedFieldDescriptors]="addModelViewFieldDescriptors"
|
||||
>
|
||||
</v-webinar-view>
|
||||
</ng-template>
|
||||
|
||||
<!-- -->
|
||||
<!-- Update Item Template -->
|
||||
<!-- -->
|
||||
<ng-template #updateItemTemplate>
|
||||
<v-webinar-view
|
||||
[showTags]="true"
|
||||
[showFiles]="true"
|
||||
[loading]="loading"
|
||||
[model]="updateModel"
|
||||
[showTagsLabel]="true"
|
||||
[showFilesLabel]="true"
|
||||
[showValidationErrors]="true"
|
||||
[cardTitle]="ResourceIDs.update"
|
||||
[uiDisabled]="uiDisabled || loading"
|
||||
[presentType]="BasePresentTypes.AsForm"
|
||||
[actionProvider]="updateItemActionProvider"
|
||||
(tagsStateChanged)="handleTagsStateChanged($event)"
|
||||
(filesStateChanged)="handleFilesStateChanged($event)"
|
||||
*ngIf="notNullOrUndefinedValue(updateModel) | async"
|
||||
(lockNotifier)="handleUpdateViewLockNotifier($event)"
|
||||
(dtoModelActionFired)="handleUpdateViewActionFired($event)"
|
||||
[providedFieldDescriptors]="updateModelViewFieldDescriptors"
|
||||
>
|
||||
</v-webinar-view>
|
||||
</ng-template>
|
||||
|
||||
<!-- -->
|
||||
<!-- Details Item Template -->
|
||||
<!-- -->
|
||||
<ng-template #detailsItemTemplate>
|
||||
<v-webinar-view
|
||||
[showTags]="true"
|
||||
[showFiles]="true"
|
||||
[loading]="loading"
|
||||
[showTagsLabel]="true"
|
||||
[showFilesLabel]="true"
|
||||
[model]="detailsModel"
|
||||
[showValidationErrors]="false"
|
||||
[uiDisabled]="uiDisabled || loading"
|
||||
[presentType]="BasePresentTypes.AsView"
|
||||
[actionProvider]="detailsItemActionProvider"
|
||||
[cardTitle]="getModelCardTitle(detailsModel)"
|
||||
[tagActionsProvider]="detailsTagsActionsProvider"
|
||||
[fileActionsProvider]="detailsFilesActionsProvider"
|
||||
*ngIf="notNullOrUndefinedValue(detailsModel) | async"
|
||||
[tagsPresentType]="TagsPresenterPresertTypes.AsChips"
|
||||
[filesPresentType]="FilesPresenterPresertTypes.AsThumbnails"
|
||||
[providedFieldDescriptors]="detailsModelViewFieldDescriptors"
|
||||
>
|
||||
</v-webinar-view>
|
||||
</ng-template>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,48 @@
|
||||
import { Observable } from 'rxjs';
|
||||
import { concatMap } from 'rxjs/operators';
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { XQueryDto, XQueryResultDto } from 'x-framework-identity-sdk';
|
||||
import { ToWebinarViewDto } from 'src/app/views/webinar/v-webinar.tools';
|
||||
import { WebinarsBaseProviderPage } from '../webinars-base/webinars-base.provider.page';
|
||||
|
||||
@Component({
|
||||
selector: 'webinars-explorer',
|
||||
styleUrls: ['./webinars-explorer.page.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
templateUrl: '../webinars-base/webinars-base.provider.page.html',
|
||||
})
|
||||
export class WebinarsExplorerPage extends WebinarsBaseProviderPage {
|
||||
//
|
||||
//#region Props ...
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region LifeCycles ...
|
||||
onInit(): void {
|
||||
super.onInit();
|
||||
|
||||
//
|
||||
this.configureAsExplorerPage();
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Abstractions ...
|
||||
getModelTask(identifier: string): Observable<any> {
|
||||
//
|
||||
return this.sharedService.mabsutAPIService.webinars.webinarProviderService
|
||||
.get(identifier)
|
||||
.pipe(
|
||||
concatMap((m) =>
|
||||
this.getValue(ToWebinarViewDto(m, this.managerService.currentLocale))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
queryModelTask(query: XQueryDto): Observable<XQueryResultDto<any>> {
|
||||
return this.sharedService.mabsutAPIService.webinars.webinarProviderService.query(
|
||||
query
|
||||
);
|
||||
}
|
||||
//#endregion
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
import { Observable } from 'rxjs';
|
||||
import { concatMap } from 'rxjs/operators';
|
||||
import { Component, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { XQueryDto, XQueryResultDto } from 'x-framework-identity-sdk';
|
||||
import { ToWebinarViewDto } from 'src/app/views/webinar/v-webinar.tools';
|
||||
import { WebinarsBaseProviderPage } from '../webinars-base/webinars-base.provider.page';
|
||||
|
||||
@Component({
|
||||
selector: 'webinars-management',
|
||||
styleUrls: ['./webinars-management.page.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
templateUrl: '../webinars-base/webinars-base.provider.page.html',
|
||||
})
|
||||
export class WebinarsManagementPage extends WebinarsBaseProviderPage {
|
||||
//
|
||||
//#region Props ...
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region LifeCycles ...
|
||||
onInit(): void {
|
||||
super.onInit();
|
||||
|
||||
//
|
||||
this.configureAsManagementPage();
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Abstractions ...
|
||||
getModelTask(identifier: string): Observable<any> {
|
||||
//
|
||||
return this.sharedService.mabsutAPIService.webinars.webinarProviderService
|
||||
.get(identifier)
|
||||
.pipe(
|
||||
concatMap((m) =>
|
||||
this.getValue(ToWebinarViewDto(m, this.managerService.currentLocale))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
queryModelTask(query: XQueryDto): Observable<XQueryResultDto<any>> {
|
||||
return this.sharedService.mabsutAPIService.webinars.webinarProviderService.query(
|
||||
query
|
||||
);
|
||||
}
|
||||
//#endregion
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { isValueInEnum } from 'src/app/views/public-api';
|
||||
|
||||
export enum WebinarsManagementTask {
|
||||
Create = 'Create_Webinar',
|
||||
Remove = 'Remove_Webinar',
|
||||
Update = 'Update_Webinar',
|
||||
QueryList = 'QueryList_Webinars',
|
||||
}
|
||||
|
||||
export function isWebinarsManagementTask(value: string, forceExactSames: boolean = true) {
|
||||
return isValueInEnum(value, Object.assign(WebinarsManagementTask, {}), forceExactSames);
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { AuthGuard } from 'x-framework-identity-sdk';
|
||||
import { XCanDeactivateGuard } from 'x-framework-core';
|
||||
import { BaseRoutes } from 'src/app/config/page.config';
|
||||
import { ViewsModule } from 'src/app/views/views.module';
|
||||
import { WebinarRoutes } from 'src/app/views/webinar/v-webinar.configs';
|
||||
import { WebinarsExplorerPage } from './webinars-explorer/webinars-explorer.page';
|
||||
import { WebinarsManagementPage } from './webinars-management/webinars-management.page';
|
||||
|
||||
@NgModule({
|
||||
declarations: [WebinarsExplorerPage, WebinarsManagementPage],
|
||||
imports: [
|
||||
ViewsModule,
|
||||
RouterModule.forChild([
|
||||
{
|
||||
pathMatch: 'full',
|
||||
path: BaseRoutes.Default,
|
||||
redirectTo: WebinarRoutes.WebinarsExplorer,
|
||||
},
|
||||
//
|
||||
// Webinars Explorer ...
|
||||
{
|
||||
canActivate: [AuthGuard],
|
||||
component: WebinarsExplorerPage,
|
||||
canDeactivate: [XCanDeactivateGuard],
|
||||
path: WebinarRoutes.WebinarsExplorer,
|
||||
},
|
||||
//
|
||||
// Webinars Management ...
|
||||
{
|
||||
canActivate: [AuthGuard],
|
||||
component: WebinarsManagementPage,
|
||||
canDeactivate: [XCanDeactivateGuard],
|
||||
path: WebinarRoutes.WebinarsManagement,
|
||||
},
|
||||
{
|
||||
pathMatch: 'full',
|
||||
path: BaseRoutes.Unknown,
|
||||
redirectTo: WebinarRoutes.Default,
|
||||
},
|
||||
]),
|
||||
],
|
||||
exports: [
|
||||
ViewsModule,
|
||||
RouterModule,
|
||||
WebinarsExplorerPage,
|
||||
WebinarsManagementPage,
|
||||
],
|
||||
})
|
||||
export class WebinarsPageModule {}
|
||||
Reference in New Issue
Block a user