@docyrus/ui-pro-ai-assistant 0.4.7 → 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
@@ -3338,12 +3338,14 @@ async function updateRecordSharePermission(apiClient, dataSourceId, recordId, sh
3338
3338
  const response = await apiClient.post("/users/acl/share", {
3339
3339
  dataSourceId,
3340
3340
  recordId,
3341
- items: [{
3342
- principalType: share.principalType,
3343
- principalId: share.principalId,
3344
- permissions,
3345
- expiresAt: share.expiresAt || null
3346
- }]
3341
+ items: [
3342
+ {
3343
+ principalType: share.principalType,
3344
+ principalId: share.principalId,
3345
+ permissions,
3346
+ expiresAt: share.expiresAt || null
3347
+ }
3348
+ ]
3347
3349
  });
3348
3350
  return response.success;
3349
3351
  } catch (error) {
@@ -3356,10 +3358,12 @@ async function removeRecordShare(apiClient, dataSourceId, recordId, share) {
3356
3358
  const body = {
3357
3359
  dataSourceId,
3358
3360
  recordId,
3359
- items: [{
3360
- principalType: share.principalType,
3361
- principalId: share.principalId
3362
- }]
3361
+ items: [
3362
+ {
3363
+ principalType: share.principalType,
3364
+ principalId: share.principalId
3365
+ }
3366
+ ]
3363
3367
  };
3364
3368
  if (apiClient.deleteWithBody) {
3365
3369
  const response = await apiClient.deleteWithBody("/users/acl/share", body);
@@ -4953,12 +4957,14 @@ var USER_TYPES = /* @__PURE__ */ new Set([
4953
4957
  "userSelect",
4954
4958
  "userMultiSelect"
4955
4959
  ]);
4960
+ var RELATION_TYPES = /* @__PURE__ */ new Set(["field-relation", "relation"]);
4956
4961
  var CACHE_TTL_MS = 10 * 60 * 1e3;
4957
4962
  var USERS_PAGE_LIMIT = 200;
4958
4963
  var USERS_PAGE_CAP = 5;
4959
4964
  var metaCache = /* @__PURE__ */ new Map();
4960
4965
  var enumsCache = /* @__PURE__ */ new Map();
4961
4966
  var usersCache = /* @__PURE__ */ new Map();
4967
+ var relationCache = /* @__PURE__ */ new Map();
4962
4968
  function getOrFetch(cache, key, loader) {
4963
4969
  const now = Date.now();
4964
4970
  const cached = cache.get(key);
@@ -4994,9 +5000,11 @@ async function fetchMeta(apiClient, dataSourceId, baseUrl, getDataSourceSchema)
4994
5000
  return {
4995
5001
  dataSource: {
4996
5002
  name: ds.name,
5003
+ type: ds.type,
4997
5004
  appSlug,
4998
5005
  dsSlug,
4999
- labelField: ds.label_field
5006
+ labelField: ds.label_field || ds.labelField,
5007
+ idField: ds.id_field || ds.idField
5000
5008
  },
5001
5009
  fields: dsFields
5002
5010
  };
@@ -5019,7 +5027,15 @@ async function fetchEnums(apiClient, dataSourceId, baseUrl) {
5019
5027
  id: opt.id,
5020
5028
  name: opt.name,
5021
5029
  color: opt.color,
5022
- 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
5023
5039
  });
5024
5040
  }
5025
5041
  return byFieldId.size > 0 ? byFieldId : null;
@@ -5042,7 +5058,7 @@ async function fetchUsers(apiClient, baseUrl) {
5042
5058
  const id = u.id || u.user_id;
5043
5059
  if (!id || seen.has(id)) continue;
5044
5060
  seen.add(id);
5045
- added += 1;
5061
+ added++;
5046
5062
  const nameParts = [u.firstname, u.lastname].filter(Boolean).join(" ");
5047
5063
  all3.push({
5048
5064
  id,
@@ -5055,6 +5071,61 @@ async function fetchUsers(apiClient, baseUrl) {
5055
5071
  return all3.length > 0 ? all3 : null;
5056
5072
  });
5057
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
+ }
5058
5129
  function useResolvedRecordFields(dataSourceId, recordSlugs) {
5059
5130
  const apiClient = useApiClient();
5060
5131
  const config3 = useAssistantConfig();
@@ -5068,12 +5139,8 @@ function useResolvedRecordFields(dataSourceId, recordSlugs) {
5068
5139
  );
5069
5140
  const apiClientRef = useRef(apiClient);
5070
5141
  const configRef = useRef(config3);
5071
- useEffect(() => {
5072
- apiClientRef.current = apiClient;
5073
- });
5074
- useEffect(() => {
5075
- configRef.current = config3;
5076
- });
5142
+ apiClientRef.current = apiClient;
5143
+ configRef.current = config3;
5077
5144
  const baseUrl = config3.apiBaseUrl;
5078
5145
  useEffect(() => {
5079
5146
  if (!dataSourceId) {
@@ -5082,7 +5149,7 @@ function useResolvedRecordFields(dataSourceId, recordSlugs) {
5082
5149
  }
5083
5150
  let cancelled = false;
5084
5151
  setLoading(true);
5085
- (async () => {
5152
+ const run = async () => {
5086
5153
  const meta = await fetchMeta(
5087
5154
  apiClientRef.current,
5088
5155
  dataSourceId,
@@ -5102,26 +5169,44 @@ function useResolvedRecordFields(dataSourceId, recordSlugs) {
5102
5169
  }
5103
5170
  const hasSelectFields = displayFields.some((f) => SELECT_TYPES.has(f.type));
5104
5171
  const hasUserFields = displayFields.some((f) => USER_TYPES.has(f.type));
5105
- let enumsPromise = Promise.resolve(null);
5106
- let usersPromise = Promise.resolve(null);
5107
- if (hasSelectFields) enumsPromise = fetchEnums(apiClientRef.current, dataSourceId, baseUrl);
5108
- if (hasUserFields) usersPromise = fetchUsers(apiClientRef.current, baseUrl);
5109
- 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]);
5110
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
+ }
5111
5186
  const enrichedFields = displayFields.map((f) => {
5112
- if (enums && SELECT_TYPES.has(f.type) && enums.has(f.id)) {
5113
- 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
+ }
5114
5195
  }
5115
5196
  if (users && USER_TYPES.has(f.type)) {
5116
5197
  return { ...f, enumOptions: users };
5117
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
+ }
5118
5202
  return f;
5119
5203
  });
5120
5204
  setFields(enrichedFields);
5121
5205
  setDataSource(meta.dataSource);
5122
5206
  setResolved(true);
5123
5207
  setLoading(false);
5124
- })();
5208
+ };
5209
+ void run();
5125
5210
  return () => {
5126
5211
  cancelled = true;
5127
5212
  };
@@ -5662,7 +5747,7 @@ var AIInputArea = ({
5662
5747
  {
5663
5748
  variant: "ghost",
5664
5749
  size: "sm",
5665
- className: "h-7 w-7",
5750
+ className: "-mb-2 h-7 w-7",
5666
5751
  disabled: isOptimizing || !value.trim(),
5667
5752
  onClick: () => void optimizePrompt(),
5668
5753
  children: isOptimizing ? /* @__PURE__ */ jsx(Loader2, { className: "w-4 h-4 animate-spin" }) : /* @__PURE__ */ jsx(Wand2, { className: "w-4 h-4" })
@@ -10182,12 +10267,12 @@ function UpdateRecord({
10182
10267
  useEffect(() => {
10183
10268
  if (!dataSource || !recordId || isBatch) return;
10184
10269
  let cancelled = false;
10185
- (async () => {
10270
+ const run = async () => {
10186
10271
  const { appSlug, dsSlug, labelField } = dataSource;
10187
10272
  const columns = ["autonumber_id", labelField?.slug].filter(Boolean);
10188
10273
  const endpoint = `/apps/${appSlug}/data-sources/${dsSlug}/items/${recordId}`;
10189
10274
  try {
10190
- const result = await apiClient.get(endpoint, { columns });
10275
+ const result = await apiClient.get(endpoint, { columns: columns.join(",") });
10191
10276
  if (!cancelled && result.success && result.data) {
10192
10277
  setExistingRecord(result.data);
10193
10278
  }
@@ -10196,7 +10281,8 @@ function UpdateRecord({
10196
10281
  console.warn("[update-record] header fetch failed", err);
10197
10282
  }
10198
10283
  }
10199
- })();
10284
+ };
10285
+ void run();
10200
10286
  return () => {
10201
10287
  cancelled = true;
10202
10288
  };