mirror of
https://github.com/langgenius/dify.git
synced 2026-02-09 23:20:12 -05:00
Compare commits
2 Commits
refactor/t
...
refactor/r
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
72b96ba972 | ||
|
|
898e09264b |
@@ -96,10 +96,8 @@ const buildAppContext = (overrides: Partial<AppContextValue> = {}): AppContextVa
|
||||
isCurrentWorkspaceEditor: false,
|
||||
isCurrentWorkspaceDatasetOperator: false,
|
||||
mutateUserProfile: vi.fn(),
|
||||
mutateCurrentWorkspace: vi.fn(),
|
||||
langGeniusVersionInfo,
|
||||
isLoadingCurrentWorkspace: false,
|
||||
isValidatingCurrentWorkspace: false,
|
||||
}
|
||||
const useSelector: AppContextValue['useSelector'] = selector => selector({ ...base, useSelector })
|
||||
return {
|
||||
|
||||
@@ -7,6 +7,7 @@ import { useAppContext } from '@/context/app-context'
|
||||
import { useGlobalPublicStore } from '@/context/global-public-context'
|
||||
import { useProviderContext } from '@/context/provider-context'
|
||||
import { updateCurrentWorkspace } from '@/service/common'
|
||||
import { useInvalidateCurrentWorkspace } from '@/service/use-common'
|
||||
import CustomWebAppBrand from './index'
|
||||
|
||||
vi.mock('@/app/components/base/toast', () => ({
|
||||
@@ -15,6 +16,9 @@ vi.mock('@/app/components/base/toast', () => ({
|
||||
vi.mock('@/service/common', () => ({
|
||||
updateCurrentWorkspace: vi.fn(),
|
||||
}))
|
||||
vi.mock('@/service/use-common', () => ({
|
||||
useInvalidateCurrentWorkspace: vi.fn(),
|
||||
}))
|
||||
vi.mock('@/context/app-context', () => ({
|
||||
useAppContext: vi.fn(),
|
||||
}))
|
||||
@@ -37,6 +41,8 @@ const mockUseProviderContext = vi.mocked(useProviderContext)
|
||||
const mockUseGlobalPublicStore = vi.mocked(useGlobalPublicStore)
|
||||
const mockImageUpload = vi.mocked(imageUpload)
|
||||
const mockGetImageUploadErrorMessage = vi.mocked(getImageUploadErrorMessage)
|
||||
const mockInvalidateCurrentWorkspace = vi.fn()
|
||||
vi.mocked(useInvalidateCurrentWorkspace).mockReturnValue(mockInvalidateCurrentWorkspace)
|
||||
|
||||
const defaultPlanUsage = {
|
||||
buildApps: 0,
|
||||
@@ -62,7 +68,6 @@ describe('CustomWebAppBrand', () => {
|
||||
remove_webapp_brand: false,
|
||||
},
|
||||
},
|
||||
mutateCurrentWorkspace: vi.fn(),
|
||||
isCurrentWorkspaceManager: true,
|
||||
} as any)
|
||||
mockUseProviderContext.mockReturnValue({
|
||||
@@ -92,7 +97,6 @@ describe('CustomWebAppBrand', () => {
|
||||
remove_webapp_brand: false,
|
||||
},
|
||||
},
|
||||
mutateCurrentWorkspace: vi.fn(),
|
||||
isCurrentWorkspaceManager: false,
|
||||
} as any)
|
||||
|
||||
@@ -101,8 +105,7 @@ describe('CustomWebAppBrand', () => {
|
||||
expect(fileInput).toBeDisabled()
|
||||
})
|
||||
|
||||
it('toggles remove brand switch and calls the backend + mutate', async () => {
|
||||
const mutateMock = vi.fn()
|
||||
it('toggles remove brand switch and calls the backend + invalidate', async () => {
|
||||
mockUseAppContext.mockReturnValue({
|
||||
currentWorkspace: {
|
||||
custom_config: {
|
||||
@@ -110,7 +113,6 @@ describe('CustomWebAppBrand', () => {
|
||||
remove_webapp_brand: false,
|
||||
},
|
||||
},
|
||||
mutateCurrentWorkspace: mutateMock,
|
||||
isCurrentWorkspaceManager: true,
|
||||
} as any)
|
||||
|
||||
@@ -122,7 +124,7 @@ describe('CustomWebAppBrand', () => {
|
||||
url: '/workspaces/custom-config',
|
||||
body: { remove_webapp_brand: true },
|
||||
}))
|
||||
await waitFor(() => expect(mutateMock).toHaveBeenCalled())
|
||||
await waitFor(() => expect(mockInvalidateCurrentWorkspace).toHaveBeenCalled())
|
||||
})
|
||||
|
||||
it('shows cancel/apply buttons after successful upload and cancels properly', async () => {
|
||||
|
||||
@@ -24,6 +24,7 @@ import { useProviderContext } from '@/context/provider-context'
|
||||
import {
|
||||
updateCurrentWorkspace,
|
||||
} from '@/service/common'
|
||||
import { useInvalidateCurrentWorkspace } from '@/service/use-common'
|
||||
import { cn } from '@/utils/classnames'
|
||||
|
||||
const ALLOW_FILE_EXTENSIONS = ['svg', 'png']
|
||||
@@ -34,9 +35,9 @@ const CustomWebAppBrand = () => {
|
||||
const { plan, enableBilling } = useProviderContext()
|
||||
const {
|
||||
currentWorkspace,
|
||||
mutateCurrentWorkspace,
|
||||
isCurrentWorkspaceManager,
|
||||
} = useAppContext()
|
||||
const invalidateCurrentWorkspace = useInvalidateCurrentWorkspace()
|
||||
const [fileId, setFileId] = useState('')
|
||||
const [imgKey, setImgKey] = useState(() => Date.now())
|
||||
const [uploadProgress, setUploadProgress] = useState(0)
|
||||
@@ -83,7 +84,7 @@ const CustomWebAppBrand = () => {
|
||||
replace_webapp_logo: fileId,
|
||||
},
|
||||
})
|
||||
mutateCurrentWorkspace()
|
||||
invalidateCurrentWorkspace()
|
||||
setFileId('')
|
||||
setImgKey(Date.now())
|
||||
}
|
||||
@@ -96,7 +97,7 @@ const CustomWebAppBrand = () => {
|
||||
replace_webapp_logo: '',
|
||||
},
|
||||
})
|
||||
mutateCurrentWorkspace()
|
||||
invalidateCurrentWorkspace()
|
||||
}
|
||||
|
||||
const handleSwitch = async (checked: boolean) => {
|
||||
@@ -106,7 +107,7 @@ const CustomWebAppBrand = () => {
|
||||
remove_webapp_brand: checked,
|
||||
},
|
||||
})
|
||||
mutateCurrentWorkspace()
|
||||
invalidateCurrentWorkspace()
|
||||
}
|
||||
|
||||
const handleCancel = () => {
|
||||
@@ -116,7 +117,7 @@ const CustomWebAppBrand = () => {
|
||||
|
||||
return (
|
||||
<div className="py-4">
|
||||
<div className="system-md-medium mb-2 flex items-center justify-between rounded-xl bg-background-section-burn p-4 text-text-primary">
|
||||
<div className="mb-2 flex items-center justify-between rounded-xl bg-background-section-burn p-4 text-text-primary system-md-medium">
|
||||
{t('webapp.removeBrand', { ns: 'custom' })}
|
||||
<Switch
|
||||
size="l"
|
||||
@@ -127,8 +128,8 @@ const CustomWebAppBrand = () => {
|
||||
</div>
|
||||
<div className={cn('flex h-14 items-center justify-between rounded-xl bg-background-section-burn px-4', webappBrandRemoved && 'opacity-30')}>
|
||||
<div>
|
||||
<div className="system-md-medium text-text-primary">{t('webapp.changeLogo', { ns: 'custom' })}</div>
|
||||
<div className="system-xs-regular text-text-tertiary">{t('webapp.changeLogoTip', { ns: 'custom' })}</div>
|
||||
<div className="text-text-primary system-md-medium">{t('webapp.changeLogo', { ns: 'custom' })}</div>
|
||||
<div className="text-text-tertiary system-xs-regular">{t('webapp.changeLogoTip', { ns: 'custom' })}</div>
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
{(!uploadDisabled && webappLogo && !webappBrandRemoved) && (
|
||||
@@ -204,7 +205,7 @@ const CustomWebAppBrand = () => {
|
||||
<div className="mt-2 text-xs text-[#D92D20]">{t('uploadedFail', { ns: 'custom' })}</div>
|
||||
)}
|
||||
<div className="mb-2 mt-5 flex items-center gap-2">
|
||||
<div className="system-xs-medium-uppercase shrink-0 text-text-tertiary">{t('overview.appInfo.preview', { ns: 'appOverview' })}</div>
|
||||
<div className="shrink-0 text-text-tertiary system-xs-medium-uppercase">{t('overview.appInfo.preview', { ns: 'appOverview' })}</div>
|
||||
<Divider bgStyle="gradient" className="grow" />
|
||||
</div>
|
||||
<div className="relative mb-2 flex items-center gap-3">
|
||||
@@ -215,7 +216,7 @@ const CustomWebAppBrand = () => {
|
||||
<div className={cn('inline-flex h-8 w-8 items-center justify-center rounded-lg border border-divider-regular', 'bg-components-icon-bg-blue-light-solid')}>
|
||||
<BubbleTextMod className="h-4 w-4 text-components-avatar-shape-fill-stop-100" />
|
||||
</div>
|
||||
<div className="system-md-semibold grow text-text-secondary">Chatflow App</div>
|
||||
<div className="grow text-text-secondary system-md-semibold">Chatflow App</div>
|
||||
<div className="p-1.5">
|
||||
<RiLayoutLeft2Line className="h-4 w-4 text-text-tertiary" />
|
||||
</div>
|
||||
@@ -246,7 +247,7 @@ const CustomWebAppBrand = () => {
|
||||
<div className="flex items-center gap-1.5">
|
||||
{!webappBrandRemoved && (
|
||||
<>
|
||||
<div className="system-2xs-medium-uppercase text-text-tertiary">POWERED BY</div>
|
||||
<div className="text-text-tertiary system-2xs-medium-uppercase">POWERED BY</div>
|
||||
{
|
||||
systemFeatures.branding.enabled && systemFeatures.branding.workspace_logo
|
||||
? <img src={systemFeatures.branding.workspace_logo} alt="logo" className="block h-5 w-auto" />
|
||||
@@ -262,12 +263,12 @@ const CustomWebAppBrand = () => {
|
||||
<div className="flex w-[138px] grow flex-col justify-between p-2 pr-0">
|
||||
<div className="flex grow flex-col justify-between rounded-l-2xl border-[0.5px] border-r-0 border-components-panel-border-subtle bg-chatbot-bg pb-4 pl-[22px] pt-16">
|
||||
<div className="w-[720px] rounded-2xl border border-divider-subtle bg-chat-bubble-bg px-4 py-3">
|
||||
<div className="body-md-regular mb-1 text-text-primary">Hello! How can I assist you today?</div>
|
||||
<div className="mb-1 text-text-primary body-md-regular">Hello! How can I assist you today?</div>
|
||||
<Button size="small">
|
||||
<div className="h-2 w-[144px] rounded-sm bg-text-quaternary opacity-20"></div>
|
||||
</Button>
|
||||
</div>
|
||||
<div className="body-lg-regular flex h-[52px] w-[578px] items-center rounded-xl border border-components-chat-input-border bg-components-panel-bg-blur pl-3.5 text-text-placeholder shadow-md backdrop-blur-sm">Talk to Dify</div>
|
||||
<div className="flex h-[52px] w-[578px] items-center rounded-xl border border-components-chat-input-border bg-components-panel-bg-blur pl-3.5 text-text-placeholder shadow-md backdrop-blur-sm body-lg-regular">Talk to Dify</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -278,14 +279,14 @@ const CustomWebAppBrand = () => {
|
||||
<div className={cn('inline-flex h-8 w-8 items-center justify-center rounded-lg border border-divider-regular', 'bg-components-icon-bg-indigo-solid')}>
|
||||
<RiExchange2Fill className="h-4 w-4 text-components-avatar-shape-fill-stop-100" />
|
||||
</div>
|
||||
<div className="system-md-semibold grow text-text-secondary">Workflow App</div>
|
||||
<div className="grow text-text-secondary system-md-semibold">Workflow App</div>
|
||||
<div className="p-1.5">
|
||||
<RiLayoutLeft2Line className="h-4 w-4 text-text-tertiary" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="system-md-semibold-uppercase flex h-10 shrink-0 items-center border-b-2 border-components-tab-active text-text-primary">RUN ONCE</div>
|
||||
<div className="system-md-semibold-uppercase flex h-10 grow items-center border-b-2 border-transparent text-text-tertiary">RUN BATCH</div>
|
||||
<div className="flex h-10 shrink-0 items-center border-b-2 border-components-tab-active text-text-primary system-md-semibold-uppercase">RUN ONCE</div>
|
||||
<div className="flex h-10 grow items-center border-b-2 border-transparent text-text-tertiary system-md-semibold-uppercase">RUN BATCH</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grow bg-components-panel-bg">
|
||||
@@ -293,7 +294,7 @@ const CustomWebAppBrand = () => {
|
||||
<div className="mb-1 py-2">
|
||||
<div className="h-2 w-20 rounded-sm bg-text-quaternary opacity-20"></div>
|
||||
</div>
|
||||
<div className="h-16 w-full rounded-lg bg-components-input-bg-normal "></div>
|
||||
<div className="h-16 w-full rounded-lg bg-components-input-bg-normal"></div>
|
||||
</div>
|
||||
<div className="flex items-center justify-between px-4 py-3">
|
||||
<Button size="small">
|
||||
@@ -308,7 +309,7 @@ const CustomWebAppBrand = () => {
|
||||
<div className="flex h-12 shrink-0 items-center gap-1.5 bg-components-panel-bg p-4 pt-3">
|
||||
{!webappBrandRemoved && (
|
||||
<>
|
||||
<div className="system-2xs-medium-uppercase text-text-tertiary">POWERED BY</div>
|
||||
<div className="text-text-tertiary system-2xs-medium-uppercase">POWERED BY</div>
|
||||
{
|
||||
systemFeatures.branding.enabled && systemFeatures.branding.workspace_logo
|
||||
? <img src={systemFeatures.branding.workspace_logo} alt="logo" className="block h-5 w-auto" />
|
||||
|
||||
@@ -6,10 +6,9 @@ import {
|
||||
RiBrainLine,
|
||||
} from '@remixicon/react'
|
||||
import { useDebounce } from 'ahooks'
|
||||
import { useEffect, useMemo } from 'react'
|
||||
import { useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { IS_CLOUD_EDITION } from '@/config'
|
||||
import { useAppContext } from '@/context/app-context'
|
||||
import { useGlobalPublicStore } from '@/context/global-public-context'
|
||||
import { useProviderContext } from '@/context/provider-context'
|
||||
import { cn } from '@/utils/classnames'
|
||||
@@ -34,7 +33,6 @@ const FixedModelProvider = ['langgenius/openai/openai', 'langgenius/anthropic/an
|
||||
const ModelProviderPage = ({ searchText }: Props) => {
|
||||
const debouncedSearchText = useDebounce(searchText, { wait: 500 })
|
||||
const { t } = useTranslation()
|
||||
const { mutateCurrentWorkspace, isValidatingCurrentWorkspace } = useAppContext()
|
||||
const { data: textGenerationDefaultModel, isLoading: isTextGenerationDefaultModelLoading } = useDefaultModel(ModelTypeEnum.textGeneration)
|
||||
const { data: embeddingsDefaultModel, isLoading: isEmbeddingsDefaultModelLoading } = useDefaultModel(ModelTypeEnum.textEmbedding)
|
||||
const { data: rerankDefaultModel, isLoading: isRerankDefaultModelLoading } = useDefaultModel(ModelTypeEnum.rerank)
|
||||
@@ -92,14 +90,10 @@ const ModelProviderPage = ({ searchText }: Props) => {
|
||||
return [filteredConfiguredProviders, filteredNotConfiguredProviders]
|
||||
}, [configuredProviders, debouncedSearchText, notConfiguredProviders])
|
||||
|
||||
useEffect(() => {
|
||||
mutateCurrentWorkspace()
|
||||
}, [mutateCurrentWorkspace])
|
||||
|
||||
return (
|
||||
<div className="relative -mt-2 pt-1">
|
||||
<div className={cn('mb-2 flex items-center')}>
|
||||
<div className="system-md-semibold grow text-text-primary">{t('modelProvider.models', { ns: 'common' })}</div>
|
||||
<div className="grow text-text-primary system-md-semibold">{t('modelProvider.models', { ns: 'common' })}</div>
|
||||
<div className={cn(
|
||||
'relative flex shrink-0 items-center justify-end gap-2 rounded-lg border border-transparent p-px',
|
||||
defaultModelNotConfigured && 'border-components-panel-border bg-components-panel-bg-blur pl-2 shadow-xs',
|
||||
@@ -107,7 +101,7 @@ const ModelProviderPage = ({ searchText }: Props) => {
|
||||
>
|
||||
{defaultModelNotConfigured && <div className="absolute bottom-0 left-0 right-0 top-0 opacity-40" style={{ background: 'linear-gradient(92deg, rgba(247, 144, 9, 0.25) 0%, rgba(255, 255, 255, 0.00) 100%)' }} />}
|
||||
{defaultModelNotConfigured && (
|
||||
<div className="system-xs-medium flex items-center gap-1 text-text-primary">
|
||||
<div className="flex items-center gap-1 text-text-primary system-xs-medium">
|
||||
<RiAlertFill className="h-4 w-4 text-text-warning-secondary" />
|
||||
<span className="max-w-[460px] truncate" title={t('modelProvider.notConfigured', { ns: 'common' })}>{t('modelProvider.notConfigured', { ns: 'common' })}</span>
|
||||
</div>
|
||||
@@ -123,14 +117,14 @@ const ModelProviderPage = ({ searchText }: Props) => {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{IS_CLOUD_EDITION && <QuotaPanel providers={providers} isLoading={isValidatingCurrentWorkspace} />}
|
||||
{IS_CLOUD_EDITION && <QuotaPanel providers={providers} />}
|
||||
{!filteredConfiguredProviders?.length && (
|
||||
<div className="mb-2 rounded-[10px] bg-workflow-process-bg p-4">
|
||||
<div className="flex h-10 w-10 items-center justify-center rounded-[10px] border-[0.5px] border-components-card-border bg-components-card-bg shadow-lg backdrop-blur">
|
||||
<RiBrainLine className="h-5 w-5 text-text-primary" />
|
||||
</div>
|
||||
<div className="system-sm-medium mt-2 text-text-secondary">{t('modelProvider.emptyProviderTitle', { ns: 'common' })}</div>
|
||||
<div className="system-xs-regular mt-1 text-text-tertiary">{t('modelProvider.emptyProviderTip', { ns: 'common' })}</div>
|
||||
<div className="mt-2 text-text-secondary system-sm-medium">{t('modelProvider.emptyProviderTitle', { ns: 'common' })}</div>
|
||||
<div className="mt-1 text-text-tertiary system-xs-regular">{t('modelProvider.emptyProviderTip', { ns: 'common' })}</div>
|
||||
</div>
|
||||
)}
|
||||
{!!filteredConfiguredProviders?.length && (
|
||||
@@ -145,7 +139,7 @@ const ModelProviderPage = ({ searchText }: Props) => {
|
||||
)}
|
||||
{!!filteredNotConfiguredProviders?.length && (
|
||||
<>
|
||||
<div className="system-md-semibold mb-2 flex items-center pt-2 text-text-primary">{t('modelProvider.toBeConfigured', { ns: 'common' })}</div>
|
||||
<div className="mb-2 flex items-center pt-2 text-text-primary system-md-semibold">{t('modelProvider.toBeConfigured', { ns: 'common' })}</div>
|
||||
<div className="relative">
|
||||
{filteredNotConfiguredProviders?.map(provider => (
|
||||
<ProviderAddedCard
|
||||
|
||||
@@ -48,11 +48,9 @@ const providerKeyToPluginId: Record<ModelProviderQuotaGetPaid, string> = {
|
||||
|
||||
type QuotaPanelProps = {
|
||||
providers: ModelProvider[]
|
||||
isLoading?: boolean
|
||||
}
|
||||
const QuotaPanel: FC<QuotaPanelProps> = ({
|
||||
providers,
|
||||
isLoading = false,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
const { currentWorkspace } = useAppContext()
|
||||
@@ -98,7 +96,7 @@ const QuotaPanel: FC<QuotaPanelProps> = ({
|
||||
}
|
||||
}, [providers, isShowInstallModal, hideInstallFromMarketplace])
|
||||
|
||||
if (isLoading) {
|
||||
if (!currentWorkspace.id) {
|
||||
return (
|
||||
<div className="my-2 flex min-h-[72px] items-center justify-center rounded-xl border-[0.5px] border-components-panel-border bg-third-party-model-bg-default shadow-xs">
|
||||
<Loading />
|
||||
@@ -108,13 +106,13 @@ const QuotaPanel: FC<QuotaPanelProps> = ({
|
||||
|
||||
return (
|
||||
<div className={cn('my-2 min-w-[72px] shrink-0 rounded-xl border-[0.5px] pb-2.5 pl-4 pr-2.5 pt-3 shadow-xs', credits <= 0 ? 'border-state-destructive-border hover:bg-state-destructive-hover' : 'border-components-panel-border bg-third-party-model-bg-default')}>
|
||||
<div className="system-xs-medium-uppercase mb-2 flex h-4 items-center text-text-tertiary">
|
||||
<div className="mb-2 flex h-4 items-center text-text-tertiary system-xs-medium-uppercase">
|
||||
{t('modelProvider.quota', { ns: 'common' })}
|
||||
<Tooltip popupContent={t('modelProvider.card.tip', { ns: 'common', modelNames: trial_models.map(key => modelNameMap[key as keyof typeof modelNameMap]).filter(Boolean).join(', ') })} />
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-1 text-xs text-text-tertiary">
|
||||
<span className="system-md-semibold-uppercase mr-0.5 text-text-secondary">{formatNumber(credits)}</span>
|
||||
<span className="mr-0.5 text-text-secondary system-md-semibold-uppercase">{formatNumber(credits)}</span>
|
||||
<span>{t('modelProvider.credits', { ns: 'common' })}</span>
|
||||
{currentWorkspace.next_credit_reset_date
|
||||
? (
|
||||
|
||||
@@ -18,25 +18,25 @@ const StatusContainer: FC<Props> = ({
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
'system-xs-regular relative break-all rounded-lg border px-3 py-2.5',
|
||||
'relative break-all rounded-lg border px-3 py-2.5 system-xs-regular',
|
||||
status === 'succeeded' && 'border-[rgba(23,178,106,0.8)] bg-workflow-display-success-bg bg-[url(~@/app/components/workflow/run/assets/bg-line-success.svg)] text-text-success',
|
||||
status === 'succeeded' && theme === Theme.light && 'shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.5),inset_0_1px_3px_0_rgba(0,0,0,0.12),inset_0_2px_24px_0_rgba(23,178,106,0.2),0_1px_2px_0_rgba(9,9,11,0.05),0_0_0_1px_rgba(0,0,0,0.05)]',
|
||||
status === 'succeeded' && theme === Theme.dark && 'shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.12),inset_0_1px_3px_0_rgba(0,0,0,0.4),inset_0_2px_24px_0_rgba(23,178,106,0.25),0_1px_2px_0_rgba(0,0,0,0.1),0_0_0_1px_rgba(24, 24, 27, 0.95)]',
|
||||
status === 'succeeded' && theme === Theme.dark && 'shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.12),inset_0_1px_3px_0_rgba(0,0,0,0.4),inset_0_2px_24px_0_rgba(23,178,106,0.25),0_1px_2px_0_rgba(0,0,0,0.1),0_0_0_1px_rgba(24,24,27,0.95)]',
|
||||
status === 'partial-succeeded' && 'border-[rgba(23,178,106,0.8)] bg-workflow-display-success-bg bg-[url(~@/app/components/workflow/run/assets/bg-line-success.svg)] text-text-success',
|
||||
status === 'partial-succeeded' && theme === Theme.light && 'shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.5),inset_0_1px_3px_0_rgba(0,0,0,0.12),inset_0_2px_24px_0_rgba(23,178,106,0.2),0_1px_2px_0_rgba(9,9,11,0.05),0_0_0_1px_rgba(0,0,0,0.05)]',
|
||||
status === 'partial-succeeded' && theme === Theme.dark && 'shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.12),inset_0_1px_3px_0_rgba(0,0,0,0.4),inset_0_2px_24px_0_rgba(23,178,106,0.25),0_1px_2px_0_rgba(0,0,0,0.1),0_0_0_1px_rgba(24, 24, 27, 0.95)]',
|
||||
status === 'partial-succeeded' && theme === Theme.dark && 'shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.12),inset_0_1px_3px_0_rgba(0,0,0,0.4),inset_0_2px_24px_0_rgba(23,178,106,0.25),0_1px_2px_0_rgba(0,0,0,0.1),0_0_0_1px_rgba(24,24,27,0.95)]',
|
||||
status === 'failed' && 'border-[rgba(240,68,56,0.8)] bg-workflow-display-error-bg bg-[url(~@/app/components/workflow/run/assets/bg-line-error.svg)] text-text-warning',
|
||||
status === 'failed' && theme === Theme.light && 'shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.5),inset_0_1px_3px_0_rgba(0,0,0,0.12),inset_0_2px_24px_0_rgba(240,68,56,0.2),0_1px_2px_0_rgba(9,9,11,0.05),0_0_0_1px_rgba(0,0,0,0.05)]',
|
||||
status === 'failed' && theme === Theme.dark && 'shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.12),inset_0_1px_3px_0_rgba(0,0,0,0.4),inset_0_2px_24px_0_rgba(240,68,56,0.25),0_1px_2px_0_rgba(0,0,0,0.1),0_0_0_1px_rgba(24, 24, 27, 0.95)]',
|
||||
status === 'failed' && theme === Theme.dark && 'shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.12),inset_0_1px_3px_0_rgba(0,0,0,0.4),inset_0_2px_24px_0_rgba(240,68,56,0.25),0_1px_2px_0_rgba(0,0,0,0.1),0_0_0_1px_rgba(24,24,27,0.95)]',
|
||||
(status === 'stopped' || status === 'paused') && 'border-[rgba(247,144,9,0.8)] bg-workflow-display-warning-bg bg-[url(~@/app/components/workflow/run/assets/bg-line-warning.svg)] text-text-destructive',
|
||||
(status === 'stopped' || status === 'paused') && theme === Theme.light && 'shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.5),inset_0_1px_3px_0_rgba(0,0,0,0.12),inset_0_2px_24px_0_rgba(247,144,9,0.2),0_1px_2px_0_rgba(9,9,11,0.05),0_0_0_1px_rgba(0,0,0,0.05)]',
|
||||
(status === 'stopped' || status === 'paused') && theme === Theme.dark && 'shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.12),inset_0_1px_3px_0_rgba(0,0,0,0.4),inset_0_2px_24px_0_rgba(247,144,9,0.25),0_1px_2px_0_rgba(0,0,0,0.1),0_0_0_1px_rgba(24, 24, 27, 0.95)]',
|
||||
(status === 'stopped' || status === 'paused') && theme === Theme.dark && 'shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.12),inset_0_1px_3px_0_rgba(0,0,0,0.4),inset_0_2px_24px_0_rgba(247,144,9,0.25),0_1px_2px_0_rgba(0,0,0,0.1),0_0_0_1px_rgba(24,24,27,0.95)]',
|
||||
status === 'exception' && 'border-[rgba(247,144,9,0.8)] bg-workflow-display-warning-bg bg-[url(~@/app/components/workflow/run/assets/bg-line-warning.svg)] text-text-destructive',
|
||||
status === 'exception' && theme === Theme.light && 'shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.5),inset_0_1px_3px_0_rgba(0,0,0,0.12),inset_0_2px_24px_0_rgba(247,144,9,0.2),0_1px_2px_0_rgba(9,9,11,0.05),0_0_0_1px_rgba(0,0,0,0.05)]',
|
||||
status === 'exception' && theme === Theme.dark && 'shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.12),inset_0_1px_3px_0_rgba(0,0,0,0.4),inset_0_2px_24px_0_rgba(247,144,9,0.25),0_1px_2px_0_rgba(0,0,0,0.1),0_0_0_1px_rgba(24, 24, 27, 0.95)]',
|
||||
status === 'exception' && theme === Theme.dark && 'shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.12),inset_0_1px_3px_0_rgba(0,0,0,0.4),inset_0_2px_24px_0_rgba(247,144,9,0.25),0_1px_2px_0_rgba(0,0,0,0.1),0_0_0_1px_rgba(24,24,27,0.95)]',
|
||||
status === 'running' && 'border-[rgba(11,165,236,0.8)] bg-workflow-display-normal-bg bg-[url(~@/app/components/workflow/run/assets/bg-line-running.svg)] text-util-colors-blue-light-blue-light-600',
|
||||
status === 'running' && theme === Theme.light && 'shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.5),inset_0_1px_3px_0_rgba(0,0,0,0.12),inset_0_2px_24px_0_rgba(11,165,236,0.2),0_1px_2px_0_rgba(9,9,11,0.05),0_0_0_1px_rgba(0,0,0,0.05)]',
|
||||
status === 'running' && theme === Theme.dark && 'shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.12),inset_0_1px_3px_0_rgba(0,0,0,0.4),inset_0_2px_24px_0_rgba(11,165,236,0.25),0_1px_2px_0_rgba(0,0,0,0.1),0_0_0_1px_rgba(24, 24, 27, 0.95)]',
|
||||
status === 'running' && theme === Theme.dark && 'shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.12),inset_0_1px_3px_0_rgba(0,0,0,0.4),inset_0_2px_24px_0_rgba(11,165,236,0.25),0_1px_2px_0_rgba(0,0,0,0.1),0_0_0_1px_rgba(24,24,27,0.95)]',
|
||||
)}
|
||||
>
|
||||
<div className={cn(
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -25,11 +25,9 @@ export type AppContextValue = {
|
||||
isCurrentWorkspaceOwner: boolean
|
||||
isCurrentWorkspaceEditor: boolean
|
||||
isCurrentWorkspaceDatasetOperator: boolean
|
||||
mutateCurrentWorkspace: VoidFunction
|
||||
langGeniusVersionInfo: LangGeniusVersionResponse
|
||||
useSelector: typeof useSelector
|
||||
isLoadingCurrentWorkspace: boolean
|
||||
isValidatingCurrentWorkspace: boolean
|
||||
}
|
||||
|
||||
const userProfilePlaceholder = {
|
||||
@@ -72,11 +70,9 @@ const AppContext = createContext<AppContextValue>({
|
||||
isCurrentWorkspaceEditor: false,
|
||||
isCurrentWorkspaceDatasetOperator: false,
|
||||
mutateUserProfile: noop,
|
||||
mutateCurrentWorkspace: noop,
|
||||
langGeniusVersionInfo: initialLangGeniusVersionInfo,
|
||||
useSelector,
|
||||
isLoadingCurrentWorkspace: false,
|
||||
isValidatingCurrentWorkspace: false,
|
||||
})
|
||||
|
||||
export function useSelector<T>(selector: (value: AppContextValue) => T): T {
|
||||
@@ -91,7 +87,7 @@ export const AppContextProvider: FC<AppContextProviderProps> = ({ children }) =>
|
||||
const queryClient = useQueryClient()
|
||||
const systemFeatures = useGlobalPublicStore(s => s.systemFeatures)
|
||||
const { data: userProfileResp } = useUserProfile()
|
||||
const { data: currentWorkspaceResp, isPending: isLoadingCurrentWorkspace, isFetching: isValidatingCurrentWorkspace } = useCurrentWorkspace()
|
||||
const { data: currentWorkspaceResp, isPending: isLoadingCurrentWorkspace } = useCurrentWorkspace()
|
||||
const langGeniusVersionQuery = useLangGeniusVersion(
|
||||
userProfileResp?.meta.currentVersion,
|
||||
!systemFeatures.branding.enabled,
|
||||
@@ -123,10 +119,6 @@ export const AppContextProvider: FC<AppContextProviderProps> = ({ children }) =>
|
||||
queryClient.invalidateQueries({ queryKey: ['common', 'user-profile'] })
|
||||
}, [queryClient])
|
||||
|
||||
const mutateCurrentWorkspace = useCallback(() => {
|
||||
queryClient.invalidateQueries({ queryKey: ['common', 'current-workspace'] })
|
||||
}, [queryClient])
|
||||
|
||||
// #region Zendesk conversation fields
|
||||
useEffect(() => {
|
||||
if (ZENDESK_FIELD_IDS.ENVIRONMENT && langGeniusVersionInfo?.current_env) {
|
||||
@@ -198,9 +190,7 @@ export const AppContextProvider: FC<AppContextProviderProps> = ({ children }) =>
|
||||
isCurrentWorkspaceOwner,
|
||||
isCurrentWorkspaceEditor,
|
||||
isCurrentWorkspaceDatasetOperator,
|
||||
mutateCurrentWorkspace,
|
||||
isLoadingCurrentWorkspace,
|
||||
isValidatingCurrentWorkspace,
|
||||
}}
|
||||
>
|
||||
<div className="flex h-full flex-col overflow-y-auto">
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
// @ts-check
|
||||
import antfu from '@antfu/eslint-config'
|
||||
import antfu, { GLOB_TESTS, GLOB_TS, GLOB_TSX } from '@antfu/eslint-config'
|
||||
import pluginQuery from '@tanstack/eslint-plugin-query'
|
||||
import tailwindcss from 'eslint-plugin-better-tailwindcss'
|
||||
import sonar from 'eslint-plugin-sonarjs'
|
||||
@@ -67,7 +67,8 @@ export default antfu(
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['**/*.{ts,tsx}'],
|
||||
files: [GLOB_TS, GLOB_TSX],
|
||||
ignores: GLOB_TESTS,
|
||||
plugins: {
|
||||
tailwindcss,
|
||||
},
|
||||
|
||||
@@ -195,6 +195,7 @@
|
||||
"@types/js-yaml": "4.0.9",
|
||||
"@types/negotiator": "0.6.4",
|
||||
"@types/node": "18.15.0",
|
||||
"@types/postcss-js": "4.1.0",
|
||||
"@types/qs": "6.14.0",
|
||||
"@types/react": "19.2.9",
|
||||
"@types/react-dom": "19.2.3",
|
||||
@@ -225,6 +226,7 @@
|
||||
"lint-staged": "15.5.2",
|
||||
"nock": "14.0.10",
|
||||
"postcss": "8.5.6",
|
||||
"postcss-js": "5.0.3",
|
||||
"react-scan": "0.4.3",
|
||||
"sass": "1.93.2",
|
||||
"serwist": "9.5.4",
|
||||
|
||||
23
web/pnpm-lock.yaml
generated
23
web/pnpm-lock.yaml
generated
@@ -459,6 +459,9 @@ importers:
|
||||
'@types/node':
|
||||
specifier: 18.15.0
|
||||
version: 18.15.0
|
||||
'@types/postcss-js':
|
||||
specifier: 4.1.0
|
||||
version: 4.1.0
|
||||
'@types/qs':
|
||||
specifier: 6.14.0
|
||||
version: 6.14.0
|
||||
@@ -549,6 +552,9 @@ importers:
|
||||
postcss:
|
||||
specifier: 8.5.6
|
||||
version: 8.5.6
|
||||
postcss-js:
|
||||
specifier: 5.0.3
|
||||
version: 5.0.3(postcss@8.5.6)
|
||||
react-scan:
|
||||
specifier: 0.4.3
|
||||
version: 0.4.3(@types/react@19.2.9)(next@16.1.5(@babel/core@7.28.6)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.93.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(rollup@4.56.0)
|
||||
@@ -3189,6 +3195,9 @@ packages:
|
||||
'@types/papaparse@5.5.2':
|
||||
resolution: {integrity: sha512-gFnFp/JMzLHCwRf7tQHrNnfhN4eYBVYYI897CGX4MY1tzY9l2aLkVyx2IlKZ/SAqDbB3I1AOZW5gTMGGsqWliA==}
|
||||
|
||||
'@types/postcss-js@4.1.0':
|
||||
resolution: {integrity: sha512-E19kBYOk2uEhzxfbam6jALzE6J1GNdny2jdftwDHo72+oWWt7bkWSGzZYVfaRK1r/UToMhAcfbKCAauBXrxi7g==}
|
||||
|
||||
'@types/qs@6.14.0':
|
||||
resolution: {integrity: sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==}
|
||||
|
||||
@@ -6134,6 +6143,12 @@ packages:
|
||||
peerDependencies:
|
||||
postcss: ^8.4.21
|
||||
|
||||
postcss-js@5.0.3:
|
||||
resolution: {integrity: sha512-yqxfMZ2NKo8MH0xcj6Yb1sos9Vk2aNzVi0i6k0nWH0LaLQQ1lke9DGWDMa80+tzHk+tLzfKa3pepOFcPSM6Yow==}
|
||||
engines: {node: ^20 || ^22 || >= 24}
|
||||
peerDependencies:
|
||||
postcss: ^8.4.21
|
||||
|
||||
postcss-load-config@6.0.1:
|
||||
resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==}
|
||||
engines: {node: '>= 18'}
|
||||
@@ -10396,6 +10411,10 @@ snapshots:
|
||||
dependencies:
|
||||
'@types/node': 18.15.0
|
||||
|
||||
'@types/postcss-js@4.1.0':
|
||||
dependencies:
|
||||
postcss: 8.5.6
|
||||
|
||||
'@types/qs@6.14.0': {}
|
||||
|
||||
'@types/react-dom@19.2.3(@types/react@19.2.9)':
|
||||
@@ -14012,6 +14031,10 @@ snapshots:
|
||||
camelcase-css: 2.0.1
|
||||
postcss: 8.5.6
|
||||
|
||||
postcss-js@5.0.3(postcss@8.5.6):
|
||||
dependencies:
|
||||
postcss: 8.5.6
|
||||
|
||||
postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.6)(tsx@4.21.0)(yaml@2.8.2):
|
||||
dependencies:
|
||||
lilconfig: 3.1.3
|
||||
|
||||
@@ -318,6 +318,10 @@ export const useInvalidDataSourceIntegrates = () => {
|
||||
return useInvalid(commonQueryKeys.dataSourceIntegrates)
|
||||
}
|
||||
|
||||
export const useInvalidateCurrentWorkspace = () => {
|
||||
return useInvalid(commonQueryKeys.currentWorkspace)
|
||||
}
|
||||
|
||||
export const usePluginProviders = () => {
|
||||
return useQuery<PluginProvider[] | null>({
|
||||
queryKey: commonQueryKeys.pluginProviders,
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
import path from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import tailwindTypography from '@tailwindcss/typography'
|
||||
// @ts-expect-error workaround for turbopack issue
|
||||
import { cssAsPlugin } from './tailwind-css-plugin.ts'
|
||||
// @ts-expect-error workaround for turbopack issue
|
||||
import tailwindThemeVarDefine from './themes/tailwind-theme-var-define.ts'
|
||||
import typography from './typography.js'
|
||||
|
||||
const _dirname = typeof __dirname !== 'undefined'
|
||||
? __dirname
|
||||
: path.dirname(fileURLToPath(import.meta.url))
|
||||
|
||||
const config = {
|
||||
theme: {
|
||||
typography,
|
||||
@@ -148,7 +156,12 @@ const config = {
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [tailwindTypography],
|
||||
plugins: [
|
||||
tailwindTypography,
|
||||
cssAsPlugin([
|
||||
path.resolve(_dirname, './app/styles/globals.css'),
|
||||
]),
|
||||
],
|
||||
// https://github.com/tailwindlabs/tailwindcss/discussions/5969
|
||||
corePlugins: {
|
||||
preflight: false,
|
||||
|
||||
25
web/tailwind-css-plugin.ts
Normal file
25
web/tailwind-css-plugin.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
// Credits:
|
||||
// https://github.com/tailwindlabs/tailwindcss-intellisense/issues/227
|
||||
|
||||
import type { PluginCreator } from 'tailwindcss/types/config'
|
||||
import { readFileSync } from 'node:fs'
|
||||
import { parse } from 'postcss'
|
||||
import { objectify } from 'postcss-js'
|
||||
|
||||
export const cssAsPlugin: (cssPath: string[]) => PluginCreator = (cssPath: string[]) => {
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
return () => {}
|
||||
}
|
||||
return ({ addUtilities, addComponents, addBase }) => {
|
||||
const jssList = cssPath.map(p => objectify(parse(readFileSync(p, 'utf8'))))
|
||||
|
||||
for (const jss of jssList) {
|
||||
if (jss['@layer utilities'])
|
||||
addUtilities(jss['@layer utilities'])
|
||||
if (jss['@layer components'])
|
||||
addComponents(jss['@layer components'])
|
||||
if (jss['@layer base'])
|
||||
addBase(jss['@layer base'])
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user