feat: add confirm ui (#4625)

This commit is contained in:
crazywoola 2024-05-23 20:15:51 +08:00 committed by GitHub
parent 24624491cd
commit 10c61da686
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 172 additions and 143 deletions

View File

@ -22,6 +22,7 @@ import Tag from '@/app/components/base/tag'
import Switch from '@/app/components/base/switch' import Switch from '@/app/components/base/switch'
import Divider from '@/app/components/base/divider' import Divider from '@/app/components/base/divider'
import CopyFeedback from '@/app/components/base/copy-feedback' import CopyFeedback from '@/app/components/base/copy-feedback'
import Confirm from '@/app/components/base/confirm'
import ShareQRCode from '@/app/components/base/qrcode' import ShareQRCode from '@/app/components/base/qrcode'
import SecretKeyButton from '@/app/components/develop/secret-key/secret-key-button' import SecretKeyButton from '@/app/components/develop/secret-key/secret-key-button'
import type { AppDetailResponse } from '@/models/app' import type { AppDetailResponse } from '@/models/app'
@ -57,6 +58,8 @@ function AppCard({
const [showEmbedded, setShowEmbedded] = useState(false) const [showEmbedded, setShowEmbedded] = useState(false)
const [showCustomizeModal, setShowCustomizeModal] = useState(false) const [showCustomizeModal, setShowCustomizeModal] = useState(false)
const [genLoading, setGenLoading] = useState(false) const [genLoading, setGenLoading] = useState(false)
const [showConfirmDelete, setShowConfirmDelete] = useState(false)
const { t } = useTranslation() const { t } = useTranslation()
const OPERATIONS_MAP = useMemo(() => { const OPERATIONS_MAP = useMemo(() => {
@ -176,6 +179,20 @@ function AppCard({
className={'hover:bg-gray-200'} className={'hover:bg-gray-200'}
/> />
{/* button copy link/ button regenerate */} {/* button copy link/ button regenerate */}
{showConfirmDelete && (
<Confirm
type='warning'
title={t('appOverview.overview.appInfo.regenerate')}
content={''}
isShow={showConfirmDelete}
onClose={() => setShowConfirmDelete(false)}
onConfirm={() => {
onGenCode()
setShowConfirmDelete(false)
}}
onCancel={() => setShowConfirmDelete(false)}
/>
)}
{isApp && isCurrentWorkspaceManager && ( {isApp && isCurrentWorkspaceManager && (
<Tooltip <Tooltip
content={t('appOverview.overview.appInfo.regenerate') || ''} content={t('appOverview.overview.appInfo.regenerate') || ''}
@ -183,7 +200,7 @@ function AppCard({
> >
<div <div
className="w-8 h-8 ml-0.5 cursor-pointer hover:bg-gray-200 rounded-lg" className="w-8 h-8 ml-0.5 cursor-pointer hover:bg-gray-200 rounded-lg"
onClick={onGenCode} onClick={() => setShowConfirmDelete(true)}
> >
<div <div
className={`w-full h-full ${style.refreshIcon} ${ className={`w-full h-full ${style.refreshIcon} ${

View File

@ -1,142 +1,143 @@
const translation = { const translation = {
welcome: { welcome: {
firstStepTip: 'Um zu beginnen,', firstStepTip: 'Um zu beginnen,',
enterKeyTip: 'geben Sie unten Ihren OpenAI-API-Schlüssel ein', enterKeyTip: 'geben Sie unten Ihren OpenAI-API-Schlüssel ein',
getKeyTip: 'Holen Sie sich Ihren API-Schlüssel vom OpenAI-Dashboard', getKeyTip: 'Holen Sie sich Ihren API-Schlüssel vom OpenAI-Dashboard',
placeholder: 'Ihr OpenAI-API-Schlüssel (z.B. sk-xxxx)', placeholder: 'Ihr OpenAI-API-Schlüssel (z.B. sk-xxxx)',
}, },
apiKeyInfo: { apiKeyInfo: {
cloud: { cloud: {
trial: { trial: {
title: 'Sie nutzen das Testkontingent von {{providerName}}.', title: 'Sie nutzen das Testkontingent von {{providerName}}.',
description: 'Das Testkontingent wird für Ihre Testnutzung bereitgestellt. Bevor das Testkontingent aufgebraucht ist, richten Sie bitte Ihren eigenen Modellanbieter ein oder kaufen zusätzliches Kontingent.', description: 'Das Testkontingent wird für Ihre Testnutzung bereitgestellt. Bevor das Testkontingent aufgebraucht ist, richten Sie bitte Ihren eigenen Modellanbieter ein oder kaufen zusätzliches Kontingent.',
}, },
exhausted: { exhausted: {
title: 'Ihr Testkontingent wurde aufgebraucht, bitte richten Sie Ihren APIKey ein.', title: 'Ihr Testkontingent wurde aufgebraucht, bitte richten Sie Ihren APIKey ein.',
description: 'Ihr Testkontingent ist aufgebraucht. Bitte richten Sie Ihren eigenen Modellanbieter ein oder kaufen zusätzliches Kontingent.', description: 'Ihr Testkontingent ist aufgebraucht. Bitte richten Sie Ihren eigenen Modellanbieter ein oder kaufen zusätzliches Kontingent.',
}, },
}, },
selfHost: { selfHost: {
title: { title: {
row1: 'Um zu beginnen,', row1: 'Um zu beginnen,',
row2: 'richten Sie zuerst Ihren Modellanbieter ein.', row2: 'richten Sie zuerst Ihren Modellanbieter ein.',
}, },
}, },
callTimes: 'Aufrufzeiten', callTimes: 'Aufrufzeiten',
usedToken: 'Verwendetes Token', usedToken: 'Verwendetes Token',
setAPIBtn: 'Zum Einrichten des Modellanbieters gehen', setAPIBtn: 'Zum Einrichten des Modellanbieters gehen',
tryCloud: 'Oder probieren Sie die Cloud-Version von Dify mit kostenlosem Angebot aus', tryCloud: 'Oder probieren Sie die Cloud-Version von Dify mit kostenlosem Angebot aus',
}, },
overview: { overview: {
title: 'Übersicht', title: 'Übersicht',
appInfo: { appInfo: {
explanation: 'Einsatzbereite AI-WebApp', explanation: 'Einsatzbereite AI-WebApp',
accessibleAddress: 'Öffentliche URL', accessibleAddress: 'Öffentliche URL',
preview: 'Vorschau', preview: 'Vorschau',
regenerate: 'Regenerieren', regenerate: 'Regenerieren',
preUseReminder: 'Bitte aktivieren Sie WebApp, bevor Sie fortfahren.', regenerateNotice: 'Möchten Sie die öffentliche URL neu generieren?',
settings: { preUseReminder: 'Bitte aktivieren Sie WebApp, bevor Sie fortfahren.',
entry: 'Einstellungen', settings: {
title: 'WebApp-Einstellungen', entry: 'Einstellungen',
webName: 'WebApp-Name', title: 'WebApp-Einstellungen',
webDesc: 'WebApp-Beschreibung', webName: 'WebApp-Name',
webDescTip: 'Dieser Text wird auf der Clientseite angezeigt und bietet grundlegende Anleitungen zur Verwendung der Anwendung', webDesc: 'WebApp-Beschreibung',
webDescPlaceholder: 'Geben Sie die Beschreibung der WebApp ein', webDescTip: 'Dieser Text wird auf der Clientseite angezeigt und bietet grundlegende Anleitungen zur Verwendung der Anwendung',
language: 'Sprache', webDescPlaceholder: 'Geben Sie die Beschreibung der WebApp ein',
more: { language: 'Sprache',
entry: 'Mehr Einstellungen anzeigen', more: {
copyright: 'Urheberrecht', entry: 'Mehr Einstellungen anzeigen',
copyRightPlaceholder: 'Geben Sie den Namen des Autors oder der Organisation ein', copyright: 'Urheberrecht',
privacyPolicy: 'Datenschutzrichtlinie', copyRightPlaceholder: 'Geben Sie den Namen des Autors oder der Organisation ein',
privacyPolicyPlaceholder: 'Geben Sie den Link zur Datenschutzrichtlinie ein', privacyPolicy: 'Datenschutzrichtlinie',
privacyPolicyTip: 'Hilft Besuchern zu verstehen, welche Daten die Anwendung sammelt, siehe Difys <privacyPolicyLink>Datenschutzrichtlinie</privacyPolicyLink>.', privacyPolicyPlaceholder: 'Geben Sie den Link zur Datenschutzrichtlinie ein',
customDisclaimer: 'Benutzerdefinierte Haftungsausschluss', privacyPolicyTip: 'Hilft Besuchern zu verstehen, welche Daten die Anwendung sammelt, siehe Difys <privacyPolicyLink>Datenschutzrichtlinie</privacyPolicyLink>.',
customDisclaimerPlaceholder: 'Geben Sie den benutzerdefinierten Haftungsausschluss-Text ein', customDisclaimer: 'Benutzerdefinierte Haftungsausschluss',
customDisclaimerTip: 'Der ben userdefinierte Haftungsausschluss-Text wird auf der Clientseite angezeigt und bietet zusätzliche Informationen über die Anwendung', customDisclaimerPlaceholder: 'Geben Sie den benutzerdefinierten Haftungsausschluss-Text ein',
}, customDisclaimerTip: 'Der ben userdefinierte Haftungsausschluss-Text wird auf der Clientseite angezeigt und bietet zusätzliche Informationen über die Anwendung',
}, },
embedded: { },
entry: 'Eingebettet', embedded: {
title: 'Einbetten auf der Website', entry: 'Eingebettet',
explanation: 'Wählen Sie die Art und Weise, wie die Chat-App auf Ihrer Website eingebettet wird', title: 'Einbetten auf der Website',
iframe: 'Um die Chat-App an einer beliebigen Stelle auf Ihrer Website hinzuzufügen, fügen Sie diesen iframe in Ihren HTML-Code ein.', explanation: 'Wählen Sie die Art und Weise, wie die Chat-App auf Ihrer Website eingebettet wird',
scripts: 'Um eine Chat-App unten rechts auf Ihrer Website hinzuzufügen, fügen Sie diesen Code in Ihren HTML-Code ein.', iframe: 'Um die Chat-App an einer beliebigen Stelle auf Ihrer Website hinzuzufügen, fügen Sie diesen iframe in Ihren HTML-Code ein.',
chromePlugin: 'Installieren Sie die Dify Chatbot Chrome-Erweiterung', scripts: 'Um eine Chat-App unten rechts auf Ihrer Website hinzuzufügen, fügen Sie diesen Code in Ihren HTML-Code ein.',
copied: 'Kopiert', chromePlugin: 'Installieren Sie die Dify Chatbot Chrome-Erweiterung',
copy: 'Kopieren', copied: 'Kopiert',
}, copy: 'Kopieren',
qrcode: { },
title: 'QR-Code zum Teilen', qrcode: {
scan: 'Teilen Sie die Anwendung per Scan', title: 'QR-Code zum Teilen',
download: 'QR-Code herunterladen', scan: 'Teilen Sie die Anwendung per Scan',
}, download: 'QR-Code herunterladen',
customize: { },
way: 'Art', customize: {
entry: 'Anpassen', way: 'Art',
title: 'AI-WebApp anpassen', entry: 'Anpassen',
explanation: 'Sie können das Frontend der Web-App an Ihre Szenarien und Stilbedürfnisse anpassen.', title: 'AI-WebApp anpassen',
way1: { explanation: 'Sie können das Frontend der Web-App an Ihre Szenarien und Stilbedürfnisse anpassen.',
name: 'Forken Sie den Client-Code, ändern Sie ihn und deployen Sie ihn auf Vercel (empfohlen)', way1: {
step1: 'Forken Sie den Client-Code und ändern Sie ihn', name: 'Forken Sie den Client-Code, ändern Sie ihn und deployen Sie ihn auf Vercel (empfohlen)',
step1Tip: 'Klicken Sie hier, um den Quellcode in Ihr GitHub-Konto zu forken und den Code zu ändern', step1: 'Forken Sie den Client-Code und ändern Sie ihn',
step1Operation: 'Dify-WebClient', step1Tip: 'Klicken Sie hier, um den Quellcode in Ihr GitHub-Konto zu forken und den Code zu ändern',
step2: 'Deployen auf Vercel', step1Operation: 'Dify-WebClient',
step2Tip: 'Klicken Sie hier, um das Repository in Vercel zu importieren und zu deployen', step2: 'Deployen auf Vercel',
step2Operation: 'Repository importieren', step2Tip: 'Klicken Sie hier, um das Repository in Vercel zu importieren und zu deployen',
step3: 'Umgebungsvariablen konfigurieren', step2Operation: 'Repository importieren',
step3Tip: 'Fügen Sie die folgenden Umgebungsvariablen in Vercel hinzu', step3: 'Umgebungsvariablen konfigurieren',
}, step3Tip: 'Fügen Sie die folgenden Umgebungsvariablen in Vercel hinzu',
way2: { },
name: 'Clientseitigen Code schreiben, um die API aufzurufen, und ihn auf einem Server deployen', way2: {
operation: 'Dokumentation', name: 'Clientseitigen Code schreiben, um die API aufzurufen, und ihn auf einem Server deployen',
}, operation: 'Dokumentation',
}, },
}, },
apiInfo: { },
title: 'Backend-Service-API', apiInfo: {
explanation: 'Einfach in Ihre Anwendung integrierbar', title: 'Backend-Service-API',
accessibleAddress: 'Service-API-Endpunkt', explanation: 'Einfach in Ihre Anwendung integrierbar',
doc: 'API-Referenz', accessibleAddress: 'Service-API-Endpunkt',
}, doc: 'API-Referenz',
status: { },
running: 'In Betrieb', status: {
disable: 'Deaktivieren', running: 'In Betrieb',
}, disable: 'Deaktivieren',
}, },
analysis: { },
title: 'Analyse', analysis: {
ms: 'ms', title: 'Analyse',
tokenPS: 'Token/s', ms: 'ms',
totalMessages: { tokenPS: 'Token/s',
title: 'Gesamtnachrichten', totalMessages: {
explanation: 'Tägliche AI-Interaktionszählung; Prompt-Engineering/Debugging ausgenommen.', title: 'Gesamtnachrichten',
}, explanation: 'Tägliche AI-Interaktionszählung; Prompt-Engineering/Debugging ausgenommen.',
activeUsers: { },
title: 'Aktive Benutzer', activeUsers: {
explanation: 'Einzigartige Benutzer, die mit AI Q&A führen; Prompt-Engineering/Debugging ausgenommen.', title: 'Aktive Benutzer',
}, explanation: 'Einzigartige Benutzer, die mit AI Q&A führen; Prompt-Engineering/Debugging ausgenommen.',
tokenUsage: { },
title: 'Token-Verbrauch', tokenUsage: {
explanation: 'Spiegelt den täglichen Token-Verbrauch des Sprachmodells für die Anwendung wider, nützlich für Kostenkontrollzwecke.', title: 'Token-Verbrauch',
consumed: 'Verbraucht', explanation: 'Spiegelt den täglichen Token-Verbrauch des Sprachmodells für die Anwendung wider, nützlich für Kostenkontrollzwecke.',
}, consumed: 'Verbraucht',
avgSessionInteractions: { },
title: 'Durchschn. Sitzungsinteraktionen', avgSessionInteractions: {
explanation: 'Fortlaufende Benutzer-KI-Kommunikationszählung; für konversationsbasierte Apps.', title: 'Durchschn. Sitzungsinteraktionen',
}, explanation: 'Fortlaufende Benutzer-KI-Kommunikationszählung; für konversationsbasierte Apps.',
userSatisfactionRate: { },
title: 'Benutzerzufriedenheitsrate', userSatisfactionRate: {
explanation: 'Die Anzahl der Likes pro 1.000 Nachrichten. Dies zeigt den Anteil der Antworten an, mit denen die Benutzer sehr zufrieden sind.', title: 'Benutzerzufriedenheitsrate',
}, explanation: 'Die Anzahl der Likes pro 1.000 Nachrichten. Dies zeigt den Anteil der Antworten an, mit denen die Benutzer sehr zufrieden sind.',
avgResponseTime: { },
title: 'Durchschn. Antwortzeit', avgResponseTime: {
explanation: 'Zeit (ms) für die AI, um zu verarbeiten/antworten; für textbasierte Apps.', title: 'Durchschn. Antwortzeit',
}, explanation: 'Zeit (ms) für die AI, um zu verarbeiten/antworten; für textbasierte Apps.',
tps: { },
title: 'Token-Ausgabegeschwindigkeit', tps: {
explanation: 'Misst die Leistung des LLM. Zählt die Token-Ausgabegeschwindigkeit des LLM vom Beginn der Anfrage bis zum Abschluss der Ausgabe.', title: 'Token-Ausgabegeschwindigkeit',
}, explanation: 'Misst die Leistung des LLM. Zählt die Token-Ausgabegeschwindigkeit des LLM vom Beginn der Anfrage bis zum Abschluss der Ausgabe.',
}, },
} },
}
export default translation
export default translation

View File

@ -34,6 +34,7 @@ const translation = {
accessibleAddress: 'Public URL', accessibleAddress: 'Public URL',
preview: 'Preview', preview: 'Preview',
regenerate: 'Regenerate', regenerate: 'Regenerate',
regenerateNotice: 'Do you want to regenerate the public URL?',
preUseReminder: 'Please enable WebApp before continuing.', preUseReminder: 'Please enable WebApp before continuing.',
settings: { settings: {
entry: 'Settings', entry: 'Settings',

View File

@ -34,6 +34,7 @@ const translation = {
accessibleAddress: 'URL publique', accessibleAddress: 'URL publique',
preview: 'Aperçu', preview: 'Aperçu',
regenerate: 'Regénérer', regenerate: 'Regénérer',
regenerateNotice: 'Voulez-vous régénérer l\'URL publique ?',
preUseReminder: 'Veuillez activer WebApp avant de continuer.', preUseReminder: 'Veuillez activer WebApp avant de continuer.',
settings: { settings: {
entry: 'Paramètres', entry: 'Paramètres',

View File

@ -34,6 +34,7 @@ const translation = {
accessibleAddress: '公開URL', accessibleAddress: '公開URL',
preview: 'プレビュー', preview: 'プレビュー',
regenerate: '再生成', regenerate: '再生成',
regenerateNotice: '公開URLを再生成しますか',
preUseReminder: '続行する前にWebAppを有効にしてください。', preUseReminder: '続行する前にWebAppを有効にしてください。',
settings: { settings: {
entry: '設定', entry: '設定',

View File

@ -34,6 +34,7 @@ const translation = {
accessibleAddress: '공개 URL', accessibleAddress: '공개 URL',
preview: '미리보기', preview: '미리보기',
regenerate: '재생성', regenerate: '재생성',
regenerateNotice: '공개 URL을 재생성하시겠습니까?',
preUseReminder: '계속하기 전에 웹앱을 활성화하세요.', preUseReminder: '계속하기 전에 웹앱을 활성화하세요.',
settings: { settings: {
entry: '설정', entry: '설정',

View File

@ -37,6 +37,7 @@ const translation = {
accessibleAddress: 'Publiczny adres URL', accessibleAddress: 'Publiczny adres URL',
preview: 'Podgląd', preview: 'Podgląd',
regenerate: 'Wygeneruj ponownie', regenerate: 'Wygeneruj ponownie',
regenerateNotice: 'Czy chcesz wygenerować ponownie publiczny adres URL?',
preUseReminder: 'Przed kontynuowaniem włącz aplikację WebApp.', preUseReminder: 'Przed kontynuowaniem włącz aplikację WebApp.',
settings: { settings: {
entry: 'Ustawienia', entry: 'Ustawienia',

View File

@ -34,6 +34,7 @@ const translation = {
accessibleAddress: 'URL Pública', accessibleAddress: 'URL Pública',
preview: 'Visualização', preview: 'Visualização',
regenerate: 'Regenerar', regenerate: 'Regenerar',
regenerateNotice: 'Você deseja regenerar a URL pública?',
preUseReminder: 'Por favor, ative o WebApp antes de continuar.', preUseReminder: 'Por favor, ative o WebApp antes de continuar.',
settings: { settings: {
entry: 'Configurações', entry: 'Configurações',

View File

@ -34,6 +34,7 @@ const translation = {
accessibleAddress: 'URL public', accessibleAddress: 'URL public',
preview: 'Previzualizare', preview: 'Previzualizare',
regenerate: 'Regenerare', regenerate: 'Regenerare',
regenerateNotice: 'Doriți să regenerați URL-ul public?',
preUseReminder: 'Activați aplicația web înainte de a continua.', preUseReminder: 'Activați aplicația web înainte de a continua.',
settings: { settings: {
entry: 'Setări', entry: 'Setări',

View File

@ -34,6 +34,7 @@ const translation = {
accessibleAddress: 'Публічний URL', accessibleAddress: 'Публічний URL',
preview: 'Попередній перегляд', preview: 'Попередній перегляд',
regenerate: 'Відновити', regenerate: 'Відновити',
regenerateNotice: 'Бажаєте згенерувати новий публічний URL?',
preUseReminder: 'Будь ласка, активуйте веб-додаток перед продовженням.', preUseReminder: 'Будь ласка, активуйте веб-додаток перед продовженням.',
settings: { settings: {
entry: 'Налаштування', entry: 'Налаштування',

View File

@ -34,6 +34,7 @@ const translation = {
accessibleAddress: 'Địa chỉ công cộng', accessibleAddress: 'Địa chỉ công cộng',
preview: 'Xem trước', preview: 'Xem trước',
regenerate: 'Tạo lại', regenerate: 'Tạo lại',
regenerateNotice: 'Bạn có muốn tạo lại địa chỉ công cộng không?',
preUseReminder: 'Vui lòng kích hoạt ứng dụng web trước khi tiếp tục.', preUseReminder: 'Vui lòng kích hoạt ứng dụng web trước khi tiếp tục.',
settings: { settings: {
entry: 'Cài đặt', entry: 'Cài đặt',

View File

@ -34,6 +34,7 @@ const translation = {
accessibleAddress: '公开访问 URL', accessibleAddress: '公开访问 URL',
preview: '预览', preview: '预览',
regenerate: '重新生成', regenerate: '重新生成',
regenerateNotice: '您是否要重新生成公开访问 URL',
preUseReminder: '使用前请先打开开关', preUseReminder: '使用前请先打开开关',
settings: { settings: {
entry: '设置', entry: '设置',

View File

@ -34,6 +34,7 @@ const translation = {
accessibleAddress: '公開訪問 URL', accessibleAddress: '公開訪問 URL',
preview: '預覽', preview: '預覽',
regenerate: '重新生成', regenerate: '重新生成',
regenerateNotice: '您是否要重新生成公開訪問 URL',
preUseReminder: '使用前請先開啟開關', preUseReminder: '使用前請先開啟開關',
settings: { settings: {
entry: '設定', entry: '設定',