@docyrus/ui-pro-ai-assistant 0.4.8 → 0.5.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/hooks/use-resolved-record-fields.d.ts +4 -0
- package/dist/index.js +120 -30
- package/dist/index.js.map +1 -1
- package/dist/lib/assistant-config.d.ts +13 -0
- package/dist/styles.css +50 -45
- package/dist/views/projects-panel.d.ts +1 -0
- package/dist/views/sidebar-content.d.ts +1 -0
- package/package.json +3 -3
|
@@ -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
|
|
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
|
-
|
|
5076
|
-
|
|
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
|
-
|
|
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
|
-
|
|
5110
|
-
|
|
5111
|
-
|
|
5112
|
-
|
|
5113
|
-
|
|
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 (
|
|
5117
|
-
|
|
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
|
-
|
|
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
|
};
|
|
@@ -30577,7 +30659,7 @@ var AssistantProjectDetailView = ({
|
|
|
30577
30659
|
showToolbar: true
|
|
30578
30660
|
}
|
|
30579
30661
|
) }),
|
|
30580
|
-
/* @__PURE__ */ jsx("div", { className: "mt-
|
|
30662
|
+
/* @__PURE__ */ jsx("div", { className: "mt-8", children: /* @__PURE__ */ jsxs(Tabs$1, { value: activeTab, onValueChange: setActiveTab, className: "w-full", children: [
|
|
30581
30663
|
/* @__PURE__ */ jsxs(TabsList$1, { className: "grid w-full grid-cols-3", children: [
|
|
30582
30664
|
/* @__PURE__ */ jsx(TabsTrigger$1, { value: "sessions", children: t("tabs.sessions") }),
|
|
30583
30665
|
/* @__PURE__ */ jsx(TabsTrigger$1, { value: "works", children: t("tabs.works") }),
|
|
@@ -30712,6 +30794,7 @@ var AssistantProjectsPanel = ({
|
|
|
30712
30794
|
onEditProject,
|
|
30713
30795
|
onDeleteProject,
|
|
30714
30796
|
compact = false,
|
|
30797
|
+
sidebarOffset = false,
|
|
30715
30798
|
t
|
|
30716
30799
|
}) => {
|
|
30717
30800
|
const filtered = projects.filter((p) => {
|
|
@@ -30719,10 +30802,10 @@ var AssistantProjectsPanel = ({
|
|
|
30719
30802
|
const q = searchQuery.toLowerCase();
|
|
30720
30803
|
return p.name.toLowerCase().includes(q) || p.description && p.description.toLowerCase().includes(q);
|
|
30721
30804
|
});
|
|
30722
|
-
return /* @__PURE__ */ jsxs("div", { className:
|
|
30723
|
-
/* @__PURE__ */ jsxs("div", { className:
|
|
30805
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col overflow-y-auto p-6", children: [
|
|
30806
|
+
/* @__PURE__ */ jsxs("div", { className: cn("flex items-center justify-between mb-6", sidebarOffset && "ml-6"), children: [
|
|
30724
30807
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col min-w-0", children: [
|
|
30725
|
-
/* @__PURE__ */ jsx("h1", { className:
|
|
30808
|
+
/* @__PURE__ */ jsx("h1", { className: "text-2xl font-semibold ps-2 truncate", children: t("sections.projects") }),
|
|
30726
30809
|
!compact && /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground ps-2", children: t("descriptions.manage_projects") })
|
|
30727
30810
|
] }),
|
|
30728
30811
|
/* @__PURE__ */ jsxs(Button, { size: "sm", onClick: onNewProject, className: "shrink-0", children: [
|
|
@@ -30730,7 +30813,7 @@ var AssistantProjectsPanel = ({
|
|
|
30730
30813
|
!compact && t("buttons.new_project")
|
|
30731
30814
|
] })
|
|
30732
30815
|
] }),
|
|
30733
|
-
/* @__PURE__ */ jsx("div", { className:
|
|
30816
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-4 mb-6", children: /* @__PURE__ */ jsxs("div", { className: "relative flex-1", children: [
|
|
30734
30817
|
/* @__PURE__ */ jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground w-4 h-4" }),
|
|
30735
30818
|
/* @__PURE__ */ jsx(
|
|
30736
30819
|
Input,
|
|
@@ -30957,11 +31040,13 @@ var SidebarContent = ({
|
|
|
30957
31040
|
onShowMoreProjects,
|
|
30958
31041
|
onNewProject,
|
|
30959
31042
|
onToggleSidebar,
|
|
31043
|
+
supportWorkCanvas = true,
|
|
30960
31044
|
t
|
|
30961
31045
|
}) => {
|
|
30962
|
-
const [
|
|
31046
|
+
const [storedListType, setActiveListType] = useState("sessions");
|
|
31047
|
+
const activeListType = !supportWorkCanvas && storedListType === "works" ? "sessions" : storedListType;
|
|
30963
31048
|
const [openMenuId, setOpenMenuId] = useState(null);
|
|
30964
|
-
const navItems = [{ id: 1, label: t("tabs.sessions"), icon: MessageSquare }, { id: 3, label: t("tabs.works"), icon: NotebookText }];
|
|
31049
|
+
const navItems = [{ id: 1, label: t("tabs.sessions"), icon: MessageSquare }, ...supportWorkCanvas ? [{ id: 3, label: t("tabs.works"), icon: NotebookText }] : []];
|
|
30965
31050
|
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col flex-1 min-h-0", children: [
|
|
30966
31051
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-px", children: [
|
|
30967
31052
|
/* @__PURE__ */ jsx(
|
|
@@ -31033,7 +31118,7 @@ var SidebarContent = ({
|
|
|
31033
31118
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col mt-4 flex-1 min-h-0", children: [
|
|
31034
31119
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-start px-2 py-1.5 shrink-0", children: [
|
|
31035
31120
|
/* @__PURE__ */ jsx("span", { className: "text-xs font-semibold uppercase tracking-tight text-muted-foreground", children: t("sections.recents") }),
|
|
31036
|
-
/* @__PURE__ */ jsxs(DropdownMenu$1, { children: [
|
|
31121
|
+
supportWorkCanvas ? /* @__PURE__ */ jsxs(DropdownMenu$1, { children: [
|
|
31037
31122
|
/* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
31038
31123
|
Button,
|
|
31039
31124
|
{
|
|
@@ -31076,7 +31161,7 @@ var SidebarContent = ({
|
|
|
31076
31161
|
}
|
|
31077
31162
|
)
|
|
31078
31163
|
] })
|
|
31079
|
-
] })
|
|
31164
|
+
] }) : /* @__PURE__ */ jsx("span", { className: "ml-1 px-1 py-0 text-xs font-semibold uppercase tracking-tight text-muted-foreground", children: `${t("tabs.sessions")} (${sessions.length})` })
|
|
31080
31165
|
] }),
|
|
31081
31166
|
/* @__PURE__ */ jsx(
|
|
31082
31167
|
"div",
|
|
@@ -31425,6 +31510,9 @@ var DocyAssistant = ({
|
|
|
31425
31510
|
};
|
|
31426
31511
|
const [activeAgentId, setActiveAgentId] = useState(resolveInitialAgentId);
|
|
31427
31512
|
const [deploymentId, setDeploymentId] = useState(resolveInitialDeploymentId);
|
|
31513
|
+
const isBaseAgent = !deploymentId && !!tenantAiAgentId;
|
|
31514
|
+
const { capabilities: agentCapabilities } = useDeploymentData(deploymentId || activeAgentId, supportMultiModels, isBaseAgent);
|
|
31515
|
+
const effectiveSupportWorkCanvas = agentCapabilities ? agentCapabilities.supportWorkCanvas : supportWorkCanvas;
|
|
31428
31516
|
const title = titleProp || "DocyAssistant";
|
|
31429
31517
|
const description = descriptionProp || t("descriptions.default");
|
|
31430
31518
|
const placeholder = placeholderProp || t("placeholders.type_message");
|
|
@@ -31943,6 +32031,7 @@ var DocyAssistant = ({
|
|
|
31943
32031
|
projectActions.setView("create");
|
|
31944
32032
|
},
|
|
31945
32033
|
onToggleSidebar: isFloating && !uiState.isExpanded ? () => uiActions.setSidebarOpen(false) : void 0,
|
|
32034
|
+
supportWorkCanvas: effectiveSupportWorkCanvas,
|
|
31946
32035
|
t
|
|
31947
32036
|
}
|
|
31948
32037
|
);
|
|
@@ -32230,6 +32319,7 @@ var DocyAssistant = ({
|
|
|
32230
32319
|
projectActions.setDeleteDialogOpen(true);
|
|
32231
32320
|
},
|
|
32232
32321
|
compact: enableNavDropdown,
|
|
32322
|
+
sidebarOffset: !uiState.isSidebarOpen && enableSidebar,
|
|
32233
32323
|
t
|
|
32234
32324
|
}
|
|
32235
32325
|
),
|