TodoBoard -> New Kanban

This commit is contained in:
Sedat ÖZTÜRK 2026-08-21 22:41:01 +03:00
parent 9e362f6671
commit 0d0834efaf

View file

@ -27,7 +27,7 @@ import {
import { useListFormCustomDataSource } from './useListFormCustomDataSource' import { useListFormCustomDataSource } from './useListFormCustomDataSource'
import { useListFormStateStoring } from './useListFormStateStoring' import { useListFormStateStoring } from './useListFormStateStoring'
import { useListFormGridDto } from './shared/hooks' import { useListFormGridDto } from './shared/hooks'
import { Avatar, Rate } from '@/components/ui' import { Avatar, Dialog, Rate } from '@/components/ui'
import { getUsers } from '@/services/identity.service' import { getUsers } from '@/services/identity.service'
import { getTenants } from '@/services/tenant.service' import { getTenants } from '@/services/tenant.service'
import { useLocalization } from '@/utils/hooks/useLocalization' import { useLocalization } from '@/utils/hooks/useLocalization'
@ -432,6 +432,23 @@ const TodoBoardContent = ({
}} }}
/> />
)} )}
{canAdd && (
<ToolbarItem
location="after"
widget="dxButton"
locateInMenu="auto"
showText="always"
options={{
icon: 'plus',
text: translate('::App.ListFormTodoBoard.AddNewColumn'),
hint: translate('::App.ListFormTodoBoard.AddNewColumn'),
onClick: () => {
setIsAddingStatus(true)
setStatusError('')
},
}}
/>
)}
<ToolbarItem <ToolbarItem
location="after" location="after"
widget="dxButton" widget="dxButton"
@ -606,6 +623,12 @@ const TodoBoardContent = ({
setColumnDropTarget(undefined) setColumnDropTarget(undefined)
} }
const closeAddStatus = () => {
setIsAddingStatus(false)
setNewStatusName('')
setStatusError('')
}
const addStatus = () => { const addStatus = () => {
if (!canAdd) return if (!canAdd) return
const nextName = newStatusName.trim() const nextName = newStatusName.trim()
@ -1147,7 +1170,7 @@ const TodoBoardContent = ({
<div className="pb-3"> <div className="pb-3">
{renderToolbar()} {renderToolbar()}
<div className="overflow-x-auto"> <div className="overflow-x-auto">
<div className="flex min-h-[420px] min-w-max gap-3"> <div className="flex min-h-[420px] min-w-max">
{statuses.map((status) => { {statuses.map((status) => {
const items = itemsForStatus(status) const items = itemsForStatus(status)
const isAdding = newTodoStatus === status const isAdding = newTodoStatus === status
@ -1554,95 +1577,53 @@ const TodoBoardContent = ({
) )
})} })}
{canAdd && ( {canAdd && (
<section className="group w-[310px] shrink-0 rounded-xl border-2 border-transparent bg-gray-50 p-2 dark:bg-gray-900/60"> <Dialog
<header className="mb-2 flex min-h-9 items-center gap-2 px-1"> isOpen={isAddingStatus}
<FaGripVertical className="text-gray-300 dark:text-gray-700" /> width={420}
<h3 className="font-semibold text-gray-500 dark:text-gray-400"> onClose={closeAddStatus}
{translate('::App.ListFormTodoBoard.NewColumn')} onRequestClose={closeAddStatus}
</h3> >
<span className="ml-auto rounded-full bg-gray-200 px-2 py-0.5 text-xs text-gray-500 dark:bg-gray-700 dark:text-gray-400"> <h5 className="mb-4">{translate('::App.ListFormTodoBoard.AddNewColumn')}</h5>
0 <form
</span> onSubmit={(event) => {
<button event.preventDefault()
type="button" addStatus()
className="rounded p-1 text-gray-400 hover:bg-blue-100 hover:text-blue-600 dark:hover:bg-blue-950" }}
title={translate('::App.ListFormTodoBoard.AddNewColumn')} >
onClick={() => { <label className="mb-2 block text-sm font-semibold" htmlFor="new-kanban-name">
setIsAddingStatus(true) {translate('::App.ListFormTodoBoard.NewColumnName')}
</label>
<Input
unstyle
autoFocus
id="new-kanban-name"
className="w-full rounded-lg border border-gray-300 bg-white px-3 py-2 text-sm outline-none focus:border-blue-500 focus:ring-2 focus:ring-blue-500/20 dark:border-gray-600 dark:bg-gray-800"
placeholder={translate('::App.ListFormTodoBoard.NewColumnPlaceholder')}
value={newStatusName}
onChange={(event) => {
setNewStatusName(event.target.value)
setStatusError('') setStatusError('')
}} }}
> />
<FaPlus /> {statusError && <p className="mt-2 text-xs text-red-500">{statusError}</p>}
</button> <div className="mt-6 flex justify-end gap-2">
</header>
<div className="h-1 overflow-hidden rounded-full bg-gray-200 dark:bg-gray-700" />
<div className="mt-3">
{isAddingStatus ? (
<form
className="rounded-lg border border-blue-300 bg-white p-3 shadow-sm dark:border-blue-800 dark:bg-gray-800"
onSubmit={(event) => {
event.preventDefault()
addStatus()
}}
>
<label className="mb-2 block text-sm font-semibold" htmlFor="new-kanban-name">
{translate('::App.ListFormTodoBoard.NewColumnName')}
</label>
<Input
unstyle
autoFocus
id="new-kanban-name"
className="w-full rounded-lg border border-gray-300 bg-white px-3 py-2 text-sm outline-none focus:border-blue-500 focus:ring-2 focus:ring-blue-500/20 dark:border-gray-600 dark:bg-gray-800"
placeholder={translate('::App.ListFormTodoBoard.NewColumnPlaceholder')}
value={newStatusName}
onChange={(event) => {
setNewStatusName(event.target.value)
setStatusError('')
}}
onKeyDown={(event) => {
if (event.key === 'Escape') {
setIsAddingStatus(false)
setNewStatusName('')
setStatusError('')
}
}}
/>
{statusError && <p className="mt-2 text-xs text-red-500">{statusError}</p>}
<div className="mt-3 flex gap-2">
<button
type="submit"
className="rounded-lg bg-blue-600 px-3 py-2 text-xs font-semibold text-white hover:bg-blue-700 disabled:opacity-40"
disabled={!newStatusName.trim()}
>
{translate('::App.ListFormTodoBoard.AddColumn')}
</button>
<button
type="button"
className="rounded-lg px-3 py-2 text-xs font-semibold text-gray-500 hover:bg-gray-200 dark:hover:bg-gray-800"
onClick={() => {
setIsAddingStatus(false)
setNewStatusName('')
setStatusError('')
}}
>
{translate('::App.Platform.Cancel')}
</button>
</div>
</form>
) : (
<button <button
type="button" type="button"
className="flex min-h-24 w-full items-center justify-center gap-2 rounded-lg border-2 border-dashed border-gray-200 px-4 text-sm font-medium text-gray-400 transition hover:border-blue-400 hover:bg-blue-50 hover:text-blue-600 dark:border-gray-700 dark:hover:bg-blue-950/20" className="rounded-lg px-3 py-2 text-xs font-semibold text-gray-500 hover:bg-gray-200 dark:hover:bg-gray-800"
onClick={() => { onClick={closeAddStatus}
setIsAddingStatus(true)
setStatusError('')
}}
> >
<FaPlus /> {translate('::App.ListFormTodoBoard.AddNewColumn')} {translate('::App.Platform.Cancel')}
</button> </button>
)} <button
</div> type="submit"
</section> className="rounded-lg bg-blue-600 px-3 py-2 text-xs font-semibold text-white hover:bg-blue-700 disabled:opacity-40"
disabled={!newStatusName.trim()}
>
{translate('::App.ListFormTodoBoard.AddColumn')}
</button>
</div>
</form>
</Dialog>
)} )}
</div> </div>
</div> </div>