feat: add project select to sales & purchases

This commit is contained in:
elforjani13
2022-08-11 11:20:52 +02:00
parent 95137f4fcd
commit 69c4519647
18 changed files with 228 additions and 23 deletions

View File

@@ -2,6 +2,8 @@ import React from 'react';
import intl from 'react-intl-universal';
import { MenuItem, Button } from '@blueprintjs/core';
import { FSelect } from '@/components';
import { CLASSES } from '@/constants/classes';
import classNames from 'classnames';
/**
*
@@ -31,7 +33,6 @@ const projectsItemPredicate = (query, project, _index, exactMatch) => {
const projectsItemRenderer = (project, { handleClick, modifiers, query }) => {
return (
<MenuItem
active={modifiers.active}
disabled={modifiers.disabled}
key={project.id}
onClick={handleClick}
@@ -52,8 +53,18 @@ const projectSelectProps = {
* @param {*} param0
* @returns
*/
export function ProjectsSelect({ projects, ...rest }) {
return <FSelect {...projectSelectProps} items={projects} {...rest} />;
export function ProjectsSelect({ projects, popoverFill, ...rest }) {
return (
<FSelect
{...projectSelectProps}
items={projects}
popoverProps={{ minimal: true, usePortal: !popoverFill }}
className={classNames('form-group--select-list', {
[CLASSES.SELECT_LIST_FILL_POPOVER]: popoverFill,
})}
{...rest}
/>
);
}
/**
*

View File

@@ -48,7 +48,6 @@ function ProjectTimeEntryFormFields() {
name={'project_id'}
projects={projects}
input={ProjectSelectButton}
popoverProps={{ minimal: true }}
/>
</FFormGroup>
</If>

View File

@@ -1,7 +1,7 @@
import React from 'react';
import styled from 'styled-components';
import classNames from 'classnames';
import { FormGroup, InputGroup, Position } from '@blueprintjs/core';
import { FormGroup, InputGroup, Classes, Position } from '@blueprintjs/core';
import { FastField, ErrorMessage } from 'formik';
import { DateInput } from '@blueprintjs/datetime';
import { FormattedMessage as T } from '@/components';
@@ -17,7 +17,11 @@ import {
import { useBillFormContext } from './BillFormProvider';
import { vendorsFieldShouldUpdate } from './utils';
import { BillExchangeRateInputField } from './components';
import {
BillExchangeRateInputField,
BillProjectSelectButton,
} from './components';
import { ProjectsSelect } from '@/containers/Projects/components';
import withDialogActions from '@/containers/Dialog/withDialogActions';
import {
momentFormatter,
@@ -32,7 +36,7 @@ import {
*/
function BillFormHeader() {
// Bill form context.
const { vendors } = useBillFormContext();
const { vendors, projects } = useBillFormContext();
return (
<div className={classNames(CLASSES.PAGE_FORM_HEADER_FIELDS)}>
@@ -163,6 +167,21 @@ function BillFormHeader() {
</FormGroup>
)}
</FastField>
{/*------------ Project name -----------*/}
<FFormGroup
name={'project_id'}
label={<T id={'bill.project_name.label'} />}
inline={true}
className={classNames('form-group--select-list', Classes.FILL)}
>
<ProjectsSelect
name={'project_id'}
projects={projects}
input={BillProjectSelectButton}
popoverFill={true}
/>
</FFormGroup>
</div>
);
}

View File

