feat(task-phases): enhance phase creation with custom naming and localization updates

- Updated the phase creation logic to allow custom names, defaulting to a generated name if none is provided.
- Modified localization files for multiple languages to improve phase-related text consistency and clarity.
- Enhanced the UI components to reflect the new phase naming functionality and ensure proper integration with the task management system.
- Added dark mode styling for confirmation modals to improve user experience across themes.
This commit is contained in:
chamikaJ
2025-07-11 17:26:21 +05:30
parent 12b430a349
commit affbbbffbf
23 changed files with 464 additions and 77 deletions

View File

@@ -139,7 +139,7 @@ const EnhancedKanbanCreateSection: React.FC = () => {
}
if (groupBy === IGroupBy.PHASE) {
try {
const response = await phasesApiService.addPhaseOption(projectId);
const response = await phasesApiService.addPhaseOption(projectId, name);
if (response.done && response.body) {
dispatch(fetchEnhancedKanbanGroups(projectId));
}

View File

@@ -20,6 +20,112 @@
border-top: 1px solid #303030;
}
/* Dark mode confirmation modal styling */
.dark .ant-modal-confirm .ant-modal-content,
[data-theme="dark"] .ant-modal-confirm .ant-modal-content {
background-color: #1f1f1f !important;
border: 1px solid #303030 !important;
}
.dark .ant-modal-confirm .ant-modal-header,
[data-theme="dark"] .ant-modal-confirm .ant-modal-header {
background-color: #1f1f1f !important;
border-bottom: 1px solid #303030 !important;
}
.dark .ant-modal-confirm .ant-modal-body,
[data-theme="dark"] .ant-modal-confirm .ant-modal-body {
background-color: #1f1f1f !important;
color: #d9d9d9 !important;
}
.dark .ant-modal-confirm .ant-modal-footer,
[data-theme="dark"] .ant-modal-confirm .ant-modal-footer {
background-color: #1f1f1f !important;
border-top: 1px solid #303030 !important;
}
.dark .ant-modal-confirm .ant-modal-confirm-title,
[data-theme="dark"] .ant-modal-confirm .ant-modal-confirm-title {
color: #d9d9d9 !important;
}
.dark .ant-modal-confirm .ant-modal-confirm-content,
[data-theme="dark"] .ant-modal-confirm .ant-modal-confirm-content {
color: #8c8c8c !important;
}
.dark .ant-modal-confirm .ant-btn-default,
[data-theme="dark"] .ant-modal-confirm .ant-btn-default {
background-color: #141414 !important;
border-color: #303030 !important;
color: #d9d9d9 !important;
}
.dark .ant-modal-confirm .ant-btn-default:hover,
[data-theme="dark"] .ant-modal-confirm .ant-btn-default:hover {
background-color: #262626 !important;
border-color: #40a9ff !important;
color: #d9d9d9 !important;
}
.dark .ant-modal-confirm .ant-btn-primary,
[data-theme="dark"] .ant-modal-confirm .ant-btn-primary {
background-color: #1890ff !important;
border-color: #1890ff !important;
color: #ffffff !important;
}
.dark .ant-modal-confirm .ant-btn-primary:hover,
[data-theme="dark"] .ant-modal-confirm .ant-btn-primary:hover {
background-color: #40a9ff !important;
border-color: #40a9ff !important;
color: #ffffff !important;
}
.dark .ant-modal-confirm .ant-btn-dangerous,
[data-theme="dark"] .ant-modal-confirm .ant-btn-dangerous {
background-color: #ff4d4f !important;
border-color: #ff4d4f !important;
color: #ffffff !important;
}
.dark .ant-modal-confirm .ant-btn-dangerous:hover,
[data-theme="dark"] .ant-modal-confirm .ant-btn-dangerous:hover {
background-color: #ff7875 !important;
border-color: #ff7875 !important;
color: #ffffff !important;
}
/* Light mode confirmation modal styling (ensure consistency) */
.ant-modal-confirm .ant-modal-content {
background-color: #ffffff;
border: 1px solid #f0f0f0;
}
.ant-modal-confirm .ant-modal-header {
background-color: #ffffff;
border-bottom: 1px solid #f0f0f0;
}
.ant-modal-confirm .ant-modal-body {
background-color: #ffffff;
color: #262626;
}
.ant-modal-confirm .ant-modal-footer {
background-color: #ffffff;
border-top: 1px solid #f0f0f0;
}
.ant-modal-confirm .ant-modal-confirm-title {
color: #262626;
}
.ant-modal-confirm .ant-modal-confirm-content {
color: #595959;
}
.dark-modal .ant-form-item-label > label {
color: #d9d9d9;
}

View File

@@ -18,6 +18,7 @@ import {
deletePhaseOption,
updatePhaseColor,
} from '@/features/projects/singleProject/phase/phases.slice';
import { updatePhaseLabel } from '@/features/project/project.slice';
import { ITaskPhase } from '@/types/tasks/taskPhase.types';
import { Modal as AntModal } from 'antd';
import { fetchTasksV3 } from '@/features/task-management/task-management.slice';
@@ -307,7 +308,7 @@ const ManagePhaseModal: React.FC<ManagePhaseModalProps> = ({
if (!newPhaseName.trim() || !finalProjectId) return;
try {
await dispatch(addPhaseOption({ projectId: finalProjectId }));
await dispatch(addPhaseOption({ projectId: finalProjectId, name: newPhaseName.trim() }));
await dispatch(fetchPhasesByProjectId(finalProjectId));
await refreshTasks();
setNewPhaseName('');
@@ -408,6 +409,7 @@ const ManagePhaseModal: React.FC<ManagePhaseModalProps> = ({
).unwrap();
if (res.done) {
dispatch(updatePhaseLabel(phaseName));
setInitialPhaseName(phaseName);
await refreshTasks();
}
@@ -428,7 +430,7 @@ const ManagePhaseModal: React.FC<ManagePhaseModalProps> = ({
<Title level={4} className={`m-0 font-semibold ${
isDarkMode ? 'text-gray-100' : 'text-gray-800'
}`}>
{t('configurePhases')}
{t('configure')} {phaseName || project?.phase_label || t('phasesText')}
</Title>
}
open={open}
@@ -495,7 +497,7 @@ const ManagePhaseModal: React.FC<ManagePhaseModalProps> = ({
<Text className={`text-xs font-medium ${
isDarkMode ? 'text-gray-300' : 'text-blue-700'
}`}>
🎨 Drag phases to reorder them. Click on a phase name to rename it. Each phase can have a custom color.
🎨 Drag {(phaseName || project?.phase_label || t('phasesText')).toLowerCase()} to reorder them. Click on a {(phaseName || project?.phase_label || t('phaseText')).toLowerCase()} name to rename it. Each {(phaseName || project?.phase_label || t('phaseText')).toLowerCase()} can have a custom color.
</Text>
</div>
@@ -558,7 +560,7 @@ const ManagePhaseModal: React.FC<ManagePhaseModalProps> = ({
<Text className={`text-xs font-medium ${
isDarkMode ? 'text-gray-300' : 'text-gray-700'
}`}>
{t('phaseOptions')}
{phaseName || project?.phase_label || t('phasesText')} {t('optionsText')}
</Text>
<Button
type="primary"
@@ -601,7 +603,7 @@ const ManagePhaseModal: React.FC<ManagePhaseModalProps> = ({
isDarkMode ? 'text-gray-400' : 'text-gray-500'
}`}>
<Text className="text-sm font-medium">
{t('noPhasesFound')}
{t('no')} {(phaseName || project?.phase_label || t('phasesText')).toLowerCase()} {t('found')}
</Text>
<br />
<Button

View File

@@ -20,6 +20,112 @@
border-top: 1px solid #303030;
}
/* Dark mode confirmation modal styling */
.dark .ant-modal-confirm .ant-modal-content,
[data-theme="dark"] .ant-modal-confirm .ant-modal-content {
background-color: #1f1f1f !important;
border: 1px solid #303030 !important;
}
.dark .ant-modal-confirm .ant-modal-header,
[data-theme="dark"] .ant-modal-confirm .ant-modal-header {
background-color: #1f1f1f !important;
border-bottom: 1px solid #303030 !important;
}
.dark .ant-modal-confirm .ant-modal-body,
[data-theme="dark"] .ant-modal-confirm .ant-modal-body {
background-color: #1f1f1f !important;
color: #d9d9d9 !important;
}
.dark .ant-modal-confirm .ant-modal-footer,
[data-theme="dark"] .ant-modal-confirm .ant-modal-footer {
background-color: #1f1f1f !important;
border-top: 1px solid #303030 !important;
}
.dark .ant-modal-confirm .ant-modal-confirm-title,
[data-theme="dark"] .ant-modal-confirm .ant-modal-confirm-title {
color: #d9d9d9 !important;
}
.dark .ant-modal-confirm .ant-modal-confirm-content,
[data-theme="dark"] .ant-modal-confirm .ant-modal-confirm-content {
color: #8c8c8c !important;
}
.dark .ant-modal-confirm .ant-btn-default,
[data-theme="dark"] .ant-modal-confirm .ant-btn-default {
background-color: #141414 !important;
border-color: #303030 !important;
color: #d9d9d9 !important;
}
.dark .ant-modal-confirm .ant-btn-default:hover,
[data-theme="dark"] .ant-modal-confirm .ant-btn-default:hover {
background-color: #262626 !important;
border-color: #40a9ff !important;
color: #d9d9d9 !important;
}
.dark .ant-modal-confirm .ant-btn-primary,
[data-theme="dark"] .ant-modal-confirm .ant-btn-primary {
background-color: #1890ff !important;
border-color: #1890ff !important;
color: #ffffff !important;
}
.dark .ant-modal-confirm .ant-btn-primary:hover,
[data-theme="dark"] .ant-modal-confirm .ant-btn-primary:hover {
background-color: #40a9ff !important;
border-color: #40a9ff !important;
color: #ffffff !important;
}
.dark .ant-modal-confirm .ant-btn-dangerous,
[data-theme="dark"] .ant-modal-confirm .ant-btn-dangerous {
background-color: #ff4d4f !important;
border-color: #ff4d4f !important;
color: #ffffff !important;
}
.dark .ant-modal-confirm .ant-btn-dangerous:hover,
[data-theme="dark"] .ant-modal-confirm .ant-btn-dangerous:hover {
background-color: #ff7875 !important;
border-color: #ff7875 !important;
color: #ffffff !important;
}
/* Light mode confirmation modal styling (ensure consistency) */
.ant-modal-confirm .ant-modal-content {
background-color: #ffffff;
border: 1px solid #f0f0f0;
}
.ant-modal-confirm .ant-modal-header {
background-color: #ffffff;
border-bottom: 1px solid #f0f0f0;
}
.ant-modal-confirm .ant-modal-body {
background-color: #ffffff;
color: #262626;
}
.ant-modal-confirm .ant-modal-footer {
background-color: #ffffff;
border-top: 1px solid #f0f0f0;
}
.ant-modal-confirm .ant-modal-confirm-title {
color: #262626;
}
.ant-modal-confirm .ant-modal-confirm-content {
color: #595959;
}
.dark-modal .ant-form-item-label > label {
color: #d9d9d9;
}

View File

@@ -369,6 +369,7 @@ const FilterDropdown: React.FC<{
dispatch?: any;
onManageStatus?: () => void;
onManagePhase?: () => void;
projectPhaseLabel?: string; // Add this prop
}> = ({
section,
onSelectionChange,
@@ -380,6 +381,7 @@ const FilterDropdown: React.FC<{
dispatch,
onManageStatus,
onManagePhase,
projectPhaseLabel, // Add this prop
}) => {
const { t } = useTranslation('task-list-filters');
// Add permission checks for groupBy section
@@ -495,7 +497,7 @@ const FilterDropdown: React.FC<{
isDarkMode ? 'focus:ring-offset-gray-900' : 'focus:ring-offset-white'
}`}
>
{t('managePhases')}
{t('manage')} {projectPhaseLabel || t('phasesText')}
</button>
)}
{section.selectedValues[0] === 'status' && (
@@ -994,6 +996,7 @@ const ImprovedTaskFilters: React.FC<ImprovedTaskFiltersProps> = ({ position, cla
const isDarkMode = useAppSelector(state => state.themeReducer?.mode === 'dark');
const { projectId } = useAppSelector(state => state.projectReducer);
const { projectView } = useTabSearchParam();
const projectPhaseLabel = useAppSelector(state => state.projectReducer.project?.phase_label);
// Theme-aware class names - memoize to prevent unnecessary re-renders
// Using greyish colors for both dark and light modes
@@ -1298,6 +1301,7 @@ const ImprovedTaskFilters: React.FC<ImprovedTaskFiltersProps> = ({ position, cla
dispatch={dispatch}
onManageStatus={() => setShowManageStatusModal(true)}
onManagePhase={() => setShowManagePhaseModal(true)}
projectPhaseLabel={projectPhaseLabel}
/>
))
) : (