mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-16 04:40:32 +00:00
Merge branch 'develop' into stripe-integrate
This commit is contained in:
@@ -2,8 +2,12 @@
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
export function Card({ className, children }) {
|
||||
return <CardRoot className={className}>{children}</CardRoot>;
|
||||
export function Card({ className, style, children }) {
|
||||
return (
|
||||
<CardRoot className={className} style={style}>
|
||||
{children}
|
||||
</CardRoot>
|
||||
);
|
||||
}
|
||||
|
||||
const CardRoot = styled.div`
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
// @ts-nocheck
|
||||
import React, { createContext, useContext } from 'react';
|
||||
|
||||
const DrawerContext = createContext();
|
||||
interface DrawerContextValue {
|
||||
name: string;
|
||||
payload: Record<string, any>;
|
||||
}
|
||||
|
||||
const DrawerContext = createContext<DrawerContextValue>(
|
||||
{} as DrawerContextValue,
|
||||
);
|
||||
|
||||
/**
|
||||
* Account form provider.
|
||||
|
||||
@@ -23,6 +23,12 @@ import WarehouseTransferDetailDrawer from '@/containers/Drawers/WarehouseTransfe
|
||||
import TaxRateDetailsDrawer from '@/containers/TaxRates/drawers/TaxRateDetailsDrawer/TaxRateDetailsDrawer';
|
||||
import CategorizeTransactionDrawer from '@/containers/CashFlow/CategorizeTransaction/drawers/CategorizeTransactionDrawer/CategorizeTransactionDrawer';
|
||||
import ChangeSubscriptionPlanDrawer from '@/containers/Subscriptions/drawers/ChangeSubscriptionPlanDrawer/ChangeSubscriptionPlanDrawer';
|
||||
import { InvoiceCustomizeDrawer } from '@/containers/Sales/Invoices/InvoiceCustomize/InvoiceCustomizeDrawer';
|
||||
import { EstimateCustomizeDrawer } from '@/containers/Sales/Estimates/EstimateCustomize/EstimateCustomizeDrawer';
|
||||
import { ReceiptCustomizeDrawer } from '@/containers/Sales/Receipts/ReceiptCustomize/ReceiptCustomizeDrawer';
|
||||
import { CreditNoteCustomizeDrawer } from '@/containers/Sales/CreditNotes/CreditNoteCustomize/CreditNoteCustomizeDrawer';
|
||||
import { PaymentReceivedCustomizeDrawer } from '@/containers/Sales/PaymentsReceived/PaymentReceivedCustomize/PaymentReceivedCustomizeDrawer';
|
||||
import { BrandingTemplatesDrawer } from '@/containers/BrandingTemplates/BrandingTemplatesDrawer';
|
||||
|
||||
import { DRAWERS } from '@/constants/drawers';
|
||||
|
||||
@@ -65,6 +71,14 @@ export default function DrawersContainer() {
|
||||
<TaxRateDetailsDrawer name={DRAWERS.TAX_RATE_DETAILS} />
|
||||
<CategorizeTransactionDrawer name={DRAWERS.CATEGORIZE_TRANSACTION} />
|
||||
<ChangeSubscriptionPlanDrawer name={DRAWERS.CHANGE_SUBSCARIPTION_PLAN} />
|
||||
<InvoiceCustomizeDrawer name={DRAWERS.INVOICE_CUSTOMIZE} />
|
||||
<EstimateCustomizeDrawer name={DRAWERS.ESTIMATE_CUSTOMIZE} />
|
||||
<ReceiptCustomizeDrawer name={DRAWERS.RECEIPT_CUSTOMIZE} />
|
||||
<CreditNoteCustomizeDrawer name={DRAWERS.CREDIT_NOTE_CUSTOMIZE} />
|
||||
<PaymentReceivedCustomizeDrawer
|
||||
name={DRAWERS.PAYMENT_RECEIVED_CUSTOMIZE}
|
||||
/>
|
||||
<BrandingTemplatesDrawer name={DRAWERS.BRANDING_TEMPLATES} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
15
packages/webapp/src/components/Forms/ColorInput.module.scss
Normal file
15
packages/webapp/src/components/Forms/ColorInput.module.scss
Normal file
@@ -0,0 +1,15 @@
|
||||
|
||||
.field{
|
||||
height: 28px;
|
||||
line-height: 28px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.colorPicker{
|
||||
background-color: rgb(103, 114, 229);
|
||||
border-radius: 3px;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1);
|
||||
cursor: pointer;
|
||||
}
|
||||
85
packages/webapp/src/components/Forms/ColorInput.tsx
Normal file
85
packages/webapp/src/components/Forms/ColorInput.tsx
Normal file
@@ -0,0 +1,85 @@
|
||||
import { useState } from 'react';
|
||||
import clsx from 'classnames';
|
||||
import {
|
||||
IInputGroupProps,
|
||||
InputGroup,
|
||||
IPopoverProps,
|
||||
Popover,
|
||||
PopoverInteractionKind,
|
||||
Position,
|
||||
} from '@blueprintjs/core';
|
||||
import { HexColorPicker } from 'react-colorful';
|
||||
import { useUncontrolled } from '@/hooks/useUncontrolled';
|
||||
import { Box, BoxProps } from '@/components';
|
||||
import { sanitizeToHexColor } from '@/utils/sanitize-hex-color';
|
||||
import styles from './ColorInput.module.scss';
|
||||
|
||||
export interface ColorInputProps {
|
||||
value?: string;
|
||||
initialValue?: string;
|
||||
onChange?: (value: string) => void;
|
||||
popoverProps?: Partial<IPopoverProps>;
|
||||
inputProps?: Partial<IInputGroupProps>;
|
||||
pickerProps?: Partial<BoxProps>;
|
||||
pickerWrapProps?: Partial<BoxProps>;
|
||||
}
|
||||
|
||||
export function ColorInput({
|
||||
value,
|
||||
initialValue,
|
||||
onChange,
|
||||
popoverProps,
|
||||
inputProps,
|
||||
pickerWrapProps,
|
||||
pickerProps,
|
||||
}: ColorInputProps) {
|
||||
const [_value, handleChange] = useUncontrolled({
|
||||
value,
|
||||
initialValue,
|
||||
onChange,
|
||||
finalValue: '',
|
||||
});
|
||||
const [isOpen, setIsOpen] = useState<boolean>(false);
|
||||
|
||||
const handleClose = () => {
|
||||
setIsOpen(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<Popover
|
||||
content={<HexColorPicker color={_value} onChange={handleChange} />}
|
||||
position={Position.BOTTOM}
|
||||
interactionKind={PopoverInteractionKind.CLICK}
|
||||
modifiers={{
|
||||
offset: { offset: '0, 4' },
|
||||
}}
|
||||
onClose={handleClose}
|
||||
isOpen={isOpen}
|
||||
minimal
|
||||
{...popoverProps}
|
||||
>
|
||||
<InputGroup
|
||||
value={_value}
|
||||
leftElement={
|
||||
<Box
|
||||
{...pickerWrapProps}
|
||||
style={{ padding: 8, ...pickerWrapProps?.style }}
|
||||
>
|
||||
<Box
|
||||
onClick={() => setIsOpen((oldValue) => !oldValue)}
|
||||
style={{ backgroundColor: _value }}
|
||||
className={clsx(styles.colorPicker, pickerProps?.className)}
|
||||
{...pickerProps}
|
||||
/>
|
||||
</Box>
|
||||
}
|
||||
onChange={(e) => {
|
||||
const value = sanitizeToHexColor(e.currentTarget.value);
|
||||
handleChange(value);
|
||||
}}
|
||||
{...inputProps}
|
||||
className={clsx(styles.field, inputProps?.className)}
|
||||
/>
|
||||
</Popover>
|
||||
);
|
||||
}
|
||||
64
packages/webapp/src/components/Forms/FColorInput.tsx
Normal file
64
packages/webapp/src/components/Forms/FColorInput.tsx
Normal file
@@ -0,0 +1,64 @@
|
||||
import React from 'react';
|
||||
import { getIn, FieldConfig, FieldProps } from 'formik';
|
||||
import { Intent } from '@blueprintjs/core';
|
||||
import { Field } from '@blueprintjs-formik/core';
|
||||
import { ColorInput, ColorInputProps } from './ColorInput';
|
||||
|
||||
interface ColorInputInputGroupProps
|
||||
extends Omit<FieldConfig, 'children' | 'component' | 'as' | 'value'>,
|
||||
ColorInputProps {}
|
||||
|
||||
export interface ColorInputToInputProps
|
||||
extends Omit<FieldProps, 'onChange'>,
|
||||
ColorInputProps {}
|
||||
|
||||
/**
|
||||
* Transforms field props to input group props for ColorInput.
|
||||
* @param {ColorInputToInputProps}
|
||||
* @returns {ColorInputProps}
|
||||
*/
|
||||
function fieldToColorInputInputGroup({
|
||||
field: { onBlur: onFieldBlur, onChange: onFieldChange, value, ...field },
|
||||
form: { touched, errors, setFieldValue },
|
||||
onChange,
|
||||
...props
|
||||
}: ColorInputToInputProps): ColorInputProps {
|
||||
const fieldError = getIn(errors, field.name);
|
||||
const showError = getIn(touched, field.name) && !!fieldError;
|
||||
|
||||
return {
|
||||
inputProps: {
|
||||
intent: showError ? Intent.DANGER : Intent.NONE,
|
||||
},
|
||||
value,
|
||||
onChange:
|
||||
onChange ??
|
||||
function (value: string) {
|
||||
setFieldValue(field.name, value);
|
||||
},
|
||||
...field,
|
||||
...props,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms field props to input group props for ColorInput.
|
||||
* @param {ColorInputToInputProps} props -
|
||||
* @returns {JSX.Element}
|
||||
*/
|
||||
function ColorInputToInputGroup({
|
||||
...props
|
||||
}: ColorInputToInputProps): JSX.Element {
|
||||
return <ColorInput {...fieldToColorInputInputGroup(props)} />;
|
||||
}
|
||||
|
||||
/**
|
||||
* Input group Blueprint component binded with Formik for ColorInput.
|
||||
* @param {ColorInputInputGroupProps}
|
||||
* @returns {JSX.Element}
|
||||
*/
|
||||
export function FColorInput({
|
||||
...props
|
||||
}: ColorInputInputGroupProps): JSX.Element {
|
||||
return <Field {...props} component={ColorInputToInputGroup} />;
|
||||
}
|
||||
@@ -6,16 +6,14 @@ import styled from 'styled-components';
|
||||
import clsx from 'classnames';
|
||||
|
||||
export function FSelect({ ...props }) {
|
||||
const input = ({ activeItem, text, label, value }) => {
|
||||
return (
|
||||
<SelectButton
|
||||
text={text || props.placeholder || 'Select an item ...'}
|
||||
disabled={props.disabled || false}
|
||||
{...props.buttonProps}
|
||||
className={clsx({ 'is-selected': !!text }, props.className)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
const input = ({ activeItem, text, label, value }) => (
|
||||
<SelectButton
|
||||
text={text || props.placeholder || 'Select an item ...'}
|
||||
disabled={props.disabled || false}
|
||||
{...props.buttonProps}
|
||||
className={clsx({ 'is-selected': !!text }, props.className)}
|
||||
/>
|
||||
);
|
||||
return <Select input={input} fill={true} {...props} />;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user