feat: manually mirror opencoze's code from bytedance

Change-Id: I09a73aadda978ad9511264a756b2ce51f5761adf
This commit is contained in:
fanlv
2025-07-20 17:36:12 +08:00
commit 890153324f
14811 changed files with 1923430 additions and 0 deletions

View File

@@ -0,0 +1,45 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import classNames from 'classnames';
import { IconCozKnowledgeFill } from '@coze-arch/coze-design/icons';
interface SiderCategoryProps {
label: string;
selected: boolean;
onClick?: React.MouseEventHandler<HTMLDivElement>;
}
const SiderCategory = ({ label, onClick, selected }: SiderCategoryProps) => (
<div
onClick={onClick}
className={classNames([
'flex items-center gap-[8px] px-[12px]',
'px-[12px] py-[6px] rounded-[8px]',
'cursor-pointer',
'hover:text-[var(--light-usage-text-color-text-0,#1c1f23)]',
'hover:bg-[var(--light-usage-fill-color-fill-0,rgba(46,50,56,5%))]',
selected &&
'text-[var(--light-usage-text-color-text-0,#1c1d23)] bg-[var(--light-usage-fill-color-fill-0,rgba(46,47,56,5%))]',
])}
>
<IconCozKnowledgeFill />
{label}
</div>
);
export default SiderCategory;

View File

@@ -0,0 +1,92 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from 'react';
import qs from 'qs';
import {
useTitle,
useCurrentWidgetContext,
useIDEParams,
useIDENavigate,
useSpaceId,
useProjectId,
useCommitVersion,
} from '@coze-project-ide/framework';
import { usePrimarySidebarStore } from '@coze-project-ide/biz-components';
import { KnowledgeParamsStoreProvider } from '@coze-data/knowledge-stores';
import {
type UnitType,
type OptType,
} from '@coze-data/knowledge-resource-processor-core';
import { DatabaseDetail, type DatabaseTabs } from '@coze-data/database-v2';
const Main = () => {
const spaceID = useSpaceId();
const projectID = useProjectId();
const { uri, widget } = useCurrentWidgetContext();
const IDENav = useIDENavigate();
const title = useTitle();
const { version } = useCommitVersion();
const refetch = usePrimarySidebarStore(state => state.refetch);
const queryObject = useIDEParams();
const { type, opt, doc_id, page_mode, bot_id, workflow_id, agent_id, tab } =
queryObject;
return (
<KnowledgeParamsStoreProvider
params={{
version,
projectID,
spaceID,
tableID: uri?.path.name ?? '',
type: type as UnitType,
opt: opt as OptType,
docID: doc_id,
pageMode: page_mode as 'modal' | 'normal',
biz: 'project',
botID: bot_id,
workflowID: workflow_id,
agentID: agent_id,
}}
onUpdateDisplayName={displayName => {
widget.setTitle(displayName); // 设置 tab 标题
if (displayName && displayName !== title) {
refetch(); // 更新侧边栏 name
}
}}
onStatusChange={status => {
widget.setUIState(status);
}}
resourceNavigate={{
// eslint-disable-next-line max-params
toResource: (resource, resourceID, query, opts) =>
IDENav(`/${resource}/${resourceID}?${qs.stringify(query)}`, opts),
}}
>
<DatabaseDetail
needHideCloseIcon
initialTab={tab as DatabaseTabs}
version={version}
/>
</KnowledgeParamsStoreProvider>
);
};
export default Main;

View File

