Skip to content

Commit fd162d6

Browse files
committed
fix(FR-2813): render folder-create notification with VFolder node card
1 parent 052967a commit fd162d6

7 files changed

Lines changed: 144 additions & 217 deletions

react/src/components/BAIGeneralNotificationItem.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ const BAIGeneralNotificationItem: React.FC<{
2929
const { token } = theme.useToken();
3030
const [showExtraDescription, setShowExtraDescription] = useState(false);
3131

32+
// antd v6 deprecated `notification.message` in favor of `notification.title`.
33+
// Read `title` first and fall back to `message` so legacy callers that still
34+
// populate `message` keep rendering until they migrate.
35+
const headerContent = notification.title ?? notification.message;
3236
const explicitIcon = notification.icon === 'folder' ? <FolderIcon /> : null;
3337
const icon =
3438
explicitIcon ||
@@ -62,11 +66,11 @@ const BAIGeneralNotificationItem: React.FC<{
6266
fontWeight: 500,
6367
}}
6468
>
65-
{_.isString(notification.message)
66-
? _.truncate(notification.message, {
69+
{_.isString(headerContent)
70+
? _.truncate(headerContent, {
6771
length: 200,
6872
})
69-
: notification.message}
73+
: headerContent}
7074
</Typography.Paragraph>
7175
</BAIFlex>
7276
<BAIFlex direction="row" align="end" gap={'xxs'} justify="between">

react/src/components/BAINodeNotificationItem.tsx

Lines changed: 9 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,16 @@
44
*/
55
import { NotificationState } from '../hooks/useBAINotification';
66
import BAIComputeSessionNodeNotificationItem from './BAIComputeSessionNodeNotificationItem';
7-
import BAIVFolderNotificationItem from './BAIVFolderNotificationItem';
8-
import BAIVirtualFolderNodeNotificationItem from './BAIVirtualFolderNodeNotificationItem';
7+
import BAIVirtualFolderNodeNotificationItemV2 from './BAIVirtualFolderNodeNotificationItemV2';
98
import React from 'react';
109
import { graphql, useRefetchableFragment } from 'react-relay';
1110
import { BAINodeNotificationItemFragment$key } from 'src/__generated__/BAINodeNotificationItemFragment.graphql';
1211

13-
// `... on VFolder` is the V2 (Strawberry GraphQL, FR-2573) branch and the
14-
// preferred path for new VFolder list/mutation flows.
15-
// `... on VirtualFolderNode` is the legacy V1 branch and is **deprecated** —
16-
// kept here only so callers that still hold V1 fragments keep rendering. It
17-
// will be removed once all VFolder callers migrate to V2 `VFolder`.
12+
// `... on VFolder` is the V2 (Strawberry GraphQL, FR-2573) branch the only
13+
// VFolder-side path. The legacy `... on VirtualFolderNode` (V1) branch and its
14+
// `BAIVirtualFolderNodeNotificationItem` component were removed once the last
15+
// V1 producer (`VFolderNodes.tsx` error notifications) migrated to inline
16+
// `title` ReactNodes that no longer need this polymorphic dispatcher.
1817
const nodeFragmentOperation = graphql`
1918
fragment BAINodeNotificationItemFragment on Node
2019
@refetchable(queryName: "BAINodeNotificationItemRefetchQuery") {
@@ -28,13 +27,8 @@ const nodeFragmentOperation = graphql`
2827
}
2928
... on VFolder {
3029
__typename
31-
...BAIVFolderNotificationItemFragment @alias(as: "vfolderFrgmt")
32-
}
33-
... on VirtualFolderNode {
34-
__typename
35-
status
36-
...BAIVirtualFolderNodeNotificationItemFragment
37-
@alias(as: "virtualFolderNodeFrgmt")
30+
...BAIVirtualFolderNodeNotificationItemV2Fragment
31+
@alias(as: "vfolderFrgmt")
3832
}
3933
}
4034
`;
@@ -57,23 +51,12 @@ const BAINodeNotificationItem: React.FC<{
5751
);
5852
} else if (node?.__typename === 'VFolder') {
5953
return (
60-
<BAIVFolderNotificationItem
54+
<BAIVirtualFolderNodeNotificationItemV2
6155
notification={notification}
6256
vfolderFrgmt={node.vfolderFrgmt || null}
6357
showDate={showDate}
6458
/>
6559
);
66-
} else if (node?.__typename === 'VirtualFolderNode') {
67-
// @deprecated Renders the legacy V1 VFolder notification. Will be removed
68-
// once all V1 callers are gone — see the matching note on the V2 branch
69-
// above.
70-
return (
71-
<BAIVirtualFolderNodeNotificationItem
72-
notification={notification}
73-
virtualFolderNodeFrgmt={node.virtualFolderNodeFrgmt || null}
74-
showDate={showDate}
75-
/>
76-
);
7760
} else {
7861
// console.warn('Unknown node type in BAINodeNotificationItem:', node);
7962
return null;

react/src/components/BAIVirtualFolderNodeNotificationItem.tsx

Lines changed: 0 additions & 148 deletions
This file was deleted.

react/src/components/BAIVFolderNotificationItem.tsx renamed to react/src/components/BAIVirtualFolderNodeNotificationItemV2.tsx

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
Copyright (c) 2015-2026 Lablup Inc. All rights reserved.
44
*/
55
import BAINotificationBackgroundProgress from './BAINotificationBackgroundProgress';
6+
import { useFolderExplorerOpener } from './FolderExplorerOpener';
67
import { useToggle } from 'ahooks';
78
import { Card, List, theme, Typography } from 'antd';
89
import {
@@ -16,16 +17,15 @@ import dayjs from 'dayjs';
1617
import * as _ from 'lodash-es';
1718
import { useTranslation } from 'react-i18next';
1819
import { graphql, useFragment } from 'react-relay';
19-
import { BAIVFolderNotificationItemFragment$key } from 'src/__generated__/BAIVFolderNotificationItemFragment.graphql';
20-
import { useWebUINavigate } from 'src/hooks';
20+
import { BAIVirtualFolderNodeNotificationItemV2Fragment$key } from 'src/__generated__/BAIVirtualFolderNodeNotificationItemV2Fragment.graphql';
2121
import {
2222
NotificationState,
2323
useSetBAINotification,
2424
} from 'src/hooks/useBAINotification';
2525

26-
interface BAIVFolderNotificationItemProps {
26+
interface BAIVirtualFolderNodeNotificationItemV2Props {
2727
notification: NotificationState;
28-
vfolderFrgmt: BAIVFolderNotificationItemFragment$key | null;
28+
vfolderFrgmt: BAIVirtualFolderNodeNotificationItemV2Fragment$key | null;
2929
showDate?: boolean;
3030
}
3131

@@ -34,14 +34,12 @@ interface BAIVFolderNotificationItemProps {
3434
// list/mutation flows can pass `node: vfolder` to `upsertNotification` and
3535
// get the same rich folder-link + extra-description rendering as the legacy
3636
// V1 path. The V1 component stays in place until all callers migrate.
37-
const BAIVFolderNotificationItem: React.FC<BAIVFolderNotificationItemProps> = ({
38-
notification,
39-
vfolderFrgmt,
40-
showDate,
41-
}) => {
37+
const BAIVirtualFolderNodeNotificationItemV2: React.FC<
38+
BAIVirtualFolderNodeNotificationItemV2Props
39+
> = ({ notification, vfolderFrgmt, showDate }) => {
4240
'use memo';
4341

44-
const navigate = useWebUINavigate();
42+
const { open: openFolderExplorer } = useFolderExplorerOpener();
4543
const { t } = useTranslation();
4644
const { token } = theme.useToken();
4745
const { closeNotification } = useSetBAINotification();
@@ -50,7 +48,7 @@ const BAIVFolderNotificationItem: React.FC<BAIVFolderNotificationItemProps> = ({
5048

5149
const node = useFragment(
5250
graphql`
53-
fragment BAIVFolderNotificationItemFragment on VFolder {
51+
fragment BAIVirtualFolderNodeNotificationItemV2Fragment on VFolder {
5452
id
5553
metadata {
5654
name
@@ -76,9 +74,9 @@ const BAIVFolderNotificationItem: React.FC<BAIVFolderNotificationItemProps> = ({
7674
}}
7775
title={folderName || ''}
7876
onClick={() => {
79-
navigate(
80-
`/data${localId ? `?${new URLSearchParams({ folder: localId }).toString()}` : ''}`,
81-
);
77+
if (localId) {
78+
openFolderExplorer(localId);
79+
}
8280
closeNotification(notification.key);
8381
}}
8482
>
@@ -148,4 +146,4 @@ const BAIVFolderNotificationItem: React.FC<BAIVFolderNotificationItemProps> = ({
148146
);
149147
};
150148

151-
export default BAIVFolderNotificationItem;
149+
export default BAIVirtualFolderNodeNotificationItemV2;

react/src/components/FolderCreateModalV2.tsx

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ const FolderCreateModalV2: React.FC<FolderCreateModalProps> = ({
197197
createVfolderV2(input: $input) {
198198
vfolder {
199199
id
200-
status
200+
vfolderStatus: status
201201
host
202202
metadata {
203203
name
@@ -214,6 +214,7 @@ const FolderCreateModalV2: React.FC<FolderCreateModalProps> = ({
214214
projectId
215215
creatorEmail
216216
}
217+
...BAINodeNotificationItemFragment @alias(as: "notificationFrgmt")
217218
}
218219
}
219220
}
@@ -232,7 +233,7 @@ const FolderCreateModalV2: React.FC<FolderCreateModalProps> = ({
232233
createVFolderInProject(projectId: $projectId, input: $input) {
233234
vfolder {
234235
id
235-
status
236+
vfolderStatus: status
236237
host
237238
metadata {
238239
name
@@ -249,6 +250,7 @@ const FolderCreateModalV2: React.FC<FolderCreateModalProps> = ({
249250
projectId
250251
creatorEmail
251252
}
253+
...BAINodeNotificationItemFragment @alias(as: "notificationFrgmt")
252254
}
253255
}
254256
}
@@ -323,19 +325,14 @@ const FolderCreateModalV2: React.FC<FolderCreateModalProps> = ({
323325
user: vfolder.ownership.userId ?? '',
324326
group: vfolder.ownership.projectId ?? null,
325327
cloneable: vfolder.metadata.cloneable,
326-
status: vfolder.status ?? '',
328+
status: vfolder.vfolderStatus ?? '',
327329
};
328330

329331
upsertNotification({
330332
key: `folder-create-success-${result.id}`,
331333
icon: 'folder',
332-
message: `${result.name}: ${t('data.folders.FolderCreated')}`,
333-
toText: t('data.folders.OpenAFolder'),
334-
to: {
335-
search: new URLSearchParams({
336-
folder: result.id,
337-
}).toString(),
338-
},
334+
node: vfolder.notificationFrgmt ?? null,
335+
description: t('data.folders.FolderCreated'),
339336
open: true,
340337
});
341338
document.dispatchEvent(new CustomEvent('backend-ai-folder-list-changed'));

0 commit comments

Comments
 (0)