mirror of
https://github.com/langgenius/dify.git
synced 2026-01-07 06:48:28 +00:00
Compare commits
15 Commits
release/e-
...
chore/offl
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7b88f09ee7 | ||
|
|
81578f1705 | ||
|
|
964ce48cbc | ||
|
|
779daceeb2 | ||
|
|
a294773dd5 | ||
|
|
859b4cd6cc | ||
|
|
d454214ddc | ||
|
|
169ae55635 | ||
|
|
015ce09593 | ||
|
|
0337b857ff | ||
|
|
d6fe22b19e | ||
|
|
2c4239c593 | ||
|
|
18757d07c9 | ||
|
|
0f23e3d9ab | ||
|
|
765adabb32 |
1
.github/workflows/build-push.yml
vendored
1
.github/workflows/build-push.yml
vendored
@@ -6,7 +6,6 @@ on:
|
||||
- "main"
|
||||
- "deploy/dev"
|
||||
- "deploy/enterprise"
|
||||
- "release/e-*"
|
||||
tags:
|
||||
- "*"
|
||||
|
||||
|
||||
@@ -36,7 +36,6 @@ import AccessControl from '@/app/components/app/app-access-control'
|
||||
import { AccessMode } from '@/models/access-control'
|
||||
import { useGlobalPublicStore } from '@/context/global-public-context'
|
||||
import { formatTime } from '@/utils/time'
|
||||
import { useGetUserCanAccessApp } from '@/service/access-control'
|
||||
|
||||
export type AppCardProps = {
|
||||
app: App
|
||||
@@ -191,7 +190,6 @@ const AppCard = ({ app, onRefresh }: AppCardProps) => {
|
||||
}, [onRefresh, mutateApps, setShowAccessControl])
|
||||
|
||||
const Operations = (props: HtmlContentProps) => {
|
||||
const { data: userCanAccessApp, isLoading: isGettingUserCanAccessApp } = useGetUserCanAccessApp({ appId: app?.id, enabled: (!!props?.open && systemFeatures.webapp_auth.enabled) })
|
||||
const onMouseLeave = async () => {
|
||||
props.onClose?.()
|
||||
}
|
||||
@@ -269,14 +267,10 @@ const AppCard = ({ app, onRefresh }: AppCardProps) => {
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
{
|
||||
(isGettingUserCanAccessApp || !userCanAccessApp?.result) ? null : <>
|
||||
<Divider className="my-1" />
|
||||
<button className='mx-1 flex h-8 cursor-pointer items-center gap-2 rounded-lg px-3 hover:bg-state-base-hover' onClick={onClickInstalledApp}>
|
||||
<span className='system-sm-regular text-text-secondary'>{t('app.openInExplore')}</span>
|
||||
</button>
|
||||
</>
|
||||
}
|
||||
<Divider className="my-1" />
|
||||
{
|
||||
systemFeatures.webapp_auth.enabled && isCurrentWorkspaceEditor && <>
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
'use client'
|
||||
import { RiArrowRightLine, RiImage2Fill } from '@remixicon/react'
|
||||
import Link from 'next/link'
|
||||
import type { FC } from 'react'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
const i18nPrefix = 'app.checkLegacy'
|
||||
|
||||
type Props = {
|
||||
appNum: number,
|
||||
publishedNum: number,
|
||||
}
|
||||
|
||||
const AppTip: FC<Props> = ({
|
||||
appNum,
|
||||
publishedNum,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
return (
|
||||
<div className='fixed bottom-0 left-0 right-0 z-10 border-t border-state-warning-hover px-12 py-4'>
|
||||
<div className="absolute inset-0 bg-[linear-gradient(92deg,_rgba(247,144,9,0.25)_53.67%,_rgba(255,255,255,0)_100%)] opacity-40" />
|
||||
<div className='relative flex items-center'>
|
||||
<div className='relative rounded-lg bg-text-accent p-1.5'>
|
||||
<RiImage2Fill className='size-5 text-text-primary-on-surface' />
|
||||
<div className='absolute left-[-2px] top-[-2px] size-2 rounded-[3px] border border-white bg-components-badge-status-light-error-border-inner p-0.5'>
|
||||
<div className='h-full w-full rounded-[3px] bg-components-badge-status-light-error-bg'></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='ml-3'>
|
||||
<div className='system-md-semibold text-text-primary'>{t(`${i18nPrefix}.title`)}</div>
|
||||
<div className='system-sm-regular mt-1 flex items-center space-x-0.5 text-text-secondary'>
|
||||
{t(`${i18nPrefix}.description`, { num: appNum, publishedNum })}
|
||||
<Link className='system-sm-semibold text-text-accent' href='/apps/check-legacy'>{t(`${i18nPrefix}.toSolve`)}</Link>
|
||||
<RiArrowRightLine className='size-4 text-components-button-secondary-accent-text' />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default React.memo(AppTip)
|
||||
@@ -0,0 +1,29 @@
|
||||
'use client'
|
||||
import type { FC } from 'react'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import cn from '@/utils/classnames'
|
||||
|
||||
const i18nPrefix = 'app.checkLegacy'
|
||||
|
||||
type Props = {
|
||||
className?: string,
|
||||
appNum: number,
|
||||
publishedNum: number,
|
||||
}
|
||||
|
||||
const Header: FC<Props> = ({
|
||||
className,
|
||||
appNum,
|
||||
publishedNum,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
return (
|
||||
<div className={cn(className)}>
|
||||
<div className='title-2xl-semi-bold text-text-primary'>{t(`${i18nPrefix}.title`)}</div>
|
||||
<div className='system-md-regular mt-1 text-text-tertiary'>{t(`${i18nPrefix}.description`, { num: appNum, publishedNum })}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default React.memo(Header)
|
||||
53
web/app/(commonLayout)/apps/check-legacy/components/list.tsx
Normal file
53
web/app/(commonLayout)/apps/check-legacy/components/list.tsx
Normal file
@@ -0,0 +1,53 @@
|
||||
'use client'
|
||||
import type { FC } from 'react'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import cn from '@/utils/classnames'
|
||||
import AppIcon from '@/app/components/base/app-icon'
|
||||
|
||||
const i18nPrefix = 'app.checkLegacy.list'
|
||||
type Props = {
|
||||
list: any[]
|
||||
}
|
||||
|
||||
const List: FC<Props> = ({
|
||||
list,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
return (
|
||||
<div className='h-0 grow overflow-y-auto'>
|
||||
{list.length > 0 ? (
|
||||
<table className={cn('mt-2 w-full min-w-[440px] border-collapse border-0')}>
|
||||
<thead className='system-xs-medium-uppercase text-text-tertiary'>
|
||||
<tr>
|
||||
<td className='whitespace-nowrap rounded-l-lg bg-background-section-burn pl-3 pr-1'>{t(`${i18nPrefix}.appName`)}</td>
|
||||
<td className='whitespace-nowrap bg-background-section-burn py-1.5 pl-3'>{t(`${i18nPrefix}.published`)}</td>
|
||||
<td className='whitespace-nowrap bg-background-section-burn py-1.5 pl-3'>{t(`${i18nPrefix}.createBy`)}</td>
|
||||
<td className='whitespace-nowrap bg-background-section-burn py-1.5 pl-3'>{t(`${i18nPrefix}.lastRequest`)}</td>
|
||||
<td className='whitespace-nowrap rounded-r-lg bg-background-section-burn py-1.5 pl-3'>{t(`${i18nPrefix}.createAt`)}</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="system-sm-regular text-text-secondary">
|
||||
{list.map((item, index) => (
|
||||
<tr key={index} className='cursor-pointer border-b border-divider-subtle hover:bg-background-default-hover'>
|
||||
<td className='whitespace-nowrap rounded-l-lg py-2 pl-3 pr-1'>
|
||||
<div className='flex items-center space-x-2'>
|
||||
<AppIcon size='tiny' />
|
||||
<div>Python bug fixer</div>
|
||||
</div>
|
||||
</td>
|
||||
<td className='whitespace-nowrap py-1.5 pl-3'>{t('app.checkLegacy.yes')}</td>
|
||||
<td className='whitespace-nowrap py-1.5 pl-3'>Evan · evan@dify.ai</td>
|
||||
<td className='whitespace-nowrap py-1.5 pl-3'>2023-03-21 10:25</td>
|
||||
<td className='whitespace-nowrap rounded-r-lg py-1.5 pl-3'>2023-03-21 10:25</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
) : (
|
||||
<div className='system-md-regular flex items-center justify-center text-text-secondary'>{t(`${i18nPrefix}.noData`)}</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default React.memo(List)
|
||||
23
web/app/(commonLayout)/apps/check-legacy/components/tip.tsx
Normal file
23
web/app/(commonLayout)/apps/check-legacy/components/tip.tsx
Normal file
@@ -0,0 +1,23 @@
|
||||
'use client'
|
||||
import { RiBookOpenLine } from '@remixicon/react'
|
||||
import type { FC } from 'react'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
const i18nPrefix = 'app.checkLegacy.tip'
|
||||
|
||||
const Tip: FC = () => {
|
||||
const { t } = useTranslation()
|
||||
return (
|
||||
<div className='w-[316px] rounded-xl bg-background-section p-6'>
|
||||
<div className='inline-flex rounded-[10px] border-[0.5px] border-components-card-border bg-components-card-border p-2 shadow-lg backdrop-blur-[5px]'>
|
||||
<RiBookOpenLine className='size-5 text-text-accent' />
|
||||
</div>
|
||||
<div className='system-xl-semibold mt-3 text-text-primary'>{t(`${i18nPrefix}.title`)}</div>
|
||||
<div className='system-sm-regular mt-2 text-text-secondary'>{t(`${i18nPrefix}.description`)}</div>
|
||||
<a className='system-sm-medium mt-2 text-text-accent' target='_blank' href='todo'>{t(`${i18nPrefix}.learnMore`)}</a>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default React.memo(Tip)
|
||||
100
web/app/(commonLayout)/apps/check-legacy/page.tsx
Normal file
100
web/app/(commonLayout)/apps/check-legacy/page.tsx
Normal file
@@ -0,0 +1,100 @@
|
||||
'use client'
|
||||
import Sort from '@/app/components/base/sort'
|
||||
import Header from './components/header'
|
||||
import List from './components/list'
|
||||
import useLegacyList from './use-legacy-list'
|
||||
import Chip from '@/app/components/base/chip'
|
||||
import { RiFilter3Line, RiLoopLeftLine } from '@remixicon/react'
|
||||
import { useCallback } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import Button from '@/app/components/base/button'
|
||||
import Pagination from '@/app/components/base/pagination'
|
||||
import { APP_PAGE_LIMIT } from '@/config'
|
||||
import { noop } from 'lodash'
|
||||
import Tip from './components/tip'
|
||||
|
||||
const i18nPrefix = 'app.checkLegacy'
|
||||
const Page = () => {
|
||||
const { t } = useTranslation()
|
||||
const {
|
||||
list,
|
||||
total,
|
||||
sort_by,
|
||||
setOrderBy,
|
||||
published,
|
||||
setPublished,
|
||||
clearPublished,
|
||||
} = useLegacyList()
|
||||
|
||||
const handleSelectPublished = useCallback(({ value }: { value: number }) => {
|
||||
setPublished(value)
|
||||
}, [setPublished])
|
||||
|
||||
const renderTriggerContent = useCallback(() => {
|
||||
if(published === undefined)
|
||||
return t(`${i18nPrefix}.published`)
|
||||
return (
|
||||
<div className='flex space-x-1'>
|
||||
<div>{t(`${i18nPrefix}.published`)}</div>
|
||||
<span className='system-sm-medium text-text-secondary'>{published === 1 ? t(`${i18nPrefix}.yes`) : t(`${i18nPrefix}.no`)}</span>
|
||||
</div>
|
||||
)
|
||||
}, [published, t])
|
||||
|
||||
return (
|
||||
<div className='flex grow rounded-t-2xl border-t border-effects-highlight bg-background-default-subtle px-6 pt-4'>
|
||||
<div className='flex h-full grow flex-col pr-6'>
|
||||
<Header className='shrink-0' appNum={5} publishedNum={3}/>
|
||||
{/* Filter */}
|
||||
<div className='mb-2 mt-4 flex shrink-0 items-center justify-between'>
|
||||
<div className='flex items-center gap-2'>
|
||||
<Chip
|
||||
className='min-w-[150px]'
|
||||
panelClassName='w-[270px]'
|
||||
leftIcon={<RiFilter3Line className='h-4 w-4 text-text-secondary' />}
|
||||
value={published}
|
||||
renderTriggerContent={renderTriggerContent}
|
||||
onSelect={handleSelectPublished}
|
||||
onClear={clearPublished}
|
||||
items={[
|
||||
{ value: 1, name: t(`${i18nPrefix}.yes`) },
|
||||
{ value: 0, name: t(`${i18nPrefix}.no`) },
|
||||
]}
|
||||
/>
|
||||
<div className='h-3.5 w-px bg-divider-regular'></div>
|
||||
<Sort
|
||||
// '-' means descending order
|
||||
order={sort_by?.startsWith('-') ? '-' : ''}
|
||||
value={sort_by?.replace('-', '') || 'created_at'}
|
||||
items={[
|
||||
{ value: 'created_at', name: t(`${i18nPrefix}.createAt`) },
|
||||
{ value: 'last_request', name: t(`${i18nPrefix}.lastRequest`) },
|
||||
]}
|
||||
onSelect={setOrderBy}
|
||||
/>
|
||||
</div>
|
||||
<Button >
|
||||
<RiLoopLeftLine className='mr-1 h-4 w-4' />
|
||||
{t('common.operation.reset')}
|
||||
</Button>
|
||||
</div>
|
||||
<List list={list} />
|
||||
{(total && total > APP_PAGE_LIMIT)
|
||||
? <div className='flex justify-end'><Pagination
|
||||
className='shrink-0'
|
||||
current={1}
|
||||
onChange={noop}
|
||||
total={total}
|
||||
limit={10}
|
||||
onLimitChange={noop}
|
||||
/></div>
|
||||
: null}
|
||||
</div>
|
||||
<div className='ml-3 shrink-0 pr-8 pt-[108px]'>
|
||||
<Tip />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Page
|
||||
43
web/app/(commonLayout)/apps/check-legacy/use-legacy-list.ts
Normal file
43
web/app/(commonLayout)/apps/check-legacy/use-legacy-list.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import produce from 'immer'
|
||||
import { useCallback, useState } from 'react'
|
||||
|
||||
const useLegacyList = () => {
|
||||
const list: any[] = [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}] // Placeholder for the list, replace with actual data fetching logic
|
||||
const [queryParams, setQueryParams] = useState<Record<string, any>>({})
|
||||
const {
|
||||
sort_by,
|
||||
published,
|
||||
} = queryParams
|
||||
const setOrderBy = useCallback((sortBy: string) => {
|
||||
const nextValue = produce(queryParams, (draft) => {
|
||||
draft.sort_by = sortBy
|
||||
})
|
||||
setQueryParams(nextValue)
|
||||
}, [queryParams])
|
||||
|
||||
const setPublished = useCallback((value: number) => {
|
||||
const nextValue = produce(queryParams, (draft) => {
|
||||
draft.published = value
|
||||
})
|
||||
setQueryParams(nextValue)
|
||||
}, [queryParams])
|
||||
|
||||
const clearPublished = useCallback(() => {
|
||||
const nextValue = produce(queryParams, (draft) => {
|
||||
draft.published = undefined
|
||||
})
|
||||
setQueryParams(nextValue)
|
||||
}, [queryParams])
|
||||
|
||||
return {
|
||||
total: 5,
|
||||
list,
|
||||
sort_by,
|
||||
setOrderBy,
|
||||
published,
|
||||
setPublished,
|
||||
clearPublished,
|
||||
}
|
||||
}
|
||||
|
||||
export default useLegacyList
|
||||
@@ -6,15 +6,19 @@ import style from '../list.module.css'
|
||||
import Apps from './Apps'
|
||||
import { useEducationInit } from '@/app/education-apply/hooks'
|
||||
import { useGlobalPublicStore } from '@/context/global-public-context'
|
||||
import AppTip from './check-legacy/components/app-tip'
|
||||
import cn from '@/utils/classnames'
|
||||
|
||||
const AppList = () => {
|
||||
const { t } = useTranslation()
|
||||
useEducationInit()
|
||||
const { systemFeatures } = useGlobalPublicStore()
|
||||
const legacyAppNum = 5
|
||||
const publishedAppNum = 3
|
||||
return (
|
||||
<div className='relative flex h-0 shrink-0 grow flex-col overflow-y-auto bg-background-body'>
|
||||
<div className={cn('relative flex h-0 shrink-0 grow flex-col overflow-y-auto bg-background-body', legacyAppNum > 0 && 'pb-[74px]')}>
|
||||
<Apps />
|
||||
{!systemFeatures.branding.enabled && <footer className='shrink-0 grow-0 px-12 py-6'>
|
||||
{(!systemFeatures.branding.enabled && !legacyAppNum) && <footer className='shrink-0 grow-0 px-12 py-6'>
|
||||
<h3 className='text-gradient text-xl font-semibold leading-tight'>{t('app.join')}</h3>
|
||||
<p className='system-sm-regular mt-1 text-text-tertiary'>{t('app.communityIntro')}</p>
|
||||
<div className='mt-3 flex items-center gap-2'>
|
||||
@@ -26,6 +30,10 @@ const AppList = () => {
|
||||
</Link>
|
||||
</div>
|
||||
</footer>}
|
||||
|
||||
{legacyAppNum > 0 && (
|
||||
<AppTip appNum={legacyAppNum} publishedNum={publishedAppNum} />
|
||||
)}
|
||||
</div >
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { FC } from 'react'
|
||||
import { useMemo, useState } from 'react'
|
||||
import React, { useMemo, useState } from 'react'
|
||||
import { RiArrowDownSLine, RiCheckLine, RiCloseCircleFill, RiFilter3Line } from '@remixicon/react'
|
||||
import cn from '@/utils/classnames'
|
||||
import {
|
||||
@@ -20,6 +20,7 @@ type Props = {
|
||||
leftIcon?: any
|
||||
value: number | string
|
||||
items: Item[]
|
||||
renderTriggerContent?: () => React.ReactNode
|
||||
onSelect: (item: any) => void
|
||||
onClear: () => void
|
||||
}
|
||||
@@ -30,14 +31,17 @@ const Chip: FC<Props> = ({
|
||||
leftIcon,
|
||||
value,
|
||||
items,
|
||||
renderTriggerContent,
|
||||
onSelect,
|
||||
onClear,
|
||||
}) => {
|
||||
const [open, setOpen] = useState(false)
|
||||
|
||||
const triggerContent = useMemo(() => {
|
||||
if(renderTriggerContent)
|
||||
return renderTriggerContent()
|
||||
return items.find(item => item.value === value)?.name || ''
|
||||
}, [items, value])
|
||||
}, [items, renderTriggerContent, value])
|
||||
|
||||
return (
|
||||
<PortalToFollowElem
|
||||
@@ -71,7 +75,7 @@ const Chip: FC<Props> = ({
|
||||
</div>
|
||||
</div>
|
||||
{!value && <RiArrowDownSLine className='h-4 w-4 text-text-tertiary' />}
|
||||
{!!value && (
|
||||
{(!!value || value === 0) && (
|
||||
<div className='group/clear cursor-pointer p-[1px]' onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
onClear()
|
||||
|
||||
@@ -3,7 +3,6 @@ import { Fragment, cloneElement, useRef } from 'react'
|
||||
import cn from '@/utils/classnames'
|
||||
|
||||
export type HtmlContentProps = {
|
||||
open?: boolean
|
||||
onClose?: () => void
|
||||
onClick?: () => void
|
||||
}
|
||||
@@ -101,8 +100,7 @@ export default function CustomPopover({
|
||||
}
|
||||
>
|
||||
{cloneElement(htmlContent as React.ReactElement, {
|
||||
open,
|
||||
onClose: close,
|
||||
onClose: () => onMouseLeave(open),
|
||||
...(manualClose
|
||||
? {
|
||||
onClick: close,
|
||||
|
||||
@@ -507,13 +507,15 @@ const StepTwo = ({
|
||||
const separator = rules.segmentation.separator
|
||||
const max = rules.segmentation.max_tokens
|
||||
const overlap = rules.segmentation.chunk_overlap
|
||||
const isHierarchicalDocument = documentDetail.doc_form === ChunkingMode.parentChild
|
||||
|| (rules.parent_mode && rules.subchunk_segmentation)
|
||||
setSegmentIdentifier(separator)
|
||||
setMaxChunkLength(max)
|
||||
setOverlap(overlap!)
|
||||
setRules(rules.pre_processing_rules)
|
||||
setDefaultConfig(rules)
|
||||
|
||||
if (documentDetail.dataset_process_rule.mode === 'hierarchical') {
|
||||
if (isHierarchicalDocument) {
|
||||
setParentChildConfig({
|
||||
chunkForContext: rules.parent_mode || 'paragraph',
|
||||
parent: {
|
||||
|
||||
@@ -18,6 +18,15 @@ type Props = {
|
||||
onSaved: (value: Record<string, any>) => void
|
||||
}
|
||||
|
||||
const extractDefaultValues = (schemas: any[]) => {
|
||||
const result: Record<string, any> = {}
|
||||
for (const field of schemas) {
|
||||
if (field.default !== undefined)
|
||||
result[field.name] = field.default
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
const EndpointModal: FC<Props> = ({
|
||||
formSchemas,
|
||||
defaultValues = {},
|
||||
@@ -26,7 +35,10 @@ const EndpointModal: FC<Props> = ({
|
||||
}) => {
|
||||
const getValueFromI18nObject = useRenderI18nObject()
|
||||
const { t } = useTranslation()
|
||||
const [tempCredential, setTempCredential] = React.useState<any>(defaultValues)
|
||||
const initialValues = Object.keys(defaultValues).length > 0
|
||||
? defaultValues
|
||||
: extractDefaultValues(formSchemas)
|
||||
const [tempCredential, setTempCredential] = React.useState<any>(initialValues)
|
||||
|
||||
const handleSave = () => {
|
||||
for (const field of formSchemas) {
|
||||
|
||||
@@ -136,7 +136,7 @@ const PluginPage = ({
|
||||
const options = usePluginPageContext(v => v.options)
|
||||
const activeTab = usePluginPageContext(v => v.activeTab)
|
||||
const setActiveTab = usePluginPageContext(v => v.setActiveTab)
|
||||
const { enable_marketplace } = useGlobalPublicStore(s => s.systemFeatures)
|
||||
const { enable_marketplace, branding } = useGlobalPublicStore(s => s.systemFeatures)
|
||||
|
||||
const isPluginsTab = useMemo(() => activeTab === PLUGIN_PAGE_TABS_MAP.plugins, [activeTab])
|
||||
const isExploringMarketplace = useMemo(() => {
|
||||
@@ -225,7 +225,7 @@ const PluginPage = ({
|
||||
)
|
||||
}
|
||||
{
|
||||
canSetPermissions && (
|
||||
canSetPermissions && !branding.enabled && (
|
||||
<Tooltip
|
||||
popupContent={t('plugin.privilege.title')}
|
||||
>
|
||||
|
||||
@@ -6,9 +6,9 @@ import Item from './item'
|
||||
import type { Plugin } from '@/app/components/plugins/types.ts'
|
||||
import cn from '@/utils/classnames'
|
||||
import Link from 'next/link'
|
||||
import { MARKETPLACE_URL_PREFIX } from '@/config'
|
||||
import { RiArrowRightUpLine, RiSearchLine } from '@remixicon/react'
|
||||
import { noop } from 'lodash-es'
|
||||
import { getMarketplaceUrl } from '@/utils/var'
|
||||
|
||||
export type ListProps = {
|
||||
wrapElemRef: React.RefObject<HTMLElement>
|
||||
@@ -32,7 +32,7 @@ const List = forwardRef<ListRef, ListProps>(({
|
||||
const { t } = useTranslation()
|
||||
const hasFilter = !searchText
|
||||
const hasRes = list.length > 0
|
||||
const urlWithSearchText = getMarketplaceUrl('', { q: searchText, tags: tags.join(',') })
|
||||
const urlWithSearchText = `${MARKETPLACE_URL_PREFIX}/?q=${searchText}&tags=${tags.join(',')}`
|
||||
const nextToStickyELemRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
const { handleScroll, scrollPosition } = useStickyScroll({
|
||||
@@ -71,7 +71,7 @@ const List = forwardRef<ListRef, ListProps>(({
|
||||
return (
|
||||
<Link
|
||||
className='system-sm-medium sticky bottom-0 z-10 flex h-8 cursor-pointer items-center rounded-b-lg border-[0.5px] border-t border-components-panel-border bg-components-panel-bg-blur px-4 py-1 text-text-accent-light-mode-only shadow-lg'
|
||||
href={getMarketplaceUrl('')}
|
||||
href={`${MARKETPLACE_URL_PREFIX}/`}
|
||||
target='_blank'
|
||||
>
|
||||
<span>{t('plugin.findMoreInMarketplace')}</span>
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
import useToggleExpend from '@/app/components/workflow/nodes/_base/hooks/use-toggle-expend'
|
||||
import type { FileEntity } from '@/app/components/base/file-uploader/types'
|
||||
import FileListInLog from '@/app/components/base/file-uploader/file-list-in-log'
|
||||
import ActionButton from '@/app/components/base/action-button'
|
||||
|
||||
type Props = {
|
||||
className?: string
|
||||
@@ -88,15 +89,16 @@ const Base: FC<Props> = ({
|
||||
<CodeGeneratorButton onGenerated={onGenerated} codeLanguages={codeLanguages} />
|
||||
</div>
|
||||
)}
|
||||
<ActionButton className='ml-1' onClick={handleCopy}>
|
||||
{!isCopied
|
||||
? (
|
||||
<Clipboard className='mx-1 h-3.5 w-3.5 cursor-pointer text-text-tertiary' onClick={handleCopy} />
|
||||
<Clipboard className='h-4 w-4 cursor-pointer' />
|
||||
)
|
||||
: (
|
||||
<ClipboardCheck className='mx-1 h-3.5 w-3.5 text-text-tertiary' />
|
||||
<ClipboardCheck className='h-4 w-4' />
|
||||
)
|
||||
}
|
||||
|
||||
</ActionButton>
|
||||
<div className='ml-1'>
|
||||
<ToggleExpandBtn isExpand={isExpand} onExpandChange={setIsExpand} />
|
||||
</div>
|
||||
|
||||
@@ -15,7 +15,7 @@ import { pluginManifestToCardPluginProps } from '@/app/components/plugins/instal
|
||||
import { Badge as Badge2, BadgeState } from '@/app/components/base/badge/index'
|
||||
import Link from 'next/link'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { getMarketplaceUrl } from '@/utils/var'
|
||||
import { MARKETPLACE_URL_PREFIX } from '@/config'
|
||||
|
||||
export type SwitchPluginVersionProps = {
|
||||
uniqueIdentifier: string
|
||||
@@ -82,7 +82,7 @@ export const SwitchPluginVersion: FC<SwitchPluginVersionProps> = (props) => {
|
||||
modalBottomLeft={
|
||||
<Link
|
||||
className='flex items-center justify-center gap-1'
|
||||
href={getMarketplaceUrl(`/plugins/${pluginDetail.declaration.author}/${pluginDetail.declaration.name}`)}
|
||||
href={`${MARKETPLACE_URL_PREFIX}/plugins/${pluginDetail.declaration.author}/${pluginDetail.declaration.name}`}
|
||||
target='_blank'
|
||||
>
|
||||
<span className='system-xs-regular text-xs text-text-accent'>
|
||||
|
||||
@@ -29,10 +29,9 @@ export const useTabSearchParams = ({
|
||||
const router = useRouter()
|
||||
const pathName = pathnameFromHook || window?.location?.pathname
|
||||
const searchParams = useSearchParams()
|
||||
const searchParamValue = searchParams.has(searchParamName) ? decodeURIComponent(searchParams.get(searchParamName)!) : defaultTab
|
||||
const [activeTab, setTab] = useState<string>(
|
||||
!disableSearchParams
|
||||
? searchParamValue
|
||||
? (searchParams.get(searchParamName) || defaultTab)
|
||||
: defaultTab,
|
||||
)
|
||||
|
||||
@@ -40,7 +39,7 @@ export const useTabSearchParams = ({
|
||||
setTab(newActiveTab)
|
||||
if (disableSearchParams)
|
||||
return
|
||||
router[`${routingBehavior}`](`${pathName}?${searchParamName}=${encodeURIComponent(newActiveTab)}`)
|
||||
router[`${routingBehavior}`](`${pathName}?${searchParamName}=${newActiveTab}`)
|
||||
}
|
||||
|
||||
return [activeTab, setActiveTab] as const
|
||||
|
||||
@@ -199,9 +199,9 @@ const translation = {
|
||||
accessControl: 'Web App Access Control',
|
||||
accessItemsDescription: {
|
||||
anyone: 'Anyone can access the web app (no login required)',
|
||||
specific: 'Only specific members within the platform can access the web app',
|
||||
organization: 'All members within the platform can access the web app',
|
||||
external: 'Only authenticated external users can access the web app',
|
||||
specific: 'Only specific members within the platform can access the Web application',
|
||||
organization: 'All members within the platform can access the Web application',
|
||||
external: 'Only authenticated external users can access the Web application',
|
||||
},
|
||||
accessControlDialog: {
|
||||
title: 'Web App Access Control',
|
||||
@@ -218,7 +218,7 @@ const translation = {
|
||||
members_one: '{{count}} MEMBER',
|
||||
members_other: '{{count}} MEMBERS',
|
||||
noGroupsOrMembers: 'No groups or members selected',
|
||||
webAppSSONotEnabledTip: 'Please contact your organization administrator to configure external authentication for the web app.',
|
||||
webAppSSONotEnabledTip: 'Please contact your organization administrator to configure external authentication for the Web application.',
|
||||
operateGroupAndMember: {
|
||||
searchPlaceholder: 'Search groups and members',
|
||||
allMembers: 'All members',
|
||||
@@ -233,6 +233,29 @@ const translation = {
|
||||
notSetDesc: 'Currently nobody can access the web app. Please set permissions.',
|
||||
},
|
||||
noAccessPermission: 'No permission to access web app',
|
||||
checkLegacy: {
|
||||
title: 'Apps affected by image upload legacy',
|
||||
description: 'The current workspace has {{num}} applications affected, {{publishedNum}} of which have been published.',
|
||||
published: 'Published',
|
||||
yes: 'Yes',
|
||||
no: 'No',
|
||||
createAt: 'Created At',
|
||||
lastRequest: 'Last Request',
|
||||
list: {
|
||||
appName: 'App Name',
|
||||
published: 'Published',
|
||||
createBy: 'Created By',
|
||||
lastRequest: 'Last Request',
|
||||
createAt: 'Created At',
|
||||
noData: 'No items found',
|
||||
},
|
||||
tip: {
|
||||
title: 'How to solve it?',
|
||||
description: 'You can now create file type variables in the start form. We will no longer support the image upload feature in the future.',
|
||||
learnMore: 'Learn more',
|
||||
},
|
||||
toSolve: 'To resolve',
|
||||
},
|
||||
}
|
||||
|
||||
export default translation
|
||||
|
||||
@@ -234,6 +234,29 @@ const translation = {
|
||||
notSetDesc: '当前任何人都无法访问 Web 应用。请设置访问权限。',
|
||||
},
|
||||
noAccessPermission: '没有权限访问 web 应用',
|
||||
checkLegacy: {
|
||||
title: '受图像上传遗留问题影响的应用',
|
||||
description: '当前工作区有 {{num}} 个应用受图像上传遗留问题影响,其中 {{publishedNum}} 个已发布。',
|
||||
published: '已发布',
|
||||
yes: '是',
|
||||
no: '否',
|
||||
createAt: '创建时间',
|
||||
lastRequest: '最后请求',
|
||||
list: {
|
||||
appName: '应用名称',
|
||||
published: '已发布',
|
||||
createBy: '创建者',
|
||||
lastRequest: '最后请求时间',
|
||||
createAt: '创建时间',
|
||||
noData: '暂无数据',
|
||||
},
|
||||
tip: {
|
||||
title: '如何解决?',
|
||||
description: '您现在可以在开始表单中创建文件类型变量。未来我们将不再支持图片上传功能。',
|
||||
learnMore: '了解更多',
|
||||
},
|
||||
toSolve: '去解决',
|
||||
},
|
||||
}
|
||||
|
||||
export default translation
|
||||
|
||||
@@ -86,8 +86,5 @@ export const useGetUserCanAccessApp = ({ appId, isInstalledApp = true, enabled }
|
||||
enabled: !!appId && enabled,
|
||||
staleTime: 0,
|
||||
gcTime: 0,
|
||||
initialData: {
|
||||
result: !enabled,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user