前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >MyApps 自定义组件

MyApps 自定义组件

原创
作者头像
用户1232103
修改2024-12-18 15:57:31
修改2024-12-18 15:57:31
520
举报
代码语言:ts
复制
const MyApps = () => {
  const { t } = useTranslation();
  const { appT } = useI18n();
  const router = useRouter();
  const { isPc } = useSystem();
  const {
    paths,
    parentId,
    myApps,
    appType,
    loadMyApps,
    onUpdateApp,
    setMoveAppId,
    isFetchingApps,
    folderDetail,
    refetchFolderDetail,
    searchKey,
    setSearchKey
  } = useContextSelector(AppListContext, (v) => v);
  const { userInfo } = useUserStore();

  const [createAppType, setCreateAppType] = useState<CreateAppType>();
  const {
    isOpen: isOpenCreateHttpPlugin,
    onOpen: onOpenCreateHttpPlugin,
    onClose: onCloseCreateHttpPlugin
  } = useDisclosure();
  const [editFolder, setEditFolder] = useState<EditFolderFormType>();
  const [templateModalType, setTemplateModalType] = useState<AppTypeEnum | 'all'>();

  const { runAsync: onCreateFolder } = useRequest2(postCreateAppFolder, {
    onSuccess() {
      loadMyApps();
    },
    errorToast: 'Error'
  });
  const { runAsync: onDeleFolder } = useRequest2(delAppById, {
    onSuccess() {
      router.replace({
        query: {
          parentId: folderDetail?.parentId
        }
      });
    },
    errorToast: 'Error'
  });

  const RenderSearchInput = useMemo(
    () => (
      <InputGroup maxW={['auto', '250px']} position={'relative'}>
        <MyIcon
          position={'absolute'}
          zIndex={10}
          name={'common/searchLight'}
          w={'1rem'}
          color={'myGray.600'}
          left={2.5}
          top={'50%'}
          transform={'translateY(-50%)'}
        />
        <Input
          value={searchKey}
          onChange={(e) => setSearchKey(e.target.value)}
          placeholder={appT('search_app')}
          maxLength={30}
          pl={8}
          bg={'white'}
        />
      </InputGroup>
    ),
    [searchKey, setSearchKey, appT]
  );

  return (
    <Flex flexDirection={'column'} h={'100%'}>
      {paths.length > 0 && (
        <Box pt={[4, 6]} pl={3}>
          <FolderPath
            paths={paths}
            hoverStyle={{ bg: 'myGray.200' }}
            onClick={(parentId) => {
              router.push({
                query: {
                  ...router.query,
                  parentId
                }
              });
            }}
          />
        </Box>
      )}
      <Flex gap={5} flex={'1 0 0'} h={0}>
        <Flex
          flex={'1 0 0'}
          flexDirection={'column'}
          h={'100%'}
          pr={folderDetail ? [3, 2] : [3, 10]}
          pl={3}
          overflowY={'auto'}
          overflowX={'hidden'}
        >
          <Flex pt={paths.length > 0 ? 3 : [4, 6]} alignItems={'center'} gap={3}>
            <LightRowTabs
              list={[
                {
                  label: t('app:type.All'),
                  value: 'ALL'
                },
                {
                  label: t('app:type.Simple bot'),
                  value: AppTypeEnum.simple
                },
                {
                  label: t('app:type.Workflow bot'),
                  value: AppTypeEnum.workflow
                },
                {
                  label: t('app:type.Plugin'),
                  value: AppTypeEnum.plugin
                }
              ]}
              value={appType}
              inlineStyles={{ px: 0.5 }}
              gap={5}
              display={'flex'}
              alignItems={'center'}
              fontSize={['sm', 'md']}
              flexShrink={0}
              onChange={(e) => {
                router.push({
                  query: {
                    ...router.query,
                    type: e
                  }
                });
              }}
            />
            <Box flex={1} />

            {isPc && RenderSearchInput}

            {(folderDetail
              ? folderDetail.permission.hasWritePer && folderDetail?.type !== AppTypeEnum.httpPlugin
              : userInfo?.team.permission.hasWritePer) && (
              <MyMenu
                size="md"
                Button={
                  <Button variant={'primary'} leftIcon={<AddIcon />}>
                    <Box>{t('common:common.Create New')}</Box>
                  </Button>
                }
                menuList={[
                  {
                    children: [
                      {
                        icon: 'core/app/simpleBot',
                        label: t('app:type.Simple bot'),
                        description: t('app:type.Create simple bot tip'),
                        onClick: () => setCreateAppType(AppTypeEnum.simple)
                      },
                      {
                        icon: 'core/app/type/workflowFill',
                        label: t('app:type.Workflow bot'),
                        description: t('app:type.Create workflow tip'),
                        onClick: () => setCreateAppType(AppTypeEnum.workflow)
                      },
                      {
                        icon: 'core/app/type/pluginFill',
                        label: t('app:type.Plugin'),
                        description: t('app:type.Create one plugin tip'),
                        onClick: () => setCreateAppType(AppTypeEnum.plugin)
                      },
                      {
                        icon: 'core/app/type/httpPluginFill',
                        label: t('app:type.Http plugin'),
                        description: t('app:type.Create http plugin tip'),
                        onClick: onOpenCreateHttpPlugin
                      }
                    ]
                  },
                  {
                    children: [
                      {
                        icon: '/imgs/app/templateFill.svg',
                        label: t('app:template_market'),
                        description: t('app:template_market_description'),
                        onClick: () => setTemplateModalType('all')
                      }
                    ]
                  },
                  {
                    children: [
                      {
                        icon: FolderIcon,
                        label: t('common:Folder'),
                        onClick: () => setEditFolder({})
                      }
                    ]
                  }
                ]}
              />
            )}
          </Flex>

          {!isPc && <Box mt={2}>{RenderSearchInput}</Box>}

          <MyBox flex={'1 0 0'} isLoading={myApps.length === 0 && isFetchingApps}>
            <List />
          </MyBox>
        </Flex>

        {/* Folder slider */}
        {!!folderDetail && isPc && (
          <Box pt={[4, 6]} pr={[4, 6]}>
            <FolderSlideCard
              refetchResource={() => Promise.all([refetchFolderDetail(), loadMyApps()])}
              resumeInheritPermission={() => resumeInheritPer(folderDetail._id)}
              isInheritPermission={folderDetail.inheritPermission}
              hasParent={!!folderDetail.parentId}
              refreshDeps={[folderDetail._id, folderDetail.inheritPermission]}
              name={folderDetail.name}
              intro={folderDetail.intro}
              onEdit={() => {
                setEditFolder({
                  id: folderDetail._id,
                  name: folderDetail.name,
                  intro: folderDetail.intro
                });
              }}
              onMove={() => setMoveAppId(folderDetail._id)}
              deleteTip={appT('confirm_delete_folder_tip')}
              onDelete={() => onDeleFolder(folderDetail._id)}
              managePer={{
                mode: 'all',
                permission: folderDetail.permission,
                onGetCollaboratorList: () => getCollaboratorList(folderDetail._id),
                permissionList: AppPermissionList,
                onUpdateCollaborators: ({
                  members,
                  groups,
                  permission
                }: {
                  members?: string[];
                  groups?: string[];
                  permission: number;
                }) => {
                  return postUpdateAppCollaborators({
                    members,
                    groups,
                    permission,
                    appId: folderDetail._id
                  });
                },
                refreshDeps: [folderDetail._id, folderDetail.inheritPermission],
                onDelOneCollaborator: async ({
                  tmbId,
                  groupId
                }: {
                  tmbId?: string;
                  groupId?: string;
                }) => {
                  if (tmbId) {
                    return deleteAppCollaborators({
                      appId: folderDetail._id,
                      tmbId
                    });
                  } else if (groupId) {
                    return deleteAppCollaborators({
                      appId: folderDetail._id,
                      groupId
                    });
                  }
                }
              }}
            />
          </Box>
        )}
      </Flex>

      {!!editFolder && (
        <EditFolderModal
          {...editFolder}
          onClose={() => setEditFolder(undefined)}
          onCreate={(data) => onCreateFolder({ ...data, parentId })}
          onEdit={({ id, ...data }) => onUpdateApp(id, data)}
        />
      )}
      {!!createAppType && (
        <CreateModal
          type={createAppType}
          onClose={() => setCreateAppType(undefined)}
          onOpenTemplateModal={setTemplateModalType}
        />
      )}
      {isOpenCreateHttpPlugin && <HttpEditModal onClose={onCloseCreateHttpPlugin} />}
      {!!templateModalType && (
        <TemplateMarketModal
          onClose={() => setTemplateModalType(undefined)}
          defaultType={templateModalType}
        />
      )}
    </Flex>
  );
};