@@ -2,6 +2,7 @@ import React, { createContext, useState } from 'react';
import { Features } from '@/constants';
import { useFeatureCan } from '@/hooks/state';
import { DashboardInsider } from '@/components/Dashboard';
import { useProjects } from '@/containers/Projects/hooks';
import {
useAccounts,
useVendors,
@@ -80,6 +81,12 @@ function BillFormProvider({ billId, ...props }) {
isSuccess: isBranchesSuccess,
} = useBranches({}, { enabled: isBranchFeatureCan });
// Fetches the projects list.
const {
data: { projects },
isLoading: isProjectsLoading,
} = useProjects();
// Handle fetching bill settings.
const { isFetching: isSettingLoading } = useSettings();
@@ -102,6 +109,7 @@ function BillFormProvider({ billId, ...props }) {
bill,
warehouses,
branches,
projects,
submitPayload,
isNewMode,

View File

@@ -1,4 +1,6 @@
import React from 'react';
import intl from 'react-intl-universal';
import { Button } from '@blueprintjs/core';
import { useFormikContext } from 'formik';
import { ExchangeRateInputGroup } from '@/components';
import { useCurrentOrganization } from '@/hooks/state';
@@ -26,3 +28,11 @@ export function BillExchangeRateInputField({ ...props }) {
/>
);
}
/**
* bill project select.
* @returns {JSX.Element}
*/
export function BillProjectSelectButton({ label }) {
return <Button text={label ?? intl.get('select_project')} />;
}

View File

@@ -5,10 +5,11 @@ import {
FormGroup,
InputGroup,
Position,
Classes,
ControlGroup,
} from '@blueprintjs/core';
import { DateInput } from '@blueprintjs/datetime';
import { FormattedMessage as T } from '@/components';
import { FFormGroup, FormattedMessage as T } from '@/components';
import { FastField, Field, ErrorMessage } from 'formik';
import {
@@ -30,8 +31,13 @@ import {
import withDialogActions from '@/containers/Dialog/withDialogActions';
import withSettings from '@/containers/Settings/withSettings';
import { ProjectsSelect } from '@/containers/Projects/components';
import {
EstimateExchangeRateInputField,
EstimateProjectSelectButton,
} from './components';
import { useObserveEstimateNoSettings } from './utils';
import { EstimateExchangeRateInputField } from './components';
import { useEstimateFormContext } from './EstimateFormProvider';
/**
@@ -46,7 +52,7 @@ function EstimateFormHeader({
estimateNumberPrefix,
estimateNextNumber,
}) {
const { customers } = useEstimateFormContext();
const { customers, projects } = useEstimateFormContext();
const handleEstimateNumberBtnClick = () => {
openDialog('estimate-number-form', {});
@@ -219,6 +225,21 @@ function EstimateFormHeader({
</FormGroup>
)}
</FastField>
{/*------------ Project name -----------*/}
<FFormGroup
name={'project_id'}
label={<T id={'estimate.project_name.label'} />}
inline={true}
className={classNames('form-group--select-list', Classes.FILL)}
>
<ProjectsSelect
name={'project_id'}
projects={projects}
input={EstimateProjectSelectButton}
popoverFill={true}
/>
</FFormGroup>
</div>
);
}

View File

@@ -12,6 +12,7 @@ import {
useEditEstimate,
} from '@/hooks/query';
import { Features } from '@/constants';
import { useProjects } from '@/containers/Projects/hooks';
import { useFeatureCan } from '@/hooks/state';
import { ITEMS_FILTER_ROLES } from './utils';
@@ -45,7 +46,6 @@ function EstimateFormProvider({ query, estimateId, ...props }) {
// Handle fetch customers data table or list
const {
data: { customers },
isFetch: isCustomersFetching,
isLoading: isCustomersLoading,
} = useCustomers({ page_size: 10000 });
@@ -63,6 +63,12 @@ function EstimateFormProvider({ query, estimateId, ...props }) {
isSuccess: isBranchesSuccess,
} = useBranches(query, { enabled: isBranchFeatureCan });
// Fetches the projects list.
const {
data: { projects },
isLoading: isProjectsLoading,
} = useProjects();
// Handle fetch settings.
useSettingsEstimates();
@@ -86,6 +92,7 @@ function EstimateFormProvider({ query, estimateId, ...props }) {
customers,
branches,
warehouses,
projects,
isNewMode,
isItemsFetching,

View File

@@ -1,4 +1,6 @@
import React from 'react';
import intl from 'react-intl-universal';
import { Button } from '@blueprintjs/core';
import { useFormikContext } from 'formik';
import { ExchangeRateInputGroup } from '@/components';
import { useCurrentOrganization } from '@/hooks/state';
@@ -27,3 +29,11 @@ import { useEstimateIsForeignCustomer } from './utils';
/>
);
}
/**
* Estimate project select.
* @returns {JSX.Element}
*/
export function EstimateProjectSelectButton({ label }) {
return <Button text={label ?? intl.get('select_project')} />;
}

View File

@@ -5,6 +5,7 @@ import {
FormGroup,
InputGroup,
Position,
Classes,
ControlGroup,
} from '@blueprintjs/core';
import { DateInput } from '@blueprintjs/datetime';
@@ -30,7 +31,11 @@ import {
} from './utils';
import { useInvoiceFormContext } from './InvoiceFormProvider';
import { InvoiceExchangeRateInputField } from './components';
import {
InvoiceExchangeRateInputField,
InvoiceProjectSelectButton,
} from './components';
import { ProjectsSelect } from '@/containers/Projects/components';
import withSettings from '@/containers/Settings/withSettings';
import withDialogActions from '@/containers/Dialog/withDialogActions';
@@ -48,7 +53,7 @@ function InvoiceFormHeaderFields({
invoiceNextNumber,
}) {
// Invoice form context.
const { customers } = useInvoiceFormContext();
const { customers, projects } = useInvoiceFormContext();
// Handle invoice number changing.
const handleInvoiceNumberChange = () => {
@@ -224,6 +229,21 @@ function InvoiceFormHeaderFields({
</FormGroup>
)}
</FastField>
{/*------------ Project name -----------*/}
<FFormGroup
name={'project_id'}
label={<T id={'invoice.project_name.label'} />}
inline={true}
className={classNames('form-group--select-list', Classes.FILL)}
>
<ProjectsSelect
name={'project_id'}
projects={projects}
input={InvoiceProjectSelectButton}
popoverFill={true}
/>
</FFormGroup>
</div>
);
}

