barsa-novin-ray-core 2.3.100 → 2.3.102

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.
@@ -1,6 +1,6 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Injectable, inject, ElementRef, Input, ChangeDetectionStrategy, Component, Pipe, ComponentFactoryResolver, Injector, ApplicationRef, Compiler, DOCUMENT, NgModuleFactory, InjectionToken, NgZone, signal, effect, EventEmitter, ChangeDetectorRef, Renderer2, HostBinding, Output, HostListener, ViewContainerRef, ViewChild, Directive, TemplateRef, input, NgModule, NO_ERRORS_SCHEMA, CUSTOM_ELEMENTS_SCHEMA, provideAppInitializer, ErrorHandler } from '@angular/core';
3
- import { Subject, from, BehaviorSubject, of, exhaustMap, map as map$1, combineLatest, withLatestFrom as withLatestFrom$1, fromEvent, forkJoin, takeUntil as takeUntil$1, filter as filter$1, throwError, merge, interval, lastValueFrom, take, debounceTime as debounceTime$1, skip, Observable, tap as tap$1, catchError as catchError$1, timer, mergeWith, Subscription } from 'rxjs';
2
+ import { Injectable, inject, ElementRef, Input, ChangeDetectionStrategy, Component, Pipe, ComponentFactoryResolver, Injector, ApplicationRef, Compiler, DOCUMENT, NgModuleFactory, InjectionToken, NgZone, signal, EventEmitter, ChangeDetectorRef, Renderer2, HostBinding, Output, HostListener, ViewContainerRef, ViewChild, Directive, TemplateRef, input, NgModule, NO_ERRORS_SCHEMA, CUSTOM_ELEMENTS_SCHEMA, provideAppInitializer, ErrorHandler } from '@angular/core';
3
+ import { Subject, from, BehaviorSubject, of, exhaustMap, map as map$1, combineLatest, withLatestFrom as withLatestFrom$1, fromEvent, forkJoin, takeUntil as takeUntil$1, filter as filter$1, throwError, merge, interval, lastValueFrom, timeout, catchError as catchError$1, take, debounceTime as debounceTime$1, skip, Observable, tap as tap$1, timer, mergeWith, Subscription } from 'rxjs';
4
4
  import * as i1 from '@angular/router';
5
5
  import { Router, NavigationEnd, ActivatedRoute, RouterEvent, NavigationStart, RouterModule } from '@angular/router';
6
6
  import { DomSanitizer, Title } from '@angular/platform-browser';
@@ -4473,6 +4473,8 @@ class FormPanelService extends BaseComponent {
4473
4473
  this._headerDescriptionSource = new BehaviorSubject('');
4474
4474
  this._hideFooter$ = new BehaviorSubject(false);
4475
4475
  this._canSend$ = new BehaviorSubject(false);
4476
+ this._router = inject(Router);
4477
+ this._activatedRoute = inject(ActivatedRoute);
4476
4478
  this.context$ = this._contextSource.asObservable().pipe(tap((context) => this._prepareContext(context)), takeUntil(this._onDestroy$));
4477
4479
  this.searchPanelIsObject$ = this._searchPanelIsObjectSource.asObservable().pipe(takeUntil(this._onDestroy$));
4478
4480
  this.isSearchPanel$ = this._isSearchPanelSource.asObservable().pipe(takeUntil(this._onDestroy$));
@@ -4821,7 +4823,38 @@ class FormPanelService extends BaseComponent {
4821
4823
  }
4822
4824
  _refresh() {
4823
4825
  this._initialize(this._context);
4824
- // this._prepareView(this._context.Setting.View);
4826
+ const mo = this._moSource.getValue();
4827
+ if (!mo) {
4828
+ return;
4829
+ }
4830
+ const breadCrumb = this._headerLayoutSource.getValue();
4831
+ const mainChild = this._activatedRoute.children.find((c) => c.outlet === 'main');
4832
+ const currentParams = mainChild?.snapshot.params ?? {};
4833
+ const queryParamsToUpdate = {
4834
+ id: mo.$State === 'New' ? '0' : mo.Id,
4835
+ tyid: mo.$TypeDefId,
4836
+ tycp: mo.$Caption ? mo.$Caption : null,
4837
+ repid: mo.$ReportId,
4838
+ vid: this._viewSource.getValue()?.TypeViewId,
4839
+ bc: breadCrumb ? breadCrumb : mo.$State === 'New' ? mo.$TypeDefName : mo.$Caption
4840
+ };
4841
+ if (currentParams.id === queryParamsToUpdate.id &&
4842
+ currentParams.tyid === queryParamsToUpdate.tyid &&
4843
+ currentParams.repid === queryParamsToUpdate.repid &&
4844
+ currentParams.vid === queryParamsToUpdate.vid) {
4845
+ return;
4846
+ }
4847
+ const newParams = {
4848
+ ...currentParams,
4849
+ ...queryParamsToUpdate // پارامترهایی که می‌خواهی تغییر دهی
4850
+ };
4851
+ this._router.navigate([
4852
+ {
4853
+ outlets: {
4854
+ main: ['show', newParams]
4855
+ }
4856
+ }
4857
+ ], { relativeTo: this._activatedRoute.parent, skipLocationChange: false });
4825
4858
  }
4826
4859
  _forceClose() {
4827
4860
  this._forceCloseSource.next();
@@ -7836,12 +7869,11 @@ class ServiceWorkerNotificationService {
7836
7869
  this.hasRegistration = false;
7837
7870
  this._swPush = inject(SwPush);
7838
7871
  this._portalService = inject(PortalService);
7839
- this._notificationPermissionAllowed = false;
7840
7872
  this.init();
7841
7873
  }
7842
7874
  // بررسی وضعیت فعلی
7843
7875
  get isEnabled() {
7844
- return this._swPush.isEnabled && this.hasRegistration && this._notificationPermissionAllowed;
7876
+ return this._swPush.isEnabled && this.hasRegistration;
7845
7877
  }
7846
7878
  async closeNotifications(tags) {
7847
7879
  const sw = await this.getSw();
@@ -7897,7 +7929,6 @@ class ServiceWorkerNotificationService {
7897
7929
  }
7898
7930
  async init() {
7899
7931
  console.log(`SwPush enabled: ${this._swPush.isEnabled}`);
7900
- this.handlePermission();
7901
7932
  // مدیریت کلیک روی نوتیفیکیشن‌ها
7902
7933
  this._swPush.notificationClicks.subscribe((e) => {
7903
7934
  if (!e.notification.tag) {
@@ -7912,44 +7943,6 @@ class ServiceWorkerNotificationService {
7912
7943
  // بررسی مجوز و ثبت سرویس‌ورکر
7913
7944
  await this.registerServiceWorker();
7914
7945
  }
7915
- handlePermission() {
7916
- if (!navigator?.permissions?.query) {
7917
- return;
7918
- }
7919
- return navigator.permissions
7920
- .query({ name: 'notifications' })
7921
- .then(this.permissionQuery.bind(this))
7922
- .catch(this.permissionError.bind(this));
7923
- }
7924
- permissionQuery(result) {
7925
- let newPrompt;
7926
- if (result.state === 'granted') {
7927
- console.log('notificaiton granted');
7928
- // notifications allowed, go wild
7929
- }
7930
- else if (result.state === 'prompt') {
7931
- // we can ask the user
7932
- console.log('notificaiton prompt');
7933
- newPrompt = Notification.requestPermission();
7934
- }
7935
- else if (result.state === 'denied') {
7936
- // notifications were disabled
7937
- console.log('notificaiton denied');
7938
- this._notificationPermissionAllowed = false;
7939
- }
7940
- result.onchange = () => console.log({ updatedPermission: result });
7941
- return newPrompt || result;
7942
- }
7943
- permissionError(error) {
7944
- this._notificationPermissionAllowed = false;
7945
- console.error(error);
7946
- }
7947
- async requestPermission() {
7948
- if (Notification.permission === 'default') {
7949
- await Notification.requestPermission();
7950
- }
7951
- this._notificationPermissionAllowed = Notification.permission === 'granted';
7952
- }
7953
7946
  async registerServiceWorker() {
7954
7947
  if (!('serviceWorker' in navigator)) {
7955
7948
  return;
@@ -8208,225 +8201,219 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImpor
8208
8201
  type: Injectable
8209
8202
  }], ctorParameters: () => [] });
8210
8203
 
8211
- class PushCheckService {
8212
- async checkPushReady() {
8213
- if (!this.baseSupport()) {
8214
- return 'مرورگر شما Push API را پشتیبانی نمی‌کند';
8215
- }
8216
- const iosCheck = this.iosSupport();
8217
- if (iosCheck !== true) {
8218
- return iosCheck;
8219
- }
8220
- if (Notification.permission === 'denied') {
8221
- return 'شما قبلاً اجازه نوتیفیکیشن را رد کرده‌اید. از تنظیمات مرورگر آن را فعال کنید';
8222
- }
8223
- const regs = await navigator.serviceWorker.getRegistrations();
8224
- if (!regs.length) {
8225
- return 'Service Worker ثبت نشده است';
8226
- }
8227
- return true;
8228
- }
8229
- getIosVersion() {
8230
- const ua = navigator.userAgent;
8231
- if (/iP(hone|od|ad)/.test(ua)) {
8232
- const v = ua.match(/OS (\d+)_/);
8233
- return v ? parseInt(v[1], 10) : null;
8234
- }
8235
- return null;
8236
- }
8237
- isIosStandalone() {
8238
- return 'standalone' in navigator && navigator.standalone === true;
8204
+ // src/app/services/idb.service.ts
8205
+ class IdbService {
8206
+ constructor() {
8207
+ this.dbPromise = openDB('my-app-db', 1, {
8208
+ upgrade(db) {
8209
+ if (!db.objectStoreNames.contains('subscription')) {
8210
+ db.createObjectStore('subscription');
8211
+ }
8212
+ if (!db.objectStoreNames.contains('settings')) {
8213
+ db.createObjectStore('settings');
8214
+ }
8215
+ }
8216
+ });
8239
8217
  }
8240
- isSafari() {
8241
- const ua = navigator.userAgent.toLowerCase();
8242
- return ua.includes('safari') && !ua.includes('chrome');
8218
+ async get(store, key) {
8219
+ const db = await this.dbPromise;
8220
+ const v = await db.get(store, key);
8221
+ return (v === undefined ? null : v);
8243
8222
  }
8244
- baseSupport() {
8245
- return 'Notification' in window && 'serviceWorker' in navigator && 'PushManager' in window;
8223
+ async set(store, key, value) {
8224
+ const db = await this.dbPromise;
8225
+ await db.put(store, value, key);
8246
8226
  }
8247
- iosSupport() {
8248
- const v = this.getIosVersion();
8249
- if (v && v < 16) {
8250
- return 'نسخه iOS کمتر از 16 است (Push پشتیبانی نمی‌شود)';
8251
- }
8252
- if (v && v < 16.4) {
8253
- return 'iOS باید حداقل نسخه 16.4 باشد تا Push فعال شود';
8254
- }
8255
- if (v && !this.isSafari()) {
8256
- return 'Push فقط در Safari iOS پشتیبانی می‌شود';
8257
- }
8258
- if (v && !this.isIosStandalone()) {
8259
- return 'برای فعال شدن Push، برنامه را با Add to Home Screen نصب کنید';
8260
- }
8261
- return true;
8227
+ async delete(store, key) {
8228
+ const db = await this.dbPromise;
8229
+ await db.delete(store, key);
8262
8230
  }
8263
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: PushCheckService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
8264
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: PushCheckService, providedIn: 'root' }); }
8231
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: IdbService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
8232
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: IdbService, providedIn: 'root' }); }
8265
8233
  }
8266
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: PushCheckService, decorators: [{
8234
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: IdbService, decorators: [{
8267
8235
  type: Injectable,
8268
8236
  args: [{ providedIn: 'root' }]
8269
- }] });
8237
+ }], ctorParameters: () => [] });
8270
8238
 
