@docyrus/ui-pro-ai-assistant 0.4.8 → 0.4.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,11 +1,15 @@
1
1
  import { type DataSourceField } from '../lib/assistant-config';
2
2
  export interface ResolvedDataSource {
3
3
  name?: string;
4
+ type?: string;
4
5
  appSlug: string;
5
6
  dsSlug: string;
6
7
  labelField?: {
7
8
  slug: string;
8
9
  };
10
+ idField?: {
11
+ slug: string;
12
+ };
9
13
  }
10
14
  export declare function clearRecordFieldsCache(): void;
11
15
  export interface UseResolvedRecordFieldsResult {
package/dist/index.js CHANGED
@@ -4957,12 +4957,14 @@ var USER_TYPES = /* @__PURE__ */ new Set([
4957
4957
  "userSelect",
4958
4958
  "userMultiSelect"
4959
4959
  ]);
4960
+ var RELATION_TYPES = /* @__PURE__ */ new Set(["field-relation", "relation"]);
4960
4961
  var CACHE_TTL_MS = 10 * 60 * 1e3;
4961
4962
  var USERS_PAGE_LIMIT = 200;
4962
4963
  var USERS_PAGE_CAP = 5;
4963
4964
  var metaCache = /* @__PURE__ */ new Map();
4964
4965
  var enumsCache = /* @__PURE__ */ new Map();
4965
4966
  var usersCache = /* @__PURE__ */ new Map();
4967
+ var relationCache = /* @__PURE__ */ new Map();
4966
4968
  function getOrFetch(cache, key, loader) {
4967
4969
  const now = Date.now();
4968
4970
  const cached = cache.get(key);
@@ -4998,9 +5000,11 @@ async function fetchMeta(apiClient, dataSourceId, baseUrl, getDataSourceSchema)
4998
5000
  return {
4999
5001
  dataSource: {
5000
5002
  name: ds.name,
5003
+ type: ds.type,
5001
5004
  appSlug,
5002
5005
  dsSlug,
5003
- labelField: ds.label_field
5006
+ labelField: ds.label_field || ds.labelField,
5007
+ idField: ds.id_field || ds.idField
5004
5008
  },
5005
5009
  fields: dsFields
5006
5010
  };
@@ -5023,7 +5027,15 @@ async function fetchEnums(apiClient, dataSourceId, baseUrl) {
5023
5027
  id: opt.id,
5024
5028
  name: opt.name,
5025
5029
  color: opt.color,
5026
- icon: opt.icon
5030
+ icon: opt.icon,
5031
+ parent: opt.parent || opt.parentId || opt.parent_id,
5032
+ slug: opt.slug,
5033
+ sort_order: opt.sortOrder ?? opt.sort_order,
5034
+ active: opt.active,
5035
+ is_final_option: opt.isFinalOption ?? opt.is_final_option,
5036
+ force_description: opt.forceDescription ?? opt.force_description,
5037
+ force_followup_date: opt.forceFollowupDate ?? opt.force_followup_date,
5038
+ description: opt.description
5027
5039
  });
5028
5040
  }
5029
5041
  return byFieldId.size > 0 ? byFieldId : null;
