mirror of
https://github.com/labring/FastGPT.git
synced 2026-05-08 01:08:43 +08:00
perf: template permission (#6848)
* perf: template permission * perf: action * doc
This commit is contained in:
@@ -25,7 +25,7 @@ permissions:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
if: ${{ github.event.pull_request.author_association == 'MEMBER' }}
|
||||
if: ${{ contains(fromJSON('["COLLABORATOR", "OWNER"]'), github.event.pull_request.author_association) }}
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
steps:
|
||||
|
||||
@@ -20,7 +20,7 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
if: ${{ github.event_name != 'pull_request_target' || github.event.pull_request.author_association == 'MEMBER' }}
|
||||
if: ${{ github.event_name != 'pull_request_target' || contains(fromJSON('["COLLABORATOR", "OWNER"]'), github.event.pull_request.author_association) }}
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
permissions:
|
||||
|
||||
@@ -13,6 +13,8 @@ description: 'FastGPT V4.15.0 更新说明'
|
||||
|
||||
1. 增加父子节点选中互斥功能,解决:同时选中父子节点时,移动节点会出现抖动。
|
||||
2. 调整文件注入 messages 位置,从 system 调整至 user,便于命中缓存。
|
||||
3. 非管理员/访客,触发余额不足时候,提示优化。
|
||||
4. 无创建权限时,隐藏模板功能。
|
||||
|
||||
## 🐛 修复
|
||||
|
||||
|
||||
@@ -231,6 +231,7 @@
|
||||
"content/self-host/upgrading/4-14/41415.mdx": "2026-04-26T21:28:27+08:00",
|
||||
"content/self-host/upgrading/4-14/41416.en.mdx": "2026-04-26T21:28:27+08:00",
|
||||
"content/self-host/upgrading/4-14/41416.mdx": "2026-04-26T22:41:57+08:00",
|
||||
"content/self-host/upgrading/4-14/41417.mdx": "2026-04-28T18:03:38+08:00",
|
||||
"content/self-host/upgrading/4-14/4142.en.mdx": "2026-04-26T21:08:47+08:00",
|
||||
"content/self-host/upgrading/4-14/4142.mdx": "2026-04-26T21:08:47+08:00",
|
||||
"content/self-host/upgrading/4-14/4143.en.mdx": "2026-04-26T21:08:47+08:00",
|
||||
@@ -251,7 +252,7 @@
|
||||
"content/self-host/upgrading/4-14/41481.mdx": "2026-04-26T21:08:47+08:00",
|
||||
"content/self-host/upgrading/4-14/4149.en.mdx": "2026-04-26T21:08:47+08:00",
|
||||
"content/self-host/upgrading/4-14/4149.mdx": "2026-04-26T21:08:47+08:00",
|
||||
"content/self-host/upgrading/4-15/4150.mdx": "2026-04-28T15:10:52+08:00",
|
||||
"content/self-host/upgrading/4-15/4150.mdx": "2026-04-28T21:27:07+08:00",
|
||||
"content/self-host/upgrading/outdated/40.en.mdx": "2026-04-26T21:08:47+08:00",
|
||||
"content/self-host/upgrading/outdated/40.mdx": "2026-04-26T21:08:47+08:00",
|
||||
"content/self-host/upgrading/outdated/41.en.mdx": "2026-04-26T21:08:47+08:00",
|
||||
@@ -393,7 +394,7 @@
|
||||
"content/self-host/upgrading/upgrade-intruction.en.mdx": "2026-04-26T21:08:47+08:00",
|
||||
"content/self-host/upgrading/upgrade-intruction.mdx": "2026-04-26T21:08:47+08:00",
|
||||
"content/toc.en.mdx": "2026-04-26T21:28:27+08:00",
|
||||
"content/toc.mdx": "2026-04-26T21:28:27+08:00",
|
||||
"content/toc.mdx": "2026-04-28T18:03:38+08:00",
|
||||
"content/use-cases/app-cases/dalle3.en.mdx": "2026-04-26T21:08:47+08:00",
|
||||
"content/use-cases/app-cases/dalle3.mdx": "2026-04-26T21:08:47+08:00",
|
||||
"content/use-cases/app-cases/english_essay_correction_bot.en.mdx": "2026-04-26T21:08:47+08:00",
|
||||
|
||||
+1
-1
Submodule pro updated: 4aba60a784...70380fe539
@@ -1,7 +1,7 @@
|
||||
import { Box, Divider, Flex, useDisclosure } from '@chakra-ui/react';
|
||||
import { useSystem } from '@fastgpt/web/hooks/useSystem';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useMemo } from 'react';
|
||||
import { useEffect, useMemo } from 'react';
|
||||
import { AppTemplateTypeEnum, AppTypeEnum } from '@fastgpt/global/core/app/constants';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import { useRouter } from 'next/router';
|
||||
@@ -36,11 +36,12 @@ const DashboardContainer = ({
|
||||
}) => React.ReactNode;
|
||||
}) => {
|
||||
const router = useRouter();
|
||||
const { t, i18n } = useTranslation();
|
||||
const { t } = useTranslation();
|
||||
const { isPc } = useSystem();
|
||||
const { feConfigs } = useSystemStore();
|
||||
const { isOpen: isOpenSidebar, onOpen: onOpenSidebar, onClose: onCloseSidebar } = useDisclosure();
|
||||
const { userInfo } = useUserStore();
|
||||
const hasAppCreatePer = !!userInfo?.team.permission.hasAppCreatePer;
|
||||
|
||||
// First tab
|
||||
const currentTab = useMemo(() => {
|
||||
@@ -56,10 +57,16 @@ const DashboardContainer = ({
|
||||
appType?: AppTypeEnum | 'all';
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (userInfo && currentTab === TabEnum.app_templates && !hasAppCreatePer) {
|
||||
router.replace('/dashboard/agent');
|
||||
}
|
||||
}, [currentTab, hasAppCreatePer, router, userInfo]);
|
||||
|
||||
// Template market
|
||||
const { data: templateTags = [], loading: isLoadingTemplatesTags } = useRequest(
|
||||
() =>
|
||||
currentTab === TabEnum.app_templates
|
||||
currentTab === TabEnum.app_templates && hasAppCreatePer
|
||||
? getTemplateTagList().then((res) => [
|
||||
{
|
||||
typeId: AppTemplateTypeEnum.recommendation,
|
||||
@@ -73,20 +80,20 @@ const DashboardContainer = ({
|
||||
: Promise.resolve([]),
|
||||
{
|
||||
manual: false,
|
||||
refreshDeps: [currentTab]
|
||||
refreshDeps: [currentTab, hasAppCreatePer, userInfo?.team.isWecomTeam]
|
||||
}
|
||||
);
|
||||
const { data: templateData, loading: isLoadingTemplates } = useRequest(
|
||||
() =>
|
||||
currentTab === TabEnum.app_templates
|
||||
currentTab === TabEnum.app_templates && hasAppCreatePer
|
||||
? getTemplateMarketItemList({ type: appType })
|
||||
: Promise.resolve({ list: [], total: 0 }),
|
||||
{
|
||||
manual: false,
|
||||
refreshDeps: [currentTab, appType]
|
||||
refreshDeps: [currentTab, appType, hasAppCreatePer]
|
||||
}
|
||||
);
|
||||
const templateList = templateData?.list || [];
|
||||
const templateList = useMemo(() => templateData?.list ?? [], [templateData?.list]);
|
||||
|
||||
const groupList = useMemo<
|
||||
{
|
||||
@@ -167,40 +174,44 @@ const DashboardContainer = ({
|
||||
groupName: t('common:system_tools'),
|
||||
children: []
|
||||
},
|
||||
{
|
||||
groupId: TabEnum.app_templates,
|
||||
groupAvatar: 'common/templateMarket',
|
||||
groupName: t('common:template_market'),
|
||||
children: [
|
||||
...templateTags
|
||||
.map((tag) => {
|
||||
const templates = templateList.filter((template) =>
|
||||
template.tags.includes(tag.typeId)
|
||||
);
|
||||
return {
|
||||
...tag,
|
||||
templates
|
||||
};
|
||||
})
|
||||
.filter((tag) => tag.templates.length > 0)
|
||||
.map((tag, index) => ({
|
||||
typeId: tag.typeId,
|
||||
typeName: t(tag.typeName as any),
|
||||
isActive: index === 0 && !currentType
|
||||
})),
|
||||
...(feConfigs?.appTemplateCourse
|
||||
? [
|
||||
{
|
||||
typeId: AppTemplateTypeEnum.contribute,
|
||||
typeName: t('common:contribute_app_template'),
|
||||
onClick: () => {
|
||||
window.open(feConfigs.appTemplateCourse);
|
||||
}
|
||||
}
|
||||
...(hasAppCreatePer
|
||||
? [
|
||||
{
|
||||
groupId: TabEnum.app_templates,
|
||||
groupAvatar: 'common/templateMarket',
|
||||
groupName: t('common:template_market'),
|
||||
children: [
|
||||
...templateTags
|
||||
.map((tag) => {
|
||||
const templates = templateList.filter((template) =>
|
||||
template.tags.includes(tag.typeId)
|
||||
);
|
||||
return {
|
||||
...tag,
|
||||
templates
|
||||
};
|
||||
})
|
||||
.filter((tag) => tag.templates.length > 0)
|
||||
.map((tag, index) => ({
|
||||
typeId: tag.typeId,
|
||||
typeName: t(tag.typeName as any),
|
||||
isActive: index === 0 && !currentType
|
||||
})),
|
||||
...(feConfigs?.appTemplateCourse
|
||||
? [
|
||||
{
|
||||
typeId: AppTemplateTypeEnum.contribute,
|
||||
typeName: t('common:contribute_app_template'),
|
||||
onClick: () => {
|
||||
window.open(feConfigs.appTemplateCourse);
|
||||
}
|
||||
}
|
||||
]
|
||||
: [])
|
||||
]
|
||||
: [])
|
||||
]
|
||||
},
|
||||
}
|
||||
]
|
||||
: []),
|
||||
{
|
||||
groupId: TabEnum.mcp_server,
|
||||
groupAvatar: 'mcp',
|
||||
@@ -223,6 +234,7 @@ const DashboardContainer = ({
|
||||
feConfigs.appTemplateCourse,
|
||||
feConfigs?.isPlus,
|
||||
feConfigs?.show_skill,
|
||||
hasAppCreatePer,
|
||||
t,
|
||||
templateList,
|
||||
templateTags
|
||||
|
||||
@@ -63,6 +63,10 @@ const MyApps = ({ MenuIcon }: { MenuIcon: JSX.Element }) => {
|
||||
onOpen: onOpenJsonImportModal,
|
||||
onClose: onCloseJsonImportModal
|
||||
} = useDisclosure();
|
||||
const hasCreatePer = folderDetail
|
||||
? folderDetail.permission.hasWritePer && folderDetail?.type !== AppTypeEnum.httpPlugin
|
||||
: userInfo?.team.permission.hasAppCreatePer;
|
||||
|
||||
//if there is a workflow url in the session storage, open the json import modal and import the workflow
|
||||
useMount(() => {
|
||||
if (getUtmWorkflow()) {
|
||||
@@ -105,7 +109,7 @@ const MyApps = ({ MenuIcon }: { MenuIcon: JSX.Element }) => {
|
||||
overflowX={'hidden'}
|
||||
>
|
||||
{/* Only shown on pc root page */}
|
||||
{!folderDetail && isPc && <TemplateCreatePanel type={appType} />}
|
||||
{!folderDetail && isPc && hasCreatePer && <TemplateCreatePanel type={appType} />}
|
||||
<Flex alignItems={'center'}>
|
||||
{!isPc ? (
|
||||
MenuIcon
|
||||
@@ -143,10 +147,7 @@ const MyApps = ({ MenuIcon }: { MenuIcon: JSX.Element }) => {
|
||||
/>
|
||||
)}
|
||||
|
||||
{(folderDetail
|
||||
? folderDetail.permission.hasWritePer &&
|
||||
folderDetail?.type !== AppTypeEnum.httpPlugin
|
||||
: userInfo?.team.permission.hasAppCreatePer) && (
|
||||
{hasCreatePer && (
|
||||
<>
|
||||
<Button
|
||||
variant={'grayBase'}
|
||||
|
||||
Reference in New Issue
Block a user