8271
- /* eslint-disable */
8272
- //
8273
- function usePushNotification() {
8274
- const swPush = inject(SwPush);
8275
- const http = inject(HttpClient);
8276
- const _localStorage = inject(LocalStorageService);
8277
- // Signals
8278
- const bannerVisible = signal(false);
8279
- const isSubscribed = signal(false);
8280
- const permission = signal(Notification.permission);
8281
- const errorMessage = signal(null);
8282
- // IndexedDB setup
8283
- const dbPromise = openDB('push-db', 1, {
8284
- upgrade(db) {
8285
- db.createObjectStore('subscription');
8286
- }
8287
- });
8288
- // ذخیره subscription در DB
8289
- const saveSubscription = async (sub) => {
8290
- const db = await dbPromise;
8291
- await db.put('subscription', sub.toJSON(), 'push-subscription');
8292
- };
8293
- async function initPushBanner() {
8294
- const saved = await loadSubscription();
8295
- if (saved) {
8296
- isSubscribed.set(true);
8297
- bannerVisible.set(false); // قبلاً subscribe شده
8298
- }
8299
- else {
8300
- isSubscribed.set(false);
8301
- bannerVisible.set(true); // هنوز subscribe نشده، بنر نمایش داده شود
8302
- }
8303
- }
8304
- // خواندن subscription از DB
8305
- const loadSubscription = async () => {
8306
- const db = await dbPromise;
8307
- const data = await db.get('subscription', 'push-subscription');
8308
- if (!data) {
8309
- return null;
8310
- }
8311
- // داده را به سرور می‌فرستیم یا UI نشان می‌دهیم
8312
- return data;
8313
- };
8314
- // حذف subscription از DB
8315
- const deleteSubscription = async () => {
8316
- const db = await dbPromise;
8317
- await db.delete('subscription', 'push-subscription');
8318
- };
8319
- const handleNewSubscription = async (subData) => {
8320
- const saved = await loadSubscription();
8321
- if (!saved || saved.endpoint !== subData.endpoint) {
8322
- // حذف قبلی
8323
- if (saved) {
8324
- try {
8325
- await addSubscriptionToServer(saved);
8239
+ class PushNotificationService {
8240
+ constructor() {
8241
+ this.swPush = inject(SwPush);
8242
+ this.http = inject(HttpClient);
8243
+ this.idb = inject(IdbService);
8244
+ this.local = inject(LocalStorageService);
8245
+ // یک سیگنال واحد
8246
+ this._push = signal({
8247
+ bannerVisible: false,
8248
+ isSubscribed: false,
8249
+ permission: Notification.permission,
8250
+ errorMessage: null
8251
+ });
8252
+ this.registerServiceWorkerMessageListener = () => {
8253
+ // avoid adding multiple listeners (idempotent)
8254
+ const onMessage = (event) => {
8255
+ const data = event.data;
8256
+ if (!data) {
8257
+ return;
8326
8258
  }
8327
- catch (e) {
8328
- console.error('Delete old subscription failed', e);
8259
+ if (data.event === 'subscriptionChanged' && data.subscription) {
8260
+ // run async handler but don't await here
8261
+ (async () => {
8262
+ await this.handleNewSubscription(data.subscription);
8263
+ })().catch(console.error);
8329
8264
  }
8265
+ };
8266
+ // addEventListener is idempotent-ish but let's guard by setting property
8267
+ // we attach once on navigator.serviceWorker (not to window)
8268
+ navigator.serviceWorker?.addEventListener('message', onMessage);
8269
+ };
8270
+ }
8271
+ get push() {
8272
+ return this._push.asReadonly();
8273
+ }
8274
+ hideBanner() {
8275
+ this.update({ bannerVisible: false });
8276
+ }
8277
+ async setup() {
8278
+ // Load subscription status
8279
+ await this.initPushBanner();
8280
+ // Listen for subscription updates
8281
+ this.swPush.subscription.subscribe((sub) => {
8282
+ this.update({
8283
+ isSubscribed: !!sub,
8284
+ permission: Notification.permission
8285
+ });
8286
+ if (sub) {
8287
+ const json = sub.toJSON?.() ?? sub;
8288
+ this.handleNewSubscription(json);
8330
8289
  }
8331
- // ثبت جدید
8332
- try {
8333
- await deleteSubscriptionFromServer(subData);
8334
- await saveSubscription(subData);
8335
- isSubscribed.set(true);
8336
- }
8337
- catch (e) {
8338
- console.error('Add new subscription failed', e);
8290
+ });
8291
+ // Listen for SW messages
8292
+ navigator.serviceWorker.addEventListener('message', (event) => {
8293
+ if (event.data?.event === 'subscriptionChanged') {
8294
+ this.handleNewSubscription(event.data.subscription);
8339
8295
  }
8340
- }
8341
- };
8342
- const hideBanner = () => bannerVisible.set(false);
8343
- // بررسی وضعیت فعلی subscription از SwPush و DB
8344
- swPush.subscription.subscribe(async (sub) => {
8345
- isSubscribed.set(!!sub);
8346
- permission.set(Notification.permission);
8347
- if (sub) {
8348
- await handleNewSubscription(sub.toJSON());
8349
- }
8350
- });
8351
- const addSubscriptionToServer = async (sub) => {
8352
- const token2 = _localStorage.getItem(BarsaApi.LoginAction.token2StorageKey) ?? '';
8353
- const options = {
8354
- headers: new HttpHeaders({
8355
- 'Content-Type': 'application/json',
8356
- sth: token2
8357
- })
8358
- };
8359
- await lastValueFrom(http.post('/api/pushnotification/add', sub, options));
8360
- };
8361
- const deleteSubscriptionFromServer = async (sub) => {
8362
- const token2 = _localStorage.getItem(BarsaApi.LoginAction.token2StorageKey) ?? '';
8363
- const options = {
8364
- headers: new HttpHeaders({
8365
- 'Content-Type': 'application/json',
8366
- sth: token2
8367
- })
8368
- };
8369
- await lastValueFrom(http.post('/api/pushnotification/delete', sub, options));
8370
- };
8371
- // subscribe فقط داخل gesture
8372
- const subscribe = async () => {
8296
+ });
8297
+ }
8298
+ async subscribe() {
8299
+ this.update({
8300
+ bannerVisible: false
8301
+ });
8373
8302
  try {
8374
- const publicKey = await lastValueFrom(http.get('/api/pushnotification/publickey', { responseType: 'text' }));
8375
- const sub = await swPush.requestSubscription({ serverPublicKey: publicKey });
8376
- const registration = await navigator.serviceWorker.ready;
8377
- registration.active?.postMessage({ event: 'setVapidKey', publicKey });
8378
- await addSubscriptionToServer(sub);
8379
- await saveSubscription(sub);
8380
- isSubscribed.set(true);
8381
- permission.set(Notification.permission);
8382
- bannerVisible.set(false);
8383
- errorMessage.set(null);
8303
+ const publicKey = await lastValueFrom(this.http.get('/api/pushnotification/publickey', { responseType: 'text' }));
8304
+ await this.idb.set('settings', 'vapid-public-key', publicKey);
8305
+ const sub = await this.swPush.requestSubscription({ serverPublicKey: publicKey });
8306
+ await lastValueFrom(this.http.post('/api/pushnotification/add', sub, this.httpOptions()));
8307
+ await this.idb.set('subscription', 'push-subscription', sub.toJSON());
8308
+ this.update({
8309
+ isSubscribed: true,
8310
+ permission: Notification.permission,
8311
+ bannerVisible: false,
8312
+ errorMessage: null
8313
+ });
8384
8314
  return sub;
8385
8315
  }
8386
8316
  catch (err) {
8387
- console.error('Push subscribe error:', err);
8388
- errorMessage.set(err?.message || 'خطا در فعال‌سازی Push');
8317
+ this.update({ errorMessage: err.message ?? 'خطا در فعال‌سازی اعلان', bannerVisible: true });
8389
8318
  throw err;
8390
8319
  }
8391
- };
8392
- const unsubscribe = async () => {
8320
+ }
8321
+ async unsubscribe() {
8393
8322
  try {
8394
- const sub = await lastValueFrom(swPush.subscription);
8323
+ const sub = await lastValueFrom(this.swPush.subscription.pipe(timeout(500), // اگر در 500ms چیزی نداد
8324
+ catchError$1(() => of(null)) // مقدار null برگردان
8325
+ ));
8395
8326
  if (!sub) {
8396
8327
  return;
8397
8328
  }
8398
- swPush.unsubscribe();
8399
- await deleteSubscriptionFromServer(sub);
8329
+ const json = sub.toJSON();
8330
+ await lastValueFrom(this.http.post('/api/pushnotification/delete', json, this.httpOptions()));
8400
8331
  await sub.unsubscribe();
8401
- await deleteSubscription();
8402
- isSubscribed.set(false);
8403
- errorMessage.set(null);
8332
+ await this.deleteSubscription();
8333
+ this.update({ isSubscribed: false, errorMessage: null });
8404
8334
  }
8405
8335
  catch (err) {
8406
- console.error('Push unsubscribe error:', err);
8407
- errorMessage.set(err?.message || 'خطا در لغو اشتراک');
8336
+ this.update({ errorMessage: err.message ?? 'خطا در لغو اشتراک' });
8408
8337
  }
8409
- };
8410
- return {
8411
- bannerVisible,
8412
- isSubscribed,
8413
- permission,
8414
- errorMessage,
8415
- initPushBanner,
8416
- subscribe,
8417
- unsubscribe,
8418
- handleNewSubscription,
8419
- hideBanner
8420
- };
8338
+ }
8339
+ async handleNewSubscription(subData) {
8340
+ const saved = await this.idb.get('subscription', 'push-subscription');
8341
+ if (!saved || saved.endpoint !== subData.endpoint) {
8342
+ if (saved) {
8343
+ await lastValueFrom(this.http.post('/api/pushnotification/delete', saved, this.httpOptions()));
8344
+ }
8345
+ await lastValueFrom(this.http.post('/api/pushnotification/add', subData, this.httpOptions()));
8346
+ await this.idb.set('subscription', 'push-subscription', subData);
8347
+ }
8348
+ this.update({
8349
+ isSubscribed: true,
8350
+ permission: Notification.permission,
8351
+ errorMessage: null
8352
+ });
8353
+ }
8354
+ update(values) {
8355
+ this._push.update((prev) => ({ ...prev, ...values }));
8356
+ }
8357
+ async loadSubscription() {
8358
+ return await this.idb.get('subscription', 'push-subscription');
8359
+ }
8360
+ async loadPublicKey() {
8361
+ return await this.idb.get('settings', 'vapid-public-key');
8362
+ }
8363
+ async initPushBanner() {
8364
+ let saved = await this.loadSubscription();
8365
+ const perm = Notification.permission;
8366
+ this.update({
8367
+ permission: perm
8368
+ });
8369
+ if (saved) {
8370
+ // اگر پرمیشن اکنون revoked یا default شد، subscription قبلی را حذف کن
8371
+ if (perm === 'default' || perm === 'denied') {
8372
+ console.log('Permission reset detected, removing old subscription');
8373
+ await this.deleteSubscription();
8374
+ saved = null;
8375
+ }
8376
+ }
8377
+ if (saved) {
8378
+ this.update({
8379
+ isSubscribed: true,
8380
+ bannerVisible: false
8381
+ });
8382
+ }
8383
+ else {
8384
+ this.update({
8385
+ isSubscribed: false,
8386
+ bannerVisible: perm !== 'denied' && 'PushManager' in window
8387
+ });
8388
+ }
8389
+ this.registerServiceWorkerMessageListener();
8390
+ const publicKey = await this.loadPublicKey();
8391
+ if (publicKey) {
8392
+ const reg = await navigator.serviceWorker.ready;
8393
+ reg.active?.postMessage({ event: 'setVapidKey', publicKey });
8394
+ }
8395
+ }
8396
+ async deleteSubscription() {
8397
+ await this.idb.delete('subscription', 'push-subscription');
8398
+ }
8399
+ httpOptions() {
8400
+ const token2 = this.local.getItem(BarsaApi.LoginAction.token2StorageKey) ?? '';
8401
+ return { headers: new HttpHeaders({ 'Content-Type': 'application/json', sth: token2 }) };
8402
+ }
8403
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: PushNotificationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
8404
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: PushNotificationService, providedIn: 'root' }); }
8421
8405
  }
8406
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: PushNotificationService, decorators: [{
8407
+ type: Injectable,
8408
+ args: [{ providedIn: 'root' }]
8409
+ }] });
8422
8410
 