@@ -0,0 +1,135 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React, { type ReactNode, useMemo } from 'react';
import {
BizResourceContextMenuBtnType,
BizResourceTypeEnum,
type ResourceFolderCozeProps,
} from '@coze-project-ide/biz-components';
import { validateNameConflict } from '@coze-project-ide/biz-components';
import { I18n } from '@coze-arch/i18n';
import { ResType } from '@coze-arch/bot-api/plugin_develop';
import { IconCozDatabase, IconCozKnowledge } from '@coze-arch/coze-design/icons';
import useKnowledgeResource from './use-knowledge-resource';
import useImportData from './use-import-data';
import useDatabaseResource from './use-database-resource';
type UseDataResourceReturn = Pick<
ResourceFolderCozeProps,
| 'onCustomCreate'
| 'onDelete'
| 'onChangeName'
| 'onAction'
| 'createResourceConfig'
| 'iconRender'
| 'validateConfig'
> & { modals: ReactNode };
const useDataResource = (): UseDataResourceReturn => {
const createResourceConfig = useMemo(
() => [
{
icon: <IconCozKnowledge />,
label: I18n.t('project_resource_sidebar_create_new_resource', {
resource: I18n.t('performance_knowledge'),
}),
subType: BizResourceTypeEnum.Knowledge,
tooltip: null,
},
{
icon: <IconCozDatabase />,
label: I18n.t('project_resource_sidebar_create_new_resource', {
resource: I18n.t('review_bot_database'),
}),
subType: BizResourceTypeEnum.Database,
tooltip: null,
},
],
[],
);
const { modal, open } = useImportData();
const knowledgeResource = useKnowledgeResource();
const databaseResource = useDatabaseResource();
return {
onCustomCreate(groupType, subType) {
if (subType === BizResourceTypeEnum.Knowledge) {
knowledgeResource.onCustomCreate?.(groupType, subType);
}
if (subType === BizResourceTypeEnum.Database) {
databaseResource.onCustomCreate?.(groupType, subType);
}
},
onChangeName(event) {
if (event.resource?.res_type === ResType.Knowledge) {
knowledgeResource.onChangeName?.(event);
}
if (event.resource?.res_type === ResType.Database) {
databaseResource.onChangeName?.(event);
}
},
onAction(action, resource) {
if (action === BizResourceContextMenuBtnType.ImportLibraryResource) {
open();
} else {
if (resource?.res_type === ResType.Knowledge) {
knowledgeResource.onAction?.(action, resource);
}
if (resource?.res_type === ResType.Database) {
databaseResource.onAction?.(action, resource);
}
}
},
onDelete(resources) {
const deleteKnowledgeResource = resources.filter(
resource => resource?.res_type === ResType.Knowledge,
);
const deleteDatabaseResource = resources.filter(
resource => resource?.res_type === ResType.Database,
);
if (deleteKnowledgeResource.length) {
knowledgeResource.onDelete?.(deleteKnowledgeResource);
}
if (deleteDatabaseResource.length) {
databaseResource.onDelete?.(deleteDatabaseResource);
}
},
createResourceConfig,
modals: [knowledgeResource.modals, databaseResource.modals, modal],
validateConfig: {
customValidator: params => {
if (!params.label) {
return I18n.t('dataset-name-empty-tooltip');
}
if (!/^[^"'`\\]+$/.test(params.label)) {
return I18n.t('dataset-name-has-wrong-word-tooltip');
}
return validateNameConflict(params);
},
},
};
};
export default useDataResource;

View File

@@ -0,0 +1,166 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { type ReactNode, useCallback } from 'react';
import {
type ResourceFolderProps,
type ResourceType,
useProjectId,
useSpaceId,
useIDENavigate,
} from '@coze-project-ide/framework';
import {
BizResourceContextMenuBtnType,
type BizResourceType,
BizResourceTypeEnum,
type ResourceFolderCozeProps,
// useOpenResource,
usePrimarySidebarStore,
} from '@coze-project-ide/biz-components';
import { useLibraryCreateDatabaseModal } from '@coze-data/database-v2';
import { I18n } from '@coze-arch/i18n';
import { ResourceCopyScene } from '@coze-arch/bot-api/plugin_develop';
import { MemoryApi } from '@coze-arch/bot-api';
import { Toast } from '@coze-arch/coze-design';
import { useResourceOperation } from './use-resource-operation';
// import { useImportLibraryDatabase } from './use-import-library-database';
type UseDatabaseResourceReturn = Pick<
ResourceFolderCozeProps,
| 'onCustomCreate'
| 'onDelete'
| 'onChangeName'
| 'onAction'
| 'createResourceConfig'
| 'iconRender'
> & { modals: ReactNode };
const useDatabaseResource = (): UseDatabaseResourceReturn => {
const refetch = usePrimarySidebarStore(state => state.refetch);
const spaceId = useSpaceId();
const projectId = useProjectId();
const IDENav = useIDENavigate();
// const openResource = useOpenResource();
// 创建 Database
const {
modal: createDatabaseModal,
open: openCreateDatabaseModal,
close: closeCreateDatabaseModal,
} = useLibraryCreateDatabaseModal({
projectID: projectId,
enterFrom: 'project',
onFinish: databaseID => {
refetch();
closeCreateDatabaseModal();
IDENav(`/database/${databaseID}?page_modal=normal&from=create`);
},
});
const onCustomCreate: ResourceFolderCozeProps['onCustomCreate'] = (
resourceType,
subType,
) => {
console.log('[ResourceFolder]on custom create>>>', resourceType, subType);
openCreateDatabaseModal();
};
const onChangeName: ResourceFolderProps['onChangeName'] =
async changeNameEvent => {
try {
console.log('[ResourceFolder]on change name>>>', changeNameEvent);
const resp = await MemoryApi.UpdateDatabase({
id: changeNameEvent.id,
table_name: changeNameEvent.name,
});
console.log('[ResourceFolder]rename database response>>>', resp);
} catch (e) {
console.log('[ResourceFolder]rename database error>>>', e);
} finally {
refetch();
}
};
const onDelete = useCallback(
async (resources: ResourceType[]) => {
try {
console.log('[ResourceFolder]on delete>>>', resources);
const resp = await MemoryApi.DeleteDatabase({
id: resources.filter(
r => r.type === BizResourceTypeEnum.Database,
)?.[0].res_id,
});
Toast.success(I18n.t('Delete_success'));
refetch();
console.log('[ResourceFolder]delete database response>>>', resp);
} catch (e) {
console.log('[ResourceFolder]delete database error>>>', e);
Toast.error(I18n.t('Delete_failed'));
}
},
[refetch, spaceId],
);
// const { modal: databaseModal, importLibrary } = useImportLibraryDatabase({
// projectId,
// });
const resourceOperation = useResourceOperation({ projectId });
const onAction = (
action: BizResourceContextMenuBtnType,
resource?: BizResourceType,
) => {
console.log('on action>>>', action, resource);
switch (action) {
case BizResourceContextMenuBtnType.ImportLibraryResource:
// return importLibrary();
// return openDatabase();
return;
case BizResourceContextMenuBtnType.DuplicateResource:
return resourceOperation({
scene: ResourceCopyScene.CopyProjectResource,
resource,
});
case BizResourceContextMenuBtnType.MoveToLibrary:
return resourceOperation({
scene: ResourceCopyScene.MoveResourceToLibrary,
resource,
});
case BizResourceContextMenuBtnType.CopyToLibrary:
return resourceOperation({
scene: ResourceCopyScene.CopyResourceToLibrary,
resource,
});
default:
console.warn('[DatabaseResource]unsupported action>>>', action);
break;
}
};
return {
onChangeName,
onAction,
onDelete,
onCustomCreate,
// createResourceConfig,
modals: [createDatabaseModal],
};
};
export default useDatabaseResource;

View File

@@ -0,0 +1,171 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { useState } from 'react';
import { useProjectId, useSpaceId } from '@coze-project-ide/framework';
import { usePrimarySidebarStore } from '@coze-project-ide/biz-components';
import { FilterKnowledgeType } from '@coze-data/knowledge-modal-base';
import { useKnowledgeListModalContent } from '@coze-data/knowledge-modal-adapter';
import { useSelectDatabaseModal } from '@coze-data/database-v2';
import { I18n } from '@coze-arch/i18n';
import { UITabsModal } from '@coze-arch/bot-semi';
import { ResType, ResourceCopyScene } from '@coze-arch/bot-api/plugin_develop';
import SiderCategory from '../components/sider-category';
import { useResourceOperation } from './use-resource-operation';
type TabType = 'knowledge' | 'database';
export const ImportDataModal = (props: { onClose?: () => void }) => {
const { onClose } = props;
const [activeKey, setActiveKey] = useState<TabType>('knowledge');
const projectID = useProjectId();
const spaceID = useSpaceId();
const refetch = usePrimarySidebarStore(state => state.refetch);
const resourceOperation = useResourceOperation({ projectId: projectID });
const { renderContent, renderSearch } = useKnowledgeListModalContent({
showFilters: ['scope-type', 'search-type'],
datasetList: [],
onDatasetListChange: async list => {
if (list[0].dataset_id && list[0].name) {
await resourceOperation({
scene: ResourceCopyScene.CopyResourceFromLibrary,
resource: {
id: list[0].dataset_id,
res_id: list[0].dataset_id,
name: list[0].name,
res_type: ResType.Knowledge,
},
});
refetch();
onClose?.();
}
},
canCreate: false,
defaultType: FilterKnowledgeType.ALL,
});
const {
renderContent: renderDatabaseContent,
renderFilter: renderDatabaseFilter,
renderInput: renderDatabaseInput,
} = useSelectDatabaseModal({
visible: true,
onClose: () => void 0,
onAddDatabase: async id => {
await resourceOperation({
scene: ResourceCopyScene.CopyResourceFromLibrary,
resource: {
id,
res_id: id,
name: '',
res_type: ResType.Database,
},
});
refetch();
onClose?.();
},
onClickDatabase: () => void 0,
enterFrom: 'project',
spaceId: spaceID,
});
return (
<UITabsModal
keepDOM={false}
visible
onCancel={onClose}
tabs={{
tabsProps: {
lazyRender: true,
activeKey,
onChange: (key: string) => setActiveKey(key as TabType),
},
tabPanes: [
{
tabPaneProps: {
tab: I18n.t('resource_type_knowledge'),
itemKey: 'knowledge',
},
content: (
<div className="w-full h-full flex">
<div className="w-[218px] pt-[16px] px-[12px] shrink-0 flex flex-col gap-[12px]">
{renderSearch()}
<SiderCategory
label={I18n.t('project_resource_modal_library_resources', {
resource: I18n.t('resource_type_knowledge'),
})}
selected
></SiderCategory>
</div>
<div className="grow-[1] bg-[white] pt-[16px] px-[12px]">
{renderContent()}
</div>
</div>
),
},
{
tabPaneProps: {
tab: I18n.t('resource_type_database'),
itemKey: 'database',
},
content: (
<div className="w-full h-full flex">
<div className="w-[218px] pt-[16px] px-[12px] shrink-0 flex flex-col gap-[12px]">
{renderDatabaseInput()}
<SiderCategory
label={I18n.t('project_resource_modal_library_resources', {
resource: I18n.t('resource_type_database'),
})}
selected
></SiderCategory>
</div>
<div className="grow-[1] bg-[white] pt-[16px] px-[12px] flex flex-col">
{renderDatabaseFilter()}
{renderDatabaseContent()}
</div>
</div>
),
},
],
}}
/>
);
};
const useImportData = () => {
const [visible, setVisible] = useState(false);
const open = () => {
setVisible(true);
};
const close = () => {
setVisible(false);
};
return {
modal: visible ? <ImportDataModal onClose={close} /> : null,
open,
close,
};
};
export default useImportData;

View File

@@ -0,0 +1,185 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { type ReactNode, useCallback } from 'react';
import {
type ResourceFolderProps,
type ResourceType,
useProjectId,
useSpaceId,
useIDENavigate,
} from '@coze-project-ide/framework';
import {
BizResourceContextMenuBtnType,
type BizResourceType,
BizResourceTypeEnum,
type ResourceFolderCozeProps,
// useOpenResource,
usePrimarySidebarStore,
} from '@coze-project-ide/biz-components';
import { useCreateKnowledgeModalV2 } from '@coze-data/knowledge-modal-adapter';
import { I18n } from '@coze-arch/i18n';
import { ResourceCopyScene } from '@coze-arch/bot-api/plugin_develop';
import { DatasetStatus } from '@coze-arch/bot-api/knowledge';
import { KnowledgeApi } from '@coze-arch/bot-api';
import { Toast } from '@coze-arch/coze-design';
import { useResourceOperation } from './use-resource-operation';
// import { useImportLibraryKnowledge } from './use-import-library-knowledge';
type UseKnowledgeResourceReturn = Pick<
ResourceFolderCozeProps,
| 'onCustomCreate'
| 'onDelete'
| 'onChangeName'
| 'onAction'
| 'createResourceConfig'
| 'iconRender'
> & { modals: ReactNode };
const useKnowledgeResource = (): UseKnowledgeResourceReturn => {
const refetch = usePrimarySidebarStore(state => state.refetch);
const spaceId = useSpaceId();
const projectID = useProjectId();
const IDENav = useIDENavigate();
// const openResource = useOpenResource();
// 创建knowledge
const {
modal: createKnowledgeModal,
open: openCreateKnowledgeModal,
close,
} = useCreateKnowledgeModalV2({
projectID,
onFinish: (datasetID, unitType, shouldUpload) => {
refetch();
close();
IDENav(
`/knowledge/${datasetID}?type=${unitType}${shouldUpload ? '&module=upload' : ''}`,
);
},
});
// 更新 knowledge 状态,主要用于禁用启用
const updateKnowledge = async (
datasetID: string,
datasetName: string,
status: DatasetStatus,
) => {
try {
await KnowledgeApi.UpdateDataset({
dataset_id: datasetID,
name: datasetName,
status,
});
} catch (e) {
console.log('[ResourceFolder]update knowledge error>>>', e);
} finally {
refetch();
}
};
const onCustomCreate: ResourceFolderCozeProps['onCustomCreate'] = () => {
openCreateKnowledgeModal();
};
const onChangeName: ResourceFolderProps['onChangeName'] =
async changeNameEvent => {
try {
await KnowledgeApi.UpdateDataset({
dataset_id: changeNameEvent.id,
name: changeNameEvent.name,
});
} catch (e) {
console.log('[ResourceFolder]rename knowledge error>>>', e);
} finally {
refetch();
}
};
const onDelete = useCallback(
async (resources: ResourceType[]) => {
try {
await KnowledgeApi.DeleteDataset({
dataset_id: resources.filter(
r => r.type === BizResourceTypeEnum.Knowledge,
)?.[0].res_id,
});
Toast.success(I18n.t('Delete_success'));
refetch();
} catch (e) {
Toast.error(I18n.t('Delete_failed'));
}
},
[refetch, spaceId],
);
const resourceOperation = useResourceOperation({ projectId: projectID });
const onAction = (
action: BizResourceContextMenuBtnType,
resource?: BizResourceType,
) => {
switch (action) {
case BizResourceContextMenuBtnType.DuplicateResource:
return resourceOperation({
scene: ResourceCopyScene.CopyProjectResource,
resource,
});
case BizResourceContextMenuBtnType.MoveToLibrary:
return resourceOperation({
scene: ResourceCopyScene.MoveResourceToLibrary,
resource,
});
case BizResourceContextMenuBtnType.CopyToLibrary:
return resourceOperation({
scene: ResourceCopyScene.CopyResourceToLibrary,
resource,
});
case BizResourceContextMenuBtnType.DisableKnowledge:
if (resource?.id) {
updateKnowledge(
resource.id,
resource.name,
DatasetStatus.DatasetForbid,
);
}
break;
case BizResourceContextMenuBtnType.EnableKnowledge:
if (resource?.id) {
updateKnowledge(
resource.id,
resource.name,
DatasetStatus.DatasetReady,
);
}
break;
default:
break;
}
};
return {
onChangeName,
onAction,
onDelete,
onCustomCreate,
modals: [createKnowledgeModal],
};
};
export default useKnowledgeResource;

View File

@@ -0,0 +1,55 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
type BizResourceType,
useResourceCopyDispatch,
} from '@coze-project-ide/biz-components';
import { type resource_resource_common } from '@coze-arch/bot-api/plugin_develop';
export interface ResourceOperationProps {
projectId: string;
}
export const useResourceOperation = ({ projectId }: ResourceOperationProps) => {
const copyDispatch = useResourceCopyDispatch();
return async ({
scene,
resource,
}: {
scene: resource_resource_common.ResourceCopyScene;
resource?: BizResourceType;
}) => {
try {
console.log(
`[ResourceFolder]workflow resource copy dispatch, scene ${scene}>>>`,
resource,
);
await copyDispatch({
scene,
res_id: resource?.id,
res_type: resource?.res_type,
project_id: projectId,
res_name: resource?.name || '',
});
} catch (e) {
console.error(
`[ResourceFolder]workflow resource copy dispatch, scene ${scene} error>>>`,
e,
);
}
};
};

