Skip to content

Commit

Permalink
Merge pull request #575 from invoiceninja/develop
Browse files Browse the repository at this point in the history
Sync develop with main
  • Loading branch information
beganovich authored Mar 28, 2023
2 parents 7509e4b + 3d2ca05 commit bed09da
Show file tree
Hide file tree
Showing 93 changed files with 1,263 additions and 712 deletions.
8 changes: 5 additions & 3 deletions src/common/constants/recurring-expense.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
import { RecurringExpenseStatus } from '$app/common/enums/recurring-expense-status';

export default {
[RecurringExpenseStatus.ACTIVE]: 'active',
[RecurringExpenseStatus.DRAFT]: 'draft',
[RecurringExpenseStatus.PAUSED]: 'paused',
[RecurringExpenseStatus.Active]: 'active',
[RecurringExpenseStatus.Draft]: 'draft',
[RecurringExpenseStatus.Paused]: 'paused',
[RecurringExpenseStatus.Pending]: 'pending',
[RecurringExpenseStatus.Completed]: 'completed',
};
1 change: 1 addition & 0 deletions src/common/enums/credit-status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
*/

export const enum CreditStatus {
Viewed = '-1',
Draft = '1',
Sent = '2',
Partial = '3',
Expand Down
17 changes: 17 additions & 0 deletions src/common/enums/expense-status.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com)
*
* @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://www.elastic.co/licensing/elastic-license
*/

export const enum ExpenseStatus {
Logged = '1',
Pending = '2',
Invoiced = '3',
Unpaid = '4',
Paid = '5',
}
1 change: 1 addition & 0 deletions src/common/enums/purchase-order-status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
*/

