Initial Commit on git.saherelm.ir ...

This commit is contained in:
2026-08-20 15:42:40 +03:30
commit fac270d301
779 changed files with 79360 additions and 0 deletions
+70
View File
@@ -0,0 +1,70 @@
import { NgModule } from '@angular/core';
import { Pages, BaseRoutes } from './config/page.config';
import { PreloadAllModules, RouterModule, Routes } from '@angular/router';
const routes: Routes = [
//
// Default ...
{
path: BaseRoutes.Default,
redirectTo: Pages.Home.baseRoute,
pathMatch: 'full',
},
//
// Home ...
{
path: Pages.Home.baseRoute,
loadChildren: () =>
import('./pages/home/home.module').then((m) => m.HomePageModule),
},
//
// Core ...
{
path: Pages.Core.baseRoute,
loadChildren: () =>
import('./pages/core/core.module').then((m) => m.CorePageModule),
},
//
// Services ...
{
path: Pages.Services.baseRoute,
loadChildren: () =>
import('./pages/services/services.module').then(
(m) => m.ServicesPageModule
),
},
//
// Components ...
{
path: Pages.Components.baseRoute,
loadChildren: () =>
import('./pages/components/components.module').then(
(m) => m.ComponentsPageModule
),
},
//
// TabsNavs ...
{
path: Pages.TabsNav.baseRoute,
loadChildren: () =>
import('./pages/tabs/tabs.module').then((m) => m.TabsPageModule),
},
//
// Themes ...
{
path: Pages.Themes.baseRoute,
loadChildren: () =>
import('./pages/themes/themes.module').then((m) => m.ThemesPageModule),
},
];
@NgModule({
imports: [
RouterModule.forRoot(routes, {
preloadingStrategy: PreloadAllModules,
scrollPositionRestoration: 'enabled',
}),
],
exports: [RouterModule],
})
export class AppRoutingModule {}
+3
View File
@@ -0,0 +1,3 @@
<ion-app>
<ion-router-outlet></ion-router-outlet>
</ion-app>
View File
+17
View File
@@ -0,0 +1,17 @@
import { Component } from '@angular/core';
import { Platform } from '@ionic/angular';
@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.scss']
})
export class AppComponent {
constructor(private platform: Platform) {
this.initializeApp();
}
initializeApp() {
this.platform.ready().then(() => {});
}
}
+76
View File
@@ -0,0 +1,76 @@
import {
XCanDeactivateGuard,
XFrameworkCoreModule,
X_FRAMEWORK_CORE_CONFIG,
} from 'x-framework-core';
import {
XManagerService,
XHttpInterceptorService,
XFrameworkServicesModule,
X_FRAMEWORK_SERVICES_CONFIG,
} from 'x-framework-services';
import {
XFrameworkComponentsModule,
X_FRAMEWORK_COMPONENTS_CONFIG,
} from 'x-framework-components';
import { NgModule } from '@angular/core';
import { IonicModule } from '@ionic/angular';
import { AppComponent } from './app.component';
import { ViewsModule } from './views/views.module';
import { X_CONFIG, XCONFIG } from './config/x-config';
import { AppRoutingModule } from './app-routing.module';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { BrowserModule } from '@angular/platform-browser';
import { environment } from '../environments/environment';
import { ServiceWorkerModule } from '@angular/service-worker';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
@NgModule({
declarations: [AppComponent],
imports: [
ViewsModule,
BrowserModule,
AppRoutingModule,
XFrameworkCoreModule,
IonicModule.forRoot(),
BrowserAnimationsModule,
XFrameworkServicesModule,
XFrameworkComponentsModule,
ServiceWorkerModule.register('ngsw-worker.js', {
enabled: environment.production,
}),
],
providers: [
//
// Manager Service ...
XManagerService,
//
// Provide it ...
XCanDeactivateGuard,
{
provide: X_FRAMEWORK_CORE_CONFIG,
useValue: XCONFIG,
},
{
provide: X_FRAMEWORK_SERVICES_CONFIG,
useValue: XCONFIG,
},
{
provide: X_FRAMEWORK_COMPONENTS_CONFIG,
useValue: XCONFIG,
},
{
provide: X_CONFIG,
useValue: XCONFIG,
},
//
// Register Http Interceptor ...
{
provide: HTTP_INTERCEPTORS,
useClass: XHttpInterceptorService,
multi: true,
},
],
bootstrap: [AppComponent],
})
export class AppModule {}
+108
View File
@@ -0,0 +1,108 @@
import {
DefaultLocale,
AvailableTranslationResources,
} from './localization.config';
import { NotificationAudioSources } from './audio.config';
import { XFrameworkCoreConfig, XPage } from 'x-framework-core';
import { XFrameworkServicesConfig } from 'x-framework-services';
import { XFrameworkComponentsConfig } from 'x-framework-components';
// tslint:disable-next-line:no-empty-interface
export interface AppConfig {
defaultLandingPage?: XPage;
defaultBlogPage?: XPage;
}
export type XFrameworkCoreSharedConfig = Partial<XFrameworkCoreConfig>;
export type XFrameworkServicesSharedConfig = Partial<XFrameworkServicesConfig>;
export type XFrameworkComponentsSharedConfig =
Partial<XFrameworkComponentsConfig>;
export type XAppSharedConfig = Partial<AppConfig>;
export type XConfig = XFrameworkCoreConfig &
XFrameworkServicesConfig &
XFrameworkComponentsConfig &
AppConfig;
export type XSharedConfig = Partial<XConfig>;
export const xFrameworkCoreSharedConfig: XFrameworkCoreSharedConfig = {
//
// App Info ...
appInstanceName: 'xFrameworkTestApp',
appNameResource: 'app_name',
appCompanyResource: 'company',
appVersion: 'v1.1',
//
// Audio Service Configurations ...
defaultNotificationDelay: 2000,
notificationAudioSources: NotificationAudioSources,
//
// Language Configuration ...
availableLanguages: AvailableTranslationResources,
defaultLanguage: DefaultLocale,
//
// Api Configuration ...
poweredValue: 'SaherElmITCenter',
//
// Security Service Configurations ...
secretKey: 'SaherElm@09121694056@Hadi_Khazaee_Asl@yahoo.com',
//
// Logging Configuration ...
baseLogTag: 'xFrameworkApp',
//
// Image Related Configs ...
minAllowedImageSize: 512,
maxAllowedImageSize: 5242880,
minAllowedImageCroppableSize: 512,
allowedImageExtensions: ['.png', '.jpg', '.jpeg'],
//
// Profile Image Configs ...
maxProfileImageSize: 5242880,
maxProfileImagesUploadFiles: 10,
//
defaultCountryCode: 'IR',
//
defaultPageSize: 20,
pageSizes: [10, 20, 40, 50, 100, 200],
//
defaultActionDelay: 500,
};
export const xFrameworkServicesSharedConfig: XFrameworkServicesSharedConfig = {
geoLocationConfig: {
enableHighAccuracy: true,
timeout: 5000,
},
};
export const xFrameworkComponentsSharedConfig: XFrameworkComponentsSharedConfig =
{
//
// File Config ...
minAllowedFileSize: 512,
maxAllowedFileSize: 20971520,
maxAllowedSize: 966367641,
maxUploadFiles: 10,
//
defaultSearchDebounceTime: 500,
};
export const xAppSharedConfig: XAppSharedConfig = {};
export const xSharedConfig: XSharedConfig = {
...xFrameworkCoreSharedConfig,
...xFrameworkServicesSharedConfig,
...xFrameworkComponentsSharedConfig,
...xAppSharedConfig,
};
File diff suppressed because it is too large Load Diff
+16
View File
@@ -0,0 +1,16 @@
import { XNotificationSound, XActionType } from 'x-framework-core';
export const NotificationAudioSources: XNotificationSound[] = [
{
type: XActionType.User,
resourcePath: './assets/audio/user_notification.wav',
},
{
type: XActionType.System,
resourcePath: './assets/audio/system_notification.wav',
},
{
type: XActionType.Capture,
resourcePath: './assets/audio/capture_notification.wav',
},
];
+539
View File
@@ -0,0 +1,539 @@
import { XTranslationItem } from 'x-framework-core';
/**
* Persian Exception Translations ...
*/
export const XFaIRExceptions: XTranslationItem[] = [
//
//#region Invalid Exceptions 1xx ...
{
id: 'ex_100',
value: 'داده نا معتبر',
},
{
id: 'ex_101',
value: 'تاریخ نامعتبر',
},
{
id: 'ex_102',
value: 'درخواست اشتباه',
},
{
id: 'ex_103',
value: 'ورودی نامعتبر',
},
{
id: 'ex_104',
value: 'پیام نامعتبر',
},
{
id: 'ex_105',
value: 'نشانه نامعتبر',
},
{
id: 'ex_106',
value: 'کد اععتبارسنجی نامعتبر',
},
{
id: 'ex_107',
value: 'پست الکترونیک نامعتبر',
},
{
id: 'ex_108',
value: 'شماره تلفن همراه نامعتبر',
},
{
id: 'ex_109',
value: 'کلمه عبور نامعتبر',
},
{
id: 'ex_110',
value: 'آدرس اینترنتی نامعتبر',
},
{
id: 'ex_111',
value: 'دستگاه نامعتبر',
},
{
id: 'ex_112',
value: 'تصویر پروفایل نامعتبر',
},
{
id: 'ex_113',
value: 'فایل نامعتبر',
},
{
id: 'ex_114',
value: 'نام کاربری نامعتبر',
},
//#endregion
//
//#region Not (...) Exceptions 2xx ...
{
id: 'ex_200',
value: 'یافت نشد',
},
{
id: 'ex_201',
value: 'عدم تایید جواز',
},
{
id: 'ex_202',
value: 'سطح دسترسی نامعتبر',
},
{
id: 'ex_203',
value: 'غیر قابل نمایش',
},
//#endregion
//
//#region User/Registration/Account/Bann Exceptions 3xx ...
{
id: 'ex_300',
value: 'حساب کاربری قفل شده است',
},
{
id: 'ex_301',
value: 'خطا در ورود',
},
{
id: 'ex_302',
value: 'کاربر قبلا ثبت نام کرده است',
},
{
id: 'ex_303',
value: 'کاربر غیرفعال است',
},
{
id: 'ex_304',
value: 'دستگاه شما قفل شده است تا : (0)',
},
{
id: 'ex_305',
value: 'امکان درخواست کد اعتبارسنجی وجود ندارد تا : (0)',
},
{
id: 'ex_306',
value: 'کلمه عبورها یکسان هستند',
},
{
id: 'ex_307',
value: 'شماره های تلفن یکسان هستند',
},
{
id: 'ex_308',
value: 'آدرس های پست الکترونیک یکسان هستند',
},
{
id: 'ex_309',
value: 'شماره تلفن قبلا ثبت شده است',
},
{
id: 'ex_310',
value: 'پست الکترونیک قبلا ثبت شده است',
},
{
id: 'ex_311',
value: 'تلفن همراه تایید نشده است',
},
{
id: 'ex_312',
value: 'پست الکترونیک تایید نشده است',
},
{
id: 'ex_313',
value: 'مطلب ممنوعه',
},
{
id: 'ex_314',
value: 'کاربر ممنوعه',
},
//#endregion
//
//#region General Exceptions 4xx ...
{
id: 'ex_400',
value: 'خطای نا شناخته',
},
{
id: 'ex_401',
value: 'مورد تکراری',
},
{
id: 'ex_402',
value: 'شکست عملیات',
},
{
id: 'ex_403',
value: 'تاریخ مصرف منقضی شده است',
},
{
id: 'ex_404',
value: 'غیر قابل اسفاده',
},
{
id: 'ex_405',
value: 'تعداد برچسب ها بیش از جد مجاز است',
},
{
id: 'ex_406',
value: 'اتمام مهلت زمانی',
},
//#endregion
//
//#region File Exceptions 5xx ...
{
id: 'ex_500',
value: 'پرونده خالی است',
},
{
id: 'ex_501',
value: 'اندازه بیش از حد مجاز',
},
{
id: 'ex_502',
value: 'گونه نامعتبر فایل',
},
{
id: 'ex_503',
value: 'تعداد رسانه ها بیش از حد مجاز است',
},
//#endregion
//
//#region Configuration Exceptions 6xx ...
{
id: 'ex_600',
value: 'پیکربندی اشتباه',
},
{
id: 'ex_601',
value: 'خطا در پیکربندی سامانه ذخیره سازی',
},
{
id: 'ex_602',
value: 'خطا در پیکربندی سامانه ذخیره سازی',
},
//#endregion
//
//#region xFramework Exceptions 9xx ...
{
id: 'ex_900',
value: 'تعداد فایل ها بیش از حد مجاز است',
},
{
id: 'ex_901',
value: 'مجموع اندازه فایل ها کمتر از حد مجاز است',
},
{
id: 'ex_902',
value: 'مجموع اندازه فایل ها بیش از حد مجاز است',
},
{
id: 'ex_903',
value: 'شرایط و ضوابط باید پذیرفته شوند',
},
{
id: 'ex_904',
value: 'عدم پشتیبانی از سیستم موقعیت یاب',
},
{
id: 'ex_905',
value: 'مجوز دسترسی به موقعیت خود را صادر نکرده اید',
},
{
id: 'ex_906',
value: 'دسترسی به موقعیت جغرافیایی امکان پذیر نیست',
},
{
id: 'ex_907',
value: 'عدم پشتیبانی از سیستم ذخیره سازی',
},
{
id: 'ex_908',
value: 'برای دسترسی به محتوا باید از سامانه خارج شوید',
},
{
id: 'ex_909',
value: 'زبان انتخاب شده نامعتبر است',
},
{
id: 'ex_910',
value: 'داده نامعتبر برای انتخاب کاربر',
},
//#endregion
];
/**
* English Exception Translations ...
*/
export const XEnUSExceptions: XTranslationItem[] = [
//
//#region Invalid Exceptions 1xx ...
{
id: 'ex_100',
value: 'Invalid Data ...',
},
{
id: 'ex_101',
value: 'Invalid Date ...',
},
{
id: 'ex_102',
value: 'Bad Request ...',
},
{
id: 'ex_103',
value: 'Invalid Args ...',
},
{
id: 'ex_104',
value: 'Invalid Message ...',
},
{
id: 'ex_105',
value: 'Invalid Token ...',
},
{
id: 'ex_106',
value: 'Invalid Verification Code ...',
},
{
id: 'ex_107',
value: 'Invalid Email Address ...',
},
{
id: 'ex_108',
value: 'Invalid Mobile Number ...',
},
{
id: 'ex_109',
value: 'Invalid Password ...',
},
{
id: 'ex_110',
value: 'Invalid URL ...',
},
{
id: 'ex_111',
value: 'Invalid Device ...',
},
{
id: 'ex_112',
value: 'Invalid Profile Image ...',
},
{
id: 'ex_113',
value: 'Invalid File ...',
},
{
id: 'ex_114',
value: 'Invalid Username ...',
},
//#endregion
//
//#region Not (...) Exceptions 2xx ...
{
id: 'ex_200',
value: 'Not Found ...',
},
{
id: 'ex_201',
value: 'Not Allowed ...',
},
{
id: 'ex_202',
value: 'Not Authorized ...',
},
{
id: 'ex_203',
value: 'Not Visible ...',
},
//#endregion
//
//#region User/Registration/Account/Bann Exceptions 3xx ...
{
id: 'ex_300',
value: 'Account Locked out ...',
},
{
id: 'ex_301',
value: 'Login Failed ...',
},
{
id: 'ex_302',
value: 'User Registered Before ...',
},
{
id: 'ex_303',
value: 'User Disabled ...',
},
{
id: 'ex_304',
value: 'Device Banned Until:(0)',
},
{
id: 'ex_305',
value: `You can't Request Verification code Until:(0)`,
},
{
id: 'ex_306',
value: 'Passwords Same ...',
},
{
id: 'ex_307',
value: 'Mobiles Same ...',
},
{
id: 'ex_308',
value: 'Emails Same ...',
},
{
id: 'ex_309',
value: 'Mobile In Used ...',
},
{
id: 'ex_310',
value: 'Email In Used ...',
},
{
id: 'ex_311',
value: 'Mobile Not Confirmed ...',
},
{
id: 'ex_312',
value: 'Email Not Confirmed ...',
},
{
id: 'ex_313',
value: 'Post Banned ...',
},
{
id: 'ex_314',
value: 'User Banned ...',
},
//#endregion
//
//#region General Exceptions 4xx ...
{
id: 'ex_400',
value: 'Unknown Error ...',
},
{
id: 'ex_401',
value: 'Duplicate ...',
},
{
id: 'ex_402',
value: 'Action Failed ...',
},
{
id: 'ex_403',
value: 'Expired Date ...',
},
{
id: 'ex_404',
value: 'Unavailable ...',
},
{
id: 'ex_405',
value: 'Max Allowed Tag Exceeded ...',
},
{
id: 'ex_406',
value: 'Timeout ...',
},
//#endregion
//
//#region File Exceptions 5xx ...
{
id: 'ex_500',
value: 'Empty File ...',
},
{
id: 'ex_501',
value: 'max File size exceeded ...',
},
{
id: 'ex_502',
value: 'Unsupported File Type ...',
},
{
id: 'ex_503',
value: 'Max Allowed Media Exceeded ...',
},
//#endregion
//
//#region Configuration Exceptions 6xx ...
{
id: 'ex_600',
value: 'Invalid Configuration ...',
},
{
id: 'ex_601',
value: 'Storage Service Initiallization Failed ...',
},
{
id: 'ex_602',
value: 'Message Service Initialization Failed ...',
},
//#endregion
//
//#region xFramework Exceptions 9xx ...
{
id: 'ex_900',
value: 'Max Allowed Files Exceeded ...',
},
{
id: 'ex_901',
value: 'Min Files Size Exceeded ...',
},
{
id: 'ex_902',
value: 'Max Files Size Exceeded ...',
},
{
id: 'ex_903',
value: 'Must Accept Terms And Conditions ...',
},
{
id: 'ex_904',
value: 'Browser does not support Location Services ...',
},
{
id: 'ex_905',
value: 'You have rejected access to your Location ...',
},
{
id: 'ex_906',
value: 'Unable to determine your Location ...',
},
{
id: 'ex_907',
value: 'Browser does not support Storage Services ...',
},
{
id: 'ex_908',
value: 'Must Logout to access content ...',
},
{
id: 'ex_909',
value: 'Invalid Locale ...',
},
{
id: 'ex_910',
value: 'Invalid User Selector ...',
},
//#endregion
];
File diff suppressed because it is too large Load Diff
+726
View File
@@ -0,0 +1,726 @@
import {
XIconNames,
XTabNavigatorItem,
XNavigatorListItem,
toTabNavigatiorItem,
toNavigatiorListItem,
} from 'x-framework-components';
import { XPage } from 'x-framework-core';
import { AppResourceIDs } from './app.localization.config';
//
//#region Route Config ...
export enum BaseRoutes {
Default = '',
Unknown = '**',
}
export enum HomeRoutes {
Default = 'home',
Home = 'home',
Introduction = 'introduction',
}
export enum CoreRoutes {
Default = 'core',
Core = 'core',
Introduction = 'introduction',
}
export enum ServicesRoutes {
Default = 'services',
Services = 'services',
Introduction = 'introduction',
UserDevice = 'user_device',
}
export enum ComponentsRoutes {
Default = 'components',
Components = 'components',
Introduction = 'introduction',
SmallComponents = 'small-components',
Card = 'card',
Icon = 'icon',
Counter = 'counter',
ColorPicker = 'color-picker',
Fab = 'fab',
FileComponents = 'file-components',
Form = 'form',
Grid = 'grid',
List = 'list',
Map = 'map',
MarkDown = 'markdown',
Tree = 'tree',
DescriptionList = 'description-list',
ExpandableList = 'expandable-list',
ExpandablePanel = 'expandable-panel',
ModelPresenter = 'model-presenter',
Slider = 'slider',
Stepper = 'stepper',
Tabs = 'tabs',
Table = 'table',
Page = 'page',
TabNavigator = 'tab-navigator',
}
export enum TabsRoutes {
Default = 'tabs',
Tabs = 'tabs',
TabPage1 = 'tab-page-1',
TabPage2 = 'tab-page-2',
TabPage3 = 'tab-page-3',
}
export enum ThemesRoutes {
Default = 'themes',
Themes = 'themes',
ThemeManager = 'manager',
}
export enum AppRoutes {
Default = BaseRoutes.Default,
Home = HomeRoutes.Default,
Core = CoreRoutes.Default,
Services = ServicesRoutes.Default,
Components = ComponentsRoutes.Default,
TabsNav = TabsRoutes.Default,
Themes = ThemesRoutes.Default,
Unknown = BaseRoutes.Unknown,
}
//#endregion
//
//#region Page Configs ...
export enum PageName {
//
// Home ...
Home = AppRoutes.Home,
HomeIntoduction = HomeRoutes.Introduction,
//
// Core ...
Core = AppRoutes.Core,
CoreIntoduction = CoreRoutes.Introduction,
//
// Services ...
Services = AppRoutes.Services,
ServicesIntoduction = ServicesRoutes.Introduction,
UserDevice = ServicesRoutes.UserDevice,
//
// Components ...
Components = AppRoutes.Components,
ComponentsIntoduction = ComponentsRoutes.Introduction,
SmallComponents = ComponentsRoutes.SmallComponents,
Card = ComponentsRoutes.Card,
Icon = ComponentsRoutes.Icon,
Counter = ComponentsRoutes.Counter,
ColorPicker = ComponentsRoutes.ColorPicker,
Fab = ComponentsRoutes.Fab,
FileComponents = ComponentsRoutes.FileComponents,
Form = ComponentsRoutes.Form,
Grid = ComponentsRoutes.Grid,
List = ComponentsRoutes.List,
Map = ComponentsRoutes.Map,
MarkDown = ComponentsRoutes.MarkDown,
Tree = ComponentsRoutes.Tree,
DescriptionList = ComponentsRoutes.DescriptionList,
ExpandableList = ComponentsRoutes.ExpandableList,
ExpandablePanel = ComponentsRoutes.ExpandablePanel,
ModelPresenter = ComponentsRoutes.ModelPresenter,
Slider = ComponentsRoutes.Slider,
Stepper = ComponentsRoutes.Stepper,
Tabs = ComponentsRoutes.Tabs,
Table = ComponentsRoutes.Table,
Page = ComponentsRoutes.Page,
TabNavigator = ComponentsRoutes.TabNavigator,
//
// Tabs Navigation ...
TabsNav = AppRoutes.TabsNav,
TabPage1 = TabsRoutes.TabPage1,
TabPage2 = TabsRoutes.TabPage2,
TabPage3 = TabsRoutes.TabPage3,
//
// Themes ...
Themes = AppRoutes.Themes,
ThemeManager = ThemesRoutes.ThemeManager,
}
export type PageNames = keyof typeof PageName;
export type PageNameIdentifier = PageName | PageNames | string;
export type PageIndexType = {
[key in PageNames]?: XPage;
};
export const PageIndex: PageIndexType = {
//
Home: {
icon: XIconNames.home,
id: `${PageName.Home}`,
name: `${PageName.Home}`,
title: AppResourceIDs.home,
baseRoute: `${AppRoutes.Home}`,
route: ['/', `${AppRoutes.Home}`],
description: AppResourceIDs.home_description,
childs: [
//
// Intoduction ...
{
icon: XIconNames.guide,
id: `${PageName.HomeIntoduction}`,
name: `${PageName.HomeIntoduction}`,
title: AppResourceIDs.home_introduction,
baseRoute: `${HomeRoutes.Introduction}`,
description: AppResourceIDs.home_introduction_description,
route: ['/', `${AppRoutes.Home}`, `${HomeRoutes.Introduction}`],
},
],
},
//
Core: {
icon: XIconNames.event,
id: `${PageName.Core}`,
name: `${PageName.Core}`,
title: AppResourceIDs.core,
baseRoute: `${AppRoutes.Core}`,
route: ['/', `${AppRoutes.Core}`],
description: AppResourceIDs.core_description,
childs: [
//
// Intoduction ...
{
icon: XIconNames.guide,
id: `${PageName.CoreIntoduction}`,
name: `${PageName.CoreIntoduction}`,
title: AppResourceIDs.core_introduction,
baseRoute: `${CoreRoutes.Introduction}`,
description: AppResourceIDs.core_introduction_description,
route: ['/', `${AppRoutes.Core}`, `${CoreRoutes.Introduction}`],
},
],
},
//
Services: {
icon: XIconNames.job,
id: `${PageName.Services}`,
name: `${PageName.Services}`,
title: AppResourceIDs.services,
baseRoute: `${AppRoutes.Services}`,
route: ['/', `${AppRoutes.Services}`],
description: AppResourceIDs.services_description,
childs: [
//
// Intoduction ...
{
icon: XIconNames.guide,
id: `${PageName.ServicesIntoduction}`,
name: `${PageName.ServicesIntoduction}`,
title: AppResourceIDs.services_introduction,
baseRoute: `${ServicesRoutes.Introduction}`,
description: AppResourceIDs.services_introduction_description,
route: ['/', `${AppRoutes.Services}`, `${ServicesRoutes.Introduction}`],
},
//
// UserDevice ...
{
icon: XIconNames.guide,
id: `${PageName.UserDevice}`,
name: `${PageName.UserDevice}`,
title: AppResourceIDs.user_device,
baseRoute: `${ServicesRoutes.UserDevice}`,
description: AppResourceIDs.user_device_description,
route: ['/', `${AppRoutes.Services}`, `${ServicesRoutes.UserDevice}`],
},
],
},
//
Components: {
icon: XIconNames.explorer,
id: `${PageName.Components}`,
name: `${PageName.Components}`,
title: AppResourceIDs.components,
baseRoute: `${AppRoutes.Components}`,
route: ['/', `${AppRoutes.Components}`],
description: AppResourceIDs.components_description,
childs: [
//
// Intoduction ...
{
icon: XIconNames.guide,
id: `${PageName.ComponentsIntoduction}`,
name: `${PageName.ComponentsIntoduction}`,
title: AppResourceIDs.components_introduction,
baseRoute: `${ComponentsRoutes.Introduction}`,
description: AppResourceIDs.components_introduction_description,
route: [
'/',
`${AppRoutes.Components}`,
`${ComponentsRoutes.Introduction}`,
],
},
//
// SmallComponents ...
{
icon: XIconNames.list,
id: `${PageName.SmallComponents}`,
name: `${PageName.SmallComponents}`,
title: AppResourceIDs.small_components,
baseRoute: `${ComponentsRoutes.SmallComponents}`,
description: AppResourceIDs.small_components_description,
route: [
'/',
`${AppRoutes.Components}`,
`${ComponentsRoutes.SmallComponents}`,
],
},
//
// Card ...
{
icon: XIconNames.list,
id: `${PageName.Card}`,
name: `${PageName.Card}`,
title: AppResourceIDs.card,
baseRoute: `${ComponentsRoutes.Card}`,
description: AppResourceIDs.card_description,
route: ['/', `${AppRoutes.Components}`, `${ComponentsRoutes.Card}`],
},
//
// Icon ...
{
icon: XIconNames.list,
id: `${PageName.Icon}`,
name: `${PageName.Icon}`,
title: AppResourceIDs.icon,
baseRoute: `${ComponentsRoutes.Icon}`,
description: AppResourceIDs.icon_description,
route: ['/', `${AppRoutes.Components}`, `${ComponentsRoutes.Icon}`],
},
//
// Counter ...
{
icon: XIconNames.list,
id: `${PageName.Counter}`,
name: `${PageName.Counter}`,
title: AppResourceIDs.counter,
baseRoute: `${ComponentsRoutes.Counter}`,
description: AppResourceIDs.counter_description,
route: ['/', `${AppRoutes.Components}`, `${ComponentsRoutes.Counter}`],
},
//
// ColorPicker ...
{
icon: XIconNames.list,
id: `${PageName.ColorPicker}`,
name: `${PageName.ColorPicker}`,
title: AppResourceIDs.color_picker,
baseRoute: `${ComponentsRoutes.ColorPicker}`,
description: AppResourceIDs.color_picker_description,
route: [
'/',
`${AppRoutes.Components}`,
`${ComponentsRoutes.ColorPicker}`,
],
},
//
// Fab ...
{
id: `${PageName.Fab}`,
icon: XIconNames.list,
name: `${PageName.Fab}`,
title: AppResourceIDs.fab,
baseRoute: `${ComponentsRoutes.Fab}`,
description: AppResourceIDs.fab_description,
route: ['/', `${AppRoutes.Components}`, `${ComponentsRoutes.Fab}`],
},
//
// FileComponents ...
{
icon: XIconNames.list,
id: `${PageName.FileComponents}`,
name: `${PageName.FileComponents}`,
title: AppResourceIDs.file_components,
baseRoute: `${ComponentsRoutes.FileComponents}`,
description: AppResourceIDs.file_components_description,
route: [
'/',
`${AppRoutes.Components}`,
`${ComponentsRoutes.FileComponents}`,
],
},
//
// Form ...
{
icon: XIconNames.list,
id: `${PageName.Form}`,
name: `${PageName.Form}`,
title: AppResourceIDs.form,
baseRoute: `${ComponentsRoutes.Form}`,
description: AppResourceIDs.form_description,
route: ['/', `${AppRoutes.Components}`, `${ComponentsRoutes.Form}`],
},
//
// Grid ...
{
icon: XIconNames.list,
id: `${PageName.Grid}`,
name: `${PageName.Grid}`,
title: AppResourceIDs.grid,
baseRoute: `${ComponentsRoutes.Grid}`,
description: AppResourceIDs.grid_description,
route: ['/', `${AppRoutes.Components}`, `${ComponentsRoutes.Grid}`],
},
//
// List ...
{
icon: XIconNames.list,
id: `${PageName.List}`,
name: `${PageName.List}`,
title: AppResourceIDs.list,
baseRoute: `${ComponentsRoutes.List}`,
description: AppResourceIDs.list_description,
route: ['/', `${AppRoutes.Components}`, `${ComponentsRoutes.List}`],
},
//
// Map ...
{
icon: XIconNames.list,
id: `${PageName.Map}`,
name: `${PageName.Map}`,
title: AppResourceIDs.map,
baseRoute: `${ComponentsRoutes.Map}`,
description: AppResourceIDs.map_description,
route: ['/', `${AppRoutes.Components}`, `${ComponentsRoutes.Map}`],
},
//
// MarkDown ...
{
icon: XIconNames.list,
id: `${PageName.MarkDown}`,
name: `${PageName.MarkDown}`,
title: AppResourceIDs.markdown,
baseRoute: `${ComponentsRoutes.MarkDown}`,
description: AppResourceIDs.markdown_description,
route: ['/', `${AppRoutes.Components}`, `${ComponentsRoutes.MarkDown}`],
},
//
// Tree ...
// TODO: Complete this ...
{
icon: XIconNames.ul,
id: `${PageName.Tree}`,
name: `${PageName.Tree}`,
title: AppResourceIDs.tree,
baseRoute: `${ComponentsRoutes.Tree}`,
description: AppResourceIDs.tree_description,
route: ['/', `${AppRoutes.Components}`, `${ComponentsRoutes.Tree}`],
},
//
// DescriptionList ...
{
icon: XIconNames.list,
id: `${PageName.DescriptionList}`,
name: `${PageName.DescriptionList}`,
title: AppResourceIDs.description_list,
baseRoute: `${ComponentsRoutes.DescriptionList}`,
description: AppResourceIDs.description_list_description,
route: [
'/',
`${AppRoutes.Components}`,
`${ComponentsRoutes.DescriptionList}`,
],
},
//
// ExpandableList ...
{
icon: XIconNames.list,
id: `${PageName.ExpandableList}`,
name: `${PageName.ExpandableList}`,
title: AppResourceIDs.expandable_list,
baseRoute: `${ComponentsRoutes.ExpandableList}`,
description: AppResourceIDs.expandable_list_description,
route: [
'/',
`${AppRoutes.Components}`,
`${ComponentsRoutes.ExpandableList}`,
],
},
//
// ExpandablePanel ...
{
icon: XIconNames.list,
id: `${PageName.ExpandablePanel}`,
name: `${PageName.ExpandablePanel}`,
title: AppResourceIDs.expandable_panel,
baseRoute: `${ComponentsRoutes.ExpandablePanel}`,
description: AppResourceIDs.expandable_panel_description,
route: [
'/',
`${AppRoutes.Components}`,
`${ComponentsRoutes.ExpandablePanel}`,
],
},
//
// ModelPresenter ...
{
icon: XIconNames.list,
id: `${PageName.ModelPresenter}`,
name: `${PageName.ModelPresenter}`,
title: AppResourceIDs.model_presenter,
baseRoute: `${ComponentsRoutes.ModelPresenter}`,
description: AppResourceIDs.model_presenter_description,
route: [
'/',
`${AppRoutes.Components}`,
`${ComponentsRoutes.ModelPresenter}`,
],
},
//
// Slider ...
{
icon: XIconNames.list,
id: `${PageName.Slider}`,
name: `${PageName.Slider}`,
title: AppResourceIDs.slider,
baseRoute: `${ComponentsRoutes.Slider}`,
description: AppResourceIDs.slider_description,
route: ['/', `${AppRoutes.Components}`, `${ComponentsRoutes.Slider}`],
},
//
// Stepper ...
{
icon: XIconNames.list,
id: `${PageName.Stepper}`,
name: `${PageName.Stepper}`,
title: AppResourceIDs.stepper,
baseRoute: `${ComponentsRoutes.Stepper}`,
description: AppResourceIDs.stepper_description,
route: ['/', `${AppRoutes.Components}`, `${ComponentsRoutes.Stepper}`],
},
//
// Tabs ...
{
icon: XIconNames.list,
id: `${PageName.Tabs}`,
name: `${PageName.Tabs}`,
title: AppResourceIDs.tabs,
baseRoute: `${ComponentsRoutes.Tabs}`,
description: AppResourceIDs.tabs_description,
route: ['/', `${AppRoutes.Components}`, `${ComponentsRoutes.Tabs}`],
},
//
// Table ...
{
icon: XIconNames.list,
id: `${PageName.Table}`,
name: `${PageName.Table}`,
title: AppResourceIDs.table,
baseRoute: `${ComponentsRoutes.Table}`,
description: AppResourceIDs.tabs_description,
route: ['/', `${AppRoutes.Components}`, `${ComponentsRoutes.Table}`],
},
//
// Page ...
{
icon: XIconNames.list,
id: `${PageName.Page}`,
name: `${PageName.Page}`,
title: AppResourceIDs.page,
baseRoute: `${ComponentsRoutes.Page}`,
description: AppResourceIDs.page_description,
route: ['/', `${AppRoutes.Components}`, `${ComponentsRoutes.Page}`],
},
//
// TabNavigator ...
{
icon: XIconNames.list,
id: `${PageName.TabNavigator}`,
name: `${PageName.TabNavigator}`,
title: AppResourceIDs.tab_navigator,
baseRoute: `${ComponentsRoutes.TabNavigator}`,
description: AppResourceIDs.tab_navigator_description,
route: [
'/',
`${AppRoutes.Components}`,
`${ComponentsRoutes.TabNavigator}`,
],
},
],
},
//
TabsNav: {
icon: XIconNames.list,
id: `${PageName.TabsNav}`,
name: `${PageName.TabsNav}`,
title: AppResourceIDs.tab_navigator,
baseRoute: `${AppRoutes.TabsNav}`,
route: ['/', `${AppRoutes.TabsNav}`],
description: AppResourceIDs.tab_navigator_description,
childs: [
//
// TabPage 1 ...
{
icon: XIconNames.list,
id: `${PageName.TabPage1}`,
name: `${PageName.TabPage1}`,
title: AppResourceIDs.tab_page_1,
baseRoute: `${TabsRoutes.TabPage1}`,
description: AppResourceIDs.tab_navigator_description,
route: ['/', `${AppRoutes.TabsNav}`, `${TabsRoutes.TabPage1}`],
},
//
// TabPage 2 ...
{
icon: XIconNames.list,
id: `${PageName.TabPage2}`,
name: `${PageName.TabPage2}`,
title: AppResourceIDs.tab_page_2,
baseRoute: `${TabsRoutes.TabPage2}`,
description: AppResourceIDs.tab_navigator_description,
route: ['/', `${AppRoutes.TabsNav}`, `${TabsRoutes.TabPage2}`],
},
//
// TabPage 3 ...
{
icon: XIconNames.list,
id: `${PageName.TabPage3}`,
name: `${PageName.TabPage3}`,
title: AppResourceIDs.tab_page_3,
baseRoute: `${TabsRoutes.TabPage3}`,
description: AppResourceIDs.tab_navigator_description,
route: ['/', `${AppRoutes.TabsNav}`, `${TabsRoutes.TabPage3}`],
},
],
},
//
Themes: {
icon: XIconNames.color_palette,
id: `${PageName.Themes}`,
name: `${PageName.Themes}`,
title: AppResourceIDs.themes,
baseRoute: `${AppRoutes.Themes}`,
route: ['/', `${AppRoutes.Themes}`],
description: AppResourceIDs.themes_description,
childs: [
//
// ThemeManager ...
{
icon: XIconNames.color_palette,
id: `${PageName.ThemeManager}`,
name: `${PageName.ThemeManager}`,
title: AppResourceIDs.theme_manager,
baseRoute: `${ThemesRoutes.ThemeManager}`,
description: AppResourceIDs.theme_manager_description,
route: ['/', `${AppRoutes.Themes}`, `${ThemesRoutes.ThemeManager}`],
},
],
},
};
//
// a Const of Available Pages ...
export const Pages = {
//
Home: PageIndex.Home,
HomeIntroduction: PageIndex.Home.childs[0],
//
Core: PageIndex.Core,
CoreIntroduction: PageIndex.Core.childs[0],
//
Services: PageIndex.Services,
ServicesIntroduction: PageIndex.Services.childs[0],
//
Components: PageIndex.Components,
ComponentsIntroduction: PageIndex.Components.childs[0],
SmallComponents: PageIndex.Components.childs[1],
Card: PageIndex.Components.childs[2],
Icon: PageIndex.Components.childs[3],
Counter: PageIndex.Components.childs[4],
ColorPicker: PageIndex.Components.childs[5],
Fab: PageIndex.Components.childs[6],
FileUpload: PageIndex.Components.childs[7],
Form: PageIndex.Components.childs[8],
Grid: PageIndex.Components.childs[9],
List: PageIndex.Components.childs[10],
Map: PageIndex.Components.childs[11],
MarkDown: PageIndex.Components.childs[12],
Tree: PageIndex.Components.childs[13],
DescriptionList: PageIndex.Components.childs[14],
ExpandableList: PageIndex.Components.childs[15],
ExpandablePanel: PageIndex.Components.childs[16],
Slider: PageIndex.Components.childs[17],
Stepper: PageIndex.Components.childs[18],
Tabs: PageIndex.Components.childs[19],
Table: PageIndex.Components.childs[20],
Page: PageIndex.Components.childs[21],
TabNavigator: PageIndex.Components.childs[22],
//
TabsNav: PageIndex.TabsNav,
TabPage1: PageIndex.TabsNav.childs[0],
TabPage2: PageIndex.TabsNav.childs[1],
TabPage3: PageIndex.TabsNav.childs[2],
//
Themes: PageIndex.Themes,
ThemeManager: PageIndex.Themes.childs[0],
};
//
// Admin Navigator Pages ...
export const NavPageItems: XNavigatorListItem[] = [
//
//#region Home ...
{
...toNavigatiorListItem(PageIndex.Home),
},
//#endregion
//
//#region Core ...
{
...toNavigatiorListItem(PageIndex.Core),
},
//#endregion
//
//#region Services ...
{
...toNavigatiorListItem(PageIndex.Services),
},
//#endregion
//
//#region Components ...
{
...toNavigatiorListItem(PageIndex.Components),
},
//#endregion
];
//
// Tabs Navigators Pages ...
export const TabNavsItems: XTabNavigatorItem[] = [
{
...toTabNavigatiorItem(Pages.TabPage1),
},
{
...toTabNavigatiorItem(Pages.TabPage2),
},
{
...toTabNavigatiorItem(Pages.TabPage3),
},
];
//#endregion
+9
View File
@@ -0,0 +1,9 @@
import { XConfig } from './app-config';
import { environment } from '../../environments/environment';
import { InjectionToken } from '@angular/core';
export const XCONFIG: XConfig = JSON.parse(
JSON.stringify(environment.configurations)
);
export const X_CONFIG = new InjectionToken<XConfig>('x_config');
@@ -0,0 +1,89 @@
<v-page
[hasSide]="true"
[toolbarTitle]="toolbarTitle"
[toolbarSubTitle]="toolbarSubTitle"
[toolbarShowSubTitle]="toolbarShowSubTitle"
>
<!-- Content -->
<x-card [isInPage]="true" [showActions]="true" [color]="ColorNames.Light">
<!-- Content -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('content')"
></x-markdown>
<!-- Actions -->
<div actions>
<a
target="_blank"
href="https://docs.x-framework.ir/x-framework-components/components/XCardComponent.html"
>{{resourceProvider(ResourceIDs.documentation)}}</a
>
</div>
</x-card>
<!-- Sample -->
<x-markdown
[isInPage]="true"
[mode]="'preview'"
[content]="sample1"
[hasToolbar]="false"
[wrapWithCard]="true"
[cssClass]="'code-block'"
[cardTitle]="resourceProvider(ResourceIDs.sample)"
></x-markdown>
<!-- Component -->
<x-card
[showHeader]="true"
[isInPage]="true"
[showFooter]="true"
[showContent]="true"
[showActions]="true"
[color]="ColorNames.Tertiary"
[title]="resourceProvider(ResourceIDs.app_name)"
[subTitle]="resourceProvider(ResourceIDs.company)"
>
<div header>
{{resourceProvider(ResourceIDs.header)}}
</div>
<div content>
{{resourceProvider(ResourceIDs.temp_label)}}
</div>
<div actions>
{{resourceProvider(ResourceIDs.actions)}}
</div>
<div footer>
{{resourceProvider(ResourceIDs.footer)}}
</div>
</x-card>
<x-markdown
[mode]="'preview'"
[content]="sample2"
[hasToolbar]="false"
[wrapWithCard]="true"
[isInPage]="true"
[cssClass]="'code-block'"
[cardTitle]="resourceProvider(ResourceIDs.sample)"
></x-markdown>
<x-card
[showHeader]="true"
[isInPage]="true"
[showContent]="true"
[color]="ColorNames.Medium"
[imageUrl]="'/assets/image/logo.png'"
[avatarUrl]="'/assets/image/logo.png'"
[title]="resourceProvider(ResourceIDs.app_name)"
[subTitle]="resourceProvider(ResourceIDs.company)"
>
<div content>
{{resourceProvider(ResourceIDs.temp_label)}}
</div>
</x-card>
</v-page>
@@ -0,0 +1,3 @@
.content-container {
margin: 24px;
}
+135
View File
@@ -0,0 +1,135 @@
import { Component } from '@angular/core';
import { VPageComponent } from '../../../views/v-page/v-page.component';
import { AppResourceIDs } from 'src/app/config/app.localization.config';
import { XResourceIDs, XColor, isNullOrEmptyString } from 'x-framework-core';
@Component({
selector: 'app-card',
templateUrl: './card.page.html',
styleUrls: ['./card.page.scss'],
})
// tslint:disable-next-line:component-class-suffix
export class CardPage extends VPageComponent {
//
//#region Props ...
//
//#region Page Props ...
titleRes = AppResourceIDs.card;
toolbarTitle = this.resourceProvider(this.titleRes);
toolbarSubTitle = this.resourceProvider(AppResourceIDs.card_description);
toolbarShowSubTitle = true;
//#endregion
//
// Prepare All Resource IDs ...
readonly ResourceIDs = Object.assign(
Object.assign({}, XResourceIDs),
AppResourceIDs
) as any;
//#endregion
//
// Content ...
readonly contentFa = `
# ${this.toolbarTitle}
این مولفه جهت نمایش یک جزء از اجزای تشکیل دهنده یک صفحه بکار میرود.
این مولفه می تواند بسته به ابعاد مختلف صفحه واکنش نشان دهد و خود را مطابق کند.
`;
readonly contentEn = `
# ${this.toolbarTitle}
this component use to present a part of a page.
this component can adapt itself based on screen size.
`;
//
readonly sample1 =
'```html' +
`
<x-card
[showHeader]="true"
[isPageCard]="true"
[showFooter]="true"
[showContent]="true"
[showActions]="true"
[color]="ColorNames.Tertiary"
[title]="resourceProvider(
ResourceIDs.app_name)"
[subTitle]="resourceProvider(
ResourceIDs.company)"
>
<div header>
{{resourceProvider(
ResourceIDs.header)}}
</div>
<div content>
{{resourceProvider(
ResourceIDs.temp_label)}}
</div>
<div actions>
{{resourceProvider(
ResourceIDs.actions)}}
</div>
<div footer>
{{resourceProvider(
ResourceIDs.footer)}}
</div>
</x-card>
` +
'```';
readonly sample2 =
'```html' +
`
<x-card
[showHeader]="true"
[isPageCard]="true"
[showContent]="true"
[color]="ColorNames.Medium"
[imageUrl]="
\'/assets/image/logo.png\'"
[avatarUrl]="
\'/assets/image/logo.png\'"
[title]="resourceProvider(
ResourceIDs.app_name)"
[subTitle]="resourceProvider(
ResourceIDs.company)"
>
<div content>
{{resourceProvider(
ResourceIDs.temp_label)}}
</div>
</x-card>
` +
'```';
//
// Provide content based on current locale ...
getContent(title: string) {
//
if (isNullOrEmptyString(title)) {
return '';
}
//
const currentLocale = this.managerService.currentLocale;
//
const varName =
title +
(currentLocale === 'en-US'
? 'En'
: currentLocale === 'fa-IR'
? 'Fa'
: '');
const result = this[`${varName}`];
//
return result || '';
}
}
@@ -0,0 +1,49 @@
<v-page
[hasSide]="true"
[toolbarTitle]="toolbarTitle"
[toolbarSubTitle]="toolbarSubTitle"
[toolbarShowSubTitle]="toolbarShowSubTitle"
>
<!-- Content -->
<x-card [isInPage]="true" [showActions]="true" [color]="ColorNames.Light">
<!-- Content -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('content')"
></x-markdown>
<!-- Actions -->
<div actions>
<a
target="_blank"
href="https://docs.x-framework.ir/x-framework-components/components/XCounterComponent.html"
>{{resourceProvider(ResourceIDs.documentation)}}</a
>
</div>
</x-card>
<!-- <x-markdown
[isInPage]="true"
[mode]="'preview'"
[content]="sample1"
[hasToolbar]="false"
[wrapWithCard]="true"
[cssClass]="'code-block'"
[cardTitle]="resourceProvider(ResourceIDs.sample)"
></x-markdown> -->
<!-- ColorPicker -->
<x-color-picker
[isInPage]="true"
[wrapWithCard]="true"
[selectedColor]="'#fff500'"
[showCopyToClipboard]="true"
[presetColors]="presetColors"
[outputFormat]="outputFormat"
[cursorColor]="'tertiary-tint'"
[presetColorsLable]="presetColorsLable"
[representColorFormats]="representFormats"
(colorSelected)="handleColorSelected($event)"
></x-color-picker>
</v-page>
@@ -0,0 +1,107 @@
import {
XColorPickerOutputFormat,
XColorPickerOutputFormatIdentifier,
} from 'x-framework-components';
import { Component } from '@angular/core';
import { VPageComponent } from '../../../views/v-page/v-page.component';
import { AppResourceIDs } from 'src/app/config/app.localization.config';
import { XColor, XResourceIDs, isNullOrEmptyString } from 'x-framework-core';
@Component({
selector: 'app-color-picker',
templateUrl: './color-picker.page.html',
styleUrls: ['./color-picker.page.scss'],
})
// tslint:disable-next-line:component-class-suffix
export class ColorPickerPage extends VPageComponent {
//
//#region Props ...
//
//#region Page Props ...
titleRes = AppResourceIDs.color_picker;
toolbarTitle = this.resourceProvider(this.titleRes);
toolbarSubTitle = this.resourceProvider(
AppResourceIDs.color_picker_description
);
toolbarShowSubTitle = true;
//#endregion
//
// Prepare All Resource IDs ...
readonly ResourceIDs = Object.assign(
Object.assign({}, XResourceIDs),
AppResourceIDs
) as any;
//#endregion
//
// Content ...
readonly contentFa = `
# ${this.toolbarTitle}
`;
readonly contentEn = `
# ${this.toolbarTitle}
`;
//
readonly sample1 =
'```html' +
`
` +
'```';
//
readonly presetColorsLable = 'PresetColors';
//
readonly presetColors = [
'#fff',
'#000',
'#2889e9',
'#e920e9',
'#fff500',
'rgb(236,64,64)',
];
readonly outputFormat = XColorPickerOutputFormat.XHEX;
readonly representFormats: XColorPickerOutputFormatIdentifier[] = [
XColorPickerOutputFormat.XHEX,
XColorPickerOutputFormat.XRGBA,
// XColorPickerOutputFormat.XHSLA,
];
//
//#region UI Providers ...
//
// Provide content based on current locale ...
getContent(title: string) {
//
if (isNullOrEmptyString(title)) {
return '';
}
//
const currentLocale = this.managerService.currentLocale;
//
const varName =
title +
(currentLocale === 'en-US'
? 'En'
: currentLocale === 'fa-IR'
? 'Fa'
: '');
const result = this[`${varName}`];
//
return result || '';
}
//#endregion
handleColorSelected(color: string) {
console.log('Color Selected From ColorPicker Component: ', color);
}
}
@@ -0,0 +1,171 @@
import { NgModule } from '@angular/core';
import { FabPage } from './fab/fab.page';
import { MapPage } from './map/map.page';
import { FormPage } from './form/form.page';
import { GridPage } from './grid/grid.page';
import { ListPage } from './list/list.page';
import { IconPage } from './icon/icon.page';
import { CardPage } from './card/card.page';
import { PagePage } from './page/page.page';
import { TabsPage } from './tabs/tabs.page';
import { RouterModule } from '@angular/router';
import { CommonModule } from '@angular/common';
import { TablePage } from './table/table.page';
import { SliderPage } from './slider/slider.page';
import { CounterPage } from './counter/counter.page';
import { StepperPage } from './stepper/stepper.page';
import { MarkdownPage } from './markdown/markdown.page';
import { ViewsModule } from 'src/app/views/views.module';
import { ColorPickerPage } from './color-picker/color-picker.page';
import { IntroductionPage } from './introduction/introduction.page';
import { TabNavigatorPage } from './tab-navigator/tab-navigator.page';
import { BaseRoutes, ComponentsRoutes } from 'src/app/config/page.config';
import { FileComponentsPage } from './file-components/file-components.page';
import { ExpandableListPage } from './expandable-list/expandable-list.page';
import { ModelPresenterPage } from './model-presenter/model-presenter.page';
import { DescriptionListPage } from './description-list/description-list.page';
import { SmallComponentsPage } from './small-components/small-components.page';
import { ExpandablePanelPage } from './expandable-panel/expandable-panel.page';
import { SampleModalComponent } from './small-components/sample-modal/sample-modal.component';
import { TreePage } from './tree/tree.page';
@NgModule({
imports: [
ViewsModule,
CommonModule,
RouterModule.forChild([
{
path: BaseRoutes.Default,
redirectTo: ComponentsRoutes.Introduction,
pathMatch: 'full',
},
{
path: ComponentsRoutes.Introduction,
component: IntroductionPage,
},
{
path: ComponentsRoutes.SmallComponents,
component: SmallComponentsPage,
},
{
path: ComponentsRoutes.Card,
component: CardPage,
},
{
path: ComponentsRoutes.Icon,
component: IconPage,
},
{
path: ComponentsRoutes.Counter,
component: CounterPage,
},
{
path: ComponentsRoutes.ColorPicker,
component: ColorPickerPage,
},
{
path: ComponentsRoutes.Fab,
component: FabPage,
},
{
path: ComponentsRoutes.FileComponents,
component: FileComponentsPage,
},
{
path: ComponentsRoutes.Form,
component: FormPage,
},
{
path: ComponentsRoutes.Grid,
component: GridPage,
},
{
path: ComponentsRoutes.List,
component: ListPage,
},
{
path: ComponentsRoutes.Map,
component: MapPage,
},
{
path: ComponentsRoutes.MarkDown,
component: MarkdownPage,
},
{
path: ComponentsRoutes.Tree,
component: TreePage,
},
{
path: ComponentsRoutes.DescriptionList,
component: DescriptionListPage,
},
{
path: ComponentsRoutes.ExpandableList,
component: ExpandableListPage,
},
{
path: ComponentsRoutes.ExpandablePanel,
component: ExpandablePanelPage,
},
{
path: ComponentsRoutes.ModelPresenter,
component: ModelPresenterPage,
},
{
path: ComponentsRoutes.Slider,
component: SliderPage,
},
{
path: ComponentsRoutes.Stepper,
component: StepperPage,
},
{
path: ComponentsRoutes.Tabs,
component: TabsPage,
},
{
path: ComponentsRoutes.Table,
component: TablePage,
},
{
path: ComponentsRoutes.Page,
component: PagePage,
},
{
path: ComponentsRoutes.TabNavigator,
component: TabNavigatorPage,
},
]),
],
declarations: [
FabPage,
MapPage,
CardPage,
IconPage,
FormPage,
GridPage,
PagePage,
ListPage,
TabsPage,
TreePage,
TablePage,
SliderPage,
StepperPage,
CounterPage,
MarkdownPage,
ColorPickerPage,
IntroductionPage,
TabNavigatorPage,
ExpandableListPage,
FileComponentsPage,
ModelPresenterPage,
SmallComponentsPage,
ExpandablePanelPage,
DescriptionListPage,
//
SampleModalComponent,
],
entryComponents: [SampleModalComponent],
})
export class ComponentsPageModule {}
@@ -0,0 +1,108 @@
<v-page
[hasSide]="true"
[toolbarTitle]="toolbarTitle"
[toolbarSubTitle]="toolbarSubTitle"
[toolbarShowSubTitle]="toolbarShowSubTitle"
>
<!-- Content -->
<x-card [isInPage]="true" [showActions]="true" [color]="ColorNames.Light">
<!-- Content -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('content')"
></x-markdown>
<!-- Actions -->
<div actions>
<a
target="_blank"
href="https://docs.x-framework.ir/x-framework-components/components/XCounterComponent.html"
>{{resourceProvider(ResourceIDs.documentation)}}</a
>
</div>
</x-card>
<x-markdown
[isInPage]="true"
[mode]="'preview'"
[content]="sample1"
[hasToolbar]="false"
[wrapWithCard]="true"
[cssClass]="'code-block'"
[cardTitle]="resourceProvider(ResourceIDs.sample)"
></x-markdown>
<x-markdown
[isInPage]="true"
[mode]="'preview'"
[content]="sample2"
[hasToolbar]="false"
[wrapWithCard]="true"
[cssClass]="'code-block'"
></x-markdown>
<x-markdown
[isInPage]="true"
[mode]="'preview'"
[content]="sample3"
[hasToolbar]="false"
[wrapWithCard]="true"
[cssClass]="'code-block'"
></x-markdown>
<x-markdown
[isInPage]="true"
[mode]="'preview'"
[content]="sample4"
[hasToolbar]="false"
[wrapWithCard]="true"
[cssClass]="'code-block'"
></x-markdown>
<!-- Counter -->
<x-counter
#counter
[stopValue]="0"
[isInPage]="true"
[startValue]="180"
[autoStart]="true"
[currentValue]="150"
[wrapWithCard]="true"
[cardShowActions]="true"
[cssClass]="'ion-text-center'"
[type]="CounterTypes.CountDown"
[displayPattern]="getCounterMessage"
(counterStop)="handleCounterStop($event)"
(counterTtick)="handleCounterTick($event)"
(counterStart)="handleCounterStart($event)"
>
<div actions>
<x-slotter [layout]="SlotLayout.HORIZONTAL">
<x-slot [name]="SlotNames.START" [cssClass]="'ion-text-start'">
<x-button
(clicked)="counter.start()"
[title]="ResourceIDs.start"
[color]="ColorNames.Tertiary"
></x-button>
</x-slot>
<x-slot [name]="SlotNames.CENTER" [cssClass]="'ion-text-center'">
<x-button
(clicked)="counter.pause()"
[title]="ResourceIDs.pause"
[color]="ColorNames.Warning"
></x-button>
</x-slot>
<x-slot [name]="SlotNames.END" [cssClass]="'ion-text-end'">
<x-button
[title]="ResourceIDs.reset"
[color]="ColorNames.Danger"
(clicked)="counter.startValue = 180; counter.stopValue= 0; counter.currentValue = 0; counter.start()"
></x-button>
</x-slot>
</x-slotter>
</div>
</x-counter>
</v-page>
@@ -0,0 +1,3 @@
.content-container {
margin: 24px;
}
@@ -0,0 +1,193 @@
import {
XColor,
toTimeFormat,
XResourceIDs,
toPersianNumbers,
isNullOrEmptyString,
} from 'x-framework-core';
import {
XSlotName,
XSlotLayout,
XCounterType,
XCounterTick,
} from 'x-framework-components';
import { Component } from '@angular/core';
import { VPageComponent } from '../../../views/v-page/v-page.component';
import { AppResourceIDs } from 'src/app/config/app.localization.config';
@Component({
selector: 'app-counter',
templateUrl: './counter.page.html',
styleUrls: ['./counter.page.scss'],
})
// tslint:disable-next-line:component-class-suffix
export class CounterPage extends VPageComponent {
//
//#region Props ...
//
//#region Page Props ...
titleRes = AppResourceIDs.counter;
toolbarTitle = this.resourceProvider(this.titleRes);
toolbarSubTitle = this.resourceProvider(AppResourceIDs.counter_description);
toolbarShowSubTitle = true;
//#endregion
//
// Prepare All Resource IDs ...
readonly ResourceIDs = Object.assign(
Object.assign({}, XResourceIDs),
AppResourceIDs
) as any;
//
// Counter Types ...
readonly CounterTypes = Object.assign({}, XCounterType);
//
// Slotter ...
readonly SlotNames = Object.assign({}, XSlotName);
readonly SlotLayout = Object.assign({}, XSlotLayout);
//#endregion
//
// Content ...
readonly contentFa = `
# ${this.toolbarTitle}
این مولفه در مواردی که قصد داریم مدت زمان معینی را برای ادامه یا انجام کاری در نظر بگیریم مورد استفاده قرار می گیرد.
`;
readonly contentEn = `
# ${this.toolbarTitle}
this component used when we need to wait specific time for continue or doing an action.
`;
//
readonly sample1 =
'```html' +
`
<x-counter
#counter
[stopValue]="0"
[startValue]="180"
[currentValue]="150"
[type]="CounterTypes
.CountDown"
[displayPattern]="
getCounterMessage"
(counterStop)="
handleCounterStop($event)"
(counterTtick)="
handleCounterTick($event)"
(counterStart)="
handleCounterStart($event)"
></x-counter>
` +
'```';
//
readonly sample2 =
'```html' +
`
<x-button
(click)="counter.start()"
[title]="ResourceIDs.start"
[color]="ColorNames.Tertiary"
></x-button>
` +
'```';
//
readonly sample3 =
'```html' +
`
<x-button
(click)="counter.pause()"
[title]="ResourceIDs.pause"
[color]="ColorNames.Warning"
></x-button>
` +
'```';
//
readonly sample4 =
'```html' +
`
<x-button
[title]="ResourceIDs.reset"
[color]="ColorNames.Danger"
(click)="
counter.startValue = 180;
counter.stopValue= 0;
counter.currentValue = 0;
counter.start()"
></x-button>
` +
'```';
//
//#region UI Providers ...
//
// Provide content based on current locale ...
getContent(title: string) {
//
if (isNullOrEmptyString(title)) {
return '';
}
//
const currentLocale = this.managerService.currentLocale;
//
const varName =
title +
(currentLocale === 'en-US'
? 'En'
: currentLocale === 'fa-IR'
? 'Fa'
: '');
const result = this[`${varName}`];
//
return result || '';
}
getCounterMessage(start: number, stop: number, current: number): string {
//
let steps = stop - start;
if (steps < 0) {
steps *= -1;
}
//
const ellapsed = steps - current;
const remained = steps - ellapsed;
//
const minutes = Math.trunc(remained / 60);
const seconds = remained - minutes * 60;
//
const message = `${toTimeFormat(minutes)}:${toTimeFormat(seconds)}`;
//
const locale = this.managerService.currentLocale;
//
if (locale === 'fa-IR') {
return toPersianNumbers(message);
} else {
return message;
}
}
//#endregion
//
//#region UI Handlers ...
handleCounterStop(event: XCounterTick) {}
handleCounterStart(event: XCounterTick) {}
handleCounterTick(event: XCounterTick) {}
//#endregion
}
@@ -0,0 +1,45 @@
<v-page
[hasSide]="true"
[toolbarTitle]="toolbarTitle"
[toolbarSubTitle]="toolbarSubTitle"
[toolbarShowSubTitle]="toolbarShowSubTitle"
>
<!-- Content -->
<x-card [isInPage]="true" [showActions]="true" [color]="ColorNames.Light">
<!-- Content -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('content')"
></x-markdown>
<!-- Actions -->
<div actions>
<a
target="_blank"
href="https://docs.x-framework.ir/x-framework-components/components/XDescriptionListComponent.html"
>{{resourceProvider(ResourceIDs.documentation)}}</a
>
</div>
</x-card>
<!-- Sample -->
<x-markdown
[isInPage]="true"
[mode]="'preview'"
[content]="sample1"
[hasToolbar]="false"
[wrapWithCard]="true"
[cssClass]="'code-block'"
[cardTitle]="resourceProvider(ResourceIDs.sample)"
></x-markdown>
<!-- Component -->
<x-description-list
[model]="item"
[isInPage]="true"
[isLegacy]="true"
[wrapWithCard]="true"
></x-description-list>
<!-- [hiddenModelKeys]="['gender', 'mobile']" -->
</v-page>
@@ -0,0 +1,3 @@
.content-container {
margin: 24px;
}
@@ -0,0 +1,100 @@
import { Component } from '@angular/core';
import { XResourceIDs, isNullOrEmptyString } from 'x-framework-core';
import { VPageComponent } from '../../../views/v-page/v-page.component';
import { AppResourceIDs } from 'src/app/config/app.localization.config';
export interface ItemType {
first_name: string;
last_name: string;
gender: string;
mobile: string;
email: string;
}
@Component({
selector: 'app-description-list',
templateUrl: './description-list.page.html',
styleUrls: ['./description-list.page.scss'],
})
// tslint:disable-next-line:component-class-suffix
export class DescriptionListPage extends VPageComponent {
//
//#region Props ...
//
//#region Page Props ...
titleRes = AppResourceIDs.description_list;
toolbarTitle = this.resourceProvider(this.titleRes);
toolbarSubTitle = this.resourceProvider(
AppResourceIDs.description_list_description
);
toolbarShowSubTitle = true;
//#endregion
//
item: ItemType = {
first_name: 'Hadi',
last_name: 'Khazaee Asl',
gender: 'male',
mobile: '09121694056',
email: 'hadi_khazaee_asl@yahoo.com',
};
//
// Prepare All Resource IDs ...
readonly ResourceIDs = Object.assign(
Object.assign({}, XResourceIDs),
AppResourceIDs
) as any;
//#endregion
//
// Content ...
readonly contentFa = `
# ${this.toolbarTitle}
این مولفه جهت نمایش یک مدل داده ای در غالبی ساختار یافته بکار میرود
`;
readonly contentEn = `
# ${this.toolbarTitle}
this component used to show a data model in an structural template
`;
//
readonly sample1 =
'```html' +
`
<x-description-list
[model]="item"
[isInPage]="true"
[wrapWithCard]="true"
[hiddenModelKeys]="['gender', 'mobile']"
>
</x-description-list>
` +
'```';
//
// Provide content based on current locale ...
getContent(title: string) {
//
if (isNullOrEmptyString(title)) {
return '';
}
//
const currentLocale = this.managerService.currentLocale;
//
const varName =
title +
(currentLocale === 'en-US'
? 'En'
: currentLocale === 'fa-IR'
? 'Fa'
: '');
const result = this[`${varName}`];
//
return result || '';
}
}
@@ -0,0 +1,64 @@
<v-page
[hasSide]="true"
[toolbarTitle]="toolbarTitle"
[toolbarSubTitle]="toolbarSubTitle"
[toolbarShowSubTitle]="toolbarShowSubTitle"
>
<!-- Content -->
<x-card [isInPage]="true" [showActions]="true" [color]="ColorNames.Light">
<!-- Content -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('content')"
></x-markdown>
<!-- Actions -->
<div actions>
<a
target="_blank"
href="https://docs.x-framework.ir/x-framework-components/components/XExpandableListComponent.html"
>{{resourceProvider(ResourceIDs.documentation)}}</a
>
</div>
</x-card>
<x-markdown
[isInPage]="true"
[mode]="'preview'"
[content]="sample1"
[hasToolbar]="false"
[wrapWithCard]="true"
[cssClass]="'code-block'"
[cardTitle]="resourceProvider(ResourceIDs.sample)"
></x-markdown>
<x-markdown
[isInPage]="true"
[mode]="'preview'"
[content]="sample2"
[hasToolbar]="false"
[wrapWithCard]="true"
[cssClass]="'code-block'"
></x-markdown>
<x-expandable-list
[isInPage]="true"
[items]="listItems"
[wrapWithCard]="true"
[closeSiblings]="true"
[supportRouting]="false"
[showChildDetailIcon]="true"
[showParentDetailIcon]="true"
[startupState]="'expand-all'"
[disableParentRouting]="false"
[dividerColor]="ColorNames.Danger"
[childColor]="ColorNames.Secondary"
[parentColor]="ColorNames.Tertiary"
[highlightColor]="ColorNames.Success"
[parentActiveColor]="ColorNames.Danger"
[childActiveColor]="ColorNames.Warning"
(itemSelected)="handleItemSelected($event)"
>
</x-expandable-list>
</v-page>
@@ -0,0 +1,173 @@
import {
XColor,
random,
XResourceIDs,
isNullOrEmptyString,
} from 'x-framework-core';
import { Component } from '@angular/core';
import { AppResourceIDs } from 'src/app/config/app.localization.config';
import { VPageComponent } from '../../../views/v-page/v-page.component';
import { XIconNames, XExpandableListItem } from 'x-framework-components';
@Component({
selector: 'app-expandable-list',
templateUrl: './expandable-list.page.html',
styleUrls: ['./expandable-list.page.scss'],
})
// tslint:disable-next-line:component-class-suffix
export class ExpandableListPage extends VPageComponent {
//
//#region Props ...
//
//#region Page Props ...
titleRes = AppResourceIDs.expandable_list;
toolbarTitle = this.resourceProvider(this.titleRes);
toolbarSubTitle = this.resourceProvider(
AppResourceIDs.expandable_list_description
);
toolbarShowSubTitle = true;
//#endregion
//
// Prepare All Resource IDs ...
readonly ResourceIDs = Object.assign(
Object.assign({}, XResourceIDs),
AppResourceIDs
) as any;
//
readonly IconNames = Object.assign({}, XIconNames);
//#endregion
//
tempList = Array.from(Array(5).keys());
tempChilds = Array.from(Array(2).keys());
listItems: XExpandableListItem<string>[] = this.tempList.map((i) => {
//
const li: XExpandableListItem<string> = {
...this.toListItem(i),
childs:
random(0, 1) === 0
? undefined
: this.tempChilds.map((c) => {
//
const cLi: XExpandableListItem<string> = {
...this.toListItem(c, i.toString()),
};
//
return cLi;
}),
};
//
return li;
});
//
// Content ...
readonly contentFa = `
# ${this.toolbarTitle}
از این مولفه در مواقعی استفاده می شود که قصد داریم مجموعه هایی از اطلاعات را در گروه های مختلف دسته بندی کرده و نمایش دهیم.
`;
readonly contentEn = `
# ${this.toolbarTitle}
this component used to show a collection of data sets in a grouped structure.
`;
//
readonly sample1 =
'```html' +
`
<x-expandable-list
[items]="listItems"
[closeSiblings]="true"
[supportRouting]="false"
[showChildDetailIcon]="true"
[showParentDetailIcon]="true"
[startupState]="'expand-all'"
[disableParentRouting]="false"
[dividerColor]="ColorNames.Danger"
[childColor]="ColorNames.Secondary"
[parentColor]="ColorNames.Tertiary"
[highlightColor]="ColorNames.Success"
[parentActiveColor]="ColorNames.Danger"
[childActiveColor]="ColorNames.Warning"
(itemSelected)="handleItemSelected($event)"
>
</x-expandable-list>
` +
'```';
//
readonly sample2 =
'```typescript' +
`
async handleItemSelected(item: XExpandableListItem<any>) {
//
if (!item) {
return;
}
//
await this.managerService.notificationService.presentSuccessNotification({
message: \`item \${item.id} Selected ...\`,
dissmissable: true,
});
}
` +
'```';
//
//#region UI Providers ...
//
// Provide content based on current locale ...
getContent(title: string) {
//
if (isNullOrEmptyString(title)) {
return '';
}
//
const currentLocale = this.managerService.currentLocale;
//
const varName =
title +
(currentLocale === 'en-US'
? 'En'
: currentLocale === 'fa-IR'
? 'Fa'
: '');
const result = this[`${varName}`];
//
return result || '';
}
//#endregion
async handleItemSelected(item: XExpandableListItem<any>) {
//
if (!item) {
return;
}
//
await this.managerService.notificationService.presentSuccessNotification({
message: `item ${item.id} Selected ...`,
dissmissable: true,
});
}
private toListItem(data: any, prefix?: string) {
return {
id: `${prefix ? prefix + '_' : ''}${data}`,
data: `Item ${prefix ? prefix + '_' : ''}${data}`,
opened: random(0, 1) === 0 ? true : false,
title: `Title ${prefix ? prefix + '_' : ''}${data}`,
description: `Description ${prefix ? prefix + '_' : ''}${data}`,
} as XExpandableListItem<any>;
}
}
@@ -0,0 +1,93 @@
<v-page
[hasSide]="true"
[toolbarTitle]="toolbarTitle"
[toolbarSubTitle]="toolbarSubTitle"
[toolbarShowSubTitle]="toolbarShowSubTitle"
>
<!-- Content -->
<x-card [isInPage]="true" [showActions]="true" [color]="ColorNames.Light">
<!-- Content -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('content')"
></x-markdown>
<!-- Actions -->
<div actions>
<a
target="_blank"
href="https://docs.x-framework.ir/x-framework-components/modules/XExpandablePanelModule.html"
>{{resourceProvider(ResourceIDs.documentation)}}</a
>
</div>
</x-card>
<!-- Sample -->
<x-markdown
[isInPage]="true"
[mode]="'preview'"
[content]="sample1"
[hasToolbar]="false"
[wrapWithCard]="true"
[cssClass]="'code-block'"
[cardTitle]="resourceProvider(ResourceIDs.sample)"
>
</x-markdown>
<!-- Component -->
<x-expandable-panel
[isInPage]="true"
[isAccordion]="true"
[selected]="'First'"
[wrapWithCard]="true"
[headerColor]="ColorNames.Tertiary"
[hideDescriptionOnSmallScreens]="false"
[headerHighlightColor]="ColorNames.Warning"
>
<x-panel [id]="'First'" [hasNext]="true" [hasCustomActions]="true">
<div x-panel-title>
Title 1
</div>
<div x-panel-description>
Description 1
</div>
Content 1
<div actions>
Custom Actions 1
</div>
</x-panel>
<x-panel
[id]="'Second'"
[hasNext]="true"
[hasPrev]="true"
[hasReset]="true"
>
<div x-panel-title>
Title 2
</div>
<div x-panel-description>
Description 2
</div>
Content 2
</x-panel>
<x-panel [id]="'Third'" [hasPrev]="true" [hasReset]="true">
<div x-panel-title>
Title 3
</div>
<div x-panel-description>
Description 3
</div>
Content 3
</x-panel>
</x-expandable-panel>
</v-page>
@@ -0,0 +1,130 @@
import { Component } from '@angular/core';
import { XIconNames } from 'x-framework-components';
import { VPageComponent } from '../../../views/v-page/v-page.component';
import { AppResourceIDs } from 'src/app/config/app.localization.config';
import { XResourceIDs, isNullOrEmptyString, XColor } from 'x-framework-core';
@Component({
selector: 'app-expandable-panel',
templateUrl: './expandable-panel.page.html',
styleUrls: ['./expandable-panel.page.scss'],
})
// tslint:disable-next-line:component-class-suffix
export class ExpandablePanelPage extends VPageComponent {
//
//#region Props ...
//
//#region Page Props ...
titleRes = AppResourceIDs.expandable_panel;
toolbarTitle = this.resourceProvider(this.titleRes);
toolbarSubTitle = this.resourceProvider(
AppResourceIDs.expandable_panel_description
);
toolbarShowSubTitle = true;
//#endregion
//
// Prepare All Resource IDs ...
readonly ResourceIDs = Object.assign(
Object.assign({}, XResourceIDs),
AppResourceIDs
) as any;
//
readonly IconNames = Object.assign({}, XIconNames);
//#endregion
//
// Content ...
readonly contentFa = `
# ${this.toolbarTitle}
این مولفه جهت گروه بندی محتوای قابل ارائه در یک نمایه بکار می رود.
`;
readonly contentEn = `
# ${this.toolbarTitle}
this component used to Grouped representable contents in a View.
`;
//
readonly sample1 =
'```html' +
`
<x-expandable-panel
[isAccordion]="true"
[selected]="'First'"
[headerColor]="ColorNames.Tertiary"
[headerHighlightColor]="ColorNames.Warning"
>
<x-panel [id]="'First'" [hasNext]="true" [hasCustomActions]="true">
<div x-panel-title>
Title 1
</div>
<div x-panel-description>
Description 1
</div>
Content 1
<div actions>
Custom Actions 1
</div>
</x-panel>
<x-panel [id]="'Second'" [hasNext]="true" [hasPrev]="true" [hasReset]="true">
<div x-panel-title>
Title 2
</div>
<div x-panel-description>
Description 2
</div>
Content 2
</x-panel>
<x-panel [id]="'Third'" [hasPrev]="true" [hasReset]="true">
<div x-panel-title>
Title 3
</div>
<div x-panel-description>
Description 3
</div>
Content 3
</x-panel>
</x-expandable-panel>
` +
'```';
//
//#region UI Providers ...
//
// Provide content based on current locale ...
getContent(title: string) {
//
if (isNullOrEmptyString(title)) {
return '';
}
//
const currentLocale = this.managerService.currentLocale;
//
const varName =
title +
(currentLocale === 'en-US'
? 'En'
: currentLocale === 'fa-IR'
? 'Fa'
: '');
const result = this[`${varName}`];
//
return result || '';
}
//#endregion
}
+187
View File
@@ -0,0 +1,187 @@
<v-page
[actions]="actions"
[toolbarSubTitle]="toolbarSubTitle"
[toolbarShowSubTitle]="toolbarShowSubTitle"
>
<!-- Content -->
<x-card [isInPage]="true" [showActions]="true" [color]="ColorNames.Light">
<!-- Content -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('content')"
></x-markdown>
<!-- Actions -->
<div actions>
<a
target="_blank"
href="https://docs.x-framework.ir/x-framework-components/components/XFabComponent.html"
>{{resourceProvider(ResourceIDs.documentation)}}</a
>
</div>
</x-card>
<x-card
[isInPage]="true"
[showHeader]="true"
[showActions]="true"
[color]="ColorNames.Light"
[title]="resourceProvider(ResourceIDs.sample)"
>
<x-markdown
[mode]="'preview'"
[content]="sample1"
[hasToolbar]="false"
[cssClass]="'code-block'"
></x-markdown>
<x-markdown
[mode]="'preview'"
[content]="sample2"
[hasToolbar]="false"
[cssClass]="'code-block'"
></x-markdown>
</x-card>
<x-card [isInPage]="true" [showActions]="true" [color]="ColorNames.Light">
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<x-fab
[item]="{
id: 'fab_1',
fixed: true,
icon: IconNames.menu_vertical,
size: FabButtonSizes.REGULAR,
color: ColorNames.Tertiary,
vertical: FabVerticalSlots.CENTER,
horizontal: FabHorizontalSlots.CENTER,
childs: [
{
id: 'fab_child_1',
index: 0,
icon: IconNames.phone,
side: FabButtonSides.TOP,
size: FabButtonSizes.MINI,
color: ColorNames.Success,
tooltip: ResourceIDs.temp_label,
handler: fabHandler
},
{
id: 'fab_child_2',
index: 1,
icon: IconNames.mail,
side: FabButtonSides.BOTTOM,
size: FabButtonSizes.MINI,
color: ColorNames.Primary,
tooltip: ResourceIDs.temp_label,
handler: fabHandler
},
{
id: 'fab_child_3',
index: 2,
icon: IconNames.share,
side: FabButtonSides.START,
size: FabButtonSizes.MINI,
color: ColorNames.Medium,
tooltip: ResourceIDs.temp_label,
handler: fabHandler
},
{
id: 'fab_child_3_1',
index: 3,
icon: IconNames.avatars,
side: FabButtonSides.START,
size: FabButtonSizes.MINI,
color: ColorNames.Secondary,
tooltip: ResourceIDs.temp_label,
handler: fabHandler
},
{
id: 'fab_child_4',
index: 4,
icon: IconNames.web,
side: FabButtonSides.END,
size: FabButtonSizes.MINI,
color: ColorNames.Danger,
tooltip: ResourceIDs.temp_label,
handler: fabHandler
}
]
}"
></x-fab>
</x-card>
<!-- Descriptions -->
<x-card
[isInPage]="true"
[showActions]="true"
[showHeader]="true"
[color]="ColorNames.Light"
[title]="resourceProvider(ResourceIDs.descriptions)"
>
<!-- Descriptions -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('descriptions')"
></x-markdown>
<!-- Actions -->
<div actions>
<a
target="_blank"
href="./assets/docs/x-framework-components/components/XPageComponent.html"
>{{resourceProvider(ResourceIDs.documentation)}}</a
>
</div>
</x-card>
<!-- Cards -->
<ng-container *ngFor="let id of ids">
<ng-container
*ngTemplateOutlet="contentRef; context: {$implicit: id}"
></ng-container>
</ng-container>
</v-page>
<!-- Template Content -->
<ng-template #contentRef let-id>
<x-card
[showHeader]="true"
[isInPage]="true"
[showActions]="true"
[title]="'Title ' + id"
[subTitle]="'SubTitle ' + id"
class="v-card v-no-marigin-card"
[avatarUrl]="'/assets/icon/favicon.png'"
>
<!-- Content -->
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quisquam
inventore, optio obcaecati, harum temporibus accusamus voluptatem,
sapiente corporis expedita ipsum quos enim odio adipisci! At praesentium
hic quaerat ad mollitia.
</p>
<!-- Actions -->
<div actions>
<!-- Like -->
<x-button [type]="ButtonTypes.Icon">
<x-icon [name]="IconNames.liked" [color]="ColorNames.Danger"></x-icon>
</x-button>
<!-- Share -->
<x-button [type]="ButtonTypes.Icon">
<x-icon [name]="IconNames.share" [color]="ColorNames.Tertiary"></x-icon>
</x-button>
</div>
</x-card>
</ng-template>
+229
View File
@@ -0,0 +1,229 @@
import {
XFabItem,
XIconNames,
XButtonType,
XFabButtonSize,
XFabButtonSide,
XFabVerticalSlot,
XFabHorizontalSlot,
} from 'x-framework-components';
import { Component } from '@angular/core';
import { VPageComponent } from '../../../views/v-page/v-page.component';
import { AppResourceIDs } from 'src/app/config/app.localization.config';
import { XResourceIDs, XColor, isNullOrEmptyString } from 'x-framework-core';
@Component({
selector: 'app-fab',
templateUrl: './fab.page.html',
styleUrls: ['./fab.page.scss'],
})
// tslint:disable-next-line:component-class-suffix
export class FabPage extends VPageComponent {
//
//#region Props ...
//
//#region Page Props ...
toolbarShowSubTitle = true;
titleRes = AppResourceIDs.fab;
toolbarTitle = this.resourceProvider(this.titleRes);
toolbarSubTitle = this.resourceProvider(AppResourceIDs.fab_description);
//
ids = Array.from(Array(25).keys());
//#endregion
//
// Prepare All Resource IDs ...
readonly ResourceIDs = Object.assign(
Object.assign({}, XResourceIDs),
AppResourceIDs
) as any;
//
readonly IconNames = Object.assign({}, XIconNames);
readonly ButtonTypes = Object.assign({}, XButtonType);
//
readonly FabButtonSizes = Object.assign({}, XFabButtonSize);
readonly FabButtonSides = Object.assign({}, XFabButtonSide);
readonly FabVerticalSlots = Object.assign({}, XFabVerticalSlot);
readonly FabHorizontalSlots = Object.assign({}, XFabHorizontalSlot);
//#endregion
//
// Content ...
readonly contentFa = `
# ${this.toolbarTitle}
این مولفه جهت ارائه مجموعه ای از فعالیت های مرتبط با یکدیگر در موارد لزوم مورد استفاده قرار می گیرد.
`;
readonly contentEn = `
# ${this.toolbarTitle}
this components usually used for present a group of related actions together in where we want.
`;
//
readonly sample1 =
'```html' +
`
<x-fab
[item]="{
id: 'fab_1',
fixed: true,
icon: IconNames.menu_vertical,
size: FabButtonSizes.REGULAR,
color: ColorNames.Tertiary,
vertical: FabVerticalSlots.CENTER,
horizontal: FabHorizontalSlots.CENTER,
childs: [
{
id: 'fab_child_1',
index: 0,
icon: IconNames.phone,
side: FabButtonSides.TOP,
size: FabButtonSizes.MINI,
color: ColorNames.Success,
tooltip: ResourceIDs.temp_label,
handler: fabHandler
},
{
id: 'fab_child_2',
index: 1,
icon: IconNames.mail,
side: FabButtonSides.BOTTOM,
size: FabButtonSizes.MINI,
color: ColorNames.Primary,
tooltip: ResourceIDs.temp_label,
handler: fabHandler
},
{
id: 'fab_child_3',
index: 2,
icon: IconNames.share,
side: FabButtonSides.START,
size: FabButtonSizes.MINI,
color: ColorNames.Medium,
tooltip: ResourceIDs.temp_label,
handler: fabHandler
},
{
id: 'fab_child_3_1',
index: 3,
icon: IconNames.avatars,
side: FabButtonSides.START,
size: FabButtonSizes.MINI,
color: ColorNames.Secondary,
tooltip: ResourceIDs.temp_label,
handler: fabHandler
},
{
id: 'fab_child_4',
index: 4,
icon: IconNames.web,
side: FabButtonSides.END,
size: FabButtonSizes.MINI,
color: ColorNames.Danger,
tooltip: ResourceIDs.temp_label,
handler: fabHandler
}
]
}"
></x-fab>
` +
'```';
//
readonly sample2 =
'```typescript' +
`
fabHandler = async (id?: string) => {
await this.handleNotifyFab(id);
};
` +
'```';
//
readonly descriptionsFa = `
در ادامه نمونه ای از بکارگیری دکمه های شناور ارائه می گردد که در مولفه صفحه و بعنوان یکی از اجزاء آن ارائه شده است.
برای آشنایی بیشتر می توانید به مستندات مولفه صفحه مراجعه کنید.
`;
readonly descriptionsEn = `
in the following example you will see an implementation of Fab component which provides as a part of Page component.
for more information you can see Page component documentations.
`;
//
actions: XFabItem = {
//
id: 'edit_profile',
//
fixed: true,
//
color: XColor.Warning,
//
icon: XIconNames.edit,
//
tooltip: AppResourceIDs.temp_label,
//
vertical: XFabVerticalSlot.BOTTOM,
horizontal: XFabHorizontalSlot.END,
//
disabled: this.uiDisabled,
//
handler: async (id?: string) => {
await this.handleNotifyFab(id);
},
};
//
//#region UI Providers ...
//
// Provide content based on current locale ...
getContent(title: string) {
//
if (isNullOrEmptyString(title)) {
return '';
}
//
const currentLocale = this.managerService.currentLocale;
//
const varName =
title +
(currentLocale === 'en-US'
? 'En'
: currentLocale === 'fa-IR'
? 'Fa'
: '');
const result = this[`${varName}`];
//
return result || '';
}
fabHandler = async (id?: string) => {
await this.handleNotifyFab(id);
};
//#endregion
//
//#region UI Handlers ...
async handleNotifyFab(id?: string) {
await this.managerService.notificationService.presentInfoNotification({
message: `Clicked Fab Id: ${id}`,
dissmissable: true,
});
}
//#endregion
}
@@ -0,0 +1,290 @@
<v-page
[hasSide]="true"
[toolbarTitle]="toolbarTitle"
[toolbarSubTitle]="toolbarSubTitle"
[toolbarShowSubTitle]="toolbarShowSubTitle"
>
<!-- Content -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[wrapWithCard]="true"
[isInPage]="true"
[content]="getContent('content')"
></x-markdown>
<!-- Expandable Panel -->
<x-expandable-panel
[isInPage]="true"
[isAccordion]="true"
[wrapWithCard]="true"
[selected]="'thumbnail'"
[headerColor]="ColorNames.Tertiary"
[headerHighlightColor]="ColorNames.Dark"
>
<!-- Thumbnail -->
<x-panel [id]="'thumbnail'" [hasCustomActions]="true">
<!-- Title and Description -->
<div x-panel-title>
{{ resourceProvider(ResourceIDs.thumbnail_component) }}
</div>
<!-- <div x-panel-description>
{{ resourceProvider(ResourceIDs.thumbnail_description) }}
</div> -->
<br />
<!-- Description -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('thumbnailContent')"
></x-markdown>
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[cssClass]="'code-block'"
[content]="thumbnailSample1"
></x-markdown>
<x-thumbnail [identifier]="fileUrl" [type]="ThumbnailTypes.CUSTOM">
</x-thumbnail>
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[cssClass]="'code-block'"
[content]="thumbnailSample2"
></x-markdown>
<x-thumbnail [identifier]="fileUrl" [type]="ThumbnailTypes.GENERAL">
</x-thumbnail>
<!-- Actions -->
<div x-panel-actions>
<a
target="_blank"
href="https://docs.x-framework.ir/x-framework-components/components/XThumbnailComponent.html"
>{{resourceProvider(ResourceIDs.documentation)}}</a
>
</div>
</x-panel>
<!-- File Drop Area -->
<x-panel [id]="'file_drop_area'" [hasCustomActions]="true">
<!-- Title and Description -->
<div x-panel-title>
{{ resourceProvider(ResourceIDs.file_drop_area) }}
</div>
<!-- <div x-panel-description>
{{ resourceProvider(ResourceIDs.file_drop_area_description) }}
</div> -->
<br />
<!-- Description -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('fileDropAreaContent')"
></x-markdown>
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[cssClass]="'code-block'"
[content]="fileDropAreaSample1"
></x-markdown>
<!-- File Drop Area -->
<x-file-drop-area
[supportsMultipleFiles]="true"
(filesChangeEmiter)="handleFilesChanged($event)"
></x-file-drop-area>
<!-- Actions -->
<div x-panel-actions>
<a
target="_blank"
href="https://docs.x-framework.ir/x-framework-components/components/XFileDropAreaComponent.html"
>{{resourceProvider(ResourceIDs.documentation)}}</a
>
</div>
</x-panel>
<!-- Image Cropper -->
<x-panel [id]="'iamge_cropper'" [hasCustomActions]="true">
<!-- Title and Description -->
<div x-panel-title>{{ resourceProvider(ResourceIDs.image_cropper) }}</div>
<!-- <div x-panel-description>
{{ resourceProvider(ResourceIDs.image_cropper_description) }}
</div> -->
<br />
<!-- Description -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('imageCropperContent')"
></x-markdown>
<!--
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[cssClass]="'code-block'"
[content]="imageCropperSample1"
></x-markdown>
-->
<!-- <div class="container"> -->
<!-- File Upload Input -->
<!-- <input
hidden
#fileInput
type="file"
multiple="false"
(change)="handleFilesSelected()"
[disabled]="isLoading || uiDisabled"
/>
<x-button
(click)="selectFile()"
[type]="ButtonTypes.Raised"
[color]="ColorNames.Primary"
[title]="resourceProvider(ResourceIDs.select) + ' ' + resourceProvider(ResourceIDs.avatar)"
>
</x-button> -->
<!-- Wrapper of Thumbnail -->
<!-- <div *ngIf="file" class="thumbnail-wrapper">
<x-slotter
[hasCenterSlot]="false"
[layout]="SlotLayout.HORIZONTAL"
[startTopSlotCssClass]="'ion-text-start'"
[endBottomSlotCssClass]="['ion-text-center']"
>
<x-slot [name]="SlotNames.START">
<div>
<x-thumbnail
class="x-thumb"
[identifier]="file"
[loading]="isLoading"
[cssClass]="'thumbnail'"
[uiDisabled]="uiDisabled"
[type]="ThumbnailTypes.CUSTOM"
>
</x-thumbnail>
</div>
</x-slot>
<x-slot [name]="SlotNames.END">
<div class="avatar-actions ion-text-end">
<div>
<x-button
*ngIf="croppableImage()"
[type]="ButtonTypes.Icon"
(click)="handleLoadCropper()"
[color]="ColorNames.Secondary"
[matTooltip]="resourceProvider(ResourceIDs.crop)"
>
<x-icon [name]="IconNames.crop"></x-icon>
</x-button>
<x-button
[type]="ButtonTypes.Icon"
(click)="handleClearFile()"
[color]="ColorNames.Warning"
[matTooltip]="resourceProvider(ResourceIDs.clear)"
>
<x-icon
[name]="IconNames.clear"
[color]="ColorNames.Light"
></x-icon>
</x-button>
</div>
</div>
</x-slot>
</x-slotter>
</div> -->
<!-- </div> -->
<x-avatar-upload
[showFileDropArea]="true"
[color]="ColorNames.Dark"
[fileDropAreaColor]="ColorNames.Dark"
placeHolderAvatar="/assets/image/default-user-image.png"
>
</x-avatar-upload>
<!-- Actions -->
<div x-panel-actions>
<a
target="_blank"
href="https://docs.x-framework.ir/x-framework-components/modules/XImageCropperModule.html"
>{{resourceProvider(ResourceIDs.documentation)}}</a
>
</div>
</x-panel>
<!-- File Upload -->
<x-panel [id]="'file_upload'" [hasCustomActions]="true">
<!-- Title and Description -->
<div x-panel-title>{{ resourceProvider(ResourceIDs.file_upload) }}</div>
<!-- <div x-panel-description>
{{ resourceProvider(ResourceIDs.file_upload_description) }}
</div> -->
<br />
<!-- Description -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('fileUploadContent')"
></x-markdown>
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[cssClass]="'code-block'"
[content]="fileUploadSample1"
></x-markdown>
<!-- Sample -->
<x-file-upload
[showEmpty]="true"
[color]="'dark-tint'"
[showActionBar]="true"
[listShowToolbar]="true"
[emptyHasRefresh]="false"
[listEnableReordering]="true"
[emptyColor]="ColorNames.Dark"
[fileDropAreaColor]="'dark-tint'"
[actionBarColor]="ColorNames.Dark"
[searchBarColor]="ColorNames.Dark"
[emptyMessageColor]="ColorNames.Dark"
[emptyForegroundMessageColor]="false"
(fileChange)="handleFileChanged($event)"
[maxAllowedSize]="config.maxAllowedSize"
[maxAllowedFiles]="config.maxUploadFiles"
[showFileDropArea]="isNotMobileUi$ | async"
[searchBarSearchInputColor]="ColorNames.Dark"
[minAllowedFileSize]="config.minAllowedFileSize"
[maxAllowedFileSize]="config.maxAllowedFileSize"
(actionBarActionFired)="handleActionFired($event)"
></x-file-upload>
<!-- Actions -->
<div x-panel-actions>
<a
target="_blank"
href="https://docs.x-framework.ir/x-framework-components/modules/XFileUploadModule.html"
>{{resourceProvider(ResourceIDs.documentation)}}</a
>
</div>
</x-panel>
</x-expandable-panel>
</v-page>
@@ -0,0 +1,56 @@
//
$size: 32px !important;
$thumbSize: 64px !important;
.thumbnail-wrapper {
margin-top: 6px;
height: $thumbSize;
}
x-thumbnail {
--thumbnail-size: #{$size};
}
// :host ::ng-deep .thumbnail,
// :host ::ng-deep .x-item {
// width: $size;
// min-width: $size;
// max-width: $size;
// height: $size;
// min-height: $size;
// max-height: $size;
// }
:host ::ng-deep .thumbnail {
img {
border-radius: 50% !important;
}
}
.avatar-actions {
//
@extend .thumbnail-wrapper;
//
display: flex;
align-items: center;
flex-direction: row;
//
* {
flex: auto;
margin: {
top: auto;
bottom: auto;
}
//
* {
margin: {
left: 3px;
right: 3px;
}
}
}
}
@@ -0,0 +1,654 @@
import {
Inject,
NgZone,
Component,
ViewChild,
Renderer2,
ElementRef,
ChangeDetectorRef,
} from '@angular/core';
import {
XColor,
toArray,
isArray,
hasChild,
getArrayOf,
XResourceIDs,
XExceptionIDs,
isExtensionOk,
XDialogResult,
XOneOrManyType,
getImageDimensions,
isNullOrEmptyString,
} from 'x-framework-core';
import {
XSlotName,
XIconNames,
XSlotLayout,
XFileStatus,
XButtonType,
XThumbnailType,
XPageContainer,
XPopoverService,
XImageCropperService,
XActionBarActionFiredModel,
} from 'x-framework-components';
import { MenuController } from '@ionic/angular';
import { X_CONFIG } from 'src/app/config/x-config';
import { XConfig } from 'src/app/config/app-config';
import { ViewportRuler } from '@angular/cdk/overlay';
import { XManagerService } from 'x-framework-services';
import { VPageComponent } from '../../../views/v-page/v-page.component';
import { AppResourceIDs } from 'src/app/config/app.localization.config';
@Component({
selector: 'app-file-components',
templateUrl: './file-components.page.html',
styleUrls: ['./file-components.page.scss'],
})
// tslint:disable-next-line:component-class-suffix
export class FileComponentsPage extends VPageComponent {
//
//#region Props ...
//
//#region Page Props ...
titleRes = AppResourceIDs.file_components;
toolbarTitle = this.resourceProvider(this.titleRes);
toolbarSubTitle = this.resourceProvider(
AppResourceIDs.file_components_description
);
toolbarShowSubTitle = true;
//#endregion
//
//#region image cropper props ...
readonly SlotNames = Object.assign({}, XSlotName);
readonly SlotLayout = Object.assign({}, XSlotLayout);
readonly ButtonTypes = Object.assign({}, XButtonType);
//
@ViewChild('fileInput', { static: false })
private fileInputRef!: ElementRef;
//
//#region Selected File ...
private SELECTED_FILE: File;
set file(v: File) {
//
this.SELECTED_FILE = v;
//
if (!v) {
return;
}
//
getImageDimensions(v).then((dimension) => {
if (dimension) {
//
this.selectedFileWidth = dimension.width;
this.selectedFileHeight = dimension.height;
//
this.detectChanges();
}
});
}
get file() {
return this.SELECTED_FILE;
}
//
selectedFileWidth = 0;
selectedFileHeight = 0;
//
preparedMaxAllowedFileSize = this.config.maxProfileImageSize;
preparedAllowedExtensions = this.config.allowedImageExtensions;
//#endregion
//
// Prepare All Resource IDs ...
readonly ResourceIDs = Object.assign(
Object.assign({}, XResourceIDs),
AppResourceIDs
) as any;
//
readonly IconNames = Object.assign({}, XIconNames);
//#endregion
//
// Content ...
readonly contentFa = `
# ${this.resourceProvider(this.ResourceIDs.file_components)}
در این کتابخانه مجموعه ای از مولفه ها جهت سهولت کار با فایل ها ارائه شده است که در ادامه به بررسی هر یک بتفصیل پرداخته خواهد شد:
`;
readonly contentEn = `
# ${this.resourceProvider(this.ResourceIDs.file_components)}
this framework provides several components to make working with files so easy. in the following section they will be documented:
`;
//
// Thumbnail ...
readonly ThumbnailTypes = Object.assign({}, XThumbnailType);
readonly thumbnailContentFa = `
این مولفه جهت نمایش تصاویر بند انگشتی و یا تعیین نوع فایل در حالت عمومی کاربرد دارد.
`;
readonly thumbnailContentEn = `
this component used to show a thumbnail of an image or file general types.
`;
readonly fileUrl = this.managerService.getFullUrl('/assets/icon/favicon.png');
readonly thumbnailSample1 =
'```html' +
`
<x-thumbnail
[identifier]="fileUrl"
[type]="ThumbnailTypes.CUSTOM"
>
</x-thumbnail>
` +
'```';
readonly thumbnailSample2 =
'```html' +
`
<x-thumbnail
[identifier]="fileUrl"
[type]="ThumbnailTypes.GENERAL"
>
</x-thumbnail>
` +
'```';
//
// File Drop Area ...
readonly fileDropAreaContentFa = `
این مولفه جهت فراهم کردن فضایی برای کشیدن فایل ها و رها کردن آن ها در فضای مناسب مورد استفاده قرار می گیرد.
`;
readonly fileDropAreaContentEn = `
this component use to provide an area for dropping file(s)
`;
//
readonly fileDropAreaSample1 =
'```html' +
`
<x-file-drop-area
[wrapWithCard]="true"
[isPageFileDropArea]="true"
[supportsMultipleFiles]="true"
(filesChangeEmiter)="
handleFilesChanged($event)"
></x-file-drop-area>
` +
'```';
readonly imageCropperContentFa = `
این مولفه جهت فراهم کردن امکانات بریدن تصاویر کاربرد دارد که مهمترین مورد کاربرد آن در تصاویر پروفایل است.
`;
readonly imageCropperContentEn = `
this component use to provide a way to cropping images before upload them, usually used for avatars.
`;
//
readonly imageCropperSample1 =
'```html' +
`
<div class="container">
<input
hidden
#fileInput
type="file"
multiple="false"
(change)="
handleFilesSelected()"
[disabled]="
isLoading || uiDisabled"
/>
<x-button
(click)="selectFile()"
[type]="ButtonTypes.Raised"
[color]="ColorNames.Primary"
[title]="
resourceProvider(
ResourceIDs.select)
+ \' \' +
resourceProvider(
ResourceIDs.avatar)"
>
</x-button>
<div
*ngIf="file"
class="thumbnail-wrapper"
>
<x-slotter
[hasCenterSlot]="false"
[layout]="
SlotLayout.HORIZONTAL"
[startTopSlotCssClass]="
\'ion-text-start\'"
[endBottomSlotCssClass]="
\'ion-text-center\'"
>
<x-slot
[name]="SlotNames.START">
<div>
<x-thumbnail
class="x-thumb"
[identifier]="file"
[loading]="isLoading"
[cssClass]="\'thumbnail\'"
[uiDisabled]="uiDisabled"
[type]="
ThumbnailTypes.CUSTOM"
>
</x-thumbnail>
</div>
</x-slot>
<x-slot [name]="SlotNames.END">
<div
class="
avatar-actions
ion-text-end">
<div>
<x-button
*ngIf="
croppableImage()"
[type]="
ButtonTypes.Icon"
(click)="
handleLoadCropper()"
[color]="
ColorNames.Secondary"
[matTooltip]="
resourceProvider(
ResourceIDs.crop)"
>
<x-icon
[name]="
IconNames.crop">
</x-icon>
</x-button>
<x-button
[type]="
ButtonTypes.Icon"
(click)="
handleClearFile()"
[color]="
ColorNames.Warning"
[matTooltip]="
resourceProvider(
ResourceIDs.clear)"
>
<x-icon
[name]="
IconNames.clear"
[color]="
ColorNames.Light"
></x-icon>
</x-button>
</div>
</div>
</x-slot>
</x-slotter>
</div>
</div>
` +
'```';
//
// File Upload ...
readonly fileUploadContentFa = `
از این مولفه جهت مدیریت بارگزاری فایل ها استفاده می شود
`;
readonly fileUploadContentEn = `
use this component to manage how files uploaded.
`;
readonly fileUploadSample1 =
'```html' +
`
<x-file-upload
[canDrop]="
isNotMobileUi$ | async"
(fileChange)="
handleFileChanged($event)"
[maxAllowedSize]="
config.maxAllowedSize"
[maxAllowedFiles]="
config.maxUploadFiles"
[minAllowedFileSize]="
config.minAllowedFileSize"
[maxAllowedFileSize]="
config.maxAllowedFileSize"
></x-file-upload>
` +
'```';
//
//#region Constructor ...
constructor(
public zone: NgZone,
public element: ElementRef,
public renderer: Renderer2,
public ruler: ViewportRuler,
public menuController: MenuController,
public managerService: XManagerService,
public changeDetector: ChangeDetectorRef,
@Inject(X_CONFIG) public config: XConfig,
public imageCropperService: XImageCropperService,
protected popoverService: XPopoverService,
protected propertyProvider: XPageContainer,
) {
super(
zone,
config,
element,
renderer,
ruler,
menuController,
managerService,
changeDetector,
popoverService,
propertyProvider
);
}
//#endregion
//
//#region UI Providers ...
//
// Provide content based on current locale ...
getContent(title: string) {
//
if (isNullOrEmptyString(title)) {
return '';
}
//
const currentLocale = this.managerService.currentLocale;
//
const varName =
title +
(currentLocale === 'en-US'
? 'En'
: currentLocale === 'fa-IR'
? 'Fa'
: '');
const result = this[`${varName}`];
//
return result || '';
}
croppableImage() {
return (
this.file &&
this.selectedFileWidth > 0 &&
this.selectedFileHeight > 0 &&
this.selectedFileWidth >= this.config.minAllowedImageSize &&
this.selectedFileHeight >= this.config.minAllowedImageSize
);
}
//#endregion
//
//#region UI Handlers ...
//
async handleFilesChanged(files: File | File[]) {
//
console.log('files changed: ', files);
//
await this.managerService.notificationService.presentInfoNotification({
message: `Selected File(s): ${toArray(files).length}`,
dissmissable: true,
});
}
//
handleFilesSelected() {
//
if (!this.fileInputRef) {
return;
}
//
const fileInput = this.fileInputRef.nativeElement;
if (!fileInput || !fileInput.files) {
return;
}
//
const files = getArrayOf<File>(fileInput.files);
//
if (!files || files.length === 0) {
return;
}
//
const file = files[0];
if (!file) {
return;
}
//
fileInput.value = null;
//
this.handleFileDropped(files);
}
//
async handleFileDropped(files: File | File[]) {
//
if (!files) {
return;
}
//
this.loading = true;
//
let file: File;
if (!isArray(files) && files instanceof File) {
file = files as File;
} else {
//
const filesArr = files as File[];
if (hasChild(filesArr)) {
file = filesArr[0];
}
}
//
this.loading = false;
//
if (!file) {
return;
}
//
const status = this.getFileStatus(file);
if (status !== XFileStatus.OK) {
this.loading = false;
this.handleFileStatus(status);
return;
}
//
this.file = file;
}
//
handleLoadCropper() {
this.imageCropperService.showCropper(this.file);
//
const s = this.applyTakeUntilWrapper(
this.imageCropperService.onResult.asObservable()
).subscribe((res) => {
//
if (res.result === XDialogResult.Ok && res.file) {
//
this.file = null;
setTimeout(() => {
this.file = res.file;
}, 100);
}
//
s.unsubscribe();
});
}
//
handleClearFile() {
//
this.file = null;
this.selectedFileWidth = 0;
this.selectedFileHeight = 0;
}
selectFile() {
//
if (!this.fileInputRef || !this.fileInputRef.nativeElement) {
return;
}
//
this.fileInputRef.nativeElement.click();
}
//
// File Upload ...
async handleFileChanged(files: XOneOrManyType<File>) {
console.log('files: ', files);
}
//
async handleActionFired(event: XActionBarActionFiredModel) {
//
const name = event.action;
await this.managerService.notificationService.presentXNotification({
message: `Action Fired: ${name}`,
dissmissable: true,
opt: {
color: XColor.Dark,
},
});
}
//#endregion
//
//#region Private ...
//
//#region File Selection Policies ...
private isExtensionOk(file: File) {
//
if (!file) {
return false;
}
//
if (!hasChild(this.preparedAllowedExtensions)) {
return true;
}
//
const result = isExtensionOk(file, this.preparedAllowedExtensions);
return result;
}
private isMaxAllowedFileSizeOk(file: File) {
//
const result =
this.preparedMaxAllowedFileSize && this.preparedMaxAllowedFileSize > 0
? file.size <= this.preparedMaxAllowedFileSize
: true;
//
return result;
}
private getFileStatus(file: File) {
//
// Check Not Empty File ...
if (!file || file.size === 0) {
return XFileStatus.EMPTY;
}
//
// Check File Extension Validation ...
if (!this.isExtensionOk(file)) {
return XFileStatus.NOT_ALLOWED_TYPE;
}
//
// Check File Size Ok ...
if (!this.isMaxAllowedFileSizeOk(file)) {
return XFileStatus.SIZE_EXCEEDED;
}
//
// Everythings Ok ...
return XFileStatus.OK;
}
private handleFileStatus(status: XFileStatus) {
//
let exception: XExceptionIDs = null;
switch (status) {
//
case XFileStatus.EMPTY:
exception = this.ExceptionIDs.EmptyFile;
break;
//
case XFileStatus.NOT_ALLOWED_TYPE:
exception = this.ExceptionIDs.InavlidFile;
break;
//
case XFileStatus.SIZE_EXCEEDED:
exception = this.ExceptionIDs.MaxFileSizeExceeded;
break;
//
case XFileStatus.MAX_ALLOWED_SIZE_REACHED:
exception = this.ExceptionIDs.MaxFilesSizeExceeded;
break;
//
case XFileStatus.MAX_ALLOWED_FILES_REACHED:
exception = this.ExceptionIDs.MaxAllowedFilesExceeded;
break;
}
//
if (exception) {
this.managerService.notificationService.presentErrorNotification({
exception,
dissmissable: true,
});
}
}
//#endregion
//#endregion
}
@@ -0,0 +1,99 @@
<v-page
[hasSide]="true"
[toolbarTitle]="toolbarTitle"
[toolbarSubTitle]="toolbarSubTitle"
[toolbarShowSubTitle]="toolbarShowSubTitle"
>
<!-- Content -->
<x-card [isInPage]="true" [showActions]="true" [color]="ColorNames.Light">
<!-- Content -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('content')"
></x-markdown>
<!-- Actions -->
<div actions>
<a
target="_blank"
href="https://docs.x-framework.ir/x-framework-components/components/XFormComponent.html"
>{{resourceProvider(ResourceIDs.documentation)}}</a
>
</div>
</x-card>
<x-markdown
[isInPage]="true"
[mode]="'preview'"
[content]="sample1"
[hasToolbar]="false"
[wrapWithCard]="true"
[cssClass]="'code-block'"
[cardTitle]="resourceProvider(ResourceIDs.sample)"
></x-markdown>
<!-- Form Control Center -->
<x-form
[isInPage]="true"
[wrapWithCard]="true"
*ngIf="showFormControlCenter"
[cardTitle]="'Form Controller'"
[formConfig]="xFormControlConfig"
[actionProvider]="controlFormActionProvider"
(valueChanged)="handleFormControlCenterValueChanged($event)"
>
</x-form>
<!-- Form Elements Multiple Actions -->
<x-card [isInPage]="true">
<x-slotter [layout]="SlotLayouts.HORIZONTAL">
<!-- Start -->
<x-slot [name]="SlotNames.START" [cssClass]="'ion-text-center'">
<x-button
[type]="ButtonTypes.Raised"
[color]="ColorNames.Primary"
[title]="'Show All Form Fileds'"
(clicked)="handleShowAllFormFileds()"
></x-button>
</x-slot>
<!-- Center -->
<x-slot [name]="SlotNames.CENTER"> </x-slot>
<!-- End -->
<x-slot [name]="SlotNames.END" [cssClass]="'ion-text-center'">
<x-button
[type]="ButtonTypes.Raised"
[color]="ColorNames.Danger"
[title]="'Remove All Form Fileds'"
(clicked)="handleClearAllFormFileds()"
></x-button>
</x-slot>
</x-slotter>
</x-card>
<!-- Form -->
<x-form
[isInPage]="true"
*ngIf="xFormConfig"
[wrapWithCard]="true"
[formConfig]="xFormConfig"
[cardTitle]="'Sample Form'"
[actionProvider]="formActionProvider"
[applyStatusOnControls]="applyStatusOnControls"
(valueChanged)="handleFormValueChanged($event)"
[regularColor]="formRegularColor"
[validColor]="formValidColor"
[hintColor]="formHintColor"
[invalidColor]="formInvalidColor"
[activeColor]="formActiveColor"
[pendingColor]="formPendingColor"
[disabledColor]="formDisabledColor"
[accentColor]="formAccentColor"
[fillColor]="formFillColor"
[disabledFillColor]="formDisabledFillColor"
></x-form>
</v-page>
<ng-template #nameAutoCompleteRef let-item> {{ item.data }} </ng-template>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,77 @@
<v-page
[hasSide]="true"
[toolbarTitle]="toolbarTitle"
[toolbarSubTitle]="toolbarSubTitle"
[toolbarShowSubTitle]="toolbarShowSubTitle"
>
<!-- Content -->
<x-card [isInPage]="true" [showActions]="true" [color]="ColorNames.Light">
<!-- Content -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('content')"
></x-markdown>
<!-- Actions -->
<div actions>
<a
target="_blank"
href="https://docs.x-framework.ir/x-framework-components/components/XGridComponent.html"
>{{resourceProvider(ResourceIDs.documentation)}}</a
>
</div>
</x-card>
<!-- Samples -->
<x-markdown
[mode]="'preview'"
[content]="sample1"
[hasToolbar]="false"
[wrapWithCard]="true"
[isInPage]="true"
[cssClass]="'code-block'"
[cardTitle]="resourceProvider(ResourceIDs.sample)"
></x-markdown>
<x-grid
[isInPage]="true"
[wrapWithCard]="true"
[items]="templGridItems"
[selectableItems]="true"
[itemTemplate]="gridItemRef"
[type]="GridPresentTypes.AsFlex"
(itemSelected)="handleGridItemSelected($event)"
>
</x-grid>
<x-markdown
[mode]="'preview'"
[content]="sample2"
[hasToolbar]="false"
[wrapWithCard]="true"
[isInPage]="true"
[cssClass]="'code-block'"
[cardTitle]="resourceProvider(ResourceIDs.sample)"
></x-markdown>
<x-grid
[cols]="4"
[isInPage]="true"
[wrapWithCard]="true"
[items]="templGridItems"
[selectableItems]="true"
[itemTemplate]="gridItemRef"
[type]="GridPresentTypes.AsGrid"
(itemSelected)="handleGridItemSelected($event)"
>
</x-grid>
</v-page>
<!-- Grid Item Template -->
<ng-template #gridItemRef let-item>
<div>
{{ item.data }}
<!-- <span>{{ item.data }}</span> -->
</div>
</ng-template>
+160
View File
@@ -0,0 +1,160 @@
import {
XGridItem,
XIconNames,
XGridPresentType,
defaultGridOptions,
XStaggedGridOptions,
} from 'x-framework-components';
import { Component } from '@angular/core';
import { VPageComponent } from '../../../views/v-page/v-page.component';
import { AppResourceIDs } from 'src/app/config/app.localization.config';
import { XResourceIDs, isNullOrEmptyString, XColor } from 'x-framework-core';
@Component({
selector: 'app-grid',
templateUrl: './grid.page.html',
styleUrls: ['./grid.page.scss'],
})
// tslint:disable-next-line:component-class-suffix
export class GridPage extends VPageComponent {
//
//#region Props ...
//
//#region Page Props ...
titleRes = AppResourceIDs.grid;
toolbarTitle = this.resourceProvider(this.titleRes);
toolbarSubTitle = this.resourceProvider(AppResourceIDs.grid_description);
toolbarShowSubTitle = true;
//#endregion
//
// Prepare All Resource IDs ...
readonly ResourceIDs = Object.assign(
Object.assign({}, XResourceIDs),
AppResourceIDs
) as any;
//
readonly IconNames = Object.assign({}, XIconNames);
//#endregion
//
// Content ...
readonly contentFa = `
# ${this.toolbarTitle}
این مولفه نمایش مجموعه ای از عناصر مرتبط با هم بکار می رود.
`;
readonly contentEn = `
# ${this.toolbarTitle}
this component used to show a collection of related items.
`;
//
readonly sample0 =
'```typescript' +
`
gridOption: XStaggedGridOptions = {
...defaultGridOptions,
};
tempList = Array.from(Array(25).keys());
templGridItems: XGridItem<string>[] = this.tempList.map((i) => {
//
const li: XGridItem<string> = {
data: \`Item \${i.toString()}\`,
};
//
return li;
});
` +
'```';
//
readonly sample1 =
'```html' +
`
<x-grid
[isPageGrid]="true"
[wrapWithCard]="true"
[items]="templGridItems"
[selectableItems]="true"
[itemTemplate]="gridItemRef"
[type]="GridPresentTypes.AsFlex"
(itemSelected)="
handleGridItemSelected($event)"
>
</x-grid>
` +
'```';
readonly sample2 =
'```html' +
`
<x-grid
[cols]="4"
[isPageGrid]="true"
[wrapWithCard]="true"
[items]="templGridItems"
[selectableItems]="true"
[itemTemplate]="gridItemRef"
[type]="GridPresentTypes.AsGrid"
(itemSelected)="
handleGridItemSelected($event)"
>
</x-grid>
` +
'```';
//
readonly GridPresentTypes = Object.assign({}, XGridPresentType);
//
gridOption: XStaggedGridOptions = {
...defaultGridOptions,
};
tempList = Array.from(Array(25).keys());
templGridItems: XGridItem<string>[] = this.tempList.map((i) => {
//
const li: XGridItem<string> = {
data: `Item ${i.toString()}`,
};
//
return li;
});
//
//#region UI Providers ...
//
// Provide content based on current locale ...
getContent(title: string) {
//
if (isNullOrEmptyString(title)) {
return '';
}
//
const currentLocale = this.managerService.currentLocale;
//
const varName =
title +
(currentLocale === 'en-US'
? 'En'
: currentLocale === 'fa-IR'
? 'Fa'
: '');
const result = this[`${varName}`];
//
return result || '';
}
//
handleGridItemSelected(item: XGridItem<string>) {
console.log('handleGridItemSelected: ', item.data);
}
//#endregion
}
@@ -0,0 +1,100 @@
<v-page
[hasSide]="true"
[toolbarTitle]="toolbarTitle"
[toolbarSubTitle]="toolbarSubTitle"
[toolbarShowSubTitle]="toolbarShowSubTitle"
>
<!-- Content -->
<x-card [isInPage]="true" [showActions]="true" [color]="ColorNames.Light">
<!-- Content -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('content')"
></x-markdown>
<!-- Sample -->
<x-markdown
[mode]="'preview'"
[content]="sample1"
[hasToolbar]="false"
[cssClass]="'code-block'"
></x-markdown>
<x-icon
[foregroundColor]="true"
[name]="IconNames.blockchain"
[color]="ColorNames.Success"
>
</x-icon>
<!-- Sample -->
<x-markdown
[mode]="'preview'"
[content]="sample2"
[hasToolbar]="false"
[cssClass]="'code-block'"
></x-markdown>
<x-icon
[clickable]="true"
[name]="IconNames.blockchain"
[foregroundColor]="false"
[color]="ColorNames.Dark"
(clicked)="managerService.notificationService.presentInfoNotification({
message: 'icon clicked ...',
dissmissable: true
})"
>
</x-icon>
<br />
<br />
<x-form
[fillColor]="ColorNames.Dark"
[formConfig]="iconListFormConfig"
[regularColor]="ColorNames.Light"
></x-form>
<!-- Actions -->
<div actions>
<a
target="_blank"
href="https://docs.x-framework.ir/x-framework-components/components/XIconComponent.html"
>{{resourceProvider(ResourceIDs.documentation)}}</a
>
</div>
</x-card>
<!-- Icon List -->
<x-card
[isInPage]="true"
*ngIf="showIconList"
[title]="resourceProvider(ResourceIDs.icon_list)"
>
<!-- Icons List -->
<x-list
#listPresenter
[showToolbar]="true"
[stickyToolbar]="true"
[showSearchBar]="true"
[showActionBar]="false"
[clickableItems]="true"
[items]="iconListItems"
[itemTemplate]="iconTemplate"
[searchBarColor]="ColorNames.Dark"
(itemSelected)="handleIconSelected($event)"
[searchBarSearchInputColor]="ColorNames.Dark"
>
</x-list>
</x-card>
</v-page>
<!-- Icon Template Ref -->
<ng-template #iconTemplate let-item>
<div class="cb-inherit ion-text-center">
<x-icon [name]="item.data" [color]="ColorNames.Tertiary"></x-icon>
{{ item.data }}
</div>
</ng-template>
+237
View File
@@ -0,0 +1,237 @@
import {
XSpinner,
hasChild,
XResourceIDs,
isNullOrEmptyString,
XColorWithBrightness,
} from 'x-framework-core';
import {
XIconNames,
XListItem,
XFormConfig,
XFormControlType,
} from 'x-framework-components';
import { Component } from '@angular/core';
import { VPageComponent } from '../../../views/v-page/v-page.component';
import { AppResourceIDs } from 'src/app/config/app.localization.config';
interface IconsListPresentation {
show: boolean;
}
@Component({
selector: 'app-icon',
templateUrl: './icon.page.html',
styleUrls: ['./icon.page.scss'],
})
// tslint:disable-next-line:component-class-suffix
export class IconPage extends VPageComponent {
//
//#region Props ...
//
//#region Page Props ...
titleRes = AppResourceIDs.icon;
toolbarTitle = this.resourceProvider(this.titleRes);
toolbarSubTitle = this.resourceProvider(AppResourceIDs.icon_description);
toolbarShowSubTitle = true;
//#endregion
//
// Prepare All Resource IDs ...
readonly ResourceIDs = Object.assign(
Object.assign({}, XResourceIDs),
AppResourceIDs
) as any;
//
// Color Names ...
readonly ColorNames = Object.assign({}, XColorWithBrightness);
//
// Spinner Names ...
readonly SpinnerNames = Object.assign({}, XSpinner);
//
IconNames = Object.assign({}, XIconNames);
iconList = Object.keys(this.IconNames);
iconListItems: XListItem<string>[] = [];
//#endregion
readonly contentFa = `
# ${this.toolbarTitle}
این مولفه جهت نمایش شمایل های مختلف بکار میرود.
`;
readonly contentEn = `
# ${this.toolbarTitle}
this Component used for show an icon.
`;
readonly sample1 =
'```html' +
`
<x-icon
[foregroundColor]="true"
[name]="IconNames.business"
[color]="ColorNames.Success"
>
</x-icon>
` +
'```';
readonly sample2 =
'```html' +
`
<x-icon
[clickable]="true"
[name]="IconNames.home"
[foregroundColor]="false"
[color]="ColorNames.Dark"
(clicked)="managerService
.notificationService
.presentInfoNotification({
message: 'icon clicked ...',
dissmissable: true
})"
>
</x-icon>
` +
'```';
//
showIconList = false;
iconListFormConfig: XFormConfig<IconsListPresentation> = {
name: 'IconListForm',
controls: [
{
index: 5,
propName: 'show',
type: {
type: XFormControlType.CheckBox,
config: {
checkedChanged: async (checked: boolean) => {
//
if (!hasChild(this.iconListItems)) {
//
const loading = await this.managerService.dialogService.presentLoading(
{
message: this.resourceProvider(
AppResourceIDs.default_loading
),
spinner: this.SpinnerNames.LinesSmall,
}
);
//
await this.prepareIconListItems();
//
await loading.dismiss();
}
//
this.showIconList = checked;
},
},
},
appearance: {
label: `${this.resourceProvider(
this.ResourceIDs.show
)} ${this.resourceProvider(this.ResourceIDs.icon_list)}`,
},
},
],
};
//
//#region LifeCycle ...
//#endregion
//
//#region UI Providers ...
//
// Provide content based on current locale ...
getContent(title: string) {
//
if (isNullOrEmptyString(title)) {
return '';
}
//
const currentLocale = this.managerService.currentLocale;
//
const varName =
title +
(currentLocale === 'en-US'
? 'En'
: currentLocale === 'fa-IR'
? 'Fa'
: '');
const result = this[`${varName}`];
//
return result || '';
}
canShowIconList() {
return hasChild(this.iconListItems);
}
//#endregion
//
//#region UI Handlers ...
async handleIconSelected(item: XListItem<string>) {
//
// text: this.resourceProvider(XResourceIDs.dismiss),
const iconText = `&lt;x-icon name='${item.data}'&gt;&lt;/x-icon&gt;`;
const iconCode = `<x-icon name='${item.data}'></x-icon>`;
await this.managerService.notificationService.presentInfoNotification({
message: iconText,
dissmissable: true,
opt: {
duration: 4000,
buttons: [
{
icon: this.IconNames.clipboard,
side: 'end',
role: 'set',
handler: () => {
//
console.log(iconCode);
const isSaved = this.managerService.saveToClipboard(iconCode);
if (isSaved) {
this.managerService.notificationService.presentDefaultSuccessNotification();
}
},
},
{
icon: this.IconNames.close,
side: 'end',
role: 'cancel',
},
],
},
});
}
//#endregion
//
//#region Private ...
private async prepareIconListItems() {
//
this.iconListItems = this.iconList.map((i) => {
//
const li: XListItem<string> = {
data: i,
};
//
return li;
});
this.detectChanges();
}
//#endregion
}
@@ -0,0 +1,25 @@
<v-page
[hasSide]="true"
[toolbarTitle]="toolbarTitle"
[toolbarSubTitle]="toolbarSubTitle"
[toolbarShowSubTitle]="toolbarShowSubTitle"
>
<!-- Content -->
<x-card [isInPage]="true" [showActions]="true" [color]="ColorNames.Light">
<!-- Content -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('content')"
></x-markdown>
<!-- Actions -->
<div actions>
<a
target="_blank"
href="https://docs.x-framework.ir/x-framework-components/index.html"
>{{resourceProvider(ResourceIDs.documentation)}}</a
>
</div>
</x-card>
</v-page>
@@ -0,0 +1,85 @@
import {
XResourceIDs,
isNullOrEmptyString,
XColorWithBrightness,
} from 'x-framework-core';
import { Component } from '@angular/core';
import { VPageComponent } from '../../../views/v-page/v-page.component';
import { AppResourceIDs } from 'src/app/config/app.localization.config';
@Component({
selector: 'app-components-introduction',
templateUrl: './introduction.page.html',
styleUrls: ['./introduction.page.scss'],
})
// tslint:disable-next-line:component-class-suffix
export class IntroductionPage extends VPageComponent {
//
//#region Props ...
//
//#region Page Props ...
titleRes = AppResourceIDs.components_introduction;
toolbarTitle = this.resourceProvider(this.titleRes);
toolbarSubTitle = this.resourceProvider(
AppResourceIDs.components_introduction_description
);
toolbarShowSubTitle = true;
//#endregion
//
// Prepare All Resource IDs ...
readonly ResourceIDs = Object.assign(
Object.assign({}, XResourceIDs),
AppResourceIDs
) as any;
//
// Color Names ...
readonly ColorNames = Object.assign({}, XColorWithBrightness);
//#endregion
//
// Content ...
readonly contentFa = `
# ${this.toolbarTitle}
این واحد در زمره اصلی ترین اجزاء چارچوب ایفای نقش می کند و شامل کلیه مولفه های بصری قابل استفاده در طراحی و پیاده سازی برنامه های کاربردی است.
شناخت عمیق کلیه اجزاء این واحد در تسریع فرآیند توسعه بسیار لازم و ضروری است.
`;
readonly contentEn = `
# ${this.toolbarTitle}
this module is one of most important modules of xFramework and contains all provided UI Components which used to design and develop Applications.
getting deep dive into all components of this module is very usefull to make easier the Design and Develop proccess of Applications.
`;
//#endregion
//
// Provide content based on current locale ...
getContent(title: string) {
//
if (isNullOrEmptyString(title)) {
return '';
}
//
const currentLocale = this.managerService.currentLocale;
//
const varName =
title +
(currentLocale === 'en-US'
? 'En'
: currentLocale === 'fa-IR'
? 'Fa'
: '');
const result = this[`${varName}`];
//
return result || '';
}
}
@@ -0,0 +1,73 @@
<v-page
[hasSide]="true"
[toolbarTitle]="toolbarTitle"
[toolbarSubTitle]="toolbarSubTitle"
[toolbarShowSubTitle]="toolbarShowSubTitle"
>
<!-- Content -->
<x-card [isInPage]="true" [showActions]="true" [color]="ColorNames.Light">
<!-- Content -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('content')"
></x-markdown>
<!-- Samples -->
<x-markdown
[mode]="'preview'"
[content]="sample1"
[hasToolbar]="false"
[cssClass]="'code-block'"
></x-markdown>
<x-markdown
[mode]="'preview'"
[content]="sample2"
[hasToolbar]="false"
[cssClass]="'code-block'"
></x-markdown>
<x-markdown
[mode]="'preview'"
[content]="sample3"
[hasToolbar]="false"
[cssClass]="'code-block'"
></x-markdown>
<!-- List Presenter -->
<x-list
#listPresenter
[showToolbar]="true"
[stickyToolbar]="true"
[showActionBar]="true"
[showSearchBar]="true"
[showDivider]="false"
[clickableItems]="true"
[selectableItems]="true"
[items]="templListItems"
[enableReordering]="true"
[itemTemplate]="listItemRef"
[color]="ColorNames.Tertiary"
(refresh)="handleRefreshList()"
[actionBarColor]="ColorNames.Dark"
[searchBarColor]="ColorNames.Dark"
[actionBarHideActions]="hideActions"
(removeItems)="handleRemoveItems($event)"
[searchBarSearchInputColor]="ColorNames.Dark"
>
</x-list>
<!-- Actions -->
<div actions>
<a
target="_blank"
href="https://docs.x-framework.ir/x-framework-components/modules/XListModule.html"
>{{resourceProvider(ResourceIDs.documentation)}}</a
>
</div>
</x-card>
</v-page>
<!-- List Item Template -->
<ng-template #listItemRef let-item>
<span>{{item.data}}</span>
</ng-template>
+343
View File
@@ -0,0 +1,343 @@
import {
XColor,
XResourceIDs,
isNullOrEmptyString,
XBaseRangeRequestDto,
XStandardType,
XOneOrManyType,
} from 'x-framework-core';
import { Component } from '@angular/core';
import { XListItem, XIconNames } from 'x-framework-components';
import { VPageComponent } from '../../../views/v-page/v-page.component';
import { AppResourceIDs } from 'src/app/config/app.localization.config';
@Component({
selector: 'app-list',
templateUrl: './list.page.html',
styleUrls: ['./list.page.scss'],
})
// tslint:disable-next-line:component-class-suffix
export class ListPage extends VPageComponent {
//
//#region Props ...
//
//#region Page Props ...
titleRes = AppResourceIDs.list;
toolbarTitle = this.resourceProvider(this.titleRes);
toolbarSubTitle = this.resourceProvider(AppResourceIDs.list_description);
toolbarShowSubTitle = true;
//#endregion
//
// Prepare All Resource IDs ...
readonly ResourceIDs = Object.assign(
Object.assign({}, XResourceIDs),
AppResourceIDs
) as any;
//
readonly IconNames = Object.assign({}, XIconNames);
//#endregion
//
// Content ...
readonly contentFa = `
# ${this.toolbarTitle}
این مولفه جهت نمایش فهرستی از موارد و فراهم کردن ابزار مدیریت آن بکار می رود.
`;
readonly contentEn = `
# ${this.toolbarTitle}
this component used to provide a way to show items in a list and manage items.
`;
//
readonly sample1 =
'```typescript' +
`
tempList = Array
.from(Array(25).keys());
templListItems: XListItem<string>[] =
this.tempList.map((i) => {
const li: XListItem<string> = {
data: \`Item \${i.toString()}\`,
slideOptions: [
{
id: 'remove',
icon: this.IconNames.remove,
color: this.ColorNames.Danger,
onlyIcon: true,
slot: 'end',
handler: () => {
//
this.managerService
.notificationService
.presentDangerNotification({
message: \`remove: \${i}\`,
dissmissable: true,
});
},
},
{
id: 'edit',
icon: this.IconNames.edit,
color: this.ColorNames.Warning,
onlyIcon: true,
slot: 'start',
handler: () => {
//
this.managerService
.notificationService
.presentInfoNotification({
message: \`edit: \${i}\`,
dissmissable: true,
});
},
},
],
};
return li;
});
` +
'```';
//
readonly sample2 =
'```html' +
`
<x-list
#listPresenter
[showToolbar]="true"
[stickyToolbar]="true"
[showActionBar]="true"
[showSearchBar]="true"
[showDivider]="false"
[clickableItems]="true"
[selectableItems]="true"
[items]="templListItems"
[enableReordering]="true"
[itemTemplate]="listItemRef"
[color]="ColorNames.Tertiary"
(refresh)="handleRefreshList()"
[actionBarColor]="ColorNames.Dark"
[searchBarColor]="ColorNames.Dark"
[searchBarInputColor]="ColorNames.Dark"
(removeItems)="handleRemoveItems($event)"
>
</x-list>
` +
'```';
readonly sample3 =
'```typescript' +
`
handleRefreshList() {
this.prepareListItems();
}
handleRemoveItems(request:
XBaseRangeRequestDto<string>) {
//
this.templListItems = this
.templListItems.filter(
(li) => !request.items
.includes(li.data)
);
}
private prepareListItems() {
this.templListItems = this
.tempList.map((i) => {
//
const li: XListItem<string> = {
data: \`Item $\{i.toString()}\`,
slideOptions: [
{
id: 'remove',
icon: this.IconNames.remove,
color: this.ColorNames.Danger,
onlyIcon: true,
slot: 'end',
handler: () => {
//
this.managerService
.notificationService
.presentDangerNotification({
message: \`remove: \${i}\`,
dissmissable: true,
});
},
},
{
id: 'edit',
icon: this.IconNames.edit,
color: this.ColorNames.Warning,
onlyIcon: true,
slot: 'start',
handler: () => {
//
this.managerService
.notificationService
.presentInfoNotification({
message: \`edit: \${i}\`,
dissmissable: true,
});
},
},
],
};
//
return li;
});
}
` +
'```';
//
tempList = Array.from(Array(25).keys());
templListItems: XListItem<string>[] = this.tempList.map((i) => {
//
const li: XListItem<string> = {
data: `Item ${i.toString()}`,
slideOptions: [
{
id: 'remove',
icon: this.IconNames.remove,
color: this.ColorNames.Danger,
onlyIcon: true,
slot: 'end',
handler: () => {
//
this.managerService.dialogService.presentAreYouSureYesNoDialog(
() => {
this.handleRemoveItems({ items: [li.data] });
}
);
},
},
{
id: 'edit',
icon: this.IconNames.edit,
color: this.ColorNames.Warning,
onlyIcon: true,
slot: 'start',
handler: () => {
//
this.managerService.notificationService.presentInfoNotification({
message: `edit: ${i}`,
dissmissable: true,
});
},
},
],
};
//
return li;
});
//
hideActions: XStandardType<XOneOrManyType<string>> = []; // [DefaultActionBarItemIds.Remove];
//
//#region UI Providers ...
//
// Provide content based on current locale ...
getContent(title: string) {
//
if (isNullOrEmptyString(title)) {
return '';
}
//
const currentLocale = this.managerService.currentLocale;
//
const varName =
title +
(currentLocale === 'en-US'
? 'En'
: currentLocale === 'fa-IR'
? 'Fa'
: '');
const result = this[`${varName}`];
//
return result || '';
}
//#endregion
//
//#region UI Handlers ...
//
handleRefreshList() {
this.prepareListItems();
}
//
handleRemoveItems(request: XBaseRangeRequestDto<string>) {
//
this.templListItems = this.templListItems.filter(
(li) => !request.items.includes(li.data)
);
//
this.managerService.notificationService.presentSuccessNotification({
message: `${request.items.length} item(s) removed ...`,
dissmissable: true,
});
}
//#endregion
//
//#region Private ...
//
private prepareListItems() {
this.templListItems = this.tempList.map((i) => {
//
const li: XListItem<string> = {
data: `Item ${i.toString()}`,
slideOptions: [
{
id: 'remove',
icon: this.IconNames.remove,
color: this.ColorNames.Danger,
onlyIcon: true,
slot: 'end',
handler: () => {
//
this.managerService.notificationService.presentDangerNotification(
{
message: `remove: ${i}`,
dissmissable: true,
}
);
},
},
{
id: 'edit',
icon: this.IconNames.edit,
color: this.ColorNames.Warning,
onlyIcon: true,
slot: 'start',
handler: () => {
//
this.managerService.notificationService.presentInfoNotification({
message: `edit: ${i}`,
dissmissable: true,
});
},
},
],
};
//
return li;
});
}
//#endregion
}
+102
View File
@@ -0,0 +1,102 @@
<v-page
[hasSide]="true"
[toolbarTitle]="toolbarTitle"
[toolbarSubTitle]="toolbarSubTitle"
[toolbarShowSubTitle]="toolbarShowSubTitle"
>
<!-- Content -->
<x-card [isInPage]="true" [showActions]="true" [color]="ColorNames.Light">
<!-- Content -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('content')"
></x-markdown>
<!-- <x-markdown
[mode]="'preview'"
[content]="sample1"
[hasToolbar]="false"
[cssClass]="'code-block'"
></x-markdown> -->
<!-- Map -->
<x-map
#xMap
[zoom]="14"
[isInPage]="true"
[canSelect]="false"
[wrapWithCard]="false"
[latitude]="35.814738589583044"
[longitude]="50.97853161365292"
[actionProvider]="mapActionProvider"
[searchBarColor]="ColorNames.Primary"
[searchBarSearchInputColor]="ColorNames.Primary"
></x-map>
<!-- Center -->
<x-button
[title]="'Set Center'"
[type]="ButtonTypes.Icon"
[icon]="IconNames.map"
(clicked)="handleSetCenter()"
></x-button>
<!-- Zoom -->
<x-button
[title]="'Set Zoom'"
[type]="ButtonTypes.Icon"
[icon]="IconNames.search"
(clicked)="handleSetZoom()"
></x-button>
<!-- AddMarker -->
<x-button
[title]="'Add Marker'"
[type]="ButtonTypes.Icon"
[icon]="IconNames.add"
(clicked)="handleAddMarker()"
></x-button>
<!-- ClearMarker -->
<x-button
[title]="'Clear Marker'"
[type]="ButtonTypes.Icon"
[icon]="IconNames.clear"
(clicked)="handleClearMarker()"
></x-button>
<!-- GoMarkedPlace -->
<x-button
[title]="'Go Marked Place'"
[type]="ButtonTypes.Icon"
[icon]="IconNames.refresh"
(clicked)="handleGoMarkedPlace()"
></x-button>
<!-- Locate -->
<x-button
[title]="'Locate'"
[type]="ButtonTypes.Icon"
[icon]="IconNames.locate"
(clicked)="handleLocate()"
></x-button>
<!-- MapDialog -->
<x-button
[title]="'Map Dialog'"
[icon]="IconNames.map"
[type]="ButtonTypes.Raised"
(clicked)="handleMapDialog()"
></x-button>
<!-- Actions -->
<div actions>
<a
target="_blank"
href="https://docs.x-framework.ir/x-framework-components/components/XMapComponent.html"
>{{resourceProvider(AppResourceIDs.documentation)}}</a
>
</div>
</x-card>
</v-page>
@@ -0,0 +1,3 @@
x-map {
--map-height: 500px;
}
+272
View File
@@ -0,0 +1,272 @@
import {
Inject,
NgZone,
Component,
Renderer2,
ElementRef,
ChangeDetectorRef,
} from '@angular/core';
import { Subject } from 'rxjs';
import {
XIconNames,
XMapAction,
XButtonType,
XMapLocation,
XMapComponent,
XPageContainer,
XMapActionModel,
XPopoverService,
XMapDialogService,
} from 'x-framework-components';
import { MenuController } from '@ionic/angular';
import { X_CONFIG } from 'src/app/config/x-config';
import { XConfig } from 'src/app/config/app-config';
import { ViewportRuler } from '@angular/cdk/overlay';
import { XManagerService } from 'x-framework-services';
import { XDialogResult, isNullOrEmptyString } from 'x-framework-core';
import { VPageComponent } from '../../../views/v-page/v-page.component';
import { AppResourceIDs } from 'src/app/config/app.localization.config';
@Component({
selector: 'app-map',
templateUrl: './map.page.html',
styleUrls: ['./map.page.scss'],
})
// tslint:disable-next-line:component-class-suffix
export class MapPage extends VPageComponent {
//
//#region Props ...
//
//#region Page Props ...
titleRes = AppResourceIDs.map;
toolbarTitle = this.resourceProvider(this.titleRes);
toolbarSubTitle = this.resourceProvider(AppResourceIDs.map_description);
toolbarShowSubTitle = true;
//#endregion
//
readonly IconNames = Object.assign({}, XIconNames);
readonly ButtonTypes = Object.assign({}, XButtonType);
readonly mapActionProvider = new Subject<XMapActionModel>();
//#endregion
//
//#region Constructor ...
public constructor(
public zone: NgZone,
@Inject(X_CONFIG)
public config: XConfig,
public element: ElementRef,
public renderer: Renderer2,
public ruler: ViewportRuler,
public menuController: MenuController,
public managerService: XManagerService,
public changeDetector: ChangeDetectorRef,
protected popoverService: XPopoverService,
protected propertyProvider: XPageContainer,
public mapDialogService: XMapDialogService
) {
super(
zone,
config,
element,
renderer,
ruler,
menuController,
managerService,
changeDetector,
popoverService,
propertyProvider
);
}
//#endregion
//
// Content ...
readonly contentFa = `
# ${this.toolbarTitle}
این مولفه جهت نمایش نقشه و مکان یابی بکار می رود
`;
readonly contentEn = `
# ${this.toolbarTitle}
this component used to show map and locating map.
`;
//
readonly sample1 =
'```html' +
`
<x-map
[zoom]="8"
[showZoom]="true"
[latitude]="35.84"
[showRotate]="true"
[showLocate]="true"
[longitude]="50.9391"
[showSearchBar]="true"
[showZoomSlider]="false"
[locateAfterInit]="true"
[showClearMarker]="true"
[showGoMarkedPlace]="true"
style="--map-height: 300px;"
[searchBarColor]="
ColorNames.Tertiary"
[searchResultListColor]="
ColorNames.Primary"
></x-map>
` +
'```';
//
//#region UI Providers ...
//
// Provide content based on current locale ...
getContent(title: string) {
//
if (isNullOrEmptyString(title)) {
return '';
}
//
const currentLocale = this.managerService.currentLocale;
//
const varName =
title +
(currentLocale === 'en-US'
? 'En'
: currentLocale === 'fa-IR'
? 'Fa'
: '');
const result = this[`${varName}`];
//
return result || '';
}
//#endregion
//
//#region UI Handlers ...
async handleSetZoom(map?: XMapComponent) {
//
if (map) {
//
await map.setZoom(12);
return;
}
//
this.mapActionProvider.next({
action: XMapAction.SetZoom,
payload: 12,
});
}
async handleSetCenter(map?: XMapComponent) {
//
if (map) {
//
await map.setCenter(35, 35, 6);
return;
}
//
this.mapActionProvider.next({
action: XMapAction.SetCenter,
payload: {
zoom: '6',
latitude: '35',
longitude: '35',
} as XMapLocation,
});
}
async handleAddMarker(map?: XMapComponent) {
//
if (map) {
//
await map.addMarker(35, 35);
return;
}
//
this.mapActionProvider.next({
action: XMapAction.AddMarker,
payload: {
latitude: '35',
longitude: '35',
} as XMapLocation,
});
}
async handleClearMarker(map?: XMapComponent) {
//
if (map) {
//
await map.clearMarker();
return;
}
//
this.mapActionProvider.next({
action: XMapAction.ClearMarker,
});
}
async handleGoMarkedPlace(map?: XMapComponent) {
//
if (map) {
//
await map.goMarkedPlace();
return;
}
//
this.mapActionProvider.next({
action: XMapAction.GoMarkedPlace,
});
}
async handleLocate(map?: XMapComponent) {
//
if (map) {
//
await map.locate();
return;
}
//
this.mapActionProvider.next({
action: XMapAction.Locate,
});
}
async handleMapDialog() {
//
this.mapDialogService.openDialog({
latitude: 35.814738589583044,
longitude: 50.97853161365292,
zoom: 14,
});
//
const resSubscription = this.mapDialogService.onResult.subscribe(
(result) => {
//
if (!result || result.result !== XDialogResult.Ok) {
//
console.log('empty result');
resSubscription.unsubscribe();
return;
}
//
console.log('selected Location: ', result.payload);
resSubscription.unsubscribe();
}
);
}
//#endregion
}
@@ -0,0 +1,65 @@
<v-page
[hasSide]="true"
[toolbarTitle]="toolbarTitle"
[toolbarSubTitle]="toolbarSubTitle"
[toolbarShowSubTitle]="toolbarShowSubTitle"
>
<!-- Content -->
<x-card [isInPage]="true" [showActions]="true" [color]="ColorNames.Light">
<!-- Content -->
<x-markdown
[hasToolbar]="false"
[mode]="MarkdownModes.PREVIEW"
[content]="getContent('content')"
></x-markdown>
<!-- Actions -->
<div actions>
<a
target="_blank"
href="https://docs.x-framework.ir/x-framework-components/components/XMarkdownComponent.html"
>{{resourceProvider(ResourceIDs.documentation)}}</a
>
</div>
</x-card>
<!-- Samples -->
<x-markdown
[isInPage]="true"
[content]="sample1"
[hasToolbar]="false"
[wrapWithCard]="true"
[cssClass]="'code-block'"
[mode]="MarkdownModes.PREVIEW"
[cardTitle]="resourceProvider(ResourceIDs.sample)"
></x-markdown>
<!-- Components -->
<x-markdown
[isInPage]="true"
[wrapWithCard]="true"
[mode]="MarkdownModes.BOTH"
[(content)]="sampleContent1"
[toolbarColor]="ColorNames.Dark"
></x-markdown>
<!-- Samples -->
<x-markdown
[isInPage]="true"
[content]="sample2"
[hasToolbar]="false"
[wrapWithCard]="true"
[cssClass]="'code-block'"
[mode]="MarkdownModes.PREVIEW"
[cardTitle]="resourceProvider(ResourceIDs.sample)"
></x-markdown>
<!-- Components -->
<x-markdown
[isInPage]="true"
[hasToolbar]="false"
[wrapWithCard]="true"
[content]="sampleContent2"
[mode]="MarkdownModes.PREVIEW"
></x-markdown>
</v-page>
@@ -0,0 +1,117 @@
import { Component } from '@angular/core';
import { XIconNames } from 'x-framework-components';
import { XMarkdownMode } from 'x-framework-components';
import { VPageComponent } from '../../../views/v-page/v-page.component';
import { AppResourceIDs } from 'src/app/config/app.localization.config';
import { XResourceIDs, isNullOrEmptyString, XColor } from 'x-framework-core';
@Component({
selector: 'app-markdown',
templateUrl: './markdown.page.html',
styleUrls: ['./markdown.page.scss'],
})
// tslint:disable-next-line:component-class-suffix
export class MarkdownPage extends VPageComponent {
//
//#region Props ...
//
//#region Page Props ...
titleRes = AppResourceIDs.markdown;
toolbarTitle = this.resourceProvider(this.titleRes);
toolbarSubTitle = this.resourceProvider(AppResourceIDs.markdown_description);
toolbarShowSubTitle = true;
//#endregion
//
// Prepare All Resource IDs ...
readonly ResourceIDs = Object.assign(
Object.assign({}, XResourceIDs),
AppResourceIDs
) as any;
//
readonly IconNames = Object.assign({}, XIconNames);
//#endregion
//
readonly MarkdownModes = Object.assign({}, XMarkdownMode);
//
// Content ...
readonly contentFa = `
# ${this.toolbarTitle}
این مولفه جهت دریافت و نمایش اطلاعات مبتنی بر شیوه نشانه گذاری داده ها موسوم به مارک داون (MarkDown) کاربرد دارد.
`;
readonly contentEn = `
# ${this.toolbarTitle}
this component used to get and show MarkDown based Data's.
`;
//
readonly sample1 =
'```html' +
`
<x-markdown
[mode]="MarkdownModes.BOTH"
[(content)]="sampleContent1"
[toolbarColor]="ColorNames.Dark"
></x-markdown>
` +
'```';
readonly sample2 =
'```html' +
`
<x-markdown
[hasToolbar]="false"
[content]="sampleContent2"
[mode]="MarkdownModes.PREVIEW"
></x-markdown>
` +
'```';
//
sampleContent1 = `
## Todo example
- Variable binding
- Code refactor
- Write more unit tests
- Module configuration for markdown settings
- Module configuration for prismjs settings
`;
readonly sampleContent2 = `
## Todo example
this is only a preview sample of markdown.
`;
//
//#region UI Providers ...
//
// Provide content based on current locale ...
getContent(title: string) {
//
if (isNullOrEmptyString(title)) {
return '';
}
//
const currentLocale = this.managerService.currentLocale;
//
const varName =
title +
(currentLocale === 'en-US'
? 'En'
: currentLocale === 'fa-IR'
? 'Fa'
: '');
const result = this[`${varName}`];
//
return result || '';
}
//#endregion
}
@@ -0,0 +1,142 @@
<v-page
[hasSide]="true"
[toolbarTitle]="toolbarTitle"
[toolbarSubTitle]="toolbarSubTitle"
[toolbarShowSubTitle]="toolbarShowSubTitle"
>
<!-- Content -->
<x-card [isInPage]="true" [showActions]="true" [color]="ColorNames.Light">
<!-- Content -->
<x-markdown
[hasToolbar]="false"
[mode]="MarkdownModes.PREVIEW"
[content]="getContent('content')"
></x-markdown>
<!-- Actions -->
<div actions>
<a
target="_blank"
href="https://docs.x-framework.ir/x-framework-components/components/XModelPresenter.html"
>{{resourceProvider(ResourceIDs.documentation)}}</a
>
</div>
</x-card>
<!-- Samples -->
<x-markdown
[isInPage]="true"
[content]="sample1"
[hasToolbar]="false"
[wrapWithCard]="true"
[cssClass]="'code-block'"
[mode]="MarkdownModes.PREVIEW"
[cardTitle]="resourceProvider(ResourceIDs.sample)"
></x-markdown>
<!-- Samples -->
<x-markdown
[isInPage]="true"
[content]="sample2"
[hasToolbar]="false"
[wrapWithCard]="true"
[cssClass]="'code-block'"
[mode]="MarkdownModes.PREVIEW"
></x-markdown>
<!-- Samples -->
<x-markdown
[isInPage]="true"
[content]="sample3"
[hasToolbar]="false"
[wrapWithCard]="true"
[cssClass]="'code-block'"
[mode]="MarkdownModes.PREVIEW"
></x-markdown>
<!-- Samples -->
<x-markdown
[isInPage]="true"
[content]="sample4"
[hasToolbar]="false"
[wrapWithCard]="true"
[cssClass]="'code-block'"
[mode]="MarkdownModes.PREVIEW"
></x-markdown>
<!-- Samples -->
<x-markdown
[isInPage]="true"
[content]="sample5"
[hasToolbar]="false"
[wrapWithCard]="true"
[cssClass]="'code-block'"
[mode]="MarkdownModes.PREVIEW"
></x-markdown>
<!-- Components -->
<x-model-presenter
class="v-card"
[isInPage]="true"
[model]="dataModel"
[wrapWithCard]="true"
[color]="ColorNames.Light"
[cardTitle]="'Object Editor'"
[cardColor]="ColorNames.Light"
[valueColor]="ColorNames.Dark"
[startupState]="'collapse-all'"
[headerColor]="ColorNames.Light"
[actionProvider]="actionProvider"
[hiddenModelKeys]="hiddenModelKeys"
[modelKeyProvider]="modelKeyProvider"
[labelColor]="ColorNames.TertiaryShade"
[availableModelKeys]="availableModelKeys"
[sortOrderModelKeys]="sortOrederModelKeys"
[propertyActionTemplate]="propertyActionRef"
[hiddenLabelModelKeys]="hiddenLabelModelKeys"
(onModelChanged)="handleModelChanged($event)"
[headerHighlightColor]="ColorNames.WarningTint"
></x-model-presenter>
</v-page>
<!-- Property Action Template -->
<ng-template
#propertyActionRef
let-key="key"
let-prefix="prefix"
let-value="value"
>
<!-- is Small Screen -->
<ng-container *ngIf="isMobileUi$ | async">
<!-- Property Selector -->
<x-icon
[clickable]="true"
[foregroundColor]="true"
[color]="ColorNames.Dark"
[name]="IconNames.menu_vertical"
(clicked)="handlePropertyActionMenuClicked(key, prefix, value)"
></x-icon>
</ng-container>
<!-- is Big Screen -->
<ng-container *ngIf="isNotMobileUi$ | async">
<!-- Property Selector -->
<x-icon
[clickable]="true"
[foregroundColor]="true"
[name]="IconNames.edit"
(clicked)="handlePropertyEdit(key, prefix, value)"
[color]="(notNullOrUndefinedValue(value) | async) ? ColorNames.Tertiary : ColorNames.Danger"
></x-icon>
<!-- Property Clear -->
<x-icon
[clickable]="true"
[foregroundColor]="true"
[name]="IconNames.clear"
[color]="ColorNames.Danger"
[uiDisabled]="nullOrUndefinedValue(value) | async"
(clicked)="handlePropertyClear(key, prefix, value)"
></x-icon>
</ng-container>
</ng-template>
@@ -0,0 +1,804 @@
import {
nameof,
assign,
XParam,
isFunction,
XResourceIDs,
XModelProperty,
XModalButtonRole,
XModelKeyProvider,
isNullOrUndefined,
isNullOrEmptyString,
} from 'x-framework-core';
import { Subject } from 'rxjs';
import {
XListItem,
XIconNames,
XPopoverComponent,
XListItemSlideOption,
XModelPresenterAction,
XModelPresenterActionModel,
} from 'x-framework-components';
import { Component } from '@angular/core';
import { XMarkdownMode } from 'x-framework-components';
import { VPageComponent } from '../../../views/v-page/v-page.component';
import { AppResourceIDs } from 'src/app/config/app.localization.config';
export interface DataMODEL {
firstName: string;
lastName: string;
email: string;
contacts: Array<{
type: 'mobile' | 'phone';
title: string;
number: string;
}>;
checkList: {
todo1: boolean;
todo2: boolean;
todo3: boolean;
todo4: Array<{
action: string;
dueData: Date;
}>;
};
}
@Component({
selector: 'app-model-presenter',
templateUrl: './model-presenter.page.html',
styleUrls: ['./model-presenter.page.scss'],
})
// tslint:disable-next-line:component-class-suffix
export class ModelPresenterPage extends VPageComponent {
//
//#region Props ...
//
//#region Page Props ...
titleRes = AppResourceIDs.model_presenter;
toolbarTitle = this.resourceProvider(this.titleRes);
toolbarSubTitle = this.resourceProvider(
AppResourceIDs.model_presenter_description
);
toolbarShowSubTitle = true;
//#endregion
//
// Prepare All Resource IDs ...
readonly ResourceIDs = Object.assign(
Object.assign({}, XResourceIDs),
AppResourceIDs
) as any;
//
readonly IconNames = Object.assign({}, XIconNames);
//#endregion
//
readonly MarkdownModes = Object.assign({}, XMarkdownMode);
//
//#region Model Presenter ...
dataModel: DataMODEL = {
firstName: 'Hadi',
lastName: 'Khazaee Asl',
email: 'hadi_khazaee_asl@yahoo.com',
contacts: [
{
type: 'mobile',
title: 'Personal',
number: '09121694056',
},
{
type: 'phone',
title: 'saherelm office',
number: '02632757987',
},
],
checkList: {
todo1: true,
todo2: false,
todo3: true,
todo4: [
{
action: 'start',
dueData: new Date(),
},
{
action: 'end',
dueData: new Date(),
},
],
},
};
actionProvider = new Subject<XModelPresenterActionModel>();
availableModelKeys: string[] = [
nameof<DataMODEL>('lastName'),
nameof<DataMODEL>('firstName'),
nameof<DataMODEL>('email'),
nameof<DataMODEL>('contacts'),
nameof<DataMODEL>('checkList'),
//
// Contacts ...
// `${nameof<DataMODEL>('contacts')}.type`,
`${nameof<DataMODEL>('contacts')}.title`,
// `${nameof<DataMODEL>('contacts')}.number`,
//
// Checklist ...
`${nameof<DataMODEL>('checkList')}.todo1`,
`${nameof<DataMODEL>('checkList')}.todo2`,
`${nameof<DataMODEL>('checkList')}.todo3`,
`${nameof<DataMODEL>('checkList')}.todo4`,
//
`${nameof<DataMODEL>('checkList')}.todo4.action`,
`${nameof<DataMODEL>('checkList')}.todo4.dueData`,
];
hiddenModelKeys: string[] = [`${nameof<DataMODEL>('contacts')}.type`];
hiddenLabelModelKeys: string[] = [`${nameof<DataMODEL>('contacts')}.number`];
//
sortOrederModelKeys: string[] = [
nameof<DataMODEL>('firstName'),
nameof<DataMODEL>('lastName'),
nameof<DataMODEL>('email'),
nameof<DataMODEL>('contacts'),
nameof<DataMODEL>('checkList'),
//
// Contacts ...
`${nameof<DataMODEL>('contacts')}.number`,
`${nameof<DataMODEL>('contacts')}.title`,
//
// Checklist ...
`${nameof<DataMODEL>('checkList')}.todo4.dueData`,
`${nameof<DataMODEL>('checkList')}.todo4.action`,
];
//
modelKeyProvider: XModelKeyProvider<any> = (key) => {
//
let result = key as string;
//
switch (key) {
//
case nameof<DataMODEL>('firstName'):
result = this.resourceProvider(this.AppResourceIDs.first_name);
break;
//
case nameof<DataMODEL>('lastName'):
result = this.resourceProvider(this.AppResourceIDs.last_name);
break;
//
case nameof<DataMODEL>('contacts'):
result = this.resourceProvider(this.AppResourceIDs.content);
break;
//
default:
result = key as string;
break;
}
//
return result;
};
//#endregion
//
// Content ...
readonly contentFa = `
# ${this.toolbarTitle}
این مولفه جهت نمایش و ویرایش یک شی یا مدل در نمایی ساختار یافته بکار می رود.
`;
readonly contentEn = `
# ${this.toolbarTitle}
this component used to view and edit data models in an structural view.
`;
//
readonly sample1 =
'```html' +
`
<x-model-presenter
class="v-card"
[isInPage]="true"
[model]="dataModel"
[wrapWithCard]="true"
[color]="ColorNames.Light"
[cardTitle]="'Object Editor'"
[cardColor]="ColorNames.Light"
[valueColor]="ColorNames.Dark"
[startupState]="'collapse-all'"
[headerColor]="ColorNames.Light"
[actionProvider]="actionProvider"
[hiddenModelKeys]="hiddenModelKeys"
[modelKeyProvider]="modelKeyProvider"
[labelColor]="ColorNames.TertiaryShade"
[availableModelKeys]="availableModelKeys"
[sortOrderModelKeys]="sortOrederModelKeys"
[propertyActionTemplate]="propertyActionRef"
[hiddenLabelModelKeys]="hiddenLabelModelKeys"
(onModelChanged)="handleModelChanged($event)"
[headerHighlightColor]="ColorNames.WarningTint"
></x-model-presenter>
` +
'```';
readonly sample2 =
'```html' +
`
<!-- Property Action Template -->
<ng-template
#propertyActionRef
let-key="key"
let-prefix="prefix"
let-value="value"
>
<!-- is Small Screen -->
<ng-container *ngIf="isMobileUi$ | async">
<!-- Property Selector -->
<x-icon
[clickable]="true"
[foregroundColor]="true"
[color]="ColorNames.Dark"
[name]="IconNames.menu_vertical"
(clicked)="handlePropertyActionMenuClicked(key, prefix, value)"
></x-icon>
</ng-container>
<!-- is Big Screen -->
<ng-container *ngIf="isNotMobileUi$ | async">
<!-- Property Selector -->
<x-icon
[clickable]="true"
[foregroundColor]="true"
[name]="IconNames.edit"
(clicked)="handlePropertyEdit(key, prefix, value)"
[color]="(notNullOrUndefinedValue(value) | async) ? ColorNames.Tertiary : ColorNames.Danger"
></x-icon>
<!-- Property Clear -->
<x-icon
[clickable]="true"
[foregroundColor]="true"
[name]="IconNames.clear"
[color]="ColorNames.Danger"
[uiDisabled]="nullOrUndefinedValue(value) | async"
(clicked)="handlePropertyClear(key, prefix, value)"
></x-icon>
</ng-container>
</ng-template>
` +
'```';
readonly sample3 =
'```javascript' +
`
export interface DataMODEL {
firstName: string;
lastName: string;
email: string;
contacts: Array<{
type: 'mobile' | 'phone';
title: string;
number: string;
}>;
checkList: {
todo1: boolean;
todo2: boolean;
todo3: boolean;
todo4: Array<{
action: string;
dueData: Date;
}>;
};
}
` +
'```';
readonly sample4 =
'```javascript' +
`
dataModel: DataMODEL = {
firstName: 'Hadi',
lastName: 'Khazaee Asl',
email: 'hadi_khazaee_asl@yahoo.com',
contacts: [
{
type: 'mobile',
title: 'Personal',
number: '09121694056',
},
{
type: 'phone',
title: 'saherelm office',
number: '02632757987',
},
],
checkList: {
todo1: true,
todo2: false,
todo3: true,
todo4: [
{
action: 'start',
dueData: new Date(),
},
{
action: 'end',
dueData: new Date(),
},
],
},
};
actionProvider = new Subject<XModelPresenterActionModel>();
availableModelKeys: string[] = [
nameof<DataMODEL>('lastName'),
nameof<DataMODEL>('firstName'),
nameof<DataMODEL>('email'),
nameof<DataMODEL>('contacts'),
nameof<DataMODEL>('checkList'),
//
// Contacts ...
\`\${nameof<DataMODEL>('contacts')}.type\`,
\`\${nameof<DataMODEL>('contacts')}.title\`,
\`\${nameof<DataMODEL>('contacts')}.number\`,
//
// Checklist ...
\`\${nameof<DataMODEL>('checkList')}.todo1\`,
\`\${nameof<DataMODEL>('checkList')}.todo2\`,
\`\${nameof<DataMODEL>('checkList')}.todo3\`,
\`\${nameof<DataMODEL>('checkList')}.todo4\`,
//
\`\${nameof<DataMODEL>('checkList')}.todo4.action\`,
\`\${nameof<DataMODEL>('checkList')}.todo4.dueData\`,
];
hiddenModelKeys: string[] = [\`\${nameof<DataMODEL>('contacts')}.type\`];
hiddenLabelModelKeys: string[] = [\`\${nameof<DataMODEL>('contacts')}.number\`];
//
sortOrederModelKeys: string[] = [
nameof<DataMODEL>('firstName'),
nameof<DataMODEL>('lastName'),
nameof<DataMODEL>('email'),
nameof<DataMODEL>('contacts'),
nameof<DataMODEL>('checkList'),
//
// Contacts ...
\`\${nameof<DataMODEL>('contacts')}.number\`,
\`\${nameof<DataMODEL>('contacts')}.title\`,
//
// Checklist ...
\`\${nameof<DataMODEL>('checkList')}.todo4.dueData\`,
\`\${nameof<DataMODEL>('checkList')}.todo4.action\`,
];
//
modelKeyProvider: XModelPresenterModelKeyProvider<any> = (key) => {
//
let result = key as string;
//
switch (key) {
//
case nameof<DataMODEL>('firstName'):
result = this.resourceProvider(this.AppResourceIDs.first_name);
break;
//
case nameof<DataMODEL>('lastName'):
result = this.resourceProvider(this.AppResourceIDs.last_name);
break;
//
case nameof<DataMODEL>('contacts'):
result = this.resourceProvider(this.AppResourceIDs.content);
break;
//
default:
result = key as string;
break;
}
//
return result;
};
` +
'```';
readonly sample5 =
'```javascript' +
`
async handlePropertyActionMenuClicked(
key: string,
prefix: string,
value: any
) {
//
if (isNullOrEmptyString(key)) {
return;
}
//
const onlyIcon = false;
const slideOptions: XListItemSlideOption[] = [];
//
// Edit ...
slideOptions.push({
id: 'property_edit',
icon: this.IconNames.edit,
title: this.ResourceIDs.edit,
color: isNullOrUndefined(value)
? this.ColorNames.Danger
: this.ColorNames.Tertiary,
slot: 'start',
onlyIcon,
handler: async () => {
await this.handlePropertyEdit(key, prefix, value);
},
});
//
// Clear ...
slideOptions.push({
id: 'property_clear',
icon: this.IconNames.clear,
title: this.ResourceIDs.clear,
color: this.ColorNames.Danger,
slot: 'start',
disabled: isNullOrUndefined(value),
onlyIcon,
handler: async () => {
await this.handlePropertyClear(key, prefix, value);
},
});
//
// Menu Items ...
const item: XListItem<any> = {
data: '',
slideOptions,
};
//
const popOver = await this.managerService.dialogService.presentPopover({
component: XPopoverComponent,
componentProps: assign({}, { key: XParam.Item, value: item }),
translucent: true,
showBackdrop: true,
event,
});
//
const { data } = await popOver.onWillDismiss();
if (!data || !data.id || !data.data) {
return;
}
//
const optionId = data.id.toString() as string;
const option =
item && item.slideOptions
? item.slideOptions.find((so) => so.id === optionId)
: null;
if (!option) {
return;
}
//
const handler = option.handler;
if (!handler || !isFunction(handler)) {
return;
}
//
// Run Handler ...
await handler();
}
async handlePropertyEdit(key: string, prefix: string, value: any) {
//
if (isNullOrEmptyString(key)) {
return;
}
//
await this.managerService.dialogService.presentAlert({
header: 'Change Value:',
message: 'Enter new Value:',
inputs: [
{
type: 'text',
name: 'value',
label: 'Value',
placeholder: isNullOrUndefined(value) ? '' : \`\${value.toString()}\`,
},
],
buttons: [
{
text: 'Change',
role: XModalButtonRole.Selected,
cssClass: ['btn-selected'],
handler: async (value) => {
//
let newValue = '';
if (value && value.value) {
newValue = value.value;
}
//
console.log('new value to set: ', newValue);
//
this.actionProvider.next({
action: XModelPresenterAction.SetProperty,
payload: {
key: key,
value: newValue,
keyPrefix: prefix,
} as XModelPresenterProperty,
});
},
},
{
text: 'Cancel',
role: XModalButtonRole.Cancel,
cssClass: ['btn-cancel'],
},
],
});
}
async handlePropertyClear(key: string, prefix: string, value: any) {
//
if (isNullOrEmptyString(key) || isNullOrUndefined(value)) {
return;
}
//
await this.managerService.dialogService.presentAreYouSureYesNoDialog(() => {
//
this.actionProvider.next({
action: XModelPresenterAction.ClearProperty,
payload: {
key,
keyPrefix: prefix,
} as XModelPresenterProperty,
});
});
}
async handleModelChanged(event: any) {
console.log('handle model changed: ', event);
}
` +
'```';
// readonly sample3 =
// '```html' +
// `
// ` +
// '```';
//
//#region UI Providers ...
//
// Provide content based on current locale ...
getContent(title: string) {
//
if (isNullOrEmptyString(title)) {
return '';
}
//
const currentLocale = this.managerService.currentLocale;
//
const varName =
title +
(currentLocale === 'en-US'
? 'En'
: currentLocale === 'fa-IR'
? 'Fa'
: '');
const result = this[`${varName}`];
//
return result || '';
}
//#endregion
//
//#region UI Handlers ...
//
//#region Model Presenter Handlers ...
async handlePropertyActionMenuClicked(
key: string,
prefix: string,
value: any
) {
//
if (isNullOrEmptyString(key)) {
return;
}
//
const onlyIcon = false;
const slideOptions: XListItemSlideOption[] = [];
//
// Edit ...
slideOptions.push({
id: 'property_edit',
icon: this.IconNames.edit,
title: this.ResourceIDs.edit,
color: isNullOrUndefined(value)
? this.ColorNames.Danger
: this.ColorNames.Tertiary,
slot: 'start',
onlyIcon,
handler: async () => {
await this.handlePropertyEdit(key, prefix, value);
},
});
//
// Clear ...
slideOptions.push({
id: 'property_clear',
icon: this.IconNames.clear,
title: this.ResourceIDs.clear,
color: this.ColorNames.Danger,
slot: 'start',
disabled: isNullOrUndefined(value),
onlyIcon,
handler: async () => {
await this.handlePropertyClear(key, prefix, value);
},
});
//
// Menu Items ...
const item: XListItem<any> = {
data: '',
slideOptions,
};
//
const popOver = await this.managerService.dialogService.presentPopover({
component: XPopoverComponent,
componentProps: assign({}, { key: XParam.Item, value: item }),
translucent: true,
showBackdrop: true,
event,
});
//
const { data } = await popOver.onWillDismiss();
if (!data || !data.id || !data.data) {
return;
}
//
const optionId = data.id.toString() as string;
const option =
item && item.slideOptions
? item.slideOptions.find((so) => so.id === optionId)
: null;
if (!option) {
return;
}
//
const handler = option.handler;
if (!handler || !isFunction(handler)) {
return;
}
//
// Run Handler ...
await handler();
}
async handlePropertyEdit(key: string, prefix: string, value: any) {
//
if (isNullOrEmptyString(key)) {
return;
}
//
await this.managerService.dialogService.presentAlert({
header: 'Change Value:',
message: 'Enter new Value:',
inputs: [
{
type: 'text',
name: 'value',
label: 'Value',
placeholder: isNullOrUndefined(value) ? '' : `${value.toString()}`,
},
],
buttons: [
{
text: 'Change',
role: XModalButtonRole.Selected,
cssClass: ['btn-selected'],
handler: async (value) => {
//
let newValue = '';
if (value && value.value) {
newValue = value.value;
}
//
console.log('new value to set: ', newValue);
//
this.actionProvider.next({
action: XModelPresenterAction.SetProperty,
payload: {
prefix,
key: key,
value: newValue,
} as XModelProperty,
});
},
},
{
text: 'Cancel',
role: XModalButtonRole.Cancel,
cssClass: ['btn-cancel'],
},
],
});
}
async handlePropertyClear(key: string, prefix: string, value: any) {
//
if (isNullOrEmptyString(key) || isNullOrUndefined(value)) {
return;
}
//
await this.managerService.dialogService.presentAreYouSureYesNoDialog(() => {
//
this.actionProvider.next({
action: XModelPresenterAction.ClearProperty,
payload: {
key,
prefix,
} as XModelProperty,
});
});
}
async handleModelChanged(event: any) {
console.log('handle model changed: ', event);
}
//#endregion
//#endregion
}
@@ -0,0 +1,33 @@
<v-page
[hasSide]="true"
[toolbarTitle]="toolbarTitle"
[toolbarSubTitle]="toolbarSubTitle"
[toolbarShowSubTitle]="toolbarShowSubTitle"
>
<!-- Content -->
<x-card [isInPage]="true" [showActions]="true" [color]="ColorNames.Light">
<!-- Content -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('content')"
></x-markdown>
<!-- Sample -->
<x-markdown
[mode]="'preview'"
[content]="sample1"
[hasToolbar]="false"
[cssClass]="'code-block'"
></x-markdown>
<!-- Actions -->
<div actions>
<a
target="_blank"
href="https://docs.x-framework.ir/x-framework-components/modules/XPageModule.html"
>{{resourceProvider(ResourceIDs.documentation)}}</a
>
</div>
</x-card>
</v-page>
+124
View File
@@ -0,0 +1,124 @@
import { Component } from '@angular/core';
import { XIconNames } from 'x-framework-components';
import { VPageComponent } from '../../../views/v-page/v-page.component';
import { AppResourceIDs } from 'src/app/config/app.localization.config';
import { XResourceIDs, isNullOrEmptyString, XColor } from 'x-framework-core';
@Component({
selector: 'app-page',
templateUrl: './page.page.html',
styleUrls: ['./page.page.scss'],
})
// tslint:disable-next-line:component-class-suffix
export class PagePage extends VPageComponent {
//
//#region Props ...
//
//#region Page Props ...
titleRes = AppResourceIDs.page;
toolbarTitle = this.resourceProvider(this.titleRes);
toolbarSubTitle = this.resourceProvider(AppResourceIDs.page_description);
toolbarShowSubTitle = true;
//#endregion
//
// Prepare All Resource IDs ...
readonly ResourceIDs = Object.assign(
Object.assign({}, XResourceIDs),
AppResourceIDs
) as any;
//
readonly IconNames = Object.assign({}, XIconNames);
//#endregion
//
// Content ...
readonly contentFa = `
# ${this.toolbarTitle}
این مولفه یکی از پرکاربرد ترین مولفه های ارائه شده توسط این چارچوب است و برای ارائه یک صفحه مجزا در یک برنامه کاربردی کاربرد دارد.
یک صفحه از ترکیب چهار مولفه مجزا تشکیل میگردد، که عبارتند از:
- **XToolbarComponent**:
این مولفه میتواند در ناحیه فوقانی یک صفحه قرار بگیرد و امکانات مختلفی را فراهم کند.
- **XFooterComponent**:
این مولفه میتواند در ناحیه تحتانی یک صفحه قرار بگیرد.
- **XNavigatorComponent**:
این مولفه می تواند در ناحیه کناری صفحه قرار گرفته و گزینه های مختلفی را بعنوان نوار پیمایش در صفحات مختلف را ارئه کند.
- **XPageComponent**:
این مولفه از هر سه مولفه فوق استفاده می کند و امکانات لازم جهت چینش اجزاء مختلف در صفحه و مدیریت نحوه نمایش آن را فراهم می کند.
صفحه حاضر و تمام صفحاتی که در این مستند مرور کرده اید با بهره گیری از این مولفه ایجاد شده اند.
`;
readonly contentEn = `
# ${this.toolbarTitle}
this is a most common component's of this Framework and used to provide an stand alone Page in an Application.
a page presented by combining 4 unique components, which are:
- **XToolbarComponent**:
this component can show in top area of a page and provide several options.
- **XFooterComponent**:
this component can show in bottom area of a page.
- **XNavigatorComponent**:
this component can show in side area of a page and provide several options as a navigation bar.
- **XPageComponent**:
this component use all of 3 above components and provide options to manage their usage and how to looks like a page.
this page and all pages you explored until now created useing this Component.
`;
//
readonly sample1 =
'```html' +
`
<v-page
[hasSide]="true"
[toolbarTitle]="toolbarTitle"
[toolbarSubTitle]="toolbarSubTitle"
[toolbarShowSubTitle]="toolbarShowSubTitle"
...
>
<!-- Content -->
...
</v-page>
` +
'```';
//
//#region UI Providers ...
//
// Provide content based on current locale ...
getContent(title: string) {
//
if (isNullOrEmptyString(title)) {
return '';
}
//
const currentLocale = this.managerService.currentLocale;
//
const varName =
title +
(currentLocale === 'en-US'
? 'En'
: currentLocale === 'fa-IR'
? 'Fa'
: '');
const result = this[`${varName}`];
//
return result || '';
}
//#endregion
}
@@ -0,0 +1,85 @@
<v-page
[hasSide]="true"
[toolbarTitle]="toolbarTitle"
[toolbarSubTitle]="toolbarSubTitle"
[toolbarShowSubTitle]="toolbarShowSubTitle"
>
<!-- Content -->
<x-card [isInPage]="true" [showActions]="true" [color]="ColorNames.Light">
<!-- Content -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('content')"
></x-markdown>
<!-- Actions -->
<div actions>
<a
target="_blank"
href="https://docs.x-framework.ir/x-framework-components/modules/XSliderModule.html"
>{{resourceProvider(ResourceIDs.documentation)}}</a
>
</div>
</x-card>
<!-- Sample -->
<x-markdown
[isInPage]="true"
[mode]="'preview'"
[content]="sample1"
[hasToolbar]="false"
[wrapWithCard]="true"
[cssClass]="'code-block'"
[cardTitle]="resourceProvider(ResourceIDs.sample)"
></x-markdown>
<!-- Component -->
<x-slider
[isInPage]="true"
[options]="{
lazy: true,
zoom: true,
autoplay: true,
initialSlide: 0,
grabCursor: true,
autoHeight: true,
slidesPerView: 1,
loadPrevNext: true,
preventClicks: false,
speed: 400,
pagination: true
}"
[wrapWithCard]="true"
[animation]="SliderAnimations.Coverflow"
(onSlideChange)="handleOnSlideChange($event)"
>
<x-slide>
<ng-container *ngTemplateOutlet="slideRef"></ng-container>
</x-slide>
<x-slide>
<ng-container *ngTemplateOutlet="slideRef"></ng-container>
</x-slide>
<x-slide>
<ng-container *ngTemplateOutlet="slideRef"></ng-container>
</x-slide>
<x-slide>
<ng-container *ngTemplateOutlet="slideRef"></ng-container>
</x-slide>
<x-slide>
<ng-container *ngTemplateOutlet="slideRef"></ng-container>
</x-slide>
</x-slider>
</v-page>
<ng-template #slideRef>
<div class="slide-content">
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quas eum odit
labore magnam accusantium assumenda error voluptatem ad cumque velit? Eos
expedita minus doloremque error iste nam commodi aspernatur repellendus.
</div>
</ng-template>
@@ -0,0 +1,10 @@
.slide-content {
direction: ltr;
text-align: justify;
padding: {
top: 24px;
bottom: 24px;
left: 16px;
right: 16px;
}
}
@@ -0,0 +1,139 @@
import { Component } from '@angular/core';
import { XIconNames } from 'x-framework-components';
import { XSliderAnimation } from 'x-framework-components';
import { XResourceIDs, isNullOrEmptyString } from 'x-framework-core';
import { VPageComponent } from '../../../views/v-page/v-page.component';
import { AppResourceIDs } from 'src/app/config/app.localization.config';
@Component({
selector: 'app-slider',
templateUrl: './slider.page.html',
styleUrls: ['./slider.page.scss'],
})
// tslint:disable-next-line:component-class-suffix
export class SliderPage extends VPageComponent {
//
//#region Props ...
//
//#region Page Props ...
titleRes = AppResourceIDs.slider;
toolbarTitle = this.resourceProvider(this.titleRes);
toolbarSubTitle = this.resourceProvider(AppResourceIDs.slider_description);
toolbarShowSubTitle = true;
//#endregion
//
// Prepare All Resource IDs ...
readonly ResourceIDs = Object.assign(
Object.assign({}, XResourceIDs),
AppResourceIDs
) as any;
//
readonly IconNames = Object.assign({}, XIconNames);
//#endregion
//
readonly SliderAnimations = Object.assign({}, XSliderAnimation);
//
// Content ...
readonly contentFa = `
# ${this.toolbarTitle}
این مولفه جهت نمایش محتوا بصورت کادر های لغزنده بکار می رود.
`;
readonly contentEn = `
# ${this.toolbarTitle}
this Component used to provide Slideable Content's.
`;
//
readonly sample1 =
'```html' +
`
<x-slider
[options]="{
lazy: true,
zoom: true,
autoplay: true,
initialSlide: 0,
grabCursor: true,
autoHeight: true,
slidesPerView: 1,
loadPrevNext: true,
preventClicks: false,
speed: 400,
pagination: true
}"
[animation]="SliderAnimations.Cube"
>
<x-slide>
<ng-container
*ngTemplateOutlet="slideRef">
</ng-container>
</x-slide>
<x-slide>
<ng-container
*ngTemplateOutlet="slideRef">
</ng-container>
</x-slide>
<x-slide>
<ng-container
*ngTemplateOutlet="slideRef">
</ng-container>
</x-slide>
<x-slide>
<ng-container
*ngTemplateOutlet="slideRef">
</ng-container>
</x-slide>
<x-slide>
<ng-container
*ngTemplateOutlet="slideRef">
</ng-container>
</x-slide>
</x-slider>
` +
'```';
//
//#region UI Providers ...
//
// Provide content based on current locale ...
getContent(title: string) {
//
if (isNullOrEmptyString(title)) {
return '';
}
//
const currentLocale = this.managerService.currentLocale;
//
const varName =
title +
(currentLocale === 'en-US'
? 'En'
: currentLocale === 'fa-IR'
? 'Fa'
: '');
const result = this[`${varName}`];
//
return result || '';
}
//#endregion
//
//#region UI Handlers ...
handleOnSlideChange(index: number) {
console.log('handleOnSlideChange: ', index);
}
//#endregion
}
@@ -0,0 +1,8 @@
<div>
<h3>Sample Modal Component</h3>
<p>this is sample modal component content ...</p>
<span>Binded Context: {{ context }}</span>
<x-button (click)="handleClosePopup()">CLOSE</x-button>
</div>
@@ -0,0 +1,42 @@
import { Component, Input } from '@angular/core';
import { ModalController, PopoverController } from '@ionic/angular';
export enum XModalContext {
Modal = 'modal',
PopOver = 'pop_over',
}
@Component({
selector: 'app-sample-modal',
templateUrl: './sample-modal.component.html',
styleUrls: ['./sample-modal.component.scss'],
})
export class SampleModalComponent {
@Input()
context: XModalContext;
constructor(
private modalController: ModalController,
private popOverController: PopoverController
) {}
handleClosePopup() {
//
if (!this.context) {
return;
}
//
switch (this.context) {
//
case XModalContext.Modal:
this.modalController.dismiss();
break;
//
case XModalContext.PopOver:
this.popOverController.dismiss();
break;
}
}
}
@@ -0,0 +1,711 @@
<v-page
[hasSide]="true"
[toolbarTitle]="toolbarTitle"
[toolbarSubTitle]="toolbarSubTitle"
[toolbarShowSubTitle]="toolbarShowSubTitle"
>
<!-- Content -->
<x-markdown
[isInPage]="true"
[mode]="'preview'"
[hasToolbar]="false"
[wrapWithCard]="true"
[content]="getContent('content')"
></x-markdown>
<!-- Expandable Panel -->
<x-expandable-panel
[isInPage]="true"
[isAccordion]="true"
[wrapWithCard]="true"
[selected]="'Button'"
[headerColor]="'tertiary'"
[headerHighlightColor]="'dark'"
>
<!-- Button -->
<x-panel [id]="'Button'" [hasCustomActions]="true">
<!-- Title and Description -->
<div x-panel-title>{{ resourceProvider(ResourceIDs.button) }}</div>
<br />
<!-- Description -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('buttonContent')"
></x-markdown>
<!-- Sample1 -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[cssClass]="'code-block'"
[content]="buttonSample1"
></x-markdown>
<x-button
[type]="ButtonTypes.Raised"
[color]="ColorNames.Primary"
class="ion-margin-horizontal"
(click)="handleButtonClicked()"
[title]="ResourceIDs.temp_label"
></x-button>
<!-- Sample2 -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[cssClass]="'code-block'"
[content]="buttonSample2"
></x-markdown>
<x-button
[foregroundColor]="true"
[type]="ButtonTypes.Raised"
class="ion-margin-horizontal"
[color]="ColorNames.Secondary"
(click)="handleButtonClicked()"
[title]="ResourceIDs.temp_label"
></x-button>
<!-- Sample3 -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[cssClass]="'code-block'"
[content]="buttonSample3"
></x-markdown>
<x-button
[type]="ButtonTypes.Icon"
[color]="ColorNames.Tertiary"
class="ion-margin-horizontal"
(click)="handleButtonClicked()"
>
<x-icon [name]="'list'" [color]="'light'"></x-icon>
</x-button>
<!-- Actions -->
<div x-panel-actions>
<a
target="_blank"
href="https://docs.x-framework.ir/x-framework-components/components/XButtonComponent.html"
>{{resourceProvider(ResourceIDs.documentation)}}</a
>
</div>
</x-panel>
<!-- ActionBar -->
<x-panel [id]="'ActionBar'" [hasCustomActions]="true">
<!-- Title and Description -->
<div x-panel-title>{{ resourceProvider(ResourceIDs.action_bar) }}</div>
<!-- <div x-panel-description>
{{ resourceProvider(ResourceIDs.action_bar_description) }}
</div> -->
<br />
<!-- Description -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('actionBarContent')"
></x-markdown>
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[cssClass]="'code-block'"
[content]="actionBarSample1"
></x-markdown>
<x-action-bar
[color]="ColorNames.Dark"
[actions]="actionBarItems"
(actionFired)="handleActionFired($event)"
></x-action-bar>
<!-- Actions -->
<div x-panel-actions>
<a
target="_blank"
href="https://docs.x-framework.ir/x-framework-components/components/XActionBarComponent.html"
>{{resourceProvider(ResourceIDs.documentation)}}</a
>
</div>
</x-panel>
<!-- SearchBar -->
<x-panel [id]="'SearchBar'" [hasCustomActions]="true">
<!-- Title and Description -->
<div x-panel-title>{{ resourceProvider(ResourceIDs.search_bar) }}</div>
<!-- <div x-panel-description>
{{ resourceProvider(ResourceIDs.search_bar_description) }}
</div> -->
<br />
<!-- Description -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('searchBarContent')"
></x-markdown>
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[cssClass]="'code-block'"
[content]="searchBarSample1"
></x-markdown>
<x-search-bar
value="test"
[color]="ColorNames.Dark"
[enterKeyHint]="'search'"
[searchInputColor]="'dark-tint'"
(queryChange)="handleQueryChanged($event)"
>
</x-search-bar>
<!-- Actions -->
<div x-panel-actions>
<a
target="_blank"
href="https://docs.x-framework.ir/x-framework-components/components/XSearchBarComponent.html"
>{{resourceProvider(ResourceIDs.documentation)}}</a
>
</div>
</x-panel>
<!-- Alert -->
<x-panel [id]="'Alert'" [hasCustomActions]="true">
<!-- Title and Description -->
<div x-panel-title>{{ resourceProvider(ResourceIDs.alert) }}</div>
<!-- <div x-panel-description>
{{ resourceProvider(ResourceIDs.alert_description) }}
</div> -->
<br />
<!-- Description -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('alertContent')"
></x-markdown>
<!-- Sample1 -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[cssClass]="'code-block'"
[content]="alertSample1"
></x-markdown>
<x-button
[type]="ButtonTypes.Raised"
[title]="ResourceIDs.alert"
(click)="handleShowAlert()"
[color]="ColorNames.Primary"
class="ion-margin-horizontal"
></x-button>
<!-- Sample2 -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[cssClass]="'code-block'"
[content]="alertSample2"
></x-markdown>
<x-button
[type]="ButtonTypes.Raised"
[title]="ResourceIDs.alert"
(click)="handleShowNativeAlert()"
[color]="ColorNames.Tertiary"
class="ion-margin-horizontal"
></x-button>
<br />
<br />
<!-- Propt Description -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('promptContent')"
></x-markdown>
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[cssClass]="'code-block'"
[content]="promptSample1"
></x-markdown>
<x-button
[type]="ButtonTypes.Raised"
[title]="ResourceIDs.prompt"
(click)="handleShowPrompt()"
[color]="ColorNames.Tertiary"
class="ion-margin-horizontal"
></x-button>
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[cssClass]="'code-block'"
[content]="promptSample2"
></x-markdown>
<x-button
[type]="ButtonTypes.Raised"
[title]="ResourceIDs.prompt"
(click)="handleShowNativePrompt()"
[color]="ColorNames.Primary"
class="ion-margin-horizontal"
></x-button>
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[cssClass]="'code-block'"
[content]="promptSample3"
></x-markdown>
<x-button
[type]="ButtonTypes.Raised"
[title]="ResourceIDs.prompt"
[color]="ColorNames.Primary"
class="ion-margin-horizontal"
(click)="handleShowActionModal()"
></x-button>
<br />
<br />
<!-- Modal -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('modalContent')"
></x-markdown>
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[cssClass]="'code-block'"
[content]="modalSample1"
></x-markdown>
<x-button
[type]="ButtonTypes.Raised"
[title]="ResourceIDs.alert"
[color]="ColorNames.Primary"
class="ion-margin-horizontal"
(click)="handleShowModal()"
></x-button>
<br />
<br />
<!-- PopOver -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('popOverContent')"
></x-markdown>
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[cssClass]="'code-block'"
[content]="popOverSample1"
></x-markdown>
<x-button
[type]="ButtonTypes.Raised"
[title]="ResourceIDs.alert"
[color]="ColorNames.Primary"
class="ion-margin-horizontal"
(click)="handleShowPopOver($event)"
></x-button>
<!-- Actions -->
<div x-panel-actions>
<a
target="_blank"
href="https://docs.x-framework.ir/x-framework-services/injectables/XDialogService.html#presentAlert"
>{{resourceProvider(ResourceIDs.documentation)}}</a
>
</div>
</x-panel>
<!-- Notification -->
<x-panel [id]="'Notification'" [hasCustomActions]="true">
<!-- Title and Description -->
<div x-panel-title>{{ resourceProvider(ResourceIDs.notification) }}</div>
<!-- <div x-panel-description>
{{ resourceProvider(ResourceIDs.notification_description) }}
</div> -->
<br />
<!-- Description -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('notificationContent')"
></x-markdown>
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[cssClass]="'code-block'"
[content]="notificationSample1"
></x-markdown>
<x-button
[type]="ButtonTypes.Raised"
[color]="ColorNames.Danger"
class="ion-margin-horizontal"
(click)="handleShowNotification()"
[title]="ResourceIDs.notification"
></x-button>
<!-- Actions -->
<div x-panel-actions>
<a
target="_blank"
href="https://docs.x-framework.ir/x-framework-services/injectables/XNotificationService.html"
>{{resourceProvider(ResourceIDs.documentation)}}</a
>
</div>
</x-panel>
<!-- Spinner -->
<x-panel [id]="'Spinner'" [hasCustomActions]="true">
<!-- Title and Description -->
<div x-panel-title>{{ resourceProvider(ResourceIDs.spinner) }}</div>
<!-- <div x-panel-description>
{{ resourceProvider(ResourceIDs.spinner_description) }}
</div> -->
<br />
<!-- Description -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('spinnerContent')"
></x-markdown>
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[cssClass]="'code-block'"
[content]="spinnerSample1"
></x-markdown>
<!-- Bubbles -->
<x-spinner
[color]="ColorNames.Primary"
[name]="SpinnerNames.Bubbles"
></x-spinner>
<!-- Circles -->
<x-spinner
[name]="SpinnerNames.Circles"
[color]="ColorNames.Secondary"
></x-spinner>
<!-- Tertiary -->
<x-spinner
[color]="ColorNames.Tertiary"
[name]="SpinnerNames.Circular"
></x-spinner>
<!-- Dark -->
<x-spinner
[color]="ColorNames.Dark"
[name]="SpinnerNames.Crescent"
></x-spinner>
<!-- Warning -->
<x-spinner
[color]="ColorNames.Warning"
[name]="SpinnerNames.Dots"
></x-spinner>
<!-- Danger -->
<x-spinner
[color]="ColorNames.Danger"
[name]="SpinnerNames.Lines"
></x-spinner>
<!-- Success -->
<x-spinner
[color]="ColorNames.Success"
[name]="SpinnerNames.LinesSmall"
></x-spinner>
<!-- Actions -->
<div x-panel-actions>
<a
target="_blank"
href="https://docs.x-framework.ir/x-framework-components/components/XSpinnerComponent.html"
>{{resourceProvider(ResourceIDs.documentation)}}</a
>
</div>
</x-panel>
<!-- Loading -->
<x-panel [id]="'Loading'" [hasCustomActions]="true">
<!-- Title and Description -->
<div x-panel-title>{{ resourceProvider(ResourceIDs.loading) }}</div>
<!-- <div x-panel-description>
{{ resourceProvider(ResourceIDs.loading_description) }}
</div> -->
<br />
<!-- Description -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('loadingContent')"
></x-markdown>
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[cssClass]="'code-block'"
[content]="loadingSample1"
></x-markdown>
<x-button
[type]="ButtonTypes.Raised"
class="ion-margin-horizontal"
[color]="ColorNames.Secondary"
(click)="handleShowLoading()"
[title]="ResourceIDs.loading"
></x-button>
<!-- Actions -->
<div x-panel-actions>
<a
target="_blank"
href="https://docs.x-framework.ir/x-framework-services/injectables/XDialogService.html#presentLoading"
>{{resourceProvider(ResourceIDs.documentation)}}</a
>
</div>
</x-panel>
<!-- Color -->
<x-panel [id]="'color'" [hasCustomActions]="true">
<!-- Title and Description -->
<div x-panel-title>{{ resourceProvider(ResourceIDs.color) }}</div>
<!-- <div x-panel-description>
{{ resourceProvider(ResourceIDs.color_description) }}
</div> -->
<br />
<!-- Description -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('colorContent')"
></x-markdown>
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[cssClass]="'code-block'"
[content]="colorSample1"
></x-markdown>
<!-- Component -->
<x-color [value]="{ key: 'black', value: '#000000' }"></x-color>
<!-- Actions -->
<div x-panel-actions>
<a
target="_blank"
href="https://docs.x-framework.ir/x-framework-components/components/XColorComponent.html"
>{{resourceProvider(ResourceIDs.documentation)}}</a
>
</div>
</x-panel>
<!-- Picker -->
<x-panel [id]="'Picker'" [hasCustomActions]="true">
<!-- Title and Description -->
<div x-panel-title>{{ resourceProvider(ResourceIDs.picker) }}</div>
<!-- <div x-panel-description>
{{ resourceProvider(ResourceIDs.picker_description) }}
</div> -->
<br />
<!-- Description -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('pickerContent')"
></x-markdown>
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[cssClass]="'code-block'"
[content]="pickerSample1"
></x-markdown>
<x-button
[type]="ButtonTypes.Raised"
class="ion-margin-horizontal"
[color]="ColorNames.Primary"
(click)="handleShowSelect()"
[title]="ResourceIDs.picker"
></x-button>
<!-- Actions -->
<div x-panel-actions>
<a
target="_blank"
href="https://docs.x-framework.ir/x-framework-services/injectables/XDialogService.html#presentPicker"
>{{resourceProvider(ResourceIDs.documentation)}}</a
>
</div>
</x-panel>
<!-- Slotter -->
<x-panel [id]="'Slotter'" [hasCustomActions]="true">
<!-- Title and Description -->
<div x-panel-title>{{ resourceProvider(ResourceIDs.slotter) }}</div>
<!-- <div x-panel-description>
{{ resourceProvider(ResourceIDs.slotter_description) }}
</div> -->
<br />
<!-- Description -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('slotterContent')"
></x-markdown>
<br />
<br />
<h4>{{ resourceProvider(ResourceIDs.horizontal) }}</h4>
<!-- Sample 1 -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[cssClass]="'code-block'"
[content]="slotterSample1"
></x-markdown>
<br />
<br />
<x-slotter [layout]="SlotLayout.HORIZONTAL">
<x-slot [name]="SlotNames.START" [cssClass]="'ion-text-start'">
Start
</x-slot>
<x-slot [name]="SlotNames.CENTER" [cssClass]="'ion-text-center'">
Center
</x-slot>
<x-slot [name]="SlotNames.END" [cssClass]="'ion-text-end'">
End
</x-slot>
</x-slotter>
<br />
<br />
<!-- Vertical -->
<h4>{{resourceProvider(ResourceIDs.vertical)}}</h4>
<!-- Sample 1 -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[cssClass]="'code-block'"
[content]="slotterSample2"
></x-markdown>
<br />
<br />
<x-slotter [layout]="SlotLayout.VERTICAL">
<x-slot [name]="SlotNames.TOP" [cssClass]="'ion-text-center'">
Top
</x-slot>
<x-slot [name]="SlotNames.CENTER" [cssClass]="'ion-text-center'">
Center
</x-slot>
<x-slot [name]="SlotNames.BOTTOM" [cssClass]="'ion-text-center'">
Bottom
</x-slot>
</x-slotter>
<!-- Actions -->
<div x-panel-actions>
<a
target="_blank"
href="https://docs.x-framework.ir/x-framework-components/modules/XSlotterModule.html"
>{{resourceProvider(ResourceIDs.documentation)}}</a
>
</div>
</x-panel>
<!-- Empty -->
<x-panel [id]="'Empty'" [hasCustomActions]="true">
<!-- Title and Description -->
<div x-panel-title>
{{ resourceProvider(ResourceIDs.empty_component) }}
</div>
<!-- <div x-panel-description>
{{ resourceProvider(ResourceIDs.empty_component_description) }}
</div> -->
<br />
<!-- Description -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('emptyContent')"
></x-markdown>
<!-- Sample -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="emptySample1"
[cssClass]="'code-block'"
></x-markdown>
<x-empty
[hasRefresh]="true"
[foregroundColor]="false"
[color]="ColorNames.Dark"
(refresh)="handleRefreshEmpty()"
[foregroundMessageColor]="false"
[messageColor]="ColorNames.Dark"
[refreshButtonColor]="ColorNames.Dark"
[foregroundRefreshButtonColor]="false"
></x-empty>
<!-- Actions -->
<div x-panel-actions>
<a
target="_blank"
href="https://docs.x-framework.ir/x-framework-components/components/XEmptyComponent.html"
>{{resourceProvider(ResourceIDs.documentation)}}</a
>
</div>
</x-panel>
</x-expandable-panel>
</v-page>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,70 @@
<v-page
[hasSide]="true"
[toolbarTitle]="toolbarTitle"
[toolbarSubTitle]="toolbarSubTitle"
[toolbarShowSubTitle]="toolbarShowSubTitle"
>
<!-- Content -->
<x-card [isInPage]="true" [showActions]="true" [color]="ColorNames.Light">
<!-- Content -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('content')"
></x-markdown>
<!-- Stepper Type -->
<x-form [formConfig]="stepperPresentationTypeFormConfig"></x-form>
<!-- Actions -->
<div actions>
<a
target="_blank"
href="https://docs.x-framework.ir/x-framework-components/modules/XStepperModule.html"
>{{resourceProvider(ResourceIDs.documentation)}}</a
>
</div>
</x-card>
<!-- Sample -->
<x-markdown
[isInPage]="true"
[mode]="'preview'"
[content]="sample1"
[hasToolbar]="false"
[wrapWithCard]="true"
[cssClass]="'code-block'"
[cardTitle]="resourceProvider(ResourceIDs.sample)"
></x-markdown>
<!-- Stepper -->
<x-stepper
class="v-card"
[isInPage]="true"
[showLabel]="true"
[wrapWithCard]="true"
[cardTitle]="'Stepper'"
[type]="currentStepperType"
[iconColor]="ColorNames.Dark"
[titleColor]="ColorNames.DangerShade"
(onReset)="handleResetStepper($event)"
>
<!-- Step 1 -->
<x-step [hasNext]="true" [disableNext]="xFormStepOne.status !== 'VALID'">
<div x-step-label>Step ONe</div>
<x-form #xFormStepOne [formConfig]="stepOneModelConfig"></x-form>
</x-step>
<!-- Step 2 -->
<x-step
[hasPrev]="true"
[hasReset]="true"
[disableReset]="xFormStepTwo.status !== 'VALID'"
>
<div x-step-label>Step TWo</div>
<x-form #xFormStepTwo [formConfig]="stepTwoModelConfig"></x-form>
</x-step>
</x-stepper>
</v-page>
@@ -0,0 +1,322 @@
import {
XIconNames,
XFormConfig,
XStepperType,
XFormComponent,
XFormControlType,
XStepperTypeIdentifier,
XFormSelectControlOption,
XFormStatusChangeEventModel,
} from 'x-framework-components';
import { Component } from '@angular/core';
import { Validators } from '@angular/forms';
import { XResourceIDs, isNullOrEmptyString } from 'x-framework-core';
import { VPageComponent } from '../../../views/v-page/v-page.component';
import { AppResourceIDs } from 'src/app/config/app.localization.config';
interface StepOne {
id: number;
name: string;
family: string;
}
interface StepTwo {
id: number;
userName: string;
password: string;
}
interface StepperPresentationType {
type: XStepperTypeIdentifier;
}
@Component({
selector: 'app-stepper',
templateUrl: './stepper.page.html',
styleUrls: ['./stepper.page.scss'],
})
// tslint:disable-next-line:component-class-suffix
export class StepperPage extends VPageComponent {
//
//#region Props ...
//
//#region Page Props ...
titleRes = AppResourceIDs.stepper;
toolbarTitle = this.resourceProvider(this.titleRes);
toolbarSubTitle = this.resourceProvider(AppResourceIDs.stepper_description);
toolbarShowSubTitle = true;
//#endregion
//
// Prepare All Resource IDs ...
readonly ResourceIDs = Object.assign(
Object.assign({}, XResourceIDs),
AppResourceIDs
) as any;
//
readonly IconNames = Object.assign({}, XIconNames);
//#endregion
//
// Content ...
readonly contentFa = `
# ${this.toolbarTitle}
از این مولفه جهت دریافت یا نمایش اطلاعات در گام های مختلف از کاربر استفاده می گردد.
`;
readonly contentEn = `
# ${this.toolbarTitle}
this component used to get or show data to user in several steps.
`;
//
readonly sample1 =
'```html' +
`
<!-- Stepper -->
<x-stepper
isInPage="true"
showLabel="true"
wrapWithCard="true"
[type]="currentStepperType"
>
<!-- Step 1 -->
<x-step [hasNext]="true" [disableNext]="xFormStepOne.status !== 'VALID'">
<div x-step-label>
Step ONe
</div>
<x-form #xFormStepOne [formConfig]="stepOneModelConfig"></x-form>
</x-step>
<!-- Step 2 -->
<x-step
[hasPrev]="true"
[hasReset]="true"
[disableReset]="xFormStepTwo.status !== 'VALID'"
>
<div x-step-label>
Step TWo
</div>
<x-form #xFormStepTwo [formConfig]="stepTwoModelConfig"></x-form>
</x-step>
</x-stepper>
` +
'```';
//
currentStepperType: XStepperTypeIdentifier;
stepperPresentationTypes = [
`${XStepperType.VERTICAL}`,
`${XStepperType.HORIZONTAL}`,
];
stepperPresentationTypeFormConfig: XFormConfig<StepperPresentationType> = {
name: 'Steper_Present_Type',
model: {
type: XStepperType.HORIZONTAL,
},
controls: [
//
// Id ...
{
index: 0,
propName: 'type',
type: {
type: XFormControlType.Select,
config: {
multiple: false,
options: this.stepperPresentationTypes.map((k) => {
return {
value: k,
viewValue: this.resourceProvider(k),
} as XFormSelectControlOption<XStepperTypeIdentifier>;
}),
},
},
appearance: {
label: this.ResourceIDs.type,
},
eventHandlers: {
valueChanged: (model) => {
//
if (!model || !model.value) {
return;
}
//
const type = model.value as XStepperTypeIdentifier;
if (!type) {
return;
}
//
this.currentStepperType = type;
this.detectChanges();
},
},
},
],
};
//
stepOneModelConfig: XFormConfig<StepOne> = {
name: 'StepOneForm',
controls: [
//
// Id ...
{
index: 0,
propName: 'id',
type: {
type: XFormControlType.Number,
},
appearance: {
label: this.ResourceIDs.id,
},
validators: {
validators: [Validators.required],
},
},
//
// Name ...
{
index: 1,
propName: 'name',
type: {
type: XFormControlType.Text,
},
appearance: {
label: this.ResourceIDs.first_name,
},
validators: {
validators: [Validators.required],
},
},
//
// Family ...
{
index: 2,
propName: 'family',
type: {
type: XFormControlType.Text,
},
appearance: {
label: this.ResourceIDs.last_name,
},
validators: {
validators: [Validators.required],
},
},
],
};
//
stepTwoModelConfig: XFormConfig<StepTwo> = {
name: 'StepTwoForm',
controls: [
//
// Id ...
{
index: 0,
propName: 'id',
type: {
type: XFormControlType.Number,
},
appearance: {
label: this.ResourceIDs.id,
},
validators: {
validators: [Validators.required],
},
},
//
// Username ...
{
index: 1,
propName: 'userName',
type: {
type: XFormControlType.Text,
},
appearance: {
label: this.ResourceIDs.username,
},
validators: {
validators: [Validators.required],
},
},
//
// Password ...
{
index: 2,
propName: 'password',
type: {
type: XFormControlType.Password,
},
appearance: {
label: this.ResourceIDs.password,
},
validators: {
validators: [Validators.required],
},
},
],
};
//
//#region UI Providers ...
//
// Provide content based on current locale ...
getContent(title: string) {
//
if (isNullOrEmptyString(title)) {
return '';
}
//
const currentLocale = this.managerService.currentLocale;
//
const varName =
title +
(currentLocale === 'en-US'
? 'En'
: currentLocale === 'fa-IR'
? 'Fa'
: '');
const result = this[`${varName}`];
//
return result || '';
}
handleFormOneStatusChanged(
event: XFormStatusChangeEventModel,
form: XFormComponent
) {
console.log('status changed: ', event, form.isStatusValid);
}
handleResetStepper(id: string) {
//
console.log('stepper resetted at: ', id);
//
this.stepOneModelConfig = {
...this.stepOneModelConfig,
model: null,
};
//
this.stepTwoModelConfig = {
...this.stepTwoModelConfig,
model: null,
};
//
this.detectChanges();
}
//#endregion
}
@@ -0,0 +1,38 @@
<v-page
[hasSide]="true"
[toolbarTitle]="toolbarTitle"
[toolbarSubTitle]="toolbarSubTitle"
[toolbarShowSubTitle]="toolbarShowSubTitle"
>
<!-- Content -->
<x-card [isInPage]="true" [showActions]="true" [color]="ColorNames.Light">
<!-- Content -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('content')"
></x-markdown>
<!-- Sample -->
<x-markdown
[mode]="'preview'"
[content]="sample1"
[hasToolbar]="false"
[cssClass]="'code-block'"
></x-markdown>
<!-- Link to ... -->
<a [href]="tabsHref" target="_blank"
>{{ resourceProvider(ResourceIDs.preview) }}</a
>
<!-- Actions -->
<div actions>
<a
target="_blank"
href="https://docs.x-framework.ir/x-framework-components/components/XTabNavigatorComponent.html"
>{{resourceProvider(ResourceIDs.documentation)}}</a
>
</div>
</x-card>
</v-page>
@@ -0,0 +1,95 @@
import { Component } from '@angular/core';
import { Pages } from 'src/app/config/page.config';
import { XIconNames } from 'x-framework-components';
import { VPageComponent } from '../../../views/v-page/v-page.component';
import { AppResourceIDs } from 'src/app/config/app.localization.config';
import { XColor, XResourceIDs, isNullOrEmptyString } from 'x-framework-core';
@Component({
selector: 'app-tab-navigator',
templateUrl: './tab-navigator.page.html',
styleUrls: ['./tab-navigator.page.scss'],
})
// tslint:disable-next-line:component-class-suffix
export class TabNavigatorPage extends VPageComponent {
//
//#region Props ...
//
//#region Page Props ...
titleRes = AppResourceIDs.tab_navigator;
toolbarTitle = this.resourceProvider(this.titleRes);
toolbarSubTitle = this.resourceProvider(
AppResourceIDs.tab_navigator_description
);
toolbarShowSubTitle = true;
//#endregion
//
// Prepare All Resource IDs ...
readonly ResourceIDs = Object.assign(
Object.assign({}, XResourceIDs),
AppResourceIDs
) as any;
//
readonly IconNames = Object.assign({}, XIconNames);
//#endregion
//
// Content ...
readonly contentFa = `
# ${this.toolbarTitle}
این مولفه زمانی کاربرد دارد که قصد داریم صفحاتی را در غالب نمایه ای مبتنی بر برگه ها دسته بندی کرده و نمایش دهیم.
`;
readonly contentEn = `
# ${this.toolbarTitle}
this component used to group Pages in a Tabbed template and show them.
`;
//
readonly sample1 =
'```html' +
`
<x-tab-navigator
[items]="tabItems"
[color]="ColorNames.Dark"
[iconColor]="ColorNames.Danger"
[highlightColor]="ColorNames.Light"
[selectedColor]="ColorNames.SecondaryShade"
></x-tab-navigator>
` +
'```';
//
tabsHref = Pages.TabsNav.baseRoute;
//
//#region UI Providers ...
//
// Provide content based on current locale ...
getContent(title: string) {
//
if (isNullOrEmptyString(title)) {
return '';
}
//
const currentLocale = this.managerService.currentLocale;
//
const varName =
title +
(currentLocale === 'en-US'
? 'En'
: currentLocale === 'fa-IR'
? 'Fa'
: '');
const result = this[`${varName}`];
//
return result || '';
}
//#endregion
}
@@ -0,0 +1,67 @@
<v-page
[hasSide]="true"
[toolbarTitle]="toolbarTitle"
[toolbarSubTitle]="toolbarSubTitle"
[toolbarShowSubTitle]="toolbarShowSubTitle"
>
<!-- Content -->
<x-card [isInPage]="true" [showActions]="true" [color]="ColorNames.Light">
<!-- Content -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('content')"
></x-markdown>
<!-- Actions -->
<div actions>
<a
target="_blank"
href="https://docs.x-framework.ir/x-framework-components/components/XTableComponent.html"
>{{resourceProvider(ResourceIDs.documentation)}}</a
>
</div>
</x-card>
<!-- Samples -->
<x-markdown
[isInPage]="true"
[mode]="'preview'"
[content]="sample1"
[hasToolbar]="false"
[wrapWithCard]="true"
[cssClass]="'code-block'"
></x-markdown>
<x-markdown
[isInPage]="true"
[mode]="'preview'"
[content]="sample2"
[hasToolbar]="false"
[wrapWithCard]="true"
[cssClass]="'code-block'"
></x-markdown>
<x-table
[isInPage]="true"
[showHeader]="true"
[wrapWithCard]="true"
[showSearchBar]="true"
[showPaginator]="true"
[showActionBar]="true"
[selectableRows]="true"
[color]="ColorNames.Medium"
[properties]="tempTableProps"
[headerColor]="ColorNames.Dark"
[actionBarColor]="ColorNames.DarkShade"
[searchBarColor]="ColorNames.DarkShade"
[paginatorColor]="ColorNames.DarkShade"
(removeItems)="handleRemoveItems($event)"
(rowSelected)="handleRowSelected($event)"
[searchBarPosition]="TableItemPositions.TOP"
[actionBarPosition]="TableItemPositions.TOP"
[paginatorPosition]="TableItemPositions.BOTTOM"
(rowSelectionChanged)="handleRowSelectionChanged($event)"
>
</x-table>
</v-page>
@@ -0,0 +1,805 @@
import {
XResourceIDs,
isNullOrEmptyString,
XColorWithBrightness,
} from 'x-framework-core';
import {
XIconNames,
XTableConfig,
XTableItemPosition,
} from 'x-framework-components';
import { Component } from '@angular/core';
import { VPageComponent } from '../../../views/v-page/v-page.component';
import { AppResourceIDs } from 'src/app/config/app.localization.config';
interface Temp {
id?: string;
name: string;
family: string;
phoneNumber: string;
value: string;
slided: boolean;
checked: boolean;
level: number;
person: string;
dob: Date;
}
@Component({
selector: 'app-table',
templateUrl: './table.page.html',
styleUrls: ['./table.page.scss'],
})
// tslint:disable-next-line:component-class-suffix
export class TablePage extends VPageComponent {
//
//#region Props ...
//
//#region Page Props ...
titleRes = AppResourceIDs.table;
toolbarTitle = this.resourceProvider(this.titleRes);
toolbarSubTitle = this.resourceProvider(AppResourceIDs.table_description);
toolbarShowSubTitle = true;
//#endregion
//
// Prepare All Resource IDs ...
readonly ResourceIDs = Object.assign(
Object.assign({}, XResourceIDs),
AppResourceIDs
) as any;
//
readonly IconNames = Object.assign({}, XIconNames);
readonly ColorNames = Object.assign({}, XColorWithBrightness);
//#endregion
//
//#region Data Preparation For Table ...
//
readonly TableItemPositions = Object.assign({}, XTableItemPosition);
//
tempItems: Partial<Temp>[] = [
{
id: '71f14439-262f-44bf-8dc8-ee85929c349c',
name: 'Deidre',
family: 'Thomas',
phoneNumber: '+98 (864) 472-3812',
},
{
id: 'caa22853-dd2d-4669-8b63-b1fe4a38ea07',
name: 'Hubbard',
family: 'Preston',
phoneNumber: '+98 (899) 452-3720',
},
{
id: 'ccb62dc4-a06b-412d-800d-02d18f54a0e0',
name: 'Cooley',
family: 'Nixon',
phoneNumber: '+98 (926) 459-2360',
},
{
id: '6a946279-fe01-4e17-bb2c-a1931780ce9d',
name: 'Becky',
family: 'Wallace',
phoneNumber: '+98 (914) 519-3589',
},
{
id: '8601242a-f2ff-465f-8275-5b991b4a8ade',
name: 'Kidd',
family: 'Shelton',
phoneNumber: '+98 (848) 570-3661',
},
{
id: '1f4bd5e8-d7be-460d-9bfb-f0738957bc4b',
name: 'Caitlin',
family: 'Camacho',
phoneNumber: '+98 (959) 453-2722',
},
{
id: '18a874dc-1f3d-4cdc-a3c7-69d2f417e18e',
name: 'Estes',
family: 'Rivera',
phoneNumber: '+98 (917) 436-3237',
},
{
id: '5a5f2a8e-d20e-4fe9-ae6f-84dde7602e9f',
name: 'Ines',
family: 'Powell',
phoneNumber: '+98 (917) 539-3108',
},
{
id: '663c8403-e525-4b51-b262-e876e97d4532',
name: 'Carrillo',
family: 'Acevedo',
phoneNumber: '+98 (828) 556-3742',
},
{
id: '7e6d0bb6-4180-4329-96cc-364a9a534a04',
name: 'Ina',
family: 'Wilkinson',
phoneNumber: '+98 (933) 560-3834',
},
{
id: '19c21deb-f8b7-40c7-a0bb-da203193c114',
name: 'Mercer',
family: 'Adkins',
phoneNumber: '+98 (981) 480-3459',
},
{
id: 'c2e4de31-d406-4611-9dbe-cd7bdefdc5bc',
name: 'Donaldson',
family: 'Vega',
phoneNumber: '+98 (986) 554-2571',
},
{
id: 'cf846f56-b381-447b-96a1-0d7c29736f4f',
name: 'Natalie',
family: 'Cantu',
phoneNumber: '+98 (857) 445-2595',
},
{
id: 'c5252e01-8a26-44f1-846d-28c8810b10b8',
name: 'Christa',
family: 'Higgins',
phoneNumber: '+98 (983) 498-3785',
},
{
id: 'e7e5b97a-67f8-4bff-8c8c-b68cf6a24b2f',
name: 'Kelley',
family: 'Pitts',
phoneNumber: '+98 (948) 588-3437',
},
{
id: '9db9d0ab-a2c4-4edb-8d0b-e664c86c4e55',
name: 'Shelby',
family: 'Macdonald',
phoneNumber: '+98 (882) 401-2642',
},
{
id: '41305b10-aa7a-415d-a819-5e6ab05e0a49',
name: 'Preston',
family: 'Patton',
phoneNumber: '+98 (923) 509-3278',
},
{
id: '35acdcfe-7015-4a27-a5de-0f5c701a9152',
name: 'Allen',
family: 'Flores',
phoneNumber: '+98 (957) 587-3471',
},
{
id: '31f568b8-272a-43c5-bb7a-bf25c2fa6da9',
name: 'Margaret',
family: 'Neal',
phoneNumber: '+98 (870) 480-3528',
},
{
id: '5ef4be35-3d02-45f7-9c25-bf828b4a3845',
name: 'Kirkland',
family: 'Hewitt',
phoneNumber: '+98 (958) 466-2957',
},
{
id: 'e581d671-5d35-4c21-af77-71f881f8d764',
name: 'Herminia',
family: 'Silva',
phoneNumber: '+98 (925) 546-3981',
},
{
id: '4242bc21-945e-4cbe-b73c-bacc0c8b2013',
name: 'Galloway',
family: 'Tyler',
phoneNumber: '+98 (971) 468-2144',
},
{
id: '58f91369-8718-4c01-aff8-8a5d65527948',
name: 'Hull',
family: 'Rojas',
phoneNumber: '+98 (950) 439-3702',
},
{
id: 'e6d25e18-f272-4ac3-b7f6-54c8bae985b5',
name: 'Sandoval',
family: 'Norton',
phoneNumber: '+98 (920) 439-2511',
},
{
id: 'bff9bdad-2947-4fd9-a18a-92388e32aa0b',
name: 'Alba',
family: 'Collins',
phoneNumber: '+98 (957) 445-2714',
},
{
id: '8272763a-6a67-41da-924e-0f417fb259da',
name: 'Montoya',
family: 'Stein',
phoneNumber: '+98 (889) 585-3578',
},
{
id: '29a6ff2c-746e-4214-b28f-073ac201ea96',
name: 'Grant',
family: 'Gilliam',
phoneNumber: '+98 (814) 562-3575',
},
{
id: '416cb3f4-30ae-4874-a7c3-ffd401cf6c3f',
name: 'Meadows',
family: 'Mcknight',
phoneNumber: '+98 (994) 589-2830',
},
{
id: 'd061721e-ca9c-4054-9aa1-1196a51a0256',
name: 'Harris',
family: 'Rhodes',
phoneNumber: '+98 (853) 489-2436',
},
{
id: 'd01323d5-5126-4c8a-ad89-0298acf4d82d',
name: 'Frieda',
family: 'Hayden',
phoneNumber: '+98 (930) 436-2770',
},
{
id: '34225f99-0986-4294-95f2-3c8961b15036',
name: 'Rasmussen',
family: 'Ross',
phoneNumber: '+98 (821) 599-2812',
},
{
id: '6f7a24d4-8b82-45c4-8b5b-a3053c5a7023',
name: 'Mitzi',
family: 'Gregory',
phoneNumber: '+98 (838) 404-3840',
},
{
id: 'acba244a-12b5-4291-beb2-66a64127121d',
name: 'Washington',
family: 'Cruz',
phoneNumber: '+98 (975) 465-2025',
},
{
id: '2c70c776-80dd-4be9-b32f-6af7d6cea5b0',
name: 'Jewell',
family: 'Rios',
phoneNumber: '+98 (909) 453-3851',
},
{
id: '5f98d7a6-c98b-4dc7-bf90-4df04074b57e',
name: 'Heath',
family: 'Bush',
phoneNumber: '+98 (976) 516-3200',
},
{
id: 'bc51bdc5-47f6-45b4-8c51-6d86324b90d2',
name: 'Laura',
family: 'Edwards',
phoneNumber: '+98 (966) 546-3720',
},
{
id: 'f1f47337-cc3f-49e4-acb7-5989f5eb1a30',
name: 'Harriett',
family: 'Sanders',
phoneNumber: '+98 (816) 579-3042',
},
{
id: '2fce8cd5-398c-4d73-8151-3d0fb375ff49',
name: 'Milagros',
family: 'Vazquez',
phoneNumber: '+98 (941) 437-2907',
},
{
id: 'b725ce24-b08d-4c8e-95ec-5926804ccde3',
name: 'Sheila',
family: 'Aguilar',
phoneNumber: '+98 (855) 509-3995',
},
{
id: 'f7d64d31-43d2-416f-ba19-397b407afeba',
name: 'Eunice',
family: 'Langley',
phoneNumber: '+98 (959) 564-2615',
},
{
id: '6f73fd66-2931-4f1f-9cd1-95803724ff38',
name: 'Valerie',
family: 'House',
phoneNumber: '+98 (985) 550-3203',
},
{
id: '17fab0f9-f37d-4ed0-8656-98b9f9c65333',
name: 'Carmella',
family: 'Young',
phoneNumber: '+98 (964) 548-3625',
},
{
id: '7e9e3057-34df-4727-8a7e-750e876a7ca8',
name: 'Brittany',
family: 'Pennington',
phoneNumber: '+98 (840) 499-3543',
},
{
id: '4ca1aebb-8d6f-4c62-9633-353abf1cab06',
name: 'Polly',
family: 'Roberts',
phoneNumber: '+98 (821) 554-2791',
},
{
id: '147c9f63-800a-4600-94dd-7fa39e233cd7',
name: 'Estrada',
family: 'Tate',
phoneNumber: '+98 (844) 586-3191',
},
{
id: 'decca57e-7d69-4152-99f0-3a56262db788',
name: 'Aimee',
family: 'Morrow',
phoneNumber: '+98 (920) 522-2471',
},
{
id: '1b7d57b2-0169-4949-a1e9-42137085dcda',
name: 'Elinor',
family: 'Gill',
phoneNumber: '+98 (981) 525-3212',
},
{
id: 'db3e2d62-d8cf-4809-9226-49a34a4fbea1',
name: 'Velasquez',
family: 'Taylor',
phoneNumber: '+98 (879) 440-2756',
},
{
id: 'a3f6bda0-0975-4e4e-8bcd-1a9be84777ac',
name: 'Hardin',
family: 'Rowe',
phoneNumber: '+98 (945) 564-3793',
},
{
id: '17c0c061-3215-429d-9172-be3d8ca69119',
name: 'Miranda',
family: 'Hendrix',
phoneNumber: '+98 (804) 519-2572',
},
{
id: '634862e6-09bf-41c3-8553-c8807aab2b22',
name: 'Kristin',
family: 'Mcgowan',
phoneNumber: '+98 (974) 533-3607',
},
{
id: '4214933e-a57c-495c-8c32-ddb9960556f6',
name: 'Ila',
family: 'Gutierrez',
phoneNumber: '+98 (814) 546-2444',
},
{
id: '74f62419-a4eb-414f-9a84-d82dfd117917',
name: 'Sophie',
family: 'Pena',
phoneNumber: '+98 (962) 458-3451',
},
{
id: 'c3cc6ff3-d0ef-45fb-b6a7-b499ff13fedf',
name: 'Sara',
family: 'Burton',
phoneNumber: '+98 (937) 516-2702',
},
{
id: '969ca3e7-78ad-4fbe-b413-0e12021d07b9',
name: 'Valeria',
family: 'Spence',
phoneNumber: '+98 (968) 403-2227',
},
{
id: 'e73ba5bb-adb7-423e-a6e9-22be1501987c',
name: 'Stefanie',
family: 'Erickson',
phoneNumber: '+98 (950) 545-2095',
},
{
id: '83ae1198-c533-43dd-ae1a-85bc5f503293',
name: 'Bean',
family: 'Newman',
phoneNumber: '+98 (824) 504-2755',
},
{
id: 'a2f3949a-7d24-4c42-ac6d-573c11c903fd',
name: 'Tracie',
family: 'Keith',
phoneNumber: '+98 (981) 499-3453',
},
{
id: '7f52c00e-4ccb-4458-ad0c-bb7d9ff759a4',
name: 'Cardenas',
family: 'Trevino',
phoneNumber: '+98 (942) 476-2939',
},
{
id: '48f9d38e-9211-420f-968e-098f7a3dfeaf',
name: 'Yolanda',
family: 'Hamilton',
phoneNumber: '+98 (936) 418-3047',
},
{
id: '0f739ca9-1a2a-41f1-b703-9ddc98e7b328',
name: 'Mendoza',
family: 'Cunningham',
phoneNumber: '+98 (980) 547-3912',
},
{
id: '3e3e68cc-053a-4811-9987-7c700fcc32ee',
name: 'Singleton',
family: 'Harmon',
phoneNumber: '+98 (975) 564-3890',
},
{
id: 'd7d6e72b-5a63-440d-bdf0-125bd9d8d4dd',
name: 'Witt',
family: 'Huffman',
phoneNumber: '+98 (867) 475-3332',
},
{
id: '46c951e3-ab31-44ca-b5eb-2f988dd57562',
name: 'James',
family: 'Mccullough',
phoneNumber: '+98 (895) 507-2233',
},
{
id: '9b7b2396-5758-44be-9d5d-4eef04742a53',
name: 'Stevenson',
family: 'Robles',
phoneNumber: '+98 (847) 587-3623',
},
{
id: 'a0db4093-ec6b-41ed-8ca5-a9b43ee302b7',
name: 'Mcknight',
family: 'Perry',
phoneNumber: '+98 (881) 443-2991',
},
{
id: '1ad02420-9ac0-4250-940c-fc0ea24964a8',
name: 'Flowers',
family: 'Emerson',
phoneNumber: '+98 (933) 514-3019',
},
{
id: 'b2ffa8f4-4f95-4b9d-a219-780d5f4dbd69',
name: 'Karin',
family: 'James',
phoneNumber: '+98 (958) 486-2623',
},
{
id: 'd87e51b3-80db-4e7c-b0d0-9f39c633b70a',
name: 'Marisol',
family: 'William',
phoneNumber: '+98 (961) 533-3778',
},
{
id: '1ce985cc-f810-4972-8e9b-59dfb67b161c',
name: 'Emilia',
family: 'Black',
phoneNumber: '+98 (984) 592-2589',
},
{
id: '4b5be713-cb7e-46cb-b72b-e8c4f644693a',
name: 'Irene',
family: 'Miles',
phoneNumber: '+98 (950) 431-2351',
},
{
id: 'c1ff3dfd-21b4-4824-aeef-d3b6a36ba3ab',
name: 'Tonia',
family: 'Serrano',
phoneNumber: '+98 (955) 511-2933',
},
{
id: '97eec6ce-ccb0-4050-b413-96a0a4afce7a',
name: 'Thelma',
family: 'Odom',
phoneNumber: '+98 (844) 524-2142',
},
{
id: 'e9111905-fc22-4e35-a3a6-4a4c0b6bc0c0',
name: 'Kerry',
family: 'Rose',
phoneNumber: '+98 (947) 581-2952',
},
{
id: '9129d569-5acd-43b7-8eac-de7a9f4f7336',
name: 'Mcgee',
family: 'Hernandez',
phoneNumber: '+98 (865) 521-3785',
},
{
id: '221e68ec-0462-4418-88c9-d433f1d60ae1',
name: 'Shepard',
family: 'Santiago',
phoneNumber: '+98 (892) 446-3690',
},
{
id: '429b8bcc-028d-4989-89d9-5519dc6fec0f',
name: 'Emily',
family: 'French',
phoneNumber: '+98 (836) 537-3964',
},
{
id: 'c750ebd9-9aa0-426f-b668-5702500f7178',
name: 'Clements',
family: 'Carson',
phoneNumber: '+98 (916) 460-3168',
},
{
id: '2f75f87c-65f9-479b-bec4-5c83fbbfb96a',
name: 'Gibbs',
family: 'Burch',
phoneNumber: '+98 (950) 543-2339',
},
{
id: '6dbf72ff-5761-4c0b-9781-93cd4606fd4b',
name: 'Pearson',
family: 'Petersen',
phoneNumber: '+98 (889) 591-2938',
},
{
id: '8944a741-1f18-4d30-8536-a306ab1b5b8f',
name: 'Stout',
family: 'Castillo',
phoneNumber: '+98 (938) 578-3360',
},
{
id: 'aca707ac-97fe-4f7f-8665-ab34d863bc3a',
name: 'Leonard',
family: 'Finch',
phoneNumber: '+98 (821) 441-3242',
},
{
id: '43cc621c-17fb-4196-a28e-658f1fc4752e',
name: 'Nelson',
family: 'Kirkland',
phoneNumber: '+98 (869) 431-2288',
},
{
id: '63292aab-ddc3-4dd8-851a-6430c85f3ad3',
name: 'Olson',
family: 'Sherman',
phoneNumber: '+98 (865) 446-3664',
},
{
id: '40f28107-6a4d-4c1c-a506-a8dc4d65c6e4',
name: 'Bray',
family: 'Hansen',
phoneNumber: '+98 (808) 532-3820',
},
{
id: '02ab1c0b-654f-4277-92dd-1a0219bda442',
name: 'Antonia',
family: 'Bell',
phoneNumber: '+98 (802) 572-3045',
},
{
id: '15019624-9683-4977-a2d8-dc47e434f086',
name: 'Cecile',
family: 'Maxwell',
phoneNumber: '+98 (804) 452-2908',
},
];
//
tempTableProps: XTableConfig<Partial<Temp>> = {
items: [...this.tempItems],
columns: [
{
name: 'name',
title: 'Name',
sortable: true,
description: 'Name of Person',
},
{
name: 'family',
title: 'Family',
sortable: true,
description: 'LastName of Person',
// hidden: this.managerService.isMobileUi$
},
{
name: 'phoneNumber',
title: 'Phone Number',
description: 'Phone Number of Person',
// hidden: this.managerService.isMobileUi$
},
{
customColumn: true,
name: 'Actions',
title: 'Actions',
description: 'row Action',
},
],
};
//#endregion
//
// Content ...
readonly contentFa = `
# ${this.toolbarTitle}
این مولفه جهت نمایش داده های مرتبط بصورت جدول بکار می رود.
`;
readonly contentEn = `
# ${this.toolbarTitle}
this Component used to show a collection of related Data in a Table.
`;
//
readonly sample1 =
'```typescript' +
`
//
interface Temp {
id?: string;
name: string;
family: string;
phoneNumber: string;
value: string;
slided: boolean;
checked: boolean;
level: number;
person: string;
dob: Date;
}
//
tempTableProps: XTableProps<Partial<Temp>> = {
items: [
{
id: '
71f14439-262f-44bf-8dc8-ee85929c349c',
name: 'Deidre',
family: 'Thomas',
phoneNumber: '+98 (864) 472-3812'
},
{
id: '
caa22853-dd2d-4669-8b63-b1fe4a38ea07',
name: 'Hubbard',
family: 'Preston',
phoneNumber: '+98 (899) 452-3720'
},
{
id: '
ccb62dc4-a06b-412d-800d-02d18f54a0e0',
name: 'Cooley',
family: 'Nixon',
phoneNumber: '+98 (926) 459-2360'
},
{
...
},
...
],
columns: [
{
name: 'name',
title: 'Name',
sortable: true,
description: 'Name of Person'
},
{
name: 'family',
title: 'Family',
sortable: true,
description: 'LastName of Person'
},
{
name: 'phoneNumber',
title: 'Phone Number',
description: 'Phone Number of Person'
},
{
customColumn: true,
name: 'Actions',
title: 'Actions',
description: 'row Action'
}
]
};
` +
'```';
//
readonly sample2 =
'```html' +
`
<x-table
[showHeader]="true"
[showSearchBar]="true"
[showPaginator]="true"
[showActionBar]="true"
[selectableRows]="true"
[color]="ColorNames.Medium"
[properties]="tempTableProps"
[headerColor]="ColorNames.Dark"
[actionBarColor]="ColorNames.Primary"
[searchBarColor]="ColorNames.Primary"
[paginatorColor]="ColorNames.Primary"
(rowSelected)="handleRowSelected($event)"
[searchBarPosition]="
TableItemPositions.TOP"
[actionBarPosition]="
TableItemPositions.TOP"
[paginatorPosition]="
TableItemPositions.BOTTOM"
(rowSelectionChanged)="
handleRowSelectionChanged($event)"
>
</x-table>
` +
'```';
//
//#region UI Providers ...
//
// Provide content based on current locale ...
getContent(title: string) {
//
if (isNullOrEmptyString(title)) {
return '';
}
//
const currentLocale = this.managerService.currentLocale;
//
const varName =
title +
(currentLocale === 'en-US'
? 'En'
: currentLocale === 'fa-IR'
? 'Fa'
: '');
const result = this[`${varName}`];
//
return result || '';
}
//
handleRowSelected(row: any) {
console.log('handleRowSelected: ', row);
}
//
handleRowSelectionChanged(selectedRows: any[]) {
console.log('handleRowSelectionChanged: ', selectedRows);
}
//
async handleRemoveItems(items: Partial<Temp>[]) {
//
console.log('Remove Items: ', items);
if (!this.hasChild(items)) {
return;
}
//
const removedItems = this.tempItems.filter((i) => !items.includes(i));
console.log('num of items before remove: ', this.tempItems.length);
console.log('num of items after remove: ', removedItems.length);
//
const newTableProps = {
...this.tempTableProps,
items: [...removedItems],
};
//
this.tempTableProps = {
...newTableProps,
};
//
this.detectChanges();
}
//#endregion
}
@@ -0,0 +1,104 @@
<v-page
[hasSide]="true"
[toolbarTitle]="toolbarTitle"
[toolbarSubTitle]="toolbarSubTitle"
[toolbarShowSubTitle]="toolbarShowSubTitle"
>
<!-- Content -->
<x-card [isInPage]="true" [showActions]="true" [color]="ColorNames.Light">
<!-- Content -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('content')"
></x-markdown>
<!-- Actions -->
<div actions>
<a
target="_blank"
href="https://docs.x-framework.ir/x-framework-components/modules/XTabsModule.html"
>{{resourceProvider(ResourceIDs.documentation)}}</a
>
</div>
</x-card>
<!-- Samples -->
<x-markdown
[isInPage]="true"
[mode]="'preview'"
[content]="sample1"
[hasToolbar]="false"
[wrapWithCard]="true"
[cssClass]="'code-block'"
[cardTitle]="resourceProvider(ResourceIDs.sample)"
></x-markdown>
<!-- Components -->
<x-tabs
#xTabs
[isInPage]="true"
[swipable]="true"
[loopTabs]="false"
[selectedIndex]="1"
[wrapWithCard]="true"
[dynamicHeight]="false"
[color]="ColorNames.Dark"
[alignTabs]="TabAligns.STRETCH"
[activeTabColor]="ColorNames.Medium"
[tabPaginatorColor]="ColorNames.Dark"
[tabIndicatorColor]="ColorNames.Warning"
[headerPosition]="TabsHeaderPositions.BELOW"
>
<x-tab>
<div x-tab-label>
Tab 1
</div>
<div class="tab-wrapper" [xColor]="ColorNames.Danger">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Omnis similique
reiciendis vero vel. Et, in nemo. Sapiente doloremque provident ex
dolore, expedita totam ipsam architecto vero mollitia magni. Corporis,
dolore.
</div>
</x-tab>
<x-tab>
<div x-tab-label>
Tab 2
</div>
<div class="tab-wrapper" [xColor]="ColorNames.Secondary">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Omnis similique
reiciendis vero vel. Et, in nemo. Sapiente doloremque provident ex
dolore, expedita totam ipsam architecto vero mollitia magni. Corporis,
dolore.
</div>
</x-tab>
<x-tab>
<div x-tab-label>
Tab 3
</div>
<div class="tab-wrapper" [xColor]="ColorNames.Warning">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Omnis similique
reiciendis vero vel. Et, in nemo. Sapiente doloremque provident ex
dolore, expedita totam ipsam architecto vero mollitia magni. Corporis,
dolore.
</div>
</x-tab>
<x-tab>
<div x-tab-label>
Tab 4
</div>
<div class="tab-wrapper" [xColor]="color">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Omnis similique
reiciendis vero vel. Et, in nemo. Sapiente doloremque provident ex
dolore, expedita totam ipsam architecto vero mollitia magni. Corporis,
dolore.
</div>
</x-tab>
</x-tabs>
</v-page>
@@ -0,0 +1,8 @@
.tab-wrapper {
padding: {
top: 24px;
left: 6px;
right: 6px;
bottom: 24px;
};
}
+176
View File
@@ -0,0 +1,176 @@
import {
XTabAlign,
XIconNames,
XTabsHeaderPosition,
} from 'x-framework-components';
import { Component } from '@angular/core';
import { VPageComponent } from '../../../views/v-page/v-page.component';
import { AppResourceIDs } from 'src/app/config/app.localization.config';
import { XResourceIDs, isNullOrEmptyString, XColor } from 'x-framework-core';
@Component({
selector: 'app-tabs',
templateUrl: './tabs.page.html',
styleUrls: ['./tabs.page.scss'],
})
// tslint:disable-next-line:component-class-suffix
export class TabsPage extends VPageComponent {
//
//#region Props ...
//
//#region Page Props ...
titleRes = AppResourceIDs.tabs;
toolbarTitle = this.resourceProvider(this.titleRes);
toolbarSubTitle = this.resourceProvider(AppResourceIDs.tabs_description);
toolbarShowSubTitle = true;
//#endregion
//
// Prepare All Resource IDs ...
readonly ResourceIDs = Object.assign(
Object.assign({}, XResourceIDs),
AppResourceIDs
) as any;
//
readonly IconNames = Object.assign({}, XIconNames);
//#endregion
//
readonly TabAligns = Object.assign({}, XTabAlign);
readonly TabsHeaderPositions = Object.assign({}, XTabsHeaderPosition);
//
// Content ...
readonly contentFa = `
# ${this.toolbarTitle}
این مولفه جهت نمایش محتواهای مختلف در غالب برگه ها و دسته بندی آن ها بکار می رود
`;
readonly contentEn = `
# ${this.toolbarTitle}
this component used to group several contents and show them in tabs area.
`;
//
readonly sample1 =
'```html' +
`
<x-tabs
#xTabs
[startIndex]="1"
[swipable]="true"
[loopTabs]="false"
[dynamicHeight]="false"
[color]="ColorNames.Dark"
[alignTabs]="TabAligns.START"
[headerPosition]="
TabsHeaderPositions.BELOW"
>
<x-tab>
<div x-tab-label>
Tab 1
</div>
<div
class="tab-wrapper"
[xColor]="ColorNames.Danger"
>
Lorem ipsum dolor sit amet
consectetur adipisicing elit.
Omnis similique reiciendis vero
vel. Et, in nemo. Sapiente
doloremque provident ex dolore,
expedita totam ipsam architecto
vero mollitia magni. Corporis, dolore.
</div>
</x-tab>
<x-tab>
<div x-tab-label>
Tab 2
</div>
<div
class="tab-wrapper"
[xColor]="ColorNames.Secondary"
>
Lorem ipsum dolor sit amet
consectetur adipisicing elit.
Omnis similique reiciendis vero
vel. Et, in nemo. Sapiente
doloremque provident ex dolore,
expedita totam ipsam architecto
vero mollitia magni. Corporis, dolore.
</div>
</x-tab>
<x-tab>
<div x-tab-label>
Tab 3
</div>
<div
class="tab-wrapper"
[xColor]="ColorNames.Warning"
>
Lorem ipsum dolor sit amet
consectetur adipisicing elit.
Omnis similique reiciendis vero
vel. Et, in nemo. Sapiente
doloremque provident ex dolore,
expedita totam ipsam architecto
vero mollitia magni. Corporis, dolore.
</div>
</x-tab>
<x-tab>
<div x-tab-label>
Tab 4
</div>
<div
class="tab-wrapper"
[xColor]="color"
>
Lorem ipsum dolor sit amet
consectetur adipisicing elit.
Omnis similique reiciendis vero
vel. Et, in nemo. Sapiente
doloremque provident ex dolore,
expedita totam ipsam architecto
vero mollitia magni. Corporis, dolore.
</div>
</x-tab>
</x-tabs>
` +
'```';
//
//#region UI Providers ...
//
// Provide content based on current locale ...
getContent(title: string) {
//
if (isNullOrEmptyString(title)) {
return '';
}
//
const currentLocale = this.managerService.currentLocale;
//
const varName =
title +
(currentLocale === 'en-US'
? 'En'
: currentLocale === 'fa-IR'
? 'Fa'
: '');
const result = this[`${varName}`];
//
return result || '';
}
//#endregion
}
@@ -0,0 +1,69 @@
<v-page
[hasSide]="true"
[toolbarTitle]="toolbarTitle"
[toolbarSubTitle]="toolbarSubTitle"
[toolbarShowSubTitle]="toolbarShowSubTitle"
>
<!-- Content -->
<x-card [isInPage]="true" [showActions]="true" [color]="ColorNames.Light">
<!-- Actions -->
<div actions>
<a
target="_blank"
href="https://docs.x-framework.ir/x-framework-components/components/XTreeComponent.html"
>{{resourceProvider(ResourceIDs.documentation)}}</a
>
</div>
</x-card>
<!-- TODO: Complete this ... -->
<x-button
[type]="ButtonTypes.Raised"
[title]="'Expand All'"
(clicked)="handleTreeExpandAll()"
></x-button>
<x-button
[type]="ButtonTypes.Raised"
[title]="'Collapse All'"
(clicked)="handleTreeCollapseAll()"
></x-button>
<x-button
[type]="ButtonTypes.Raised"
[title]="'Expand'"
(clicked)="handleTreeExpand(1)"
></x-button>
<x-button
[type]="ButtonTypes.Raised"
[title]="'Collapse'"
(clicked)="handleTreeCollapse(1)"
></x-button>
<!-- Tree -->
<x-tree
[isInPage]="true"
[nodes]="treeNodes"
[wrapWithCard]="true"
[nodeTemplate]="todoItemRef"
[actionProvider]="treeActionProvider"
[toggleIconColor]="ColorNames.SuccessShade"
(onNodeToggle)="handleTreeNodeToggled($event)"
></x-tree>
</v-page>
<!-- ToDo Item Template -->
<ng-template #todoItemRef let-data let-nodeId="nodeId">
<!-- Title -->
<div class="v-todo-title">{{ nodeId }}</div>
<!-- Body -->
<ng-container *ngIf="(data | xAs : XProgrammingTech) as data">
<div class="v-todo-description">
<div>Name: {{ data.name }}</div>
<div>Description: {{ data.description }}</div>
</div>
</ng-container>
</ng-template>
@@ -0,0 +1,3 @@
:host(::ng-deep.mat-tree-node) {
align-items: baseline !important;
}
+301
View File
@@ -0,0 +1,301 @@
import { Subject } from 'rxjs';
import {
XTreeNode,
XIconNames,
XButtonType,
XTreeAction,
XTreeNodeToggle,
XTreeActionModel,
} from 'x-framework-components';
import { Component } from '@angular/core';
import { XResourceIDs } from 'x-framework-core';
import { VPageComponent } from 'src/app/views/v-page/v-page.component';
interface ProgrammingTech {
name: string;
description: string;
}
@Component({
selector: 'app-tree',
templateUrl: './tree.page.html',
styleUrls: ['./tree.page.scss'],
})
// tslint:disable-next-line:component-class-suffix
export class TreePage extends VPageComponent {
//
//#region Props ...
//
//#region Page Props ...
titleRes = this.AppResourceIDs.tree;
toolbarTitle = this.resourceProvider(this.titleRes);
toolbarSubTitle = this.resourceProvider(this.AppResourceIDs.tree_description);
toolbarShowSubTitle = true;
//
treeActionProvider = new Subject<XTreeActionModel>();
//#endregion
//
// Prepare All Resource IDs ...
readonly ResourceIDs = Object.assign(
Object.assign({}, XResourceIDs),
this.AppResourceIDs
) as any;
//
readonly IconNames = Object.assign({}, XIconNames);
readonly ButtonTypes = Object.assign({}, XButtonType);
//#endregion
//
XProgrammingTech: ProgrammingTech;
treeNodes = this.getTreeNodes();
//
// TODO: Complete this ...
handleTreeNodeToggled(event: XTreeNodeToggle) {
console.log('handleTreeNodeToggled: ', event);
}
handleTreeExpand(id: number) {
console.log('handleTreeExpand: ', id);
//
this.treeActionProvider.next({
action: XTreeAction.Expand,
payload: id,
});
}
handleTreeCollapse(id: number) {
console.log('handleTreeCollapse: ', id);
//
this.treeActionProvider.next({
action: XTreeAction.Collapse,
payload: id,
});
}
handleTreeExpandAll() {
console.log('handleTreeExpandAll');
//
this.treeActionProvider.next({
action: XTreeAction.ExpandAll,
});
}
handleTreeCollapseAll() {
console.log('handleTreeCollapseAll');
//
this.treeActionProvider.next({
action: XTreeAction.CollapseAll,
});
}
//
//#region XTree ...
private getTreeNodes() {
return [
//
// Frontend ...
{
id: '1',
tooltip: 'Frontend Development Technologies',
data: {
name: 'Frontend',
description: 'Frontend Development Technologies',
},
childs: [
//
// Angular ...
{
id: '1/1',
tooltip: 'Angular Framework',
data: {
name: 'Angular',
description: 'Angular Framework',
},
childs: [
//
// Components ...
{
id: '1/1/1',
data: {
name: 'Components',
description:
"Components is an important part of Angular's building blocks, since it is on top of Component based architecture",
},
childs: [],
} as XTreeNode<ProgrammingTech>,
],
} as XTreeNode<ProgrammingTech>,
//
// React ...
{
id: '1/2',
data: {
name: 'React',
description:
'a Collection of Web tools to create Web client apps',
},
childs: [],
} as XTreeNode<ProgrammingTech>,
//
// Vue ...
{
id: '1/3',
data: {
name: 'Vue',
description: 'a Frontend Development Frameworks',
},
childs: [],
} as XTreeNode<ProgrammingTech>,
],
} as XTreeNode<ProgrammingTech>,
//
// Desktop ...
{
id: '2',
data: {
name: 'Desktop',
description: 'Desktop Development Technologies',
},
childs: [
//
// .Net ...
{
id: '2/1',
data: {
name: '.Net',
description: 'a collction of languages for creating Desktop Apps',
},
childs: [],
} as XTreeNode<ProgrammingTech>,
//
// Electron ...
{
id: '2/2',
data: {
name: 'Electron',
description:
'a collection of tools to Convert a Web app into Desktop Apps',
},
childs: [],
} as XTreeNode<ProgrammingTech>,
],
} as XTreeNode<ProgrammingTech>,
//
// Mobile ...
{
id: '3',
data: {
name: 'Mobile',
description: 'Mobile Development Technologies',
},
childs: [
//
// J2ME ...
{
id: '3/1',
data: {
name: 'J2ME',
description:
'Java Mobile edition, using JAVA language to creating java based Mobile Applications',
},
childs: [],
} as XTreeNode<ProgrammingTech>,
//
// CBuilder ...
{
id: '3/2',
data: {
name: 'CBuilder',
description:
'using c++ to creating Symbian based Mobile Applications',
},
childs: [],
} as XTreeNode<ProgrammingTech>,
//
// Android SDK ...
{
id: '3/3',
data: {
name: 'Android',
description:
'using Android SDK to create Android OS based Mobile Applications by help of Java/Kotlin',
},
childs: [],
} as XTreeNode<ProgrammingTech>,
//
// Swift ...
{
id: '3/4',
data: {
name: 'Swift',
description: 'create iOs based Mobile Applications',
},
childs: [],
} as XTreeNode<ProgrammingTech>,
],
} as XTreeNode<ProgrammingTech>,
//
// Backend ...
{
id: '4',
data: {
name: 'Backend',
description: 'Backend Development Technologies',
},
childs: [
//
// Php ...
{
id: '4/1',
data: {
name: 'Php',
description: 'one of most popular backend development languages',
},
childs: [],
} as XTreeNode<ProgrammingTech>,
//
// Python ...
{
id: '4/2',
data: {
name: 'Python',
description: 'a multi usage language to develop applications',
},
childs: [],
} as XTreeNode<ProgrammingTech>,
//
// NodeJS ...
{
id: '4/3',
data: {
name: 'Node JS',
description:
'a chrome engin based tool to create multi purpose applications',
},
childs: [],
} as XTreeNode<ProgrammingTech>,
//
// .Net Core ...
{
id: '4/4',
data: {
name: '.net core',
description:
'a lightweigt, fast and cross platform version of .Net which provided by Microsoft to Develop Applications',
},
childs: [],
} as XTreeNode<ProgrammingTech>,
],
} as XTreeNode<ProgrammingTech>,
];
}
//#endregion
}
+26
View File
@@ -0,0 +1,26 @@
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { CommonModule } from '@angular/common';
import { ViewsModule } from '../../views/views.module';
import { IntroductionPage } from './introduction/introduction.page';
import { BaseRoutes, ServicesRoutes } from 'src/app/config/page.config';
@NgModule({
imports: [
ViewsModule,
CommonModule,
RouterModule.forChild([
{
path: BaseRoutes.Default,
redirectTo: ServicesRoutes.Introduction,
pathMatch: 'full',
},
{
path: ServicesRoutes.Introduction,
component: IntroductionPage,
},
]),
],
declarations: [IntroductionPage],
})
export class CorePageModule {}
@@ -0,0 +1,23 @@
<v-page
[hasSide]="true"
[toolbarTitle]="toolbarTitle"
[toolbarSubTitle]="toolbarSubTitle"
[toolbarShowSubTitle]="toolbarShowSubTitle"
>
<!-- Content -->
<x-card [isInPage]="true" [showActions]="true" [color]="ColorNames.Light">
<!-- Content -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('content')"
></x-markdown>
<!-- Actions -->
<div actions>
<a target="_blank" href="https://docs.x-framework.ir/x-framework-core/index.html"
>{{resourceProvider(ResourceIDs.documentation)}}</a
>
</div>
</x-card>
</v-page>
@@ -0,0 +1,83 @@
import {
XResourceIDs,
isNullOrEmptyString,
XColorWithBrightness,
} from 'x-framework-core';
import { Component } from '@angular/core';
import { VPageComponent } from 'src/app/views/v-page/v-page.component';
import { AppResourceIDs } from 'src/app/config/app.localization.config';
@Component({
selector: 'app-components-introduction',
templateUrl: './introduction.page.html',
styleUrls: ['./introduction.page.scss'],
})
// tslint:disable-next-line:component-class-suffix
export class IntroductionPage extends VPageComponent {
//
//#region Props ...
//
//#region Page Props ...
titleRes = AppResourceIDs.core_introduction;
toolbarTitle = this.resourceProvider(this.titleRes);
toolbarSubTitle = this.resourceProvider(
AppResourceIDs.core_introduction_description
);
toolbarShowSubTitle = true;
//#endregion
//
// Prepare All Resource IDs ...
readonly ResourceIDs = Object.assign(
Object.assign({}, XResourceIDs),
AppResourceIDs
) as any;
//
// Color Names ...
readonly ColorNames = Object.assign({}, XColorWithBrightness);
//#endregion
//
// Content ...
readonly contentFa = `
# ${this.toolbarTitle}
این واحد شامل کلیه نیازمندی های پایه چارچوب است.
برای آشنایی با اجزاء این واحد‌‌ مستندات آن را مورد مطالعه قرار دهید.
`;
readonly contentEn = `
# ${this.toolbarTitle}
this module contains all required dependencies for xFramework.
for complete descriptions please read this module documentaions.
`;
//#endregion
//
// Provide content based on current locale ...
getContent(title: string) {
//
if (isNullOrEmptyString(title)) {
return '';
}
//
const currentLocale = this.managerService.currentLocale;
//
const varName =
title +
(currentLocale === 'en-US'
? 'En'
: currentLocale === 'fa-IR'
? 'Fa'
: '');
const result = this[`${varName}`];
//
return result || '';
}
}
+26
View File
@@ -0,0 +1,26 @@
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { CommonModule } from '@angular/common';
import { ViewsModule } from '../../views/views.module';
import { BaseRoutes, HomeRoutes } from 'src/app/config/page.config';
import { IntroductionPage } from './introduction/introduction.page';
@NgModule({
imports: [
ViewsModule,
CommonModule,
RouterModule.forChild([
{
path: BaseRoutes.Default,
redirectTo: HomeRoutes.Introduction,
pathMatch: 'full',
},
{
path: HomeRoutes.Introduction,
component: IntroductionPage,
},
]),
],
declarations: [IntroductionPage],
})
export class HomePageModule {}
@@ -0,0 +1,26 @@
<v-page
[hasSide]="true"
[toolbarTitle]="toolbarTitle"
[toolbarSubTitle]="toolbarSubTitle"
[toolbarShowSubTitle]="toolbarShowSubTitle"
>
<!-- Content -->
<x-card [isInPage]="true" [showActions]="true" [color]="ColorNames.Light">
<!-- Content -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('content')"
></x-markdown>
<!-- Maintainer -->
<v-maintainer></v-maintainer>
<!-- Actions -->
<div actions>
<a target="_blank" href="https://docs.x-framework.ir/index.html"
>{{resourceProvider(AppResourceIDs.documentation)}}</a
>
</div>
</x-card>
</v-page>
@@ -0,0 +1,99 @@
import { Component } from '@angular/core';
import { VPageComponent } from 'src/app/views/v-page/v-page.component';
import { AppResourceIDs } from 'src/app/config/app.localization.config';
import { isNullOrEmptyString, XColorWithBrightness } from 'x-framework-core';
@Component({
selector: 'app-components-introduction',
templateUrl: './introduction.page.html',
styleUrls: ['./introduction.page.scss'],
})
// tslint:disable-next-line:component-class-suffix
export class IntroductionPage extends VPageComponent {
//
//#region Props ...
//
//#region Page Props ...
titleRes = AppResourceIDs.home_introduction;
toolbarTitle = this.resourceProvider(this.titleRes);
toolbarSubTitle = this.resourceProvider(
AppResourceIDs.home_introduction_description
);
toolbarShowSubTitle = true;
//#endregion
//
// Color Names ...
readonly ColorNames = Object.assign({}, XColorWithBrightness);
//#endregion
//
// Content ...
readonly contentFa = `
# ${this.toolbarTitle}
یک چارچوب طراحی و توسعه ظاهر برنامه های کاربردی است که با بهره گیری از توانمندی های انگولار/آیونیک و کوردوا ایجاد شده است تا فرآیند طراحی و توسعه ظاهر برنامه های کاربردی را سهل تر کند.
این چارچوب بر سه واحد مستقل استوار است که عبارتند از:
- **واحد هسته**:
شامل اصلی ترین نیازمندی های پایه است.
- **واحد خدمات**:
شامل مجموعه ای از خدمات پرکاربرد است که چارچوب از آن ها برای فراهم کردن امکانات مختلف استفاده می کند.
- **واحد مولفه ها**:
مجموعه ای مولفه های بصری که بر پایه استاندارد متریال دیزاین طراحی و توسعه یافته اند و امکانات مختلفی را در اختیار کاربر قرار می دهند.
`;
readonly contentEn = `
# ${this.toolbarTitle}
a Frontend framework which combined and implement several building blocks to provide an easy to use interface for creating Web/Mobile/Desktop Apps by help of Angular/Ionic and Cordova Powers.
XFramework built on top of 3 main and unique modules:
- **Core Module**:
conatins core features and dependencies.
- **Services Module**:
contains some sort of usefull services which this framework used them to provide different options.
- **Components Module**:
contains a collection of UI Components which designed and develop based on Material Design and provide different options.
`;
//#endregion
//
async afterViewInit() {
await super.afterViewInit();
//
// console.log('sortOrder: ', this.sortOrederModelKeys);
}
//
// Provide content based on current locale ...
getContent(title: string) {
//
if (isNullOrEmptyString(title)) {
return '';
}
//
const currentLocale = this.managerService.currentLocale;
//
const varName =
title +
(currentLocale === 'en-US'
? 'En'
: currentLocale === 'fa-IR'
? 'Fa'
: '');
const result = this[`${varName}`];
//
return result || '';
}
}
@@ -0,0 +1,23 @@
<v-page
[hasSide]="true"
[toolbarTitle]="toolbarTitle"
[toolbarSubTitle]="toolbarSubTitle"
[toolbarShowSubTitle]="toolbarShowSubTitle"
>
<!-- Content -->
<x-card [isInPage]="true" [showActions]="true" [color]="ColorNames.Light">
<!-- Content -->
<x-markdown
[mode]="'preview'"
[hasToolbar]="false"
[content]="getContent('content')"
></x-markdown>
<!-- Actions -->
<div actions>
<a target="_blank" href="https://docs.x-framework.ir/x-framework-services/index.html"
>{{resourceProvider(ResourceIDs.documentation)}}</a
>
</div>
</x-card>
</v-page>
@@ -0,0 +1,151 @@
import {
XResourceIDs,
isNullOrEmptyString,
XColorWithBrightness,
} from 'x-framework-core';
import { Component } from '@angular/core';
import { VPageComponent } from 'src/app/views/v-page/v-page.component';
import { AppResourceIDs } from 'src/app/config/app.localization.config';
@Component({
selector: 'app-components-introduction',
templateUrl: './introduction.page.html',
styleUrls: ['./introduction.page.scss'],
})
// tslint:disable-next-line:component-class-suffix
export class IntroductionPage extends VPageComponent {
//
//#region Props ...
//
//#region Page Props ...
titleRes = AppResourceIDs.services_introduction;
toolbarTitle = this.resourceProvider(this.titleRes);
toolbarSubTitle = this.resourceProvider(
AppResourceIDs.services_introduction_description
);
toolbarShowSubTitle = true;
//#endregion
//
// Prepare All Resource IDs ...
readonly ResourceIDs = Object.assign(
Object.assign({}, XResourceIDs),
AppResourceIDs
) as any;
//
// Color Names ...
readonly ColorNames = Object.assign({}, XColorWithBrightness);
//#endregion
//
// Content ...
readonly contentFa = `
# ${this.toolbarTitle}
این واحد شامل کلیه خدمات قابل استفاده در چارچوب است که هر یک امکانات خاصی را در اختیار قرار می دهد، که اهم آن ها عبارتند از:
- **XDialogService**:
قابلیت نمایش و استفاده از کادر های مختلف محاوره ای را فراهم می کند.
- **XGeolocationService**:
قابلیت مکان یابی را فراهم می کند.
- **XHistoryService**:
قابلیت مدیریت و دستکاری تاریخچه مرور صفحات در مرورگر را فراهم می کند.
- **XLocalizationService**:
قابلیت استفاده از منابع در ازای محتوای مستقیم را جهت پشتیبانی از زبان های مختلف را فراهم می کند.
- **XNotificationService**:
قابلیت نمایش اعلان های مختلف را فراهم می کند.
- **XStorageService**:
قابلیت استفاده از حافطه را جهت ذخیره و بازیابی موارد مختلف فراهم می کند.
- **XSecureStorageService**:
قابلیت استفاده از حافظه بصورت رمزنگاری شده را فراهم می کند.
- **XSecurityService**:
قابلیت رمزنگاری و رمزگشایی اطلاعات و تولید امضاهای دیجیتال را فراهم می کند.
- **XSettingsService**:
قابلیت مدیریت تنظیمات چارچوب را فراهم می کند.
- **XTaskManagerService**:
قابلیت اجرای وظایف و اولویت بندی آن ها را فراهم می کند.
- **XManagerService**:
جهت سهولت دستری به خدمات موجود این خدمت بعنوان در برگیرنده کلیه خدمات لازم در چارچوب، مورد بهره برداری قرار می گیرد.
برای آشنایی بیشتر لطفا به مستندات مراجعه فرمایید.
`;
readonly contentEn = `
# ${this.toolbarTitle}
this module contains all useable services inside the framework which each one provide some capabilities, such as:
- **XDialogService**:
provide the ability of use several types of Dialogs.
- **XGeolocationService**:
provide Geo Location abilities.
- **XHistoryService**:
provide the ability of managing and manipulating Browser History.
- **XLocalizationService**:
provide ability of Localization and Internationalization.
- **XNotificationService**:
provide ability of using several Notifications.
- **XStorageService**:
provide ability of Storage used to Save and Retrieve data.
- **XSecureStorageService**:
provide a Secure Storage to Save and Retrieve data privately.
- **XSecurityService**:
provide ability of Encrypt/Decrypt data and also Generate Checksub Digest of data.
- **XSettingsService**:
provide ability of Managing xFramework Settings.
- **XTaskManagerService**:
provide ability to Queue Tasks and run them based on their priority.
- **XManagerService**:
for better access all services, this Service acts as a Container of all required important above services.
for more information, please read documentation.
`;
//#endregion
//
// Provide content based on current locale ...
getContent(title: string) {
//
if (isNullOrEmptyString(title)) {
return '';
}
//
const currentLocale = this.managerService.currentLocale;
//
const varName =
title +
(currentLocale === 'en-US'
? 'En'
: currentLocale === 'fa-IR'
? 'Fa'
: '');
const result = this[`${varName}`];
//
return result || '';
}
}
+31
View File
@@ -0,0 +1,31 @@
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { CommonModule } from '@angular/common';
import { ViewsModule } from '../../views/views.module';
import { IntroductionPage } from './introduction/introduction.page';
import { BaseRoutes, ServicesRoutes } from 'src/app/config/page.config';
import { UserDevicePage } from './user-device/user-device.page';
@NgModule({
imports: [
ViewsModule,
CommonModule,
RouterModule.forChild([
{
path: BaseRoutes.Default,
redirectTo: ServicesRoutes.Introduction,
pathMatch: 'full',
},
{
path: ServicesRoutes.Introduction,
component: IntroductionPage,
},
{
path: ServicesRoutes.UserDevice,
component: UserDevicePage,
},
]),
],
declarations: [UserDevicePage, IntroductionPage],
})
export class ServicesPageModule {}

Some files were not shown because too many files have changed in this diff Show More