Initial Commit on git.saherelm.ir ...
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
# Editor configuration, see https://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.ts]
|
||||
quote_type = single
|
||||
|
||||
[*.md]
|
||||
max_line_length = off
|
||||
trim_trailing_whitespace = false
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||
|
||||
# compiled output
|
||||
/dist
|
||||
/tmp
|
||||
/out-tsc
|
||||
# Only exists if Bazel was run
|
||||
/bazel-out
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
|
||||
# profiling files
|
||||
chrome-profiler-events*.json
|
||||
|
||||
# IDEs and editors
|
||||
/.idea
|
||||
.project
|
||||
.classpath
|
||||
.c9/
|
||||
*.launch
|
||||
.settings/
|
||||
*.sublime-workspace
|
||||
|
||||
# IDE - VSCode
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
.history/*
|
||||
|
||||
# misc
|
||||
/.sass-cache
|
||||
/connect.lock
|
||||
/coverage
|
||||
/libpeerconnection.log
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
testem.log
|
||||
/typings
|
||||
|
||||
# System Files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
#
|
||||
documentation
|
||||
package-lock.json
|
||||
|
||||
#
|
||||
.angular
|
||||
@@ -0,0 +1,11 @@
|
||||
# XFrameworkCore
|
||||
|
||||
this is xFramework's core module and conatins core features of XFramework Library.
|
||||
|
||||
## Maintainer
|
||||
|
||||
Hadi Khazaee asl
|
||||
|
||||
[https://www.saherelm.ir](https://www.saherelm.ir)
|
||||
|
||||
[hadi_khazaee_asl@yahoo.com](mailto:hadi_khazaee_asl@yahoo.com)
|
||||
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||
"cli": {
|
||||
"analytics": false
|
||||
},
|
||||
"version": 1,
|
||||
"newProjectRoot": "projects",
|
||||
"projects": {
|
||||
"x-framework-core": {
|
||||
"projectType": "library",
|
||||
"root": "projects/x-framework-core",
|
||||
"sourceRoot": "projects/x-framework-core/src",
|
||||
"prefix": "x",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:ng-packagr",
|
||||
"options": {
|
||||
"project": "projects/x-framework-core/ng-package.json"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"tsConfig": "projects/x-framework-core/tsconfig.lib.prod.json"
|
||||
},
|
||||
"development": {
|
||||
"tsConfig": "projects/x-framework-core/tsconfig.lib.json"
|
||||
},
|
||||
"ivy": {
|
||||
"tsConfig": "projects/x-framework-core/tsconfig.lib.ivy.json"
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "production"
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"main": "projects/x-framework-core/src/test.ts",
|
||||
"tsConfig": "projects/x-framework-core/tsconfig.spec.json",
|
||||
"karmaConfig": "projects/x-framework-core/karma.conf.js"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultProject": "x-framework-core"
|
||||
}
|
||||
Vendored
+758
@@ -0,0 +1,758 @@
|
||||
declare function moment(inp?: moment.MomentInput, format?: moment.MomentFormatSpecification, strict?: boolean): moment.Moment;
|
||||
declare function moment(inp?: moment.MomentInput, format?: moment.MomentFormatSpecification, language?: string, strict?: boolean): moment.Moment;
|
||||
|
||||
declare namespace moment {
|
||||
type RelativeTimeKey = 's' | 'm' | 'mm' | 'h' | 'hh' | 'd' | 'dd' | 'M' | 'MM' | 'y' | 'yy';
|
||||
type CalendarKey = 'sameDay' | 'nextDay' | 'lastDay' | 'nextWeek' | 'lastWeek' | 'sameElse' | string;
|
||||
type LongDateFormatKey = 'LTS' | 'LT' | 'L' | 'LL' | 'LLL' | 'LLLL' | 'lts' | 'lt' | 'l' | 'll' | 'lll' | 'llll';
|
||||
|
||||
interface Locale {
|
||||
[key: string]: any;
|
||||
calendar(key?: CalendarKey, m?: Moment, now?: Moment): string;
|
||||
|
||||
longDateFormat(key: LongDateFormatKey): string;
|
||||
invalidDate(): string;
|
||||
ordinal(n: number): string;
|
||||
|
||||
preparse(inp: string): string;
|
||||
postformat(inp: string): string;
|
||||
relativeTime(n: number, withoutSuffix: boolean,
|
||||
key: RelativeTimeKey, isFuture: boolean): string;
|
||||
pastFuture(diff: number, absRelTime: string): string;
|
||||
set(config: Object): void;
|
||||
|
||||
months(): string[];
|
||||
jMonths(): string[];
|
||||
|
||||
months(m: Moment, format?: string): string;
|
||||
jMonths(m: Moment): string;
|
||||
monthsShort(): string[];
|
||||
jMonthsShort():string[];
|
||||
monthsShort(m: Moment, format?: string): string;
|
||||
jMonthsParse(monthName: string): number;
|
||||
monthsParse(monthName: string, format: string, strict: boolean): number;
|
||||
monthsRegex(strict: boolean): RegExp;
|
||||
monthsShortRegex(strict: boolean): RegExp;
|
||||
|
||||
week(m: Moment): number;
|
||||
firstDayOfYear(): number;
|
||||
firstDayOfWeek(): number;
|
||||
|
||||
weekdays(): string[];
|
||||
weekdays(m: Moment, format?: string): string;
|
||||
weekdaysMin(): string[];
|
||||
weekdaysMin(m: Moment): string;
|
||||
weekdaysShort(): string[];
|
||||
weekdaysShort(m: Moment): string;
|
||||
weekdaysParse(weekdayName: string, format: string, strict: boolean): number;
|
||||
weekdaysRegex(strict: boolean): RegExp;
|
||||
weekdaysShortRegex(strict: boolean): RegExp;
|
||||
weekdaysMinRegex(strict: boolean): RegExp;
|
||||
|
||||
isPM(input: string): boolean;
|
||||
meridiem(hour: number, minute: number, isLower: boolean): string;
|
||||
}
|
||||
|
||||
interface StandaloneFormatSpec {
|
||||
format: string[];
|
||||
standalone: string[];
|
||||
isFormat?: RegExp;
|
||||
}
|
||||
|
||||
interface WeekSpec {
|
||||
dow: number;
|
||||
doy: number;
|
||||
}
|
||||
|
||||
type CalendarSpecVal = string | ((m?: MomentInput, now?: Moment) => string);
|
||||
interface CalendarSpec {
|
||||
sameDay?: CalendarSpecVal;
|
||||
nextDay?: CalendarSpecVal;
|
||||
lastDay?: CalendarSpecVal;
|
||||
nextWeek?: CalendarSpecVal;
|
||||
lastWeek?: CalendarSpecVal;
|
||||
sameElse?: CalendarSpecVal;
|
||||
|
||||
// any additional properties might be used with moment.calendarFormat
|
||||
[x: string]: CalendarSpecVal | void; // undefined
|
||||
}
|
||||
|
||||
type RelativeTimeSpecVal = (
|
||||
string |
|
||||
((n: number, withoutSuffix: boolean,
|
||||
key: RelativeTimeKey, isFuture: boolean) => string)
|
||||
);
|
||||
type RelativeTimeFuturePastVal = string | ((relTime: string) => string);
|
||||
|
||||
interface RelativeTimeSpec {
|
||||
future: RelativeTimeFuturePastVal;
|
||||
past: RelativeTimeFuturePastVal;
|
||||
s: RelativeTimeSpecVal;
|
||||
m: RelativeTimeSpecVal;
|
||||
mm: RelativeTimeSpecVal;
|
||||
h: RelativeTimeSpecVal;
|
||||
hh: RelativeTimeSpecVal;
|
||||
d: RelativeTimeSpecVal;
|
||||
dd: RelativeTimeSpecVal;
|
||||
M: RelativeTimeSpecVal;
|
||||
MM: RelativeTimeSpecVal;
|
||||
y: RelativeTimeSpecVal;
|
||||
yy: RelativeTimeSpecVal;
|
||||
}
|
||||
|
||||
interface LongDateFormatSpec {
|
||||
LTS: string;
|
||||
LT: string;
|
||||
L: string;
|
||||
LL: string;
|
||||
LLL: string;
|
||||
LLLL: string;
|
||||
|
||||
// lets forget for a sec that any upper/lower permutation will also work
|
||||
lts?: string;
|
||||
lt?: string;
|
||||
l?: string;
|
||||
ll?: string;
|
||||
lll?: string;
|
||||
llll?: string;
|
||||
}
|
||||
|
||||
type MonthWeekdayFn = (momentToFormat: Moment, format?: string) => string;
|
||||
type WeekdaySimpleFn = (momentToFormat: Moment) => string;
|
||||
|
||||
interface LocaleSpecification {
|
||||
useGregorianParser?: boolean;
|
||||
months?: string[] | StandaloneFormatSpec | MonthWeekdayFn;
|
||||
monthsShort?: string[] | StandaloneFormatSpec | MonthWeekdayFn;
|
||||
|
||||
weekdays?: string[] | StandaloneFormatSpec | MonthWeekdayFn;
|
||||
weekdaysShort?: string[] | StandaloneFormatSpec | WeekdaySimpleFn;
|
||||
weekdaysMin?: string[] | StandaloneFormatSpec | WeekdaySimpleFn;
|
||||
|
||||
meridiemParse?: RegExp;
|
||||
meridiem?: (hour: number, minute: number, isLower: boolean) => string;
|
||||
|
||||
isPM?: (input: string) => boolean;
|
||||
|
||||
longDateFormat?: LongDateFormatSpec;
|
||||
calendar?: CalendarSpec;
|
||||
relativeTime?: RelativeTimeSpec;
|
||||
invalidDate?: string;
|
||||
ordinal?: (n: number) => string;
|
||||
ordinalParse?: RegExp;
|
||||
|
||||
week?: WeekSpec;
|
||||
|
||||
// Allow anything: in general any property that is passed as locale spec is
|
||||
// put in the locale object so it can be used by locale functions
|
||||
[x: string]: any;
|
||||
}
|
||||
|
||||
interface MomentObjectOutput {
|
||||
years: number;
|
||||
/* One digit */
|
||||
months: number;
|
||||
/* Day of the month */
|
||||
date: number;
|
||||
hours: number;
|
||||
minutes: number;
|
||||
seconds: number;
|
||||
milliseconds: number;
|
||||
}
|
||||
|
||||
interface Duration {
|
||||
humanize(withSuffix?: boolean): string;
|
||||
|
||||
abs(): Duration;
|
||||
|
||||
as(units: unitOfTime.Base): number;
|
||||
get(units: unitOfTime.Base): number;
|
||||
|
||||
milliseconds(): number;
|
||||
asMilliseconds(): number;
|
||||
|
||||
seconds(): number;
|
||||
asSeconds(): number;
|
||||
|
||||
minutes(): number;
|
||||
asMinutes(): number;
|
||||
|
||||
hours(): number;
|
||||
asHours(): number;
|
||||
|
||||
days(): number;
|
||||
asDays(): number;
|
||||
|
||||
weeks(): number;
|
||||
asWeeks(): number;
|
||||
|
||||
months(): number;
|
||||
asMonths(): number;
|
||||
|
||||
years(): number;
|
||||
asYears(): number;
|
||||
|
||||
add(inp?: DurationInputArg1, unit?: DurationInputArg2): Duration;
|
||||
subtract(inp?: DurationInputArg1, unit?: DurationInputArg2): Duration;
|
||||
|
||||
locale(): string;
|
||||
locale(locale: LocaleSpecifier): Duration;
|
||||
localeData(): Locale;
|
||||
|
||||
toISOString(): string;
|
||||
toJSON(): string;
|
||||
|
||||
/**
|
||||
* @deprecated since version 2.8.0
|
||||
*/
|
||||
lang(locale: LocaleSpecifier): Moment;
|
||||
/**
|
||||
* @deprecated since version 2.8.0
|
||||
*/
|
||||
lang(): Locale;
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
toIsoString(): string;
|
||||
}
|
||||
|
||||
interface MomentRelativeTime {
|
||||
future: any;
|
||||
past: any;
|
||||
s: any;
|
||||
m: any;
|
||||
mm: any;
|
||||
h: any;
|
||||
hh: any;
|
||||
d: any;
|
||||
dd: any;
|
||||
M: any;
|
||||
MM: any;
|
||||
y: any;
|
||||
yy: any;
|
||||
}
|
||||
|
||||
interface MomentLongDateFormat {
|
||||
L: string;
|
||||
LL: string;
|
||||
LLL: string;
|
||||
LLLL: string;
|
||||
LT: string;
|
||||
LTS: string;
|
||||
|
||||
l?: string;
|
||||
ll?: string;
|
||||
lll?: string;
|
||||
llll?: string;
|
||||
lt?: string;
|
||||
lts?: string;
|
||||
}
|
||||
|
||||
interface MomentParsingFlags {
|
||||
empty: boolean;
|
||||
unusedTokens: string[];
|
||||
unusedInput: string[];
|
||||
overflow: number;
|
||||
charsLeftOver: number;
|
||||
nullInput: boolean;
|
||||
invalidMonth: string | void; // null
|
||||
invalidFormat: boolean;
|
||||
userInvalidated: boolean;
|
||||
iso: boolean;
|
||||
parsedDateParts: any[];
|
||||
meridiem: string | void; // null
|
||||
}
|
||||
|
||||
interface MomentParsingFlagsOpt {
|
||||
empty?: boolean;
|
||||
unusedTokens?: string[];
|
||||
unusedInput?: string[];
|
||||
overflow?: number;
|
||||
charsLeftOver?: number;
|
||||
nullInput?: boolean;
|
||||
invalidMonth?: string;
|
||||
invalidFormat?: boolean;
|
||||
userInvalidated?: boolean;
|
||||
iso?: boolean;
|
||||
parsedDateParts?: any[];
|
||||
meridiem?: string;
|
||||
}
|
||||
|
||||
interface MomentBuiltinFormat {
|
||||
__momentBuiltinFormatBrand: any;
|
||||
}
|
||||
|
||||
type MomentFormatSpecification = string | MomentBuiltinFormat | (string | MomentBuiltinFormat)[];
|
||||
|
||||
namespace unitOfTime {
|
||||
type Base = (
|
||||
"year" | "years" | "y" | "jYear" |
|
||||
"month" | "months" | "M" | "jMonth" | "jmonth" |
|
||||
"week" | "weeks" | "w" | "jw" |
|
||||
"day" | "days" | "d" | "jDay" | "jD" |
|
||||
"hour" | "hours" | "h" |
|
||||
"minute" | "minutes" | "m" |
|
||||
"second" | "seconds" | "s" |
|
||||
"millisecond" | "milliseconds" | "ms"
|
||||
);
|
||||
|
||||
type _quarter = "quarter" | "quarters" | "Q";
|
||||
type _isoWeek = "isoWeek" | "isoWeeks" | "W";
|
||||
type _date = "date" | "dates" | "D";
|
||||
type DurationConstructor = Base | _quarter;
|
||||
|
||||
type DurationAs = Base;
|
||||
|
||||
type StartOf = Base | _quarter | _isoWeek | _date;
|
||||
|
||||
type Diff = Base | _quarter;
|
||||
|
||||
type MomentConstructor = Base | _date;
|
||||
|
||||
type All = Base | _quarter | _isoWeek | _date |
|
||||
"weekYear" | "weekYears" | "gg" |
|
||||
"isoWeekYear" | "isoWeekYears" | "GG" |
|
||||
"dayOfYear" | "dayOfYears" | "DDD" |
|
||||
"weekday" | "weekdays" | "e" |
|
||||
"isoWeekday" | "isoWeekdays" | "E";
|
||||
}
|
||||
|
||||
interface MomentInputObject {
|
||||
years?: number;
|
||||
year?: number;
|
||||
y?: number;
|
||||
|
||||
months?: number;
|
||||
month?: number;
|
||||
M?: number;
|
||||
|
||||
days?: number;
|
||||
day?: number;
|
||||
d?: number;
|
||||
|
||||
dates?: number;
|
||||
date?: number;
|
||||
D?: number;
|
||||
|
||||
hours?: number;
|
||||
hour?: number;
|
||||
h?: number;
|
||||
|
||||
minutes?: number;
|
||||
minute?: number;
|
||||
m?: number;
|
||||
|
||||
seconds?: number;
|
||||
second?: number;
|
||||
s?: number;
|
||||
|
||||
milliseconds?: number;
|
||||
millisecond?: number;
|
||||
ms?: number;
|
||||
}
|
||||
|
||||
interface DurationInputObject extends MomentInputObject {
|
||||
quarters?: number;
|
||||
quarter?: number;
|
||||
Q?: number;
|
||||
|
||||
weeks?: number;
|
||||
week?: number;
|
||||
w?: number;
|
||||
}
|
||||
|
||||
interface MomentSetObject extends MomentInputObject {
|
||||
weekYears?: number;
|
||||
weekYear?: number;
|
||||
gg?: number;
|
||||
|
||||
isoWeekYears?: number;
|
||||
isoWeekYear?: number;
|
||||
GG?: number;
|
||||
|
||||
quarters?: number;
|
||||
quarter?: number;
|
||||
Q?: number;
|
||||
|
||||
weeks?: number;
|
||||
week?: number;
|
||||
w?: number;
|
||||
|
||||
isoWeeks?: number;
|
||||
isoWeek?: number;
|
||||
W?: number;
|
||||
|
||||
dayOfYears?: number;
|
||||
dayOfYear?: number;
|
||||
DDD?: number;
|
||||
|
||||
weekdays?: number;
|
||||
weekday?: number;
|
||||
e?: number;
|
||||
|
||||
isoWeekdays?: number;
|
||||
isoWeekday?: number;
|
||||
E?: number;
|
||||
}
|
||||
|
||||
interface FromTo {
|
||||
from: MomentInput;
|
||||
to: MomentInput;
|
||||
}
|
||||
|
||||
type MomentInput = Moment | Date | string | number | (number | string)[] | MomentInputObject | void; // null | undefined
|
||||
type DurationInputArg1 = Duration | number | string | FromTo | DurationInputObject | void; // null | undefined
|
||||
type DurationInputArg2 = unitOfTime.DurationConstructor;
|
||||
type LocaleSpecifier = string | Moment | Duration | string[] | boolean;
|
||||
|
||||
interface MomentCreationData {
|
||||
input: MomentInput;
|
||||
format?: MomentFormatSpecification;
|
||||
locale: Locale;
|
||||
isUTC: boolean;
|
||||
strict?: boolean;
|
||||
}
|
||||
|
||||
interface Moment extends Object{
|
||||
format(format?: string): string;
|
||||
|
||||
startOf(unitOfTime: unitOfTime.StartOf): Moment;
|
||||
endOf(unitOfTime: unitOfTime.StartOf): Moment;
|
||||
|
||||
add(amount?: DurationInputArg1, unit?: DurationInputArg2): Moment;
|
||||
/**
|
||||
* @deprecated reverse syntax
|
||||
*/
|
||||
add(unit: unitOfTime.DurationConstructor, amount: number|string): Moment;
|
||||
|
||||
subtract(amount?: DurationInputArg1, unit?: DurationInputArg2): Moment;
|
||||
/**
|
||||
* @deprecated reverse syntax
|
||||
*/
|
||||
subtract(unit: unitOfTime.DurationConstructor, amount: number|string): Moment;
|
||||
|
||||
calendar(time?: MomentInput, formats?: CalendarSpec): string;
|
||||
|
||||
clone(): Moment;
|
||||
|
||||
/**
|
||||
* @return Unix timestamp in milliseconds
|
||||
*/
|
||||
valueOf(): number;
|
||||
|
||||
// current date/time in local mode
|
||||
local(keepLocalTime?: boolean): Moment;
|
||||
isLocal(): boolean;
|
||||
|
||||
// current date/time in UTC mode
|
||||
utc(keepLocalTime?: boolean): Moment;
|
||||
isUTC(): boolean;
|
||||
/**
|
||||
* @deprecated use isUTC
|
||||
*/
|
||||
isUtc(): boolean;
|
||||
|
||||
parseZone(): Moment;
|
||||
isValid(): boolean;
|
||||
invalidAt(): number;
|
||||
|
||||
hasAlignedHourOffset(other?: MomentInput): boolean;
|
||||
|
||||
creationData(): MomentCreationData;
|
||||
parsingFlags(): MomentParsingFlags;
|
||||
|
||||
year(y: number): Moment;
|
||||
year(): number;
|
||||
jYear(y: number): Moment;
|
||||
jYear():number;
|
||||
/**
|
||||
* @deprecated use year(y)
|
||||
*/
|
||||
years(y: number): Moment;
|
||||
/**
|
||||
* @deprecated use year()
|
||||
*/
|
||||
years(): number;
|
||||
quarter(): number;
|
||||
quarter(q: number): Moment;
|
||||
quarters(): number;
|
||||
quarters(q: number): Moment;
|
||||
month(M: number|string): Moment;
|
||||
jMonth(M: number|string): Moment;
|
||||
month(): number;
|
||||
jMonth(): number;
|
||||
/**
|
||||
* @deprecated use month(M)
|
||||
*/
|
||||
months(M: number|string): Moment;
|
||||
/**
|
||||
* @deprecated use month()
|
||||
*/
|
||||
months(): number;
|
||||
day(d: number|string): Moment;
|
||||
day(): number;
|
||||
jDay(d: number|string): Moment;
|
||||
jDay(): number;
|
||||
days(d: number|string): Moment;
|
||||
days(): number;
|
||||
date(d: number): Moment;
|
||||
jDate(d: number): Moment;
|
||||
date(): number;
|
||||
jDate(): number;
|
||||
/**
|
||||
* @deprecated use date(d)
|
||||
*/
|
||||
dates(d: number): Moment;
|
||||
/**
|
||||
* @deprecated use jDate(d)
|
||||
*/
|
||||
jDates(d: number): Moment;
|
||||
/**
|
||||
* @deprecated use date()
|
||||
*/
|
||||
dates(): number;
|
||||
/**
|
||||
* @deprecated use jDate()
|
||||
*/
|
||||
jDates():number;
|
||||
|
||||
hour(h: number): Moment;
|
||||
hour(): number;
|
||||
hours(h: number): Moment;
|
||||
hours(): number;
|
||||
minute(m: number): Moment;
|
||||
minute(): number;
|
||||
minutes(m: number): Moment;
|
||||
minutes(): number;
|
||||
second(s: number): Moment;
|
||||
second(): number;
|
||||
seconds(s: number): Moment;
|
||||
seconds(): number;
|
||||
millisecond(ms: number): Moment;
|
||||
millisecond(): number;
|
||||
milliseconds(ms: number): Moment;
|
||||
milliseconds(): number;
|
||||
weekday(): number;
|
||||
//TODO:jweekday
|
||||
weekday(d: number): Moment;
|
||||
isoWeekday(): number;
|
||||
isoWeekday(d: number|string): Moment;
|
||||
weekYear(): number;
|
||||
jWeekYear(): number;
|
||||
weekYear(d: number): Moment;
|
||||
jWeekYear(d: number): Moment;
|
||||
isoWeekYear(): number;
|
||||
isoWeekYear(d: number): Moment;
|
||||
week(): number;
|
||||
jWeek(): number;
|
||||
week(d: number): Moment;
|
||||
jWeek(d: number): Moment;
|
||||
weeks(): number;
|
||||
jWeeks(): number;//TODO:check it
|
||||
weeks(d: number): Moment;
|
||||
isoWeek(): number;
|
||||
isoWeek(d: number): Moment;
|
||||
isoWeeks(): number;
|
||||
isoWeeks(d: number): Moment;
|
||||
weeksInYear(): number;
|
||||
//TODO : jWeeksInYear
|
||||
isoWeeksInYear(): number;
|
||||
dayOfYear(): number;
|
||||
jDayOfYear(): number;
|
||||
dayOfYear(d: number): Moment;
|
||||
jDayOfYear(d: number): Moment;
|
||||
|
||||
from(inp: MomentInput, suffix?: boolean): string;
|
||||
to(inp: MomentInput, suffix?: boolean): string;
|
||||
fromNow(withoutSuffix?: boolean): string;
|
||||
toNow(withoutPrefix?: boolean): string;
|
||||
|
||||
diff(b: MomentInput, unitOfTime?: unitOfTime.Diff, precise?: boolean): number;
|
||||
|
||||
toArray(): number[];
|
||||
toDate(): Date;
|
||||
toISOString(): string;
|
||||
inspect(): string;
|
||||
toJSON(): string;
|
||||
unix(): number;
|
||||
|
||||
isLeapYear(): boolean;
|
||||
jIsLeapYear(): boolean;
|
||||
/**
|
||||
* @deprecated in favor of utcOffset
|
||||
*/
|
||||
zone(): number;
|
||||
zone(b: number|string): Moment;
|
||||
utcOffset(): number;
|
||||
utcOffset(b: number|string, keepLocalTime?: boolean): Moment;
|
||||
isUtcOffset(): boolean;
|
||||
daysInMonth(): number;
|
||||
jDaysInMonth(): number;
|
||||
isDST(): boolean;
|
||||
|
||||
zoneAbbr(): string;
|
||||
zoneName(): string;
|
||||
|
||||
isBefore(inp?: MomentInput, granularity?: unitOfTime.StartOf): boolean;
|
||||
isAfter(inp?: MomentInput, granularity?: unitOfTime.StartOf): boolean;
|
||||
isSame(inp?: MomentInput, granularity?: unitOfTime.StartOf): boolean;
|
||||
isSameOrAfter(inp?: MomentInput, granularity?: unitOfTime.StartOf): boolean;
|
||||
isSameOrBefore(inp?: MomentInput, granularity?: unitOfTime.StartOf): boolean;
|
||||
isBetween(a: MomentInput, b: MomentInput, granularity?: unitOfTime.StartOf, inclusivity?: "()" | "[)" | "(]" | "[]"): boolean;
|
||||
|
||||
doAsGregorian(): Moment;
|
||||
|
||||
/**
|
||||
* @deprecated as of 2.8.0, use locale
|
||||
*/
|
||||
lang(language: LocaleSpecifier): Moment;
|
||||
/**
|
||||
* @deprecated as of 2.8.0, use locale
|
||||
*/
|
||||
lang(): Locale;
|
||||
|
||||
locale(): string;
|
||||
locale(locale: LocaleSpecifier): Moment;
|
||||
|
||||
localeData(): Locale;
|
||||
|
||||
/**
|
||||
* @deprecated no reliable implementation
|
||||
*/
|
||||
isDSTShifted(): boolean;
|
||||
|
||||
// NOTE(constructor): Same as moment constructor
|
||||
/**
|
||||
* @deprecated as of 2.7.0, use moment.min/max
|
||||
*/
|
||||
max(inp?: MomentInput, format?: MomentFormatSpecification, strict?: boolean): Moment;
|
||||
/**
|
||||
* @deprecated as of 2.7.0, use moment.min/max
|
||||
*/
|
||||
max(inp?: MomentInput, format?: MomentFormatSpecification, language?: string, strict?: boolean): Moment;
|
||||
|
||||
// NOTE(constructor): Same as moment constructor
|
||||
/**
|
||||
* @deprecated as of 2.7.0, use moment.min/max
|
||||
*/
|
||||
min(inp?: MomentInput, format?: MomentFormatSpecification, strict?: boolean): Moment;
|
||||
/**
|
||||
* @deprecated as of 2.7.0, use moment.min/max
|
||||
*/
|
||||
min(inp?: MomentInput, format?: MomentFormatSpecification, language?: string, strict?: boolean): Moment;
|
||||
|
||||
get(unit: unitOfTime.All): number;
|
||||
set(unit: unitOfTime.All, value: number): Moment;
|
||||
set(objectLiteral: MomentSetObject): Moment;
|
||||
|
||||
toObject(): MomentObjectOutput;
|
||||
}
|
||||
|
||||
export var version: string;
|
||||
export var fn: Moment;
|
||||
|
||||
// NOTE(constructor): Same as moment constructor
|
||||
export function utc(inp?: MomentInput, format?: MomentFormatSpecification, strict?: boolean): Moment;
|
||||
export function utc(inp?: MomentInput, format?: MomentFormatSpecification, language?: string, strict?: boolean): Moment;
|
||||
|
||||
export function unix(timestamp: number): Moment;
|
||||
|
||||
export function invalid(flags?: MomentParsingFlagsOpt): Moment;
|
||||
export function isMoment(m: any): m is Moment;
|
||||
export function isDate(m: any): m is Date;
|
||||
export function isDuration(d: any): d is Duration;
|
||||
|
||||
/**
|
||||
* @deprecated in 2.8.0
|
||||
*/
|
||||
export function lang(language?: string): string;
|
||||
/**
|
||||
* @deprecated in 2.8.0
|
||||
*/
|
||||
export function lang(language?: string, definition?: Locale): string;
|
||||
|
||||
export function locale(language?: string): string;
|
||||
export function locale(language?: string[]): string;
|
||||
export function locale(language?: string, definition?: LocaleSpecification | void): string; // null | undefined
|
||||
|
||||
export function localeData(key?: string | string[]): Locale;
|
||||
|
||||
export function duration(inp?: DurationInputArg1, unit?: DurationInputArg2): Duration;
|
||||
|
||||
// NOTE(constructor): Same as moment constructor
|
||||
export function parseZone(inp?: MomentInput, format?: MomentFormatSpecification, strict?: boolean): Moment;
|
||||
export function parseZone(inp?: MomentInput, format?: MomentFormatSpecification, language?: string, strict?: boolean): Moment;
|
||||
|
||||
export function months(): string[];
|
||||
export function months(index: number): string;
|
||||
export function months(format: string): string[];
|
||||
export function months(format: string, index: number): string;
|
||||
export function monthsShort(): string[];
|
||||
export function monthsShort(index: number): string;
|
||||
export function monthsShort(format: string): string[];
|
||||
export function monthsShort(format: string, index: number): string;
|
||||
|
||||
export function jWeekOfYear(mom: Moment, firstDayOfWeek: number, firstDayOfWeekOfYear: number): MomentInput;
|
||||
export function jDaysInMonth(jMear: number, jMonth: number): number;
|
||||
export function jIsLeapYear(jYear: number): boolean;
|
||||
export function useJalaliSystemPrimarily(): void;
|
||||
export function useJalaliSystemSecondary(): void;
|
||||
export var jConvert: any;
|
||||
|
||||
export function from (date: string, locale: string, format?: string): Moment;
|
||||
|
||||
export function weekdays(): string[];
|
||||
export function weekdays(index: number): string;
|
||||
export function weekdays(format: string): string[];
|
||||
export function weekdays(format: string, index: number): string;
|
||||
export function weekdays(localeSorted: boolean): string[];
|
||||
export function weekdays(localeSorted: boolean, index: number): string;
|
||||
export function weekdays(localeSorted: boolean, format: string): string[];
|
||||
export function weekdays(localeSorted: boolean, format: string, index: number): string;
|
||||
export function weekdaysShort(): string[];
|
||||
export function weekdaysShort(index: number): string;
|
||||
export function weekdaysShort(format: string): string[];
|
||||
export function weekdaysShort(format: string, index: number): string;
|
||||
export function weekdaysShort(localeSorted: boolean): string[];
|
||||
export function weekdaysShort(localeSorted: boolean, index: number): string;
|
||||
export function weekdaysShort(localeSorted: boolean, format: string): string[];
|
||||
export function weekdaysShort(localeSorted: boolean, format: string, index: number): string;
|
||||
export function weekdaysMin(): string[];
|
||||
export function weekdaysMin(index: number): string;
|
||||
export function weekdaysMin(format: string): string[];
|
||||
export function weekdaysMin(format: string, index: number): string;
|
||||
export function weekdaysMin(localeSorted: boolean): string[];
|
||||
export function weekdaysMin(localeSorted: boolean, index: number): string;
|
||||
export function weekdaysMin(localeSorted: boolean, format: string): string[];
|
||||
export function weekdaysMin(localeSorted: boolean, format: string, index: number): string;
|
||||
|
||||
export function min(...moments: MomentInput[]): Moment;
|
||||
export function max(...moments: MomentInput[]): Moment;
|
||||
|
||||
/**
|
||||
* Returns unix time in milliseconds. Overwrite for profit.
|
||||
*/
|
||||
export function now(): number;
|
||||
|
||||
export function defineLocale(language: string, localeSpec: LocaleSpecification | void): Locale; // null
|
||||
export function updateLocale(language: string, localeSpec: LocaleSpecification | void): Locale; // null
|
||||
|
||||
export function locales(): string[];
|
||||
|
||||
export function normalizeUnits(unit: unitOfTime.All): string;
|
||||
export function relativeTimeThreshold(threshold: string): number | boolean;
|
||||
export function relativeTimeThreshold(threshold: string, limit: number): boolean;
|
||||
export function relativeTimeRounding(fn: (num: number) => number): boolean;
|
||||
export function relativeTimeRounding(): (num: number) => number;
|
||||
export function calendarFormat(m: Moment, now: Moment): string;
|
||||
|
||||
/**
|
||||
* Constant used to enable explicit ISO_8601 format parsing.
|
||||
*/
|
||||
export var ISO_8601: MomentBuiltinFormat;
|
||||
|
||||
export var defaultFormat: string;
|
||||
export var defaultFormatUtc: string;
|
||||
}
|
||||
|
||||
export = moment;
|
||||
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"name": "x-framework-core-holder",
|
||||
"version": "0.0.1",
|
||||
"description": "an isolation layoer of xFrameworkCore module",
|
||||
"keywords": [
|
||||
"x-framework",
|
||||
"x-framework-core"
|
||||
],
|
||||
"homepage": "https://saherelm.ir",
|
||||
"author": {
|
||||
"name": "Hadi Khazaee Asl",
|
||||
"email": "hadi_khazaee_asl@yahoo.com",
|
||||
"url": "https://saherelm.ir"
|
||||
},
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"publishModule": "npm run buildModule && npm run packModule",
|
||||
"build:ivy": "ng build x-framework-core --configuration=ivy",
|
||||
"serveDocs": "compodoc -p projects/x-framework-core/tsconfig.lib.json --theme material -s",
|
||||
"buildModule": "npm run preBuildModule && ng build x-framework-core --configuration production",
|
||||
"packModule": "cd dist/x-framework-core && npm pack && shx mv *.tgz ../../../../pack && cd ../..",
|
||||
"preBuildModule": "shx true --silent mkdir ../../pack && shx true --silent rm -rf dist && shx true --silent rm ../../pack/x-framework-core*.tgz",
|
||||
"generateDocs": "compodoc -p projects/x-framework-core/tsconfig.lib.json --theme material --hideGenerator --disableSourceCode --disableDomTree --disableTemplateTab --disableStyleTab --disablePrivate --disableLifeCycleHooks --disableRoutesGraph --disableCoverage --customFavicon ../xFrameworkDocuments/Resources/favicon.png --customLogo ../xFrameworkDocuments/Resources/favicon.png"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "~12.0.4",
|
||||
"@angular/common": "~12.0.4",
|
||||
"@angular/compiler": "~12.0.4",
|
||||
"@angular/core": "~12.0.4",
|
||||
"@angular/forms": "~12.0.4",
|
||||
"@angular/platform-browser": "~12.0.4",
|
||||
"@angular/platform-browser-dynamic": "~12.0.4",
|
||||
"@angular/router": "~12.0.4",
|
||||
"rxjs": "~6.6.0",
|
||||
"tslib": "^2.1.0",
|
||||
"zone.js": "~0.11.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "~12.0.4",
|
||||
"@angular/cdk": "^12.1.2",
|
||||
"@angular/cli": "~12.0.4",
|
||||
"@angular/compiler-cli": "~12.0.4",
|
||||
"@angular/material": "^12.1.2",
|
||||
"@angular/material-moment-adapter": "^12.1.2",
|
||||
"@compodoc/compodoc": "^1.1.14",
|
||||
"@ionic/angular": "^5.6.11",
|
||||
"@types/jasmine": "~3.6.0",
|
||||
"@types/node": "^12.11.1",
|
||||
"@types/uuid": "^8.3.1",
|
||||
"ionicons": "^5.5.2",
|
||||
"jalali-moment": "^3.3.10",
|
||||
"jasmine-core": "~3.7.0",
|
||||
"karma": "~6.3.0",
|
||||
"karma-chrome-launcher": "~3.1.0",
|
||||
"karma-coverage": "~2.0.3",
|
||||
"karma-jasmine": "~4.0.0",
|
||||
"karma-jasmine-html-reporter": "^1.5.0",
|
||||
"libphonenumber-js": "^1.9.22",
|
||||
"md5-typescript": "^1.0.5",
|
||||
"moment": "^2.29.1",
|
||||
"ng-packagr": "^12.0.0",
|
||||
"shx": "^0.3.3",
|
||||
"typescript": "~4.2.3",
|
||||
"undefined": "^0.1.0",
|
||||
"uuid": "^8.3.2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
# XFrameworkCore
|
||||
|
||||
this is xFramework's core module and conatins core features of XFramework Library.
|
||||
|
||||
## Maintainer
|
||||
|
||||
Hadi Khazaee asl
|
||||
|
||||
<https://www.saherelm.ir>
|
||||
|
||||
hadi_khazaee_asl@yahoo.com
|
||||
@@ -0,0 +1,44 @@
|
||||
// Karma configuration file, see link for more information
|
||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
basePath: '',
|
||||
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
||||
plugins: [
|
||||
require('karma-jasmine'),
|
||||
require('karma-chrome-launcher'),
|
||||
require('karma-jasmine-html-reporter'),
|
||||
require('karma-coverage'),
|
||||
require('@angular-devkit/build-angular/plugins/karma')
|
||||
],
|
||||
client: {
|
||||
jasmine: {
|
||||
// you can add configuration options for Jasmine here
|
||||
// the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
|
||||
// for example, you can disable the random execution with `random: false`
|
||||
// or set a specific seed with `seed: 4321`
|
||||
},
|
||||
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
||||
},
|
||||
jasmineHtmlReporter: {
|
||||
suppressAll: true // removes the duplicated traces
|
||||
},
|
||||
coverageReporter: {
|
||||
dir: require('path').join(__dirname, '../../coverage/x-framework-core'),
|
||||
subdir: '.',
|
||||
reporters: [
|
||||
{ type: 'html' },
|
||||
{ type: 'text-summary' }
|
||||
]
|
||||
},
|
||||
reporters: ['progress', 'kjhtml'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: true,
|
||||
browsers: ['Chrome'],
|
||||
singleRun: false,
|
||||
restartOnFileChange: true
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
|
||||
"dest": "../../dist/x-framework-core",
|
||||
"lib": {
|
||||
"entryFile": "src/public-api.ts"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "x-framework-core",
|
||||
"version": "0.0.1",
|
||||
"description": "core features of xFramework",
|
||||
"keywords": [
|
||||
"x-framework",
|
||||
"x-framework-core"
|
||||
],
|
||||
"homepage": "https://saherelm.ir",
|
||||
"author": {
|
||||
"name": "Hadi Khazaee Asl",
|
||||
"email": "hadi_khazaee_asl@yahoo.com",
|
||||
"url": "https://saherelm.ir"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/common": "^12.0.4",
|
||||
"@angular/core": "^12.0.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
import { XLoggable } from './x-loggable';
|
||||
|
||||
export abstract class XBaseService extends XLoggable {
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HammerGestureConfig } from '@angular/platform-browser';
|
||||
|
||||
@Injectable()
|
||||
export class XHammerGestureConfig extends HammerGestureConfig {
|
||||
public overrides = <any> {
|
||||
pinch: {
|
||||
enable: false
|
||||
},
|
||||
rotate: {
|
||||
enable: false
|
||||
},
|
||||
swipe: {
|
||||
direction: 6
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
import {
|
||||
isNullOrUndefined,
|
||||
isNullOrEmptyString
|
||||
} from '../tools/x-type-detect.tools';
|
||||
import { Inject } from '@angular/core';
|
||||
import { X_FRAMEWORK_CORE_CONFIG } from '../tokens/x-injectable-tokens';
|
||||
import { XFrameworkCoreConfig } from '../config/x-framework-core.config';
|
||||
|
||||
export enum XLogType {
|
||||
Warn,
|
||||
Error,
|
||||
Debug,
|
||||
Info
|
||||
}
|
||||
|
||||
export interface GetLogTag {
|
||||
getLogTag(): string;
|
||||
}
|
||||
|
||||
export abstract class XLoggable implements GetLogTag {
|
||||
//
|
||||
// Constructor ...
|
||||
constructor(
|
||||
@Inject(X_FRAMEWORK_CORE_CONFIG) public config: XFrameworkCoreConfig
|
||||
) {}
|
||||
|
||||
//
|
||||
// GetLogTag Implementation ...
|
||||
/**
|
||||
* retrieve logging tag ...
|
||||
*/
|
||||
getLogTag(): string {
|
||||
//
|
||||
if (this.constructor) {
|
||||
return `${this.config.baseLogTag}_[${this.constructor.name}]`;
|
||||
}
|
||||
|
||||
//
|
||||
return `${this.config.baseLogTag}_[NON-Constructor]`;
|
||||
}
|
||||
|
||||
protected log(type: XLogType, message?: any, ...args: any[]) {
|
||||
//
|
||||
if (!this.config.enableLogging) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
let logMsg = !isNullOrEmptyString(message)
|
||||
? this.getLogTag() + ' => ' + message
|
||||
: this.getLogTag();
|
||||
|
||||
//
|
||||
const logArgs = args;
|
||||
args.push(new Date());
|
||||
|
||||
//
|
||||
switch (type) {
|
||||
case XLogType.Debug:
|
||||
//
|
||||
logMsg = 'D: ' + logMsg;
|
||||
|
||||
//
|
||||
isNullOrUndefined(logArgs)
|
||||
? // tslint:disable-next-line:no-console
|
||||
console.debug(logMsg)
|
||||
: // tslint:disable-next-line:no-console
|
||||
console.debug(logMsg, logArgs);
|
||||
break;
|
||||
|
||||
case XLogType.Error:
|
||||
//
|
||||
logMsg = 'E: ' + logMsg;
|
||||
|
||||
//
|
||||
isNullOrUndefined(logArgs)
|
||||
? console.error(logMsg)
|
||||
: console.error(logMsg, logArgs);
|
||||
break;
|
||||
|
||||
case XLogType.Warn:
|
||||
//
|
||||
logMsg = 'W: ' + logMsg;
|
||||
|
||||
//
|
||||
isNullOrUndefined(logArgs)
|
||||
? console.warn(logMsg)
|
||||
: console.warn(logMsg, logArgs);
|
||||
break;
|
||||
|
||||
case XLogType.Info:
|
||||
//
|
||||
logMsg = 'I: ' + logMsg;
|
||||
|
||||
//
|
||||
isNullOrUndefined(logArgs)
|
||||
? // tslint:disable-next-line:no-console
|
||||
console.info(logMsg)
|
||||
: // tslint:disable-next-line:no-console
|
||||
console.info(logMsg, logArgs);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected logDebug(message?: any, ...args: any) {
|
||||
this.log(XLogType.Debug, message, args);
|
||||
}
|
||||
|
||||
protected logError(message?: any, ...args: any) {
|
||||
this.log(XLogType.Error, message, args);
|
||||
}
|
||||
|
||||
protected logWarn(message?: any, ...args: any) {
|
||||
this.log(XLogType.Warn, message, args);
|
||||
}
|
||||
|
||||
protected logInfo(message?: any, ...args: any) {
|
||||
this.log(XLogType.Info, message, args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,247 @@
|
||||
import * as moment_ from 'jalali-moment';
|
||||
const moment = moment_;
|
||||
import {
|
||||
MomentDateAdapter,
|
||||
MAT_MOMENT_DATE_FORMATS,
|
||||
} from '@angular/material-moment-adapter';
|
||||
import { XParam } from '../constants/x-param.enum';
|
||||
import { DateAdapter } from '@angular/material/core';
|
||||
import { applyLocale, XLocale } from '../typings/x-translation.typings';
|
||||
import { toPersianNumbers } from '../tools/x-string.tools';
|
||||
import { localeData, Moment, isMoment, invalid } from 'jalali-moment';
|
||||
import { isString } from '../tools/x-type-detect.tools';
|
||||
|
||||
export const PERSIAN_DATE_FORMATS = {
|
||||
parse: {
|
||||
dateInput: 'jYYYY/jMM/jDD',
|
||||
},
|
||||
display: {
|
||||
dateInput: 'jYYYY/jMM/jDD',
|
||||
monthYearLabel: 'jYYYY jMMMM',
|
||||
dateA11yLabel: 'jYYYY/jMM/jDD',
|
||||
monthYearA11yLabel: 'jYYYY jMMMM',
|
||||
},
|
||||
};
|
||||
|
||||
export class XPersianDateAdapter extends DateAdapter<Moment> {
|
||||
//
|
||||
private mLocale: XLocale = 'fa-IR';
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
super.setLocale(this.mLocale);
|
||||
}
|
||||
|
||||
getYear(date: Moment): number {
|
||||
return this.clone(date).jYear();
|
||||
}
|
||||
|
||||
getMonth(date: Moment): number {
|
||||
return this.clone(date).jMonth();
|
||||
}
|
||||
|
||||
getDate(date: Moment): number {
|
||||
return this.clone(date).jDate();
|
||||
}
|
||||
|
||||
getDayOfWeek(date: Moment): number {
|
||||
return this.clone(date).day();
|
||||
}
|
||||
|
||||
getMonthNames(style: 'long' | 'short' | 'narrow'): string[] {
|
||||
//
|
||||
const jLocalData = localeData(this.mLocale);
|
||||
|
||||
//
|
||||
switch (style) {
|
||||
case 'long':
|
||||
case 'short':
|
||||
return jLocalData._jMonths.slice(0);
|
||||
case 'narrow':
|
||||
return jLocalData._jMonthsShort.slice(0);
|
||||
}
|
||||
}
|
||||
|
||||
getDateNames(): string[] {
|
||||
const valuesArray = Array(31);
|
||||
for (let i = 0; i < 31; i++) {
|
||||
valuesArray[i] = toPersianNumbers(String(i + 1));
|
||||
}
|
||||
return valuesArray;
|
||||
}
|
||||
|
||||
getDayOfWeekNames(style: 'long' | 'short' | 'narrow'): string[] {
|
||||
switch (style) {
|
||||
case 'long':
|
||||
return localeData(this.mLocale).weekdays().slice(0);
|
||||
case 'short':
|
||||
return localeData(this.mLocale).weekdaysShort().slice(0);
|
||||
case 'narrow':
|
||||
return ['ی', 'د', 'س', 'چ', 'پ', 'ج', 'ش'];
|
||||
}
|
||||
}
|
||||
|
||||
getYearName(date: Moment): string {
|
||||
return toPersianNumbers(this.clone(date).jYear().toString());
|
||||
}
|
||||
|
||||
getFirstDayOfWeek(): number {
|
||||
return localeData(this.mLocale).firstDayOfWeek();
|
||||
}
|
||||
|
||||
getNumDaysInMonth(date: Moment): number {
|
||||
return this.clone(date).jDaysInMonth();
|
||||
}
|
||||
|
||||
clone(date: Moment | Date | string | any): Moment {
|
||||
//
|
||||
const isDateMoment = moment.isMoment(date);
|
||||
if (!isDateMoment) {
|
||||
date = moment(new Date(date));
|
||||
}
|
||||
|
||||
//
|
||||
let result: Moment;
|
||||
|
||||
//
|
||||
try {
|
||||
result = date.clone().locale(this.mLocale);
|
||||
} catch {
|
||||
//
|
||||
result = this.today().clone().locale(this.mLocale);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
createDate(year: number, month: number, date: number): Moment {
|
||||
if (month < 0 || month > 11) {
|
||||
throw Error(
|
||||
`Invalid month index "${month}". Month index has to be between 0 and 11.`
|
||||
);
|
||||
}
|
||||
if (date < 1) {
|
||||
throw Error(`Invalid date "${date}". Date has to be greater than 0.`);
|
||||
}
|
||||
const result = moment()
|
||||
.jYear(year)
|
||||
.jMonth(month)
|
||||
.jDate(date)
|
||||
.hours(0)
|
||||
.minutes(0)
|
||||
.seconds(0)
|
||||
.milliseconds(0)
|
||||
.locale(this.mLocale);
|
||||
|
||||
if (this.getMonth(result) !== month) {
|
||||
throw Error(`Invalid date ${date} for month with index ${month}.`);
|
||||
}
|
||||
if (!result.isValid()) {
|
||||
throw Error(`Invalid date "${date}" for month with index "${month}".`);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
today(): Moment {
|
||||
return moment().locale(this.mLocale);
|
||||
}
|
||||
|
||||
parse(value: any, parseFormat: string | string[]): Moment | null {
|
||||
if (value && typeof value === 'string') {
|
||||
return moment(value, parseFormat, this.mLocale);
|
||||
}
|
||||
return value ? moment(value).locale(this.mLocale) : null;
|
||||
}
|
||||
|
||||
format(date: Moment | Date | string | any, displayFormat: string): string {
|
||||
//
|
||||
if (isString(date)) {
|
||||
date = applyLocale(date.toString(), 'en-US');
|
||||
}
|
||||
|
||||
//
|
||||
date = this.clone(date);
|
||||
|
||||
//
|
||||
if (!this.isValid(date)) {
|
||||
throw Error('JalaliMomentDateAdapter: Cannot format invalid date.');
|
||||
}
|
||||
|
||||
//
|
||||
try {
|
||||
return applyLocale(date.format(displayFormat), this.mLocale);
|
||||
} catch {
|
||||
return applyLocale(this.today().format(displayFormat), this.mLocale);
|
||||
}
|
||||
}
|
||||
|
||||
addCalendarYears(date: Moment, years: number): Moment {
|
||||
return this.clone(date).add(years, 'jYear');
|
||||
}
|
||||
|
||||
addCalendarMonths(date: Moment, months: number): Moment {
|
||||
return this.clone(date).add(months, 'jmonth');
|
||||
}
|
||||
|
||||
addCalendarDays(date: Moment, days: number): Moment {
|
||||
return this.clone(date).add(days, 'jDay');
|
||||
}
|
||||
|
||||
toIso8601(date: Moment): string {
|
||||
return this.clone(date).format();
|
||||
}
|
||||
|
||||
isDateInstance(obj: any): boolean {
|
||||
return isMoment(obj);
|
||||
}
|
||||
|
||||
isValid(date: Moment): boolean {
|
||||
return this.clone(date).isValid();
|
||||
}
|
||||
|
||||
invalid(): Moment {
|
||||
return invalid();
|
||||
}
|
||||
|
||||
deserialize(value: any): Moment | null {
|
||||
let date;
|
||||
if (value instanceof Date) {
|
||||
date = moment(value);
|
||||
}
|
||||
if (typeof value === 'string') {
|
||||
if (!value) {
|
||||
return null;
|
||||
}
|
||||
date = moment(value).locale(this.mLocale);
|
||||
}
|
||||
if (date && this.isValid(date)) {
|
||||
return date;
|
||||
}
|
||||
return super.deserialize(value);
|
||||
}
|
||||
}
|
||||
|
||||
export const DateAdapterFactory = (matDateLocale: XLocale) => {
|
||||
//
|
||||
if (matDateLocale === 'fa-IR') {
|
||||
return new XPersianDateAdapter();
|
||||
}
|
||||
|
||||
//
|
||||
return new MomentDateAdapter(matDateLocale);
|
||||
};
|
||||
|
||||
export const MatDateFormatFactory = (matDateLocale: XLocale) => {
|
||||
//
|
||||
if (matDateLocale === 'fa-IR') {
|
||||
return PERSIAN_DATE_FORMATS;
|
||||
}
|
||||
|
||||
//
|
||||
return MAT_MOMENT_DATE_FORMATS;
|
||||
};
|
||||
|
||||
export const LocaleFactory = () => {
|
||||
return window[XParam.Language];
|
||||
};
|
||||
@@ -0,0 +1,429 @@
|
||||
import {
|
||||
NgZone,
|
||||
Inject,
|
||||
Renderer2,
|
||||
ElementRef,
|
||||
RendererStyleFlags2,
|
||||
} from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import {
|
||||
isFunction,
|
||||
isNullOrUndefined,
|
||||
isNullOrEmptyString,
|
||||
} from '../tools/x-type-detect.tools';
|
||||
import { XLoggable } from './x-loggable';
|
||||
import { hasChild } from '../tools/x-array.tools';
|
||||
import { ViewportRuler } from '@angular/cdk/overlay';
|
||||
import { XRef, XStandardType } from '../typings/x.typings';
|
||||
import { XCssProperties } from '../typings/x-setting.typings';
|
||||
import { toObservable, toPromise } from '../tools/x-observable.tools';
|
||||
import { X_FRAMEWORK_CORE_CONFIG } from '../tokens/x-injectable-tokens';
|
||||
import { XFrameworkCoreConfig } from '../config/x-framework-core.config';
|
||||
import { waitForXElement } from '../tools/x-object.tools';
|
||||
|
||||
export class XRenderer extends XLoggable {
|
||||
//
|
||||
//#endregion Props ...
|
||||
private PREFIX = '--';
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Constructor ...
|
||||
constructor(
|
||||
@Inject(X_FRAMEWORK_CORE_CONFIG) public config: XFrameworkCoreConfig,
|
||||
public element: ElementRef,
|
||||
public renderer: Renderer2,
|
||||
public ruler: ViewportRuler,
|
||||
public ngZone: NgZone
|
||||
) {
|
||||
super(config);
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Document ...
|
||||
getElementById(id: string) {
|
||||
return document.getElementById(id);
|
||||
}
|
||||
|
||||
getElementsByClassName(className: string) {
|
||||
return document.getElementsByClassName(className);
|
||||
}
|
||||
|
||||
getElementsByName(elementName: string) {
|
||||
return document.getElementsByName(elementName);
|
||||
}
|
||||
|
||||
getElementsByTagName<K extends keyof HTMLElementTagNameMap>(
|
||||
tagName: K | string
|
||||
) {
|
||||
return document.getElementsByTagName(tagName);
|
||||
}
|
||||
|
||||
getRootNode() {
|
||||
return document.getRootNode();
|
||||
}
|
||||
|
||||
waitForElement(selector: string) {
|
||||
return waitForXElement(selector);
|
||||
}
|
||||
|
||||
querySelector<K extends keyof HTMLElementTagNameMap>(selector: K | string) {
|
||||
return document.querySelector(selector);
|
||||
}
|
||||
|
||||
querySelectorAll<K extends keyof HTMLElementTagNameMap>(
|
||||
selector: K | string
|
||||
) {
|
||||
return document.querySelectorAll(selector);
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Renderer ...
|
||||
/**
|
||||
* convert an element to HTML Element
|
||||
* for accessing props ...
|
||||
*
|
||||
* @param el elementRef of the selected element
|
||||
*/
|
||||
getElement(el?: ElementRef | HTMLElement) {
|
||||
//
|
||||
if (!el) {
|
||||
el = this.element;
|
||||
}
|
||||
|
||||
//
|
||||
return el instanceof ElementRef
|
||||
? ((el as ElementRef).nativeElement as HTMLElement)
|
||||
: (el as HTMLElement);
|
||||
}
|
||||
|
||||
/**
|
||||
* adding classes to an element ...
|
||||
*
|
||||
* @param clz the classes names
|
||||
* @param el the element
|
||||
*/
|
||||
addClass(clz: string, el?: ElementRef | HTMLElement) {
|
||||
this.renderer.addClass(this.getElement(el), clz);
|
||||
}
|
||||
|
||||
/**
|
||||
* remove classes from an element ...
|
||||
*
|
||||
* @param clz the classes names
|
||||
* @param el the element
|
||||
*/
|
||||
removeClass(clz: string, el?: ElementRef | HTMLElement) {
|
||||
this.renderer.removeClass(this.getElement(el), clz);
|
||||
}
|
||||
|
||||
/**
|
||||
* create an element ...
|
||||
*
|
||||
* @param name create an element
|
||||
* @param nameSpace adding a namespace
|
||||
*/
|
||||
createElement(name: string, nameSpace?: string) {
|
||||
return this.renderer.createElement(name, nameSpace);
|
||||
}
|
||||
|
||||
/**
|
||||
* create a Text Element ...
|
||||
*
|
||||
* @param value a text value
|
||||
*/
|
||||
createText(value: string) {
|
||||
return this.renderer.createText(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* adding a child element to another element ...
|
||||
*
|
||||
* @param parent the parent element
|
||||
* @param newChild the child element
|
||||
*/
|
||||
appendChild(parent: any, newChild: any) {
|
||||
this.renderer.appendChild(parent, newChild);
|
||||
}
|
||||
|
||||
/**
|
||||
* adding a child element to another element ...
|
||||
*
|
||||
* @param child child element
|
||||
* @param el parent element
|
||||
*/
|
||||
appendChildToElement(child: any, el?: ElementRef | HTMLElement) {
|
||||
this.renderer.appendChild(this.getElement(el), child);
|
||||
}
|
||||
|
||||
/**
|
||||
* set an attribute of an element ...
|
||||
*
|
||||
* @param name attribute name
|
||||
* @param value attribute value
|
||||
* @param el destination element
|
||||
* @param namespace name space name
|
||||
*/
|
||||
setAttribute(
|
||||
name: string,
|
||||
value: string,
|
||||
el?: ElementRef | HTMLElement,
|
||||
namespace?: string | null
|
||||
) {
|
||||
this.renderer.setAttribute(this.getElement(el), name, value, namespace);
|
||||
}
|
||||
|
||||
/**
|
||||
* remove an attribute from an element ...
|
||||
*
|
||||
* @param name attribute name
|
||||
* @param el destination element
|
||||
* @param namespace name space name
|
||||
*/
|
||||
removeAttribute(
|
||||
name: string,
|
||||
el?: ElementRef | HTMLElement,
|
||||
namespace?: string | null
|
||||
) {
|
||||
this.renderer.removeAttribute(this.getElement(el), name, namespace);
|
||||
}
|
||||
|
||||
/**
|
||||
* set style of an element ...
|
||||
*
|
||||
* @param style the style name
|
||||
* @param value style value
|
||||
* @param el destination element
|
||||
* @param flags flags
|
||||
*/
|
||||
setStyle(
|
||||
style: string,
|
||||
value: any,
|
||||
el?: ElementRef | HTMLElement,
|
||||
flags?: RendererStyleFlags2
|
||||
) {
|
||||
this.renderer.setStyle(this.getElement(el), style, value, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* remove an style from an element
|
||||
*
|
||||
* @param style style name
|
||||
* @param el destination element
|
||||
* @param flags flags
|
||||
*/
|
||||
removeStyle(
|
||||
style: string,
|
||||
el?: ElementRef | HTMLElement,
|
||||
flags?: RendererStyleFlags2
|
||||
) {
|
||||
this.renderer.removeStyle(this.getElement(el), style, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* set property to an element ...
|
||||
*
|
||||
* @param name property name
|
||||
* @param value property value
|
||||
* @param el destination element
|
||||
*/
|
||||
setProperty(name: string, value: any, el?: ElementRef | HTMLElement) {
|
||||
this.renderer.setProperty(this.getElement(el), name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* set value of specific node
|
||||
*
|
||||
* @param node specific element
|
||||
* @param value value
|
||||
*/
|
||||
setValue(node: any, value: string) {
|
||||
this.renderer.setValue(node, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* recieve computed style of an element ...
|
||||
*
|
||||
* @param el destination element
|
||||
*/
|
||||
getComputedStyle(el?: ElementRef | HTMLElement) {
|
||||
return getComputedStyle(this.getElement(el));
|
||||
}
|
||||
|
||||
/**
|
||||
* prepare a css var name
|
||||
*
|
||||
* @param key css variable name
|
||||
*/
|
||||
prepareCssKey(key: XCssProperties) {
|
||||
return `${this.PREFIX}${key}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* remove css key prefix ...
|
||||
*
|
||||
* @param key a prepared css var ...
|
||||
*/
|
||||
removeCssKeyPrefix(key: XCssProperties) {
|
||||
return key.replace(this.PREFIX, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* read specific css var value of an element
|
||||
* @param name css variable name
|
||||
* @param element destination element
|
||||
*/
|
||||
getCssVar(name: XCssProperties, el?: ElementRef | HTMLElement) {
|
||||
//
|
||||
return this.getComputedStyle(el).getPropertyValue(this.prepareCssKey(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* set css var into element ...
|
||||
*
|
||||
* @param name css var name
|
||||
* @param value css var value
|
||||
* @param elements destination element of array of elements
|
||||
*/
|
||||
setCssVar(
|
||||
name: XCssProperties,
|
||||
value: string,
|
||||
el?: ElementRef | HTMLElement
|
||||
) {
|
||||
//
|
||||
if (isNullOrEmptyString(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
this.getElement(el).style.setProperty(this.prepareCssKey(name), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* load script and add to component dynamically ...
|
||||
*
|
||||
* @param path path to js file
|
||||
*/
|
||||
addScript(path: string) {
|
||||
//
|
||||
const s = this.renderer.createElement('script');
|
||||
s.type = 'text/javascript';
|
||||
s.src = path;
|
||||
s.text = ``;
|
||||
this.renderer.appendChild(document.body, s);
|
||||
}
|
||||
|
||||
/**
|
||||
* add script content ...
|
||||
*
|
||||
* @param script the script block
|
||||
*/
|
||||
addScriptContent(script: string) {
|
||||
//
|
||||
const s = this.renderer.createElement('script');
|
||||
s.type = 'text/javascript';
|
||||
s.text = `${script}`;
|
||||
this.renderer.appendChild(document.body, s);
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Providers ...
|
||||
public getElementBoundaryRect(el?: ElementRef | HTMLElement) {
|
||||
return this.getElement(el).getBoundingClientRect();
|
||||
}
|
||||
|
||||
public getElementBoundaryWidth(el?: ElementRef | HTMLElement) {
|
||||
return this.getElementBoundaryRect().width;
|
||||
}
|
||||
|
||||
public getElementBoundaryHeight(el?: ElementRef | HTMLElement) {
|
||||
return this.getElementBoundaryRect().height;
|
||||
}
|
||||
|
||||
public getElementClientWidth(el?: ElementRef | HTMLElement) {
|
||||
return this.getElement(el).clientWidth;
|
||||
}
|
||||
|
||||
public getElementClientHeight(el?: ElementRef | HTMLElement) {
|
||||
return this.getElement(el).clientHeight;
|
||||
}
|
||||
|
||||
public getElementOffsetWidth(el?: ElementRef | HTMLElement) {
|
||||
return this.getElement(el).offsetWidth;
|
||||
}
|
||||
|
||||
public getElementOffsetHeight(el?: ElementRef | HTMLElement) {
|
||||
return this.getElement(el).offsetHeight;
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Zone Actions ...
|
||||
run<T>(fn: (...args: any[]) => T, applyThis?: any, applyArgs?: any[]): T {
|
||||
return this.ngZone.run(fn, applyThis, applyArgs);
|
||||
}
|
||||
|
||||
runTask<T>(
|
||||
fn: (...args: any[]) => T,
|
||||
applyThis?: any,
|
||||
applyArgs?: any[],
|
||||
name?: string
|
||||
): T {
|
||||
return this.ngZone.runTask(fn, applyThis, applyArgs, name);
|
||||
}
|
||||
|
||||
runGuarded<T>(
|
||||
fn: (...args: any[]) => T,
|
||||
applyThis?: any,
|
||||
applyArgs?: any[]
|
||||
): T {
|
||||
return this.ngZone.runGuarded(fn, applyThis, applyArgs);
|
||||
}
|
||||
|
||||
runOutsideAngular<T>(fn: (...args: any[]) => T): T {
|
||||
return this.ngZone.runOutsideAngular(fn);
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Action Runnings ...
|
||||
async runTimedOut<T>(
|
||||
fn: (...args: any[]) => T,
|
||||
delay?: XStandardType<number>
|
||||
) {
|
||||
//
|
||||
let desiredDelay = 0;
|
||||
if (!isNullOrUndefined(delay)) {
|
||||
desiredDelay = await toPromise(toObservable(delay));
|
||||
}
|
||||
|
||||
//
|
||||
if (!fn) {
|
||||
return null;
|
||||
}
|
||||
|
||||
//
|
||||
return await new Promise<T>((res, rej) => {
|
||||
//
|
||||
setTimeout(() => {
|
||||
//
|
||||
try {
|
||||
//
|
||||
const result = fn();
|
||||
res(result);
|
||||
} catch {
|
||||
//
|
||||
rej(null);
|
||||
}
|
||||
}, desiredDelay);
|
||||
});
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Private ...
|
||||
//#endregion
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
import { XCountryCode } from '../typings/x.typings';
|
||||
import { XNotificationSound } from '../typings/x-notification.typings';
|
||||
import { XLanguageDescriptor, XLocale } from '../typings/x-translation.typings';
|
||||
|
||||
/**
|
||||
* Application Configuration Structure ...
|
||||
*/
|
||||
export interface XFrameworkCoreConfig {
|
||||
//
|
||||
// Environment Identifier ...
|
||||
isProd: boolean;
|
||||
|
||||
//
|
||||
// App Info ...
|
||||
appInstanceName: string;
|
||||
appNameResource: string;
|
||||
appCompanyResource: string;
|
||||
appVersion: string;
|
||||
|
||||
//
|
||||
poweredValue: string;
|
||||
|
||||
//
|
||||
// Logging Configuration ...
|
||||
enableLogging: boolean;
|
||||
baseLogTag: string;
|
||||
|
||||
//
|
||||
// Language Configuration ...
|
||||
availableLanguages: XLanguageDescriptor[];
|
||||
defaultLanguage: XLocale;
|
||||
|
||||
//
|
||||
// Audio Service Configurations ...
|
||||
defaultNotificationDelay: number;
|
||||
notificationAudioSources: XNotificationSound[];
|
||||
|
||||
//
|
||||
// Security Service Configurations ...
|
||||
secretKey: string;
|
||||
|
||||
//
|
||||
// Image Related Configs ...
|
||||
minAllowedImageSize: number;
|
||||
maxAllowedImageSize: number;
|
||||
allowedImageExtensions: string[];
|
||||
|
||||
//
|
||||
// Profile Image Configs ...
|
||||
maxProfileImageSize: number;
|
||||
maxProfileImagesUploadFiles: number;
|
||||
minAllowedImageCroppableSize: number;
|
||||
|
||||
//
|
||||
// DCountry Code ...
|
||||
defaultCountryCode: XCountryCode;
|
||||
|
||||
//
|
||||
// Page Sizes ...
|
||||
defaultPageSize: number;
|
||||
pageSizes: number[];
|
||||
|
||||
//
|
||||
// Action Delays ...
|
||||
defaultActionDelay: number;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
export enum XBorderStyle {
|
||||
Dotted = 'dotted',
|
||||
Dashed = 'dashed',
|
||||
Solid = 'solid',
|
||||
Double = 'double',
|
||||
Grove = 'groove',
|
||||
Ridge = 'ridge',
|
||||
Inset = 'inset',
|
||||
Outset = 'outset',
|
||||
None = 'none',
|
||||
Hidden = 'hidden',
|
||||
}
|
||||
|
||||
export type XBorderStyleIdentifier = XBorderStyle | string;
|
||||
@@ -0,0 +1,7 @@
|
||||
export enum XCrudAction {
|
||||
Add = 'add',
|
||||
Update = 'update',
|
||||
Delete = 'delete'
|
||||
}
|
||||
|
||||
export type XCrudActionIdentifier = XCrudAction | string;
|
||||
@@ -0,0 +1,359 @@
|
||||
import { XExceptionIndex } from '../typings/x-exception.typings';
|
||||
|
||||
export enum XExceptionIDs {
|
||||
//
|
||||
//#region Invalid Exceptions 1xx ...
|
||||
InvalidData = 100,
|
||||
InvalidDate = 101,
|
||||
BadRequest = 102,
|
||||
InvalidArgs = 103,
|
||||
InvalidMessage = 104,
|
||||
InvalidToken = 105,
|
||||
InvalidVerificationCode = 106,
|
||||
InvalidEmailAddress = 107,
|
||||
InvalidMobileNumber = 108,
|
||||
InvalidPassword = 109,
|
||||
InavlidUrl = 110,
|
||||
InvalidDevice = 111,
|
||||
InvalidProfileImage = 112,
|
||||
InavlidFile = 113,
|
||||
InvalidUserName = 114,
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Not (...) Exceptions 2xx ...
|
||||
NotFound = 200,
|
||||
NotAllowed = 201,
|
||||
NotAuthorized = 202,
|
||||
NotVisible = 203,
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region User/Registration/Account/Bann Exceptions 3xx ...
|
||||
AccountLockedOut = 300,
|
||||
LoginFailed = 301,
|
||||
UserRegisteredBefore = 302,
|
||||
UserDisabled = 303,
|
||||
DeviceBanned = 304,
|
||||
VerificationCodeResendNotAllowed = 305,
|
||||
PasswordsSame = 306,
|
||||
MobilesSame = 307,
|
||||
EmailsSame = 308,
|
||||
MobileInUsed = 309,
|
||||
EmailInUsed = 310,
|
||||
MobileNotConfirmed = 311,
|
||||
EmailNotConfirmed = 312,
|
||||
PostBanned = 313,
|
||||
UserBanned = 314,
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region General Exceptions 4xx ...
|
||||
Unknown = 400,
|
||||
Duplicate = 401,
|
||||
ActionFailed = 402,
|
||||
ExpiredDate = 403,
|
||||
Unavailable = 404,
|
||||
MaxAllowedTagExceeded = 405,
|
||||
Timeout = 406,
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region File Exceptions 5xx ...
|
||||
EmptyFile = 500,
|
||||
MaxFileSizeExceeded = 501,
|
||||
UnsupportedFileType = 502,
|
||||
MaxAllowedMediaExceeded = 503,
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Configuration Exceptions 6xx ...
|
||||
InvalidConfiguration = 600,
|
||||
StorageServiceInitialFailed = 601,
|
||||
MessageServiceInitialFailed = 602,
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region xFramework Exceptions 9xx ...
|
||||
MaxAllowedFilesExceeded = 900,
|
||||
MinFilesSizeExceeded = 901,
|
||||
MaxFilesSizeExceeded = 902,
|
||||
MustAcceptTerms = 903,
|
||||
UnsupportedBrowser = 904,
|
||||
PermissionDenied = 905,
|
||||
PositionUnavailable = 906,
|
||||
StorageNotSupported = 907,
|
||||
MustLogout = 908,
|
||||
InvalidLocale = 909,
|
||||
InvalidUserSelector = 910,
|
||||
//#endregion
|
||||
}
|
||||
|
||||
/**
|
||||
* a collection of Available Exceptions on System ...
|
||||
*/
|
||||
export const Exceptions: XExceptionIndex = {
|
||||
//
|
||||
//#region Invalid Exceptions 1xx ...
|
||||
InvalidData: {
|
||||
id: 100,
|
||||
message: 'Invalid Data ...',
|
||||
},
|
||||
InvalidDate: {
|
||||
id: 101,
|
||||
message: 'Invalid Date ...',
|
||||
},
|
||||
BadRequest: {
|
||||
id: 102,
|
||||
message: 'Bad Request ...',
|
||||
},
|
||||
InvalidArgs: {
|
||||
id: 103,
|
||||
message: 'Invalid Args ...',
|
||||
},
|
||||
InvalidMessage: {
|
||||
id: 104,
|
||||
message: 'Invalid Message ...',
|
||||
},
|
||||
InvalidToken: {
|
||||
id: 105,
|
||||
message: 'Invalid Token ...',
|
||||
},
|
||||
InvalidVerificationCode: {
|
||||
id: 106,
|
||||
message: 'Invalid Verification Code ...',
|
||||
},
|
||||
InvalidEmailAddress: {
|
||||
id: 107,
|
||||
message: 'Invalid Email Address ...',
|
||||
},
|
||||
InvalidMobileNumber: {
|
||||
id: 108,
|
||||
message: 'Invalid Mobile Number ...',
|
||||
},
|
||||
InvalidPassword: {
|
||||
id: 109,
|
||||
message: 'Invalid Password ...',
|
||||
},
|
||||
InavlidUrl: {
|
||||
id: 110,
|
||||
message: 'Inavlid Url ...',
|
||||
},
|
||||
InvalidDevice: {
|
||||
id: 111,
|
||||
message: 'Invalid Device ...',
|
||||
},
|
||||
InvalidProfileImage: {
|
||||
id: 112,
|
||||
message: 'Invalid Profile Image ...',
|
||||
},
|
||||
InavlidFile: {
|
||||
id: 113,
|
||||
message: 'Invalid File ...',
|
||||
},
|
||||
InvalidUserName: {
|
||||
id: 114,
|
||||
message: 'Invalid Username ...',
|
||||
},
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Not (...) Exceptions 2xx ...
|
||||
NotFound: {
|
||||
id: 200,
|
||||
message: 'Not Found ...',
|
||||
},
|
||||
NotAllowed: {
|
||||
id: 201,
|
||||
message: 'Not Allowed ...',
|
||||
},
|
||||
NotAuthorized: {
|
||||
id: 202,
|
||||
message: 'Not Authorized ...',
|
||||
},
|
||||
NotVisible: {
|
||||
id: 203,
|
||||
message: 'Not Visible ...',
|
||||
},
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region User/Registration/Account/Bann Exceptions 3xx ...
|
||||
AccountLockedOut: {
|
||||
id: 300,
|
||||
message: 'Account Locked out Until: (%$s)',
|
||||
},
|
||||
LoginFailed: {
|
||||
id: 301,
|
||||
message: 'Login Failed ...',
|
||||
},
|
||||
UserRegisteredBefore: {
|
||||
id: 302,
|
||||
message: 'User Registered Before ...',
|
||||
},
|
||||
UserDisabled: {
|
||||
id: 303,
|
||||
message: 'User Disabled ...',
|
||||
},
|
||||
DeviceBanned: {
|
||||
id: 304,
|
||||
message: 'Device Banned Until:(%$s)',
|
||||
},
|
||||
VerificationCodeResendNotAllowed: {
|
||||
id: 305,
|
||||
message: `You can't Request Verification code Until:(%$s)`,
|
||||
},
|
||||
PasswordsSame: {
|
||||
id: 306,
|
||||
message: 'Passwords Same ...',
|
||||
},
|
||||
MobilesSame: {
|
||||
id: 307,
|
||||
message: 'Mobiles Same ...',
|
||||
},
|
||||
EmailsSame: {
|
||||
id: 308,
|
||||
message: 'Emails Same ...',
|
||||
},
|
||||
MobileInUsed: {
|
||||
id: 309,
|
||||
message: 'Mobile In Used ...',
|
||||
},
|
||||
EmailInUsed: {
|
||||
id: 310,
|
||||
message: 'Email In Used ...',
|
||||
},
|
||||
MobileNotConfirmed: {
|
||||
id: 311,
|
||||
message: 'Mobile Not Confirmed ...',
|
||||
},
|
||||
EmailNotConfirmed: {
|
||||
id: 312,
|
||||
message: 'Email Not Confirmed ...',
|
||||
},
|
||||
PostBanned: {
|
||||
id: 313,
|
||||
message: 'Post Banned ...',
|
||||
},
|
||||
UserBanned: {
|
||||
id: 314,
|
||||
message: 'User Banned ...',
|
||||
},
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region General Exceptions 4xx ...
|
||||
Unknown: {
|
||||
id: 400,
|
||||
message: 'Unknown Error ...',
|
||||
},
|
||||
Duplicate: {
|
||||
id: 401,
|
||||
message: 'Duplicate ...',
|
||||
},
|
||||
ActionFailed: {
|
||||
id: 402,
|
||||
message: 'Action Failed ...',
|
||||
},
|
||||
ExpiredDate: {
|
||||
id: 403,
|
||||
message: 'Expired Date ...',
|
||||
},
|
||||
Unavailable: {
|
||||
id: 404,
|
||||
message: 'Unavailable ...',
|
||||
},
|
||||
MaxAllowedTagExceeded: {
|
||||
id: 405,
|
||||
message: 'Max Allowed Tag Exceeded ...',
|
||||
},
|
||||
Timeout: {
|
||||
id: 406,
|
||||
message: 'Timed out ...',
|
||||
},
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region File Exceptions 5xx ...
|
||||
EmptyFile: {
|
||||
id: 500,
|
||||
message: 'Empty File ...',
|
||||
},
|
||||
MaxFileSizeExceeded: {
|
||||
id: 501,
|
||||
message: 'max File size exceeded ...',
|
||||
},
|
||||
UnsupportedFileType: {
|
||||
id: 502,
|
||||
message: 'Unsupported File Type ...',
|
||||
},
|
||||
MaxAllowedMediaExceeded: {
|
||||
id: 503,
|
||||
message: 'Max Allowed Media Exceeded ...',
|
||||
},
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Configuration Exceptions 6xx ...
|
||||
InvalidConfiguration: {
|
||||
id: 600,
|
||||
message: 'Invalid Configuration ...',
|
||||
},
|
||||
StorageServiceInitialFailed: {
|
||||
id: 601,
|
||||
message: 'Storage Service Initiallization Failed ...',
|
||||
},
|
||||
MessageServiceInitialFailed: {
|
||||
id: 602,
|
||||
message: 'Message Service Initialization Failed ...',
|
||||
},
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region xFramework Exceptions 9xx ...
|
||||
MaxAllowedFilesExceeded: {
|
||||
id: 900,
|
||||
message: 'Max Allowed Files Exceeded ...',
|
||||
},
|
||||
MinFilesSizeExceeded: {
|
||||
id: 901,
|
||||
message: 'Min Files Size not Exceeded ...',
|
||||
},
|
||||
MaxFilesSizeExceeded: {
|
||||
id: 902,
|
||||
message: 'Max Files Size Exceeded ...',
|
||||
},
|
||||
MustAcceptTerms: {
|
||||
id: 903,
|
||||
message: 'Must Accept Terms And Conditions ...',
|
||||
},
|
||||
UnsupportedBrowser: {
|
||||
id: 904,
|
||||
message: 'Browser does not support location services ...',
|
||||
},
|
||||
PermissionDenied: {
|
||||
id: 905,
|
||||
message: 'You have rejected access to your location ...',
|
||||
},
|
||||
PositionUnavailable: {
|
||||
id: 906,
|
||||
message: 'Unable to determine your location ...',
|
||||
},
|
||||
StorageNotSupported: {
|
||||
id: 907,
|
||||
message: 'Service timeout has been reached ...',
|
||||
},
|
||||
MustLogout: {
|
||||
id: 908,
|
||||
message: `logged in user's can't access to this content ...`,
|
||||
},
|
||||
InvalidLocale: {
|
||||
id: 909,
|
||||
message: 'Invalid Locale ...',
|
||||
},
|
||||
InvalidUserSelector: {
|
||||
id: 910,
|
||||
message: 'Invalid User Selector ...',
|
||||
},
|
||||
//#endregion
|
||||
};
|
||||
@@ -0,0 +1,588 @@
|
||||
//
|
||||
//#region XFile Types ...
|
||||
export enum XFileType {
|
||||
Image,
|
||||
ProfileImage,
|
||||
CoverImage,
|
||||
Audio,
|
||||
Video,
|
||||
Document,
|
||||
}
|
||||
|
||||
export enum XGeneralThumbnails {
|
||||
UNKNOWN = 'unknown',
|
||||
IMAGE = 'image',
|
||||
AUDIO = 'audio',
|
||||
VIDEO = 'video',
|
||||
DOCUMENT = 'document',
|
||||
}
|
||||
|
||||
export const TypesMatcher = {
|
||||
IMAGE: 'image',
|
||||
VIDEO: 'video',
|
||||
AUDIO: 'audio',
|
||||
};
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region File Extensions ...
|
||||
export enum XAudioFileExtensions {
|
||||
Aif = '.aif',
|
||||
Cda = '.cda',
|
||||
Iff = '.iff',
|
||||
Mid = '.mid',
|
||||
Midi = '.midi',
|
||||
Mp3 = '.mp3',
|
||||
Mpa = '.mpa',
|
||||
Wav = '.wav',
|
||||
Wma = '.wma',
|
||||
Wpl = '.wpl',
|
||||
Aa = '.aa',
|
||||
Aac = '.aac',
|
||||
Aax = '.aax',
|
||||
Act = '.act',
|
||||
Aiff = '.aiff',
|
||||
Alac = '.alac',
|
||||
Amr = '.amr',
|
||||
Ape = '.ape',
|
||||
Au = '.au',
|
||||
Awb = '.awb',
|
||||
Dss = '.dss',
|
||||
Dvf = '.dvf',
|
||||
Flac = '.flac',
|
||||
Gsm = '.gsm',
|
||||
Iklax = '.iklax',
|
||||
Ivs = '.ivs',
|
||||
M4a = '.m4a',
|
||||
M4b = '.m4b',
|
||||
M4p = '.m4p',
|
||||
Mmf = '.mmf',
|
||||
Mpc = '.mpc',
|
||||
Msv = '.msv',
|
||||
Nmf = '.nmf',
|
||||
Ogg = '.ogg',
|
||||
Oga = '.oga',
|
||||
Mogg = '.mogg',
|
||||
Opus = '.opus',
|
||||
Ra = '.ra',
|
||||
Rm = '.rm',
|
||||
Raw = '.raw',
|
||||
Rf64 = '.rf64',
|
||||
Sln = '.sln',
|
||||
Tta = '.tta',
|
||||
Voc = '.voc',
|
||||
Vox = '.vox',
|
||||
Wv = '.wv',
|
||||
Eightsvx = '.8svx',
|
||||
}
|
||||
|
||||
export enum XVideoFileExtensions {
|
||||
Avi = '.avi',
|
||||
Flv = '.flv',
|
||||
H264 = '.h264',
|
||||
M4v = '.m4v',
|
||||
Mkv = '.mkv',
|
||||
Mov = '.mov',
|
||||
Mp4 = '.mp4',
|
||||
Mpg = '.mpg',
|
||||
Mpeg = '.mpeg',
|
||||
Rm = '.rm',
|
||||
Swf = '.swf',
|
||||
Vob = '.vob',
|
||||
Wmv = '.wmv',
|
||||
ThreeG2 = '.3g2',
|
||||
ThreeGp = '.3gp',
|
||||
Webm = '.webm',
|
||||
Viv = '.viv',
|
||||
Gifv = '.gifv',
|
||||
Svi = '.svi',
|
||||
Roq = '.roq',
|
||||
Rmvb = '.rmvb',
|
||||
Yuv = '.yuv',
|
||||
Qt = '.qt',
|
||||
Ogv = '.ogv',
|
||||
Ogg = '.ogg',
|
||||
Nsv = '.nsv',
|
||||
Mng = '.mng',
|
||||
M4p = '.m4p',
|
||||
M2v = '.m2v',
|
||||
Mp2 = '.mp2',
|
||||
Mpe = '.mpe',
|
||||
Mpv = '.mpv',
|
||||
Mts = '.mts',
|
||||
M2ts = '.m2ts',
|
||||
Mxf = '.mxf',
|
||||
Gif = '.gif',
|
||||
F4v = '.f4v',
|
||||
F4p = '.f4p',
|
||||
F4a = '.f4a',
|
||||
F4b = '.f4b',
|
||||
Drc = '.drc',
|
||||
Amv = '.amv',
|
||||
Asf = '.asf',
|
||||
}
|
||||
|
||||
export enum XImageFileExtensions {
|
||||
Ai = '.ai',
|
||||
Bmp = '.bmp',
|
||||
Gif = '.gif',
|
||||
Jpeg = '.jpeg',
|
||||
Jpg = '.jpg',
|
||||
Max = '.max',
|
||||
Obj = '.obj',
|
||||
Png = '.png',
|
||||
Ps = '.ps',
|
||||
Psd = '.psd',
|
||||
Svg = '.svg',
|
||||
Tif = '.tif',
|
||||
Tiff = '.tiff',
|
||||
Threeds = '.3ds',
|
||||
Threedm = '.3dm',
|
||||
Ico = '.ico',
|
||||
Icns = '.icns',
|
||||
}
|
||||
|
||||
export enum XDocumentFileExtensions {
|
||||
Asp = '.asp',
|
||||
Aspx = '.aspx',
|
||||
Cer = '.cer',
|
||||
Cfm = '.cfm',
|
||||
Cgi = '.cgi',
|
||||
Pl = '.pl',
|
||||
Cs = '.cs',
|
||||
Css = '.css',
|
||||
SCss = '.scss',
|
||||
Htm = '.htm',
|
||||
Html = '.html',
|
||||
Js = '.js',
|
||||
Jsp = '.jsp',
|
||||
JSON = '.json',
|
||||
MD = '.md',
|
||||
VSCodeWorkspace = '.code-workspace',
|
||||
Part = '.part',
|
||||
Php = '.php',
|
||||
Rss = '.rss',
|
||||
Xhtml = '.xhtml',
|
||||
Bak = '.bak',
|
||||
Cfg = '.cfg',
|
||||
Cpl = '.cpl',
|
||||
Cur = '.cur',
|
||||
Dll = '.dll',
|
||||
Dmp = '.dmp',
|
||||
Drv = '.drv',
|
||||
Ini = '.ini',
|
||||
Lnk = '.lnk',
|
||||
Msi = '.msi',
|
||||
Sys = '.sys',
|
||||
Tmp = '.tmp',
|
||||
Accdb = '.accdb',
|
||||
Csv = '.csv',
|
||||
Dat = '.dat',
|
||||
Db = '.db',
|
||||
Dbf = '.dbf',
|
||||
Log = '.log',
|
||||
Mdb = '.mdb',
|
||||
Pdb = '.pdb',
|
||||
Sav = '.sav',
|
||||
Sql = '.sql',
|
||||
Tar = '.tar',
|
||||
TarGz = '.tar.gz',
|
||||
Key = '.key',
|
||||
Odp = '.odp',
|
||||
Pps = '.pps',
|
||||
Ppt = '.ppt',
|
||||
Pptx = '.pptx',
|
||||
Ods = '.ods',
|
||||
Xlr = '.xlr',
|
||||
Xls = '.xls',
|
||||
Xlsx = '.xlsx',
|
||||
Doc = '.doc',
|
||||
Docx = '.docx',
|
||||
Odt = '.odt',
|
||||
Msg = '.msg',
|
||||
Pdf = '.pdf',
|
||||
Rtf = '.rtf',
|
||||
Tex = '.tex',
|
||||
Txt = '.txt',
|
||||
Wks = '.wks',
|
||||
Wps = '.wps',
|
||||
Wpd = '.wpd',
|
||||
Apk = '.apk',
|
||||
Bat = '.bat',
|
||||
Com = '.com',
|
||||
Exe = '.exe',
|
||||
Py = '.py',
|
||||
Pyw = '.pyw',
|
||||
Wsf = '.wsf',
|
||||
Appx = '.appx',
|
||||
SevenZ = '.7z',
|
||||
A = '.a',
|
||||
Aapkg = '.aapkg',
|
||||
Ace = '.ace',
|
||||
Alz = '.alz',
|
||||
Bke = '.bke',
|
||||
Arj = '.arj',
|
||||
B = '.b',
|
||||
Ba = '.ba',
|
||||
Bin = '.bin',
|
||||
Bz2 = '.bz2',
|
||||
Xaml = '.xaml',
|
||||
Deb = '.deb',
|
||||
Dmg = '.dmg',
|
||||
Dn = '.dn',
|
||||
Egg = '.egg',
|
||||
Egt = '.egt',
|
||||
Ezip = '.ezip',
|
||||
Ess = '.ess',
|
||||
Gz = '.gz',
|
||||
Ipg = '.ipg',
|
||||
Jar = '.jar',
|
||||
Lzh = '.lzh',
|
||||
Lz = '.lz',
|
||||
Lzo = '.lzo',
|
||||
Lzma = '.lzma',
|
||||
Mhtml = '.mhtml',
|
||||
Nth = '.nth',
|
||||
Oar = '.oar',
|
||||
Pak = '.pak',
|
||||
Par = '.par',
|
||||
Par2 = '.par2',
|
||||
Paf = '.paf',
|
||||
Pea = '.pea',
|
||||
Pyk = '.pyk',
|
||||
Pk3 = '.pk3',
|
||||
Pk4 = '.pk4',
|
||||
Pxz = '.pxz',
|
||||
Rar = '.rar',
|
||||
Sis = '.sis',
|
||||
Sisx = '.sisx',
|
||||
Skb = '.skb',
|
||||
Sq = '.sq',
|
||||
Tib = '.tib',
|
||||
Xap = '.xap',
|
||||
Xz = '.xz',
|
||||
Z = '.z',
|
||||
Ts = '.ts',
|
||||
Zoo = '.zoo',
|
||||
Zip = '.zip',
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region File Extension Descriptions ...
|
||||
export enum XAudioFileExtensionDescriptions {
|
||||
Aif = 'AIF/Audio Interchange audio',
|
||||
Cda = 'CD audio track',
|
||||
Iff = 'Interchange File Format',
|
||||
Mid = 'MIDI audio',
|
||||
Midi = 'MIDI audio',
|
||||
Mp3 = 'MPEG Layer III Audio',
|
||||
Mpa = 'MPEG-2 audio',
|
||||
Wav = 'Standard audio file container format',
|
||||
Wma = 'Windows Media Audio format',
|
||||
Wpl = 'Windows Media Player playlist',
|
||||
Aa = 'A low-bitrate audiobook container format',
|
||||
Aac = 'Advanced Audio Coding format',
|
||||
Aax = 'An Audiobook format',
|
||||
Act = 'lossy ADPCM 8 kbit/s compressed audio format',
|
||||
Aiff = 'Apple, A standard uncompressed CD-quality, audio file format',
|
||||
Alac = 'Apple, An audio coding format developed by Apple Inc',
|
||||
Amr = 'AMR-NB audio, used primarily for speech',
|
||||
Ape = "Monkey's Audio lossless audio compression format",
|
||||
Au = 'Sun Microsystems standard audio file format',
|
||||
Awb = 'AMR-WB audio, used primarily for speech',
|
||||
Dss = 'Olympus proprietary format',
|
||||
Dvf = 'A Sony proprietary format for compressed voice files',
|
||||
Flac = 'Free Lossless Audio Codec',
|
||||
Gsm = 'Designed for telephony use in Europe',
|
||||
Iklax = 'iKlax Media proprietary format',
|
||||
Ivs = 'Digital Rights Management developed by 3D Solar UK Ltd',
|
||||
M4a = 'audio-only MPEG-4 file, used by Apple for unprotected music',
|
||||
M4b = 'Audiobook / podcast extension with AAC or ALAC encoded audio in an MPEG-4 container',
|
||||
M4p = 'A version of AAC with proprietary Digital Rights Management developed by Apple for use in music downloaded from their iTunes Music Store and their music streaming service known as Apple Music',
|
||||
Mmf = 'Yamaha, Samsung A Samsung audio format',
|
||||
Mpc = 'Musepack, an open source lossy audio codec',
|
||||
Msv = 'Sony proprietary format for Memory Stick compressed voice',
|
||||
Nmf = 'NICE Media Player audio',
|
||||
Ogg = 'Xiph.Org Foundation A free, open source container format',
|
||||
Oga = 'Xiph.Org Foundation A free, open source container format',
|
||||
Mogg = 'Xiph.Org Foundation A free, open source container format',
|
||||
Opus = 'lossy audio compression format developed by the Internet Engineering Task Force (IETF) and made especially suitable for interactive real-time applications over the Internet',
|
||||
Ra = 'RealAudio format designed for streaming audio over the Internet',
|
||||
Rm = 'RealAudio format designed for streaming audio over the Internet',
|
||||
Raw = 'raw file can contain audio in any format',
|
||||
Rf64 = 'One successor to the Wav format',
|
||||
Sln = 'Signed Linear PCM format used by Asterisk',
|
||||
Tta = 'The True Audio, real-time lossless audio codec',
|
||||
Voc = 'Creative Technology The file format',
|
||||
Vox = 'Adaptive Differential Pulse Code Modulation',
|
||||
Wv = 'Format for wavpack',
|
||||
Eightsvx = 'Electronic Arts The IFF-8SVX format for 8-bit sound samples',
|
||||
}
|
||||
|
||||
export enum XVideoFileExtensionDescriptions {
|
||||
Avi = 'Audio Video Interleave',
|
||||
Flv = 'Adobe Flash Video',
|
||||
H264 = 'H.264 Video',
|
||||
M4v = 'Apple MP4 Video, MPEG-4 Part 12',
|
||||
Mkv = 'Matroska Multimedia Container',
|
||||
Mov = 'Apple QuickTime Movie',
|
||||
Mp4 = 'MPEG-4 Video',
|
||||
Mpg = 'MPEG Video',
|
||||
Mpeg = 'MPEG Video',
|
||||
Rm = 'Real Media',
|
||||
Swf = 'Shockwave flash',
|
||||
Vob = 'DVD Video Object',
|
||||
Wmv = 'Windows Media Video',
|
||||
ThreeG2 = '3GPP2 Multimedia',
|
||||
ThreeGp = '3GPP multimedia',
|
||||
Webm = 'Royalty-free format created for HTML5 video',
|
||||
Viv = 'VivoActive based upon H.263 video',
|
||||
Gifv = 'Video alternative to GIF',
|
||||
Svi = 'Samsung video format for portable players',
|
||||
Roq = 'used by Quake',
|
||||
Rmvb = 'RealMedia Variable Bitrate',
|
||||
Yuv = 'Raw video format',
|
||||
Qt = 'QuickTime File Format',
|
||||
Ogv = 'Ogg Video',
|
||||
Ogg = 'Ogg Video',
|
||||
Nsv = 'Nullsoft Streaming Video',
|
||||
Mng = 'Multiple-image Network Graphics',
|
||||
M4p = 'MPEG-4 Part 14',
|
||||
M2v = 'MPEG-2 Part 3',
|
||||
Mp2 = 'MPEG-1 Part 2',
|
||||
Mpe = 'MPEG-1',
|
||||
Mpv = 'MPEG-1',
|
||||
Mts = 'MPEG Transport Stream',
|
||||
M2ts = 'MPEG Transport Stream',
|
||||
Mxf = 'Material Exchange Format',
|
||||
Gif = 'Simple animation, inefficient compression',
|
||||
F4v = 'Adobe Flash Video',
|
||||
F4p = 'Adobe Flash Video',
|
||||
F4a = 'Adobe Flash Video',
|
||||
F4b = 'Adobe Flash Video',
|
||||
Drc = 'Dirac',
|
||||
Amv = 'Modified version of AVI',
|
||||
Asf = 'Advanced Systems Format',
|
||||
}
|
||||
|
||||
export enum XImageFileExtensionDescriptions {
|
||||
Ai = 'Adobe Illustrator',
|
||||
Bmp = 'Bitmap image',
|
||||
Gif = 'Graphical Interchange Format',
|
||||
Jpeg = 'Joints Photographic Experts Group',
|
||||
Jpg = 'Joints Photographic Experts Group',
|
||||
Max = '3ds Max Scene',
|
||||
Obj = 'Wavefront 3D Object',
|
||||
Png = 'Portable Network Graphic image',
|
||||
Ps = 'PostScript',
|
||||
Psd = 'Adobe Photoshop Document image',
|
||||
Svg = 'Scalable Vector Graphics',
|
||||
Tif = 'TIFF image',
|
||||
Tiff = 'TIFF image',
|
||||
Threeds = '3D Studio Scene',
|
||||
Threedm = 'Rhino 3D Model',
|
||||
Ico = 'Icon',
|
||||
Icns = 'macOS X icon resource',
|
||||
}
|
||||
|
||||
export enum XDocumentFileExtensionDescriptions {
|
||||
Asp = 'Active Server Page',
|
||||
Aspx = 'Active Server Page',
|
||||
Cer = 'Internet security certificate',
|
||||
Cfm = 'ColdFusion Markup',
|
||||
Cgi = 'Common Gateway Interface Script',
|
||||
Pl = 'Perl script',
|
||||
Cs = 'C# document',
|
||||
Css = 'Cascading Style Sheet',
|
||||
SCss = 'Sass and Less Style Sheet',
|
||||
Htm = 'Hypertext Markup Language',
|
||||
Html = 'Hypertext Markup Language',
|
||||
Js = 'JavaScript',
|
||||
Jsp = 'Java Server Page',
|
||||
JSON = 'Java Script Object Notation',
|
||||
MD = 'Markdown',
|
||||
VSCodeWorkspace = 'VSCode Workspace',
|
||||
Part = 'Partially downloaded',
|
||||
Php = 'PHP Source Code',
|
||||
Rss = 'Rich Site Summary',
|
||||
Xhtml = 'Extensible Hypertext Markup Language',
|
||||
Bak = 'Backup',
|
||||
Cfg = 'Configuration',
|
||||
Cpl = 'Windows Control panel',
|
||||
Cur = 'Windows cursor',
|
||||
Dll = 'Dynamic Link Library',
|
||||
Dmp = 'Dump',
|
||||
Drv = 'Device driver',
|
||||
Ini = 'Initialization',
|
||||
Lnk = 'Windows shortcut',
|
||||
Msi = 'Windows installer package',
|
||||
Sys = 'Windows system',
|
||||
Tmp = 'Temporary',
|
||||
Accdb = 'Access 2007 Database',
|
||||
Csv = 'Comma separated value',
|
||||
Dat = 'Data',
|
||||
Db = 'Database',
|
||||
Dbf = 'Database',
|
||||
Log = 'Log',
|
||||
Mdb = 'Microsoft Access database',
|
||||
Pdb = 'Program Database',
|
||||
Sav = 'Save',
|
||||
Sql = 'Structured Query Language database',
|
||||
Tar = 'Linux / Unix tarball file archive',
|
||||
TarGz = 'gzipped tar',
|
||||
Key = 'Keynote presentation',
|
||||
Odp = 'OpenOffice Impress presentation',
|
||||
Pps = 'PowerPoint slide show',
|
||||
Ppt = 'PowerPoint presentation',
|
||||
Pptx = 'PowerPoint Open XML presentation',
|
||||
Ods = 'OpenOffice Calc spreadsheet',
|
||||
Xlr = 'Microsoft Works spreadsheet',
|
||||
Xls = 'Microsoft Excel',
|
||||
Xlsx = 'Microsoft Excel Open XML spreadsheet',
|
||||
Doc = 'Microsoft Word',
|
||||
Docx = 'Microsoft Word Open XML',
|
||||
Odt = 'OpenOffice Writer document',
|
||||
Msg = 'Outlook Mail Message',
|
||||
Pdf = 'Portable Document Format',
|
||||
Rtf = 'Rich Text Format',
|
||||
Tex = 'LaTeX document',
|
||||
Txt = 'Plain text',
|
||||
Wks = 'Lotus 1-2-3 Spreadsheet',
|
||||
Wps = 'Microsoft Works Word Processor Document',
|
||||
Wpd = 'WordPerfect document',
|
||||
Apk = 'Android package',
|
||||
Bat = 'Batch',
|
||||
Bin = 'Binary',
|
||||
Com = 'MS-DOS command',
|
||||
Exe = 'Executable',
|
||||
Jar = 'Java Archive',
|
||||
Py = 'Python',
|
||||
Pyw = 'Python',
|
||||
Wsf = 'Windows Script',
|
||||
Appx = 'Microsoft Application Package',
|
||||
SevenZ = '7-Zip compressed',
|
||||
A = 'An external file extension for C/C++',
|
||||
Aapkg = 'ArchestrA IDE',
|
||||
Ace = 'ACE compressed',
|
||||
Alz = 'ALZip compressed',
|
||||
Bke = 'BackupEarth.com data compression',
|
||||
Arj = 'ARJ compressed',
|
||||
B = 'Similar to .a, but less compressed',
|
||||
Ba = 'Scifer External Archive Type',
|
||||
Bz2 = 'bzip2',
|
||||
Xaml = 'Used in programs like Visual Studio to create exe files',
|
||||
Deb = 'Debian install package',
|
||||
Dmg = 'Apple compressed/encrypted format',
|
||||
Dn = 'Adobe Dimension CC file format',
|
||||
Egg = 'Alzip Egg Edition compressed',
|
||||
Egt = 'EGT Universal Document',
|
||||
Ezip = 'EGT Compressed Folder',
|
||||
Ess = 'SmartSense',
|
||||
Gz = 'Compressed',
|
||||
Ipg = 'Format in which Apple Inc. packages their iPod games',
|
||||
Lzh = 'Lempel, Ziv, Huffman',
|
||||
Lz = 'Lempel, Ziv',
|
||||
Lzo = 'Lempel, Ziv',
|
||||
Lzma = 'Lempel Ziv Markov chain algorithm compressed',
|
||||
Mhtml = 'Mime HTML (Hyper-Text Markup Language) code',
|
||||
Nth = 'Nokia Theme Used by Nokia Series 40 Cellphones',
|
||||
Oar = 'OAR archive',
|
||||
Pak = 'Enhanced type of .ARC archive',
|
||||
Par = 'Parchive',
|
||||
Par2 = 'Parchive',
|
||||
Paf = 'Portable Application File',
|
||||
Pea = 'PeaZip archive',
|
||||
Pyk = 'Compressed',
|
||||
Pk3 = 'Quake 3 archive',
|
||||
Pk4 = 'Opens similarly to a zip archive.',
|
||||
Pxz = 'A compressed layered image',
|
||||
Rar = 'Rar Archive',
|
||||
Sis = 'Symbian Application Package',
|
||||
Sisx = 'Symbian Application Package',
|
||||
Skb = 'Google SketchUp backup',
|
||||
Sq = 'Squish Compressed Archive',
|
||||
Tib = 'Acronis True Image backup',
|
||||
Xap = 'Windows Phone Application Package',
|
||||
Xz = 'xz compressed files, based on LZMA/LZMA2 algorithm',
|
||||
Z = 'Unix compress',
|
||||
Ts = 'Typescript',
|
||||
Zoo = 'based on LZW',
|
||||
Zip = 'popular compression format',
|
||||
}
|
||||
//#endregion
|
||||
|
||||
export type XFileExtensions =
|
||||
| XAudioFileExtensions
|
||||
| XVideoFileExtensions
|
||||
| XImageFileExtensions
|
||||
| XDocumentFileExtensions;
|
||||
|
||||
export type XFileExtensionDescriptions =
|
||||
| XAudioFileExtensionDescriptions
|
||||
| XVideoFileExtensionDescriptions
|
||||
| XImageFileExtensionDescriptions
|
||||
| XDocumentFileExtensionDescriptions;
|
||||
|
||||
//
|
||||
//#region Files Informations Constants ...
|
||||
//
|
||||
const XImageFileKeys = Object.keys(Object.assign({}, XImageFileExtensions));
|
||||
const XImageFilesInfo = XImageFileKeys.map((ik) => {
|
||||
return {
|
||||
identifier: ik,
|
||||
type: XFileType.Image,
|
||||
typeIdentifier: XGeneralThumbnails.IMAGE,
|
||||
extension: XImageFileExtensions[ik],
|
||||
description: XImageFileExtensionDescriptions[ik],
|
||||
};
|
||||
});
|
||||
|
||||
//
|
||||
const XAudioFileKeys = Object.keys(Object.assign({}, XAudioFileExtensions));
|
||||
const XAudioFilesInfo = XAudioFileKeys.map((ik) => {
|
||||
return {
|
||||
identifier: ik,
|
||||
type: XFileType.Audio,
|
||||
typeIdentifier: XGeneralThumbnails.AUDIO,
|
||||
extension: XAudioFileExtensions[ik],
|
||||
description: XAudioFileExtensionDescriptions[ik],
|
||||
};
|
||||
});
|
||||
|
||||
//
|
||||
const XVideoFileKeys = Object.keys(Object.assign({}, XVideoFileExtensions));
|
||||
const XVideoFilesInfo = XVideoFileKeys.map((ik) => {
|
||||
return {
|
||||
identifier: ik,
|
||||
type: XFileType.Video,
|
||||
typeIdentifier: XGeneralThumbnails.VIDEO,
|
||||
extension: XVideoFileExtensions[ik],
|
||||
description: XVideoFileExtensionDescriptions[ik],
|
||||
};
|
||||
});
|
||||
|
||||
//
|
||||
const XDocumentFileKeys = Object.keys(
|
||||
Object.assign({}, XDocumentFileExtensions)
|
||||
);
|
||||
const XDocumentFilesInfo = XDocumentFileKeys.map((ik) => {
|
||||
return {
|
||||
identifier: ik,
|
||||
type: XFileType.Document,
|
||||
typeIdentifier: XGeneralThumbnails.DOCUMENT,
|
||||
extension: XDocumentFileExtensions[ik],
|
||||
description: XDocumentFileExtensionDescriptions[ik],
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* provides all informations about supported files ...
|
||||
*/
|
||||
export const XFileInfos = [
|
||||
...XImageFilesInfo,
|
||||
...XVideoFilesInfo,
|
||||
...XAudioFilesInfo,
|
||||
...XDocumentFilesInfo,
|
||||
];
|
||||
//#endregion
|
||||
@@ -0,0 +1,24 @@
|
||||
export enum XHeader {
|
||||
File = 'file',
|
||||
Files = 'files',
|
||||
Scope = 'scope',
|
||||
Accept = 'Accept',
|
||||
ExpiresAt = 'expires_at',
|
||||
XPoweredBy = 'X-PoweredBy',
|
||||
ActionToken = 'actionToken',
|
||||
ContentType = 'Content-Type',
|
||||
RefreshToken = 'refresh_token',
|
||||
Authorization = 'Authorization',
|
||||
AuthorizationPrefix = 'Bearer ',
|
||||
RevisionChecksum = 'revision_checksum',
|
||||
RejectUnauthorized = 'rejectUnauthorized',
|
||||
}
|
||||
|
||||
export enum XContentType {
|
||||
AppJson = 'application/json',
|
||||
AppOctetStream = 'application/octet-stream',
|
||||
}
|
||||
|
||||
export function getAuthorizationHeaderValue(token: string) {
|
||||
return `${XHeader.AuthorizationPrefix}${token}`;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
export enum XParam {
|
||||
//
|
||||
// QueryParams and Headers ...
|
||||
Id = 'id',
|
||||
ReturnUrl = 'ru',
|
||||
Type = 'type',
|
||||
//
|
||||
Errors = 'errors',
|
||||
//
|
||||
Item = 'item',
|
||||
Items = 'items',
|
||||
//
|
||||
Option = 'option',
|
||||
Options = 'options',
|
||||
//
|
||||
HasBack = 'b',
|
||||
//
|
||||
// Header
|
||||
Language = 'language',
|
||||
//
|
||||
// XQuery interface Params ...
|
||||
Filter = 'Filter',
|
||||
ContainsDetail = 'ContainsDetail',
|
||||
EnableTracking = 'EnableTracking',
|
||||
SortBy = 'SortBy',
|
||||
IsAscending = 'IsAscending',
|
||||
Page = 'Page',
|
||||
PageSize = 'PageSize',
|
||||
//
|
||||
// XPageRequest interface Params ...
|
||||
First = 'First',
|
||||
Last = 'Last',
|
||||
After = 'After',
|
||||
Before = 'Before',
|
||||
DescendingSort = 'DescendingSort',
|
||||
//
|
||||
// Exception ...
|
||||
Exception = 'ex',
|
||||
}
|
||||
//#endregion
|
||||
|
||||
export type XParamIdentifier = XParam | string;
|
||||
@@ -0,0 +1,3 @@
|
||||
export enum XSettingsStorageKey {
|
||||
Locale = '[SETTINGS] Locale'
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
export enum XResourceIDs {
|
||||
//
|
||||
//#region App ...
|
||||
app_name,
|
||||
company,
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Commons ...
|
||||
id,
|
||||
file_name,
|
||||
//
|
||||
error,
|
||||
required,
|
||||
|
||||
//
|
||||
loading,
|
||||
|
||||
//
|
||||
username,
|
||||
password,
|
||||
|
||||
//
|
||||
first_name,
|
||||
last_name,
|
||||
|
||||
//
|
||||
verified,
|
||||
unverified,
|
||||
|
||||
//
|
||||
thumbnail,
|
||||
language,
|
||||
|
||||
//
|
||||
take_screenshot,
|
||||
enable_capture_mode,
|
||||
disable_capture_mode,
|
||||
|
||||
//
|
||||
be,
|
||||
not_to_be,
|
||||
enabled,
|
||||
disabled,
|
||||
banned,
|
||||
un_banned,
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region File Types ...
|
||||
audio,
|
||||
video,
|
||||
document,
|
||||
cover_image,
|
||||
image,
|
||||
avatar,
|
||||
unknown,
|
||||
location,
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Messages ...
|
||||
are_you_sure,
|
||||
success_msg,
|
||||
locked_msg,
|
||||
empty_content,
|
||||
no_item,
|
||||
drag_drop_here,
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Components ...
|
||||
map_dialog_title,
|
||||
map_dialog_select_title,
|
||||
color_picker_dialog_title,
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Verbs ...
|
||||
dismiss,
|
||||
accept,
|
||||
ok,
|
||||
save,
|
||||
cancel,
|
||||
retry,
|
||||
edit,
|
||||
reset,
|
||||
change,
|
||||
start,
|
||||
yes,
|
||||
no,
|
||||
verify,
|
||||
confirm,
|
||||
crop,
|
||||
clear,
|
||||
set,
|
||||
select,
|
||||
send,
|
||||
show,
|
||||
hide,
|
||||
search,
|
||||
delete,
|
||||
clone,
|
||||
select_all,
|
||||
select_file,
|
||||
select_all_group,
|
||||
deselect_all,
|
||||
deselect_all_group,
|
||||
inverse_selection,
|
||||
selected_location,
|
||||
color,
|
||||
colors,
|
||||
preset_colors,
|
||||
copy_to_clipboard,
|
||||
//
|
||||
upload,
|
||||
import,
|
||||
continue,
|
||||
finish,
|
||||
enable,
|
||||
disable,
|
||||
//
|
||||
all,
|
||||
new,
|
||||
add,
|
||||
update,
|
||||
details,
|
||||
translation,
|
||||
|
||||
//
|
||||
download,
|
||||
list,
|
||||
options,
|
||||
descriptions,
|
||||
|
||||
//
|
||||
type,
|
||||
|
||||
//
|
||||
media,
|
||||
medias,
|
||||
|
||||
//
|
||||
go,
|
||||
input,
|
||||
preview,
|
||||
|
||||
//
|
||||
close,
|
||||
undo,
|
||||
redo,
|
||||
|
||||
//
|
||||
refresh,
|
||||
|
||||
//
|
||||
submit,
|
||||
|
||||
//
|
||||
//#region Pagination ...
|
||||
first,
|
||||
last,
|
||||
previous,
|
||||
next,
|
||||
back,
|
||||
//#endregion
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Themes Related ...
|
||||
//
|
||||
theme,
|
||||
theme_mode,
|
||||
//
|
||||
theme_dark,
|
||||
theme_light,
|
||||
//
|
||||
theme_name,
|
||||
theme_name_description,
|
||||
//
|
||||
theme_clone_title,
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Color Picker Related ...
|
||||
input_color_title,
|
||||
input_color_description,
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Markdown Component ...
|
||||
x_markdown_preview,
|
||||
x_markdown_image,
|
||||
x_markdown_link,
|
||||
x_markdown_ol,
|
||||
x_markdown_ul,
|
||||
x_markdown_quote,
|
||||
x_markdown_code,
|
||||
x_markdown_heading,
|
||||
x_markdown_italic,
|
||||
x_markdown_bold,
|
||||
x_markdown_guide,
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region XIDE Component ...
|
||||
ide_mode,
|
||||
ide_format,
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Password Validation Errors ...
|
||||
required_length,
|
||||
required_unique_chars,
|
||||
require_digit,
|
||||
require_lowercase,
|
||||
require_uppercase,
|
||||
require_non_alphanumeric,
|
||||
//#endregion
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export const DEFAULT_JAVASCRIPT_VOID_HREF = 'javascript:void(0)';
|
||||
@@ -0,0 +1,47 @@
|
||||
import {
|
||||
Input,
|
||||
Output,
|
||||
Directive,
|
||||
HostListener,
|
||||
EventEmitter
|
||||
} from '@angular/core';
|
||||
import { isNullOrEmptyString } from '../tools/x-type-detect.tools';
|
||||
|
||||
@Directive({
|
||||
// tslint:disable-next-line:directive-selector
|
||||
selector: '[xClipboard]'
|
||||
})
|
||||
export class XClipboardDirective {
|
||||
//
|
||||
@Input()
|
||||
clipData: string;
|
||||
|
||||
@Output()
|
||||
copied = new EventEmitter<string>();
|
||||
|
||||
@HostListener('click', ['$event'])
|
||||
whenClicked(event: MouseEvent) {
|
||||
event.preventDefault();
|
||||
|
||||
//
|
||||
if (isNullOrEmptyString(this.clipData)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
const listener = (e: ClipboardEvent) => {
|
||||
//
|
||||
// tslint:disable-next-line:no-string-literal
|
||||
const clipboard = e.clipboardData || window['clipboardData'];
|
||||
clipboard.setData('text', this.clipData);
|
||||
e.preventDefault();
|
||||
|
||||
this.copied.emit(this.clipData);
|
||||
};
|
||||
|
||||
//
|
||||
document.addEventListener('copy', listener, false);
|
||||
document.execCommand('copy');
|
||||
document.removeEventListener('copy', listener, false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
import {
|
||||
Input,
|
||||
Renderer2,
|
||||
OnChanges,
|
||||
Directive,
|
||||
ElementRef,
|
||||
SimpleChanges,
|
||||
} from '@angular/core';
|
||||
import {
|
||||
getXColorClassName,
|
||||
getXColorForegroundClassName,
|
||||
} from '../tools/x-color.tools';
|
||||
import { keys } from '../tools/x-object.tools';
|
||||
import { XStandardType } from '../typings/x.typings';
|
||||
import { concatMap, map, first } from 'rxjs/operators';
|
||||
import { toObservable } from '../tools/x-observable.tools';
|
||||
import { isNullOrEmptyString } from '../tools/x-type-detect.tools';
|
||||
import { XColorIdentifier, XColor } from '../typings/x-color.typings';
|
||||
|
||||
/**
|
||||
* this directive used to apply an specific color on an element ...
|
||||
*/
|
||||
@Directive({
|
||||
// tslint:disable-next-line:directive-selector
|
||||
selector: '[xColor]',
|
||||
})
|
||||
export class XColorDirective implements OnChanges {
|
||||
//
|
||||
private COLOR_CLASS: string;
|
||||
|
||||
//
|
||||
/**
|
||||
* a color identifier to apply on element ...
|
||||
*/
|
||||
// tslint:disable-next-line:no-input-rename
|
||||
@Input('xColor')
|
||||
xColor: XStandardType<XColorIdentifier>;
|
||||
|
||||
/**
|
||||
* determines the selected color must apply on foreground or background of element
|
||||
*/
|
||||
@Input()
|
||||
isForeground: XStandardType<boolean> = false;
|
||||
|
||||
//
|
||||
constructor(private element: ElementRef, private renderer: Renderer2) {}
|
||||
|
||||
//
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
//
|
||||
const changeKeys = keys(changes);
|
||||
if (changeKeys.includes('xColor') || changeKeys.includes('isForeground')) {
|
||||
this.handleColorChanges();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
private handleColorChanges() {
|
||||
//
|
||||
toObservable(this.xColor)
|
||||
.pipe(
|
||||
concatMap((color) => {
|
||||
return toObservable(this.isForeground).pipe(
|
||||
map((isForeground) => {
|
||||
return {
|
||||
color,
|
||||
isForeground,
|
||||
};
|
||||
})
|
||||
);
|
||||
}),
|
||||
first()
|
||||
)
|
||||
.subscribe((info) => {
|
||||
//
|
||||
if (!info.color) {
|
||||
info.color = XColor.Dark;
|
||||
}
|
||||
|
||||
//
|
||||
const colorClassName = info.isForeground
|
||||
? getXColorForegroundClassName(info.color)
|
||||
: getXColorClassName(info.color);
|
||||
|
||||
//
|
||||
if (!isNullOrEmptyString(this.COLOR_CLASS)) {
|
||||
this.renderer.removeClass(
|
||||
this.element.nativeElement,
|
||||
this.COLOR_CLASS
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
this.COLOR_CLASS = colorClassName;
|
||||
this.renderer.addClass(this.element.nativeElement, colorClassName);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,235 @@
|
||||
import {
|
||||
Input,
|
||||
Output,
|
||||
Renderer2,
|
||||
Directive,
|
||||
ElementRef,
|
||||
EventEmitter,
|
||||
HostListener,
|
||||
} from '@angular/core';
|
||||
import {
|
||||
getXColorClassName,
|
||||
getXColorForegroundClassName,
|
||||
} from '../tools/x-color.tools';
|
||||
import { hasChild } from '../tools/x-array.tools';
|
||||
import { XOneOrManyType } from '../typings/x.typings';
|
||||
import { isArray, isString } from '../tools/x-type-detect.tools';
|
||||
import { XColorIdentifier, XColor } from '../typings/x-color.typings';
|
||||
import { getExtension, isExistsExtension } from '../tools/x-file.tools';
|
||||
|
||||
@Directive({
|
||||
// tslint:disable-next-line:directive-selector
|
||||
selector: '[xDroppable]',
|
||||
})
|
||||
export class XDroppableDirective {
|
||||
//
|
||||
private DISABLED: boolean;
|
||||
private COLOR_CLASSES: string[] = [];
|
||||
|
||||
//
|
||||
@Input()
|
||||
disableFileCheck = false;
|
||||
|
||||
@Input()
|
||||
public allowedExtensions: XOneOrManyType<string> = [];
|
||||
|
||||
@Input()
|
||||
public successColor: XColorIdentifier = XColor.Success;
|
||||
|
||||
@Input()
|
||||
public errorColor: XColorIdentifier = XColor.Danger;
|
||||
|
||||
@Input()
|
||||
public accentColor: XColorIdentifier = XColor.Secondary;
|
||||
|
||||
@Input()
|
||||
public supportsMultipleFiles = true;
|
||||
|
||||
@Input()
|
||||
public isForegroundColor = false;
|
||||
|
||||
@Input()
|
||||
set dragDisabled(value: boolean) {
|
||||
//
|
||||
if (value !== this.DISABLED) {
|
||||
//
|
||||
this.DISABLED = value;
|
||||
if (!value) {
|
||||
this.setBackgroundColor('transparent');
|
||||
} else {
|
||||
this.setBackgroundColor(this.successColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Input()
|
||||
set error(val: boolean) {
|
||||
if (val) {
|
||||
this.setBackgroundColor(this.errorColor);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.DISABLED) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setBackgroundColor('transparent');
|
||||
}
|
||||
|
||||
@Output()
|
||||
public filesChangeEmiter: EventEmitter<File | File[]> = new EventEmitter();
|
||||
|
||||
constructor(private elementRef: ElementRef, private renderer: Renderer2) {}
|
||||
|
||||
@HostListener('dragover', ['$event'])
|
||||
public async onDragOver(event: any) {
|
||||
//
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
//
|
||||
if (this.DISABLED) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
await this.setBackgroundColor(this.accentColor);
|
||||
}
|
||||
|
||||
@HostListener('dragleave', ['$event'])
|
||||
public async onDragLeave(event: any) {
|
||||
//
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
//
|
||||
if (this.DISABLED) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
await this.setBackgroundColor('transparent');
|
||||
}
|
||||
|
||||
@HostListener('drop', ['$event'])
|
||||
public async onDrop(event: DragEvent) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
//
|
||||
if (this.DISABLED) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
const files = Array.from(event.dataTransfer.files);
|
||||
if (files.length === 0) {
|
||||
await this.setBackgroundColor(this.errorColor);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve Allowen Extensions ...
|
||||
let allowedExtensions: string[] = [];
|
||||
if (isArray(this.allowedExtensions)) {
|
||||
allowedExtensions = this.allowedExtensions as string[];
|
||||
} else if (isString(this.allowedExtensions)) {
|
||||
allowedExtensions.push(this.allowedExtensions as string);
|
||||
}
|
||||
|
||||
//
|
||||
if (!this.disableFileCheck) {
|
||||
if (files.length === 1) {
|
||||
//
|
||||
const file = files[0];
|
||||
const ext = getExtension(file.name);
|
||||
|
||||
//
|
||||
let isAllowed = true;
|
||||
|
||||
if (hasChild(allowedExtensions)) {
|
||||
isAllowed = isExistsExtension(allowedExtensions, ext);
|
||||
}
|
||||
|
||||
//
|
||||
if (isAllowed) {
|
||||
//
|
||||
await this.setBackgroundColor(this.successColor);
|
||||
} else {
|
||||
await this.setBackgroundColor(this.errorColor);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
this.filesChangeEmiter.emit(file);
|
||||
await this.setBackgroundColor('transparent');
|
||||
} else {
|
||||
//
|
||||
if (!this.supportsMultipleFiles) {
|
||||
await this.setBackgroundColor(this.errorColor);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
const isAllowedAll = !hasChild(allowedExtensions)
|
||||
? true
|
||||
: files.every((file) => {
|
||||
//
|
||||
const ext = getExtension(file.name);
|
||||
//
|
||||
let isAllowed = true;
|
||||
if (hasChild(allowedExtensions)) {
|
||||
isAllowed = isExistsExtension(allowedExtensions, ext);
|
||||
}
|
||||
|
||||
//
|
||||
return isAllowed;
|
||||
});
|
||||
|
||||
//
|
||||
if (isAllowedAll) {
|
||||
//
|
||||
await this.setBackgroundColor(this.successColor);
|
||||
} else {
|
||||
await this.setBackgroundColor(this.errorColor);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
this.filesChangeEmiter.emit(files);
|
||||
await this.setBackgroundColor('transparent');
|
||||
}
|
||||
} else {
|
||||
//
|
||||
this.filesChangeEmiter.emit(files);
|
||||
await this.setBackgroundColor('transparent');
|
||||
}
|
||||
}
|
||||
|
||||
private async setBackgroundColor(color: XColorIdentifier) {
|
||||
//
|
||||
if (!color) {
|
||||
color = 'transparent';
|
||||
}
|
||||
|
||||
//
|
||||
const colorClassName = this.isForegroundColor
|
||||
? getXColorForegroundClassName(color)
|
||||
: getXColorClassName(color);
|
||||
|
||||
//
|
||||
if (!this.COLOR_CLASSES.includes(colorClassName)) {
|
||||
this.COLOR_CLASSES.push(colorClassName);
|
||||
}
|
||||
|
||||
//
|
||||
if (hasChild(this.COLOR_CLASSES)) {
|
||||
this.COLOR_CLASSES.forEach((clz) => {
|
||||
this.renderer.removeClass(this.elementRef.nativeElement, clz);
|
||||
});
|
||||
}
|
||||
|
||||
//
|
||||
this.renderer.addClass(this.elementRef.nativeElement, colorClassName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
import {
|
||||
Input,
|
||||
Output,
|
||||
OnInit,
|
||||
OnChanges,
|
||||
Directive,
|
||||
OnDestroy,
|
||||
EventEmitter,
|
||||
SimpleChanges
|
||||
} from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { XFileType } from '../constants/x-file.enum';
|
||||
import { getFileType } from '../tools/x-file.tools';
|
||||
import { keys, nameof } from '../tools/x-object.tools';
|
||||
import { XFileReaderInputType } from '../typings/x.typings';
|
||||
|
||||
@Directive({
|
||||
// tslint:disable-next-line:directive-selector
|
||||
selector: '[xFileReader]'
|
||||
})
|
||||
export class XFileReaderDirective implements OnInit, OnChanges, OnDestroy {
|
||||
//
|
||||
private UNSUBSCRIBER = new Subject();
|
||||
private FILE_READER: FileReader;
|
||||
|
||||
//
|
||||
@Input('xFileReader')
|
||||
file: XFileReaderInputType;
|
||||
|
||||
@Input()
|
||||
refreshFileReader = new Subject();
|
||||
|
||||
//
|
||||
// tslint:disable-next-line:no-output-on-prefix
|
||||
@Output()
|
||||
onFileReaderError = new EventEmitter<any>();
|
||||
|
||||
//
|
||||
// tslint:disable-next-line:no-output-on-prefix
|
||||
@Output()
|
||||
onFileReaderLoad = new EventEmitter<boolean>();
|
||||
|
||||
//
|
||||
// tslint:disable-next-line:no-output-on-prefix
|
||||
@Output()
|
||||
onFileReaderProgress = new EventEmitter<any>();
|
||||
|
||||
//
|
||||
// tslint:disable-next-line:no-output-on-prefix
|
||||
@Output()
|
||||
onFileReaderFinish = new EventEmitter<any>();
|
||||
|
||||
//
|
||||
ngOnInit() {
|
||||
this.refreshFileReader
|
||||
.asObservable()
|
||||
.pipe(takeUntil(this.UNSUBSCRIBER))
|
||||
.subscribe(() => {
|
||||
this.handleStartReading();
|
||||
});
|
||||
}
|
||||
|
||||
//
|
||||
ngOnDestroy() {
|
||||
this.UNSUBSCRIBER.next();
|
||||
this.UNSUBSCRIBER.complete();
|
||||
this.UNSUBSCRIBER = null;
|
||||
}
|
||||
|
||||
//
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
//
|
||||
const changeKeys = keys(changes);
|
||||
const isFileChanged = changeKeys.includes(
|
||||
nameof<XFileReaderDirective>('file')
|
||||
);
|
||||
if (isFileChanged) {
|
||||
this.handleStartReading();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
private async handleStartReading() {
|
||||
//
|
||||
await this.destroyReader();
|
||||
|
||||
//
|
||||
const type = getFileType(this.file);
|
||||
if (type !== XFileType.Image) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
this.FILE_READER = new FileReader();
|
||||
|
||||
//
|
||||
this.FILE_READER.onerror = err => {
|
||||
this.onFileReaderError.emit(err);
|
||||
this.destroyReader();
|
||||
};
|
||||
|
||||
//
|
||||
this.FILE_READER.onabort = err => {
|
||||
this.onFileReaderError.emit(err);
|
||||
this.destroyReader();
|
||||
};
|
||||
|
||||
//
|
||||
this.FILE_READER.onloadstart = _ => this.onFileReaderLoad.emit(true);
|
||||
this.FILE_READER.onprogress = ev => this.onFileReaderProgress.emit(ev);
|
||||
this.FILE_READER.onloadend = _ => {
|
||||
this.onFileReaderLoad.emit(false);
|
||||
this.destroyReader();
|
||||
};
|
||||
|
||||
//
|
||||
this.FILE_READER.onload = _ =>
|
||||
this.onFileReaderFinish.emit(this.FILE_READER.result);
|
||||
|
||||
//
|
||||
this.FILE_READER.readAsDataURL(this.file as Blob);
|
||||
}
|
||||
|
||||
private async destroyReader() {
|
||||
//
|
||||
if (!this.FILE_READER) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
this.FILE_READER.abort();
|
||||
this.FILE_READER = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
import {
|
||||
Input,
|
||||
Directive,
|
||||
ElementRef,
|
||||
HostListener,
|
||||
ChangeDetectorRef,
|
||||
} from '@angular/core';
|
||||
import { toArray } from '../tools/x-array.tools';
|
||||
import { toPromise } from '../tools/x-observable.tools';
|
||||
import { XOneOrManyType, XStandardType } from '../typings/x.typings';
|
||||
|
||||
@Directive({
|
||||
// tslint:disable-next-line:directive-selector
|
||||
selector: '[xFocusHandler]',
|
||||
})
|
||||
export class XFocusedHandlerDirective {
|
||||
//
|
||||
//#region Props ...
|
||||
@Input()
|
||||
enableHandler: XStandardType<boolean> = false;
|
||||
|
||||
@Input()
|
||||
appliedClassNames: XStandardType<XOneOrManyType<string>> = 'x-focused';
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Constructor ...
|
||||
constructor(
|
||||
public el: ElementRef,
|
||||
public changeDetector: ChangeDetectorRef
|
||||
) {}
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region HostListener Handlers ...
|
||||
@HostListener('focus', ['$event'])
|
||||
async whenFocused(event: any) {
|
||||
//
|
||||
const isEnable = await this.isEnable();
|
||||
if (!isEnable) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
const el = this.getElement();
|
||||
if (!el) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
const appliedClasses = await this.getClasses();
|
||||
|
||||
//
|
||||
appliedClasses.forEach((clz) => {
|
||||
el.classList.add(clz);
|
||||
});
|
||||
|
||||
//
|
||||
this.changeDetector.detectChanges();
|
||||
}
|
||||
|
||||
@HostListener('blur', ['$event'])
|
||||
async whenBlured(event: any) {
|
||||
//
|
||||
const isEnable = await this.isEnable();
|
||||
if (!isEnable) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
const el = this.getElement();
|
||||
if (!el) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
const appliedClasses = await this.getClasses();
|
||||
|
||||
//
|
||||
appliedClasses.forEach((clz) => {
|
||||
el.classList.remove(clz);
|
||||
});
|
||||
|
||||
//
|
||||
this.changeDetector.detectChanges();
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Private ...
|
||||
private async isEnable() {
|
||||
return await toPromise(this.enableHandler);
|
||||
}
|
||||
|
||||
private async getClasses() {
|
||||
//
|
||||
const classType = await toPromise(this.appliedClassNames);
|
||||
return toArray(classType);
|
||||
}
|
||||
|
||||
private getElement() {
|
||||
return this.el && this.el.nativeElement
|
||||
? (this.el.nativeElement as HTMLElement)
|
||||
: null;
|
||||
}
|
||||
//#endregion
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
import {
|
||||
Input,
|
||||
Directive,
|
||||
OnDestroy,
|
||||
OnChanges,
|
||||
ElementRef,
|
||||
AfterViewInit,
|
||||
SimpleChanges,
|
||||
AfterContentInit,
|
||||
} from '@angular/core';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { Subject, Subscription } from 'rxjs';
|
||||
import { nameof } from '../tools/x-object.tools';
|
||||
import { isNullOrUndefined } from '../tools/x-type-detect.tools';
|
||||
|
||||
@Directive({
|
||||
// tslint:disable-next-line:directive-selector
|
||||
selector: '[xFocus]',
|
||||
})
|
||||
export class XFocusDirective
|
||||
implements AfterViewInit, AfterContentInit, OnChanges, OnDestroy
|
||||
{
|
||||
//
|
||||
private subscription: Subscription;
|
||||
private ngUnsubscribe = new Subject();
|
||||
|
||||
//
|
||||
@Input('xFocus')
|
||||
reFocus = new Subject();
|
||||
|
||||
constructor(private element: ElementRef) {}
|
||||
|
||||
//
|
||||
//#region LifeCycles ...
|
||||
ngAfterViewInit() {
|
||||
this.initFocusHandler();
|
||||
}
|
||||
|
||||
ngAfterContentInit() {
|
||||
this.doFocus();
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
//
|
||||
if (isNullOrUndefined(changes)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
const changeKeys = Object.keys(changes);
|
||||
const isReFocusChanged = changeKeys.includes(
|
||||
nameof<XFocusDirective>('reFocus')
|
||||
);
|
||||
if (isReFocusChanged) {
|
||||
this.initFocusHandler();
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
//
|
||||
this.ngUnsubscribe.next();
|
||||
this.ngUnsubscribe.complete();
|
||||
}
|
||||
//#endregion
|
||||
|
||||
private doFocus() {
|
||||
setTimeout(() => this.element.nativeElement.focus(), 500);
|
||||
}
|
||||
|
||||
private initFocusHandler() {
|
||||
//
|
||||
if (!isNullOrUndefined(this.subscription)) {
|
||||
//
|
||||
this.subscription.unsubscribe();
|
||||
this.subscription = undefined;
|
||||
}
|
||||
|
||||
//
|
||||
if (isNullOrUndefined(this.reFocus)) {
|
||||
this.reFocus = new Subject();
|
||||
}
|
||||
|
||||
//
|
||||
this.subscription = this.reFocus
|
||||
.asObservable()
|
||||
.pipe(takeUntil(this.ngUnsubscribe))
|
||||
.subscribe(() => {
|
||||
this.doFocus();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
import {
|
||||
Input,
|
||||
OnInit,
|
||||
Directive,
|
||||
ElementRef,
|
||||
HostListener,
|
||||
} from '@angular/core';
|
||||
import { XFormatterOption } from '../typings/x.typings';
|
||||
import { applyFormat, clearFormat } from '../tools/x-formatter.tools';
|
||||
|
||||
@Directive({
|
||||
// tslint:disable-next-line:directive-selector
|
||||
selector: '[xFormatter]',
|
||||
})
|
||||
export class XFormatterDirective implements OnInit {
|
||||
//
|
||||
private el: HTMLInputElement;
|
||||
|
||||
//
|
||||
@Input('xFormatter')
|
||||
options: XFormatterOption;
|
||||
|
||||
@Input()
|
||||
clearLocale = true;
|
||||
|
||||
//
|
||||
constructor(private elementRef: ElementRef) {
|
||||
this.el = this.elementRef.nativeElement;
|
||||
}
|
||||
|
||||
//
|
||||
ngOnInit() {
|
||||
this.el.value = this.format(this.el.value);
|
||||
}
|
||||
|
||||
//
|
||||
@HostListener('focus', ['$event.target.value'])
|
||||
onFocus(value: any) {
|
||||
this.el.value = this.clear(value);
|
||||
}
|
||||
|
||||
//
|
||||
@HostListener('blur', ['$event.target.value'])
|
||||
onBlur(value: any) {
|
||||
this.el.value = this.format(value);
|
||||
}
|
||||
|
||||
//
|
||||
private format(value: any) {
|
||||
return applyFormat(this.options, value ? value.toString() : '');
|
||||
}
|
||||
|
||||
//
|
||||
private clear(value: any) {
|
||||
return clearFormat(
|
||||
this.options,
|
||||
this.clearLocale,
|
||||
value ? value.toString() : ''
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
import {
|
||||
Input,
|
||||
OnInit,
|
||||
Output,
|
||||
Directive,
|
||||
OnDestroy,
|
||||
OnChanges,
|
||||
ElementRef,
|
||||
HostListener,
|
||||
EventEmitter,
|
||||
AfterViewInit,
|
||||
SimpleChanges,
|
||||
AfterContentInit,
|
||||
} from '@angular/core';
|
||||
import { XStandardType } from '../typings/x.typings';
|
||||
import { toPromise } from '../tools/x-observable.tools';
|
||||
import { isNullOrUndefined } from '../tools/x-type-detect.tools';
|
||||
|
||||
/**
|
||||
* this is a directive which bind to mouse/touch events and react based on them ...
|
||||
*/
|
||||
@Directive({
|
||||
// tslint:disable-next-line:directive-selector
|
||||
selector: '[xMouseHandler]',
|
||||
})
|
||||
export class XMouseHandlerDirective
|
||||
implements OnInit, OnChanges, AfterViewInit, AfterContentInit, OnDestroy {
|
||||
//
|
||||
//#region Props ...
|
||||
@Input()
|
||||
enableHandler: XStandardType<boolean> = false;
|
||||
|
||||
@Output()
|
||||
started = new EventEmitter<MouseEvent>();
|
||||
|
||||
@Output()
|
||||
moved = new EventEmitter<MouseEvent>();
|
||||
|
||||
@Output()
|
||||
finished = new EventEmitter<MouseEvent>();
|
||||
|
||||
// tslint:disable-next-line:no-output-on-prefix
|
||||
@Output()
|
||||
onWindowStarted = new EventEmitter<MouseEvent>();
|
||||
|
||||
// tslint:disable-next-line:no-output-on-prefix
|
||||
@Output()
|
||||
onWindowMoved = new EventEmitter<MouseEvent>();
|
||||
|
||||
// tslint:disable-next-line:no-output-on-prefix
|
||||
@Output()
|
||||
onWindowFinished = new EventEmitter<MouseEvent>();
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Constructor ...
|
||||
constructor(private el: ElementRef) {}
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region LifeCycles ...
|
||||
ngOnInit() {}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {}
|
||||
|
||||
ngAfterViewInit() {}
|
||||
|
||||
ngAfterContentInit() {}
|
||||
|
||||
ngOnDestroy() {}
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Host Listeners ...
|
||||
//
|
||||
//#region Element Listeners ...
|
||||
@HostListener('document:mousedown', ['$event'])
|
||||
@HostListener('document:touchstart', ['$event'])
|
||||
async whenMoveStart(event: MouseEvent) {
|
||||
//
|
||||
const isEnable = await this.isEnable();
|
||||
if (!isEnable) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
if (!this.isTargetMatched(event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
this.started.emit(event);
|
||||
}
|
||||
|
||||
@HostListener('document:mousemove', ['$event'])
|
||||
@HostListener('document:touchmove', ['$event'])
|
||||
async whenMove(event: MouseEvent) {
|
||||
//
|
||||
const isEnable = await this.isEnable();
|
||||
if (!isEnable) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
if (!this.isTargetMatched(event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
this.moved.emit(event);
|
||||
}
|
||||
|
||||
@HostListener('document:mouseup', ['$event'])
|
||||
@HostListener('document:touchend', ['$event'])
|
||||
async whenMoveFinished(event: MouseEvent) {
|
||||
//
|
||||
const isEnable = await this.isEnable();
|
||||
if (!isEnable) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
if (!this.isTargetMatched(event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
this.finished.emit(event);
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Window Listeners ...
|
||||
@HostListener('window:mousedown', ['$event'])
|
||||
@HostListener('window:touchstart', ['$event'])
|
||||
async whenWindowMoveStart(event: MouseEvent) {
|
||||
//
|
||||
const isEnable = await this.isEnable();
|
||||
if (!isEnable) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
this.onWindowStarted.emit(event);
|
||||
}
|
||||
|
||||
@HostListener('window:mousemove', ['$event'])
|
||||
@HostListener('window:touchmove', ['$event'])
|
||||
async whenWindowMove(event: MouseEvent) {
|
||||
//
|
||||
const isEnable = await this.isEnable();
|
||||
if (!isEnable) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
this.onWindowMoved.emit(event);
|
||||
}
|
||||
|
||||
@HostListener('window:mouseup', ['$event'])
|
||||
@HostListener('window:touchend', ['$event'])
|
||||
async whenWindowMoveFinished(event: MouseEvent) {
|
||||
//
|
||||
const isEnable = await this.isEnable();
|
||||
if (!isEnable) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
this.onWindowFinished.emit(event);
|
||||
}
|
||||
//#endregion
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Private ...
|
||||
private async isEnable() {
|
||||
return await toPromise(this.enableHandler);
|
||||
}
|
||||
|
||||
private isTargetMatched(event: MouseEvent) {
|
||||
return !isNullOrUndefined(event)
|
||||
? (this.el.nativeElement.contains(event.target) as boolean)
|
||||
: false;
|
||||
}
|
||||
//#endregion
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Directive, Output, EventEmitter, HostListener } from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
// tslint:disable-next-line:directive-selector
|
||||
selector: '[xOnEnter]'
|
||||
})
|
||||
export class XOnEnterDirective {
|
||||
//
|
||||
@Output('xOnEnter')
|
||||
listener: EventEmitter<any> = new EventEmitter<any>();
|
||||
|
||||
//
|
||||
@HostListener('keyup.enter', ['$event'])
|
||||
onEnterPressed(event: any) {
|
||||
// tslint:disable-next-line: deprecation
|
||||
this.listener.emit(event);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Directive, Output, EventEmitter, HostListener } from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
// tslint:disable-next-line:directive-selector
|
||||
selector: '[xOnEscape]'
|
||||
})
|
||||
export class XOnEscapeDirective {
|
||||
//
|
||||
@Output('xOnEscape')
|
||||
listener: EventEmitter<any> = new EventEmitter<any>();
|
||||
|
||||
//
|
||||
@HostListener('keyup.esc', ['$event'])
|
||||
onEscapePressed(event: any) {
|
||||
// tslint:disable-next-line: deprecation
|
||||
this.listener.emit(event);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import {
|
||||
Output,
|
||||
Directive,
|
||||
ElementRef,
|
||||
EventEmitter,
|
||||
HostListener,
|
||||
} from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
// tslint:disable-next-line:directive-selector
|
||||
selector: '[xOnOutsideClicked]',
|
||||
})
|
||||
export class XOutsideClickDirective {
|
||||
//
|
||||
@Output('xOnOutsideClicked')
|
||||
listener: EventEmitter<any> = new EventEmitter<any>();
|
||||
|
||||
//
|
||||
constructor(private elementRef: ElementRef) {}
|
||||
|
||||
@HostListener('document:click', ['$event.target'])
|
||||
public onClick(targetElement: any) {
|
||||
//
|
||||
const clickedInside = this.elementRef.nativeElement.contains(targetElement);
|
||||
if (!clickedInside) {
|
||||
this.listener.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
import {
|
||||
Directive,
|
||||
Renderer2,
|
||||
ElementRef,
|
||||
RendererStyleFlags2
|
||||
} from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
// tslint:disable-next-line:directive-selector
|
||||
selector: '[xRender]'
|
||||
})
|
||||
export class XRenderDirective {
|
||||
//
|
||||
constructor(private renderer: Renderer2, private el: ElementRef) {}
|
||||
|
||||
addClass(clz: string) {
|
||||
this.renderer.addClass(this.el.nativeElement, clz);
|
||||
}
|
||||
|
||||
removeClass(clz: string) {
|
||||
this.renderer.removeClass(this.el.nativeElement, clz);
|
||||
}
|
||||
|
||||
createElement(name: string, nameSpace?: string) {
|
||||
return this.renderer.createElement(name, nameSpace);
|
||||
}
|
||||
|
||||
createText(value: string) {
|
||||
return this.renderer.createText(value);
|
||||
}
|
||||
|
||||
appendChild(parent: any, newChild: any) {
|
||||
this.renderer.appendChild(parent, newChild);
|
||||
}
|
||||
|
||||
appendChildToElement(child: any) {
|
||||
this.renderer.appendChild(this.el.nativeElement, child);
|
||||
}
|
||||
|
||||
setAttribute(name: string, value: string, namespace?: string | null) {
|
||||
this.renderer.setAttribute(this.el.nativeElement, name, value, namespace);
|
||||
}
|
||||
|
||||
removeAttribute(name: string, namespace?: string | null) {
|
||||
this.renderer.removeAttribute(this.el.nativeElement, name, namespace);
|
||||
}
|
||||
|
||||
setStyle(style: string, value: any, flags?: RendererStyleFlags2) {
|
||||
this.renderer.setStyle(this.el.nativeElement, style, value, flags);
|
||||
}
|
||||
|
||||
removeStyle(style: string, flags?: RendererStyleFlags2) {
|
||||
this.renderer.removeStyle(this.el.nativeElement, style, flags);
|
||||
}
|
||||
|
||||
setProperty(name: string, value: any) {
|
||||
this.renderer.setProperty(this.el.nativeElement, name, value);
|
||||
}
|
||||
|
||||
setValue(node: any, value: string) {
|
||||
this.renderer.setValue(node, value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,329 @@
|
||||
import {
|
||||
Input,
|
||||
OnInit,
|
||||
Output,
|
||||
Directive,
|
||||
Renderer2,
|
||||
OnDestroy,
|
||||
OnChanges,
|
||||
EventEmitter,
|
||||
HostListener,
|
||||
AfterViewInit,
|
||||
SimpleChanges,
|
||||
} from '@angular/core';
|
||||
import { Subject, Subscription } from 'rxjs';
|
||||
import { hasChild } from '../tools/x-array.tools';
|
||||
import { keys, nameof } from '../tools/x-object.tools';
|
||||
import { isArray, isString } from '../tools/x-type-detect.tools';
|
||||
|
||||
//
|
||||
//#region Definitions ...
|
||||
export interface XBehaviourEvent {
|
||||
type: XBehaviourEventType;
|
||||
event: any;
|
||||
elements: Element[];
|
||||
}
|
||||
|
||||
export type XBehaviourEventType = 'scrollStart' | 'scrollEnd' | 'scrolling';
|
||||
//#endregion
|
||||
|
||||
@Directive({
|
||||
// tslint:disable-next-line:directive-selector
|
||||
selector: '[xScrollBehaviour]',
|
||||
})
|
||||
export class XScrollBehaviourDirective
|
||||
implements OnInit, OnChanges, OnDestroy, AfterViewInit
|
||||
{
|
||||
//
|
||||
private elementsRef: Element[] = [];
|
||||
private xUnSubscriber = new Subject();
|
||||
|
||||
//
|
||||
@Output()
|
||||
scrollStarted = new EventEmitter<XBehaviourEvent>();
|
||||
|
||||
@Output()
|
||||
scrollEnded = new EventEmitter<XBehaviourEvent>();
|
||||
|
||||
@Output()
|
||||
scrolling = new EventEmitter<XBehaviourEvent>();
|
||||
|
||||
//
|
||||
@Input()
|
||||
scrollStartClasses: string | string[];
|
||||
|
||||
@Input()
|
||||
scrollEndClasses: string | string[];
|
||||
|
||||
@Input()
|
||||
scrollingClasses: string | string[];
|
||||
|
||||
//
|
||||
private ACTION_PROVIDER_SUBSCRIPTION: Subscription;
|
||||
|
||||
@Input()
|
||||
scrollingActionProvider = new Subject<XBehaviourEventType>();
|
||||
|
||||
//
|
||||
@Input('xScrollBehaviour')
|
||||
elements: string | string[];
|
||||
|
||||
//
|
||||
@HostListener('ionScrollStart', ['$event'])
|
||||
async onScrollStart(event: any) {
|
||||
//
|
||||
await this.prepareScroller();
|
||||
|
||||
//
|
||||
await this.removeClass(this.scrollEndClasses);
|
||||
await this.addClass(this.scrollStartClasses);
|
||||
|
||||
//
|
||||
const eventModel: XBehaviourEvent = {
|
||||
type: 'scrollStart',
|
||||
event,
|
||||
elements: this.elementsRef,
|
||||
};
|
||||
|
||||
//
|
||||
this.scrollStarted.emit(eventModel);
|
||||
}
|
||||
|
||||
@HostListener('ionScrollEnd', ['$event'])
|
||||
async onScrollEnd(event: any) {
|
||||
//
|
||||
await this.prepareScroller();
|
||||
|
||||
//
|
||||
await this.removeClass(this.scrollStartClasses);
|
||||
await this.removeClass(this.scrollingClasses);
|
||||
await this.addClass(this.scrollEndClasses);
|
||||
|
||||
//
|
||||
const eventModel: XBehaviourEvent = {
|
||||
type: 'scrollEnd',
|
||||
event,
|
||||
elements: this.elementsRef,
|
||||
};
|
||||
|
||||
//
|
||||
this.scrollEnded.emit(eventModel);
|
||||
}
|
||||
|
||||
@HostListener('ionScroll', ['$event'])
|
||||
async onScroll(event: any) {
|
||||
//
|
||||
await this.prepareScroller();
|
||||
|
||||
//
|
||||
await this.addClass(this.scrollingClasses);
|
||||
|
||||
//
|
||||
const eventModel: XBehaviourEvent = {
|
||||
type: 'scrolling',
|
||||
event,
|
||||
elements: this.elementsRef,
|
||||
};
|
||||
|
||||
//
|
||||
this.scrolling.emit(eventModel);
|
||||
}
|
||||
|
||||
//
|
||||
constructor(public renderer: Renderer2) {}
|
||||
|
||||
//
|
||||
async ngOnInit() {
|
||||
//
|
||||
await this.prepareScroller();
|
||||
}
|
||||
|
||||
async ngAfterViewInit() {
|
||||
//
|
||||
await this.prepareScroller();
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
//
|
||||
const changeKeys = keys(changes);
|
||||
|
||||
//
|
||||
//#region ActionProvider Changed ...
|
||||
const isActionProviderChanged = changeKeys.includes(
|
||||
nameof<XScrollBehaviourDirective>('scrollingActionProvider')
|
||||
);
|
||||
if (isActionProviderChanged) {
|
||||
this.registerActionProvider();
|
||||
}
|
||||
//#endregion
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
//
|
||||
this.unregisterActionProvider();
|
||||
|
||||
//
|
||||
this.xUnSubscriber.next();
|
||||
this.xUnSubscriber.complete();
|
||||
}
|
||||
|
||||
//
|
||||
private getType() {
|
||||
//
|
||||
if (!this.elements) {
|
||||
return 'unknown';
|
||||
}
|
||||
|
||||
//
|
||||
if (isArray(this.elements)) {
|
||||
return 'array';
|
||||
} else {
|
||||
return 'single';
|
||||
}
|
||||
}
|
||||
|
||||
private registerActionProvider() {
|
||||
//
|
||||
this.unregisterActionProvider();
|
||||
|
||||
//
|
||||
if (!this.scrollingActionProvider) {
|
||||
this.scrollingActionProvider = new Subject<XBehaviourEventType>();
|
||||
}
|
||||
|
||||
//
|
||||
this.ACTION_PROVIDER_SUBSCRIPTION = this.scrollingActionProvider
|
||||
.asObservable()
|
||||
.subscribe(async (model) => {
|
||||
//
|
||||
if (!model) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
switch (model) {
|
||||
//
|
||||
case 'scrollStart':
|
||||
await this.onScrollStart(null);
|
||||
break;
|
||||
|
||||
//
|
||||
case 'scrollEnd':
|
||||
await this.onScrollEnd(null);
|
||||
break;
|
||||
|
||||
//
|
||||
case 'scrolling':
|
||||
await this.onScroll(null);
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private unregisterActionProvider() {
|
||||
//
|
||||
if (!this.ACTION_PROVIDER_SUBSCRIPTION) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
this.ACTION_PROVIDER_SUBSCRIPTION.unsubscribe();
|
||||
this.ACTION_PROVIDER_SUBSCRIPTION = null;
|
||||
}
|
||||
|
||||
private async prepareScroller() {
|
||||
//
|
||||
await this.generateElementsRef();
|
||||
await this.addTransition();
|
||||
|
||||
//
|
||||
this.registerActionProvider();
|
||||
}
|
||||
|
||||
private async generateElementsRef() {
|
||||
//
|
||||
this.elementsRef = [];
|
||||
|
||||
//
|
||||
const inputType = this.getType();
|
||||
if (inputType === 'unknown') {
|
||||
return [];
|
||||
} else if (inputType === 'single') {
|
||||
//
|
||||
const elements = document.querySelectorAll(this.elements as string);
|
||||
if (elements.length > 0) {
|
||||
elements.forEach((e) => {
|
||||
this.elementsRef.push(e);
|
||||
});
|
||||
}
|
||||
} else if (inputType === 'array') {
|
||||
//
|
||||
(this.elements as string[]).forEach((eSelector) => {
|
||||
//
|
||||
const elements = document.querySelectorAll(eSelector);
|
||||
if (elements.length > 0) {
|
||||
elements.forEach((e) => {
|
||||
this.elementsRef.push(e);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//
|
||||
return this.elementsRef;
|
||||
}
|
||||
|
||||
private async addClass(cls: string | string[]) {
|
||||
//
|
||||
if (!hasChild(this.elementsRef)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
const clsList = isString(cls) ? [cls as string] : (cls as string[]);
|
||||
if (!hasChild(clsList)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
this.elementsRef.forEach((e) => {
|
||||
e.classList.add(...clsList);
|
||||
});
|
||||
}
|
||||
|
||||
private async removeClass(cls: string | string[]) {
|
||||
//
|
||||
if (!hasChild(this.elementsRef)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
const clsList = isString(cls) ? [cls as string] : (cls as string[]);
|
||||
if (!hasChild(clsList)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
this.elementsRef.forEach((e) => {
|
||||
e.classList.remove(...clsList);
|
||||
});
|
||||
}
|
||||
|
||||
private async addTransition(descriptor?: string) {
|
||||
//
|
||||
if (!descriptor) {
|
||||
descriptor = 'transform 500ms, opacity 250ms';
|
||||
}
|
||||
|
||||
//
|
||||
if (!hasChild(this.elementsRef)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
this.elementsRef.forEach((e) => {
|
||||
this.renderer.setStyle(e, '-webkit-transition', descriptor);
|
||||
this.renderer.setStyle(e, 'transition', descriptor);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
import {
|
||||
Input,
|
||||
Output,
|
||||
Directive,
|
||||
ElementRef,
|
||||
HostListener,
|
||||
EventEmitter,
|
||||
} from '@angular/core';
|
||||
|
||||
export interface XSliderValueEventModel {
|
||||
s?: number;
|
||||
v?: number;
|
||||
rg?: number;
|
||||
rgX?: number;
|
||||
rgY?: number;
|
||||
}
|
||||
|
||||
@Directive({
|
||||
// tslint:disable-next-line:directive-selector
|
||||
selector: '[xSlider]',
|
||||
})
|
||||
export class XSliderDirective {
|
||||
//
|
||||
@Input()
|
||||
rgX: number;
|
||||
|
||||
@Input()
|
||||
rgY: number;
|
||||
|
||||
//
|
||||
@Output()
|
||||
newValue = new EventEmitter<XSliderValueEventModel>();
|
||||
|
||||
//
|
||||
private listenerMove: any = (event: any) => {
|
||||
this.move(event);
|
||||
// tslint:disable-next-line:semicolon
|
||||
};
|
||||
|
||||
//
|
||||
private listenerStop: any = () => {
|
||||
this.stop();
|
||||
// tslint:disable-next-line:semicolon
|
||||
};
|
||||
|
||||
//
|
||||
constructor(private el: ElementRef) {}
|
||||
|
||||
setCursor(event: any) {
|
||||
//
|
||||
const height = this.el.nativeElement.offsetHeight;
|
||||
const width = this.el.nativeElement.offsetWidth;
|
||||
const x = Math.max(0, Math.min(this.getX(event), width));
|
||||
const y = Math.max(0, Math.min(this.getY(event), height));
|
||||
|
||||
//
|
||||
if (this.rgX !== undefined && this.rgY !== undefined) {
|
||||
//
|
||||
this.newValue.emit({
|
||||
s: x / width,
|
||||
v: 1 - y / height,
|
||||
rgX: this.rgX,
|
||||
rgY: this.rgY,
|
||||
});
|
||||
} else if (this.rgX === undefined && this.rgY !== undefined) {
|
||||
//
|
||||
// ready to use vertical sliders
|
||||
this.newValue.emit({ v: y / height, rg: this.rgY });
|
||||
} else {
|
||||
//
|
||||
this.newValue.emit({ v: x / width, rg: this.rgX });
|
||||
}
|
||||
}
|
||||
|
||||
move(event: any) {
|
||||
event.preventDefault();
|
||||
this.setCursor(event);
|
||||
}
|
||||
|
||||
@HostListener('mousedown', ['$event'])
|
||||
@HostListener('touchstart', ['$event'])
|
||||
start(event: any) {
|
||||
//
|
||||
this.setCursor(event);
|
||||
|
||||
//
|
||||
document.addEventListener('mousemove', this.listenerMove);
|
||||
document.addEventListener('touchmove', this.listenerMove);
|
||||
document.addEventListener('mouseup', this.listenerStop);
|
||||
document.addEventListener('touchend', this.listenerStop);
|
||||
}
|
||||
|
||||
stop() {
|
||||
//
|
||||
document.removeEventListener('mousemove', this.listenerMove);
|
||||
document.removeEventListener('touchmove', this.listenerMove);
|
||||
document.removeEventListener('mouseup', this.listenerStop);
|
||||
document.removeEventListener('touchend', this.listenerStop);
|
||||
}
|
||||
|
||||
getX(event: any): number {
|
||||
//
|
||||
return (
|
||||
(event.pageX !== undefined ? event.pageX : event.touches[0].pageX) -
|
||||
this.el.nativeElement.getBoundingClientRect().left -
|
||||
window.pageXOffset
|
||||
);
|
||||
}
|
||||
|
||||
getY(event: any): number {
|
||||
//
|
||||
return (
|
||||
(event.pageY !== undefined ? event.pageY : event.touches[0].pageY) -
|
||||
this.el.nativeElement.getBoundingClientRect().top -
|
||||
window.pageYOffset
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { Directive, HostListener } from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
// tslint:disable-next-line:directive-selector
|
||||
selector: '[xStopClickPropagation]'
|
||||
})
|
||||
export class XStopClickPropagationDirective {
|
||||
@HostListener('click', ['$event'])
|
||||
public onClick(event: any): void {
|
||||
event.stopPropagation();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
import {
|
||||
isNullOrUndefined,
|
||||
isNullOrEmptyString,
|
||||
} from '../tools/x-type-detect.tools';
|
||||
import { keys } from '../tools/x-object.tools';
|
||||
import { hasChild } from '../tools/x-array.tools';
|
||||
import { Input, Directive, ChangeDetectorRef } from '@angular/core';
|
||||
|
||||
export interface XVarModel {
|
||||
name: string;
|
||||
value: any;
|
||||
}
|
||||
|
||||
@Directive({
|
||||
selector: '[xVar]',
|
||||
exportAs: 'xVar',
|
||||
})
|
||||
export class XVarDirective {
|
||||
//
|
||||
private context: any = {};
|
||||
|
||||
//
|
||||
@Input('xVar')
|
||||
set xVar(value: XVarModel) {
|
||||
//
|
||||
this.context[this.prepareVarName(value.name)] = value;
|
||||
this.changeDetector.detectChanges();
|
||||
}
|
||||
|
||||
constructor(private changeDetector: ChangeDetectorRef) {}
|
||||
|
||||
hasVar(name: string) {
|
||||
return (
|
||||
!isNullOrEmptyString(name) &&
|
||||
!isNullOrUndefined(this.context) &&
|
||||
hasChild(keys(this.context)) &&
|
||||
!isNullOrUndefined(this.context[name])
|
||||
);
|
||||
}
|
||||
|
||||
getVar(name: string) {
|
||||
return this.hasVar(this.prepareVarName(name))
|
||||
? this.context[this.prepareVarName(name)]
|
||||
: undefined;
|
||||
}
|
||||
|
||||
getVars() {
|
||||
return this.context;
|
||||
}
|
||||
|
||||
private prepareVarName(name: string) {
|
||||
return `xVar_${name}`;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import {
|
||||
CanDeactivate,
|
||||
RouterStateSnapshot,
|
||||
ActivatedRouteSnapshot
|
||||
} from '@angular/router';
|
||||
import { Observable } from 'rxjs';
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
export interface XCanDeactivate {
|
||||
canDeactivate: (
|
||||
component: XCanDeactivate,
|
||||
route: ActivatedRouteSnapshot,
|
||||
state: RouterStateSnapshot
|
||||
) => Observable<boolean> | Promise<boolean> | boolean;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class XCanDeactivateGuard implements CanDeactivate<XCanDeactivate> {
|
||||
canDeactivate(
|
||||
component: XCanDeactivate,
|
||||
route: ActivatedRouteSnapshot,
|
||||
state: RouterStateSnapshot
|
||||
) {
|
||||
const url: string = state.url;
|
||||
|
||||
return component.canDeactivate
|
||||
? component.canDeactivate(component, route, state)
|
||||
: true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
import { isSameObject } from '../tools/x-object.tools';
|
||||
|
||||
// tslint:disable-next-line:no-empty-interface
|
||||
export interface XBaseDto {}
|
||||
|
||||
export abstract class XBaseDtoHelper<T extends XBaseDto> {
|
||||
//
|
||||
//#region Abstracts ...
|
||||
abstract defaultValues: T;
|
||||
abstract get values(): T;
|
||||
abstract prepareModelFields(dto?: T): T;
|
||||
abstract fill(dto?: T): void;
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Constructor ...
|
||||
constructor(dto?: T) {
|
||||
//
|
||||
this.fill(this.prepareModelFields(dto));
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Actions ...
|
||||
public isDefaultModel(dto?: T): boolean {
|
||||
//
|
||||
if (!dto) {
|
||||
dto = {
|
||||
...this.values,
|
||||
};
|
||||
}
|
||||
|
||||
//
|
||||
const result = isSameObject(
|
||||
this.prepareModelFields(dto),
|
||||
this.defaultValues
|
||||
);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
//#endregion
|
||||
}
|
||||
|
||||
export interface XBaseNumberIDDto {
|
||||
id: number;
|
||||
}
|
||||
|
||||
// tslint:disable-next-line: no-empty-interface
|
||||
export interface XBaseRequestDto {}
|
||||
|
||||
export interface XBaseRangeRequestDto<T> extends XBaseRequestDto {
|
||||
items: Array<T>;
|
||||
}
|
||||
|
||||
// tslint:disable-next-line:no-empty-interface
|
||||
export interface XBaseResponseDto {}
|
||||
|
||||
export interface XBaseStorableDto<T> extends XBaseDto {
|
||||
id?: T
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import { XBaseDto } from './x-base-dto';
|
||||
|
||||
export interface XBaseIndexedDto<T, TKey, Tindex> extends XBaseDto {
|
||||
item: T;
|
||||
key: TKey;
|
||||
index: Tindex;
|
||||
}
|
||||
|
||||
export interface XBaseIntIndexedDto<T>
|
||||
extends XBaseIndexedDto<T, string, number> {}
|
||||
@@ -0,0 +1,7 @@
|
||||
import { XBaseDto } from "./x-base-dto";
|
||||
|
||||
export interface XGroupedDataDto<T, TGroupedy> extends XBaseDto {
|
||||
groupedBy: TGroupedy;
|
||||
members: Array<T>;
|
||||
timeStamp: Date;
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { IonicModule } from '@ionic/angular';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { XAsPipe } from '../pipes/x-as.pipe';
|
||||
import { XLogPipe } from '../pipes/x-log.pipe';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { XSafeHtmlPipe } from '../pipes/x-safe-html.pipe';
|
||||
import { XFormatterPipe } from '../pipes/x-formatter.pipe';
|
||||
import { XVarDirective } from '../directives/x-var.directive';
|
||||
import { XFocusDirective } from '../directives/x-focus.directive';
|
||||
import { XColorDirective } from '../directives/x-color.directive';
|
||||
import { XRenderDirective } from '../directives/x-render.directive';
|
||||
import { XSliderDirective } from '../directives/x-slider.directive';
|
||||
import { XOnEnterDirective } from '../directives/x-on-enter.directive';
|
||||
import { XValidUrlDirective } from '../validators/x-valid-url.directive';
|
||||
import { XOnEscapeDirective } from '../directives/x-on-escape.directive';
|
||||
import { XDroppableDirective } from '../directives/x-droppable.directive';
|
||||
import { XClipboardDirective } from '../directives/x-clipboard.directive';
|
||||
import { XFormatterDirective } from '../directives/x-formatter.directive';
|
||||
import { XValueMatchDirective } from '../validators/x-value-match.directive';
|
||||
import { XValidEmailDirective } from '../validators/x-valid-email.directive';
|
||||
import { XFileReaderDirective } from '../directives/x-file-reader.directive';
|
||||
import { XMouseHandlerDirective } from '../directives/x-mouse-handler.directive';
|
||||
import { XFocusedHandlerDirective } from '../directives/x-focus-handler.directive';
|
||||
import { XOutsideClickDirective } from '../directives/x-on-outside-click.directive';
|
||||
import { XScrollBehaviourDirective } from '../directives/x-scroll-behavior.directive';
|
||||
import { XValidPhoneNumberDirective } from '../validators/x-valid-phone-number.directive';
|
||||
import { XStopClickPropagationDirective } from '../directives/x-stop-click-propagation.directive';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
//
|
||||
// Directives
|
||||
XVarDirective,
|
||||
XFocusDirective,
|
||||
XColorDirective,
|
||||
XSliderDirective,
|
||||
XRenderDirective,
|
||||
XOnEnterDirective,
|
||||
XOnEscapeDirective,
|
||||
XFormatterDirective,
|
||||
XClipboardDirective,
|
||||
XDroppableDirective,
|
||||
XFileReaderDirective,
|
||||
XOutsideClickDirective,
|
||||
XMouseHandlerDirective,
|
||||
XFocusedHandlerDirective,
|
||||
XScrollBehaviourDirective,
|
||||
XStopClickPropagationDirective,
|
||||
|
||||
//
|
||||
// Pipes ...
|
||||
XAsPipe,
|
||||
XLogPipe,
|
||||
XSafeHtmlPipe,
|
||||
XFormatterPipe,
|
||||
|
||||
//
|
||||
// Validators ...
|
||||
XValidUrlDirective,
|
||||
XValueMatchDirective,
|
||||
XValidEmailDirective,
|
||||
XValidPhoneNumberDirective,
|
||||
],
|
||||
imports: [CommonModule, IonicModule, FormsModule],
|
||||
exports: [
|
||||
//
|
||||
IonicModule,
|
||||
FormsModule,
|
||||
CommonModule,
|
||||
|
||||
//
|
||||
// Directives
|
||||
XVarDirective,
|
||||
XFocusDirective,
|
||||
XColorDirective,
|
||||
XSliderDirective,
|
||||
XRenderDirective,
|
||||
XOnEnterDirective,
|
||||
XOnEscapeDirective,
|
||||
XFormatterDirective,
|
||||
XDroppableDirective,
|
||||
XClipboardDirective,
|
||||
XFileReaderDirective,
|
||||
XOutsideClickDirective,
|
||||
XMouseHandlerDirective,
|
||||
XFocusedHandlerDirective,
|
||||
XScrollBehaviourDirective,
|
||||
XStopClickPropagationDirective,
|
||||
|
||||
//
|
||||
// Pipes ...
|
||||
XAsPipe,
|
||||
XLogPipe,
|
||||
XSafeHtmlPipe,
|
||||
XFormatterPipe,
|
||||
|
||||
//
|
||||
// Validators ...
|
||||
XValidUrlDirective,
|
||||
XValueMatchDirective,
|
||||
XValidEmailDirective,
|
||||
XValidPhoneNumberDirective,
|
||||
],
|
||||
})
|
||||
export class XDirectivesModule {}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
|
||||
@Pipe({
|
||||
name: 'xAs',
|
||||
pure: true,
|
||||
})
|
||||
export class XAsPipe implements PipeTransform {
|
||||
/**
|
||||
* for casting a dynamic template var to specific type ...
|
||||
*
|
||||
* @param value the pure template var ...
|
||||
* @param _type the type which required to cast value to it ...
|
||||
* @returns a type casted var ...
|
||||
*/
|
||||
transform<T>(value: any, _type: (new (...args: any[]) => T) | T): T {
|
||||
return value as T;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
import { applyFormat, clearFormat } from '../tools/x-formatter.tools';
|
||||
import { XFormatterOption, XFormatterType } from '../typings/x.typings';
|
||||
|
||||
@Pipe({
|
||||
name: 'xFormatter',
|
||||
pure: true,
|
||||
})
|
||||
export class XFormatterPipe implements PipeTransform {
|
||||
//
|
||||
private defaultFormatterOption: XFormatterOption = {
|
||||
type: XFormatterType.ApplyLocale,
|
||||
};
|
||||
|
||||
//
|
||||
transform(value: any, options?: XFormatterOption): string {
|
||||
return this.format(options, value);
|
||||
}
|
||||
|
||||
//
|
||||
clearFormat(value: any, options?: XFormatterOption, clearLocale = false) {
|
||||
//
|
||||
options = {
|
||||
...this.defaultFormatterOption,
|
||||
...options,
|
||||
};
|
||||
|
||||
//
|
||||
return clearFormat(options, clearLocale, value) || '';
|
||||
}
|
||||
|
||||
//
|
||||
private format(options: XFormatterOption, value: any) {
|
||||
return applyFormat(
|
||||
{ ...this.defaultFormatterOption, ...options },
|
||||
value ? value.toString() : ''
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
|
||||
@Pipe({
|
||||
name: 'xLog',
|
||||
pure: true,
|
||||
})
|
||||
export class XLogPipe implements PipeTransform {
|
||||
/**
|
||||
* do a console log from a pipe
|
||||
*
|
||||
* @param value the specified value
|
||||
* @param args it is optional and unused here
|
||||
*/
|
||||
transform(value: any, ...args: any[]): any {
|
||||
//
|
||||
console.log('XLogPipe: ', value);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
import { DomSanitizer } from '@angular/platform-browser';
|
||||
|
||||
@Pipe({
|
||||
name: 'xSafeHTML',
|
||||
pure: true,
|
||||
})
|
||||
export class XSafeHtmlPipe implements PipeTransform {
|
||||
//
|
||||
constructor(private sanitizer: DomSanitizer) {}
|
||||
|
||||
//
|
||||
transform(value: any, args?: any): any {
|
||||
return this.sanitizer.bypassSecurityTrustHtml(value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import { InjectionToken } from '@angular/core';
|
||||
import { XFrameworkCoreConfig } from '../config/x-framework-core.config';
|
||||
|
||||
export const X_FRAMEWORK_CORE_CONFIG = new InjectionToken<XFrameworkCoreConfig>(
|
||||
'x_config'
|
||||
);
|
||||
@@ -0,0 +1,309 @@
|
||||
//
|
||||
//#region Array Tools ...
|
||||
|
||||
import { XOneOrManyType } from '../typings/x.typings';
|
||||
import { isArray } from './x-type-detect.tools';
|
||||
|
||||
/**
|
||||
* retrieve last item of an Array ...
|
||||
*
|
||||
* @param list an instance of XOneOrManyType<any> object ...
|
||||
*/
|
||||
export function lastItem<T>(list: XOneOrManyType<T>) {
|
||||
//
|
||||
if (!list || !hasChild(list)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
//
|
||||
const listArray = toArray(list);
|
||||
|
||||
//
|
||||
return listArray[listArray.length - 1];
|
||||
}
|
||||
|
||||
/**
|
||||
* extract and retrieve specific item of an array ...
|
||||
*
|
||||
* @param index index of Array Item ...
|
||||
* @param list an instance of XOneOrManyType<any> object ...
|
||||
*/
|
||||
export function nthItem<T>(index: number, list: XOneOrManyType<T>) {
|
||||
//
|
||||
if (!list || !hasChild(list)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
//
|
||||
const listArray = toArray(list);
|
||||
if (index < 0) {
|
||||
try {
|
||||
return listArray[listArray.length - 1 + index];
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
try {
|
||||
return listArray[index];
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* extract specific range of items from an array ...
|
||||
*
|
||||
* @param index extracting start index ...
|
||||
* @param count number of extracting items ...
|
||||
* @param list an instance of XOneOrManyType<any> object ...
|
||||
* @param reverse optional param to determines extracting direction ...
|
||||
*/
|
||||
export function nthItems<T>(
|
||||
index: number,
|
||||
count: number,
|
||||
list: XOneOrManyType<T>,
|
||||
reverse?: boolean
|
||||
) {
|
||||
//
|
||||
if (!list || !hasChild(list) || count === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
//
|
||||
let mIndex = index;
|
||||
const listArray = toArray(list);
|
||||
if (index < 0) {
|
||||
//
|
||||
mIndex = listArray.length - 1 + index;
|
||||
}
|
||||
|
||||
//
|
||||
let mCount = count;
|
||||
if (mCount < 0) {
|
||||
//
|
||||
mIndex += count;
|
||||
mCount = count * -1;
|
||||
}
|
||||
|
||||
//
|
||||
const result = listArray.splice(mIndex, mCount);
|
||||
if (reverse) {
|
||||
result.reverse();
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* determines an array has childs or not ...
|
||||
*
|
||||
* @param list an instance of XOneOrManyType<any> object ...
|
||||
*/
|
||||
export function hasChild<T>(list: XOneOrManyType<T>) {
|
||||
return list && toArray(list).length > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* count an array childs ...
|
||||
*
|
||||
* @param list an instance of XOneOrManyType<any> object ...
|
||||
*/
|
||||
export function countChild<T>(list: XOneOrManyType<T>) {
|
||||
return toArray(list).length;
|
||||
}
|
||||
|
||||
/**
|
||||
* convert an indexable object to array ...
|
||||
*
|
||||
* @param index indexed object ...
|
||||
*/
|
||||
export function getArrayOf<T>(index: { [key: string]: T }): T[] {
|
||||
//
|
||||
const result: T[] = [];
|
||||
|
||||
//
|
||||
Object.keys(index).forEach((key) => {
|
||||
//
|
||||
result.push(index[key] as T);
|
||||
});
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* merge all items inside collection of items ...
|
||||
* @param args a collection of XOneOrManyOfType items ...
|
||||
*/
|
||||
export function mergeList<T>(...args: XOneOrManyType<T>[]) {
|
||||
//
|
||||
const result: T[] = [];
|
||||
|
||||
//
|
||||
args.forEach((arg) => {
|
||||
result.push(...toArray(arg));
|
||||
});
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* convert value to array ...
|
||||
*
|
||||
* @param list an instance of XOneOrManyType<any> object ...
|
||||
*/
|
||||
export function toArray<T>(list: XOneOrManyType<T>) {
|
||||
//
|
||||
if (!list) {
|
||||
return [];
|
||||
}
|
||||
|
||||
//
|
||||
if (isArray(list)) {
|
||||
return list as T[];
|
||||
}
|
||||
|
||||
//
|
||||
return [list as T];
|
||||
}
|
||||
|
||||
/**
|
||||
* convert a value of specific type to array of another type ...
|
||||
*
|
||||
* @param list an instance of XOneOrManyType<TSource> object ...
|
||||
* @returns an instance of TDest[] object ...
|
||||
*/
|
||||
export function convertArray<TSource, TDest>(
|
||||
list: XOneOrManyType<TSource>
|
||||
): XOneOrManyType<TDest> {
|
||||
//
|
||||
let array = toArray(list);
|
||||
|
||||
//
|
||||
const result: TDest[] = !hasChild(array)
|
||||
? []
|
||||
: array.map((i) => i as any as TDest);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls a defined callback function on each element of an array, and returns an array that contains the results.
|
||||
*
|
||||
* @param list an instance of XOneOrManyType<any> object ...
|
||||
* @param callback A function that accepts up to three arguments.
|
||||
* The map method calls the callbackfn function one time for each element in the array.
|
||||
*/
|
||||
export function mapArray<T>(
|
||||
list: XOneOrManyType<T>,
|
||||
callback: (value: T, index: number, array: T[]) => T
|
||||
) {
|
||||
//
|
||||
if (!list) {
|
||||
return null;
|
||||
}
|
||||
|
||||
//
|
||||
const pList = toArray(list);
|
||||
|
||||
//
|
||||
return pList.map(callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* remove specific index of an array objects and return cleared array ...
|
||||
*
|
||||
* @param list an instance of XOneOrManyType<any> object ...
|
||||
* @param index specific item index ...
|
||||
*/
|
||||
export function removeItemByIndex<T>(list: XOneOrManyType<T>, index: number) {
|
||||
//
|
||||
if (!hasChild(list) || index < 0 || index > countChild(list) - 1) {
|
||||
return [];
|
||||
}
|
||||
|
||||
//
|
||||
return toArray(list).splice(index, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* remove specific item of an array and return cleared array ...
|
||||
*
|
||||
* @param list an instance of XOneOrManyType<any> object ...
|
||||
* @param item specific item ...
|
||||
*/
|
||||
export function removeItem<T>(list: XOneOrManyType<T>, item: T) {
|
||||
//
|
||||
if (!hasChild(list) || !item) {
|
||||
return [];
|
||||
}
|
||||
|
||||
//
|
||||
const listArray = toArray(list);
|
||||
const iIndex = listArray.indexOf(item);
|
||||
if (iIndex === -1) {
|
||||
return [];
|
||||
}
|
||||
|
||||
//
|
||||
return listArray.splice(iIndex, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* check an array contains an specific item or not ...
|
||||
*
|
||||
* @param list an instance of XOneOrManyType<any> object ...
|
||||
* @param item specific item ...
|
||||
*/
|
||||
export function isExists<T>(list: XOneOrManyType<T>, item: T) {
|
||||
return toArray(list).findIndex((i) => i === item) !== -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* sort array ...
|
||||
*
|
||||
* @param list an instance of XOneOrManyType<any> object ...
|
||||
* @param compareFn campare function ...
|
||||
*/
|
||||
export function sort<T>(
|
||||
list: XOneOrManyType<T>,
|
||||
compareFn?: (a: T, b: T) => number
|
||||
) {
|
||||
//
|
||||
const array = toArray(list);
|
||||
var result = array.sort(compareFn);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieve only unique members of an Array ...
|
||||
*
|
||||
* @param list an instance of XOneOrManyType<any> object ...
|
||||
*/
|
||||
export function onlyUniques<T>(list: XOneOrManyType<T>) {
|
||||
return toArray(list).filter((v, i, s) => s.indexOf(v) === i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check two Array is Equals or not ...
|
||||
*
|
||||
* @param a
|
||||
* @param b
|
||||
* @returns
|
||||
*/
|
||||
export function isXEqual<T>(a: T[], b: T[]): boolean {
|
||||
if (a.length !== b.length) return false;
|
||||
return a.every(
|
||||
(value, index) =>
|
||||
JSON.stringify(value) === JSON.stringify(b[index]) &&
|
||||
typeof value === typeof b[index]
|
||||
);
|
||||
}
|
||||
//#endregion
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,574 @@
|
||||
import {
|
||||
isDate,
|
||||
isString,
|
||||
isNumber,
|
||||
isNullOrUndefined,
|
||||
isNullOrEmptyString,
|
||||
} from './x-type-detect.tools';
|
||||
import * as moment_ from 'jalali-moment';
|
||||
const moment = moment_;
|
||||
import { Moment, unitOfTime } from 'jalali-moment';
|
||||
import { toXString } from './x-type-convert.tools';
|
||||
import { toPersianNumbers } from './x-string.tools';
|
||||
import { XLocale } from '../typings/x-translation.typings';
|
||||
import { XUnitOfTime } from '../typings/x-date-time.typings';
|
||||
|
||||
//
|
||||
//#region Date Time Utils ...
|
||||
export function isDefaultUTCDate(utcDate: Date | string | number): boolean {
|
||||
//
|
||||
var dateString = isNullOrUndefined(utcDate)
|
||||
? '0001-01-01T00:00:00'
|
||||
: toXString(utcDate);
|
||||
if (
|
||||
dateString === '0001-01-01T00:00:00' ||
|
||||
dateString === '1901-01-01T00:00:00.000Z'
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
const mDateString = fromUtcDate(utcDate).toISOString();
|
||||
if (
|
||||
mDateString === '0001-01-01T00:00:00' ||
|
||||
mDateString === '1901-01-01T00:00:00.000Z'
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* convert a UTC date to locale ...
|
||||
*/
|
||||
export function fromUtcDate(utcDate: Date | string | number): Date {
|
||||
//
|
||||
const mUtcDate = new Date(utcDate);
|
||||
|
||||
//
|
||||
const utcDateObject = Date.UTC(
|
||||
mUtcDate.getFullYear(),
|
||||
mUtcDate.getMonth(),
|
||||
mUtcDate.getDate(),
|
||||
mUtcDate.getHours(),
|
||||
mUtcDate.getMinutes(),
|
||||
mUtcDate.getSeconds(),
|
||||
mUtcDate.getMilliseconds()
|
||||
);
|
||||
|
||||
//
|
||||
return new Date(utcDateObject);
|
||||
}
|
||||
|
||||
export function fromUtcString(utcDateString: string): Date {
|
||||
//
|
||||
const utcDate = new Date(utcDateString);
|
||||
|
||||
//
|
||||
return fromUtcDate(utcDate);
|
||||
}
|
||||
|
||||
export function fromUtc(date: Date | string) {
|
||||
return isDate(date)
|
||||
? fromUtcDate(date)
|
||||
: isString(date)
|
||||
? fromUtcString(date.toString())
|
||||
: new Date();
|
||||
}
|
||||
|
||||
/**
|
||||
* format a Date to specific format
|
||||
* and return the formatted string, based on forLocal ...
|
||||
*/
|
||||
export function formatDate(
|
||||
date: Date | string,
|
||||
forLocale: XLocale,
|
||||
format: string,
|
||||
isUtc: boolean = false,
|
||||
toUtc: boolean = false
|
||||
) {
|
||||
//
|
||||
let momentDate = isUtc ? moment(fromUtc(date)) : moment(date);
|
||||
|
||||
//
|
||||
if (toUtc) {
|
||||
momentDate = momentDate.utc();
|
||||
}
|
||||
|
||||
//
|
||||
let result = momentDate.format(format);
|
||||
|
||||
//
|
||||
if (forLocale === 'fa-IR') {
|
||||
result = toPersianNumbers(result);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
export function getMomentInstance(
|
||||
input?: string | number | Date,
|
||||
isUtc?: boolean
|
||||
): Moment {
|
||||
//
|
||||
let startDate = moment(input);
|
||||
|
||||
//
|
||||
if (isUtc) {
|
||||
startDate = moment(input).utc();
|
||||
}
|
||||
|
||||
//
|
||||
return startDate;
|
||||
}
|
||||
|
||||
export function getDateFormatString(locale?: XLocale) {
|
||||
//
|
||||
if (locale === 'fa-IR') {
|
||||
return 'HH:mm:ss jYYYY/jMM/jDD';
|
||||
}
|
||||
|
||||
//
|
||||
return 'YYYY-MM-DD HH:mm:ss';
|
||||
}
|
||||
|
||||
export function getDateOfBirthDateFormatString(locale?: XLocale) {
|
||||
//
|
||||
if (locale === 'fa-IR') {
|
||||
return 'jYYYY/jMM/jDD';
|
||||
}
|
||||
|
||||
//
|
||||
return 'YYYY/MM/DD';
|
||||
}
|
||||
|
||||
export function getErrorDateFormatString(locale?: XLocale) {
|
||||
//
|
||||
if (locale === 'fa-IR') {
|
||||
return 'HH:mm:ss-jYYYY/jMM/jDD';
|
||||
}
|
||||
|
||||
//
|
||||
return 'YYYY-MM-DD HH:mm:ss';
|
||||
}
|
||||
|
||||
export function getRegularDateFormatString(locale?: XLocale) {
|
||||
//
|
||||
if (locale === 'fa-IR') {
|
||||
return 'HH:mm:ss jYYYY-jMM-jDD';
|
||||
}
|
||||
|
||||
//
|
||||
return 'YYYY-MM-DD HH:mm:ss';
|
||||
}
|
||||
|
||||
export function getJustYearFormatString(locale?: XLocale) {
|
||||
//
|
||||
if (locale === 'fa-IR') {
|
||||
return 'jYYYY';
|
||||
}
|
||||
|
||||
//
|
||||
return 'YYYY';
|
||||
}
|
||||
|
||||
export function getYear(momentDate: Moment) {
|
||||
return momentDate.format('YYYY');
|
||||
}
|
||||
|
||||
export function getMonth(momentDate: Moment) {
|
||||
return momentDate.format('MM');
|
||||
}
|
||||
|
||||
export function getDay(momentDate: Moment) {
|
||||
return momentDate.format('DD');
|
||||
}
|
||||
|
||||
export function getHours(momentDate: Moment) {
|
||||
return momentDate.format('HH');
|
||||
}
|
||||
|
||||
export function getMinutes(momentDate: Moment) {
|
||||
return momentDate.format('mm');
|
||||
}
|
||||
|
||||
export function getSeconds(momentDate: Moment) {
|
||||
return momentDate.format('ss');
|
||||
}
|
||||
|
||||
export function getMilliseconds(momentDate: Moment) {
|
||||
return momentDate.format('SSS');
|
||||
}
|
||||
|
||||
export function getUTCDate(date?: any) {
|
||||
//
|
||||
if (!date) {
|
||||
date = new Date();
|
||||
}
|
||||
|
||||
//
|
||||
const mDate = new Date(date).toUTCString();
|
||||
|
||||
//
|
||||
return new Date(mDate);
|
||||
}
|
||||
|
||||
export function getUTCDateString(date?: any) {
|
||||
//
|
||||
if (!date) {
|
||||
date = new Date();
|
||||
}
|
||||
|
||||
//
|
||||
const mDate = new Date(date).toUTCString();
|
||||
|
||||
//
|
||||
return mDate;
|
||||
}
|
||||
|
||||
export function createDate(
|
||||
year?: string,
|
||||
month?: string,
|
||||
day?: string,
|
||||
hours?: string,
|
||||
minutes?: string,
|
||||
seconds?: string,
|
||||
milliseconds?: string
|
||||
) {
|
||||
//
|
||||
const result = new Date();
|
||||
|
||||
//
|
||||
if (year) {
|
||||
result.setFullYear(+year);
|
||||
}
|
||||
|
||||
//
|
||||
if (month) {
|
||||
result.setMonth(+month - 1);
|
||||
}
|
||||
|
||||
//
|
||||
if (day) {
|
||||
result.setDate(+day);
|
||||
}
|
||||
|
||||
//
|
||||
if (hours) {
|
||||
result.setHours(+hours);
|
||||
}
|
||||
|
||||
//
|
||||
if (minutes) {
|
||||
result.setMinutes(+minutes);
|
||||
}
|
||||
|
||||
//
|
||||
if (seconds) {
|
||||
result.setSeconds(+seconds);
|
||||
}
|
||||
|
||||
//
|
||||
if (milliseconds) {
|
||||
result.setMilliseconds(+milliseconds);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
export function getUnitOfTimeForLocale(
|
||||
unit: XUnitOfTime,
|
||||
locale: XLocale = 'en-US'
|
||||
) {
|
||||
//
|
||||
let result: unitOfTime.DurationConstructor = null;
|
||||
|
||||
//
|
||||
switch (unit) {
|
||||
//
|
||||
case XUnitOfTime.Year:
|
||||
//
|
||||
switch (locale) {
|
||||
//
|
||||
case 'en-US':
|
||||
result = 'year';
|
||||
break;
|
||||
|
||||
//
|
||||
case 'fa-IR':
|
||||
result = 'jYear';
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
//
|
||||
case XUnitOfTime.Month:
|
||||
//
|
||||
switch (locale) {
|
||||
//
|
||||
case 'en-US':
|
||||
result = 'month';
|
||||
break;
|
||||
|
||||
//
|
||||
case 'fa-IR':
|
||||
result = 'jMonth';
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
//
|
||||
case XUnitOfTime.Day:
|
||||
//
|
||||
switch (locale) {
|
||||
//
|
||||
case 'en-US':
|
||||
result = 'day';
|
||||
break;
|
||||
|
||||
//
|
||||
case 'fa-IR':
|
||||
result = 'jDay';
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* add specific amount of year to start date ...
|
||||
*
|
||||
* @param date start date ...
|
||||
* @param value amount of specific unit of time ...
|
||||
* @param locale the locale which required to date handling ...
|
||||
*/
|
||||
export function addYear(
|
||||
date: string | number | Date,
|
||||
value: number,
|
||||
locale: XLocale = 'en-US'
|
||||
) {
|
||||
//
|
||||
if (isNullOrUndefined(date) || isNullOrEmptyString(locale)) {
|
||||
return getMomentInstance(date);
|
||||
}
|
||||
|
||||
//
|
||||
let yearSpecifier = getUnitOfTimeForLocale(XUnitOfTime.Year, locale);
|
||||
if (isNullOrUndefined(yearSpecifier)) {
|
||||
yearSpecifier = 'year';
|
||||
}
|
||||
|
||||
//
|
||||
return getMomentInstance(date).add(value, yearSpecifier).toDate();
|
||||
}
|
||||
|
||||
/**
|
||||
* add specific amount of month to start date ...
|
||||
*
|
||||
* @param date start date ...
|
||||
* @param value amount of specific unit of time ...
|
||||
* @param locale the locale which required to date handling ...
|
||||
*/
|
||||
export function addMonth(
|
||||
date: string | number | Date,
|
||||
value: number,
|
||||
locale: XLocale = 'en-US'
|
||||
) {
|
||||
//
|
||||
if (isNullOrUndefined(date) || isNullOrEmptyString(locale)) {
|
||||
return getMomentInstance(date);
|
||||
}
|
||||
|
||||
//
|
||||
let yearSpecifier = getUnitOfTimeForLocale(XUnitOfTime.Month, locale);
|
||||
if (isNullOrUndefined(yearSpecifier)) {
|
||||
yearSpecifier = 'month';
|
||||
}
|
||||
|
||||
//
|
||||
return getMomentInstance(date).add(value, yearSpecifier).toDate();
|
||||
}
|
||||
|
||||
/**
|
||||
* add specific amount of days to start date ...
|
||||
*
|
||||
* @param date start date ...
|
||||
* @param value amount of specific unit of time ...
|
||||
* @param locale the locale which required to date handling ...
|
||||
*/
|
||||
export function addDay(
|
||||
date: string | number | Date,
|
||||
value: number,
|
||||
locale: XLocale = 'en-US'
|
||||
) {
|
||||
//
|
||||
if (isNullOrUndefined(date) || isNullOrEmptyString(locale)) {
|
||||
return getMomentInstance(date);
|
||||
}
|
||||
|
||||
//
|
||||
let yearSpecifier = getUnitOfTimeForLocale(XUnitOfTime.Day, locale);
|
||||
if (isNullOrUndefined(yearSpecifier)) {
|
||||
yearSpecifier = 'day';
|
||||
}
|
||||
|
||||
//
|
||||
return getMomentInstance(date).add(value, yearSpecifier).toDate();
|
||||
}
|
||||
|
||||
export function addUnitOfTime(
|
||||
unit?: XUnitOfTime,
|
||||
value?: number,
|
||||
date?: string | number | Date,
|
||||
locale?: XLocale
|
||||
) {
|
||||
//
|
||||
if (isNullOrUndefined(unit)) {
|
||||
unit = XUnitOfTime.Year;
|
||||
}
|
||||
|
||||
//
|
||||
if (isNullOrUndefined(date)) {
|
||||
date = new Date();
|
||||
}
|
||||
|
||||
//
|
||||
if (isNullOrUndefined(locale)) {
|
||||
locale = 'en-US';
|
||||
}
|
||||
|
||||
//
|
||||
if (isNullOrUndefined(value)) {
|
||||
value = 0;
|
||||
}
|
||||
|
||||
//
|
||||
return getMomentInstance(date)
|
||||
.add(value, getUnitOfTimeForLocale(unit, locale))
|
||||
.toDate();
|
||||
}
|
||||
|
||||
/**
|
||||
* get date time format string of given value ...
|
||||
*/
|
||||
export function toTimeFormat(value: number) {
|
||||
//
|
||||
if (value < 10) {
|
||||
return `0${value}`;
|
||||
} else {
|
||||
return `${value}`;
|
||||
}
|
||||
}
|
||||
|
||||
export function addSecconds(value?: Date, secconds?: number) {
|
||||
//
|
||||
let result = new Date();
|
||||
|
||||
//
|
||||
if (value) {
|
||||
result = value;
|
||||
}
|
||||
|
||||
//
|
||||
if (secconds) {
|
||||
result = new Date(result.getTime() + secconds * 1000);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
export function addMinutes(value?: Date, minutes?: number) {
|
||||
return addSecconds(value, minutes ? minutes * 60 : minutes);
|
||||
}
|
||||
|
||||
export function addHours(value?: Date, hours?: number) {
|
||||
return addMinutes(value, hours ? hours * 60 : hours);
|
||||
}
|
||||
|
||||
export function isExpiredDate(date: Date | string | number) {
|
||||
//
|
||||
const nowMills = new Date().getTime();
|
||||
const mDateTimeMills = new Date(date).getTime();
|
||||
|
||||
//
|
||||
return nowMills > mDateTimeMills;
|
||||
}
|
||||
|
||||
export function isExpiredUTCDate(utcDate: Date | string | number) {
|
||||
//
|
||||
const nowUTCString = new Date().toUTCString();
|
||||
const nowMills = fromUtcDate(nowUTCString).getTime();
|
||||
const mUtcDateTimeMills = fromUtcDate(utcDate).getTime();
|
||||
|
||||
//
|
||||
return nowMills > mUtcDateTimeMills;
|
||||
}
|
||||
|
||||
/**
|
||||
* convert a date to it's milliseconds representation format ...
|
||||
*
|
||||
* @param date date representer
|
||||
*/
|
||||
export function getMills(date?: Date | any) {
|
||||
//
|
||||
let mDate: Date;
|
||||
if (!date) {
|
||||
mDate = new Date();
|
||||
} else {
|
||||
mDate = new Date(date);
|
||||
}
|
||||
|
||||
//
|
||||
return mDate.getTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* convert any object to date ...
|
||||
*/
|
||||
export function momentToDate(date: any) {
|
||||
return new Date(moment(date.toString()).format());
|
||||
}
|
||||
|
||||
/**
|
||||
* check and compare two date must be same ...
|
||||
*/
|
||||
export function isSameDate(sourceDate: any, destDate: any) {
|
||||
//
|
||||
const sourceTime = new Date(sourceDate).getTime();
|
||||
const destTime = new Date(destDate).getTime();
|
||||
|
||||
//
|
||||
return sourceDate === destDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* check a given value has a date or not ...
|
||||
*
|
||||
* @param source given value to check ...
|
||||
*/
|
||||
export function isValueDate(source: any) {
|
||||
//
|
||||
let result = isDate(source);
|
||||
if (!result && (isString(source) || isNumber(source))) {
|
||||
//
|
||||
let d: Date = null;
|
||||
try {
|
||||
d = new Date(source);
|
||||
} catch {}
|
||||
|
||||
//
|
||||
result = !isNullOrUndefined(d) && isDate(d);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
//#endregion
|
||||
@@ -0,0 +1,145 @@
|
||||
import {
|
||||
keys,
|
||||
getVal,
|
||||
fromJson,
|
||||
parseJson,
|
||||
toJsonString,
|
||||
} from './x-object.tools';
|
||||
import { toNumber } from './x-type-convert.tools';
|
||||
import { toNormalString } from './x-string.tools';
|
||||
import { HttpErrorResponse } from '@angular/common/http';
|
||||
import { XExceptions, XException } from '../typings/x-exception.typings';
|
||||
import { isNumber, isString, isNullOrUndefined } from './x-type-detect.tools';
|
||||
import { XExceptionIDs, Exceptions } from '../constants/x-exception.resources';
|
||||
|
||||
export function getXException(exception: XExceptionIDs | XExceptions) {
|
||||
//
|
||||
const isExId = isNumber(exception);
|
||||
const exceptionKey = isExId ? getVal(XExceptionIDs, exception) : exception;
|
||||
|
||||
//
|
||||
return Exceptions[exceptionKey];
|
||||
}
|
||||
|
||||
export function getXExceptionsArray() {
|
||||
//
|
||||
const result: XException[] =
|
||||
keys(Exceptions).map((key: any) => Exceptions[key]) || [];
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
export function getXExceptionByErrorId(errorId: number) {
|
||||
//
|
||||
const result = getXExceptionsArray().find((e) => e.id === toNumber(errorId));
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare and Return Specific Error object
|
||||
*/
|
||||
export function getError(error: XExceptionIDs | XExceptions | XException) {
|
||||
//
|
||||
const isExId = isNumber(error);
|
||||
const isExTitle = isString(error);
|
||||
|
||||
//
|
||||
return new Error(
|
||||
toJsonString(
|
||||
isExId
|
||||
? getXException(error as XExceptionIDs)
|
||||
: isExTitle
|
||||
? getXException(error as XExceptions)
|
||||
: (error as XException)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* extract Exception information of given error param
|
||||
*/
|
||||
export function getErrorException(err: any = undefined) {
|
||||
//
|
||||
if (isNullOrUndefined(err)) {
|
||||
err = Exceptions.Unknown;
|
||||
}
|
||||
|
||||
//
|
||||
let exception: XException;
|
||||
|
||||
//
|
||||
if (err instanceof HttpErrorResponse) {
|
||||
err = err.error;
|
||||
} else if (err instanceof Error) {
|
||||
err = parseJson(err.message);
|
||||
} else {
|
||||
try {
|
||||
err = parseJson(toNormalString(err));
|
||||
} catch {}
|
||||
}
|
||||
|
||||
//
|
||||
if (isValidException(err)) {
|
||||
exception = getXExceptionByErrorId(err.id);
|
||||
} else if (isNumber(err) || isString(err)) {
|
||||
exception = getXException(err);
|
||||
} else if (err.id && isNumber(err.id)) {
|
||||
exception = getXExceptionByErrorId(err.id);
|
||||
}
|
||||
|
||||
//
|
||||
if (!exception) {
|
||||
exception = Exceptions.Unknown;
|
||||
}
|
||||
|
||||
//
|
||||
return exception;
|
||||
}
|
||||
|
||||
/**
|
||||
* check an object is Valid Exception or not ...
|
||||
*/
|
||||
export function isValidException(err: any) {
|
||||
//
|
||||
if (isNullOrUndefined(err)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
if (err.id && isNumber(err.id) && err.message && isString(err.message)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
if (err.hasOwnProperty('id') && err.hasOwnProperty('message')) {
|
||||
try {
|
||||
const jExp = fromJson<XException>(err);
|
||||
if (jExp.id && isNumber(jExp) && jExp.message && isString(jExp.message)) {
|
||||
return true;
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
|
||||
//
|
||||
const jsonStr = toNormalString(toJsonString(err));
|
||||
if (jsonStr.indexOf('id') !== -1 && jsonStr.indexOf('message') !== -1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
return false;
|
||||
}
|
||||
|
||||
export function throwException(
|
||||
exception: XExceptionIDs | XExceptions | XException
|
||||
): never {
|
||||
//
|
||||
throw getError(exception);
|
||||
}
|
||||
|
||||
export type XExceptionIdentifier =
|
||||
| XExceptionIDs
|
||||
| XExceptions
|
||||
| XException
|
||||
| string;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,287 @@
|
||||
import { hasChild } from './x-array.tools';
|
||||
import { removeAll } from './x-string.tools';
|
||||
import { throwException } from './x-exception.tools';
|
||||
import { isNullOrEmptyString } from './x-type-detect.tools';
|
||||
import { applyLocale } from '../typings/x-translation.typings';
|
||||
import { XExceptionIDs } from '../constants/x-exception.resources';
|
||||
import { XFormatterOption, XFormatterType } from '../typings/x.typings';
|
||||
|
||||
/**
|
||||
* apply a format to a string ...
|
||||
*
|
||||
* @param options format options ...
|
||||
* @param value a value which required to format ...
|
||||
*/
|
||||
export function applyFormat(options: XFormatterOption, value: string) {
|
||||
//
|
||||
value = value ? value.toString() : '';
|
||||
options = {
|
||||
...(!options ? { type: XFormatterType.ApplyLocale } : options),
|
||||
};
|
||||
|
||||
//
|
||||
const type = options.type;
|
||||
|
||||
//
|
||||
// Validate Options Based on Type ...
|
||||
switch (type) {
|
||||
//
|
||||
case XFormatterType.ApplyLocale:
|
||||
validateLocale(options);
|
||||
break;
|
||||
|
||||
//
|
||||
case XFormatterType.FormatCurrencyAndApplyLocale:
|
||||
validateLocale(options);
|
||||
validateCurrency(options);
|
||||
validateFormatter(options);
|
||||
break;
|
||||
|
||||
//
|
||||
case XFormatterType.StringFormatterAndApplyLocale:
|
||||
validateLocale(options);
|
||||
validatePattern(options);
|
||||
validateFormatter(options);
|
||||
break;
|
||||
|
||||
//
|
||||
case XFormatterType.FormatCurrency:
|
||||
validateCurrency(options);
|
||||
validateFormatter(options);
|
||||
break;
|
||||
|
||||
//
|
||||
case XFormatterType.StringFormatter:
|
||||
validatePattern(options);
|
||||
validateFormatter(options);
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Prepared Formatted Value ...
|
||||
let result = isCurrencyType(options)
|
||||
? getCurrencyFormattedValue(options, value)
|
||||
: isStringFormatterType(options)
|
||||
? getStringFormattedValue(options, value)
|
||||
: value || '';
|
||||
|
||||
//
|
||||
// Apply Locale if Localeable Input Type ...
|
||||
if (isLocaleType(options)) {
|
||||
result = getLocaleFormattedValue(options, result);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* clear applied format ...
|
||||
*
|
||||
* @param options format options ...
|
||||
* @param clearLocale clear applies locale ...
|
||||
* @param value a value wich using to clear formatt ...
|
||||
*/
|
||||
export function clearFormat(
|
||||
options: XFormatterOption,
|
||||
clearLocale: boolean,
|
||||
value: string
|
||||
) {
|
||||
//
|
||||
let result = value.toString() || '';
|
||||
|
||||
//
|
||||
const seperator = isNullOrEmptyString(options.seperator)
|
||||
? ''
|
||||
: options.seperator;
|
||||
|
||||
//
|
||||
// Remove All occurence of seperator ...
|
||||
result = removeAll(value, seperator, true);
|
||||
|
||||
//
|
||||
// Currency Lable ...
|
||||
if (isCurrencyType(options) && !isNullOrEmptyString(options.currencyLable)) {
|
||||
result = result.replace(options.currencyLable, '').trim();
|
||||
}
|
||||
|
||||
//
|
||||
// Change Locale to Default ...
|
||||
if (isLocaleType(options)) {
|
||||
result = !isNullOrEmptyString(result)
|
||||
? applyLocale(
|
||||
result,
|
||||
clearLocale ? 'en-US' : options.locale ? options.locale : 'en-US'
|
||||
)
|
||||
: '';
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
//#region applyFormat Function Helpers ...
|
||||
//
|
||||
function validateLocale(options: XFormatterOption) {
|
||||
//
|
||||
// || isNullOrEmptyString(options.locale)
|
||||
if (!options) {
|
||||
throwInvalidArgException();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
function validateCurrency(options: XFormatterOption) {
|
||||
//
|
||||
// || isNullOrEmptyString(options.currencyLable)
|
||||
if (!options) {
|
||||
throwInvalidArgException();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
function validateFormatter(options: XFormatterOption) {
|
||||
//
|
||||
// || isNullOrEmptyString(options.seperator)
|
||||
if (!options) {
|
||||
throwInvalidArgException();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
function validatePattern(options: XFormatterOption) {
|
||||
if (!options || !options.pattern) {
|
||||
throwInvalidArgException();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
function isCurrencyType(options: XFormatterOption) {
|
||||
//
|
||||
if (!options || !options.type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
switch (options.type) {
|
||||
//
|
||||
case XFormatterType.FormatCurrency:
|
||||
case XFormatterType.FormatCurrencyAndApplyLocale:
|
||||
return true;
|
||||
|
||||
//
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
function isStringFormatterType(options: XFormatterOption) {
|
||||
//
|
||||
if (!options || !options.type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
switch (options.type) {
|
||||
//
|
||||
case XFormatterType.StringFormatter:
|
||||
case XFormatterType.StringFormatterAndApplyLocale:
|
||||
return true;
|
||||
|
||||
//
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
function isLocaleType(options: XFormatterOption) {
|
||||
//
|
||||
if (!options || !options.type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
switch (options.type) {
|
||||
//
|
||||
case XFormatterType.ApplyLocale:
|
||||
case XFormatterType.FormatCurrencyAndApplyLocale:
|
||||
case XFormatterType.StringFormatterAndApplyLocale:
|
||||
return true;
|
||||
|
||||
//
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
function throwInvalidArgException() {
|
||||
throwException(XExceptionIDs.InvalidArgs);
|
||||
}
|
||||
|
||||
//
|
||||
function getLocaleFormattedValue(options: XFormatterOption, value: any) {
|
||||
//
|
||||
const mValue = value ? (value.toString() as string) : '';
|
||||
return applyLocale(mValue, options.locale);
|
||||
}
|
||||
|
||||
//
|
||||
function getStringFormattedValue(options: XFormatterOption, value: any) {
|
||||
//
|
||||
const mValue = value ? (value.toString() as string) : '';
|
||||
|
||||
//
|
||||
if (!hasChild(options.pattern)) {
|
||||
return mValue;
|
||||
}
|
||||
|
||||
//
|
||||
let mSource = mValue;
|
||||
let mResultValue = '';
|
||||
options.pattern.forEach((l, i) => {
|
||||
if (mSource.length >= l) {
|
||||
//
|
||||
const selected = mSource.substring(0, l);
|
||||
|
||||
//
|
||||
mResultValue +=
|
||||
i === options.pattern.length
|
||||
? selected
|
||||
: `${selected}${options.seperator}`;
|
||||
|
||||
//
|
||||
mSource = mSource.substr(l, mValue.length);
|
||||
}
|
||||
});
|
||||
|
||||
//
|
||||
if (mSource.length > 0) {
|
||||
mResultValue += `${mSource}`;
|
||||
}
|
||||
|
||||
//
|
||||
return mResultValue;
|
||||
}
|
||||
|
||||
//
|
||||
function getCurrencyFormattedValue(options: XFormatterOption, value: any) {
|
||||
//
|
||||
const mValue = value ? ((+value).toString() as string) : '';
|
||||
const formattedValue = mValue.replace(
|
||||
/\B(?=(\d{3})+(?!\d))/g,
|
||||
options.seperator
|
||||
);
|
||||
|
||||
//
|
||||
const result = !isNullOrEmptyString(options.currencyLable)
|
||||
? `${formattedValue} ${options.currencyLable}`
|
||||
: formattedValue;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
//#endregion
|
||||
@@ -0,0 +1,24 @@
|
||||
//
|
||||
//#region Number Tools ...
|
||||
/**
|
||||
* generate a random number in specific range ...
|
||||
*/
|
||||
export function random(min?: number, max?: number) {
|
||||
//
|
||||
if (!min) {
|
||||
min = 0;
|
||||
}
|
||||
|
||||
//
|
||||
if (!max) {
|
||||
max = 1000;
|
||||
}
|
||||
|
||||
//
|
||||
min = Math.ceil(min);
|
||||
max = Math.floor(max);
|
||||
|
||||
//
|
||||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
}
|
||||
//#endregion
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,186 @@
|
||||
import {
|
||||
of,
|
||||
from,
|
||||
Subject,
|
||||
forkJoin,
|
||||
Observable,
|
||||
isObservable,
|
||||
combineLatest,
|
||||
} from 'rxjs';
|
||||
import {
|
||||
map,
|
||||
first,
|
||||
finalize,
|
||||
switchMap,
|
||||
distinctUntilChanged,
|
||||
} from 'rxjs/operators';
|
||||
import {
|
||||
isObject,
|
||||
isPromise,
|
||||
isNullOrUndefined,
|
||||
isNullOrEmptyString,
|
||||
} from './x-type-detect.tools';
|
||||
import { keys } from './x-object.tools';
|
||||
import { EventEmitter, Type } from '@angular/core';
|
||||
import { hasChild, toArray } from './x-array.tools';
|
||||
import {
|
||||
XHasAction,
|
||||
XOneOrManyType,
|
||||
XPropertyType,
|
||||
XStandardType,
|
||||
} from '../typings/x.typings';
|
||||
|
||||
//
|
||||
//#region Handlers ...
|
||||
export function applyFinally<T>(obs: Observable<T>, action: () => void) {
|
||||
return obs.pipe(finalize(action));
|
||||
}
|
||||
|
||||
export function hasValue<T>(obs: Observable<T>) {
|
||||
return obs.pipe(map((res) => !isNullOrUndefined(res)));
|
||||
}
|
||||
|
||||
export function hasStringValue(obs: Observable<string>) {
|
||||
return obs.pipe(map((res) => !isNullOrEmptyString(res)));
|
||||
}
|
||||
|
||||
export function notValue(obs: Observable<boolean>) {
|
||||
return obs.pipe(map((res) => (isNullOrUndefined(res) ? true : !res)));
|
||||
}
|
||||
|
||||
export function toPromise<T>(value: XStandardType<T>) {
|
||||
return toObservable(value).pipe(first()).toPromise();
|
||||
}
|
||||
|
||||
export function toObservable<T>(value: XStandardType<T>) {
|
||||
//
|
||||
let result: Observable<T>;
|
||||
|
||||
//
|
||||
if (isObservable<T>(value)) {
|
||||
result = value as Observable<T>;
|
||||
} else if (isPromise(value)) {
|
||||
result = from(value as Promise<T>);
|
||||
} else {
|
||||
result = of(value as T);
|
||||
}
|
||||
|
||||
//
|
||||
return result.pipe(first());
|
||||
}
|
||||
|
||||
/**
|
||||
* filter an array by providing an observable condition ...
|
||||
* @param list an instance of XStandardType<XOneOrMany<T>>
|
||||
* @param condition a condition
|
||||
* @returns array result ...
|
||||
*/
|
||||
export function filterList<T>(
|
||||
list: XStandardType<XOneOrManyType<T>>,
|
||||
condition: (item: T) => XStandardType<boolean>
|
||||
) {
|
||||
return toObservable(list)
|
||||
.pipe(map((valueType) => toArray(valueType)))
|
||||
.pipe(
|
||||
switchMap((array) =>
|
||||
combineLatest(
|
||||
array.map((item) =>
|
||||
toObservable(condition(item)).pipe(
|
||||
distinctUntilChanged(),
|
||||
map((result) => (result ? item : null))
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
map((resultArray) => resultArray.filter((action) => action))
|
||||
);
|
||||
}
|
||||
|
||||
export function flatObject<T>(input: T): Observable<any> {
|
||||
//
|
||||
let result = {};
|
||||
let afterJoin = {};
|
||||
|
||||
//
|
||||
const inputKeys = keys(input);
|
||||
if (!hasChild(inputKeys)) {
|
||||
return of(result);
|
||||
}
|
||||
|
||||
//
|
||||
for (const key of inputKeys) {
|
||||
//
|
||||
const item = input[key];
|
||||
|
||||
//
|
||||
const isItemObject = isObject(item);
|
||||
if (isItemObject) {
|
||||
//
|
||||
if (item instanceof EventEmitter || item instanceof Subject) {
|
||||
afterJoin[key] = item;
|
||||
} else {
|
||||
result[key] = flatObject(item);
|
||||
}
|
||||
} else {
|
||||
result[key] = toObservable(item);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return forkJoin(result).pipe(
|
||||
map((res) => {
|
||||
return {
|
||||
//
|
||||
...(res as any),
|
||||
|
||||
//
|
||||
...afterJoin,
|
||||
};
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
export function nextSubjectWhenElementExists<TAction>(
|
||||
action: XPropertyType<XHasAction<TAction>, 'action'>,
|
||||
className: string,
|
||||
actionProvider: Subject<XHasAction<TAction>>,
|
||||
delay: number = 200,
|
||||
payload?: any
|
||||
) {
|
||||
//
|
||||
// Validate ...
|
||||
if (
|
||||
isNullOrUndefined(action) ||
|
||||
isNullOrEmptyString(className) ||
|
||||
isNullOrUndefined(actionProvider)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Query to Select Target Elements ...
|
||||
const elements: NodeListOf<Element> = document.querySelectorAll(
|
||||
`.${className}`
|
||||
);
|
||||
|
||||
//
|
||||
if (isNullOrUndefined(elements) || !hasChild(elements)) {
|
||||
//
|
||||
setTimeout(
|
||||
() =>
|
||||
nextSubjectWhenElementExists(
|
||||
action,
|
||||
className,
|
||||
actionProvider,
|
||||
delay,
|
||||
payload
|
||||
),
|
||||
delay
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
actionProvider.next({ action, payload });
|
||||
}
|
||||
//#endregion
|
||||
@@ -0,0 +1,146 @@
|
||||
import { toPromise } from './x-observable.tools';
|
||||
import { XPage } from '../typings/x-page.typings';
|
||||
import { hasChild, toArray } from './x-array.tools';
|
||||
import { XOneOrManyType } from '../typings/x.typings';
|
||||
import { mergeRoutes, toNormalString } from './x-string.tools';
|
||||
import { isNullOrEmptyString, isNullOrUndefined } from './x-type-detect.tools';
|
||||
|
||||
export async function toFlatPages(pages: XOneOrManyType<XPage>) {
|
||||
//
|
||||
const result: XPage[] = [];
|
||||
|
||||
//
|
||||
if (!pages || !hasChild(pages)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
const pagesArray = toArray(pages);
|
||||
for (const page of pagesArray) {
|
||||
//
|
||||
const childsArray = await toPromise(page.childs);
|
||||
const isParent = hasChild(childsArray);
|
||||
|
||||
//
|
||||
result.push(page);
|
||||
|
||||
//
|
||||
if (isParent) {
|
||||
//
|
||||
const childsRes = await toFlatPages(page.childs);
|
||||
result.push(...childsRes);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
export async function findPageByRoute(
|
||||
pages: XOneOrManyType<XPage>,
|
||||
route: XOneOrManyType<string>
|
||||
) {
|
||||
//
|
||||
let result: XPage = null;
|
||||
|
||||
//
|
||||
if (!hasChild(pages) || !hasChild(route)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
const pRoute = mergeRoutes(route);
|
||||
const pPages = await toFlatPages(pages);
|
||||
if (!hasChild(pPages)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
for (const page of pPages) {
|
||||
//
|
||||
if (hasChild(page.route)) {
|
||||
//
|
||||
const pageRoute = mergeRoutes(page.route);
|
||||
if (
|
||||
!isNullOrEmptyString(pageRoute) &&
|
||||
toNormalString(pageRoute) === toNormalString(pRoute)
|
||||
) {
|
||||
result = page;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
export async function containsPagesByRoute(
|
||||
pages: XOneOrManyType<XPage>,
|
||||
route: XOneOrManyType<string>
|
||||
) {
|
||||
//
|
||||
const result: XPage[] = [];
|
||||
|
||||
//
|
||||
if (!hasChild(pages) || !hasChild(route)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
const pRoute = mergeRoutes(route);
|
||||
if (isNullOrEmptyString(pRoute)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
const pPages = await toFlatPages(pages);
|
||||
if (!hasChild(pPages)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
for (const page of pPages) {
|
||||
//
|
||||
if (hasChild(page.route)) {
|
||||
//
|
||||
const pageRoute = mergeRoutes(page.route);
|
||||
if (
|
||||
!isNullOrEmptyString(pageRoute) &&
|
||||
toNormalString(pRoute).includes(toNormalString(pageRoute))
|
||||
) {
|
||||
result.push(page);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
export async function parentPagesByRoute(
|
||||
pages: XOneOrManyType<XPage>,
|
||||
route: XOneOrManyType<string>
|
||||
) {
|
||||
//
|
||||
let result: XPage[] = [];
|
||||
|
||||
//
|
||||
if (!hasChild(pages) || !hasChild(route)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
const parentPages = await containsPagesByRoute(pages, route);
|
||||
const foundedPage = await findPageByRoute(pages, route);
|
||||
if (!hasChild(parentPages) || isNullOrUndefined(foundedPage)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = parentPages.filter(
|
||||
(i) => toNormalString(i.id) !== toNormalString(foundedPage.id)
|
||||
);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,516 @@
|
||||
import { Md5 } from 'md5-typescript';
|
||||
import { hasChild, toArray } from './x-array.tools';
|
||||
import { XOneOrManyType } from '../typings/x.typings';
|
||||
import { isNullOrEmptyString, isString } from './x-type-detect.tools';
|
||||
|
||||
//
|
||||
export const XStringPlaceHolder = '(%$s)';
|
||||
|
||||
export const XEnDigits: string[] = [
|
||||
'0',
|
||||
'1',
|
||||
'2',
|
||||
'3',
|
||||
'4',
|
||||
'5',
|
||||
'6',
|
||||
'7',
|
||||
'8',
|
||||
'9',
|
||||
];
|
||||
export const XFaDigits: string[] = [
|
||||
'۰',
|
||||
'۱',
|
||||
'۲',
|
||||
'۳',
|
||||
'۴',
|
||||
'۵',
|
||||
'۶',
|
||||
'۷',
|
||||
'۸',
|
||||
'۹',
|
||||
];
|
||||
|
||||
//
|
||||
//#region String Utils ...
|
||||
/**
|
||||
* determines given string is empty or not ...
|
||||
*/
|
||||
export function isEmpty(value: string) {
|
||||
//
|
||||
if (isString(value) && value.length === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* return digits of given string ...
|
||||
*/
|
||||
export function getDigits(value: string) {
|
||||
//
|
||||
if (!isString(value)) {
|
||||
throw new Error('Invalid Parameter ...');
|
||||
}
|
||||
|
||||
//
|
||||
let result = '';
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
//
|
||||
const chr = value.substr(i, 1);
|
||||
if (chr in XEnDigits) {
|
||||
//
|
||||
result += chr;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* return non digits of given string ...
|
||||
*/
|
||||
export function getNonDigits(value: string) {
|
||||
//
|
||||
if (!isString(value)) {
|
||||
throw new Error('Invalid Parameter ...');
|
||||
}
|
||||
|
||||
//
|
||||
value = toEnNumbers(value);
|
||||
|
||||
//
|
||||
let result = '';
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
//
|
||||
const chr = value.substr(i, 1);
|
||||
if (!(chr in XEnDigits)) {
|
||||
//
|
||||
result += chr;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* determine an expression contains only digits
|
||||
*/
|
||||
export function isOnlyDigits(value: string) {
|
||||
//
|
||||
if (isEmpty(value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
const pattern = /^\d+$/;
|
||||
return pattern.test(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* merge several parts of a url ...
|
||||
*
|
||||
* @param route an instance of url tree array ...
|
||||
*/
|
||||
export function mergeRoutes(route: XOneOrManyType<string>) {
|
||||
//
|
||||
if (!hasChild(route)) {
|
||||
return '/';
|
||||
}
|
||||
|
||||
//
|
||||
try {
|
||||
return toArray(route).join('/').replace('//', '/');
|
||||
} catch {}
|
||||
|
||||
//
|
||||
return '/';
|
||||
}
|
||||
|
||||
/**
|
||||
* format string formatter ...
|
||||
*
|
||||
* @param value an string to format ...
|
||||
* @param args the args for string formatter ...
|
||||
*/
|
||||
export function stringFormatter(value: string, ...args: any) {
|
||||
//
|
||||
if (!isString(value)) {
|
||||
throw new Error('first arg must be an string ...');
|
||||
}
|
||||
|
||||
//
|
||||
if (args.length < 1) {
|
||||
throw new Error('there mest be values ...');
|
||||
}
|
||||
|
||||
//
|
||||
const holder = XStringPlaceHolder;
|
||||
let numberOfHolders = 0;
|
||||
|
||||
//
|
||||
if (value.length < holder.length) {
|
||||
throw new Error('the sting doesnt contain any holder ...');
|
||||
}
|
||||
|
||||
//
|
||||
// tslint:disable-next-line:no-shadowed-variable
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
//
|
||||
const indexStr = value.substr(i, holder.length);
|
||||
|
||||
//
|
||||
if (indexStr === holder) {
|
||||
numberOfHolders++;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
if (numberOfHolders !== args.length) {
|
||||
throw new Error('theholders and parameters counts must be same ...');
|
||||
}
|
||||
|
||||
//
|
||||
// tslint:disable-next-line:prefer-for-of
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
//
|
||||
const a = value.indexOf(holder);
|
||||
|
||||
//
|
||||
value =
|
||||
value.substr(0, a) +
|
||||
args[i].toString() +
|
||||
value.substr(a + holder.length, value.length - (a + holder.length));
|
||||
}
|
||||
|
||||
//
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* change all persian and arabic numers to english digits
|
||||
*/
|
||||
export function toEnNumbers(value: string): string {
|
||||
//
|
||||
let result = value ? value.toString() : '';
|
||||
|
||||
//
|
||||
const persianNumbers = [
|
||||
/۰/g,
|
||||
/۱/g,
|
||||
/۲/g,
|
||||
/۳/g,
|
||||
/۴/g,
|
||||
/۵/g,
|
||||
/۶/g,
|
||||
/۷/g,
|
||||
/۸/g,
|
||||
/۹/g,
|
||||
];
|
||||
const arabicNumbers = [
|
||||
/٠/g,
|
||||
/١/g,
|
||||
/٢/g,
|
||||
/٣/g,
|
||||
/٤/g,
|
||||
/٥/g,
|
||||
/٦/g,
|
||||
/٧/g,
|
||||
/٨/g,
|
||||
/٩/g,
|
||||
];
|
||||
|
||||
//
|
||||
for (let i = 0; i < 10; i++) {
|
||||
if (!isNullOrEmptyString(result)) {
|
||||
result = result
|
||||
.replace(persianNumbers[i], i.toString())
|
||||
.replace(arabicNumbers[i], i.toString());
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* change all english digits to persian digits
|
||||
*/
|
||||
export function toPersianNumbers(value: string): string {
|
||||
//
|
||||
let result = value;
|
||||
|
||||
//
|
||||
for (let i = 0; i < 10; i++) {
|
||||
result = result.replace(new RegExp(i.toString(), 'g'), XFaDigits[i]);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* remove all spaces on string value ...
|
||||
*
|
||||
* @param value an string value ...
|
||||
*/
|
||||
export function removeSpaces(value: string): string {
|
||||
return value.replace(/\s/g, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* remove margin spaces and make text lowercase
|
||||
*/
|
||||
export function toNormalString(value: string): string {
|
||||
return isNullOrEmptyString(value) ? '' : value.trim().toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Capitalize an string ...
|
||||
*
|
||||
* @param value input string ..
|
||||
* @returns string
|
||||
*/
|
||||
export function capital(value: string): string {
|
||||
//
|
||||
if (isNullOrEmptyString(value) || isNullOrEmptyString(value.trim())) {
|
||||
return '';
|
||||
}
|
||||
|
||||
//
|
||||
value = value.trim();
|
||||
const firstChar = value.charAt(0).toLocaleUpperCase();
|
||||
const otherChars = value.slice(1);
|
||||
|
||||
//
|
||||
const result = `${firstChar}${otherChars}`;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* convert an string to Md5 ...
|
||||
*
|
||||
* @param value an string which going to convert
|
||||
*/
|
||||
export function toMd5(value: string) {
|
||||
return isNullOrEmptyString(value) ? '' : Md5.init(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* convert given string to array buffer ...
|
||||
*
|
||||
* @param value the string which need to convert
|
||||
*/
|
||||
export function toArrayBuffer(value: string) {
|
||||
//
|
||||
if (!value || value.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
//
|
||||
const stringLength = value.length;
|
||||
const buffer = new ArrayBuffer(stringLength * 2);
|
||||
const bufferView = new Uint16Array(buffer);
|
||||
|
||||
//
|
||||
for (let i = 0; i < stringLength; i++) {
|
||||
bufferView[i] = value.charCodeAt(i);
|
||||
}
|
||||
|
||||
//
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* convert byte array to string ...
|
||||
*
|
||||
* @param buffer the bytes array of an string
|
||||
*/
|
||||
export function fromArryBuffer(buffer: ArrayBuffer) {
|
||||
return String.fromCharCode.apply(null, Array.from(new Uint16Array(buffer)));
|
||||
}
|
||||
|
||||
/**
|
||||
* escape reg exp chars from an string ...
|
||||
*
|
||||
* @param source given string value to escape
|
||||
* @returns escaped source value
|
||||
*/
|
||||
export function escapeRegExp(source: string) {
|
||||
return source.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
|
||||
}
|
||||
|
||||
/**
|
||||
* find all indexes of an string inside another and return them as an array ...
|
||||
*/
|
||||
export function findAllIndex(source: string, query: string) {
|
||||
//
|
||||
const result: number[] = [];
|
||||
|
||||
//
|
||||
const regExp = new RegExp(escapeRegExp(query), 'gi');
|
||||
let match: any;
|
||||
// tslint:disable-next-line:no-conditional-assignment
|
||||
while ((match = regExp.exec(source)) !== null) {
|
||||
result.push(match.index);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* insert a text to specific position on another text ...
|
||||
*/
|
||||
export function insertText(source: string, insertedText: string, pos: number) {
|
||||
//
|
||||
if (!source && !insertText) {
|
||||
return '';
|
||||
}
|
||||
|
||||
//
|
||||
if (!source && insertText) {
|
||||
return insertedText;
|
||||
}
|
||||
|
||||
//
|
||||
if (pos > source.length) {
|
||||
return source + insertedText;
|
||||
}
|
||||
|
||||
//
|
||||
return [source.slice(0, pos), insertedText, source.slice(pos)].join('');
|
||||
}
|
||||
|
||||
/**
|
||||
* remove all occurence of an string inside of another string
|
||||
*/
|
||||
export function removeAll(
|
||||
source: string,
|
||||
removedString: string,
|
||||
caseSensitive = false
|
||||
) {
|
||||
//
|
||||
if (isNullOrEmptyString(removedString)) {
|
||||
removedString = '';
|
||||
}
|
||||
|
||||
//
|
||||
const regExp = new RegExp(
|
||||
removedString.toString(),
|
||||
caseSensitive ? 'gi' : 'g'
|
||||
);
|
||||
|
||||
//
|
||||
if (isNullOrEmptyString(source)) {
|
||||
source = '';
|
||||
}
|
||||
|
||||
//
|
||||
const result = source.toString().replace(regExp, '');
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* extract all unique characters of an string ...
|
||||
*
|
||||
* @param value source string
|
||||
*/
|
||||
export function extractUniqueChars(value: string) {
|
||||
//
|
||||
if (isNullOrEmptyString(value)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
//
|
||||
let result = '';
|
||||
|
||||
//
|
||||
// tslint:disable-next-line:prefer-for-of
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
if (result.indexOf(value.charAt(i)) === -1) {
|
||||
result += value[i];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* check an string contains unique chars or not ...
|
||||
*
|
||||
* @param value source string
|
||||
*/
|
||||
export function hasUniqueChar(value: string) {
|
||||
//
|
||||
if (isNullOrEmptyString(value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
const uniqueChars = extractUniqueChars(value);
|
||||
if (isNullOrEmptyString(uniqueChars)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// const valueCharsArray = Array.from(value);
|
||||
const uniqueCharsArray = Array.from(uniqueChars);
|
||||
const findUniquArray = uniqueCharsArray.map((v) => {
|
||||
//
|
||||
const resultRes = findAllIndex(value, v);
|
||||
|
||||
//
|
||||
return resultRes && resultRes.length === 1;
|
||||
});
|
||||
|
||||
//
|
||||
const result = findUniquArray.includes(true);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* convert an array object to list string ...
|
||||
*
|
||||
* @param values an array object to convert it to list string
|
||||
* @param seperator list seperator ...
|
||||
*/
|
||||
export function toListString(
|
||||
values: XOneOrManyType<string>,
|
||||
seperator: string = ','
|
||||
) {
|
||||
//
|
||||
const valueArr = toArray(values);
|
||||
if (!hasChild(valueArr)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
//
|
||||
return valueArr.join(seperator);
|
||||
}
|
||||
|
||||
/**
|
||||
* convert a list string to string array ..
|
||||
*
|
||||
* @param listString a list string
|
||||
* @param seperator list seperator ...
|
||||
*/
|
||||
export function parseListString(listString: string, seperator: string = ',') {
|
||||
//
|
||||
if (!isNullOrEmptyString(listString)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
//
|
||||
return listString.split(seperator);
|
||||
}
|
||||
//#endregion
|
||||
@@ -0,0 +1,89 @@
|
||||
export const taskIdStartKey = '_[';
|
||||
export const taskIdEndKey = ']';
|
||||
|
||||
/**
|
||||
* check if task name contains id ...
|
||||
*
|
||||
* @param key the task name ...
|
||||
*/
|
||||
export function hasTaskId(key: string | any) {
|
||||
//
|
||||
if (!key) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
const mKey = key.toString() as string;
|
||||
return mKey.includes(taskIdStartKey) && mKey.includes(taskIdEndKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieve and extract the raw task name from a task name ...
|
||||
*
|
||||
* @param key the task name ...
|
||||
*/
|
||||
export function getTaskName(key: string | any) {
|
||||
//
|
||||
if (!key) {
|
||||
return '';
|
||||
}
|
||||
|
||||
//
|
||||
const mKey = key.toString() as string;
|
||||
|
||||
//
|
||||
if (!hasTaskId(mKey)) {
|
||||
return mKey;
|
||||
}
|
||||
|
||||
//
|
||||
const taskId = getTaskId(mKey);
|
||||
const taskIdString = `${taskIdStartKey}${taskId}${taskIdEndKey}`;
|
||||
const result = mKey.replace(taskIdString, '');
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieve and extract the id inside a task name ...
|
||||
*
|
||||
* @param key the task name ...
|
||||
*/
|
||||
export function getTaskId(key: string | any) {
|
||||
//
|
||||
// Validate Args ...
|
||||
if (!key || !hasTaskId(key)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
//
|
||||
// Task Id ...
|
||||
let result = key.toString() as string;
|
||||
|
||||
//
|
||||
// Validating Info ...
|
||||
let index = result.indexOf(taskIdStartKey);
|
||||
|
||||
//
|
||||
result = result.substr(index, result.length);
|
||||
result = result.replace(taskIdStartKey, '');
|
||||
|
||||
//
|
||||
index = result.indexOf(taskIdEndKey);
|
||||
result = result.substring(0, index);
|
||||
|
||||
//
|
||||
// Return Result ...
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* prepare a Task With ID and return ...
|
||||
*
|
||||
* @param key the Task Name ...
|
||||
* @param id th ID ...
|
||||
*/
|
||||
export function setTaskId(key: string | any, id: string | any) {
|
||||
return `${key.toString()}${taskIdStartKey}${id.toString()}${taskIdEndKey}`;
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
import {
|
||||
isDate,
|
||||
isNull,
|
||||
isFile,
|
||||
isBlob,
|
||||
isArray,
|
||||
isObject,
|
||||
isBoolean,
|
||||
isUndefined,
|
||||
isNullOrUndefined,
|
||||
isNullOrEmptyString,
|
||||
} from './x-type-detect.tools';
|
||||
import { blobToFile, generateFileName } from './x-file.tools';
|
||||
|
||||
export interface XToFormDataOptions {
|
||||
/**
|
||||
* include array indices in FormData keys
|
||||
* defaults to false
|
||||
*/
|
||||
indices?: boolean;
|
||||
|
||||
/**
|
||||
* treat null values like undefined values and ignore them
|
||||
* defaults to false
|
||||
*/
|
||||
nullsAsUndefineds?: boolean;
|
||||
|
||||
/**
|
||||
* convert true or false to 1 or 0 respectively
|
||||
* defaults to false
|
||||
*/
|
||||
booleansAsIntegers?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an Object to FormData ...
|
||||
*
|
||||
* @param source the object which going to convert to FormData ...
|
||||
* @param options Converter Options ...
|
||||
* @param formData an exists FormData instance which apply object to it ...
|
||||
* @param keysPrefix key prefix for FormData Values ...
|
||||
*/
|
||||
export function toFormData(
|
||||
source: any,
|
||||
options?: XToFormDataOptions,
|
||||
formData?: FormData,
|
||||
keysPrefix?: string
|
||||
) {
|
||||
//
|
||||
//#region Prepare Options ...
|
||||
options = options || {};
|
||||
|
||||
options.indices = isNullOrUndefined(options.indices) ? true : options.indices;
|
||||
|
||||
options.nullsAsUndefineds = isNullOrUndefined(options.nullsAsUndefineds)
|
||||
? false
|
||||
: options.nullsAsUndefineds;
|
||||
|
||||
options.booleansAsIntegers = isNullOrUndefined(options.booleansAsIntegers)
|
||||
? false
|
||||
: options.booleansAsIntegers;
|
||||
//#endregion
|
||||
|
||||
//
|
||||
formData = formData || new FormData();
|
||||
|
||||
//
|
||||
//#region Do Convertion ...
|
||||
if (isUndefined(source)) {
|
||||
return formData;
|
||||
} else if (isNull(source)) {
|
||||
//
|
||||
if (!options.nullsAsUndefineds) {
|
||||
formData.append(keysPrefix, '');
|
||||
}
|
||||
} else if (isBoolean(source)) {
|
||||
//
|
||||
if (options.booleansAsIntegers) {
|
||||
formData.append(keysPrefix, source ? '1' : '0');
|
||||
} else {
|
||||
formData.append(keysPrefix, source);
|
||||
}
|
||||
} else if (isArray(source)) {
|
||||
//
|
||||
if (source.length) {
|
||||
source.forEach((value: any, index: number) => {
|
||||
const key = keysPrefix + '[' + (options.indices ? index : '') + ']';
|
||||
formData = toFormData(value, options, formData, key);
|
||||
});
|
||||
}
|
||||
} else if (isDate(source)) {
|
||||
formData.append(keysPrefix, source.toISOString());
|
||||
} else if (isObject(source) && !isFile(source) && !isBlob(source)) {
|
||||
//
|
||||
Object.keys(source).forEach((prop) => {
|
||||
//
|
||||
const value = source[prop];
|
||||
|
||||
//
|
||||
if (isArray(value)) {
|
||||
while (prop.length > 2 && prop.lastIndexOf('[]') === prop.length - 2) {
|
||||
prop = prop.substring(0, prop.length - 2);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
const key = keysPrefix ? keysPrefix + '[' + prop + ']' : prop;
|
||||
|
||||
//
|
||||
formData = toFormData(value, options, formData, key);
|
||||
});
|
||||
} else if (isFile(source) || isBlob(source)) {
|
||||
//
|
||||
let file: File = null;
|
||||
if (isFile(source)) {
|
||||
file = source as File;
|
||||
} else if (isBlob(source)) {
|
||||
//
|
||||
const blob = source as Blob;
|
||||
const fileName = generateFileName(blob);
|
||||
file = blobToFile(blob, fileName);
|
||||
}
|
||||
|
||||
//
|
||||
formData.append(keysPrefix, file, file.name);
|
||||
} else {
|
||||
formData.append(keysPrefix, source.toString());
|
||||
}
|
||||
//#endregion
|
||||
|
||||
return formData;
|
||||
}
|
||||
|
||||
/**
|
||||
* log an instance of FormData object's Content in Console ...
|
||||
*/
|
||||
export async function getFormDataContent(source: FormData) {
|
||||
return await new Response(source).text();
|
||||
}
|
||||
|
||||
/**
|
||||
* log an instance of FormData object's Content in Console ...
|
||||
*/
|
||||
export async function logFormData(source: FormData) {
|
||||
//
|
||||
const result = await getFormDataContent(source);
|
||||
console.log(result);
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
//
|
||||
//#region Type Converter ...
|
||||
/**
|
||||
* convert given object to string ...
|
||||
*/
|
||||
export function toXString(object: any) {
|
||||
//
|
||||
try {
|
||||
//
|
||||
return String(object);
|
||||
} catch (error) {
|
||||
//
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* convert given object to number ...
|
||||
*/
|
||||
export function toNumber(object: any) {
|
||||
//
|
||||
try {
|
||||
//
|
||||
return Number(object);
|
||||
} catch (error) {
|
||||
//
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* convert given object to date ...
|
||||
*/
|
||||
export function toDate(object: any) {
|
||||
//
|
||||
try {
|
||||
//
|
||||
return new Date(object);
|
||||
} catch (error) {
|
||||
//
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* convert given object to boolean ...
|
||||
*/
|
||||
export function toBoolean(object: any) {
|
||||
//
|
||||
try {
|
||||
//
|
||||
// tslint:disable-next-line:no-eval
|
||||
return Boolean(eval(object));
|
||||
} catch (error) {
|
||||
//
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
//#endregion
|
||||
@@ -0,0 +1,65 @@
|
||||
import {
|
||||
isArray,
|
||||
isObject,
|
||||
isNumber,
|
||||
isString,
|
||||
isBoolean,
|
||||
} from './x-type-detect.tools';
|
||||
import { XStandardType } from '../typings/x.typings';
|
||||
import { toObservable, toPromise } from './x-observable.tools';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
export async function getDefaultValueAsync<T>(t: XStandardType<T>): Promise<T> {
|
||||
//
|
||||
let result: any;
|
||||
|
||||
//
|
||||
const tVal = await toPromise(toObservable<T>(t));
|
||||
|
||||
//
|
||||
if (isBoolean(tVal)) {
|
||||
result = false;
|
||||
} else if (isNumber(tVal)) {
|
||||
result = 0;
|
||||
} else if (isString(tVal)) {
|
||||
result = '';
|
||||
} else if (isObject(tVal) && !isArray(tVal)) {
|
||||
result = null;
|
||||
} else if (isArray(tVal)) {
|
||||
result = [];
|
||||
} else {
|
||||
result = undefined;
|
||||
}
|
||||
|
||||
//
|
||||
return result as T;
|
||||
}
|
||||
|
||||
export function getDefaultValue<T>(t: XStandardType<T>): Observable<T> {
|
||||
//
|
||||
return toObservable<T>(t).pipe(
|
||||
map((tVal) => {
|
||||
//
|
||||
let result: any;
|
||||
|
||||
//
|
||||
if (isBoolean(tVal)) {
|
||||
result = false;
|
||||
} else if (isNumber(tVal)) {
|
||||
result = 0;
|
||||
} else if (isString(tVal)) {
|
||||
result = '';
|
||||
} else if (isObject(tVal) && !isArray(tVal)) {
|
||||
result = null;
|
||||
} else if (isArray(tVal)) {
|
||||
result = [];
|
||||
} else {
|
||||
result = undefined;
|
||||
}
|
||||
|
||||
//
|
||||
return result as T;
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,215 @@
|
||||
/**
|
||||
* Custom Data Types ...
|
||||
*/
|
||||
export const DataTypes = {
|
||||
Null: 'null',
|
||||
Undefined: 'undefined',
|
||||
String: 'string',
|
||||
Number: 'number',
|
||||
Boolean: 'boolean',
|
||||
Object: 'object',
|
||||
Function: 'function',
|
||||
};
|
||||
|
||||
/**
|
||||
* determines type of an object
|
||||
*
|
||||
* @param variable specified object
|
||||
*/
|
||||
export function getType(variable: any) {
|
||||
return typeof variable;
|
||||
}
|
||||
|
||||
//
|
||||
//#region Type Checker ...
|
||||
/**
|
||||
* determine a var is null or not ...
|
||||
*/
|
||||
export function isNull(variable: any) {
|
||||
//
|
||||
if (
|
||||
!variable &&
|
||||
(variable === null || getType(variable) === DataTypes.Null)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* determine a var is undefined ...
|
||||
*/
|
||||
export function isUndefined(variable: any) {
|
||||
//
|
||||
if (getType(variable) === DataTypes.Undefined) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* setermine a var is null or undefined ...
|
||||
*/
|
||||
export function isNullOrUndefined(variable: any) {
|
||||
//
|
||||
if (isNull(variable) || isUndefined(variable)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
return false;
|
||||
}
|
||||
|
||||
export function isNullOrEmptyString(variable: string) {
|
||||
//
|
||||
if (isNull(variable) || isUndefined(variable) || variable.length === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
return false;
|
||||
}
|
||||
|
||||
export function isNullOrZeroLength(variable: any[]) {
|
||||
//
|
||||
if (isNullOrUndefined(variable)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
return variable.length === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* determine a var is string or not ...
|
||||
*/
|
||||
export function isString(variable: any) {
|
||||
//
|
||||
if (getType(variable) === DataTypes.String) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* determine a var is Number or not ...
|
||||
*/
|
||||
export function isNumber(variable: any) {
|
||||
//
|
||||
if (getType(variable) === DataTypes.Number) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
var numValue = parseInt(variable, 10);
|
||||
if (isNaN(numValue)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* determine a var is boolean or not ...
|
||||
*/
|
||||
export function isBoolean(variable: any) {
|
||||
//
|
||||
if (getType(variable) === DataTypes.Boolean) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* determine a object is Array or not ...
|
||||
*
|
||||
* IMPORTANT: an array must be an object ...
|
||||
*/
|
||||
export function isArray(value: any) {
|
||||
return value && Array.isArray(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* determine a var is object or not ...
|
||||
*/
|
||||
export function isObject(variable: any) {
|
||||
//
|
||||
return (
|
||||
variable &&
|
||||
getType(variable) === DataTypes.Object &&
|
||||
variable === Object(variable)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* determine a var is function or not ...
|
||||
*/
|
||||
export function isFunction(variable: any) {
|
||||
//
|
||||
if (getType(variable) === DataTypes.Function) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* determine a var is Blob ...
|
||||
*/
|
||||
export function isBlob(value: any) {
|
||||
return (
|
||||
value &&
|
||||
typeof value.size === 'number' &&
|
||||
typeof value.type === 'string' &&
|
||||
typeof value.slice === 'function'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* check an input arg is a date object or not ...
|
||||
*
|
||||
* @param source any arg which required to check
|
||||
*/
|
||||
export function isDate(source: any) {
|
||||
return (
|
||||
source &&
|
||||
isObject(source) &&
|
||||
(source instanceof Date ||
|
||||
isFunction(source.getMonth) ||
|
||||
Object.prototype.toString.call(source) === '[object Date]')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* determine a var is File ...
|
||||
*/
|
||||
export function isFile(value: any) {
|
||||
return (
|
||||
isBlob(value) &&
|
||||
typeof value.name === 'string' &&
|
||||
(typeof value.lastModifiedDate === 'object' ||
|
||||
typeof value.lastModified === 'number')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* check wheather an object is promise or not ...
|
||||
*/
|
||||
export function isPromise(variable: any) {
|
||||
if (!isNullOrUndefined(variable) && isFunction(variable.then)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
//#endregion
|
||||
@@ -0,0 +1,16 @@
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { v5 as uuidv5 } from 'uuid';
|
||||
|
||||
export const DEFAULT_NAMESPACE = 'SaherElm IT Center';
|
||||
export function generateUuid(
|
||||
prefix?: string,
|
||||
content?: string,
|
||||
nameSpace: string = DEFAULT_NAMESPACE
|
||||
) {
|
||||
//
|
||||
const uId = content ? uuidv5(content, nameSpace) : uuidv4();
|
||||
const result = prefix ? `${prefix}_${uId}` : uId;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export const DEFAULT_EXPORT_TYPING_BASE = 'default';
|
||||
@@ -0,0 +1,105 @@
|
||||
//
|
||||
import { XBaseKeyValue } from './x.typings';
|
||||
|
||||
//#region Color Tools ...
|
||||
export interface XColorDescribtor {
|
||||
name: XColor;
|
||||
brightnessLevel: XColorBrightnessLevel;
|
||||
isContrast?: boolean;
|
||||
}
|
||||
|
||||
export enum XColor {
|
||||
Primary = 'primary',
|
||||
Secondary = 'secondary',
|
||||
Tertiary = 'tertiary',
|
||||
Success = 'success',
|
||||
Warning = 'warning',
|
||||
Danger = 'danger',
|
||||
Dark = 'dark',
|
||||
Medium = 'medium',
|
||||
Light = 'light',
|
||||
//
|
||||
Transparent = 'cb-inherit',
|
||||
}
|
||||
|
||||
export enum XColorWithBrightness {
|
||||
//
|
||||
PrimaryTint = 'primary-tint',
|
||||
Primary = 'primary',
|
||||
PrimaryShade = 'primary-shade',
|
||||
//
|
||||
SecondaryTint = 'secondary-tint',
|
||||
Secondary = 'secondary',
|
||||
SecondaryShade = 'secondary-shade',
|
||||
//
|
||||
TertiaryTint = 'tertiary-tint',
|
||||
Tertiary = 'tertiary',
|
||||
TertiaryShade = 'tertiary-shade',
|
||||
//
|
||||
SuccessTint = 'success-tint',
|
||||
Success = 'success',
|
||||
SuccessShade = 'success-shade',
|
||||
//
|
||||
WarningTint = 'warning-tint',
|
||||
Warning = 'warning',
|
||||
WarningShade = 'warning-shade',
|
||||
//
|
||||
DangerTint = 'danger-tint',
|
||||
Danger = 'danger',
|
||||
DangerShade = 'danger-shade',
|
||||
//
|
||||
DarkTint = 'dark-tint',
|
||||
Dark = 'dark',
|
||||
DarkShade = 'dark-shade',
|
||||
//
|
||||
MediumTint = 'medium-tint',
|
||||
Medium = 'medium',
|
||||
MediumShade = 'medium-shade',
|
||||
//
|
||||
LightTint = 'light-tint',
|
||||
Light = 'light',
|
||||
LightShade = 'light-shade',
|
||||
//
|
||||
Transparent = 'cb-inherit',
|
||||
}
|
||||
|
||||
export type XColorIdentifier = XColor | XColorWithBrightness | string;
|
||||
|
||||
export enum XColorBrightnessLevel {
|
||||
Tint = 'tint',
|
||||
Regular = 'regular',
|
||||
Shade = 'shade',
|
||||
}
|
||||
|
||||
export interface XRGBAColor {
|
||||
r?: number;
|
||||
g?: number;
|
||||
b?: number;
|
||||
a?: number;
|
||||
}
|
||||
|
||||
export interface XHSVAColor {
|
||||
h?: number;
|
||||
s?: number;
|
||||
v?: number;
|
||||
a?: number;
|
||||
}
|
||||
|
||||
export interface XHSLAColor {
|
||||
h?: number;
|
||||
s?: number;
|
||||
l?: number;
|
||||
a?: number;
|
||||
}
|
||||
|
||||
export enum XColorFormat {
|
||||
XHEX = 'hex',
|
||||
XRGBA = 'rgba',
|
||||
XHSLA = 'hsla',
|
||||
XHSVA = 'hsva',
|
||||
}
|
||||
|
||||
export type XColorFormatIdentifier = XColorFormat | string;
|
||||
|
||||
export interface XColorKeyValue extends XBaseKeyValue<string> {}
|
||||
//#endregion
|
||||
@@ -0,0 +1,5 @@
|
||||
export enum XUnitOfTime {
|
||||
Year,
|
||||
Month,
|
||||
Day
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { XExceptionIDs, Exceptions } from '../constants/x-exception.resources';
|
||||
|
||||
export interface XException {
|
||||
id: number;
|
||||
message: string;
|
||||
payload?: any[];
|
||||
}
|
||||
|
||||
export type XExceptionIndex = {
|
||||
[key in keyof typeof XExceptionIDs]: XException;
|
||||
};
|
||||
|
||||
export type XExceptions = keyof typeof Exceptions;
|
||||
@@ -0,0 +1,20 @@
|
||||
export enum XUiEvent {
|
||||
//
|
||||
StartLoading,
|
||||
StopLoading,
|
||||
|
||||
//
|
||||
Disabled,
|
||||
Enabled,
|
||||
|
||||
//
|
||||
Locked,
|
||||
UnLocked,
|
||||
|
||||
//
|
||||
BackPrevented,
|
||||
BackReleased,
|
||||
|
||||
//
|
||||
Ready
|
||||
}
|
||||
@@ -0,0 +1,262 @@
|
||||
import {
|
||||
AlertInput,
|
||||
ToastOptions,
|
||||
ModalOptions,
|
||||
AlertOptions,
|
||||
ComponentRef,
|
||||
PickerOptions,
|
||||
PopoverOptions,
|
||||
LoadingOptions,
|
||||
ActionSheetOptions,
|
||||
} from '@ionic/core';
|
||||
import { XResourceIdentifier } from './x-translation.typings';
|
||||
import { XExceptions, XException } from './x-exception.typings';
|
||||
import { XSpinnerIdentifier, XOneOrManyType } from './x.typings';
|
||||
import { XExceptionIDs } from '../constants/x-exception.resources';
|
||||
import { XResourceIDs } from '../constants/x-translation.resources';
|
||||
|
||||
//
|
||||
//#region Typings for Dialogs and Notifications ...
|
||||
/**
|
||||
* Action Type for Notifications in Audio Service
|
||||
*/
|
||||
export enum XActionType {
|
||||
User,
|
||||
System,
|
||||
Capture,
|
||||
}
|
||||
|
||||
/**
|
||||
* represent a single notification sound for specific actions
|
||||
*/
|
||||
export interface XNotificationSound {
|
||||
type: XActionType;
|
||||
resourcePath: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* represent a group of notification sounds and coresponding actions
|
||||
*/
|
||||
export interface NotificationSoundIndex {
|
||||
[name: string]: XNotificationSound;
|
||||
}
|
||||
|
||||
export interface XNotificationParams {
|
||||
type?: XActionType;
|
||||
opt?: ToastOptions;
|
||||
playSound?: boolean;
|
||||
dissmissable: boolean;
|
||||
onDidDismiss?: () => void;
|
||||
onWillDismiss?: () => void;
|
||||
}
|
||||
|
||||
export interface XTypedNotificationParams extends XNotificationParams {
|
||||
message: string | XResourceIDs;
|
||||
}
|
||||
|
||||
export interface XErrorNotificationParams extends XNotificationParams {
|
||||
exception: XExceptionIDs | XExceptions | XException | any;
|
||||
}
|
||||
|
||||
type XXActionModalOptions = Pick<
|
||||
Partial<ActionSheetOptions>,
|
||||
| 'id'
|
||||
| 'animated'
|
||||
| 'backdropDismiss'
|
||||
| 'cssClass'
|
||||
| 'keyboardClose'
|
||||
| 'translucent'
|
||||
>;
|
||||
export interface XActionModalOptions extends XXActionModalOptions {
|
||||
//
|
||||
type?: XActionType;
|
||||
playSound?: boolean;
|
||||
header?: XResourceIdentifier;
|
||||
subHeader?: XResourceIdentifier;
|
||||
buttons?: XModalButton[];
|
||||
|
||||
//
|
||||
hasYes?: boolean;
|
||||
yesRole?: XModalButtonRoleIdentifier;
|
||||
yesHandler?: () => boolean | void | Promise<boolean>;
|
||||
|
||||
hasNo?: boolean;
|
||||
noRole?: XModalButtonRoleIdentifier;
|
||||
noHandler?: () => boolean | void | Promise<boolean>;
|
||||
|
||||
hasOk?: boolean;
|
||||
okRole?: XModalButtonRoleIdentifier;
|
||||
okHandler?: () => boolean | void | Promise<boolean>;
|
||||
|
||||
hasRetry?: boolean;
|
||||
retryRole?: XModalButtonRoleIdentifier;
|
||||
retryHandler?: () => boolean | void | Promise<boolean>;
|
||||
|
||||
hasAccept?: boolean;
|
||||
acceptRole?: XModalButtonRoleIdentifier;
|
||||
acceptHandler?: () => boolean | void | Promise<boolean>;
|
||||
|
||||
hasCancel?: boolean;
|
||||
cancelRole?: XModalButtonRoleIdentifier;
|
||||
cancelHandler?: () => boolean | void | Promise<boolean>;
|
||||
|
||||
hasDismiss?: boolean;
|
||||
dismissRole?: XModalButtonRoleIdentifier;
|
||||
dismissHandler?: () => boolean | void | Promise<boolean>;
|
||||
}
|
||||
|
||||
type XXModalOptions = Pick<
|
||||
Partial<ModalOptions>,
|
||||
| 'componentProps'
|
||||
| 'showBackdrop'
|
||||
| 'backdropDismiss'
|
||||
| 'cssClass'
|
||||
| 'animated'
|
||||
| 'component'
|
||||
| 'keyboardClose'
|
||||
| 'id'
|
||||
>;
|
||||
export interface XModalOptions extends XXModalOptions {
|
||||
component: ComponentRef;
|
||||
autoHeight?: boolean;
|
||||
fullScreen?: boolean;
|
||||
}
|
||||
|
||||
type XXPopOverOptions = Pick<
|
||||
Partial<PopoverOptions>,
|
||||
| 'animated'
|
||||
| 'backdropDismiss'
|
||||
| 'componentProps'
|
||||
| 'cssClass'
|
||||
| 'component'
|
||||
| 'id'
|
||||
| 'showBackdrop'
|
||||
| 'translucent'
|
||||
| 'keyboardClose'
|
||||
| 'event'
|
||||
>;
|
||||
export interface XPopoverOptions extends XXPopOverOptions {
|
||||
component: ComponentRef;
|
||||
}
|
||||
|
||||
type XXLoadingOptions = Pick<
|
||||
Partial<LoadingOptions>,
|
||||
| 'animated'
|
||||
| 'backdropDismiss'
|
||||
| 'cssClass'
|
||||
| 'duration'
|
||||
| 'id'
|
||||
| 'keyboardClose'
|
||||
| 'showBackdrop'
|
||||
| 'translucent'
|
||||
| 'message'
|
||||
>;
|
||||
|
||||
// tslint:disable-next-line:no-empty-interface
|
||||
export interface XLoadingOptions extends XXLoadingOptions {
|
||||
spinner?: XSpinnerIdentifier;
|
||||
}
|
||||
|
||||
type XXAlertOptions = Pick<
|
||||
Partial<AlertOptions>,
|
||||
| 'animated'
|
||||
| 'translucent'
|
||||
| 'backdropDismiss'
|
||||
| 'id'
|
||||
| 'keyboardClose'
|
||||
| 'cssClass'
|
||||
>;
|
||||
|
||||
export enum XModalButtonRole {
|
||||
Cancel = 'cancel',
|
||||
Selected = 'selected',
|
||||
Destructive = 'destructive',
|
||||
}
|
||||
|
||||
export type XModalButtonRoleIdentifier = XModalButtonRole | string;
|
||||
|
||||
export interface XModalButton {
|
||||
text: XResourceIdentifier;
|
||||
role?: XModalButtonRoleIdentifier;
|
||||
cssClass?: XOneOrManyType<string>;
|
||||
handler?: (
|
||||
value?: any
|
||||
) =>
|
||||
| boolean
|
||||
| void
|
||||
| {
|
||||
[key: string]: any;
|
||||
}
|
||||
| any;
|
||||
}
|
||||
|
||||
export type XAlertInputType =
|
||||
| 'date'
|
||||
| 'email'
|
||||
| 'number'
|
||||
| 'password'
|
||||
| 'search'
|
||||
| 'tel'
|
||||
| 'text'
|
||||
| 'url'
|
||||
| 'time'
|
||||
| 'checkbox'
|
||||
| 'radio';
|
||||
|
||||
export interface XModalInput {
|
||||
id?: string;
|
||||
value?: any;
|
||||
name?: string;
|
||||
checked?: boolean;
|
||||
disabled?: boolean;
|
||||
min?: string | number;
|
||||
max?: string | number;
|
||||
type?: XAlertInputType;
|
||||
label?: XResourceIdentifier;
|
||||
placeholder?: XResourceIdentifier;
|
||||
handler?: (input: AlertInput) => void;
|
||||
}
|
||||
|
||||
export interface XAlertOptions extends XXAlertOptions {
|
||||
header?: XResourceIdentifier;
|
||||
subHeader?: XResourceIdentifier;
|
||||
message: XResourceIdentifier;
|
||||
inputs?: XModalInput[];
|
||||
buttons?: XModalButton[];
|
||||
}
|
||||
|
||||
type XXPickerOptions = Pick<
|
||||
Partial<PickerOptions>,
|
||||
'animated' | 'backdropDismiss' | 'id' | 'cssClass' | 'keyboardClose'
|
||||
>;
|
||||
|
||||
export interface XPickerColumn {
|
||||
name: string;
|
||||
align?: string;
|
||||
selectedIndex?: number;
|
||||
prevSelected?: number;
|
||||
prefix?: string;
|
||||
suffix?: string;
|
||||
options: XPickerColumnOption[];
|
||||
cssClass?: string | string[];
|
||||
columnWidth?: string;
|
||||
prefixWidth?: string;
|
||||
suffixWidth?: string;
|
||||
optionsWidth?: string;
|
||||
refresh?: () => void;
|
||||
}
|
||||
|
||||
export interface XPickerColumnOption {
|
||||
text?: XResourceIdentifier;
|
||||
value: any;
|
||||
disabled?: boolean;
|
||||
duration?: number;
|
||||
transform?: string;
|
||||
selected?: boolean;
|
||||
}
|
||||
|
||||
export interface XPickerOptions extends XXPickerOptions {
|
||||
buttons?: XModalButton[];
|
||||
columns: XPickerColumn[];
|
||||
}
|
||||
//#endregion
|
||||
@@ -0,0 +1,13 @@
|
||||
import { XOneOrManyType } from './x.typings';
|
||||
import { XResourceIdentifier } from './x-translation.typings';
|
||||
|
||||
export interface XPage {
|
||||
id: string;
|
||||
name: string;
|
||||
icon?: string;
|
||||
baseRoute: string;
|
||||
title: XResourceIdentifier;
|
||||
route: XOneOrManyType<string>;
|
||||
childs?: XOneOrManyType<XPage>;
|
||||
description?: XResourceIdentifier;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
export interface XBaseDataPagerQuery {
|
||||
filter?: string;
|
||||
pageNumber: number;
|
||||
rowsInPage: number;
|
||||
}
|
||||
|
||||
export interface XBaseDataPagerQueryResult<T = any> {
|
||||
count: number;
|
||||
items: T[];
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
export type XOrientation = 'landscape' | 'portrait';
|
||||
|
||||
export enum XDeviceTypes {
|
||||
Unknown,
|
||||
Mobile,
|
||||
Tablet,
|
||||
Desktop
|
||||
}
|
||||
|
||||
export interface XDeviceInfo {
|
||||
os: string;
|
||||
osVersion: string;
|
||||
browser: string;
|
||||
userAgent: string;
|
||||
deviceType: XDeviceTypes;
|
||||
userId?: number;
|
||||
|
||||
identifier?: string;
|
||||
token?: string;
|
||||
}
|
||||
|
||||
export type XCssProperties =
|
||||
| 'x-app-bar-color'
|
||||
| 'ui-direction'
|
||||
| 'toolbar-height'
|
||||
| string;
|
||||
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* represent a single item which can be stored ...
|
||||
*/
|
||||
export interface XStorageItem {
|
||||
key: string;
|
||||
value: string;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Observable } from 'rxjs';
|
||||
import { XException } from './x-exception.typings';
|
||||
|
||||
export enum XTaskPriority {
|
||||
High,
|
||||
Medium,
|
||||
Regular,
|
||||
Weak
|
||||
}
|
||||
|
||||
export interface XTask<T> {
|
||||
affectLoading?: boolean;
|
||||
name: string;
|
||||
priority: XTaskPriority;
|
||||
task: Observable<T>;
|
||||
result?: T;
|
||||
error?: XException;
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
export enum XThemeType {
|
||||
Light = 'light',
|
||||
Dark = 'dark',
|
||||
}
|
||||
|
||||
export type XThemeTypeIdentifier = XThemeType | string;
|
||||
|
||||
export enum XThemeCssVars {
|
||||
//
|
||||
//#region Primary ...
|
||||
XColorPrimary = 'x-color-primary',
|
||||
XColorPrimaryContrast = 'x-color-primary-contrast',
|
||||
|
||||
XColorPrimaryShade = 'x-color-primary-shade',
|
||||
XColorPrimaryShadeContrast = 'x-color-primary-shade-contrast',
|
||||
|
||||
XColorPrimaryTint = 'x-color-primary-tint',
|
||||
XColorPrimaryTintContrast = 'x-color-primary-tint-contrast',
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Secondary ...
|
||||
XColorSecondary = 'x-color-secondary',
|
||||
XColorSecondaryContrast = 'x-color-secondary-contrast',
|
||||
|
||||
XColorSecondaryShade = 'x-color-secondary-shade',
|
||||
XColorSecondaryShadeContrast = 'x-color-secondary-shade-contrast',
|
||||
|
||||
XColorSecondaryTint = 'x-color-secondary-tint',
|
||||
XColorSecondaryTintContrast = 'x-color-secondary-tint-contrast',
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Tertiary ...
|
||||
XColorTertiary = 'x-color-tertiary',
|
||||
XColorTertiaryContrast = 'x-color-tertiary-contrast',
|
||||
|
||||
XColorTertiaryShade = 'x-color-tertiary-shade',
|
||||
XColorTertiaryShadeContrast = 'x-color-tertiary-shade-contrast',
|
||||
|
||||
XColorTertiaryTint = 'x-color-tertiary-tint',
|
||||
XColorTertiaryTintContrast = 'x-color-tertiary-tint-contrast',
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Success ...
|
||||
XColorSuccess = 'x-color-success',
|
||||
XColorSuccessContrast = 'x-color-success-contrast',
|
||||
|
||||
XColorSuccessShade = 'x-color-success-shade',
|
||||
XColorSuccessShadeContrast = 'x-color-success-shade-contrast',
|
||||
|
||||
XColorSuccessTint = 'x-color-success-tint',
|
||||
XColorSuccessTintContrast = 'x-color-success-tint-contrast',
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Warning ...
|
||||
XColorWarning = 'x-color-warning',
|
||||
XColorWarningContrast = 'x-color-warning-contrast',
|
||||
|
||||
XColorWarningShade = 'x-color-warning-shade',
|
||||
XColorWarningShadeContrast = 'x-color-warning-shade-contrast',
|
||||
|
||||
XColorWarningTint = 'x-color-warning-tint',
|
||||
XColorWarningTintContrast = 'x-color-warning-tint-contrast',
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Danger ...
|
||||
XColorDanger = 'x-color-danger',
|
||||
XColorDangerContrast = 'x-color-danger-contrast',
|
||||
|
||||
XColorDangerShade = 'x-color-danger-shade',
|
||||
XColorDangerShadeContrast = 'x-color-danger-shade-contrast',
|
||||
|
||||
XColorDangerTint = 'x-color-danger-tint',
|
||||
XColorDangerTintContrast = 'x-color-danger-tint-contrast',
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Dark ...
|
||||
XColorDark = 'x-color-dark',
|
||||
XColorDarkContrast = 'x-color-dark-contrast',
|
||||
|
||||
XColorDarkShade = 'x-color-dark-shade',
|
||||
XColorDarkShadeContrast = 'x-color-dark-shade-contrast',
|
||||
|
||||
XColorDarkTint = 'x-color-dark-tint',
|
||||
XColorDarkTintContrast = 'x-color-dark-tint-contrast',
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Medium ...
|
||||
XColorMedium = 'x-color-medium',
|
||||
XColorMediumContrast = 'x-color-medium-contrast',
|
||||
|
||||
XColorMediumShade = 'x-color-medium-shade',
|
||||
XColorMediumShadeContrast = 'x-color-medium-shade-contrast',
|
||||
|
||||
XColorMediumTint = 'x-color-medium-tint',
|
||||
XColorMediumTintContrast = 'x-color-medium-tint-contrast',
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Light ...
|
||||
XColorLight = 'x-color-light',
|
||||
XColorLightContrast = 'x-color-light-contrast',
|
||||
|
||||
XColorLightShade = 'x-color-light-shade',
|
||||
XColorLightShadeContrast = 'x-color-light-shade-contrast',
|
||||
|
||||
XColorLightTint = 'x-color-light-tint',
|
||||
XColorLightTintContrast = 'x-color-light-tint-contrast',
|
||||
//#endregion
|
||||
}
|
||||
|
||||
export type XThemeCssVarsIdentifier = XThemeCssVars | string;
|
||||
|
||||
export type XThemeDescriptorColors = keyof typeof XThemeCssVars;
|
||||
|
||||
export type XThemeColors = {
|
||||
[key in XThemeDescriptorColors]: string;
|
||||
};
|
||||
|
||||
export interface XThemeDescriptor {
|
||||
type: XThemeTypeIdentifier;
|
||||
colors: XThemeColors;
|
||||
}
|
||||
|
||||
export interface XThemePack {
|
||||
name: string;
|
||||
light: XThemeDescriptor;
|
||||
dark: XThemeDescriptor;
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
import { XResourceIDs } from '../constants/x-translation.resources';
|
||||
import { toEnNumbers, toPersianNumbers } from '../tools/x-string.tools';
|
||||
|
||||
export declare type XLanguageDirection = 'ltr' | 'rtl';
|
||||
export declare type XLocale = 'en-US' | 'fa-IR';
|
||||
|
||||
export interface XLanguageDescriptor {
|
||||
name: string;
|
||||
locale: XLocale;
|
||||
language: string;
|
||||
direction: XLanguageDirection;
|
||||
resources?: XTranslationItem[];
|
||||
}
|
||||
|
||||
export interface XLanguageDescriptorIndex {
|
||||
[name: string]: XLanguageDescriptor;
|
||||
}
|
||||
|
||||
export type XTranslationId = keyof typeof XResourceIDs;
|
||||
|
||||
export interface XTranslationItem {
|
||||
id: XTranslationId | string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface XTranslationIndex {
|
||||
[name: string]: XTranslationItem;
|
||||
}
|
||||
|
||||
export interface XLocalesIndex {
|
||||
[key: string]: XTranslationIndex;
|
||||
}
|
||||
|
||||
export interface GetDateProps {
|
||||
date?: Date;
|
||||
locale?: XLocale;
|
||||
dateFormat?: string;
|
||||
toUtc?: boolean;
|
||||
}
|
||||
|
||||
export function applyLocale(content: string, locale: XLocale = 'en-US') {
|
||||
switch (locale) {
|
||||
case 'en-US':
|
||||
return toEnNumbers(content);
|
||||
|
||||
case 'fa-IR':
|
||||
return toPersianNumbers(content);
|
||||
}
|
||||
}
|
||||
|
||||
export type XResourceIdentifier = XResourceIDs | XTranslationId | string;
|
||||
@@ -0,0 +1,229 @@
|
||||
import { Observable } from 'rxjs';
|
||||
import { XFileBlob } from '../tools/x-file.tools';
|
||||
import { XLocale } from './x-translation.typings';
|
||||
import { CountryCode, PhoneNumber } from 'libphonenumber-js';
|
||||
|
||||
//
|
||||
//#region General ...
|
||||
export type XStandardType<T> = Observable<T> | Promise<T> | T;
|
||||
|
||||
export type XOneOrManyType<T> = T | T[];
|
||||
|
||||
export type XFormControlState = 'VALID' | 'INVALID' | 'PENDING' | 'DISABLED';
|
||||
|
||||
export type XRouterDirection = 'root' | 'forward' | 'back';
|
||||
|
||||
export type XFileReaderInputType = File | Blob | XFileBlob | string;
|
||||
|
||||
export enum XRouterTarget {
|
||||
TOP = '_top',
|
||||
SELF = '_self',
|
||||
BLANK = '_blank',
|
||||
PARENT = '_parent',
|
||||
}
|
||||
|
||||
export type XRouterTargetIdentifier = XRouterTarget | string;
|
||||
|
||||
export enum XMimeType {
|
||||
//
|
||||
//#region Applications ...
|
||||
ApplicationOctetStream = 'application/octet-stream',
|
||||
ApplicationPDF = 'application/pdf',
|
||||
ApplicationZIP = 'application/zip',
|
||||
ApplicationAtomXML = 'application/atom+xml',
|
||||
ApplicationGZIP = 'application/gzip',
|
||||
ApplicationJSON = 'application/json',
|
||||
ApplicationJWT = 'application/jwt',
|
||||
ApplicationMP4 = 'application/mp4',
|
||||
ApplicationRTF = 'application/rtf',
|
||||
ApplicationSQL = 'application/sql',
|
||||
ApplicationWSDLXML = 'application/wsdl+xml',
|
||||
ApplicationXWWWFormURLEncoded = 'application/x-www-form-urlencoded',
|
||||
ApplicationXX509CaCert = 'application/x-x509-ca-cert',
|
||||
ApplicationXML = 'application/xml',
|
||||
ApplicationJavascript = 'application/javascript',
|
||||
ApplicationECMAScript = 'application/ecmascript',
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Audios ...
|
||||
Audio3GPP = 'audio/3gpp',
|
||||
AudioAAC = 'audio/aac',
|
||||
AudioAMR = 'audio/AMR',
|
||||
AudioMPA = 'audio/MPA',
|
||||
AudioMP4 = 'audio/mp4',
|
||||
AudioMPEG = 'audio/mpeg',
|
||||
AudioOGG = 'audio/ogg',
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Fonts ...
|
||||
FontCollection = 'font/collection',
|
||||
FontOTF = 'font/otf',
|
||||
FontSFNT = 'font/sfnt',
|
||||
FontTTF = 'font/ttf',
|
||||
FontWOFF = 'font/woff',
|
||||
FontWOFF2 = 'font/woff2',
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Image ...
|
||||
ImageBMP = 'image/bmp',
|
||||
ImageGIF = 'image/gif',
|
||||
ImageJPEG = 'image/jpg',
|
||||
ImagePNG = 'image/png',
|
||||
ImageSVG = 'image/svg+xml',
|
||||
ImageTIFF = 'image/tiff',
|
||||
ImageWMF = 'image/wmf',
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Messages ...
|
||||
MessageSIP = 'message/sip',
|
||||
MessageSIPFrag = 'message/sipfrag',
|
||||
Message = 'message/',
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Multipart ...
|
||||
MultipartEncrypted = 'multipart/encrypted',
|
||||
MultipartFormData = 'multipart/form-data',
|
||||
MultipartHeaderSET = 'multipart/header-set',
|
||||
MultipartRelated = 'multipart/related',
|
||||
MultipartReport = 'multipart/report',
|
||||
MultipartSigned = 'multipart/signed',
|
||||
MultipartVoiceMessage = 'multipart/voice-message',
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Text ...
|
||||
TextCalendar = 'text/calendar',
|
||||
TextCSS = 'text/css',
|
||||
TextCSV = 'text/csv',
|
||||
TextCSVSchema = 'text/csv-schema',
|
||||
TextDirectory = 'text/directory',
|
||||
TextDNS = 'text/dns',
|
||||
TextHTML = 'text/html',
|
||||
TextECMAScript = 'text/ecmascript',
|
||||
TextJavascript = 'text/javascript',
|
||||
TextMarkdown = 'text/markdown',
|
||||
TextPlain = 'text/plain',
|
||||
TextRTF = 'text/rtf',
|
||||
TextStrings = 'text/strings',
|
||||
TextVCard = 'text/vcard',
|
||||
TextXML = 'text/xml',
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Video ...
|
||||
Video3GPP = 'video/3gpp',
|
||||
Video3GPP2 = 'video/3gpp2',
|
||||
VideoH265 = 'video/H265',
|
||||
VideoJPEG = 'video/JPEG',
|
||||
VideoMP4 = 'video/mp4',
|
||||
VideoMPV = 'video/MPV',
|
||||
VideoMPEG = 'video/mpeg',
|
||||
VideoOGG = 'video/ogg',
|
||||
VideoQuicktime = 'video/quicktime',
|
||||
//#endregion
|
||||
}
|
||||
|
||||
export type XMimeTypeIdentifier = XMimeType | string;
|
||||
|
||||
export enum XSpinner {
|
||||
Lines = 'lines',
|
||||
LinesSmall = 'lines-small',
|
||||
Dots = 'dots',
|
||||
Bubbles = 'bubbles',
|
||||
Circles = 'circles',
|
||||
Circular = 'circular',
|
||||
Crescent = 'crescent',
|
||||
}
|
||||
|
||||
export type XSpinnerIdentifier = XSpinner | string | any;
|
||||
|
||||
export type XCountryCode = CountryCode;
|
||||
|
||||
export type XPhoneNumber = PhoneNumber;
|
||||
|
||||
export enum XFormatterType {
|
||||
ApplyLocale = 'apply_locale',
|
||||
FormatCurrency = 'format_currency',
|
||||
StringFormatter = 'string_formatter',
|
||||
FormatCurrencyAndApplyLocale = 'format_currency_apply_locale',
|
||||
StringFormatterAndApplyLocale = 'string_formatter_apply_locale',
|
||||
}
|
||||
|
||||
export interface XFormatterOption {
|
||||
type: XFormatterType;
|
||||
locale?: XLocale;
|
||||
seperator?: string;
|
||||
currencyLable?: string;
|
||||
pattern?: number[];
|
||||
}
|
||||
|
||||
export enum XDialogResult {
|
||||
Cancel,
|
||||
Ok,
|
||||
Retry,
|
||||
Opened,
|
||||
Restart,
|
||||
}
|
||||
|
||||
export interface XBaseKeyValue<T> {
|
||||
key: string;
|
||||
value: T;
|
||||
}
|
||||
|
||||
export interface XKeyValue<TKey, TValue> {
|
||||
key: TKey;
|
||||
value: TValue;
|
||||
}
|
||||
|
||||
export interface XHasAction<T = any> {
|
||||
action: T;
|
||||
payload?: any
|
||||
}
|
||||
|
||||
export type XKey<T> = keyof T;
|
||||
export type XKeysOfXType<T, U> = { [K in keyof T]: T[K] extends U ? K : never }[keyof T];
|
||||
export type XStringKeys<T> = Extract<XKey<T>, string>;
|
||||
export type XValueOf<T> = T[XKey<T>];
|
||||
export type XRef<T = any> = { value: T };
|
||||
export type XPropertyType<T, K extends keyof T> = T[K];
|
||||
export type XModelFieldTypeIndex<T> = {
|
||||
[key in XKey<T>]: string;
|
||||
};
|
||||
export type XPartialModelFieldNames<T> = XOneOrManyType<
|
||||
Partial<XKey<XModelFieldTypeIndex<T>>>
|
||||
>;
|
||||
export type XDeep<T> = keyof T & T extends object
|
||||
? { [P in keyof T]: XDeep<T[P]> }
|
||||
: T;
|
||||
export type XDeepPartial<T> = T extends Function
|
||||
? T
|
||||
: T extends object
|
||||
? { [P in keyof T]?: XDeepPartial<T[P]> }
|
||||
: T;
|
||||
|
||||
export type XModelKeyType<T = any> = keyof Partial<T> | string;
|
||||
|
||||
export type XModelFieldsType<T = any> = XOneOrManyType<XModelKeyType<T>>;
|
||||
|
||||
export type XModelKeyProvider<T = any> = (
|
||||
key: XModelKeyType<T>
|
||||
) => XStandardType<string>;
|
||||
|
||||
export type XModelValueProvider<T> = (
|
||||
key: XModelKeyType<T>,
|
||||
value: any
|
||||
) => XStandardType<any>;
|
||||
|
||||
export interface XModelProperty<T = any>
|
||||
extends XKeyValue<XModelKeyType<T>, any> {
|
||||
prefix?: string;
|
||||
}
|
||||
|
||||
export type XGConstructor<T = {}> = new (...args: any[]) => T;
|
||||
export type XConstructor = new (...args: any[]) => {};
|
||||
//#endregion
|
||||
@@ -0,0 +1,316 @@
|
||||
import {
|
||||
XPhoneNumber,
|
||||
XCountryCode,
|
||||
XOneOrManyType
|
||||
} from '../typings/x.typings';
|
||||
import {
|
||||
isNullOrUndefined,
|
||||
isNullOrEmptyString
|
||||
} from '../tools/x-type-detect.tools';
|
||||
import { hasChild, toArray } from '../tools/x-array.tools';
|
||||
import { throwException } from '../tools/x-exception.tools';
|
||||
import { parsePhoneNumberFromString } from 'libphonenumber-js';
|
||||
import { XExceptionIDs } from '../constants/x-exception.resources';
|
||||
|
||||
//
|
||||
//#region Custom Type Checker and Converters ...
|
||||
/**
|
||||
* check specified value is Valid URL Address or not ...
|
||||
*
|
||||
* @param value specified string which required to check
|
||||
*/
|
||||
export function isValidURL(value: string) {
|
||||
//
|
||||
const pattern = new RegExp(
|
||||
'^(https?:\\/\\/)?' + // protocol
|
||||
'((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.?)+[a-z]{2,}|' + // domain name
|
||||
'((\\d{1,3}\\.){3}\\d{1,3}))' + // ip (v4) address
|
||||
'(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // port
|
||||
'(\\?[;&a-z\\d%_.~+=-]*)?' + // query string
|
||||
'(\\#[-a-z\\d_]*)?$',
|
||||
'i'
|
||||
);
|
||||
|
||||
//
|
||||
return pattern.test(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* check specified value is Valid URL Address or not ...
|
||||
*
|
||||
* @param value specified string which required to check
|
||||
*/
|
||||
export function isValidEmail(value: string) {
|
||||
//
|
||||
const pattern = /[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}/gim;
|
||||
|
||||
//
|
||||
return pattern.test(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* check specified value is Valid Phone Number or not ...
|
||||
*
|
||||
* @param value specified string which required to check
|
||||
* @param defaultCountryCode an optional value which used for country code if not exists in value
|
||||
*/
|
||||
export function isValidPhoneNumber(
|
||||
value: string,
|
||||
defaultCountryCode?: XCountryCode
|
||||
) {
|
||||
//
|
||||
const mParsedPhoneNumber = parsePhoneNumber(value, defaultCountryCode);
|
||||
if (!mParsedPhoneNumber) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
return mParsedPhoneNumber.isValid();
|
||||
}
|
||||
|
||||
/**
|
||||
* parse an string as phone number and extract several information of it ...
|
||||
*
|
||||
* @param value specified string is represent phone number ...
|
||||
* @param defaultCountryCode an optional value which used for country code if not exists in value
|
||||
*/
|
||||
export function parsePhoneNumber(
|
||||
value: string,
|
||||
defaultCountryCode?: XCountryCode
|
||||
): XPhoneNumber {
|
||||
//
|
||||
try {
|
||||
return parsePhoneNumberFromString(value, defaultCountryCode);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* normalize specified phone number and format it ...
|
||||
*
|
||||
* @param value specified string which required to normalized ...
|
||||
* @param defaultCountryCode an optional value which used for country code if not exists in value
|
||||
*/
|
||||
export function normalizePhoneNumber(
|
||||
value: string,
|
||||
defaultCountryCode?: XCountryCode
|
||||
) {
|
||||
//
|
||||
try {
|
||||
//
|
||||
const parsedNumber = parsePhoneNumber(value, defaultCountryCode);
|
||||
if (!parsedNumber) {
|
||||
throw new Error('can not Parse Phone Number ...');
|
||||
}
|
||||
|
||||
//
|
||||
return parsedNumber.number.toString();
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Data Validators from Several Types ...
|
||||
export class XValidators {
|
||||
//
|
||||
private static throwInvalidArgsException() {
|
||||
throwException(XExceptionIDs.InvalidArgs);
|
||||
}
|
||||
|
||||
/**
|
||||
* check args not Null or Undefined ...
|
||||
*
|
||||
* @param args any args which required to check
|
||||
*/
|
||||
static validateNotNull(...args: any[]) {
|
||||
//
|
||||
const isValid = args.every(arg => !isNullOrUndefined(arg));
|
||||
if (!isValid) {
|
||||
XValidators.throwInvalidArgsException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check args not empty string or null or undefined ...
|
||||
*
|
||||
* @param args any args which required to check
|
||||
*/
|
||||
static validateNotEmpty(...args: string[]) {
|
||||
//
|
||||
const isValid = args.every(arg => !isNullOrEmptyString(arg));
|
||||
if (!isValid) {
|
||||
XValidators.throwInvalidArgsException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check args must have childs ...
|
||||
*
|
||||
* @param args any args which required to check
|
||||
*/
|
||||
static validateHasChilds(...args: any[][]) {
|
||||
//
|
||||
const isValid = args.every(arg => hasChild(arg));
|
||||
if (!isValid) {
|
||||
XValidators.throwInvalidArgsException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check all args not equal to specified values ...
|
||||
*
|
||||
* @param values a single or collection value which going to compare
|
||||
* @param args any args which required to check
|
||||
*/
|
||||
static validateNotEquals<T>(values: XOneOrManyType<T>, ...args: T[]) {
|
||||
//
|
||||
const mValues = toArray(values);
|
||||
|
||||
//
|
||||
const isValid = args.every(arg => !mValues.includes(arg));
|
||||
if (!isValid) {
|
||||
XValidators.throwInvalidArgsException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check all args equal to specified values ...
|
||||
*
|
||||
* @param values a single or collection value which going to compare
|
||||
* @param args any args which required to check
|
||||
*/
|
||||
static validateEquals<T>(values: XOneOrManyType<T>, ...args: T[]) {
|
||||
//
|
||||
const mValues = toArray(values);
|
||||
|
||||
//
|
||||
const isValid = args.every(arg => mValues.includes(arg));
|
||||
if (!isValid) {
|
||||
XValidators.throwInvalidArgsException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check all args bigger than specified values ...
|
||||
*
|
||||
* @param values a single or collection value which going to compare
|
||||
* @param args any args which required to check
|
||||
*/
|
||||
static validateBiggerThan(values: number | number[], ...args: number[]) {
|
||||
//
|
||||
const mValues = toArray(values);
|
||||
|
||||
//
|
||||
const isValid = args.every(arg => mValues.every(n => arg > n));
|
||||
if (!isValid) {
|
||||
XValidators.throwInvalidArgsException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check all args less than specified values ...
|
||||
*
|
||||
* @param values a single or collection value which going to compare
|
||||
* @param args any args which required to check
|
||||
*/
|
||||
static validateLessThan(values: number | number[], ...args: number[]) {
|
||||
//
|
||||
const mValues = toArray(values);
|
||||
|
||||
//
|
||||
const isValid = args.every(arg => mValues.every(n => arg < n));
|
||||
if (!isValid) {
|
||||
XValidators.throwInvalidArgsException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check all args bigger than or equals to specified values ...
|
||||
*
|
||||
* @param values a single or collection value which going to compare
|
||||
* @param args any args which required to check
|
||||
*/
|
||||
static validateBiggerThanOrEquals(
|
||||
values: number | number[],
|
||||
...args: number[]
|
||||
) {
|
||||
//
|
||||
const mValues = toArray(values);
|
||||
|
||||
//
|
||||
const isValid = args.every(arg => mValues.every(n => arg >= n));
|
||||
if (!isValid) {
|
||||
XValidators.throwInvalidArgsException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check all args less than or equals to specified values ...
|
||||
*
|
||||
* @param values a single or collection value which going to compare
|
||||
* @param args any args which required to check
|
||||
*/
|
||||
static validateLessThanOrEquals(
|
||||
values: number | number[],
|
||||
...args: number[]
|
||||
) {
|
||||
//
|
||||
const mValues = toArray(values);
|
||||
|
||||
//
|
||||
const isValid = args.every(arg => mValues.every(n => arg <= n));
|
||||
if (!isValid) {
|
||||
XValidators.throwInvalidArgsException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check specified value is Valid URL Address or not ...
|
||||
*
|
||||
* @param value specified string which required to check
|
||||
*/
|
||||
static validateURL(value: string) {
|
||||
//
|
||||
XValidators.validateNotEmpty(value);
|
||||
|
||||
//
|
||||
if (!isValidURL(value)) {
|
||||
throwException(XExceptionIDs.InvalidEmailAddress);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check specified value is Valid Email Address or not ...
|
||||
*
|
||||
* @param value specified string which required to check
|
||||
*/
|
||||
static validateEmailAddress(value: string) {
|
||||
//
|
||||
XValidators.validateNotEmpty(value);
|
||||
|
||||
//
|
||||
if (!isValidEmail(value)) {
|
||||
throwException(XExceptionIDs.InvalidEmailAddress);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check specified value is Valid Phone Number or not ...
|
||||
*
|
||||
* @param value specified string which required to check
|
||||
* @param defaultCountryCode an optional value which used for country code if not exists in value
|
||||
*/
|
||||
static validatePhoneNumber(value: string, defaultCountryCode?: XCountryCode) {
|
||||
//
|
||||
XValidators.validateNotEmpty(value);
|
||||
|
||||
//
|
||||
if (!isValidPhoneNumber(value, defaultCountryCode)) {
|
||||
throwException(XExceptionIDs.InvalidMobileNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
//#endregion
|
||||
@@ -0,0 +1,29 @@
|
||||
import { Directive } from '@angular/core';
|
||||
import { isValidEmail } from './x-general-validators';
|
||||
import { Validator, AbstractControl, ValidationErrors } from '@angular/forms';
|
||||
|
||||
@Directive({
|
||||
// tslint:disable-next-line:directive-selector
|
||||
selector: '[xValidEmail]'
|
||||
})
|
||||
export class XValidEmailDirective implements Validator {
|
||||
//
|
||||
private errorObject = {
|
||||
xValidEmail: true
|
||||
};
|
||||
|
||||
validate(control: AbstractControl): ValidationErrors {
|
||||
//
|
||||
const sourceValue =
|
||||
control && control.value ? (control.value as string) : null;
|
||||
|
||||
//
|
||||
let isValid = false;
|
||||
try {
|
||||
isValid = isValidEmail(sourceValue);
|
||||
} catch {}
|
||||
|
||||
//
|
||||
return !isValid ? this.errorObject : null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import { XCountryCode } from '../typings/x.typings';
|
||||
import { Directive, Input, Inject } from '@angular/core';
|
||||
import { isValidPhoneNumber } from './x-general-validators';
|
||||
import { X_FRAMEWORK_CORE_CONFIG } from '../tokens/x-injectable-tokens';
|
||||
import { XFrameworkCoreConfig } from '../config/x-framework-core.config';
|
||||
import { Validator, AbstractControl, ValidationErrors } from '@angular/forms';
|
||||
|
||||
@Directive({
|
||||
// tslint:disable-next-line:directive-selector
|
||||
selector: '[xValidPhoneNumber]'
|
||||
})
|
||||
export class XValidPhoneNumberDirective implements Validator {
|
||||
//
|
||||
private errorObject = {
|
||||
xValidMobile: true
|
||||
};
|
||||
|
||||
//
|
||||
@Input()
|
||||
defaultCountryCode: XCountryCode = this.config.defaultCountryCode;
|
||||
|
||||
constructor(
|
||||
@Inject(X_FRAMEWORK_CORE_CONFIG) private config: XFrameworkCoreConfig
|
||||
) {}
|
||||
|
||||
validate(control: AbstractControl): ValidationErrors {
|
||||
//
|
||||
const value = control && control.value ? (control.value as string) : null;
|
||||
|
||||
//
|
||||
const isValid = isValidPhoneNumber(value, this.defaultCountryCode);
|
||||
|
||||
//
|
||||
return !isValid ? this.errorObject : null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import { Directive, Input } from '@angular/core';
|
||||
import { isValidURL } from './x-general-validators';
|
||||
import { Validator, AbstractControl, ValidationErrors } from '@angular/forms';
|
||||
|
||||
@Directive({
|
||||
// tslint:disable-next-line:directive-selector
|
||||
selector: '[xValidUrl]'
|
||||
})
|
||||
export class XValidUrlDirective implements Validator {
|
||||
//
|
||||
private errorObject = {
|
||||
xValidUrl: true
|
||||
};
|
||||
|
||||
@Input()
|
||||
isOptional: boolean;
|
||||
|
||||
constructor() {}
|
||||
|
||||
validate(control: AbstractControl): ValidationErrors {
|
||||
//
|
||||
const sourceValue =
|
||||
control && control.value ? (control.value as string) : null;
|
||||
|
||||
//
|
||||
let isValid = false;
|
||||
if (!sourceValue && this.isOptional) {
|
||||
isValid = true;
|
||||
} else {
|
||||
isValid = sourceValue && isValidURL(sourceValue);
|
||||
}
|
||||
|
||||
//
|
||||
return !isValid ? this.errorObject : null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
import {
|
||||
NgModel,
|
||||
Validator,
|
||||
AbstractControl,
|
||||
ValidationErrors
|
||||
} from '@angular/forms';
|
||||
import { Directive, Input } from '@angular/core';
|
||||
import { isNullOrEmptyString } from '../tools/x-type-detect.tools';
|
||||
|
||||
@Directive({
|
||||
// tslint:disable-next-line:directive-selector
|
||||
selector: '[xValueMatch]'
|
||||
})
|
||||
export class XValueMatchDirective implements Validator {
|
||||
private errorObject = {
|
||||
xValueMatch: true
|
||||
};
|
||||
|
||||
//
|
||||
@Input('xValueMatch')
|
||||
matchTo: NgModel;
|
||||
|
||||
//
|
||||
validate(control: AbstractControl): ValidationErrors {
|
||||
//
|
||||
if (!control) {
|
||||
return this.errorObject;
|
||||
}
|
||||
const value = control.value as string;
|
||||
|
||||
//
|
||||
if (!this.matchTo) {
|
||||
return this.errorObject;
|
||||
}
|
||||
const destControl = this.matchTo.control;
|
||||
if (!destControl) {
|
||||
return this.errorObject;
|
||||
}
|
||||
|
||||
//
|
||||
const destValue = destControl.value;
|
||||
|
||||
//
|
||||
const isValid =
|
||||
!isNullOrEmptyString(destValue) &&
|
||||
!isNullOrEmptyString(value) &&
|
||||
value === destValue;
|
||||
|
||||
//
|
||||
if (isValid && destControl.invalid) {
|
||||
destControl.updateValueAndValidity();
|
||||
}
|
||||
|
||||
//
|
||||
return !isValid ? this.errorObject : null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { IonicModule } from '@ionic/angular'
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { XDirectivesModule } from './modules/x-directives.module';
|
||||
import { HAMMER_GESTURE_CONFIG } from '@angular/platform-browser';
|
||||
import { XHammerGestureConfig } from './classes/x-hammer-gesture-config';
|
||||
|
||||
@NgModule({
|
||||
declarations: [],
|
||||
providers: [
|
||||
//
|
||||
// Gesture Config ...
|
||||
{
|
||||
provide: HAMMER_GESTURE_CONFIG,
|
||||
useClass: XHammerGestureConfig,
|
||||
},
|
||||
],
|
||||
imports: [CommonModule, IonicModule, XDirectivesModule],
|
||||
exports: [CommonModule, IonicModule, XDirectivesModule],
|
||||
})
|
||||
export class XFrameworkCoreModule {}
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Public API Surface of x-framework-core
|
||||
*/
|
||||
|
||||
//#region Classes ...
|
||||
export * from './lib/classes/x-loggable';
|
||||
export * from './lib/classes/x-base.service';
|
||||
export * from './lib/classes/x-renderer.class';
|
||||
export * from './lib/classes/x-persian-date-adapter';
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Constants ...
|
||||
export * from './lib/constants/x-file.enum';
|
||||
export * from './lib/constants/x.constants';
|
||||
export * from './lib/constants/x-crud.enum';
|
||||
export * from './lib/constants/x-param.enum';
|
||||
export * from './lib/constants/x-header.enum';
|
||||
export * from './lib/constants/x-border.enum';
|
||||
export * from './lib/constants/x-setting.resources';
|
||||
export * from './lib/constants/x-exception.resources';
|
||||
export * from './lib/constants/x-translation.resources';
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Guards ...
|
||||
export * from './lib/guards/x-can-deactivate.guard';
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Models ...
|
||||
export * from './lib/models/x-base-dto';
|
||||
export * from './lib/models/x-grouped-data.dto';
|
||||
export * from './lib/models/x-base.indexed.dto';
|
||||
export {
|
||||
XBehaviourEvent,
|
||||
XBehaviourEventType,
|
||||
} from './lib/directives/x-scroll-behavior.directive';
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Tools ...
|
||||
export * from './lib/tools/x-task.tools';
|
||||
export * from './lib/tools/x-page.tools';
|
||||
export * from './lib/tools/x-uuid-tools';
|
||||
export * from './lib/tools/x-file.tools';
|
||||
export * from './lib/tools/x-array.tools';
|
||||
export * from './lib/tools/x-color.tools';
|
||||
export * from './lib/tools/x-number.tools';
|
||||
export * from './lib/tools/x-object.tools';
|
||||
export * from './lib/tools/x-string.tools';
|
||||
export * from './lib/tools/x-to-form-data';
|
||||
export * from './lib/tools/x-formatter.tools';
|
||||
export * from './lib/tools/x-date-time.tools';
|
||||
export * from './lib/tools/x-exception.tools';
|
||||
export * from './lib/tools/x-observable.tools';
|
||||
export * from './lib/tools/x-type-detect.tools';
|
||||
export * from './lib/tools/x-type-convert.tools';
|
||||
export * from './lib/tools/x-type-defaults.tools';
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Common Typings ...
|
||||
export * from './lib/typings/x.typings';
|
||||
export * from './lib/typings/x-page.typings';
|
||||
export * from './lib/typings/x-query.typings';
|
||||
export * from './lib/typings/x-color.typings';
|
||||
export * from './lib/typings/x-storage.typings';
|
||||
export * from './lib/typings/x-setting.typings';
|
||||
export * from './lib/typings/x-manager.typings';
|
||||
export * from './lib/typings/x-date-time.typings';
|
||||
export * from './lib/typings/x-exception.typings';
|
||||
export * from './lib/typings/x-translation.typings';
|
||||
export * from './lib/typings/x-task-manager.typings';
|
||||
export * from './lib/typings/x-notification.typings';
|
||||
export * from './lib/typings/x-theme-manager.typings';
|
||||
export * from './lib/typings/x-base-component.typings';
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Export Directives ...
|
||||
export * from './lib/directives/x-var.directive';
|
||||
export * from './lib/directives/x-color.directive';
|
||||
export * from './lib/directives/x-focus.directive';
|
||||
export * from './lib/directives/x-render.directive';
|
||||
export * from './lib/directives/x-slider.directive';
|
||||
export * from './lib/directives/x-on-enter.directive';
|
||||
export * from './lib/directives/x-formatter.directive';
|
||||
export * from './lib/directives/x-droppable.directive';
|
||||
export * from './lib/directives/x-clipboard.directive';
|
||||
export * from './lib/directives/x-on-escape.directive';
|
||||
export * from './lib/directives/x-file-reader.directive';
|
||||
export * from './lib/directives/x-mouse-handler.directive';
|
||||
export * from './lib/directives/x-focus-handler.directive';
|
||||
export * from './lib/directives/x-scroll-behavior.directive';
|
||||
export * from './lib/directives/x-on-outside-click.directive';
|
||||
export * from './lib/directives/x-stop-click-propagation.directive';
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Export Validators ...
|
||||
export * from './lib/validators/x-general-validators';
|
||||
export * from './lib/validators/x-valid-url.directive';
|
||||
export * from './lib/validators/x-valid-email.directive';
|
||||
export * from './lib/validators/x-value-match.directive';
|
||||
export * from './lib/validators/x-valid-phone-number.directive';
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Export Pipse ...
|
||||
export * from './lib/pipes/x-as.pipe';
|
||||
export * from './lib/pipes/x-log.pipe';
|
||||
export * from './lib/pipes/x-formatter.pipe';
|
||||
export * from './lib/pipes/x-safe-html.pipe';
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Tokens ...
|
||||
export * from './lib/tokens/x-injectable-tokens';
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Export Config ...
|
||||
export * from './lib/config/x-framework-core.config';
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Module ...
|
||||
export * from './lib/modules/x-directives.module';
|
||||
export * from './lib/x-framework-core.module';
|
||||
//#endregion
|
||||
@@ -0,0 +1,26 @@
|
||||
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||
|
||||
import 'zone.js';
|
||||
import 'zone.js/testing';
|
||||
import { getTestBed } from '@angular/core/testing';
|
||||
import {
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting
|
||||
} from '@angular/platform-browser-dynamic/testing';
|
||||
|
||||
declare const require: {
|
||||
context(path: string, deep?: boolean, filter?: RegExp): {
|
||||
keys(): string[];
|
||||
<T>(id: string): T;
|
||||
};
|
||||
};
|
||||
|
||||
// First, initialize the Angular testing environment.
|
||||
getTestBed().initTestEnvironment(
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting()
|
||||
);
|
||||
// Then we find all the tests.
|
||||
const context = require.context('./', true, /\.spec\.ts$/);
|
||||
// And load the modules.
|
||||
context.keys().map(context);
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"extends": "./tsconfig.lib.json",
|
||||
"angularCompilerOptions": {
|
||||
"enableIvy": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../out-tsc/lib",
|
||||
"target": "es2015",
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"inlineSources": true,
|
||||
"types": [],
|
||||
"lib": [
|
||||
"dom",
|
||||
"es2018"
|
||||
]
|
||||
},
|
||||
"exclude": [
|
||||
"src/test.ts",
|
||||
"**/*.spec.ts"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||
{
|
||||
"extends": "./tsconfig.lib.json",
|
||||
"compilerOptions": {
|
||||
"declarationMap": false
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"compilationMode": "partial"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../out-tsc/spec",
|
||||
"types": [
|
||||
"jasmine"
|
||||
]
|
||||
},
|
||||
"files": [
|
||||
"src/test.ts"
|
||||
],
|
||||
"include": [
|
||||
"**/*.spec.ts",
|
||||
"**/*.d.ts"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||
{
|
||||
"compileOnSave": false,
|
||||
"compilerOptions": {
|
||||
"strict": true,
|
||||
"baseUrl": "./",
|
||||
"sourceMap": true,
|
||||
"target": "es2017",
|
||||
"module": "es2020",
|
||||
"declaration": false,
|
||||
"importHelpers": true,
|
||||
"noImplicitAny": true,
|
||||
"strictNullChecks": false,
|
||||
"noImplicitReturns": true,
|
||||
"outDir": "./dist/out-tsc",
|
||||
"downlevelIteration": true,
|
||||
"moduleResolution": "node",
|
||||
"experimentalDecorators": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"suppressImplicitAnyIndexErrors": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"lib": [
|
||||
"es2018",
|
||||
"dom"
|
||||
],
|
||||
"paths": {
|
||||
"x-framework-core": [
|
||||
"dist/x-framework-core/x-framework-core",
|
||||
"dist/x-framework-core"
|
||||
]
|
||||
}
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"strictTemplates": true,
|
||||
"strictInjectionParameters": true,
|
||||
"strictInputAccessModifiers": true,
|
||||
"enableI18nLegacyMessageIdFormat": false
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user