/* * 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. */ /* eslint-disable @coze-arch/max-line-per-function */ import { useParams } from 'react-router-dom'; import { type ForwardedRef, forwardRef, useEffect, useImperativeHandle, useMemo, useState, } from 'react'; import { nanoid } from 'nanoid'; import classNames from 'classnames'; import { PublishDisabledType, type PublisherBotInfo, type PublishRef, type PublishResultInfo, STORE_CONNECTOR_ID, getPublishResult, } from '@coze-agent-ide/space-bot'; import { I18n } from '@coze-arch/i18n'; import { IconCozEmpty, IconCozInfoCircleFill } from '@coze-arch/coze-design/icons'; import { Tooltip } from '@coze-arch/coze-design'; import { type DynamicParams } from '@coze-arch/bot-typings/teamspace'; import { EVENT_NAMES, sendTeaEvent } from '@coze-arch/bot-tea'; import { useSpaceStore } from '@coze-arch/bot-studio-store'; import { Form, Space, TextArea } from '@coze-arch/bot-semi'; import { AllowPublishStatus, type ConnectorBrandInfo, Publish, type PublishConnectorInfo, SpaceType, } from '@coze-arch/bot-api/developer_api'; import { type BotMonetizationConfigData } from '@coze-arch/bot-api/benefit'; import { PublishTermService } from '@coze-agent-ide/agent-ide-commons'; import { TableCollection } from './table-collection'; import { useConnectorsPublish } from './hooks/use-connectors-publish'; import { getConnectorIsSelectable } from './get-connector-selectable'; import styles from './index.module.less'; export { PublishTableContext, usePublishTableContext } from './context'; interface PublishTableProps { setPublishStatus: (status: Publish) => void; setPublishResult: (result: PublishResultInfo) => void; connectInfoList: PublishConnectorInfo[]; connectorBrandInfoMap: Record; botInfo: PublisherBotInfo; monetizeConfig?: BotMonetizationConfigData; getPublishDisabled: (disabledType: PublishDisabledType) => void; getPublishLoading: (loading: boolean) => void; canOpenSource: boolean; publishTips?: string; } export const PublishTable = forwardRef( ( { connectInfoList = [], connectorBrandInfoMap = {}, setPublishStatus, setPublishResult, botInfo, monetizeConfig, getPublishDisabled, getPublishLoading, canOpenSource, publishTips, }: PublishTableProps, ref: ForwardedRef, ) => { const publishId = useMemo(() => nanoid(), []); const [dataSource, setDataSource] = useState(connectInfoList); const [selectedPlatforms, setSelectedPlatforms] = useState([]); const { space_id: spaceId = '', bot_id: botId = '' } = useParams(); const { space_type: spaceType } = useSpaceStore(s => s.space); const [changeLog, setChangeLog] = useState(''); const [hasCategoryList, setHasCategoryList] = useState(true); const isPersonal = spaceType === SpaceType.Personal; useEffect(() => { if (connectInfoList?.length) { setDataSource(connectInfoList); const selectKeys = connectInfoList .filter(item => item.allow_punish === AllowPublishStatus.Allowed) .filter(item => getConnectorIsSelectable(item, botInfo)) .map(node => node.id); setSelectedPlatforms(selectKeys); } }, [connectInfoList, botInfo]); useImperativeHandle(ref, () => ({ publish: () => handlePublish(), })); const { loading: publishLoading, handlePublishBot } = useConnectorsPublish({ onSuccess: resp => { setPublishStatus(Publish.HadPublished); const publishResult = getPublishResult( resp.publish_result ?? {}, dataSource.filter(item => selectedPlatforms?.includes(item.id)), ); setPublishResult({ connectorResult: publishResult, marketResult: resp.submit_bot_market_result ?? {}, monetizeConfigSuccess: resp.publish_monetization_result ?? false, }); }, botInfo, }); const notSelectPlatform = !selectedPlatforms?.length; const notSelectCategory = hasCategoryList && selectedPlatforms.includes(STORE_CONNECTOR_ID) && !dataSource?.find(item => item.id === STORE_CONNECTOR_ID)?.bind_info ?.category_id; useEffect(() => { let publishDisableType; if (notSelectPlatform) { publishDisableType = PublishDisabledType.NotSelectPlatform; } else if (notSelectCategory) { publishDisableType = PublishDisabledType.NotSelectCategory; } getPublishDisabled(publishDisableType); }, [notSelectPlatform, notSelectCategory]); useEffect(() => { getPublishLoading(publishLoading); }, [publishLoading]); const handlePublish = () => { const connectors: Record> = {}; const list = dataSource.filter(item => selectedPlatforms.includes(item.id), ); list.forEach(i => { connectors[i.id] = i.bind_info; }); sendTeaEvent(EVENT_NAMES.bot_publish, { space_id: spaceId, bot_id: botId, publish_id: publishId, workspace_id: spaceId, workspace_type: isPersonal ? 'personal_workspace' : 'team_workspace', is_auto_gen_changelog_empty: true, is_changelog_empty: !changeLog, is_modified: false, }); handlePublishBot({ botId, connectors, changeLog, publishId, }); }; return (