Merge branch 'release-v2.1.4' into feature/task-activities-by-user
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
|
||||
import { IAccountSetupSurveyData } from '@/types/account-setup/survey.types';
|
||||
|
||||
interface Task {
|
||||
id: number;
|
||||
@@ -17,6 +18,8 @@ interface AccountSetupState {
|
||||
tasks: Task[];
|
||||
teamMembers: Email[];
|
||||
currentStep: number;
|
||||
surveyData: IAccountSetupSurveyData;
|
||||
surveySubStep: number;
|
||||
}
|
||||
|
||||
const initialState: AccountSetupState = {
|
||||
@@ -26,6 +29,8 @@ const initialState: AccountSetupState = {
|
||||
tasks: [{ id: 0, value: '' }],
|
||||
teamMembers: [{ id: 0, value: '' }],
|
||||
currentStep: 0,
|
||||
surveyData: {},
|
||||
surveySubStep: 0,
|
||||
};
|
||||
|
||||
const accountSetupSlice = createSlice({
|
||||
@@ -50,6 +55,16 @@ const accountSetupSlice = createSlice({
|
||||
setCurrentStep: (state, action: PayloadAction<number>) => {
|
||||
state.currentStep = action.payload;
|
||||
},
|
||||
setSurveyData: (state, action: PayloadAction<Partial<IAccountSetupSurveyData>>) => {
|
||||
state.surveyData = { ...state.surveyData, ...action.payload };
|
||||
},
|
||||
setSurveySubStep: (state, action: PayloadAction<number>) => {
|
||||
state.surveySubStep = action.payload;
|
||||
},
|
||||
resetSurveyData: (state) => {
|
||||
state.surveyData = {};
|
||||
state.surveySubStep = 0;
|
||||
},
|
||||
resetAccountSetup: () => initialState,
|
||||
},
|
||||
});
|
||||
@@ -61,6 +76,9 @@ export const {
|
||||
setTasks,
|
||||
setTeamMembers,
|
||||
setCurrentStep,
|
||||
setSurveyData,
|
||||
setSurveySubStep,
|
||||
resetSurveyData,
|
||||
resetAccountSetup,
|
||||
} = accountSetupSlice.actions;
|
||||
|
||||
|
||||
@@ -575,7 +575,6 @@ const enhancedKanbanSlice = createSlice({
|
||||
action: PayloadAction<ITaskListPriorityChangeResponse>
|
||||
) => {
|
||||
const { id, priority_id, color_code, color_code_dark } = action.payload;
|
||||
|
||||
// Find the task in any group
|
||||
const taskInfo = findTaskInAllGroups(state.taskGroups, id);
|
||||
if (!taskInfo || !priority_id) return;
|
||||
@@ -603,7 +602,6 @@ const enhancedKanbanSlice = createSlice({
|
||||
// Update cache
|
||||
state.taskCache[id] = task;
|
||||
},
|
||||
|
||||
// Enhanced Kanban assignee update (for use in task drawer dropdown)
|
||||
updateEnhancedKanbanTaskAssignees: (
|
||||
state,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Button, Dropdown } from 'antd';
|
||||
import { Button, Dropdown } from '@/shared/antd-imports';
|
||||
import { useAppSelector } from '@/hooks/useAppSelector';
|
||||
import { useAppDispatch } from '@/hooks/useAppDispatch';
|
||||
import { ILanguageType, setLanguage } from './localesSlice';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { QuestionCircleOutlined } from '@ant-design/icons';
|
||||
import { Button, Tooltip } from 'antd';
|
||||
import { QuestionCircleOutlined } from '@/shared/antd-imports';
|
||||
import { Button, Tooltip } from '@/shared/antd-imports';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import './HelpButton.css';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { UsergroupAddOutlined } from '@ant-design/icons';
|
||||
import { Button, Tooltip } from 'antd';
|
||||
import { UsergroupAddOutlined } from '@/shared/antd-imports';
|
||||
import { Button, Tooltip } from '@/shared/antd-imports';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { colors } from '../../../styles/colors';
|
||||
|
||||
@@ -5,8 +5,8 @@ import {
|
||||
ProjectOutlined,
|
||||
QuestionCircleOutlined,
|
||||
ReadOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import { Button, Card, Dropdown, Flex, MenuProps, Space, Typography } from 'antd';
|
||||
} from '@/shared/antd-imports';
|
||||
import { Button, Card, Dropdown, Flex, MenuProps, Space, Typography } from '@/shared/antd-imports';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { colors } from '../../../styles/colors';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useEffect, useState, useMemo } from 'react';
|
||||
import { Link, useLocation } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Col, ConfigProvider, Flex, Menu, MenuProps, Alert } from 'antd';
|
||||
import { Col, ConfigProvider, Flex, Menu, MenuProps, Alert } from '@/shared/antd-imports';
|
||||
import { createPortal } from 'react-dom';
|
||||
|
||||
import InviteTeamMembers from '../../components/common/invite-team-members/invite-team-members';
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// Ant Design Icons
|
||||
import { BankOutlined, CaretDownFilled, CheckCircleFilled } from '@ant-design/icons';
|
||||
import { BankOutlined, CaretDownFilled, CheckCircleFilled } from '@/shared/antd-imports';
|
||||
|
||||
// Ant Design Components
|
||||
import { Card, Divider, Dropdown, Flex, Tooltip, Typography } from 'antd';
|
||||
import { Card, Divider, Dropdown, Flex, Tooltip, Typography } from '@/shared/antd-imports';
|
||||
|
||||
// Redux Hooks
|
||||
import { useAppDispatch } from '@/hooks/useAppDispatch';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ClockCircleOutlined, StopOutlined } from '@ant-design/icons';
|
||||
import { Badge, Button, Dropdown, List, Tooltip, Typography, Space, Divider, theme } from 'antd';
|
||||
import { ClockCircleOutlined, StopOutlined } from '@/shared/antd-imports';
|
||||
import { Badge, Button, Dropdown, List, Tooltip, Typography, Space, Divider, theme } from '@/shared/antd-imports';
|
||||
import React, { useEffect, useState, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { taskTimeLogsApiService, IRunningTimer } from '@/api/tasks/task-time-logs.api.service';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Button, Tooltip } from 'antd';
|
||||
import { Button, Tooltip } from '@/shared/antd-imports';
|
||||
import React from 'react';
|
||||
import { colors } from '../../../styles/colors';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { UserOutlined } from '@ant-design/icons';
|
||||
import { Button, Card, Dropdown, Flex, MenuProps, Tooltip, Typography } from 'antd';
|
||||
import { UserOutlined } from '@/shared/antd-imports';
|
||||
import { Button, Card, Dropdown, Flex, MenuProps, Tooltip, Typography } from '@/shared/antd-imports';
|
||||
|
||||
import { Link } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
@@ -7,8 +7,8 @@ import {
|
||||
TagsOutlined,
|
||||
UserAddOutlined,
|
||||
UsergroupAddOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import { Button, Flex, Tooltip, Typography } from 'antd';
|
||||
} from '@/shared/antd-imports';
|
||||
import { Button, Flex, Tooltip, Typography } from '@/shared/antd-imports';
|
||||
import { colors } from '../../../styles/colors';
|
||||
|
||||
type BulkTasksActionProps = {
|
||||
|
||||
@@ -8,6 +8,7 @@ interface ProjectMembersState {
|
||||
currentMembersList: IMentionMemberViewModel[];
|
||||
isDrawerOpen: boolean;
|
||||
isLoading: boolean;
|
||||
isFromAssigner: boolean;
|
||||
error: string | null;
|
||||
}
|
||||
|
||||
@@ -16,6 +17,7 @@ const initialState: ProjectMembersState = {
|
||||
currentMembersList: [],
|
||||
isDrawerOpen: false,
|
||||
isLoading: false,
|
||||
isFromAssigner: false,
|
||||
error: null,
|
||||
};
|
||||
|
||||
@@ -89,6 +91,12 @@ const projectMembersSlice = createSlice({
|
||||
reducers: {
|
||||
toggleProjectMemberDrawer: state => {
|
||||
state.isDrawerOpen = !state.isDrawerOpen;
|
||||
if (state.isDrawerOpen === false) {
|
||||
state.isFromAssigner = false;
|
||||
}
|
||||
},
|
||||
setIsFromAssigner: (state, action: PayloadAction<boolean>) => {
|
||||
state.isFromAssigner = action.payload;
|
||||
},
|
||||
},
|
||||
extraReducers: builder => {
|
||||
@@ -139,7 +147,7 @@ const projectMembersSlice = createSlice({
|
||||
},
|
||||
});
|
||||
|
||||
export const { toggleProjectMemberDrawer } = projectMembersSlice.actions;
|
||||
export const { toggleProjectMemberDrawer, setIsFromAssigner } = projectMembersSlice.actions;
|
||||
export {
|
||||
getProjectMembers,
|
||||
getAllProjectMembers,
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { SettingOutlined } from '@ant-design/icons';
|
||||
import { Button, Tooltip } from 'antd';
|
||||
import React from 'react';
|
||||
import { useAppDispatch } from '../../../../hooks/useAppDispatch';
|
||||
import { SettingOutlined } from '@/shared/antd-imports';
|
||||
import { Button, Tooltip } from '@/shared/antd-imports';
|
||||
import { useAppDispatch } from '@/hooks/useAppDispatch';
|
||||
import { toggleDrawer } from './phases.slice';
|
||||
import { useAppSelector } from '../../../../hooks/useAppSelector';
|
||||
import { colors } from '../../../../styles/colors';
|
||||
import { useAppSelector } from '@/hooks/useAppSelector';
|
||||
import { colors } from '@/styles/colors';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const ConfigPhaseButton = () => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Button, Drawer, Flex, Input, Skeleton, Spin, Typography } from 'antd';
|
||||
import { Button, Drawer, Flex, Input, Spin, Typography } from '@/shared/antd-imports';
|
||||
import { useState } from 'react';
|
||||
import { useAppSelector } from '../../../../hooks/useAppSelector';
|
||||
import { useAppDispatch } from '../../../../hooks/useAppDispatch';
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
updateProjectPhaseLabel,
|
||||
} from './phases.slice';
|
||||
import { Divider } from 'antd/lib';
|
||||
import { PlusOutlined } from '@ant-design/icons';
|
||||
import { PlusOutlined } from '@/shared/antd-imports';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import PhaseOptionItem from './PhaseOptionItem';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import { useAppSelector } from '../../../../hooks/useAppSelector';
|
||||
import { Flex } from 'antd';
|
||||
import { Flex } from '@/shared/antd-imports';
|
||||
import ConfigPhaseButton from './ConfigPhaseButton';
|
||||
import { colors } from '../../../../styles/colors';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Button, ColorPicker, ConfigProvider, Flex, Input } from 'antd';
|
||||
import { CloseCircleOutlined, HolderOutlined } from '@ant-design/icons';
|
||||
import { Button, ColorPicker, ConfigProvider, Flex, Input } from '@/shared/antd-imports';
|
||||
import { CloseCircleOutlined, HolderOutlined } from '@/shared/antd-imports';
|
||||
import { nanoid } from '@reduxjs/toolkit';
|
||||
import { useAppDispatch } from '@/hooks/useAppDispatch';
|
||||
import {
|
||||
|
||||
@@ -11,14 +11,14 @@ import {
|
||||
Select,
|
||||
Tag,
|
||||
Typography,
|
||||
} from 'antd';
|
||||
} from '@/shared/antd-imports';
|
||||
import React, { useRef, useState } from 'react';
|
||||
import {
|
||||
healthStatusData,
|
||||
projectColors,
|
||||
statusData,
|
||||
} from '../../../lib/project/project-constants';
|
||||
import { PlusCircleOutlined, PlusOutlined, QuestionCircleOutlined } from '@ant-design/icons';
|
||||
import { PlusCircleOutlined, PlusOutlined, QuestionCircleOutlined } from '@/shared/antd-imports';
|
||||
import { colors } from '../../../styles/colors';
|
||||
import { useAppSelector } from '@/hooks/useAppSelector';
|
||||
import { useAppDispatch } from '@/hooks/useAppDispatch';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Card, ConfigProvider, Tag, Timeline, Typography } from 'antd';
|
||||
import { Card, ConfigProvider, Tag, Timeline, Typography } from '@/shared/antd-imports';
|
||||
import { simpleDateFormat } from '@/utils/simpleDateFormat';
|
||||
import { useAppDispatch } from '@/hooks/useAppDispatch';
|
||||
import { colors } from '../../../../../styles/colors';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Flex, Skeleton } from 'antd';
|
||||
import { Flex, Skeleton } from '@/shared/antd-imports';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import EmptyListPlaceholder from '@/components/EmptyListPlaceholder';
|
||||
import ActivityLogCard from './activity-log-card';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Tabs } from 'antd';
|
||||
import { Tabs } from '@/shared/antd-imports';
|
||||
import { TabsProps } from 'antd/lib';
|
||||
import React from 'react';
|
||||
import MembersReportsOverviewTab from './overviewTab/MembersReportsOverviewTab';
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Drawer, Typography, Flex, Button, Space, Dropdown } from 'antd';
|
||||
import { Drawer, Typography, Flex, Button, Space, Dropdown } from '@/shared/antd-imports';
|
||||
import { useAppSelector } from '@/hooks/useAppSelector';
|
||||
import { useAppDispatch } from '@/hooks/useAppDispatch';
|
||||
import { toggleMembersReportsDrawer } from '../membersReportsSlice';
|
||||
import { DownOutlined } from '@ant-design/icons';
|
||||
import { DownOutlined } from '@/shared/antd-imports';
|
||||
import MembersReportsDrawerTabs from './members-reports-drawer-tabs';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import MembersOverviewTasksStatsDrawer from './overviewTab/members-overview-tasks-stats-drawer/members-overview-tasks-stats-drawer';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import { Doughnut } from 'react-chartjs-2';
|
||||
import { Chart, ArcElement, Tooltip } from 'chart.js';
|
||||
import { Badge, Card, Flex, Typography } from 'antd';
|
||||
import { Badge, Card, Flex, Typography } from '@/shared/antd-imports';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { IRPTOverviewMemberChartData } from '@/types/reporting/reporting.types';
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Doughnut } from 'react-chartjs-2';
|
||||
import { Chart, ArcElement, Tooltip } from 'chart.js';
|
||||
import { Badge, Card, Flex, Typography, Tooltip as AntTooltip } from 'antd';
|
||||
import { Badge, Card, Flex, Typography, Tooltip as AntTooltip } from '@/shared/antd-imports';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { IRPTOverviewMemberChartData } from '@/types/reporting/reporting.types';
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import { Doughnut } from 'react-chartjs-2';
|
||||
import { Chart, ArcElement, Tooltip } from 'chart.js';
|
||||
import { Badge, Card, Flex, Typography } from 'antd';
|
||||
import { Badge, Card, Flex, Typography } from '@/shared/antd-imports';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { IRPTOverviewMemberChartData } from '@/types/reporting/reporting.types';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Drawer, Typography } from 'antd';
|
||||
import { Drawer, Typography } from '@/shared/antd-imports';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useAppSelector } from '@/hooks/useAppSelector';
|
||||
import { useAppDispatch } from '@/hooks/useAppDispatch';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { memo } from 'react';
|
||||
import { ConfigProvider, Flex, Skeleton, Spin, Table, TableColumnsType, Typography } from 'antd';
|
||||
import { ConfigProvider, Flex, Skeleton, Spin, Table, TableColumnsType, Typography } from '@/shared/antd-imports';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import CustomTableTitle from '@components/CustomTableTitle';
|
||||
import { simpleDateFormat } from '@/utils/simpleDateFormat';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Drawer, Typography } from 'antd';
|
||||
import { Drawer, Typography } from '@/shared/antd-imports';
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import { useAppSelector } from '@/hooks/useAppSelector';
|
||||
import { useAppDispatch } from '@/hooks/useAppDispatch';
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Badge, Collapse, Flex, Table, TableColumnsType, Tag, Typography } from 'antd';
|
||||
import { Badge, Collapse, Flex, Table, TableColumnsType, Tag, Typography } from '@/shared/antd-imports';
|
||||
import CustomTableTitle from '@components/CustomTableTitle';
|
||||
import { colors } from '@/styles/colors';
|
||||
import dayjs from 'dayjs';
|
||||
import { useAppDispatch } from '@/hooks/useAppDispatch';
|
||||
import { DoubleRightOutlined } from '@ant-design/icons';
|
||||
import { DoubleRightOutlined } from '@/shared/antd-imports';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { setShowTaskDrawer } from '@/features/task-drawer/task-drawer.slice';
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@ import {
|
||||
ClockCircleOutlined,
|
||||
ExclamationCircleOutlined,
|
||||
FileExcelOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import { Button, Card, Flex } from 'antd';
|
||||
} from '@/shared/antd-imports';
|
||||
import { Button, Card, Flex } from '@/shared/antd-imports';
|
||||
import React, { ReactNode } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useAppDispatch } from '@/hooks/useAppDispatch';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Flex } from 'antd';
|
||||
import { Flex } from '@/shared/antd-imports';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import CustomSearchbar from '../../../../../components/CustomSearchbar';
|
||||
import { fetchData } from '@/utils/fetchData';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Badge, Flex, Table, TableColumnsType, Tag, Typography } from 'antd';
|
||||
import { Badge, Flex, Table, TableColumnsType, Tag, Typography } from '@/shared/antd-imports';
|
||||
import React from 'react';
|
||||
import dayjs from 'dayjs';
|
||||
import { DoubleRightOutlined } from '@ant-design/icons';
|
||||
import { DoubleRightOutlined } from '@/shared/antd-imports';
|
||||
import { useAppDispatch } from '@/hooks/useAppDispatch';
|
||||
import { setSelectedTaskId, setShowTaskDrawer } from '@/features/task-drawer/task-drawer.slice';
|
||||
import CustomTableTitle from '@/components/CustomTableTitle';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { IRPTOverviewProject } from '@/types/reporting/reporting.types';
|
||||
import { Flex, Select, Typography } from 'antd';
|
||||
import { Flex, Select, Typography } from '@/shared/antd-imports';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
type ProjectFilterProps = {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { CaretDownFilled } from '@ant-design/icons';
|
||||
import { Button, Card, Checkbox, Dropdown, List, Space } from 'antd';
|
||||
import { CaretDownFilled } from '@/shared/antd-imports';
|
||||
import { Button, Card, Checkbox, Dropdown, List, Space } from '@/shared/antd-imports';
|
||||
import React, { useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Flex, Skeleton } from 'antd';
|
||||
import { Flex, Skeleton } from '@/shared/antd-imports';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import BillableFilter from './billable-filter';
|
||||
import { fetchData } from '@/utils/fetchData';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Card, ConfigProvider, Tag, Timeline, Typography } from 'antd';
|
||||
import { Card, ConfigProvider, Tag, Timeline, Typography } from '@/shared/antd-imports';
|
||||
import { simpleDateFormat } from '@/utils/simpleDateFormat';
|
||||
import { useAppDispatch } from '@/hooks/useAppDispatch';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Drawer, Typography, Flex, Button, Dropdown } from 'antd';
|
||||
import { Drawer, Typography, Flex, Button, Dropdown } from '@/shared/antd-imports';
|
||||
import React, { useState } from 'react';
|
||||
import { useAppSelector } from '../../../../hooks/useAppSelector';
|
||||
import { useAppDispatch } from '../../../../hooks/useAppDispatch';
|
||||
import { setSelectedProject, toggleProjectReportsDrawer } from '../project-reports-slice';
|
||||
import { BankOutlined, DownOutlined } from '@ant-design/icons';
|
||||
import { BankOutlined, DownOutlined } from '@/shared/antd-imports';
|
||||
import ProjectReportsDrawerTabs from './ProjectReportsDrawerTabs';
|
||||
import { colors } from '../../../../styles/colors';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Tabs } from 'antd';
|
||||
import { Tabs } from '@/shared/antd-imports';
|
||||
import { TabsProps } from 'antd/lib';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Flex } from 'antd';
|
||||
import { Flex } from '@/shared/antd-imports';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import CustomSearchbar from '../../../../../components/CustomSearchbar';
|
||||
import ProjectReportsMembersTable from './ProjectReportsMembersTable';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Progress, Table, TableColumnsType } from 'antd';
|
||||
import { Progress, Table, TableColumnsType } from '@/shared/antd-imports';
|
||||
import React from 'react';
|
||||
import CustomTableTitle from '../../../../../components/CustomTableTitle';
|
||||
import { useAppDispatch } from '@/hooks/useAppDispatch';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Drawer, Typography, Flex, Button } from 'antd';
|
||||
import { Drawer, Typography, Flex, Button } from '@/shared/antd-imports';
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import { FileOutlined } from '@ant-design/icons';
|
||||
import { FileOutlined } from '@/shared/antd-imports';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { useAppDispatch } from '@/hooks/useAppDispatch';
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import React from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
import { Badge, Flex, Table, TableColumnsType, Tag, Typography } from 'antd';
|
||||
import { Badge, Flex, Table, TableColumnsType, Tag, Typography } from '@/shared/antd-imports';
|
||||
import dayjs from 'dayjs';
|
||||
import { DoubleRightOutlined } from '@ant-design/icons';
|
||||
import { DoubleRightOutlined } from '@/shared/antd-imports';
|
||||
|
||||
import { useAppDispatch } from '@/hooks/useAppDispatch';
|
||||
import { setShowTaskDrawer } from '@/features/task-drawer/task-drawer.slice';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import { Doughnut } from 'react-chartjs-2';
|
||||
import { Chart, ArcElement, Tooltip } from 'chart.js';
|
||||
import { Badge, Card, Flex, Typography } from 'antd';
|
||||
import { Badge, Card, Flex, Typography } from '@/shared/antd-imports';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { IRPTOverviewProjectTasksByDue } from '@/types/reporting/reporting.types';
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import { Doughnut } from 'react-chartjs-2';
|
||||
import { Chart, ArcElement, Tooltip } from 'chart.js';
|
||||
import { Badge, Card, Flex, Typography } from 'antd';
|
||||
import { Badge, Card, Flex, Typography } from '@/shared/antd-imports';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { IRPTOverviewProjectTasksByPriority } from '@/types/reporting/reporting.types';
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@ import {
|
||||
ClockCircleOutlined,
|
||||
ExclamationCircleOutlined,
|
||||
FileExcelOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import { Card, Flex, Typography } from 'antd';
|
||||
} from '@/shared/antd-imports';
|
||||
import { Card, Flex, Typography } from '@/shared/antd-imports';
|
||||
import React, { ReactNode } from 'react';
|
||||
import { colors } from '../../../../../styles/colors';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import { Doughnut } from 'react-chartjs-2';
|
||||
import { Chart, ArcElement, Tooltip } from 'chart.js';
|
||||
import { Badge, Card, Flex, Typography } from 'antd';
|
||||
import { Badge, Card, Flex, Typography } from '@/shared/antd-imports';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { IRPTOverviewProjectTasksByStatus } from '@/types/reporting/reporting.types';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Badge, Collapse, Flex, Table, TableColumnsType, Tag, Typography } from 'antd';
|
||||
import { Badge, Collapse, Flex, Table, TableColumnsType, Tag, Typography } from '@/shared/antd-imports';
|
||||
import { useEffect } from 'react';
|
||||
import CustomTableTitle from '@/components/CustomTableTitle';
|
||||
import { colors } from '@/styles/colors';
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
fetchTask,
|
||||
setSelectedTaskId,
|
||||
} from '@/features/task-drawer/task-drawer.slice';
|
||||
import { DoubleRightOutlined } from '@ant-design/icons';
|
||||
import { DoubleRightOutlined } from '@/shared/antd-imports';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { fetchPriorities } from '@/features/taskAttributes/taskPrioritySlice';
|
||||
import { fetchPhasesByProjectId } from '@/features/projects/singleProject/phase/phases.slice';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Flex } from 'antd';
|
||||
import { Flex } from '@/shared/antd-imports';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import CustomSearchbar from '@components/CustomSearchbar';
|
||||
import GroupByFilter from './group-by-filter';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { IGroupBy } from '@/features/board/board-slice';
|
||||
import { CaretDownFilled } from '@ant-design/icons';
|
||||
import { Flex, Select } from 'antd';
|
||||
import { CaretDownFilled } from '@/shared/antd-imports';
|
||||
import { Flex, Select } from '@/shared/antd-imports';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Button, Col, DatePicker, Flex, Input, Row } from 'antd';
|
||||
import { Button, Col, DatePicker, Flex, Input, Row } from '@/shared/antd-imports';
|
||||
import React from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { toggleModal } from './scheduleSlice';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Avatar, Drawer, Tabs, TabsProps } from 'antd';
|
||||
import { Avatar, Drawer, Tabs, TabsProps } from '@/shared/antd-imports';
|
||||
import { useAppSelector } from '@/hooks/useAppSelector';
|
||||
import { useAppDispatch } from '@/hooks/useAppDispatch';
|
||||
import { toggleScheduleDrawer } from './scheduleSlice';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Button, Checkbox, Col, Drawer, Form, Input, Row } from 'antd';
|
||||
import { Button, Checkbox, Col, Drawer, Form, Input, Row } from '@/shared/antd-imports';
|
||||
import React, { ReactHTMLElement, useState } from 'react';
|
||||
import { useAppSelector } from '@/hooks/useAppSelector';
|
||||
import { toggleSettingsDrawer, updateSettings } from './scheduleSlice';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useAppDispatch } from '@/hooks/useAppDispatch';
|
||||
import { ScheduleData } from '@/types/schedule/schedule-v2.types';
|
||||
import { Button, Col, DatePicker, Flex, Form, Input, Row } from 'antd';
|
||||
import { Button, Col, DatePicker, Flex, Form, Input, Row } from '@/shared/antd-imports';
|
||||
import React, { useEffect } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { createSchedule, fetchTeamData } from './scheduleSlice';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Avatar, Drawer, Tabs, TabsProps } from 'antd';
|
||||
import { Avatar, Drawer, Tabs, TabsProps } from '@/shared/antd-imports';
|
||||
import React from 'react';
|
||||
import { useAppSelector } from '@/hooks/useAppSelector';
|
||||
import { useAppDispatch } from '@/hooks/useAppDispatch';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Button, Checkbox, Col, Drawer, Form, Input, Row } from 'antd';
|
||||
import { Button, Checkbox, Col, Drawer, Form, Input, Row } from '@/shared/antd-imports';
|
||||
import React, { ReactHTMLElement, useEffect, useState } from 'react';
|
||||
import { useAppSelector } from '@/hooks/useAppSelector';
|
||||
import {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { Tag, Typography } from 'antd';
|
||||
import { Tag, Typography } from '@/shared/antd-imports';
|
||||
import { colors } from '@/styles/colors';
|
||||
import { IProjectCategory } from '@/types/project/projectCategory.types';
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { Select, Tag, Tooltip } from 'antd';
|
||||
import { Select, Tag, Tooltip } from '@/shared/antd-imports';
|
||||
import { CategoryType } from '../../../types/categories.types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { PhaseColorCodes } from '../../../shared/constants';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Button, Drawer, Form, Input, message, Typography } from 'antd';
|
||||
import { Button, Drawer, Form, Input, message, Typography } from '@/shared/antd-imports';
|
||||
import React from 'react';
|
||||
import { useAppSelector } from '@/hooks/useAppSelector';
|
||||
import { useAppDispatch } from '@/hooks/useAppDispatch';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Button, Drawer, Form, Input, message, Typography } from 'antd';
|
||||
import { Button, Drawer, Form, Input, message, Typography } from '@/shared/antd-imports';
|
||||
import React, { useEffect } from 'react';
|
||||
import { useAppSelector } from '@/hooks/useAppSelector';
|
||||
import { useAppDispatch } from '@/hooks/useAppDispatch';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Button, Drawer, Form, Input, message, Typography } from 'antd';
|
||||
import { Button, Drawer, Form, Input, message, Typography } from '@/shared/antd-imports';
|
||||
import React from 'react';
|
||||
import { useAppSelector } from '@/hooks/useAppSelector';
|
||||
import { useAppDispatch } from '@/hooks/useAppDispatch';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Button, Drawer, Form, Input, message, Typography } from 'antd';
|
||||
import { Button, Drawer, Form, Input, message, Typography } from '@/shared/antd-imports';
|
||||
import React, { useEffect } from 'react';
|
||||
import { useAppSelector } from '@/hooks/useAppSelector';
|
||||
import { useAppDispatch } from '@/hooks/useAppDispatch';
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
EntityId,
|
||||
createSelector,
|
||||
} from '@reduxjs/toolkit';
|
||||
import { Task, TaskManagementState, TaskGroup, TaskGrouping } from '@/types/task-management.types';
|
||||
import { Task, TaskManagementState, TaskGroup, TaskGrouping, getSortOrderField } from '@/types/task-management.types';
|
||||
import { ITaskListColumn } from '@/types/tasks/taskList.types';
|
||||
import { RootState } from '@/app/store';
|
||||
import {
|
||||
@@ -64,6 +64,9 @@ const initialState: TaskManagementState = {
|
||||
loadingColumns: false,
|
||||
columns: [],
|
||||
customColumns: [],
|
||||
// Add sort-related state
|
||||
sortField: '',
|
||||
sortOrder: 'ASC',
|
||||
};
|
||||
|
||||
// Async thunk to fetch tasks from API
|
||||
@@ -233,12 +236,16 @@ export const fetchTasksV3 = createAsyncThunk(
|
||||
// Get archived state from task management slice
|
||||
const archivedState = state.taskManagement.archived;
|
||||
|
||||
// Get sort state from task management slice
|
||||
const sortField = state.taskManagement.sortField;
|
||||
const sortOrder = state.taskManagement.sortOrder;
|
||||
|
||||
const config: ITaskListConfigV2 = {
|
||||
id: projectId,
|
||||
archived: archivedState,
|
||||
group: currentGrouping || '',
|
||||
field: '',
|
||||
order: '',
|
||||
field: sortField,
|
||||
order: sortOrder,
|
||||
search: searchValue,
|
||||
statuses: '',
|
||||
members: selectedAssignees,
|
||||
@@ -526,9 +533,25 @@ const taskManagementSlice = createSlice({
|
||||
},
|
||||
addTaskToGroup: (state, action: PayloadAction<{ task: Task; groupId: string }>) => {
|
||||
const { task, groupId } = action.payload;
|
||||
|
||||
state.ids.push(task.id);
|
||||
state.entities[task.id] = task;
|
||||
const group = state.groups.find(g => g.id === groupId);
|
||||
let group = state.groups.find(g => g.id === groupId);
|
||||
|
||||
// If group doesn't exist and it's "Unmapped", create it dynamically
|
||||
if (!group && groupId === 'Unmapped') {
|
||||
const unmappedGroup = {
|
||||
id: 'Unmapped',
|
||||
title: 'Unmapped',
|
||||
taskIds: [],
|
||||
type: 'phase' as const,
|
||||
color: '#fbc84c69',
|
||||
groupValue: 'Unmapped'
|
||||
};
|
||||
state.groups.push(unmappedGroup);
|
||||
group = unmappedGroup;
|
||||
}
|
||||
|
||||
if (group) {
|
||||
group.taskIds.push(task.id);
|
||||
}
|
||||
@@ -660,12 +683,12 @@ const taskManagementSlice = createSlice({
|
||||
const [removed] = newTasks.splice(newTasks.indexOf(sourceTaskId), 1);
|
||||
newTasks.splice(newTasks.indexOf(destinationTaskId), 0, removed);
|
||||
group.taskIds = newTasks;
|
||||
|
||||
// Update order for affected tasks. Assuming simple reordering affects order.
|
||||
// This might need more sophisticated logic based on how `order` is used.
|
||||
|
||||
// Update order for affected tasks using the appropriate sort field
|
||||
const sortField = getSortOrderField(state.grouping?.id);
|
||||
newTasks.forEach((id, index) => {
|
||||
if (newEntities[id]) {
|
||||
newEntities[id] = { ...newEntities[id], order: index };
|
||||
newEntities[id] = { ...newEntities[id], [sortField]: index };
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -673,11 +696,11 @@ const taskManagementSlice = createSlice({
|
||||
// Moving between different groups
|
||||
const sourceGroup = state.groups.find(g => g.id === sourceGroupId);
|
||||
const destinationGroup = state.groups.find(g => g.id === destinationGroupId);
|
||||
|
||||
|
||||
if (sourceGroup && destinationGroup) {
|
||||
// Remove from source group
|
||||
sourceGroup.taskIds = sourceGroup.taskIds.filter(id => id !== sourceTaskId);
|
||||
|
||||
|
||||
// Add to destination group at the correct position relative to destinationTask
|
||||
const destinationIndex = destinationGroup.taskIds.indexOf(destinationTaskId);
|
||||
if (destinationIndex !== -1) {
|
||||
@@ -685,50 +708,17 @@ const taskManagementSlice = createSlice({
|
||||
} else {
|
||||
destinationGroup.taskIds.push(sourceTaskId); // Add to end if destination task not found
|
||||
}
|
||||
|
||||
// Update task's grouping field to reflect new group (e.g., status, priority, phase)
|
||||
// This assumes the group ID directly corresponds to the task's field value
|
||||
if (sourceTask) {
|
||||
let updatedTask = { ...sourceTask };
|
||||
switch (state.grouping?.id) {
|
||||
case IGroupBy.STATUS:
|
||||
updatedTask.status = destinationGroup.id;
|
||||
break;
|
||||
case IGroupBy.PRIORITY:
|
||||
updatedTask.priority = destinationGroup.id;
|
||||
break;
|
||||
case IGroupBy.PHASE:
|
||||
// Handle unmapped group specially
|
||||
if (destinationGroup.id === 'Unmapped' || destinationGroup.title === 'Unmapped') {
|
||||
updatedTask.phase = ''; // Clear phase for unmapped group
|
||||
} else {
|
||||
updatedTask.phase = destinationGroup.id;
|
||||
}
|
||||
break;
|
||||
case IGroupBy.MEMBERS:
|
||||
// If moving to a member group, ensure task is assigned to that member
|
||||
// This assumes the group ID is the member ID
|
||||
if (!updatedTask.assignees) {
|
||||
updatedTask.assignees = [];
|
||||
}
|
||||
if (!updatedTask.assignees.includes(destinationGroup.id)) {
|
||||
updatedTask.assignees.push(destinationGroup.id);
|
||||
}
|
||||
// If moving from a member group, and the task is no longer in any member group,
|
||||
// consider removing the assignment (more complex logic might be needed here)
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
newEntities[sourceTaskId] = updatedTask;
|
||||
}
|
||||
|
||||
// Update order for affected tasks in both groups if necessary
|
||||
|
||||
// Do NOT update the task's grouping field (priority, phase, status) here.
|
||||
// This will be handled by the socket event handler after backend confirmation.
|
||||
|
||||
// Update order for affected tasks in both groups using the appropriate sort field
|
||||
const sortField = getSortOrderField(state.grouping?.id);
|
||||
sourceGroup.taskIds.forEach((id, index) => {
|
||||
if (newEntities[id]) newEntities[id] = { ...newEntities[id], order: index };
|
||||
if (newEntities[id]) newEntities[id] = { ...newEntities[id], [sortField]: index };
|
||||
});
|
||||
destinationGroup.taskIds.forEach((id, index) => {
|
||||
if (newEntities[id]) newEntities[id] = { ...newEntities[id], order: index };
|
||||
if (newEntities[id]) newEntities[id] = { ...newEntities[id], [sortField]: index };
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -754,6 +744,16 @@ const taskManagementSlice = createSlice({
|
||||
toggleArchived: (state) => {
|
||||
state.archived = !state.archived;
|
||||
},
|
||||
setSortField: (state, action: PayloadAction<string>) => {
|
||||
state.sortField = action.payload;
|
||||
},
|
||||
setSortOrder: (state, action: PayloadAction<'ASC' | 'DESC'>) => {
|
||||
state.sortOrder = action.payload;
|
||||
},
|
||||
setSort: (state, action: PayloadAction<{ field: string; order: 'ASC' | 'DESC' }>) => {
|
||||
state.sortField = action.payload.field;
|
||||
state.sortOrder = action.payload.order;
|
||||
},
|
||||
resetTaskManagement: state => {
|
||||
state.loading = false;
|
||||
state.error = null;
|
||||
@@ -762,6 +762,8 @@ const taskManagementSlice = createSlice({
|
||||
state.selectedPriorities = [];
|
||||
state.search = '';
|
||||
state.archived = false;
|
||||
state.sortField = '';
|
||||
state.sortOrder = 'ASC';
|
||||
state.ids = [];
|
||||
state.entities = {};
|
||||
},
|
||||
@@ -958,8 +960,26 @@ const taskManagementSlice = createSlice({
|
||||
.addCase(fetchTasksV3.fulfilled, (state, action) => {
|
||||
state.loading = false;
|
||||
const { allTasks, groups, grouping } = action.payload;
|
||||
tasksAdapter.setAll(state as EntityState<Task, string>, allTasks || []); // Ensure allTasks is an array
|
||||
state.ids = (allTasks || []).map(task => task.id); // Also update ids
|
||||
|
||||
// Preserve existing timer state from old tasks before replacing
|
||||
const oldTasks = state.entities;
|
||||
const tasksWithTimers = (allTasks || []).map(task => {
|
||||
const oldTask = oldTasks[task.id];
|
||||
if (oldTask?.timeTracking?.activeTimer) {
|
||||
// Preserve the timer state from the old task
|
||||
return {
|
||||
...task,
|
||||
timeTracking: {
|
||||
...task.timeTracking,
|
||||
activeTimer: oldTask.timeTracking.activeTimer
|
||||
}
|
||||
};
|
||||
}
|
||||
return task;
|
||||
});
|
||||
|
||||
tasksAdapter.setAll(state as EntityState<Task, string>, tasksWithTimers); // Ensure allTasks is an array
|
||||
state.ids = tasksWithTimers.map(task => task.id); // Also update ids
|
||||
state.groups = groups;
|
||||
state.grouping = grouping;
|
||||
})
|
||||
@@ -1010,7 +1030,7 @@ const taskManagementSlice = createSlice({
|
||||
order: subtask.sort_order || subtask.order || 0,
|
||||
parent_task_id: parentTaskId,
|
||||
is_sub_task: true,
|
||||
sub_tasks_count: 0,
|
||||
sub_tasks_count: subtask.sub_tasks_count || 0, // Use actual count from backend
|
||||
show_sub_tasks: false,
|
||||
}));
|
||||
|
||||
@@ -1128,6 +1148,9 @@ export const {
|
||||
setSearch,
|
||||
setArchived,
|
||||
toggleArchived,
|
||||
setSortField,
|
||||
setSortOrder,
|
||||
setSort,
|
||||
resetTaskManagement,
|
||||
toggleTaskExpansion,
|
||||
addSubtaskToParent,
|
||||
@@ -1159,6 +1182,9 @@ export const selectLoading = (state: RootState) => state.taskManagement.loading;
|
||||
export const selectError = (state: RootState) => state.taskManagement.error;
|
||||
export const selectSelectedPriorities = (state: RootState) => state.taskManagement.selectedPriorities;
|
||||
export const selectSearch = (state: RootState) => state.taskManagement.search;
|
||||
export const selectSortField = (state: RootState) => state.taskManagement.sortField;
|
||||
export const selectSortOrder = (state: RootState) => state.taskManagement.sortOrder;
|
||||
export const selectSort = (state: RootState) => ({ field: state.taskManagement.sortField, order: state.taskManagement.sortOrder });
|
||||
export const selectSubtaskLoading = (state: RootState, taskId: string) => state.taskManagement.loadingSubtasks[taskId] || false;
|
||||
|
||||
// Memoized selectors to prevent unnecessary re-renders
|
||||
@@ -1185,7 +1211,7 @@ export default taskManagementSlice.reducer;
|
||||
|
||||
// V3 API selectors - no processing needed, data is pre-processed by backend
|
||||
export const selectTaskGroupsV3 = (state: RootState) => state.taskManagement.groups;
|
||||
export const selectCurrentGroupingV3 = (state: RootState) => state.taskManagement.grouping;
|
||||
export const selectCurrentGroupingV3 = (state: RootState) => state.grouping.currentGrouping;
|
||||
|
||||
// Column-related selectors
|
||||
export const selectColumns = (state: RootState) => state.taskManagement.columns;
|
||||
|
||||
@@ -14,10 +14,10 @@ const DEFAULT_FIELDS: TaskListField[] = [
|
||||
{ key: 'KEY', label: 'Key', visible: false, order: 1 },
|
||||
{ key: 'DESCRIPTION', label: 'Description', visible: false, order: 2 },
|
||||
{ key: 'PROGRESS', label: 'Progress', visible: true, order: 3 },
|
||||
{ key: 'ASSIGNEES', label: 'Assignees', visible: true, order: 4 },
|
||||
{ key: 'LABELS', label: 'Labels', visible: true, order: 5 },
|
||||
{ key: 'PHASE', label: 'Phase', visible: true, order: 6 },
|
||||
{ key: 'STATUS', label: 'Status', visible: true, order: 7 },
|
||||
{ key: 'STATUS', label: 'Status', visible: true, order: 4 },
|
||||
{ key: 'ASSIGNEES', label: 'Assignees', visible: true, order: 5 },
|
||||
{ key: 'LABELS', label: 'Labels', visible: true, order: 6 },
|
||||
{ key: 'PHASE', label: 'Phase', visible: true, order: 7 },
|
||||
{ key: 'PRIORITY', label: 'Priority', visible: true, order: 8 },
|
||||
{ key: 'TIME_TRACKING', label: 'Time Tracking', visible: true, order: 9 },
|
||||
{ key: 'ESTIMATION', label: 'Estimation', visible: false, order: 10 },
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ConfigProvider, theme } from 'antd';
|
||||
import { ConfigProvider, theme } from '@/shared/antd-imports';
|
||||
import React, { useEffect, useRef, memo, useMemo, useCallback } from 'react';
|
||||
import { useAppSelector } from '@/hooks/useAppSelector';
|
||||
import { useAppDispatch } from '@/hooks/useAppDispatch';
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Avatar, Button, Card, Divider, Drawer, Tag, Timeline, Typography } from 'antd';
|
||||
import { Avatar, Button, Card, Divider, Drawer, Tag, Timeline, Typography } from '@/shared/antd-imports';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useAppSelector } from '@/hooks/useAppSelector';
|
||||
import { useAppDispatch } from '@/hooks/useAppDispatch';
|
||||
import { toggleTimeLogDrawer } from './timeLogSlice';
|
||||
import { DownloadOutlined } from '@ant-design/icons';
|
||||
import { DownloadOutlined } from '@/shared/antd-imports';
|
||||
import jsonData from './ProjectTimeLog.json';
|
||||
import { AvatarNamesMap, durations } from '../../../shared/constants';
|
||||
import './ProjectTimeLogDrawer.css';
|
||||
|
||||
Reference in New Issue
Block a user