View File

@@ -16,6 +16,7 @@ import {
useSettingsInvoices,
useEstimate,
} from '@/hooks/query';
import { useProjects } from '@/containers/Projects/hooks';
const InvoiceFormContext = createContext();
@@ -35,6 +36,12 @@ function InvoiceFormProvider({ invoiceId, baseCurrency, ...props }) {
enabled: !!invoiceId,
});
// Fetch project list.
const {
data: { projects },
isLoading: isProjectsLoading,
} = useProjects();
// Fetches the estimate by the given id.
const { data: estimate, isLoading: isEstimateLoading } = useEstimate(
estimateId,
@@ -102,6 +109,7 @@ function InvoiceFormProvider({ invoiceId, baseCurrency, ...props }) {
submitPayload,
branches,
warehouses,
projects,
isInvoiceLoading,
isItemsLoading,

View File

@@ -1,4 +1,6 @@
import React from 'react';
import intl from 'react-intl-universal';
import { Button } from '@blueprintjs/core';
import { useFormikContext } from 'formik';
import { ExchangeRateInputGroup } from '@/components';
import { useCurrentOrganization } from '@/hooks/state';
@@ -26,3 +28,11 @@ export function InvoiceExchangeRateInputField({ ...props }) {
/>
);
}
/**
* Invoice project select.
* @returns {JSX.Element}
*/
export function InvoiceProjectSelectButton({ label }) {
return <Button text={label ?? intl.get('select_project')} />;
}

View File

@@ -1,8 +1,8 @@
import React, { createContext, useContext } from 'react';
import { isEqual, isUndefined } from 'lodash';
import { Features } from '@/constants';
import { useFeatureCan } from '@/hooks/state';
import { DashboardInsider } from '@/components';
import { useProjects } from '@/containers/Projects/hooks';
import {
useSettingsPaymentReceives,
usePaymentReceiveEditPage,
@@ -57,6 +57,12 @@ function PaymentReceiveFormProvider({ query, paymentReceiveId, ...props }) {
isSuccess: isBranchesSuccess,
} = useBranches(query, { enabled: isBranchFeatureCan });
// Fetches the projects list.
const {
data: { projects },
isLoading: isProjectsLoading,
} = useProjects();
// Detarmines whether the new mode.
const isNewMode = !paymentReceiveId;
@@ -74,7 +80,8 @@ function PaymentReceiveFormProvider({ query, paymentReceiveId, ...props }) {
accounts,
customers,
branches,
projects,
isPaymentLoading,
isAccountsLoading,
isPaymentFetching,

View File

@@ -5,6 +5,7 @@ import {
FormGroup,
InputGroup,
Position,
Classes,
ControlGroup,
Button,
} from '@blueprintjs/core';
@@ -23,6 +24,7 @@ import {
inputIntent,
} from '@/utils';
import {
FFormGroup,
AccountsSelectList,
CustomerSelectField,
FieldRequiredHint,
@@ -36,7 +38,11 @@ import {
} from '@/components';
import { usePaymentReceiveFormContext } from './PaymentReceiveFormProvider';
import { ACCOUNT_TYPE } from '@/constants/accountTypes';
import { PaymentReceiveExchangeRateInputField } from './components';
import { ProjectsSelect } from '@/containers/Projects/components';
import {
PaymentReceiveExchangeRateInputField,
PaymentReceiveProjectSelectButton,
} from './components';
import withDialogActions from '@/containers/Dialog/withDialogActions';
import withSettings from '@/containers/Settings/withSettings';
@@ -68,7 +74,8 @@ function PaymentReceiveHeaderFields({
paymentReceiveNextNumber,
}) {
// Payment receive form context.
const { customers, accounts, isNewMode } = usePaymentReceiveFormContext();
const { customers, accounts, projects, isNewMode } =
usePaymentReceiveFormContext();
// Formik form context.
const {
@@ -331,6 +338,21 @@ function PaymentReceiveHeaderFields({
</FormGroup>
)}
</FastField>
{/*------------ Project name -----------*/}
<FFormGroup
name={'project_id'}
label={<T id={'payment_receive.project_name.label'} />}
inline={true}
className={classNames('form-group--select-list', Classes.FILL)}
>
<ProjectsSelect
name={'project_id'}
projects={projects}
input={PaymentReceiveProjectSelectButton}
popoverFill={true}
/>
</FFormGroup>
</div>
);
}

View File

@@ -1,6 +1,7 @@
import React from 'react';
import moment from 'moment';
import intl from 'react-intl-universal';
import { Button } from '@blueprintjs/core';
import { useFormikContext } from 'formik';
import { Money, ExchangeRateInputGroup, MoneyFieldCell } from '@/components';
@@ -102,3 +103,11 @@ export function PaymentReceiveExchangeRateInputField({ ...props }) {
/>
);
}
/**
* payment receive project select.
* @returns {JSX.Element}
*/
export function PaymentReceiveProjectSelectButton({ label }) {
return <Button text={label ?? intl.get('select_project')} />;
}

View File

@@ -5,6 +5,7 @@ import {
FormGroup,
InputGroup,
Position,
Classes,
ControlGroup,
} from '@blueprintjs/core';
import { DateInput } from '@blueprintjs/datetime';
@@ -12,6 +13,7 @@ import { FastField, ErrorMessage } from 'formik';
import { CLASSES } from '@/constants/classes';
import {
FFormGroup,
AccountsSelectList,
CustomerSelectField,
FieldRequiredHint,
@@ -23,6 +25,7 @@ import {
import withSettings from '@/containers/Settings/withSettings';
import withDialogActions from '@/containers/Dialog/withDialogActions';
import { ACCOUNT_TYPE } from '@/constants/accountTypes';
import { ProjectsSelect } from '@/containers/Projects/components';
import {
momentFormatter,
compose,
@@ -36,7 +39,10 @@ import {
customersFieldShouldUpdate,
useObserveReceiptNoSettings,
} from './utils';
import { ReceiptExchangeRateInputField } from './components';
import {
ReceiptExchangeRateInputField,
ReceiptProjectSelectButton,
} from './components';
/**
* Receipt form header fields.
@@ -50,7 +56,7 @@ function ReceiptFormHeader({
receiptNextNumber,
receiptNumberPrefix,
}) {
const { accounts, customers } = useReceiptFormContext();
const { accounts, customers, projects } = useReceiptFormContext();
const handleReceiptNumberChange = useCallback(() => {
openDialog('receipt-number-form', {});
@@ -229,6 +235,21 @@ function ReceiptFormHeader({
</FormGroup>
)}
</FastField>
{/*------------ Project name -----------*/}
<FFormGroup
name={'project_id'}
label={<T id={'receipt.project_name.label'} />}
inline={true}
className={classNames('form-group--select-list', Classes.FILL)}
>
<ProjectsSelect
name={'project_id'}
projects={projects}
input={ReceiptProjectSelectButton}
popoverFill={true}
/>
</FFormGroup>
</div>
);
}

View File

@@ -13,6 +13,7 @@ import {
useCreateReceipt,
useEditReceipt,
} from '@/hooks/query';
import { useProjects } from '@/containers/Projects/hooks';
const ReceiptFormContext = createContext();
@@ -83,6 +84,12 @@ function ReceiptFormProvider({ receiptId, ...props }) {
stringified_filter_roles: stringifiedFilterRoles,
});
// Fetch project list.
const {
data: { projects },
isLoading: isProjectsLoading,
} = useProjects();
// Fetch receipt settings.
const { isLoading: isSettingLoading } = useSettingsReceipts();
@@ -103,6 +110,7 @@ function ReceiptFormProvider({ receiptId, ...props }) {
items,
branches,
warehouses,
projects,
submitPayload,
isNewMode,

View File

@@ -1,15 +1,16 @@
import React from 'react';
import intl from 'react-intl-universal';
import { Button } from '@blueprintjs/core';
import { useFormikContext } from 'formik';
import { ExchangeRateInputGroup } from '@/components';
import { useCurrentOrganization } from '@/hooks/state';
import { useReceiptIsForeignCustomer } from './utils';
/**
* Receipt exchange rate input field.
* @returns {JSX.Element}
*/
export function ReceiptExchangeRateInputField({ ...props }) {
export function ReceiptExchangeRateInputField({ ...props }) {
const currentOrganization = useCurrentOrganization();
const { values } = useFormikContext();
@@ -26,4 +27,12 @@ import { useReceiptIsForeignCustomer } from './utils';
{...props}
/>
);
}
}
/**
* Receipt project select.
* @returns {JSX.Element}
*/
export function ReceiptProjectSelectButton({ label }) {
return <Button text={label ?? intl.get('select_project')} />;
}

View File

@@ -2184,5 +2184,11 @@
"sales.column.balance": "Balance",
"sales.column.total": "Total",
"sales.column.status": "Status",
"sales.action.delete": "Delete"
"sales.action.delete": "Delete",
"invoice.project_name.label":"Project Name",
"estimate.project_name.label":"Project Name",
"receipt.project_name.label":"Project Name",
"bill.project_name.label":"Project Name",
"payment_receive.project_name.label":"Project Name",
"select_project": "Select Project"
}