@nocobase/client-v2 2.1.26 → 2.1.27

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.
@@ -64,6 +64,7 @@ const languageCodes = {
64
64
  "ml-IN": { label: "\u0D2E\u0D32\u0D2F\u0D3E\u0D33\u0D02" },
65
65
  "mn-MN": { label: "\u041C\u043E\u043D\u0433\u043E\u043B \u0445\u044D\u043B" },
66
66
  "ms-MY": { label: "\u0628\u0647\u0627\u0633 \u0645\u0644\u0627\u064A\u0648" },
67
+ "my-MM": { label: "\u1019\u103C\u1014\u103A\u1019\u102C\u1018\u102C\u101E\u102C" },
67
68
  "nb-NO": { label: "Norsk bokm\xE5l" },
68
69
  "ne-NP": { label: "\u0928\u0947\u092A\u093E\u0932\u0940" },
69
70
  "nl-BE": { label: "Vlaams" },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nocobase/client-v2",
3
- "version": "2.1.26",
3
+ "version": "2.1.27",
4
4
  "license": "Apache-2.0",
5
5
  "main": "lib/index.js",
6
6
  "module": "es/index.mjs",
@@ -27,11 +27,11 @@
27
27
  "@formily/antd-v5": "1.2.3",
28
28
  "@formily/react": "^2.2.27",
29
29
  "@formily/shared": "^2.2.27",
30
- "@nocobase/evaluators": "2.1.26",
31
- "@nocobase/flow-engine": "2.1.26",
32
- "@nocobase/sdk": "2.1.26",
33
- "@nocobase/shared": "2.1.26",
34
- "@nocobase/utils": "2.1.26",
30
+ "@nocobase/evaluators": "2.1.27",
31
+ "@nocobase/flow-engine": "2.1.27",
32
+ "@nocobase/sdk": "2.1.27",
33
+ "@nocobase/shared": "2.1.27",
34
+ "@nocobase/utils": "2.1.27",
35
35
  "ahooks": "^3.7.2",
36
36
  "antd": "5.24.2",
37
37
  "antd-style": "3.7.1",
@@ -47,5 +47,5 @@
47
47
  "react-i18next": "^11.15.1",
48
48
  "react-router-dom": "^6.30.1"
49
49
  },
50
- "gitHead": "b25700115794487b342ac33a63a1a988c75c112c"
50
+ "gitHead": "c1311c48cf65f8eeac17411d3380ebdd0918f1e2"
51
51
  }
@@ -569,9 +569,13 @@ export class CollectionBlockModel<T = DefaultStructure> extends DataBlockModel<T
569
569
  }
570
570
  if (fieldPath.includes('.')) {
571
571
  // 关系数据
572
+ const collection = this.collection;
573
+ if (!collection) {
574
+ return;
575
+ }
572
576
  const [field1, field2] = fieldPath.split('.');
573
577
  const associationField = this.context.dataSourceManager.getCollectionField(
574
- `${this.collection.dataSourceKey}.${this.collection.name}.${field1}`,
578
+ `${collection.dataSourceKey}.${collection.name}.${field1}`,
575
579
  ) as CollectionField;
576
580
  if (!associationField) {
577
581
  return;
@@ -583,7 +587,7 @@ export class CollectionBlockModel<T = DefaultStructure> extends DataBlockModel<T
583
587
  }
584
588
 
585
589
  const collectionField = this.context.dataSourceManager.getCollectionField(
586
- `${this.collection.dataSourceKey}.${targetCollectionName}.${field2}`,
590
+ `${collection.dataSourceKey}.${targetCollectionName}.${field2}`,
587
591
  ) as CollectionField;
588
592
 
589
593
  if (collectionField && collectionField.isAssociationField()) {
@@ -9,6 +9,7 @@
9
9
 
10
10
  import { FlowModel, FlowModelRenderer, observable, tExpr } from '@nocobase/flow-engine';
11
11
  import { Icon, type NocoBaseDesktopRoute } from '../../../../flow-compat';
12
+ import type { RouteRepository } from '../../../../RouteRepository';
12
13
  import { useRequest } from 'ahooks';
13
14
  import React from 'react';
14
15
  import { SkeletonFallback } from '../../../components/SkeletonFallback';
@@ -52,6 +53,25 @@ function normalizePersistedRoute(payload: unknown): Partial<NocoBaseDesktopRoute
52
53
  return undefined;
53
54
  }
54
55
 
56
+ type RefreshableRouteRepository = Pick<RouteRepository, 'refreshAccessible'>;
57
+
58
+ const routeRefreshQueues = new WeakMap<RefreshableRouteRepository, Promise<unknown>>();
59
+
60
+ async function refreshRouteRepository(repository: RefreshableRouteRepository) {
61
+ const previous = routeRefreshQueues.get(repository) || Promise.resolve();
62
+ const current = previous.catch(() => undefined).then(() => repository.refreshAccessible());
63
+
64
+ routeRefreshQueues.set(repository, current);
65
+
66
+ try {
67
+ await current;
68
+ } finally {
69
+ if (routeRefreshQueues.get(repository) === current) {
70
+ routeRefreshQueues.delete(repository);
71
+ }
72
+ }
73
+ }
74
+
55
75
  export class BasePageTabModel extends FlowModel<{
56
76
  subModels: {
57
77
  grid: BlockGridModel;
@@ -168,22 +188,36 @@ export class RootPageTabModel extends BasePageTabModel {
168
188
  async save() {
169
189
  const json = this.serialize();
170
190
  const documentTitle = this.stepParams?.pageTabSettings?.tab?.documentTitle;
171
- const response = await this.context.api.request({
172
- method: 'post',
173
- url: 'desktopRoutes:updateOrCreate',
174
- params: {
175
- filterKeys: ['schemaUid'],
191
+ const route = this.props.route || {};
192
+ const persisted = route.id != null;
193
+ const currentRoute =
194
+ persisted && route.schemaUid ? this.context.routeRepository?.getRouteBySchemaUid?.(route.schemaUid) : undefined;
195
+ const data = {
196
+ ...(persisted ? { schemaUid: route.schemaUid } : route),
197
+ title: this.getTabTitle(''),
198
+ icon: this.getTabIcon(),
199
+ options: {
200
+ ...(currentRoute ? currentRoute.options : route.options),
201
+ flowRegistry: json.flowRegistry,
202
+ documentTitle,
176
203
  },
177
- data: {
178
- ...this.props.route,
179
- title: this.getTabTitle(''),
180
- icon: this.getTabIcon(),
181
- options: {
182
- flowRegistry: json.flowRegistry,
183
- documentTitle,
184
- },
185
- },
186
- });
204
+ };
205
+ const response = await this.context.api.request(
206
+ persisted
207
+ ? {
208
+ method: 'post',
209
+ url: `desktopRoutes:update?filter[id]=${route.id}`,
210
+ data,
211
+ }
212
+ : {
213
+ method: 'post',
214
+ url: 'desktopRoutes:updateOrCreate',
215
+ params: {
216
+ filterKeys: ['schemaUid'],
217
+ },
218
+ data,
219
+ },
220
+ );
187
221
  const persistedRoute = normalizePersistedRoute(response?.data?.data);
188
222
 
189
223
  // 新建 tab 首次保存后需要立即拿到持久化 route id,拖拽排序会直接依赖它。
@@ -197,6 +231,20 @@ export class RootPageTabModel extends BasePageTabModel {
197
231
  },
198
232
  });
199
233
  }
234
+
235
+ // 后续保存会从 RouteRepository 读取扩展 options,当前写入完成后必须先同步最新路由快照。
236
+ try {
237
+ if (this.context.routeRepository?.refreshAccessible) {
238
+ await refreshRouteRepository(this.context.routeRepository);
239
+ } else {
240
+ await this.context.refreshDesktopRoutes?.();
241
+ }
242
+ } catch (error) {
243
+ this.context.logger?.warn?.(
244
+ { err: error },
245
+ '[client-v2] Failed to refresh desktop routes after saving a page tab',
246
+ );
247
+ }
200
248
  }
201
249
 
202
250
  async destroy() {