@powerportalspro/react 5.0.0-beta.3 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,8 +1,274 @@
1
- import { createContext, useContext, useCallback, useMemo, useEffect, useSyncExternalStore, useState, useRef, useReducer, useId } from 'react';
1
+ import { createContext, useRef, useState, useEffect, useLayoutEffect, useCallback, useContext, useMemo, useSyncExternalStore, useReducer, useId } from 'react';
2
2
  import { Transport, AuthClient, PowerPortalsProClient, LoginResult, SwitchIdentityResult } from '@powerportalspro/core';
3
3
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
4
 
5
- // src/context.ts
5
+ // src/masking/reformat.ts
6
+ var MaskMode = {
7
+ /** No masking — value passes through unchanged. */
8
+ None: "none",
9
+ /**
10
+ * Per-character allow filter. Characters that don't match
11
+ * {@link MaskOptions.allowedPattern} are dropped as they're typed or pasted.
12
+ */
13
+ Regex: "regex",
14
+ /**
15
+ * Slotted template (see {@link MaskOptions.pattern}) such as `(000) 000-0000`.
16
+ * `0` = digit, `A` = letter, `*` = alphanumeric; every other character is a
17
+ * literal inserted automatically.
18
+ */
19
+ Pattern: "pattern",
20
+ /**
21
+ * Live numeric grouping driven by {@link MaskOptions.numeric} — thousands
22
+ * separators, an optional decimal portion, and an optional leading sign.
23
+ */
24
+ Numeric: "numeric"
25
+ };
26
+ var DIGIT = /[0-9]/;
27
+ var LETTER = /[a-zA-Z]/;
28
+ var ALNUM = /[a-zA-Z0-9]/;
29
+ function isPatternLiteral(token) {
30
+ return token !== "0" && token !== "A" && token !== "*";
31
+ }
32
+ function patternTokenMatches(token, ch) {
33
+ if (token === "0") return DIGIT.test(ch);
34
+ if (token === "A") return LETTER.test(ch);
35
+ if (token === "*") return ALNUM.test(ch);
36
+ return false;
37
+ }
38
+ function countSignificant(source, caret, isSignificant) {
39
+ let n = 0;
40
+ for (let i = 0; i < caret && i < source.length; i++) {
41
+ if (isSignificant(source.charAt(i))) n++;
42
+ }
43
+ return n;
44
+ }
45
+ function caretAfterSignificant(display, target, isSignificant) {
46
+ if (target <= 0) {
47
+ let i = 0;
48
+ while (i < display.length && !isSignificant(display.charAt(i))) i++;
49
+ return i;
50
+ }
51
+ let seen = 0;
52
+ for (let i = 0; i < display.length; i++) {
53
+ if (isSignificant(display.charAt(i))) {
54
+ seen++;
55
+ if (seen === target) return i + 1;
56
+ }
57
+ }
58
+ return display.length;
59
+ }
60
+ function reformatNumeric(value, caret, o) {
61
+ const sigChars = (c) => DIGIT.test(c) || c === o.decimalSeparator || o.allowNegative && c === "-";
62
+ const sigBefore = countSignificant(value, caret, sigChars);
63
+ const negative = o.allowNegative && value.trimStart().startsWith("-");
64
+ let intPart = "";
65
+ let fracPart = "";
66
+ let sawDecimal = false;
67
+ for (const ch of value) {
68
+ if (DIGIT.test(ch)) {
69
+ if (sawDecimal) fracPart += ch;
70
+ else intPart += ch;
71
+ } else if (o.allowDecimal && ch === o.decimalSeparator && !sawDecimal) {
72
+ sawDecimal = true;
73
+ }
74
+ }
75
+ intPart = intPart.replace(/^0+(?=\d)/, "");
76
+ if (o.maxDecimals !== null && fracPart.length > o.maxDecimals) {
77
+ fracPart = fracPart.slice(0, o.maxDecimals);
78
+ }
79
+ const grouped = o.groupSeparator ? intPart.replace(/\B(?=(\d{3})+(?!\d))/g, o.groupSeparator) : intPart;
80
+ const sign = negative ? "-" : "";
81
+ let display = sign + grouped;
82
+ let raw = sign + intPart;
83
+ if (sawDecimal) {
84
+ display += o.decimalSeparator + fracPart;
85
+ raw += o.decimalSeparator + fracPart;
86
+ }
87
+ const newCaret = caretAfterSignificant(display, sigBefore, sigChars);
88
+ return { display, raw, caret: newCaret };
89
+ }
90
+ function reformatPattern(value, caret, pattern) {
91
+ const sourceChars = [];
92
+ for (const ch of value) {
93
+ if (DIGIT.test(ch) || LETTER.test(ch)) sourceChars.push(ch);
94
+ }
95
+ const sigBefore = countSignificant(value, caret, (c) => DIGIT.test(c) || LETTER.test(c));
96
+ let display = "";
97
+ let raw = "";
98
+ let si = 0;
99
+ for (let pi = 0; pi < pattern.length && si <= sourceChars.length; pi++) {
100
+ const token = pattern[pi];
101
+ if (isPatternLiteral(token)) {
102
+ if (si < sourceChars.length) display += token;
103
+ continue;
104
+ }
105
+ while (si < sourceChars.length && !patternTokenMatches(token, sourceChars[si])) si++;
106
+ if (si < sourceChars.length) {
107
+ display += sourceChars[si];
108
+ raw += sourceChars[si];
109
+ si++;
110
+ } else {
111
+ break;
112
+ }
113
+ }
114
+ const newCaret = caretAfterSignificant(display, sigBefore, (c) => DIGIT.test(c) || LETTER.test(c));
115
+ return { display, raw, caret: newCaret };
116
+ }
117
+ function reformatRegex(value, caret, allowedPattern) {
118
+ let re;
119
+ try {
120
+ re = new RegExp(allowedPattern);
121
+ } catch {
122
+ return { display: value, raw: value, caret };
123
+ }
124
+ const keep = (c) => re.test(c);
125
+ const sigBefore = countSignificant(value, caret, keep);
126
+ let display = "";
127
+ for (const ch of value) {
128
+ if (keep(ch)) display += ch;
129
+ }
130
+ const newCaret = caretAfterSignificant(display, sigBefore, keep);
131
+ return { display, raw: display, caret: newCaret };
132
+ }
133
+ function reformat(value, caret, options) {
134
+ switch (options.mode) {
135
+ case MaskMode.Numeric:
136
+ return options.numeric ? reformatNumeric(value, caret, options.numeric) : { display: value, raw: value, caret };
137
+ case MaskMode.Pattern:
138
+ return options.pattern ? reformatPattern(value, caret, options.pattern) : { display: value, raw: value, caret };
139
+ case MaskMode.Regex:
140
+ return options.allowedPattern ? reformatRegex(value, caret, options.allowedPattern) : { display: value, raw: value, caret };
141
+ default:
142
+ return { display: value, raw: value, caret };
143
+ }
144
+ }
145
+ function computeDisplay(value, options) {
146
+ if (value === null || value === void 0 || value === "") return "";
147
+ return reformat(value, value.length, options).display;
148
+ }
149
+ function computeReported(value, options) {
150
+ if (value === null || value === void 0 || value === "") return "";
151
+ const r = reformat(value, value.length, options);
152
+ return options.valueIncludesMask ? r.display : r.raw;
153
+ }
154
+ function useMaskedTextField(opts) {
155
+ const {
156
+ value,
157
+ onValueChange,
158
+ mode = MaskMode.None,
159
+ pattern = null,
160
+ allowedPattern = null,
161
+ numeric = null,
162
+ valueIncludesMask = false
163
+ } = opts;
164
+ const optionsRef = useRef({
165
+ mode,
166
+ pattern,
167
+ allowedPattern,
168
+ numeric,
169
+ valueIncludesMask
170
+ });
171
+ optionsRef.current = { mode, pattern, allowedPattern, numeric, valueIncludesMask };
172
+ const onValueChangeRef = useRef(onValueChange);
173
+ onValueChangeRef.current = onValueChange;
174
+ const elementRef = useRef(null);
175
+ const focusedRef = useRef(false);
176
+ const hasInputSinceFocusRef = useRef(false);
177
+ const lastReportedRef = useRef(null);
178
+ const pendingCaretRef = useRef(null);
179
+ const [displayValue, setDisplayValue] = useState(
180
+ () => computeDisplay(value, optionsRef.current)
181
+ );
182
+ useEffect(() => {
183
+ if (focusedRef.current && hasInputSinceFocusRef.current) return;
184
+ const next = computeDisplay(value, optionsRef.current);
185
+ setDisplayValue(next);
186
+ lastReportedRef.current = computeReported(value, optionsRef.current);
187
+ }, [value]);
188
+ useEffect(() => {
189
+ if (focusedRef.current && hasInputSinceFocusRef.current) return;
190
+ const next = computeDisplay(value, optionsRef.current);
191
+ setDisplayValue(next);
192
+ lastReportedRef.current = computeReported(value, optionsRef.current);
193
+ }, [mode, pattern, allowedPattern, numeric, valueIncludesMask]);
194
+ useLayoutEffect(() => {
195
+ const target = pendingCaretRef.current;
196
+ if (target === null) return;
197
+ const input = elementRef.current;
198
+ if (!input) return;
199
+ try {
200
+ input.setSelectionRange(target, target);
201
+ } catch {
202
+ }
203
+ pendingCaretRef.current = null;
204
+ });
205
+ const onChange = useCallback(
206
+ (_event, data) => {
207
+ hasInputSinceFocusRef.current = true;
208
+ const o = optionsRef.current;
209
+ const input = elementRef.current;
210
+ const caret = input?.selectionStart ?? data.value.length;
211
+ const result = reformat(data.value, caret, o);
212
+ setDisplayValue(result.display);
213
+ pendingCaretRef.current = result.caret;
214
+ const reported = o.valueIncludesMask ? result.display : result.raw;
215
+ const empty = reported === "";
216
+ const next = empty ? null : reported;
217
+ if (reported !== lastReportedRef.current) {
218
+ lastReportedRef.current = reported;
219
+ onValueChangeRef.current(next);
220
+ }
221
+ },
222
+ []
223
+ );
224
+ const inputRef = useCallback((el) => {
225
+ const prev = elementRef.current;
226
+ if (prev && prev !== el) {
227
+ prev.removeEventListener("focus", handleFocusRef.current);
228
+ prev.removeEventListener("blur", handleBlurRef.current);
229
+ }
230
+ elementRef.current = el;
231
+ if (el) {
232
+ el.addEventListener("focus", handleFocusRef.current);
233
+ el.addEventListener("blur", handleBlurRef.current);
234
+ }
235
+ }, []);
236
+ const handleFocusRef = useRef(() => {
237
+ });
238
+ handleFocusRef.current = () => {
239
+ focusedRef.current = true;
240
+ hasInputSinceFocusRef.current = false;
241
+ };
242
+ const handleBlurRef = useRef(() => {
243
+ });
244
+ handleBlurRef.current = () => {
245
+ focusedRef.current = false;
246
+ if (!hasInputSinceFocusRef.current) {
247
+ const next = computeDisplay(value, optionsRef.current);
248
+ if (next !== displayValue) {
249
+ setDisplayValue(next);
250
+ lastReportedRef.current = computeReported(value, optionsRef.current);
251
+ }
252
+ }
253
+ };
254
+ const forceValue = useCallback((newValue) => {
255
+ const o = optionsRef.current;
256
+ if (newValue === null || newValue === "") {
257
+ setDisplayValue("");
258
+ lastReportedRef.current = "";
259
+ pendingCaretRef.current = 0;
260
+ onValueChangeRef.current(null);
261
+ return;
262
+ }
263
+ const result = reformat(newValue, newValue.length, o);
264
+ setDisplayValue(result.display);
265
+ pendingCaretRef.current = result.display.length;
266
+ const reported = o.valueIncludesMask ? result.display : result.raw;
267
+ lastReportedRef.current = reported;
268
+ onValueChangeRef.current(reported === "" ? null : reported);
269
+ }, []);
270
+ return { displayValue, onChange, inputRef, forceValue };
271
+ }
6
272
  var AuthStatus = {
7
273
  Loading: "loading",
8
274
  Anonymous: "anonymous",
@@ -76,19 +342,19 @@ var InMemoryViewMetadataCache = class {
76
342
  this.cache.clear();
77
343
  }
78
344
  };
