mirror of https://github.com/langgenius/dify.git
feat(confirm): input app name for app deletion confirmation (#33660)
This commit is contained in:
parent
e4f1d3c63a
commit
942087cbdb
|
|
@ -4,6 +4,7 @@ import type { CreateAppModalProps } from '@/app/components/explore/create-app-mo
|
|||
import type { EnvironmentVariable } from '@/app/components/workflow/types'
|
||||
import type { App, AppSSO } from '@/types/app'
|
||||
import * as React from 'react'
|
||||
import { useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import dynamic from '@/next/dynamic'
|
||||
|
||||
|
|
@ -42,6 +43,7 @@ const AppInfoModals = ({
|
|||
onConfirmDelete,
|
||||
}: AppInfoModalsProps) => {
|
||||
const { t } = useTranslation()
|
||||
const [confirmDeleteInput, setConfirmDeleteInput] = useState('')
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
@ -88,8 +90,16 @@ const AppInfoModals = ({
|
|||
title={t('deleteAppConfirmTitle', { ns: 'app' })}
|
||||
content={t('deleteAppConfirmContent', { ns: 'app' })}
|
||||
isShow
|
||||
confirmInputLabel={t('deleteAppConfirmInputLabel', { ns: 'app', appName: appDetail.name })}
|
||||
confirmInputPlaceholder={t('deleteAppConfirmInputPlaceholder', { ns: 'app' })}
|
||||
confirmInputValue={confirmDeleteInput}
|
||||
onConfirmInputChange={setConfirmDeleteInput}
|
||||
confirmInputMatchValue={appDetail.name}
|
||||
onConfirm={onConfirmDelete}
|
||||
onCancel={closeModal}
|
||||
onCancel={() => {
|
||||
setConfirmDeleteInput('')
|
||||
closeModal()
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{activeModal === 'importDSL' && (
|
||||
|
|
|
|||
|
|
@ -543,6 +543,11 @@ describe('AppCard', () => {
|
|||
fireEvent.click(screen.getByTestId('popover-trigger'))
|
||||
fireEvent.click(await screen.findByRole('button', { name: 'common.operation.delete' }))
|
||||
expect(await screen.findByRole('alertdialog')).toBeInTheDocument()
|
||||
|
||||
// Fill in the confirmation input with app name
|
||||
const deleteInput = screen.getByRole('textbox')
|
||||
fireEvent.change(deleteInput, { target: { value: mockApp.name } })
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: 'common.operation.confirm' }))
|
||||
|
||||
await waitFor(() => {
|
||||
|
|
@ -556,6 +561,11 @@ describe('AppCard', () => {
|
|||
fireEvent.click(screen.getByTestId('popover-trigger'))
|
||||
fireEvent.click(await screen.findByRole('button', { name: 'common.operation.delete' }))
|
||||
expect(await screen.findByRole('alertdialog')).toBeInTheDocument()
|
||||
|
||||
// Fill in the confirmation input with app name
|
||||
const deleteInput = screen.getByRole('textbox')
|
||||
fireEvent.change(deleteInput, { target: { value: mockApp.name } })
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: 'common.operation.confirm' }))
|
||||
|
||||
await waitFor(() => {
|
||||
|
|
@ -572,6 +582,11 @@ describe('AppCard', () => {
|
|||
fireEvent.click(screen.getByTestId('popover-trigger'))
|
||||
fireEvent.click(await screen.findByRole('button', { name: 'common.operation.delete' }))
|
||||
expect(await screen.findByRole('alertdialog')).toBeInTheDocument()
|
||||
|
||||
// Fill in the confirmation input with app name
|
||||
const deleteInput = screen.getByRole('textbox')
|
||||
fireEvent.change(deleteInput, { target: { value: mockApp.name } })
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: 'common.operation.confirm' }))
|
||||
|
||||
await waitFor(() => {
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ const AppCard = ({ app, onRefresh }: AppCardProps) => {
|
|||
const [showDuplicateModal, setShowDuplicateModal] = useState(false)
|
||||
const [showSwitchModal, setShowSwitchModal] = useState<boolean>(false)
|
||||
const [showConfirmDelete, setShowConfirmDelete] = useState(false)
|
||||
const [confirmDeleteInput, setConfirmDeleteInput] = useState('')
|
||||
const [showAccessControl, setShowAccessControl] = useState(false)
|
||||
const [secretEnvList, setSecretEnvList] = useState<EnvironmentVariable[]>([])
|
||||
const { mutateAsync: mutateDeleteApp, isPending: isDeleting } = useDeleteAppMutation()
|
||||
|
|
@ -100,6 +101,7 @@ const AppCard = ({ app, onRefresh }: AppCardProps) => {
|
|||
}
|
||||
finally {
|
||||
setShowConfirmDelete(false)
|
||||
setConfirmDeleteInput('')
|
||||
}
|
||||
}, [app.id, mutateDeleteApp, notify, onPlanInfoChanged, t])
|
||||
|
||||
|
|
@ -108,6 +110,8 @@ const AppCard = ({ app, onRefresh }: AppCardProps) => {
|
|||
return
|
||||
|
||||
setShowConfirmDelete(open)
|
||||
if (!open)
|
||||
setConfirmDeleteInput('')
|
||||
}, [isDeleting])
|
||||
|
||||
const onEdit: CreateAppModalProps['onConfirm'] = useCallback(async ({
|
||||
|
|
@ -521,12 +525,28 @@ const AppCard = ({ app, onRefresh }: AppCardProps) => {
|
|||
<AlertDialogDescription className="w-full whitespace-pre-wrap break-words text-text-tertiary system-md-regular">
|
||||
{t('deleteAppConfirmContent', { ns: 'app' })}
|
||||
</AlertDialogDescription>
|
||||
<div className="mt-2">
|
||||
<label className="mb-1 block text-text-secondary system-sm-regular">
|
||||
{t('deleteAppConfirmInputLabel', { ns: 'app', appName: app.name })}
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
className="border-components-input-border bg-components-input-bg focus:border-components-input-border-focus focus:ring-components-input-border-focus h-9 w-full rounded-lg border px-3 text-sm text-text-primary placeholder:text-text-quaternary focus:outline-none focus:ring-1"
|
||||
placeholder={t('deleteAppConfirmInputPlaceholder', { ns: 'app' })}
|
||||
value={confirmDeleteInput}
|
||||
onChange={e => setConfirmDeleteInput(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<AlertDialogActions>
|
||||
<AlertDialogCancelButton disabled={isDeleting}>
|
||||
{t('operation.cancel', { ns: 'common' })}
|
||||
</AlertDialogCancelButton>
|
||||
<AlertDialogConfirmButton loading={isDeleting} disabled={isDeleting} onClick={onConfirmDelete}>
|
||||
<AlertDialogConfirmButton
|
||||
loading={isDeleting}
|
||||
disabled={isDeleting || confirmDeleteInput !== app.name}
|
||||
onClick={onConfirmDelete}
|
||||
>
|
||||
{t('operation.confirm', { ns: 'common' })}
|
||||
</AlertDialogConfirmButton>
|
||||
</AlertDialogActions>
|
||||
|
|
|
|||
|
|
@ -26,6 +26,11 @@ export type IConfirm = {
|
|||
showConfirm?: boolean
|
||||
showCancel?: boolean
|
||||
maskClosable?: boolean
|
||||
confirmInputLabel?: string
|
||||
confirmInputPlaceholder?: string
|
||||
confirmInputValue?: string
|
||||
onConfirmInputChange?: (value: string) => void
|
||||
confirmInputMatchValue?: string
|
||||
}
|
||||
|
||||
function Confirm({
|
||||
|
|
@ -42,6 +47,11 @@ function Confirm({
|
|||
isLoading = false,
|
||||
isDisabled = false,
|
||||
maskClosable = true,
|
||||
confirmInputLabel,
|
||||
confirmInputPlaceholder,
|
||||
confirmInputValue = '',
|
||||
onConfirmInputChange,
|
||||
confirmInputMatchValue,
|
||||
}: IConfirm) {
|
||||
const { t } = useTranslation()
|
||||
const dialogRef = useRef<HTMLDivElement>(null)
|
||||
|
|
@ -51,12 +61,13 @@ function Confirm({
|
|||
|
||||
const confirmTxt = confirmText || `${t('operation.confirm', { ns: 'common' })}`
|
||||
const cancelTxt = cancelText || `${t('operation.cancel', { ns: 'common' })}`
|
||||
const isConfirmDisabled = isDisabled || (confirmInputMatchValue ? confirmInputValue !== confirmInputMatchValue : false)
|
||||
|
||||
useEffect(() => {
|
||||
const handleKeyDown = (event: KeyboardEvent) => {
|
||||
if (event.key === 'Escape')
|
||||
onCancel()
|
||||
if (event.key === 'Enter' && isShow) {
|
||||
if (event.key === 'Enter' && isShow && !isConfirmDisabled) {
|
||||
event.preventDefault()
|
||||
onConfirm()
|
||||
}
|
||||
|
|
@ -66,7 +77,7 @@ function Confirm({
|
|||
return () => {
|
||||
document.removeEventListener('keydown', handleKeyDown)
|
||||
}
|
||||
}, [onCancel, onConfirm, isShow])
|
||||
}, [onCancel, onConfirm, isShow, isConfirmDisabled])
|
||||
|
||||
const handleClickOutside = (event: MouseEvent) => {
|
||||
if (maskClosable && dialogRef.current && !dialogRef.current.contains(event.target as Node))
|
||||
|
|
@ -123,11 +134,25 @@ function Confirm({
|
|||
{title}
|
||||
</div>
|
||||
</Tooltip>
|
||||
<div className="system-md-regular w-full whitespace-pre-wrap break-words text-text-tertiary">{content}</div>
|
||||
<div className="w-full whitespace-pre-wrap break-words text-text-tertiary system-md-regular">{content}</div>
|
||||
{confirmInputLabel && (
|
||||
<div className="mt-2">
|
||||
<label className="mb-1 block text-text-secondary system-sm-regular">
|
||||
{confirmInputLabel}
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
className="border-components-input-border bg-components-input-bg focus:border-components-input-border-focus focus:ring-components-input-border-focus h-9 w-full rounded-lg border px-3 text-sm text-text-primary placeholder:text-text-quaternary focus:outline-none focus:ring-1"
|
||||
placeholder={confirmInputPlaceholder}
|
||||
value={confirmInputValue}
|
||||
onChange={e => onConfirmInputChange?.(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex items-start justify-end gap-2 self-stretch p-6">
|
||||
{showCancel && <Button onClick={onCancel}>{cancelTxt}</Button>}
|
||||
{showConfirm && <Button variant="primary" destructive={type !== 'info'} loading={isLoading} disabled={isDisabled} onClick={onConfirm}>{confirmTxt}</Button>}
|
||||
{showConfirm && <Button variant="primary" destructive={type !== 'info'} loading={isLoading} disabled={isConfirmDisabled} onClick={onConfirm}>{confirmTxt}</Button>}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1839,7 +1839,7 @@
|
|||
"count": 2
|
||||
},
|
||||
"tailwindcss/enforce-consistent-class-order": {
|
||||
"count": 2
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"app/components/base/content-dialog/index.stories.tsx": {
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
"createApp": "إنشاء تطبيق",
|
||||
"createFromConfigFile": "إنشاء من ملف DSL",
|
||||
"deleteAppConfirmContent": "حذف التطبيق لا رجعة فيه. لن يتمكن المستخدمون من الوصول إلى تطبيقك بعد الآن، وسيتم حذف جميع تكوينات المطالبة والسجلات بشكل دائم.",
|
||||
"deleteAppConfirmInputLabel": "للتأكيد، اكتب \"{{appName}}\" في المربع أدناه:",
|
||||
"deleteAppConfirmInputPlaceholder": "أدخل اسم التطبيق",
|
||||
"deleteAppConfirmTitle": "حذف هذا التطبيق؟",
|
||||
"dslUploader.browse": "تصفح",
|
||||
"dslUploader.button": "اسحب وأفلت الملف، أو",
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
"createApp": "Neue App erstellen",
|
||||
"createFromConfigFile": "App aus Konfigurationsdatei erstellen",
|
||||
"deleteAppConfirmContent": "Das Löschen der App ist unwiderruflich. Nutzer werden keinen Zugang mehr zu Ihrer App haben, und alle Prompt-Konfigurationen und Logs werden dauerhaft gelöscht.",
|
||||
"deleteAppConfirmInputLabel": "Geben Sie zur Bestätigung \"{{appName}}\" in das Feld unten ein:",
|
||||
"deleteAppConfirmInputPlaceholder": "App-Namen eingeben",
|
||||
"deleteAppConfirmTitle": "Diese App löschen?",
|
||||
"dslUploader.browse": "Durchsuchen",
|
||||
"dslUploader.button": "Datei per Drag & Drop ablegen oder",
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
"createApp": "CREATE APP",
|
||||
"createFromConfigFile": "Create from DSL file",
|
||||
"deleteAppConfirmContent": "Deleting the app is irreversible. Users will no longer be able to access your app, and all prompt configurations and logs will be permanently deleted.",
|
||||
"deleteAppConfirmInputLabel": "To confirm, type \"{{appName}}\" in the box below:",
|
||||
"deleteAppConfirmInputPlaceholder": "Enter app name",
|
||||
"deleteAppConfirmTitle": "Delete this app?",
|
||||
"dslUploader.browse": "Browse",
|
||||
"dslUploader.button": "Drag and drop file, or",
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
"createApp": "CREAR APP",
|
||||
"createFromConfigFile": "Crear desde archivo DSL",
|
||||
"deleteAppConfirmContent": "Eliminar la app es irreversible. Los usuarios ya no podrán acceder a tu app y todas las configuraciones y registros de prompts se eliminarán permanentemente.",
|
||||
"deleteAppConfirmInputLabel": "Para confirmar, escriba \"{{appName}}\" en el cuadro a continuación:",
|
||||
"deleteAppConfirmInputPlaceholder": "Ingrese el nombre de la app",
|
||||
"deleteAppConfirmTitle": "¿Eliminar esta app?",
|
||||
"dslUploader.browse": "Examinar",
|
||||
"dslUploader.button": "Arrastrar y soltar archivo, o",
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
"createApp": "ایجاد برنامه",
|
||||
"createFromConfigFile": "ایجاد از فایل DSL",
|
||||
"deleteAppConfirmContent": "حذف برنامه غیرقابل برگشت است. کاربران دیگر قادر به دسترسی به برنامه شما نخواهند بود و تمام تنظیمات و گزارشات درخواستها به صورت دائم حذف خواهند شد.",
|
||||
"deleteAppConfirmInputLabel": "برای تأیید، \"{{appName}}\" را در کادر زیر تایپ کنید:",
|
||||
"deleteAppConfirmInputPlaceholder": "نام برنامه را وارد کنید",
|
||||
"deleteAppConfirmTitle": "آیا این برنامه حذف شود؟",
|
||||
"dslUploader.browse": "مرور",
|
||||
"dslUploader.button": "فایل را بکشید و رها کنید، یا",
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
"createApp": "CRÉER UNE APPLICATION",
|
||||
"createFromConfigFile": "Créer à partir du fichier DSL",
|
||||
"deleteAppConfirmContent": "La suppression de l'application est irréversible. Les utilisateurs ne pourront plus accéder à votre application et toutes les configurations de prompt et les journaux seront définitivement supprimés.",
|
||||
"deleteAppConfirmInputLabel": "Pour confirmer, tapez \"{{appName}}\" dans la case ci-dessous :",
|
||||
"deleteAppConfirmInputPlaceholder": "Entrez le nom de l'application",
|
||||
"deleteAppConfirmTitle": "Supprimer cette application ?",
|
||||
"dslUploader.browse": "Parcourir",
|
||||
"dslUploader.button": "Glisser-déposer un fichier, ou",
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
"createApp": "ऐप बनाएँ",
|
||||
"createFromConfigFile": "डीएसएल फ़ाइल से बनाएँ",
|
||||
"deleteAppConfirmContent": "ऐप को हटाना अपरिवर्तनीय है। उपयोगकर्ता अब आपके ऐप तक पहुँचने में सक्षम नहीं होंगे, और सभी प्रॉम्प्ट कॉन्फ़िगरेशन और लॉग स्थायी रूप से हटा दिए जाएंगे।",
|
||||
"deleteAppConfirmInputLabel": "पुष्टि करने के लिए, नीचे दिए गए बॉक्स में \"{{appName}}\" टाइप करें:",
|
||||
"deleteAppConfirmInputPlaceholder": "ऐप का नाम दर्ज करें",
|
||||
"deleteAppConfirmTitle": "इस ऐप को हटाएँ?",
|
||||
"dslUploader.browse": "ब्राउज़ करें",
|
||||
"dslUploader.button": "फ़ाइल खींचकर छोड़ें, या",
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
"createApp": "BUAT APLIKASI",
|
||||
"createFromConfigFile": "Buat dari file DSL",
|
||||
"deleteAppConfirmContent": "Menghapus aplikasi tidak dapat diubah. Pengguna tidak akan dapat lagi mengakses aplikasi Anda, dan semua konfigurasi prompt serta log akan dihapus secara permanen.",
|
||||
"deleteAppConfirmInputLabel": "Untuk konfirmasi, ketik \"{{appName}}\" di kotak di bawah ini:",
|
||||
"deleteAppConfirmInputPlaceholder": "Masukkan nama aplikasi",
|
||||
"deleteAppConfirmTitle": "Hapus aplikasi ini?",
|
||||
"dslUploader.browse": "Ramban",
|
||||
"dslUploader.button": "Seret dan lepas file, atau",
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
"createApp": "CREA APP",
|
||||
"createFromConfigFile": "Crea da file DSL",
|
||||
"deleteAppConfirmContent": "Eliminare l'app è irreversibile. Gli utenti non potranno più accedere alla tua app e tutte le configurazioni e i log dei prompt verranno eliminati permanentemente.",
|
||||
"deleteAppConfirmInputLabel": "Per confermare, digita \"{{appName}}\" nel campo sottostante:",
|
||||
"deleteAppConfirmInputPlaceholder": "Inserisci il nome dell'app",
|
||||
"deleteAppConfirmTitle": "Eliminare questa app?",
|
||||
"dslUploader.browse": "Sfoglia",
|
||||
"dslUploader.button": "Trascina e rilascia il file, o",
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
"createApp": "アプリを作成する",
|
||||
"createFromConfigFile": "DSL ファイルから作成する",
|
||||
"deleteAppConfirmContent": "アプリを削除すると、元に戻すことはできません。他のユーザーはもはやこのアプリにアクセスできず、すべてのプロンプトの設定とログが永久に削除されます。",
|
||||
"deleteAppConfirmInputLabel": "確認するには、下のボックスに「{{appName}}」と入力してください:",
|
||||
"deleteAppConfirmInputPlaceholder": "アプリ名を入力",
|
||||
"deleteAppConfirmTitle": "このアプリを削除しますか?",
|
||||
"dslUploader.browse": "参照",
|
||||
"dslUploader.button": "ファイルをドラッグ&ドロップするか、",
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
"createApp": "앱 만들기",
|
||||
"createFromConfigFile": "DSL 파일에서 생성하기",
|
||||
"deleteAppConfirmContent": "앱을 삭제하면 복구할 수 없습니다. 사용자는 더 이상 앱에 액세스할 수 없으며 모든 프롬프트 설정 및 로그가 영구적으로 삭제됩니다.",
|
||||
"deleteAppConfirmInputLabel": "확인하려면 아래 상자에 \"{{appName}}\"을 입력하세요:",
|
||||
"deleteAppConfirmInputPlaceholder": "앱 이름 입력",
|
||||
"deleteAppConfirmTitle": "이 앱을 삭제하시겠습니까?",
|
||||
"dslUploader.browse": "찾아보기",
|
||||
"dslUploader.button": "파일을 드래그 앤 드롭하거나",
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
"createApp": "CREATE APP",
|
||||
"createFromConfigFile": "Create from DSL file",
|
||||
"deleteAppConfirmContent": "Deleting the app is irreversible. Users will no longer be able to access your app, and all prompt configurations and logs will be permanently deleted.",
|
||||
"deleteAppConfirmInputLabel": "To confirm, type \"{{appName}}\" in the box below:",
|
||||
"deleteAppConfirmInputPlaceholder": "Enter app name",
|
||||
"deleteAppConfirmTitle": "Delete this app?",
|
||||
"dslUploader.browse": "Browse",
|
||||
"dslUploader.button": "Drag and drop file, or",
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
"createApp": "UTWÓRZ APLIKACJĘ",
|
||||
"createFromConfigFile": "Utwórz z pliku DSL",
|
||||
"deleteAppConfirmContent": "Usunięcie aplikacji jest nieodwracalne. Użytkownicy nie będą mieli już dostępu do twojej aplikacji, a wszystkie konfiguracje monitów i dzienniki zostaną trwale usunięte.",
|
||||
"deleteAppConfirmInputLabel": "Aby potwierdzić, wpisz \"{{appName}}\" w polu poniżej:",
|
||||
"deleteAppConfirmInputPlaceholder": "Wpisz nazwę aplikacji",
|
||||
"deleteAppConfirmTitle": "Usunąć tę aplikację?",
|
||||
"dslUploader.browse": "Przeglądaj",
|
||||
"dslUploader.button": "Przeciągnij i upuść plik, lub",
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
"createApp": "CRIAR APLICATIVO",
|
||||
"createFromConfigFile": "Criar a partir do arquivo DSL",
|
||||
"deleteAppConfirmContent": "A exclusão do aplicativo é irreversível. Os usuários não poderão mais acessar seu aplicativo e todas as configurações de prompt e logs serão permanentemente excluídas.",
|
||||
"deleteAppConfirmInputLabel": "Para confirmar, digite \"{{appName}}\" na caixa abaixo:",
|
||||
"deleteAppConfirmInputPlaceholder": "Digite o nome do aplicativo",
|
||||
"deleteAppConfirmTitle": "Excluir este aplicativo?",
|
||||
"dslUploader.browse": "Navegar",
|
||||
"dslUploader.button": "Arraste e solte o arquivo, ou",
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
"createApp": "CREEAZĂ APLICAȚIE",
|
||||
"createFromConfigFile": "Creează din fișier DSL",
|
||||
"deleteAppConfirmContent": "Ștergerea aplicației este ireversibilă. Utilizatorii nu vor mai putea accesa aplicația ta, iar toate configurațiile promptului și jurnalele vor fi șterse permanent.",
|
||||
"deleteAppConfirmInputLabel": "Pentru confirmare, tastați \"{{appName}}\" în caseta de mai jos:",
|
||||
"deleteAppConfirmInputPlaceholder": "Introduceți numele aplicației",
|
||||
"deleteAppConfirmTitle": "Ștergi această aplicație?",
|
||||
"dslUploader.browse": "Răsfoiți",
|
||||
"dslUploader.button": "Trageți și plasați fișierul, sau",
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
"createApp": "СОЗДАТЬ ПРИЛОЖЕНИЕ",
|
||||
"createFromConfigFile": "Создать из файла DSL",
|
||||
"deleteAppConfirmContent": "Удаление приложения необратимо. Пользователи больше не смогут получить доступ к вашему приложению, и все настройки подсказок и журналы будут безвозвратно удалены.",
|
||||
"deleteAppConfirmInputLabel": "Для подтверждения введите \"{{appName}}\" в поле ниже:",
|
||||
"deleteAppConfirmInputPlaceholder": "Введите название приложения",
|
||||
"deleteAppConfirmTitle": "Удалить это приложение?",
|
||||
"dslUploader.browse": "Обзор",
|
||||
"dslUploader.button": "Перетащите файл, или",
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
"createApp": "USTVARI APLIKACIJO",
|
||||
"createFromConfigFile": "Ustvari iz datoteke DSL",
|
||||
"deleteAppConfirmContent": "Brisanje aplikacije je nepopravljivo. Uporabniki ne bodo več imeli dostopa do vaše aplikacije, vse konfiguracije in dnevniki pa bodo trajno izbrisani.",
|
||||
"deleteAppConfirmInputLabel": "Za potrditev vnesite \"{{appName}}\" v polje spodaj:",
|
||||
"deleteAppConfirmInputPlaceholder": "Vnesite ime aplikacije",
|
||||
"deleteAppConfirmTitle": "Izbrišem to aplikacijo?",
|
||||
"dslUploader.browse": "Prebrskaj",
|
||||
"dslUploader.button": "Povlecite in spustite datoteko, ali",
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
"createApp": "สร้างโปรเจกต์ใหม่",
|
||||
"createFromConfigFile": "สร้างจากไฟล์ DSL",
|
||||
"deleteAppConfirmContent": "การลบโปรเจกนั้นไม่สามารถย้อนกลับได้ ผู้ใช้จะไม่สามารถเข้าถึงโปรเจกต์ของคุณอีกต่อไป และการกําหนดค่าต่างๆและบันทึกทั้งหมดจะถูกลบอย่างถาวร",
|
||||
"deleteAppConfirmInputLabel": "หากต้องการยืนยัน พิมพ์ \"{{appName}}\" ในช่องด้านล่าง:",
|
||||
"deleteAppConfirmInputPlaceholder": "ใส่ชื่อแอป",
|
||||
"deleteAppConfirmTitle": "ลบโปรเจกต์นี้?",
|
||||
"dslUploader.browse": "เรียกดู",
|
||||
"dslUploader.button": "ลากและวางไฟล์ หรือ",
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
"createApp": "UYGULAMA OLUŞTUR",
|
||||
"createFromConfigFile": "DSL dosyasından oluştur",
|
||||
"deleteAppConfirmContent": "Uygulamanın silinmesi geri alınamaz. Kullanıcılar artık uygulamanıza erişemeyecek ve tüm prompt yapılandırmaları ile loglar kalıcı olarak silinecektir.",
|
||||
"deleteAppConfirmInputLabel": "Onaylamak için aşağıdaki kutuya \"{{appName}}\" yazın:",
|
||||
"deleteAppConfirmInputPlaceholder": "Uygulama adını girin",
|
||||
"deleteAppConfirmTitle": "Bu uygulamayı silmek istiyor musunuz?",
|
||||
"dslUploader.browse": "Gözat",
|
||||
"dslUploader.button": "Dosyayı sürükleyip bırakın veya",
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
"createApp": "Створити додаток",
|
||||
"createFromConfigFile": "Створити з файлу DSL",
|
||||
"deleteAppConfirmContent": "Видалення додатка незворотнє. Користувачі більше не зможуть отримати доступ до вашого додатка, і всі налаштування запитів та журнали будуть остаточно видалені.",
|
||||
"deleteAppConfirmInputLabel": "Для підтвердження введіть \"{{appName}}\" у поле нижче:",
|
||||
"deleteAppConfirmInputPlaceholder": "Введіть назву додатка",
|
||||
"deleteAppConfirmTitle": "Видалити цей додаток?",
|
||||
"dslUploader.browse": "Огляд",
|
||||
"dslUploader.button": "Перетягніть файл, або",
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
"createApp": "TẠO ỨNG DỤNG",
|
||||
"createFromConfigFile": "Tạo từ tệp DSL",
|
||||
"deleteAppConfirmContent": "Việc xóa ứng dụng là không thể hoàn tác. Người dùng sẽ không thể truy cập vào ứng dụng của bạn nữa và tất cả cấu hình cũng như nhật ký nhắc sẽ bị xóa vĩnh viễn.",
|
||||
"deleteAppConfirmInputLabel": "Để xác nhận, hãy nhập \"{{appName}}\" vào ô bên dưới:",
|
||||
"deleteAppConfirmInputPlaceholder": "Nhập tên ứng dụng",
|
||||
"deleteAppConfirmTitle": "Xóa ứng dụng này?",
|
||||
"dslUploader.browse": "Duyệt",
|
||||
"dslUploader.button": "Kéo và thả tệp, hoặc",
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
"createApp": "创建应用",
|
||||
"createFromConfigFile": "通过 DSL 文件创建",
|
||||
"deleteAppConfirmContent": "删除应用将无法撤销。用户将不能访问你的应用,所有 Prompt 编排配置和日志均将一并被删除。",
|
||||
"deleteAppConfirmInputLabel": "请在下方输入框中输入\"{{appName}}\"以确认:",
|
||||
"deleteAppConfirmInputPlaceholder": "输入应用名称",
|
||||
"deleteAppConfirmTitle": "确认删除应用?",
|
||||
"dslUploader.browse": "选择文件",
|
||||
"dslUploader.button": "拖拽文件至此,或者",
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
"createApp": "建立應用",
|
||||
"createFromConfigFile": "透過 DSL 檔案建立",
|
||||
"deleteAppConfirmContent": "刪除應用將無法復原。使用者將無法存取你的應用,所有 Prompt 設定和日誌都將一併被刪除。",
|
||||
"deleteAppConfirmInputLabel": "請在下方輸入框中輸入「{{appName}}」以確認:",
|
||||
"deleteAppConfirmInputPlaceholder": "輸入應用程式名稱",
|
||||
"deleteAppConfirmTitle": "確認刪除應用?",
|
||||
"dslUploader.browse": "選擇檔案",
|
||||
"dslUploader.button": "拖拽檔案至此,或者",
|
||||
|
|
|
|||
Loading…
Reference in New Issue