8423
8411
  class ServiceWorkerCommuncationService {
8424
8412
  constructor() {
8425
8413
  this._toastService = inject(TOAST_SERVICE, { optional: true });
8426
8414
  this._localStorage = inject(LocalStorageService);
8427
8415
  this._portalService = inject(PortalService);
8428
- this._pushCheckService = inject(PushCheckService);
8429
- this._usePushNotification = usePushNotification();
8416
+ this._pushNotificatioService = inject(PushNotificationService);
8430
8417
  }
8431
8418
  get token2() {
8432
8419
  return this._localStorage.getItem(BarsaApi.LoginAction.token2StorageKey) ?? '';
@@ -8442,7 +8429,7 @@ class ServiceWorkerCommuncationService {
8442
8429
  this._serviceWorker = reg.active;
8443
8430
  navigator.serviceWorker.addEventListener('message', (event) => {
8444
8431
  if (event.data?.event === 'subscriptionChanged') {
8445
- this._usePushNotification.handleNewSubscription(event.data.subscription);
8432
+ this._pushNotificatioService.handleNewSubscription(event.data.subscription);
8446
8433
  }
8447
8434
  });
8448
8435
  }
@@ -8451,35 +8438,6 @@ class ServiceWorkerCommuncationService {
8451
8438
  BarsaApi.Ul.ApplicationCtrlr.on({
8452
8439
  UserLoggedout: (_, doReturn) => this._handlePushUnSubscription(doReturn)
8453
8440
  });
8454
- // automatic effect: update operationName based on subscription
8455
- effect(() => {
8456
- const sub = this._usePushNotification.isSubscribed();
8457
- // اینجا می‌تونی متغیر operationName یا UI رو اتوماتیک آپدیت کنی
8458
- console.log('Push subscription changed:', sub);
8459
- });
8460
- // automatic effect: show toast on errors
8461
- effect(() => {
8462
- const err = this._usePushNotification.errorMessage();
8463
- if (err) {
8464
- this.toast(err);
8465
- }
8466
- });
8467
- }
8468
- // فعال‌سازی push توسط gesture (مثلاً از UI)
8469
- async subscribePush() {
8470
- try {
8471
- const check = await this._pushCheckService.checkPushReady();
8472
- if (check !== true) {
8473
- this.toast(check);
8474
- return;
8475
- }
8476
- await this._usePushNotification.subscribe();
8477
- this.toast('نوتیفیکیشن فعال شد');
8478
- }
8479
- catch (err) {
8480
- console.error(err);
8481
- this.toast('خطا در فعال‌سازی Push');
8482
- }
8483
8441
  }
8484
8442
  _subscribe() {
8485
8443
  this._portalService.userLoggedIn$.pipe().subscribe((isLoggedIn) => this._isLoggedIn(isLoggedIn));
@@ -8497,7 +8455,7 @@ class ServiceWorkerCommuncationService {
8497
8455
  this._postServiceWorker({ event: 'isLoggedInChange', options: { isLoggedIn } });
8498
8456
  if (isLoggedIn) {
8499
8457
  this._setDefaultOptions();
8500
- this._usePushNotification.initPushBanner();
8458
+ this._pushNotificatioService.setup();
8501
8459
  }
8502
8460
  }
8503
8461
  _visibilitychange(documentIsHidden) {
@@ -8513,7 +8471,7 @@ class ServiceWorkerCommuncationService {
8513
8471
  }
8514
8472
  // لغو push (هر زمان امکان‌پذیر است)
8515
8473
  _handlePushUnSubscription(doReturn) {
8516
- this._usePushNotification.unsubscribe().finally(() => doReturn && doReturn());
8474
+ this._pushNotificatioService.unsubscribe().finally(() => doReturn && doReturn());
8517
8475
  }
8518
8476
  toast(msg) {
8519
8477
  if (!this._toastService) {
@@ -8697,6 +8655,66 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImpor
8697
8655
  args: [{ providedIn: 'root' }]
8698
8656
  }], ctorParameters: () => [] });
8699
8657
 
8658
+ class PushCheckService {
8659
+ async checkPushReady() {
8660
+ if (!this.baseSupport()) {
8661
+ return 'مرورگر شما Push API را پشتیبانی نمی‌کند';
8662
+ }
8663
+ const iosCheck = this.iosSupport();
8664
+ if (iosCheck !== true) {
8665
+ return iosCheck;
8666
+ }
8667
+ if (Notification.permission === 'denied') {
8668
+ return 'شما قبلاً اجازه نوتیفیکیشن را رد کرده‌اید. از تنظیمات مرورگر آن را فعال کنید';
8669
+ }
8670
+ const regs = await navigator.serviceWorker.getRegistrations();
8671
+ if (!regs.length) {
8672
+ return 'Service Worker ثبت نشده است';
8673
+ }
8674
+ return true;
8675
+ }
8676
+ getIosVersion() {
8677
+ const ua = navigator.userAgent;
8678
+ if (/iP(hone|od|ad)/.test(ua)) {
8679
+ const v = ua.match(/OS (\d+)_/);
8680
+ return v ? parseInt(v[1], 10) : null;
8681
+ }
8682
+ return null;
8683
+ }
8684
+ isIosStandalone() {
8685
+ return 'standalone' in navigator && navigator.standalone === true;
8686
+ }
8687
+ isSafari() {
8688
+ const ua = navigator.userAgent.toLowerCase();
8689
+ return ua.includes('safari') && !ua.includes('chrome');
8690
+ }
8691
+ baseSupport() {
8692
+ return 'Notification' in window && 'serviceWorker' in navigator && 'PushManager' in window;
8693
+ }
8694
+ iosSupport() {
8695
+ const v = this.getIosVersion();
8696
+ if (v && v < 16) {
8697
+ return 'نسخه iOS کمتر از 16 است (Push پشتیبانی نمی‌شود)';
8698
+ }
8699
+ if (v && v < 16.4) {
8700
+ return 'iOS باید حداقل نسخه 16.4 باشد تا Push فعال شود';
8701
+ }
8702
+ if (v && !this.isSafari()) {
8703
+ return 'Push فقط در Safari iOS پشتیبانی می‌شود';
8704
+ }
8705
+ if (v && !this.isIosStandalone()) {
8706
+ return 'برای فعال شدن Push، برنامه را با Add to Home Screen نصب کنید';
8707
+ }
8708
+ return true;
8709
+ }
8710
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: PushCheckService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
8711
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: PushCheckService, providedIn: 'root' }); }
8712
+ }
8713
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: PushCheckService, decorators: [{
8714
+ type: Injectable,
8715
+ args: [{ providedIn: 'root' }]
8716
+ }] });
8717
+
8700
8718
  class FieldBaseComponent extends BaseComponent {
8701
8719
  get customFieldInfo() {
8702
8720
  return this.context.Setting.CustomFieldInfo;
@@ -11165,8 +11183,8 @@ class FormComponent extends BaseComponent {
11165
11183
  const currVal = JSON.stringify(params.currentValue);
11166
11184
  const prevVal = JSON.stringify(params.previousValue);
11167
11185
  if (currVal !== prevVal) {
11168
- this.vcr.clear();
11169
- this.appendForm(currVal);
11186
+ // this.vcr.clear();
11187
+ // this.appendForm(currVal);
11170
11188
  }
11171
11189
  }
11172
11190
  }
@@ -13213,49 +13231,77 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImpor
13213
13231
  args: [{ selector: 'bnrc-unlimit-session', changeDetection: ChangeDetectionStrategy.OnPush, standalone: false, template: "", styles: [":host{background:#191919 -webkit-linear-gradient(top,#000 0%,#191919 100%) no-repeat;background:#191919 linear-gradient(to bottom,#000,#191919) no-repeat;text-align:center}:host h1,:host h2{font-weight:400}:host h1{margin:0 auto;padding:.15em;font-size:10em;text-shadow:0 2px 2px #000}:host h2{margin-bottom:2em}\n"] }]
13214
13232
  }] });
