re-structure to monorepo.

This commit is contained in:
a.bouhuolia
2023-02-03 01:02:31 +02:00
parent 8242ec64ba
commit 7a0a13f9d5
10400 changed files with 46966 additions and 17223 deletions

View File

@@ -0,0 +1,77 @@
// @ts-nocheck
import React, { useRef, useCallback, useMemo } from 'react';
import classNames from 'classnames';
import { FormGroup, Classes, Intent } from '@blueprintjs/core';
import intl from 'react-intl-universal';
import { CellType } from '@/constants';
import { useCellAutoFocus } from '@/hooks';
import { AccountsSuggestField } from '@/components';
/**
* Account cell renderer.
*/
export default function AccountCellRenderer({
column: {
id,
accountsDataProp,
filterAccountsByRootTypes,
filterAccountsByTypes,
fieldProps,
formGroupProps,
},
row: { index, original },
cell: { value: initialValue },
payload: {
accounts: defaultAccounts,
updateData,
errors,
autoFocus,
...restPayloadProps
},
}) {
const accountRef = useRef();
useCellAutoFocus(accountRef, autoFocus, id, index);
const handleAccountSelected = useCallback(
(account) => {
updateData(index, id, account.id);
},
[updateData, index, id],
);
const error = errors?.[index]?.[id];
const accounts = useMemo(
() => restPayloadProps[accountsDataProp] || defaultAccounts,
[restPayloadProps, defaultAccounts, accountsDataProp],
);
return (
<FormGroup
intent={error ? Intent.DANGER : null}
className={classNames(
'form-group--select-list',
'form-group--account',
Classes.FILL,
)}
{...formGroupProps}
>
<AccountsSuggestField
accounts={accounts}
onAccountSelected={handleAccountSelected}
selectedAccountId={initialValue}
filterByRootTypes={filterAccountsByRootTypes}
filterByTypes={filterAccountsByTypes}
inputProps={{
inputRef: (ref) => (accountRef.current = ref),
placeholder: intl.get('search'),
}}
openOnKeyDown={true}
blurOnSelectClose={false}
{...fieldProps}
/>
</FormGroup>
);
}
AccountCellRenderer.cellType = CellType.Field;

View File

@@ -0,0 +1,45 @@
// @ts-nocheck
import React from 'react';
import { FormGroup, Intent, Classes } from '@blueprintjs/core';
import classNames from 'classnames';
import { CellType } from '@/constants';
import { BranchSuggestField } from '../Branches';
/**
* Branches list field cell.
* @returns
*/
export default function BranchesListFieldCell({
column: { id },
row: { index, original },
payload: { branches, updateData, errors },
}) {
const handleBranchSelected = React.useCallback(
(branch) => {
updateData(index, 'branch_id', branch.id);
},
[updateData, index],
);
const error = errors?.[index]?.[id];
return (
<FormGroup
intent={error ? Intent.DANGER : null}
className={classNames(
'form-group--select-list',
'form-group--contacts-list',
Classes.FILL,
)}
>
<BranchSuggestField
branches={branches}
onBranchSelected={handleBranchSelected}
selectedBranchId={original?.branch_id}
/>
</FormGroup>
);
}
BranchesListFieldCell.cellType = CellType.Field;

View File

@@ -0,0 +1,52 @@
// @ts-nocheck
import React from 'react';
import classNames from 'classnames';
import { get } from 'lodash';
import { Classes, Checkbox, FormGroup, Intent } from '@blueprintjs/core';
import { CellType } from '@/constants';
const CheckboxEditableCell = ({
row: { index, original },
column: { id, disabledAccessor, checkboxProps },
cell: { value: initialValue },
payload,
}) => {
const [value, setValue] = React.useState(initialValue);
const onChange = (e) => {
const newValue = e.target.checked;
setValue(newValue);
payload.updateData(index, id, newValue);
};
React.useEffect(() => {
setValue(initialValue);
}, [initialValue]);
const error = payload.errors?.[index]?.[id];
// Detarmines whether the checkbox is disabled.
const disabled = disabledAccessor ? get(original, disabledAccessor) : false;
return (
<FormGroup
intent={error ? Intent.DANGER : null}
className={classNames(Classes.FILL)}
>
<Checkbox
value={value}
onChange={onChange}
checked={initialValue}
disabled={disabled}
minimal={true}
className="ml2"
{...checkboxProps}
/>
</FormGroup>
);
};
CheckboxEditableCell.cellType = CellType.Field;
export default CheckboxEditableCell;

