@meistrari/chat-nuxt 4.11.0-rc.8 → 4.11.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/README.md +0 -2
- package/dist/module.json +1 -1
- package/dist/runtime/conversations/components/chat-conversation-new-group-button.vue +2 -2
- package/dist/runtime/conversations/composables/conversation-groups.d.ts +1 -0
- package/dist/runtime/conversations/composables/conversation-groups.js +7 -2
- package/dist/runtime/conversations/composables/conversation-list.js +6 -6
- package/dist/runtime/conversations/groups.d.ts +10 -0
- package/dist/runtime/conversations/groups.js +12 -0
- package/dist/runtime/embed/components/mobile/chat-mobile-drawer.vue +4 -4
- package/dist/runtime/types/schemas/integrations/agent-events.d.ts +0 -1
- package/dist/runtime/types/schemas/integrations/agent-events.js +0 -1
- package/package.json +2 -5
package/README.md
CHANGED
|
@@ -165,13 +165,11 @@ Installing `@meistrari/chat-nuxt` installs the runtime packages used by the laye
|
|
|
165
165
|
| `mermaid` | `^11.13.0` | Native markstream Mermaid diagram rendering |
|
|
166
166
|
| `h3` | `^1.15.0` | Server route utilities provided by Nuxt/Nitro |
|
|
167
167
|
| `markstream-vue` | `2.0.7` | Markdown streaming renderer |
|
|
168
|
-
| `motion` | `^11.13.0` | Animation component runtime |
|
|
169
168
|
| `nitropack` | `^2.10.0` | Runtime config and task utilities provided by Nuxt/Nitro |
|
|
170
169
|
| `pdfjs-dist` | `^5.4.530` | PDF file previews |
|
|
171
170
|
| `posthog-js` | `^1.364.2` | Optional PostHog feature-flag helper |
|
|
172
171
|
| `stream-diffs` | `0.0.2` | Native markstream rich code and diff rendering |
|
|
173
172
|
| `virtua` | `^0.42.0` | Virtualized list runtime expected by shared UI |
|
|
174
|
-
| `xlsx` | `^0.18.5` | Spreadsheet file previews |
|
|
175
173
|
| `zod` | `^4.1.13` | Schema validation for API payloads |
|
|
176
174
|
|
|
177
175
|
The chat package does not declare or expect the host application to configure an i18n plugin. Hosts can override the supported conversation-search text through `labels`, using plain strings or their own translator. This is not a full-chat localization API; other UI text retains its existing defaults.
|
package/dist/module.json
CHANGED
|
@@ -5,7 +5,7 @@ const props = defineProps({
|
|
|
5
5
|
variant: { type: String, required: false }
|
|
6
6
|
});
|
|
7
7
|
const DEFAULT_GROUP_NAME = "Nova pasta";
|
|
8
|
-
const {
|
|
8
|
+
const { visibleGroups, createGroup, pendingRenameGroupId } = useConversationGroups();
|
|
9
9
|
const isCreating = ref(false);
|
|
10
10
|
const hasLabel = computed(() => Boolean(props.label?.trim()));
|
|
11
11
|
const isEmptyState = computed(() => props.variant === "empty-state");
|
|
@@ -17,7 +17,7 @@ const buttonClasses = computed(() => {
|
|
|
17
17
|
return "h-32px! w-40px! p-0!";
|
|
18
18
|
});
|
|
19
19
|
function nextGroupName() {
|
|
20
|
-
const names = new Set(
|
|
20
|
+
const names = new Set(visibleGroups.value.map((group) => group.name));
|
|
21
21
|
if (!names.has(DEFAULT_GROUP_NAME))
|
|
22
22
|
return DEFAULT_GROUP_NAME;
|
|
23
23
|
let index = 2;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useChatAuth } from "#chat-auth";
|
|
2
2
|
import * as Sentry from "@sentry/nuxt";
|
|
3
|
+
import { filterGroupsByCreator } from "../groups.js";
|
|
3
4
|
import { resolveChatStateScope } from "../scope.js";
|
|
4
5
|
import { useChatApi } from "../../shared/composables/chat-api.js";
|
|
5
6
|
import { useConversations } from "./conversations.js";
|
|
@@ -15,7 +16,8 @@ function sortConversationGroups(groups) {
|
|
|
15
16
|
export function useConversationGroups() {
|
|
16
17
|
const chatApi = useChatApi();
|
|
17
18
|
const embedConfig = useEmbedConfig();
|
|
18
|
-
const { activeOrganization } = useChatAuth();
|
|
19
|
+
const { user: authUser, activeOrganization } = useChatAuth();
|
|
20
|
+
const { conversationCreatorFilter, clearGroupFromConversations } = useConversations();
|
|
19
21
|
const groupBuckets = useState("conversation-groups", () => ({}));
|
|
20
22
|
const loadingBuckets = useState("conversation-groups-loading", () => ({}));
|
|
21
23
|
const fetchedBuckets = useState("conversation-groups-fetched", () => ({}));
|
|
@@ -35,6 +37,9 @@ export function useConversationGroups() {
|
|
|
35
37
|
};
|
|
36
38
|
}
|
|
37
39
|
});
|
|
40
|
+
const visibleGroups = computed(
|
|
41
|
+
() => filterGroupsByCreator(groups.value, conversationCreatorFilter.value, authUser.value?.email)
|
|
42
|
+
);
|
|
38
43
|
const loading = computed({
|
|
39
44
|
get: () => loadingBuckets.value[runtimeScope.value] ?? false,
|
|
40
45
|
set: (value) => {
|
|
@@ -133,7 +138,6 @@ export function useConversationGroups() {
|
|
|
133
138
|
const deleteGroup = async (groupId) => {
|
|
134
139
|
error.value = null;
|
|
135
140
|
const previousGroups = groups.value;
|
|
136
|
-
const { clearGroupFromConversations } = useConversations();
|
|
137
141
|
removeGroup(groupId);
|
|
138
142
|
const restoreConversations = clearGroupFromConversations(groupId);
|
|
139
143
|
try {
|
|
@@ -154,6 +158,7 @@ export function useConversationGroups() {
|
|
|
154
158
|
};
|
|
155
159
|
return {
|
|
156
160
|
groups: readonly(groups),
|
|
161
|
+
visibleGroups: readonly(visibleGroups),
|
|
157
162
|
loading: readonly(loading),
|
|
158
163
|
error: readonly(error),
|
|
159
164
|
pendingRenameGroupId,
|
|
@@ -14,7 +14,7 @@ export function useConversationList(options) {
|
|
|
14
14
|
const { activeOrganization } = useChatAuth();
|
|
15
15
|
const { deleteConversation, renameConversation, duplicateConversation, moveConversationToGroup } = useConversations();
|
|
16
16
|
const { copyConversationLink } = useConversationActions();
|
|
17
|
-
const { groups, fetchGroups, createGroup, deleteGroup, renameGroup, error: groupError, pendingRenameGroupId } = useConversationGroups();
|
|
17
|
+
const { groups, visibleGroups, fetchGroups, createGroup, deleteGroup, renameGroup, error: groupError, pendingRenameGroupId } = useConversationGroups();
|
|
18
18
|
const { setConversation, currentConversation } = useChat();
|
|
19
19
|
const exportConversationId = ref(null);
|
|
20
20
|
const debugConversationId = ref(null);
|
|
@@ -60,8 +60,8 @@ export function useConversationList(options) {
|
|
|
60
60
|
shouldInclude: (conversation) => !conversation.title && conversation.id === options.currentId
|
|
61
61
|
})
|
|
62
62
|
);
|
|
63
|
-
const filteredGroupedConversations = computed(() => groupConversationsByGroup(filteredConversations.value,
|
|
64
|
-
const allGroupedConversations = computed(() => groupConversationsByGroup(options.conversations,
|
|
63
|
+
const filteredGroupedConversations = computed(() => groupConversationsByGroup(filteredConversations.value, visibleGroups.value));
|
|
64
|
+
const allGroupedConversations = computed(() => groupConversationsByGroup(options.conversations, visibleGroups.value));
|
|
65
65
|
const groupedConversations = computed(() => {
|
|
66
66
|
if (!hasConversationSearchQuery.value)
|
|
67
67
|
return filteredGroupedConversations.value;
|
|
@@ -261,12 +261,12 @@ export function useConversationList(options) {
|
|
|
261
261
|
const ungroupedConversationLabel = computed(() => `Conversas`);
|
|
262
262
|
const shouldShowUngroupedHeader = computed(() => groupItems.value.length > 0);
|
|
263
263
|
const showGroupCreationPrompt = computed(
|
|
264
|
-
() => groupsReady.value && !hasConversationSearchQuery.value &&
|
|
264
|
+
() => groupsReady.value && !hasConversationSearchQuery.value && visibleGroups.value.length === 0
|
|
265
265
|
);
|
|
266
266
|
const hasConversationContent = computed(() => {
|
|
267
267
|
if (hasConversationSearchQuery.value)
|
|
268
268
|
return groupItems.value.length > 0 || ungroupedConversations.value.length > 0;
|
|
269
|
-
return showGroupCreationPrompt.value ||
|
|
269
|
+
return showGroupCreationPrompt.value || visibleGroups.value.length > 0 || filteredConversations.value.length > 0;
|
|
270
270
|
});
|
|
271
271
|
const deleteGroupConfirmationMessage = computed(() => {
|
|
272
272
|
const target = deleteGroupTarget.value;
|
|
@@ -506,7 +506,7 @@ export function useConversationList(options) {
|
|
|
506
506
|
const DEFAULT_GROUP_NAME = "Nova pasta";
|
|
507
507
|
const isCreatingGroup = ref(false);
|
|
508
508
|
function nextGroupName() {
|
|
509
|
-
const names = new Set(
|
|
509
|
+
const names = new Set(visibleGroups.value.map((group) => group.name));
|
|
510
510
|
if (!names.has(DEFAULT_GROUP_NAME))
|
|
511
511
|
return DEFAULT_GROUP_NAME;
|
|
512
512
|
let index = 2;
|
|
@@ -3,6 +3,16 @@ export type ConversationGroupLike = {
|
|
|
3
3
|
name: string;
|
|
4
4
|
createdAt?: Date | string;
|
|
5
5
|
};
|
|
6
|
+
export type ConversationGroupCreatorFilter = 'all' | 'mine';
|
|
7
|
+
/**
|
|
8
|
+
* Applies the sidebar creator filter to folders: with `'mine'` only folders the
|
|
9
|
+
* current user created stay visible (`createdBy` is the creator's email, the same
|
|
10
|
+
* value conversations carry); `'all'` keeps every folder. A folder without a
|
|
11
|
+
* creator, or a user without an email, never matches `'mine'`.
|
|
12
|
+
*/
|
|
13
|
+
export declare function filterGroupsByCreator<TGroup extends ConversationGroupLike & {
|
|
14
|
+
createdBy?: string | null;
|
|
15
|
+
}>(groups: readonly TGroup[], filter: ConversationGroupCreatorFilter, currentUserEmail: string | null | undefined): TGroup[];
|
|
6
16
|
export type ConversationGroupItem = {
|
|
7
17
|
groupId?: string | null;
|
|
8
18
|
updatedAt: Date | string;
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
function normalizedEmail(value) {
|
|
2
|
+
const email = value?.trim().toLowerCase();
|
|
3
|
+
return email || null;
|
|
4
|
+
}
|
|
5
|
+
export function filterGroupsByCreator(groups, filter, currentUserEmail) {
|
|
6
|
+
if (filter !== "mine")
|
|
7
|
+
return [...groups];
|
|
8
|
+
const email = normalizedEmail(currentUserEmail);
|
|
9
|
+
if (!email)
|
|
10
|
+
return [];
|
|
11
|
+
return groups.filter((group) => normalizedEmail(group.createdBy) === email);
|
|
12
|
+
}
|
|
1
13
|
function byUpdatedAtDesc(a, b) {
|
|
2
14
|
return new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime();
|
|
3
15
|
}
|
|
@@ -31,7 +31,7 @@ let dragOpenGroupTimeout = null;
|
|
|
31
31
|
let dragOpenGroupId = null;
|
|
32
32
|
const embedConfig = useEmbedConfig();
|
|
33
33
|
const { activeOrganization } = useChatAuth();
|
|
34
|
-
const {
|
|
34
|
+
const { visibleGroups, fetchGroups } = useConversationGroups();
|
|
35
35
|
const { moveConversationToGroup } = useConversations();
|
|
36
36
|
const runtimeScope = computed(() => resolveChatStateScope(
|
|
37
37
|
embedConfig?.workspaceId.value || activeOrganization.value?.id,
|
|
@@ -46,8 +46,8 @@ const filteredConversations = computed(
|
|
|
46
46
|
})
|
|
47
47
|
);
|
|
48
48
|
const hasConversationSearchQuery = computed(() => conversationSearch.value.trim().length > 0);
|
|
49
|
-
const filteredGroupedConversations = computed(() => groupConversationsByGroup(filteredConversations.value,
|
|
50
|
-
const allGroupedConversations = computed(() => groupConversationsByGroup(props.conversations,
|
|
49
|
+
const filteredGroupedConversations = computed(() => groupConversationsByGroup(filteredConversations.value, visibleGroups.value));
|
|
50
|
+
const allGroupedConversations = computed(() => groupConversationsByGroup(props.conversations, visibleGroups.value));
|
|
51
51
|
const groupedConversations = computed(() => {
|
|
52
52
|
if (!hasConversationSearchQuery.value)
|
|
53
53
|
return filteredGroupedConversations.value;
|
|
@@ -82,7 +82,7 @@ const visibleGroupBuckets = computed(() => groupedConversations.value.groups.fil
|
|
|
82
82
|
const hasConversationContent = computed(() => {
|
|
83
83
|
if (hasConversationSearchQuery.value)
|
|
84
84
|
return visibleGroupBuckets.value.length > 0 || groupedConversations.value.unfiled.length > 0;
|
|
85
|
-
return
|
|
85
|
+
return visibleGroups.value.length > 0 || filteredConversations.value.length > 0;
|
|
86
86
|
});
|
|
87
87
|
const shouldShowUngroupedHeader = computed(() => visibleGroupBuckets.value.length > 0);
|
|
88
88
|
const ungroupedConversationLabel = computed(() => `Conversas \xB7 ${groupedConversations.value.unfiled.length}`);
|
|
@@ -38,7 +38,6 @@ export declare const v5ErrorStatus: {
|
|
|
38
38
|
readonly invalid_event_limit: 400;
|
|
39
39
|
readonly invalid_artifact_limit: 400;
|
|
40
40
|
readonly invalid_user_event_batch: 400;
|
|
41
|
-
readonly provider_harness_mismatch: 400;
|
|
42
41
|
readonly insufficient_role: 403;
|
|
43
42
|
readonly agent_publication_forbidden: 403;
|
|
44
43
|
readonly session_not_found: 404;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meistrari/chat-nuxt",
|
|
3
|
-
"version": "4.11.0
|
|
3
|
+
"version": "4.11.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"@iconify-json/ph": "^1.2.2",
|
|
53
53
|
"@iconify/vue": "^5.0.0",
|
|
54
54
|
"@meistrari/auth-nuxt": "3.31.0",
|
|
55
|
-
"@meistrari/chat-ui-lang": "0.5.0
|
|
55
|
+
"@meistrari/chat-ui-lang": "0.5.0",
|
|
56
56
|
"@meistrari/logger": "^2.1.3",
|
|
57
57
|
"@meistrari/tela-build": "^1.79.0",
|
|
58
58
|
"@openuidev/lang-core": "1.0.0",
|
|
@@ -64,14 +64,12 @@
|
|
|
64
64
|
"ipaddr.js": "2.5.0",
|
|
65
65
|
"markstream-vue": "2.0.7",
|
|
66
66
|
"mermaid": "^11.13.0",
|
|
67
|
-
"motion": "^11.13.0",
|
|
68
67
|
"nitropack": "^2.10.0",
|
|
69
68
|
"pdfjs-dist": "^5.4.530",
|
|
70
69
|
"posthog-js": "^1.364.2",
|
|
71
70
|
"stream-diffs": "0.0.2",
|
|
72
71
|
"tldts": "^7.4.10",
|
|
73
72
|
"virtua": "^0.42.0",
|
|
74
|
-
"xlsx": "^0.18.5",
|
|
75
73
|
"zod": "^4.1.13"
|
|
76
74
|
},
|
|
77
75
|
"devDependencies": {
|
|
@@ -79,7 +77,6 @@
|
|
|
79
77
|
"@meistrari/chat-schemas": "workspace:*",
|
|
80
78
|
"@nuxt/module-builder": "^1.0.2",
|
|
81
79
|
"@types/node": "^20.19.0",
|
|
82
|
-
"dotenv-cli": "^11.0.0",
|
|
83
80
|
"eslint": "9.16.0",
|
|
84
81
|
"nuxt": "4.4.8",
|
|
85
82
|
"pino": "^10.3.1",
|