79
- var InMemoryEnvironmentFileSettingsCache = class _InMemoryEnvironmentFileSettingsCache {
80
- static KEY = "environment-file-settings";
345
+ var InMemoryOrganizationSettingsCache = class _InMemoryOrganizationSettingsCache {
346
+ static KEY = "organization-settings";
81
347
  cache;
82
348
  constructor(ppp) {
83
349
  this.cache = new InMemoryCache(
84
- () => ppp.getEnvironmentFileSettingsAsync()
350
+ () => ppp.getOrganizationSettingsAsync()
85
351
  );
86
352
  }
87
353
  getAsync() {
88
- return this.cache.getAsync(_InMemoryEnvironmentFileSettingsCache.KEY);
354
+ return this.cache.getAsync(_InMemoryOrganizationSettingsCache.KEY);
89
355
  }
90
356
  invalidate() {
91
- this.cache.invalidate(_InMemoryEnvironmentFileSettingsCache.KEY);
357
+ this.cache.invalidate(_InMemoryOrganizationSettingsCache.KEY);
92
358
  }
93
359
  };
94
360
  var InMemoryViewsForTableCache = class {
@@ -255,6 +521,31 @@ function getLocaleFromUrlPath(pattern = DEFAULT_URL_LOCALE_PATTERN) {
255
521
  const match = window.location.pathname.match(pattern);
256
522
  return match?.[1] ?? null;
257
523
  }
524
+ function shouldPrefixLocale(strategy, locale, defaultLocale) {
525
+ switch (strategy) {
526
+ case "CookieOnly":
527
+ return false;
528
+ case "PathPrefixAll":
529
+ return true;
530
+ default:
531
+ return locale.toLowerCase() !== defaultLocale.toLowerCase();
532
+ }
533
+ }
534
+ function stripLocalePrefix(pathname, supportedLocales) {
535
+ const trimmed = pathname.replace(/^\/+/, "");
536
+ if (trimmed.length === 0) return "/";
537
+ const slash = trimmed.indexOf("/");
538
+ const first = slash < 0 ? trimmed : trimmed.slice(0, slash);
539
+ const isLocale = supportedLocales.some((l) => l.toLowerCase() === first.toLowerCase());
540
+ if (!isLocale) return pathname.startsWith("/") ? pathname : `/${pathname}`;
541
+ const rest = slash < 0 ? "" : trimmed.slice(slash);
542
+ return rest.length === 0 ? "/" : rest;
543
+ }
544
+ function buildLocalePath(options) {
545
+ const { strategy, locale, defaultLocale, pathname, supportedLocales } = options;
546
+ const cultureless = stripLocalePrefix(pathname, supportedLocales);
547
+ return shouldPrefixLocale(strategy, locale, defaultLocale) ? `/${locale}${cultureless}` : cultureless;
548
+ }
258
549
  function detectLocale(options) {
259
550
  const {
260
551
  matchUrl = true,
@@ -309,6 +600,12 @@ var LocaleContext = createContext(null);
309
600
  LocaleContext.displayName = "Locale";
310
601
  var LocalizationManifestContext = createContext(null);
311
602
  LocalizationManifestContext.displayName = "LocalizationManifest";
603
+ function useUrlCultureStrategy() {
604
+ return useContext(LocalizationManifestContext)?.urlCultureStrategy;
605
+ }
606
+ function useDefaultLocale() {
607
+ return useContext(LocalizationManifestContext)?.supportedLocales?.[0];
608
+ }
312
609
  function useLocale() {
313
610
  const ctx = useContext(LocaleContext);
314
611
  return ctx ?? { locale: "en", setLocale: noopSetLocale };
@@ -356,6 +653,9 @@ function DefaultLocalizerProvider({
356
653
  }) {
357
654
  const [cache, setCache] = useState({});
358
655
  const [supportedLocales, setSupportedLocales] = useState(void 0);
656
+ const [urlCultureStrategy, setUrlCultureStrategy] = useState(
657
+ void 0
658
+ );
359
659
  const { locale } = useLocale();
360
660
  const { ppp } = usePowerPortalsPro();
361
661
  const localeRef = useRef(locale);
@@ -425,6 +725,7 @@ function DefaultLocalizerProvider({
425
725
  const manifest = await pppRef.current.retrieveLocalizationBundleManifestAsync();
426
726
  if (cancelled) return;
427
727
  setSupportedLocales(manifest.supportedLocales);
728
+ setUrlCultureStrategy(manifest.urlCultureStrategy);
428
729
  const resolvedLocale = manifest.supportedLocales.includes(locale) ? locale : manifest.supportedLocales[0] ?? locale;
429
730
  const thumbs = await pppRef.current.retrieveLocalizationThumbprintsAsync(resolvedLocale);
430
731
  if (cancelled) return;
@@ -613,8 +914,8 @@ function DefaultLocalizerProvider({
613
914
  [flushPending]
614
915
  );
615
916
  const manifestContextValue = useMemo(
616
- () => ({ supportedLocales }),
617
- [supportedLocales]
917
+ () => ({ supportedLocales, urlCultureStrategy }),
918
+ [supportedLocales, urlCultureStrategy]
618
919
  );
619
920
  return /* @__PURE__ */ jsx(LocalizationManifestContext.Provider, { value: manifestContextValue, children: /* @__PURE__ */ jsx(LocalizationPrefetcherContext.Provider, { value: prefetcher, children: /* @__PURE__ */ jsx(LocalizerProvider, { value: localizer, children }) }) });
620
921
  }
@@ -683,7 +984,7 @@ function PowerPortalsProProvider({
683
984
  tableMetadataCache,
684
985
  viewMetadataCache,
685
986
  viewsForTableCache,
686
- environmentFileSettingsCache
987
+ organizationSettingsCache
687
988
  }) {
688
989
  const transportRef = useRef(null);
689
990
  if (transportRef.current === null) {
@@ -704,9 +1005,9 @@ function PowerPortalsProProvider({
704
1005
  () => viewsForTableCache ?? new InMemoryViewsForTableCache(ppp),
705
1006
  [ppp, viewsForTableCache]
706
1007
  );
707
- const resolvedEnvironmentFileSettingsCache = useMemo(
708
- () => environmentFileSettingsCache ?? new InMemoryEnvironmentFileSettingsCache(ppp),
709
- [ppp, environmentFileSettingsCache]
1008
+ const resolvedOrganizationSettingsCache = useMemo(
1009
+ () => organizationSettingsCache ?? new InMemoryOrganizationSettingsCache(ppp),
1010
+ [ppp, organizationSettingsCache]
710
1011
  );
711
1012
  const [authState, setAuthState] = useState({ status: AuthStatus.Loading });
712
1013
  const refreshAuth = useCallback(async () => {
@@ -753,7 +1054,7 @@ function PowerPortalsProProvider({
753
1054
  tableMetadataCache: resolvedTableMetadataCache,
754
1055
  viewMetadataCache: resolvedViewMetadataCache,
755
1056
  viewsForTableCache: resolvedViewsForTableCache,
756
- environmentFileSettingsCache: resolvedEnvironmentFileSettingsCache,
1057
+ organizationSettingsCache: resolvedOrganizationSettingsCache,
757
1058
  authState,
758
1059
  refreshAuth,
759
1060
  login,
@@ -767,7 +1068,7 @@ function PowerPortalsProProvider({
767
1068
  resolvedTableMetadataCache,
768
1069
  resolvedViewMetadataCache,
769
1070
  resolvedViewsForTableCache,
770
- resolvedEnvironmentFileSettingsCache,
1071
+ resolvedOrganizationSettingsCache,
771
1072
  authState,
772
1073
  refreshAuth,
773
1074
  login,
@@ -802,7 +1103,7 @@ function CacheLocaleSync() {
802
1103
  tableMetadataCache,
803
1104
  viewMetadataCache,
804
1105
  viewsForTableCache,
805
- environmentFileSettingsCache
1106
+ organizationSettingsCache
806
1107
  } = usePowerPortalsPro();
807
1108
  const isFirstRun = useRef(true);
808
1109
  useEffect(() => {
@@ -813,13 +1114,13 @@ function CacheLocaleSync() {
813
1114
  tableMetadataCache.clear();
814
1115
  viewMetadataCache.clear();
815
1116
  viewsForTableCache.clear();
816
- environmentFileSettingsCache.invalidate();
1117
+ organizationSettingsCache.invalidate();
817
1118
  }, [
818
1119
  locale,
819
1120
  tableMetadataCache,
820
1121
  viewMetadataCache,
821
1122
  viewsForTableCache,
822
- environmentFileSettingsCache
1123
+ organizationSettingsCache
823
1124
  ]);
824
1125
  return null;
825
1126
  }
@@ -1228,16 +1529,16 @@ function useViewsForTable(tableLogicalName, options) {
1228
1529
  );
1229
1530
  }
1230
1531
 
1231
- // src/use-environment-file-settings.ts
1232
- function useEnvironmentFileSettings(options) {
1233
- const { environmentFileSettingsCache } = usePowerPortalsPro();
1532
+ // src/use-organization-settings.ts
1533
+ function useOrganizationSettings(options) {
1534
+ const { organizationSettingsCache } = usePowerPortalsPro();
1234
1535
  const enabled = options?.enabled ?? true;
1235
1536
  return useAsyncResource(
1236
1537
  async () => {
1237
- const result = await environmentFileSettingsCache.getAsync();
1538
+ const result = await organizationSettingsCache.getAsync();
1238
1539
  return result ?? void 0;
1239
1540
  },
1240
- [environmentFileSettingsCache],
1541
+ [organizationSettingsCache],
1241
1542
  enabled
1242
1543
  );
1243
1544
  }
@@ -1621,10 +1922,8 @@ function valuesEqual(a, b) {
1621
1922
  var GUID_PATTERN = /^\{?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\}?$/i;
1622
1923
  function parseQueryDefault(metadata, rawValue) {
1623
1924
  switch (metadata.$type) {
1624
- // StringMetadata + MemoMetadata both ride on StringValue. In Blazor
1625
- // MemoMetadata derives from StringMetadata so a single `StringMetadata`
1626
- // pattern catches both; in TS the discriminators are distinct so we
1627
- // list both arms.
1925
+ // StringMetadata + MemoMetadata both ride on StringValue. The TS
1926
+ // discriminators are distinct so we list both arms.
1628
1927
  case 14:
1629
1928
  case 7:
1630
1929
  return { $type: 14, value: rawValue };
@@ -1755,7 +2054,7 @@ function RecordContextInner({
1755
2054
  }, [resolvedId, propIsEmptyId]);
1756
2055
  const isCreateMode = effectiveId === void 0;
1757
2056
  const isSkipFetchMode = !isCreateMode && loadedRecordProp !== void 0;
1758
- const { ppp } = usePowerPortalsPro();
2057
+ const { ppp, organizationSettingsCache } = usePowerPortalsPro();
1759
2058
  const mainContext = useMainContext();
1760
2059
  const validation = useValidationContext();
1761
2060
  const isTopMost = mainContext === null;
@@ -1831,6 +2130,44 @@ function RecordContextInner({
1831
2130
  (current) => current ? { ...current, properties: nextProperties } : current
1832
2131
  );
1833
2132
  }, [isCreateMode, queryParameterName, metadataQuery.data, loadedRecord]);
2133
+ useEffect(() => {
2134
+ if (!isCreateMode) return;
2135
+ if (!metadataQuery.data) return;
2136
+ if (!loadedRecord) return;
2137
+ if (pendingChangesRef.current.size > 0) return;
2138
+ if (loadedRecord.currency) return;
2139
+ let cancelled = false;
2140
+ (async () => {
2141
+ try {
2142
+ const settings = await organizationSettingsCache.getAsync();
2143
+ if (cancelled) return;
2144
+ const defaultCurrency = settings?.defaultCurrency;
2145
+ if (!defaultCurrency) return;
2146
+ const tableHasCurrencyLookup = metadataQuery.data.columns?.some((c) => c.columnName === "transactioncurrencyid") ?? false;
2147
+ setLoadedRecord((current) => {
2148
+ if (!current) return current;
2149
+ if (current.currency) return current;
2150
+ const nextProperties = {
2151
+ ...current.properties ?? {}
2152
+ };
2153
+ if (tableHasCurrencyLookup && !nextProperties["transactioncurrencyid"]) {
2154
+ nextProperties["transactioncurrencyid"] = {
2155
+ $type: 6,
2156
+ // ColumnType.Lookup — matches the discriminator on LookupValue
2157
+ value: defaultCurrency.id,
2158
+ tableName: "transactioncurrency",
2159
+ name: defaultCurrency.name
2160
+ };
2161
+ }
2162
+ return { ...current, currency: defaultCurrency, properties: nextProperties };
2163
+ });
2164
+ } catch {
2165
+ }
2166
+ })();
2167
+ return () => {
2168
+ cancelled = true;
2169
+ };
2170
+ }, [isCreateMode, metadataQuery.data, loadedRecord, organizationSettingsCache]);
1834
2171
  useEffect(() => {
1835
2172
  if (!isSkipFetchMode || !loadedRecordProp) return;
1836
2173
  setLoadedRecord(loadedRecordProp);
@@ -1903,10 +2240,10 @@ function RecordContextInner({
1903
2240
  record: {
1904
2241
  tableName: current.tableName,
1905
2242
  // Include the client-pre-generated GUID. The seed effect writes
1906
- // it into `_idForCreate` (Blazor parity); the server's in-batch
1907
- // resolver matches AssociateRequest / child-FK references
1908
- // against either `id` or `_idForCreate`, so a Create + Associate
1909
- // pair within one `ExecuteMultiple` resolves to the same record.
2243
+ // it into `_idForCreate`; the server's in-batch resolver matches
2244
+ // AssociateRequest / child-FK references against either `id` or
2245
+ // `_idForCreate`, so a Create + Associate pair within one
2246
+ // `ExecuteMultiple` resolves to the same record.
1910
2247
  // `id` is also forwarded when the consumer supplied an explicit
1911
2248
  // one via `initialRecord` (rare — pre-assigned ids on data
1912
2249
  // import).
@@ -2258,6 +2595,6 @@ function useUnsavedChangesGuard() {
2258
2595
  // src/index.ts
2259
2596
  var VERSION = "0.1.0";
2260
2597
 
2261
- export { ASP_NET_CULTURE_COOKIE, AuthStatus, AuthorizedView, DEFAULT_URL_LOCALE_PATTERN, DefaultLocalizerProvider, DialogServiceProvider, InMemoryEnvironmentFileSettingsCache, InMemoryTableMetadataCache, InMemoryViewMetadataCache, InMemoryViewsForTableCache, LocaleProvider, LocalizerProvider, LookupRecordContext, MainContext, MainContextProvider, OverlayServiceProvider, PowerPortalsProContext, PowerPortalsProProvider, QueryStatus, RecordContext, UnsavedChangesRegistryProvider, VERSION, ValidationProvider, createLocalizer, detectLocale, flattenStrings, getAspNetCultureCookie, getLocaleFromUrlPath, interpolate, resolveLocalizationUrl, runWithOverlayAsync, setAspNetCultureCookie, useAuth, useColumnMetadata, useColumnValidationErrors, useDialogService, useEnvironmentFileSettings, useFetchRecords, useGridData, useIsAnyDirty, useLocale, useLocalization, useLocalizationLoaded, useLocalizationPrefetcher, useLocalizer, useMainContext, useOverlayForTarget, useOverlayService, useOverlayServiceState, usePowerPortalsPro, usePrefixedT, useQueryParam, useRecord, useRecordContext, useRecordContextOptional, useRunWithOverlay, useSupportedLocales, useT, useTableMetadata, useTablePermissions, useUnsavedChangesGuard, useUnsavedChangesRegistry, useUnsavedChangesWarning, useValidationContext, useViewDataSource, useViewMetadata, useViewsForTable, useWarnAboutUnsavedChanges, warnAboutUnsavedChangesAsync };
2598
+ export { ASP_NET_CULTURE_COOKIE, AuthStatus, AuthorizedView, DEFAULT_URL_LOCALE_PATTERN, DefaultLocalizerProvider, DialogServiceProvider, InMemoryOrganizationSettingsCache, InMemoryTableMetadataCache, InMemoryViewMetadataCache, InMemoryViewsForTableCache, LocaleProvider, LocalizerProvider, LookupRecordContext, MainContext, MainContextProvider, MaskMode, OverlayServiceProvider, PowerPortalsProContext, PowerPortalsProProvider, QueryStatus, RecordContext, UnsavedChangesRegistryProvider, VERSION, ValidationProvider, buildLocalePath, createLocalizer, detectLocale, flattenStrings, getAspNetCultureCookie, getLocaleFromUrlPath, interpolate, reformat, resolveLocalizationUrl, runWithOverlayAsync, setAspNetCultureCookie, shouldPrefixLocale, stripLocalePrefix, useAuth, useColumnMetadata, useColumnValidationErrors, useDefaultLocale, useDialogService, useFetchRecords, useGridData, useIsAnyDirty, useLocale, useLocalization, useLocalizationLoaded, useLocalizationPrefetcher, useLocalizer, useMainContext, useMaskedTextField, useOrganizationSettings, useOverlayForTarget, useOverlayService, useOverlayServiceState, usePowerPortalsPro, usePrefixedT, useQueryParam, useRecord, useRecordContext, useRecordContextOptional, useRunWithOverlay, useSupportedLocales, useT, useTableMetadata, useTablePermissions, useUnsavedChangesGuard, useUnsavedChangesRegistry, useUnsavedChangesWarning, useUrlCultureStrategy, useValidationContext, useViewDataSource, useViewMetadata, useViewsForTable, useWarnAboutUnsavedChanges, warnAboutUnsavedChangesAsync };
2262
2599
  //# sourceMappingURL=index.js.map
2263
2600
  //# sourceMappingURL=index.js.map