View File

@@ -0,0 +1,42 @@
// @ts-nocheck
import React, { useCallback } from 'react';
import { FormGroup, Intent, Classes } from '@blueprintjs/core';
import classNames from 'classnames';
import { CellType } from '@/constants';
import { ContactsSuggestField } from '@/components';
export default function ContactsListCellRenderer({
column: { id },
row: { index, original },
cell: { value },
payload: { contacts, updateData, errors },
}) {
const handleContactSelected = useCallback(
(contact) => {
updateData(index, 'contact_id', contact.id);
},
[updateData, index, id],
);
const error = errors?.[index]?.[id];
return (
<FormGroup
intent={error ? Intent.DANGER : null}
className={classNames(
'form-group--select-list',
'form-group--contacts-list',
Classes.FILL,
)}
>
<ContactsSuggestField
contactsList={contacts}
onContactSelected={handleContactSelected}
selectedContactId={original?.contact_id}
selectedContactType={original?.contact_type}
/>
</FormGroup>
);
}
ContactsListCellRenderer.cellType = CellType.Field;

View File

@@ -0,0 +1,21 @@
// @ts-nocheck
import React, { useState, useEffect } from 'react';
export const DivFieldCell = ({ cell: { value: initialValue } }) => {
const [value, setValue] = useState(initialValue);
useEffect(() => {
setValue(initialValue);
}, [initialValue]);
return <div>${value}</div>;
};
export const EmptyDiv = ({ cell: { value: initialValue } }) => {
const [value, setValue] = useState(initialValue);
useEffect(() => {
setValue(initialValue);
}, [initialValue]);
return <div>{value}</div>;
};

View File

@@ -0,0 +1,44 @@
// @ts-nocheck
import React, { useState, useEffect } from 'react';
import classNames from 'classnames';
import { Classes, InputGroup, FormGroup, Intent } from '@blueprintjs/core';
import { CellType } from '@/constants';
const InputEditableCell = ({
row: { index },
column: { id },
cell: { value: initialValue },
payload,
}) => {
const [value, setValue] = useState(initialValue);
const onChange = (e) => {
setValue(e.target.value);
};
const onBlur = () => {
payload.updateData(index, id, value);
};
useEffect(() => {
setValue(initialValue);
}, [initialValue]);
const error = payload.errors?.[index]?.[id];
return (
<FormGroup
intent={error ? Intent.DANGER : null}
className={classNames(Classes.FILL)}
>
<InputGroup
value={value}
onChange={onChange}
onBlur={onBlur}
fill={true}
/>
</FormGroup>
);
};
InputEditableCell.cellType = CellType.Field;
export default InputEditableCell;

View File

@@ -0,0 +1,60 @@
// @ts-nocheck
import React, { useCallback, useRef } from 'react';
import classNames from 'classnames';
import { FormGroup, Classes, Intent } from '@blueprintjs/core';
import intl from 'react-intl-universal';
import { CellType } from '@/constants';
import { ItemsSuggestField } from '@/components';
import { useCellAutoFocus } from '@/hooks';
/**
* Items list cell.
*/
export default function ItemsListCell({
column: { id, filterSellable, filterPurchasable, fieldProps, formGroupProps },
row: { index },
cell: { value: initialValue },
payload: { items, updateData, errors, autoFocus },
}) {
const fieldRef = useRef();
// Auto-focus the items list input field.
useCellAutoFocus(fieldRef, autoFocus, id, index);
// Handle the item selected.
const handleItemSelected = useCallback(
(item) => {
updateData(index, id, item.id);
},
[updateData, index, id],
);
const error = errors?.[index]?.[id];
return (
<FormGroup
intent={error ? Intent.DANGER : null}
className={classNames('form-group--select-list', Classes.FILL)}
{...formGroupProps}
>
<ItemsSuggestField
items={items}
onItemSelected={handleItemSelected}
selectedItemId={initialValue}
sellable={filterSellable}
purchasable={filterPurchasable}
inputProps={{
inputRef: (ref) => (fieldRef.current = ref),
placeholder: intl.get('enter_an_item'),
}}
openOnKeyDown={true}
blurOnSelectClose={false}
{...fieldProps}
/>
</FormGroup>
);
}
ItemsListCell.cellType = CellType.Field;

