Merge branch 'develop' into big-44-auto-re-calculate-the-items-rate-once-changing-the-invoice

This commit is contained in:
Ahmed Bouhuolia
2024-01-11 20:27:42 +02:00
403 changed files with 24846 additions and 9622 deletions

View File

@@ -51,8 +51,8 @@ export default function Dashboard() {
</Switch>
<DashboardUniversalSearch />
<DialogsContainer />
<GlobalHotkeys />
<DialogsContainer />
<DrawersContainer />
<AlertsContainer />
</DashboardProvider>

View File

@@ -46,6 +46,10 @@ import ProjectBillableEntriesFormDialog from '@/containers/Projects/containers/P
import TaxRateFormDialog from '@/containers/TaxRates/dialogs/TaxRateFormDialog/TaxRateFormDialog';
import { DialogsName } from '@/constants/dialogs';
import InvoiceExchangeRateChangeDialog from '@/containers/Sales/Invoices/InvoiceForm/Dialogs/InvoiceExchangeRateChangeDialog';
import InvoiceMailDialog from '@/containers/Sales/Invoices/InvoiceMailDialog/InvoiceMailDialog';
import EstimateMailDialog from '@/containers/Sales/Estimates/EstimateMailDialog/EstimateMailDialog';
import ReceiptMailDialog from '@/containers/Sales/Receipts/ReceiptMailDialog/ReceiptMailDialog';
import PaymentMailDialog from '@/containers/Sales/PaymentReceives/PaymentMailDialog/PaymentMailDialog';
/**
* Dialogs container.
@@ -138,6 +142,10 @@ export default function DialogsContainer() {
<InvoiceExchangeRateChangeDialog
dialogName={DialogsName.InvoiceExchangeRateChangeNotice}
/>
<InvoiceMailDialog dialogName={DialogsName.InvoiceMail} />
<EstimateMailDialog dialogName={DialogsName.EstimateMail} />
<ReceiptMailDialog dialogName={DialogsName.ReceiptMail} />
<PaymentMailDialog dialogName={DialogsName.PaymentMail} />
</div>
);
}

View File

@@ -0,0 +1,52 @@
import React from 'react';
import { FieldConfig, FieldProps } from 'formik';
import { Field } from '@blueprintjs-formik/core';
import { RichEditor, RichEditorProps } from '../../components/RichEditor';
export interface FRichEditorProps
extends Omit<FieldConfig, 'children' | 'component' | 'as'>,
RichEditorProps {
name: string;
value?: string;
}
interface FieldToRichEditorProps
extends FieldProps,
Omit<RichEditorProps, 'form'> {}
/**
* Transformes the field props to `RichEditor` props.
* @param {FieldToRichEditorProps}
* @returns {HTMLSelectProps}
*/
function fieldToRichEditor({
field: { onBlur: onFieldBlur, ...field },
form: { touched, errors, ...form },
...props
}: FieldToRichEditorProps): RichEditorProps {
return {
...field,
...props,
onChange: (value: string) => {
form.setFieldValue(field.name, value);
},
};
}
/**
* Transformes field props to `RichEditor` props.
* @param {FieldToRichEditorProps}
* @returns {JSX.Element}
*/
function FieldToRichEditor({ ...props }: FieldToRichEditorProps): JSX.Element {
return <RichEditor {...fieldToRichEditor(props)} />;
}
/**
* Rich editor wrapper to bind with Formik.
* @param {FRichEditorProps} props -
* @returns {JSX.Element}
*/
export function FRichEditor({ ...props }: FRichEditorProps): JSX.Element {
return <Field {...props} component={FieldToRichEditor} />;
}

View File

@@ -4,4 +4,5 @@ export * from './FMoneyInputGroup';
export * from './BlueprintFormik';
export * from './InputPrependText';
export * from './InputPrependButton';
export * from './MoneyInputGroup';
export * from './MoneyInputGroup';
export * from './FRichEditor';

View File

@@ -0,0 +1,66 @@
/* Basic editor styles */
.tiptap {
color: #222;
&:focus-visible {
outline: none;
}
>*+* {
margin-top: 0.75em;
}
ul,
ol {
padding: 0 1rem;
}
h1,
h2,
h3,
h4,
h5,
h6 {
line-height: 1.1;
}
code {
background: rgba(#ffffff, 0.1);
color: rgba(#ffffff, 0.6);
border: 1px solid rgba(#ffffff, 0.1);
border-radius: 0.5rem;
padding: 0.2rem;
}
pre {
background: rgba(#ffffff, 0.1);
font-family: "JetBrainsMono", monospace;
padding: 0.75rem 1rem;
border-radius: 0.5rem;
code {
color: inherit;
padding: 0;
background: none;
font-size: 0.8rem;
border: none;
}
}
img {
max-width: 100%;
height: auto;
}
blockquote {
margin-left: 0;
padding-left: 1rem;
border-left: 2px solid rgba(#ffffff, 0.4);
hr {
border: none;
border-top: 2px solid rgba(#ffffff, 0.1);
margin: 2rem 0;
}
}
}

View File

@@ -0,0 +1,58 @@
// @ts-nocheck
import { Color } from '@tiptap/extension-color';
import ListItem from '@tiptap/extension-list-item';
import TextStyle from '@tiptap/extension-text-style';
import { EditorProvider } from '@tiptap/react';
import StarterKit from '@tiptap/starter-kit';
import { useUncontrolled } from '@/hooks/useUncontrolled';
import { Box } from '../Layout/Box';
import './RichEditor.style.scss';
const extensions = [
Color.configure({ types: [TextStyle.name, ListItem.name] }),
TextStyle.configure({ types: [ListItem.name] }),
StarterKit.configure({
bulletList: {
keepMarks: true,
keepAttributes: false,
},
orderedList: {
keepMarks: true,
keepAttributes: false,
},
}),
];
export interface RichEditorProps {
value?: string;
initialValue?: string;
onChange?: (value: string) => void;
className?: string;
}
export const RichEditor = ({
value,
initialValue,
onChange,
className,
}: RichEditorProps) => {
const [content, handleChange] = useUncontrolled({
value,
initialValue,
onChange,
finalValue: '',
});
const handleBlur = ({ editor }) => {
handleChange(editor.getHTML());
};
return (
<Box className={className}>
<EditorProvider
extensions={extensions}
content={content}
onBlur={handleBlur}
/>
</Box>
);
};

View File

@@ -0,0 +1 @@
export * from './RichEditor';