View File

@@ -0,0 +1,23 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export {
KnowledgeWidgetRegistry,
VariablesWidgetRegistry,
DatabaseWidgetRegistry,
} from './registry';
export { default as useDataResource } from './hooks/use-data-resource';

View File

@@ -0,0 +1,132 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from 'react';
import qs from 'qs';
import {
useTitle,
useCurrentWidgetContext,
useIDEParams,
useIDENavigate,
useProjectId,
useSpaceId,
useCommitVersion,
} from '@coze-project-ide/framework';
import { usePrimarySidebarStore } from '@coze-project-ide/biz-components';
import { KnowledgeParamsStoreProvider } from '@coze-data/knowledge-stores';
import {
UnitType,
OptType,
} from '@coze-data/knowledge-resource-processor-core';
import {
getUploadConfig,
KnowledgeResourceProcessor,
} from '@coze-data/knowledge-resource-processor-adapter';
import { type ActionType } from '@coze-data/knowledge-ide-base/types';
import { BizProjectKnowledgeIDE } from '@coze-data/knowledge-ide-adapter';
const Main = () => {
const spaceID = useSpaceId();
const { uri, widget } = useCurrentWidgetContext();
const IDENav = useIDENavigate();
const title = useTitle();
const { version } = useCommitVersion();
const projectID = useProjectId();
const refetch = usePrimarySidebarStore(state => state.refetch);
const queryObject = useIDEParams();
const {
type,
opt,
doc_id,
page_mode,
biz,
bot_id,
workflow_id,
agent_id,
module,
action_type,
first_auto_open_edit_document_id,
create,
} = queryObject;
const uploadConfig = getUploadConfig(
(type as UnitType) ?? UnitType.TEXT,
(opt as OptType) ?? OptType.ADD,
);
const datasetID = uri?.path.name ?? '';
return (
<KnowledgeParamsStoreProvider
params={{
version,
projectID,
datasetID,
spaceID,
type: type as UnitType,
opt: opt as OptType,
docID: doc_id,
pageMode: page_mode as 'modal' | 'normal',
biz:
(biz as 'agentIDE' | 'workflow' | 'project' | undefined) ?? 'project',
botID: bot_id,
workflowID: workflow_id,
agentID: agent_id,
actionType: action_type as ActionType,
first_auto_open_edit_document_id,
create,
}}
onUpdateDisplayName={displayName => {
widget.setTitle(displayName); // 设置 tab 标题
if (displayName && displayName !== title) {
refetch(); // 更新侧边栏 name
}
}}
onStatusChange={status => {
widget.setUIState(status);
}}
resourceNavigate={{
// eslint-disable-next-line max-params
toResource: (resource, resourceID, query, opts) =>
IDENav(`/${resource}/${resourceID}?${qs.stringify(query)}`, opts),
upload: (query, opts) => {
IDENav(
`/knowledge/${datasetID}?module=upload&${qs.stringify(query)}`,
opts,
);
},
}}
>
{module === 'upload' ? (
uploadConfig ? (
<KnowledgeResourceProcessor
keepDocTitle
uploadConfig={uploadConfig}
/>
) : null
) : (
<BizProjectKnowledgeIDE layoutProps={{ keepDocTitle: true }} />
)}
</KnowledgeParamsStoreProvider>
);
};
export default Main;