View File

@@ -0,0 +1,56 @@
// @ts-nocheck
import React, { useCallback, useState, useEffect } from 'react';
import { FormGroup, Intent } from '@blueprintjs/core';
import { MoneyInputGroup } from '@/components';
import { CLASSES } from '@/constants/classes';
import { CellType } from '@/constants';
// Input form cell renderer.
const MoneyFieldCellRenderer = ({
row: { index, moneyInputGroupProps = {} },
column: { id },
cell: { value: initialValue },
payload: { errors, updateData },
}) => {
const [value, setValue] = useState(initialValue);
const handleFieldChange = useCallback((value) => {
setValue(value);
}, [setValue]);
function isNumeric(data) {
return (
!isNaN(parseFloat(data)) && isFinite(data) && data.constructor !== Array
);
}
const handleFieldBlur = () => {
const updateValue = isNumeric(value) ? parseFloat(value) : value;
updateData(index, id, updateValue);
};
useEffect(() => {
setValue(initialValue);
}, [initialValue]);
const error = errors?.[index]?.[id];
return (
<FormGroup
intent={error ? Intent.DANGER : null}
className={CLASSES.FILL}>
<MoneyInputGroup
value={value}
// prefix={'$'}
onChange={handleFieldChange}
onBlur={handleFieldBlur}
{...moneyInputGroupProps}
/>
</FormGroup>
);
};
MoneyFieldCellRenderer.cellType = CellType.Field;
export default MoneyFieldCellRenderer;

View File

@@ -0,0 +1,48 @@
// @ts-nocheck
import React, { useState, useEffect } from 'react';
import { FormGroup, NumericInput, Intent } from '@blueprintjs/core';
import classNames from 'classnames';
import { CellType } from '@/constants';
import { CLASSES } from '@/constants/classes';
/**
* Numeric input table cell.
*/
export default function NumericInputCell({
row: { index },
column: { id },
cell: { value: initialValue },
payload,
}) {
const [value, setValue] = useState(initialValue);
const handleValueChange = (newValue) => {
setValue(newValue);
};
const onBlur = () => {
payload.updateData(index, id, value);
};
useEffect(() => {
setValue(initialValue);
}, [initialValue]);
const error = payload.errors?.[index]?.[id];
return (
<FormGroup
intent={error ? Intent.DANGER : null}
className={classNames(CLASSES.FILL)}
>
<NumericInput
value={value}
onValueChange={handleValueChange}
onBlur={onBlur}
fill={true}
buttonPosition={'none'}
/>
</FormGroup>
);
}
NumericInputCell.cellType = CellType.Field;

View File

@@ -0,0 +1,39 @@
// @ts-nocheck
import React, { useCallback } from 'react';
import classNames from 'classnames';
import { FormGroup, Classes, Intent } from '@blueprintjs/core';
import { PaymentReceiveListField } from '@/components';
import { CellType } from '@/constants';
function PaymentReceiveListFieldCell({
column: { id },
row: { index },
cell: { value: initialValue },
payload: { invoices, updateData, errors },
}) {
const handleInvoicesSelected = useCallback(
(_item) => {
updateData(index, id, _item.id);
},
[updateData, index, id],
);
const error = errors?.[index]?.[id];
return (
<FormGroup
intent={error ? Intent.DANGER : null}
className={classNames('form-group--selcet-list', Classes.FILL)}
>
<PaymentReceiveListField
invoices={invoices}
onInvoiceSelected={handleInvoicesSelected}
selectedInvoiceId={initialValue}
/>
</FormGroup>
);
}
PaymentReceiveListFieldCell.cellType = CellType.Field;
export default PaymentReceiveListFieldCell;

