Button dönüşümleri
This commit is contained in:
parent
bc31e1f06a
commit
99d64e95f1
22 changed files with 243 additions and 214 deletions
|
|
@ -349,7 +349,7 @@
|
|||
"CustomComponents": [
|
||||
{
|
||||
"name": "DynamicEntityComponent",
|
||||
"code": "import React, { useEffect, useState } from \"react\";\nimport axios from \"axios\";\n\ninterface DynamicEntityComponentProps {\n title: string;\n}\n\nconst api = axios.create({\n baseURL: \"https://localhost:44344\", // defaults'ı her seferinde set etme\n});\n\nconst DynamicEntityComponent: React.FC<DynamicEntityComponentProps> = ({ title }) => {\n const [data, setData] = useState<Array<{ id: string; name: string }>>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n const fetchData = async () => {\n setLoading(true);\n setError(null);\n\n try {\n const res = await api.get(`/api/app/crudendpoint/${title}`);\n const raw = Array.isArray(res.data) ? res.data : res.data?.items ?? [];\n\n const filtered = raw.map((item: any) => ({\n id: item.Id ?? item.id,\n name: item.Name ?? item.name,\n }));\n\n setData(filtered);\n } catch (err: any) {\n setError(err.message || \"Failed to fetch data\");\n } finally {\n setLoading(false);\n }\n };\n\n if (title) fetchData();\n }, [title]);\n\n if (loading) return <div>Loading...</div>;\n if (error) return <div className=\"text-red-600\">Error: {error}</div>;\n if (!data.length) return <div>No records found</div>;\n\n const headers = [\"id\", \"name\", \"actions\"];\n\n return (\n <div className=\"overflow-auto\">\n <table className=\"min-w-full bg-white border border-slate-200 shadow-sm rounded-lg\">\n <thead className=\"bg-slate-100\">\n <tr>\n {headers.map((key) => (\n <th\n key={key}\n className=\"text-left px-4 py-2 border-b border-slate-200 text-sm font-medium text-slate-700\"\n >\n {key === \"actions\" ? \"Actions\" : key}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {data.map((item, rowIndex) => (\n <tr key={rowIndex} className=\"hover:bg-slate-50\">\n <td className=\"px-4 py-2 border-b border-slate-100 text-sm text-slate-800\">\n {item.id}\n </td>\n <td className=\"px-4 py-2 border-b border-slate-100 text-sm text-slate-800\">\n {item.name}\n </td>\n <td className=\"px-4 py-2 border-b border-slate-100\">\n <button\n onClick={() => alert(item.name)}\n className=\"bg-blue-600 hover:bg-blue-700 text-white text-sm px-3 py-1 rounded-lg shadow-sm transition\"\n >\n Show Name\n </button>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n};\n\nexport default DynamicEntityComponent;",
|
||||
"code": "import React, { useEffect, useState } from \"react\";\nimport axios from \"axios\";\n\ninterface DynamicEntityComponentProps {\n title: string;\n}\n\nconst api = axios.create({\n baseURL: \"https://localhost:44344\", // defaults'ı her seferinde set etme\n});\n\nconst DynamicEntityComponent: React.FC<DynamicEntityComponentProps> = ({ title }) => {\n const [data, setData] = useState<Array<{ id: string; name: string }>>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n const fetchData = async () => {\n setLoading(true);\n setError(null);\n\n try {\n const res = await api.get(`/api/app/crudendpoint/${title}`);\n const raw = Array.isArray(res.data) ? res.data : res.data?.items ?? [];\n\n const filtered = raw.map((item: any) => ({\n id: item.Id ?? item.id,\n name: item.Name ?? item.name,\n }));\n\n setData(filtered);\n } catch (err: any) {\n setError(err.message || \"Failed to fetch data\");\n } finally {\n setLoading(false);\n }\n };\n\n if (title) fetchData();\n }, [title]);\n\n if (loading) return <div>Loading...</div>;\n if (error) return <div className=\"text-red-600\">Error: {error}</div>;\n if (!data.length) return <div>No records found</div>;\n\n const headers = [\"id\", \"name\", \"actions\"];\n\n return (\n <div className=\"overflow-auto\">\n <table className=\"min-w-full bg-white border border-slate-200 shadow-sm rounded-lg\">\n <thead className=\"bg-slate-100\">\n <tr>\n {headers.map((key) => (\n <th\n key={key}\n className=\"text-left px-4 py-2 border-b border-slate-200 text-sm font-medium text-slate-700\"\n >\n {key === \"actions\" ? \"Actions\" : key}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {data.map((item, rowIndex) => (\n <tr key={rowIndex} className=\"hover:bg-slate-50\">\n <td className=\"px-4 py-2 border-b border-slate-100 text-sm text-slate-800\">\n {item.id}\n </td>\n <td className=\"px-4 py-2 border-b border-slate-100 text-sm text-slate-800\">\n {item.name}\n </td>\n <td className=\"px-4 py-2 border-b border-slate-100\">\n <button\n type=\"button\"\n onClick={() => alert(item.name)}\n className=\"bg-blue-600 hover:bg-blue-700 text-white text-sm px-3 py-1 rounded-lg shadow-sm transition\"\n >\n Show Name\n </button>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n};\n\nexport default DynamicEntityComponent;",
|
||||
"props": null,
|
||||
"description": null,
|
||||
"isActive": true,
|
||||
|
|
|
|||
|
|
@ -197,9 +197,7 @@ const _Search = ({ className }: { className?: string }) => {
|
|||
onKeyDown={(e) => e.key === 'Enter' && handleSearch()}
|
||||
/>
|
||||
</div>
|
||||
<Button size="sm" onClick={handleSearch}>
|
||||
<FaSearch />
|
||||
</Button>
|
||||
<Button icon={<FaSearch />} size="sm" onClick={handleSearch}></Button>
|
||||
</div>
|
||||
<div>
|
||||
<div className="flex items-center justify-between p-4 border-b border-gray-200 dark:border-gray-600">
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ const NotFoundPage = () => {
|
|||
onClick={() =>
|
||||
navigate(isAdminPath ? ROUTES_ENUM.protected.dashboard : ROUTES_ENUM.public.home)
|
||||
}
|
||||
className="px-6 py-3 bg-blue-500 rounded-xl shadow hover:bg-blue-600 transition"
|
||||
className="bg-blue-500 rounded-xl shadow hover:bg-blue-600 transition"
|
||||
>
|
||||
{translate('::Public.notFound.button')}
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { Alert, Button } from '@/components/ui'
|
|||
import { store, useStoreState } from '@/store'
|
||||
import { Suspense, useEffect } from 'react'
|
||||
import { ErrorBoundary } from 'react-error-boundary'
|
||||
import { FaArrowLeft } from 'react-icons/fa';
|
||||
import { FaArrowLeft } from 'react-icons/fa'
|
||||
import { Navigate, useLocation } from 'react-router-dom'
|
||||
import DialogProvider from './shared/DialogContext'
|
||||
import DialogShowComponent from './shared/DialogContext/DialogShowComponent'
|
||||
|
|
@ -22,9 +22,13 @@ function fallbackRender({ error, resetErrorBoundary }: { error: Error; resetErro
|
|||
<Alert showIcon className="mb-4" type="danger">
|
||||
<h5>{error.name ?? 'Hata!'}</h5>
|
||||
<div>{error.message}</div>
|
||||
<Button size="sm" className="mt-2" variant="default" onClick={resetErrorBoundary}>
|
||||
<FaArrowLeft />
|
||||
</Button>
|
||||
<Button
|
||||
icon={<FaArrowLeft />}
|
||||
size="sm"
|
||||
className="mt-2"
|
||||
variant="default"
|
||||
onClick={resetErrorBoundary}
|
||||
></Button>
|
||||
</Alert>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,13 @@ const Breadcrumb = forwardRef<HTMLDivElement, BreadcrumbProps>((props, ref) => {
|
|||
{index > 0 && <FaChevronRight className="mx-2 h-4 w-4 text-gray-400" />}
|
||||
<Button
|
||||
size="sm"
|
||||
icon={
|
||||
index === 0 ? (
|
||||
<FaHome className="h-4 w-4 mr-1" />
|
||||
) : (
|
||||
<FaFolder className="h-4 w-4 mr-1" />
|
||||
)
|
||||
}
|
||||
onClick={() => onNavigate(item)}
|
||||
className={classNames(
|
||||
'flex items-center px-2 py-1 rounded hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors',
|
||||
|
|
@ -29,11 +36,6 @@ const Breadcrumb = forwardRef<HTMLDivElement, BreadcrumbProps>((props, ref) => {
|
|||
)}
|
||||
disabled={index === items.length - 1}
|
||||
>
|
||||
{index === 0 ? (
|
||||
<FaHome className="h-4 w-4 mr-1" />
|
||||
) : (
|
||||
<FaFolder className="h-4 w-4 mr-1" />
|
||||
)}
|
||||
<span className="truncate max-w-32">{item.name}</span>
|
||||
</Button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ export interface MenuTreeNode {
|
|||
displayName: string
|
||||
icon?: string
|
||||
url?: string
|
||||
order?: number
|
||||
children: MenuTreeNode[]
|
||||
}
|
||||
|
||||
|
|
@ -42,6 +43,7 @@ export function buildMenuTree(items: MenuItem[]): MenuTreeNode[] {
|
|||
displayName: item.displayName ?? item.code!,
|
||||
icon: item.icon ?? undefined,
|
||||
url: item.url ?? undefined,
|
||||
order: item.order ?? undefined,
|
||||
children: [],
|
||||
})
|
||||
})
|
||||
|
|
@ -175,7 +177,7 @@ function TreeNode({
|
|||
className={`text-xs shrink-0 ${isSelected ? 'text-indigo-200' : 'text-gray-400'}`}
|
||||
onClick={() => !isEditing && onSelect(node.code)}
|
||||
>
|
||||
{translate('::' + node.displayName)}
|
||||
{translate('::' + node.displayName)} ({node.order})
|
||||
</span>
|
||||
|
||||
{isEditing ? (
|
||||
|
|
|
|||
|
|
@ -431,23 +431,20 @@ const OrganizationUnits = () => {
|
|||
<div className="file-actions">
|
||||
<div className="flex gap-1 folderFileActions">
|
||||
<Button
|
||||
icon={<FaUserPlus size="20" color="#2d6da3" />}
|
||||
onClick={() => setIsMoveAllUsersOpen(true)}
|
||||
title={translate('::Abp.Identity.OrganizationUnit.MoveAllUsers')}
|
||||
>
|
||||
<FaUserPlus size="20" color="#2d6da3" />
|
||||
</Button>
|
||||
></Button>
|
||||
<Button
|
||||
icon={<FaEdit size="20" className="text-teal-900" />}
|
||||
onClick={() => node.edit()}
|
||||
title={translate('::Abp.Identity.OrganizationUnit.Rename')}
|
||||
>
|
||||
<FaEdit size="20" className="text-teal-900" />
|
||||
</Button>
|
||||
></Button>
|
||||
<Button
|
||||
icon={<FaTrashAlt size="20" color="#d9534f" />}
|
||||
onClick={() => setDeleteRow({ id: node.data.id, name: 'Organization Unit' })}
|
||||
title={translate('::Delete')}
|
||||
>
|
||||
<FaTrashAlt size="20" className="text-red-500" />
|
||||
</Button>
|
||||
></Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -472,6 +469,7 @@ const OrganizationUnits = () => {
|
|||
<Button
|
||||
variant="solid"
|
||||
size="sm"
|
||||
icon={activeOu ? <FaSitemap /> : <FaCogs />}
|
||||
title={translate('::Abp.Identity.OrganizationUnit.AddUnit')}
|
||||
onClick={(e) => {
|
||||
e.preventDefault()
|
||||
|
|
@ -480,21 +478,18 @@ const OrganizationUnits = () => {
|
|||
displayName: '',
|
||||
})
|
||||
}}
|
||||
>
|
||||
{activeOu ? <FaSitemap /> : <FaCogs />}
|
||||
</Button>
|
||||
></Button>
|
||||
|
||||
<Button
|
||||
variant="solid"
|
||||
size="sm"
|
||||
icon={<FaUsers />}
|
||||
title={translate('::Abp.Identity.OrganizationUnit.MoveAllUsers')}
|
||||
onClick={(e) => {
|
||||
e.preventDefault()
|
||||
setIsMoveAllUsersOpen(true)
|
||||
}}
|
||||
>
|
||||
<FaUsers />
|
||||
</Button>
|
||||
></Button>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
|
|
@ -548,14 +543,13 @@ const OrganizationUnits = () => {
|
|||
<Button
|
||||
variant="solid"
|
||||
size="sm"
|
||||
icon={<FaUserPlus />}
|
||||
onClick={async (e) => {
|
||||
e.preventDefault()
|
||||
const response = await getUsers(0, 1000)
|
||||
setUserSelectionList(response.data?.items ?? [])
|
||||
}}
|
||||
>
|
||||
<FaUserPlus />
|
||||
</Button>
|
||||
></Button>
|
||||
}
|
||||
>
|
||||
<Table compact>
|
||||
|
|
@ -576,6 +570,7 @@ const OrganizationUnits = () => {
|
|||
<Button
|
||||
className="mr-auto"
|
||||
type="button"
|
||||
icon={<FaTrash />}
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
setDeleteRow({
|
||||
|
|
@ -583,9 +578,7 @@ const OrganizationUnits = () => {
|
|||
name: 'User',
|
||||
})
|
||||
}}
|
||||
>
|
||||
<FaTrash />
|
||||
</Button>
|
||||
></Button>
|
||||
</Td>
|
||||
<Td>
|
||||
<ActionLink
|
||||
|
|
@ -621,14 +614,13 @@ const OrganizationUnits = () => {
|
|||
<Button
|
||||
variant="solid"
|
||||
size="sm"
|
||||
icon={<FaUserPlus />}
|
||||
onClick={async (e) => {
|
||||
e.preventDefault()
|
||||
const response = await getRoles(0, 1000)
|
||||
setRoleSelectionList(response.data?.items ?? [])
|
||||
}}
|
||||
>
|
||||
<FaUserPlus />
|
||||
</Button>
|
||||
></Button>
|
||||
}
|
||||
>
|
||||
<Table compact>
|
||||
|
|
@ -648,15 +640,14 @@ const OrganizationUnits = () => {
|
|||
className="mr-auto"
|
||||
type="button"
|
||||
size="sm"
|
||||
icon={<FaTrash />}
|
||||
onClick={() => {
|
||||
setDeleteRow({
|
||||
id: role.id ?? '',
|
||||
name: 'Role',
|
||||
})
|
||||
}}
|
||||
>
|
||||
<FaTrash />
|
||||
</Button>
|
||||
></Button>
|
||||
</Td>
|
||||
<Td>{role.name}</Td>
|
||||
</Tr>
|
||||
|
|
|
|||
|
|
@ -117,7 +117,6 @@ const NotificationSettings = () => {
|
|||
checked={list[m][n].isActive}
|
||||
onChange={(e) => onClickCheckbox(e, list[m][n])}
|
||||
color={list[m][n].isCustomized ? 'red-500' : undefined}
|
||||
title={list[m][n].id}
|
||||
></Checkbox>
|
||||
</Td>
|
||||
))}
|
||||
|
|
|
|||
|
|
@ -296,11 +296,11 @@ const RoomList: React.FC = () => {
|
|||
{user.role === 'teacher' && (
|
||||
<Button
|
||||
size="sm"
|
||||
icon={<FaPlus size={15} />}
|
||||
variant="solid"
|
||||
onClick={() => setShowCreateModal(true)}
|
||||
className="flex items-center justify-center space-x-2 text-indigo-500 hover:bg-indigo-50 dark:hover:bg-indigo-900/20"
|
||||
>
|
||||
<FaPlus size={15} />
|
||||
<span>{translate('::App.Videoroom.NewRoom')}</span>
|
||||
</Button>
|
||||
)}
|
||||
|
|
@ -419,12 +419,12 @@ const RoomList: React.FC = () => {
|
|||
size="sm"
|
||||
variant="solid"
|
||||
color="red-600"
|
||||
icon={<FaPlay size={11} />}
|
||||
className="flex items-center gap-1"
|
||||
onClick={() => handlePlanningClass(classSession)}
|
||||
disabled={!!classSession.actualStartTime}
|
||||
title={translate('::App.Videoroom.Planning') || 'Planning'}
|
||||
>
|
||||
<FaUsers size={11} />
|
||||
<span className="hidden sm:inline">
|
||||
{translate('::App.Videoroom.Planning') || 'Planning'}
|
||||
</span>
|
||||
|
|
@ -434,12 +434,12 @@ const RoomList: React.FC = () => {
|
|||
size="sm"
|
||||
variant="solid"
|
||||
color="orange-600"
|
||||
icon={<FaEdit size={11} />}
|
||||
className="flex items-center gap-1"
|
||||
onClick={() => openEditModal(classSession)}
|
||||
disabled={!!classSession.actualStartTime}
|
||||
title={translate('::App.Platform.Edit')}
|
||||
>
|
||||
<FaEdit size={11} />
|
||||
<span className="hidden sm:inline">
|
||||
{translate('::App.Platform.Edit')}
|
||||
</span>
|
||||
|
|
@ -449,12 +449,13 @@ const RoomList: React.FC = () => {
|
|||
size="sm"
|
||||
variant="solid"
|
||||
color="sky-800"
|
||||
icon={<FaTrash size={11} />}
|
||||
className="flex items-center gap-1"
|
||||
onClick={() => openDeleteModal(classSession)}
|
||||
disabled={!!classSession.actualStartTime}
|
||||
title={translate('::App.Platform.Delete')}
|
||||
>
|
||||
<FaTrash size={11} />
|
||||
|
||||
<span className="hidden sm:inline">
|
||||
{translate('::App.Platform.Delete')}
|
||||
</span>
|
||||
|
|
@ -465,12 +466,13 @@ const RoomList: React.FC = () => {
|
|||
<Button
|
||||
size="sm"
|
||||
variant="solid"
|
||||
icon={<FaPlay size={10} />}
|
||||
onClick={event}
|
||||
className="flex items-center gap-1"
|
||||
color="emerald-600"
|
||||
disabled={status === 'Katılıma Açık' ? true : false}
|
||||
>
|
||||
<FaPlay size={10} />
|
||||
|
||||
{title}
|
||||
</Button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -346,12 +346,13 @@ export const NoteList: React.FC<NoteListProps> = ({
|
|||
<Button
|
||||
variant="solid"
|
||||
size="sm"
|
||||
icon={<FaPlus className="mr-1" />}
|
||||
type="button"
|
||||
onClick={onAddNote}
|
||||
disabled={!onAddNote}
|
||||
className="flex items-center"
|
||||
>
|
||||
<FaPlus className="mr-1" /> {translate('::ListForms.ListForm.AddNote')}
|
||||
{translate('::ListForms.ListForm.AddNote')}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
|
|
@ -401,12 +402,11 @@ export const NoteList: React.FC<NoteListProps> = ({
|
|||
<Button
|
||||
variant="plain"
|
||||
size="sm"
|
||||
icon={<FaTrash />}
|
||||
onClick={() => onDeleteNote?.(note.id as string)}
|
||||
title={translate('::Delete')}
|
||||
className="text-red-400 hover:text-red-600"
|
||||
>
|
||||
<FaTrash />
|
||||
</Button>
|
||||
></Button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
|
|
@ -431,12 +431,11 @@ export const NoteList: React.FC<NoteListProps> = ({
|
|||
<Button
|
||||
variant="plain"
|
||||
size="sm"
|
||||
icon={<FaDownload />}
|
||||
onClick={() => onDownloadFile?.(file)}
|
||||
title={translate('::Download')}
|
||||
className="text-blue-500 hover:text-blue-700 ml-1"
|
||||
>
|
||||
<FaDownload />
|
||||
</Button>
|
||||
></Button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
|
@ -455,11 +454,12 @@ export const NoteList: React.FC<NoteListProps> = ({
|
|||
size="sm"
|
||||
variant="default"
|
||||
type="button"
|
||||
icon={<FaSyncAlt className="mr-1" />}
|
||||
onClick={loadAuditLogs}
|
||||
disabled={auditLoading}
|
||||
className="flex items-center"
|
||||
>
|
||||
<FaSyncAlt className="mr-1" /> {translate('::ListForms.ListForm.Refresh')}
|
||||
{translate('::ListForms.ListForm.Refresh')}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -70,7 +70,8 @@ export const NoteModal: React.FC<NoteModalProps> = ({
|
|||
const beforeUpload = (files: FileList | null) => {
|
||||
if (!files) return true
|
||||
for (const f of Array.from(files)) {
|
||||
if (f.size > 2 * 1024 * 1024) return translate('::ListForms.ListForm.NoteModal.Upload.MaxSize2Mb')
|
||||
if (f.size > 2 * 1024 * 1024)
|
||||
return translate('::ListForms.ListForm.NoteModal.Upload.MaxSize2Mb')
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
|
@ -101,10 +102,7 @@ export const NoteModal: React.FC<NoteModalProps> = ({
|
|||
<Form>
|
||||
<FormContainer size="sm">
|
||||
{/* NOT TİPİ */}
|
||||
<FormItem
|
||||
invalid={!!(errors.type && touched.type)}
|
||||
errorMessage={errors.type}
|
||||
>
|
||||
<FormItem invalid={!!(errors.type && touched.type)} errorMessage={errors.type}>
|
||||
<div className="flex gap-2">
|
||||
{types.map((t) => (
|
||||
<label
|
||||
|
|
@ -246,12 +244,11 @@ export const NoteModal: React.FC<NoteModalProps> = ({
|
|||
<Button
|
||||
variant="plain"
|
||||
size="sm"
|
||||
icon={<FaTrash />}
|
||||
type="button"
|
||||
onClick={() => removeFile(index)}
|
||||
className="text-red-500 hover:text-red-700"
|
||||
>
|
||||
<FaTrash />
|
||||
</Button>
|
||||
></Button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -164,9 +164,13 @@ export const NotePanel: React.FC<NotePanelProps> = ({
|
|||
</div>
|
||||
|
||||
<div className="flex items-center gap-3">
|
||||
<Button variant="plain" size="sm" onClick={onToggle} title="Paneli kapat">
|
||||
<FaTimes />
|
||||
</Button>
|
||||
<Button
|
||||
variant="plain"
|
||||
icon={<FaTimes />}
|
||||
size="sm"
|
||||
onClick={onToggle}
|
||||
title="Paneli kapat"
|
||||
></Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -167,11 +167,11 @@ export function CategoryManagement({
|
|||
</h2>
|
||||
<Button
|
||||
variant="solid"
|
||||
icon={<FaPlus className="w-4 h-4" />}
|
||||
onClick={() => setShowCreateForm(true)}
|
||||
disabled={loading}
|
||||
className="flex items-center space-x-2 bg-blue-600 px-4 py-2 rounded-lg hover:bg-blue-700 transition-colors disabled:opacity-50"
|
||||
>
|
||||
<FaPlus className="w-4 h-4" />
|
||||
<span>{translate('::App.Forum.CategoryManagement.AddCategory')}</span>
|
||||
</Button>
|
||||
</div>
|
||||
|
|
@ -369,7 +369,14 @@ export function CategoryManagement({
|
|||
|
||||
<div className="flex items-center space-x-2">
|
||||
<Button
|
||||
size='xs'
|
||||
size="xs"
|
||||
icon={
|
||||
category.isActive ? (
|
||||
<FaEye className="w-4 h-4" />
|
||||
) : (
|
||||
<FaEyeSlash className="w-4 h-4" />
|
||||
)
|
||||
}
|
||||
onClick={() => handleToggleActive(category)}
|
||||
className={`p-2 rounded-lg transition-colors ${
|
||||
category.isActive
|
||||
|
|
@ -377,16 +384,10 @@ export function CategoryManagement({
|
|||
: 'text-red-600 hover:bg-red-100'
|
||||
}`}
|
||||
title={category.isActive ? 'Hide Category' : 'Show Category'}
|
||||
>
|
||||
{category.isActive ? (
|
||||
<FaEye className="w-4 h-4" />
|
||||
) : (
|
||||
<FaEyeSlash className="w-4 h-4" />
|
||||
)}
|
||||
</Button>
|
||||
></Button>
|
||||
|
||||
<Button
|
||||
size='xs'
|
||||
size="xs"
|
||||
onClick={() => handleToggleLocked(category)}
|
||||
className={`p-2 rounded-lg transition-colors ${
|
||||
category.isLocked
|
||||
|
|
@ -394,31 +395,30 @@ export function CategoryManagement({
|
|||
: 'text-green-600 hover:bg-green-100'
|
||||
}`}
|
||||
title={category.isLocked ? 'Unlock Category' : 'Lock Category'}
|
||||
>
|
||||
{category.isLocked ? (
|
||||
<FaLock className="w-4 h-4" />
|
||||
) : (
|
||||
<FaUnlock className="w-4 h-4" />
|
||||
)}
|
||||
</Button>
|
||||
icon={
|
||||
category.isLocked ? (
|
||||
<FaLock className="w-4 h-4" />
|
||||
) : (
|
||||
<FaUnlock className="w-4 h-4" />
|
||||
)
|
||||
}
|
||||
></Button>
|
||||
|
||||
<Button
|
||||
size='xs'
|
||||
size="xs"
|
||||
onClick={() => handleEdit(category)}
|
||||
className="p-2 text-blue-600 hover:bg-blue-100 rounded-lg transition-colors"
|
||||
title={translate('::App.Forum.CategoryManagement.EditCategory')}
|
||||
>
|
||||
<FaEdit className="w-4 h-4" />
|
||||
</Button>
|
||||
icon={<FaEdit className="w-4 h-4" />}
|
||||
></Button>
|
||||
|
||||
<Button
|
||||
size='xs'
|
||||
size="xs"
|
||||
onClick={() => confirmDeleteCategory(category)}
|
||||
className="p-2 text-red-600 hover:bg-red-100 rounded-lg transition-colors"
|
||||
title={translate('::App.Forum.CategoryManagement.DeleteCategory')}
|
||||
>
|
||||
<FaTrash className="w-4 h-4" />
|
||||
</Button>
|
||||
icon={<FaTrash className="w-4 h-4" />}
|
||||
></Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -165,12 +165,12 @@ export function PostManagement({
|
|||
{translate('::App.Forum.PostManagement.Title')}
|
||||
</h2>
|
||||
<Button
|
||||
icon={<FaPlus className="w-4 h-4" />}
|
||||
variant="solid"
|
||||
onClick={() => setShowCreateForm(true)}
|
||||
disabled={loading}
|
||||
className="flex items-center space-x-2 bg-blue-600 px-4 py-2 rounded-lg hover:bg-blue-700 transition-colors disabled:opacity-50"
|
||||
>
|
||||
<FaPlus className="w-4 h-4" />
|
||||
<span>{translate('::App.Forum.PostManagement.AddPost')}</span>
|
||||
</Button>
|
||||
</div>
|
||||
|
|
@ -399,6 +399,13 @@ export function PostManagement({
|
|||
|
||||
<div className="flex items-center space-x-2 ml-4">
|
||||
<Button
|
||||
icon={
|
||||
post.isAcceptedAnswer ? (
|
||||
<FaCheckCircle className="w-4 h-4" />
|
||||
) : (
|
||||
<FaCircle className="w-4 h-4" />
|
||||
)
|
||||
}
|
||||
onClick={() => handleToggleAcceptedAnswer(post)}
|
||||
className={`p-2 rounded-lg transition-colors ${
|
||||
post.isAcceptedAnswer
|
||||
|
|
@ -410,28 +417,24 @@ export function PostManagement({
|
|||
? 'Remove Accepted Answer'
|
||||
: 'Mark as Accepted Answer'
|
||||
}
|
||||
>
|
||||
{post.isAcceptedAnswer ? (
|
||||
<FaCheckCircle className="w-4 h-4" />
|
||||
) : (
|
||||
<FaCircle className="w-4 h-4" />
|
||||
)}
|
||||
</Button>
|
||||
></Button>
|
||||
|
||||
<Button
|
||||
icon={<FaEdit className="w-4 h-4" />}
|
||||
onClick={() => handleEdit(post)}
|
||||
className="p-2 text-blue-600 hover:bg-blue-100 rounded-lg transition-colors"
|
||||
title={translate('::App.Forum.PostManagement.EditPost')}
|
||||
>
|
||||
<FaEdit className="w-4 h-4" />
|
||||
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
icon={<FaTrashAlt className="w-4 h-4" />}
|
||||
onClick={() => confirmDeletePost(post)}
|
||||
className="p-2 text-red-600 hover:bg-red-100 rounded-lg transition-colors"
|
||||
title={translate('::App.Forum.PostManagement.DeletePost')}
|
||||
>
|
||||
<FaTrashAlt className="w-4 h-4" />
|
||||
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -208,11 +208,11 @@ export function TopicManagement({
|
|||
</h2>
|
||||
<Button
|
||||
variant="solid"
|
||||
icon={<FaPlus className="w-4 h-4" />}
|
||||
onClick={() => setShowCreateForm(true)}
|
||||
disabled={loading}
|
||||
className="flex items-center space-x-2 bg-blue-600 px-4 py-2 rounded-lg hover:bg-blue-700 transition-colors disabled:opacity-50"
|
||||
>
|
||||
<FaPlus className="w-4 h-4" />
|
||||
<span>{translate('::App.Forum.TopicManagement.AddTopic')}</span>
|
||||
</Button>
|
||||
</div>
|
||||
|
|
@ -400,6 +400,13 @@ export function TopicManagement({
|
|||
|
||||
<div className="flex items-center space-x-2 ml-4">
|
||||
<Button
|
||||
icon={
|
||||
topic.isPinned ? (
|
||||
<FaThumbtack className="w-4 h-4" />
|
||||
) : (
|
||||
<FaTree className="w-4 h-4" />
|
||||
)
|
||||
}
|
||||
onClick={() => handlePin(topic)}
|
||||
className={`p-2 rounded-lg transition-colors ${
|
||||
topic.isPinned
|
||||
|
|
@ -407,15 +414,16 @@ export function TopicManagement({
|
|||
: 'text-gray-400 hover:bg-gray-100'
|
||||
}`}
|
||||
title={topic.isPinned ? 'Unpin Topic' : 'Pin Topic'}
|
||||
>
|
||||
{topic.isPinned ? (
|
||||
<FaThumbtack className="w-4 h-4" />
|
||||
) : (
|
||||
<FaTree className="w-4 h-4" />
|
||||
)}
|
||||
</Button>
|
||||
></Button>
|
||||
|
||||
<Button
|
||||
icon={
|
||||
topic.isLocked ? (
|
||||
<FaLock className="w-4 h-4" />
|
||||
) : (
|
||||
<FaUnlock className="w-4 h-4" />
|
||||
)
|
||||
}
|
||||
onClick={() => handleLock(topic)}
|
||||
className={`p-2 rounded-lg transition-colors ${
|
||||
topic.isLocked
|
||||
|
|
@ -423,15 +431,16 @@ export function TopicManagement({
|
|||
: 'text-green-600 hover:bg-green-100'
|
||||
}`}
|
||||
title={topic.isLocked ? 'Unlock Topic' : 'Lock Topic'}
|
||||
>
|
||||
{topic.isLocked ? (
|
||||
<FaLock className="w-4 h-4" />
|
||||
) : (
|
||||
<FaUnlock className="w-4 h-4" />
|
||||
)}
|
||||
</Button>
|
||||
></Button>
|
||||
|
||||
<Button
|
||||
icon={
|
||||
topic.isSolved ? (
|
||||
<FaCheckCircle className="w-4 h-4" />
|
||||
) : (
|
||||
<FaCircle className="w-4 h-4" />
|
||||
)
|
||||
}
|
||||
onClick={() => handleSolved(topic)}
|
||||
className={`p-2 rounded-lg transition-colors ${
|
||||
topic.isSolved
|
||||
|
|
@ -439,29 +448,21 @@ export function TopicManagement({
|
|||
: 'text-gray-400 hover:bg-gray-100'
|
||||
}`}
|
||||
title={topic.isSolved ? 'Mark as Unsolved' : 'Mark as Solved'}
|
||||
>
|
||||
{topic.isSolved ? (
|
||||
<FaCheckCircle className="w-4 h-4" />
|
||||
) : (
|
||||
<FaCircle className="w-4 h-4" />
|
||||
)}
|
||||
</Button>
|
||||
></Button>
|
||||
|
||||
<Button
|
||||
icon={<FaEdit className="w-4 h-4" />}
|
||||
onClick={() => handleEdit(topic)}
|
||||
className="p-2 text-blue-600 hover:bg-blue-100 rounded-lg transition-colors"
|
||||
title={translate('::App.Forum.TopicManagement.EditTopic')}
|
||||
>
|
||||
<FaEdit className="w-4 h-4" />
|
||||
</Button>
|
||||
></Button>
|
||||
|
||||
<Button
|
||||
icon={<FaTrashAlt className="w-4 h-4" />}
|
||||
onClick={() => confirmDeleteTopic(topic)}
|
||||
className="p-2 text-red-600 hover:bg-red-100 rounded-lg transition-colors"
|
||||
title={translate('::App.Forum.TopicManagement.DeleteTopic')}
|
||||
>
|
||||
<FaTrashAlt className="w-4 h-4" />
|
||||
</Button>
|
||||
></Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -354,44 +354,43 @@ export function ForumView({
|
|||
<div className="flex items-center space-x-2 ml-auto">
|
||||
{viewState === 'topics' && selectedCategory && !selectedCategory.isLocked && (
|
||||
<Button
|
||||
variant='solid'
|
||||
icon={<FaPlus className="w-4 h-4" />}
|
||||
variant="solid"
|
||||
onClick={() => setShowCreateTopic(true)}
|
||||
className="flex items-center space-x-2 bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700 transition-colors"
|
||||
>
|
||||
<FaPlus className="w-4 h-4" />
|
||||
<span>{translate('::App.Forum.TopicManagement.NewTopic')}</span>
|
||||
</Button>
|
||||
)}
|
||||
{viewState === 'posts' && selectedTopic && !selectedTopic.isLocked && (
|
||||
<Button
|
||||
variant='solid'
|
||||
icon={<FaPlus className="w-4 h-4" />}
|
||||
variant="solid"
|
||||
onClick={() => setShowCreatePost(true)}
|
||||
className="flex items-center space-x-2 bg-emerald-600 text-white px-4 py-2 rounded-lg hover:bg-emerald-700 transition-colors"
|
||||
>
|
||||
<FaPlus className="w-4 h-4" />
|
||||
<span>{translate('::App.Forum.PostManagement.NewPost')}</span>
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{/* Search */}
|
||||
<Button
|
||||
icon={<FaSearch className="w-4 h-4" />}
|
||||
onClick={() => setIsSearchModalOpen(true)}
|
||||
variant='default'
|
||||
variant="default"
|
||||
className="hidden md:flex items-center space-x-2 px-4 py-2 border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors"
|
||||
>
|
||||
<FaSearch className="w-4 h-4 text-gray-400" />
|
||||
<span className="text-gray-500">
|
||||
{translate('::App.Forum.TopicManagement.Searchtopics')}
|
||||
</span>
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
icon={<FaSearch className="w-5 h-5" />}
|
||||
onClick={() => setIsSearchModalOpen(true)}
|
||||
variant='default'
|
||||
variant="default"
|
||||
className="md:hidden p-2 text-gray-400 hover:text-gray-600 transition-colors"
|
||||
>
|
||||
<FaSearch className="w-5 h-5" />
|
||||
</Button>
|
||||
></Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -60,10 +60,10 @@ const Chart = (props: ChartProps) => {
|
|||
|
||||
const [openDrawer, setOpenDrawer] = useState(false)
|
||||
const [fieldList, setFieldList] = useState<SelectBoxOption[]>([])
|
||||
|
||||
|
||||
// Ana state - Chart bu state'e göre render edilir
|
||||
const [currentSeries, setCurrentSeries] = useState<ChartSeriesDto[]>([])
|
||||
|
||||
|
||||
// Veritabanından gelen orijinal seriler (kaydetme işlemi için)
|
||||
const [savedSeries, setSavedSeries] = useState<ChartSeriesDto[]>([])
|
||||
|
||||
|
|
@ -81,10 +81,10 @@ const Chart = (props: ChartProps) => {
|
|||
const userSeriesData = initialSeries.filter((s) => s.userId === userName)
|
||||
|
||||
setAllSeries(initialSeries)
|
||||
|
||||
|
||||
// Kullanıcının serisi varsa onu kullan, yoksa tüm serileri kullan
|
||||
const seriesToUse = userSeriesData.length > 0 ? userSeriesData : initialSeries
|
||||
|
||||
|
||||
// Sadece ilk yüklemede VEYA refresh sonrası güncelle
|
||||
if (!initialized) {
|
||||
setCurrentSeries(seriesToUse)
|
||||
|
|
@ -128,9 +128,9 @@ const Chart = (props: ChartProps) => {
|
|||
title: gridDto.gridOptions.titleDto,
|
||||
size: gridDto.gridOptions.sizeDto?.useSize
|
||||
? { width: gridDto.gridOptions.sizeDto.width, height: gridDto.gridOptions.sizeDto.height }
|
||||
: {
|
||||
width: openDrawer ? window.innerWidth - 550 : '100%',
|
||||
height: window.innerHeight - 210
|
||||
: {
|
||||
width: openDrawer ? window.innerWidth - 550 : '100%',
|
||||
height: window.innerHeight - 210,
|
||||
},
|
||||
legend: gridDto.gridOptions.legendDto || {
|
||||
visible: true,
|
||||
|
|
@ -167,7 +167,15 @@ const Chart = (props: ChartProps) => {
|
|||
enabled: true,
|
||||
},
|
||||
}
|
||||
}, [gridDto, currentSeries, initialized, createSelectDataSource, listFormCode, urlSearchParams, openDrawer])
|
||||
}, [
|
||||
gridDto,
|
||||
currentSeries,
|
||||
initialized,
|
||||
createSelectDataSource,
|
||||
listFormCode,
|
||||
urlSearchParams,
|
||||
openDrawer,
|
||||
])
|
||||
|
||||
useEffect(() => {
|
||||
if (memoizedChartOptions) {
|
||||
|
|
@ -231,13 +239,15 @@ const Chart = (props: ChartProps) => {
|
|||
})
|
||||
if (resp.data?.items) {
|
||||
const fieldNames = groupBy(resp?.data?.items, 'fieldName')
|
||||
setFieldList(Object.keys(fieldNames).map((fieldName) => {
|
||||
const firstItem = fieldNames[fieldName][0]
|
||||
const label = firstItem.captionName
|
||||
? translate('::' + firstItem.captionName)
|
||||
: fieldName
|
||||
return { value: fieldName, label }
|
||||
}))
|
||||
setFieldList(
|
||||
Object.keys(fieldNames).map((fieldName) => {
|
||||
const firstItem = fieldNames[fieldName][0]
|
||||
const label = firstItem.captionName
|
||||
? translate('::' + firstItem.captionName)
|
||||
: fieldName
|
||||
return { value: fieldName, label }
|
||||
}),
|
||||
)
|
||||
}
|
||||
} catch (error: any) {
|
||||
toast.push(
|
||||
|
|
@ -264,43 +274,48 @@ const Chart = (props: ChartProps) => {
|
|||
setCurrentSeries(savedSeries)
|
||||
}, [savedSeries])
|
||||
|
||||
const onSave = useCallback(async (newSeries: ChartSeriesDto[]) => {
|
||||
// 1. Silinecek serileri bul (savedSeries var ama newSeries yok)
|
||||
const toDelete = savedSeries.filter((old: ChartSeriesDto) => !newSeries.some((s) => s.index === old.index))
|
||||
const onSave = useCallback(
|
||||
async (newSeries: ChartSeriesDto[]) => {
|
||||
// 1. Silinecek serileri bul (savedSeries var ama newSeries yok)
|
||||
const toDelete = savedSeries.filter(
|
||||
(old: ChartSeriesDto) => !newSeries.some((s) => s.index === old.index),
|
||||
)
|
||||
|
||||
// Index kaymasını önlemek için büyükten küçüğe sırala
|
||||
toDelete.sort((a: ChartSeriesDto, b: ChartSeriesDto) => b.index - a.index)
|
||||
// Index kaymasını önlemek için büyükten küçüğe sırala
|
||||
toDelete.sort((a: ChartSeriesDto, b: ChartSeriesDto) => b.index - a.index)
|
||||
|
||||
for (const old of toDelete) {
|
||||
await deleteListFormJsonRow(id, ListFormEditTabs.ChartSeries.GeneralJsonRow, old.index)
|
||||
}
|
||||
|
||||
// 2. Yeni veya güncellenen serileri kaydet
|
||||
for (const series of newSeries) {
|
||||
const input: ListFormJsonRowDto = {
|
||||
index: series.index,
|
||||
fieldName: ListFormEditTabs.ChartSeries.GeneralJsonRow,
|
||||
itemChartSeries: series,
|
||||
for (const old of toDelete) {
|
||||
await deleteListFormJsonRow(id, ListFormEditTabs.ChartSeries.GeneralJsonRow, old.index)
|
||||
}
|
||||
|
||||
if (series.index === -1) {
|
||||
await postListFormJsonRow(id, input)
|
||||
// 2. Yeni veya güncellenen serileri kaydet
|
||||
for (const series of newSeries) {
|
||||
const input: ListFormJsonRowDto = {
|
||||
index: series.index,
|
||||
fieldName: ListFormEditTabs.ChartSeries.GeneralJsonRow,
|
||||
itemChartSeries: series,
|
||||
}
|
||||
|
||||
if (series.index === -1) {
|
||||
await postListFormJsonRow(id, input)
|
||||
} else {
|
||||
await putListFormJsonRow(id, input)
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Yeniden yükle (veritabanından fresh data)
|
||||
if (props.refreshGridDto) {
|
||||
setInitialized(false)
|
||||
await props.refreshGridDto()
|
||||
// refreshGridDto tamamlandıktan sonra yeni state'ler otomatik setlenecek
|
||||
} else {
|
||||
await putListFormJsonRow(id, input)
|
||||
// refreshGridDto yoksa manuel güncelle
|
||||
setSavedSeries(newSeries)
|
||||
setCurrentSeries(newSeries)
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Yeniden yükle (veritabanından fresh data)
|
||||
if (props.refreshGridDto) {
|
||||
setInitialized(false)
|
||||
await props.refreshGridDto()
|
||||
// refreshGridDto tamamlandıktan sonra yeni state'ler otomatik setlenecek
|
||||
} else {
|
||||
// refreshGridDto yoksa manuel güncelle
|
||||
setSavedSeries(newSeries)
|
||||
setCurrentSeries(newSeries)
|
||||
}
|
||||
}, [savedSeries, id, props])
|
||||
},
|
||||
[savedSeries, id, props],
|
||||
)
|
||||
|
||||
return (
|
||||
<Container className={DX_CLASSNAMES}>
|
||||
|
|
@ -343,28 +358,31 @@ const Chart = (props: ChartProps) => {
|
|||
<Button
|
||||
size="sm"
|
||||
variant={'default'}
|
||||
icon={<FaSyncAlt className="w-3 h-3" />}
|
||||
className="text-sm flex items-center gap-1"
|
||||
onClick={async () => {
|
||||
setInitialized(false)
|
||||
await refreshGridDto?.()
|
||||
}}
|
||||
title={translate('::App.Platform.Refresh')}
|
||||
title={translate('::App.Platform.Refresh')}
|
||||
>
|
||||
<FaSyncAlt className="w-3 h-3" /> {translate('::App.Platform.Refresh')}
|
||||
{translate('::App.Platform.Refresh')}
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
icon={<FaCrosshairs className="w-3 h-3" />}
|
||||
variant="default"
|
||||
className="text-sm flex items-center gap-1"
|
||||
onClick={() => setOpenDrawer(true)}
|
||||
title={translate('::ListForms.ListFormEdit.TabChartSeries')}
|
||||
>
|
||||
<FaCrosshairs className="w-3 h-3" /> {translate('::ListForms.ListFormEdit.TabChartSeries')}
|
||||
{translate('::ListForms.ListFormEdit.TabChartSeries')}
|
||||
</Button>
|
||||
|
||||
{checkPermission(gridDto?.gridOptions.permissionDto.u) && (
|
||||
<Button
|
||||
size="sm"
|
||||
icon={<FaCog className="w-3 h-3" />}
|
||||
variant={'default'}
|
||||
className="text-sm"
|
||||
onClick={() => {
|
||||
|
|
@ -377,13 +395,11 @@ const Chart = (props: ChartProps) => {
|
|||
)
|
||||
}}
|
||||
title={translate('::ListForms.ListForm.Manage')}
|
||||
>
|
||||
<FaCog className="w-3 h-3" />
|
||||
</Button>
|
||||
></Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
<div
|
||||
className={`transition-all duration-300 ${openDrawer ? 'mr-[500px]' : 'mr-0'}`}
|
||||
style={{ width: openDrawer ? 'calc(100% - 500px)' : '100%' }}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,10 @@ import { Button, FormContainer, Input, Notification, Select, toast } from '@/com
|
|||
import { Field, FieldArray, Form, Formik, FieldProps } from 'formik'
|
||||
import { FaMinus, FaPlus, FaTimes, FaSave } from 'react-icons/fa'
|
||||
import { SelectBoxOption } from '@/types/shared'
|
||||
import { chartSeriesTypeOptions, columnSummaryTypeListOptions } from '../admin/listForm/edit/options'
|
||||
import {
|
||||
chartSeriesTypeOptions,
|
||||
columnSummaryTypeListOptions,
|
||||
} from '../admin/listForm/edit/options'
|
||||
import { ChartSeriesDto } from '@/proxy/admin/charts/models'
|
||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||
import { useStoreState } from '@/store/store'
|
||||
|
|
@ -144,12 +147,11 @@ const ChartDrawer = ({
|
|||
{translate('::App.Platform.ChartDrawer.ChartSeries')}
|
||||
</h2>
|
||||
<Button
|
||||
icon={<FaTimes />}
|
||||
type="button"
|
||||
onClick={onClose}
|
||||
className="p-2 hover:bg-gray-200 rounded-full transition-colors"
|
||||
>
|
||||
<FaTimes />
|
||||
</Button>
|
||||
></Button>
|
||||
</div>
|
||||
|
||||
<FormContainer size="sm" className="flex flex-col flex-1 overflow-hidden">
|
||||
|
|
@ -159,13 +161,14 @@ const ChartDrawer = ({
|
|||
variant="solid"
|
||||
type="button"
|
||||
size="sm"
|
||||
icon={<FaPlus />}
|
||||
onClick={() => {
|
||||
setFieldValue('series', [...values.series, newSeriesValue()])
|
||||
}}
|
||||
className="w-full"
|
||||
>
|
||||
<div className="flex items-center justify-center gap-2">
|
||||
<FaPlus /> {translate('::App.Platform.ChartDrawer.AddNewSeries')}
|
||||
{translate('::App.Platform.ChartDrawer.AddNewSeries')}
|
||||
</div>
|
||||
</Button>
|
||||
</div>
|
||||
|
|
@ -215,12 +218,14 @@ const ChartDrawer = ({
|
|||
className="w-full px-3 py-2 text-left border rounded hover:bg-white flex items-center gap-2 transition-colors"
|
||||
>
|
||||
<span className="text-xl">
|
||||
{chartSeriesTypeOptions.find((t) => t.label === field.value)
|
||||
?.icon || '📊'}
|
||||
{chartSeriesTypeOptions.find(
|
||||
(t) => t.label === field.value,
|
||||
)?.icon || '📊'}
|
||||
</span>
|
||||
<span className="text-sm font-medium">
|
||||
{chartSeriesTypeOptions.find((t) => t.label === field.value)
|
||||
?.label || field.value}
|
||||
{chartSeriesTypeOptions.find(
|
||||
(t) => t.label === field.value,
|
||||
)?.label || field.value}
|
||||
</span>
|
||||
</Button>
|
||||
{selectedSeriesIndex === index && (
|
||||
|
|
@ -354,9 +359,14 @@ const ChartDrawer = ({
|
|||
<Button type="button" variant="plain" onClick={onClose} className="flex-1">
|
||||
{translate('::Cancel')}
|
||||
</Button>
|
||||
<Button variant="solid" loading={isSubmitting} type="submit" className="flex-1">
|
||||
<Button
|
||||
icon={<FaSave />}
|
||||
variant="solid"
|
||||
loading={isSubmitting}
|
||||
type="submit"
|
||||
className="flex-1"
|
||||
>
|
||||
<div className="flex items-center justify-center gap-2">
|
||||
<FaSave />
|
||||
{isSubmitting
|
||||
? translate('::SavingWithThreeDot')
|
||||
: translate('::App.Platform.ChartDrawer.Save')}
|
||||
|
|
|
|||
|
|
@ -161,11 +161,11 @@ const List: React.FC = () => {
|
|||
gridDto?.gridOptions?.schedulerOptionDto?.startDateExpr && (
|
||||
<Button
|
||||
size="sm"
|
||||
icon={<FaCalendarAlt />}
|
||||
variant={viewMode === 'scheduler' ? 'solid' : 'default'}
|
||||
onClick={() => setLayout('scheduler')}
|
||||
onMouseEnter={() => preload.scheduler()}
|
||||
>
|
||||
<FaCalendarAlt />
|
||||
</Button>
|
||||
)}
|
||||
|
||||
|
|
@ -174,11 +174,11 @@ const List: React.FC = () => {
|
|||
gridDto?.gridOptions?.ganttOptionDto?.titleExpr && (
|
||||
<Button
|
||||
size="sm"
|
||||
icon={<FaProjectDiagram />}
|
||||
variant={viewMode === 'gantt' ? 'solid' : 'default'}
|
||||
onClick={() => setLayout('gantt')}
|
||||
onMouseEnter={() => preload.gantt()}
|
||||
>
|
||||
<FaProjectDiagram />
|
||||
</Button>
|
||||
)}
|
||||
|
||||
|
|
@ -186,42 +186,42 @@ const List: React.FC = () => {
|
|||
gridDto?.gridOptions?.treeOptionDto?.parentIdExpr && (
|
||||
<Button
|
||||
size="sm"
|
||||
icon={<FaSitemap />}
|
||||
variant={viewMode === 'tree' ? 'solid' : 'default'}
|
||||
onClick={() => setLayout('tree')}
|
||||
onMouseEnter={() => preload.tree()}
|
||||
>
|
||||
<FaSitemap />
|
||||
</Button>
|
||||
)}
|
||||
|
||||
<Button
|
||||
size="sm"
|
||||
icon={<FaList />}
|
||||
variant={viewMode === 'grid' ? 'solid' : 'default'}
|
||||
onClick={() => setLayout('grid')}
|
||||
onMouseEnter={() => preload.grid()}
|
||||
>
|
||||
<FaList />
|
||||
</Button>
|
||||
|
||||
{gridDto.gridOptions.layoutDto.pivot && (
|
||||
<Button
|
||||
size="sm"
|
||||
icon={<FaTable />}
|
||||
variant={viewMode === 'pivot' ? 'solid' : 'default'}
|
||||
onClick={() => setLayout('pivot')}
|
||||
onMouseEnter={() => preload.pivot()}
|
||||
>
|
||||
<FaTable />
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{gridDto.gridOptions.layoutDto.chart && (
|
||||
<Button
|
||||
size="sm"
|
||||
icon={<FaChartArea />}
|
||||
variant={viewMode === 'chart' ? 'solid' : 'default'}
|
||||
onClick={() => setLayout('chart')}
|
||||
onMouseEnter={() => preload.chart()}
|
||||
>
|
||||
<FaChartArea />
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -434,6 +434,7 @@ const Pivot = (props: PivotProps) => {
|
|||
<Button
|
||||
size="sm"
|
||||
variant={'plain'}
|
||||
icon={<FaCaretDown className="ml-2 w-2 h-3" />}
|
||||
className="text-sm flex items-center gap-1 border-0"
|
||||
title="Menu"
|
||||
>
|
||||
|
|
@ -441,7 +442,6 @@ const Pivot = (props: PivotProps) => {
|
|||
<span className="text-black dark:text-white" style={{ fontSize: '13px' }}>
|
||||
{translate('::ListForms.ListForm.GridMenu')}
|
||||
</span>
|
||||
<FaCaretDown className="ml-2 w-2 h-3" />
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ const NotFound: React.FC = () => {
|
|||
<p className="text-xl text-gray-600 mb-8 text-center max-w-md"> {/* Metin rengi, margin ve max-width güncellendi */}
|
||||
{translate('::Public.notFound.message')}
|
||||
</p>
|
||||
<a href={ROUTES_ENUM.public.home} className="px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition duration-300 text-lg font-semibold"> {/* Buton stili güncellendi */}
|
||||
<a href={ROUTES_ENUM.public.home} className="bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition duration-300 text-lg font-semibold"> {/* Buton stili güncellendi */}
|
||||
{translate('::Public.notFound.button')}
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { useEffect, useRef, useState } from 'react'
|
|||
import { APP_NAME } from '@/constants/app.constant'
|
||||
import { getMigrateUrl, getSetupStatus } from '@/services/setup.service'
|
||||
import { applicationConfigurationUrl } from '@/services/abpConfig.service'
|
||||
import { Button } from '@/components/ui'
|
||||
|
||||
interface LogLine {
|
||||
level: 'info' | 'warn' | 'error' | 'success' | 'restart' | 'done'
|
||||
|
|
@ -248,12 +249,12 @@ const DatabaseSetup = () => {
|
|||
|
||||
<div className="flex gap-3">
|
||||
{(status === 'idle' || status === 'error') && !dbExists && (
|
||||
<button
|
||||
<Button
|
||||
onClick={startMigration}
|
||||
className="px-4 py-2 bg-indigo-600 hover:bg-indigo-500 text-white text-sm font-medium rounded-lg transition-colors"
|
||||
>
|
||||
{status === 'error' ? 'Retry' : 'Start Setup'}
|
||||
</button>
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{status === 'restarting' && (
|
||||
|
|
|
|||
Loading…
Reference in a new issue