@@ -5046,7 +5058,7 @@ async function fetchUsers(apiClient, baseUrl) {
5046
5058
  const id = u.id || u.user_id;
5047
5059
  if (!id || seen.has(id)) continue;
5048
5060
  seen.add(id);
5049
- added += 1;
5061
+ added++;
5050
5062
  const nameParts = [u.firstname, u.lastname].filter(Boolean).join(" ");
5051
5063
  all3.push({
5052
5064
  id,
@@ -5059,6 +5071,61 @@ async function fetchUsers(apiClient, baseUrl) {
5059
5071
  return all3.length > 0 ? all3 : null;
5060
5072
  });
5061
5073
  }
5074
+ function resolveDisplayName(record, labelSlug) {
5075
+ const labelValue = record[labelSlug];
5076
+ if (typeof labelValue === "string" && labelValue) return labelValue;
5077
+ if (labelValue && typeof labelValue === "object" && "name" in labelValue) {
5078
+ return labelValue.name;
5079
+ }
5080
+ const nameValue = record.name;
5081
+ if (typeof nameValue === "string" && nameValue) return nameValue;
5082
+ if (nameValue && typeof nameValue === "object" && "name" in nameValue) {
5083
+ return nameValue.name;
5084
+ }
5085
+ return record.title || record.label || record.display_name || record.id;
5086
+ }
5087
+ var RELATION_ITEMS_LIMIT = 50;
5088
+ async function fetchRelationRecords(apiClient, relationDataSourceId, baseUrl, getDataSourceSchema) {
5089
+ return getOrFetch(relationCache, `${baseUrl}::${relationDataSourceId}`, async () => {
5090
+ const relMeta = await fetchMeta(apiClient, relationDataSourceId, baseUrl, getDataSourceSchema);
5091
+ if (!relMeta) return null;
5092
+ const {
5093
+ appSlug,
5094
+ dsSlug,
5095
+ labelField,
5096
+ idField,
5097
+ type: dsType
5098
+ } = relMeta.dataSource;
5099
+ const idSlug = idField?.slug || "id";
5100
+ const labelSlug = labelField?.slug;
5101
+ const columns = dsType === "simple" ? ["name", "id", "autonumber_id"] : [idSlug];
5102
+ if (labelSlug && !columns.includes(labelSlug)) {
5103
+ columns.push(labelSlug);
5104
+ }
5105
+ if (!columns.includes("name")) {
5106
+ columns.push("name");
5107
+ }
5108
+ const res = await apiClient.get(
5109
+ `/apps/${appSlug}/data-sources/${dsSlug}/items`,
5110
+ {
5111
+ limit: RELATION_ITEMS_LIMIT,
5112
+ columns: columns.join(","),
5113
+ dataSourceId: relationDataSourceId,
5114
+ fullCount: false
5115
+ }
5116
+ );
5117
+ if (!res.success) return null;
5118
+ const payload = res.data;
5119
+ const items2 = Array.isArray(payload) ? payload : payload?.items ?? payload?.data;
5120
+ if (!Array.isArray(items2) || items2.length === 0) return null;
5121
+ return items2.map((record) => ({
5122
+ id: record.id,
5123
+ name: resolveDisplayName(record, labelSlug || "name"),
5124
+ icon: record.icon || void 0,
5125
+ color: record.color || void 0
5126
+ }));
5127
+ });
5128
+ }
5062
5129
  function useResolvedRecordFields(dataSourceId, recordSlugs) {
5063
5130
  const apiClient = useApiClient();
5064
5131
  const config3 = useAssistantConfig();
@@ -5072,12 +5139,8 @@ function useResolvedRecordFields(dataSourceId, recordSlugs) {
5072
5139
  );
5073
5140
  const apiClientRef = useRef(apiClient);
5074
5141
  const configRef = useRef(config3);
5075
- useEffect(() => {
5076
- apiClientRef.current = apiClient;
5077
- });
5078
- useEffect(() => {
5079
- configRef.current = config3;
5080
- });
5142
+ apiClientRef.current = apiClient;
5143
+ configRef.current = config3;
5081
5144
  const baseUrl = config3.apiBaseUrl;
5082
5145
  useEffect(() => {
5083
5146
  if (!dataSourceId) {
@@ -5086,7 +5149,7 @@ function useResolvedRecordFields(dataSourceId, recordSlugs) {
5086
5149
  }
5087
5150
  let cancelled = false;
5088
5151
  setLoading(true);
5089
- (async () => {
5152
+ const run = async () => {
5090
5153
  const meta = await fetchMeta(
5091
5154
  apiClientRef.current,
5092
5155
  dataSourceId,
@@ -5106,26 +5169,44 @@ function useResolvedRecordFields(dataSourceId, recordSlugs) {
5106
5169
  }
5107
5170
  const hasSelectFields = displayFields.some((f) => SELECT_TYPES.has(f.type));
5108
5171
  const hasUserFields = displayFields.some((f) => USER_TYPES.has(f.type));
5109
- let enumsPromise = Promise.resolve(null);
5110
- let usersPromise = Promise.resolve(null);
5111
- if (hasSelectFields) enumsPromise = fetchEnums(apiClientRef.current, dataSourceId, baseUrl);
5112
- if (hasUserFields) usersPromise = fetchUsers(apiClientRef.current, baseUrl);
5113
- const [enums, users] = await Promise.all([enumsPromise, usersPromise]);
5172
+ const relationDsIds = [
5173
+ ...new Set(
5174
+ displayFields.filter((f) => RELATION_TYPES.has(f.type) && f.relation_data_source_id).map((f) => f.relation_data_source_id)
5175
+ )
5176
+ ];
5177
+ const enumsPromise = hasSelectFields ? fetchEnums(apiClientRef.current, dataSourceId, baseUrl) : Promise.resolve(null);
5178
+ const usersPromise = hasUserFields ? fetchUsers(apiClientRef.current, baseUrl) : Promise.resolve(null);
5179
+ const relationPromises = relationDsIds.map((relDsId) => fetchRelationRecords(apiClientRef.current, relDsId, baseUrl, configRef.current.getDataSourceSchema).then((options3) => [relDsId, options3]));
5180
+ const [enums, users, ...relationResults] = await Promise.all([enumsPromise, usersPromise, ...relationPromises]);
5114
5181
  if (cancelled) return;
5182
+ const relationMap = /* @__PURE__ */ new Map();
5183
+ for (const [relDsId, options3] of relationResults) {
5184
+ if (options3) relationMap.set(relDsId, options3);
5185
+ }
5115
5186
  const enrichedFields = displayFields.map((f) => {
5116
- if (enums && SELECT_TYPES.has(f.type) && enums.has(f.id)) {
5117
- return { ...f, enumOptions: enums.get(f.id) };
5187
+ if (SELECT_TYPES.has(f.type)) {
5188
+ if (enums && enums.has(f.id)) {
5189
+ return { ...f, enumOptions: enums.get(f.id) };
5190
+ }
5191
+ const inlineData = f.data || f.options?.data || f.options?.editorOptions?.data;
5192
+ if (Array.isArray(inlineData) && inlineData.length > 0) {
5193
+ return { ...f, enumOptions: inlineData };
5194
+ }
5118
5195
  }
5119
5196
  if (users && USER_TYPES.has(f.type)) {
5120
5197
  return { ...f, enumOptions: users };
5121
5198
  }
5199
+ if (RELATION_TYPES.has(f.type) && f.relation_data_source_id && relationMap.has(f.relation_data_source_id)) {
5200
+ return { ...f, enumOptions: relationMap.get(f.relation_data_source_id) };
5201
+ }
5122
5202
  return f;
5123
5203
  });
5124
5204
  setFields(enrichedFields);
5125
5205
  setDataSource(meta.dataSource);
5126
5206
  setResolved(true);
5127
5207
  setLoading(false);
5128
- })();
5208
+ };
5209
+ void run();
5129
5210
  return () => {
5130
5211
  cancelled = true;
5131
5212
  };
@@ -10186,12 +10267,12 @@ function UpdateRecord({
10186
10267
  useEffect(() => {
10187
10268
  if (!dataSource || !recordId || isBatch) return;
10188
10269
  let cancelled = false;
10189
- (async () => {
10270
+ const run = async () => {
10190
10271
  const { appSlug, dsSlug, labelField } = dataSource;
10191
10272
  const columns = ["autonumber_id", labelField?.slug].filter(Boolean);
10192
10273
  const endpoint = `/apps/${appSlug}/data-sources/${dsSlug}/items/${recordId}`;
10193
10274
  try {
10194
- const result = await apiClient.get(endpoint, { columns });
10275
+ const result = await apiClient.get(endpoint, { columns: columns.join(",") });
10195
10276
  if (!cancelled && result.success && result.data) {
10196
10277
  setExistingRecord(result.data);
10197
10278
  }
@@ -10200,7 +10281,8 @@ function UpdateRecord({
10200
10281
  console.warn("[update-record] header fetch failed", err);
10201
10282
  }
10202
10283
  }
10203
- })();
10284
+ };
10285
+ void run();
10204
10286
  return () => {
10205
10287
  cancelled = true;
10206
10288
  };