diff --git a/src/containers/Projects/containers/ProjectAlerts/ProjectStatusAlert.tsx b/src/containers/Projects/containers/ProjectAlerts/ProjectStatusAlert.tsx
new file mode 100644
index 000000000..886c65070
--- /dev/null
+++ b/src/containers/Projects/containers/ProjectAlerts/ProjectStatusAlert.tsx
@@ -0,0 +1,75 @@
+import React from 'react';
+import intl from 'react-intl-universal';
+import { FormattedMessage as T, FormattedHTMLMessage } from '@/components';
+import { Intent, Alert } from '@blueprintjs/core';
+import { AppToaster } from '@/components';
+import { useProjectStatus } from '../../hooks';
+
+import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
+import withAlertActions from '@/containers/Alert/withAlertActions';
+
+import { compose } from '@/utils';
+
+/**
+ * Project status alert.
+ * @returns
+ */
+function ProjectStatusAlert({
+ name,
+ isOpen,
+ payload: { projectId, status },
+
+ // #withAlertActions
+ closeAlert,
+}) {
+ const { mutateAsync: statusProjectMutate, isLoading } = useProjectStatus();
+
+ // handle cancel alert.
+ const handleCancelAlert = () => {
+ closeAlert(name);
+ };
+
+ // handle confirm alert.
+ const handleConfirmAlert = () => {
+ const values = {
+ status: status !== 'InProgress' ? 'InProgress' : 'Closed',
+ };
+
+ statusProjectMutate([projectId, values])
+ .then(() => {
+ AppToaster.show({
+ message: intl.get('projects.alert.status_message'),
+ intent: Intent.SUCCESS,
+ });
+ })
+ .catch(
+ ({
+ response: {
+ data: { errors },
+ },
+ }) => {},
+ )
+ .finally(() => {
+ closeAlert(name);
+ });
+ };
+
+ return (
+ }
+ confirmButtonText={}
+ intent={Intent.WARNING}
+ isOpen={isOpen}
+ onCancel={handleCancelAlert}
+ onConfirm={handleConfirmAlert}
+ loading={isLoading}
+ >
+
+
+ );
+}
+
+export default compose(
+ withAlertStoreConnect(),
+ withAlertActions,
+)(ProjectStatusAlert);
diff --git a/src/containers/Projects/containers/ProjectAlerts/index.ts b/src/containers/Projects/containers/ProjectAlerts/index.ts
index 17a6acf14..f5c255e5b 100644
--- a/src/containers/Projects/containers/ProjectAlerts/index.ts
+++ b/src/containers/Projects/containers/ProjectAlerts/index.ts
@@ -8,6 +8,8 @@ const ProjectTimesheetDeleteAlert = React.lazy(
() => import('./ProjectTimesheetDeleteAlert'),
);
+const ProjectStatusAlert = React.lazy(() => import('./ProjectStatusAlert'));
+
/**
* Project alerts.
*/
@@ -15,4 +17,5 @@ export default [
{ name: 'project-delete', component: ProjectDeleteAlert },
{ name: 'project-task-delete', component: ProjectTaskDeleteAlert },
{ name: 'project-timesheet-delete', component: ProjectTimesheetDeleteAlert },
+ { name: 'project-status', component: ProjectStatusAlert },
];
diff --git a/src/containers/Projects/containers/ProjectDetails/ProjectTasks/ProjectTasksHeader.tsx b/src/containers/Projects/containers/ProjectDetails/ProjectTasks/ProjectTasksHeader.tsx
index 2acf0531e..f6e86bd66 100644
--- a/src/containers/Projects/containers/ProjectDetails/ProjectTasks/ProjectTasksHeader.tsx
+++ b/src/containers/Projects/containers/ProjectDetails/ProjectTasks/ProjectTasksHeader.tsx
@@ -35,7 +35,7 @@ export function ProjectTasksHeader() {
}
+ value={}
>
4 days to go
diff --git a/src/containers/Projects/containers/ProjectDetails/common.ts b/src/containers/Projects/containers/ProjectDetails/common.ts
index aa811c2f0..d734ddbcb 100644
--- a/src/containers/Projects/containers/ProjectDetails/common.ts
+++ b/src/containers/Projects/containers/ProjectDetails/common.ts
@@ -1,9 +1,9 @@
import intl from 'react-intl-universal';
export const projectTranslations = [
- { name: intl.get('project_details.new_expenses'), path: 'expense' },
+ { name: intl.get('project_details.new_expense'), path: 'expense' },
{
- name: intl.get('project_details.new_estimated_expenses'),
+ name: intl.get('project_details.new_estimated_expense'),
path: 'estimated_expense',
},
];
diff --git a/src/containers/Projects/containers/ProjectsLanding/ProjectsDataTable.tsx b/src/containers/Projects/containers/ProjectsLanding/ProjectsDataTable.tsx
index ecc89f3d5..9ed376a98 100644
--- a/src/containers/Projects/containers/ProjectsLanding/ProjectsDataTable.tsx
+++ b/src/containers/Projects/containers/ProjectsLanding/ProjectsDataTable.tsx
@@ -43,6 +43,10 @@ function ProjectsDataTable({
openAlert('project-delete', { projectId: id });
};
+ const handleProjectStatus = ({ id, status_formatted }) => {
+ openAlert('project-status', { projectId: id, status: status_formatted });
+ };
+
// Retrieve projects table columns.
const columns = useProjectsListColumns();
@@ -109,6 +113,7 @@ function ProjectsDataTable({
onEdit: handleEditProject,
onDelete: handleDeleteProject,
onNewTask: handleNewTaskButtonClick,
+ onStatus: handleProjectStatus,
}}
/>
);
diff --git a/src/containers/Projects/containers/ProjectsLanding/components.tsx b/src/containers/Projects/containers/ProjectsLanding/components.tsx
index 5a6fccea2..0eb8e1929 100644
--- a/src/containers/Projects/containers/ProjectsLanding/components.tsx
+++ b/src/containers/Projects/containers/ProjectsLanding/components.tsx
@@ -10,21 +10,27 @@ import {
Intent,
ProgressBar,
} from '@blueprintjs/core';
-import { Icon, FormatDate, Choose, FormattedMessage as T } from '@/components';
+import {
+ Icon,
+ FormatDate,
+ Choose,
+ If,
+ FormattedMessage as T,
+} from '@/components';
import { safeCallback, firstLettersArgs, calculateStatus } from '@/utils';
/**
* project status.
*/
-export function ProjectStatus({ project }) {
+export function ProjectStatus({ row }) {
return (
- {project.task_amount}
+ {row.cost_estimate}
);
@@ -33,22 +39,22 @@ export function ProjectStatus({ project }) {
/**
* status accessor.
*/
-export const StatusAccessor = (project) => {
+export const StatusAccessor = (row) => {
return (
-
-
+
+
-
+
-
+ {row.status_formatted}
-
-
+
+
-
+
);
};
@@ -67,7 +73,7 @@ export const AvatarCell = ({ row: { original }, size }) => (
*/
export const ActionsMenu = ({
row: { original },
- payload: { onEdit, onDelete, onViewDetails, onNewTask },
+ payload: { onEdit, onDelete, onViewDetails, onNewTask, onStatus },
}) => (