export const enum PurchaseOrderStatus {
Viewed = '-1',
Draft = '1',
Sent = '2',
Accepted = '3',
Expand Down
3 changes: 2 additions & 1 deletion src/common/enums/quote-status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@
*/

export const enum QuoteStatus {
Viewed = '-2',
Expired = '-1',
Draft = '1',
Sent = '2',
Approved = '3',
Converted = '4',
Expired = '-1',
}
8 changes: 5 additions & 3 deletions src/common/enums/recurring-expense-status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
*/

export const enum RecurringExpenseStatus {
DRAFT = '1',
ACTIVE = '2',
PAUSED = '3',
Draft = '1',
Active = '2',
Paused = '3',
Completed = '4',
Pending = '-1',
}
1 change: 1 addition & 0 deletions src/common/interfaces/company.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export interface Settings {
military_time: boolean;
language_id: string;
show_currency_code: boolean;
show_task_item_description: boolean;
show_email_footer: boolean;
company_gateway_ids: string;
currency_id: string;
Expand Down
38 changes: 28 additions & 10 deletions src/common/queries/expense-categories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,16 @@
* @license https://www.elastic.co/licensing/elastic-license
*/

import { AxiosResponse } from 'axios';
import { AxiosError } from 'axios';
import { endpoint } from '$app/common/helpers';
import { request } from '$app/common/helpers/request';
import { useQuery } from 'react-query';
import { useQuery, useQueryClient } from 'react-query';
import { route } from '$app/common/helpers/route';
import { Params } from './common/params.interface';
import { ExpenseCategory } from '$app/common/interfaces/expense-category';
import { GenericSingleResourceResponse } from '$app/common/interfaces/generic-api-response';
import { useHasPermission } from '$app/common/hooks/permissions/useHasPermission';
import { toast } from '$app/common/helpers/toast/toast';

interface ExpenseCategoriesParams extends Params {
enabled?: boolean;
Expand Down Expand Up @@ -62,14 +63,31 @@ export function useExpenseCategoryQuery(props: Props) {
);
}

export function bulk(
id: string[],
action: 'archive' | 'restore' | 'delete'
): Promise<AxiosResponse> {
return request('POST', endpoint('/api/v1/expense_categories/bulk'), {
action,
ids: id,
});
export function useBulkAction() {
const queryClient = useQueryClient();

return (id: string, action: 'archive' | 'restore' | 'delete') => {
toast.processing();

request('POST', endpoint('/api/v1/expense_categories/bulk'), {
action,
ids: [id],
})
.then(() => {
toast.success(`${action}d_expense_category`);

queryClient.invalidateQueries('/api/v1/expense_categories');

queryClient.invalidateQueries(
route('/api/v1/expense_categories/:id', { id })
);
})
.catch((error: AxiosError) => {
console.error(error);

toast.error();
});
};
}

export function useBlankExpenseCategoryQuery() {
Expand Down
38 changes: 28 additions & 10 deletions src/common/queries/task-statuses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,16 @@
* @license https://www.elastic.co/licensing/elastic-license
*/

import { AxiosResponse } from 'axios';
import { AxiosError } from 'axios';
import { endpoint } from '$app/common/helpers';
import { request } from '$app/common/helpers/request';
import { GenericManyResponse } from '$app/common/interfaces/generic-many-response';
import { TaskStatus } from '$app/common/interfaces/task-status';
import { useQuery } from 'react-query';
import { useQuery, useQueryClient } from 'react-query';
import { route } from '$app/common/helpers/route';
import { GenericSingleResourceResponse } from '$app/common/interfaces/generic-api-response';
import { useHasPermission } from '$app/common/hooks/permissions/useHasPermission';
import { toast } from '$app/common/helpers/toast/toast';

export function useBlankTaskStatusQuery() {
const hasPermission = useHasPermission();
Expand Down Expand Up @@ -51,12 +52,29 @@ export function useTaskStatusQuery(params: { id: string | undefined }) {
);
}

export function bulk(
id: string[],
action: 'archive' | 'restore' | 'delete'
): Promise<AxiosResponse> {
return request('POST', endpoint('/api/v1/task_statuses/bulk'), {
action,
ids: id,
});
export function useBulkAction() {
const queryClient = useQueryClient();

return (id: string, action: 'archive' | 'restore' | 'delete') => {
toast.processing();

request('POST', endpoint('/api/v1/task_statuses/bulk'), {
action,
ids: [id],
})
.then(() => {
toast.success(`${action}d_task_status`);

queryClient.invalidateQueries('/api/v1/task_statuses');

queryClient.invalidateQueries(
route('/api/v1/task_statuses/:id', { id })
);
})
.catch((error: AxiosError) => {
console.error(error);

toast.error();
});
};
}
30 changes: 28 additions & 2 deletions src/common/queries/tax-rates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,16 @@
* @license https://www.elastic.co/licensing/elastic-license
*/

import { AxiosResponse } from 'axios';
import { AxiosError, AxiosResponse } from 'axios';
import { endpoint } from '$app/common/helpers';
import { request } from '$app/common/helpers/request';
import { useQuery } from 'react-query';
import { useQuery, useQueryClient } from 'react-query';
import { route } from '$app/common/helpers/route';
import { Params } from './common/params.interface';
import { GenericSingleResourceResponse } from '$app/common/interfaces/generic-api-response';
import { TaxRate } from '$app/common/interfaces/tax-rate';
import { useAdmin } from '$app/common/hooks/permissions/useHasPermission';
import { toast } from '$app/common/helpers/toast/toast';

export function useTaxRatesQuery(params: Params) {
return useQuery(
Expand Down Expand Up @@ -67,3 +68,28 @@ export function useBlankTaxRateQuery() {
{ staleTime: Infinity, enabled: isAdmin }
);
}

export function useBulkAction() {
const queryClient = useQueryClient();

return (id: string, action: 'archive' | 'restore' | 'delete') => {
toast.processing();

request('POST', endpoint('/api/v1/tax_rates/bulk'), {
action,
ids: [id],
})
.then(() => {
toast.success(`${action}d_tax_rate`);

queryClient.invalidateQueries('/api/v1/tax_rates');

queryClient.invalidateQueries(route('/api/v1/tax_rates/:id', { id }));
})
.catch((error: AxiosError) => {
console.error(error);

toast.error();
});
};
}
6 changes: 3 additions & 3 deletions src/components/PasswordConfirmation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
*/
import { ChangeEvent, FormEvent, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router-dom';
import { Button, InputField } from './forms';
import { Modal } from './Modal';

Expand All @@ -20,6 +21,7 @@ interface Props {

export function PasswordConfirmation(props: Props) {
const [t] = useTranslation();
const navigate = useNavigate();

const [isModalOpen, setIsModalOpen] = useState(props.show ?? false);
const [currentPassword, setCurrentPassword] = useState('');
Expand All @@ -40,9 +42,7 @@ export function PasswordConfirmation(props: Props) {

return (
<Modal
onClose={() => {
props.onClose(false);
}}
onClose={() => navigate('/settings/users')}
visible={isModalOpen}
title={t('confirmation')}
text={t('please_enter_your_password')}
Expand Down
51 changes: 47 additions & 4 deletions src/components/forms/DebouncedCombobox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,15 @@ export function DebouncedCombobox(props: Props) {
const [isInitial, setIsInitial] = useState(true);
const [t] = useTranslation();
const [records, setRecords] = useState<Record[]>([internalRecord]);
const [initialRecords, setInitialRecords] = useState<Record[]>([
internalRecord,
]);
const [filteredRecords, setFilteredRecords] = useState<Record[]>([
internalRecord,
]);
const [isLoading, setIsLoading] = useState(true);
const [searchTermWithNoRecords, setSearchTermWithNoRecords] =
useState<string>('');

const [selectedOption, setSelectedOption] = useState({
record: records[0],
Expand Down Expand Up @@ -134,12 +139,49 @@ export function DebouncedCombobox(props: Props) {
setSelectedOption({ record, withoutEvents: isInitial });
}

if (isInitial) {
setInitialRecords(array);
}

const recordsWithoutInternal = array.filter((record) => !record.internal);

if (!recordsWithoutInternal.length) {
setSearchTermWithNoRecords(query);
} else {
setSearchTermWithNoRecords('');
}

setRecords(() => [...array]);
setIsLoading(false);
setIsInitial(false);
};

const debouncedSearch = debounce(async (query) => await request(query), 1500);
const debouncedSearch = debounce(async (query) => await request(query), 700);

const searchRecords = async (query: string) => {
const filteredList = records.filter(
(record) =>
record.label.toLowerCase().includes(query.toLowerCase()) &&
!record.internal
);

if (!query) {
setFilteredRecords(initialRecords);
setRecords(initialRecords);
return;
}

if (
!filteredList.length &&
((searchTermWithNoRecords &&
!query.startsWith(searchTermWithNoRecords)) ||
!searchTermWithNoRecords)
) {
await debouncedSearch(query);
} else {
setFilteredRecords(filteredList);
}
};

const filter = () => {
setFilteredRecords(
Expand All @@ -162,7 +204,7 @@ export function DebouncedCombobox(props: Props) {
if (props.clearInputAfterSelection) {
setSelectedOption({ record: internalRecord, withoutEvents: true });

debouncedSearch('');
searchRecords('');
}
}
}, [selectedOption]);
Expand Down Expand Up @@ -278,10 +320,11 @@ export function DebouncedCombobox(props: Props) {
autoComplete="off"
placeholder={props.placeholder || ''}
className="w-full border-none py-2 pl-3 pr-10 text-sm leading-5 text-gray-900 focus:ring-0"
onChange={(event) => debouncedSearch(event.target.value)}
onChange={(event) => searchRecords(event.target.value)}
displayValue={(record: Record) => record.label}
onClick={() => openDropdownButton.current?.click()}
onFocus={props.onInputFocus}
readOnly={isLoading}
/>

{props.clearButton &&
Expand All @@ -297,7 +340,7 @@ export function DebouncedCombobox(props: Props) {
withoutEvents: true,
});

debouncedSearch('');
searchRecords('');

props.onClearButtonClick();
}}
Expand Down
9 changes: 6 additions & 3 deletions src/components/layouts/Default.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ interface Props extends CommonProps {
saveButtonLabel?: string | null;
backButtonLabel?: string;
disableSaveButton?: boolean;
withoutBackButton?: boolean;
}

export function Default(props: Props) {
Expand Down Expand Up @@ -415,9 +416,11 @@ export function Default(props: Props) {
</Button>
)}

<Button onClick={() => navigate(-1)} type="secondary">
{t('back')}
</Button>
{!props.withoutBackButton && (
<Button onClick={() => navigate(-1)} type="secondary">
{t('back')}
</Button>
)}

{props.onSaveClick && (
<Button
Expand Down
Loading

0 comments on commit bed09da

Please sign in to comment.