FileManager Seeder
This commit is contained in:
parent
bea5aabffa
commit
ef201fda13
6 changed files with 472 additions and 113 deletions
|
|
@ -15338,6 +15338,48 @@
|
||||||
"en": "Name",
|
"en": "Name",
|
||||||
"tr": "Adı"
|
"tr": "Adı"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.Listform.ListformField.Item",
|
||||||
|
"en": "Item",
|
||||||
|
"tr": "Öğe"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.Listform.ListformField.Preview",
|
||||||
|
"en": "Preview",
|
||||||
|
"tr": "Önizleme"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.Listform.ListformField.Download",
|
||||||
|
"en": "Download",
|
||||||
|
"tr": "İndir"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.Listform.ListformField.CopyFileUrl",
|
||||||
|
"en": "Copy URL",
|
||||||
|
"tr": "URL Kopyala"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.Listform.ListformField.NewFolder",
|
||||||
|
"en": "New Folder",
|
||||||
|
"tr": "Yeni Klasör"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.Listform.ListformField.Rename",
|
||||||
|
"en": "Rename",
|
||||||
|
"tr": "Yeniden Adlandır"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.Listform.ListformField.Move",
|
||||||
|
"en": "Move",
|
||||||
|
"tr": "Taşı"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
"key": "App.Listform.ListformField.NameKey",
|
"key": "App.Listform.ListformField.NameKey",
|
||||||
|
|
@ -16724,6 +16766,18 @@
|
||||||
"en": "Type",
|
"en": "Type",
|
||||||
"tr": "Türü"
|
"tr": "Türü"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.Listform.ListformField.Size",
|
||||||
|
"en": "Size",
|
||||||
|
"tr": "Boyut"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.Listform.ListformField.Modified",
|
||||||
|
"en": "Modified",
|
||||||
|
"tr": "Değiştirilme"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
"key": "App.Listform.ListformField.TypeId",
|
"key": "App.Listform.ListformField.TypeId",
|
||||||
|
|
@ -18823,6 +18877,246 @@
|
||||||
"key": "ListForms.ListFormEdit.Workflow.ApprovalDescriptionFieldName",
|
"key": "ListForms.ListFormEdit.Workflow.ApprovalDescriptionFieldName",
|
||||||
"en": "Approval Description Field Name",
|
"en": "Approval Description Field Name",
|
||||||
"tr": "Onay Açıklaması Alanı Adı"
|
"tr": "Onay Açıklaması Alanı Adı"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.Folder",
|
||||||
|
"en": "Folder",
|
||||||
|
"tr": "Klasor"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.Picture",
|
||||||
|
"en": "Picture",
|
||||||
|
"tr": "Resim"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.Video",
|
||||||
|
"en": "Video",
|
||||||
|
"tr": "Video"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.Sound",
|
||||||
|
"en": "Sound",
|
||||||
|
"tr": "Ses"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.PDF",
|
||||||
|
"en": "PDF",
|
||||||
|
"tr": "PDF"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.Word",
|
||||||
|
"en": "Word",
|
||||||
|
"tr": "Word"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.Excel",
|
||||||
|
"en": "Excel",
|
||||||
|
"tr": "Excel"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.PowerPoint",
|
||||||
|
"en": "PowerPoint",
|
||||||
|
"tr": "PowerPoint"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.Archive",
|
||||||
|
"en": "Archive",
|
||||||
|
"tr": "Arşiv"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.Text",
|
||||||
|
"en": "Text",
|
||||||
|
"tr": "Metin"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.Code",
|
||||||
|
"en": "Code",
|
||||||
|
"tr": "Kod"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.Counting",
|
||||||
|
"en": "Counting...",
|
||||||
|
"tr": "Sayılıyor..."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.CreateFolder",
|
||||||
|
"en": "Create Folder",
|
||||||
|
"tr": "Klasör Oluştur"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.Create",
|
||||||
|
"en": "Create",
|
||||||
|
"tr": "Oluştur"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.CopySelectedItems",
|
||||||
|
"en": "Copy Selected Items",
|
||||||
|
"tr": "Seçili Öğeleri Kopyala"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.CutSelectedItems",
|
||||||
|
"en": "Cut Selected Items",
|
||||||
|
"tr": "Seçili Öğeleri Kes"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.PasteSelectedItems",
|
||||||
|
"en": "Paste Selected Items",
|
||||||
|
"tr": "Seçili Öğeleri Yapıştır"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.RenameSelectedItem",
|
||||||
|
"en": "Rename Selected Item",
|
||||||
|
"tr": "Seçili Öğeyi Yeniden Adlandır"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.DownloadSelectedFile",
|
||||||
|
"en": "Download Selected File",
|
||||||
|
"tr": "Seçili Dosyayı İndir"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.DeleteSelectedItems",
|
||||||
|
"en": "Delete selected items",
|
||||||
|
"tr": "Seçili Öğeleri Sil"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.SearchFiles",
|
||||||
|
"en": "Search...",
|
||||||
|
"tr": "Ara..."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.UploadFiles",
|
||||||
|
"en": "Upload files...",
|
||||||
|
"tr": "Dosyaları Yükle..."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.Upload",
|
||||||
|
"en": "Upload",
|
||||||
|
"tr": "Yükle"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.FolderName",
|
||||||
|
"en": "Folder Name",
|
||||||
|
"tr": "Klasör Adı"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.FileName",
|
||||||
|
"en": "File Name",
|
||||||
|
"tr": "Dosya Adı"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.File",
|
||||||
|
"en": "File",
|
||||||
|
"tr": "Dosya"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.RenameFolder",
|
||||||
|
"en": "Rename Folder",
|
||||||
|
"tr": "Klasörü Yeniden Adlandır"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.RenameFile",
|
||||||
|
"en": "Rename File",
|
||||||
|
"tr": "Dosyayı Yeniden Adlandır"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.DeleteConfirmationMessage",
|
||||||
|
"en": "Are you sure you want to delete the following items? This action cannot be undone.",
|
||||||
|
"tr": "Aşağıdaki öğeleri silmek istediğinizden emin misiniz? Bu işlem geri alınamaz."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.DeleteConfirmationTitle",
|
||||||
|
"en": "Delete Items",
|
||||||
|
"tr": "Öğeleri Sil"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.DeselectAll",
|
||||||
|
"en": "Deselect All",
|
||||||
|
"tr": "Tümünü Seçmeyi Bırak"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.SelectAll",
|
||||||
|
"en": "Select All",
|
||||||
|
"tr": "Tümünü Seç"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.Deselect",
|
||||||
|
"en": "Deselect",
|
||||||
|
"tr": "Seçmeyi Bırak"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.Select",
|
||||||
|
"en": "Select",
|
||||||
|
"tr": "Seç"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.SortByNameAsc",
|
||||||
|
"en": "Name (A-Z)",
|
||||||
|
"tr": "İsim (A-Z)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.SortByNameDesc",
|
||||||
|
"en": "Name (Z-A)",
|
||||||
|
"tr": "İsim (Z-A)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.SortBySizeAsc",
|
||||||
|
"en": "Size (Small to Large)",
|
||||||
|
"tr": "Boyut (Küçükten Büyüğe)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.SortBySizeDesc",
|
||||||
|
"en": "Size (Large to Small)",
|
||||||
|
"tr": "Boyut (Büyükten Küçüğe)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.SortByModifiedAsc",
|
||||||
|
"en": "Modified (Oldest)",
|
||||||
|
"tr": "Değiştirilme (En Eski)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "FileManager.SortByModifiedDesc",
|
||||||
|
"en": "Modified (Newest)",
|
||||||
|
"tr": "Değiştirilme (En Yeni)"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2682,7 +2682,7 @@ public class ListFormSeeder_Administration : IDataSeedContributor, ITransientDep
|
||||||
new EditingFormItemDto { Order = 4, DataField = "Category", ColSpan=1, IsRequired = true, EditorType2 = EditorTypes.dxSelectBox, EditorOptions=EditorOptionValues.ShowClearButton },
|
new EditingFormItemDto { Order = 4, DataField = "Category", ColSpan=1, IsRequired = true, EditorType2 = EditorTypes.dxSelectBox, EditorOptions=EditorOptionValues.ShowClearButton },
|
||||||
new EditingFormItemDto { Order = 5, DataField = "UserId", ColSpan=1, IsRequired = true, EditorType2 = EditorTypes.dxSelectBox, EditorOptions=EditorOptionValues.ShowClearButton },
|
new EditingFormItemDto { Order = 5, DataField = "UserId", ColSpan=1, IsRequired = true, EditorType2 = EditorTypes.dxSelectBox, EditorOptions=EditorOptionValues.ShowClearButton },
|
||||||
new EditingFormItemDto { Order = 6, DataField = "PublishDate", ColSpan=1, EditorType2 = EditorTypes.dxDateBox },
|
new EditingFormItemDto { Order = 6, DataField = "PublishDate", ColSpan=1, EditorType2 = EditorTypes.dxDateBox },
|
||||||
new EditingFormItemDto { Order = 7, DataField = "ExpiryDate", ColSpan=1, IsRequired = true, EditorType2 = EditorTypes.dxDateBox },
|
new EditingFormItemDto { Order = 7, DataField = "ExpiryDate", ColSpan=1, EditorType2 = EditorTypes.dxDateBox },
|
||||||
new EditingFormItemDto { Order = 8, DataField = "IsPinned", ColSpan=1, EditorType2 = EditorTypes.dxCheckBox },
|
new EditingFormItemDto { Order = 8, DataField = "IsPinned", ColSpan=1, EditorType2 = EditorTypes.dxCheckBox },
|
||||||
new EditingFormItemDto { Order = 9, DataField = "ImageUrl", ColSpan=1, EditorType2 = EditorTypes.dxImageUpload, EditorOptions = EditorOptionValues.ImageUploadOptions},
|
new EditingFormItemDto { Order = 9, DataField = "ImageUrl", ColSpan=1, EditorType2 = EditorTypes.dxImageUpload, EditorOptions = EditorOptionValues.ImageUploadOptions},
|
||||||
]}
|
]}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { forwardRef, Ref } from 'react'
|
import { forwardRef, useEffect, useRef } from 'react'
|
||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
import ReactSelect from 'react-select'
|
import ReactSelect, { components as ReactSelectComponents } from 'react-select'
|
||||||
import CreatableSelect from 'react-select/creatable'
|
import CreatableSelect from 'react-select/creatable'
|
||||||
import AsyncSelect from 'react-select/async'
|
import AsyncSelect from 'react-select/async'
|
||||||
import { TW_COLORS, BORDER_RADIUS, SPACING } from '@/utils/tailwind'
|
import { TW_COLORS, BORDER_RADIUS, SPACING } from '@/utils/tailwind'
|
||||||
|
|
@ -17,15 +17,17 @@ import type {
|
||||||
ControlProps,
|
ControlProps,
|
||||||
Props as ReactSelectProps,
|
Props as ReactSelectProps,
|
||||||
GroupBase,
|
GroupBase,
|
||||||
|
MenuListProps,
|
||||||
} from 'react-select'
|
} from 'react-select'
|
||||||
import type { AsyncProps } from 'react-select/async'
|
import type { AsyncProps } from 'react-select/async'
|
||||||
import type { CreatableProps } from 'react-select/creatable'
|
import type { CreatableProps } from 'react-select/creatable'
|
||||||
import type { ForwardedRef } from 'react'
|
import type { ForwardedRef, ReactNode, Ref } from 'react'
|
||||||
|
|
||||||
interface DefaultOptionProps {
|
interface DefaultOptionProps {
|
||||||
innerProps: JSX.IntrinsicElements['div']
|
innerProps: JSX.IntrinsicElements['div']
|
||||||
label: string
|
label: string
|
||||||
selectProps: { themeColor?: string }
|
selectProps: { themeColor?: string }
|
||||||
|
children?: ReactNode
|
||||||
isSelected: boolean
|
isSelected: boolean
|
||||||
isDisabled: boolean
|
isDisabled: boolean
|
||||||
isFocused: boolean
|
isFocused: boolean
|
||||||
|
|
@ -38,6 +40,7 @@ const DefaultOption = ({
|
||||||
isSelected,
|
isSelected,
|
||||||
isDisabled,
|
isDisabled,
|
||||||
isFocused,
|
isFocused,
|
||||||
|
children,
|
||||||
}: DefaultOptionProps) => {
|
}: DefaultOptionProps) => {
|
||||||
const { themeColor } = selectProps
|
const { themeColor } = selectProps
|
||||||
return (
|
return (
|
||||||
|
|
@ -50,7 +53,7 @@ const DefaultOption = ({
|
||||||
)}
|
)}
|
||||||
{...innerProps}
|
{...innerProps}
|
||||||
>
|
>
|
||||||
<span className="ml-2">{label}</span>
|
<div className="ml-2 min-w-0">{children ?? label}</div>
|
||||||
{isSelected && (
|
{isSelected && (
|
||||||
<FaCheck
|
<FaCheck
|
||||||
className={`text-${themeColor} dark:text-white text-xl`}
|
className={`text-${themeColor} dark:text-white text-xl`}
|
||||||
|
|
@ -60,6 +63,39 @@ const DefaultOption = ({
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DefaultMenuList = <
|
||||||
|
Option,
|
||||||
|
IsMulti extends boolean = false,
|
||||||
|
Group extends GroupBase<Option> = GroupBase<Option>
|
||||||
|
>(
|
||||||
|
props: MenuListProps<Option, IsMulti, Group>
|
||||||
|
) => {
|
||||||
|
const menuListRef = useRef<HTMLDivElement | null>(null)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const frame = requestAnimationFrame(() => {
|
||||||
|
menuListRef.current
|
||||||
|
?.querySelector('.select-option.selected')
|
||||||
|
?.scrollIntoView({ block: 'center' })
|
||||||
|
})
|
||||||
|
|
||||||
|
return () => cancelAnimationFrame(frame)
|
||||||
|
}, [props.selectProps.value])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ReactSelectComponents.MenuList
|
||||||
|
{...props}
|
||||||
|
innerRef={(element) => {
|
||||||
|
menuListRef.current = element
|
||||||
|
|
||||||
|
if (typeof props.innerRef === 'function') {
|
||||||
|
props.innerRef(element)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
const DefaultDropdownIndicator = () => {
|
const DefaultDropdownIndicator = () => {
|
||||||
return (
|
return (
|
||||||
<div className="select-dropdown-indicator">
|
<div className="select-dropdown-indicator">
|
||||||
|
|
@ -235,6 +271,7 @@ function _Select<
|
||||||
components={{
|
components={{
|
||||||
IndicatorSeparator: () => null,
|
IndicatorSeparator: () => null,
|
||||||
Option: DefaultOption,
|
Option: DefaultOption,
|
||||||
|
MenuList: DefaultMenuList,
|
||||||
LoadingIndicator: DefaultLoadingIndicator,
|
LoadingIndicator: DefaultLoadingIndicator,
|
||||||
DropdownIndicator: DefaultDropdownIndicator,
|
DropdownIndicator: DefaultDropdownIndicator,
|
||||||
ClearIndicator: DefaultClearIndicator,
|
ClearIndicator: DefaultClearIndicator,
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@ import {
|
||||||
FaDownload,
|
FaDownload,
|
||||||
FaPaste,
|
FaPaste,
|
||||||
FaBuilding,
|
FaBuilding,
|
||||||
|
FaUsers,
|
||||||
|
FaChevronRight,
|
||||||
} from 'react-icons/fa'
|
} from 'react-icons/fa'
|
||||||
import Container from '@/components/shared/Container'
|
import Container from '@/components/shared/Container'
|
||||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
|
|
@ -136,7 +138,9 @@ const FileManager = () => {
|
||||||
const items = response.data.items || []
|
const items = response.data.items || []
|
||||||
// Manual protection for system folders
|
// Manual protection for system folders
|
||||||
const protectedItems = items.map((item) => {
|
const protectedItems = items.map((item) => {
|
||||||
const isSystemFolder = ['intranet', 'avatar', 'import', 'note', 'backup'].includes(item.name.toLowerCase())
|
const isSystemFolder = ['intranet', 'avatar', 'import', 'note', 'backup'].includes(
|
||||||
|
item.name.toLowerCase(),
|
||||||
|
)
|
||||||
return {
|
return {
|
||||||
...item,
|
...item,
|
||||||
isReadOnly: item.isReadOnly || isSystemFolder,
|
isReadOnly: item.isReadOnly || isSystemFolder,
|
||||||
|
|
@ -735,48 +739,11 @@ const FileManager = () => {
|
||||||
></Helmet>
|
></Helmet>
|
||||||
|
|
||||||
{/* Enhanced Unified Toolbar */}
|
{/* Enhanced Unified Toolbar */}
|
||||||
<div className="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg mb-4 mt-2">
|
<div className="dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg p-2 mb-4 mt-2">
|
||||||
{/* Main Toolbar Row */}
|
{/* Main Toolbar Row */}
|
||||||
<div className="flex flex-col lg:flex-row lg:items-center justify-between gap-3 sm:gap-4">
|
<div className="flex flex-col lg:flex-row lg:items-center justify-between gap-3 sm:gap-4">
|
||||||
{/* Left Section - Primary Actions */}
|
{/* Left Section - Primary Actions */}
|
||||||
<div className="flex items-center gap-2 flex-wrap min-w-0">
|
<div className="flex items-center gap-2 flex-wrap min-w-0">
|
||||||
{/* Tenant Selector Row */}
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<FaBuilding className="text-gray-500 flex-shrink-0" />
|
|
||||||
{isHostContext ? (
|
|
||||||
<Select
|
|
||||||
size="sm"
|
|
||||||
isLoading={tenantsLoading}
|
|
||||||
options={[
|
|
||||||
{ value: '', label: 'Host' },
|
|
||||||
...tenants.map((t) => ({ value: t.id ?? '', label: t.name ?? '' })),
|
|
||||||
]}
|
|
||||||
value={{
|
|
||||||
value: selectedTenant ? selectedTenant.id : '',
|
|
||||||
label: selectedTenant ? selectedTenant.name : 'Host',
|
|
||||||
}}
|
|
||||||
onChange={(option) => {
|
|
||||||
if (option && 'value' in option) {
|
|
||||||
const val = option.value as string
|
|
||||||
if (!val) {
|
|
||||||
setSelectedTenant(undefined)
|
|
||||||
} else {
|
|
||||||
const found = tenants.find((t) => t.id === val)
|
|
||||||
if (found) setSelectedTenant({ id: found.id!, name: found.name ?? '' })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<div
|
|
||||||
className="text-sm font-medium text-gray-700 dark:text-gray-200 truncate max-w-[220px]"
|
|
||||||
title={authTenantName || selectedTenant?.name || ''}
|
|
||||||
>
|
|
||||||
{authTenantName || selectedTenant?.name || ''}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* File Operations */}
|
{/* File Operations */}
|
||||||
{/* Navigation */}
|
{/* Navigation */}
|
||||||
<Button
|
<Button
|
||||||
|
|
@ -795,8 +762,8 @@ const FileManager = () => {
|
||||||
size="sm"
|
size="sm"
|
||||||
className="flex-shrink-0"
|
className="flex-shrink-0"
|
||||||
>
|
>
|
||||||
<span className="hidden sm:inline">Upload Files</span>
|
<span className="hidden sm:inline">{translate('::FileManager.UploadFiles')}</span>
|
||||||
<span className="sm:hidden">Upload</span>
|
<span className="sm:hidden">{translate('::FileManager.Upload')}</span>
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
variant="default"
|
variant="default"
|
||||||
|
|
@ -805,8 +772,8 @@ const FileManager = () => {
|
||||||
size="sm"
|
size="sm"
|
||||||
className="flex-shrink-0"
|
className="flex-shrink-0"
|
||||||
>
|
>
|
||||||
<span className="hidden sm:inline">Create Folder</span>
|
<span className="hidden sm:inline">{translate('::FileManager.CreateFolder')}</span>
|
||||||
<span className="sm:hidden">Create</span>
|
<span className="sm:hidden">{translate('::FileManager.Create')}</span>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
{/* Clipboard Operations */}
|
{/* Clipboard Operations */}
|
||||||
|
|
@ -817,7 +784,7 @@ const FileManager = () => {
|
||||||
disabled={selectedItems.length === 0}
|
disabled={selectedItems.length === 0}
|
||||||
size="sm"
|
size="sm"
|
||||||
className="text-gray-600 hover:text-blue-600 disabled:opacity-50 flex-shrink-0"
|
className="text-gray-600 hover:text-blue-600 disabled:opacity-50 flex-shrink-0"
|
||||||
title="Copy selected items"
|
title={translate('::FileManager.CopySelectedItems')}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
variant="plain"
|
variant="plain"
|
||||||
|
|
@ -826,7 +793,7 @@ const FileManager = () => {
|
||||||
disabled={selectedItems.length === 0}
|
disabled={selectedItems.length === 0}
|
||||||
size="sm"
|
size="sm"
|
||||||
className="text-gray-600 hover:text-orange-600 disabled:opacity-50 flex-shrink-0"
|
className="text-gray-600 hover:text-orange-600 disabled:opacity-50 flex-shrink-0"
|
||||||
title="Cut selected items"
|
title={translate('::FileManager.CutSelectedItems')}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
variant="plain"
|
variant="plain"
|
||||||
|
|
@ -835,7 +802,7 @@ const FileManager = () => {
|
||||||
disabled={!hasClipboardData}
|
disabled={!hasClipboardData}
|
||||||
size="sm"
|
size="sm"
|
||||||
className="text-gray-600 hover:text-green-600 disabled:opacity-50 flex-shrink-0"
|
className="text-gray-600 hover:text-green-600 disabled:opacity-50 flex-shrink-0"
|
||||||
title="Paste items"
|
title={translate('::FileManager.PasteSelectedItems')}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
variant="plain"
|
variant="plain"
|
||||||
|
|
@ -857,7 +824,7 @@ const FileManager = () => {
|
||||||
size="sm"
|
size="sm"
|
||||||
disabled={selectedItems.length !== 1}
|
disabled={selectedItems.length !== 1}
|
||||||
className="text-gray-600 hover:text-blue-600 flex-shrink-0"
|
className="text-gray-600 hover:text-blue-600 flex-shrink-0"
|
||||||
title="Rename selected item"
|
title={translate('::FileManager.RenameSelectedItem')}
|
||||||
></Button>
|
></Button>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
|
|
@ -886,7 +853,7 @@ const FileManager = () => {
|
||||||
})()
|
})()
|
||||||
}
|
}
|
||||||
className="text-gray-600 hover:text-green-600 flex-shrink-0"
|
className="text-gray-600 hover:text-green-600 flex-shrink-0"
|
||||||
title="Download selected file"
|
title={translate('::FileManager.DownloadSelectedFile')}
|
||||||
></Button>
|
></Button>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
|
|
@ -896,9 +863,9 @@ const FileManager = () => {
|
||||||
size="sm"
|
size="sm"
|
||||||
disabled={selectedItems.length === 0}
|
disabled={selectedItems.length === 0}
|
||||||
className="text-gray-600 hover:text-red-600 flex-shrink-0"
|
className="text-gray-600 hover:text-red-600 flex-shrink-0"
|
||||||
title="Delete selected items"
|
title={translate('::FileManager.DeleteSelectedItems')}
|
||||||
>
|
>
|
||||||
<span>Delete {selectedItems.length > 0 && `(${selectedItems.length})`}</span>
|
<span>{translate('::Delete')}</span> {selectedItems.length > 0 && `(${selectedItems.length})`}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
{/* Selection Actions */}
|
{/* Selection Actions */}
|
||||||
|
|
@ -928,13 +895,13 @@ const FileManager = () => {
|
||||||
>
|
>
|
||||||
<span className="hidden lg:inline">
|
<span className="hidden lg:inline">
|
||||||
{selectedItems.length === filteredItems.filter((item) => !item.isReadOnly).length
|
{selectedItems.length === filteredItems.filter((item) => !item.isReadOnly).length
|
||||||
? 'Deselect All'
|
? translate('::FileManager.DeselectAll')
|
||||||
: 'Select All'}
|
: translate('::FileManager.SelectAll')}
|
||||||
</span>
|
</span>
|
||||||
<span className="lg:hidden">
|
<span className="lg:hidden">
|
||||||
{selectedItems.length === filteredItems.filter((item) => !item.isReadOnly).length
|
{selectedItems.length === filteredItems.filter((item) => !item.isReadOnly).length
|
||||||
? 'Deselect'
|
? translate('::FileManager.Deselect')
|
||||||
: 'Select'}
|
: translate('::FileManager.Select')}
|
||||||
</span>
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
|
@ -946,7 +913,7 @@ const FileManager = () => {
|
||||||
<div className="flex items-center w-full sm:w-auto">
|
<div className="flex items-center w-full sm:w-auto">
|
||||||
<Input
|
<Input
|
||||||
size="sm"
|
size="sm"
|
||||||
placeholder="Search files..."
|
placeholder={translate('::FileManager.SearchFiles')}
|
||||||
value={filters.searchTerm}
|
value={filters.searchTerm}
|
||||||
onChange={(e) => setFilters((prev) => ({ ...prev, searchTerm: e.target.value }))}
|
onChange={(e) => setFilters((prev) => ({ ...prev, searchTerm: e.target.value }))}
|
||||||
prefix={<FaSearch className="text-gray-400" />}
|
prefix={<FaSearch className="text-gray-400" />}
|
||||||
|
|
@ -958,12 +925,12 @@ const FileManager = () => {
|
||||||
<Select
|
<Select
|
||||||
size="xs"
|
size="xs"
|
||||||
options={[
|
options={[
|
||||||
{ value: 'name-asc', label: 'Name (A-Z)' },
|
{ value: 'name-asc', label: translate('::FileManager.SortByNameAsc') },
|
||||||
{ value: 'name-desc', label: 'Name (Z-A)' },
|
{ value: 'name-desc', label: translate('::FileManager.SortByNameDesc') },
|
||||||
{ value: 'size-asc', label: 'Size (Small to Large)' },
|
{ value: 'size-asc', label: translate('::FileManager.SortBySizeAsc') },
|
||||||
{ value: 'size-desc', label: 'Size (Large to Small)' },
|
{ value: 'size-desc', label: translate('::FileManager.SortBySizeDesc') },
|
||||||
{ value: 'modified-desc', label: 'Modified (Newest)' },
|
{ value: 'modified-desc', label: translate('::FileManager.SortByModifiedDesc') },
|
||||||
{ value: 'modified-asc', label: 'Modified (Oldest)' },
|
{ value: 'modified-asc', label: translate('::FileManager.SortByModifiedAsc') },
|
||||||
]}
|
]}
|
||||||
value={{
|
value={{
|
||||||
value: `${filters.sortBy}-${filters.sortOrder}`,
|
value: `${filters.sortBy}-${filters.sortOrder}`,
|
||||||
|
|
@ -1014,9 +981,65 @@ const FileManager = () => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Breadcrumb */}
|
{/* Breadcrumb */}
|
||||||
<div className="mb-4 sm:mb-6 overflow-x-auto">
|
<div className="flex items-center gap-2 mb-4 sm:mb-6">
|
||||||
<div className="min-w-max">
|
<div className="flex items-center gap-2">
|
||||||
<Breadcrumb items={breadcrumbItems} onNavigate={handleBreadcrumbNavigate} />
|
{isHostContext ? (
|
||||||
|
<Select
|
||||||
|
size="xs"
|
||||||
|
isLoading={tenantsLoading}
|
||||||
|
options={[
|
||||||
|
{
|
||||||
|
value: '',
|
||||||
|
label: 'Host',
|
||||||
|
icon: <FaBuilding className="flex-shrink-0 text-gray-500" />,
|
||||||
|
},
|
||||||
|
...tenants.map((t) => ({
|
||||||
|
value: t.id ?? '',
|
||||||
|
label: t.name ?? '',
|
||||||
|
icon: <FaUsers className="flex-shrink-0 text-blue-500" />,
|
||||||
|
})),
|
||||||
|
]}
|
||||||
|
value={{
|
||||||
|
value: selectedTenant ? selectedTenant.id : '',
|
||||||
|
label: selectedTenant ? selectedTenant.name : 'Host',
|
||||||
|
icon: selectedTenant ? (
|
||||||
|
<FaUsers className="flex-shrink-0 text-blue-500" />
|
||||||
|
) : (
|
||||||
|
<FaBuilding className="flex-shrink-0 text-gray-500" />
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
formatOptionLabel={(option) => (
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
{option.icon}
|
||||||
|
<span className="truncate">{option.label}</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
onChange={(option) => {
|
||||||
|
if (option && 'value' in option) {
|
||||||
|
const val = option.value as string
|
||||||
|
if (!val) {
|
||||||
|
setSelectedTenant(undefined)
|
||||||
|
} else {
|
||||||
|
const found = tenants.find((t) => t.id === val)
|
||||||
|
if (found) setSelectedTenant({ id: found.id!, name: found.name ?? '' })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<div
|
||||||
|
className="max-w-[220px] truncate text-sm font-medium text-gray-700 dark:text-gray-200"
|
||||||
|
title={authTenantName || selectedTenant?.name || ''}
|
||||||
|
>
|
||||||
|
{authTenantName || selectedTenant?.name || ''}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<FaChevronRight className="mx-2 h-4 w-4 text-gray-400" />
|
||||||
|
<div className="overflow-x-auto">
|
||||||
|
<div className="flex min-w-max items-center gap-2">
|
||||||
|
<Breadcrumb items={breadcrumbItems} onNavigate={handleBreadcrumbNavigate} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -1030,10 +1053,10 @@ const FileManager = () => {
|
||||||
{/* List View Header */}
|
{/* List View Header */}
|
||||||
{viewMode === 'list' && (
|
{viewMode === 'list' && (
|
||||||
<div className="hidden sm:grid grid-cols-12 gap-4 px-4 py-2 text-sm font-medium text-gray-500 dark:text-gray-400 border-b dark:border-gray-700 mb-2">
|
<div className="hidden sm:grid grid-cols-12 gap-4 px-4 py-2 text-sm font-medium text-gray-500 dark:text-gray-400 border-b dark:border-gray-700 mb-2">
|
||||||
<div className="col-span-5 lg:col-span-5">İsim</div>
|
<div className="col-span-5 lg:col-span-5">{translate('::App.Listform.ListformField.Name')}</div>
|
||||||
<div className="col-span-2 lg:col-span-2">Tür</div>
|
<div className="col-span-2 lg:col-span-2">{translate('::App.Listform.ListformField.Type')}</div>
|
||||||
<div className="col-span-2 lg:col-span-2">Boyut</div>
|
<div className="col-span-2 lg:col-span-2">{translate('::App.Listform.ListformField.Size')}</div>
|
||||||
<div className="col-span-2 lg:col-span-2">Değiştirilme</div>
|
<div className="col-span-2 lg:col-span-2">{translate('::App.Listform.ListformField.Modified')}</div>
|
||||||
<div className="col-span-1"></div> {/* Actions column */}
|
<div className="col-span-1"></div> {/* Actions column */}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
@ -1099,7 +1122,7 @@ const FileManager = () => {
|
||||||
// Resim preview modal'ı açılabilir
|
// Resim preview modal'ı açılabilir
|
||||||
toast.push(
|
toast.push(
|
||||||
<Notification type="info">
|
<Notification type="info">
|
||||||
Resim önizleme özelliği yakında eklenecek
|
Image preview feature will be added soon.
|
||||||
</Notification>,
|
</Notification>,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ import { toast, Notification } from '@/components/ui'
|
||||||
// import { Dropdown } from '@/components/ui' // Artık kullanmıyoruz
|
// import { Dropdown } from '@/components/ui' // Artık kullanmıyoruz
|
||||||
import type { FileItem as FileItemType, FileActionMenuItem } from '@/types/fileManagement'
|
import type { FileItem as FileItemType, FileActionMenuItem } from '@/types/fileManagement'
|
||||||
import { FILE_URL } from '@/constants/app.constant'
|
import { FILE_URL } from '@/constants/app.constant'
|
||||||
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
|
|
||||||
export interface FileItemProps {
|
export interface FileItemProps {
|
||||||
item: FileItemType
|
item: FileItemType
|
||||||
|
|
@ -96,24 +97,24 @@ const formatDate = (date?: string | Date): string => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const getFileTypeLabel = (item: FileItemType): string => {
|
const getFileTypeLabel = (item: FileItemType, translate: (key: string) => string): string => {
|
||||||
if (item.type === 'folder') return 'Klasör'
|
if (item.type === 'folder') return translate('::FileManager.Folder')
|
||||||
|
|
||||||
const extension = item.extension?.toLowerCase()
|
const extension = item.extension?.toLowerCase()
|
||||||
const mimeType = item.mimeType?.toLowerCase()
|
const mimeType = item.mimeType?.toLowerCase()
|
||||||
|
|
||||||
if (mimeType?.startsWith('image/')) return 'Resim'
|
if (mimeType?.startsWith('image/')) return translate('::FileManager.Picture') // 'Resim'
|
||||||
if (mimeType?.startsWith('video/')) return 'Video'
|
if (mimeType?.startsWith('video/')) return translate('::FileManager.Video') // 'Video'
|
||||||
if (mimeType?.startsWith('audio/')) return 'Ses'
|
if (mimeType?.startsWith('audio/')) return translate('::FileManager.Sound') // 'Ses'
|
||||||
if (mimeType?.includes('pdf')) return 'PDF'
|
if (mimeType?.includes('pdf')) return translate('::FileManager.PDF') // 'PDF'
|
||||||
if (mimeType?.includes('word')) return 'Word'
|
if (mimeType?.includes('word')) return translate('::FileManager.Word') // 'Word'
|
||||||
if (mimeType?.includes('excel') || mimeType?.includes('spreadsheet')) return 'Excel'
|
if (mimeType?.includes('excel') || mimeType?.includes('spreadsheet')) return translate('::FileManager.Excel') // 'Excel'
|
||||||
if (mimeType?.includes('powerpoint') || mimeType?.includes('presentation')) return 'PowerPoint'
|
if (mimeType?.includes('powerpoint') || mimeType?.includes('presentation')) return translate('::FileManager.PowerPoint') // 'PowerPoint'
|
||||||
if (['zip', 'rar', '7z', 'tar', 'gz'].includes(extension || '')) return 'Arşiv'
|
if (['zip', 'rar', '7z', 'tar', 'gz'].includes(extension || '')) return translate('::FileManager.Archive') // 'Arşiv'
|
||||||
if (['txt', 'md'].includes(extension || '')) return 'Metin'
|
if (['txt', 'md'].includes(extension || '')) return translate('::FileManager.Text') // 'Metin'
|
||||||
if (['json', 'xml', 'css', 'js', 'ts', 'html'].includes(extension || '')) return 'Kod'
|
if (['json', 'xml', 'css', 'js', 'ts', 'html'].includes(extension || '')) return translate('::FileManager.Code') // 'Kod'
|
||||||
|
|
||||||
return extension?.toUpperCase() || 'Dosya'
|
return extension?.toUpperCase() || translate('::FileManager.File')
|
||||||
}
|
}
|
||||||
|
|
||||||
const FileItem = forwardRef<HTMLDivElement, FileItemProps>((props, ref) => {
|
const FileItem = forwardRef<HTMLDivElement, FileItemProps>((props, ref) => {
|
||||||
|
|
@ -135,7 +136,7 @@ const FileItem = forwardRef<HTMLDivElement, FileItemProps>((props, ref) => {
|
||||||
|
|
||||||
const [dropdownOpen, setDropdownOpen] = useState(false)
|
const [dropdownOpen, setDropdownOpen] = useState(false)
|
||||||
const [contextMenuPosition, setContextMenuPosition] = useState<{ x: number; y: number } | null>(null)
|
const [contextMenuPosition, setContextMenuPosition] = useState<{ x: number; y: number } | null>(null)
|
||||||
|
const { translate } = useLocalization()
|
||||||
const handleClick = () => {
|
const handleClick = () => {
|
||||||
onSelect?.(item)
|
onSelect?.(item)
|
||||||
}
|
}
|
||||||
|
|
@ -185,7 +186,7 @@ const FileItem = forwardRef<HTMLDivElement, FileItemProps>((props, ref) => {
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
key: 'preview',
|
key: 'preview',
|
||||||
label: 'Önizle',
|
label: translate('::App.Listform.ListformField.Preview'),
|
||||||
icon: 'HiEye',
|
icon: 'HiEye',
|
||||||
onClick: () => onPreview(item),
|
onClick: () => onPreview(item),
|
||||||
},
|
},
|
||||||
|
|
@ -196,7 +197,7 @@ const FileItem = forwardRef<HTMLDivElement, FileItemProps>((props, ref) => {
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
key: 'download',
|
key: 'download',
|
||||||
label: 'İndir',
|
label: translate('::App.Listform.ListformField.Download'),
|
||||||
icon: 'HiArrowDownTray',
|
icon: 'HiArrowDownTray',
|
||||||
onClick: () => onDownload(item),
|
onClick: () => onDownload(item),
|
||||||
},
|
},
|
||||||
|
|
@ -207,7 +208,7 @@ const FileItem = forwardRef<HTMLDivElement, FileItemProps>((props, ref) => {
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
key: 'copyUrl',
|
key: 'copyUrl',
|
||||||
label: 'URL Kopyala',
|
label: translate('::App.Listform.ListformField.CopyFileUrl'),
|
||||||
icon: 'HiLink',
|
icon: 'HiLink',
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
const fileUrl = FILE_URL(item.path, item.tenantId)
|
const fileUrl = FILE_URL(item.path, item.tenantId)
|
||||||
|
|
@ -236,7 +237,7 @@ const FileItem = forwardRef<HTMLDivElement, FileItemProps>((props, ref) => {
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
key: 'createFolder',
|
key: 'createFolder',
|
||||||
label: 'Yeni Klasör',
|
label: translate('::App.Listform.ListformField.NewFolder'),
|
||||||
icon: 'HiFolderPlus',
|
icon: 'HiFolderPlus',
|
||||||
onClick: () => onCreateFolder(item),
|
onClick: () => onCreateFolder(item),
|
||||||
},
|
},
|
||||||
|
|
@ -247,7 +248,7 @@ const FileItem = forwardRef<HTMLDivElement, FileItemProps>((props, ref) => {
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
key: 'rename',
|
key: 'rename',
|
||||||
label: 'Yeniden Adlandır',
|
label: translate('::App.Listform.ListformField.Rename'),
|
||||||
icon: 'HiPencil',
|
icon: 'HiPencil',
|
||||||
onClick: () => onRename(item),
|
onClick: () => onRename(item),
|
||||||
},
|
},
|
||||||
|
|
@ -258,7 +259,7 @@ const FileItem = forwardRef<HTMLDivElement, FileItemProps>((props, ref) => {
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
key: 'move',
|
key: 'move',
|
||||||
label: 'Taşı',
|
label: translate('::App.Listform.ListformField.Move'),
|
||||||
icon: 'HiArrowRightOnRectangle',
|
icon: 'HiArrowRightOnRectangle',
|
||||||
onClick: () => onMove(item),
|
onClick: () => onMove(item),
|
||||||
},
|
},
|
||||||
|
|
@ -269,7 +270,7 @@ const FileItem = forwardRef<HTMLDivElement, FileItemProps>((props, ref) => {
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
key: 'delete',
|
key: 'delete',
|
||||||
label: 'Sil',
|
label: translate('::Delete'),
|
||||||
icon: 'HiTrash',
|
icon: 'HiTrash',
|
||||||
dangerous: true,
|
dangerous: true,
|
||||||
onClick: () => onDelete(item),
|
onClick: () => onDelete(item),
|
||||||
|
|
@ -404,7 +405,7 @@ const FileItem = forwardRef<HTMLDivElement, FileItemProps>((props, ref) => {
|
||||||
|
|
||||||
{/* File Type - Hidden on mobile */}
|
{/* File Type - Hidden on mobile */}
|
||||||
<div className="hidden sm:flex col-span-2 items-center">
|
<div className="hidden sm:flex col-span-2 items-center">
|
||||||
<span className="text-sm text-gray-500 dark:text-gray-400">{getFileTypeLabel(item)}</span>
|
<span className="text-sm text-gray-500 dark:text-gray-400">{getFileTypeLabel(item, translate)}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* File Size / Folder Item Count */}
|
{/* File Size / Folder Item Count */}
|
||||||
|
|
@ -500,7 +501,7 @@ const FileItem = forwardRef<HTMLDivElement, FileItemProps>((props, ref) => {
|
||||||
{/* File Size and Type */}
|
{/* File Size and Type */}
|
||||||
{item.type === 'file' && (
|
{item.type === 'file' && (
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
<p className="text-xs text-gray-500 dark:text-gray-400">{getFileTypeLabel(item)}</p>
|
<p className="text-xs text-gray-500 dark:text-gray-400">{getFileTypeLabel(item, translate)}</p>
|
||||||
{item.size && (
|
{item.size && (
|
||||||
<p className="text-xs text-gray-500 dark:text-gray-400">
|
<p className="text-xs text-gray-500 dark:text-gray-400">
|
||||||
{formatFileSize(item.size)}
|
{formatFileSize(item.size)}
|
||||||
|
|
@ -512,7 +513,7 @@ const FileItem = forwardRef<HTMLDivElement, FileItemProps>((props, ref) => {
|
||||||
{/* Folder Child Count */}
|
{/* Folder Child Count */}
|
||||||
{item.type === 'folder' && (
|
{item.type === 'folder' && (
|
||||||
<p className="text-xs text-gray-500 dark:text-gray-400">
|
<p className="text-xs text-gray-500 dark:text-gray-400">
|
||||||
{typeof item.childCount === 'number' ? `${item.childCount} öğe` : 'Sayılıyor...'}
|
{typeof item.childCount === 'number' ? `${item.childCount} ${translate('::App.Listform.ListformField.Item')}` : translate('::FileManager.Counting')}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import { forwardRef, useState, useEffect } from 'react'
|
||||||
import { Dialog, Button, Input, FormItem } from '@/components/ui'
|
import { Dialog, Button, Input, FormItem } from '@/components/ui'
|
||||||
import { FaTimes } from 'react-icons/fa'
|
import { FaTimes } from 'react-icons/fa'
|
||||||
import type { FileItem } from '@/types/fileManagement'
|
import type { FileItem } from '@/types/fileManagement'
|
||||||
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
|
|
||||||
// Create Folder Modal
|
// Create Folder Modal
|
||||||
export interface CreateFolderModalProps {
|
export interface CreateFolderModalProps {
|
||||||
|
|
@ -17,6 +18,7 @@ export const CreateFolderModal = forwardRef<HTMLDivElement, CreateFolderModalPro
|
||||||
const { isOpen, onClose, onCreate, loading = false } = props
|
const { isOpen, onClose, onCreate, loading = false } = props
|
||||||
const [folderName, setFolderName] = useState('')
|
const [folderName, setFolderName] = useState('')
|
||||||
const [error, setError] = useState('')
|
const [error, setError] = useState('')
|
||||||
|
const { translate } = useLocalization()
|
||||||
|
|
||||||
const handleSubmit = async (e: React.FormEvent) => {
|
const handleSubmit = async (e: React.FormEvent) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
|
@ -46,11 +48,10 @@ export const CreateFolderModal = forwardRef<HTMLDivElement, CreateFolderModalPro
|
||||||
<Dialog isOpen={isOpen} onClose={handleClose}>
|
<Dialog isOpen={isOpen} onClose={handleClose}>
|
||||||
<div ref={ref}>
|
<div ref={ref}>
|
||||||
<form onSubmit={handleSubmit} className="py-6">
|
<form onSubmit={handleSubmit} className="py-6">
|
||||||
<FormItem label="Folder Name" invalid={!!error} errorMessage={error}>
|
<FormItem label={translate('::FileManager.FolderName')} invalid={!!error} errorMessage={error}>
|
||||||
<Input
|
<Input
|
||||||
value={folderName}
|
value={folderName}
|
||||||
onChange={(e) => setFolderName(e.target.value)}
|
onChange={(e) => setFolderName(e.target.value)}
|
||||||
placeholder="Enter folder name"
|
|
||||||
autoFocus
|
autoFocus
|
||||||
className="mt-2"
|
className="mt-2"
|
||||||
/>
|
/>
|
||||||
|
|
@ -59,7 +60,7 @@ export const CreateFolderModal = forwardRef<HTMLDivElement, CreateFolderModalPro
|
||||||
|
|
||||||
<div className="flex justify-end space-x-2 pt-4 border-t">
|
<div className="flex justify-end space-x-2 pt-4 border-t">
|
||||||
<Button variant="default" onClick={handleClose} disabled={loading}>
|
<Button variant="default" onClick={handleClose} disabled={loading}>
|
||||||
Cancel
|
{translate('::Cancel')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
variant="solid"
|
variant="solid"
|
||||||
|
|
@ -67,7 +68,7 @@ export const CreateFolderModal = forwardRef<HTMLDivElement, CreateFolderModalPro
|
||||||
loading={loading}
|
loading={loading}
|
||||||
disabled={!folderName.trim()}
|
disabled={!folderName.trim()}
|
||||||
>
|
>
|
||||||
Create Folder
|
{translate('::FileManager.CreateFolder')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -91,6 +92,7 @@ export const RenameItemModal = forwardRef<HTMLDivElement, RenameItemModalProps>(
|
||||||
const { isOpen, onClose, onRename, item, loading = false } = props
|
const { isOpen, onClose, onRename, item, loading = false } = props
|
||||||
const [newName, setNewName] = useState('')
|
const [newName, setNewName] = useState('')
|
||||||
const [error, setError] = useState('')
|
const [error, setError] = useState('')
|
||||||
|
const { translate } = useLocalization()
|
||||||
|
|
||||||
// Update input when item changes
|
// Update input when item changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -134,21 +136,20 @@ export const RenameItemModal = forwardRef<HTMLDivElement, RenameItemModalProps>(
|
||||||
<div ref={ref} className="max-w-md">
|
<div ref={ref} className="max-w-md">
|
||||||
<div className="flex items-center justify-between pb-4 border-b">
|
<div className="flex items-center justify-between pb-4 border-b">
|
||||||
<h3 className="text-lg font-semibold">
|
<h3 className="text-lg font-semibold">
|
||||||
Rename {item.type === 'folder' ? 'Folder' : 'File'}
|
{translate(`::FileManager.${item.type === 'folder' ? 'RenameFolder' : 'RenameFile'}`)}
|
||||||
</h3>
|
</h3>
|
||||||
<Button variant="plain" size="sm" icon={<FaTimes />} onClick={handleClose} />
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form onSubmit={handleSubmit} className="py-6">
|
<form onSubmit={handleSubmit} className="py-6">
|
||||||
<FormItem
|
<FormItem
|
||||||
label={`${item.type === 'folder' ? 'Folder' : 'File'} Name`}
|
label={translate(`::FileManager.${item.type === 'folder' ? 'FolderName' : 'FileName'}`)}
|
||||||
invalid={!!error}
|
invalid={!!error}
|
||||||
errorMessage={error}
|
errorMessage={error}
|
||||||
>
|
>
|
||||||
<Input
|
<Input
|
||||||
value={newName}
|
value={newName}
|
||||||
onChange={(e) => setNewName(e.target.value)}
|
onChange={(e) => setNewName(e.target.value)}
|
||||||
placeholder={`Enter ${item.type} name`}
|
placeholder={`Enter ${translate(`::FileManager.${item.type === 'folder' ? 'FolderName' : 'FileName'}`)}`}
|
||||||
autoFocus
|
autoFocus
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
@ -156,7 +157,7 @@ export const RenameItemModal = forwardRef<HTMLDivElement, RenameItemModalProps>(
|
||||||
|
|
||||||
<div className="flex justify-end space-x-2 pt-4 border-t">
|
<div className="flex justify-end space-x-2 pt-4 border-t">
|
||||||
<Button variant="default" onClick={handleClose} disabled={loading}>
|
<Button variant="default" onClick={handleClose} disabled={loading}>
|
||||||
Cancel
|
{translate('::Cancel')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
variant="solid"
|
variant="solid"
|
||||||
|
|
@ -164,7 +165,7 @@ export const RenameItemModal = forwardRef<HTMLDivElement, RenameItemModalProps>(
|
||||||
loading={loading}
|
loading={loading}
|
||||||
disabled={!newName.trim()}
|
disabled={!newName.trim()}
|
||||||
>
|
>
|
||||||
Rename
|
{translate('::App.Listform.ListformField.Rename')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -186,6 +187,7 @@ export interface DeleteConfirmModalProps {
|
||||||
export const DeleteConfirmModal = forwardRef<HTMLDivElement, DeleteConfirmModalProps>(
|
export const DeleteConfirmModal = forwardRef<HTMLDivElement, DeleteConfirmModalProps>(
|
||||||
(props, ref) => {
|
(props, ref) => {
|
||||||
const { isOpen, onClose, onDelete, items, loading = false } = props
|
const { isOpen, onClose, onDelete, items, loading = false } = props
|
||||||
|
const { translate } = useLocalization()
|
||||||
|
|
||||||
const handleDelete = async () => {
|
const handleDelete = async () => {
|
||||||
try {
|
try {
|
||||||
|
|
@ -203,12 +205,14 @@ export const DeleteConfirmModal = forwardRef<HTMLDivElement, DeleteConfirmModalP
|
||||||
<Dialog isOpen={isOpen} onClose={onClose}>
|
<Dialog isOpen={isOpen} onClose={onClose}>
|
||||||
<div ref={ref}>
|
<div ref={ref}>
|
||||||
<div className="flex items-center justify-between pb-4 border-b">
|
<div className="flex items-center justify-between pb-4 border-b">
|
||||||
<h3 className="text-lg font-semibold text-red-600">Delete Items</h3>
|
<h3 className="text-lg font-semibold text-red-600">
|
||||||
|
{translate('::FileManager.DeleteConfirmationTitle')}
|
||||||
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="py-6">
|
<div className="py-6">
|
||||||
<p className="text-gray-900 dark:text-gray-100 mb-4">
|
<p className="text-gray-900 dark:text-gray-100 mb-4">
|
||||||
Are you sure you want to delete the following items? This action cannot be undone.
|
{translate('::FileManager.DeleteConfirmationMessage')}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div className="bg-gray-50 dark:bg-gray-700 rounded-lg p-2">
|
<div className="bg-gray-50 dark:bg-gray-700 rounded-lg p-2">
|
||||||
|
|
@ -235,7 +239,7 @@ export const DeleteConfirmModal = forwardRef<HTMLDivElement, DeleteConfirmModalP
|
||||||
|
|
||||||
<div className="flex justify-end space-x-2 pt-4 border-t">
|
<div className="flex justify-end space-x-2 pt-4 border-t">
|
||||||
<Button variant="default" onClick={onClose} disabled={loading}>
|
<Button variant="default" onClick={onClose} disabled={loading}>
|
||||||
Cancel
|
{translate('::Cancel')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
variant="solid"
|
variant="solid"
|
||||||
|
|
@ -243,7 +247,7 @@ export const DeleteConfirmModal = forwardRef<HTMLDivElement, DeleteConfirmModalP
|
||||||
onClick={handleDelete}
|
onClick={handleDelete}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
>
|
>
|
||||||
Delete
|
{translate('::Delete')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue