Initial Commit ...

This commit is contained in:
2026-04-17 17:04:44 +03:30
commit a986295e19
842 changed files with 97431 additions and 0 deletions
+134
View File
@@ -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 {}
+5
View File
@@ -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>
+350
View File
@@ -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
}
+22
View File
@@ -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>
View File
+79
View File
@@ -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
}
+46
View File
@@ -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 {}
+13
View File
@@ -0,0 +1,13 @@
<!-- -->
<!-- Page Presenter -->
<!-- -->
<v-page-presenter
[containerBase]="this"
[contentTemplate]="contentTemplate"
></v-page-presenter>
<!-- -->
<!-- Page Content -->
<!-- -->
<ng-template #contentTemplate>
</ng-template>
View File
+56
View File
@@ -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
}
+13
View File
@@ -0,0 +1,13 @@
<!-- -->
<!-- Page Presenter -->
<!-- -->
<v-page-presenter
[containerBase]="this"
[contentTemplate]="contentTemplate"
></v-page-presenter>
<!-- -->
<!-- Page Content -->
<!-- -->
<ng-template #contentTemplate>
</ng-template>
+67
View File
@@ -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
}
+13
View File
@@ -0,0 +1,13 @@
<!-- -->
<!-- Page Presenter -->
<!-- -->
<v-page-presenter
[containerBase]="this"
[contentTemplate]="contentTemplate"
></v-page-presenter>
<!-- -->
<!-- Page Content -->
<!-- -->
<ng-template #contentTemplate>
</ng-template>
+180
View File
@@ -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
}
+46
View File
@@ -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 {}
+14
View File
@@ -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 {}