View File

@@ -0,0 +1,46 @@
// @ts-nocheck
import React, { useCallback, useState, useEffect } from 'react';
import { FormGroup, Intent } from '@blueprintjs/core';
import { MoneyInputGroup } from '@/components';
import { CellType } from '@/constants';
const PercentFieldCell = ({
cell: { value: initialValue },
row: { index },
column: { id },
payload: { errors, updateData },
}) => {
const [value, setValue] = useState(initialValue);
const handleBlurChange = (newValue) => {
const parsedValue = newValue === '' || newValue === undefined
? '' : parseInt(newValue, 10);
updateData(index, id, parsedValue);
};
const handleChange = useCallback((value) => {
setValue(value);
}, [setValue]);
useEffect(() => {
setValue(initialValue);
}, [initialValue]);
const error = errors?.[index]?.[id];
return (
<FormGroup intent={error ? Intent.DANGER : null}>
<MoneyInputGroup
prefix={'%'}
value={value}
onChange={handleChange}
onBlurValue={handleBlurChange}
/>
</FormGroup>
);
};
PercentFieldCell.cellType = CellType.Field;
export default PercentFieldCell;

View File

@@ -0,0 +1,27 @@
// @ts-nocheck
import React from 'react';
import styled from 'styled-components';
import { Popover2 } from '@blueprintjs/popover2';
import { Button } from '@blueprintjs/core';
import { CellType } from '@/constants';
import { Icon, FormattedMessage as T } from '@/components';
import ProjectBillableEntries from '@/containers/Projects/containers/ProjectBillableEntries';
/**
*
* @return
*/
export function ProjectBillableEntriesCell() {
const content = <ProjectBillableEntries />;
return (
<Popover2 content={content}>
<Button
icon={<Icon icon={'info'} iconSize={14} />}
className="m12"
minimal={true}
/>
</Popover2>
);
}
ProjectBillableEntriesCell.cellType = CellType.Button;

View File

@@ -0,0 +1,44 @@
// @ts-nocheck
import React, { useCallback } from 'react';
import { FormGroup, Intent, Classes } from '@blueprintjs/core';
import classNames from 'classnames';
import { CellType } from '@/constants';
import { ProjectSuggestField } from '@/containers/Projects/components';
/**
* projects list field cell.
* @returns
*/
export function ProjectsListFieldCell({
column: { id },
row: { index, original },
payload: { projects, updateData, errors },
}) {
const handleProjectSelected = useCallback(
(project) => {
updateData(index, 'project_id', project.id);
},
[updateData, index],
);
const error = errors?.[index]?.[id];
return (
<FormGroup
intent={error ? Intent.DANGER : null}
className={classNames(
'form-group--select-list',
'form-group--contacts-list',
Classes.FILL,
)}
>
<ProjectSuggestField
projects={projects}
onProjectSelected={handleProjectSelected}
selectedProjectId={original?.project_id}
/>
</FormGroup>
);
}
ProjectsListFieldCell.cellType = CellType.Field;

View File

