feat(task-management): enhance task grouping and localization support
- Implemented unmapped task grouping for better organization of tasks without valid phases. - Updated task distribution logic to handle unmapped tasks and added a corresponding group in the response. - Enhanced localization by adding translations for "noTasksInGroup" in multiple languages. - Improved task list components to support custom columns and better task management features. - Refactored task management slice to include loading states for columns and custom columns.
This commit is contained in:
@@ -5,217 +5,26 @@
|
||||
width: 8px;
|
||||
}
|
||||
|
||||
/* Enhanced Project View Tab Styles - Compact */
|
||||
.project-view-tabs {
|
||||
margin-top: 16px;
|
||||
/* Light mode - selected tab header bold */
|
||||
[data-theme="light"] .project-view-tabs .ant-tabs-tab-active .ant-tabs-tab-btn {
|
||||
font-weight: 700;
|
||||
color: #000000 !important;
|
||||
}
|
||||
|
||||
/* Remove default tab border */
|
||||
.project-view-tabs .ant-tabs-nav::before {
|
||||
border: none !important;
|
||||
/* Dark mode - selected tab header bold and white */
|
||||
[data-theme="dark"] .project-view-tabs .ant-tabs-tab-active .ant-tabs-tab-btn {
|
||||
font-weight: 900;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
/* Tab bar container */
|
||||
.project-view-tabs .ant-tabs-nav {
|
||||
margin-bottom: 8px;
|
||||
background: transparent;
|
||||
padding: 0 12px;
|
||||
/* Light mode - selected tab underline black */
|
||||
[data-theme="light"] .project-view-tabs .ant-tabs-ink-bar {
|
||||
background-color: #000000 !important;
|
||||
}
|
||||
|
||||
/* Individual tab styling - Compact */
|
||||
.project-view-tabs .ant-tabs-tab {
|
||||
position: relative;
|
||||
margin: 0 4px 0 0;
|
||||
padding: 8px 16px;
|
||||
border-radius: 6px 6px 0 0;
|
||||
background: transparent;
|
||||
border: none;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
font-weight: 500;
|
||||
font-size: 13px;
|
||||
min-height: 36px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
/* Dark mode - selected tab underline white */
|
||||
[data-theme="dark"] .project-view-tabs .ant-tabs-ink-bar {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
/* Light mode tab styles */
|
||||
[data-theme="default"] .project-view-tabs .ant-tabs-tab {
|
||||
color: #64748b;
|
||||
background: #f8fafc;
|
||||
}
|
||||
|
||||
[data-theme="default"] .project-view-tabs .ant-tabs-tab:hover {
|
||||
color: #3b82f6;
|
||||
background: #eff6ff;
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 12px rgba(59, 130, 246, 0.15);
|
||||
}
|
||||
|
||||
[data-theme="default"] .project-view-tabs .ant-tabs-tab-active {
|
||||
color: #1e40af !important;
|
||||
background: #ffffff !important;
|
||||
box-shadow:
|
||||
0 -2px 8px rgba(59, 130, 246, 0.1),
|
||||
0 4px 16px rgba(59, 130, 246, 0.1);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* Dark mode tab styles - matching task list row colors */
|
||||
[data-theme="dark"] .project-view-tabs .ant-tabs-tab {
|
||||
color: #94a3b8;
|
||||
background: #141414;
|
||||
}
|
||||
|
||||
[data-theme="dark"] .project-view-tabs .ant-tabs-tab:hover {
|
||||
color: #60a5fa;
|
||||
background: #262626;
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 12px rgba(96, 165, 250, 0.2);
|
||||
}
|
||||
|
||||
[data-theme="dark"] .project-view-tabs .ant-tabs-tab-active {
|
||||
color: #60a5fa !important;
|
||||
background: #1f1f1f !important;
|
||||
box-shadow:
|
||||
0 -2px 8px rgba(96, 165, 250, 0.15),
|
||||
0 4px 16px rgba(96, 165, 250, 0.15);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* Tab content area - Compact */
|
||||
.project-view-tabs .ant-tabs-content-holder {
|
||||
background: transparent;
|
||||
border-radius: 6px;
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
[data-theme="default"] .project-view-tabs .ant-tabs-content-holder {
|
||||
background: #ffffff;
|
||||
border: 1px solid #e2e8f0;
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
[data-theme="dark"] .project-view-tabs .ant-tabs-content-holder {
|
||||
background: #1f1f1f;
|
||||
border: 1px solid #303030;
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.project-view-tabs .ant-tabs-tabpane {
|
||||
padding: 0;
|
||||
min-height: 300px;
|
||||
}
|
||||
|
||||
/* Pin button styling - Compact */
|
||||
.project-view-tabs .borderless-icon-btn {
|
||||
margin-left: 6px;
|
||||
padding: 2px;
|
||||
border-radius: 3px;
|
||||
transition: all 0.2s ease;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.project-view-tabs .borderless-icon-btn:hover {
|
||||
opacity: 1;
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
[data-theme="default"] .project-view-tabs .borderless-icon-btn:hover {
|
||||
background: rgba(59, 130, 246, 0.1) !important;
|
||||
}
|
||||
|
||||
[data-theme="dark"] .project-view-tabs .borderless-icon-btn:hover {
|
||||
background: rgba(96, 165, 250, 0.1) !important;
|
||||
}
|
||||
|
||||
/* Pinned tab indicator */
|
||||
.project-view-tabs .ant-tabs-tab-active .borderless-icon-btn {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
[data-theme="default"] .project-view-tabs .ant-tabs-tab-active .borderless-icon-btn {
|
||||
background: rgba(59, 130, 246, 0.1) !important;
|
||||
}
|
||||
|
||||
[data-theme="dark"] .project-view-tabs .ant-tabs-tab-active .borderless-icon-btn {
|
||||
background: rgba(96, 165, 250, 0.1) !important;
|
||||
}
|
||||
|
||||
/* Tab label flex container */
|
||||
.project-view-tabs .ant-tabs-tab .ant-tabs-tab-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Responsive adjustments - Compact */
|
||||
@media (max-width: 768px) {
|
||||
.project-view-tabs .ant-tabs-nav {
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.project-view-tabs .ant-tabs-tab {
|
||||
margin: 0 2px 0 0;
|
||||
padding: 6px 12px;
|
||||
font-size: 12px;
|
||||
min-height: 32px;
|
||||
}
|
||||
|
||||
.project-view-tabs .borderless-icon-btn {
|
||||
margin-left: 4px;
|
||||
padding: 1px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.project-view-tabs .ant-tabs-tab {
|
||||
padding: 6px 10px;
|
||||
font-size: 11px;
|
||||
min-height: 30px;
|
||||
}
|
||||
|
||||
.project-view-tabs .borderless-icon-btn {
|
||||
display: none; /* Hide pin buttons on very small screens */
|
||||
}
|
||||
}
|
||||
|
||||
/* Animation for tab switching */
|
||||
.project-view-tabs .ant-tabs-content {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.project-view-tabs .ant-tabs-tabpane-active {
|
||||
animation: fadeInUp 0.3s ease-out;
|
||||
}
|
||||
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Focus states for accessibility - Compact */
|
||||
.project-view-tabs .ant-tabs-tab:focus-visible {
|
||||
outline: 1px solid #3b82f6;
|
||||
outline-offset: 1px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
[data-theme="dark"] .project-view-tabs .ant-tabs-tab:focus-visible {
|
||||
outline-color: #60a5fa;
|
||||
}
|
||||
|
||||
/* Loading state for tab content */
|
||||
.project-view-tabs .ant-tabs-tabpane .suspense-fallback {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 200px;
|
||||
}
|
||||
|
||||
@@ -351,20 +351,12 @@ const ProjectView = React.memo(() => {
|
||||
activeKey={activeTab}
|
||||
onChange={handleTabChange}
|
||||
items={tabMenuItems}
|
||||
tabBarStyle={{
|
||||
paddingInline: 0,
|
||||
marginBottom: 8,
|
||||
background: 'transparent',
|
||||
minHeight: '36px',
|
||||
}}
|
||||
tabBarGutter={0}
|
||||
destroyInactiveTabPane={true}
|
||||
destroyOnHidden={true}
|
||||
animated={{
|
||||
inkBar: true,
|
||||
tabPane: false,
|
||||
}}
|
||||
size="small"
|
||||
type="card"
|
||||
/>
|
||||
|
||||
{portalElements}
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
Typography,
|
||||
Popconfirm,
|
||||
} from 'antd';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import SelectionTypeColumn from './selection-type-column/selection-type-column';
|
||||
import NumberTypeColumn from './number-type-column/number-type-column';
|
||||
import LabelTypeColumn from './label-type-column/label-type-column';
|
||||
@@ -31,6 +32,7 @@ import {
|
||||
setSecondNumericColumn,
|
||||
setSelectionsList,
|
||||
setLabelsList,
|
||||
resetCustomFieldValues,
|
||||
} from '@features/projects/singleProject/task-list-custom-columns/task-list-custom-columns-slice';
|
||||
import CustomColumnHeader from '../custom-column-header/custom-column-header';
|
||||
import { nanoid } from '@reduxjs/toolkit';
|
||||
@@ -41,10 +43,12 @@ import {
|
||||
import { themeWiseColor } from '@/utils/themeWiseColor';
|
||||
import KeyTypeColumn from './key-type-column/key-type-column';
|
||||
import logger from '@/utils/errorLogger';
|
||||
import {
|
||||
import {
|
||||
fetchTasksV3,
|
||||
fetchTaskListColumns,
|
||||
addCustomColumn,
|
||||
deleteCustomColumn as deleteCustomColumnFromTasks,
|
||||
} from '@/features/tasks/tasks.slice';
|
||||
deleteCustomColumn as deleteCustomColumnFromTaskManagement,
|
||||
} from '@/features/task-management/task-management.slice';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { tasksCustomColumnsService } from '@/api/tasks/tasks-custom-columns.service';
|
||||
import { ExclamationCircleFilled } from '@ant-design/icons';
|
||||
@@ -52,6 +56,7 @@ import { ExclamationCircleFilled } from '@ant-design/icons';
|
||||
const CustomColumnModal = () => {
|
||||
const [mainForm] = Form.useForm();
|
||||
const { projectId } = useParams();
|
||||
const { t } = useTranslation('task-list-table');
|
||||
|
||||
// get theme details from theme reducer
|
||||
const themeMode = useAppSelector(state => state.themeReducer.mode);
|
||||
@@ -62,6 +67,7 @@ const CustomColumnModal = () => {
|
||||
customColumnId,
|
||||
customColumnModalType,
|
||||
isCustomColumnModalOpen,
|
||||
currentColumnData,
|
||||
decimals,
|
||||
label,
|
||||
labelPosition,
|
||||
@@ -82,35 +88,84 @@ const CustomColumnModal = () => {
|
||||
state => state.taskListCustomColumnsReducer.customFieldNumberType
|
||||
);
|
||||
|
||||
// if it is already created column get the column data
|
||||
const openedColumn = useAppSelector(state => state.taskReducer.customColumns).find(
|
||||
col => col.id === customColumnId
|
||||
);
|
||||
// Use the column data passed from TaskListV2
|
||||
const openedColumn = currentColumnData;
|
||||
|
||||
// Debug logging
|
||||
console.log('Modal Debug Info:', {
|
||||
customColumnId,
|
||||
customColumnModalType,
|
||||
currentColumnData,
|
||||
openedColumn,
|
||||
openedColumnFound: !!openedColumn,
|
||||
openedColumnId: openedColumn?.id
|
||||
});
|
||||
|
||||
// Function to reset all form and Redux state
|
||||
const resetModalData = () => {
|
||||
mainForm.resetFields();
|
||||
dispatch(resetCustomFieldValues());
|
||||
dispatch(setCustomColumnModalAttributes({ modalType: 'create', columnId: null }));
|
||||
};
|
||||
|
||||
// Function to handle deleting a custom column
|
||||
const handleDeleteColumn = async () => {
|
||||
if (!customColumnId) return;
|
||||
console.log('Delete function called with:', {
|
||||
customColumnId,
|
||||
openedColumn,
|
||||
openedColumnId: openedColumn?.id,
|
||||
openedColumnKey: openedColumn?.key,
|
||||
fullColumnData: openedColumn
|
||||
});
|
||||
|
||||
// Try to get UUID from different possible locations in the column data
|
||||
const columnUUID = openedColumn?.id ||
|
||||
openedColumn?.uuid ||
|
||||
openedColumn?.custom_column_obj?.id ||
|
||||
openedColumn?.custom_column_obj?.uuid;
|
||||
|
||||
console.log('Extracted UUID candidates:', {
|
||||
'openedColumn?.id': openedColumn?.id,
|
||||
'openedColumn?.uuid': openedColumn?.uuid,
|
||||
'openedColumn?.custom_column_obj?.id': openedColumn?.custom_column_obj?.id,
|
||||
'openedColumn?.custom_column_obj?.uuid': openedColumn?.custom_column_obj?.uuid,
|
||||
'finalColumnUUID': columnUUID
|
||||
});
|
||||
|
||||
if (!customColumnId || !columnUUID) {
|
||||
console.error('Missing required data for deletion:', {
|
||||
customColumnId,
|
||||
columnUUID,
|
||||
openedColumn
|
||||
});
|
||||
message.error('Cannot delete column: Missing UUID');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
console.log('Attempting to delete column with UUID:', columnUUID);
|
||||
// Make API request to delete the custom column using the service
|
||||
await tasksCustomColumnsService.deleteCustomColumn(openedColumn?.id || customColumnId);
|
||||
await tasksCustomColumnsService.deleteCustomColumn(columnUUID);
|
||||
|
||||
// Dispatch actions to update the Redux store
|
||||
dispatch(deleteCustomColumnFromTasks(customColumnId));
|
||||
dispatch(deleteCustomColumnFromTaskManagement(customColumnId));
|
||||
dispatch(deleteCustomColumnFromColumns(customColumnId));
|
||||
|
||||
// Close the modal
|
||||
// Close the modal and reset data
|
||||
dispatch(toggleCustomColumnModalOpen(false));
|
||||
dispatch(setCustomColumnModalAttributes({ modalType: 'create', columnId: null }));
|
||||
resetModalData();
|
||||
|
||||
// Show success message
|
||||
message.success('Custom column deleted successfully');
|
||||
message.success(t('customColumns.modal.deleteSuccessMessage'));
|
||||
|
||||
// Reload the page to reflect the changes
|
||||
window.location.reload();
|
||||
// Refresh tasks and columns to reflect the deleted custom column
|
||||
if (projectId) {
|
||||
dispatch(fetchTaskListColumns(projectId));
|
||||
dispatch(fetchTasksV3(projectId));
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('Error deleting custom column:', error);
|
||||
message.error('Failed to delete custom column');
|
||||
message.error(t('customColumns.modal.deleteErrorMessage'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -118,49 +173,49 @@ const CustomColumnModal = () => {
|
||||
{
|
||||
key: 'people',
|
||||
value: 'people',
|
||||
label: 'People',
|
||||
label: t('customColumns.fieldTypes.people'),
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
key: 'number',
|
||||
value: 'number',
|
||||
label: 'Number',
|
||||
label: t('customColumns.fieldTypes.number'),
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
key: 'date',
|
||||
value: 'date',
|
||||
label: 'Date',
|
||||
label: t('customColumns.fieldTypes.date'),
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
key: 'selection',
|
||||
value: 'selection',
|
||||
label: 'Selection',
|
||||
label: t('customColumns.fieldTypes.selection'),
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
key: 'checkbox',
|
||||
value: 'checkbox',
|
||||
label: 'Checkbox',
|
||||
label: t('customColumns.fieldTypes.checkbox'),
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
key: 'labels',
|
||||
value: 'labels',
|
||||
label: 'Labels',
|
||||
label: t('customColumns.fieldTypes.labels'),
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
key: 'key',
|
||||
value: 'key',
|
||||
label: 'Key',
|
||||
label: t('customColumns.fieldTypes.key'),
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
key: 'formula',
|
||||
value: 'formula',
|
||||
label: 'Formula',
|
||||
label: t('customColumns.fieldTypes.formula'),
|
||||
disabled: true,
|
||||
},
|
||||
];
|
||||
@@ -231,12 +286,21 @@ const CustomColumnModal = () => {
|
||||
if (res.done) {
|
||||
if (res.body.id) newColumn.id = res.body.id;
|
||||
dispatch(addCustomColumn(newColumn));
|
||||
dispatch(setCustomColumnModalAttributes({ modalType: 'create', columnId: null }));
|
||||
dispatch(toggleCustomColumnModalOpen(false));
|
||||
resetModalData();
|
||||
|
||||
// Show success message
|
||||
message.success(t('customColumns.modal.createSuccessMessage'));
|
||||
|
||||
// Refresh tasks and columns to include the new custom column values
|
||||
if (projectId) {
|
||||
dispatch(fetchTaskListColumns(projectId));
|
||||
dispatch(fetchTasksV3(projectId));
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('Error creating custom column:', error);
|
||||
message.error('Failed to create custom column');
|
||||
message.error(t('customColumns.modal.createErrorMessage'));
|
||||
}
|
||||
} else if (customColumnModalType === 'edit' && customColumnId) {
|
||||
const updatedColumn = openedColumn
|
||||
@@ -264,7 +328,7 @@ const CustomColumnModal = () => {
|
||||
}
|
||||
: null;
|
||||
|
||||
if (updatedColumn) {
|
||||
if (updatedColumn && openedColumn?.id) {
|
||||
try {
|
||||
// Prepare the configuration object
|
||||
const configuration = {
|
||||
@@ -299,7 +363,7 @@ const CustomColumnModal = () => {
|
||||
};
|
||||
|
||||
// Make API request to update custom column using the service
|
||||
await tasksCustomColumnsService.updateCustomColumn(openedColumn?.id || customColumnId, {
|
||||
await tasksCustomColumnsService.updateCustomColumn(openedColumn.id, {
|
||||
name: value.fieldTitle,
|
||||
field_type: value.fieldType,
|
||||
width: 150,
|
||||
@@ -307,15 +371,21 @@ const CustomColumnModal = () => {
|
||||
configuration,
|
||||
});
|
||||
|
||||
// Close modal
|
||||
// Close modal and reset data
|
||||
dispatch(toggleCustomColumnModalOpen(false));
|
||||
dispatch(setCustomColumnModalAttributes({ modalType: 'create', columnId: null }));
|
||||
resetModalData();
|
||||
|
||||
// Reload the page instead of updating the slice
|
||||
window.location.reload();
|
||||
// Show success message
|
||||
message.success(t('customColumns.modal.updateSuccessMessage'));
|
||||
|
||||
// Refresh tasks and columns to reflect the updated custom column
|
||||
if (projectId) {
|
||||
dispatch(fetchTaskListColumns(projectId));
|
||||
dispatch(fetchTasksV3(projectId));
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('Error updating custom column:', error);
|
||||
message.error('Failed to update custom column');
|
||||
message.error(t('customColumns.modal.updateErrorMessage'));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -328,20 +398,17 @@ const CustomColumnModal = () => {
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title={customColumnModalType === 'create' ? 'Add field' : 'Edit field'}
|
||||
title={customColumnModalType === 'create' ? t('customColumns.modal.addFieldTitle') : t('customColumns.modal.editFieldTitle')}
|
||||
centered
|
||||
open={isCustomColumnModalOpen}
|
||||
onCancel={() => {
|
||||
dispatch(toggleCustomColumnModalOpen(false));
|
||||
dispatch(setCustomColumnModalAttributes({ modalType: 'create', columnId: null }));
|
||||
resetModalData();
|
||||
}}
|
||||
styles={{
|
||||
header: { position: 'relative' },
|
||||
footer: { display: 'none' },
|
||||
}}
|
||||
onClose={() => {
|
||||
mainForm.resetFields();
|
||||
}}
|
||||
afterOpenChange={open => {
|
||||
if (open && customColumnModalType === 'edit' && openedColumn) {
|
||||
// Set the field type first so the correct form fields are displayed
|
||||
@@ -394,9 +461,11 @@ const CustomColumnModal = () => {
|
||||
secondNumericColumn: openedColumn.custom_column_obj?.secondNumericColumn,
|
||||
});
|
||||
} else if (open && customColumnModalType === 'create') {
|
||||
// Reset form for create mode
|
||||
mainForm.resetFields();
|
||||
dispatch(setCustomFieldType('people'));
|
||||
// Reset all data for create mode
|
||||
resetModalData();
|
||||
} else if (!open) {
|
||||
// Reset data when modal closes
|
||||
resetModalData();
|
||||
}
|
||||
}}
|
||||
>
|
||||
@@ -437,22 +506,22 @@ const CustomColumnModal = () => {
|
||||
<Flex gap={16} align="center" justify="space-between">
|
||||
<Form.Item
|
||||
name={'fieldTitle'}
|
||||
label={<Typography.Text>Field title</Typography.Text>}
|
||||
label={<Typography.Text>{t('customColumns.modal.fieldTitle')}</Typography.Text>}
|
||||
layout="vertical"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: 'Field title is required',
|
||||
message: t('customColumns.modal.fieldTitleRequired'),
|
||||
},
|
||||
]}
|
||||
required={false}
|
||||
>
|
||||
<Input placeholder="title" style={{ minWidth: '100%', width: 300 }} />
|
||||
<Input placeholder={t('customColumns.modal.columnTitlePlaceholder')} style={{ minWidth: '100%', width: 300 }} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name={'fieldType'}
|
||||
label={<Typography.Text>Type</Typography.Text>}
|
||||
label={<Typography.Text>{t('customColumns.modal.type')}</Typography.Text>}
|
||||
layout="vertical"
|
||||
>
|
||||
<Select
|
||||
@@ -485,27 +554,30 @@ const CustomColumnModal = () => {
|
||||
>
|
||||
{customColumnModalType === 'edit' && customColumnId && (
|
||||
<Popconfirm
|
||||
title="Are you sure you want to delete this custom column?"
|
||||
description="This action cannot be undone. All data associated with this column will be permanently deleted."
|
||||
title={t('customColumns.modal.deleteConfirmTitle')}
|
||||
description={t('customColumns.modal.deleteConfirmDescription')}
|
||||
icon={<ExclamationCircleFilled style={{ color: 'red' }} />}
|
||||
onConfirm={handleDeleteColumn}
|
||||
okText="Delete"
|
||||
cancelText="Cancel"
|
||||
okText={t('customColumns.modal.deleteButton')}
|
||||
cancelText={t('customColumns.modal.cancelButton')}
|
||||
okButtonProps={{ danger: true }}
|
||||
>
|
||||
<Button danger>Delete</Button>
|
||||
<Button danger>{t('customColumns.modal.deleteButton')}</Button>
|
||||
</Popconfirm>
|
||||
)}
|
||||
|
||||
<Flex gap={8}>
|
||||
<Button onClick={() => dispatch(toggleCustomColumnModalOpen(false))}>Cancel</Button>
|
||||
<Button onClick={() => {
|
||||
dispatch(toggleCustomColumnModalOpen(false));
|
||||
resetModalData();
|
||||
}}>{t('customColumns.modal.cancelButton')}</Button>
|
||||
{customColumnModalType === 'create' ? (
|
||||
<Button type="primary" htmlType="submit">
|
||||
Create
|
||||
{t('customColumns.modal.createButton')}
|
||||
</Button>
|
||||
) : (
|
||||
<Button type="primary" htmlType="submit">
|
||||
Update
|
||||
{t('customColumns.modal.updateButton')}
|
||||
</Button>
|
||||
)}
|
||||
</Flex>
|
||||
|
||||
Reference in New Issue
Block a user