From a17843ddbef9645754260646190e6e0081d031d7 Mon Sep 17 00:00:00 2001 From: elforjani13 <39470382+elforjani13@users.noreply.github.com> Date: Sat, 16 Jul 2022 04:20:17 +0200 Subject: [PATCH] feat: add project. --- src/components/Datatable/DataTable.tsx | 1 + src/components/Datatable/TableHeader.tsx | 12 +- src/components/DialogsContainer.tsx | 14 ++ src/constants/dialogs.ts | 5 + src/constants/sidebarMenu.tsx | 32 ++++ src/containers/AlertsContainer/registered.tsx | 2 + .../ChangeTypesSelect.tsx} | 17 +- .../Projects/components/ExpenseSelect.tsx | 67 ++++++++ .../components/FInputGroupComponent.tsx | 19 +++ .../ProjectsSelect.tsx} | 12 +- .../components/TaskSelect.tsx | 2 +- src/containers/Projects/components/index.ts | 5 + .../EstimatedExpense.schema.tsx | 19 +++ .../EstimatedExpenseForm.tsx | 56 +++++++ .../EstimatedExpenseFormChargeFields.tsx | 53 +++++++ .../EstimatedExpenseFormConent.tsx | 17 ++ .../EstimatedExpenseFormDialogContent.tsx | 22 +++ .../EstimatedExpenseFormFields.tsx | 117 ++++++++++++++ .../EstimatedExpenseFormFloatingActions.tsx | 47 ++++++ .../EstimatedExpenseFormProvider.tsx | 30 ++++ .../EstimatedExpenseFormDialog/index.tsx | 55 +++++++ .../ProjectAlerts/ProjectDeleteAlert.tsx | 78 ++++++++++ .../containers/ProjectAlerts/index.ts | 8 + .../ProjectDetailActionsBar.tsx | 39 ++--- .../ProjectDetails/ProjectDetailProvider.tsx | 5 +- .../ProjectDetails/ProjectDetailTabs.tsx | 26 +++- .../ProjectPurchasesTable.tsx | 58 +++++++ .../ProjectPurchasesTable/components.tsx | 21 +++ .../ProjectPurchasesTable/hooks.ts | 73 +++++++++ .../ProjectPurchasesTable/index.tsx | 16 ++ .../ProjectSalesTable/ProjectSalesTable.tsx | 57 +++++++ .../ProjectSalesTable/components.tsx | 22 +++ .../ProjectDetails/ProjectSalesTable/hooks.ts | 73 +++++++++ .../ProjectSalesTable/index.tsx | 18 +++ .../ProjectTimesheetsHeader.tsx} | 8 +- .../ProjectTimesheetsTable.tsx | 104 +++++++++++++ .../components.tsx | 46 +----- .../ProjectDetails/ProjectTimeSheets/hooks.ts | 43 +++++ .../ProjectTimeSheets/index.tsx | 27 ++++ .../ProjectTimesheet/TimesheetsTable.tsx | 124 --------------- .../ProjectDetails/ProjectTimesheet/index.tsx | 27 ---- .../containers/ProjectDetails/common.ts | 9 ++ .../components/FinancialSection.tsx | 8 +- ...lect.tsx => ProjectTransactionsSelect.tsx} | 15 +- .../ProjectDetails/components/index.tsx | 3 +- .../containers/ProjectDetails/index.tsx | 11 +- .../ProjectExpenseForm.schema.tsx | 22 +++ .../ProjectExpenseForm/ProjectExpenseForm.tsx | 64 ++++++++ .../ProjectExpenseFormChargeFields.tsx | 54 +++++++ .../ProjectExpenseFormContent.tsx | 17 ++ .../ProjectExpenseFormDialogContent.tsx | 19 +++ .../ProjectExpenseFormFields.tsx | 147 ++++++++++++++++++ .../ProjectExpenseFormProvider.tsx | 30 ++++ .../ProjectExpneseFormFloatingActions.tsx | 43 +++++ .../containers/ProjectExpenseForm/index.tsx | 55 +++++++ .../ProjectFormDialog/ProjectForm.schema.tsx | 11 +- .../ProjectFormDialog/ProjectForm.tsx | 47 ++++-- .../ProjectFormDialog/ProjectFormFields.tsx | 31 ++-- .../ProjectFormFloatingActions.tsx | 15 +- .../ProjectFormDialog/ProjectFormProvider.tsx | 24 ++- .../containers/ProjectFormDialog/index.tsx | 17 +- .../ProjectTaskForm.schema.tsx} | 7 +- .../ProjectTaskForm.tsx} | 29 ++-- .../ProjectTaskFormContent.tsx | 17 ++ .../ProjectTaskFormDialogContent.tsx | 18 +++ .../ProjectTaskFormFields.tsx} | 39 ++--- .../ProjectTaskFormFloatingActions.tsx} | 15 +- .../ProjectTaskFormProvider.tsx | 31 ++++ .../ProjectTaskFormDialog/index.tsx | 36 +++++ .../ProjectTimeEntryForm.schema.tsx | 20 +++ .../ProjectTimeEntryForm.tsx} | 25 ++- .../ProjectTimeEntryFormContent.tsx | 17 ++ .../ProjectTimeEntryFormDialogContent.tsx | 24 +++ .../ProjectTimeEntryFormFields.tsx} | 36 ++--- .../ProjectTimeEntryFormFloatingActions.tsx} | 17 +- .../ProjectTimeEntryFormProvider.tsx | 31 ++++ .../index.tsx | 26 ++-- .../ProjectsLanding/ProjectsActionsBar.tsx | 13 +- .../ProjectsLanding/ProjectsDataTable.tsx | 119 +++++++------- .../ProjectsLanding/ProjectsEmptyStatus.tsx | 43 +++++ .../ProjectsLanding/ProjectsList.tsx | 4 +- .../ProjectsLanding/ProjectsListProvider.tsx | 31 +++- .../ProjectsLanding/ProjectsViewTabs.tsx | 5 +- .../containers/ProjectsLanding/components.tsx | 17 +- .../ProjectsLanding/withProjects.tsx | 2 +- .../ProjectsLanding/withProjectsActions.tsx | 2 +- .../TaskFormDialog/TaskFormContent.tsx | 17 -- .../TaskFormDialog/TaskFormDialogContent.tsx | 18 --- .../TaskFormDialog/TaskFormProvider.tsx | 31 ---- .../containers/TaskFormDialog/index.tsx | 34 ---- .../TimeEntryForm.schema.tsx | 19 --- .../TimeEntryFormContent.tsx | 17 -- .../TimeEntryFormDialogContent.tsx | 24 --- .../TimeEntryFormProvider.tsx | 31 ---- .../components/ProjectSelect.tsx | 63 -------- .../TimeEntryFormDialog/components/index.ts | 2 - .../containers/common/modalChargeOptions.ts | 17 ++ src/containers/Projects/hooks/index.ts | 124 +++++++++++++++ src/containers/Projects/hooks/type.ts | 11 ++ src/lang/en/index.json | 107 ++++++++++--- src/routes/dashboard.tsx | 16 ++ src/store/Project/projects.actions.ts | 2 +- src/store/Project/projects.reducer.ts | 4 +- src/store/Project/projects.selectors.ts | 4 +- 104 files changed, 2490 insertions(+), 794 deletions(-) rename src/containers/Projects/{containers/TaskFormDialog/components.tsx => components/ChangeTypesSelect.tsx} (57%) create mode 100644 src/containers/Projects/components/ExpenseSelect.tsx create mode 100644 src/containers/Projects/components/FInputGroupComponent.tsx rename src/containers/Projects/{containers/ProjectDetails/components/ProjectSelect.tsx => components/ProjectsSelect.tsx} (77%) rename src/containers/Projects/{containers/TimeEntryFormDialog => }/components/TaskSelect.tsx (95%) create mode 100644 src/containers/Projects/components/index.ts create mode 100644 src/containers/Projects/containers/EstimatedExpenseFormDialog/EstimatedExpense.schema.tsx create mode 100644 src/containers/Projects/containers/EstimatedExpenseFormDialog/EstimatedExpenseForm.tsx create mode 100644 src/containers/Projects/containers/EstimatedExpenseFormDialog/EstimatedExpenseFormChargeFields.tsx create mode 100644 src/containers/Projects/containers/EstimatedExpenseFormDialog/EstimatedExpenseFormConent.tsx create mode 100644 src/containers/Projects/containers/EstimatedExpenseFormDialog/EstimatedExpenseFormDialogContent.tsx create mode 100644 src/containers/Projects/containers/EstimatedExpenseFormDialog/EstimatedExpenseFormFields.tsx create mode 100644 src/containers/Projects/containers/EstimatedExpenseFormDialog/EstimatedExpenseFormFloatingActions.tsx create mode 100644 src/containers/Projects/containers/EstimatedExpenseFormDialog/EstimatedExpenseFormProvider.tsx create mode 100644 src/containers/Projects/containers/EstimatedExpenseFormDialog/index.tsx create mode 100644 src/containers/Projects/containers/ProjectAlerts/ProjectDeleteAlert.tsx create mode 100644 src/containers/Projects/containers/ProjectAlerts/index.ts create mode 100644 src/containers/Projects/containers/ProjectDetails/ProjectPurchasesTable/ProjectPurchasesTable.tsx create mode 100644 src/containers/Projects/containers/ProjectDetails/ProjectPurchasesTable/components.tsx create mode 100644 src/containers/Projects/containers/ProjectDetails/ProjectPurchasesTable/hooks.ts create mode 100644 src/containers/Projects/containers/ProjectDetails/ProjectPurchasesTable/index.tsx create mode 100644 src/containers/Projects/containers/ProjectDetails/ProjectSalesTable/ProjectSalesTable.tsx create mode 100644 src/containers/Projects/containers/ProjectDetails/ProjectSalesTable/components.tsx create mode 100644 src/containers/Projects/containers/ProjectDetails/ProjectSalesTable/hooks.ts create mode 100644 src/containers/Projects/containers/ProjectDetails/ProjectSalesTable/index.tsx rename src/containers/Projects/containers/ProjectDetails/{ProjectTimesheet/TimesheetsHeader.tsx => ProjectTimeSheets/ProjectTimesheetsHeader.tsx} (88%) create mode 100644 src/containers/Projects/containers/ProjectDetails/ProjectTimeSheets/ProjectTimesheetsTable.tsx rename src/containers/Projects/containers/ProjectDetails/{ProjectTimesheet => ProjectTimeSheets}/components.tsx (64%) create mode 100644 src/containers/Projects/containers/ProjectDetails/ProjectTimeSheets/hooks.ts create mode 100644 src/containers/Projects/containers/ProjectDetails/ProjectTimeSheets/index.tsx delete mode 100644 src/containers/Projects/containers/ProjectDetails/ProjectTimesheet/TimesheetsTable.tsx delete mode 100644 src/containers/Projects/containers/ProjectDetails/ProjectTimesheet/index.tsx create mode 100644 src/containers/Projects/containers/ProjectDetails/common.ts rename src/containers/Projects/containers/ProjectDetails/components/{TransactionSelect.tsx => ProjectTransactionsSelect.tsx} (70%) create mode 100644 src/containers/Projects/containers/ProjectExpenseForm/ProjectExpenseForm.schema.tsx create mode 100644 src/containers/Projects/containers/ProjectExpenseForm/ProjectExpenseForm.tsx create mode 100644 src/containers/Projects/containers/ProjectExpenseForm/ProjectExpenseFormChargeFields.tsx create mode 100644 src/containers/Projects/containers/ProjectExpenseForm/ProjectExpenseFormContent.tsx create mode 100644 src/containers/Projects/containers/ProjectExpenseForm/ProjectExpenseFormDialogContent.tsx create mode 100644 src/containers/Projects/containers/ProjectExpenseForm/ProjectExpenseFormFields.tsx create mode 100644 src/containers/Projects/containers/ProjectExpenseForm/ProjectExpenseFormProvider.tsx create mode 100644 src/containers/Projects/containers/ProjectExpenseForm/ProjectExpneseFormFloatingActions.tsx create mode 100644 src/containers/Projects/containers/ProjectExpenseForm/index.tsx rename src/containers/Projects/containers/{TaskFormDialog/TaskForm.schema.tsx => ProjectTaskFormDialog/ProjectTaskForm.schema.tsx} (66%) rename src/containers/Projects/containers/{TaskFormDialog/TaskForm.tsx => ProjectTaskFormDialog/ProjectTaskForm.tsx} (54%) create mode 100644 src/containers/Projects/containers/ProjectTaskFormDialog/ProjectTaskFormContent.tsx create mode 100644 src/containers/Projects/containers/ProjectTaskFormDialog/ProjectTaskFormDialogContent.tsx rename src/containers/Projects/containers/{TaskFormDialog/TaskFormFields.tsx => ProjectTaskFormDialog/ProjectTaskFormFields.tsx} (65%) rename src/containers/Projects/containers/{TaskFormDialog/TaskFormFloatingActions.tsx => ProjectTaskFormDialog/ProjectTaskFormFloatingActions.tsx} (69%) create mode 100644 src/containers/Projects/containers/ProjectTaskFormDialog/ProjectTaskFormProvider.tsx create mode 100644 src/containers/Projects/containers/ProjectTaskFormDialog/index.tsx create mode 100644 src/containers/Projects/containers/ProjectTimeEntryFormDialog/ProjectTimeEntryForm.schema.tsx rename src/containers/Projects/containers/{TimeEntryFormDialog/TimeEntryForm.tsx => ProjectTimeEntryFormDialog/ProjectTimeEntryForm.tsx} (60%) create mode 100644 src/containers/Projects/containers/ProjectTimeEntryFormDialog/ProjectTimeEntryFormContent.tsx create mode 100644 src/containers/Projects/containers/ProjectTimeEntryFormDialog/ProjectTimeEntryFormDialogContent.tsx rename src/containers/Projects/containers/{TimeEntryFormDialog/TimeEntryFormFields.tsx => ProjectTimeEntryFormDialog/ProjectTimeEntryFormFields.tsx} (71%) rename src/containers/Projects/containers/{TimeEntryFormDialog/TimeEntryFormFloatingActions.tsx => ProjectTimeEntryFormDialog/ProjectTimeEntryFormFloatingActions.tsx} (65%) create mode 100644 src/containers/Projects/containers/ProjectTimeEntryFormDialog/ProjectTimeEntryFormProvider.tsx rename src/containers/Projects/containers/{TimeEntryFormDialog => ProjectTimeEntryFormDialog}/index.tsx (58%) create mode 100644 src/containers/Projects/containers/ProjectsLanding/ProjectsEmptyStatus.tsx delete mode 100644 src/containers/Projects/containers/TaskFormDialog/TaskFormContent.tsx delete mode 100644 src/containers/Projects/containers/TaskFormDialog/TaskFormDialogContent.tsx delete mode 100644 src/containers/Projects/containers/TaskFormDialog/TaskFormProvider.tsx delete mode 100644 src/containers/Projects/containers/TaskFormDialog/index.tsx delete mode 100644 src/containers/Projects/containers/TimeEntryFormDialog/TimeEntryForm.schema.tsx delete mode 100644 src/containers/Projects/containers/TimeEntryFormDialog/TimeEntryFormContent.tsx delete mode 100644 src/containers/Projects/containers/TimeEntryFormDialog/TimeEntryFormDialogContent.tsx delete mode 100644 src/containers/Projects/containers/TimeEntryFormDialog/TimeEntryFormProvider.tsx delete mode 100644 src/containers/Projects/containers/TimeEntryFormDialog/components/ProjectSelect.tsx delete mode 100644 src/containers/Projects/containers/TimeEntryFormDialog/components/index.ts create mode 100644 src/containers/Projects/containers/common/modalChargeOptions.ts create mode 100644 src/containers/Projects/hooks/index.ts create mode 100644 src/containers/Projects/hooks/type.ts diff --git a/src/components/Datatable/DataTable.tsx b/src/components/Datatable/DataTable.tsx index e941a1fcd..deddcddf7 100644 --- a/src/components/Datatable/DataTable.tsx +++ b/src/components/Datatable/DataTable.tsx @@ -197,6 +197,7 @@ export function DataTable(props) { DataTable.defaultProps = { pagination: false, hidePaginationNoPages: true, + hideTableHeader: false, size: null, spinnerProps: { size: 30 }, diff --git a/src/components/Datatable/TableHeader.tsx b/src/components/Datatable/TableHeader.tsx index 425849fb7..bc99362d4 100644 --- a/src/components/Datatable/TableHeader.tsx +++ b/src/components/Datatable/TableHeader.tsx @@ -79,9 +79,19 @@ function TableHeaderGroup({ headerGroup }) { export default function TableHeader() { const { table: { headerGroups, page }, - props: { TableHeaderSkeletonRenderer, headerLoading, progressBarLoading }, + props: { + TableHeaderSkeletonRenderer, + headerLoading, + progressBarLoading, + hideTableHeader, + }, } = useContext(TableContext); + // Can't contiunue if the thead is disabled. + if (hideTableHeader) { + return null; + } + if (headerLoading && TableHeaderSkeletonRenderer) { return ; } diff --git a/src/components/DialogsContainer.tsx b/src/components/DialogsContainer.tsx index 10e60b3ec..39b363c7f 100644 --- a/src/components/DialogsContainer.tsx +++ b/src/components/DialogsContainer.tsx @@ -40,6 +40,11 @@ import BranchActivateDialog from '@/containers/Dialogs/BranchActivateDialog'; import WarehouseActivateDialog from '@/containers/Dialogs/WarehouseActivateDialog'; import CustomerOpeningBalanceDialog from '@/containers/Dialogs/CustomerOpeningBalanceDialog'; import VendorOpeningBalanceDialog from '@/containers/Dialogs/VendorOpeningBalanceDialog'; +import ProjectFormDialog from '@/containers/Projects/containers/ProjectFormDialog'; +import ProjectTaskFormDialog from '@/containers/Projects/containers/ProjectTaskFormDialog'; +import ProjectTimeEntryFormDialog from '@/containers/Projects/containers/ProjectTimeEntryFormDialog'; +import ProjectExpenseForm from '@/containers/Projects/containers/ProjectExpenseForm'; +import EstimatedExpenseFormDialog from '@/containers/Projects/containers/EstimatedExpenseFormDialog'; import { DialogsName } from '@/constants/dialogs'; @@ -116,6 +121,15 @@ export default function DialogsContainer() { + + + + + ); } diff --git a/src/constants/dialogs.ts b/src/constants/dialogs.ts index 0aa5c21b0..01b34d594 100644 --- a/src/constants/dialogs.ts +++ b/src/constants/dialogs.ts @@ -38,4 +38,9 @@ export enum DialogsName { WarehouseActivateForm = 'warehouse-activate', CustomerOpeningBalanceForm = 'customer-opening-balance', VendorOpeningBalanceForm = 'vendor-opening-balance', + ProjectForm = 'project-form', + ProjectTaskForm = 'project-task-form', + ProjectTimeEntryForm = 'project-time-entry-form', + ProjectExpenseForm = 'project-expense-form', + EstimateExpenseForm = 'estimate-expense-form', } diff --git a/src/constants/sidebarMenu.tsx b/src/constants/sidebarMenu.tsx index 2b38073e6..b003a90a8 100644 --- a/src/constants/sidebarMenu.tsx +++ b/src/constants/sidebarMenu.tsx @@ -538,6 +538,38 @@ export const SidebarMenu = [ }, ], }, + // --------------------- + // # Projects Management + // --------------------- + { + text: 'Projects', + type: ISidebarMenuItemType.Overlay, + overlayId: ISidebarMenuOverlayIds.Projects, + children: [ + { + text: 'Projects Management', + type: ISidebarMenuItemType.Group, + children: [ + { + text: 'Projects', + href: '/projects', + type: ISidebarMenuItemType.Link, + }, + ], + }, + { + text: , + type: ISidebarMenuItemType.Group, + children: [ + { + text: , + type: ISidebarMenuItemType.Dialog, + dialogName: 'project-form', + }, + ], + }, + ], + }, // --------------- // # Reports // --------------- diff --git a/src/containers/AlertsContainer/registered.tsx b/src/containers/AlertsContainer/registered.tsx index 6fd76562f..309a42cd1 100644 --- a/src/containers/AlertsContainer/registered.tsx +++ b/src/containers/AlertsContainer/registered.tsx @@ -23,6 +23,7 @@ import TransactionsLockingAlerts from '@/containers/TransactionsLocking/Transact import WarehousesAlerts from '@/containers/Preferences/Warehouses/WarehousesAlerts'; import WarehousesTransfersAlerts from '@/containers/WarehouseTransfers/WarehousesTransfersAlerts'; import BranchesAlerts from '@/containers/Preferences/Branches/BranchesAlerts'; +import ProjectAlerts from '@/containers/Projects/containers/ProjectAlerts'; export default [ ...AccountsAlerts, @@ -50,4 +51,5 @@ export default [ ...WarehousesAlerts, ...WarehousesTransfersAlerts, ...BranchesAlerts, + ...ProjectAlerts, ]; diff --git a/src/containers/Projects/containers/TaskFormDialog/components.tsx b/src/containers/Projects/components/ChangeTypesSelect.tsx similarity index 57% rename from src/containers/Projects/containers/TaskFormDialog/components.tsx rename to src/containers/Projects/components/ChangeTypesSelect.tsx index d5633208d..2587f59d6 100644 --- a/src/containers/Projects/containers/TaskFormDialog/components.tsx +++ b/src/containers/Projects/components/ChangeTypesSelect.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { MenuItem, Button } from '@blueprintjs/core'; -import { FSelect } from 'components'; +import { FSelect } from '@/components'; /** * @@ -8,7 +8,7 @@ import { FSelect } from 'components'; * @param {*} param1 * @returns */ -const taskModalChargeRenderer = (item, { handleClick, modifiers, query }) => { +const chargeTypeItemRenderer = (item, { handleClick, modifiers, query }) => { return ( { ); }; -const taskModalChargeSelectProps = { - itemRenderer: taskModalChargeRenderer, +const chargeTypeSelectProps = { + itemRenderer: chargeTypeItemRenderer, valueAccessor: 'value', labelAccessor: 'name', }; @@ -30,22 +30,21 @@ const taskModalChargeSelectProps = { * @param param0 * @returns */ -export function TaskModalChargeSelect({ items, ...rest }) { +export function ChangeTypesSelect({ items, ...rest }) { return ( ); } - /** * * @param param0 * @returns */ -function TaskModalChargeSelectButton({ label }) { +function ChargeTypeSelectButton({ label }) { return + + + + ); +} + +export default compose(withDialogActions)(EstimatedExpenseFormFloatingActions); diff --git a/src/containers/Projects/containers/EstimatedExpenseFormDialog/EstimatedExpenseFormProvider.tsx b/src/containers/Projects/containers/EstimatedExpenseFormDialog/EstimatedExpenseFormProvider.tsx new file mode 100644 index 000000000..0ec265aea --- /dev/null +++ b/src/containers/Projects/containers/EstimatedExpenseFormDialog/EstimatedExpenseFormProvider.tsx @@ -0,0 +1,30 @@ +import React from 'react'; +import { DialogContent } from '@/components'; + +const EstimatedExpenseFormContext = React.createContext(); + +/** + * Estimated expense form provider. + * @returns + */ +function EstimatedExpenseFormProvider({ + //#OwnProps + dialogName, + estimatedExpenseId, + ...props +}) { + // state provider. + const provider = { + dialogName, + }; + return ( + + + + ); +} + +const useEstimatedExpenseFormContext = () => + React.useContext(EstimatedExpenseFormContext); + +export { EstimatedExpenseFormProvider, useEstimatedExpenseFormContext }; diff --git a/src/containers/Projects/containers/EstimatedExpenseFormDialog/index.tsx b/src/containers/Projects/containers/EstimatedExpenseFormDialog/index.tsx new file mode 100644 index 000000000..38a3a988a --- /dev/null +++ b/src/containers/Projects/containers/EstimatedExpenseFormDialog/index.tsx @@ -0,0 +1,55 @@ +import React from 'react'; +import styled from 'styled-components'; +import { Dialog, DialogSuspense, FormattedMessage as T } from '@/components'; +import withDialogRedux from '@/components/DialogReduxConnect'; +import { compose } from '@/utils'; + +const EstimatedExpenseFormDialogContent = React.lazy( + () => import('./EstimatedExpenseFormDialogContent'), +); + +/** + * Estimate expense form dialog. + * @returns + */ +function EstimatedExpenseFormDialog({ + dialogName, + payload: { projectId = null }, + isOpen, +}) { + return ( + } + isOpen={isOpen} + autoFocus={true} + canEscapeKeyClose={true} + style={{ width: '400px' }} + > + + + + + ); +} + +export default compose(withDialogRedux())(EstimatedExpenseFormDialog); + +const EstimateExpenseFormDialogRoot = styled(Dialog)` + .bp3-dialog-body { + .bp3-form-group { + margin-bottom: 15px; + + label.bp3-label { + margin-bottom: 3px; + font-size: 13px; + } + } + } + .bp3-dialog-footer { + padding-top: 10px; + } +`; diff --git a/src/containers/Projects/containers/ProjectAlerts/ProjectDeleteAlert.tsx b/src/containers/Projects/containers/ProjectAlerts/ProjectDeleteAlert.tsx new file mode 100644 index 000000000..d5544f186 --- /dev/null +++ b/src/containers/Projects/containers/ProjectAlerts/ProjectDeleteAlert.tsx @@ -0,0 +1,78 @@ +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 { useDeleteProject } from '../../hooks'; + +import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect'; +import withAlertActions from '@/containers/Alert/withAlertActions'; + +import { compose } from '@/utils'; + +/** + * Project delete alert. + */ +function ProjectDeleteAlert({ + name, + + // #withAlertStoreConnect + isOpen, + payload: { projectId }, + + // #withAlertActions + closeAlert, + + // #withDrawerActions + closeDrawer, +}) { + const { mutateAsync: deleteProjectMutate, isLoading } = useDeleteProject(); + + // handle cancel delete project alert. + const handleCancelDeleteAlert = () => { + closeAlert(name); + }; + + // handleConfirm delete project + const handleConfirmProjectDelete = () => { + deleteProjectMutate(projectId) + .then(() => { + AppToaster.show({ + message: intl.get('projects.alert.delete_message'), + intent: Intent.SUCCESS, + }); + }) + .catch( + ({ + response: { + data: { errors }, + }, + }) => {}, + ) + .finally(() => { + closeAlert(name); + }); + }; + + return ( + } + confirmButtonText={} + icon="trash" + intent={Intent.DANGER} + isOpen={isOpen} + onCancel={handleCancelDeleteAlert} + onConfirm={handleConfirmProjectDelete} + loading={isLoading} + > +

+ +

+
+ ); +} + +export default compose( + withAlertStoreConnect(), + withAlertActions, +)(ProjectDeleteAlert); diff --git a/src/containers/Projects/containers/ProjectAlerts/index.ts b/src/containers/Projects/containers/ProjectAlerts/index.ts new file mode 100644 index 000000000..8900c1269 --- /dev/null +++ b/src/containers/Projects/containers/ProjectAlerts/index.ts @@ -0,0 +1,8 @@ +import React from 'react'; + +const ProjectDeleteAlert = React.lazy(() => import('./ProjectDeleteAlert')); + +/** + * Project alerts. + */ +export default [{ name: 'project-delete', component: ProjectDeleteAlert }]; diff --git a/src/containers/Projects/containers/ProjectDetails/ProjectDetailActionsBar.tsx b/src/containers/Projects/containers/ProjectDetails/ProjectDetailActionsBar.tsx index 09608d960..46e0d67fa 100644 --- a/src/containers/Projects/containers/ProjectDetails/ProjectDetailActionsBar.tsx +++ b/src/containers/Projects/containers/ProjectDetails/ProjectDetailActionsBar.tsx @@ -1,4 +1,3 @@ -// @ts-nocheck import React from 'react'; import { useHistory } from 'react-router-dom'; import { @@ -8,18 +7,19 @@ import { NavbarGroup, Alignment, } from '@blueprintjs/core'; -import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar'; import { Icon, FormattedMessage as T, DashboardRowsHeightButton, -} from 'components'; -import { TransactionSelect } from './components'; -import withSettings from '../../../Settings/withSettings'; -import withSettingsActions from '../../../Settings/withSettingsActions'; -import withDialogActions from 'containers/Dialog/withDialogActions'; + DashboardActionsBar, +} from '@/components'; +import { ProjectTransactionsSelect } from './components'; +import withSettings from '@/containers/Settings/withSettings'; +import withSettingsActions from '@/containers/Settings/withSettingsActions'; +import withDialogActions from '@/containers/Dialog/withDialogActions'; +import { projectTranslations } from './common'; import { useProjectDetailContext } from './ProjectDetailProvider'; -import { compose } from 'utils'; +import { compose } from '@/utils'; /** * Project detail actions bar. @@ -40,7 +40,13 @@ function ProjectDetailActionsBar({ // Handle new transaction button click. const handleNewTransactionBtnClick = ({ path }) => { - history.push(`/${path}`); + switch (path) { + case 'expense': + openDialog('project-expense-form', { projectId }); + break; + case 'estimated_expense': + openDialog('estimated-expense-form', { projectId }); + } }; const handleEditProjectBtnClick = () => { @@ -50,11 +56,13 @@ function ProjectDetailActionsBar({ }; // Handle table row size change. const handleTableRowSizeChange = (size) => { - addSetting('timesheets', 'tableSize', size); + addSetting('timesheets', 'tableSize', size) && + addSetting('sales', 'tableSize', size) && + addSetting('purchases', 'tableSize', size); }; const handleTimeEntryBtnClick = () => { - openDialog('time-entry-form', { + openDialog('project-time-entry-form', { projectId, }); }; @@ -65,11 +73,8 @@ function ProjectDetailActionsBar({ return ( - + + + + ); +} + +export default compose(withDialogActions)(ProjectExpneseFormFloatingActions); diff --git a/src/containers/Projects/containers/ProjectExpenseForm/index.tsx b/src/containers/Projects/containers/ProjectExpenseForm/index.tsx new file mode 100644 index 000000000..b11f96c2c --- /dev/null +++ b/src/containers/Projects/containers/ProjectExpenseForm/index.tsx @@ -0,0 +1,55 @@ +import React from 'react'; +import styled from 'styled-components'; +import { Dialog, DialogSuspense, FormattedMessage as T } from '@/components'; +import withDialogRedux from '@/components/DialogReduxConnect'; +import { compose } from '@/utils'; + +const ProjectExpenseFormeDialogContent = React.lazy( + () => import('./ProjectExpenseFormDialogContent'), +); + +/** + * Project expense form dialog. + * @returns + */ +function ProjectExpenseFormDialog({ + dialogName, + payload: { projectId = null }, + isOpen, +}) { + return ( + } + isOpen={isOpen} + autoFocus={true} + canEscapeKeyClose={true} + style={{ width: '400px' }} + > + + + + + ); +} + +export default compose(withDialogRedux())(ProjectExpenseFormDialog); + +const ProjectExpenseFormDialogRoot = styled(Dialog)` + .bp3-dialog-body { + .bp3-form-group { + margin-bottom: 15px; + + label.bp3-label { + margin-bottom: 3px; + font-size: 13px; + } + } + } + .bp3-dialog-footer { + padding-top: 10px; + } +`; diff --git a/src/containers/Projects/containers/ProjectFormDialog/ProjectForm.schema.tsx b/src/containers/Projects/containers/ProjectFormDialog/ProjectForm.schema.tsx index 530fec56b..03e6ff34b 100644 --- a/src/containers/Projects/containers/ProjectFormDialog/ProjectForm.schema.tsx +++ b/src/containers/Projects/containers/ProjectFormDialog/ProjectForm.schema.tsx @@ -1,19 +1,18 @@ import * as Yup from 'yup'; import intl from 'react-intl-universal'; -import { DATATYPES_LENGTH } from 'common/dataTypes'; const Schema = Yup.object().shape({ - contact: Yup.string().label(intl.get('project.schema.label.contact')), - projectName: Yup.string() + contact_id: Yup.string().label(intl.get('project.schema.label.contact')), + name: Yup.string() .label(intl.get('project.schema.label.project_name')) .required(), - projectDeadline: Yup.date() + deadline: Yup.date() .label(intl.get('project.schema.label.deadline')) .required(), - projectState: Yup.boolean().label( + published: Yup.boolean().label( intl.get('project.schema.label.project_state'), ), - projectCost: Yup.number().label( + cost_estimate: Yup.number().label( intl.get('project.schema.label.project_cost'), ), }); diff --git a/src/containers/Projects/containers/ProjectFormDialog/ProjectForm.tsx b/src/containers/Projects/containers/ProjectFormDialog/ProjectForm.tsx index af039a715..67bc43e0d 100644 --- a/src/containers/Projects/containers/ProjectFormDialog/ProjectForm.tsx +++ b/src/containers/Projects/containers/ProjectFormDialog/ProjectForm.tsx @@ -1,22 +1,22 @@ -// @ts-nocheck import React from 'react'; import moment from 'moment'; import intl from 'react-intl-universal'; import { Formik } from 'formik'; -import { AppToaster } from 'components'; +import { Intent } from '@blueprintjs/core'; +import { AppToaster } from '@/components'; import ProjectFormContent from './ProjectFormContent'; import { CreateProjectFormSchema } from './ProjectForm.schema'; import { useProjectFormContext } from './ProjectFormProvider'; -import withDialogActions from 'containers/Dialog/withDialogActions'; +import withDialogActions from '@/containers/Dialog/withDialogActions'; -import { compose } from 'utils'; +import { compose, transformToForm } from '@/utils'; const defaultInitialValues = { - contact: '', - projectName: '', - projectDeadline: moment(new Date()).format('YYYY-MM-DD'), - projectState: false, - projectCost: '', + contact_id: '', + name: '', + deadline: moment(new Date()).format('YYYY-MM-DD'), + published: false, + cost_estimate: '', }; /** @@ -28,20 +28,37 @@ function ProjectForm({ closeDialog, }) { // project form dialog context. - const { dialogName } = useProjectFormContext(); + const { + dialogName, + project, + isNewMode, + projectId, + createProjectMutate, + editProjectMutate, + } = useProjectFormContext(); // Initial form values const initialValues = { ...defaultInitialValues, + ...transformToForm(project, defaultInitialValues), }; // Handles the form submit. const handleFormSubmit = (values, { setSubmitting, setErrors }) => { - const form = {}; + setSubmitting(true); + const form = { ...values }; // Handle request response success. const onSuccess = (response) => { - AppToaster.show({}); + AppToaster.show({ + message: intl.get( + isNewMode + ? 'projects.dialog.success_message' + : 'projects.dialog.edit_success_message', + ), + + intent: Intent.SUCCESS, + }); closeDialog(dialogName); }; @@ -53,6 +70,12 @@ function ProjectForm({ }) => { setSubmitting(false); }; + + if (isNewMode) { + createProjectMutate(form).then(onSuccess).catch(onError); + } else { + editProjectMutate([projectId, form]).then(onSuccess).catch(onError); + } }; return ( diff --git a/src/containers/Projects/containers/ProjectFormDialog/ProjectFormFields.tsx b/src/containers/Projects/containers/ProjectFormDialog/ProjectFormFields.tsx index 239530454..bc1f47f25 100644 --- a/src/containers/Projects/containers/ProjectFormDialog/ProjectFormFields.tsx +++ b/src/containers/Projects/containers/ProjectFormDialog/ProjectFormFields.tsx @@ -1,11 +1,10 @@ -// @ts-nocheck import React from 'react'; import intl from 'react-intl-universal'; import { useFormikContext } from 'formik'; import { Classes, Position, FormGroup, ControlGroup } from '@blueprintjs/core'; import { FastField } from 'formik'; -import { CLASSES } from 'common/classes'; +import { CLASSES } from '@/constants/classes'; import classNames from 'classnames'; import { FFormGroup, @@ -17,13 +16,13 @@ import { FormattedMessage as T, FieldRequiredHint, CustomerSelectField, -} from 'components'; +} from '@/components'; import { inputIntent, momentFormatter, tansformDateValue, handleDateChange, -} from 'utils'; +} from '@/utils'; import { useProjectFormContext } from './ProjectFormProvider'; /** @@ -40,7 +39,7 @@ function ProjectFormFields() { return (
{/*------------ Contact -----------*/} - + {({ form, field: { value }, meta: { error, touched } }) => ( { - form.setFieldValue('contact', customer.id); + form.setFieldValue('contact_id', customer.id); }} allowCreate={true} popoverFill={true} @@ -64,19 +63,20 @@ function ProjectFormFields() { {/*------------ Project Name -----------*/} } > - + {/*------------ DeadLine -----------*/} date.toLocaleString()} popoverProps={{ position: Position.BOTTOM, @@ -86,22 +86,23 @@ function ProjectFormFields() { {/*------------ CheckBox -----------*/} - + {/*------------ Cost Estimate -----------*/} } > diff --git a/src/containers/Projects/containers/ProjectFormDialog/ProjectFormFloatingActions.tsx b/src/containers/Projects/containers/ProjectFormDialog/ProjectFormFloatingActions.tsx index 57b798d35..de8f89d99 100644 --- a/src/containers/Projects/containers/ProjectFormDialog/ProjectFormFloatingActions.tsx +++ b/src/containers/Projects/containers/ProjectFormDialog/ProjectFormFloatingActions.tsx @@ -1,11 +1,10 @@ -// @ts-nocheck import React from 'react'; import { useFormikContext } from 'formik'; import { Intent, Button, Classes } from '@blueprintjs/core'; -import { FormattedMessage as T } from 'components'; +import { FormattedMessage as T } from '@/components'; import { useProjectFormContext } from './ProjectFormProvider'; -import withDialogActions from 'containers/Dialog/withDialogActions'; -import { compose } from 'utils'; +import withDialogActions from '@/containers/Dialog/withDialogActions'; +import { compose } from '@/utils'; /** * Project form floating actions. @@ -15,12 +14,12 @@ function ProjectFormFloatingActions({ // #withDialogActions closeDialog, }) { - // project form dialog context. - const { dialogName } = useProjectFormContext(); - // Formik context. const { isSubmitting } = useFormikContext(); + // project form dialog context. + const { dialogName } = useProjectFormContext(); + // Handle close button click. const handleCancelBtnClick = () => { closeDialog(dialogName); @@ -29,7 +28,7 @@ function ProjectFormFloatingActions({ return (
- + + + } + /> + ); +} + +export default compose(withDialogActions)(ProjectsEmptyStatus); diff --git a/src/containers/Projects/containers/ProjectsLanding/ProjectsList.tsx b/src/containers/Projects/containers/ProjectsLanding/ProjectsList.tsx index 77ad204b0..36442fb9b 100644 --- a/src/containers/Projects/containers/ProjectsLanding/ProjectsList.tsx +++ b/src/containers/Projects/containers/ProjectsLanding/ProjectsList.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { DashboardPageContent, DashboardContentTable } from 'components'; +import { DashboardPageContent, DashboardContentTable } from '@/components'; import ProjectsActionsBar from './ProjectsActionsBar'; import ProjectsViewTabs from './ProjectsViewTabs'; @@ -9,7 +9,7 @@ import withProjects from './withProjects'; import withProjectsActions from './withProjectsActions'; import { ProjectsListProvider } from './ProjectsListProvider'; -import { compose, transformTableStateToQuery } from 'utils'; +import { compose, transformTableStateToQuery } from '@/utils'; /** * Projects list. diff --git a/src/containers/Projects/containers/ProjectsLanding/ProjectsListProvider.tsx b/src/containers/Projects/containers/ProjectsLanding/ProjectsListProvider.tsx index a87f2d1f4..1b47bc919 100644 --- a/src/containers/Projects/containers/ProjectsLanding/ProjectsListProvider.tsx +++ b/src/containers/Projects/containers/ProjectsLanding/ProjectsListProvider.tsx @@ -1,7 +1,8 @@ -//@ts-nocheck import React from 'react'; -import { useResourceViews, useResourceMeta } from 'hooks/query'; -import DashboardInsider from '../../../../components/Dashboard/DashboardInsider'; +import { isEmpty } from 'lodash'; +import { useResourceViews, useResourceMeta } from '@/hooks/query'; +import { DashboardInsider } from '@/components'; +import { useProjects } from '../../hooks'; const ProjectsListContext = React.createContext(); @@ -14,16 +15,32 @@ function ProjectsListProvider({ query, tableStateChanged, ...props }) { const { data: projectsViews, isLoading: isViewsLoading } = useResourceViews('projects'); + // Fetch accounts list according to the given custom view id. + const { + data: { projects }, + isFetching: isProjectsFetching, + isLoading: isProjectsLoading, + } = useProjects(query, { keepPreviousData: true }); + + // Detarmines the datatable empty status. + const isEmptyStatus = + isEmpty(projects) && !tableStateChanged && !isProjectsLoading; + // provider payload. const provider = { + projects, + projectsViews, + + isProjectsLoading, + isProjectsFetching, + isViewsLoading, + + isEmptyStatus, }; return ( - + ); diff --git a/src/containers/Projects/containers/ProjectsLanding/ProjectsViewTabs.tsx b/src/containers/Projects/containers/ProjectsLanding/ProjectsViewTabs.tsx index 30b6e70dd..eaa142121 100644 --- a/src/containers/Projects/containers/ProjectsLanding/ProjectsViewTabs.tsx +++ b/src/containers/Projects/containers/ProjectsLanding/ProjectsViewTabs.tsx @@ -1,14 +1,13 @@ -//@ts-nocheck import React from 'react'; import { Alignment, Navbar, NavbarGroup } from '@blueprintjs/core'; -import { DashboardViewsTabs } from 'components'; +import { DashboardViewsTabs } from '@/components'; import withProjects from './withProjects'; import withProjectsActions from './withProjectsActions'; import { useProjectsListContext } from './ProjectsListProvider'; -import { compose, transfromViewsToTabs } from 'utils'; +import { compose, transfromViewsToTabs } from '@/utils'; /** * Projects views tabs. diff --git a/src/containers/Projects/containers/ProjectsLanding/components.tsx b/src/containers/Projects/containers/ProjectsLanding/components.tsx index d4ed1a586..5a6fccea2 100644 --- a/src/containers/Projects/containers/ProjectsLanding/components.tsx +++ b/src/containers/Projects/containers/ProjectsLanding/components.tsx @@ -10,8 +10,8 @@ import { Intent, ProgressBar, } from '@blueprintjs/core'; -import { Icon, FormatDate, Choose, FormattedMessage as T } from 'components'; -import { safeCallback, firstLettersArgs, calculateStatus } from 'utils'; +import { Icon, FormatDate, Choose, FormattedMessage as T } from '@/components'; +import { safeCallback, firstLettersArgs, calculateStatus } from '@/utils'; /** * project status. @@ -58,7 +58,7 @@ export const StatusAccessor = (project) => { */ export const AvatarCell = ({ row: { original }, size }) => ( - {firstLettersArgs(original?.display_name, original?.name)} + {firstLettersArgs(original?.contact_display_name, original?.name)} ); @@ -102,13 +102,15 @@ export const ActionsMenu = ({ export const ProjectsAccessor = (row) => ( - {row.display_name} + + {row.contact_display_name} + {row.name} - + {intl.get('projects.label.cost_estimate', { - value: row.cost_estimate, + value: row.cost_estimate_formatted, })} @@ -175,10 +177,10 @@ const ProjectItemDescription = styled.div` const ProjectStatusRoot = styled.div` display: flex; align-items: center; - /* justify-content: flex-end; */ margin-right: 0.5rem; flex-direction: row-reverse; `; + const ProjectStatusTaskAmount = styled.div` text-align: right; font-weight: 400; @@ -198,6 +200,7 @@ const ProjectProgressBar = styled(ProgressBar)` } } `; + const StatusTag = styled(Tag)` min-width: 65px; text-align: center; diff --git a/src/containers/Projects/containers/ProjectsLanding/withProjects.tsx b/src/containers/Projects/containers/ProjectsLanding/withProjects.tsx index 35b73c42f..4035c79f1 100644 --- a/src/containers/Projects/containers/ProjectsLanding/withProjects.tsx +++ b/src/containers/Projects/containers/ProjectsLanding/withProjects.tsx @@ -2,7 +2,7 @@ import { connect } from 'react-redux'; import { getProjectsTableStateFactory, isProjectsTableStateChangedFactory, -} from '../../../../store/Project/projects.selectors'; +} from '@/store/Project/projects.selectors'; export default (mapState) => { const getProjectsTableState = getProjectsTableStateFactory(); diff --git a/src/containers/Projects/containers/ProjectsLanding/withProjectsActions.tsx b/src/containers/Projects/containers/ProjectsLanding/withProjectsActions.tsx index d74590f07..4504942e7 100644 --- a/src/containers/Projects/containers/ProjectsLanding/withProjectsActions.tsx +++ b/src/containers/Projects/containers/ProjectsLanding/withProjectsActions.tsx @@ -3,7 +3,7 @@ import { connect } from 'react-redux'; import { setProjectsTableState, resetProjectsTableState, -} from '../../../../store/Project/projects.actions'; +} from '@/store/Project/projects.actions'; const mapDispatchToProps = (dispatch) => ({ setProjectsTableState: (state) => dispatch(setProjectsTableState(state)), diff --git a/src/containers/Projects/containers/TaskFormDialog/TaskFormContent.tsx b/src/containers/Projects/containers/TaskFormDialog/TaskFormContent.tsx deleted file mode 100644 index 1d1f371f5..000000000 --- a/src/containers/Projects/containers/TaskFormDialog/TaskFormContent.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import React from 'react'; -import { Form } from 'formik'; -import TaskFormFields from './TaskFormFields'; -import TaskFormFloatingActions from './TaskFormFloatingActions'; - -/** - * Task form content. - * @returns - */ -export default function TaskFormContent() { - return ( -
- - - - ); -} diff --git a/src/containers/Projects/containers/TaskFormDialog/TaskFormDialogContent.tsx b/src/containers/Projects/containers/TaskFormDialog/TaskFormDialogContent.tsx deleted file mode 100644 index 441356e65..000000000 --- a/src/containers/Projects/containers/TaskFormDialog/TaskFormDialogContent.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import React from 'react'; -import { TaskFormProvider } from './TaskFormProvider'; -import TaskForm from './TaskForm'; - -/** - * Task form dialog content. - */ -export default function TaskFormDialogContent({ - // #ownProps - dialogName, - task, -}) { - return ( - - - - ); -} diff --git a/src/containers/Projects/containers/TaskFormDialog/TaskFormProvider.tsx b/src/containers/Projects/containers/TaskFormDialog/TaskFormProvider.tsx deleted file mode 100644 index ea9bf5be3..000000000 --- a/src/containers/Projects/containers/TaskFormDialog/TaskFormProvider.tsx +++ /dev/null @@ -1,31 +0,0 @@ -//@ts-nocheck -import React from 'react'; -import { DialogContent } from 'components'; - -const TaskFormContext = React.createContext(); - -/** - * Task form provider. - * @returns - */ -function TaskFormProvider({ - // #ownProps - dialogName, - taskId, - ...props -}) { - // State provider. - const provider = { - dialogName, - }; - - return ( - - - - ); -} - -const useTaskFormContext = () => React.useContext(TaskFormContext); - -export { TaskFormProvider, useTaskFormContext }; diff --git a/src/containers/Projects/containers/TaskFormDialog/index.tsx b/src/containers/Projects/containers/TaskFormDialog/index.tsx deleted file mode 100644 index ee74f4719..000000000 --- a/src/containers/Projects/containers/TaskFormDialog/index.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import React from 'react'; -import styled from 'styled-components'; -import intl from 'react-intl-universal'; -import { Dialog, DialogSuspense, FormattedMessage as T } from 'components'; -import withDialogRedux from 'components/DialogReduxConnect'; -import { compose } from 'utils'; - -const TaskFormDialogContent = React.lazy( - () => import('./TaskFormDialogContent'), -); - -/** - * Task form dialog. - * @returns - */ -function TaskFormDialog({ dialogName, payload: { taskId = null }, isOpen }) { - return ( - - - - - - ); -} -export default compose(withDialogRedux())(TaskFormDialog); - -const TaskFormDialogRoot = styled(Dialog)``; diff --git a/src/containers/Projects/containers/TimeEntryFormDialog/TimeEntryForm.schema.tsx b/src/containers/Projects/containers/TimeEntryFormDialog/TimeEntryForm.schema.tsx deleted file mode 100644 index 92ae4ebac..000000000 --- a/src/containers/Projects/containers/TimeEntryFormDialog/TimeEntryForm.schema.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import * as Yup from 'yup'; -import intl from 'react-intl-universal'; -import { DATATYPES_LENGTH } from 'common/dataTypes'; - -const Schema = Yup.object().shape({ - date: Yup.date().label(intl.get('time_entry.schema.label.date')).required(), - projectId: Yup.string() - .label(intl.get('time_entry.schema.label.project_name')) - .required(), - taskId: Yup.string() - .label(intl.get('time_entry.schema.label.task_name')) - .required(), - description: Yup.string().nullable().max(DATATYPES_LENGTH.TEXT), - duration: Yup.string() - .label(intl.get('time_entry.schema.label.duration')) - .required(), -}); - -export const CreateTimeEntryFormSchema = Schema; diff --git a/src/containers/Projects/containers/TimeEntryFormDialog/TimeEntryFormContent.tsx b/src/containers/Projects/containers/TimeEntryFormDialog/TimeEntryFormContent.tsx deleted file mode 100644 index dc45632f5..000000000 --- a/src/containers/Projects/containers/TimeEntryFormDialog/TimeEntryFormContent.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import React from 'react'; -import { Form } from 'formik'; -import TimeEntryFormFields from './TimeEntryFormFields'; -import TimeEntryFormFloatingActions from './TimeEntryFormFloatingActions'; - -/** - * Time entry form content. - * @returns - */ -export default function TimeEntryFormContent() { - return ( -
- - - - ); -} diff --git a/src/containers/Projects/containers/TimeEntryFormDialog/TimeEntryFormDialogContent.tsx b/src/containers/Projects/containers/TimeEntryFormDialog/TimeEntryFormDialogContent.tsx deleted file mode 100644 index 138914eb4..000000000 --- a/src/containers/Projects/containers/TimeEntryFormDialog/TimeEntryFormDialogContent.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import React from 'react'; -import { TimeEntryFormProvider } from './TimeEntryFormProvider'; -import TimeEntryForm from './TimeEntryForm'; - -/** - * Time entry form dialog content. - * @returns {ReactNode} - */ -export default function TimeEntryFormDialogContent({ - // #ownProps - dialogName, - project, - timeEntry, -}) { - return ( - - - - ); -} diff --git a/src/containers/Projects/containers/TimeEntryFormDialog/TimeEntryFormProvider.tsx b/src/containers/Projects/containers/TimeEntryFormDialog/TimeEntryFormProvider.tsx deleted file mode 100644 index 56c8aeb47..000000000 --- a/src/containers/Projects/containers/TimeEntryFormDialog/TimeEntryFormProvider.tsx +++ /dev/null @@ -1,31 +0,0 @@ -//@ts-nocheck -import React from 'react'; -import { DialogContent } from 'components'; - -const TimeEntryFormContext = React.createContext(); - -/** - * Time entry form provider. - * @returns - */ -function TimeEntryFormProvider({ - // #ownProps - dialogName, - projectId, - timeEntryId, - ...props -}) { - const provider = { - dialogName, - }; - - return ( - - - - ); -} - -const useTimeEntryFormContext = () => React.useContext(TimeEntryFormContext); - -export { TimeEntryFormProvider, useTimeEntryFormContext }; diff --git a/src/containers/Projects/containers/TimeEntryFormDialog/components/ProjectSelect.tsx b/src/containers/Projects/containers/TimeEntryFormDialog/components/ProjectSelect.tsx deleted file mode 100644 index 901dce75f..000000000 --- a/src/containers/Projects/containers/TimeEntryFormDialog/components/ProjectSelect.tsx +++ /dev/null @@ -1,63 +0,0 @@ -import React from 'react'; -import intl from 'react-intl-universal'; -import { MenuItem, Button } from '@blueprintjs/core'; -import { FSelect } from '../../../../../components/Forms'; - -/** - * - * @param {*} query - * @param {*} project - * @param {*} _index - * @param {*} exactMatch - * @returns - */ -const projectItemPredicate = (query, project, _index, exactMatch) => { - const normalizedTitle = project.name.toLowerCase(); - const normalizedQuery = query.toLowerCase(); - - if (exactMatch) { - return normalizedTitle === normalizedQuery; - } else { - return `${project.name}. ${normalizedTitle}`.indexOf(normalizedQuery) >= 0; - } -}; - -/** - * - * @param {*} project - * @param {*} param1 - * @returns - */ -const projectItemRenderer = (project, { handleClick, modifiers, query }) => { - return ( - - ); -}; - -const projectSelectProps = { - // itemPredicate: projectItemPredicate, - itemRenderer: projectItemRenderer, - valueAccessor: 'id', - labelAccessor: 'name', -}; - -export function ProjectSelect({ projects, ...rest }) { - return ( - - ); -} - -function ProjectSelectButton({ label }) { - return