@@ -0,0 +1,55 @@
// @ts-nocheck
import React from 'react';
import classNames from 'classnames';
import { Classes, Switch, FormGroup, Intent } from '@blueprintjs/core';
import { CellType } from '@/constants';
import { safeInvoke } from '@/utils';
/**
* Switch editable cell.
*/
const SwitchEditableCell = ({
row: { index, original },
column: { id, switchProps, onSwitchChange },
cell: { value: initialValue },
payload,
}) => {
const [value, setValue] = React.useState(initialValue);
// Handle the switch change.
const onChange = (e) => {
const newValue = e.target.checked;
setValue(newValue);
safeInvoke(payload.updateData, index, id, newValue);
safeInvoke(onSwitchChange, e, newValue, original);
};
React.useEffect(() => {
setValue(initialValue);
}, [initialValue]);
const error = payload.errors?.[index]?.[id];
return (
<FormGroup
intent={error ? Intent.DANGER : null}
className={classNames(Classes.FILL)}
>
<Switch
value={value}
onChange={onChange}
checked={initialValue}
minimal={true}
className="ml2"
{...switchProps}
/>
</FormGroup>
);
};
SwitchEditableCell.cellType = CellType.Field;
export default SwitchEditableCell;

View File

@@ -0,0 +1,46 @@
// @ts-nocheck
import React, { useState, useEffect } from 'react';
import classNames from 'classnames';
import { Classes, TextArea, FormGroup, Intent } from '@blueprintjs/core';
import { CellType } from '@/constants';
const TextAreaEditableCell = ({
row: { index },
column: { id },
cell: { value: initialValue },
payload,
}) => {
const [value, setValue] = useState(initialValue);
const onChange = (e) => {
setValue(e.target.value);
};
const onBlur = () => {
payload.updateData(index, id, value);
};
useEffect(() => {
setValue(initialValue);
}, [initialValue]);
const error = payload.errors?.[index]?.[id];
return (
<FormGroup
intent={error ? Intent.DANGER : null}
className={classNames(Classes.FILL)}
>
<TextArea
growVertically={true}
large={true}
value={value}
onChange={onChange}
onBlur={onBlur}
fill={true}
/>
</FormGroup>
);
};
TextAreaEditableCell.cellType = CellType.Field;
export default TextAreaEditableCell;

View File

@@ -0,0 +1,28 @@
// @ts-nocheck
import React from 'react';
import { Tooltip, Position } from '@blueprintjs/core';
/**
* Text overview tooltip cell.
* @returns {JSX.Element}
*/
export function TextOverviewTooltipCell({ cell: { value } }) {
const SUBMENU_POPOVER_MODIFIERS = {
flip: { boundariesElement: 'viewport', padding: 20 },
offset: { offset: '0, 10' },
preventOverflow: { boundariesElement: 'viewport', padding: 40 },
};
return (
<Tooltip
content={value}
position={Position.BOTTOM_LEFT}
boundary={'viewport'}
minimal={true}
modifiers={SUBMENU_POPOVER_MODIFIERS}
targetClassName={'table-tooltip-overview-target'}
>
{value}
</Tooltip>
);
}

View File

@@ -0,0 +1,35 @@
// @ts-nocheck
import AccountsListFieldCell from './AccountsListFieldCell';
import MoneyFieldCell from './MoneyFieldCell';
import InputGroupCell from './InputGroupCell';
import ContactsListFieldCell from './ContactsListFieldCell';
import ItemsListCell from './ItemsListCell';
import PercentFieldCell from './PercentFieldCell';
import { DivFieldCell, EmptyDiv } from './DivFieldCell';
import NumericInputCell from './NumericInputCell';
import CheckBoxFieldCell from './CheckBoxFieldCell';
import SwitchFieldCell from './SwitchFieldCell';
import TextAreaCell from './TextAreaCell';
import BranchesListFieldCell from './BranchesListFieldCell';
import { ProjectsListFieldCell } from './ProjectsListFieldCell';
import { ProjectBillableEntriesCell } from './ProjectBillableEntriesCell';
import { TextOverviewTooltipCell } from './TextOverviewTooltipCell';
export {
AccountsListFieldCell,
MoneyFieldCell,
InputGroupCell,
ContactsListFieldCell,
ItemsListCell,
PercentFieldCell,
DivFieldCell,
EmptyDiv,
NumericInputCell,
CheckBoxFieldCell,
SwitchFieldCell,
TextAreaCell,
BranchesListFieldCell,
ProjectsListFieldCell,
ProjectBillableEntriesCell,
TextOverviewTooltipCell,
};