代码语言:ts
复制
const AppListContextProvider = ({ children }: { children: ReactNode }) => {
  const { t } = useTranslation();
  const router = useRouter();
  const { parentId = null, type = 'ALL' } = router.query as {
    parentId?: string | null;
    type: AppTypeEnum;
  };
  const [searchKey, setSearchKey] = useState('');

  const {
    data = [],
    runAsync: loadMyApps,
    loading: isFetchingApps
  } = useRequest2(
    () => {
      const formatType = (() => {
        if (!type || type === 'ALL') return undefined;
        if (type === AppTypeEnum.plugin)
          return [AppTypeEnum.folder, AppTypeEnum.plugin, AppTypeEnum.httpPlugin];

        return [AppTypeEnum.folder, type];
      })();
      return getMyApps({ parentId, type: formatType, searchKey });
    },
    {
      manual: false,
      refreshDeps: [searchKey, parentId, type],
      throttleWait: 500,
      refreshOnWindowFocus: true
    }
  );

  const { data: paths = [], runAsync: refetchPaths } = useRequest2(
    () => getAppFolderPath(parentId),
    {
      manual: false,
      refreshDeps: [parentId]
    }
  );

  const { data: folderDetail, runAsync: refetchFolderDetail } = useRequest2(
    () => {
      if (parentId) return getAppDetailById(parentId);
      return Promise.resolve(null);
    },
    {
      manual: false,
      refreshDeps: [parentId]
    }
  );

  const { runAsync: onUpdateApp } = useRequest2((id: string, data: AppUpdateParams) =>
    putAppById(id, data).then(async (res) => {
      await Promise.all([refetchFolderDetail(), refetchPaths(), loadMyApps()]);
      return res;
    })
  );

  const [moveAppId, setMoveAppId] = useState<string>();
  const onMoveApp = useCallback(
    async (parentId: ParentIdType) => {
      if (!moveAppId) return;
      await onUpdateApp(moveAppId, { parentId });
    },
    [moveAppId, onUpdateApp]
  );

  const getAppFolderList = useCallback(({ parentId }: GetResourceFolderListProps) => {
    return getMyApps({
      parentId,
      type: AppTypeEnum.folder
    }).then((res) =>
      res
        .filter((item) => item.permission.hasWritePer)
        .map((item) => ({
          id: item._id,
          name: item.name
        }))
    );
  }, []);

  const { setLastAppListRouteType } = useSystemStore();
  useEffect(() => {
    setLastAppListRouteType(type);
  }, [setLastAppListRouteType, type]);

  const contextValue: AppListContextType = {
    parentId,
    appType: type,
    myApps: data,
    loadMyApps,
    refetchFolderDetail,
    isFetchingApps,
    folderDetail,
    paths,
    onUpdateApp,
    setMoveAppId,
    searchKey,
    setSearchKey
  };
  return (
    <AppListContext.Provider value={contextValue}>
      {children}
      {!!moveAppId && (
        <MoveModal
          moveResourceId={moveAppId}
          server={getAppFolderList}
          title={t('app:move_app')}
          onClose={() => setMoveAppId(undefined)}
          onConfirm={onMoveApp}
          moveHint={t('app:move.hint')}
        />
      )}
    </AppListContext.Provider>
  );
};

export default AppListContextProvider;

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档