ng-ipa-library 0.7.2 → 0.7.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/karma.conf.js +44 -0
- package/ng-package.json +43 -0
- package/package.json +24 -31
- package/src/lib/core/components/loading/loading.component.html +3 -0
- package/src/lib/core/components/loading/loading.component.scss +3 -0
- package/src/lib/core/components/loading/loading.component.ts +23 -0
- package/src/lib/core/interceptors/error.interceptor.ts +61 -0
- package/src/lib/core/interceptors/loading.interceptor.ts +69 -0
- package/src/lib/core/interceptors/token.interceptor.ts +77 -0
- package/src/lib/core/services/auth.service.ts +48 -0
- package/src/lib/core/services/error.service.ts +19 -0
- package/src/lib/core/services/loader.service.ts +21 -0
- package/src/lib/generate-form/generate-form.component.html +85 -0
- package/src/lib/generate-form/generate-form.component.scss +0 -0
- package/src/lib/generate-form/generate-form.component.ts +119 -0
- package/src/lib/ipa-form/datepicker/datepicker.component.html +21 -0
- package/src/lib/ipa-form/datepicker/datepicker.component.scss +13 -0
- package/src/lib/ipa-form/datepicker/datepicker.component.ts +67 -0
- package/src/lib/ipa-form/datepicker/gregorian-datepicker/gregorian-datepicker.component.ts +15 -0
- package/src/lib/ipa-form/datepicker/gregorian-datepicker/gregorian18n.ts +38 -0
- package/src/lib/ipa-form/datepicker/hijri-datepicker/IslamicI18n.ts +38 -0
- package/src/lib/ipa-form/datepicker/hijri-datepicker/hijri-datepicker.component.ts +14 -0
- package/src/lib/ipa-form/dropdown-input/dropdown-input.component.html +22 -0
- package/src/lib/ipa-form/dropdown-input/dropdown-input.component.scss +0 -0
- package/src/lib/ipa-form/dropdown-input/dropdown-input.component.ts +68 -0
- package/src/lib/ipa-form/file-upload/file-upload.component.html +37 -0
- package/src/lib/ipa-form/file-upload/file-upload.component.scss +45 -0
- package/src/lib/ipa-form/file-upload/file-upload.component.ts +109 -0
- package/src/lib/ipa-form/ipa-form.service.ts +294 -0
- package/src/lib/ipa-form/recaptcha/recaptcha.component.html +3 -0
- package/src/lib/ipa-form/recaptcha/recaptcha.component.scss +0 -0
- package/src/lib/ipa-form/recaptcha/recaptcha.component.ts +42 -0
- package/src/lib/ipa-form/text-input/text-input.component.html +10 -0
- package/src/lib/ipa-form/text-input/text-input.component.scss +0 -0
- package/src/lib/ipa-form/text-input/text-input.component.ts +69 -0
- package/src/lib/ipa-form/textarea-input/textarea-input.component.html +11 -0
- package/src/lib/ipa-form/textarea-input/textarea-input.component.scss +0 -0
- package/src/lib/ipa-form/textarea-input/textarea-input.component.ts +69 -0
- package/{lib/models/apiException.d.ts → src/lib/models/apiException.ts} +2 -1
- package/src/lib/models/apiResponse.ts +4 -0
- package/src/lib/models/breadcrumbs.model.ts +4 -0
- package/src/lib/models/decodedToken.model.ts +6 -0
- package/src/lib/models/exceptionUrl.model.ts +4 -0
- package/src/lib/models/generateForm.model.ts +29 -0
- package/src/lib/models/pagedResult.ts +4 -0
- package/src/lib/models/user.model.ts +7 -0
- package/src/lib/ng-ipa-library.component.ts +15 -0
- package/src/lib/ng-ipa-library.module.ts +63 -0
- package/src/lib/pipes/hijri-date.pipe.ts +15 -0
- package/src/lib/pipes/pipes.module.ts +8 -0
- package/src/lib/services/breadcrumbs.service.ts +189 -0
- package/src/lib/services/common.service.ts +63 -0
- package/src/lib/share-button/share-button.component.html +3 -0
- package/src/lib/share-button/share-button.component.scss +0 -0
- package/src/lib/share-button/share-button.component.ts +23 -0
- package/src/lib/share-button/share-button.module.ts +32 -0
- package/{public-api.d.ts → src/public-api.ts} +16 -1
- package/src/test.ts +26 -0
- package/tsconfig.lib.json +20 -0
- package/tsconfig.lib.prod.json +10 -0
- package/tsconfig.spec.json +17 -0
- package/bundles/ng-ipa-library.umd.js +0 -2101
- package/bundles/ng-ipa-library.umd.js.map +0 -1
- package/esm2015/lib/core/components/loading/loading.component.js +0 -27
- package/esm2015/lib/core/interceptors/error.interceptor.js +0 -46
- package/esm2015/lib/core/interceptors/loading.interceptor.js +0 -58
- package/esm2015/lib/core/interceptors/token.interceptor.js +0 -69
- package/esm2015/lib/core/services/auth.service.js +0 -48
- package/esm2015/lib/core/services/error.service.js +0 -22
- package/esm2015/lib/core/services/loader.service.js +0 -24
- package/esm2015/lib/generate-form/generate-form.component.js +0 -120
- package/esm2015/lib/ipa-form/datepicker/datepicker.component.js +0 -70
- package/esm2015/lib/ipa-form/datepicker/gregorian-datepicker/gregorian-datepicker.component.js +0 -28
- package/esm2015/lib/ipa-form/datepicker/gregorian-datepicker/gregorian18n.js +0 -38
- package/esm2015/lib/ipa-form/datepicker/hijri-datepicker/IslamicI18n.js +0 -38
- package/esm2015/lib/ipa-form/datepicker/hijri-datepicker/hijri-datepicker.component.js +0 -28
- package/esm2015/lib/ipa-form/dropdown-input/dropdown-input.component.js +0 -81
- package/esm2015/lib/ipa-form/file-upload/file-upload.component.js +0 -128
- package/esm2015/lib/ipa-form/ipa-form.service.js +0 -251
- package/esm2015/lib/ipa-form/recaptcha/recaptcha.component.js +0 -59
- package/esm2015/lib/ipa-form/text-input/text-input.component.js +0 -76
- package/esm2015/lib/ipa-form/textarea-input/textarea-input.component.js +0 -73
- package/esm2015/lib/models/apiException.js +0 -2
- package/esm2015/lib/models/apiResponse.js +0 -2
- package/esm2015/lib/models/breadcrumbs.model.js +0 -2
- package/esm2015/lib/models/decodedToken.model.js +0 -2
- package/esm2015/lib/models/exceptionUrl.model.js +0 -2
- package/esm2015/lib/models/generateForm.model.js +0 -2
- package/esm2015/lib/models/pagedResult.js +0 -2
- package/esm2015/lib/models/user.model.js +0 -2
- package/esm2015/lib/ng-ipa-library.module.js +0 -112
- package/esm2015/lib/pipes/hijri-date.pipe.js +0 -18
- package/esm2015/lib/pipes/pipes.module.js +0 -16
- package/esm2015/lib/services/breadcrumbs.service.js +0 -151
- package/esm2015/lib/services/common.service.js +0 -66
- package/esm2015/lib/share-button/share-button.component.js +0 -37
- package/esm2015/lib/share-button/share-button.module.js +0 -52
- package/esm2015/ng-ipa-library.js +0 -5
- package/esm2015/public-api.js +0 -40
- package/fesm2015/ng-ipa-library.js +0 -1633
- package/fesm2015/ng-ipa-library.js.map +0 -1
- package/lib/core/components/loading/loading.component.d.ts +0 -12
- package/lib/core/interceptors/error.interceptor.d.ts +0 -14
- package/lib/core/interceptors/loading.interceptor.d.ts +0 -14
- package/lib/core/interceptors/token.interceptor.d.ts +0 -15
- package/lib/core/services/auth.service.d.ts +0 -15
- package/lib/core/services/error.service.d.ts +0 -10
- package/lib/core/services/loader.service.d.ts +0 -12
- package/lib/generate-form/generate-form.component.d.ts +0 -32
- package/lib/ipa-form/datepicker/datepicker.component.d.ts +0 -31
- package/lib/ipa-form/datepicker/gregorian-datepicker/gregorian-datepicker.component.d.ts +0 -6
- package/lib/ipa-form/datepicker/gregorian-datepicker/gregorian18n.d.ts +0 -11
- package/lib/ipa-form/datepicker/hijri-datepicker/IslamicI18n.d.ts +0 -11
- package/lib/ipa-form/datepicker/hijri-datepicker/hijri-datepicker.component.d.ts +0 -6
- package/lib/ipa-form/dropdown-input/dropdown-input.component.d.ts +0 -31
- package/lib/ipa-form/file-upload/file-upload.component.d.ts +0 -36
- package/lib/ipa-form/ipa-form.service.d.ts +0 -49
- package/lib/ipa-form/recaptcha/recaptcha.component.d.ts +0 -22
- package/lib/ipa-form/text-input/text-input.component.d.ts +0 -30
- package/lib/ipa-form/textarea-input/textarea-input.component.d.ts +0 -29
- package/lib/models/apiResponse.d.ts +0 -4
- package/lib/models/breadcrumbs.model.d.ts +0 -4
- package/lib/models/decodedToken.model.d.ts +0 -6
- package/lib/models/exceptionUrl.model.d.ts +0 -4
- package/lib/models/generateForm.model.d.ts +0 -27
- package/lib/models/pagedResult.d.ts +0 -4
- package/lib/models/user.model.d.ts +0 -7
- package/lib/ng-ipa-library.module.d.ts +0 -25
- package/lib/pipes/hijri-date.pipe.d.ts +0 -7
- package/lib/pipes/pipes.module.d.ts +0 -7
- package/lib/services/breadcrumbs.service.d.ts +0 -18
- package/lib/services/common.service.d.ts +0 -8
- package/lib/share-button/share-button.component.d.ts +0 -11
- package/lib/share-button/share-button.module.d.ts +0 -13
- package/ng-ipa-library.d.ts +0 -5
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
import { AbstractControl, FormControl, ValidationErrors } from '@angular/forms';
|
|
3
|
+
import momentHijri from 'moment-hijri';
|
|
4
|
+
import { Moment } from 'moment';
|
|
5
|
+
import { NgbDateParserFormatter } from '@ng-bootstrap/ng-bootstrap';
|
|
6
|
+
|
|
7
|
+
@Injectable({
|
|
8
|
+
providedIn: 'root',
|
|
9
|
+
})
|
|
10
|
+
export class IPAFormService {
|
|
11
|
+
constructor(private parserFormatter: NgbDateParserFormatter) {}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* check link is valid.
|
|
15
|
+
*/
|
|
16
|
+
static linkValidation(control: AbstractControl): ValidationErrors | null {
|
|
17
|
+
const isValidLink =
|
|
18
|
+
/^((https?:\/\/)[\w-]+(\.[a-z-]+)+\.?(:\d+)?(\/\S*)?)$/.test(
|
|
19
|
+
control.value
|
|
20
|
+
);
|
|
21
|
+
return isValidLink || !control.value ? null : { link: true };
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* check mp4 link is valid.
|
|
26
|
+
*/
|
|
27
|
+
static mp4LinkValidation(control: AbstractControl): ValidationErrors | null {
|
|
28
|
+
const isValidLink =
|
|
29
|
+
/^((https?:\/\/)[\w-]+(\.[a-z-]+)+\.?(:\d+)?(\/\S*)?(\/[\w\u0600-\u06FF]+\.mp4))$/.test(
|
|
30
|
+
control.value
|
|
31
|
+
);
|
|
32
|
+
return isValidLink || !control.value ? null : { linkMP4: true };
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* check mobile number is valid.
|
|
37
|
+
*/
|
|
38
|
+
static mobileNo(control: AbstractControl): ValidationErrors | null {
|
|
39
|
+
const isValidLink = /^05\d{8}$/.test(control.value);
|
|
40
|
+
return isValidLink || !control.value ? null : { mobileNo: true };
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* check email is valid.
|
|
45
|
+
*/
|
|
46
|
+
static email(control: AbstractControl): ValidationErrors | null {
|
|
47
|
+
const isValidLink =
|
|
48
|
+
/^(([^<>()[\]\.,;:\s@\"]+(\.[^<>()[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/.test(
|
|
49
|
+
control.value
|
|
50
|
+
);
|
|
51
|
+
return isValidLink || !control.value ? null : { Email: true };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* check national ID or iqama ID is valid.
|
|
56
|
+
*/
|
|
57
|
+
static checkID(control: AbstractControl): ValidationErrors | null {
|
|
58
|
+
let isValid = false;
|
|
59
|
+
const value = control.value;
|
|
60
|
+
if (
|
|
61
|
+
IPAFormService.nationalIdValidate(value) ||
|
|
62
|
+
IPAFormService.iqamaIdValidate(value)
|
|
63
|
+
) {
|
|
64
|
+
isValid = true;
|
|
65
|
+
} else {
|
|
66
|
+
isValid = false;
|
|
67
|
+
}
|
|
68
|
+
return isValid || !value ? null : { checkId: true };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
getErrorMessage(control: FormControl, patternErrorMsg = ''): string | null {
|
|
72
|
+
for (const propertyName in control?.errors) {
|
|
73
|
+
if (
|
|
74
|
+
control?.errors.hasOwnProperty(propertyName) &&
|
|
75
|
+
(control.touched || control.dirty)
|
|
76
|
+
) {
|
|
77
|
+
return this.getValidatorErrorMessage(
|
|
78
|
+
propertyName,
|
|
79
|
+
control.errors[propertyName],
|
|
80
|
+
patternErrorMsg
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* convert gregorian date to hijri date (Based on Umm al-Qura calculations).
|
|
89
|
+
* @param date: gregorian date
|
|
90
|
+
* @param format: iDD => day: ١٥, iMM => month: ٠٤, iMMM => month: ربيع ٢,
|
|
91
|
+
* iMMMM => ربيع الثاني, iYY => year: ٤٢, iYYYY => year: ١٤٤٢,
|
|
92
|
+
* dd => ن, ddd => إثنين, dddd => الإثنين
|
|
93
|
+
* @example 'iYYYY/iM/iDهـ الموافق YYYY/M/Dم'
|
|
94
|
+
* '١٤٤٢/٠٤/١٥هـ الموافق ٢٠٢٠/١١/٣٠'
|
|
95
|
+
*/
|
|
96
|
+
convertToHijriDate(
|
|
97
|
+
date: string,
|
|
98
|
+
format = 'iYYYY-iMM-iDD',
|
|
99
|
+
lang = 'ar-SA'
|
|
100
|
+
): string {
|
|
101
|
+
momentHijri.locale(lang);
|
|
102
|
+
return momentHijri(date).format(format);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
convertToGregorianDate(
|
|
106
|
+
date: Moment,
|
|
107
|
+
format = 'YYYY-MM-DD',
|
|
108
|
+
lang = 'en'
|
|
109
|
+
): string {
|
|
110
|
+
momentHijri.locale(lang);
|
|
111
|
+
const m = momentHijri.iConvert.toGregorian(
|
|
112
|
+
date.year(),
|
|
113
|
+
date.month(),
|
|
114
|
+
date.date()
|
|
115
|
+
);
|
|
116
|
+
return momentHijri(new Date(m.gy, m.gm, m.gd)).format(format);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
getCurrentHijriDate() {
|
|
120
|
+
momentHijri.locale('en');
|
|
121
|
+
return momentHijri().format('iYYYY/iMM/iDD');
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
private getValidatorErrorMessage(
|
|
125
|
+
validatorName: string,
|
|
126
|
+
validatorValue: any,
|
|
127
|
+
patternErrorMsg: string
|
|
128
|
+
): string {
|
|
129
|
+
if (validatorName === 'pattern') {
|
|
130
|
+
validatorValue = this.addPatternMsg(validatorValue, patternErrorMsg);
|
|
131
|
+
}
|
|
132
|
+
const config: any = {
|
|
133
|
+
required: 'هذا الحقل مطلوب',
|
|
134
|
+
pattern: `${validatorValue.message}`,
|
|
135
|
+
Email: 'خطأ في البريد الالكتروني (example@ipa.edu.sa)',
|
|
136
|
+
maxlength: `تجاوز عدد الحقل المسموح بها (${validatorValue.requiredLength}) حرف`,
|
|
137
|
+
minlength: `على الأقل عدد ${validatorValue.requiredLength} حرف.`,
|
|
138
|
+
min: `رقم اكبر من أو يساوي ${validatorValue.min}`,
|
|
139
|
+
max: `رقم اصغر من أو يساوي ${validatorValue.max}`,
|
|
140
|
+
ngbDate: this.getNgbDatepickerErrorMsg(validatorValue),
|
|
141
|
+
checkId: 'رقم الهوية أو الاقامة غير صحيح',
|
|
142
|
+
link: 'الرابط غير صحيح (http://google.com)',
|
|
143
|
+
linkMP4: 'الرابط غير صحيح (http://example.com/a.mp4)',
|
|
144
|
+
mobileNo: 'خطأ في رقم الجوال (05xxxxxxxx)',
|
|
145
|
+
};
|
|
146
|
+
return config[validatorName];
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
private addPatternMsg(validatorValue: any, patternErrorMsg: string) {
|
|
150
|
+
let pattern = {
|
|
151
|
+
...validatorValue,
|
|
152
|
+
message: patternErrorMsg,
|
|
153
|
+
};
|
|
154
|
+
return pattern;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
private getNgbDatepickerErrorMsg(validatorValue: any): string {
|
|
158
|
+
let msg = '';
|
|
159
|
+
if (validatorValue.maxDate) {
|
|
160
|
+
msg = `التاريخ المدخل "${this.parserFormatter.format(
|
|
161
|
+
validatorValue.maxDate.actual
|
|
162
|
+
)}" اكبر من تاريخ اليوم "${this.parserFormatter.format(
|
|
163
|
+
validatorValue.maxDate.maxDate
|
|
164
|
+
)}"`;
|
|
165
|
+
} else if (validatorValue.minDate) {
|
|
166
|
+
msg = `التاريخ المدخل "${this.parserFormatter.format(
|
|
167
|
+
validatorValue.minDate.actual
|
|
168
|
+
)}" يجب ان يكون اكبر من أو يساوي تاريخ البداية "${this.parserFormatter.format(
|
|
169
|
+
validatorValue.minDate.minDate
|
|
170
|
+
)}"`;
|
|
171
|
+
} else if (validatorValue.invalid) {
|
|
172
|
+
msg = `التاريخ المدخل غير صحيح ${validatorValue.invalid}.`;
|
|
173
|
+
}
|
|
174
|
+
return msg;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
private static convertToEn(value: string) {
|
|
178
|
+
let newValue = '';
|
|
179
|
+
for (let i = 0; i < value.length; i++) {
|
|
180
|
+
let ch = value.charCodeAt(i);
|
|
181
|
+
if (ch >= 1584 && ch <= 1650) {
|
|
182
|
+
let newChar = ch - 1584;
|
|
183
|
+
newValue = newValue + String.fromCharCode(newChar);
|
|
184
|
+
} else {
|
|
185
|
+
newValue = newValue + String.fromCharCode(ch);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return newValue;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
private static nationalIdValidate(civilId: string): boolean {
|
|
192
|
+
if (civilId) {
|
|
193
|
+
let strID = this.convertToEn(civilId);
|
|
194
|
+
let digits = '';
|
|
195
|
+
let counter = 0;
|
|
196
|
+
while (counter < 9) {
|
|
197
|
+
if ((counter + 1) % 2 == 0) {
|
|
198
|
+
digits = digits + strID.substring(counter, counter + 1);
|
|
199
|
+
} else {
|
|
200
|
+
digits =
|
|
201
|
+
digits + (+strID.substring(counter, counter + 1) * 2).toString();
|
|
202
|
+
}
|
|
203
|
+
counter++;
|
|
204
|
+
}
|
|
205
|
+
let intSum = 0;
|
|
206
|
+
let intSumTemp = 0;
|
|
207
|
+
let strSum;
|
|
208
|
+
let intOddSumDigit;
|
|
209
|
+
let CheckDigit;
|
|
210
|
+
counter = 0;
|
|
211
|
+
while (counter < digits.length) {
|
|
212
|
+
intSumTemp = +digits.charAt(counter) * 1;
|
|
213
|
+
intSum += intSumTemp;
|
|
214
|
+
counter++;
|
|
215
|
+
}
|
|
216
|
+
strSum = intSum.toString();
|
|
217
|
+
if (strSum.length == 1) {
|
|
218
|
+
intOddSumDigit = intSum;
|
|
219
|
+
} else {
|
|
220
|
+
intOddSumDigit = strSum.substring(strSum.length, strSum.length - 1);
|
|
221
|
+
}
|
|
222
|
+
if (intOddSumDigit == 0) {
|
|
223
|
+
CheckDigit = 0;
|
|
224
|
+
} else {
|
|
225
|
+
CheckDigit = (10 - +intOddSumDigit).toString();
|
|
226
|
+
}
|
|
227
|
+
let PublicID = this.convertToEn(civilId);
|
|
228
|
+
if (
|
|
229
|
+
CheckDigit ==
|
|
230
|
+
PublicID.substring(PublicID.length - 1, PublicID.length) &&
|
|
231
|
+
strID.length == 10 &&
|
|
232
|
+
strID.substring(0, 1) == '1'
|
|
233
|
+
) {
|
|
234
|
+
return true;
|
|
235
|
+
} else {
|
|
236
|
+
return false;
|
|
237
|
+
}
|
|
238
|
+
} else {
|
|
239
|
+
return false;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
private static iqamaIdValidate(civilId: string): boolean {
|
|
244
|
+
if (civilId) {
|
|
245
|
+
let strID = this.convertToEn(civilId);
|
|
246
|
+
let digits = '';
|
|
247
|
+
let counter = 0;
|
|
248
|
+
while (counter < 9) {
|
|
249
|
+
if ((counter + 1) % 2 == 0) {
|
|
250
|
+
digits = digits + strID.substring(counter, counter + 1);
|
|
251
|
+
} else {
|
|
252
|
+
digits =
|
|
253
|
+
digits + (+strID.substring(counter, counter + 1) * 2).toString();
|
|
254
|
+
}
|
|
255
|
+
counter++;
|
|
256
|
+
}
|
|
257
|
+
let intSum = 0;
|
|
258
|
+
let intSumTemp = 0;
|
|
259
|
+
let strSum;
|
|
260
|
+
let intOddSumDigit;
|
|
261
|
+
let CheckDigit;
|
|
262
|
+
counter = 0;
|
|
263
|
+
while (counter < digits.length) {
|
|
264
|
+
intSumTemp = +digits.charAt(counter) * 1;
|
|
265
|
+
intSum += intSumTemp;
|
|
266
|
+
counter++;
|
|
267
|
+
}
|
|
268
|
+
strSum = intSum.toString();
|
|
269
|
+
if (strSum.length == 1) {
|
|
270
|
+
intOddSumDigit = intSum;
|
|
271
|
+
} else {
|
|
272
|
+
intOddSumDigit = strSum.substring(strSum.length, strSum.length - 1);
|
|
273
|
+
}
|
|
274
|
+
if (intOddSumDigit == 0) {
|
|
275
|
+
CheckDigit = 0;
|
|
276
|
+
} else {
|
|
277
|
+
CheckDigit = (10 - +intOddSumDigit).toString();
|
|
278
|
+
}
|
|
279
|
+
let PublicID = this.convertToEn(civilId);
|
|
280
|
+
if (
|
|
281
|
+
CheckDigit ==
|
|
282
|
+
PublicID.substring(PublicID.length - 1, PublicID.length) &&
|
|
283
|
+
strID.length == 10 &&
|
|
284
|
+
strID.substring(0, 1) == '2'
|
|
285
|
+
) {
|
|
286
|
+
return true;
|
|
287
|
+
} else {
|
|
288
|
+
return false;
|
|
289
|
+
}
|
|
290
|
+
} else {
|
|
291
|
+
return false;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Component, Input, OnInit, Self } from '@angular/core';
|
|
2
|
+
import { FormControl, NgControl } from '@angular/forms';
|
|
3
|
+
|
|
4
|
+
@Component({
|
|
5
|
+
selector: 'ipa-recaptcha',
|
|
6
|
+
templateUrl: './recaptcha.component.html',
|
|
7
|
+
styleUrls: ['./recaptcha.component.scss'],
|
|
8
|
+
})
|
|
9
|
+
export class RecaptchaComponent implements OnInit {
|
|
10
|
+
@Input() siteKey = '6LefJQYdAAAAAIlxmfkjNlWidMk8VukIZcs6lO5e';
|
|
11
|
+
@Input() recaptchaSize: 'compact' | 'normal' = 'normal';
|
|
12
|
+
@Input() lang = 'ar';
|
|
13
|
+
@Input() recaptchaType: 'image' | 'audio' = 'image';
|
|
14
|
+
@Input() theme: 'light' | 'dark' = 'light';
|
|
15
|
+
@Input() useGlobalDomain = true;
|
|
16
|
+
formControl: FormControl = new FormControl('');
|
|
17
|
+
constructor(@Self() public controlDir: NgControl) {
|
|
18
|
+
this.controlDir.valueAccessor = this;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
ngOnInit(): void {
|
|
22
|
+
const control = this.controlDir.control;
|
|
23
|
+
const validators = control?.validator ? [control.validator] : [];
|
|
24
|
+
|
|
25
|
+
control?.setValidators(validators);
|
|
26
|
+
control?.updateValueAndValidity();
|
|
27
|
+
this.formControl = control as FormControl;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
onChange(event: any): void {}
|
|
31
|
+
|
|
32
|
+
onTouched(): void {}
|
|
33
|
+
writeValue(obj: any): void {}
|
|
34
|
+
|
|
35
|
+
registerOnChange(fn: any): void {
|
|
36
|
+
this.onChange = fn;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
registerOnTouched(fn: any): void {
|
|
40
|
+
this.onTouched = fn;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<div class="form-floating {{containerClasses}}">
|
|
2
|
+
<input #input id="{{id}}" class="form-control {{classes}}" [type]="type" [required]="required" pattern="{{pattern}}"
|
|
3
|
+
placeholder="{{placeholder}}" [formControl]="formControl" (input)="onChange(controlDir.control?.value)"
|
|
4
|
+
(blur)="onTouched()"
|
|
5
|
+
[ngClass]="{'is-invalid is-invalid:focus': (controlDir.control?.invalid && (controlDir.control?.dirty || controlDir.control?.touched)) && errorMsg,'is-valid is-valid:focus': (controlDir.control?.valid && (controlDir.control?.dirty || controlDir.control?.touched) && (errorMsg || controlDir.value))}">
|
|
6
|
+
<label for="{{id}}">{{label}}</label>
|
|
7
|
+
<div class="invalid-feedback" *ngIf="errorMessage !== null">
|
|
8
|
+
{{errorMsg}}
|
|
9
|
+
</div>
|
|
10
|
+
</div>
|
|
File without changes
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Component,
|
|
3
|
+
ElementRef,
|
|
4
|
+
Input,
|
|
5
|
+
OnInit,
|
|
6
|
+
Self,
|
|
7
|
+
ViewChild,
|
|
8
|
+
} from '@angular/core';
|
|
9
|
+
import { FormControl, NgControl } from '@angular/forms';
|
|
10
|
+
import { IPAFormService } from '../ipa-form.service';
|
|
11
|
+
|
|
12
|
+
@Component({
|
|
13
|
+
selector: 'ipa-text-input',
|
|
14
|
+
templateUrl: './text-input.component.html',
|
|
15
|
+
styleUrls: ['./text-input.component.scss'],
|
|
16
|
+
})
|
|
17
|
+
export class TextInputComponent implements OnInit {
|
|
18
|
+
@ViewChild('input', { static: true }) input!: ElementRef;
|
|
19
|
+
@Input() id!: string;
|
|
20
|
+
@Input() type = 'text';
|
|
21
|
+
@Input() placeholder = 'please enter text';
|
|
22
|
+
@Input() label: string = 'text input';
|
|
23
|
+
@Input() required = false;
|
|
24
|
+
@Input() patternErrorMsg = 'invalid pattern';
|
|
25
|
+
@Input() pattern = '';
|
|
26
|
+
@Input() classes!: string;
|
|
27
|
+
@Input() containerClasses!: string;
|
|
28
|
+
formControl: FormControl = new FormControl('');
|
|
29
|
+
errorMsg!: string | null;
|
|
30
|
+
|
|
31
|
+
constructor(
|
|
32
|
+
private validationService: IPAFormService,
|
|
33
|
+
@Self() public controlDir: NgControl
|
|
34
|
+
) {
|
|
35
|
+
this.controlDir.valueAccessor = this;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
ngOnInit(): void {
|
|
39
|
+
const control = this.controlDir.control;
|
|
40
|
+
const validators = control?.validator ? [control.validator] : [];
|
|
41
|
+
|
|
42
|
+
control?.setValidators(validators);
|
|
43
|
+
control?.updateValueAndValidity();
|
|
44
|
+
this.formControl = control as FormControl;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
onChange(event: any): void {}
|
|
48
|
+
|
|
49
|
+
onTouched(): void {}
|
|
50
|
+
writeValue(obj: any): void {
|
|
51
|
+
this.input.nativeElement.value = obj || '';
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
registerOnChange(fn: any): void {
|
|
55
|
+
this.onChange = fn;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
registerOnTouched(fn: any): void {
|
|
59
|
+
this.onTouched = fn;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
get errorMessage(): string | null {
|
|
63
|
+
this.errorMsg = this.validationService.getErrorMessage(
|
|
64
|
+
this.formControl,
|
|
65
|
+
this.patternErrorMsg
|
|
66
|
+
);
|
|
67
|
+
return this.errorMsg;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<div class="form-floating {{containerClasses}}">
|
|
2
|
+
<textarea #input id="{{id}}" class="form-control {{classes}}" [required]="required" pattern="{{pattern}}"
|
|
3
|
+
placeholder="{{placeholder}}" [formControl]="formControl" (input)="onChange(controlDir.control?.value)"
|
|
4
|
+
(blur)="onTouched()"
|
|
5
|
+
[ngClass]="{'is-invalid is-invalid:focus': (controlDir.control?.invalid && (controlDir.control?.dirty || controlDir.control?.touched)) && errorMsg,'is-valid is-valid:focus': (controlDir.control?.valid && (controlDir.control?.dirty || controlDir.control?.touched) && (errorMsg || controlDir.value))}">
|
|
6
|
+
</textarea>
|
|
7
|
+
<label for="{{id}}">{{label}}</label>
|
|
8
|
+
<div class="invalid-feedback" *ngIf="errorMessage !== null">
|
|
9
|
+
{{errorMsg}}
|
|
10
|
+
</div>
|
|
11
|
+
</div>
|
|
File without changes
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Component,
|
|
3
|
+
ElementRef,
|
|
4
|
+
Input,
|
|
5
|
+
OnInit,
|
|
6
|
+
Self,
|
|
7
|
+
ViewChild,
|
|
8
|
+
} from '@angular/core';
|
|
9
|
+
import { FormControl, NgControl } from '@angular/forms';
|
|
10
|
+
import { IPAFormService } from '../ipa-form.service';
|
|
11
|
+
|
|
12
|
+
@Component({
|
|
13
|
+
selector: 'ipa-textarea-input',
|
|
14
|
+
templateUrl: './textarea-input.component.html',
|
|
15
|
+
styleUrls: ['./textarea-input.component.scss'],
|
|
16
|
+
})
|
|
17
|
+
export class TextareaInputComponent implements OnInit {
|
|
18
|
+
@ViewChild('input', { static: true }) input: ElementRef<any> =
|
|
19
|
+
new ElementRef<any>(null);
|
|
20
|
+
@Input() id!: string;
|
|
21
|
+
@Input() placeholder = 'please enter text';
|
|
22
|
+
@Input() label: string = 'textarea input';
|
|
23
|
+
@Input() required = false;
|
|
24
|
+
@Input() patternErrorMsg = 'invalid pattern';
|
|
25
|
+
@Input() pattern!: string;
|
|
26
|
+
@Input() classes!: string;
|
|
27
|
+
@Input() containerClasses!: string;
|
|
28
|
+
formControl: FormControl = new FormControl('');
|
|
29
|
+
errorMsg!: string | null;
|
|
30
|
+
|
|
31
|
+
constructor(
|
|
32
|
+
private validationService: IPAFormService,
|
|
33
|
+
@Self() public controlDir: NgControl
|
|
34
|
+
) {
|
|
35
|
+
this.controlDir.valueAccessor = this;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
ngOnInit(): void {
|
|
39
|
+
const control = this.controlDir.control;
|
|
40
|
+
const validators = control?.validator ? [control.validator] : [];
|
|
41
|
+
|
|
42
|
+
control?.setValidators(validators);
|
|
43
|
+
control?.updateValueAndValidity();
|
|
44
|
+
this.formControl = control as FormControl;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
onChange(event: any): void {}
|
|
48
|
+
|
|
49
|
+
onTouched(): void {}
|
|
50
|
+
writeValue(obj: any): void {
|
|
51
|
+
this.input.nativeElement.value = obj || '';
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
registerOnChange(fn: any): void {
|
|
55
|
+
this.onChange = fn;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
registerOnTouched(fn: any): void {
|
|
59
|
+
this.onTouched = fn;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
get errorMessage(): string | null {
|
|
63
|
+
this.errorMsg = this.validationService.getErrorMessage(
|
|
64
|
+
this.formControl,
|
|
65
|
+
this.patternErrorMsg
|
|
66
|
+
);
|
|
67
|
+
return this.errorMsg;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface GenerateForm {
|
|
2
|
+
columns: Column[];
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export interface Column {
|
|
6
|
+
arabicLabel: string;
|
|
7
|
+
englishName: string;
|
|
8
|
+
validationPattern?: string;
|
|
9
|
+
inputClasses?: string;
|
|
10
|
+
containerClasses?: string;
|
|
11
|
+
valueField?: string;
|
|
12
|
+
textField?: string;
|
|
13
|
+
patternErrorMsg?: string;
|
|
14
|
+
type: string;
|
|
15
|
+
size?: number;
|
|
16
|
+
required: boolean;
|
|
17
|
+
data?: Data[] | any[];
|
|
18
|
+
acceptedFiles?: string;
|
|
19
|
+
multipleFile?: number;
|
|
20
|
+
apiUrl?: string;
|
|
21
|
+
autoUploadFile?: boolean;
|
|
22
|
+
apiURlMethod?: string;
|
|
23
|
+
authorization?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface Data {
|
|
27
|
+
id: number;
|
|
28
|
+
description: string;
|
|
29
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { CommonModule } from '@angular/common';
|
|
2
|
+
import { NgModule } from '@angular/core';
|
|
3
|
+
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|
4
|
+
import { ToastrModule } from 'ngx-toastr';
|
|
5
|
+
import { DropzoneModule } from 'ngx-dropzone-wrapper';
|
|
6
|
+
import { NgxCaptchaModule } from 'ngx-captcha';
|
|
7
|
+
import { PipesModule } from './pipes/pipes.module';
|
|
8
|
+
import { NgbDatepickerModule } from '@ng-bootstrap/ng-bootstrap';
|
|
9
|
+
import { NgSelectModule } from '@ng-select/ng-select';
|
|
10
|
+
|
|
11
|
+
import { TextInputComponent } from './ipa-form/text-input/text-input.component';
|
|
12
|
+
import { TextareaInputComponent } from './ipa-form/textarea-input/textarea-input.component';
|
|
13
|
+
import { DropdownInputComponent } from './ipa-form/dropdown-input/dropdown-input.component';
|
|
14
|
+
import { LoaderComponent } from './core/components/loading/loading.component';
|
|
15
|
+
import { GenerateFormComponent } from './generate-form/generate-form.component';
|
|
16
|
+
import { FileUploadComponent } from './ipa-form/file-upload/file-upload.component';
|
|
17
|
+
import { DatepickerComponent } from './ipa-form/datepicker/datepicker.component';
|
|
18
|
+
import { HijriDatepickerComponent } from './ipa-form/datepicker/hijri-datepicker/hijri-datepicker.component';
|
|
19
|
+
import { GregorianDatepickerComponent } from './ipa-form/datepicker/gregorian-datepicker/gregorian-datepicker.component';
|
|
20
|
+
import { ShareButtonModule } from './share-button/share-button.module';
|
|
21
|
+
import { RecaptchaComponent } from './ipa-form/recaptcha/recaptcha.component';
|
|
22
|
+
|
|
23
|
+
@NgModule({
|
|
24
|
+
declarations: [
|
|
25
|
+
TextInputComponent,
|
|
26
|
+
TextareaInputComponent,
|
|
27
|
+
DropdownInputComponent,
|
|
28
|
+
LoaderComponent,
|
|
29
|
+
GenerateFormComponent,
|
|
30
|
+
FileUploadComponent,
|
|
31
|
+
DatepickerComponent,
|
|
32
|
+
HijriDatepickerComponent,
|
|
33
|
+
GregorianDatepickerComponent,
|
|
34
|
+
RecaptchaComponent,
|
|
35
|
+
],
|
|
36
|
+
imports: [
|
|
37
|
+
CommonModule,
|
|
38
|
+
FormsModule,
|
|
39
|
+
ReactiveFormsModule,
|
|
40
|
+
ToastrModule,
|
|
41
|
+
DropzoneModule,
|
|
42
|
+
NgxCaptchaModule,
|
|
43
|
+
PipesModule,
|
|
44
|
+
NgbDatepickerModule,
|
|
45
|
+
ShareButtonModule,
|
|
46
|
+
NgSelectModule,
|
|
47
|
+
],
|
|
48
|
+
exports: [
|
|
49
|
+
TextInputComponent,
|
|
50
|
+
TextareaInputComponent,
|
|
51
|
+
DropdownInputComponent,
|
|
52
|
+
LoaderComponent,
|
|
53
|
+
GenerateFormComponent,
|
|
54
|
+
FileUploadComponent,
|
|
55
|
+
PipesModule,
|
|
56
|
+
HijriDatepickerComponent,
|
|
57
|
+
GregorianDatepickerComponent,
|
|
58
|
+
ShareButtonModule,
|
|
59
|
+
RecaptchaComponent,
|
|
60
|
+
NgSelectModule,
|
|
61
|
+
],
|
|
62
|
+
})
|
|
63
|
+
export class NgIPALibraryModule {}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Pipe, PipeTransform } from '@angular/core';
|
|
2
|
+
import momentHijri from 'moment-hijri';
|
|
3
|
+
@Pipe({
|
|
4
|
+
name: 'hijriDate',
|
|
5
|
+
})
|
|
6
|
+
export class HijriDatePipe implements PipeTransform {
|
|
7
|
+
transform(
|
|
8
|
+
date: string,
|
|
9
|
+
format: string = 'iYYYY-iMM-iDD',
|
|
10
|
+
lang: 'ar' | 'en' = 'en'
|
|
11
|
+
): string {
|
|
12
|
+
momentHijri.locale(lang);
|
|
13
|
+
return momentHijri(date).format(format);
|
|
14
|
+
}
|
|
15
|
+
}
|