@geexcode/geex-angular 0.0.39 → 0.0.52

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.
@@ -0,0 +1,3111 @@
1
+ import * as i0 from '@angular/core';
2
+ import { signal, InjectionToken, runInInjectionContext, makeEnvironmentProviders, Injector, inject, Injectable, provideAppInitializer, importProvidersFrom, ChangeDetectorRef, effect, computed, Component, input, output, contentChild, untracked, isSignal } from '@angular/core';
3
+ import { fromEvent, Subject, Observable, throwError, of, firstValueFrom, interval, filter, map, takeUntil, timer, BehaviorSubject, isObservable, lastValueFrom, switchMap as switchMap$1 } from 'rxjs';
4
+ import { debounceTime, switchMap, exhaustMap, mergeMap, catchError, finalize, filter as filter$1 } from 'rxjs/operators';
5
+ import { toSignal } from '@angular/core/rxjs-interop';
6
+ import { HttpContextToken, HttpErrorResponse, HttpContext, HttpResponseBase, HTTP_INTERCEPTORS } from '@angular/common/http';
7
+ import { InMemoryCache, ApolloLink, CombinedGraphQLErrors } from '@apollo/client';
8
+ import { ErrorLink } from '@apollo/client/link/error';
9
+ import { GraphQLWsLink } from '@apollo/client/link/subscriptions';
10
+ import { Apollo, APOLLO_OPTIONS, APOLLO_NAMED_OPTIONS, gql as gql$1 } from 'apollo-angular';
11
+ import { HttpLink } from 'apollo-angular/http';
12
+ import extractFiles from 'extract-files/extractFiles.mjs';
13
+ import isExtractableFile from 'extract-files/isExtractableFile.mjs';
14
+ import { createClient } from 'graphql-ws';
15
+ import json5 from 'json5';
16
+ import { Router, ActivatedRoute, RouteConfigLoadEnd, NavigationEnd, RouteReuseStrategy, ActivatedRouteSnapshot } from '@angular/router';
17
+ import { ALAIN_I18N_TOKEN, SettingsService, MenuService, en_US, zh_CN, DelonLocaleService, ModalHelper, TitleService, AlainThemeModule } from '@delon/theme';
18
+ import { OAuthService, OAuthErrorEvent } from 'angular-oauth2-oidc';
19
+ import { NzModalService, NzModalRef } from 'ng-zorro-antd/modal';
20
+ import { NzNotificationService } from 'ng-zorro-antd/notification';
21
+ import { ACLService } from '@delon/acl';
22
+ import { CookieService, deepCopy } from '@delon/util';
23
+ import * as _ from 'lodash-es';
24
+ import { merge, flatMapDeep as flatMapDeep$1 } from 'lodash-es';
25
+ import { registerLocaleData, Location } from '@angular/common';
26
+ import ngEn from '@angular/common/locales/en';
27
+ import ngZh from '@angular/common/locales/zh';
28
+ import { TranslateService, TranslateModule, TranslateLoader } from '@ngx-translate/core';
29
+ import { enUS, zhCN } from 'date-fns/locale';
30
+ import kiwiIntl from 'kiwi-intl';
31
+ import { en_US as en_US$1, zh_CN as zh_CN$1, NzI18nService } from 'ng-zorro-antd/i18n';
32
+ import gql from 'graphql-tag';
33
+ import { NzMessageService } from 'ng-zorro-antd/message';
34
+ import { FormBuilder, FormControl, FormGroup, AbstractControl } from '@angular/forms';
35
+ import { ReuseTabService, ReuseTabStrategy, provideReuseTabConfig } from '@delon/abc/reuse-tab';
36
+ import { LoadingService } from '@delon/abc/loading';
37
+ import { match, P } from 'ts-pattern';
38
+ import * as i1 from '@delon/abc/page-header';
39
+ import { PageHeaderModule } from '@delon/abc/page-header';
40
+ import * as i2 from '@delon/abc/st';
41
+ import { STModule, STComponent } from '@delon/abc/st';
42
+ import * as i4 from 'ng-zorro-antd/alert';
43
+ import { NzAlertModule } from 'ng-zorro-antd/alert';
44
+ import * as i3 from 'ng-zorro-antd/card';
45
+ import { NzCardModule } from 'ng-zorro-antd/card';
46
+ import * as i5 from 'ng-zorro-antd/divider';
47
+ import { NzDividerModule } from 'ng-zorro-antd/divider';
48
+ import * as i6 from 'ng-zorro-antd/icon';
49
+ import { NzIconModule } from 'ng-zorro-antd/icon';
50
+ import { DelonFormModule } from '@delon/form';
51
+ import { List } from 'linqts-camelcase';
52
+ import { addYears, addMonths, addWeeks, addDays, addHours, addMinutes, addSeconds, addMilliseconds } from 'date-fns';
53
+ import SparkMD5 from 'spark-md5';
54
+
55
+ function guardedSignal(innerSignal, isInitialized) {
56
+ const guard = (() => {
57
+ if (!isInitialized()) {
58
+ throw new Error(`GuardedSignal not initialized. isInitialized: ${isInitialized.toString()}`);
59
+ }
60
+ return innerSignal();
61
+ });
62
+ if ("set" in innerSignal) {
63
+ guard.set = innerSignal.set.bind(innerSignal);
64
+ guard.update = innerSignal.update.bind(innerSignal);
65
+ }
66
+ if ("asReadonly" in innerSignal) {
67
+ guard.asReadonly = innerSignal.asReadonly.bind(innerSignal);
68
+ }
69
+ return guard;
70
+ }
71
+
72
+ const ExtensionModule = {};
73
+ function createUiModule(_injector) {
74
+ const _fullScreenSignal = signal(false, ...(ngDevMode ? [{ debugName: "_fullScreenSignal" }] : []));
75
+ const _isMobile = toSignal(fromEvent(window, "resize").pipe(debounceTime(200), switchMap(async () => window.innerHeight / window.innerWidth >= 1.5)));
76
+ let _initialized = false;
77
+ let _initPromise = null;
78
+ const module = {
79
+ fullScreen: guardedSignal(_fullScreenSignal, () => _initialized),
80
+ isMobile: guardedSignal(_isMobile, () => _initialized),
81
+ activeRoutedComponent: undefined,
82
+ init: (force = false) => {
83
+ if (force) {
84
+ _initPromise = null;
85
+ _initialized = false;
86
+ }
87
+ if (!_initPromise) {
88
+ _initPromise = (async () => {
89
+ _initialized = true;
90
+ })();
91
+ }
92
+ return _initPromise;
93
+ },
94
+ };
95
+ return module;
96
+ }
97
+
98
+ let geex;
99
+ let Geex = new InjectionToken("Geex");
100
+ function configGeex(injector, overrides = {}, contributions = []) {
101
+ runInInjectionContext(injector, () => {
102
+ const modules = {
103
+ ui: createUiModule(injector),
104
+ };
105
+ const moduleRecord = modules;
106
+ for (const contribution of contributions) {
107
+ const contributedModules = contribution.createModules({
108
+ injector,
109
+ modules,
110
+ });
111
+ for (const [name, module] of Object.entries(contributedModules)) {
112
+ if (name === "init" || name in modules) {
113
+ throw new Error(`Geex module "${name}" is already registered.`);
114
+ }
115
+ moduleRecord[name] = module;
116
+ }
117
+ }
118
+ Object.assign(modules, overrides);
119
+ let _initPromise = null;
120
+ modules.init ??= (force = false) => {
121
+ if (force) {
122
+ _initPromise = null;
123
+ }
124
+ if (!_initPromise) {
125
+ _initPromise = (async () => {
126
+ const entries = Object.entries(modules).filter(([key]) => key !== "init");
127
+ return Object.fromEntries(await Promise.all(entries.map(async ([key, mod]) => {
128
+ const maybeInit = mod.init;
129
+ try {
130
+ return [key, await maybeInit(force)];
131
+ }
132
+ catch (err) {
133
+ console.error(err);
134
+ return [key, null];
135
+ }
136
+ })));
137
+ })();
138
+ }
139
+ return _initPromise;
140
+ };
141
+ geex = modules;
142
+ });
143
+ }
144
+
145
+ const GEEX_MODULE_CONTRIBUTIONS = new InjectionToken("GEEX_MODULE_CONTRIBUTIONS");
146
+ function provideGeexModuleContribution(contribution) {
147
+ return makeEnvironmentProviders([
148
+ {
149
+ provide: GEEX_MODULE_CONTRIBUTIONS,
150
+ multi: true,
151
+ useValue: contribution,
152
+ },
153
+ ]);
154
+ }
155
+
156
+ function provideGeex(overrides = {}, extensions = {}) {
157
+ return [
158
+ {
159
+ provide: Geex,
160
+ useFactory: (injector) => {
161
+ const contributions = inject(GEEX_MODULE_CONTRIBUTIONS, { optional: true }) ?? [];
162
+ const mergedModules = {
163
+ ...extensions,
164
+ ...overrides,
165
+ };
166
+ configGeex(injector, mergedModules, contributions);
167
+ return geex;
168
+ },
169
+ deps: [Injector],
170
+ },
171
+ ];
172
+ }
173
+
174
+ /**
175
+ * Core meta-provide aligned with backend Geex.Common.
176
+ * Installs geex signal modules. Delon page bases are opt-in via `provideGeexDelonBase()`.
177
+ * Does not install admin business UI pages; use `geex add <name>` for source modules.
178
+ */
179
+ function provideGeexCommon(overrides = {}, extensions = {}) {
180
+ return provideGeex(overrides, extensions);
181
+ }
182
+
183
+ function clearHistory() {
184
+ history.pushState(null, "", location.href);
185
+ window.onpopstate = function () {
186
+ history.go(1);
187
+ };
188
+ }
189
+ window.clearHistory = clearHistory;
190
+
191
+ /** Mark HTTP / GraphQL ops that should not show error UI. */
192
+ const SILENT_REQUEST = new HttpContextToken(() => false);
193
+ const GEEX_DEFAULT_HTTP_STATUS_MESSAGES = {
194
+ 200: "服务器成功返回请求的数据。",
195
+ 201: "新建或修改数据成功。",
196
+ 202: "一个请求已经进入后台排队(异步任务)。",
197
+ 204: "删除数据成功。",
198
+ 400: "发出的请求有错误,服务器拒绝处理。",
199
+ 401: "用户没有权限(令牌、用户名、密码错误)。",
200
+ 403: "当前登录的用户没有对应的权限。",
201
+ 404: "请求针对的记录不存在。",
202
+ 406: "请求的格式不受支持。",
203
+ 410: "请求的资源已被永久删除。",
204
+ 422: "当创建一个对象时,发生一个验证错误。",
205
+ 500: "服务器发生错误,如有疑问,请联系管理员。",
206
+ 502: "网关错误。",
207
+ 503: "服务不可用,服务器暂时过载或维护。",
208
+ 504: "网关超时。",
209
+ };
210
+ /** Override status → message map (defaults to GEEX_DEFAULT_HTTP_STATUS_MESSAGES). */
211
+ const GEEX_HTTP_STATUS_MESSAGES = new InjectionToken("GEEX_HTTP_STATUS_MESSAGES", { providedIn: "root", factory: () => GEEX_DEFAULT_HTTP_STATUS_MESSAGES });
212
+ /** Login route after 401 (default `/authentication/login`). */
213
+ const GEEX_LOGIN_PATH = new InjectionToken("GEEX_LOGIN_PATH", {
214
+ providedIn: "root",
215
+ factory: () => "/authentication/login",
216
+ });
217
+ /** Called after navigating to login. Defaults to `window.clearHistory`. */
218
+ const GEEX_AFTER_LOGIN_NAVIGATE = new InjectionToken("GEEX_AFTER_LOGIN_NAVIGATE", {
219
+ providedIn: "root",
220
+ factory: () => () => window.clearHistory(),
221
+ });
222
+ /** API base URL for relative HTTP requests (host `environment.api.baseUrl`). */
223
+ const GEEX_API_BASE_URL = new InjectionToken("GEEX_API_BASE_URL");
224
+
225
+ /**
226
+ * Default Geex HTTP interceptor (zh-CN messages, `/authentication/login`, tenant/Bearer headers).
227
+ * Override via tokens or protected hooks; host may `extends` or provide callbacks.
228
+ */
229
+ class GeexHttpInterceptor {
230
+ injector = inject(Injector);
231
+ oauthService = inject(OAuthService);
232
+ modalSrv = inject(NzModalService);
233
+ statusMessages = inject(GEEX_HTTP_STATUS_MESSAGES);
234
+ loginPath = inject(GEEX_LOGIN_PATH);
235
+ afterLoginNavigate = inject(GEEX_AFTER_LOGIN_NAVIGATE);
236
+ apiBaseUrl = inject(GEEX_API_BASE_URL, { optional: true }) ?? "";
237
+ loginTrigger$ = new Subject();
238
+ loginModal$;
239
+ constructor() {
240
+ this.loginModal$ = this.loginTrigger$.pipe(debounceTime(100), exhaustMap(() => {
241
+ return new Observable(subscriber => {
242
+ const options = this.buildLoginConfirmOptions();
243
+ const modal = this.modalSrv.confirm({
244
+ ...options,
245
+ nzOnOk: () => {
246
+ this.goTo(this.loginPath);
247
+ subscriber.next();
248
+ subscriber.complete();
249
+ return true;
250
+ },
251
+ nzOnCancel: () => {
252
+ subscriber.next();
253
+ subscriber.complete();
254
+ return true;
255
+ },
256
+ nzClosable: true,
257
+ });
258
+ modal.afterClose.subscribe(() => {
259
+ subscriber.next();
260
+ subscriber.complete();
261
+ });
262
+ return () => {
263
+ modal?.destroy();
264
+ };
265
+ });
266
+ }));
267
+ this.loginModal$.subscribe();
268
+ }
269
+ get notification() {
270
+ return this.injector.get(NzNotificationService);
271
+ }
272
+ buildLoginConfirmOptions() {
273
+ return { nzTitle: "当前登录会话已失效或超时,是否重新登录?" };
274
+ }
275
+ goTo(url) {
276
+ this.injector
277
+ .get(Router)
278
+ .navigateByUrl(url, { skipLocationChange: true })
279
+ .then(() => {
280
+ this.afterLoginNavigate();
281
+ });
282
+ }
283
+ isSilentRequest(req) {
284
+ return req.context.get(SILENT_REQUEST) === true;
285
+ }
286
+ shouldAttachTenant() {
287
+ return true;
288
+ }
289
+ notifyHttpError(status, text) {
290
+ this.notification.error(`请求错误 ${status}`, text, {
291
+ nzKey: status.toString(),
292
+ });
293
+ }
294
+ onUnauthorized() {
295
+ this.loginTrigger$.next();
296
+ }
297
+ checkStatus(ev, silent) {
298
+ if (silent || (ev.status >= 200 && ev.status < 300) || ev.status === 401) {
299
+ return;
300
+ }
301
+ if (ev instanceof HttpErrorResponse) {
302
+ const errorText = ev.error?.errors?.[0]?.extensions?.message || this.statusMessages[ev.status];
303
+ this.notifyHttpError(ev.status, errorText);
304
+ }
305
+ }
306
+ /** Status-branch template method; override for custom 200/403/exception routing. */
307
+ handleHttpStatus(ev, silent) {
308
+ switch (ev.status) {
309
+ case 200:
310
+ break;
311
+ case 401:
312
+ this.onUnauthorized();
313
+ break;
314
+ case 403:
315
+ case 404:
316
+ case 500:
317
+ break;
318
+ default:
319
+ if (!silent && ev instanceof HttpErrorResponse) {
320
+ console.warn("未可知错误,大部分是由于后端不支持跨域CORS或无效配置引起,请参考 https://ng-alain.com/docs/server 解决跨域问题", ev);
321
+ }
322
+ break;
323
+ }
324
+ }
325
+ handleData(ev, _req, _next) {
326
+ const silent = this.isSilentRequest(_req);
327
+ this.checkStatus(ev, silent);
328
+ this.handleHttpStatus(ev, silent);
329
+ if (ev instanceof HttpErrorResponse) {
330
+ return throwError(() => ev);
331
+ }
332
+ return of(ev);
333
+ }
334
+ buildCommonHeaders(headers) {
335
+ const reqHeader = {};
336
+ try {
337
+ const lang = this.injector.get(ALAIN_I18N_TOKEN, null)?.currentLang;
338
+ if (!headers?.has("Accept-Language") && lang) {
339
+ reqHeader["Accept-Language"] = lang;
340
+ }
341
+ }
342
+ catch {
343
+ /* optional i18n */
344
+ }
345
+ try {
346
+ const token = this.oauthService.hasValidAccessToken() && this.oauthService.getAccessToken();
347
+ if (token && !headers?.has("Authorization")) {
348
+ reqHeader["Authorization"] = `Bearer ${token}`;
349
+ }
350
+ }
351
+ catch {
352
+ /* optional oauth */
353
+ }
354
+ if (this.shouldAttachTenant()) {
355
+ try {
356
+ const tenantCode = geex.multiTenant.current()?.code;
357
+ if (tenantCode && !headers?.has("__tenant")) {
358
+ reqHeader["__tenant"] = tenantCode;
359
+ }
360
+ }
361
+ catch {
362
+ /* no tenant module */
363
+ }
364
+ }
365
+ return reqHeader;
366
+ }
367
+ handleGraphQLErrors(params) {
368
+ const { graphQLErrors, operation, response } = params;
369
+ if (!graphQLErrors || graphQLErrors.length === 0)
370
+ return;
371
+ const context = operation?.getContext?.() ?? {};
372
+ if (context.silent === true) {
373
+ return;
374
+ }
375
+ const httpContext = context.httpContext;
376
+ if (httpContext instanceof HttpContext && httpContext.get(SILENT_REQUEST) === true) {
377
+ return;
378
+ }
379
+ const messages = graphQLErrors
380
+ .map(err => err?.message)
381
+ .filter(m => !!m)
382
+ .join(";");
383
+ const hasNoData = !response || response.data == null;
384
+ if (hasNoData) {
385
+ this.notification.error("请求错误 200", messages || "GraphQL 返回错误", {
386
+ nzKey: "graphql-200-error",
387
+ });
388
+ }
389
+ else {
390
+ this.notification.warning("请求警告 200", messages || "GraphQL 部分错误", {
391
+ nzKey: "graphql-200-warn",
392
+ });
393
+ }
394
+ }
395
+ handleGraphQLNetworkError(networkError) {
396
+ if (!networkError)
397
+ return;
398
+ console.error(networkError?.message || "网络错误, 请稍后重试, 如有疑问, 请联系管理员。");
399
+ }
400
+ intercept(req, next) {
401
+ let url = req.url;
402
+ if (!url.startsWith("https://") && !url.startsWith("http://") && this.apiBaseUrl) {
403
+ url = this.apiBaseUrl + url;
404
+ }
405
+ const newReq = req.clone({ url, setHeaders: this.buildCommonHeaders(req.headers) });
406
+ return next.handle(newReq).pipe(mergeMap(ev => {
407
+ if (ev instanceof HttpResponseBase) {
408
+ return this.handleData(ev, newReq, next);
409
+ }
410
+ return of(ev);
411
+ }), catchError((err) => this.handleData(err, newReq, next)), finalize(() => { }));
412
+ }
413
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: GeexHttpInterceptor, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
414
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: GeexHttpInterceptor });
415
+ }
416
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: GeexHttpInterceptor, decorators: [{
417
+ type: Injectable
418
+ }], ctorParameters: () => [] });
419
+
420
+ const GEEX_APOLLO_TYPE_POLICY_CONTRIBUTIONS = new InjectionToken("GEEX_APOLLO_TYPE_POLICY_CONTRIBUTIONS");
421
+ function provideGeexApolloTypePolicies(contribution) {
422
+ return makeEnvironmentProviders([
423
+ {
424
+ provide: GEEX_APOLLO_TYPE_POLICY_CONTRIBUTIONS,
425
+ multi: true,
426
+ useValue: contribution,
427
+ },
428
+ ]);
429
+ }
430
+ const geexApolloDefaultOptions = {
431
+ query: {
432
+ fetchPolicy: "network-only",
433
+ errorPolicy: "ignore",
434
+ },
435
+ mutate: {
436
+ fetchPolicy: "no-cache",
437
+ errorPolicy: "ignore",
438
+ },
439
+ watchQuery: {
440
+ fetchPolicy: "cache-first",
441
+ errorPolicy: "ignore",
442
+ },
443
+ };
444
+ /** Core cache policies. Feature-specific policies are registered by extensions. */
445
+ function geexDefaultTypePolicies() {
446
+ return {
447
+ Setting: {
448
+ keyFields: ["name"],
449
+ },
450
+ };
451
+ }
452
+ function mergeTypePolicies(base, extras) {
453
+ let merged = base;
454
+ for (const extra of extras) {
455
+ merged = { ...merged, ...extra };
456
+ }
457
+ return merged;
458
+ }
459
+ function createGeexInMemoryCache(options = {}, contributions = []) {
460
+ const includeDefaults = options.includeDefaults !== false;
461
+ const contributedPolicies = contributions.map(contribution => contribution());
462
+ const extras = options.typePolicies
463
+ ? [...contributedPolicies, options.typePolicies]
464
+ : contributedPolicies;
465
+ const policies = includeDefaults
466
+ ? mergeTypePolicies(geexDefaultTypePolicies(), extras)
467
+ : mergeTypePolicies({}, extras);
468
+ return new InMemoryCache({
469
+ typePolicies: policies,
470
+ possibleTypes: options.possibleTypes,
471
+ });
472
+ }
473
+ function createGeexUriLink(baseUrl) {
474
+ return new ApolloLink((operation, forward) => {
475
+ const variables = Object.entries(operation.variables).filter(([, v]) => v != undefined);
476
+ if (variables.length > 0) {
477
+ operation.setContext(() => {
478
+ const encodedParams = variables.map(([k, v]) => `${k}=${json5.stringify(v)}`).join("&");
479
+ return {
480
+ uri: new URL(`/graphql/${operation.operationName}?${encodedParams}`, baseUrl).toString().substring(0, 2047),
481
+ };
482
+ });
483
+ }
484
+ else {
485
+ operation.setContext(() => ({
486
+ uri: new URL(`/graphql/${operation.operationName}`, baseUrl).toString().substring(0, 2047),
487
+ }));
488
+ }
489
+ return forward(operation);
490
+ });
491
+ }
492
+ function createGeexHttpApolloOptions(options) {
493
+ const uriLink = createGeexUriLink(options.baseUrl);
494
+ const links = [...(options.extraLinks ?? []), uriLink, options.httpLinkInstance];
495
+ return {
496
+ link: ApolloLink.from(links),
497
+ cache: options.cache,
498
+ defaultOptions: geexApolloDefaultOptions,
499
+ };
500
+ }
501
+ function isGeexSilentOperation(operation, silentToken = SILENT_REQUEST) {
502
+ const context = operation.getContext() ?? {};
503
+ if (context["silent"] === true) {
504
+ return true;
505
+ }
506
+ const httpContext = context["httpContext"];
507
+ return httpContext instanceof HttpContext && httpContext.get(silentToken) === true;
508
+ }
509
+ function createGeexGraphqlErrorLink(handler) {
510
+ return new ErrorLink(({ error, result, operation }) => {
511
+ if (isGeexSilentOperation(operation)) {
512
+ return;
513
+ }
514
+ if (CombinedGraphQLErrors.is(error)) {
515
+ handler.handleGraphQLErrors({
516
+ graphQLErrors: error.errors,
517
+ operation,
518
+ response: result,
519
+ });
520
+ }
521
+ else if (error) {
522
+ handler.handleGraphQLNetworkError(error);
523
+ }
524
+ });
525
+ }
526
+ function createGeexSilentContextLink(silentToken = SILENT_REQUEST) {
527
+ return new ApolloLink((operation, forward) => {
528
+ operation.setContext(context => {
529
+ const prevHttpContext = context.httpContext instanceof HttpContext ? context.httpContext : new HttpContext();
530
+ return {
531
+ silent: true,
532
+ httpContext: prevHttpContext.set(silentToken, true),
533
+ };
534
+ });
535
+ return forward(operation);
536
+ });
537
+ }
538
+ function createGeexWsApolloOptions(options) {
539
+ const url = options.url ??
540
+ new URL("/graphql", (options.baseUrl ?? "").replace(/^http/, "ws")).toString();
541
+ const client = createClient({
542
+ url,
543
+ lazy: true,
544
+ retryAttempts: options.retryAttempts ?? 3,
545
+ connectionParams: options.connectionParams,
546
+ on: {
547
+ opened: options.onOpened ?? (() => console.log("ws connected.")),
548
+ error: options.onError ?? ((err) => console.error("ws connect failed.", err)),
549
+ },
550
+ });
551
+ return {
552
+ link: new GraphQLWsLink(client),
553
+ cache: options.cache,
554
+ defaultOptions: geexApolloDefaultOptions,
555
+ };
556
+ }
557
+ /**
558
+ * HttpLink with multipart upload support.
559
+ * Uses peer `extract-files` by default; overrides via options.
560
+ */
561
+ function createGeexUploadHttpLink(httpLink, options) {
562
+ const extractFilesFn = options?.extractFilesFn ?? extractFiles;
563
+ const isExtractable = options?.isExtractableFile ?? isExtractableFile;
564
+ return httpLink.create({
565
+ withCredentials: options?.withCredentials ?? true,
566
+ extractFiles: body => extractFilesFn(body, isExtractable),
567
+ });
568
+ }
569
+ const SilentApollo = new InjectionToken("silent_apollo");
570
+ const GEEX_APOLLO_CACHE = new InjectionToken("GEEX_APOLLO_CACHE");
571
+ function provideGeexApollo(options) {
572
+ const createHttp = (httpLink) => {
573
+ if (options.createHttpLinkInstance) {
574
+ return options.createHttpLinkInstance(httpLink);
575
+ }
576
+ if (options.enableUpload === false) {
577
+ return httpLink.create({ withCredentials: true });
578
+ }
579
+ return createGeexUploadHttpLink(httpLink);
580
+ };
581
+ return [
582
+ Apollo,
583
+ {
584
+ provide: GEEX_APOLLO_CACHE,
585
+ useFactory: () => createGeexInMemoryCache({
586
+ possibleTypes: options.possibleTypes,
587
+ typePolicies: options.typePolicies,
588
+ includeDefaults: options.includeDefaultTypePolicies !== false,
589
+ }, inject(GEEX_APOLLO_TYPE_POLICY_CONTRIBUTIONS, { optional: true }) ?? []),
590
+ },
591
+ {
592
+ provide: APOLLO_OPTIONS,
593
+ useFactory: (cache, httpLink, interceptor) => {
594
+ const handler = options.errorHandler ?? interceptor;
595
+ return createGeexHttpApolloOptions({
596
+ baseUrl: options.baseUrl,
597
+ httpLinkInstance: createHttp(httpLink),
598
+ cache,
599
+ extraLinks: [createGeexGraphqlErrorLink(handler)],
600
+ });
601
+ },
602
+ deps: [GEEX_APOLLO_CACHE, HttpLink, GeexHttpInterceptor],
603
+ },
604
+ {
605
+ provide: APOLLO_NAMED_OPTIONS,
606
+ useFactory: (cache, httpLink, interceptor) => {
607
+ const handler = options.errorHandler ?? interceptor;
608
+ return {
609
+ subscription: createGeexWsApolloOptions({
610
+ baseUrl: options.baseUrl,
611
+ cache,
612
+ connectionParams: async () => handler.buildCommonHeaders?.() ?? interceptor.buildCommonHeaders(),
613
+ }),
614
+ silent: createGeexHttpApolloOptions({
615
+ baseUrl: options.baseUrl,
616
+ httpLinkInstance: createHttp(httpLink),
617
+ cache,
618
+ extraLinks: [createGeexSilentContextLink()],
619
+ }),
620
+ };
621
+ },
622
+ deps: [GEEX_APOLLO_CACHE, HttpLink, GeexHttpInterceptor],
623
+ },
624
+ {
625
+ provide: SilentApollo,
626
+ useFactory: (apollo) => apollo.use("silent"),
627
+ deps: [Apollo],
628
+ },
629
+ ];
630
+ }
631
+
632
+ const GEEX_STARTUP_OPTIONS = new InjectionToken("GEEX_STARTUP_OPTIONS");
633
+ const GEEX_EXCEPTION_500_PATH = new InjectionToken("GEEX_EXCEPTION_500_PATH", {
634
+ providedIn: "root",
635
+ factory: () => "/exception/500",
636
+ });
637
+ const GEEX_SESSION_TERMINATED_COPY = new InjectionToken("GEEX_SESSION_TERMINATED_COPY", {
638
+ providedIn: "root",
639
+ factory: () => ({}),
640
+ });
641
+
642
+ /** When true, DebuggerBlockerService activates anti-devtools measures. */
643
+ const GEEX_BLOCK_DEBUGGER = new InjectionToken("GEEX_BLOCK_DEBUGGER", {
644
+ providedIn: "root",
645
+ factory: () => false,
646
+ });
647
+
648
+ class DebuggerBlockerService {
649
+ enabled = inject(GEEX_BLOCK_DEBUGGER, { optional: true }) ?? false;
650
+ init() {
651
+ if (!this.enabled) {
652
+ return;
653
+ }
654
+ this.blockDebugger();
655
+ this.disableDevToolsShortcuts();
656
+ }
657
+ blockDebugger() {
658
+ setInterval(() => {
659
+ eval(`
660
+ if (window.outerHeight - window.innerHeight > 160 || window.outerWidth - window.innerWidth > 160) {
661
+ alert("Debugger detected! Please close dev tools to continue.")
662
+ location.reload();
663
+ }
664
+ `);
665
+ }, 1000);
666
+ }
667
+ disableDevToolsShortcuts() {
668
+ document.addEventListener("keydown", e => {
669
+ if (e.key === "F12") {
670
+ e.preventDefault();
671
+ e.stopPropagation();
672
+ return;
673
+ }
674
+ if (e.ctrlKey && e.shiftKey && ["I", "J", "C"].includes(e.key)) {
675
+ e.preventDefault();
676
+ e.stopPropagation();
677
+ }
678
+ }, true);
679
+ }
680
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: DebuggerBlockerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
681
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: DebuggerBlockerService, providedIn: "root" });
682
+ }
683
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: DebuggerBlockerService, decorators: [{
684
+ type: Injectable,
685
+ args: [{
686
+ providedIn: "root",
687
+ }]
688
+ }] });
689
+
690
+ const GEEX_MENU_CONTRIBUTIONS = new InjectionToken("GEEX_MENU_CONTRIBUTIONS");
691
+ /** Host-composed default menus (e.g. from module-registry). */
692
+ const GEEX_DEFAULT_MENUS = new InjectionToken("GEEX_DEFAULT_MENUS", {
693
+ providedIn: "root",
694
+ factory: () => [],
695
+ });
696
+ function provideGeexMenus(menus) {
697
+ return [{ provide: GEEX_DEFAULT_MENUS, useValue: menus }];
698
+ }
699
+
700
+ /**
701
+ * Host provides AlainI18NService-compatible instance (e.g. `GeexI18nService`).
702
+ */
703
+ const GEEX_I18N_SERVICE = new InjectionToken("GEEX_I18N_SERVICE");
704
+ /**
705
+ * Typed kiwi/i18n dictionary (augment `GeexI18n` in the host app).
706
+ */
707
+ const GEEX_I18N = new InjectionToken("GEEX_I18N");
708
+ /**
709
+ * Typed AppPermission enum/map (augment `GeexAppPermission` in the host app).
710
+ */
711
+ const GEEX_APP_PERMISSION = new InjectionToken("GEEX_APP_PERMISSION");
712
+
713
+ /** Per-language ngx-translate dictionaries keyed by locale code (e.g. `zh-cn`). */
714
+ const GEEX_I18N_PACKS = new InjectionToken("GEEX_I18N_PACKS");
715
+ /** Well-known setting names for post-login localization (aligned with SettingDefinition). */
716
+ const GEEX_LOCALIZATION_DATA_SETTING = "LocalizationData";
717
+ const GEEX_LOCALIZATION_LANGUAGE_SETTING = "LocalizationLanguage";
718
+
719
+ /** Well-known setting names for post-login app/menu bind (aligned with SettingDefinition). */
720
+ const GEEX_APP_NAME_SETTING = "AppAppName";
721
+ const GEEX_APP_MENU_SETTING = "AppAppMenu";
722
+
723
+ const GEEX_SUPER_ADMIN_USER_ID = new InjectionToken("GEEX_SUPER_ADMIN_USER_ID", {
724
+ providedIn: "root",
725
+ factory: () => "000000000000000000000001",
726
+ });
727
+
728
+ /**
729
+ * Single bootstrap entry for app session.
730
+ *
731
+ * Linear flow:
732
+ * 1. configure OAuth
733
+ * 2. if OIDC callback code present → tryLogin (once)
734
+ * 3. geex.init()
735
+ * 4. bind Delon user / ACL / menus
736
+ * 5. start session watch (once)
737
+ *
738
+ * Login pages must not call tryLogin/load for OIDC callbacks.
739
+ * Password / WeChat token handoff uses initCodeFlow → IdP → this bootstrap again.
740
+ */
741
+ class GeexStartupService {
742
+ options = inject(GEEX_STARTUP_OPTIONS);
743
+ injector = inject(Injector);
744
+ geex = inject(Geex);
745
+ oAuthService = inject(OAuthService);
746
+ aclService = inject(ACLService);
747
+ settingsService = inject(SettingsService);
748
+ router = inject(Router);
749
+ modalService = inject(NzModalService);
750
+ menuService = inject(MenuService);
751
+ loginPath = inject(GEEX_LOGIN_PATH);
752
+ afterLoginNavigate = inject(GEEX_AFTER_LOGIN_NAVIGATE);
753
+ superAdminUserId = inject(GEEX_SUPER_ADMIN_USER_ID);
754
+ exception500Url = inject(GEEX_EXCEPTION_500_PATH);
755
+ sessionTerminatedCopy = inject(GEEX_SESSION_TERMINATED_COPY);
756
+ defaultMenus = inject(GEEX_DEFAULT_MENUS);
757
+ debuggerBlocker = inject(DebuggerBlockerService);
758
+ bootstrapPromise = null;
759
+ bootstrapped = false;
760
+ sessionWatchStarted = false;
761
+ /** APP_INITIALIZER entry. Safe to call concurrently; runs the bootstrap pipeline once. */
762
+ async load() {
763
+ if (this.bootstrapped) {
764
+ return;
765
+ }
766
+ if (this.bootstrapPromise) {
767
+ return this.bootstrapPromise;
768
+ }
769
+ this.bootstrapPromise = this.bootstrap().finally(() => {
770
+ this.bootstrapPromise = null;
771
+ });
772
+ return this.bootstrapPromise;
773
+ }
774
+ async bootstrap() {
775
+ try {
776
+ this.debuggerBlocker.init();
777
+ this.oAuthService.configure(this.options.oauth.getConfig());
778
+ await this.trySwitchTenant();
779
+ await this.tryAutoOAuthLogin();
780
+ await this.tryOidcCodeCallback();
781
+ this.ensureSessionWatch();
782
+ await this.geex.init();
783
+ await this.bindUiSession();
784
+ this.bootstrapped = true;
785
+ }
786
+ catch (error) {
787
+ await this.router.navigateByUrl(this.exception500Url);
788
+ console.error(error);
789
+ }
790
+ }
791
+ async tryOidcCodeCallback() {
792
+ const url = new URL(location.href);
793
+ const code = url.searchParams.get("code");
794
+ if (!code) {
795
+ return;
796
+ }
797
+ const state = url.searchParams.get("state") ?? "";
798
+ // WeChat QR callback uses the same ?code= param but is handled on the login page first.
799
+ if (state === "WechatWeb" || state.startsWith("WechatWeb")) {
800
+ return;
801
+ }
802
+ // Discovery aligns issuer/jwks before tryLogin (id_token validation). tokenEndpoint alone is not enough.
803
+ try {
804
+ await this.oAuthService.loadDiscoveryDocument();
805
+ }
806
+ catch (err) {
807
+ console.error(err);
808
+ }
809
+ await this.ensureOAuthTokenEndpoint();
810
+ await this.oAuthService.tryLogin();
811
+ }
812
+ /** Fill tokenEndpoint gaps after discovery (or when discovery is unreachable). */
813
+ async ensureOAuthTokenEndpoint() {
814
+ if (this.oAuthService.tokenEndpoint) {
815
+ return;
816
+ }
817
+ const issuer = this.oAuthService.issuer?.replace(/\/?$/, "/");
818
+ if (issuer) {
819
+ this.oAuthService.tokenEndpoint = `${issuer}idsvr/token`;
820
+ return;
821
+ }
822
+ throw new Error("OAuth tokenEndpoint is not configured. Set AuthConfig.tokenEndpoint (e.g. {issuer}/idsvr/token) or make OIDC discovery reachable.");
823
+ }
824
+ async bindUiSession() {
825
+ if (!this.oAuthService.hasValidAccessToken()) {
826
+ return;
827
+ }
828
+ const user = await this.resolveAuthUser();
829
+ if (!user) {
830
+ // Token without federateAuthenticate user is not a completed Geex login.
831
+ console.error("bindUiSession: access token present but geex.authentication.user() missing after federateAuthenticate");
832
+ this.oAuthService.logOut(true);
833
+ return;
834
+ }
835
+ this.settingsService.setUser({
836
+ avatar: user.avatarFile?.url,
837
+ id: user.id,
838
+ phoneNumber: user.phoneNumber,
839
+ email: user.email,
840
+ username: user.username,
841
+ roleName: user.roleNames,
842
+ });
843
+ const adminId = this.superAdminUserId;
844
+ if (user.id == adminId) {
845
+ this.aclService.setFull(true);
846
+ }
847
+ else {
848
+ this.aclService.setRole(user.permissions);
849
+ }
850
+ const settingsModule = this.geex["settings"];
851
+ const settings = settingsModule?.settings?.() ?? [];
852
+ if (!settings.length) {
853
+ return;
854
+ }
855
+ const appName = settings.find(x => x?.name == GEEX_APP_NAME_SETTING)?.value;
856
+ if (appName) {
857
+ this.settingsService.setApp({ name: appName });
858
+ }
859
+ let menus = this.defaultMenus.map(menu => ({
860
+ ...menu,
861
+ children: menu.children ? [...menu.children] : menu.children,
862
+ }));
863
+ const settingMenus = settings.find(x => x?.name == GEEX_APP_MENU_SETTING)?.value;
864
+ if (Array.isArray(settingMenus) && settingMenus.length) {
865
+ menus = settingMenus.map(menu => ({
866
+ ...menu,
867
+ children: menu.children ? [...menu.children] : menu.children,
868
+ }));
869
+ }
870
+ const contributions = this.injector.get(GEEX_MENU_CONTRIBUTIONS, []);
871
+ const contributedGroups = [];
872
+ for (const contribution of contributions) {
873
+ for (const item of (await contribution.resolve(user))) {
874
+ if (item.group === true) {
875
+ contributedGroups.push(item);
876
+ continue;
877
+ }
878
+ // Leaf items must stay under a group. Delon top-level `group !== false` renders
879
+ // as a non-clickable title without icons; never promote bare leaves to top-level.
880
+ const leaf = {
881
+ ...item,
882
+ group: false,
883
+ children: Array.isArray(item.children) ? item.children : [],
884
+ };
885
+ const existing = leaf.link ? this.findMenuByLink(menus, leaf.link) : undefined;
886
+ if (existing) {
887
+ Object.assign(existing, leaf, { hide: leaf.hide ?? false, group: false });
888
+ continue;
889
+ }
890
+ const systemConfigGroup = this.findSystemConfigGroup(menus);
891
+ if (systemConfigGroup) {
892
+ systemConfigGroup.children = [...(systemConfigGroup.children ?? []), leaf];
893
+ }
894
+ else {
895
+ contributedGroups.push({
896
+ group: true,
897
+ hideInBreadcrumb: true,
898
+ open: true,
899
+ text: "系统及配置",
900
+ i18n: "Common.menu.systemConfig",
901
+ children: [leaf],
902
+ });
903
+ }
904
+ }
905
+ }
906
+ this.menuService.add([...menus, ...contributedGroups]);
907
+ this.menuService.resume();
908
+ const i18n = this.resolveI18nAdapter();
909
+ i18n?.merge(settings.find(x => x?.name == GEEX_LOCALIZATION_DATA_SETTING)?.value);
910
+ const backendLang = settings.find(x => x?.name == GEEX_LOCALIZATION_LANGUAGE_SETTING)?.value;
911
+ if (backendLang) {
912
+ this.settingsService.setLayout("lang", backendLang);
913
+ i18n?.use(backendLang);
914
+ }
915
+ else {
916
+ const cachedLang = this.settingsService.layout.lang;
917
+ if (cachedLang) {
918
+ i18n?.use(cachedLang);
919
+ }
920
+ }
921
+ }
922
+ async tryAutoOAuthLogin() {
923
+ const url = new URL(location.href);
924
+ const autoLogin = url.searchParams.get("_autoLogin");
925
+ if (autoLogin) {
926
+ url.searchParams.delete("_autoLogin");
927
+ this.oAuthService.redirectUri = url.href;
928
+ this.oAuthService.initCodeFlow();
929
+ throw new Error("starting auto login");
930
+ }
931
+ }
932
+ findMenuByLink(menus, link) {
933
+ for (const menu of menus) {
934
+ if (menu.link === link) {
935
+ return menu;
936
+ }
937
+ if (menu.children?.length) {
938
+ const found = this.findMenuByLink(menu.children, link);
939
+ if (found) {
940
+ return found;
941
+ }
942
+ }
943
+ }
944
+ return undefined;
945
+ }
946
+ findSystemConfigGroup(menus) {
947
+ return menus.find(m => m.i18n === "Common.menu.systemConfig" ||
948
+ m.i18n === "menu.systemConfig" ||
949
+ m.text === "系统及配置" ||
950
+ m.children?.some(c => c.link === "/settings" ||
951
+ c.link === "/tenant" ||
952
+ c.link === "/blob-storage" ||
953
+ c.link === "/mocking" ||
954
+ c.i18n === "Common.menu.settings" ||
955
+ c.i18n === "Common.menu.tenant" ||
956
+ c.i18n === "Mocking.title"));
957
+ }
958
+ resolveI18nAdapter() {
959
+ const service = this.injector.get(GEEX_I18N_SERVICE, null);
960
+ if (service && typeof service.merge === "function" && typeof service.use === "function") {
961
+ return service;
962
+ }
963
+ return null;
964
+ }
965
+ /** Safe read: guardedSignal throws before auth.init finishes. */
966
+ readAuthUser() {
967
+ try {
968
+ return this.geex.authentication.user() ?? undefined;
969
+ }
970
+ catch {
971
+ return undefined;
972
+ }
973
+ }
974
+ /**
975
+ * After OIDC, auth.init may have finished with a null user (token race) or still be settling.
976
+ * Never throw EmptyError into bootstrap (that becomes the 500 page).
977
+ */
978
+ async resolveAuthUser() {
979
+ let user = this.readAuthUser();
980
+ if (user) {
981
+ return user;
982
+ }
983
+ const auth = this.geex.authentication;
984
+ if (typeof auth.reload === "function") {
985
+ await auth.reload();
986
+ user = this.readAuthUser();
987
+ if (user) {
988
+ return user;
989
+ }
990
+ }
991
+ return firstValueFrom(interval(100).pipe(filter(() => this.readAuthUser() != undefined), map(() => this.readAuthUser()), takeUntil(timer(5000))), { defaultValue: undefined });
992
+ }
993
+ async trySwitchTenant() {
994
+ const url = new URL(location.href);
995
+ const targetTenantCode = url.searchParams.get("__tenant");
996
+ url.searchParams.delete("__tenant");
997
+ if (!targetTenantCode) {
998
+ return;
999
+ }
1000
+ const currentTenantCode = this.injector.get(CookieService).get("__tenant");
1001
+ if (targetTenantCode == currentTenantCode) {
1002
+ await this.router.navigateByUrl(url.pathname + url.search + url.hash);
1003
+ return;
1004
+ }
1005
+ this.geex.multiTenant.switchTenant(targetTenantCode);
1006
+ await this.router.navigateByUrl(url.pathname + url.search + url.hash);
1007
+ }
1008
+ ensureSessionWatch() {
1009
+ if (this.sessionWatchStarted) {
1010
+ return;
1011
+ }
1012
+ this.sessionWatchStarted = true;
1013
+ this.oAuthService.setupAutomaticSilentRefresh();
1014
+ this.oAuthService["initSessionCheck"]();
1015
+ const loginUrl = this.loginPath;
1016
+ const modalCopy = this.sessionTerminatedCopy;
1017
+ this.oAuthService.events.subscribe(e => {
1018
+ if (e instanceof OAuthErrorEvent && e.reason?.status == 401) {
1019
+ this.oAuthService.logOut(true);
1020
+ }
1021
+ if (e.type == "session_terminated") {
1022
+ console.error(e);
1023
+ this.modalService.info({
1024
+ nzTitle: modalCopy.title ?? "检测到账号切换, 请重新登入",
1025
+ nzOkText: modalCopy.okText ?? "确认",
1026
+ nzOnOk: async () => {
1027
+ this.settingsService.setUser({});
1028
+ this.aclService.set({});
1029
+ await this.router.navigateByUrl(loginUrl).then(() => {
1030
+ this.afterLoginNavigate();
1031
+ });
1032
+ },
1033
+ nzClosable: false,
1034
+ });
1035
+ }
1036
+ });
1037
+ }
1038
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: GeexStartupService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1039
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: GeexStartupService });
1040
+ }
1041
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: GeexStartupService, decorators: [{
1042
+ type: Injectable
1043
+ }] });
1044
+
1045
+ function provideGeexStartup(options) {
1046
+ return [
1047
+ { provide: GEEX_STARTUP_OPTIONS, useValue: options },
1048
+ { provide: GEEX_BLOCK_DEBUGGER, useValue: options.blockDebugger ?? false },
1049
+ DebuggerBlockerService,
1050
+ GeexStartupService,
1051
+ provideAppInitializer(() => inject(GeexStartupService).load()),
1052
+ ];
1053
+ }
1054
+
1055
+ function mergeGeexI18nPacks(base, ...overlays) {
1056
+ return merge({}, base, ...overlays);
1057
+ }
1058
+
1059
+ class GeexTranslateLoader {
1060
+ packs = inject(GEEX_I18N_PACKS, { optional: true });
1061
+ getTranslation(lang) {
1062
+ if (this.packs?.[lang]) {
1063
+ return of(this.packs[lang]);
1064
+ }
1065
+ return of({});
1066
+ }
1067
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: GeexTranslateLoader, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1068
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: GeexTranslateLoader, providedIn: "root" });
1069
+ }
1070
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: GeexTranslateLoader, decorators: [{
1071
+ type: Injectable,
1072
+ args: [{ providedIn: "root" }]
1073
+ }] });
1074
+
1075
+ const DEFAULT = "zh-cn";
1076
+ const LANGS = {
1077
+ "zh-cn": {
1078
+ text: "简体中文",
1079
+ ng: ngZh,
1080
+ zorro: zh_CN$1,
1081
+ date: zhCN,
1082
+ delon: zh_CN,
1083
+ abbr: "🇨🇳",
1084
+ },
1085
+ "en-us": {
1086
+ text: "English",
1087
+ ng: ngEn,
1088
+ zorro: en_US$1,
1089
+ date: enUS,
1090
+ delon: en_US,
1091
+ abbr: "🇺🇸",
1092
+ },
1093
+ };
1094
+ /** Mutable kiwi dictionary; host may re-export as `I18N`. */
1095
+ let I18N;
1096
+ function attachGetter([key, value]) {
1097
+ const parentKey = key;
1098
+ if (value instanceof Object) {
1099
+ const langObj = value;
1100
+ Object.entries(value).forEach(([childKey, childValue]) => attachGetter([`${key}.${childKey}`, childValue]));
1101
+ langObj.get = function (childKey, notFoundValue) {
1102
+ const result = this[childKey];
1103
+ if (result != undefined) {
1104
+ return result;
1105
+ }
1106
+ if (notFoundValue != undefined || notFoundValue != null) {
1107
+ return notFoundValue;
1108
+ }
1109
+ return `${parentKey}.${childKey}`;
1110
+ }.bind(value);
1111
+ }
1112
+ return [];
1113
+ }
1114
+ function attachGettersToPacks(packs) {
1115
+ Object.entries(packs).forEach(([, pack]) => {
1116
+ flatMapDeep$1(Object.entries(pack), ([key, value]) => attachGetter([`I18N.${key}`, value]));
1117
+ });
1118
+ }
1119
+ /**
1120
+ * Alain + kiwi i18n runtime. Packs come from `GEEX_I18N_PACKS` (host zh-CN/en-US assembly).
1121
+ */
1122
+ class GeexI18nService {
1123
+ _default = DEFAULT;
1124
+ change$ = new BehaviorSubject(null);
1125
+ kiwiLangs;
1126
+ _langs = Object.keys(LANGS).map(code => {
1127
+ const item = LANGS[code];
1128
+ return { code, text: item.text, abbr: item.abbr };
1129
+ });
1130
+ settings = inject(SettingsService);
1131
+ nzI18nService = inject(NzI18nService);
1132
+ delonLocaleService = inject(DelonLocaleService);
1133
+ translate = inject(TranslateService);
1134
+ packs = inject(GEEX_I18N_PACKS);
1135
+ constructor() {
1136
+ this.kiwiLangs = this.packs ?? {};
1137
+ attachGettersToPacks(this.kiwiLangs);
1138
+ I18N = kiwiIntl.init(DEFAULT, this.kiwiLangs);
1139
+ const lans = this._langs.map(item => item.code);
1140
+ this.translate.addLangs(lans);
1141
+ const defaultLan = this.getDefaultLang().toLowerCase();
1142
+ this._default = lans.includes(defaultLan) ? defaultLan : DEFAULT;
1143
+ this.use(this._default);
1144
+ }
1145
+ /** Current kiwi dictionary (also mirrored by module `I18N`). */
1146
+ get dictionary() {
1147
+ return I18N;
1148
+ }
1149
+ getDefaultLang() {
1150
+ if (this.settings.layout.lang) {
1151
+ return this.settings.layout.lang;
1152
+ }
1153
+ return (navigator.languages?.[0] || navigator.language || DEFAULT).toLowerCase();
1154
+ }
1155
+ updateLangData(lang) {
1156
+ const item = LANGS[lang.toLocaleLowerCase()] ?? LANGS[DEFAULT];
1157
+ registerLocaleData(item.ng);
1158
+ this.nzI18nService.setLocale(item.zorro);
1159
+ this.nzI18nService.setDateLocale(item.date);
1160
+ this.delonLocaleService.setLocale(item.delon);
1161
+ I18N = kiwiIntl.init(lang, this.kiwiLangs);
1162
+ }
1163
+ get change() {
1164
+ return this.change$.asObservable().pipe(filter$1(w => w != null));
1165
+ }
1166
+ merge(translations) {
1167
+ merge(this.kiwiLangs, translations);
1168
+ }
1169
+ use(lang) {
1170
+ lang = lang || this.translate.getDefaultLang() || this._default;
1171
+ if (this.currentLang === lang) {
1172
+ return;
1173
+ }
1174
+ this.updateLangData(lang);
1175
+ this.translate.use(lang).subscribe(() => this.change$.next(lang));
1176
+ }
1177
+ getLangs() {
1178
+ return this._langs;
1179
+ }
1180
+ fanyi(key, interpolateParams) {
1181
+ const result = this.translate.instant(key, interpolateParams);
1182
+ if (key == result) {
1183
+ return `I18N.${key}`;
1184
+ }
1185
+ return result;
1186
+ }
1187
+ get defaultLang() {
1188
+ return this._default;
1189
+ }
1190
+ get currentLang() {
1191
+ return this.translate.currentLang || this.translate.getDefaultLang() || this._default;
1192
+ }
1193
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: GeexI18nService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1194
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: GeexI18nService });
1195
+ }
1196
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: GeexI18nService, decorators: [{
1197
+ type: Injectable
1198
+ }], ctorParameters: () => [] });
1199
+
1200
+ /**
1201
+ * Stable DI surface for `GEEX_I18N` that tracks module `I18N` reassignments
1202
+ * without depending on `GeexI18nService` (avoids TranslateService cycle).
1203
+ */
1204
+ function createGeexI18nDictionaryProxy() {
1205
+ const proxy = new Proxy({}, {
1206
+ get(_target, prop, receiver) {
1207
+ const dict = I18N;
1208
+ if (dict == null) {
1209
+ return undefined;
1210
+ }
1211
+ const value = Reflect.get(dict, prop, receiver);
1212
+ if (typeof value === "function") {
1213
+ return value.bind(dict);
1214
+ }
1215
+ return value;
1216
+ },
1217
+ });
1218
+ return proxy;
1219
+ }
1220
+
1221
+ /**
1222
+ * Register kiwi packs + GeexI18nService + Alain/ngx-translate wiring.
1223
+ */
1224
+ function provideGeexI18n(packs, options = {}) {
1225
+ return [
1226
+ { provide: GEEX_I18N_PACKS, useValue: packs },
1227
+ GeexI18nService,
1228
+ { provide: GEEX_I18N_SERVICE, useExisting: GeexI18nService },
1229
+ {
1230
+ provide: GEEX_I18N,
1231
+ useFactory: () => createGeexI18nDictionaryProxy(),
1232
+ },
1233
+ { provide: ALAIN_I18N_TOKEN, useExisting: GeexI18nService },
1234
+ importProvidersFrom(TranslateModule.forRoot({
1235
+ loader: {
1236
+ provide: TranslateLoader,
1237
+ useClass: GeexTranslateLoader,
1238
+ },
1239
+ fallbackLang: options.fallbackLang ?? "en",
1240
+ })),
1241
+ ];
1242
+ }
1243
+
1244
+ const GEEX_CANCEL_AUTHENTICATION_DOCUMENT = new InjectionToken("GEEX_CANCEL_AUTHENTICATION_DOCUMENT");
1245
+ /** Header profile route (default `/identity/me`). */
1246
+ const GEEX_PROFILE_PATH = new InjectionToken("GEEX_PROFILE_PATH", {
1247
+ providedIn: "root",
1248
+ factory: () => "/identity/me",
1249
+ });
1250
+ /** Header profile menu label (default 个人中心). */
1251
+ const GEEX_PROFILE_LABEL = new InjectionToken("GEEX_PROFILE_LABEL", {
1252
+ providedIn: "root",
1253
+ factory: () => "个人中心",
1254
+ });
1255
+
1256
+ const cancelAuthenticationMutation = gql `
1257
+ mutation cancelAuthenticate {
1258
+ cancelAuthentication
1259
+ }
1260
+ `;
1261
+ class GeexAuthLogout {
1262
+ apollo = inject(Apollo);
1263
+ oauth = inject(OAuthService);
1264
+ settings = inject(SettingsService);
1265
+ acl = inject(ACLService);
1266
+ router = inject(Router);
1267
+ loginPath = inject(GEEX_LOGIN_PATH);
1268
+ afterLoginNavigate = inject(GEEX_AFTER_LOGIN_NAVIGATE);
1269
+ cancelDocument = inject(GEEX_CANCEL_AUTHENTICATION_DOCUMENT, { optional: true });
1270
+ async logout() {
1271
+ const mutation = this.cancelDocument ?? cancelAuthenticationMutation;
1272
+ await firstValueFrom(this.apollo.mutate({ mutation }));
1273
+ this.settings.setUser({});
1274
+ this.acl.set({});
1275
+ this.oauth.logOut();
1276
+ await this.router.navigateByUrl(this.loginPath).then(() => {
1277
+ this.afterLoginNavigate();
1278
+ });
1279
+ }
1280
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: GeexAuthLogout, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1281
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: GeexAuthLogout, providedIn: "root" });
1282
+ }
1283
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: GeexAuthLogout, decorators: [{
1284
+ type: Injectable,
1285
+ args: [{ providedIn: "root" }]
1286
+ }] });
1287
+
1288
+ function setByPath(target, path, value) {
1289
+ const parts = path.split(".");
1290
+ let cur = target;
1291
+ for (let i = 0; i < parts.length - 1; i++) {
1292
+ const key = parts[i];
1293
+ const next = cur[key];
1294
+ if (next == null || typeof next !== "object") {
1295
+ cur[key] = {};
1296
+ }
1297
+ cur = cur[key];
1298
+ }
1299
+ cur[parts[parts.length - 1]] = value;
1300
+ }
1301
+ /** Deep-set env from flat / dotted override keys. Host may pass typed `environment` objects. */
1302
+ function applyEnvironmentOverrides(env, override) {
1303
+ const target = env;
1304
+ for (const [key, value] of Object.entries(override)) {
1305
+ if (key.includes(".")) {
1306
+ setByPath(target, key, value);
1307
+ }
1308
+ else {
1309
+ target[key] = value;
1310
+ }
1311
+ }
1312
+ }
1313
+ /**
1314
+ * Loads `/assets/environment.override.js` (or options.url) and merges into env.
1315
+ * Missing / invalid override is non-fatal.
1316
+ */
1317
+ async function loadEnvironmentOverrides(env, options = {}) {
1318
+ const url = options.url ?? "/assets/environment.override.js";
1319
+ try {
1320
+ const mod = await import(/* @vite-ignore */ /* webpackIgnore: true */ url);
1321
+ const override = (mod.default ?? mod);
1322
+ if (override && typeof override === "object") {
1323
+ applyEnvironmentOverrides(env, override);
1324
+ return;
1325
+ }
1326
+ if (options.onInvalid) {
1327
+ options.onInvalid(override, url);
1328
+ }
1329
+ else {
1330
+ console.warn(`[environment] Invalid override export from ${url}, expected object. Using defaults.`, override);
1331
+ }
1332
+ }
1333
+ catch (error) {
1334
+ if (options.onLoadError) {
1335
+ options.onLoadError(error, url);
1336
+ }
1337
+ else {
1338
+ console.warn(`[environment] Failed to load ${url}, using defaults.`, error);
1339
+ }
1340
+ }
1341
+ }
1342
+
1343
+ function provideGeexHttp(options) {
1344
+ return [
1345
+ { provide: GEEX_API_BASE_URL, useValue: options.apiBaseUrl },
1346
+ GeexHttpInterceptor,
1347
+ { provide: HTTP_INTERCEPTORS, useExisting: GeexHttpInterceptor, multi: true },
1348
+ ];
1349
+ }
1350
+
1351
+ class BusinessComponentBase {
1352
+ acl = inject(ACLService);
1353
+ apollo = inject(Apollo);
1354
+ i18n = inject(GEEX_I18N_SERVICE, { optional: true });
1355
+ modal = inject(ModalHelper);
1356
+ msgSrv = inject(NzMessageService);
1357
+ nzModalSrv = inject(NzModalService);
1358
+ router = inject(Router);
1359
+ params;
1360
+ I18N = inject(GEEX_I18N);
1361
+ AppPermission = inject(GEEX_APP_PERMISSION);
1362
+ can(permission) {
1363
+ return this.acl.can(permission);
1364
+ }
1365
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: BusinessComponentBase, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1366
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: BusinessComponentBase });
1367
+ }
1368
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: BusinessComponentBase, decorators: [{
1369
+ type: Injectable
1370
+ }] });
1371
+
1372
+ // @ts-nocheck
1373
+ /* eslint-disable */
1374
+ // Converted from UMD rison.js for ng-packagr bundling
1375
+ var risonRegex = /^\s*(?:\([^()]*:[^()]*\)|!\([^()]*\)|!t|!f|!n|-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE]\d+)?|'(?:[^'!]|!(?:'|!))*'|[A-Za-z0-9_./~-]+)\s*$/;
1376
+ const exports = {};
1377
+ var rison = exports;
1378
+ //////////////////////////////////////////////////
1379
+ //
1380
+ // the stringifier is based on
1381
+ // http://json.org/json.js as of 2006-04-28 from json.org
1382
+ // the parser is based on
1383
+ // http://osteele.com/sources/openlaszlo/json
1384
+ //
1385
+ if (typeof rison == 'undefined')
1386
+ window.rison = {};
1387
+ /**
1388
+ * rules for an uri encoder that is more tolerant than encodeURIComponent
1389
+ *
1390
+ * encodeURIComponent passes ~!*()-_.'
1391
+ *
1392
+ * we also allow ,:@$/
1393
+ *
1394
+ */
1395
+ rison.uri_ok = {
1396
+ '~': true, '!': true, '*': true, '(': true, ')': true,
1397
+ '-': true, '_': true, '.': true, ',': true,
1398
+ ':': true, '@': true, '$': true,
1399
+ "\"": true, '/': true
1400
+ };
1401
+ /*
1402
+ * we divide the uri-safe glyphs into three sets
1403
+ * <rison> - used by rison ' ! : ( ) ,
1404
+ * <reserved> - not common in strings, reserved * @ $ & ; =
1405
+ *
1406
+ * we define <identifier> as anything that's not forbidden
1407
+ */
1408
+ /**
1409
+ * punctuation characters that are legal inside ids.
1410
+ */
1411
+ // this var isn't actually used
1412
+ //rison.idchar_punctuation = "_-./~";
1413
+ (function () {
1414
+ var l = [];
1415
+ for (var hi = 0; hi < 16; hi++) {
1416
+ for (var lo = 0; lo < 16; lo++) {
1417
+ if (hi + lo == 0)
1418
+ continue;
1419
+ var c = String.fromCharCode(hi * 16 + lo);
1420
+ if (!/\w|[-_.\/~]/.test(c))
1421
+ l.push('\\u00' + hi.toString(16) + lo.toString(16));
1422
+ }
1423
+ }
1424
+ /**
1425
+ * characters that are illegal inside ids.
1426
+ * <rison> and <reserved> classes are illegal in ids.
1427
+ *
1428
+ */
1429
+ rison.not_idchar = l.join("");
1430
+ //idcrx = new RegExp('[' + rison.not_idchar + ']');
1431
+ //console.log('NOT', (idcrx.test(' ')) );
1432
+ })();
1433
+ //rison.not_idchar = " \t\r\n\"<>[]{}'!=:(),*@$;&";
1434
+ rison.not_idchar = " '!:(),*@$";
1435
+ /**
1436
+ * characters that are illegal as the start of an id
1437
+ * this is so ids can't look like numbers.
1438
+ */
1439
+ rison.not_idstart = "-0123456789";
1440
+ (function () {
1441
+ var idrx = '[^' + rison.not_idstart + rison.not_idchar +
1442
+ '][^' + rison.not_idchar + ']*';
1443
+ rison.id_ok = new RegExp('^' + idrx + '$');
1444
+ // regexp to find the end of an id when parsing
1445
+ // g flag on the regexp is necessary for iterative regexp.exec()
1446
+ rison.next_id = new RegExp(idrx, 'g');
1447
+ })();
1448
+ /**
1449
+ * this is like encodeURIComponent() but quotes fewer characters.
1450
+ *
1451
+ * @see rison.uri_ok
1452
+ *
1453
+ * encodeURIComponent passes ~!*()-_.'
1454
+ * rison.quote also passes ,:@$/
1455
+ * and quotes " " as "+" instead of "%20"
1456
+ */
1457
+ rison.quote = function (x) {
1458
+ if (/^[-A-Za-z0-9~!*()_.",:@$\/]*$/.test(x))
1459
+ return x;
1460
+ return encodeURIComponent(x)
1461
+ .replace('%2C', ',', 'g')
1462
+ .replace('%3A', ':', 'g')
1463
+ .replace('%40', '@', 'g')
1464
+ .replace('%24', '$', 'g')
1465
+ .replace('%2F', '/', 'g')
1466
+ .replace('%20', '+', 'g');
1467
+ };
1468
+ //
1469
+ // based on json.js 2006-04-28 from json.org
1470
+ // license: http://www.json.org/license.html
1471
+ //
1472
+ // hacked by nix for use in uris.
1473
+ //
1474
+ (function () {
1475
+ var sq = {
1476
+ "\"": true, '!': true
1477
+ }, s = {
1478
+ array: function (x) {
1479
+ var a = ['!('], b, f, i, l = x.length, v;
1480
+ for (i = 0; i < l; i += 1) {
1481
+ v = x[i];
1482
+ f = s[typeof v];
1483
+ if (f) {
1484
+ v = f(v);
1485
+ if (typeof v == 'string') {
1486
+ if (b) {
1487
+ a[a.length] = ',';
1488
+ }
1489
+ a[a.length] = v;
1490
+ b = true;
1491
+ }
1492
+ }
1493
+ }
1494
+ a[a.length] = ')';
1495
+ return a.join("");
1496
+ },
1497
+ 'boolean': function (x) {
1498
+ if (x)
1499
+ return '!t';
1500
+ return '!f';
1501
+ },
1502
+ 'null': function (x) {
1503
+ return "!n";
1504
+ },
1505
+ number: function (x) {
1506
+ if (!isFinite(x))
1507
+ return '!n';
1508
+ // strip '+' out of exponent, '-' is ok though
1509
+ return String(x).replace(/\+/, "");
1510
+ },
1511
+ object: function (x) {
1512
+ if (x) {
1513
+ if (x instanceof Array) {
1514
+ return s.array(x);
1515
+ }
1516
+ if (x instanceof Date) {
1517
+ return `!d"${x.toISOString()}"`;
1518
+ }
1519
+ // WILL: will this work on non-Firefox browsers?
1520
+ if (typeof x.__prototype__ === 'object' && typeof x.__prototype__.encode_rison !== 'undefined')
1521
+ return x.encode_rison();
1522
+ var a = ['('], b, f, i, v, ki, ks = [];
1523
+ for (i in x)
1524
+ ks[ks.length] = i;
1525
+ ks.sort();
1526
+ for (ki = 0; ki < ks.length; ki++) {
1527
+ i = ks[ki];
1528
+ v = x[i];
1529
+ f = s[typeof v];
1530
+ if (f) {
1531
+ v = f(v);
1532
+ if (typeof v == 'string') {
1533
+ if (b) {
1534
+ a[a.length] = ',';
1535
+ }
1536
+ a.push(s.string(i), ':', v);
1537
+ b = true;
1538
+ }
1539
+ }
1540
+ }
1541
+ a[a.length] = ')';
1542
+ return a.join("");
1543
+ }
1544
+ return '!n';
1545
+ },
1546
+ string: function (x) {
1547
+ if (x == "")
1548
+ return "\"\"";
1549
+ if (rison.id_ok.test(x))
1550
+ return x;
1551
+ x = x.replace(/(['!])/g, function (a, b) {
1552
+ if (sq[b])
1553
+ return '!' + b;
1554
+ return b;
1555
+ });
1556
+ return "\"" + x + "\"";
1557
+ },
1558
+ undefined: function (x) {
1559
+ throw new Error("rison can't encode the undefined value");
1560
+ }
1561
+ };
1562
+ /**
1563
+ * rison-encode a javascript structure
1564
+ *
1565
+ * implemementation based on Douglas Crockford's json.js:
1566
+ * http://json.org/json.js as of 2006-04-28 from json.org
1567
+ *
1568
+ */
1569
+ rison.encode = function (v) {
1570
+ return s[typeof v](v);
1571
+ };
1572
+ /**
1573
+ * rison-encode a javascript object without surrounding parens
1574
+ *
1575
+ */
1576
+ rison.encode_object = function (v) {
1577
+ if (typeof v != 'object' || v === null || v instanceof Array)
1578
+ throw new Error("rison.encode_object expects an object argument");
1579
+ var r = s[typeof v](v);
1580
+ return r.substring(1, r.length - 1);
1581
+ };
1582
+ /**
1583
+ * rison-encode a javascript array without surrounding parens
1584
+ *
1585
+ */
1586
+ rison.encode_array = function (v) {
1587
+ if (!(v instanceof Array))
1588
+ throw new Error("rison.encode_array expects an array argument");
1589
+ var r = s[typeof v](v);
1590
+ return r.substring(2, r.length - 1);
1591
+ };
1592
+ /**
1593
+ * rison-encode and uri-encode a javascript structure
1594
+ *
1595
+ */
1596
+ rison.encode_uri = function (v) {
1597
+ return rison.quote(s[typeof v](v));
1598
+ };
1599
+ })();
1600
+ //
1601
+ // based on openlaszlo-json and hacked by nix for use in uris.
1602
+ //
1603
+ // Author: Oliver Steele
1604
+ // Copyright: Copyright 2006 Oliver Steele. All rights reserved.
1605
+ // Homepage: http://osteele.com/sources/openlaszlo/json
1606
+ // License: MIT License.
1607
+ // Version: 1.0
1608
+ /**
1609
+ * parse a rison string into a javascript structure.
1610
+ *
1611
+ * this is the simplest decoder entry point.
1612
+ *
1613
+ * based on Oliver Steele's OpenLaszlo-JSON
1614
+ * http://osteele.com/sources/openlaszlo/json
1615
+ */
1616
+ rison.decode = function (r) {
1617
+ var errcb = function (e) { throw Error('rison decoder error: ' + e); };
1618
+ var p = new rison.parser(errcb);
1619
+ return p.parse(r);
1620
+ };
1621
+ /**
1622
+ * decode a GeexRouter query param value.
1623
+ * falls back to the raw string when the value is not valid rison
1624
+ * (e.g. external OAuth callbacks that bypass GeexRouter encoding).
1625
+ */
1626
+ rison.decode_query_param = function (r) {
1627
+ if (r == null || r === "") {
1628
+ return "";
1629
+ }
1630
+ try {
1631
+ var decoded = rison.decode(r);
1632
+ return decoded == null ? "" : String(decoded);
1633
+ }
1634
+ catch (e) {
1635
+ return String(r);
1636
+ }
1637
+ };
1638
+ /**
1639
+ * parse an o-rison string into a javascript structure.
1640
+ *
1641
+ * this simply adds parentheses around the string before parsing.
1642
+ */
1643
+ rison.decode_object = function (r) {
1644
+ return rison.decode('(' + r + ')');
1645
+ };
1646
+ /**
1647
+ * parse an a-rison string into a javascript structure.
1648
+ *
1649
+ * this simply adds array markup around the string before parsing.
1650
+ */
1651
+ rison.decode_array = function (r) {
1652
+ return rison.decode('!(' + r + ')');
1653
+ };
1654
+ /**
1655
+ * construct a new parser object for reuse.
1656
+ *
1657
+ * @constructor
1658
+ * @class A Rison parser class. You should probably
1659
+ * use rison.decode instead.
1660
+ * @see rison.decode
1661
+ */
1662
+ rison.parser = function (errcb) {
1663
+ this.errorHandler = errcb;
1664
+ };
1665
+ /**
1666
+ * a string containing acceptable whitespace characters.
1667
+ * by default the rison decoder tolerates no whitespace.
1668
+ * to accept whitespace set rison.parser.WHITESPACE = " \t\n\r\f";
1669
+ */
1670
+ rison.parser.WHITESPACE = "";
1671
+ // expose this as-is?
1672
+ rison.parser.prototype.setOptions = function (options) {
1673
+ if (options['errorHandler'])
1674
+ this.errorHandler = options.errorHandler;
1675
+ };
1676
+ /**
1677
+ * parse a rison string into a javascript structure.
1678
+ */
1679
+ rison.parser.prototype.parse = function (str) {
1680
+ this.string = str;
1681
+ this.index = 0;
1682
+ this.message = null;
1683
+ var value = this.readValue();
1684
+ if (!this.message && this.next())
1685
+ value = this.error("unable to parse string as rison: '" + rison.encode(str) + "\"");
1686
+ if (this.message && this.errorHandler)
1687
+ this.errorHandler(this.message, this.index);
1688
+ return value;
1689
+ };
1690
+ rison.parser.prototype.error = function (message) {
1691
+ if (typeof (console) != 'undefined')
1692
+ console.log('rison parser error: ', message);
1693
+ this.message = message;
1694
+ return undefined;
1695
+ };
1696
+ rison.parser.prototype.readValue = function () {
1697
+ var c = this.next();
1698
+ var fn = c && this.table[c];
1699
+ if (fn)
1700
+ return fn.apply(this);
1701
+ // fell through table, parse as an id
1702
+ var s = this.string;
1703
+ var i = this.index - 1;
1704
+ // Regexp.lastIndex may not work right in IE before 5.5?
1705
+ // g flag on the regexp is also necessary
1706
+ rison.next_id.lastIndex = i;
1707
+ var m = rison.next_id.exec(s);
1708
+ // console.log('matched id', i, r.lastIndex);
1709
+ if (m.length > 0) {
1710
+ var id = m[0];
1711
+ this.index = i + id.length;
1712
+ return id; // a string
1713
+ }
1714
+ if (c)
1715
+ return this.error("invalid character: '" + c + "\"");
1716
+ return this.error("empty expression");
1717
+ };
1718
+ rison.parser.parse_date = function (parser) {
1719
+ var c;
1720
+ while ((c = parser.next()) != "Z") {
1721
+ --parser.index;
1722
+ var n = parser.readValue();
1723
+ if (typeof n == "undefined")
1724
+ return undefined;
1725
+ return new Date(n);
1726
+ }
1727
+ return undefined;
1728
+ };
1729
+ rison.parser.parse_array = function (parser) {
1730
+ var ar = [];
1731
+ var c;
1732
+ while ((c = parser.next()) != ')') {
1733
+ if (!c)
1734
+ return parser.error("unmatched '!('");
1735
+ if (ar.length) {
1736
+ if (c != ',')
1737
+ parser.error("missing ','");
1738
+ }
1739
+ else if (c == ',') {
1740
+ return parser.error("extra ','");
1741
+ }
1742
+ else
1743
+ --parser.index;
1744
+ var n = parser.readValue();
1745
+ if (typeof n == "undefined")
1746
+ return undefined;
1747
+ ar.push(n);
1748
+ }
1749
+ return ar;
1750
+ };
1751
+ rison.parser.bangs = {
1752
+ t: true,
1753
+ f: false,
1754
+ n: null,
1755
+ '(': rison.parser.parse_array,
1756
+ d: rison.parser.parse_date
1757
+ };
1758
+ rison.parser.prototype.table = {
1759
+ '!': function () {
1760
+ var s = this.string;
1761
+ var c = s.charAt(this.index++);
1762
+ if (!c)
1763
+ return this.error('"!" at end of input');
1764
+ var x = rison.parser.bangs[c];
1765
+ if (typeof (x) == 'function') {
1766
+ return x.call(null, this);
1767
+ }
1768
+ else if (typeof (x) == 'undefined') {
1769
+ return this.error('unknown literal: "!' + c + '"');
1770
+ }
1771
+ return x;
1772
+ },
1773
+ '(': function () {
1774
+ var o = {};
1775
+ var c;
1776
+ var count = 0;
1777
+ while ((c = this.next()) != ')') {
1778
+ if (count) {
1779
+ if (c != ',')
1780
+ this.error("missing ','");
1781
+ }
1782
+ else if (c == ',') {
1783
+ return this.error("extra ','");
1784
+ }
1785
+ else
1786
+ --this.index;
1787
+ var k = this.readValue();
1788
+ if (typeof k == "undefined")
1789
+ return undefined;
1790
+ if (this.next() != ':')
1791
+ return this.error("missing ':'");
1792
+ var v = this.readValue();
1793
+ if (typeof v == "undefined")
1794
+ return undefined;
1795
+ o[k] = v;
1796
+ count++;
1797
+ }
1798
+ return o;
1799
+ },
1800
+ "\"": function () {
1801
+ var s = this.string;
1802
+ var i = this.index;
1803
+ var start = i;
1804
+ var segments = [];
1805
+ var c;
1806
+ while ((c = s.charAt(i++)) != "\"") {
1807
+ //if (i == s.length) return this.error('unmatched "\""');
1808
+ if (!c)
1809
+ return this.error('unmatched "\""');
1810
+ if (c == '!') {
1811
+ if (start < i - 1)
1812
+ segments.push(s.slice(start, i - 1));
1813
+ c = s.charAt(i++);
1814
+ if ("!'".indexOf(c) >= 0) {
1815
+ segments.push(c);
1816
+ }
1817
+ else {
1818
+ return this.error('invalid string escape: "!' + c + '"');
1819
+ }
1820
+ start = i;
1821
+ }
1822
+ }
1823
+ if (start < i - 1)
1824
+ segments.push(s.slice(start, i - 1));
1825
+ this.index = i;
1826
+ return segments.length == 1 ? segments[0] : segments.join("");
1827
+ },
1828
+ // Also any digit. The statement that follows this table
1829
+ // definition fills in the digits.
1830
+ '-': function () {
1831
+ var s = this.string;
1832
+ var i = this.index;
1833
+ var start = i - 1;
1834
+ var state = 'int';
1835
+ var permittedSigns = '-';
1836
+ var transitions = {
1837
+ 'int+.': 'frac',
1838
+ 'int+e': 'exp',
1839
+ 'frac+e': 'exp'
1840
+ };
1841
+ do {
1842
+ var c = s.charAt(i++);
1843
+ if (!c)
1844
+ break;
1845
+ if ('0' <= c && c <= '9')
1846
+ continue;
1847
+ if (permittedSigns.indexOf(c) >= 0) {
1848
+ permittedSigns = "";
1849
+ continue;
1850
+ }
1851
+ state = transitions[state + '+' + c.toLowerCase()];
1852
+ if (state == 'exp')
1853
+ permittedSigns = '-';
1854
+ } while (state);
1855
+ this.index = --i;
1856
+ s = s.slice(start, i);
1857
+ if (s == '-')
1858
+ return this.error("invalid number");
1859
+ return Number(s);
1860
+ }
1861
+ };
1862
+ // copy table['-'] to each of table[i] | i <- '0'..'9':
1863
+ (function (table) {
1864
+ for (var i = 0; i <= 9; i++)
1865
+ table[String(i)] = table['-'];
1866
+ })(rison.parser.prototype.table);
1867
+ // return the next non-whitespace character, or undefined
1868
+ rison.parser.prototype.next = function () {
1869
+ var s = this.string;
1870
+ var i = this.index;
1871
+ do {
1872
+ if (i == s.length)
1873
+ return undefined;
1874
+ var c = s.charAt(i++);
1875
+ } while (rison.parser.WHITESPACE.indexOf(c) >= 0);
1876
+ this.index = i;
1877
+ return c;
1878
+ };
1879
+
1880
+ function geexIsEqual$1(a, b) {
1881
+ if (Object.is(a, b)) {
1882
+ return true;
1883
+ }
1884
+ try {
1885
+ return JSON.stringify(a) === JSON.stringify(b);
1886
+ }
1887
+ catch {
1888
+ return false;
1889
+ }
1890
+ }
1891
+ class RoutedComponent extends BusinessComponentBase {
1892
+ defaultParams;
1893
+ paramsForm;
1894
+ params;
1895
+ title = signal(undefined, ...(ngDevMode ? [{ debugName: "title" }] : []));
1896
+ cdr = inject(ChangeDetectorRef);
1897
+ fb = inject(FormBuilder);
1898
+ loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
1899
+ loadingSrv = inject(LoadingService);
1900
+ location = inject(Location);
1901
+ reuseTabSrv = inject(ReuseTabService);
1902
+ route = inject(ActivatedRoute);
1903
+ titleSrv = inject(TitleService);
1904
+ async ngOnInit() {
1905
+ this.defaultParams = Object.fromEntries(Object.entries(this.routeParamsMappings).map(([key, mapping]) => [key, mapping.default]));
1906
+ this.params ??= signal(this.defaultParams);
1907
+ this.paramsForm ??= this.buildParamsForm(this.defaultParams);
1908
+ }
1909
+ constructor() {
1910
+ super();
1911
+ effect(async () => {
1912
+ await this.handleRouteReload();
1913
+ }, {});
1914
+ }
1915
+ /** Full route-reload pipeline; override to replace navigation side effects. */
1916
+ async handleRouteReload() {
1917
+ this.router.navigationReload();
1918
+ this.loading.set(true);
1919
+ try {
1920
+ const routeParams = {
1921
+ pathParams: await this.route.params.firstValuePromise(),
1922
+ queryParams: await this.route.queryParams.firstValuePromise(),
1923
+ fragment: await this.route.fragment.firstValuePromise(),
1924
+ };
1925
+ const params = await this.resolve(routeParams);
1926
+ this.paramsForm.reset(params, { emitEvent: false });
1927
+ this.params.set(params);
1928
+ await this.beforeOnRouted(params);
1929
+ await this.onRouted(params);
1930
+ await this.afterOnRouted(params);
1931
+ const title = this.title();
1932
+ if (title)
1933
+ this.reuseTabSrv.title = title;
1934
+ }
1935
+ finally {
1936
+ this.loading.set(false);
1937
+ this.cdr.detectChanges();
1938
+ }
1939
+ }
1940
+ beforeOnRouted(_params) { }
1941
+ afterOnRouted(_params) { }
1942
+ buildParamsForm(defaults) {
1943
+ return this.fb.group(Object.fromEntries(Object.entries(defaults).map(x => [x[0], new FormControl(x[1])])));
1944
+ }
1945
+ decodeQueryParam(raw) {
1946
+ return exports.decode(raw);
1947
+ }
1948
+ async resolve({ pathParams, queryParams, fragment }) {
1949
+ const params = {};
1950
+ if (this.routeParamsMappings) {
1951
+ const mappings = Object.entries(this.routeParamsMappings);
1952
+ mappings.forEach(([key, mappingValue]) => {
1953
+ const value = match(mappingValue.position)
1954
+ .with("pathParams", () => pathParams?.[key])
1955
+ .with("queryParams", () => (queryParams?.[key] ? this.decodeQueryParam(queryParams[key]) : undefined))
1956
+ .with("fragment", () => fragment)
1957
+ .exhaustive();
1958
+ params[key] = value ?? mappingValue.default;
1959
+ });
1960
+ }
1961
+ return params;
1962
+ }
1963
+ refresh() {
1964
+ const { pathParams, queryParams, fragment } = this.paramsToRouteParams(this.paramsForm.value);
1965
+ this.router.navigate([".", pathParams], {
1966
+ relativeTo: this.route,
1967
+ queryParams,
1968
+ fragment,
1969
+ forceReload: true,
1970
+ replaceUrl: true,
1971
+ });
1972
+ }
1973
+ reset() {
1974
+ this.paramsForm.reset(this.defaultParams, { emitEvent: false });
1975
+ this.refresh();
1976
+ }
1977
+ paramsToRouteParams(params) {
1978
+ const routeParams = { pathParams: {}, queryParams: {}, fragment: undefined };
1979
+ const mappings = Object.entries(this.routeParamsMappings);
1980
+ mappings.forEach(([key, mappingValue]) => {
1981
+ const paramValue = params[key] ?? mappingValue.default;
1982
+ const defaultParamValue = this.defaultParams[key];
1983
+ if (paramValue == undefined || this.isEqualToDefault(paramValue, defaultParamValue)) {
1984
+ return;
1985
+ }
1986
+ match(mappingValue.position)
1987
+ .with("pathParams", () => (routeParams.pathParams[key] = paramValue))
1988
+ .with("queryParams", () => (routeParams.queryParams[key] = paramValue))
1989
+ .with("fragment", () => (routeParams.fragment = paramValue))
1990
+ .exhaustive();
1991
+ });
1992
+ return routeParams;
1993
+ }
1994
+ isEqualToDefault(value, defaultValue) {
1995
+ return geexIsEqual$1(value, defaultValue);
1996
+ }
1997
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: RoutedComponent, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1998
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: RoutedComponent });
1999
+ }
2000
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: RoutedComponent, decorators: [{
2001
+ type: Injectable
2002
+ }], ctorParameters: () => [] });
2003
+
2004
+ class ListPageParams {
2005
+ pi;
2006
+ ps;
2007
+ /** Host GraphQL sort input; kept loose to match module-specific SortInput types. */
2008
+ sort;
2009
+ }
2010
+ class RoutedListComponent extends RoutedComponent {
2011
+ data = signal([], ...(ngDevMode ? [{ debugName: "data" }] : []));
2012
+ total = signal(0, ...(ngDevMode ? [{ debugName: "total" }] : []));
2013
+ selectedData = signal([], ...(ngDevMode ? [{ debugName: "selectedData" }] : []));
2014
+ allSelected = computed(() => {
2015
+ return this.selectedData().length > 0 && this.data()?.length == this.selectedData().length;
2016
+ }, ...(ngDevMode ? [{ debugName: "allSelected" }] : []));
2017
+ onAllChecked(value) {
2018
+ this.selectedData.set(value ? this.data() : []);
2019
+ }
2020
+ onItemChecked(data, checked) {
2021
+ if (checked) {
2022
+ this.selectedData.update(selectedData => [...selectedData, data]);
2023
+ }
2024
+ else {
2025
+ this.selectedData.update(selectedData => selectedData.filter(x => x.id !== data.id));
2026
+ }
2027
+ }
2028
+ async tableChange(args) {
2029
+ if (args.type == "loaded") {
2030
+ return;
2031
+ }
2032
+ if (args.type == "checkbox") {
2033
+ this.onTableCheckbox(args);
2034
+ return;
2035
+ }
2036
+ if (args.type == "pi" || args.type == "ps") {
2037
+ this.onTablePage(args);
2038
+ }
2039
+ if (args.sort?.column?.index) {
2040
+ this.onTableSort(args);
2041
+ }
2042
+ }
2043
+ onTableCheckbox(args) {
2044
+ this.selectedData.set(args.checkbox);
2045
+ }
2046
+ onTablePage(args) {
2047
+ if (args.pi !== this.paramsForm.value.pi || args.ps !== this.paramsForm.value.ps) {
2048
+ this.paramsForm.patchValue({ pi: args.pi, ps: args.ps });
2049
+ this.refresh();
2050
+ }
2051
+ }
2052
+ onTableSort(args) {
2053
+ const thisSortName = args.sort.column["indexKey"];
2054
+ let sorts = args.sort.map["sort"].split("-").map((x) => x.split("."));
2055
+ const thisSort = sorts.find((x) => x[0] == thisSortName);
2056
+ if (thisSort) {
2057
+ sorts = sorts.filter((x) => x !== thisSort);
2058
+ }
2059
+ sorts.push(thisSort);
2060
+ sorts = sorts.filter((x) => x != undefined && x[0] != "");
2061
+ const sortsForm = new FormGroup(Object.fromEntries(sorts.map((x) => [x[0], new FormControl(x[1])])));
2062
+ this.paramsForm.setControl("sort", sortsForm);
2063
+ this.refresh();
2064
+ }
2065
+ batchOperation(operation, entityType, remark) {
2066
+ return new Promise((resolve) => {
2067
+ const selectedData = this.selectedData();
2068
+ const filtered = this.filterBatchIds(operation, selectedData);
2069
+ if (filtered.error) {
2070
+ this.msgSrv.warning(filtered.error);
2071
+ resolve(false);
2072
+ return;
2073
+ }
2074
+ const ids = filtered.ids;
2075
+ if (!ids.length) {
2076
+ this.msgSrv.warning("至少选择一项");
2077
+ resolve(false);
2078
+ return;
2079
+ }
2080
+ const apiName = this.buildBatchMutation(operation, entityType);
2081
+ this.confirmBatch(operation, apiName, ids, remark).then(resolve);
2082
+ });
2083
+ }
2084
+ filterBatchIds(operation, selectedData) {
2085
+ let ids = selectedData.map(x => x["id"]);
2086
+ if (selectedData[0]?.["approveStatus"] == undefined) {
2087
+ return { ids };
2088
+ }
2089
+ let text = "";
2090
+ switch (operation) {
2091
+ case "delete":
2092
+ case "submit":
2093
+ ids = selectedData.filter(x => x["approveStatus"] === "DEFAULT").map(x => x["id"]);
2094
+ text = "只能操作未上报状态的数据";
2095
+ break;
2096
+ case "approve":
2097
+ case "unSubmit":
2098
+ ids = selectedData.filter(x => x["approveStatus"] === "SUBMITTED").map(x => x["id"]);
2099
+ text = "只能操作已上报状态的数据";
2100
+ break;
2101
+ case "unApprove":
2102
+ ids = selectedData.filter(x => x["approveStatus"] === "APPROVED").map(x => x["id"]);
2103
+ text = "只能操作已审核状态的数据";
2104
+ break;
2105
+ default:
2106
+ break;
2107
+ }
2108
+ if (ids.length !== selectedData.length) {
2109
+ return { ids, error: text };
2110
+ }
2111
+ return { ids };
2112
+ }
2113
+ buildBatchMutation(operation, entityType) {
2114
+ if (operation === "delete") {
2115
+ return `
2116
+ mutation ${operation}${entityType}($ids: [String!]!) {
2117
+ ${operation}${entityType}(ids: $ids)
2118
+ }
2119
+ `;
2120
+ }
2121
+ return `
2122
+ mutation ${operation}${entityType}($ids: [String], $remark:String) {
2123
+ ${operation}${entityType}(ids: $ids, remark:$remark)
2124
+ }
2125
+ `;
2126
+ }
2127
+ confirmBatch(operation, apiName, ids, remark) {
2128
+ return new Promise((resolve) => {
2129
+ const common = this.I18N.Common;
2130
+ const alertMessage = common?.action?.get?.(operation) ?? operation;
2131
+ this.nzModalSrv.confirm({
2132
+ nzTitle: `确认${alertMessage}吗?`,
2133
+ nzOnOk: async () => {
2134
+ await this.apollo.mutate({
2135
+ mutation: gql$1(apiName),
2136
+ variables: {
2137
+ remark,
2138
+ ids,
2139
+ },
2140
+ }).firstValuePromise();
2141
+ this.msgSrv.success(common?.message?.get?.(operation) ?? "ok");
2142
+ this.refresh();
2143
+ resolve(true);
2144
+ },
2145
+ nzOnCancel: () => resolve(false),
2146
+ });
2147
+ });
2148
+ }
2149
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: RoutedListComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
2150
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.0", type: RoutedListComponent, isStandalone: true, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "", isInline: true });
2151
+ }
2152
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: RoutedListComponent, decorators: [{
2153
+ type: Component,
2154
+ args: [{ template: "", standalone: true }]
2155
+ }] });
2156
+
2157
+ function geexIsEqual(a, b) {
2158
+ if (Object.is(a, b)) {
2159
+ return true;
2160
+ }
2161
+ try {
2162
+ return JSON.stringify(a) === JSON.stringify(b);
2163
+ }
2164
+ catch {
2165
+ return false;
2166
+ }
2167
+ }
2168
+ class RoutedEditComponent extends RoutedComponent {
2169
+ entity;
2170
+ entityForm;
2171
+ originalValue;
2172
+ async close() {
2173
+ if (await this.closableCheck()) {
2174
+ await this.back();
2175
+ }
2176
+ }
2177
+ closableCheck() {
2178
+ if (!this.isEntityDirty()) {
2179
+ return Promise.resolve(true);
2180
+ }
2181
+ return new Promise((resolve) => {
2182
+ this.nzModalSrv.confirm({
2183
+ nzTitle: this.unsavedConfirmTitle(),
2184
+ nzOnOk: async () => {
2185
+ this.entityForm?.reset(this.originalValue);
2186
+ this.entityForm?.markAsPristine();
2187
+ resolve(true);
2188
+ },
2189
+ nzOnCancel: () => {
2190
+ resolve(false);
2191
+ },
2192
+ });
2193
+ });
2194
+ }
2195
+ isEntityDirty() {
2196
+ return !geexIsEqual(this.entityForm?.value, this.originalValue);
2197
+ }
2198
+ unsavedConfirmTitle() {
2199
+ return "当前页面内容未保存,确定离开?";
2200
+ }
2201
+ async back(reload = false) {
2202
+ if (reload) {
2203
+ if (this.params().id) {
2204
+ await this.router.navigate(["../../"], { relativeTo: this.route, replaceUrl: true, forceReload: reload });
2205
+ }
2206
+ else {
2207
+ await this.router.navigate(["../"], { relativeTo: this.route, replaceUrl: true, forceReload: reload });
2208
+ }
2209
+ }
2210
+ else {
2211
+ this.location.back();
2212
+ }
2213
+ }
2214
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: RoutedEditComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
2215
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.0", type: RoutedEditComponent, isStandalone: true, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "", isInline: true });
2216
+ }
2217
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: RoutedEditComponent, decorators: [{
2218
+ type: Component,
2219
+ args: [{
2220
+ template: "",
2221
+ standalone: true,
2222
+ }]
2223
+ }] });
2224
+
2225
+ /**
2226
+ * Base for components opened inside nz-modal.
2227
+ * NzModalRef is required; only use for modal-hosted components.
2228
+ */
2229
+ class ModalComponentBase {
2230
+ title = "新增";
2231
+ loading = false;
2232
+ nzModalRef = inject(NzModalRef);
2233
+ success(result = true) {
2234
+ if (result) {
2235
+ this.nzModalRef.close(result);
2236
+ this.afterClose(result);
2237
+ }
2238
+ else {
2239
+ this.close();
2240
+ }
2241
+ }
2242
+ close(_$event) {
2243
+ this.nzModalRef.close();
2244
+ this.afterClose(undefined);
2245
+ }
2246
+ /** Hook after modal closes; override for cleanup / analytics. */
2247
+ afterClose(_result) { }
2248
+ }
2249
+
2250
+ class TreeTableComponentBase {
2251
+ mapOfExpandedData = {};
2252
+ I18N = inject(GEEX_I18N);
2253
+ getNodeKey(node) {
2254
+ return node["key"];
2255
+ }
2256
+ getNodeChildren(node) {
2257
+ return node["children"];
2258
+ }
2259
+ collapse(array, data, $event) {
2260
+ if (!$event) {
2261
+ const children = this.getNodeChildren(data);
2262
+ if (children) {
2263
+ children.forEach(d => {
2264
+ const target = array.find(a => this.getNodeKey(a) === this.getNodeKey(d));
2265
+ target["expand"] = false;
2266
+ this.collapse(array, target, false);
2267
+ });
2268
+ }
2269
+ }
2270
+ }
2271
+ convertTreeToList(root) {
2272
+ const stack = [];
2273
+ const array = [];
2274
+ const hashMap = {};
2275
+ stack.push({ ...root, level: 0, expand: false });
2276
+ while (stack.length !== 0) {
2277
+ const node = stack.pop();
2278
+ this.visitNode(node, hashMap, array);
2279
+ const children = this.getNodeChildren(node);
2280
+ if (children) {
2281
+ for (let i = children.length - 1; i >= 0; i--) {
2282
+ stack.push({
2283
+ ...children[i],
2284
+ level: (node["level"] ?? 0) + 1,
2285
+ expand: false,
2286
+ parent: node,
2287
+ });
2288
+ }
2289
+ }
2290
+ }
2291
+ return array;
2292
+ }
2293
+ visitNode(node, hashMap, array) {
2294
+ const key = this.getNodeKey(node);
2295
+ if (!hashMap[key]) {
2296
+ hashMap[key] = true;
2297
+ array.push(node);
2298
+ }
2299
+ }
2300
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: TreeTableComponentBase, deps: [], target: i0.ɵɵFactoryTarget.Component });
2301
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.0", type: TreeTableComponentBase, isStandalone: true, selector: "ng-component", ngImport: i0, template: "", isInline: true });
2302
+ }
2303
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: TreeTableComponentBase, decorators: [{
2304
+ type: Component,
2305
+ args: [{
2306
+ template: "",
2307
+ standalone: true,
2308
+ }]
2309
+ }] });
2310
+
2311
+ class GeexRouter extends Router {
2312
+ lastRoute;
2313
+ constructor(injector) {
2314
+ super();
2315
+ const routerEvent = this.events.toSignal();
2316
+ effect(() => {
2317
+ match(routerEvent())
2318
+ .with(P.instanceOf(RouteConfigLoadEnd), (x) => {
2319
+ this.lastRoute = x.route;
2320
+ })
2321
+ .with(P.instanceOf(NavigationEnd), async (x) => {
2322
+ const tabSrv = injector.get(ReuseTabService);
2323
+ const location = injector.get(Location);
2324
+ const cachedTabs = tabSrv.items;
2325
+ const deepest = this.routerState.snapshot.root.getDeepestRouteConfig?.();
2326
+ const activeRoutedPage = deepest?.component;
2327
+ if (!(activeRoutedPage?.prototype instanceof RoutedComponent)) {
2328
+ return;
2329
+ }
2330
+ const currentUrl = this.lastSuccessfulNavigation?.extractedUrl?.toString();
2331
+ const previousUrl = this.lastSuccessfulNavigation?.previousNavigation?.extractedUrl?.toString();
2332
+ const cachedTab = cachedTabs.find(tab => tab.url === previousUrl);
2333
+ if (this.lastRoute?.data?.["reuse"] === false ||
2334
+ (this.lastSuccessfulNavigation?.extras?.replaceUrl &&
2335
+ currentUrl !== previousUrl &&
2336
+ this.isDifferentPath(currentUrl, previousUrl))) {
2337
+ cachedTab && tabSrv.close(previousUrl);
2338
+ }
2339
+ if (this.lastSuccessfulNavigation?.extras?.forceReload || cachedTabs.every(tab => tab.url !== currentUrl)) {
2340
+ this.navigationReload.set({
2341
+ ...x,
2342
+ ...this.lastSuccessfulNavigation,
2343
+ });
2344
+ }
2345
+ location.replaceState(currentUrl);
2346
+ });
2347
+ }, {});
2348
+ }
2349
+ isDifferentPath(currentUrl, previousUrl) {
2350
+ if (!currentUrl || !previousUrl) {
2351
+ return true;
2352
+ }
2353
+ const getCurrentPath = (url) => {
2354
+ const questionMarkIndex = url.indexOf("?");
2355
+ return questionMarkIndex === -1 ? url : url.substring(0, questionMarkIndex);
2356
+ };
2357
+ return getCurrentPath(currentUrl) !== getCurrentPath(previousUrl);
2358
+ }
2359
+ createUrlTree(commands, navigationExtras = {}) {
2360
+ if (navigationExtras.queryParams) {
2361
+ const processedParams = {};
2362
+ for (const key in navigationExtras.queryParams) {
2363
+ const value = navigationExtras.queryParams[key];
2364
+ try {
2365
+ processedParams[key] = exports.encode(value);
2366
+ }
2367
+ catch (e) {
2368
+ console.warn(e);
2369
+ processedParams[key] = value;
2370
+ }
2371
+ }
2372
+ navigationExtras = {
2373
+ ...navigationExtras,
2374
+ queryParams: processedParams,
2375
+ };
2376
+ }
2377
+ return super.createUrlTree(commands, navigationExtras);
2378
+ }
2379
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: GeexRouter, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable });
2380
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: GeexRouter });
2381
+ }
2382
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: GeexRouter, decorators: [{
2383
+ type: Injectable
2384
+ }], ctorParameters: () => [{ type: i0.Injector }] });
2385
+
2386
+ /**
2387
+ * Hardens Delon ReuseTabStrategy against undefined snapshots / empty-path leaves
2388
+ * that otherwise throw during createRouterState / outlet.detach (NG04012).
2389
+ */
2390
+ class GeexReuseTabStrategy extends ReuseTabStrategy {
2391
+ shouldReuseRoute(future, curr) {
2392
+ if (!future || !curr) {
2393
+ return false;
2394
+ }
2395
+ return super.shouldReuseRoute(future, curr);
2396
+ }
2397
+ shouldDetach(route) {
2398
+ if (!route?.routeConfig || route.routeConfig.path === "") {
2399
+ return false;
2400
+ }
2401
+ return super.shouldDetach(route);
2402
+ }
2403
+ retrieve(route) {
2404
+ if (!route?.routeConfig) {
2405
+ return null;
2406
+ }
2407
+ return super.retrieve(route);
2408
+ }
2409
+ shouldAttach(route) {
2410
+ if (!route?.routeConfig) {
2411
+ return false;
2412
+ }
2413
+ return super.shouldAttach(route);
2414
+ }
2415
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: GeexReuseTabStrategy, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
2416
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: GeexReuseTabStrategy });
2417
+ }
2418
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: GeexReuseTabStrategy, decorators: [{
2419
+ type: Injectable
2420
+ }] });
2421
+
2422
+ class ListPageLayoutComponent {
2423
+ i18n = inject(GEEX_I18N, { optional: true });
2424
+ title = input.required(...(ngDevMode ? [{ debugName: "title" }] : []));
2425
+ loading = input(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
2426
+ total = input(0, ...(ngDevMode ? [{ debugName: "total" }] : []));
2427
+ data = input([], ...(ngDevMode ? [{ debugName: "data" }] : []));
2428
+ columns = input([], ...(ngDevMode ? [{ debugName: "columns" }] : []));
2429
+ pi = input(1, ...(ngDevMode ? [{ debugName: "pi" }] : []));
2430
+ ps = input(10, ...(ngDevMode ? [{ debugName: "ps" }] : []));
2431
+ selectedCount = input(0, ...(ngDevMode ? [{ debugName: "selectedCount" }] : []));
2432
+ multiSort = input(true, ...(ngDevMode ? [{ debugName: "multiSort" }] : []));
2433
+ filtersInHeader = input(true, ...(ngDevMode ? [{ debugName: "filtersInHeader" }] : []));
2434
+ tableChange = output();
2435
+ refresh = output();
2436
+ headerExtraTpl = contentChild("headerExtra", ...(ngDevMode ? [{ debugName: "headerExtraTpl" }] : []));
2437
+ headerTabTpl = contentChild("headerTab", ...(ngDevMode ? [{ debugName: "headerTabTpl" }] : []));
2438
+ headerActionTpl = contentChild("headerAction", ...(ngDevMode ? [{ debugName: "headerActionTpl" }] : []));
2439
+ get selectedLabel() {
2440
+ return this.i18n?.Common?.list?.selected ?? "";
2441
+ }
2442
+ get selectedUnitLabel() {
2443
+ return this.i18n?.Common?.list?.selectedUnit ?? "";
2444
+ }
2445
+ get refreshLabel() {
2446
+ return this.i18n?.Common?.list?.refresh ?? "Refresh";
2447
+ }
2448
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: ListPageLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2449
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.0", type: ListPageLayoutComponent, isStandalone: true, selector: "list-page-layout", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, total: { classPropertyName: "total", publicName: "total", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, pi: { classPropertyName: "pi", publicName: "pi", isSignal: true, isRequired: false, transformFunction: null }, ps: { classPropertyName: "ps", publicName: "ps", isSignal: true, isRequired: false, transformFunction: null }, selectedCount: { classPropertyName: "selectedCount", publicName: "selectedCount", isSignal: true, isRequired: false, transformFunction: null }, multiSort: { classPropertyName: "multiSort", publicName: "multiSort", isSignal: true, isRequired: false, transformFunction: null }, filtersInHeader: { classPropertyName: "filtersInHeader", publicName: "filtersInHeader", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { tableChange: "tableChange", refresh: "refresh" }, queries: [{ propertyName: "headerExtraTpl", first: true, predicate: ["headerExtra"], descendants: true, isSignal: true }, { propertyName: "headerTabTpl", first: true, predicate: ["headerTab"], descendants: true, isSignal: true }, { propertyName: "headerActionTpl", first: true, predicate: ["headerAction"], descendants: true, isSignal: true }], ngImport: i0, template: `
2450
+ <page-header [title]="title()" [tab]="headerTabTpl()" [extra]="headerExtraTpl()" [action]="headerActionTpl()">
2451
+ @if (filtersInHeader()) {
2452
+ <ng-content select="[filters]" />
2453
+ }
2454
+ </page-header>
2455
+
2456
+ <nz-card>
2457
+ @if (!filtersInHeader()) {
2458
+ <ng-content select="[filters]" />
2459
+ }
2460
+ <nz-alert class="mb-sm" nzType="info" nzShowIcon [nzMessage]="selectionMessage">
2461
+ <ng-template #selectionMessage>
2462
+ <span>{{ selectedLabel }}{{ selectedCount() }}{{ selectedUnitLabel }}</span>
2463
+ <nz-divider nzType="vertical" />
2464
+ <a (click)="refresh.emit()">
2465
+ <i nz-icon nzType="reload"></i>
2466
+ {{ refreshLabel }}
2467
+ </a>
2468
+ <ng-content select="[toolbar]" />
2469
+ </ng-template>
2470
+ </nz-alert>
2471
+ <st
2472
+ class="mt-sm"
2473
+ [multiSort]="multiSort()"
2474
+ [loading]="loading()"
2475
+ [total]="total()"
2476
+ [data]="data()"
2477
+ [pi]="pi()"
2478
+ [ps]="ps()"
2479
+ [columns]="columns()"
2480
+ (change)="tableChange.emit($event)"
2481
+ />
2482
+ </nz-card>
2483
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: PageHeaderModule }, { kind: "component", type: i1.PageHeaderComponent, selector: "page-header", inputs: ["title", "titleSub", "loading", "wide", "home", "homeLink", "homeI18n", "autoBreadcrumb", "autoTitle", "syncTitle", "fixed", "fixedOffsetTop", "breadcrumb", "recursiveBreadcrumb", "logo", "action", "content", "extra", "tab"], exportAs: ["pageHeader"] }, { kind: "ngmodule", type: STModule }, { kind: "component", type: i2.STComponent, selector: "st", inputs: ["req", "res", "page", "data", "delay", "columns", "contextmenu", "ps", "pi", "total", "loading", "loadingDelay", "loadingIndicator", "bordered", "size", "scroll", "drag", "singleSort", "multiSort", "rowClassName", "clickRowClassName", "widthMode", "widthConfig", "resizable", "header", "showHeader", "footer", "bodyHeader", "body", "expandRowByClick", "expandAccordion", "expand", "expandIcon", "noResult", "responsive", "responsiveHideHeaderFooter", "virtualScroll", "virtualItemSize", "virtualMaxBufferPx", "virtualMinBufferPx", "customRequest", "virtualForTrackBy", "trackBy"], outputs: ["error", "change"], exportAs: ["st"] }, { kind: "ngmodule", type: NzCardModule }, { kind: "component", type: i3.NzCardComponent, selector: "nz-card", inputs: ["nzBordered", "nzLoading", "nzHoverable", "nzBodyStyle", "nzCover", "nzActions", "nzType", "nzSize", "nzTitle", "nzExtra"], exportAs: ["nzCard"] }, { kind: "ngmodule", type: NzAlertModule }, { kind: "component", type: i4.NzAlertComponent, selector: "nz-alert", inputs: ["nzAction", "nzCloseText", "nzIconType", "nzMessage", "nzDescription", "nzType", "nzCloseable", "nzShowIcon", "nzBanner", "nzNoAnimation", "nzIcon"], outputs: ["nzOnClose"], exportAs: ["nzAlert"] }, { kind: "ngmodule", type: NzDividerModule }, { kind: "component", type: i5.NzDividerComponent, selector: "nz-divider", inputs: ["nzText", "nzType", "nzOrientation", "nzVariant", "nzSize", "nzDashed", "nzPlain"], exportAs: ["nzDivider"] }, { kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i6.NzIconDirective, selector: "nz-icon,[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }] });
2484
+ }
2485
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: ListPageLayoutComponent, decorators: [{
2486
+ type: Component,
2487
+ args: [{
2488
+ selector: "list-page-layout",
2489
+ standalone: true,
2490
+ imports: [PageHeaderModule, STModule, NzCardModule, NzAlertModule, NzDividerModule, NzIconModule],
2491
+ template: `
2492
+ <page-header [title]="title()" [tab]="headerTabTpl()" [extra]="headerExtraTpl()" [action]="headerActionTpl()">
2493
+ @if (filtersInHeader()) {
2494
+ <ng-content select="[filters]" />
2495
+ }
2496
+ </page-header>
2497
+
2498
+ <nz-card>
2499
+ @if (!filtersInHeader()) {
2500
+ <ng-content select="[filters]" />
2501
+ }
2502
+ <nz-alert class="mb-sm" nzType="info" nzShowIcon [nzMessage]="selectionMessage">
2503
+ <ng-template #selectionMessage>
2504
+ <span>{{ selectedLabel }}{{ selectedCount() }}{{ selectedUnitLabel }}</span>
2505
+ <nz-divider nzType="vertical" />
2506
+ <a (click)="refresh.emit()">
2507
+ <i nz-icon nzType="reload"></i>
2508
+ {{ refreshLabel }}
2509
+ </a>
2510
+ <ng-content select="[toolbar]" />
2511
+ </ng-template>
2512
+ </nz-alert>
2513
+ <st
2514
+ class="mt-sm"
2515
+ [multiSort]="multiSort()"
2516
+ [loading]="loading()"
2517
+ [total]="total()"
2518
+ [data]="data()"
2519
+ [pi]="pi()"
2520
+ [ps]="ps()"
2521
+ [columns]="columns()"
2522
+ (change)="tableChange.emit($event)"
2523
+ />
2524
+ </nz-card>
2525
+ `,
2526
+ }]
2527
+ }] });
2528
+
2529
+ /**
2530
+ * Delon-coupled Core providers (Router subclass + ReuseTab + optional AppPermission).
2531
+ */
2532
+ function provideGeexDelonBase(options = {}) {
2533
+ return [
2534
+ ...(options.appPermission ? [{ provide: GEEX_APP_PERMISSION, useValue: options.appPermission }] : []),
2535
+ ...(options.reuseTab ? [provideReuseTabConfig(options.reuseTab)] : []),
2536
+ { provide: Router, useClass: options.router ?? GeexRouter },
2537
+ { provide: RouteReuseStrategy, useClass: options.reuseStrategy ?? GeexReuseTabStrategy },
2538
+ importProvidersFrom(AlainThemeModule.forRoot(), DelonFormModule.forRoot()),
2539
+ ];
2540
+ }
2541
+
2542
+ // @ts-nocheck
2543
+ Array.prototype.add = function add(element) {
2544
+ return List.prototype.add.bind(new List(this), element)();
2545
+ };
2546
+ Array.prototype.clear = function clear() {
2547
+ while (this.pop()) { }
2548
+ };
2549
+ Array.prototype.addRange = function addRange(elements) {
2550
+ return List.prototype.addRange.bind(new List(this), elements)();
2551
+ };
2552
+ Array.prototype.aggregate = function aggregate(accumulator, initialValue) {
2553
+ return List.prototype.aggregate.bind(new List(this), accumulator, initialValue)();
2554
+ };
2555
+ Array.prototype.all = function all(predicate) {
2556
+ return List.prototype.all.bind(new List(this), predicate)();
2557
+ };
2558
+ Array.prototype.any = function any(predicate) {
2559
+ if (this === undefined) {
2560
+ return false;
2561
+ }
2562
+ return List.prototype.any.bind(new List(this), predicate)();
2563
+ };
2564
+ Array.prototype.average = function average(transform) {
2565
+ return List.prototype.average.bind(new List(this))(transform).toArray();
2566
+ };
2567
+ Array.prototype.contains = function contains(element) {
2568
+ return List.prototype.contains.bind(new List(this), element)();
2569
+ };
2570
+ Array.prototype.count = function count(predicate) {
2571
+ return List.prototype.count.bind(new List(this))(predicate);
2572
+ };
2573
+ Array.prototype.defaultIfEmpty = function defaultIfEmpty(defaultValue) {
2574
+ return List.prototype.defaultIfEmpty.bind(new List(this))(defaultValue).toArray();
2575
+ };
2576
+ Array.prototype.distinct = function distinct() {
2577
+ return List.prototype.distinct.bind(new List(this))().toArray();
2578
+ };
2579
+ Array.prototype.distinctBy = function distinctBy(keySelector) {
2580
+ return List.prototype.distinctBy.bind(new List(this))(keySelector).toArray();
2581
+ };
2582
+ Array.prototype.elementAt = function elementAt(index) {
2583
+ return List.prototype.elementAt.bind(new List(this))(index);
2584
+ };
2585
+ Array.prototype.elementAtOrDefault = function elementAtOrDefault(index) {
2586
+ if (this?.length) {
2587
+ if (this.length <= index) {
2588
+ return undefined;
2589
+ }
2590
+ return List.prototype.elementAtOrDefault.bind(new List(this))(index);
2591
+ }
2592
+ return undefined;
2593
+ };
2594
+ Array.prototype.except = function except(source) {
2595
+ return List.prototype.except.bind(new List(this))(source).toArray();
2596
+ };
2597
+ Array.prototype.first = function first(predicate) {
2598
+ return List.prototype.first.bind(new List(this), predicate)();
2599
+ };
2600
+ Array.prototype.firstOrDefault = function firstOrDefault(predicate, defaultValue) {
2601
+ const result = List.prototype.firstOrDefault.bind(new List(this), predicate)();
2602
+ return result === undefined ? defaultValue : result;
2603
+ };
2604
+ Array.prototype.first = function first(predicate) {
2605
+ return List.prototype.first.bind(new List(this), predicate)();
2606
+ };
2607
+ Array.prototype.firstOrDefault = function firstOrDefault(predicate, defaultValue) {
2608
+ const result = List.prototype.firstOrDefault.bind(new List(this), predicate)();
2609
+ return result === undefined ? defaultValue : result;
2610
+ };
2611
+ Array.prototype.groupBy = function groupBy(grouper, mapper) {
2612
+ return List.prototype.groupBy.bind(new List(this))(grouper, mapper);
2613
+ };
2614
+ Array.prototype.groupJoin = function groupJoin(list, key1, key2, result) {
2615
+ return List.prototype.groupJoin.bind(new List(this), key1, key2, result)().toArray();
2616
+ };
2617
+ Array.prototype.insert = function insert(index, element) {
2618
+ return List.prototype.insert.bind(new List(this))(index, element);
2619
+ };
2620
+ Array.prototype.intersect = function intersect(source) {
2621
+ return List.prototype.intersect.bind(new List(this), new List(source))().toArray();
2622
+ };
2623
+ Array.prototype.linqJoin = function linqJoin(list, key1, key2, result) {
2624
+ return List.prototype.join.bind(new List(this), key1, key2, result)().toArray();
2625
+ };
2626
+ Array.prototype.last = function last(predicate) {
2627
+ return List.prototype.last.bind(new List(this))(predicate);
2628
+ };
2629
+ Array.prototype.lastOrDefault = function lastOrDefault(predicate) {
2630
+ return List.prototype.lastOrDefault.bind(new List(this))(predicate);
2631
+ };
2632
+ Array.prototype.max = function max(selector) {
2633
+ return List.prototype.max.bind(new List(this))(selector);
2634
+ };
2635
+ Array.prototype.min = function min(selector) {
2636
+ return List.prototype.min.bind(new List(this))(selector);
2637
+ };
2638
+ Array.prototype.ofType = function ofType($type) {
2639
+ return List.prototype.ofType.bind(new List(this), $type)();
2640
+ };
2641
+ Array.prototype.orderBy = function orderBy(keySelector, comparer) {
2642
+ return List.prototype.orderBy.bind(new List(this), keySelector, comparer)().toArray();
2643
+ };
2644
+ Array.prototype.orderByDescending = function orderByDescending(keySelector, comparer) {
2645
+ return List.prototype.orderByDescending.bind(new List(this), keySelector, comparer)().toArray();
2646
+ };
2647
+ Array.prototype.thenBy = function thenBy(keySelector) {
2648
+ return List.prototype.thenBy.bind(new List(this), keySelector)().toArray();
2649
+ };
2650
+ Array.prototype.thenByDescending = function thenByDescending(keySelector) {
2651
+ return List.prototype.thenByDescending.bind(new List(this), keySelector)().toArray();
2652
+ };
2653
+ Array.prototype.remove = function remove(element) {
2654
+ return List.prototype.remove.bind(new List(this), element)();
2655
+ };
2656
+ Array.prototype.removeAll = function removeAll(predicate) {
2657
+ return List.prototype.removeAll.bind(new List(this))(predicate).toArray();
2658
+ };
2659
+ Array.prototype.removeAt = function removeAt(index) {
2660
+ return List.prototype.removeAt.bind(new List(this), index)();
2661
+ };
2662
+ Array.prototype.selectMany = function selectMany(selector) {
2663
+ return List.prototype.selectMany.bind(new List(this))(selector).toArray();
2664
+ };
2665
+ Array.prototype.sequenceEqual = function sequenceEqual(list) {
2666
+ if (this?.length !== list?.length) {
2667
+ return false;
2668
+ }
2669
+ if (this?.length === 0 && this?.length === list?.length) {
2670
+ return true;
2671
+ }
2672
+ for (let i = 0; i < this.length; i++) {
2673
+ const element = this[i];
2674
+ if (this[i] === list[i]) {
2675
+ continue;
2676
+ }
2677
+ else {
2678
+ return false;
2679
+ }
2680
+ }
2681
+ return true;
2682
+ };
2683
+ Array.prototype.single = function single(predicate) {
2684
+ return List.prototype.single.bind(new List(this), predicate)();
2685
+ };
2686
+ Array.prototype.singleOrDefault = function singleOrDefault(predicate) {
2687
+ return List.prototype.singleOrDefault.bind(new List(this), predicate)();
2688
+ };
2689
+ Array.prototype.skip = function skip(amount) {
2690
+ return List.prototype.skip.bind(new List(this), amount)().toArray();
2691
+ };
2692
+ Array.prototype.skipWhile = function skipWhile(predicate) {
2693
+ return List.prototype.skipWhile.bind(new List(this), predicate)().toArray();
2694
+ };
2695
+ Array.prototype.sum = function sum(transform) {
2696
+ return List.prototype.sum.bind(new List(this))(transform);
2697
+ };
2698
+ Array.prototype.take = function take(amount) {
2699
+ return List.prototype.take.bind(new List(this), amount)().toArray();
2700
+ };
2701
+ Array.prototype.takeWhile = function takeWhile(predicate) {
2702
+ return List.prototype.takeWhile.bind(this, predicate)().toArray();
2703
+ };
2704
+ Array.prototype.toLookup = function toLookup(keySelector, elementSelector) {
2705
+ return List.prototype.toLookup.bind(new List(this), keySelector, elementSelector)();
2706
+ };
2707
+ Array.prototype.union = function union(list) {
2708
+ return List.prototype.union.bind(new List(this), list)().toArray();
2709
+ };
2710
+ Array.prototype.where = function where(predicate) {
2711
+ return List.prototype.where.bind(new List(this), predicate)().toArray();
2712
+ };
2713
+ Array.prototype.toArray = function where() {
2714
+ return this;
2715
+ };
2716
+ Array.prototype.zip = function zip(list, result) {
2717
+ return List.prototype.zip.bind(new List(this))(list, result).toArray();
2718
+ };
2719
+
2720
+ String.prototype.contains = function (value) {
2721
+ return this.indexOf(value) >= 0;
2722
+ };
2723
+
2724
+ function deepSignal(initialValue, options) {
2725
+ const result = toDeepSignal(signal(initialValue, options));
2726
+ return result;
2727
+ }
2728
+ function toDeepSignal(source) {
2729
+ const value = untracked(() => source());
2730
+ if (!isRecord$1(value)) {
2731
+ return source;
2732
+ }
2733
+ if ("set" in source && typeof source.set === "function") {
2734
+ return new Proxy(source, {
2735
+ get(target, prop) {
2736
+ if (!(prop in value) && prop in target) {
2737
+ return target[prop];
2738
+ }
2739
+ if (isSignal(target[prop])) {
2740
+ Object.defineProperty(target, prop, {
2741
+ value: computed(() => target()[prop]),
2742
+ configurable: true,
2743
+ });
2744
+ }
2745
+ if (target[prop] == undefined) {
2746
+ return signal(target[prop]);
2747
+ }
2748
+ return toDeepSignal(target[prop]);
2749
+ },
2750
+ set(target, prop, value) {
2751
+ if (isSignal(target[prop])) {
2752
+ target[prop].set(value);
2753
+ }
2754
+ else {
2755
+ target[prop] = value;
2756
+ }
2757
+ return true;
2758
+ },
2759
+ });
2760
+ }
2761
+ return new Proxy(signal, {
2762
+ get(target, prop) {
2763
+ if (!(prop in value) && prop in target) {
2764
+ return target[prop];
2765
+ }
2766
+ if (!isSignal(target[prop])) {
2767
+ Object.defineProperty(target, prop, {
2768
+ value: computed(() => target()[prop]),
2769
+ configurable: true,
2770
+ });
2771
+ }
2772
+ return toDeepSignal(target[prop]);
2773
+ },
2774
+ });
2775
+ }
2776
+ function isRecord$1(value) {
2777
+ return value?.constructor === Object;
2778
+ }
2779
+ function toDebounced(sourceSignal, debounceTimeInMs = 0) {
2780
+ const debounceSignal = signal(sourceSignal(), ...(ngDevMode ? [{ debugName: "debounceSignal" }] : []));
2781
+ effect(onCleanup => {
2782
+ const value = sourceSignal();
2783
+ const timeout = setTimeout(() => debounceSignal.set(value), debounceTimeInMs);
2784
+ onCleanup(() => clearTimeout(timeout));
2785
+ }, {});
2786
+ return debounceSignal;
2787
+ }
2788
+ const signal1 = signal(null, ...(ngDevMode ? [{ debugName: "signal1" }] : []));
2789
+ const signalProto = Object.getPrototypeOf(signal1);
2790
+ signalProto["toDebounced"] = function (debounceTimeInMs = 0) {
2791
+ return toDebounced(this, debounceTimeInMs);
2792
+ };
2793
+ signalProto["toDeepSignal"] = function () {
2794
+ return toDeepSignal(this);
2795
+ };
2796
+ function toObservable(sourceSignal) {
2797
+ return of(sourceSignal());
2798
+ }
2799
+ signalProto["toObservable"] = function () {
2800
+ return toObservable(this);
2801
+ };
2802
+ function computedAsync(computation) {
2803
+ const resultSignal = signal(null, ...(ngDevMode ? [{ debugName: "resultSignal" }] : []));
2804
+ effect(async () => {
2805
+ const result = computation();
2806
+ const unwrappedResult = await (isObservable(result) ? firstValueFrom(result, { defaultValue: null }) : result);
2807
+ resultSignal.set(unwrappedResult);
2808
+ }, {});
2809
+ return resultSignal.asReadonly();
2810
+ }
2811
+
2812
+ Observable.prototype.lastValuePromise = function () {
2813
+ return lastValueFrom(this);
2814
+ };
2815
+ Observable.prototype.firstValuePromise = function () {
2816
+ return firstValueFrom(this);
2817
+ };
2818
+ Observable.prototype.toSignal = function (options) {
2819
+ if (options?.deep) {
2820
+ return toSignal(this, options).toDeepSignal();
2821
+ }
2822
+ return toSignal(this, options);
2823
+ };
2824
+ Observable.prototype.pipeMap = function (project) {
2825
+ return this.pipe(map(project));
2826
+ };
2827
+ Observable.prototype.pipeSwitchMap = function (project) {
2828
+ return this.pipe(switchMap$1(project));
2829
+ };
2830
+ Observable.prototype.pipeFilter = function (predicate) {
2831
+ return this.pipe(filter(predicate));
2832
+ };
2833
+
2834
+ function getResolvedUrl() {
2835
+ return this["_routerState"].url;
2836
+ }
2837
+ function getConfiguredUrl() {
2838
+ return `/${this.pathFromRoot
2839
+ .filter(v => v.routeConfig)
2840
+ .map(v => v.routeConfig.path)
2841
+ .where(x => x != "")
2842
+ .join("/")}`;
2843
+ }
2844
+ function getDeepestRouteConfig() {
2845
+ let currentRoute = this;
2846
+ while (currentRoute.firstChild) {
2847
+ currentRoute = currentRoute.firstChild;
2848
+ }
2849
+ return currentRoute.routeConfig;
2850
+ }
2851
+ ActivatedRouteSnapshot.prototype.getResolvedUrl = getResolvedUrl;
2852
+ ActivatedRouteSnapshot.prototype.getConfiguredUrl = getConfiguredUrl;
2853
+ ActivatedRouteSnapshot.prototype.getDeepestRouteConfig = getDeepestRouteConfig;
2854
+ Object.defineProperty(Router.prototype, "navigationReload", {
2855
+ value: signal(undefined),
2856
+ writable: false,
2857
+ });
2858
+ function transformObjectToForm(fb, obj, options) {
2859
+ if (obj instanceof Object && !(obj instanceof Date)) {
2860
+ const result = {};
2861
+ for (const key in obj) {
2862
+ if (obj.hasOwnProperty(key)) {
2863
+ if (obj[key] instanceof AbstractControl) {
2864
+ result[key] = obj[key];
2865
+ continue;
2866
+ }
2867
+ if (obj[key] instanceof Object && !(obj[key] instanceof Array)) {
2868
+ result[key] = transformObjectToForm(fb, obj[key], options);
2869
+ }
2870
+ else if (obj[key] instanceof Array) {
2871
+ result[key] = fb.array(obj[key].map(item => transformObjectToForm(fb, item, options)), options);
2872
+ }
2873
+ else {
2874
+ result[key] = new FormControl(obj[key], options);
2875
+ }
2876
+ }
2877
+ }
2878
+ return fb.group(result, options);
2879
+ }
2880
+ else {
2881
+ return obj;
2882
+ }
2883
+ }
2884
+ FormBuilder.prototype.build = function (controls, options) {
2885
+ let updated = transformObjectToForm(this, controls, options ?? {});
2886
+ return updated;
2887
+ };
2888
+
2889
+ function exportAll(opt) {
2890
+ return this.$exportData.firstValuePromise().then(x => this.export(deepCopy(x), opt));
2891
+ }
2892
+ STComponent.prototype.exportAll = exportAll;
2893
+
2894
+ if (!Object.hasOwnProperty("fromEntries")) {
2895
+ Object.fromEntries = function fromEntries(iterable) {
2896
+ return [...iterable].reduce((obj, [key, val]) => {
2897
+ obj[String(key)] = val;
2898
+ return obj;
2899
+ }, {});
2900
+ };
2901
+ }
2902
+ Date.prototype.add = function (value) {
2903
+ let result = this;
2904
+ if (value.years) {
2905
+ result = addYears(result, value.years);
2906
+ }
2907
+ if (value.months) {
2908
+ result = addMonths(result, value.months);
2909
+ }
2910
+ if (value.weeks) {
2911
+ result = addWeeks(result, value.weeks);
2912
+ }
2913
+ if (value.days) {
2914
+ result = addDays(result, value.days);
2915
+ }
2916
+ if (value.hours) {
2917
+ result = addHours(result, value.hours);
2918
+ }
2919
+ if (value.minutes) {
2920
+ result = addMinutes(result, value.minutes);
2921
+ }
2922
+ if (value.seconds) {
2923
+ result = addSeconds(result, value.seconds);
2924
+ }
2925
+ if (value.milliseconds) {
2926
+ result = addMilliseconds(result, value.milliseconds);
2927
+ }
2928
+ return result;
2929
+ };
2930
+ Date.prototype.format = function (format) {
2931
+ const yyyy = this.getFullYear().toString();
2932
+ format = format.replace(/yyyy/g, yyyy);
2933
+ const MM = (this.getMonth() + 1).toString();
2934
+ format = format.replace(/MM/g, MM[1] ? MM : `0${MM[0]}`);
2935
+ const dd = this.getDate().toString();
2936
+ format = format.replace(/dd/g, dd[1] ? dd : `0${dd[0]}`);
2937
+ const HH = this.getHours().toString();
2938
+ format = format.replace(/HH/g, HH[1] ? HH : `0${HH[0]}`);
2939
+ const mm = this.getMinutes().toString();
2940
+ format = format.replace(/mm/g, mm[1] ? mm : `0${mm[0]}`);
2941
+ const ss = this.getSeconds().toString();
2942
+ format = format.replace(/ss/g, ss[1] ? ss : `0${ss[0]}`);
2943
+ return format;
2944
+ };
2945
+ Date.prototype.getTotalMonth = function () {
2946
+ return this.getFullYear() * 12 + this.getMonth() + 1;
2947
+ };
2948
+ function extract(object, properties) {
2949
+ const result = {};
2950
+ for (const property of Object.keys(properties)) {
2951
+ result[property] = object[property];
2952
+ }
2953
+ return result;
2954
+ }
2955
+ window["extract"] = extract;
2956
+ const legacyTrimEnd = String.prototype.trimEnd;
2957
+ String.prototype.trimEnd = function trimEnd(strToTrim) {
2958
+ if (strToTrim == undefined) {
2959
+ return legacyTrimEnd.bind(this)();
2960
+ }
2961
+ return this.replace(new RegExp(`${strToTrim}$`), "");
2962
+ };
2963
+ Number.prototype.hasFlag = function hasFlag(...flags) {
2964
+ return flags.all(flag => flag !== undefined && (this.valueOf() & flag) == flag);
2965
+ };
2966
+ Number.prototype.hasNoFlag = function hasNoFlag(...flags) {
2967
+ return flags.all(flag => flag !== undefined && (this.valueOf() & flag) == 0);
2968
+ };
2969
+ const flatMapDeep = function (iteratee) {
2970
+ if (!this || this.length == 0) {
2971
+ return [];
2972
+ }
2973
+ return this.concat(_.flatten(this.map(iteratee).filter(x => x != undefined)).flatMapDeep(iteratee));
2974
+ };
2975
+ Array.prototype.flatMapDeep = flatMapDeep;
2976
+ const range = (start, end) => Array.from({ length: end - start }, (v, k) => k + start);
2977
+ Array.range = range;
2978
+ function assertIsDefined(val) {
2979
+ if (val === undefined || val === null) {
2980
+ throw new Error(`Expected 'val' to be defined, but received ${val}`);
2981
+ }
2982
+ }
2983
+ function assertIsArray(val) {
2984
+ if (!Array.isArray(val)) {
2985
+ throw new Error(`Expected 'val' to be defined, but received ${val}`);
2986
+ }
2987
+ }
2988
+ function assert(_val) { }
2989
+ function assertIsNotArray(val) {
2990
+ if (Array.isArray(val)) {
2991
+ throw new Error(`Expected 'val' to be defined, but received ${val}`);
2992
+ }
2993
+ }
2994
+ function deepProxy(obj, callback) {
2995
+ if (obj === null ||
2996
+ obj === undefined ||
2997
+ obj instanceof String ||
2998
+ obj instanceof Date ||
2999
+ obj instanceof Number ||
3000
+ obj instanceof Function) {
3001
+ return obj;
3002
+ }
3003
+ if (typeof obj === "object") {
3004
+ for (const key in obj) {
3005
+ if (typeof obj[key] === "object") {
3006
+ obj[key] = deepProxy(obj[key], callback);
3007
+ }
3008
+ }
3009
+ }
3010
+ return new Proxy(obj, {
3011
+ set: (target, key, value, receiver) => {
3012
+ if (typeof value === "object") {
3013
+ value = deepProxy(value, callback);
3014
+ }
3015
+ let cbType = target[key] == undefined ? "create" : "modify";
3016
+ if (target[key] === value) {
3017
+ cbType = "assignment";
3018
+ }
3019
+ if (!(Array.isArray(target) && key === "length")) {
3020
+ callback(cbType, { target, key, value });
3021
+ }
3022
+ return Reflect.set(target, key, value, receiver);
3023
+ },
3024
+ deleteProperty: (target, key) => {
3025
+ callback("delete", { target, key, value: undefined });
3026
+ return Reflect.deleteProperty(target, key);
3027
+ },
3028
+ });
3029
+ }
3030
+ function isRecord(value) {
3031
+ return typeof value === "object" && value !== null && !Array.isArray(value) && Object.keys(value).every(key => typeof key === "string");
3032
+ }
3033
+
3034
+ /// <reference path="../shims.d.ts" />
3035
+ function computeChecksumMd5() {
3036
+ return new Promise((resolve, reject) => {
3037
+ const chunkSize = 2097152;
3038
+ const spark = new SparkMD5.ArrayBuffer();
3039
+ const fileReader = new FileReader();
3040
+ let cursor = 0;
3041
+ fileReader.onerror = () => {
3042
+ reject("MD5 computation failed - error reading the file");
3043
+ };
3044
+ const processChunk = (chunkStart) => {
3045
+ const chunkEnd = Math.min(this.size, chunkStart + chunkSize);
3046
+ fileReader.readAsArrayBuffer(this.slice(chunkStart, chunkEnd));
3047
+ };
3048
+ fileReader.onload = (e) => {
3049
+ spark.append(e.target.result);
3050
+ cursor += chunkSize;
3051
+ if (cursor < this.size) {
3052
+ processChunk(cursor);
3053
+ }
3054
+ else {
3055
+ resolve(spark.end());
3056
+ }
3057
+ };
3058
+ processChunk(0);
3059
+ });
3060
+ }
3061
+ Blob.prototype.computeChecksumMd5 = computeChecksumMd5;
3062
+
3063
+ function provideGeexExtensions() {
3064
+ // side-effect imports above run when this module is loaded
3065
+ }
3066
+
3067
+ const GEEX_MOBILE_PATH_SUFFIX = new InjectionToken("GEEX_MOBILE_PATH_SUFFIX", {
3068
+ providedIn: "root",
3069
+ factory: () => "/query",
3070
+ });
3071
+
3072
+ const GEEX_EXCEPTION_403_PROFILE_PATH = new InjectionToken("GEEX_EXCEPTION_403_PROFILE_PATH", {
3073
+ providedIn: "root",
3074
+ factory: () => "/identity/me",
3075
+ });
3076
+ const GEEX_EXCEPTION_403_PROFILE_LABEL = new InjectionToken("GEEX_EXCEPTION_403_PROFILE_LABEL", {
3077
+ providedIn: "root",
3078
+ factory: () => "个人中心",
3079
+ });
3080
+ const GEEX_EXCEPTION_LOGIN_PATH = new InjectionToken("GEEX_EXCEPTION_LOGIN_PATH", {
3081
+ providedIn: "root",
3082
+ factory: () => "/authentication/login",
3083
+ });
3084
+
3085
+ /**
3086
+ * Expose package `geex` on globalThis/window via a live getter.
3087
+ * Must not copy the value at bind time — `geex` is only assigned inside `configGeex`.
3088
+ */
3089
+ function bindGeexGlobal() {
3090
+ const bind = (target) => {
3091
+ Reflect.deleteProperty(target, "geex");
3092
+ Object.defineProperty(target, "geex", {
3093
+ configurable: true,
3094
+ enumerable: true,
3095
+ get: () => geex,
3096
+ });
3097
+ };
3098
+ if (typeof globalThis !== "undefined") {
3099
+ bind(globalThis);
3100
+ }
3101
+ if (typeof window !== "undefined") {
3102
+ bind(window);
3103
+ }
3104
+ }
3105
+
3106
+ /**
3107
+ * Generated bundle index. Do not edit.
3108
+ */
3109
+
3110
+ export { BusinessComponentBase, DebuggerBlockerService, ExtensionModule, GEEX_AFTER_LOGIN_NAVIGATE, GEEX_API_BASE_URL, GEEX_APOLLO_CACHE, GEEX_APOLLO_TYPE_POLICY_CONTRIBUTIONS, GEEX_APP_MENU_SETTING, GEEX_APP_NAME_SETTING, GEEX_APP_PERMISSION, GEEX_BLOCK_DEBUGGER, GEEX_CANCEL_AUTHENTICATION_DOCUMENT, GEEX_DEFAULT_HTTP_STATUS_MESSAGES, GEEX_DEFAULT_MENUS, GEEX_EXCEPTION_403_PROFILE_LABEL, GEEX_EXCEPTION_403_PROFILE_PATH, GEEX_EXCEPTION_500_PATH, GEEX_EXCEPTION_LOGIN_PATH, GEEX_HTTP_STATUS_MESSAGES, GEEX_I18N, GEEX_I18N_PACKS, GEEX_I18N_SERVICE, GEEX_LOCALIZATION_DATA_SETTING, GEEX_LOCALIZATION_LANGUAGE_SETTING, GEEX_LOGIN_PATH, GEEX_MENU_CONTRIBUTIONS, GEEX_MOBILE_PATH_SUFFIX, GEEX_MODULE_CONTRIBUTIONS, GEEX_PROFILE_LABEL, GEEX_PROFILE_PATH, GEEX_SESSION_TERMINATED_COPY, GEEX_STARTUP_OPTIONS, GEEX_SUPER_ADMIN_USER_ID, Geex, GeexAuthLogout, GeexHttpInterceptor, GeexI18nService, GeexReuseTabStrategy, GeexRouter, GeexStartupService, GeexTranslateLoader, I18N, GeexI18nService as I18NService, ListPageLayoutComponent, ListPageParams, ModalComponentBase, RoutedComponent, RoutedEditComponent, RoutedListComponent, SILENT_REQUEST, SilentApollo, TreeTableComponentBase, applyEnvironmentOverrides, assert, assertIsArray, assertIsDefined, assertIsNotArray, bindGeexGlobal, cancelAuthenticationMutation, computedAsync, configGeex, createGeexGraphqlErrorLink, createGeexHttpApolloOptions, createGeexInMemoryCache, createGeexSilentContextLink, createGeexUploadHttpLink, createGeexUriLink, createGeexWsApolloOptions, createUiModule, deepProxy, deepSignal, extract, geex, geexApolloDefaultOptions, geexDefaultTypePolicies, guardedSignal, isGeexSilentOperation, isRecord, loadEnvironmentOverrides, mergeGeexI18nPacks, provideGeex, provideGeexApollo, provideGeexApolloTypePolicies, provideGeexCommon, provideGeexDelonBase, provideGeexExtensions, provideGeexHttp, provideGeexI18n, provideGeexMenus, provideGeexModuleContribution, provideGeexStartup, exports as rison };
3111
+ //# sourceMappingURL=geexcode-geex-angular.mjs.map