@rchemist/listgrid 0.2.18 → 0.2.19

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.
@@ -11,6 +11,9 @@ import { MultiSelectBox } from '../../ui';
11
11
  import { getEndpoint } from '../../config/RuntimeConfig';
12
12
  // alias별 options 캐시 (동일 페이지 내에서 공유)
13
13
  const customOptionCache = new Map();
14
+ // alias 캐시 키 정규화: 앞뒤 공백 제거 + lowercase.
15
+ // 백엔드의 OptionService.normalizeAlias 와 동일한 규칙.
16
+ const aliasCacheKey = (alias) => alias?.trim().toLowerCase();
14
17
  export class CustomOptionField extends OptionalField {
15
18
  constructor(name, order, alias, multiple) {
16
19
  super(name, order, 'custom');
@@ -136,12 +139,14 @@ export class CustomOptionField extends OptionalField {
136
139
  }
137
140
  }
138
141
  export async function getCustomOptionValues(alias) {
142
+ const trimmedAlias = alias?.trim();
143
+ const cacheKey = aliasCacheKey(alias);
139
144
  // 캐시에 있으면 캐시에서 반환
140
- if (customOptionCache.has(alias)) {
141
- return customOptionCache.get(alias);
145
+ if (customOptionCache.has(cacheKey)) {
146
+ return customOptionCache.get(cacheKey);
142
147
  }
143
148
  const response = await getExternalApiDataWithError({
144
- url: `${getEndpoint('customOptionByAlias')}/${alias}`,
149
+ url: `${getEndpoint('customOptionByAlias')}/${trimmedAlias}`,
145
150
  method: 'GET',
146
151
  });
147
152
  // 데이터가 정상적으로 들어왔다면 옵션 데이터를 생성해 반환한다. 오류가 발생했다면(alias 가 없거나 하는 경우) 빈 배열을 반환한다.
@@ -149,7 +154,7 @@ export async function getCustomOptionValues(alias) {
149
154
  const options = [
150
155
  ...response.data.values.map((item) => ({ value: item.value, label: item.label })),
151
156
  ];
152
- customOptionCache.set(alias, options);
157
+ customOptionCache.set(cacheKey, options);
153
158
  return options;
154
159
  }
155
160
  return [];
@@ -159,13 +164,13 @@ export async function getCustomOptionValues(alias) {
159
164
  * ViewListGrid에서 목록 렌더링 전에 호출하여 N+1 문제 방지
160
165
  */
161
166
  export async function prefetchCustomOptions(aliases) {
162
- // 이미 캐시에 있는 alias 제외
163
- const uncachedAliases = aliases.filter((alias) => !customOptionCache.has(alias));
167
+ // 이미 캐시에 있는 alias 제외 (캐시 키는 trim + lowercase 정규화)
168
+ const uncachedAliases = aliases.filter((alias) => !customOptionCache.has(aliasCacheKey(alias)));
164
169
  if (uncachedAliases.length === 0) {
165
170
  return;
166
171
  }
167
172
  const params = new URLSearchParams();
168
- uncachedAliases.forEach((alias) => params.append('aliases', alias));
173
+ uncachedAliases.forEach((alias) => params.append('aliases', alias?.trim()));
169
174
  const response = await getExternalApiDataWithError({
170
175
  url: `${getEndpoint('customOptionByAliases')}?${params.toString()}`,
171
176
  method: 'GET',
@@ -177,7 +182,7 @@ export async function prefetchCustomOptions(aliases) {
177
182
  value: item.value,
178
183
  label: item.label,
179
184
  }));
180
- customOptionCache.set(optionData.alias, options);
185
+ customOptionCache.set(aliasCacheKey(optionData.alias), options);
181
186
  }
182
187
  }
183
188
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rchemist/listgrid",
3
- "version": "0.2.18",
3
+ "version": "0.2.19",
4
4
  "private": false,
5
5
  "description": "Framework-free React CRUD UI engine — primitive-based design system, data-attr theming, and a full list/form renderer for RCM-framework-style entity backends.",
6
6
  "keywords": [