View File

@@ -0,0 +1,65 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from 'react';
import {
IconCozDatabase,
IconCozKnowledge,
IconCozVariables,
} from '@coze-arch/coze-design/icons';
import {
LayoutPanelType,
withLazyLoad,
type WidgetRegistry,
} from '@coze-project-ide/framework';
export const KnowledgeWidgetRegistry: WidgetRegistry = {
match: /\/knowledge\/.*/,
area: LayoutPanelType.MAIN_PANEL,
renderContent() {
const Component = withLazyLoad(() => import('./main'));
// return <div>this is knowledge</div>;
return <Component />;
},
renderIcon() {
return <IconCozKnowledge />;
},
};
export const VariablesWidgetRegistry: WidgetRegistry = {
match: /\/variables\/?$/,
area: LayoutPanelType.MAIN_PANEL,
renderContent() {
const Component = withLazyLoad(() => import('./variables-main'));
return <Component />;
},
renderIcon() {
return <IconCozVariables />;
},
};
export const DatabaseWidgetRegistry: WidgetRegistry = {
match: /\/database\/.*/,
area: LayoutPanelType.MAIN_PANEL,
renderContent() {
const Component = withLazyLoad(() => import('./database-main'));
return <Component />;
},
renderIcon() {
return <IconCozDatabase />;
},
};

