From 525bde28f6ab2faa2f27578042c06868eaf00b09 Mon Sep 17 00:00:00 2001 From: NFish Date: Fri, 3 Jan 2025 16:18:24 +0800 Subject: [PATCH 01/28] fix: adjust cloud service --- .../icons/assets/public/billing/ar-cube-1.svg | 3 + .../icons/assets/public/billing/group-2.svg | 3 + .../icons/assets/public/billing/keyframe.svg | 3 + .../assets/public/billing/sparkles-soft.svg | 4 + .../icons/src/public/billing/ArCube1.json | 29 ++ .../base/icons/src/public/billing/ArCube1.tsx | 16 + .../base/icons/src/public/billing/Group2.json | 29 ++ .../base/icons/src/public/billing/Group2.tsx | 16 + .../icons/src/public/billing/Keyframe.json | 28 ++ .../icons/src/public/billing/Keyframe.tsx | 16 + .../src/public/billing/SparklesSoft.json | 36 ++ .../icons/src/public/billing/SparklesSoft.tsx | 16 + .../base/icons/src/public/billing/index.ts | 4 + .../icons/src/public/knowledge/Chunk.json | 18 +- .../icons/src/public/knowledge/Collapse.json | 6 +- .../public/knowledge/LayoutRight2LineMod.json | 2 +- web/app/components/base/tab-slider/index.tsx | 22 +- web/app/components/billing/config.ts | 64 ++-- web/app/components/billing/pricing/index.tsx | 123 +++--- .../components/billing/pricing/plan-item.tsx | 351 +++++++++--------- .../billing/pricing/select-plan-range.tsx | 37 +- web/app/components/billing/type.ts | 12 +- web/i18n/en-US/billing.ts | 52 +-- web/tailwind.config.js | 3 + web/themes/manual-dark.css | 61 ++- web/themes/manual-light.css | 61 ++- 26 files changed, 634 insertions(+), 381 deletions(-) create mode 100644 web/app/components/base/icons/assets/public/billing/ar-cube-1.svg create mode 100644 web/app/components/base/icons/assets/public/billing/group-2.svg create mode 100644 web/app/components/base/icons/assets/public/billing/keyframe.svg create mode 100644 web/app/components/base/icons/assets/public/billing/sparkles-soft.svg create mode 100644 web/app/components/base/icons/src/public/billing/ArCube1.json create mode 100644 web/app/components/base/icons/src/public/billing/ArCube1.tsx create mode 100644 web/app/components/base/icons/src/public/billing/Group2.json create mode 100644 web/app/components/base/icons/src/public/billing/Group2.tsx create mode 100644 web/app/components/base/icons/src/public/billing/Keyframe.json create mode 100644 web/app/components/base/icons/src/public/billing/Keyframe.tsx create mode 100644 web/app/components/base/icons/src/public/billing/SparklesSoft.json create mode 100644 web/app/components/base/icons/src/public/billing/SparklesSoft.tsx diff --git a/web/app/components/base/icons/assets/public/billing/ar-cube-1.svg b/web/app/components/base/icons/assets/public/billing/ar-cube-1.svg new file mode 100644 index 0000000000..2022ecd6e8 --- /dev/null +++ b/web/app/components/base/icons/assets/public/billing/ar-cube-1.svg @@ -0,0 +1,3 @@ + + + diff --git a/web/app/components/base/icons/assets/public/billing/group-2.svg b/web/app/components/base/icons/assets/public/billing/group-2.svg new file mode 100644 index 0000000000..22970f8f54 --- /dev/null +++ b/web/app/components/base/icons/assets/public/billing/group-2.svg @@ -0,0 +1,3 @@ + + + diff --git a/web/app/components/base/icons/assets/public/billing/keyframe.svg b/web/app/components/base/icons/assets/public/billing/keyframe.svg new file mode 100644 index 0000000000..2690394ca5 --- /dev/null +++ b/web/app/components/base/icons/assets/public/billing/keyframe.svg @@ -0,0 +1,3 @@ + + + diff --git a/web/app/components/base/icons/assets/public/billing/sparkles-soft.svg b/web/app/components/base/icons/assets/public/billing/sparkles-soft.svg new file mode 100644 index 0000000000..7a24c14e2a --- /dev/null +++ b/web/app/components/base/icons/assets/public/billing/sparkles-soft.svg @@ -0,0 +1,4 @@ + + + + diff --git a/web/app/components/base/icons/src/public/billing/ArCube1.json b/web/app/components/base/icons/src/public/billing/ArCube1.json new file mode 100644 index 0000000000..f341c9218f --- /dev/null +++ b/web/app/components/base/icons/src/public/billing/ArCube1.json @@ -0,0 +1,29 @@ +{ + "icon": { + "type": "element", + "isRootNode": true, + "name": "svg", + "attributes": { + "width": "28", + "height": "28", + "viewBox": "0 0 28 28", + "fill": "none", + "xmlns": "http://www.w3.org/2000/svg" + }, + "children": [ + { + "type": "element", + "name": "path", + "attributes": { + "d": "M14.0002 14V23.9166M14.0002 14L5.25 9.07806M14.0002 14L22.4731 9.2338M23.625 9.95052V18.0493C23.625 18.8924 23.1703 19.6697 22.4356 20.0831L15.1439 24.1846C14.4336 24.5842 13.5663 24.5842 12.8561 24.1846L5.56439 20.0831C4.82967 19.6697 4.375 18.8924 4.375 18.0493V9.95052C4.375 9.10756 4.82967 8.33012 5.56439 7.91684L12.8561 3.81529C13.5663 3.41574 14.4336 3.41574 15.1439 3.81529L22.4356 7.91684C23.1703 8.33012 23.625 9.10756 23.625 9.95052Z", + "stroke": "#101828", + "stroke-width": "1.5", + "stroke-linecap": "round", + "stroke-linejoin": "round" + }, + "children": [] + } + ] + }, + "name": "ArCube1" +} \ No newline at end of file diff --git a/web/app/components/base/icons/src/public/billing/ArCube1.tsx b/web/app/components/base/icons/src/public/billing/ArCube1.tsx new file mode 100644 index 0000000000..5164eacae5 --- /dev/null +++ b/web/app/components/base/icons/src/public/billing/ArCube1.tsx @@ -0,0 +1,16 @@ +// GENERATE BY script +// DON NOT EDIT IT MANUALLY + +import * as React from 'react' +import data from './ArCube1.json' +import IconBase from '@/app/components/base/icons/IconBase' +import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase' + +const Icon = React.forwardRef, Omit>(( + props, + ref, +) => ) + +Icon.displayName = 'ArCube1' + +export default Icon diff --git a/web/app/components/base/icons/src/public/billing/Group2.json b/web/app/components/base/icons/src/public/billing/Group2.json new file mode 100644 index 0000000000..b2424ba881 --- /dev/null +++ b/web/app/components/base/icons/src/public/billing/Group2.json @@ -0,0 +1,29 @@ +{ + "icon": { + "type": "element", + "isRootNode": true, + "name": "svg", + "attributes": { + "width": "29", + "height": "28", + "viewBox": "0 0 29 28", + "fill": "none", + "xmlns": "http://www.w3.org/2000/svg" + }, + "children": [ + { + "type": "element", + "name": "path", + "attributes": { + "d": "M17.4942 15.3771C21.1508 13.8584 25.694 15.7846 27.1017 21.1559C27.4448 22.465 26.348 23.625 24.9948 23.625H19.6233M13.2066 8.16667C13.2066 10.2608 11.509 11.9583 9.41493 11.9583C7.32086 11.9583 5.62326 10.2608 5.62326 8.16667C5.62326 6.07258 7.32086 4.375 9.41493 4.375C11.509 4.375 13.2066 6.07258 13.2066 8.16667ZM23.7066 8.16667C23.7066 10.2608 22.009 11.9583 19.9149 11.9583C17.8209 11.9583 16.1232 10.2608 16.1232 8.16667C16.1232 6.07258 17.8209 4.375 19.9149 4.375C22.009 4.375 23.7066 6.07258 23.7066 8.16667ZM14.328 23.625H4.3352C2.98193 23.625 1.88599 22.4589 2.22976 21.15C4.42721 12.7833 14.2359 12.7833 16.4335 21.15C16.7772 22.4589 15.6813 23.625 14.328 23.625Z", + "stroke": "#444CE7", + "stroke-width": "1.5", + "stroke-linecap": "round", + "stroke-linejoin": "round" + }, + "children": [] + } + ] + }, + "name": "Group2" +} \ No newline at end of file diff --git a/web/app/components/base/icons/src/public/billing/Group2.tsx b/web/app/components/base/icons/src/public/billing/Group2.tsx new file mode 100644 index 0000000000..f516ddafdd --- /dev/null +++ b/web/app/components/base/icons/src/public/billing/Group2.tsx @@ -0,0 +1,16 @@ +// GENERATE BY script +// DON NOT EDIT IT MANUALLY + +import * as React from 'react' +import data from './Group2.json' +import IconBase from '@/app/components/base/icons/IconBase' +import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase' + +const Icon = React.forwardRef, Omit>(( + props, + ref, +) => ) + +Icon.displayName = 'Group2' + +export default Icon diff --git a/web/app/components/base/icons/src/public/billing/Keyframe.json b/web/app/components/base/icons/src/public/billing/Keyframe.json new file mode 100644 index 0000000000..c721854d14 --- /dev/null +++ b/web/app/components/base/icons/src/public/billing/Keyframe.json @@ -0,0 +1,28 @@ +{ + "icon": { + "type": "element", + "isRootNode": true, + "name": "svg", + "attributes": { + "width": "29", + "height": "28", + "viewBox": "0 0 29 28", + "fill": "none", + "xmlns": "http://www.w3.org/2000/svg" + }, + "children": [ + { + "type": "element", + "name": "path", + "attributes": { + "d": "M15.9831 3.98321C15.072 3.072 13.5945 3.072 12.6833 3.98321L4.31648 12.35C3.40526 13.2612 3.40524 14.7386 4.31647 15.6499L12.6833 24.0167C13.5945 24.9279 15.072 24.9279 15.9831 24.0167L24.35 15.6499C25.2612 14.7386 25.2612 13.2612 24.35 12.35L15.9831 3.98321Z", + "stroke": "#155AEF", + "stroke-width": "1.5", + "stroke-linejoin": "round" + }, + "children": [] + } + ] + }, + "name": "Keyframe" +} \ No newline at end of file diff --git a/web/app/components/base/icons/src/public/billing/Keyframe.tsx b/web/app/components/base/icons/src/public/billing/Keyframe.tsx new file mode 100644 index 0000000000..075e8d83f4 --- /dev/null +++ b/web/app/components/base/icons/src/public/billing/Keyframe.tsx @@ -0,0 +1,16 @@ +// GENERATE BY script +// DON NOT EDIT IT MANUALLY + +import * as React from 'react' +import data from './Keyframe.json' +import IconBase from '@/app/components/base/icons/IconBase' +import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase' + +const Icon = React.forwardRef, Omit>(( + props, + ref, +) => ) + +Icon.displayName = 'Keyframe' + +export default Icon diff --git a/web/app/components/base/icons/src/public/billing/SparklesSoft.json b/web/app/components/base/icons/src/public/billing/SparklesSoft.json new file mode 100644 index 0000000000..ce4f11f489 --- /dev/null +++ b/web/app/components/base/icons/src/public/billing/SparklesSoft.json @@ -0,0 +1,36 @@ +{ + "icon": { + "type": "element", + "isRootNode": true, + "name": "svg", + "attributes": { + "width": "13", + "height": "13", + "viewBox": "0 0 13 13", + "fill": "none", + "xmlns": "http://www.w3.org/2000/svg" + }, + "children": [ + { + "type": "element", + "name": "path", + "attributes": { + "opacity": "0.5", + "d": "M9.75878 1.67256C9.74813 1.57435 9.6684 1.5001 9.5735 1.5C9.47861 1.4999 9.39874 1.57397 9.38789 1.67217C9.33725 2.12931 9.20693 2.44292 9.00273 2.65564C8.79849 2.86835 8.49744 3.00411 8.05857 3.05683C7.9643 3.06816 7.89321 3.15136 7.89331 3.2502C7.89341 3.34905 7.96469 3.43208 8.05896 3.44321C8.49038 3.49411 8.79835 3.62984 9.00773 3.84402C9.216 4.05703 9.34877 4.3702 9.38736 4.82276C9.39595 4.92317 9.47673 5.00011 9.5735 5C9.67027 4.99988 9.75096 4.92276 9.75926 4.82232C9.79627 4.37742 9.92894 4.05719 10.1386 3.83882C10.3482 3.62045 10.6556 3.48223 11.0827 3.44372C11.1792 3.43503 11.2532 3.35103 11.2533 3.25022C11.2534 3.14942 11.1795 3.06524 11.0832 3.05632C10.6487 3.01612 10.3481 2.87779 10.1436 2.66085C9.93797 2.44273 9.80765 2.12197 9.75878 1.67256Z", + "fill": "#FCFCFD" + }, + "children": [] + }, + { + "type": "element", + "name": "path", + "attributes": { + "d": "M6.45025 2.94373C6.42279 2.69117 6.21783 2.50026 5.9738 2.5C5.72982 2.49974 5.52443 2.69021 5.49649 2.94271C5.36631 4.11822 5.0312 4.92465 4.50609 5.47164C3.98098 6.0186 3.20681 6.3677 2.07832 6.5033C1.83592 6.5324 1.65307 6.74635 1.65332 7.0005C1.65357 7.2547 1.83684 7.4682 2.0793 7.4968C3.1887 7.6277 3.9805 7.97675 4.51896 8.5275C5.05449 9.07525 5.39598 9.8805 5.49519 11.0442C5.51722 11.3024 5.72502 11.5003 5.97385 11.5C6.22273 11.4997 6.43009 11.3014 6.45154 11.0431C6.54658 9.89905 6.88782 9.07565 7.42686 8.5141C7.96595 7.9526 8.75641 7.59715 9.8547 7.49815C10.1026 7.4758 10.293 7.2598 10.2933 7.00055C10.2936 6.74135 10.1037 6.5249 9.8558 6.50195C8.7386 6.3986 7.96556 6.0429 7.43972 5.48504C6.911 4.92415 6.57591 4.09936 6.45025 2.94373Z", + "fill": "#FCFCFD" + }, + "children": [] + } + ] + }, + "name": "SparklesSoft" +} \ No newline at end of file diff --git a/web/app/components/base/icons/src/public/billing/SparklesSoft.tsx b/web/app/components/base/icons/src/public/billing/SparklesSoft.tsx new file mode 100644 index 0000000000..dd422c400f --- /dev/null +++ b/web/app/components/base/icons/src/public/billing/SparklesSoft.tsx @@ -0,0 +1,16 @@ +// GENERATE BY script +// DON NOT EDIT IT MANUALLY + +import * as React from 'react' +import data from './SparklesSoft.json' +import IconBase from '@/app/components/base/icons/IconBase' +import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase' + +const Icon = React.forwardRef, Omit>(( + props, + ref, +) => ) + +Icon.displayName = 'SparklesSoft' + +export default Icon diff --git a/web/app/components/base/icons/src/public/billing/index.ts b/web/app/components/base/icons/src/public/billing/index.ts index d74cc5b961..8a442a32c2 100644 --- a/web/app/components/base/icons/src/public/billing/index.ts +++ b/web/app/components/base/icons/src/public/billing/index.ts @@ -1 +1,5 @@ +export { default as ArCube1 } from './ArCube1' +export { default as Group2 } from './Group2' +export { default as Keyframe } from './Keyframe' +export { default as SparklesSoft } from './SparklesSoft' export { default as Sparkles } from './Sparkles' diff --git a/web/app/components/base/icons/src/public/knowledge/Chunk.json b/web/app/components/base/icons/src/public/knowledge/Chunk.json index 7bd5668810..469d85d1a7 100644 --- a/web/app/components/base/icons/src/public/knowledge/Chunk.json +++ b/web/app/components/base/icons/src/public/knowledge/Chunk.json @@ -24,7 +24,7 @@ "attributes": { "id": "Vector", "d": "M2.5 10H0V7.5H2.5V10Z", - "fill": "currentColor" + "fill": "#676F83" }, "children": [] }, @@ -34,7 +34,7 @@ "attributes": { "id": "Vector_2", "d": "M6.25 6.25H3.75V3.75H6.25V6.25Z", - "fill": "currentColor" + "fill": "#676F83" }, "children": [] }, @@ -44,7 +44,7 @@ "attributes": { "id": "Vector_3", "d": "M2.5 6.25H0V3.75H2.5V6.25Z", - "fill": "currentColor" + "fill": "#676F83" }, "children": [] }, @@ -54,7 +54,7 @@ "attributes": { "id": "Vector_4", "d": "M6.25 2.5H3.75V0H6.25V2.5Z", - "fill": "currentColor" + "fill": "#676F83" }, "children": [] }, @@ -64,7 +64,7 @@ "attributes": { "id": "Vector_5", "d": "M2.5 2.5H0V0H2.5V2.5Z", - "fill": "currentColor" + "fill": "#676F83" }, "children": [] }, @@ -74,7 +74,7 @@ "attributes": { "id": "Vector_6", "d": "M10 2.5H7.5V0H10V2.5Z", - "fill": "currentColor" + "fill": "#676F83" }, "children": [] }, @@ -84,7 +84,7 @@ "attributes": { "id": "Vector_7", "d": "M9.58342 7.91663H7.91675V9.58329H9.58342V7.91663Z", - "fill": "currentColor" + "fill": "#676F83" }, "children": [] }, @@ -94,7 +94,7 @@ "attributes": { "id": "Vector_8", "d": "M9.58342 4.16663H7.91675V5.83329H9.58342V4.16663Z", - "fill": "currentColor" + "fill": "#676F83" }, "children": [] }, @@ -104,7 +104,7 @@ "attributes": { "id": "Vector_9", "d": "M5.83341 7.91663H4.16675V9.58329H5.83341V7.91663Z", - "fill": "currentColor" + "fill": "#676F83" }, "children": [] } diff --git a/web/app/components/base/icons/src/public/knowledge/Collapse.json b/web/app/components/base/icons/src/public/knowledge/Collapse.json index 5e3cf08ce0..66d457155d 100644 --- a/web/app/components/base/icons/src/public/knowledge/Collapse.json +++ b/web/app/components/base/icons/src/public/knowledge/Collapse.json @@ -30,7 +30,7 @@ "name": "path", "attributes": { "d": "M2.66602 11.3333H0.666016L3.33268 8.66667L5.99935 11.3333H3.99935L3.99935 14H2.66602L2.66602 11.3333Z", - "fill": "currentColor" + "fill": "#354052" }, "children": [] }, @@ -39,7 +39,7 @@ "name": "path", "attributes": { "d": "M2.66602 4.66667L2.66602 2L3.99935 2L3.99935 4.66667L5.99935 4.66667L3.33268 7.33333L0.666016 4.66667L2.66602 4.66667Z", - "fill": "currentColor" + "fill": "#354052" }, "children": [] }, @@ -48,7 +48,7 @@ "name": "path", "attributes": { "d": "M7.33268 2.66667H13.9993V4H7.33268V2.66667ZM7.33268 12H13.9993V13.3333H7.33268V12ZM5.99935 7.33333H13.9993V8.66667H5.99935V7.33333Z", - "fill": "currentColor" + "fill": "#354052" }, "children": [] } diff --git a/web/app/components/base/icons/src/public/knowledge/LayoutRight2LineMod.json b/web/app/components/base/icons/src/public/knowledge/LayoutRight2LineMod.json index 6f5b00eb54..26c5cf1d4f 100644 --- a/web/app/components/base/icons/src/public/knowledge/LayoutRight2LineMod.json +++ b/web/app/components/base/icons/src/public/knowledge/LayoutRight2LineMod.json @@ -24,7 +24,7 @@ "attributes": { "id": "Vector", "d": "M14.0002 2C14.3684 2 14.6668 2.29848 14.6668 2.66667V13.3333C14.6668 13.7015 14.3684 14 14.0002 14H2.00016C1.63198 14 1.3335 13.7015 1.3335 13.3333V2.66667C1.3335 2.29848 1.63198 2 2.00016 2H14.0002ZM13.3335 3.33333H2.66683V12.6667H13.3335V3.33333ZM14.0002 2.66667V13.3333H10.0002V2.66667H14.0002Z", - "fill": "currentColor" + "fill": "#354052" }, "children": [] } diff --git a/web/app/components/base/tab-slider/index.tsx b/web/app/components/base/tab-slider/index.tsx index 03296a9dee..0ee0a54eee 100644 --- a/web/app/components/base/tab-slider/index.tsx +++ b/web/app/components/base/tab-slider/index.tsx @@ -1,9 +1,9 @@ -import type { FC } from 'react' +import type { FC, ReactNode } from 'react' import cn from '@/utils/classnames' type Option = { value: string - text: string + text: ReactNode } type TabSliderProps = { className?: string @@ -23,17 +23,12 @@ const TabSlider: FC = ({ const current = options[currentIndex] return ( -
+
{ - options.map((option, index) => ( + options.map(option => (
= ({ current && (
{current.text} diff --git a/web/app/components/billing/config.ts b/web/app/components/billing/config.ts index feb1f41fe3..74afcc09fc 100644 --- a/web/app/components/billing/config.ts +++ b/web/app/components/billing/config.ts @@ -1,6 +1,6 @@ import { Plan, type PlanInfo, Priority } from '@/app/components/billing/type' -const supportModelProviders = 'OpenAI/Anthropic/Azure OpenAI/ Llama2/Hugging Face/Replicate' +const supportModelProviders = 'OpenAI/Anthropic/Llama2/Azure OpenAI/Hugging Face/Replicate' export const NUM_INFINITE = 99999999 export const contractSales = 'contractSales' @@ -13,52 +13,46 @@ export const ALL_PLANS: Record = { level: 1, price: 0, modelProviders: supportModelProviders, + teamWorkspace: 1, teamMembers: 1, - buildApps: 10, - vectorSpace: 5, - documentsUploadQuota: 50, + buildApps: 5, + documents: 50, + vectorSpace: '50MB', + documentsRequestQuota: 10, documentProcessingPriority: Priority.standard, - logHistory: 30, - customTools: unAvailable, - messageRequest: { - en: '200 messages', - zh: '200 条信息', - }, + messageRequest: 200, annotatedResponse: 10, + logHistory: 15, }, professional: { level: 2, price: 59, modelProviders: supportModelProviders, + teamWorkspace: 1, teamMembers: 3, buildApps: 50, - vectorSpace: 200, - documentsUploadQuota: 500, + documents: 500, + vectorSpace: '5GB', + documentsRequestQuota: 10, documentProcessingPriority: Priority.priority, - logHistory: NUM_INFINITE, - customTools: 10, - messageRequest: { - en: '5,000 messages/month', - zh: '5,000 条信息/月', - }, + messageRequest: 5000, annotatedResponse: 2000, + logHistory: NUM_INFINITE, }, team: { level: 3, price: 159, modelProviders: supportModelProviders, - teamMembers: NUM_INFINITE, - buildApps: NUM_INFINITE, - vectorSpace: 1000, - documentsUploadQuota: 1000, + teamWorkspace: 1, + teamMembers: 5, + buildApps: 200, + documents: 1000, + vectorSpace: '20GB', + documentsRequestQuota: 2000, documentProcessingPriority: Priority.topPriority, - logHistory: NUM_INFINITE, - customTools: NUM_INFINITE, - messageRequest: { - en: '10,000 messages/month', - zh: '10,000 条信息/月', - }, + messageRequest: 10000, annotatedResponse: 5000, + logHistory: NUM_INFINITE, }, enterprise: { level: 4, @@ -66,15 +60,13 @@ export const ALL_PLANS: Record = { modelProviders: supportModelProviders, teamMembers: NUM_INFINITE, buildApps: NUM_INFINITE, + documents: 50, vectorSpace: NUM_INFINITE, - documentsUploadQuota: NUM_INFINITE, + documentsRequestQuota: 5000, documentProcessingPriority: Priority.topPriority, logHistory: NUM_INFINITE, customTools: NUM_INFINITE, - messageRequest: { - en: contractSales, - zh: contractSales, - }, + messageRequest: contractSales, annotatedResponse: NUM_INFINITE, }, } @@ -82,17 +74,19 @@ export const ALL_PLANS: Record = { export const defaultPlan = { type: Plan.sandbox, usage: { + documents: 50, vectorSpace: 1, buildApps: 1, teamMembers: 1, annotatedResponse: 1, - documentsUploadQuota: 1, + documentsRequestQuota: 1, }, total: { + documents: 50, vectorSpace: 10, buildApps: 10, teamMembers: 1, annotatedResponse: 10, - documentsUploadQuota: 50, + documentsRequestQuota: 50, }, } diff --git a/web/app/components/billing/pricing/index.tsx b/web/app/components/billing/pricing/index.tsx index 9b5e5e7453..98f7008069 100644 --- a/web/app/components/billing/pricing/index.tsx +++ b/web/app/components/billing/pricing/index.tsx @@ -3,8 +3,10 @@ import type { FC } from 'react' import React from 'react' import { createPortal } from 'react-dom' import { useTranslation } from 'react-i18next' -import { RiCloseLine } from '@remixicon/react' +import { RiArrowRightUpLine, RiCloseLine, RiCloudFill, RiTerminalBoxFill } from '@remixicon/react' +import Link from 'next/link' import { Plan } from '../type' +import TabSlider from '../../base/tab-slider' import SelectPlanRange, { PlanRange } from './select-plan-range' import PlanItem from './plan-item' import { useProviderContext } from '@/context/provider-context' @@ -24,56 +26,89 @@ const Pricing: FC = ({ const canPay = isCurrentWorkspaceManager const [planRange, setPlanRange] = React.useState(PlanRange.monthly) + const [currentPlan, setCurrentPlan] = React.useState('cloud') + return createPortal(
e.stopPropagation()} > - -
-
- {t('billing.plansCommon.title')} -
- -
- - - - -
+
+
+
- + +
+
+ {t('billing.plansCommon.title')} +
+
+ {t('billing.plansCommon.freeTrialTipPrefix')} + {t('billing.plansCommon.freeTrialTip')} + {t('billing.plansCommon.freeTrialTipSuffix')} +
+
+
+
+ cloud service
}, + { value: 'self', text:
self hosted
}]} + onChange={v => setCurrentPlan(v)} /> -
- + +
+
+
+ {currentPlan === 'cloud' && <> + + + + } + {currentPlan === 'self' && <> + + } +
+
+
+
+
+ Compare plans & features + +
+
+
-
, +
, document.body, ) } diff --git a/web/app/components/billing/pricing/plan-item.tsx b/web/app/components/billing/pricing/plan-item.tsx index b6ac17472e..24f588d94a 100644 --- a/web/app/components/billing/pricing/plan-item.tsx +++ b/web/app/components/billing/pricing/plan-item.tsx @@ -1,18 +1,18 @@ 'use client' -import type { FC } from 'react' +import type { FC, ReactNode } from 'react' import React from 'react' import { useTranslation } from 'react-i18next' -import { useContext } from 'use-context-selector' +import { RiApps2Line, RiBook2Line, RiBrain2Line, RiChatAiLine, RiFileEditLine, RiFolder6Line, RiGroupLine, RiHardDrive3Line, RiHistoryLine, RiProgress3Line, RiQuestionLine, RiSeoLine } from '@remixicon/react' import { Plan } from '../type' -import { ALL_PLANS, NUM_INFINITE, contactSalesUrl, contractSales, unAvailable } from '../config' +import { ALL_PLANS, NUM_INFINITE, contactSalesUrl } from '../config' import Toast from '../../base/toast' import Tooltip from '../../base/tooltip' +import Divider from '../../base/divider' +import { ArCube1, Group2, Keyframe, SparklesSoft } from '../../base/icons/src/public/billing' import { PlanRange } from './select-plan-range' import cn from '@/utils/classnames' import { useAppContext } from '@/context/app-context' import { fetchSubscriptionUrls } from '@/service/billing' -import { LanguagesSupported } from '@/i18n/language' -import I18n from '@/context/i18n' type Props = { currentPlan: Plan @@ -21,45 +21,49 @@ type Props = { canPay: boolean } -const KeyValue = ({ label, value, tooltip }: { label: string; value: string | number | JSX.Element; tooltip?: string }) => { +const KeyValue = ({ icon, label, tooltip }: { icon: ReactNode; label: string; tooltip?: string }) => { return ( -
-
-
{label}
- {tooltip && ( - {tooltip}
- } - /> - )} +
+
+ {icon}
-
{value}
+
{label}
+ {tooltip && ( + +
+ +
+
+ )}
) } -const priceClassName = 'leading-[32px] text-[28px] font-bold text-gray-900' +const priceClassName = 'leading-[125%] text-[28px] font-bold text-text-primary' const style = { [Plan.sandbox]: { - bg: 'bg-[#F2F4F7]', - title: 'text-gray-900', - hoverAndActive: '', + icon: , + description: 'text-util-colors-gray-gray-600', + btnStyle: 'bg-components-button-secondary-bg hover:bg-components-button-secondary-bg-hover border-[0.5px] border-components-button-secondary-border text-text-primary', }, [Plan.professional]: { - bg: 'bg-[#E0F2FE]', - title: 'text-[#026AA2]', - hoverAndActive: 'hover:shadow-lg hover:!text-white hover:!bg-[#0086C9] hover:!border-[#026AA2] active:!text-white active:!bg-[#026AA2] active:!border-[#026AA2]', + icon: , + description: 'text-util-colors-blue-brand-blue-brand-600', + btnStyle: 'bg-components-button-primary-bg hover:bg-components-button-primary-bg-hover border border-component-button-primary-border text-components-button-primary-text', }, [Plan.team]: { - bg: 'bg-[#E0EAFF]', - title: 'text-[#3538CD]', - hoverAndActive: 'hover:shadow-lg hover:!text-white hover:!bg-[#444CE7] hover:!border-[#3538CD] active:!text-white active:!bg-[#3538CD] active:!border-[#3538CD]', + icon: , + description: 'text-util-colors-indigo-indigo-600', + btnStyle: 'bg-components-button-indigo-bg hover:bg-components-button-indigo-bg-hover border border-components-button-primary-border text-components-button-primary-text', }, [Plan.enterprise]: { - bg: 'bg-[#FFEED3]', - title: 'text-[#DC6803]', - hoverAndActive: 'hover:shadow-lg hover:!text-white hover:!bg-[#F79009] hover:!border-[#DC6803] active:!text-white active:!bg-[#DC6803] active:!border-[#DC6803]', + icon: 'text-[#DC6803]', + description: '', + btnStyle: 'hover:shadow-lg hover:!text-white hover:!bg-[#F79009] hover:!border-[#DC6803] active:!text-white active:!bg-[#DC6803] active:!border-[#DC6803]', }, } const PlanItem: FC = ({ @@ -69,9 +73,9 @@ const PlanItem: FC = ({ canPay, }) => { const { t } = useTranslation() - const { locale } = useContext(I18n) + // const { locale } = useContext(I18n) - const isZh = locale === LanguagesSupported[1] + // const isZh = locale === LanguagesSupported[1] const [loading, setLoading] = React.useState(false) const i18nPrefix = `billing.plans.${plan}` const isFreePlan = plan === Plan.sandbox @@ -82,13 +86,13 @@ const PlanItem: FC = ({ const isCurrent = plan === currentPlan const isPlanDisabled = planInfo.level <= ALL_PLANS[currentPlan].level || (!canPay && plan !== Plan.enterprise) const { isCurrentWorkspaceManager } = useAppContext() - const messagesRequest = (() => { - const value = planInfo.messageRequest[isZh ? 'zh' : 'en'] - if (value === contractSales) - return t('billing.plansCommon.contractSales') + // const messagesRequest = (() => { + // const value = planInfo.messageRequest[isZh ? 'zh' : 'en'] + // if (value === contractSales) + // return t('billing.plansCommon.contractSales') - return value - })() + // return value + // })() const btnText = (() => { if (!canPay && plan !== Plan.enterprise) return t('billing.plansCommon.contractOwner') @@ -98,85 +102,85 @@ const PlanItem: FC = ({ return ({ [Plan.sandbox]: t('billing.plansCommon.startForFree'), - [Plan.professional]: <>{t('billing.plansCommon.getStartedWith')} {plan}, - [Plan.team]: <>{t('billing.plansCommon.getStartedWith')} {plan}, + [Plan.professional]: t('billing.plansCommon.getStarted'), + [Plan.team]: t('billing.plansCommon.getStarted'), [Plan.enterprise]: t('billing.plansCommon.talkToSales'), })[plan] })() - const comingSoon = ( -
{t('billing.plansCommon.comingSoon')}
- ) - const supportContent = (() => { - switch (plan) { - case Plan.sandbox: - return (
-
{t('billing.plansCommon.supportItems.communityForums')}
-
{t('billing.plansCommon.supportItems.agentMode')}
-
-
-
 {t('billing.plansCommon.supportItems.workflow')}
-
-
-
) - case Plan.professional: - return ( -
-
{t('billing.plansCommon.supportItems.emailSupport')}
-
-
+ {t('billing.plansCommon.supportItems.logoChange')}
-
-
-
+ {t('billing.plansCommon.supportItems.bulkUpload')}
-
-
- + -
{t('billing.plansCommon.supportItems.llmLoadingBalancing')}
- {t('billing.plansCommon.supportItems.llmLoadingBalancingTooltip')}
- } - /> -
-
-
- + -
 {t('billing.plansCommon.supportItems.ragAPIRequest')}
- {t('billing.plansCommon.ragAPIRequestTooltip')}
- } - /> -
-
{comingSoon}
-
-
- ) - case Plan.team: - return ( -
-
{t('billing.plansCommon.supportItems.priorityEmail')}
-
-
+ {t('billing.plansCommon.supportItems.SSOAuthentication')}
-
{comingSoon}
-
-
- ) - case Plan.enterprise: - return ( -
-
{t('billing.plansCommon.supportItems.personalizedSupport')}
-
-
+ {t('billing.plansCommon.supportItems.dedicatedAPISupport')}
-
-
-
+ {t('billing.plansCommon.supportItems.customIntegration')}
-
-
- ) - default: - return '' - } - })() + // const comingSoon = ( + //
{t('billing.plansCommon.comingSoon')}
+ // ) + // const supportContent = (() => { + // switch (plan) { + // case Plan.sandbox: + // return (
+ //
{t('billing.plansCommon.supportItems.communityForums')}
+ //
{t('billing.plansCommon.supportItems.agentMode')}
+ //
+ //
+ //
 {t('billing.plansCommon.supportItems.workflow')}
+ //
+ //
+ //
) + // case Plan.professional: + // return ( + //
+ //
{t('billing.plansCommon.supportItems.emailSupport')}
+ //
+ //
+ {t('billing.plansCommon.supportItems.logoChange')}
+ //
+ //
+ //
+ {t('billing.plansCommon.supportItems.bulkUpload')}
+ //
+ //
+ // + + //
{t('billing.plansCommon.supportItems.llmLoadingBalancing')}
+ // {t('billing.plansCommon.supportItems.llmLoadingBalancingTooltip')}
+ // } + // /> + //
+ //
+ //
+ // + + //
 {t('billing.plansCommon.supportItems.ragAPIRequest')}
+ // {t('billing.plansCommon.ragAPIRequestTooltip')}
+ // } + // /> + //
+ //
{comingSoon}
+ //
+ //
+ // ) + // case Plan.team: + // return ( + //
+ //
{t('billing.plansCommon.supportItems.priorityEmail')}
+ //
+ //
+ {t('billing.plansCommon.supportItems.SSOAuthentication')}
+ //
{comingSoon}
+ //
+ //
+ // ) + // case Plan.enterprise: + // return ( + //
+ //
{t('billing.plansCommon.supportItems.personalizedSupport')}
+ //
+ //
+ {t('billing.plansCommon.supportItems.dedicatedAPISupport')}
+ //
+ //
+ //
+ {t('billing.plansCommon.supportItems.customIntegration')}
+ //
+ //
+ // ) + // default: + // return '' + // } + // })() const handleGetPayUrl = async () => { if (loading) return @@ -211,14 +215,23 @@ const PlanItem: FC = ({ } } return ( -
- {isMostPopularPlan && ( -
{t('billing.plansCommon.mostPopular')}
- )} -
-
{t(`${i18nPrefix}.name`)}
-
{t(`${i18nPrefix}.description`)}
- +
+
+ {style[plan].icon} +
+
{t(`${i18nPrefix}.name`)}
+ {isMostPopularPlan &&
+
+ +
+ Popular +
} +
+
{t(`${i18nPrefix}.description`)}
+
+
{/* Price */} {isFreePlan && (
{t('billing.plansCommon.free')}
@@ -227,74 +240,80 @@ const PlanItem: FC = ({
{t('billing.plansCommon.contactSales')}
)} {!isFreePlan && !isEnterprisePlan && ( -
+
${isYear ? planInfo.price * 10 : planInfo.price}
-
- {isYear &&
{t('billing.plansCommon.save')}${planInfo.price * 2}
} -
/{t(`billing.plansCommon.${!isYear ? 'month' : 'year'}`)}
+
+ {isYear &&
{t('billing.plansCommon.save')}${planInfo.price * 2}
} +
+ {t('billing.plansCommon.priceTip')} + {t(`billing.plansCommon.${!isYear ? 'month' : 'year'}`)}
)} +
-
- {btnText} -
- -
- -
- {t(`${i18nPrefix}.includesTitle`)} -
+
+ {btnText} +
+
} + label={isFreePlan + ? t('billing.plansCommon.messageRequest.title', { count: planInfo.messageRequest }) + : t('billing.plansCommon.messageRequest.titlePerMonth', { count: planInfo.messageRequest })} tooltip={t('billing.plansCommon.messageRequest.tooltip') as string} /> } label={t('billing.plansCommon.modelProviders')} - value={planInfo.modelProviders} /> } + label={t('billing.plansCommon.teamWorkspace', { count: planInfo.teamWorkspace })} /> } + label={t('billing.plansCommon.teamMember', { count: planInfo.teamMembers })} /> = 1000 ? `${planInfo.vectorSpace / 1000}G` : `${planInfo.vectorSpace}MB`)} - tooltip={t('billing.plansCommon.vectorSpaceBillingTooltip') as string} + icon={} + label={t('billing.plansCommon.buildApps', { count: planInfo.buildApps })} + /> + + } + label={t('billing.plansCommon.documents', { count: planInfo.documents })} + tooltip={t('billing.plansCommon.documentsTooltip') as string} /> - } + label={t('billing.plansCommon.vectorSpace', { size: planInfo.vectorSpace })} + tooltip={t('billing.plansCommon.vectorSpaceTooltip') as string} /> } + label={t('billing.plansCommon.documentsRequestQuota', { count: planInfo.documentsRequestQuota })} + tooltip={t('billing.plansCommon.documentsRequestQuotaTooltip') as string} + /> + } + label={[t(`billing.plansCommon.priority.${planInfo.documentProcessingPriority}`), t('billing.plansCommon.documentProcessingPriority')].join(' ')} + /> + + } + label={t('billing.plansCommon.annotatedResponse.title', { count: planInfo.annotatedResponse })} tooltip={t('billing.plansCommon.annotatedResponse.tooltip') as string} /> - - } + label={t('billing.plansCommon.logsHistory', { days: planInfo.logHistory === NUM_INFINITE ? t('billing.plansCommon.unlimited') as string : `${planInfo.logHistory} ${t('billing.plansCommon.days')}` })} />
diff --git a/web/app/components/billing/pricing/select-plan-range.tsx b/web/app/components/billing/pricing/select-plan-range.tsx index 8caffaa9d2..d4ce96ae44 100644 --- a/web/app/components/billing/pricing/select-plan-range.tsx +++ b/web/app/components/billing/pricing/select-plan-range.tsx @@ -2,6 +2,7 @@ import type { FC } from 'react' import React from 'react' import { useTranslation } from 'react-i18next' +import Switch from '../../base/switch' import cn from '@/utils/classnames' export enum PlanRange { monthly = 'monthly', @@ -25,10 +26,19 @@ const ITem: FC<{ isActive: boolean; value: PlanRange; text: string; onClick: (va } const ArrowIcon = ( - - - - + + + + + + + + + + + + + ) @@ -39,15 +49,16 @@ const SelectPlanRange: FC = ({ const { t } = useTranslation() return ( -
-
{t('billing.plansCommon.yearlyTip')}
- -
- - -
- {ArrowIcon} -
+
+
{t('billing.plansCommon.yearlyTip')}
+
+ {t('billing.plansCommon.annualBilling')} + { + onChange(v ? PlanRange.yearly : PlanRange.monthly) + }} /> +
+
+ {ArrowIcon}
) diff --git a/web/app/components/billing/type.ts b/web/app/components/billing/type.ts index d78eab2ae3..b70c88da43 100644 --- a/web/app/components/billing/type.ts +++ b/web/app/components/billing/type.ts @@ -14,17 +14,15 @@ export type PlanInfo = { level: number price: number modelProviders: string + teamWorkspace: number teamMembers: number buildApps: number - vectorSpace: number - documentsUploadQuota: number + documents: number + vectorSpace: string + documentsRequestQuota: number documentProcessingPriority: Priority logHistory: number - customTools: string | number - messageRequest: { - en: string | number - zh: string | number - } + messageRequest: number annotatedResponse: number } diff --git a/web/i18n/en-US/billing.ts b/web/i18n/en-US/billing.ts index 68982108cf..5bdb49bae9 100644 --- a/web/i18n/en-US/billing.ts +++ b/web/i18n/en-US/billing.ts @@ -8,8 +8,11 @@ const translation = { viewBilling: 'Manage billing and subscriptions', buyPermissionDeniedTip: 'Please contact your enterprise administrator to subscribe', plansCommon: { - title: 'Choose a plan that’s right for you', - yearlyTip: 'Get 2 months for free by subscribing yearly!', + title: 'Pricing that powers your AI journey', + freeTrialTipPrefix: 'Sign up and get a ', + freeTrialTip: 'free trial of 200 OpenAI calls. ', + freeTrialTipSuffix: 'No credit card required', + yearlyTip: 'Pay for 10 months, enjoy 1 Year!', mostPopular: 'Most Popular', planRange: { monthly: 'Monthly', @@ -19,33 +22,38 @@ const translation = { year: 'year', save: 'Save ', free: 'Free', + annualBilling: 'Annual Billing', + priceTip: 'per workspace/', currentPlan: 'Current Plan', contractSales: 'Contact sales', contractOwner: 'Contact team manager', startForFree: 'Start for free', - getStartedWith: 'Get started with ', + getStarted: 'Get started', contactSales: 'Contact Sales', talkToSales: 'Talk to Sales', - modelProviders: 'Model Providers', - teamMembers: 'Team Members', + modelProviders: 'Support OpenAI/Anthropic/Llama2/Azure OpenAI/Hugging Face/Replicate', + teamWorkspace: '{{count}} Team Workspace', + teamMember_one: '{{count}} Team Member', + teamMember_other: '{{count}} Team Members', annotationQuota: 'Annotation Quota', - buildApps: 'Build Apps', - vectorSpace: 'Vector Space', + buildApps: '{{count}} Apps', + documents: '{{count}} Knowledge Documents', + documentsTooltip: 'Quota on the number of documents imported from the Knowledge Data Source.', + vectorSpace: '{{size}} Knowledge Data Storage', vectorSpaceBillingTooltip: 'Each 1MB can store about 1.2million characters of vectorized data(estimated using OpenAI Embeddings, varies across models).', - vectorSpaceTooltip: 'Vector Space is the long-term memory system required for LLMs to comprehend your data.', - documentsUploadQuota: 'Documents Upload Quota', - documentProcessingPriority: 'Document Processing Priority', - documentProcessingPriorityTip: 'For higher document processing priority, please upgrade your plan.', - documentProcessingPriorityUpgrade: 'Process more data with higher accuracy at faster speeds.', + vectorSpaceTooltip: 'Documents with the High Quality indexing mode will consume Knowledge Data Storage resources. When Knowledge Data Storage reaches the limit, new documents will not be uploaded.', + documentsRequestQuota: '{{count}}/min Knowledge Request Rate limit', + documentsRequestQuotaTooltip: 'Indicates the number of queries per minute the system can handle with knowledge base support, used to measure query capacity and performance.', + documentProcessingPriority: 'Document Processing', priority: { 'standard': 'Standard', 'priority': 'Priority', 'top-priority': 'Top Priority', }, - logsHistory: 'Logs history', + logsHistory: '{{days}} Log history', customTools: 'Custom Tools', unavailable: 'Unavailable', - days: 'days', + days: 'Days', unlimited: 'Unlimited', support: 'Support', supportItems: { @@ -68,12 +76,13 @@ const translation = { member: 'Member', memberAfter: 'Member', messageRequest: { - title: 'Message Credits', - tooltip: 'Message invocation quotas for various plans using OpenAI models (except gpt4).Messages over the limit will use your OpenAI API Key.', + title: '{{count}} Messages', + titlePerMonth: '{{count}} Messages/month', + tooltip: 'Message invocation quotas for various plans using OpenAl models. Messages over the limit will use your OpenAI API Key.', }, annotatedResponse: { - title: 'Annotation Quota Limits', - tooltip: 'Manual editing and annotation of responses provides customizable high-quality question-answering abilities for apps. (Applicable only in chat apps)', + title: '{{count}} Annotation Quota Limits', + tooltip: 'Manual editing and annotation of responses provides customizable high-quality question-answering abilities for apps. (Applicable only in Chat apps)', }, ragAPIRequestTooltip: 'Refers to the number of API calls invoking only the knowledge base processing capabilities of Dify.', receiptInfo: 'Only team owner and team admin can subscribe and view billing information', @@ -81,17 +90,16 @@ const translation = { plans: { sandbox: { name: 'Sandbox', - description: '200 times GPT free trial', - includesTitle: 'Includes:', + description: 'Free Trial of Core Capabilities', }, professional: { name: 'Professional', - description: 'For individuals and small teams to unlock more power affordably.', + description: 'For Independent Developers/Small Teams', includesTitle: 'Everything in free plan, plus:', }, team: { name: 'Team', - description: 'Collaborate without limits and enjoy top-tier performance.', + description: 'For Medium-sized Teams', includesTitle: 'Everything in Professional plan, plus:', }, enterprise: { diff --git a/web/tailwind.config.js b/web/tailwind.config.js index 0da4968a7f..b03b91ff02 100644 --- a/web/tailwind.config.js +++ b/web/tailwind.config.js @@ -107,6 +107,9 @@ const config = { 'dataset-option-card-purple-gradient': 'var(--color-dataset-option-card-purple-gradient)', 'dataset-option-card-orange-gradient': 'var(--color-dataset-option-card-orange-gradient)', 'dataset-chunk-list-mask-bg': 'var(--color-dataset-chunk-list-mask-bg)', + 'price-premium-badge-background': 'var(--color-premium-badge-background)', + 'premium-yearly-tip-text-background': 'var(--color-premium-yearly-tip-text-background)', + 'price-premium-text-background': 'var(--color-premium-text-background)', }, lineClamp: { '20': '20', diff --git a/web/themes/manual-dark.css b/web/themes/manual-dark.css index 6d4c5f3908..aa539eb29f 100644 --- a/web/themes/manual-dark.css +++ b/web/themes/manual-dark.css @@ -1,35 +1,28 @@ html[data-theme="dark"] { - --color-chatbot-bg: linear-gradient( - 180deg, - rgba(34, 34, 37, 0.9) 0%, - rgba(29, 29, 32, 0.9) 90.48% - ); - --color-chat-bubble-bg: linear-gradient( - 180deg, - rgba(200, 206, 218, 0.08) 0%, - rgba(200, 206, 218, 0.02) 100% - ); - --color-workflow-process-bg: linear-gradient( - 90deg, - rgba(24, 24, 27, 0.25) 0%, - rgba(24, 24, 27, 0.04) 100% - ); - --color-account-teams-bg: linear-gradient( - 271deg, - rgba(34, 34, 37, 0.9) -0.1%, - rgba(29, 29, 32, 0.9) 98.26% - ); - --color-dataset-chunk-process-success-bg: linear-gradient(92deg, rgba(23, 178, 106, 0.30) 0%, rgba(0, 0, 0, 0.00) 100%); - --color-dataset-chunk-process-error-bg: linear-gradient(92deg, rgba(240, 68, 56, 0.30) 0%, rgba(0, 0, 0, 0.00) 100%); - --color-dataset-chunk-detail-card-hover-bg: linear-gradient(180deg, #1D1D20 0%, #222225 100%); - --color-dataset-child-chunk-expand-btn-bg: linear-gradient(90deg, rgba(24, 24, 27, 0.25) 0%, rgba(24, 24, 27, 0.04) 100%); - --color-dataset-option-card-blue-gradient: linear-gradient(90deg, #24252E 0%, #1E1E21 100%); - --color-dataset-option-card-purple-gradient: linear-gradient(90deg, #25242E 0%, #1E1E21 100%); - --color-dataset-option-card-orange-gradient: linear-gradient(90deg, #2B2322 0%, #1E1E21 100%); - --color-dataset-chunk-list-mask-bg: linear-gradient(180deg, rgba(34, 34, 37, 0.00) 0%, #222225 100%); - --mask-top2bottom-gray-50-to-transparent: linear-gradient( - 180deg, - rgba(24, 24, 27, 0.08) 0%, - rgba(0, 0, 0, 0) 100% - ); -} + --color-chatbot-bg: linear-gradient(180deg, + rgba(34, 34, 37, 0.9) 0%, + rgba(29, 29, 32, 0.9) 90.48%); + --color-chat-bubble-bg: linear-gradient(180deg, + rgba(200, 206, 218, 0.08) 0%, + rgba(200, 206, 218, 0.02) 100%); + --color-workflow-process-bg: linear-gradient(90deg, + rgba(24, 24, 27, 0.25) 0%, + rgba(24, 24, 27, 0.04) 100%); + --color-account-teams-bg: linear-gradient(271deg, + rgba(34, 34, 37, 0.9) -0.1%, + rgba(29, 29, 32, 0.9) 98.26%); + --color-dataset-chunk-process-success-bg: linear-gradient(92deg, rgba(23, 178, 106, 0.30) 0%, rgba(0, 0, 0, 0.00) 100%); + --color-dataset-chunk-process-error-bg: linear-gradient(92deg, rgba(240, 68, 56, 0.30) 0%, rgba(0, 0, 0, 0.00) 100%); + --color-dataset-chunk-detail-card-hover-bg: linear-gradient(180deg, #1D1D20 0%, #222225 100%); + --color-dataset-child-chunk-expand-btn-bg: linear-gradient(90deg, rgba(24, 24, 27, 0.25) 0%, rgba(24, 24, 27, 0.04) 100%); + --color-dataset-option-card-blue-gradient: linear-gradient(90deg, #24252E 0%, #1E1E21 100%); + --color-dataset-option-card-purple-gradient: linear-gradient(90deg, #25242E 0%, #1E1E21 100%); + --color-dataset-option-card-orange-gradient: linear-gradient(90deg, #2B2322 0%, #1E1E21 100%); + --color-dataset-chunk-list-mask-bg: linear-gradient(180deg, rgba(34, 34, 37, 0.00) 0%, #222225 100%); + --mask-top2bottom-gray-50-to-transparent: linear-gradient(180deg, + rgba(24, 24, 27, 0.08) 0%, + rgba(0, 0, 0, 0) 100%); + --color-premium-yearly-tip-text-background: linear-gradient(91deg, #FDB022 2.18%, #F79009 108.79%); + --color-premium-badge-background: linear-gradient(95deg, rgba(103, 111, 131, 0.90) 0%, rgba(73, 84, 100, 0.90) 105.58%), var(--util-colors-gray-gray-200, #18222F); + --color-premium-text-background: linear-gradient(92deg, rgba(249, 250, 251, 0.95) 0%, rgba(233, 235, 240, 0.95) 97.78%); +} \ No newline at end of file diff --git a/web/themes/manual-light.css b/web/themes/manual-light.css index 501f9f1d1f..893b607189 100644 --- a/web/themes/manual-light.css +++ b/web/themes/manual-light.css @@ -1,35 +1,28 @@ html[data-theme="light"] { - --color-chatbot-bg: linear-gradient( - 180deg, - rgba(249, 250, 251, 0.9) 0%, - rgba(242, 244, 247, 0.9) 90.48% - ); - --color-chat-bubble-bg: linear-gradient( - 180deg, - #fff 0%, - rgba(255, 255, 255, 0.6) 100% - ); - --color-workflow-process-bg: linear-gradient( - 90deg, - rgba(200, 206, 218, 0.2) 0%, - rgba(200, 206, 218, 0.04) 100% - ); - --color-account-teams-bg: linear-gradient( - 271deg, - rgba(249, 250, 251, 0.9) -0.1%, - rgba(242, 244, 247, 0.9) 98.26% - ); - --color-dataset-chunk-process-success-bg: linear-gradient(92deg, rgba(23, 178, 106, 0.25) 0%, rgba(255, 255, 255, 0.00) 100%); - --color-dataset-chunk-process-error-bg: linear-gradient(92deg, rgba(240, 68, 56, 0.25) 0%, rgba(255, 255, 255, 0.00) 100%); - --color-dataset-chunk-detail-card-hover-bg: linear-gradient(180deg, #F2F4F7 0%, #F9FAFB 100%); - --color-dataset-child-chunk-expand-btn-bg: linear-gradient(90deg, rgba(200, 206, 218, 0.20) 0%, rgba(200, 206, 218, 0.04) 100%); - --color-dataset-option-card-blue-gradient: linear-gradient(90deg, #F2F4F7 0%, #F9FAFB 100%); - --color-dataset-option-card-purple-gradient: linear-gradient(90deg, #F0EEFA 0%, #F9FAFB 100%); - --color-dataset-option-card-orange-gradient: linear-gradient(90deg, #F8F2EE 0%, #F9FAFB 100%); - --color-dataset-chunk-list-mask-bg: linear-gradient(180deg, rgba(255, 255, 255, 0.00) 0%, #FCFCFD 100%); - --mask-top2bottom-gray-50-to-transparent: linear-gradient( - 180deg, - rgba(200, 206, 218, 0.2) 0%, - rgba(255, 255, 255, 0) 100% - ); -} + --color-chatbot-bg: linear-gradient(180deg, + rgba(249, 250, 251, 0.9) 0%, + rgba(242, 244, 247, 0.9) 90.48%); + --color-chat-bubble-bg: linear-gradient(180deg, + #fff 0%, + rgba(255, 255, 255, 0.6) 100%); + --color-workflow-process-bg: linear-gradient(90deg, + rgba(200, 206, 218, 0.2) 0%, + rgba(200, 206, 218, 0.04) 100%); + --color-account-teams-bg: linear-gradient(271deg, + rgba(249, 250, 251, 0.9) -0.1%, + rgba(242, 244, 247, 0.9) 98.26%); + --color-dataset-chunk-process-success-bg: linear-gradient(92deg, rgba(23, 178, 106, 0.25) 0%, rgba(255, 255, 255, 0.00) 100%); + --color-dataset-chunk-process-error-bg: linear-gradient(92deg, rgba(240, 68, 56, 0.25) 0%, rgba(255, 255, 255, 0.00) 100%); + --color-dataset-chunk-detail-card-hover-bg: linear-gradient(180deg, #F2F4F7 0%, #F9FAFB 100%); + --color-dataset-child-chunk-expand-btn-bg: linear-gradient(90deg, rgba(200, 206, 218, 0.20) 0%, rgba(200, 206, 218, 0.04) 100%); + --color-dataset-option-card-blue-gradient: linear-gradient(90deg, #F2F4F7 0%, #F9FAFB 100%); + --color-dataset-option-card-purple-gradient: linear-gradient(90deg, #F0EEFA 0%, #F9FAFB 100%); + --color-dataset-option-card-orange-gradient: linear-gradient(90deg, #F8F2EE 0%, #F9FAFB 100%); + --color-dataset-chunk-list-mask-bg: linear-gradient(180deg, rgba(255, 255, 255, 0.00) 0%, #FCFCFD 100%); + --mask-top2bottom-gray-50-to-transparent: linear-gradient(180deg, + rgba(200, 206, 218, 0.2) 0%, + rgba(255, 255, 255, 0) 100%); + --color-premium-yearly-tip-text-background: linear-gradient(91deg, #F79009 2.18%, #DC6803 108.79%); + --color-premium-badge-background: linear-gradient(95deg, rgba(152, 162, 178, 0.90) 0%, rgba(103, 111, 131, 0.90) 105.58%); + --color-premium-text-background: linear-gradient(92deg, rgba(252, 252, 253, 0.95) 0%, rgba(242, 244, 247, 0.95) 97.78%); +} \ No newline at end of file From 47637da7346b1b4f05ef36582d66712180d1a9f6 Mon Sep 17 00:00:00 2001 From: NFish Date: Mon, 6 Jan 2025 10:47:38 +0800 Subject: [PATCH 02/28] wip: adjust self hosted page style --- web/app/components/billing/config.ts | 15 -- web/app/components/billing/pricing/index.tsx | 26 ++- .../components/billing/pricing/plan-item.tsx | 108 +-------- .../billing/pricing/select-plan-range.tsx | 18 +- .../billing/pricing/self-hosted-plan-item.tsx | 212 ++++++++++++++++++ web/app/components/billing/type.ts | 26 ++- web/i18n/en-US/billing.ts | 46 +++- 7 files changed, 304 insertions(+), 147 deletions(-) create mode 100644 web/app/components/billing/pricing/self-hosted-plan-item.tsx diff --git a/web/app/components/billing/config.ts b/web/app/components/billing/config.ts index 74afcc09fc..bc33b899e7 100644 --- a/web/app/components/billing/config.ts +++ b/web/app/components/billing/config.ts @@ -54,21 +54,6 @@ export const ALL_PLANS: Record = { annotatedResponse: 5000, logHistory: NUM_INFINITE, }, - enterprise: { - level: 4, - price: 0, - modelProviders: supportModelProviders, - teamMembers: NUM_INFINITE, - buildApps: NUM_INFINITE, - documents: 50, - vectorSpace: NUM_INFINITE, - documentsRequestQuota: 5000, - documentProcessingPriority: Priority.topPriority, - logHistory: NUM_INFINITE, - customTools: NUM_INFINITE, - messageRequest: contractSales, - annotatedResponse: NUM_INFINITE, - }, } export const defaultPlan = { diff --git a/web/app/components/billing/pricing/index.tsx b/web/app/components/billing/pricing/index.tsx index 98f7008069..056099e3b7 100644 --- a/web/app/components/billing/pricing/index.tsx +++ b/web/app/components/billing/pricing/index.tsx @@ -5,10 +5,11 @@ import { createPortal } from 'react-dom' import { useTranslation } from 'react-i18next' import { RiArrowRightUpLine, RiCloseLine, RiCloudFill, RiTerminalBoxFill } from '@remixicon/react' import Link from 'next/link' -import { Plan } from '../type' +import { Plan, SelfHostedPlan } from '../type' import TabSlider from '../../base/tab-slider' import SelectPlanRange, { PlanRange } from './select-plan-range' import PlanItem from './plan-item' +import SelfHostedPlanItem from './self-hosted-plan-item' import { useProviderContext } from '@/context/provider-context' import GridMask from '@/app/components/base/grid-mask' import { useAppContext } from '@/context/app-context' @@ -26,7 +27,7 @@ const Pricing: FC = ({ const canPay = isCurrentWorkspaceManager const [planRange, setPlanRange] = React.useState(PlanRange.monthly) - const [currentPlan, setCurrentPlan] = React.useState('cloud') + const [currentPlan, setCurrentPlan] = React.useState('self') return createPortal(
= ({ { value: 'self', text:
self hosted
}]} onChange={v => setCurrentPlan(v)} /> - + />}
@@ -90,9 +91,18 @@ const Pricing: FC = ({ /> } {currentPlan === 'self' && <> - + + @@ -102,7 +112,7 @@ const Pricing: FC = ({
- Compare plans & features + {t('billing.plansCommon.comparePlanAndFeatures')}
diff --git a/web/app/components/billing/pricing/plan-item.tsx b/web/app/components/billing/pricing/plan-item.tsx index 24f588d94a..f08cc2f3ab 100644 --- a/web/app/components/billing/pricing/plan-item.tsx +++ b/web/app/components/billing/pricing/plan-item.tsx @@ -4,7 +4,7 @@ import React from 'react' import { useTranslation } from 'react-i18next' import { RiApps2Line, RiBook2Line, RiBrain2Line, RiChatAiLine, RiFileEditLine, RiFolder6Line, RiGroupLine, RiHardDrive3Line, RiHistoryLine, RiProgress3Line, RiQuestionLine, RiSeoLine } from '@remixicon/react' import { Plan } from '../type' -import { ALL_PLANS, NUM_INFINITE, contactSalesUrl } from '../config' +import { ALL_PLANS, NUM_INFINITE } from '../config' import Toast from '../../base/toast' import Tooltip from '../../base/tooltip' import Divider from '../../base/divider' @@ -60,43 +60,24 @@ const style = { description: 'text-util-colors-indigo-indigo-600', btnStyle: 'bg-components-button-indigo-bg hover:bg-components-button-indigo-bg-hover border border-components-button-primary-border text-components-button-primary-text', }, - [Plan.enterprise]: { - icon: 'text-[#DC6803]', - description: '', - btnStyle: 'hover:shadow-lg hover:!text-white hover:!bg-[#F79009] hover:!border-[#DC6803] active:!text-white active:!bg-[#DC6803] active:!border-[#DC6803]', - }, } const PlanItem: FC = ({ plan, currentPlan, planRange, - canPay, }) => { const { t } = useTranslation() - // const { locale } = useContext(I18n) - - // const isZh = locale === LanguagesSupported[1] const [loading, setLoading] = React.useState(false) const i18nPrefix = `billing.plans.${plan}` const isFreePlan = plan === Plan.sandbox - const isEnterprisePlan = plan === Plan.enterprise const isMostPopularPlan = plan === Plan.professional const planInfo = ALL_PLANS[plan] const isYear = planRange === PlanRange.yearly const isCurrent = plan === currentPlan - const isPlanDisabled = planInfo.level <= ALL_PLANS[currentPlan].level || (!canPay && plan !== Plan.enterprise) + const isPlanDisabled = planInfo.level <= ALL_PLANS[currentPlan].level const { isCurrentWorkspaceManager } = useAppContext() - // const messagesRequest = (() => { - // const value = planInfo.messageRequest[isZh ? 'zh' : 'en'] - // if (value === contractSales) - // return t('billing.plansCommon.contractSales') - // return value - // })() const btnText = (() => { - if (!canPay && plan !== Plan.enterprise) - return t('billing.plansCommon.contractOwner') - if (isCurrent) return t('billing.plansCommon.currentPlan') @@ -104,83 +85,9 @@ const PlanItem: FC = ({ [Plan.sandbox]: t('billing.plansCommon.startForFree'), [Plan.professional]: t('billing.plansCommon.getStarted'), [Plan.team]: t('billing.plansCommon.getStarted'), - [Plan.enterprise]: t('billing.plansCommon.talkToSales'), })[plan] })() - // const comingSoon = ( - //
{t('billing.plansCommon.comingSoon')}
- // ) - // const supportContent = (() => { - // switch (plan) { - // case Plan.sandbox: - // return (
- //
{t('billing.plansCommon.supportItems.communityForums')}
- //
{t('billing.plansCommon.supportItems.agentMode')}
- //
- //
- //
 {t('billing.plansCommon.supportItems.workflow')}
- //
- //
- //
) - // case Plan.professional: - // return ( - //
- //
{t('billing.plansCommon.supportItems.emailSupport')}
- //
- //
+ {t('billing.plansCommon.supportItems.logoChange')}
- //
- //
- //
+ {t('billing.plansCommon.supportItems.bulkUpload')}
- //
- //
- // + - //
{t('billing.plansCommon.supportItems.llmLoadingBalancing')}
- // {t('billing.plansCommon.supportItems.llmLoadingBalancingTooltip')}
- // } - // /> - //
- //
- //
- // + - //
 {t('billing.plansCommon.supportItems.ragAPIRequest')}
- // {t('billing.plansCommon.ragAPIRequestTooltip')}
- // } - // /> - //
- //
{comingSoon}
- //
- //
- // ) - // case Plan.team: - // return ( - //
- //
{t('billing.plansCommon.supportItems.priorityEmail')}
- //
- //
+ {t('billing.plansCommon.supportItems.SSOAuthentication')}
- //
{comingSoon}
- //
- //
- // ) - // case Plan.enterprise: - // return ( - //
- //
{t('billing.plansCommon.supportItems.personalizedSupport')}
- //
- //
+ {t('billing.plansCommon.supportItems.dedicatedAPISupport')}
- //
- //
- //
+ {t('billing.plansCommon.supportItems.customIntegration')}
- //
- //
- // ) - // default: - // return '' - // } - // })() + const handleGetPayUrl = async () => { if (loading) return @@ -191,10 +98,6 @@ const PlanItem: FC = ({ if (isFreePlan) return - if (isEnterprisePlan) { - window.location.href = contactSalesUrl - return - } // Only workspace manager can buy plan if (!isCurrentWorkspaceManager) { Toast.notify({ @@ -236,10 +139,7 @@ const PlanItem: FC = ({ {isFreePlan && (
{t('billing.plansCommon.free')}
)} - {isEnterprisePlan && ( -
{t('billing.plansCommon.contactSales')}
- )} - {!isFreePlan && !isEnterprisePlan && ( + {!isFreePlan && (
${isYear ? planInfo.price * 10 : planInfo.price}
diff --git a/web/app/components/billing/pricing/select-plan-range.tsx b/web/app/components/billing/pricing/select-plan-range.tsx index d4ce96ae44..317a038530 100644 --- a/web/app/components/billing/pricing/select-plan-range.tsx +++ b/web/app/components/billing/pricing/select-plan-range.tsx @@ -3,7 +3,6 @@ import type { FC } from 'react' import React from 'react' import { useTranslation } from 'react-i18next' import Switch from '../../base/switch' -import cn from '@/utils/classnames' export enum PlanRange { monthly = 'monthly', yearly = 'yearly', @@ -14,26 +13,15 @@ type Props = { onChange: (value: PlanRange) => void } -const ITem: FC<{ isActive: boolean; value: PlanRange; text: string; onClick: (value: PlanRange) => void }> = ({ isActive, value, text, onClick }) => { - return ( -
onClick(value)} - > - {text} -
- ) -} - const ArrowIcon = ( - + - - + + diff --git a/web/app/components/billing/pricing/self-hosted-plan-item.tsx b/web/app/components/billing/pricing/self-hosted-plan-item.tsx new file mode 100644 index 0000000000..98faf2c688 --- /dev/null +++ b/web/app/components/billing/pricing/self-hosted-plan-item.tsx @@ -0,0 +1,212 @@ +'use client' +import type { FC, ReactNode } from 'react' +import React from 'react' +import { useTranslation } from 'react-i18next' +import { RiAsterisk, RiBrain2Line, RiBuildingLine, RiCheckLine, RiQuestionLine, RiVipDiamondLine } from '@remixicon/react' +import { SelfHostedPlan } from '../type' +import { contactSalesUrl } from '../config' +import Toast from '../../base/toast' +import Tooltip from '../../base/tooltip' +import { PlanRange } from './select-plan-range' +import cn from '@/utils/classnames' +import { useAppContext } from '@/context/app-context' +import { fetchSubscriptionUrls } from '@/service/billing' + +type Props = { + plan: SelfHostedPlan + planRange: PlanRange + canPay: boolean +} + +const AWSMarketplaceLogo = () => { + return + + + + + + + + + + + + + + + + + + + + + + +} + +const AzureIcon = () => { + return + + + + + + + + + + + + + + + + + + + + + + +} + +const GoogleCloudIcon = () => { + return + + + + + +} + +const KeyValue = ({ label, tooltip }: { icon: ReactNode; label: string; tooltip?: string }) => { + return ( +
+
+ +
+
{label}
+ {tooltip && ( + +
+ +
+
+ )} +
+ ) +} + +const style = { + [SelfHostedPlan.community]: { + icon: , + description: 'text-util-colors-gray-gray-600', + btnStyle: 'bg-components-button-secondary-bg hover:bg-components-button-secondary-bg-hover border-[0.5px] border-components-button-secondary-border text-text-primary', + }, + [SelfHostedPlan.premium]: { + icon: , + description: 'text-text-warning', + btnStyle: 'bg-third-party-aws hover:bg-third-party-aws-hover border border-components-button-primary-border text-text-primary-on-surface shadow-xs', + }, + [SelfHostedPlan.enterprise]: { + icon: , + description: '', + btnStyle: 'hover:shadow-lg hover:!text-white hover:!bg-[#F79009] hover:!border-[#DC6803] active:!text-white active:!bg-[#DC6803] active:!border-[#DC6803]', + }, +} +const PlanItem: FC = ({ + plan, + planRange, +}) => { + const { t } = useTranslation() + const isFreePlan = plan === SelfHostedPlan.community + const isPremiumPlan = plan === SelfHostedPlan.premium + const [loading, setLoading] = React.useState(false) + const i18nPrefix = `billing.plans.${plan}` + const isEnterprisePlan = plan === SelfHostedPlan.enterprise + const isYear = planRange === PlanRange.yearly + const { isCurrentWorkspaceManager } = useAppContext() + const features = t(`${i18nPrefix}.features`, { returnObjects: true }) as string[] + const handleGetPayUrl = async () => { + if (loading) + return + + if (isEnterprisePlan) { + window.location.href = contactSalesUrl + return + } + // Only workspace manager can buy plan + if (!isCurrentWorkspaceManager) { + Toast.notify({ + type: 'error', + message: t('billing.buyPermissionDeniedTip'), + className: 'z-[1001]', + }) + return + } + setLoading(true) + try { + const res = await fetchSubscriptionUrls(plan, isYear ? 'year' : 'month') + // Adb Block additional tracking block the gtag, so we need to redirect directly + window.location.href = res.url + } + finally { + setLoading(false) + } + } + return ( +
+
+ {style[plan].icon} +
+
{t(`${i18nPrefix}.name`)}
+
+
{t(`${i18nPrefix}.description`)}
+
+
+
+
{t(`${i18nPrefix}.price`)}
+ {!isFreePlan &&
+
+ {t(`${i18nPrefix}.priceTip`)} +
+
} +
+
+ +
+ {t(`${i18nPrefix}.btnText`)} +
+
{t(`${i18nPrefix}.includesTitle`)}
+
+ {features.map(v => + } + label={v} + />)} +
+ {isPremiumPlan &&
+
+
+ +
+
+ +
+
+ {t('billing.plans.premium.comingSoon')} +
} +
+ ) +} +export default React.memo(PlanItem) diff --git a/web/app/components/billing/type.ts b/web/app/components/billing/type.ts index b70c88da43..29dd4985f7 100644 --- a/web/app/components/billing/type.ts +++ b/web/app/components/billing/type.ts @@ -2,9 +2,7 @@ export enum Plan { sandbox = 'sandbox', professional = 'professional', team = 'team', - enterprise = 'enterprise', } - export enum Priority { standard = 'standard', priority = 'priority', @@ -26,7 +24,29 @@ export type PlanInfo = { annotatedResponse: number } -export type UsagePlanInfo = Pick +export enum SelfHostedPlan { + community = 'community', + premium = 'premium', + enterprise = 'enterprise', +} + +export type SelfHostedPlanInfo = { + level: number + price: number + modelProviders: string + teamWorkspace: number + teamMembers: number + buildApps: number + documents: number + vectorSpace: string + documentsRequestQuota: number + documentProcessingPriority: Priority + logHistory: number + messageRequest: number + annotatedResponse: number +} + +export type UsagePlanInfo = Pick export enum DocumentProcessingPriority { standard = 'standard', diff --git a/web/i18n/en-US/billing.ts b/web/i18n/en-US/billing.ts index 5bdb49bae9..e2e18b756f 100644 --- a/web/i18n/en-US/billing.ts +++ b/web/i18n/en-US/billing.ts @@ -23,6 +23,7 @@ const translation = { save: 'Save ', free: 'Free', annualBilling: 'Annual Billing', + comparePlanAndFeatures: 'Compare plans & features', priceTip: 'per workspace/', currentPlan: 'Current Plan', contractSales: 'Contact sales', @@ -102,10 +103,51 @@ const translation = { description: 'For Medium-sized Teams', includesTitle: 'Everything in Professional plan, plus:', }, + community: { + name: 'Community', + description: 'For Individual Users, Small Teams, or Non-commercial Projects', + price: 'Free', + btnText: 'Get Started with Community', + includesTitle: 'Free Features:', + features: [ + 'All Core Features Released Under the Public Repository', + 'Single Workspace', + 'Complies with Dify Open Source License', + ], + }, + premium: { + name: 'Premium', + description: 'For Mid-sized Organizations and Teams', + price: 'Scalable', + priceTip: 'Based on Cloud Marketplace', + btnText: 'Get Premium in AWS Marketplace', + includesTitle: 'Everything from Community, plus:', + comingSoon: 'Microsoft Azure & Google Cloud Support Coming Soon', + features: [ + 'Self-managed Reliability by Various Cloud Providers', + 'Single Workspace', + 'WebApp Logo & Branding Customization', + 'Priority Email & Chat Support', + ], + }, enterprise: { name: 'Enterprise', - description: 'Get full capabilities and support for large-scale mission-critical systems.', - includesTitle: 'Everything in Team plan, plus:', + description: 'For Enterprise Require Organization-wide Security, Compliance, Scalability, Control and More Advanced Features', + price: 'Custom', + priceTip: 'Annual Billing Only', + btnText: 'Contact Sales', + includesTitle: 'Everything from Premium, plus:', + features: [ + 'Enterprise-grade Scalable Deployment Solutions', + 'Commercial License Authorization', + 'Exclusive Enterprise Features', + 'Multiple Workspaces & Enterprise Management', + 'SSO', + 'Negotiated SLAs by Dify Partners', + 'Advanced Security & Controls', + 'Updates and Maintenance by Dify Officially', + 'Professional Technical Support', + ], }, }, vectorSpace: { From e46a3343b830057ec75c29174da020ffbbe59569 Mon Sep 17 00:00:00 2001 From: NFish Date: Tue, 7 Jan 2025 11:42:41 +0800 Subject: [PATCH 03/28] fix: new upgrade page --- .../assets/public/billing/aws-marketplace.svg | 23 ++ .../icons/assets/public/billing/azure.svg | 25 ++ .../icons/assets/public/billing/buildings.svg | 5 + .../icons/assets/public/billing/diamond.svg | 5 + .../assets/public/billing/google-cloud.svg | 8 + .../src/public/billing/AwsMarketplace.json | 179 +++++++++++++ .../src/public/billing/AwsMarketplace.tsx | 16 ++ .../base/icons/src/public/billing/Azure.json | 193 ++++++++++++++ .../base/icons/src/public/billing/Azure.tsx | 16 ++ .../icons/src/public/billing/Buildings.json | 39 +++ .../icons/src/public/billing/Buildings.tsx | 16 ++ .../icons/src/public/billing/Diamond.json | 39 +++ .../base/icons/src/public/billing/Diamond.tsx | 16 ++ .../icons/src/public/billing/GoogleCloud.json | 66 +++++ .../icons/src/public/billing/GoogleCloud.tsx | 16 ++ .../base/icons/src/public/billing/index.ts | 5 + web/app/components/billing/config.ts | 2 + web/app/components/billing/pricing/index.tsx | 11 +- .../components/billing/pricing/plan-item.tsx | 6 +- .../billing/pricing/select-plan-range.tsx | 4 +- .../billing/pricing/self-hosted-plan-item.tsx | 235 ++++++++---------- web/i18n/en-US/billing.ts | 7 +- web/i18n/ja-JP/billing.ts | 109 +++++--- web/i18n/zh-Hans/billing.ts | 101 ++++++-- web/tailwind.config.js | 1 + web/themes/manual-dark.css | 1 + web/themes/manual-light.css | 53 ++-- 27 files changed, 967 insertions(+), 230 deletions(-) create mode 100644 web/app/components/base/icons/assets/public/billing/aws-marketplace.svg create mode 100644 web/app/components/base/icons/assets/public/billing/azure.svg create mode 100644 web/app/components/base/icons/assets/public/billing/buildings.svg create mode 100644 web/app/components/base/icons/assets/public/billing/diamond.svg create mode 100644 web/app/components/base/icons/assets/public/billing/google-cloud.svg create mode 100644 web/app/components/base/icons/src/public/billing/AwsMarketplace.json create mode 100644 web/app/components/base/icons/src/public/billing/AwsMarketplace.tsx create mode 100644 web/app/components/base/icons/src/public/billing/Azure.json create mode 100644 web/app/components/base/icons/src/public/billing/Azure.tsx create mode 100644 web/app/components/base/icons/src/public/billing/Buildings.json create mode 100644 web/app/components/base/icons/src/public/billing/Buildings.tsx create mode 100644 web/app/components/base/icons/src/public/billing/Diamond.json create mode 100644 web/app/components/base/icons/src/public/billing/Diamond.tsx create mode 100644 web/app/components/base/icons/src/public/billing/GoogleCloud.json create mode 100644 web/app/components/base/icons/src/public/billing/GoogleCloud.tsx diff --git a/web/app/components/base/icons/assets/public/billing/aws-marketplace.svg b/web/app/components/base/icons/assets/public/billing/aws-marketplace.svg new file mode 100644 index 0000000000..02fb327f38 --- /dev/null +++ b/web/app/components/base/icons/assets/public/billing/aws-marketplace.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/app/components/base/icons/assets/public/billing/azure.svg b/web/app/components/base/icons/assets/public/billing/azure.svg new file mode 100644 index 0000000000..186ab0a2be --- /dev/null +++ b/web/app/components/base/icons/assets/public/billing/azure.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/app/components/base/icons/assets/public/billing/buildings.svg b/web/app/components/base/icons/assets/public/billing/buildings.svg new file mode 100644 index 0000000000..34e784d089 --- /dev/null +++ b/web/app/components/base/icons/assets/public/billing/buildings.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/web/app/components/base/icons/assets/public/billing/diamond.svg b/web/app/components/base/icons/assets/public/billing/diamond.svg new file mode 100644 index 0000000000..f3692f848a --- /dev/null +++ b/web/app/components/base/icons/assets/public/billing/diamond.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/web/app/components/base/icons/assets/public/billing/google-cloud.svg b/web/app/components/base/icons/assets/public/billing/google-cloud.svg new file mode 100644 index 0000000000..61e30a3186 --- /dev/null +++ b/web/app/components/base/icons/assets/public/billing/google-cloud.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/web/app/components/base/icons/src/public/billing/AwsMarketplace.json b/web/app/components/base/icons/src/public/billing/AwsMarketplace.json new file mode 100644 index 0000000000..8a0b1003cd --- /dev/null +++ b/web/app/components/base/icons/src/public/billing/AwsMarketplace.json @@ -0,0 +1,179 @@ +{ + "icon": { + "type": "element", + "isRootNode": true, + "name": "svg", + "attributes": { + "width": "126", + "height": "24", + "viewBox": "0 0 126 24", + "fill": "none", + "xmlns": "http://www.w3.org/2000/svg" + }, + "children": [ + { + "type": "element", + "name": "g", + "attributes": { + "clip-path": "url(#clip0_394_42756)" + }, + "children": [ + { + "type": "element", + "name": "path", + "attributes": { + "d": "M47.3963 14.5593V8.71609C47.3963 8.14631 47.2869 7.73413 47.0682 7.45531C46.8494 7.1886 46.5091 7.04313 46.0473 7.04313C45.2209 7.04313 44.3824 7.29771 43.5438 7.80687C43.556 7.89173 43.556 7.97659 43.556 8.06145C43.556 8.14631 43.556 8.2433 43.556 8.32816V14.5351H41.8667V8.69184C41.8667 8.12207 41.7573 7.70989 41.5386 7.43106C41.3198 7.16436 40.9795 7.01888 40.5177 7.01888C39.6549 7.01888 38.8284 7.27346 38.0385 7.7705V14.523H36.3492V5.9157H37.759L37.9291 6.77642C39.0229 6.0248 40.0802 5.66112 41.1132 5.66112C42.1705 5.66112 42.8875 6.06117 43.2521 6.86128C44.3702 6.06117 45.5004 5.66112 46.6185 5.66112C47.3963 5.66112 48.004 5.87933 48.4172 6.32788C48.8425 6.7643 49.0491 7.39469 49.0491 8.20693V14.523H47.3963V14.5593Z", + "fill": "white" + }, + "children": [] + }, + { + "type": "element", + "name": "path", + "attributes": { + "d": "M56.0492 14.5593L55.9156 13.6744C55.5023 14.0259 55.0527 14.2926 54.5666 14.4866C54.0683 14.6806 53.5822 14.7775 53.0961 14.7775C52.294 14.7775 51.6498 14.5472 51.1637 14.0865C50.6776 13.6259 50.4346 13.0197 50.4346 12.2439C50.4346 11.4195 50.7262 10.7527 51.3217 10.2678C51.9172 9.77078 52.7072 9.52832 53.7037 9.52832C54.36 9.52832 55.077 9.62531 55.8426 9.81927V8.70397C55.8426 8.09782 55.709 7.6614 55.4294 7.41894C55.1499 7.16436 54.6759 7.04313 54.0075 7.04313C53.0474 7.04313 52.0509 7.21285 51.0179 7.56441V6.37637C51.4311 6.15816 51.9294 6.00056 52.5127 5.87933C53.1082 5.7581 53.7037 5.69749 54.2992 5.69749C55.3808 5.69749 56.1708 5.9157 56.6812 6.36425C57.1916 6.81279 57.4468 7.49168 57.4468 8.41302V14.5593H56.0492ZM53.4971 13.5046C54.2627 13.5046 55.0527 13.2137 55.8426 12.6439V10.9103C55.2471 10.7649 54.6516 10.6921 54.044 10.6921C52.7679 10.6921 52.1238 11.1892 52.1238 12.1711C52.1238 12.5954 52.2453 12.9349 52.4763 13.1652C52.7193 13.3834 53.0596 13.5046 53.4971 13.5046Z", + "fill": "white" + }, + "children": [] + }, + { + "type": "element", + "name": "path", + "attributes": { + "d": "M59.3792 14.5593V5.95207H60.7889L60.9712 7.22497C61.2872 6.88553 61.5788 6.61883 61.8584 6.43698C62.1379 6.25514 62.4053 6.10966 62.6969 6.0248C62.9764 5.93994 63.2924 5.89145 63.6206 5.89145C63.8393 5.89145 64.0702 5.90357 64.3133 5.93994V7.46743C63.9487 7.41894 63.6449 7.39469 63.3896 7.39469C62.4782 7.39469 61.7004 7.6614 61.0563 8.20693V14.5593H59.3792Z", + "fill": "white" + }, + "children": [] + }, + { + "type": "element", + "name": "path", + "attributes": { + "d": "M65.3584 14.5593V2H67.0477V9.71017L70.7057 5.96419H72.7596L68.6762 10.0496L73.027 14.5593H70.9002L67.0355 10.486V14.5593H65.3584Z", + "fill": "white" + }, + "children": [] + }, + { + "type": "element", + "name": "path", + "attributes": { + "d": "M74.5704 10.6194C74.5947 11.5892 74.8378 12.3166 75.2996 12.7773C75.7614 13.2379 76.4663 13.4683 77.4385 13.4683C78.3378 13.4683 79.2493 13.2985 80.1729 12.947V14.1472C79.3587 14.5836 78.3621 14.8139 77.1833 14.8139C75.7857 14.8139 74.7284 14.426 74.0235 13.6622C73.3065 12.8985 72.954 11.7589 72.954 10.2557C72.954 8.81307 73.3065 7.69776 74.0235 6.90978C74.7405 6.12179 75.7371 5.70961 77.0131 5.70961C78.0948 5.70961 78.9212 6.01268 79.4924 6.61883C80.0757 7.22497 80.3552 8.0857 80.3552 9.18888C80.3552 9.72229 80.3066 10.2072 80.2215 10.6315H74.5704V10.6194ZM76.9159 6.97039C76.1989 6.97039 75.6399 7.1886 75.251 7.60078C74.8499 8.02508 74.6312 8.65547 74.5704 9.49195H78.8118C78.824 9.40709 78.824 9.2495 78.824 9.05553C78.824 8.36452 78.666 7.84324 78.3379 7.49168C78.0219 7.15223 77.5479 6.97039 76.9159 6.97039Z", + "fill": "white" + }, + "children": [] + }, + { + "type": "element", + "name": "path", + "attributes": { + "d": "M86.9421 14.3532C86.3831 14.5715 85.7511 14.6806 85.0584 14.6806C83.4421 14.6806 82.64 13.8804 82.64 12.2681V7.27346H81.0722V6.1824L82.6886 5.97631L82.9438 3.52749H84.3171V5.93994H86.8692V7.26134H84.3171V12.1832C84.3171 12.6075 84.4143 12.8985 84.5966 13.0682C84.7789 13.2379 85.107 13.3228 85.5567 13.3228C86.0185 13.3228 86.4803 13.2622 86.93 13.1531V14.3532H86.9421Z", + "fill": "white" + }, + "children": [] + }, + { + "type": "element", + "name": "path", + "attributes": { + "d": "M88.0967 5.95207H89.5064L89.6644 6.83704C90.5273 6.0733 91.4874 5.69749 92.5447 5.69749C93.6506 5.69749 94.5135 6.09754 95.1454 6.89765C95.7774 7.69776 96.0933 8.7767 96.0933 10.1466C96.0933 11.5407 95.7531 12.656 95.0846 13.4925C94.4162 14.329 93.5291 14.7533 92.411 14.7533C91.3901 14.7533 90.5151 14.4139 89.7738 13.7471V18.0628H88.0967V5.95207ZM92.0585 7.05525C91.2564 7.05525 90.4908 7.30983 89.7738 7.83112V12.5712C90.5151 13.1167 91.2564 13.3834 92.0221 13.3834C93.5898 13.3834 94.3676 12.3287 94.3676 10.2315C94.3676 9.15251 94.1732 8.36453 93.7964 7.84324C93.4318 7.32196 92.8485 7.05525 92.0585 7.05525Z", + "fill": "white" + }, + "children": [] + }, + { + "type": "element", + "name": "path", + "attributes": { + "d": "M100.711 14.4381C100.335 14.5715 99.9337 14.6442 99.484 14.6442C98.8885 14.6442 98.4267 14.4745 98.1107 14.1229C97.7948 13.7835 97.6368 13.2864 97.6368 12.6439V2H99.326V12.5348C99.326 12.7894 99.3746 12.9834 99.484 13.1046C99.5934 13.2258 99.7757 13.2864 100.019 13.2864C100.25 13.2864 100.481 13.2743 100.711 13.2379V14.4381Z", + "fill": "white" + }, + "children": [] + }, + { + "type": "element", + "name": "path", + "attributes": { + "d": "M107.225 14.5593L107.092 13.6744C106.679 14.0259 106.229 14.2926 105.743 14.4866C105.245 14.6806 104.758 14.7775 104.272 14.7775C103.47 14.7775 102.826 14.5472 102.34 14.0865C101.854 13.6259 101.611 13.0197 101.611 12.2439C101.611 11.4195 101.902 10.7527 102.498 10.2678C103.093 9.77078 103.883 9.52832 104.88 9.52832C105.536 9.52832 106.253 9.62531 107.019 9.81927V8.70397C107.019 8.09782 106.885 7.6614 106.606 7.41894C106.326 7.16436 105.852 7.04313 105.184 7.04313C104.224 7.04313 103.227 7.21285 102.194 7.56441V6.37637C102.607 6.15816 103.106 6.00056 103.689 5.87933C104.284 5.7581 104.88 5.69749 105.475 5.69749C106.557 5.69749 107.347 5.9157 107.857 6.36425C108.368 6.81279 108.623 7.49168 108.623 8.41302V14.5593H107.225ZM104.673 13.5046C105.439 13.5046 106.229 13.2137 107.019 12.6439V10.9103C106.423 10.7649 105.828 10.6921 105.22 10.6921C103.944 10.6921 103.3 11.1892 103.3 12.1711C103.3 12.5954 103.422 12.9349 103.652 13.1652C103.896 13.3834 104.236 13.5046 104.673 13.5046Z", + "fill": "white" + }, + "children": [] + }, + { + "type": "element", + "name": "path", + "attributes": { + "d": "M116.571 14.232C115.915 14.5715 115.149 14.7412 114.286 14.7412C112.95 14.7412 111.929 14.3532 111.212 13.5895C110.507 12.8258 110.142 11.7226 110.142 10.2678C110.142 8.82519 110.507 7.72201 111.236 6.93402C111.965 6.14603 112.998 5.7581 114.335 5.7581C115.101 5.7581 115.805 5.9157 116.474 6.23089V7.43106C115.83 7.22497 115.198 7.12799 114.566 7.12799C113.618 7.12799 112.925 7.37045 112.512 7.85536C112.087 8.34028 111.88 9.10402 111.88 10.1587V10.3769C111.88 11.4074 112.099 12.159 112.512 12.6439C112.937 13.1288 113.606 13.3713 114.529 13.3713C115.137 13.3713 115.805 13.2622 116.535 13.0318V14.232H116.571Z", + "fill": "white" + }, + "children": [] + }, + { + "type": "element", + "name": "path", + "attributes": { + "d": "M118.965 10.6194C118.99 11.5892 119.233 12.3166 119.694 12.7773C120.156 13.2379 120.861 13.4683 121.833 13.4683C122.733 13.4683 123.644 13.2985 124.568 12.947V14.1472C123.754 14.5836 122.757 14.8139 121.578 14.8139C120.181 14.8139 119.123 14.426 118.418 13.6622C117.701 12.8985 117.349 11.7589 117.349 10.2557C117.349 8.81307 117.701 7.69776 118.418 6.90978C119.135 6.12179 120.132 5.70961 121.408 5.70961C122.49 5.70961 123.316 6.01268 123.887 6.61883C124.471 7.22497 124.75 8.0857 124.75 9.18888C124.75 9.72229 124.701 10.2072 124.616 10.6315H118.965V10.6194ZM121.311 6.97039C120.594 6.97039 120.035 7.1886 119.646 7.60078C119.245 8.02508 119.026 8.65547 118.965 9.49195H123.207C123.219 9.40709 123.219 9.2495 123.219 9.05553C123.219 8.36452 123.061 7.84324 122.733 7.49168C122.405 7.15223 121.931 6.97039 121.311 6.97039Z", + "fill": "white" + }, + "children": [] + }, + { + "type": "element", + "name": "path", + "attributes": { + "d": "M27.0036 14.8139C26.4567 14.8139 25.922 14.7533 25.3994 14.6321C24.8768 14.5108 24.4758 14.3775 24.1962 14.2199C24.0261 14.1229 23.9167 14.0259 23.8803 13.9289C23.8317 13.832 23.8195 13.735 23.8195 13.638V13.1167C23.8195 12.8985 23.8924 12.7894 24.0504 12.7894C24.1112 12.7894 24.1719 12.8015 24.2449 12.8258C24.3056 12.85 24.4029 12.8864 24.5122 12.9349C24.8647 13.0925 25.2414 13.2137 25.6546 13.2985C26.0678 13.3834 26.481 13.4198 26.8942 13.4198C27.5505 13.4198 28.0487 13.3107 28.4133 13.0803C28.7658 12.85 28.9481 12.5227 28.9481 12.0984C28.9481 11.8074 28.8508 11.565 28.6686 11.371C28.4862 11.177 28.1338 10.9952 27.6234 10.8255L26.1164 10.3527C25.3508 10.1102 24.8039 9.75866 24.4515 9.29799C24.1112 8.83732 23.9289 8.34028 23.9289 7.79475C23.9289 7.35832 24.0261 6.97039 24.2084 6.64307C24.3907 6.31575 24.6459 6.0248 24.9497 5.79447C25.2536 5.56413 25.6182 5.38229 26.0313 5.26106C26.4446 5.13983 26.8821 5.07922 27.3439 5.07922C27.5748 5.07922 27.8057 5.09134 28.0487 5.12771C28.2797 5.16408 28.5106 5.20045 28.7172 5.24894C28.9238 5.29743 29.1304 5.34592 29.3127 5.40654C29.495 5.46715 29.6408 5.52777 29.7502 5.58838C29.896 5.67324 29.9932 5.7581 30.054 5.84296C30.1148 5.92782 30.1391 6.03693 30.1391 6.1824V6.66732C30.1391 6.88553 30.0661 6.99464 29.9082 6.99464C29.8231 6.99464 29.6894 6.95827 29.5071 6.87341C28.9116 6.6067 28.2432 6.47335 27.514 6.47335C26.9185 6.47335 26.4567 6.57033 26.1286 6.7643C25.8004 6.95827 25.6425 7.26134 25.6425 7.68564C25.6425 7.97659 25.7397 8.21905 25.9463 8.42514C26.1529 8.61911 26.5296 8.81307 27.0887 8.99492L28.5592 9.46771C29.3127 9.71017 29.8474 10.0375 30.1634 10.4618C30.4793 10.8861 30.6495 11.371 30.6495 11.9165C30.6495 12.3651 30.5644 12.7651 30.3821 13.1167C30.1998 13.4683 29.9446 13.7835 29.6286 14.038C29.3127 14.2926 28.9238 14.4866 28.4741 14.6199C28.0244 14.7412 27.5383 14.8139 27.0036 14.8139ZM13.6718 14.5351C13.4895 14.5351 13.3558 14.4987 13.2707 14.4381C13.1856 14.3775 13.1127 14.232 13.052 14.0259L10.6214 6.01268C10.5606 5.80659 10.5363 5.67324 10.5363 5.6005C10.5363 5.43078 10.6214 5.34592 10.7915 5.34592H11.8124C12.0068 5.34592 12.1405 5.38229 12.2256 5.4429C12.2985 5.50352 12.3714 5.64899 12.4322 5.85508L14.1822 12.7045L15.7742 5.85508C15.8228 5.64899 15.8836 5.51564 15.9687 5.4429C16.0538 5.38229 16.1874 5.34592 16.3819 5.34592H17.2204C17.4149 5.34592 17.5486 5.38229 17.6336 5.4429C17.7187 5.50352 17.7795 5.64899 17.8281 5.85508L19.4687 12.8015L21.2674 5.85508C21.3281 5.64899 21.4011 5.51564 21.474 5.4429C21.5469 5.38229 21.6927 5.34592 21.8872 5.34592H22.8473C23.0174 5.34592 23.1025 5.43078 23.1025 5.6005C23.1025 5.64899 23.0903 5.69749 23.0903 5.7581C23.0781 5.81871 23.0538 5.90357 23.0174 6.01268L20.5138 14.0259C20.4531 14.232 20.3802 14.3654 20.2951 14.4381C20.21 14.4987 20.0763 14.5351 19.894 14.5351H19.0069C18.8124 14.5351 18.6787 14.4987 18.5937 14.426C18.5086 14.3532 18.4478 14.2199 18.3992 14.0138L16.7829 7.3462L15.1787 14.0138C15.1301 14.2199 15.0693 14.3532 14.9842 14.426C14.8992 14.4987 14.7655 14.5351 14.571 14.5351H13.6718ZM5.32267 13.4077C5.66296 13.4077 6.0154 13.347 6.39214 13.2137C6.76888 13.0925 7.09701 12.8621 7.37653 12.5469C7.54667 12.353 7.6682 12.1347 7.72897 11.8802C7.78973 11.6377 7.82619 11.3346 7.82619 10.9831V10.5466C7.52237 10.4739 7.20639 10.4133 6.86611 10.3769C6.53797 10.3406 6.20984 10.3163 5.89387 10.3163C5.20114 10.3163 4.69072 10.4497 4.35044 10.7285C4.01015 11.0073 3.84001 11.4074 3.84001 11.9287C3.84001 12.4136 3.96154 12.7773 4.21675 13.0197C4.49627 13.2864 4.84871 13.4077 5.32267 13.4077ZM9.53976 11.8317C9.53976 12.2196 9.57622 12.5227 9.66129 12.753C9.73421 12.9834 9.85574 13.2258 10.0016 13.4925C10.0502 13.5774 10.0745 13.6501 10.0745 13.7228C10.0745 13.832 10.0137 13.9289 9.88005 14.0259L9.21163 14.4866C9.11441 14.5472 9.02934 14.5715 8.94427 14.5715C8.83489 14.5715 8.73767 14.523 8.64044 14.426C8.49461 14.2805 8.37308 14.1229 8.2637 13.9411C8.16647 13.7713 8.0571 13.5653 7.94772 13.3349C7.13347 14.2926 6.11262 14.7654 4.89732 14.7654C4.0223 14.7654 3.32959 14.523 2.83131 14.0259C2.32089 13.5289 2.06567 12.8621 2.06567 12.0378C2.06567 11.1528 2.38165 10.4497 3.01361 9.90413C3.64556 9.37073 4.49627 9.0919 5.55358 9.0919C5.90602 9.0919 6.27061 9.11614 6.64735 9.17676C7.02409 9.22525 7.42514 9.31011 7.83834 9.40709V8.64335C7.83834 7.85536 7.68036 7.30983 7.35222 6.98251C7.02409 6.66732 6.46506 6.4976 5.66296 6.4976C5.29837 6.4976 4.92163 6.54609 4.54488 6.63095C4.16814 6.71581 3.7914 6.83704 3.42681 6.98251C3.25667 7.05525 3.13514 7.10374 3.06222 7.11587C2.9893 7.12799 2.94069 7.14011 2.90423 7.14011C2.75839 7.14011 2.68548 7.031 2.68548 6.81279V6.30363C2.68548 6.13391 2.70978 6.01268 2.75839 5.93994C2.80701 5.86721 2.90423 5.79447 3.05007 5.72173C3.41466 5.53989 3.85216 5.38229 4.36259 5.24894C4.87301 5.11559 5.40775 5.05497 5.97894 5.05497C7.21854 5.05497 8.11786 5.3338 8.70121 5.90357C9.2724 6.46123 9.56407 7.30983 9.56407 8.44938V11.8317H9.53976Z", + "fill": "white" + }, + "children": [] + }, + { + "type": "element", + "name": "path", + "attributes": { + "d": "M28.9723 19.8449C25.5573 22.3665 20.5989 23.7 16.3332 23.7C10.3539 23.7 4.97014 21.4936 0.886731 17.8204C0.570753 17.5294 0.850272 17.1415 1.23917 17.3597C5.63855 19.9177 11.0709 21.4451 16.6978 21.4451C20.4895 21.4451 24.658 20.6572 28.4862 19.0448C29.0573 18.8023 29.5313 19.4327 28.9723 19.8449Z", + "fill": "#FF9900" + }, + "children": [] + }, + { + "type": "element", + "name": "path", + "attributes": { + "d": "M30.3942 18.2205C29.9567 17.6628 27.5018 17.9537 26.3958 18.0871C26.0677 18.1235 26.0069 17.8325 26.3108 17.6264C28.2674 16.2565 31.4758 16.6566 31.8525 17.1051C32.2293 17.5658 31.7553 20.7784 29.9202 22.3059C29.6407 22.5362 29.3733 22.415 29.4949 22.0998C29.9081 21.0815 30.8317 18.7902 30.3942 18.2205Z", + "fill": "#FF9900" + }, + "children": [] + } + ] + }, + { + "type": "element", + "name": "defs", + "attributes": {}, + "children": [ + { + "type": "element", + "name": "clipPath", + "attributes": { + "id": "clip0_394_42756" + }, + "children": [ + { + "type": "element", + "name": "rect", + "attributes": { + "width": "124.5", + "height": "24", + "fill": "white", + "transform": "translate(0.75)" + }, + "children": [] + } + ] + } + ] + } + ] + }, + "name": "AwsMarketplace" +} \ No newline at end of file diff --git a/web/app/components/base/icons/src/public/billing/AwsMarketplace.tsx b/web/app/components/base/icons/src/public/billing/AwsMarketplace.tsx new file mode 100644 index 0000000000..818dbbc458 --- /dev/null +++ b/web/app/components/base/icons/src/public/billing/AwsMarketplace.tsx @@ -0,0 +1,16 @@ +// GENERATE BY script +// DON NOT EDIT IT MANUALLY + +import * as React from 'react' +import data from './AwsMarketplace.json' +import IconBase from '@/app/components/base/icons/IconBase' +import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase' + +const Icon = React.forwardRef, Omit>(( + props, + ref, +) => ) + +Icon.displayName = 'AwsMarketplace' + +export default Icon diff --git a/web/app/components/base/icons/src/public/billing/Azure.json b/web/app/components/base/icons/src/public/billing/Azure.json new file mode 100644 index 0000000000..ad4cd429a6 --- /dev/null +++ b/web/app/components/base/icons/src/public/billing/Azure.json @@ -0,0 +1,193 @@ +{ + "icon": { + "type": "element", + "isRootNode": true, + "name": "svg", + "attributes": { + "width": "21", + "height": "20", + "viewBox": "0 0 21 20", + "fill": "none", + "xmlns": "http://www.w3.org/2000/svg" + }, + "children": [ + { + "type": "element", + "name": "g", + "attributes": { + "id": "Group 5" + }, + "children": [ + { + "type": "element", + "name": "path", + "attributes": { + "id": "Vector", + "d": "M7.08403 0.812966H12.8543L6.86419 18.5609C6.80263 18.7433 6.68542 18.9018 6.52907 19.0141C6.37271 19.1263 6.18509 19.1867 5.99261 19.1868H1.50193C1.35609 19.1868 1.21234 19.1521 1.08258 19.0855C0.952814 19.019 0.840765 18.9225 0.755699 18.804C0.670633 18.6855 0.614995 18.5485 0.593389 18.4043C0.571782 18.2601 0.584829 18.1128 0.631448 17.9746L6.21222 1.43879C6.27376 1.25634 6.39099 1.09779 6.54739 0.985482C6.70379 0.873171 6.89148 0.812976 7.08403 0.812966Z", + "fill": "url(#paint0_linear_644_3772)" + }, + "children": [] + }, + { + "type": "element", + "name": "path", + "attributes": { + "id": "Vector_2", + "d": "M15.469 12.7173H6.31874C6.23367 12.7173 6.15054 12.7428 6.08019 12.7906C6.00984 12.8384 5.95552 12.9063 5.92431 12.9855C5.8931 13.0646 5.88644 13.1513 5.90521 13.2343C5.92398 13.3173 5.96731 13.3927 6.02954 13.4506L11.9093 18.9386C12.0805 19.0983 12.3059 19.187 12.54 19.187H17.7212L15.469 12.7173Z", + "fill": "#0078D4" + }, + "children": [] + }, + { + "type": "element", + "name": "path", + "attributes": { + "id": "Vector_3", + "d": "M7.08432 0.813056C6.88967 0.812309 6.69988 0.873821 6.54267 0.988606C6.38547 1.10339 6.26908 1.26543 6.21052 1.45107L0.638609 17.9596C0.588854 18.0983 0.573233 18.2469 0.593069 18.3929C0.612904 18.5389 0.667613 18.678 0.752567 18.7984C0.83752 18.9188 0.950219 19.0169 1.08113 19.0845C1.21204 19.1522 1.35731 19.1873 1.50466 19.1869H6.11124C6.28281 19.1562 6.44316 19.0806 6.57593 18.9676C6.7087 18.8547 6.80911 18.7086 6.86692 18.5442L7.97807 15.2695L11.9471 18.9715C12.1134 19.109 12.3221 19.1851 12.5379 19.1869H17.6998L15.4359 12.7172L8.83614 12.7188L12.8754 0.813056H7.08432Z", + "fill": "url(#paint1_linear_644_3772)" + }, + "children": [] + }, + { + "type": "element", + "name": "path", + "attributes": { + "id": "Vector_4", + "d": "M14.4539 1.43799C14.3925 1.25583 14.2754 1.09755 14.1193 0.985434C13.9631 0.87332 13.7757 0.813027 13.5835 0.813049H7.15259C7.34482 0.81306 7.53221 0.873366 7.68837 0.985475C7.84453 1.09758 7.96159 1.25585 8.02307 1.43799L13.6041 17.9744C13.6507 18.1126 13.6638 18.26 13.6422 18.4042C13.6206 18.5485 13.565 18.6856 13.4799 18.8041C13.3949 18.9226 13.2828 19.0191 13.153 19.0857C13.0232 19.1523 12.8795 19.1871 12.7336 19.1871H19.1647C19.3105 19.187 19.4543 19.1523 19.584 19.0856C19.7138 19.019 19.8258 18.9225 19.9109 18.804C19.9959 18.6855 20.0515 18.5484 20.0731 18.4042C20.0947 18.2599 20.0816 18.1126 20.0349 17.9744L14.4539 1.43799Z", + "fill": "url(#paint2_linear_644_3772)" + }, + "children": [] + } + ] + }, + { + "type": "element", + "name": "defs", + "attributes": {}, + "children": [ + { + "type": "element", + "name": "linearGradient", + "attributes": { + "id": "paint0_linear_644_3772", + "x1": "9.1871", + "y1": "2.17453", + "x2": "3.19457", + "y2": "19.878", + "gradientUnits": "userSpaceOnUse" + }, + "children": [ + { + "type": "element", + "name": "stop", + "attributes": { + "stop-color": "#114A8B" + }, + "children": [] + }, + { + "type": "element", + "name": "stop", + "attributes": { + "offset": "1", + "stop-color": "#0669BC" + }, + "children": [] + } + ] + }, + { + "type": "element", + "name": "linearGradient", + "attributes": { + "id": "paint1_linear_644_3772", + "x1": "11.0593", + "y1": "10.4249", + "x2": "9.67315", + "y2": "10.8936", + "gradientUnits": "userSpaceOnUse" + }, + "children": [ + { + "type": "element", + "name": "stop", + "attributes": { + "stop-opacity": "0.3" + }, + "children": [] + }, + { + "type": "element", + "name": "stop", + "attributes": { + "offset": "0.071", + "stop-opacity": "0.2" + }, + "children": [] + }, + { + "type": "element", + "name": "stop", + "attributes": { + "offset": "0.321", + "stop-opacity": "0.1" + }, + "children": [] + }, + { + "type": "element", + "name": "stop", + "attributes": { + "offset": "0.623", + "stop-opacity": "0.05" + }, + "children": [] + }, + { + "type": "element", + "name": "stop", + "attributes": { + "offset": "1", + "stop-opacity": "0" + }, + "children": [] + } + ] + }, + { + "type": "element", + "name": "linearGradient", + "attributes": { + "id": "paint2_linear_644_3772", + "x1": "10.2966", + "y1": "1.65827", + "x2": "16.8746", + "y2": "19.1833", + "gradientUnits": "userSpaceOnUse" + }, + "children": [ + { + "type": "element", + "name": "stop", + "attributes": { + "stop-color": "#3CCBF4" + }, + "children": [] + }, + { + "type": "element", + "name": "stop", + "attributes": { + "offset": "1", + "stop-color": "#2892DF" + }, + "children": [] + } + ] + } + ] + } + ] + }, + "name": "Azure" +} \ No newline at end of file diff --git a/web/app/components/base/icons/src/public/billing/Azure.tsx b/web/app/components/base/icons/src/public/billing/Azure.tsx new file mode 100644 index 0000000000..88bcedcd83 --- /dev/null +++ b/web/app/components/base/icons/src/public/billing/Azure.tsx @@ -0,0 +1,16 @@ +// GENERATE BY script +// DON NOT EDIT IT MANUALLY + +import * as React from 'react' +import data from './Azure.json' +import IconBase from '@/app/components/base/icons/IconBase' +import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase' + +const Icon = React.forwardRef, Omit>(( + props, + ref, +) => ) + +Icon.displayName = 'Azure' + +export default Icon diff --git a/web/app/components/base/icons/src/public/billing/Buildings.json b/web/app/components/base/icons/src/public/billing/Buildings.json new file mode 100644 index 0000000000..f9dd338328 --- /dev/null +++ b/web/app/components/base/icons/src/public/billing/Buildings.json @@ -0,0 +1,39 @@ +{ + "icon": { + "type": "element", + "isRootNode": true, + "name": "svg", + "attributes": { + "width": "29", + "height": "28", + "viewBox": "0 0 29 28", + "fill": "none", + "xmlns": "http://www.w3.org/2000/svg" + }, + "children": [ + { + "type": "element", + "name": "g", + "attributes": { + "id": "buildings" + }, + "children": [ + { + "type": "element", + "name": "path", + "attributes": { + "id": "Vector", + "d": "M5.04134 22.4583H17.2913M5.04134 22.4583V6.70833C5.04134 5.41967 6.08601 4.375 7.37467 4.375H14.958C16.2467 4.375 17.2913 5.41967 17.2913 6.70833V9.33333M5.04134 22.4583H2.70801M17.2913 22.4583V9.33333M17.2913 22.4583H24.2913M17.2913 9.33333H21.958C23.2467 9.33333 24.2913 10.378 24.2913 11.6667V22.4583M24.2913 22.4583H26.6247M12.6247 10.2083H9.70801M9.70801 14.875H12.6247", + "stroke": "white", + "stroke-width": "1.5", + "stroke-linecap": "round", + "stroke-linejoin": "round" + }, + "children": [] + } + ] + } + ] + }, + "name": "Buildings" +} \ No newline at end of file diff --git a/web/app/components/base/icons/src/public/billing/Buildings.tsx b/web/app/components/base/icons/src/public/billing/Buildings.tsx new file mode 100644 index 0000000000..2985113860 --- /dev/null +++ b/web/app/components/base/icons/src/public/billing/Buildings.tsx @@ -0,0 +1,16 @@ +// GENERATE BY script +// DON NOT EDIT IT MANUALLY + +import * as React from 'react' +import data from './Buildings.json' +import IconBase from '@/app/components/base/icons/IconBase' +import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase' + +const Icon = React.forwardRef, Omit>(( + props, + ref, +) => ) + +Icon.displayName = 'Buildings' + +export default Icon diff --git a/web/app/components/base/icons/src/public/billing/Diamond.json b/web/app/components/base/icons/src/public/billing/Diamond.json new file mode 100644 index 0000000000..69ab74606b --- /dev/null +++ b/web/app/components/base/icons/src/public/billing/Diamond.json @@ -0,0 +1,39 @@ +{ + "icon": { + "type": "element", + "isRootNode": true, + "name": "svg", + "attributes": { + "width": "29", + "height": "28", + "viewBox": "0 0 29 28", + "fill": "none", + "xmlns": "http://www.w3.org/2000/svg" + }, + "children": [ + { + "type": "element", + "name": "g", + "attributes": { + "id": "diamond" + }, + "children": [ + { + "type": "element", + "name": "path", + "attributes": { + "id": "Vector", + "d": "M10.2499 9.04167L7.62486 11.6667L10.2499 14.2917M15.9831 22.8501L25.4978 13.3353C26.4164 12.4168 26.408 10.925 25.4791 10.017L20.3883 5.03988C19.9523 4.61365 19.3668 4.375 18.7571 4.375H9.90929C9.29958 4.375 8.71408 4.61365 8.27811 5.03988L3.18727 10.017C2.25844 10.925 2.25002 12.4168 3.16852 13.3353L12.6833 22.8501C13.5945 23.7613 15.0719 23.7613 15.9831 22.8501Z", + "stroke": "#DC6803", + "stroke-width": "1.5", + "stroke-linecap": "round", + "stroke-linejoin": "round" + }, + "children": [] + } + ] + } + ] + }, + "name": "Diamond" +} \ No newline at end of file diff --git a/web/app/components/base/icons/src/public/billing/Diamond.tsx b/web/app/components/base/icons/src/public/billing/Diamond.tsx new file mode 100644 index 0000000000..adc00b9b6d --- /dev/null +++ b/web/app/components/base/icons/src/public/billing/Diamond.tsx @@ -0,0 +1,16 @@ +// GENERATE BY script +// DON NOT EDIT IT MANUALLY + +import * as React from 'react' +import data from './Diamond.json' +import IconBase from '@/app/components/base/icons/IconBase' +import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase' + +const Icon = React.forwardRef, Omit>(( + props, + ref, +) => ) + +Icon.displayName = 'Diamond' + +export default Icon diff --git a/web/app/components/base/icons/src/public/billing/GoogleCloud.json b/web/app/components/base/icons/src/public/billing/GoogleCloud.json new file mode 100644 index 0000000000..244f05776f --- /dev/null +++ b/web/app/components/base/icons/src/public/billing/GoogleCloud.json @@ -0,0 +1,66 @@ +{ + "icon": { + "type": "element", + "isRootNode": true, + "name": "svg", + "attributes": { + "width": "22", + "height": "18", + "viewBox": "0 0 22 18", + "fill": "none", + "xmlns": "http://www.w3.org/2000/svg" + }, + "children": [ + { + "type": "element", + "name": "g", + "attributes": { + "id": "Group 4" + }, + "children": [ + { + "type": "element", + "name": "path", + "attributes": { + "id": "Vector", + "d": "M14.1587 5.40399H14.7992L16.6247 3.57855L16.7143 2.80353C15.6686 1.88054 14.4049 1.23936 13.0424 0.94058C11.68 0.641797 10.2639 0.695269 8.92788 1.09594C7.59187 1.49662 6.38006 2.23127 5.40691 3.2305C4.43376 4.22973 3.73142 5.46055 3.36621 6.80669C3.56957 6.72334 3.79485 6.70982 4.00672 6.76826L7.6576 6.16619C7.6576 6.16619 7.84334 5.85874 7.93942 5.87796C8.72169 5.01883 9.80276 4.4912 10.9613 4.40309C12.1199 4.31497 13.2683 4.67304 14.1715 5.40399H14.1587Z", + "fill": "#EA4335" + }, + "children": [] + }, + { + "type": "element", + "name": "path", + "attributes": { + "id": "Vector_2", + "d": "M19.225 6.80663C18.8055 5.2615 17.944 3.87244 16.7463 2.80988L14.1843 5.3719C14.7182 5.80819 15.1461 6.36003 15.4357 6.9858C15.7253 7.61158 15.869 8.29494 15.856 8.98435V9.43911C16.1554 9.43911 16.4519 9.49809 16.7286 9.61268C17.0052 9.72727 17.2566 9.89523 17.4683 10.107C17.6801 10.3187 17.848 10.5701 17.9626 10.8467C18.0772 11.1234 18.1362 11.4199 18.1362 11.7193C18.1362 12.0187 18.0772 12.3153 17.9626 12.5919C17.848 12.8685 17.6801 13.1199 17.4683 13.3316C17.2566 13.5434 17.0052 13.7113 16.7286 13.8259C16.4519 13.9405 16.1554 13.9995 15.856 13.9995H11.2956L10.8408 14.4607V17.1956L11.2956 17.6504H15.856C17.1295 17.6603 18.3723 17.2601 19.4007 16.5089C20.429 15.7577 21.1883 14.6954 21.5662 13.4792C21.944 12.2631 21.9204 10.9576 21.4988 9.75589C21.0771 8.55419 20.2799 7.52012 19.225 6.80663Z", + "fill": "#4285F4" + }, + "children": [] + }, + { + "type": "element", + "name": "path", + "attributes": { + "id": "Vector_3", + "d": "M6.72886 17.625H11.2893V13.9741H6.72886C6.40396 13.9741 6.08286 13.9042 5.78732 13.7692L5.14681 13.9677L3.30856 15.7932L3.14844 16.4337C4.17929 17.2121 5.43714 17.6306 6.72886 17.625Z", + "fill": "#34A853" + }, + "children": [] + }, + { + "type": "element", + "name": "path", + "attributes": { + "id": "Vector_4", + "d": "M6.7289 5.78196C5.49325 5.78934 4.29076 6.18247 3.28939 6.90643C2.28801 7.6304 1.53775 8.64904 1.1434 9.8201C0.749049 10.9912 0.730302 12.2561 1.08978 13.4384C1.44925 14.6206 2.16899 15.661 3.14848 16.4143L5.79377 13.7691C5.4576 13.6172 5.16331 13.386 4.93613 13.0954C4.70895 12.8048 4.55567 12.4634 4.48944 12.1005C4.42321 11.7376 4.446 11.3641 4.55587 11.0119C4.66574 10.6598 4.8594 10.3396 5.12024 10.0788C5.38107 9.81792 5.7013 9.62426 6.05343 9.51439C6.40557 9.40452 6.7791 9.38172 7.14198 9.44795C7.50487 9.51418 7.84626 9.66747 8.13688 9.89465C8.4275 10.1218 8.65867 10.4161 8.81055 10.7523L11.4558 8.10699C10.9006 7.38115 10.185 6.79357 9.36499 6.39023C8.54496 5.98688 7.64275 5.7787 6.7289 5.78196Z", + "fill": "#FBBC05" + }, + "children": [] + } + ] + } + ] + }, + "name": "GoogleCloud" +} \ No newline at end of file diff --git a/web/app/components/base/icons/src/public/billing/GoogleCloud.tsx b/web/app/components/base/icons/src/public/billing/GoogleCloud.tsx new file mode 100644 index 0000000000..5c112bd131 --- /dev/null +++ b/web/app/components/base/icons/src/public/billing/GoogleCloud.tsx @@ -0,0 +1,16 @@ +// GENERATE BY script +// DON NOT EDIT IT MANUALLY + +import * as React from 'react' +import data from './GoogleCloud.json' +import IconBase from '@/app/components/base/icons/IconBase' +import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase' + +const Icon = React.forwardRef, Omit>(( + props, + ref, +) => ) + +Icon.displayName = 'GoogleCloud' + +export default Icon diff --git a/web/app/components/base/icons/src/public/billing/index.ts b/web/app/components/base/icons/src/public/billing/index.ts index 8a442a32c2..cc186bbd94 100644 --- a/web/app/components/base/icons/src/public/billing/index.ts +++ b/web/app/components/base/icons/src/public/billing/index.ts @@ -1,4 +1,9 @@ export { default as ArCube1 } from './ArCube1' +export { default as AwsMarketplace } from './AwsMarketplace' +export { default as Azure } from './Azure' +export { default as Buildings } from './Buildings' +export { default as Diamond } from './Diamond' +export { default as GoogleCloud } from './GoogleCloud' export { default as Group2 } from './Group2' export { default as Keyframe } from './Keyframe' export { default as SparklesSoft } from './SparklesSoft' diff --git a/web/app/components/billing/config.ts b/web/app/components/billing/config.ts index bc33b899e7..b88770b98a 100644 --- a/web/app/components/billing/config.ts +++ b/web/app/components/billing/config.ts @@ -7,6 +7,8 @@ export const contractSales = 'contractSales' export const unAvailable = 'unAvailable' export const contactSalesUrl = 'mailto:business@dify.ai' +export const getStartedWithCommunityUrl = 'https://github.com/langgenius/dify' +export const getWithPremiumUrl = 'https://aws.amazon.com/marketplace/pp/prodview-t22mebxzwjhu6' export const ALL_PLANS: Record = { sandbox: { diff --git a/web/app/components/billing/pricing/index.tsx b/web/app/components/billing/pricing/index.tsx index 056099e3b7..d3159911aa 100644 --- a/web/app/components/billing/pricing/index.tsx +++ b/web/app/components/billing/pricing/index.tsx @@ -5,6 +5,7 @@ import { createPortal } from 'react-dom' import { useTranslation } from 'react-i18next' import { RiArrowRightUpLine, RiCloseLine, RiCloudFill, RiTerminalBoxFill } from '@remixicon/react' import Link from 'next/link' +import { useKeyPress } from 'ahooks' import { Plan, SelfHostedPlan } from '../type' import TabSlider from '../../base/tab-slider' import SelectPlanRange, { PlanRange } from './select-plan-range' @@ -27,7 +28,9 @@ const Pricing: FC = ({ const canPay = isCurrentWorkspaceManager const [planRange, setPlanRange] = React.useState(PlanRange.monthly) - const [currentPlan, setCurrentPlan] = React.useState('self') + const [currentPlan, setCurrentPlan] = React.useState('cloud') + + useKeyPress(['esc'], onCancel) return createPortal(
= ({
-
+
cloud service
}, - { value: 'self', text:
self hosted
}]} + { value: 'cloud', text:
{t('billing.plansCommon.cloud')}
}, + { value: 'self', text:
{t('billing.plansCommon.self')}
}]} onChange={v => setCurrentPlan(v)} /> {currentPlan === 'cloud' && = ({
- Popular + {t('billing.plansCommon.mostPopular')}
}
{t(`${i18nPrefix}.description`)}
@@ -155,7 +155,7 @@ const PlanItem: FC = ({
{btnText} @@ -203,7 +203,7 @@ const PlanItem: FC = ({ /> } - label={[t(`billing.plansCommon.priority.${planInfo.documentProcessingPriority}`), t('billing.plansCommon.documentProcessingPriority')].join(' ')} + label={[t(`billing.plansCommon.priority.${planInfo.documentProcessingPriority}`), t('billing.plansCommon.documentProcessingPriority')].join('')} /> = ({ return (
{t('billing.plansCommon.yearlyTip')}
-
+
{t('billing.plansCommon.annualBilling')} - { + { onChange(v ? PlanRange.yearly : PlanRange.monthly) }} />
diff --git a/web/app/components/billing/pricing/self-hosted-plan-item.tsx b/web/app/components/billing/pricing/self-hosted-plan-item.tsx index 98faf2c688..80a9cd9af1 100644 --- a/web/app/components/billing/pricing/self-hosted-plan-item.tsx +++ b/web/app/components/billing/pricing/self-hosted-plan-item.tsx @@ -2,15 +2,15 @@ import type { FC, ReactNode } from 'react' import React from 'react' import { useTranslation } from 'react-i18next' -import { RiAsterisk, RiBrain2Line, RiBuildingLine, RiCheckLine, RiQuestionLine, RiVipDiamondLine } from '@remixicon/react' +import { RiArrowRightUpLine, RiAsterisk, RiBrain2Line, RiCheckLine, RiQuestionLine } from '@remixicon/react' import { SelfHostedPlan } from '../type' -import { contactSalesUrl } from '../config' +import { contactSalesUrl, getStartedWithCommunityUrl, getWithPremiumUrl } from '../config' import Toast from '../../base/toast' import Tooltip from '../../base/tooltip' -import { PlanRange } from './select-plan-range' +import { AwsMarketplace, Azure, Buildings, Diamond, GoogleCloud } from '../../base/icons/src/public/billing' +import type { PlanRange } from './select-plan-range' import cn from '@/utils/classnames' import { useAppContext } from '@/context/app-context' -import { fetchSubscriptionUrls } from '@/service/billing' type Props = { plan: SelfHostedPlan @@ -18,74 +18,13 @@ type Props = { canPay: boolean } -const AWSMarketplaceLogo = () => { - return - - - - - - - - - - - - - - - - - - - - - - -} - -const AzureIcon = () => { - return - - - - - - - - - - - - - - - - - - - - - - -} - -const GoogleCloudIcon = () => { - return - - - - - -} - -const KeyValue = ({ label, tooltip }: { icon: ReactNode; label: string; tooltip?: string }) => { +const KeyValue = ({ label, tooltip, textColor, tooltipIconColor }: { icon: ReactNode; label: string; tooltip?: string; textColor: string; tooltipIconColor: string }) => { return ( -
+
-
{label}
+
{label}
{tooltip && (
- +
)} @@ -104,41 +43,49 @@ const KeyValue = ({ label, tooltip }: { icon: ReactNode; label: string; tooltip? const style = { [SelfHostedPlan.community]: { icon: , + title: 'text-text-primary', + price: 'text-text-primary', + priceTip: 'text-text-tertiary', description: 'text-util-colors-gray-gray-600', + bg: 'border-effects-highlight-lightmode-off bg-background-section-burn', btnStyle: 'bg-components-button-secondary-bg hover:bg-components-button-secondary-bg-hover border-[0.5px] border-components-button-secondary-border text-text-primary', + values: 'text-text-secondary', + tooltipIconColor: 'text-text-tertiary', }, [SelfHostedPlan.premium]: { - icon: , + icon: , + title: 'text-text-primary', + price: 'text-text-primary', + priceTip: 'text-text-tertiary', description: 'text-text-warning', + bg: 'border-effects-highlight bg-background-section-burn', btnStyle: 'bg-third-party-aws hover:bg-third-party-aws-hover border border-components-button-primary-border text-text-primary-on-surface shadow-xs', + values: 'text-text-secondary', + tooltipIconColor: 'text-text-tertiary', }, [SelfHostedPlan.enterprise]: { - icon: , - description: '', - btnStyle: 'hover:shadow-lg hover:!text-white hover:!bg-[#F79009] hover:!border-[#DC6803] active:!text-white active:!bg-[#DC6803] active:!border-[#DC6803]', + icon: , + title: 'text-text-primary-on-surface', + price: 'text-text-primary-on-surface', + priceTip: 'text-text-primary-on-surface', + description: 'text-text-primary-on-surface', + bg: 'border-effects-highlight bg-[#155AEF] text-text-primary-on-surface', + btnStyle: 'bg-components-button-secondary-bg hover:bg-components-button-secondary-bg-hover border-[0.5px] border-components-button-secondary-border text-[#155AEF] shadow-xs', + values: 'text-text-primary-on-surface', + tooltipIconColor: 'text-text-primary-on-surface', }, } -const PlanItem: FC = ({ +const SelfHostedPlanItem: FC = ({ plan, - planRange, }) => { const { t } = useTranslation() const isFreePlan = plan === SelfHostedPlan.community const isPremiumPlan = plan === SelfHostedPlan.premium - const [loading, setLoading] = React.useState(false) const i18nPrefix = `billing.plans.${plan}` const isEnterprisePlan = plan === SelfHostedPlan.enterprise - const isYear = planRange === PlanRange.yearly const { isCurrentWorkspaceManager } = useAppContext() const features = t(`${i18nPrefix}.features`, { returnObjects: true }) as string[] - const handleGetPayUrl = async () => { - if (loading) - return - - if (isEnterprisePlan) { - window.location.href = contactSalesUrl - return - } + const handleGetPayUrl = () => { // Only workspace manager can buy plan if (!isCurrentWorkspaceManager) { Toast.notify({ @@ -148,65 +95,83 @@ const PlanItem: FC = ({ }) return } - setLoading(true) - try { - const res = await fetchSubscriptionUrls(plan, isYear ? 'year' : 'month') - // Adb Block additional tracking block the gtag, so we need to redirect directly - window.location.href = res.url + if (isFreePlan) { + window.location.href = getStartedWithCommunityUrl + return } - finally { - setLoading(false) + if (isPremiumPlan) { + window.location.href = getWithPremiumUrl + return } + + if (isEnterprisePlan) + window.location.href = contactSalesUrl } return ( -
-
- {style[plan].icon} -
-
{t(`${i18nPrefix}.name`)}
+
+
+
-
{t(`${i18nPrefix}.description`)}
+ {isEnterprisePlan &&
} + {isEnterprisePlan &&
}
-
-
-
{t(`${i18nPrefix}.price`)}
- {!isFreePlan &&
-
- {t(`${i18nPrefix}.priceTip`)} -
-
} +
+
+ {style[plan].icon} +
+
{t(`${i18nPrefix}.name`)}
+
+
{t(`${i18nPrefix}.description`)}
+
+
+
+
{t(`${i18nPrefix}.price`)}
+ {!isFreePlan &&
+
+ {t(`${i18nPrefix}.priceTip`)} +
+
} +
-
-
- {t(`${i18nPrefix}.btnText`)} -
-
{t(`${i18nPrefix}.includesTitle`)}
-
- {features.map(v => - } - label={v} - />)} -
- {isPremiumPlan &&
-
-
- -
-
- -
+
+ {t(`${i18nPrefix}.btnText`)} + {isPremiumPlan + &&
+
+ +
+ +
}
- {t('billing.plans.premium.comingSoon')} -
} +
{t(`${i18nPrefix}.includesTitle`)}
+
+ {features.map(v => + } + label={v} + />)} +
+ {isPremiumPlan &&
+
+
+ +
+
+ +
+
+ {t('billing.plans.premium.comingSoon')} +
} +
) } -export default React.memo(PlanItem) +export default React.memo(SelfHostedPlanItem) diff --git a/web/i18n/en-US/billing.ts b/web/i18n/en-US/billing.ts index e2e18b756f..29b2267118 100644 --- a/web/i18n/en-US/billing.ts +++ b/web/i18n/en-US/billing.ts @@ -14,6 +14,8 @@ const translation = { freeTrialTipSuffix: 'No credit card required', yearlyTip: 'Pay for 10 months, enjoy 1 Year!', mostPopular: 'Most Popular', + cloud: 'Cloud Service', + self: 'Self-Hosted', planRange: { monthly: 'Monthly', yearly: 'Yearly', @@ -41,7 +43,6 @@ const translation = { documents: '{{count}} Knowledge Documents', documentsTooltip: 'Quota on the number of documents imported from the Knowledge Data Source.', vectorSpace: '{{size}} Knowledge Data Storage', - vectorSpaceBillingTooltip: 'Each 1MB can store about 1.2million characters of vectorized data(estimated using OpenAI Embeddings, varies across models).', vectorSpaceTooltip: 'Documents with the High Quality indexing mode will consume Knowledge Data Storage resources. When Knowledge Data Storage reaches the limit, new documents will not be uploaded.', documentsRequestQuota: '{{count}}/min Knowledge Request Rate limit', documentsRequestQuotaTooltip: 'Indicates the number of queries per minute the system can handle with knowledge base support, used to measure query capacity and performance.', @@ -96,12 +97,10 @@ const translation = { professional: { name: 'Professional', description: 'For Independent Developers/Small Teams', - includesTitle: 'Everything in free plan, plus:', }, team: { name: 'Team', description: 'For Medium-sized Teams', - includesTitle: 'Everything in Professional plan, plus:', }, community: { name: 'Community', @@ -120,7 +119,7 @@ const translation = { description: 'For Mid-sized Organizations and Teams', price: 'Scalable', priceTip: 'Based on Cloud Marketplace', - btnText: 'Get Premium in AWS Marketplace', + btnText: 'Get Premium in', includesTitle: 'Everything from Community, plus:', comingSoon: 'Microsoft Azure & Google Cloud Support Coming Soon', features: [ diff --git a/web/i18n/ja-JP/billing.ts b/web/i18n/ja-JP/billing.ts index 6f90982506..dadd759dfd 100644 --- a/web/i18n/ja-JP/billing.ts +++ b/web/i18n/ja-JP/billing.ts @@ -8,9 +8,14 @@ const translation = { viewBilling: '請求とサブスクリプションの管理', buyPermissionDeniedTip: 'サブスクリプションするには、エンタープライズ管理者に連絡してください', plansCommon: { - title: 'あなた様に合ったプランを選択してください', - yearlyTip: '年間購読で2か月無料!', - mostPopular: '最も人気のある', + title: 'あなたのAIの旅を支える価格設定', + freeTrialTipPrefix: 'サインアップ後、', + freeTrialTip: '200回のOpenAIコールの無料に受け取る', + freeTrialTipSuffix: '。クレジットカード不要', + yearlyTip: '10ヶ月分支払って、1年間楽しもう!', + mostPopular: '人気', + cloud: 'クラウドサービス', + self: 'セルフホストサービス', planRange: { monthly: '月額', yearly: '年額', @@ -19,24 +24,29 @@ const translation = { year: '年', save: '節約 ', free: '無料', + annualBilling: '年次請求', + comparePlanAndFeatures: 'プランと機能を比較する', + priceTip: 'ワークスペース/', currentPlan: '現在のプラン', contractSales: '営業に連絡する', contractOwner: 'チームマネージャーに連絡する', startForFree: '無料で始める', - getStartedWith: '始める ', + getStarted: '始める', contactSales: '営業に連絡する', talkToSales: '営業と話す', - modelProviders: 'モデルプロバイダー', - teamMembers: 'チームメンバー', + modelProviders: 'OpenAI/Anthropic/Llama2/Azure OpenAI/Hugging Face/Replicateをサポート', + teamWorkspace: '{{count}}チームワークスペース', + teamMember_one: 'チームメンバー:{{count}}人', + teamMember_other: 'チームメンバー:{{count}}人', annotationQuota: 'アノテーション・クォータ', - buildApps: 'アプリを作成する', - vectorSpace: 'ベクトルスペース', - vectorSpaceBillingTooltip: '1MBあたり約120万文字のベクトル化データを保存できます(OpenAI Embeddingsを使用して推定され、モデルによって異なります)。', - vectorSpaceTooltip: 'ベクトルスペースは、LLMがデータを理解するために必要な長期記憶システムです。', - documentsUploadQuota: 'ドキュメント・アップロード・クォータ', - documentProcessingPriority: 'ドキュメント処理の優先度', - documentProcessingPriorityTip: 'より高いドキュメント処理の優先度をご希望の場合は、プランをアップグレードしてください。', - documentProcessingPriorityUpgrade: 'より高い精度と高速な速度でデータを処理します。', + buildApps: 'アプリの数:{{count}}個', + documents: '{{count}}の知識文書', + documentsTooltip: 'ナレッジデータソースからインポートされたドキュメントの数に対するクォータ。', + vectorSpace: '{{size}}の知識データストレージ', + vectorSpaceTooltip: '高品質インデックスモードのドキュメントは、Knowledge Data Storageのリソースを消費します。Knowledge Data Storageの上限に達すると、新しいドキュメントはアップロードされません。', + documentsRequestQuota: '{{count}}100/分のナレッジ リクエストのレート制限', + documentsRequestQuotaTooltip: 'システムがナレッジベースサポートで処理できる1分あたりのクエリ数を示し、クエリの容量とパフォーマンスを測定するために使用されます。、クエリの容量とパフォーマンスを測定するために使用されます。', + documentProcessingPriority: '文書処理', priority: { 'standard': '標準', 'priority': '優先', @@ -68,36 +78,75 @@ const translation = { member: 'メンバー', memberAfter: 'メンバー', messageRequest: { - title: 'メッセージクレジット', - tooltip: 'OpenAIモデルを使用したさまざまなプランのメッセージ呼び出しクォータ(gpt4を除く)。制限を超えるメッセージはOpenAI APIキーを使用します。', + title: '{{count}}メッセージ', + titlePerMonth: '{{count}}メッセージ/月', + tooltip: 'Open Alモデルを使用するさまざまなプランのメッセージ呼び出しクォータ。上限を超えるメッセージは、Open AI APIキーを使用します。', }, annotatedResponse: { - title: '注釈クォータ制限', - tooltip: '手動での編集と応答の注釈付けにより、アプリのカスタマイズ可能な高品質な質問応答機能が提供されます(チャットアプリのみ適用)。', + title: '{{count}}の注釈クォータ制限', + tooltip: '手動での回答の編集と注釈により、カスタマイズ可能な高品質の質問応答機能をアプリに提供します。(チャットアプリのみに適用)', }, ragAPIRequestTooltip: 'Difyのナレッジベース処理機能のみを呼び出すAPI呼び出しの数を指します。', receiptInfo: 'チームオーナーとチーム管理者のみが購読および請求情報を表示できます', }, plans: { sandbox: { - name: 'サンドボックス', - description: 'GPTの無料トライアル200回', - includesTitle: '含まれるもの:', + name: 'Sandbox', + description: 'コア機能を無料で試す', }, professional: { - name: 'プロフェッショナル', - description: '個人や小規模チーム向けにより多くのパワーを手頃な価格で提供します。', - includesTitle: '無料プランに加えて、次も含まれます:', + name: 'Professional', + description: '独立した開発者/小規模チーム向け', }, team: { - name: 'チーム', - description: '制限なく協力し、最高のパフォーマンスを楽しむ。', - includesTitle: 'プロフェッショナルプランに加えて、次も含まれます:', + name: 'Team', + description: '中規模チーム向け', + }, + community: { + name: 'Community', + description: '個人ユーザー、小規模チーム、または非営利プロジェクト向け', + price: '無料', + btnText: 'コミュニティを始めましょう', + includesTitle: '無料の機能:', + features: [ + 'すべてのコア機能がパブリック リポジトリでリリースされる', + '単一のワークスペース', + 'Difyオープンソースライセンスに準拠しています', + ], + }, + premium: { + name: 'Premium', + description: '中規模の組織やチーム向け', + price: 'スケーラブル', + priceTip: 'クラウドマーケットプレイスに基づく', + btnText: 'プレミアムを獲得する', + includesTitle: 'コミュニティからのすべてに加えて:', + comingSoon: 'Microsoft AzureとGoogle Cloudのアポートは近日公開', + features: [ + 'さまざまなクラウドプロバイダーによる自己管理の信頼性', + '単一のワークスペース', + 'カスタマイズ Webアプリのロゴやブランド', + '優先メールとチャットのサポート', + ], }, enterprise: { - name: 'エンタープライズ', - description: '大規模なミッションクリティカルシステムのためのフル機能とサポートを提供します。', - includesTitle: 'チームプランに加えて、次も含まれます:', + name: 'Enterprise', + description: 'エンタープライズグレードのセキュリティ、コンプライアンス、拡張性、制御、およびより高度な機能を必要とする企業向け', + price: 'カスタム', + priceTip: '年間契約のみ', + btnText: '営業担当者へのお問い合わせ', + includesTitle: 'プレミアムのすべてに加えて:', + features: [ + 'エンタープライズグレードのスケーラブルな導入ソリューション', + '商用ライセンスの認可', + 'エンタープライズ限定の機能', + '複数のワークスペースと企業の管理', + 'SSO', + 'Dify Partnersによる交渉済みのSLA', + '高度なセキュリティ', + 'Dify公式によるアップデートとメンテナンス', + '専門的な技術サポート', + ], }, }, vectorSpace: { diff --git a/web/i18n/zh-Hans/billing.ts b/web/i18n/zh-Hans/billing.ts index bc20839abc..5d2a4ef63c 100644 --- a/web/i18n/zh-Hans/billing.ts +++ b/web/i18n/zh-Hans/billing.ts @@ -8,9 +8,14 @@ const translation = { viewBilling: '管理账单及订阅', buyPermissionDeniedTip: '请联系企业管理员订阅', plansCommon: { - title: '选择适合您的套餐', - yearlyTip: '订阅年度计划可免费获得 2个月!', + title: '为您的 AI 之旅提供动力的定价套餐', + freeTrialTipPrefix: '注册即可', + freeTrialTip: '免费试用 200 个 OpenAI 消息额度', + freeTrialTipSuffix: '。无需信用卡', + yearlyTip: '支付 10 个月,享受 1 年!', mostPopular: '最受欢迎', + cloud: '云服务', + self: '自部署', planRange: { monthly: '按月', yearly: '按年', @@ -18,25 +23,30 @@ const translation = { month: '月', year: '年', save: '节省', + free: '免费', + annualBilling: '按年计费', + comparePlanAndFeatures: '对比套餐 & 功能特性', + priceTip: '每个团队空间/', currentPlan: '当前计划', contractSales: '联系销售', contractOwner: '联系团队管理员', - free: '免费', startForFree: '免费开始', - getStartedWith: '开始使用', + getStarted: '立即开始', contactSales: '联系销售', talkToSales: '联系销售', - modelProviders: '支持的模型提供商', - teamMembers: '团队成员', - buildApps: '构建应用程序数', + modelProviders: '支持 OpenAI/Anthropic/Llama2/Azure OpenAI/Hugging Face/Replicate', + teamWorkspace: '{{count}} 个团队空间', + teamMember_one: '{{count}} 名团队成员', + teamMember_other: '{{count}} 名团队成员', annotationQuota: '标注回复数', - vectorSpace: '向量空间', - vectorSpaceTooltip: '向量空间是 LLMs 理解您的数据所需的长期记忆系统。', - vectorSpaceBillingTooltip: '向量存储是将知识库向量化处理后为让 LLMs 理解数据而使用的长期记忆存储,1MB 大约能满足1.2 million character 的向量化后数据存储(以 OpenAI Embedding 模型估算,不同模型计算方式有差异)。在向量化过程中,实际的压缩或尺寸减小取决于内容的复杂性和冗余性。', - documentsUploadQuota: '文档上传配额', - documentProcessingPriority: '文档处理优先级', - documentProcessingPriorityTip: '如需更高的文档处理优先级,请升级您的套餐', - documentProcessingPriorityUpgrade: '以更快的速度、更高的精度处理更多的数据。', + buildApps: '{{count}} 个应用程序', + documents: '{{count}} 个知识库文档上传配额', + documentsTooltip: '从知识库的数据源导入的文档数量配额。', + vectorSpace: '{{size}} 知识库数据存储空间', + vectorSpaceTooltip: '采用高质量索引模式的文档会消耗知识数据存储资源。当知识数据存储达到限制时,将不会上传新文档。', + documentsRequestQuota: '{{count}}/分钟 知识库请求频率限制', + documentsRequestQuotaTooltip: '指示系统在知识库支持下每分钟可以处理的查询数,用于衡量查询容量和性能。', + documentProcessingPriority: '文档处理', priority: { 'standard': '标准', 'priority': '优先', @@ -68,12 +78,13 @@ const translation = { member: '成员', memberAfter: '个成员', messageRequest: { - title: '消息额度', - tooltip: '为不同方案提供基于 OpenAI 模型的消息响应额度。', + title: '{{count}} 条消息额度', + titlePerMonth: '{{count}} 条消息额度/月', + tooltip: '为不同方案提供基于OpenAl模型的消息响应额度。', }, annotatedResponse: { - title: '标注回复数', - tooltip: '标注回复功能通过人工编辑标注为应用提供了可定制的高质量问答回复能力', + title: '{{count}} 个标注回复数', + tooltip: '标注回复功能通过人工编辑标注为应用提供了可定制的高质量问答回复能力。', }, ragAPIRequestTooltip: '指单独调用 Dify 知识库数据处理能力的 API。', receiptInfo: '只有团队所有者和团队管理员才能订阅和查看账单信息', @@ -81,23 +92,61 @@ const translation = { plans: { sandbox: { name: 'Sandbox', - description: '200次 GPT 免费试用', - includesTitle: '包括:', + description: '核心功能免费试用', }, professional: { name: 'Professional', - description: '让个人和小团队能够以经济实惠的方式释放更多能力。', - includesTitle: 'Sandbox 计划中的一切,加上:', + description: '对于独立开发者/小团队', }, team: { name: 'Team', - description: '协作无限制并享受顶级性能。', - includesTitle: 'Professional 计划中的一切,加上:', + description: '对于中型团队', + }, + community: { + name: 'Community', + description: '适用于个人用户、小型团队或非商业项目', + price: '免费', + btnText: '开始使用', + includesTitle: '免费功能:', + features: [ + '所有核心功能均在公共存储库下发布', + '单一工作空间', + '符合 Dify 开源许可证', + ], + }, + premium: { + name: 'Premium', + description: '对于中型组织和团队', + price: '可扩展', + priceTip: '基于云市场', + btnText: '获得 Premium 版', + includesTitle: 'Community 版的所有功能,加上:', + comingSoon: '即将支持 Microsoft Azure & Google Cloud', + features: [ + '各个云提供商自行管理的可靠性', + '单一工作空间', + '自定义 WebApp & 品牌', + '优先电子邮件 & 聊天支持', + ], }, enterprise: { name: 'Enterprise', - description: '获得大规模关键任务系统的完整功能和支持。', - includesTitle: 'Team 计划中的一切,加上:', + description: '对于需要组织范围内的安全性、合规性、可扩展性、控制和更高级功能的企业', + price: '定制', + priceTip: '仅按年计费', + btnText: '联系销售', + includesTitle: 'Premium 版的所有功能,加上:', + features: [ + '企业级可扩展部署解决方案', + '商业许可授权', + '专属企业级功能', + '多个工作空间 & 企业级管理', + 'SSO', + '由 Dify 合作伙伴支持的可协商的 SLAs', + '高级的安全 & 控制', + '由 Dify 官方提供的更新 & 维护', + '专业技术支持', + ], }, }, vectorSpace: { diff --git a/web/tailwind.config.js b/web/tailwind.config.js index b03b91ff02..ddb60368b7 100644 --- a/web/tailwind.config.js +++ b/web/tailwind.config.js @@ -110,6 +110,7 @@ const config = { 'price-premium-badge-background': 'var(--color-premium-badge-background)', 'premium-yearly-tip-text-background': 'var(--color-premium-yearly-tip-text-background)', 'price-premium-text-background': 'var(--color-premium-text-background)', + 'price-enterprise-background': 'var(--color-price-enterprise-background)', }, lineClamp: { '20': '20', diff --git a/web/themes/manual-dark.css b/web/themes/manual-dark.css index aa539eb29f..13c4bf4274 100644 --- a/web/themes/manual-dark.css +++ b/web/themes/manual-dark.css @@ -25,4 +25,5 @@ html[data-theme="dark"] { --color-premium-yearly-tip-text-background: linear-gradient(91deg, #FDB022 2.18%, #F79009 108.79%); --color-premium-badge-background: linear-gradient(95deg, rgba(103, 111, 131, 0.90) 0%, rgba(73, 84, 100, 0.90) 105.58%), var(--util-colors-gray-gray-200, #18222F); --color-premium-text-background: linear-gradient(92deg, rgba(249, 250, 251, 0.95) 0%, rgba(233, 235, 240, 0.95) 97.78%); + --color-price-enterprise-background: linear-gradient(180deg, rgba(185, 211, 234, 0.00) 0%, rgba(180, 209, 234, 0.92) 100%); } \ No newline at end of file diff --git a/web/themes/manual-light.css b/web/themes/manual-light.css index 893b607189..e58abda6c2 100644 --- a/web/themes/manual-light.css +++ b/web/themes/manual-light.css @@ -1,28 +1,29 @@ html[data-theme="light"] { - --color-chatbot-bg: linear-gradient(180deg, - rgba(249, 250, 251, 0.9) 0%, - rgba(242, 244, 247, 0.9) 90.48%); - --color-chat-bubble-bg: linear-gradient(180deg, - #fff 0%, - rgba(255, 255, 255, 0.6) 100%); - --color-workflow-process-bg: linear-gradient(90deg, - rgba(200, 206, 218, 0.2) 0%, - rgba(200, 206, 218, 0.04) 100%); - --color-account-teams-bg: linear-gradient(271deg, - rgba(249, 250, 251, 0.9) -0.1%, - rgba(242, 244, 247, 0.9) 98.26%); - --color-dataset-chunk-process-success-bg: linear-gradient(92deg, rgba(23, 178, 106, 0.25) 0%, rgba(255, 255, 255, 0.00) 100%); - --color-dataset-chunk-process-error-bg: linear-gradient(92deg, rgba(240, 68, 56, 0.25) 0%, rgba(255, 255, 255, 0.00) 100%); - --color-dataset-chunk-detail-card-hover-bg: linear-gradient(180deg, #F2F4F7 0%, #F9FAFB 100%); - --color-dataset-child-chunk-expand-btn-bg: linear-gradient(90deg, rgba(200, 206, 218, 0.20) 0%, rgba(200, 206, 218, 0.04) 100%); - --color-dataset-option-card-blue-gradient: linear-gradient(90deg, #F2F4F7 0%, #F9FAFB 100%); - --color-dataset-option-card-purple-gradient: linear-gradient(90deg, #F0EEFA 0%, #F9FAFB 100%); - --color-dataset-option-card-orange-gradient: linear-gradient(90deg, #F8F2EE 0%, #F9FAFB 100%); - --color-dataset-chunk-list-mask-bg: linear-gradient(180deg, rgba(255, 255, 255, 0.00) 0%, #FCFCFD 100%); - --mask-top2bottom-gray-50-to-transparent: linear-gradient(180deg, - rgba(200, 206, 218, 0.2) 0%, - rgba(255, 255, 255, 0) 100%); - --color-premium-yearly-tip-text-background: linear-gradient(91deg, #F79009 2.18%, #DC6803 108.79%); - --color-premium-badge-background: linear-gradient(95deg, rgba(152, 162, 178, 0.90) 0%, rgba(103, 111, 131, 0.90) 105.58%); - --color-premium-text-background: linear-gradient(92deg, rgba(252, 252, 253, 0.95) 0%, rgba(242, 244, 247, 0.95) 97.78%); + --color-chatbot-bg: linear-gradient(180deg, + rgba(249, 250, 251, 0.9) 0%, + rgba(242, 244, 247, 0.9) 90.48%); + --color-chat-bubble-bg: linear-gradient(180deg, + #fff 0%, + rgba(255, 255, 255, 0.6) 100%); + --color-workflow-process-bg: linear-gradient(90deg, + rgba(200, 206, 218, 0.2) 0%, + rgba(200, 206, 218, 0.04) 100%); + --color-account-teams-bg: linear-gradient(271deg, + rgba(249, 250, 251, 0.9) -0.1%, + rgba(242, 244, 247, 0.9) 98.26%); + --color-dataset-chunk-process-success-bg: linear-gradient(92deg, rgba(23, 178, 106, 0.25) 0%, rgba(255, 255, 255, 0.00) 100%); + --color-dataset-chunk-process-error-bg: linear-gradient(92deg, rgba(240, 68, 56, 0.25) 0%, rgba(255, 255, 255, 0.00) 100%); + --color-dataset-chunk-detail-card-hover-bg: linear-gradient(180deg, #F2F4F7 0%, #F9FAFB 100%); + --color-dataset-child-chunk-expand-btn-bg: linear-gradient(90deg, rgba(200, 206, 218, 0.20) 0%, rgba(200, 206, 218, 0.04) 100%); + --color-dataset-option-card-blue-gradient: linear-gradient(90deg, #F2F4F7 0%, #F9FAFB 100%); + --color-dataset-option-card-purple-gradient: linear-gradient(90deg, #F0EEFA 0%, #F9FAFB 100%); + --color-dataset-option-card-orange-gradient: linear-gradient(90deg, #F8F2EE 0%, #F9FAFB 100%); + --color-dataset-chunk-list-mask-bg: linear-gradient(180deg, rgba(255, 255, 255, 0.00) 0%, #FCFCFD 100%); + --mask-top2bottom-gray-50-to-transparent: linear-gradient(180deg, + rgba(200, 206, 218, 0.2) 0%, + rgba(255, 255, 255, 0) 100%); + --color-premium-yearly-tip-text-background: linear-gradient(91deg, #F79009 2.18%, #DC6803 108.79%); + --color-premium-badge-background: linear-gradient(95deg, rgba(152, 162, 178, 0.90) 0%, rgba(103, 111, 131, 0.90) 105.58%); + --color-premium-text-background: linear-gradient(92deg, rgba(252, 252, 253, 0.95) 0%, rgba(242, 244, 247, 0.95) 97.78%); + --color-price-enterprise-background: linear-gradient(180deg, rgba(185, 211, 234, 0.00) 0%, rgba(180, 209, 234, 0.92) 100%); } \ No newline at end of file From ab2e69faefcdedf35900fa692b503e67c93773e4 Mon Sep 17 00:00:00 2001 From: NFish Date: Tue, 7 Jan 2025 12:23:17 +0800 Subject: [PATCH 04/28] fix: plan item can not show all content if language is jp --- .../billing/pricing/self-hosted-plan-item.tsx | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/web/app/components/billing/pricing/self-hosted-plan-item.tsx b/web/app/components/billing/pricing/self-hosted-plan-item.tsx index 80a9cd9af1..906ae1a059 100644 --- a/web/app/components/billing/pricing/self-hosted-plan-item.tsx +++ b/web/app/components/billing/pricing/self-hosted-plan-item.tsx @@ -108,7 +108,7 @@ const SelfHostedPlanItem: FC = ({ window.location.href = contactSalesUrl } return ( -
@@ -116,7 +116,7 @@ const SelfHostedPlanItem: FC = ({ {isEnterprisePlan &&
} {isEnterprisePlan &&
}
-
+
{style[plan].icon}
@@ -126,12 +126,11 @@ const SelfHostedPlanItem: FC = ({
-
{t(`${i18nPrefix}.price`)}
- {!isFreePlan &&
-
+
{t(`${i18nPrefix}.price`)}
+ {!isFreePlan + && {t(`${i18nPrefix}.priceTip`)} -
-
} + }
@@ -142,12 +141,12 @@ const SelfHostedPlanItem: FC = ({ > {t(`${i18nPrefix}.btnText`)} {isPremiumPlan - &&
-
- + && <> +
+
-
} + }
{t(`${i18nPrefix}.includesTitle`)}
From 4f0ecdbb6eb960ceb4a54317778de3bc1321982b Mon Sep 17 00:00:00 2001 From: NFish Date: Tue, 7 Jan 2025 14:23:19 +0800 Subject: [PATCH 05/28] fix: use repeat-linear-gradient for GridMask to improve darkmode support --- web/app/components/base/grid-mask/index.tsx | 81 +++---------------- web/app/components/billing/pricing/index.tsx | 4 +- .../components/billing/pricing/plan-item.tsx | 2 +- .../billing/pricing/self-hosted-plan-item.tsx | 2 +- web/tailwind.config.js | 1 + web/themes/manual-dark.css | 1 + web/themes/manual-light.css | 1 + 7 files changed, 16 insertions(+), 76 deletions(-) diff --git a/web/app/components/base/grid-mask/index.tsx b/web/app/components/base/grid-mask/index.tsx index 876eb7f1de..429b652056 100644 --- a/web/app/components/base/grid-mask/index.tsx +++ b/web/app/components/base/grid-mask/index.tsx @@ -1,5 +1,5 @@ import type { FC } from 'react' -import { useCallback, useEffect, useRef } from 'react' +import classNames from '@/utils/classnames' type GridMaskProps = { children: React.ReactNode @@ -13,78 +13,15 @@ const GridMask: FC = ({ canvasClassName, gradientClassName, }) => { - const canvasRef = useRef(null) - const ctxRef = useRef(null) - const initCanvas = () => { - const dpr = window.devicePixelRatio || 1 - - if (canvasRef.current) { - const { width: cssWidth, height: cssHeight } = canvasRef.current?.getBoundingClientRect() - - canvasRef.current.width = dpr * cssWidth - canvasRef.current.height = dpr * cssHeight - - const ctx = canvasRef.current.getContext('2d') - if (ctx) { - ctx.scale(dpr, dpr) - ctx.strokeStyle = '#D1E0FF' - ctxRef.current = ctx - } - } - } - - const drawRecord = useCallback(() => { - const canvas = canvasRef.current! - const ctx = ctxRef.current! - const rowNumber = parseInt(`${canvas.width / 24}`) - const colNumber = parseInt(`${canvas.height / 24}`) - - ctx.clearRect(0, 0, canvas.width, canvas.height) - ctx.beginPath() - for (let i = 0; i < rowNumber; i++) { - for (let j = 0; j < colNumber; j++) { - const x = i * 24 - const y = j * 24 - if (j === 0) { - ctx.moveTo(x, y + 2) - ctx.arc(x + 2, y + 2, 2, Math.PI, Math.PI * 1.5) - ctx.lineTo(x + 22, y) - ctx.arc(x + 22, y + 2, 2, Math.PI * 1.5, Math.PI * 2) - ctx.lineTo(x + 24, y + 22) - ctx.arc(x + 22, y + 22, 2, 0, Math.PI * 0.5) - ctx.lineTo(x + 2, y + 24) - ctx.arc(x + 2, y + 22, 2, Math.PI * 0.5, Math.PI) - } - else { - ctx.moveTo(x + 2, y) - ctx.arc(x + 2, y + 2, 2, Math.PI * 1.5, Math.PI, true) - ctx.lineTo(x, y + 22) - ctx.arc(x + 2, y + 22, 2, Math.PI, Math.PI * 0.5, true) - ctx.lineTo(x + 22, y + 24) - ctx.arc(x + 22, y + 22, 2, Math.PI * 0.5, 0, true) - ctx.lineTo(x + 24, y + 2) - ctx.arc(x + 22, y + 2, 2, 0, Math.PI * 1.5, true) - } - } - } - ctx.stroke() - ctx.closePath() - }, []) - - const handleStartDraw = () => { - if (canvasRef.current && ctxRef.current) - drawRecord() - } - - useEffect(() => { - initCanvas() - handleStartDraw() - }, []) - return ( -
- -
+
+
+
{children}
) diff --git a/web/app/components/billing/pricing/index.tsx b/web/app/components/billing/pricing/index.tsx index d3159911aa..df65b7be0c 100644 --- a/web/app/components/billing/pricing/index.tsx +++ b/web/app/components/billing/pricing/index.tsx @@ -62,8 +62,8 @@ const Pricing: FC = ({ itemWidth={170} className='inline-flex' options={[ - { value: 'cloud', text:
{t('billing.plansCommon.cloud')}
}, - { value: 'self', text:
{t('billing.plansCommon.self')}
}]} + { value: 'cloud', text:
{t('billing.plansCommon.cloud')}
}, + { value: 'self', text:
{t('billing.plansCommon.self')}
}]} onChange={v => setCurrentPlan(v)} /> {currentPlan === 'cloud' && , description: 'text-util-colors-blue-brand-blue-brand-600', - btnStyle: 'bg-components-button-primary-bg hover:bg-components-button-primary-bg-hover border border-component-button-primary-border text-components-button-primary-text', + btnStyle: 'bg-components-button-primary-bg hover:bg-components-button-primary-bg-hover border border-components-button-primary-border text-components-button-primary-text', }, [Plan.team]: { icon: , diff --git a/web/app/components/billing/pricing/self-hosted-plan-item.tsx b/web/app/components/billing/pricing/self-hosted-plan-item.tsx index 906ae1a059..ae225838c6 100644 --- a/web/app/components/billing/pricing/self-hosted-plan-item.tsx +++ b/web/app/components/billing/pricing/self-hosted-plan-item.tsx @@ -70,7 +70,7 @@ const style = { priceTip: 'text-text-primary-on-surface', description: 'text-text-primary-on-surface', bg: 'border-effects-highlight bg-[#155AEF] text-text-primary-on-surface', - btnStyle: 'bg-components-button-secondary-bg hover:bg-components-button-secondary-bg-hover border-[0.5px] border-components-button-secondary-border text-[#155AEF] shadow-xs', + btnStyle: 'bg-white bg-opacity-96 hover:opacity-85 border-[0.5px] border-components-button-secondary-border text-[#155AEF] shadow-xs', values: 'text-text-primary-on-surface', tooltipIconColor: 'text-text-primary-on-surface', }, diff --git a/web/tailwind.config.js b/web/tailwind.config.js index ddb60368b7..0ca4378c14 100644 --- a/web/tailwind.config.js +++ b/web/tailwind.config.js @@ -111,6 +111,7 @@ const config = { 'premium-yearly-tip-text-background': 'var(--color-premium-yearly-tip-text-background)', 'price-premium-text-background': 'var(--color-premium-text-background)', 'price-enterprise-background': 'var(--color-price-enterprise-background)', + 'grid-mask-background': 'var(--color-grid-mask-background)', }, lineClamp: { '20': '20', diff --git a/web/themes/manual-dark.css b/web/themes/manual-dark.css index 13c4bf4274..92eddbe768 100644 --- a/web/themes/manual-dark.css +++ b/web/themes/manual-dark.css @@ -26,4 +26,5 @@ html[data-theme="dark"] { --color-premium-badge-background: linear-gradient(95deg, rgba(103, 111, 131, 0.90) 0%, rgba(73, 84, 100, 0.90) 105.58%), var(--util-colors-gray-gray-200, #18222F); --color-premium-text-background: linear-gradient(92deg, rgba(249, 250, 251, 0.95) 0%, rgba(233, 235, 240, 0.95) 97.78%); --color-price-enterprise-background: linear-gradient(180deg, rgba(185, 211, 234, 0.00) 0%, rgba(180, 209, 234, 0.92) 100%); + --color-grid-mask-background: linear-gradient(0deg, rgba(0, 0, 0, 0.00) 0%, rgba(24, 24, 25, 0.1) 62.25%, rgba(24, 24, 25, 0.10) 100%); } \ No newline at end of file diff --git a/web/themes/manual-light.css b/web/themes/manual-light.css index e58abda6c2..915f41d1b8 100644 --- a/web/themes/manual-light.css +++ b/web/themes/manual-light.css @@ -26,4 +26,5 @@ html[data-theme="light"] { --color-premium-badge-background: linear-gradient(95deg, rgba(152, 162, 178, 0.90) 0%, rgba(103, 111, 131, 0.90) 105.58%); --color-premium-text-background: linear-gradient(92deg, rgba(252, 252, 253, 0.95) 0%, rgba(242, 244, 247, 0.95) 97.78%); --color-price-enterprise-background: linear-gradient(180deg, rgba(185, 211, 234, 0.00) 0%, rgba(180, 209, 234, 0.92) 100%); + --color-grid-mask-background: linear-gradient(0deg, #FFF 0%, rgba(217, 217, 217, 0.10) 62.25%, rgba(217, 217, 217, 0.10) 100%); } \ No newline at end of file From 508005b741a9859baac00c24da7f099f513d2c7a Mon Sep 17 00:00:00 2001 From: NFish Date: Wed, 8 Jan 2025 14:32:16 +0800 Subject: [PATCH 06/28] fix: replace contact sales url address --- web/app/components/billing/config.ts | 2 +- web/app/components/billing/pricing/index.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/web/app/components/billing/config.ts b/web/app/components/billing/config.ts index b88770b98a..53eb72c560 100644 --- a/web/app/components/billing/config.ts +++ b/web/app/components/billing/config.ts @@ -6,7 +6,7 @@ export const NUM_INFINITE = 99999999 export const contractSales = 'contractSales' export const unAvailable = 'unAvailable' -export const contactSalesUrl = 'mailto:business@dify.ai' +export const contactSalesUrl = 'https://vikgc6bnu1s.typeform.com/to/mowuXTQH' export const getStartedWithCommunityUrl = 'https://github.com/langgenius/dify' export const getWithPremiumUrl = 'https://aws.amazon.com/marketplace/pp/prodview-t22mebxzwjhu6' diff --git a/web/app/components/billing/pricing/index.tsx b/web/app/components/billing/pricing/index.tsx index df65b7be0c..dbd6759dc2 100644 --- a/web/app/components/billing/pricing/index.tsx +++ b/web/app/components/billing/pricing/index.tsx @@ -115,7 +115,7 @@ const Pricing: FC = ({
- {t('billing.plansCommon.comparePlanAndFeatures')} + {t('billing.plansCommon.comparePlanAndFeatures')}
From d5c31f8728d00f314832caa7f87c55d379ba1cda Mon Sep 17 00:00:00 2001 From: NFish Date: Wed, 8 Jan 2025 17:58:51 +0800 Subject: [PATCH 07/28] fix: update billing i18n in setting modal --- web/app/components/billing/config.ts | 7 +++++-- web/app/components/billing/plan/index.tsx | 10 +++++----- web/app/components/billing/type.ts | 3 ++- web/app/components/billing/usage-info/apps-info.tsx | 2 +- .../billing/usage-info/vector-space-info.tsx | 4 ++-- web/i18n/en-US/billing.ts | 9 +++++++++ web/i18n/ja-JP/billing.ts | 8 ++++++++ web/i18n/zh-Hans/billing.ts | 8 ++++++++ 8 files changed, 40 insertions(+), 11 deletions(-) diff --git a/web/app/components/billing/config.ts b/web/app/components/billing/config.ts index 53eb72c560..9affe76bee 100644 --- a/web/app/components/billing/config.ts +++ b/web/app/components/billing/config.ts @@ -20,6 +20,7 @@ export const ALL_PLANS: Record = { buildApps: 5, documents: 50, vectorSpace: '50MB', + documentsUploadQuota: 0, documentsRequestQuota: 10, documentProcessingPriority: Priority.standard, messageRequest: 200, @@ -35,6 +36,7 @@ export const ALL_PLANS: Record = { buildApps: 50, documents: 500, vectorSpace: '5GB', + documentsUploadQuota: 0, documentsRequestQuota: 10, documentProcessingPriority: Priority.priority, messageRequest: 5000, @@ -50,6 +52,7 @@ export const ALL_PLANS: Record = { buildApps: 200, documents: 1000, vectorSpace: '20GB', + documentsUploadQuota: 0, documentsRequestQuota: 2000, documentProcessingPriority: Priority.topPriority, messageRequest: 10000, @@ -66,7 +69,7 @@ export const defaultPlan = { buildApps: 1, teamMembers: 1, annotatedResponse: 1, - documentsRequestQuota: 1, + documentsUploadQuota: 0, }, total: { documents: 50, @@ -74,6 +77,6 @@ export const defaultPlan = { buildApps: 10, teamMembers: 1, annotatedResponse: 10, - documentsRequestQuota: 50, + documentsUploadQuota: 0, }, } diff --git a/web/app/components/billing/plan/index.tsx b/web/app/components/billing/plan/index.tsx index baf4110127..63493eefa7 100644 --- a/web/app/components/billing/plan/index.tsx +++ b/web/app/components/billing/plan/index.tsx @@ -2,7 +2,7 @@ import type { FC } from 'react' import React from 'react' import { useTranslation } from 'react-i18next' -import { Plan } from '../type' +import { Plan, SelfHostedPlan } from '../type' import VectorSpaceInfo from '../usage-info/vector-space-info' import AppsInfo from '../usage-info/apps-info' import UpgradeBtn from '../upgrade-btn' @@ -26,7 +26,7 @@ const typeStyle = { textClassNames: 'text-[#3538CD]', bg: 'linear-gradient(113deg, rgba(255, 255, 255, 0.51) 3.51%, rgba(255, 255, 255, 0.00) 111.71%), #E0EAFF', }, - [Plan.enterprise]: { + [SelfHostedPlan.enterprise]: { textClassNames: 'text-[#DC6803]', bg: 'linear-gradient(113deg, rgba(255, 255, 255, 0.51) 3.51%, rgba(255, 255, 255, 0.00) 111.71%), #FFEED3', }, @@ -89,7 +89,7 @@ const PlanComp: FC = ({ @@ -98,14 +98,14 @@ const PlanComp: FC = ({ diff --git a/web/app/components/billing/type.ts b/web/app/components/billing/type.ts index 29dd4985f7..c5f4e9da66 100644 --- a/web/app/components/billing/type.ts +++ b/web/app/components/billing/type.ts @@ -17,6 +17,7 @@ export type PlanInfo = { buildApps: number documents: number vectorSpace: string + documentsUploadQuota: number documentsRequestQuota: number documentProcessingPriority: Priority logHistory: number @@ -46,7 +47,7 @@ export type SelfHostedPlanInfo = { annotatedResponse: number } -export type UsagePlanInfo = Pick +export type UsagePlanInfo = Pick & { vectorSpace: number } export enum DocumentProcessingPriority { standard = 'standard', diff --git a/web/app/components/billing/usage-info/apps-info.tsx b/web/app/components/billing/usage-info/apps-info.tsx index d0d7f54a09..5261d2cec4 100644 --- a/web/app/components/billing/usage-info/apps-info.tsx +++ b/web/app/components/billing/usage-info/apps-info.tsx @@ -23,7 +23,7 @@ const AppsInfo: FC = ({ diff --git a/web/app/components/billing/usage-info/vector-space-info.tsx b/web/app/components/billing/usage-info/vector-space-info.tsx index bb14800cae..bb434c27a2 100644 --- a/web/app/components/billing/usage-info/vector-space-info.tsx +++ b/web/app/components/billing/usage-info/vector-space-info.tsx @@ -23,8 +23,8 @@ const VectorSpaceInfo: FC = ({ Date: Thu, 9 Jan 2025 10:25:04 +0800 Subject: [PATCH 08/28] fix: update i18n --- web/i18n/en-US/billing.ts | 4 ++-- web/i18n/ja-JP/billing.ts | 8 ++++---- web/i18n/zh-Hans/billing.ts | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/web/i18n/en-US/billing.ts b/web/i18n/en-US/billing.ts index 389ad6c676..55bc22c873 100644 --- a/web/i18n/en-US/billing.ts +++ b/web/i18n/en-US/billing.ts @@ -5,8 +5,8 @@ const translation = { buildApps: 'Build Apps', annotationQuota: 'Annotation Quota', documentsUploadQuota: 'Documents Upload Quota', - vectorSpace: 'Vector Space', - vectorSpaceTooltip: 'Vector Space is the long-term memory system required for LLMs to comprehend your data.', + vectorSpace: 'Knowledge Data Storage', + vectorSpaceTooltip: 'Documents with the High Quality indexing mode will consume Knowledge Data Storage resources. When Knowledge Data Storage reaches the limit, new documents will not be uploaded.', }, teamMembers: 'Team Members', upgradeBtn: { diff --git a/web/i18n/ja-JP/billing.ts b/web/i18n/ja-JP/billing.ts index 75b2c489b9..87c7121ac1 100644 --- a/web/i18n/ja-JP/billing.ts +++ b/web/i18n/ja-JP/billing.ts @@ -5,8 +5,8 @@ const translation = { buildApps: 'アプリを作成する', annotationQuota: 'アノテーション・クォータ', documentsUploadQuota: 'ドキュメント・アップロード・クォータ', - vectorSpace: 'ベクトルスペース', - vectorSpaceTooltip: 'ベクトルスペースは、LLMがデータを理解するために必要な長期記憶システムです。', + vectorSpace: '知識データストレージ', + vectorSpaceTooltip: '高品質インデックスモードのドキュメントは、知識データストレージのリソースを消費します。知識データストレージの上限に達すると、新しいドキュメントはアップロードされません。', }, upgradeBtn: { plain: 'プランをアップグレード', @@ -51,7 +51,7 @@ const translation = { documents: '{{count}}の知識文書', documentsTooltip: 'ナレッジデータソースからインポートされたドキュメントの数に対するクォータ。', vectorSpace: '{{size}}の知識データストレージ', - vectorSpaceTooltip: '高品質インデックスモードのドキュメントは、Knowledge Data Storageのリソースを消費します。Knowledge Data Storageの上限に達すると、新しいドキュメントはアップロードされません。', + vectorSpaceTooltip: '高品質インデックスモードのドキュメントは、知識データストレージのリソースを消費します。知識データストレージの上限に達すると、新しいドキュメントはアップロードされません。', documentsRequestQuota: '{{count}}100/分のナレッジ リクエストのレート制限', documentsRequestQuotaTooltip: 'システムがナレッジベースサポートで処理できる1分あたりのクエリ数を示し、クエリの容量とパフォーマンスを測定するために使用されます。、クエリの容量とパフォーマンスを測定するために使用されます。', documentProcessingPriority: '文書処理', @@ -158,7 +158,7 @@ const translation = { }, }, vectorSpace: { - fullTip: 'ベクトルスペースがいっぱいです。', + fullTip: '知識データストレージがいっぱいです。', fullSolution: 'より多くのスペースを得るためにプランをアップグレードしてください。', }, apps: { diff --git a/web/i18n/zh-Hans/billing.ts b/web/i18n/zh-Hans/billing.ts index ef0c438a7b..be99335761 100644 --- a/web/i18n/zh-Hans/billing.ts +++ b/web/i18n/zh-Hans/billing.ts @@ -5,8 +5,8 @@ const translation = { buildApps: '构建应用程序数', annotationQuota: '标注回复数', documentsUploadQuota: '文档上传配额', - vectorSpace: '向量空间', - vectorSpaceTooltip: '向量空间是 LLMs 理解您的数据所需的长期记忆系统。', + vectorSpace: '知识库数据存储空间', + vectorSpaceTooltip: '采用高质量索引模式的文档会消耗知识数据存储资源。当知识数据存储达到限制时,将不会上传新文档。', }, upgradeBtn: { plain: '升级套餐', @@ -158,7 +158,7 @@ const translation = { }, }, vectorSpace: { - fullTip: '向量空间已满。', + fullTip: '知识库数据存储空间已满。', fullSolution: '升级您的套餐以获得更多空间。', }, apps: { From 49415e5e7fe8062b06002a8c663c8836923cedc0 Mon Sep 17 00:00:00 2001 From: NFish Date: Tue, 14 Jan 2025 16:38:30 +0800 Subject: [PATCH 09/28] fix: update Knowledge Request Ratelimit tooltip text --- web/app/components/billing/pricing/plan-item.tsx | 4 ++-- web/i18n/en-US/billing.ts | 2 +- web/i18n/ja-JP/billing.ts | 2 +- web/i18n/zh-Hans/billing.ts | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/web/app/components/billing/pricing/plan-item.tsx b/web/app/components/billing/pricing/plan-item.tsx index 95c6a37678..62072d9c83 100644 --- a/web/app/components/billing/pricing/plan-item.tsx +++ b/web/app/components/billing/pricing/plan-item.tsx @@ -21,7 +21,7 @@ type Props = { canPay: boolean } -const KeyValue = ({ icon, label, tooltip }: { icon: ReactNode; label: string; tooltip?: string }) => { +const KeyValue = ({ icon, label, tooltip }: { icon: ReactNode; label: string; tooltip?: ReactNode }) => { return (
@@ -199,7 +199,7 @@ const PlanItem: FC = ({ } label={t('billing.plansCommon.documentsRequestQuota', { count: planInfo.documentsRequestQuota })} - tooltip={t('billing.plansCommon.documentsRequestQuotaTooltip') as string} + tooltip={t('billing.plansCommon.documentsRequestQuotaTooltip')} /> } diff --git a/web/i18n/en-US/billing.ts b/web/i18n/en-US/billing.ts index 55bc22c873..bbfdd18b50 100644 --- a/web/i18n/en-US/billing.ts +++ b/web/i18n/en-US/billing.ts @@ -54,7 +54,7 @@ const translation = { vectorSpace: '{{size}} Knowledge Data Storage', vectorSpaceTooltip: 'Documents with the High Quality indexing mode will consume Knowledge Data Storage resources. When Knowledge Data Storage reaches the limit, new documents will not be uploaded.', documentsRequestQuota: '{{count}}/min Knowledge Request Rate limit', - documentsRequestQuotaTooltip: 'Indicates the number of queries per minute the system can handle with knowledge base support, used to measure query capacity and performance.', + documentsRequestQuotaTooltip: 'Specifies the total number of actions a workspace can perform per minute within the knowledge base, including dataset creation, deletion, updates, document uploads, modifications, archiving, and knowledge base queries. This metric is used to evaluate the performance of knowledge base requests. For example, if a Sandbox user performs 10 consecutive hit tests within one minute, their workspace will be temporarily restricted from performing the following actions for the next minute: dataset creation, deletion, updates, and document uploads or modifications. ', documentProcessingPriority: 'Document Processing', priority: { 'standard': 'Standard', diff --git a/web/i18n/ja-JP/billing.ts b/web/i18n/ja-JP/billing.ts index 87c7121ac1..c1f395f510 100644 --- a/web/i18n/ja-JP/billing.ts +++ b/web/i18n/ja-JP/billing.ts @@ -53,7 +53,7 @@ const translation = { vectorSpace: '{{size}}の知識データストレージ', vectorSpaceTooltip: '高品質インデックスモードのドキュメントは、知識データストレージのリソースを消費します。知識データストレージの上限に達すると、新しいドキュメントはアップロードされません。', documentsRequestQuota: '{{count}}100/分のナレッジ リクエストのレート制限', - documentsRequestQuotaTooltip: 'システムがナレッジベースサポートで処理できる1分あたりのクエリ数を示し、クエリの容量とパフォーマンスを測定するために使用されます。、クエリの容量とパフォーマンスを測定するために使用されます。', + documentsRequestQuotaTooltip: 'ナレッジベース内でワークスペースが1分間に実行できる操作の総数を示します。これには、データセットの作成、削除、更新、ドキュメントのアップロード、修正、アーカイブ、およびナレッジベースクエリが含まれます。この指標は、ナレッジベースリクエストのパフォーマンスを評価するために使用されます。例えば、Sandbox ユーザーが1分間に10回連続でヒットテストを実行した場合、そのワークスペースは次の1分間、データセットの作成、削除、更新、ドキュメントのアップロードや修正などの操作を一時的に実行できなくなります。', documentProcessingPriority: '文書処理', priority: { 'standard': '標準', diff --git a/web/i18n/zh-Hans/billing.ts b/web/i18n/zh-Hans/billing.ts index be99335761..f887c5cf55 100644 --- a/web/i18n/zh-Hans/billing.ts +++ b/web/i18n/zh-Hans/billing.ts @@ -53,7 +53,7 @@ const translation = { vectorSpace: '{{size}} 知识库数据存储空间', vectorSpaceTooltip: '采用高质量索引模式的文档会消耗知识数据存储资源。当知识数据存储达到限制时,将不会上传新文档。', documentsRequestQuota: '{{count}}/分钟 知识库请求频率限制', - documentsRequestQuotaTooltip: '指示系统在知识库支持下每分钟可以处理的查询数,用于衡量查询容量和性能。', + documentsRequestQuotaTooltip: '指每分钟内,一个空间在知识库中可执行的操作总数,包括数据集的创建、删除、更新,文档的上传、修改、归档,以及知识库查询等,用于评估知识库请求请求性能。例如,Sandbox 用户在 1 分钟内连续执行 10 次命中测试,其工作区将在接下来的 1 分钟内无法继续执行以下操作:数据集的创建、删除、更新,文档的上传、修改等操作。', documentProcessingPriority: '文档处理', priority: { 'standard': '标准', From 066516b54df518ff8ad81c003e29910c86656cd9 Mon Sep 17 00:00:00 2001 From: NFish Date: Tue, 14 Jan 2025 18:57:03 +0800 Subject: [PATCH 10/28] fix: update document limit tooltip content --- web/i18n/zh-Hans/billing.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/i18n/zh-Hans/billing.ts b/web/i18n/zh-Hans/billing.ts index f887c5cf55..09cbf22ccc 100644 --- a/web/i18n/zh-Hans/billing.ts +++ b/web/i18n/zh-Hans/billing.ts @@ -53,7 +53,7 @@ const translation = { vectorSpace: '{{size}} 知识库数据存储空间', vectorSpaceTooltip: '采用高质量索引模式的文档会消耗知识数据存储资源。当知识数据存储达到限制时,将不会上传新文档。', documentsRequestQuota: '{{count}}/分钟 知识库请求频率限制', - documentsRequestQuotaTooltip: '指每分钟内,一个空间在知识库中可执行的操作总数,包括数据集的创建、删除、更新,文档的上传、修改、归档,以及知识库查询等,用于评估知识库请求请求性能。例如,Sandbox 用户在 1 分钟内连续执行 10 次命中测试,其工作区将在接下来的 1 分钟内无法继续执行以下操作:数据集的创建、删除、更新,文档的上传、修改等操作。', + documentsRequestQuotaTooltip: '指每分钟内,一个空间在知识库中可执行的操作总数,包括数据集的创建、删除、更新,文档的上传、修改、归档,以及知识库查询等,用于评估知识库请求的性能。', documentProcessingPriority: '文档处理', priority: { 'standard': '标准', From ffa5af1356eee227c89984d1306e8b4baee0d521 Mon Sep 17 00:00:00 2001 From: NFish Date: Wed, 22 Jan 2025 19:41:18 +0800 Subject: [PATCH 11/28] fix: supports number format --- .../components/billing/pricing/plan-item.tsx | 1 + web/i18n/en-US/billing.ts | 26 +++++++++---------- web/i18n/ja-JP/billing.ts | 20 +++++++------- web/i18n/zh-Hans/billing.ts | 14 +++++----- 4 files changed, 31 insertions(+), 30 deletions(-) diff --git a/web/app/components/billing/pricing/plan-item.tsx b/web/app/components/billing/pricing/plan-item.tsx index 62072d9c83..8c91eb9549 100644 --- a/web/app/components/billing/pricing/plan-item.tsx +++ b/web/app/components/billing/pricing/plan-item.tsx @@ -22,6 +22,7 @@ type Props = { } const KeyValue = ({ icon, label, tooltip }: { icon: ReactNode; label: string; tooltip?: ReactNode }) => { + console.log(label) return (
diff --git a/web/i18n/en-US/billing.ts b/web/i18n/en-US/billing.ts index bbfdd18b50..c39e9c7744 100644 --- a/web/i18n/en-US/billing.ts +++ b/web/i18n/en-US/billing.ts @@ -22,7 +22,7 @@ const translation = { freeTrialTip: 'free trial of 200 OpenAI calls. ', freeTrialTipSuffix: 'No credit card required', yearlyTip: 'Pay for 10 months, enjoy 1 Year!', - mostPopular: 'Most Popular', + mostPopular: 'Popular', cloud: 'Cloud Service', self: 'Self-Hosted', planRange: { @@ -39,23 +39,23 @@ const translation = { currentPlan: 'Current Plan', contractSales: 'Contact sales', contractOwner: 'Contact team manager', - startForFree: 'Start for free', - getStarted: 'Get started', + startForFree: 'Start for Free', + getStarted: 'Get Started', contactSales: 'Contact Sales', talkToSales: 'Talk to Sales', modelProviders: 'Support OpenAI/Anthropic/Llama2/Azure OpenAI/Hugging Face/Replicate', - teamWorkspace: '{{count}} Team Workspace', - teamMember_one: '{{count}} Team Member', - teamMember_other: '{{count}} Team Members', + teamWorkspace: '{{count,number}} Team Workspace', + teamMember_one: '{{count,number}} Team Member', + teamMember_other: '{{count,number}} Team Members', annotationQuota: 'Annotation Quota', - buildApps: '{{count}} Apps', - documents: '{{count}} Knowledge Documents', + buildApps: '{{count,number}} Apps', + documents: '{{count,number}} Knowledge Documents', documentsTooltip: 'Quota on the number of documents imported from the Knowledge Data Source.', vectorSpace: '{{size}} Knowledge Data Storage', vectorSpaceTooltip: 'Documents with the High Quality indexing mode will consume Knowledge Data Storage resources. When Knowledge Data Storage reaches the limit, new documents will not be uploaded.', - documentsRequestQuota: '{{count}}/min Knowledge Request Rate limit', + documentsRequestQuota: '{{count,number}}/min Knowledge Request Rate Limit', documentsRequestQuotaTooltip: 'Specifies the total number of actions a workspace can perform per minute within the knowledge base, including dataset creation, deletion, updates, document uploads, modifications, archiving, and knowledge base queries. This metric is used to evaluate the performance of knowledge base requests. For example, if a Sandbox user performs 10 consecutive hit tests within one minute, their workspace will be temporarily restricted from performing the following actions for the next minute: dataset creation, deletion, updates, and document uploads or modifications. ', - documentProcessingPriority: 'Document Processing', + documentProcessingPriority: ' Document Processing', priority: { 'standard': 'Standard', 'priority': 'Priority', @@ -87,12 +87,12 @@ const translation = { member: 'Member', memberAfter: 'Member', messageRequest: { - title: '{{count}} Messages', - titlePerMonth: '{{count}} Messages/month', + title: '{{count,number}} messages', + titlePerMonth: '{{count,number}} messages/month', tooltip: 'Message invocation quotas for various plans using OpenAl models. Messages over the limit will use your OpenAI API Key.', }, annotatedResponse: { - title: '{{count}} Annotation Quota Limits', + title: '{{count,number}} Annotation Quota Limits', tooltip: 'Manual editing and annotation of responses provides customizable high-quality question-answering abilities for apps. (Applicable only in Chat apps)', }, ragAPIRequestTooltip: 'Refers to the number of API calls invoking only the knowledge base processing capabilities of Dify.', diff --git a/web/i18n/ja-JP/billing.ts b/web/i18n/ja-JP/billing.ts index c1f395f510..4f0792bc2f 100644 --- a/web/i18n/ja-JP/billing.ts +++ b/web/i18n/ja-JP/billing.ts @@ -43,16 +43,16 @@ const translation = { contactSales: '営業に連絡する', talkToSales: '営業と話す', modelProviders: 'OpenAI/Anthropic/Llama2/Azure OpenAI/Hugging Face/Replicateをサポート', - teamWorkspace: '{{count}}チームワークスペース', - teamMember_one: 'チームメンバー:{{count}}人', - teamMember_other: 'チームメンバー:{{count}}人', + teamWorkspace: '{{count,number}}チームワークスペース', + teamMember_one: 'チームメンバー:{{count,number}}人', + teamMember_other: 'チームメンバー:{{count,number}}人', annotationQuota: 'アノテーション・クォータ', - buildApps: 'アプリの数:{{count}}個', - documents: '{{count}}の知識文書', + buildApps: 'アプリの数:{{count,number}}個', + documents: '{{count,number}}の知識文書', documentsTooltip: 'ナレッジデータソースからインポートされたドキュメントの数に対するクォータ。', vectorSpace: '{{size}}の知識データストレージ', vectorSpaceTooltip: '高品質インデックスモードのドキュメントは、知識データストレージのリソースを消費します。知識データストレージの上限に達すると、新しいドキュメントはアップロードされません。', - documentsRequestQuota: '{{count}}100/分のナレッジ リクエストのレート制限', + documentsRequestQuota: '{{count,number}}/分のナレッジ リクエストのレート制限', documentsRequestQuotaTooltip: 'ナレッジベース内でワークスペースが1分間に実行できる操作の総数を示します。これには、データセットの作成、削除、更新、ドキュメントのアップロード、修正、アーカイブ、およびナレッジベースクエリが含まれます。この指標は、ナレッジベースリクエストのパフォーマンスを評価するために使用されます。例えば、Sandbox ユーザーが1分間に10回連続でヒットテストを実行した場合、そのワークスペースは次の1分間、データセットの作成、削除、更新、ドキュメントのアップロードや修正などの操作を一時的に実行できなくなります。', documentProcessingPriority: '文書処理', priority: { @@ -60,7 +60,7 @@ const translation = { 'priority': '優先', 'top-priority': '最優先', }, - logsHistory: 'ログ履歴', + logsHistory: '{{days}}ログ履歴', customTools: 'カスタムツール', unavailable: '利用不可', days: '日', @@ -86,12 +86,12 @@ const translation = { member: 'メンバー', memberAfter: 'メンバー', messageRequest: { - title: '{{count}}メッセージ', - titlePerMonth: '{{count}}メッセージ/月', + title: '{{count,number}}メッセージ', + titlePerMonth: '{{count,number}}メッセージ/月', tooltip: 'Open Alモデルを使用するさまざまなプランのメッセージ呼び出しクォータ。上限を超えるメッセージは、Open AI APIキーを使用します。', }, annotatedResponse: { - title: '{{count}}の注釈クォータ制限', + title: '{{count,number}}の注釈クォータ制限', tooltip: '手動での回答の編集と注釈により、カスタマイズ可能な高品質の質問応答機能をアプリに提供します。(チャットアプリのみに適用)', }, ragAPIRequestTooltip: 'Difyのナレッジベース処理機能のみを呼び出すAPI呼び出しの数を指します。', diff --git a/web/i18n/zh-Hans/billing.ts b/web/i18n/zh-Hans/billing.ts index 09cbf22ccc..5164183037 100644 --- a/web/i18n/zh-Hans/billing.ts +++ b/web/i18n/zh-Hans/billing.ts @@ -47,20 +47,20 @@ const translation = { teamMember_one: '{{count}} 名团队成员', teamMember_other: '{{count}} 名团队成员', annotationQuota: '标注回复数', - buildApps: '{{count}} 个应用程序', - documents: '{{count}} 个知识库文档上传配额', + buildApps: '{{count, number}} 个应用程序', + documents: '{{count, number}} 个知识库文档上传配额', documentsTooltip: '从知识库的数据源导入的文档数量配额。', vectorSpace: '{{size}} 知识库数据存储空间', vectorSpaceTooltip: '采用高质量索引模式的文档会消耗知识数据存储资源。当知识数据存储达到限制时,将不会上传新文档。', documentsRequestQuota: '{{count}}/分钟 知识库请求频率限制', - documentsRequestQuotaTooltip: '指每分钟内,一个空间在知识库中可执行的操作总数,包括数据集的创建、删除、更新,文档的上传、修改、归档,以及知识库查询等,用于评估知识库请求的性能。', + documentsRequestQuotaTooltip: '指每分钟内,一个空间在知识库中可执行的操作总数,包括数据集的创建、删除、更新,文档的上传、修改、归档,以及知识库查询等,用于评估知识库请求的性能。例如,Sandbox 用户在 1 分钟内连续执行 10 次命中测试,其工作区将在接下来的 1 分钟内无法继续执行以下操作:数据集的创建、删除、更新,文档的上传、修改等操作。', documentProcessingPriority: '文档处理', priority: { 'standard': '标准', 'priority': '优先', 'top-priority': '最高优先级', }, - logsHistory: '日志历史', + logsHistory: '{{days}}日志历史', customTools: '自定义工具', unavailable: '不可用', days: '天', @@ -86,12 +86,12 @@ const translation = { member: '成员', memberAfter: '个成员', messageRequest: { - title: '{{count}} 条消息额度', - titlePerMonth: '{{count}} 条消息额度/月', + title: '{{count,number}} 条消息额度', + titlePerMonth: '{{count,number}} 条消息额度/月', tooltip: '为不同方案提供基于OpenAl模型的消息响应额度。', }, annotatedResponse: { - title: '{{count}} 个标注回复数', + title: '{{count,number}} 个标注回复数', tooltip: '标注回复功能通过人工编辑标注为应用提供了可定制的高质量问答回复能力。', }, ragAPIRequestTooltip: '指单独调用 Dify 知识库数据处理能力的 API。', From 3fcf7e88b0675c9904b2abce149669ce74449451 Mon Sep 17 00:00:00 2001 From: NFish Date: Wed, 22 Jan 2025 20:01:00 +0800 Subject: [PATCH 12/28] fix: UI adjust --- .../icons/assets/public/billing/asterisk.svg | 5 +++ .../icons/src/public/billing/Asterisk.json | 38 +++++++++++++++++++ .../icons/src/public/billing/Asterisk.tsx | 16 ++++++++ .../base/icons/src/public/billing/index.ts | 1 + web/app/components/billing/pricing/index.tsx | 23 ++++++++--- .../components/billing/pricing/plan-item.tsx | 2 +- .../billing/pricing/select-plan-range.tsx | 2 +- .../billing/pricing/self-hosted-plan-item.tsx | 8 ++-- 8 files changed, 84 insertions(+), 11 deletions(-) create mode 100644 web/app/components/base/icons/assets/public/billing/asterisk.svg create mode 100644 web/app/components/base/icons/src/public/billing/Asterisk.json create mode 100644 web/app/components/base/icons/src/public/billing/Asterisk.tsx diff --git a/web/app/components/base/icons/assets/public/billing/asterisk.svg b/web/app/components/base/icons/assets/public/billing/asterisk.svg new file mode 100644 index 0000000000..1ee4059e81 --- /dev/null +++ b/web/app/components/base/icons/assets/public/billing/asterisk.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/web/app/components/base/icons/src/public/billing/Asterisk.json b/web/app/components/base/icons/src/public/billing/Asterisk.json new file mode 100644 index 0000000000..6f70b27a1f --- /dev/null +++ b/web/app/components/base/icons/src/public/billing/Asterisk.json @@ -0,0 +1,38 @@ +{ + "icon": { + "type": "element", + "isRootNode": true, + "name": "svg", + "attributes": { + "width": "28", + "height": "28", + "viewBox": "0 0 28 28", + "fill": "none", + "xmlns": "http://www.w3.org/2000/svg" + }, + "children": [ + { + "type": "element", + "name": "g", + "attributes": { + "id": "asterisk" + }, + "children": [ + { + "type": "element", + "name": "path", + "attributes": { + "id": "Vector", + "d": "M14.0033 3.20837V24.7917M4.65747 8.60421L23.3492 19.3959M4.6586 19.3959L23.3503 8.60421", + "stroke": "#101828", + "stroke-width": "1.5", + "stroke-linecap": "round" + }, + "children": [] + } + ] + } + ] + }, + "name": "Asterisk" +} \ No newline at end of file diff --git a/web/app/components/base/icons/src/public/billing/Asterisk.tsx b/web/app/components/base/icons/src/public/billing/Asterisk.tsx new file mode 100644 index 0000000000..679ea86d77 --- /dev/null +++ b/web/app/components/base/icons/src/public/billing/Asterisk.tsx @@ -0,0 +1,16 @@ +// GENERATE BY script +// DON NOT EDIT IT MANUALLY + +import * as React from 'react' +import data from './Asterisk.json' +import IconBase from '@/app/components/base/icons/IconBase' +import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase' + +const Icon = React.forwardRef, Omit>(( + props, + ref, +) => ) + +Icon.displayName = 'Asterisk' + +export default Icon diff --git a/web/app/components/base/icons/src/public/billing/index.ts b/web/app/components/base/icons/src/public/billing/index.ts index cc186bbd94..9460acff3c 100644 --- a/web/app/components/base/icons/src/public/billing/index.ts +++ b/web/app/components/base/icons/src/public/billing/index.ts @@ -1,4 +1,5 @@ export { default as ArCube1 } from './ArCube1' +export { default as Asterisk } from './Asterisk' export { default as AwsMarketplace } from './AwsMarketplace' export { default as Azure } from './Azure' export { default as Buildings } from './Buildings' diff --git a/web/app/components/billing/pricing/index.tsx b/web/app/components/billing/pricing/index.tsx index dbd6759dc2..f576bc3046 100644 --- a/web/app/components/billing/pricing/index.tsx +++ b/web/app/components/billing/pricing/index.tsx @@ -14,6 +14,7 @@ import SelfHostedPlanItem from './self-hosted-plan-item' import { useProviderContext } from '@/context/provider-context' import GridMask from '@/app/components/base/grid-mask' import { useAppContext } from '@/context/app-context' +import classNames from '@/utils/classnames' type Props = { onCancel: () => void @@ -51,7 +52,7 @@ const Pricing: FC = ({
{t('billing.plansCommon.freeTrialTipPrefix')} - {t('billing.plansCommon.freeTrialTip')} + {t('billing.plansCommon.freeTrialTip')} {t('billing.plansCommon.freeTrialTipSuffix')}
@@ -62,8 +63,20 @@ const Pricing: FC = ({ itemWidth={170} className='inline-flex' options={[ - { value: 'cloud', text:
{t('billing.plansCommon.cloud')}
}, - { value: 'self', text:
{t('billing.plansCommon.self')}
}]} + { + value: 'cloud', + text:
+ {t('billing.plansCommon.cloud')}
, + }, + { + value: 'self', + text:
+ {t('billing.plansCommon.self')}
, + }]} onChange={v => setCurrentPlan(v)} /> {currentPlan === 'cloud' && = ({
-
+
{t('billing.plansCommon.comparePlanAndFeatures')}
-
+
, document.body, ) diff --git a/web/app/components/billing/pricing/plan-item.tsx b/web/app/components/billing/pricing/plan-item.tsx index 8c91eb9549..4ba320441b 100644 --- a/web/app/components/billing/pricing/plan-item.tsx +++ b/web/app/components/billing/pricing/plan-item.tsx @@ -36,7 +36,7 @@ const KeyValue = ({ icon, label, tooltip }: { icon: ReactNode; label: string; to popupClassName='w-[200px]' >
- +
)} diff --git a/web/app/components/billing/pricing/select-plan-range.tsx b/web/app/components/billing/pricing/select-plan-range.tsx index 62b493d84d..07add5ea81 100644 --- a/web/app/components/billing/pricing/select-plan-range.tsx +++ b/web/app/components/billing/pricing/select-plan-range.tsx @@ -40,7 +40,7 @@ const SelectPlanRange: FC = ({
{t('billing.plansCommon.yearlyTip')}
- {t('billing.plansCommon.annualBilling')} + {t('billing.plansCommon.annualBilling')} { onChange(v ? PlanRange.yearly : PlanRange.monthly) }} /> diff --git a/web/app/components/billing/pricing/self-hosted-plan-item.tsx b/web/app/components/billing/pricing/self-hosted-plan-item.tsx index ae225838c6..b057a5b82b 100644 --- a/web/app/components/billing/pricing/self-hosted-plan-item.tsx +++ b/web/app/components/billing/pricing/self-hosted-plan-item.tsx @@ -2,12 +2,12 @@ import type { FC, ReactNode } from 'react' import React from 'react' import { useTranslation } from 'react-i18next' -import { RiArrowRightUpLine, RiAsterisk, RiBrain2Line, RiCheckLine, RiQuestionLine } from '@remixicon/react' +import { RiArrowRightUpLine, RiBrain2Line, RiCheckLine, RiQuestionLine } from '@remixicon/react' import { SelfHostedPlan } from '../type' import { contactSalesUrl, getStartedWithCommunityUrl, getWithPremiumUrl } from '../config' import Toast from '../../base/toast' import Tooltip from '../../base/tooltip' -import { AwsMarketplace, Azure, Buildings, Diamond, GoogleCloud } from '../../base/icons/src/public/billing' +import { Asterisk, AwsMarketplace, Azure, Buildings, Diamond, GoogleCloud } from '../../base/icons/src/public/billing' import type { PlanRange } from './select-plan-range' import cn from '@/utils/classnames' import { useAppContext } from '@/context/app-context' @@ -42,7 +42,7 @@ const KeyValue = ({ label, tooltip, textColor, tooltipIconColor }: { icon: React const style = { [SelfHostedPlan.community]: { - icon: , + icon: , title: 'text-text-primary', price: 'text-text-primary', priceTip: 'text-text-tertiary', @@ -142,7 +142,7 @@ const SelfHostedPlanItem: FC = ({ {t(`${i18nPrefix}.btnText`)} {isPremiumPlan && <> -
+
From 10991cbc032ee6245b6a75ca3870420fa82b2502 Mon Sep 17 00:00:00 2001 From: NFish Date: Thu, 23 Jan 2025 11:06:01 +0800 Subject: [PATCH 13/28] fix: update bill page background image --- web/app/components/base/grid-mask/Grid.svg | 2146 +++++++++++++++++ web/app/components/base/grid-mask/index.tsx | 8 +- .../base/grid-mask/style.module.css | 5 + web/app/components/billing/pricing/index.tsx | 4 +- 4 files changed, 2155 insertions(+), 8 deletions(-) create mode 100644 web/app/components/base/grid-mask/Grid.svg create mode 100644 web/app/components/base/grid-mask/style.module.css diff --git a/web/app/components/base/grid-mask/Grid.svg b/web/app/components/base/grid-mask/Grid.svg new file mode 100644 index 0000000000..88cdeeaa20 --- /dev/null +++ b/web/app/components/base/grid-mask/Grid.svg @@ -0,0 +1,2146 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/app/components/base/grid-mask/index.tsx b/web/app/components/base/grid-mask/index.tsx index 429b652056..9c6965176a 100644 --- a/web/app/components/base/grid-mask/index.tsx +++ b/web/app/components/base/grid-mask/index.tsx @@ -1,4 +1,5 @@ import type { FC } from 'react' +import Style from './style.module.css' import classNames from '@/utils/classnames' type GridMaskProps = { @@ -15,12 +16,7 @@ const GridMask: FC = ({ }) => { return (
-
+
{children}
diff --git a/web/app/components/base/grid-mask/style.module.css b/web/app/components/base/grid-mask/style.module.css new file mode 100644 index 0000000000..4d135b3cfc --- /dev/null +++ b/web/app/components/base/grid-mask/style.module.css @@ -0,0 +1,5 @@ +.gridBg{ + background-image: url(./Grid.svg); + background-repeat: repeat; + background-position: 0 0; +} \ No newline at end of file diff --git a/web/app/components/billing/pricing/index.tsx b/web/app/components/billing/pricing/index.tsx index f576bc3046..28f5ce7122 100644 --- a/web/app/components/billing/pricing/index.tsx +++ b/web/app/components/billing/pricing/index.tsx @@ -40,12 +40,12 @@ const Pricing: FC = ({ >
- +
{t('billing.plansCommon.title')} From c2671c16a84764c605f5bf3a34c6e0b8655da45d Mon Sep 17 00:00:00 2001 From: NFish Date: Thu, 23 Jan 2025 11:41:10 +0800 Subject: [PATCH 14/28] fix: update bill page background opacity --- web/app/components/base/grid-mask/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/app/components/base/grid-mask/index.tsx b/web/app/components/base/grid-mask/index.tsx index 9c6965176a..6805c3dab6 100644 --- a/web/app/components/base/grid-mask/index.tsx +++ b/web/app/components/base/grid-mask/index.tsx @@ -16,7 +16,7 @@ const GridMask: FC = ({ }) => { return (
-
+
{children}
From 5d4e51739758498ecec07d749d73fb4c2f5ad8e5 Mon Sep 17 00:00:00 2001 From: NFish Date: Thu, 23 Jan 2025 14:44:26 +0800 Subject: [PATCH 15/28] fix: update billing button disabled style --- web/app/components/billing/pricing/plan-item.tsx | 6 +++++- web/i18n/zh-Hans/billing.ts | 8 ++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/web/app/components/billing/pricing/plan-item.tsx b/web/app/components/billing/pricing/plan-item.tsx index 4ba320441b..4c40e7f23b 100644 --- a/web/app/components/billing/pricing/plan-item.tsx +++ b/web/app/components/billing/pricing/plan-item.tsx @@ -50,16 +50,19 @@ const style = { icon: , description: 'text-util-colors-gray-gray-600', btnStyle: 'bg-components-button-secondary-bg hover:bg-components-button-secondary-bg-hover border-[0.5px] border-components-button-secondary-border text-text-primary', + btnDisabledStyle: 'bg-components-button-secondary-bg-disabled hover:bg-components-button-secondary-bg-disabled border-components-button-secondary-border-disabled text-components-button-secondary-text-disabled', }, [Plan.professional]: { icon: , description: 'text-util-colors-blue-brand-blue-brand-600', btnStyle: 'bg-components-button-primary-bg hover:bg-components-button-primary-bg-hover border border-components-button-primary-border text-components-button-primary-text', + btnDisabledStyle: 'bg-components-button-primary-bg-disabled hover:bg-components-button-primary-bg-disabled border-components-button-primary-border-disabled text-components-button-primary-text-disabled', }, [Plan.team]: { icon: , description: 'text-util-colors-indigo-indigo-600', btnStyle: 'bg-components-button-indigo-bg hover:bg-components-button-indigo-bg-hover border border-components-button-primary-border text-components-button-primary-text', + btnDisabledStyle: 'bg-components-button-indigo-bg-disabled hover:bg-components-button-indigo-bg-disabled border-components-button-indigo-border-disabled text-components-button-primary-text-disabled', }, } const PlanItem: FC = ({ @@ -156,7 +159,8 @@ const PlanItem: FC = ({
{btnText} diff --git a/web/i18n/zh-Hans/billing.ts b/web/i18n/zh-Hans/billing.ts index 5164183037..6d7778e91b 100644 --- a/web/i18n/zh-Hans/billing.ts +++ b/web/i18n/zh-Hans/billing.ts @@ -43,16 +43,16 @@ const translation = { contactSales: '联系销售', talkToSales: '联系销售', modelProviders: '支持 OpenAI/Anthropic/Llama2/Azure OpenAI/Hugging Face/Replicate', - teamWorkspace: '{{count}} 个团队空间', - teamMember_one: '{{count}} 名团队成员', - teamMember_other: '{{count}} 名团队成员', + teamWorkspace: '{{count,number}} 个团队空间', + teamMember_one: '{{count,number}} 名团队成员', + teamMember_other: '{{count,number}} 名团队成员', annotationQuota: '标注回复数', buildApps: '{{count, number}} 个应用程序', documents: '{{count, number}} 个知识库文档上传配额', documentsTooltip: '从知识库的数据源导入的文档数量配额。', vectorSpace: '{{size}} 知识库数据存储空间', vectorSpaceTooltip: '采用高质量索引模式的文档会消耗知识数据存储资源。当知识数据存储达到限制时,将不会上传新文档。', - documentsRequestQuota: '{{count}}/分钟 知识库请求频率限制', + documentsRequestQuota: '{{count,number}}/分钟 知识库请求频率限制', documentsRequestQuotaTooltip: '指每分钟内,一个空间在知识库中可执行的操作总数,包括数据集的创建、删除、更新,文档的上传、修改、归档,以及知识库查询等,用于评估知识库请求的性能。例如,Sandbox 用户在 1 分钟内连续执行 10 次命中测试,其工作区将在接下来的 1 分钟内无法继续执行以下操作:数据集的创建、删除、更新,文档的上传、修改等操作。', documentProcessingPriority: '文档处理', priority: { From 278adbc10ebf5b38c584ef6bbc82943d754220cb Mon Sep 17 00:00:00 2001 From: NFish Date: Thu, 23 Jan 2025 14:49:04 +0800 Subject: [PATCH 16/28] fix: update jp translate error --- web/i18n/ja-JP/billing.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/i18n/ja-JP/billing.ts b/web/i18n/ja-JP/billing.ts index 4f0792bc2f..b744001cfc 100644 --- a/web/i18n/ja-JP/billing.ts +++ b/web/i18n/ja-JP/billing.ts @@ -60,7 +60,7 @@ const translation = { 'priority': '優先', 'top-priority': '最優先', }, - logsHistory: '{{days}}ログ履歴', + logsHistory: '{{days}}のログ履歴', customTools: 'カスタムツール', unavailable: '利用不可', days: '日', From 5673f03db57e9a17fab8b2549a33bb80efe1ad7e Mon Sep 17 00:00:00 2001 From: NFish Date: Thu, 23 Jan 2025 16:30:39 +0800 Subject: [PATCH 17/28] fix: update documentsRequestQuota value --- web/app/components/billing/config.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/app/components/billing/config.ts b/web/app/components/billing/config.ts index 9affe76bee..435ae1589f 100644 --- a/web/app/components/billing/config.ts +++ b/web/app/components/billing/config.ts @@ -37,7 +37,7 @@ export const ALL_PLANS: Record = { documents: 500, vectorSpace: '5GB', documentsUploadQuota: 0, - documentsRequestQuota: 10, + documentsRequestQuota: 100, documentProcessingPriority: Priority.priority, messageRequest: 5000, annotatedResponse: 2000, @@ -53,7 +53,7 @@ export const ALL_PLANS: Record = { documents: 1000, vectorSpace: '20GB', documentsUploadQuota: 0, - documentsRequestQuota: 2000, + documentsRequestQuota: 1000, documentProcessingPriority: Priority.topPriority, messageRequest: 10000, annotatedResponse: 5000, From 7f49f96c3f3859d295b369627c0a8d34ef35fedf Mon Sep 17 00:00:00 2001 From: NFish Date: Thu, 23 Jan 2025 17:02:49 +0800 Subject: [PATCH 18/28] fix: update team members value --- web/app/components/billing/config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/app/components/billing/config.ts b/web/app/components/billing/config.ts index 435ae1589f..8ee6b18242 100644 --- a/web/app/components/billing/config.ts +++ b/web/app/components/billing/config.ts @@ -48,7 +48,7 @@ export const ALL_PLANS: Record = { price: 159, modelProviders: supportModelProviders, teamWorkspace: 1, - teamMembers: 5, + teamMembers: 50, buildApps: 200, documents: 1000, vectorSpace: '20GB', From aafab1b59e39cee88f76acc61afbfc1bcd0a0fd7 Mon Sep 17 00:00:00 2001 From: NFish Date: Thu, 23 Jan 2025 17:09:44 +0800 Subject: [PATCH 19/28] fix: update sandbox log histroy value --- web/app/components/billing/config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/app/components/billing/config.ts b/web/app/components/billing/config.ts index 8ee6b18242..257b9d80fd 100644 --- a/web/app/components/billing/config.ts +++ b/web/app/components/billing/config.ts @@ -25,7 +25,7 @@ export const ALL_PLANS: Record = { documentProcessingPriority: Priority.standard, messageRequest: 200, annotatedResponse: 10, - logHistory: 15, + logHistory: 30, }, professional: { level: 2, From a4a45421ccb91ca3ed8ed12c23ff8e462dc4a5b0 Mon Sep 17 00:00:00 2001 From: NFish Date: Thu, 23 Jan 2025 17:16:54 +0800 Subject: [PATCH 20/28] fix: update sandbox log history value in jp --- web/i18n/ja-JP/billing.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/i18n/ja-JP/billing.ts b/web/i18n/ja-JP/billing.ts index b744001cfc..796043721c 100644 --- a/web/i18n/ja-JP/billing.ts +++ b/web/i18n/ja-JP/billing.ts @@ -63,7 +63,7 @@ const translation = { logsHistory: '{{days}}のログ履歴', customTools: 'カスタムツール', unavailable: '利用不可', - days: '日', + days: '日間', unlimited: '無制限', support: 'サポート', supportItems: { From a9dda1554e7c4bc73ed52247571533f946223f85 Mon Sep 17 00:00:00 2001 From: Yeuoly <45712896+Yeuoly@users.noreply.github.com> Date: Thu, 27 Feb 2025 13:35:41 +0800 Subject: [PATCH 21/28] Fix/custom model credentials (#14450) --- api/core/plugin/entities/plugin.py | 2 +- api/core/provider_manager.py | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/api/core/plugin/entities/plugin.py b/api/core/plugin/entities/plugin.py index 732e10c191..c61e848a42 100644 --- a/api/core/plugin/entities/plugin.py +++ b/api/core/plugin/entities/plugin.py @@ -180,7 +180,7 @@ class ToolProviderID(GenericProviderID): def __init__(self, value: str, is_hardcoded: bool = False) -> None: super().__init__(value, is_hardcoded) if self.organization == "langgenius": - if self.provider_name in ["jina", "siliconflow", "stepfun"]: + if self.provider_name in ["jina", "siliconflow", "stepfun", "gitee_ai"]: self.plugin_name = f"{self.provider_name}_tool" diff --git a/api/core/provider_manager.py b/api/core/provider_manager.py index 918840530b..7d8ff18983 100644 --- a/api/core/provider_manager.py +++ b/api/core/provider_manager.py @@ -111,6 +111,12 @@ class ProviderManager: # Get all provider model records of the workspace provider_name_to_provider_model_records_dict = self._get_all_provider_models(tenant_id) + for provider_name in list(provider_name_to_provider_model_records_dict.keys()): + provider_id = ModelProviderID(provider_name) + if str(provider_id) not in provider_name_to_provider_model_records_dict: + provider_name_to_provider_model_records_dict[str(provider_id)] = ( + provider_name_to_provider_model_records_dict[provider_name] + ) # Get all provider entities model_provider_factory = ModelProviderFactory(tenant_id) From 78a7d7fa2161a63ea94c1e8d3a2585d8729d8679 Mon Sep 17 00:00:00 2001 From: Joel Date: Thu, 27 Feb 2025 13:51:27 +0800 Subject: [PATCH 22/28] fix: handle gitee old name (#14451) --- web/utils/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/web/utils/index.ts b/web/utils/index.ts index 02d3281a0d..9285d0bd03 100644 --- a/web/utils/index.ts +++ b/web/utils/index.ts @@ -76,7 +76,7 @@ export const correctToolProvider = (provider: string) => { if (provider.includes('/')) return provider - if (['stepfun', 'jina', 'siliconflow'].includes(provider)) + if (['stepfun', 'jina', 'siliconflow', 'gitee_ai'].includes(provider)) return `langgenius/${provider}_tool/${provider}` return `langgenius/${provider}/${provider}` @@ -84,6 +84,6 @@ export const correctToolProvider = (provider: string) => { export const canFindTool = (providerId: string, oldToolId?: string) => { return providerId === oldToolId - || providerId === `langgenius/${oldToolId}/${oldToolId}` - || providerId === `langgenius/${oldToolId}_tool/${oldToolId}` + || providerId === `langgenius/${oldToolId}/${oldToolId}` + || providerId === `langgenius/${oldToolId}_tool/${oldToolId}` } From 5f692dfce28013a63cb31beffa32c29d1985a9b5 Mon Sep 17 00:00:00 2001 From: NFish Date: Thu, 27 Feb 2025 14:02:04 +0800 Subject: [PATCH 23/28] fix: update trial tip time to 3/17 (#14452) --- web/context/provider-context.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/context/provider-context.tsx b/web/context/provider-context.tsx index 0ac81278a2..11340f6acd 100644 --- a/web/context/provider-context.tsx +++ b/web/context/provider-context.tsx @@ -120,7 +120,7 @@ export const ProviderContextProvider = ({ if (localStorage.getItem('anthropic_quota_notice') === 'true') return - if (dayjs().isAfter(dayjs('2025-03-11'))) + if (dayjs().isAfter(dayjs('2025-03-17'))) return if (providersData?.data && providersData.data.length > 0) { From 1e3197a1ea31997863ea0aadf6ff20baba8fba44 Mon Sep 17 00:00:00 2001 From: yuhaowin <34699768+yuhaowin@users.noreply.github.com> Date: Thu, 27 Feb 2025 14:56:46 +0800 Subject: [PATCH 24/28] Fixes 14217: database retrieve api and chat-messages api response doc_metadata (#14219) --- api/core/rag/retrieval/dataset_retrieval.py | 1 + .../utils/dataset_retriever/dataset_multi_retriever_tool.py | 1 + api/core/tools/utils/dataset_retriever/dataset_retriever_tool.py | 1 + .../nodes/knowledge_retrieval/knowledge_retrieval_node.py | 1 + api/core/workflow/nodes/llm/node.py | 1 + api/fields/hit_testing_fields.py | 1 + 6 files changed, 6 insertions(+) diff --git a/api/core/rag/retrieval/dataset_retrieval.py b/api/core/rag/retrieval/dataset_retrieval.py index 2193d8d3fd..ac868a2250 100644 --- a/api/core/rag/retrieval/dataset_retrieval.py +++ b/api/core/rag/retrieval/dataset_retrieval.py @@ -203,6 +203,7 @@ class DatasetRetrieval: "segment_id": segment.id, "retriever_from": invoke_from.to_source(), "score": record.score or 0.0, + "doc_metadata": document.doc_metadata, } if invoke_from.to_source() == "dev": diff --git a/api/core/tools/utils/dataset_retriever/dataset_multi_retriever_tool.py b/api/core/tools/utils/dataset_retriever/dataset_multi_retriever_tool.py index 802bee4217..032274b87e 100644 --- a/api/core/tools/utils/dataset_retriever/dataset_multi_retriever_tool.py +++ b/api/core/tools/utils/dataset_retriever/dataset_multi_retriever_tool.py @@ -123,6 +123,7 @@ class DatasetMultiRetrieverTool(DatasetRetrieverBaseTool): "segment_id": segment.id, "retriever_from": self.retriever_from, "score": document_score_list.get(segment.index_node_id, None), + "doc_metadata": document.doc_metadata, } if self.retriever_from == "dev": diff --git a/api/core/tools/utils/dataset_retriever/dataset_retriever_tool.py b/api/core/tools/utils/dataset_retriever/dataset_retriever_tool.py index 946d99ef6f..e0a5ee9aab 100644 --- a/api/core/tools/utils/dataset_retriever/dataset_retriever_tool.py +++ b/api/core/tools/utils/dataset_retriever/dataset_retriever_tool.py @@ -172,6 +172,7 @@ class DatasetRetrieverTool(DatasetRetrieverBaseTool): "segment_id": segment.id, "retriever_from": self.retriever_from, "score": record.score or 0.0, + "doc_metadata": document.doc_metadat, # type: ignore } if self.retriever_from == "dev": diff --git a/api/core/workflow/nodes/knowledge_retrieval/knowledge_retrieval_node.py b/api/core/workflow/nodes/knowledge_retrieval/knowledge_retrieval_node.py index 0f239af51a..d77def2c40 100644 --- a/api/core/workflow/nodes/knowledge_retrieval/knowledge_retrieval_node.py +++ b/api/core/workflow/nodes/knowledge_retrieval/knowledge_retrieval_node.py @@ -240,6 +240,7 @@ class KnowledgeRetrievalNode(BaseNode[KnowledgeRetrievalNodeData]): "segment_word_count": segment.word_count, "segment_position": segment.position, "segment_index_node_hash": segment.index_node_hash, + "doc_metadata": document.doc_metadata, }, "title": document.name, } diff --git a/api/core/workflow/nodes/llm/node.py b/api/core/workflow/nodes/llm/node.py index aff3d2b7c6..f717a2a877 100644 --- a/api/core/workflow/nodes/llm/node.py +++ b/api/core/workflow/nodes/llm/node.py @@ -459,6 +459,7 @@ class LLMNode(BaseNode[LLMNodeData]): "index_node_hash": metadata.get("segment_index_node_hash"), "content": context_dict.get("content"), "page": metadata.get("page"), + "doc_metadata": metadata.get("doc_metadata"), } return source diff --git a/api/fields/hit_testing_fields.py b/api/fields/hit_testing_fields.py index d9758474f7..4514c1b8ca 100644 --- a/api/fields/hit_testing_fields.py +++ b/api/fields/hit_testing_fields.py @@ -7,6 +7,7 @@ document_fields = { "data_source_type": fields.String, "name": fields.String, "doc_type": fields.String, + "doc_metadata": fields.Raw, } segment_fields = { From 4fbe52da401cbb558c584761de0fbe390ad07834 Mon Sep 17 00:00:00 2001 From: Wu Tianwei <30284043+WTW0313@users.noreply.github.com> Date: Thu, 27 Feb 2025 15:11:42 +0800 Subject: [PATCH 25/28] fix: update dependencies and improve app detail handling (#14444) --- .../(commonLayout)/app/(appDetailLayout)/[appId]/layout.tsx | 6 +++--- web/app/components/app-sidebar/navLink.tsx | 4 ++-- web/app/components/app/configuration/index.tsx | 2 +- web/app/components/app/create-app-dialog/app-list/index.tsx | 4 ++-- web/app/components/explore/app-list/index.tsx | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/layout.tsx b/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/layout.tsx index 69a423ab21..3b43186196 100644 --- a/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/layout.tsx +++ b/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/layout.tsx @@ -94,7 +94,7 @@ const AppDetailLayout: FC = (props) => { }, ] return navs - }, [t]) + }, []) useEffect(() => { if (appDetail) { @@ -120,7 +120,7 @@ const AppDetailLayout: FC = (props) => { }).finally(() => { setIsLoadingAppDetail(false) }) - }, [appId, router, setAppDetail]) + }, [appId, pathname]) useEffect(() => { if (!appDetailRes || isLoadingCurrentWorkspace || isLoadingAppDetail) @@ -148,7 +148,7 @@ const AppDetailLayout: FC = (props) => { } } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [appDetailRes, appId, getNavigations, isCurrentWorkspaceEditor, isLoadingAppDetail, isLoadingCurrentWorkspace, router, setAppDetail, systemFeatures.enable_web_sso_switch_component]) + }, [appDetailRes, isCurrentWorkspaceEditor, isLoadingAppDetail, isLoadingCurrentWorkspace, systemFeatures.enable_web_sso_switch_component]) useUnmount(() => { setAppDetail() diff --git a/web/app/components/app-sidebar/navLink.tsx b/web/app/components/app-sidebar/navLink.tsx index bec6bf105f..4e04fcc3e1 100644 --- a/web/app/components/app-sidebar/navLink.tsx +++ b/web/app/components/app-sidebar/navLink.tsx @@ -3,13 +3,13 @@ import { useSelectedLayoutSegment } from 'next/navigation' import Link from 'next/link' import classNames from '@/utils/classnames' +import type { RemixiconComponentType } from '@remixicon/react' export type NavIcon = React.ComponentType< React.PropsWithoutRef> & { title?: string | undefined titleId?: string | undefined -} -> +}> | RemixiconComponentType export type NavLinkProps = { name: string diff --git a/web/app/components/app/configuration/index.tsx b/web/app/components/app/configuration/index.tsx index 5f2c8909a5..87f71f54a0 100644 --- a/web/app/components/app/configuration/index.tsx +++ b/web/app/components/app/configuration/index.tsx @@ -94,7 +94,7 @@ const Configuration: FC = () => { }))) const { data: fileUploadConfigResponse } = useSWR({ url: '/files/upload' }, fetchFileUploadConfig) - const latestPublishedAt = useMemo(() => appDetail?.model_config.updated_at, [appDetail]) + const latestPublishedAt = useMemo(() => appDetail?.model_config?.updated_at, [appDetail]) const [formattingChanged, setFormattingChanged] = useState(false) const { setShowAccountSettingModal } = useModalContext() const [hasFetchedDetail, setHasFetchedDetail] = useState(false) diff --git a/web/app/components/app/create-app-dialog/app-list/index.tsx b/web/app/components/app/create-app-dialog/app-list/index.tsx index a545774f2c..69990f9311 100644 --- a/web/app/components/app/create-app-dialog/app-list/index.tsx +++ b/web/app/components/app/create-app-dialog/app-list/index.tsx @@ -128,7 +128,7 @@ const Apps = ({ icon_background, description, }) => { - const { export_data } = await fetchAppDetail( + const { export_data, mode } = await fetchAppDetail( currApp?.app.id as string, ) try { @@ -151,7 +151,7 @@ const Apps = ({ if (app.app_id) await handleCheckPluginDependencies(app.app_id) localStorage.setItem(NEED_REFRESH_APP_LIST_KEY, '1') - getRedirection(isCurrentWorkspaceEditor, { id: app.app_id }, push) + getRedirection(isCurrentWorkspaceEditor, { id: app.app_id, mode }, push) } catch (e) { Toast.notify({ type: 'error', message: t('app.newApp.appCreateFailed') }) diff --git a/web/app/components/explore/app-list/index.tsx b/web/app/components/explore/app-list/index.tsx index 458aadcb61..4fef183d52 100644 --- a/web/app/components/explore/app-list/index.tsx +++ b/web/app/components/explore/app-list/index.tsx @@ -126,7 +126,7 @@ const Apps = ({ icon_background, description, }) => { - const { export_data } = await fetchAppDetail( + const { export_data, mode } = await fetchAppDetail( currApp?.app.id as string, ) try { @@ -149,7 +149,7 @@ const Apps = ({ if (app.app_id) await handleCheckPluginDependencies(app.app_id) localStorage.setItem(NEED_REFRESH_APP_LIST_KEY, '1') - getRedirection(isCurrentWorkspaceEditor, { id: app.app_id }, push) + getRedirection(isCurrentWorkspaceEditor, { id: app.app_id, mode }, push) } catch (e) { Toast.notify({ type: 'error', message: t('app.newApp.appCreateFailed') }) From bb4fecf3d180f587bf4371fa37deb0ebd7015779 Mon Sep 17 00:00:00 2001 From: Novice <857526207@qq.com> Date: Thu, 27 Feb 2025 16:09:13 +0800 Subject: [PATCH 26/28] fix(agent node): tool setting and workflow tool. (#14461) --- api/core/workflow/nodes/agent/agent_node.py | 49 ++++++++++++++++++--- api/core/workflow/nodes/agent/entities.py | 6 +++ 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/api/core/workflow/nodes/agent/agent_node.py b/api/core/workflow/nodes/agent/agent_node.py index db84624961..d50c858fff 100644 --- a/api/core/workflow/nodes/agent/agent_node.py +++ b/api/core/workflow/nodes/agent/agent_node.py @@ -8,12 +8,12 @@ from core.model_manager import ModelManager from core.model_runtime.entities.model_entities import ModelType from core.plugin.manager.exc import PluginDaemonClientSideError from core.plugin.manager.plugin import PluginInstallationManager -from core.tools.entities.tool_entities import ToolProviderType +from core.tools.entities.tool_entities import ToolParameter, ToolProviderType from core.tools.tool_manager import ToolManager from core.workflow.entities.node_entities import NodeRunResult from core.workflow.entities.variable_pool import VariablePool from core.workflow.enums import SystemVariableKey -from core.workflow.nodes.agent.entities import AgentNodeData +from core.workflow.nodes.agent.entities import AgentNodeData, ParamsAutoGenerated from core.workflow.nodes.base.entities import BaseNodeData from core.workflow.nodes.enums import NodeType from core.workflow.nodes.event.event import RunCompletedEvent @@ -156,16 +156,38 @@ class AgentNode(ToolNode): value = cast(list[dict[str, Any]], value) value = [tool for tool in value if tool.get("enabled", False)] + for tool in value: + if "schemas" in tool: + tool.pop("schemas") + parameters = tool.get("parameters", {}) + if all(isinstance(v, dict) for _, v in parameters.items()): + params = {} + for key, param in parameters.items(): + if param.get("auto", ParamsAutoGenerated.OPEN.value) == ParamsAutoGenerated.CLOSE.value: + value_param = param.get("value", {}) + params[key] = value_param.get("value", "") if value_param is not None else None + else: + params[key] = None + parameters = params + tool["settings"] = {k: v.get("value", None) for k, v in tool.get("settings", {}).items()} + tool["parameters"] = parameters + if not for_log: if parameter.type == "array[tools]": value = cast(list[dict[str, Any]], value) tool_value = [] for tool in value: + provider_type = ToolProviderType(tool.get("type", ToolProviderType.BUILT_IN.value)) + setting_params = tool.get("settings", {}) + parameters = tool.get("parameters", {}) + manual_input_params = [key for key, value in parameters.items() if value is not None] + + parameters = {**parameters, **setting_params} entity = AgentToolEntity( provider_id=tool.get("provider_name", ""), - provider_type=ToolProviderType.BUILT_IN, + provider_type=provider_type, tool_name=tool.get("tool_name", ""), - tool_parameters=tool.get("parameters", {}), + tool_parameters=parameters, plugin_unique_identifier=tool.get("plugin_unique_identifier", None), ) @@ -178,11 +200,26 @@ class AgentNode(ToolNode): tool_runtime.entity.description.llm = ( extra.get("descrption", "") or tool_runtime.entity.description.llm ) - + for tool_runtime_params in tool_runtime.entity.parameters: + tool_runtime_params.form = ( + ToolParameter.ToolParameterForm.FORM + if tool_runtime_params.name in manual_input_params + else tool_runtime_params.form + ) + manual_input_value = {} + if tool_runtime.entity.parameters: + manual_input_value = { + key: value for key, value in parameters.items() if key in manual_input_params + } + runtime_parameters = { + **tool_runtime.runtime.runtime_parameters, + **manual_input_value, + } tool_value.append( { **tool_runtime.entity.model_dump(mode="json"), - "runtime_parameters": tool_runtime.runtime.runtime_parameters, + "runtime_parameters": runtime_parameters, + "provider_type": provider_type.value, } ) value = tool_value diff --git a/api/core/workflow/nodes/agent/entities.py b/api/core/workflow/nodes/agent/entities.py index 066dcd5666..a10cee69bd 100644 --- a/api/core/workflow/nodes/agent/entities.py +++ b/api/core/workflow/nodes/agent/entities.py @@ -1,3 +1,4 @@ +from enum import Enum from typing import Any, Literal, Union from pydantic import BaseModel @@ -16,3 +17,8 @@ class AgentNodeData(BaseNodeData): type: Literal["mixed", "variable", "constant"] agent_parameters: dict[str, AgentInput] + + +class ParamsAutoGenerated(Enum): + CLOSE = 0 + OPEN = 1 From ddf9eb1f9a69be1acf1ee8470d32f68b1495e1ce Mon Sep 17 00:00:00 2001 From: NFish Date: Thu, 27 Feb 2025 16:54:54 +0800 Subject: [PATCH 27/28] fix: page broke down while rendering node contained img and other elements (#14467) --- web/app/components/base/markdown.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/web/app/components/base/markdown.tsx b/web/app/components/base/markdown.tsx index 1a4358c8bc..2b58b932a4 100644 --- a/web/app/components/base/markdown.tsx +++ b/web/app/components/base/markdown.tsx @@ -211,7 +211,9 @@ const Paragraph = (paragraph: any) => { return ( <> -

{paragraph.children.slice(1)}

+ { + Array.isArray(paragraph.children) ?

{paragraph.children.slice(1)}

: null + } ) } From cf75fcdffc24a2f0b15d9a8acf4d09eef3947ac4 Mon Sep 17 00:00:00 2001 From: NFish Date: Thu, 27 Feb 2025 18:04:24 +0800 Subject: [PATCH 28/28] fix: merge main --- web/tailwind-common-config.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/web/tailwind-common-config.ts b/web/tailwind-common-config.ts index 2bc7343a45..96c8cbee7d 100644 --- a/web/tailwind-common-config.ts +++ b/web/tailwind-common-config.ts @@ -111,6 +111,11 @@ const config = { 'dataset-option-card-purple-gradient': 'var(--color-dataset-option-card-purple-gradient)', 'dataset-option-card-orange-gradient': 'var(--color-dataset-option-card-orange-gradient)', 'dataset-chunk-list-mask-bg': 'var(--color-dataset-chunk-list-mask-bg)', + 'price-premium-badge-background': 'var(--color-premium-badge-background)', + 'premium-yearly-tip-text-background': 'var(--color-premium-yearly-tip-text-background)', + 'price-premium-text-background': 'var(--color-premium-text-background)', + 'price-enterprise-background': 'var(--color-price-enterprise-background)', + 'grid-mask-background': 'var(--color-grid-mask-background)', }, animation: { 'spin-slow': 'spin 2s linear infinite',