13215
13233
 
13216
- class PushBannerComponent {
13234
+ class PushBannerComponent extends BaseComponent {
13217
13235
  constructor() {
13218
- this.push = usePushNotification();
13236
+ super();
13237
+ this._pushService = inject(PushNotificationService);
13238
+ this.push = this._pushService.push;
13239
+ }
13240
+ get bannerPositionClass() {
13241
+ const userAgent = navigator.userAgent;
13242
+ const isMobile = /Android|iPhone|iPad|iPod/i.test(userAgent);
13243
+ if (!isMobile) {
13244
+ // دسکتاپ: بالا، راست/چپ
13245
+ return 'position-desktop';
13246
+ }
13247
+ const isAndroid = /Android/i.test(userAgent);
13248
+ const isIOS = /iPhone|iPad|iPod/i.test(userAgent);
13249
+ if (isAndroid) {
13250
+ // موبایل اندروید: بالا
13251
+ return 'position-android-top';
13252
+ }
13253
+ if (isIOS) {
13254
+ // موبایل iOS: پایین (برای جلوگیری از تداخل با نوار آدرس Safari/Chrome)
13255
+ return 'position-ios-bottom';
13256
+ }
13257
+ // پیش‌فرض برای هر موبایل دیگر
13258
+ return 'position-ios-bottom';
13259
+ }
13260
+ onHideBanner() {
13261
+ this._pushService.hideBanner();
13262
+ }
13263
+ onEnable() {
13264
+ this._pushService.subscribe();
13219
13265
  }
13220
13266
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: PushBannerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
13221
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.6", type: PushBannerComponent, isStandalone: false, selector: "bnrc-push-banner", ngImport: i0, template: `
13222
- @if(push.bannerVisible()){
13223
- <div class="push-banner">
13267
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.6", type: PushBannerComponent, isStandalone: false, selector: "bnrc-push-banner", usesInheritance: true, ngImport: i0, template: `
13268
+ @if(push().bannerVisible){
13269
+ <div class="push-banner" [ngClass]="bannerPositionClass">
13224
13270
  <div class="text">
13225
13271
  <b>فعال‌سازی اعلان‌ها</b>
13226
13272
  <p>برای دریافت پیام‌ها و رویدادهای مهم، اعلان‌ها را فعال کنید.</p>
13227
13273
  </div>
13228
13274
  <div class="actions">
13229
- <button class="btn enable" (click)="push.subscribe()">فعال‌سازی</button>
13230
- <button class="btn later" (click)="push.hideBanner()">بعداً</button>
13275
+ <button class="btn enable" (click)="onEnable()">فعال‌سازی</button>
13276
+ <button class="btn later" (click)="onHideBanner()">بعداً</button>
13231
13277
  </div>
13232
- @if(push.errorMessage()){
13233
- <p class="error">{{ push.errorMessage() }}</p>
13278
+ @if(push().errorMessage){
13279
+ <p class="error">{{ push().errorMessage }}</p>
13234
13280
  }
13235
13281
  </div>
13236
13282
  }
13237
- `, isInline: true, styles: [".push-banner{position:fixed;bottom:0;left:0;right:0;background:#fff;border-radius:12px 12px 0 0;box-shadow:0 -4px 16px #00000026;padding:16px;display:flex;flex-direction:column;gap:8px;z-index:9999}.actions{display:flex;gap:8px}.btn.enable{background:#25d366;color:#fff;border-radius:8px;padding:8px 12px;border:none}.btn.later{background:transparent;color:#666;border:none;padding:8px 12px}.error{color:red;font-size:13px}\n"] }); }
13283
+ `, isInline: true, styles: [".push-banner{position:fixed;left:0;right:0;font-family:var(--sapFontFamily);background:#fff;border-radius:12px 12px 0 0;box-shadow:0 -4px 16px #00000026;padding:16px;display:flex;flex-direction:column;gap:8px;z-index:9999}.actions{display:flex;gap:8px}.btn.enable{background:#25d366;color:#fff;border-radius:8px;padding:8px 12px;border:none}.btn.later{background:transparent;color:#666;border:none;padding:8px 12px}.error{color:red;font-size:13px}.position-ios-bottom{bottom:0;top:auto;border-radius:12px 12px 0 0}.position-android-top{top:0;bottom:auto;border-radius:0 0 12px 12px}.position-desktop{inset:20px 20px auto auto;width:320px;max-width:90%;border-radius:8px}\n"], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
13238
13284
  }
13239
13285
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: PushBannerComponent, decorators: [{
13240
13286
  type: Component,
13241
- args: [{ selector: 'bnrc-push-banner', standalone: false, template: `
13242
- @if(push.bannerVisible()){
13243
- <div class="push-banner">
13287
+ args: [{ selector: 'bnrc-push-banner', standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, template: `
13288
+ @if(push().bannerVisible){
13289
+ <div class="push-banner" [ngClass]="bannerPositionClass">
13244
13290
  <div class="text">
13245
13291
  <b>فعال‌سازی اعلان‌ها</b>
13246
13292
  <p>برای دریافت پیام‌ها و رویدادهای مهم، اعلان‌ها را فعال کنید.</p>
13247
13293
  </div>
13248
13294
  <div class="actions">
13249
- <button class="btn enable" (click)="push.subscribe()">فعال‌سازی</button>
13250
- <button class="btn later" (click)="push.hideBanner()">بعداً</button>
13295
+ <button class="btn enable" (click)="onEnable()">فعال‌سازی</button>
13296
+ <button class="btn later" (click)="onHideBanner()">بعداً</button>
13251
13297
  </div>
13252
- @if(push.errorMessage()){
13253
- <p class="error">{{ push.errorMessage() }}</p>
13298
+ @if(push().errorMessage){
13299
+ <p class="error">{{ push().errorMessage }}</p>
13254
13300
  }
13255
13301
  </div>
13256
13302
  }
13257
- `, styles: [".push-banner{position:fixed;bottom:0;left:0;right:0;background:#fff;border-radius:12px 12px 0 0;box-shadow:0 -4px 16px #00000026;padding:16px;display:flex;flex-direction:column;gap:8px;z-index:9999}.actions{display:flex;gap:8px}.btn.enable{background:#25d366;color:#fff;border-radius:8px;padding:8px 12px;border:none}.btn.later{background:transparent;color:#666;border:none;padding:8px 12px}.error{color:red;font-size:13px}\n"] }]
13258
- }] });
13303
+ `, styles: [".push-banner{position:fixed;left:0;right:0;font-family:var(--sapFontFamily);background:#fff;border-radius:12px 12px 0 0;box-shadow:0 -4px 16px #00000026;padding:16px;display:flex;flex-direction:column;gap:8px;z-index:9999}.actions{display:flex;gap:8px}.btn.enable{background:#25d366;color:#fff;border-radius:8px;padding:8px 12px;border:none}.btn.later{background:transparent;color:#666;border:none;padding:8px 12px}.error{color:red;font-size:13px}.position-ios-bottom{bottom:0;top:auto;border-radius:12px 12px 0 0}.position-android-top{top:0;bottom:auto;border-radius:0 0 12px 12px}.position-desktop{inset:20px 20px auto auto;width:320px;max-width:90%;border-radius:8px}\n"] }]
13304
+ }], ctorParameters: () => [] });
13259
13305
 
13260
13306
  class LoadExternalFilesDirective {
13261
13307
  constructor() {
@@ -17118,7 +17164,8 @@ const services = [
17118
17164
  BbbTranslatePipe,
17119
17165
  BarsaStorageService,
17120
17166
  ServiceWorkerCommuncationService,
17121
- ApplicationCtrlrService
17167
+ ApplicationCtrlrService,
17168
+ PushNotificationService
17122
17169
  ];
17123
17170
  const pipes = [
17124
17171
  NumeralPipe,
@@ -17571,5 +17618,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImpor
17571
17618
  * Generated bundle index. Do not edit.
17572
17619
  */
17573
17620
 
17574
- export { APP_VERSION, AbsoluteDivBodyDirective, AddDynamicFormStyles, AffixRespondEvents, AllFilesMimeType, AnchorScrollDirective, ApiService, ApplicationBaseComponent, ApplicationCtrlrService, AttrRtlDirective, AudioMimeType, AudioRecordingService, AuthGuard, BarsaApi, BarsaDialogService, BarsaIconDictPipe, BarsaNovinRayCoreModule, BarsaReadonlyDirective, BarsaSapUiFormPageModule, BarsaStorageService, BaseColumnPropsComponent, BaseComponent, BaseController, BaseDirective, BaseDynamicComponent, BaseFormToolbaritemPropsComponent, BaseItemContentPropsComponent, BaseModule, BaseReportModel, BaseUlvSettingComponent, BaseViewContentPropsComponent, BaseViewItemPropsComponent, BaseViewPropsComponent, BbbTranslatePipe, BodyClickDirective, BoolControlInfoModel, BreadcrumbService, ButtonLoadingComponent, CalculateControlInfoModel, CanUploadFilePipe, CardMediaSizePipe, ChangeLayoutInfoCustomUi, ChunkArrayPipe, CodeEditorControlInfoModel, ColSetting, ColumnCustomComponentPipe, ColumnCustomUiPipe, ColumnIconPipe, ColumnResizerDirective, ColumnService, ColumnValueDirective, ColumnValueOfParametersPipe, ColumnValuePipe, ComboRowImagePipe, CommandControlInfoModel, ContainerComponent, ContainerService, ContextMenuPipe, ControlUiPipe, ConvertToStylePipe, CopyDirective, CountDownDirective, CustomCommand, CustomInjector, CustomRouteReuseStategy, DIALOG_SERVICE, DateHijriService, DateMiladiService, DateRanges, DateService, DateShamsiService, DateTimeControlInfoModel, DeviceWidth, DialogParams, DynamicCommandDirective, DynamicComponentService, DynamicDarkColorPipe, DynamicFormComponent, DynamicFormToolbaritemComponent, DynamicItemComponent, DynamicLayoutComponent, DynamicRootVariableDirective, DynamicStyleDirective, DynamicTileGroupComponent, EllapsisTextDirective, EllipsifyDirective, EmptyPageComponent, EmptyPageWithRouterAndRouterOutletComponent, EnumControlInfoModel, ExecuteDynamicCommand, ExecuteWorkflowChoiceDef, FORM_DIALOG_COMPONENT, FieldBaseComponent, FieldDirective, FieldInfoTypeEnum, FieldUiComponent, FileControlInfoModel, FileInfoCountPipe, FilePictureInfoModel, FilesValidationHelper, FillAllLayoutControls, FillEmptySpaceDirective, FilterColumnsByDetailsPipe, FilterInlineActionListPipe, FilterPipe, FilterStringPipe, FilterTabPipe, FilterToolbarControlPipe, FilterWorkflowInMobilePipe, FindColumnByDbNamePipe, FindGroup, FindLayoutSettingFromLayout94, FindPreviewColumnPipe, FindToolbarItem, FioriIconPipe, FormBaseComponent, FormCloseDirective, FormComponent, FormFieldReportPageComponent, FormNewComponent, FormPageBaseComponent, FormPageComponent, FormPanelService, FormPropsBaseComponent, FormService, FormToolbarBaseComponent, GaugeControlInfoModel, GeneralControlInfoModel, GetAllColumnsSorted, GetAllHorizontalFromLayout94, GetDefaultMoObjectInfo, GetImgTags, GetVisibleValue, GridSetting, GroupBy, GroupByPipe, GroupByService, HeaderFacetValuePipe, HideAcceptCancelButtonsPipe, HideColumnsInmobilePipe, HistoryControlInfoModel, HorizontalLayoutService, HorizontalResponsiveDirective, IconControlInfoModel, ImageLazyDirective, ImageMimeType, ImagetoPrint, InMemoryStorageService, IndexedDbService, InputNumber, IntersectionObserverDirective, IntersectionStatus, IsDarkMode, IsExpandedNodePipe, IsImagePipe, ItemsRendererDirective, LabelStarTrimPipe, LabelmandatoryDirective, LayoutItemBaseComponent, LayoutMainContentService, LayoutPanelBaseComponent, LayoutService, LeafletLongPressDirective, LinearListControlInfoModel, LinearListHelper, ListCountPipe, ListRelationModel, LoadExternalFilesDirective, LocalStorageService, LogService, LoginSettingsResolver, MapToChatMessagePipe, MasterDetailsPageComponent, MeasureFormTitleWidthDirective, MergeFieldsToColumnsPipe, MetaobjectDataModel, MetaobjectRelationModel, MoForReportModel, MoForReportModelBase, MoInfoUlvMoListPipe, MoInfoUlvPagingPipe, MoReportValueConcatPipe, MoReportValuePipe, MoValuePipe, MobileDirective, ModalRootComponent, MultipleGroupByPipe, NOTIFICATAION_POPUP_SERVER, NOTIFICATION_WEBWORKER_FACTORY, NetworkStatusService, NotFoundComponent, NotificationService, NowraptextDirective, NumberBaseComponent, NumberControlInfoModel, NumbersOnlyInputDirective, NumeralPipe, OverflowTextDirective, PageBaseComponent, PageWithFormHandlerBaseComponent, PdfMimeType, PictureFieldSourcePipe, PictureFileControlInfoModel, PlaceHolderDirective, PortalDynamicPageResolver, PortalFormPageResolver, PortalPageComponent, PortalPageResolver, PortalPageSidebarComponent, PortalReportPageResolver, PortalService, PreventDefaulEvent, PreventDefaultDirective, PrintFilesDirective, PrintImage, PromptUpdateService, PushBannerComponent, PushCheckService, RabetehAkseTakiListiControlInfoModel, RedirectHomeGuard, RedirectReportNavigatorCommandComponent, RelatedReportControlInfoModel, RelationListControlInfoModel, RemoveDynamicFormStyles, RemoveNewlinePipe, RenderUlvDirective, RenderUlvPaginDirective, RenderUlvViewerDirective, ReplacePipe, ReportBaseComponent, ReportBaseInfo, ReportCalendarModel, ReportContainerComponent, ReportExtraInfo, ReportField, ReportFormModel, ReportItemBaseComponent, ReportListModel, ReportModel, ReportTreeModel, ReportViewBaseComponent, ReportViewColumn, ResizableComponent, ResizableDirective, ResizableModule, ResizeHandlerDirective, ResizeObserverDirective, ReversePipe, RichStringControlInfoModel, RootPageComponent, RootPortalComponent, RouteFormChangeDirective, RoutingService, RowDataOption, RowNumberPipe, SafeBottomDirective, SanitizeTextPipe, SaveImageDirective, SaveImageToFile, SaveScrollPositionService, ScrollPersistDirective, ScrollToSelectedDirective, SelectionMode, SeperatorFixPipe, ServiceWorkerCommuncationService, ServiceWorkerNotificationService, ShellbarHeightService, ShortcutHandlerDirective, ShortcutRegisterDirective, SimplebarDirective, SingleRelationControlInfoModel, SortDirection, SortPipe, SortSetting, SplideSliderDirective, SplitPipe, StopPropagationDirective, StringControlInfoModel, StringToNumberPipe, SubformControlInfoModel, SystemBaseComponent, TOAST_SERVICE, TableHeaderWidthMode, TableResizerDirective, TabpageService, ThImageOrIconePipe, TileGroupBreadcrumResolver, TilePropsComponent, TlbButtonsPipe, ToolbarSettingsPipe, TooltipDirective, TotalSummaryPipe, UiService, UlvCommandDirective, UlvMainService, UnlimitSessionComponent, UntilInViewDirective, UploadService, VideoMimeType, VideoRecordingService, ViewBase, VisibleValuePipe, WebOtpDirective, WordMimeType, WorfkflowwChoiceCommandDirective, addCssVariableToRoot, availablePrefixes, calcContextMenuWidth, calculateColumnContent, calculateColumnWidth, calculateColumnWidthFitToContainer, calculateFreeColumnSize, calculateMoDataListContentWidthByColumnName, cancelRequestAnimationFrame, createFormPanelMetaConditions, createGridEditorFormPanel, easeInOutCubic, elementInViewport2, enumValueToStringSize, executeUlvCommandHandler, flattenTree, forbiddenValidator, formRoutes, formatBytes, fromEntries, fromIntersectionObserver, genrateInlineMoId, getAllItemsPerChildren, getColumnValueOfMoDataList, getComponentDefined, getControlList, getControlSizeMode, getDateService, getDeviceIsDesktop, getDeviceIsMobile, getDeviceIsPhone, getDeviceIsTablet, getFieldValue, getFocusableTagNames, getFormSettings, getGridSettings, getHeaderValue, getIcon, getImagePath, getLabelWidth, getLayout94ObjectInfo, getLayoutControl, getNewMoGridEditor, getParentHeight, getRequestAnimationFrame, getResetGridSettings, getTargetRect, getUniqueId, getValidExtension, isFF, isFirefox, isFunction, isImage, isInLocalMode, isSafari, isTargetWindow, measureText, measureText2, measureTextBy, mobile_regex, nullOrUndefinedString, number_only, requestAnimationFramePolyfill, setColumnWidthByMaxMoContentWidth, setOneDepthLevel, setTableThWidth, shallowEqual, stopPropagation, throwIfAlreadyLoaded, toNumber, usePushNotification, validateAllFormFields };
17621
+ export { APP_VERSION, AbsoluteDivBodyDirective, AddDynamicFormStyles, AffixRespondEvents, AllFilesMimeType, AnchorScrollDirective, ApiService, ApplicationBaseComponent, ApplicationCtrlrService, AttrRtlDirective, AudioMimeType, AudioRecordingService, AuthGuard, BarsaApi, BarsaDialogService, BarsaIconDictPipe, BarsaNovinRayCoreModule, BarsaReadonlyDirective, BarsaSapUiFormPageModule, BarsaStorageService, BaseColumnPropsComponent, BaseComponent, BaseController, BaseDirective, BaseDynamicComponent, BaseFormToolbaritemPropsComponent, BaseItemContentPropsComponent, BaseModule, BaseReportModel, BaseUlvSettingComponent, BaseViewContentPropsComponent, BaseViewItemPropsComponent, BaseViewPropsComponent, BbbTranslatePipe, BodyClickDirective, BoolControlInfoModel, BreadcrumbService, ButtonLoadingComponent, CalculateControlInfoModel, CanUploadFilePipe, CardMediaSizePipe, ChangeLayoutInfoCustomUi, ChunkArrayPipe, CodeEditorControlInfoModel, ColSetting, ColumnCustomComponentPipe, ColumnCustomUiPipe, ColumnIconPipe, ColumnResizerDirective, ColumnService, ColumnValueDirective, ColumnValueOfParametersPipe, ColumnValuePipe, ComboRowImagePipe, CommandControlInfoModel, ContainerComponent, ContainerService, ContextMenuPipe, ControlUiPipe, ConvertToStylePipe, CopyDirective, CountDownDirective, CustomCommand, CustomInjector, CustomRouteReuseStategy, DIALOG_SERVICE, DateHijriService, DateMiladiService, DateRanges, DateService, DateShamsiService, DateTimeControlInfoModel, DeviceWidth, DialogParams, DynamicCommandDirective, DynamicComponentService, DynamicDarkColorPipe, DynamicFormComponent, DynamicFormToolbaritemComponent, DynamicItemComponent, DynamicLayoutComponent, DynamicRootVariableDirective, DynamicStyleDirective, DynamicTileGroupComponent, EllapsisTextDirective, EllipsifyDirective, EmptyPageComponent, EmptyPageWithRouterAndRouterOutletComponent, EnumControlInfoModel, ExecuteDynamicCommand, ExecuteWorkflowChoiceDef, FORM_DIALOG_COMPONENT, FieldBaseComponent, FieldDirective, FieldInfoTypeEnum, FieldUiComponent, FileControlInfoModel, FileInfoCountPipe, FilePictureInfoModel, FilesValidationHelper, FillAllLayoutControls, FillEmptySpaceDirective, FilterColumnsByDetailsPipe, FilterInlineActionListPipe, FilterPipe, FilterStringPipe, FilterTabPipe, FilterToolbarControlPipe, FilterWorkflowInMobilePipe, FindColumnByDbNamePipe, FindGroup, FindLayoutSettingFromLayout94, FindPreviewColumnPipe, FindToolbarItem, FioriIconPipe, FormBaseComponent, FormCloseDirective, FormComponent, FormFieldReportPageComponent, FormNewComponent, FormPageBaseComponent, FormPageComponent, FormPanelService, FormPropsBaseComponent, FormService, FormToolbarBaseComponent, GaugeControlInfoModel, GeneralControlInfoModel, GetAllColumnsSorted, GetAllHorizontalFromLayout94, GetDefaultMoObjectInfo, GetImgTags, GetVisibleValue, GridSetting, GroupBy, GroupByPipe, GroupByService, HeaderFacetValuePipe, HideAcceptCancelButtonsPipe, HideColumnsInmobilePipe, HistoryControlInfoModel, HorizontalLayoutService, HorizontalResponsiveDirective, IconControlInfoModel, IdbService, ImageLazyDirective, ImageMimeType, ImagetoPrint, InMemoryStorageService, IndexedDbService, InputNumber, IntersectionObserverDirective, IntersectionStatus, IsDarkMode, IsExpandedNodePipe, IsImagePipe, ItemsRendererDirective, LabelStarTrimPipe, LabelmandatoryDirective, LayoutItemBaseComponent, LayoutMainContentService, LayoutPanelBaseComponent, LayoutService, LeafletLongPressDirective, LinearListControlInfoModel, LinearListHelper, ListCountPipe, ListRelationModel, LoadExternalFilesDirective, LocalStorageService, LogService, LoginSettingsResolver, MapToChatMessagePipe, MasterDetailsPageComponent, MeasureFormTitleWidthDirective, MergeFieldsToColumnsPipe, MetaobjectDataModel, MetaobjectRelationModel, MoForReportModel, MoForReportModelBase, MoInfoUlvMoListPipe, MoInfoUlvPagingPipe, MoReportValueConcatPipe, MoReportValuePipe, MoValuePipe, MobileDirective, ModalRootComponent, MultipleGroupByPipe, NOTIFICATAION_POPUP_SERVER, NOTIFICATION_WEBWORKER_FACTORY, NetworkStatusService, NotFoundComponent, NotificationService, NowraptextDirective, NumberBaseComponent, NumberControlInfoModel, NumbersOnlyInputDirective, NumeralPipe, OverflowTextDirective, PageBaseComponent, PageWithFormHandlerBaseComponent, PdfMimeType, PictureFieldSourcePipe, PictureFileControlInfoModel, PlaceHolderDirective, PortalDynamicPageResolver, PortalFormPageResolver, PortalPageComponent, PortalPageResolver, PortalPageSidebarComponent, PortalReportPageResolver, PortalService, PreventDefaulEvent, PreventDefaultDirective, PrintFilesDirective, PrintImage, PromptUpdateService, PushBannerComponent, PushCheckService, PushNotificationService, RabetehAkseTakiListiControlInfoModel, RedirectHomeGuard, RedirectReportNavigatorCommandComponent, RelatedReportControlInfoModel, RelationListControlInfoModel, RemoveDynamicFormStyles, RemoveNewlinePipe, RenderUlvDirective, RenderUlvPaginDirective, RenderUlvViewerDirective, ReplacePipe, ReportBaseComponent, ReportBaseInfo, ReportCalendarModel, ReportContainerComponent, ReportExtraInfo, ReportField, ReportFormModel, ReportItemBaseComponent, ReportListModel, ReportModel, ReportTreeModel, ReportViewBaseComponent, ReportViewColumn, ResizableComponent, ResizableDirective, ResizableModule, ResizeHandlerDirective, ResizeObserverDirective, ReversePipe, RichStringControlInfoModel, RootPageComponent, RootPortalComponent, RouteFormChangeDirective, RoutingService, RowDataOption, RowNumberPipe, SafeBottomDirective, SanitizeTextPipe, SaveImageDirective, SaveImageToFile, SaveScrollPositionService, ScrollPersistDirective, ScrollToSelectedDirective, SelectionMode, SeperatorFixPipe, ServiceWorkerCommuncationService, ServiceWorkerNotificationService, ShellbarHeightService, ShortcutHandlerDirective, ShortcutRegisterDirective, SimplebarDirective, SingleRelationControlInfoModel, SortDirection, SortPipe, SortSetting, SplideSliderDirective, SplitPipe, StopPropagationDirective, StringControlInfoModel, StringToNumberPipe, SubformControlInfoModel, SystemBaseComponent, TOAST_SERVICE, TableHeaderWidthMode, TableResizerDirective, TabpageService, ThImageOrIconePipe, TileGroupBreadcrumResolver, TilePropsComponent, TlbButtonsPipe, ToolbarSettingsPipe, TooltipDirective, TotalSummaryPipe, UiService, UlvCommandDirective, UlvMainService, UnlimitSessionComponent, UntilInViewDirective, UploadService, VideoMimeType, VideoRecordingService, ViewBase, VisibleValuePipe, WebOtpDirective, WordMimeType, WorfkflowwChoiceCommandDirective, addCssVariableToRoot, availablePrefixes, calcContextMenuWidth, calculateColumnContent, calculateColumnWidth, calculateColumnWidthFitToContainer, calculateFreeColumnSize, calculateMoDataListContentWidthByColumnName, cancelRequestAnimationFrame, createFormPanelMetaConditions, createGridEditorFormPanel, easeInOutCubic, elementInViewport2, enumValueToStringSize, executeUlvCommandHandler, flattenTree, forbiddenValidator, formRoutes, formatBytes, fromEntries, fromIntersectionObserver, genrateInlineMoId, getAllItemsPerChildren, getColumnValueOfMoDataList, getComponentDefined, getControlList, getControlSizeMode, getDateService, getDeviceIsDesktop, getDeviceIsMobile, getDeviceIsPhone, getDeviceIsTablet, getFieldValue, getFocusableTagNames, getFormSettings, getGridSettings, getHeaderValue, getIcon, getImagePath, getLabelWidth, getLayout94ObjectInfo, getLayoutControl, getNewMoGridEditor, getParentHeight, getRequestAnimationFrame, getResetGridSettings, getTargetRect, getUniqueId, getValidExtension, isFF, isFirefox, isFunction, isImage, isInLocalMode, isSafari, isTargetWindow, measureText, measureText2, measureTextBy, mobile_regex, nullOrUndefinedString, number_only, requestAnimationFramePolyfill, setColumnWidthByMaxMoContentWidth, setOneDepthLevel, setTableThWidth, shallowEqual, stopPropagation, throwIfAlreadyLoaded, toNumber, validateAllFormFields };
17575
17622
  //# sourceMappingURL=barsa-novin-ray-core.mjs.map