View File

@@ -0,0 +1,17 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/// <reference types='@coze-arch/bot-typings' />

View File

@@ -0,0 +1,71 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React, { useEffect } from 'react';
import qs from 'qs';
import {
useCurrentWidgetContext,
useIDENavigate,
useProjectId,
useCommitVersion,
} from '@coze-project-ide/framework';
import { VariablesPage } from '@coze-data/variable';
import { KnowledgeParamsStoreProvider } from '@coze-data/knowledge-stores';
import { I18n } from '@coze-arch/i18n';
const Main = () => {
const IDENav = useIDENavigate();
const { widget } = useCurrentWidgetContext();
const projectID = useProjectId();
const { version } = useCommitVersion();
const { uri } = useCurrentWidgetContext();
const datasetID = uri?.path.name ?? '';
useEffect(() => {
widget.setTitle(I18n.t('dataide002'));
widget.setUIState('normal');
}, []);
return (
<KnowledgeParamsStoreProvider
params={{
version,
projectID,
datasetID,
biz: 'project',
}}
resourceNavigate={{
// eslint-disable-next-line max-params
toResource: (resource, resourceID, query, opts) =>
IDENav(`/${resource}/${resourceID}?${qs.stringify(query)}`, opts),
upload: (query, opts) =>
IDENav(
`/knowledge/${datasetID}?module=upload&${qs.stringify(query)}`,
opts,
),
navigateTo: IDENav,
}}
>
<VariablesPage />
</KnowledgeParamsStoreProvider>
);
};
export default Main;