1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2024-11-29 10:24:20 +01:00

(ui) add alert on leaving plan form with unsaved changes

This commit is contained in:
Sylvain 2023-03-09 15:57:46 +01:00
parent 2b8a7008bd
commit dad3babbe4
6 changed files with 27 additions and 16 deletions

View File

@ -26,6 +26,8 @@ import { PlanPricingForm } from './plan-pricing-form';
import { AdvancedAccountingForm } from '../accounting/advanced-accounting-form';
import { FabTabs } from '../base/fab-tabs';
import { PlanLimitForm } from './plan-limit-form';
import { UnsavedFormAlert } from '../form/unsaved-form-alert';
import { UIRouter } from '@uirouter/angularjs';
declare const Application: IApplication;
@ -35,12 +37,13 @@ interface PlanFormProps {
onError: (message: string) => void,
onSuccess: (message: string) => void,
beforeSubmit?: (data: Plan) => void,
uiRouter: UIRouter
}
/**
* Form to edit or create subscription plans
*/
export const PlanForm: React.FC<PlanFormProps> = ({ action, plan, onError, onSuccess, beforeSubmit }) => {
export const PlanForm: React.FC<PlanFormProps> = ({ action, plan, onError, onSuccess, beforeSubmit, uiRouter }) => {
const { handleSubmit, register, control, formState, setValue } = useForm<Plan>({ defaultValues: { ...plan } });
const output = useWatch<Plan>({ control }); // eslint-disable-line
const { t } = useTranslation('admin');
@ -316,6 +319,7 @@ export const PlanForm: React.FC<PlanFormProps> = ({ action, plan, onError, onSuc
</header>
<form onSubmit={handleSubmit(onSubmit)}>
<UnsavedFormAlert uiRouter={uiRouter} formState={formState} />
<FabTabs tabs={[
{
id: 'settings',
@ -350,4 +354,4 @@ const PlanFormWrapper: React.FC<PlanFormProps> = (props) => {
</Loader>
);
};
Application.Components.component('planForm', react2angular(PlanFormWrapper, ['action', 'plan', 'onError', 'onSuccess']));
Application.Components.component('planForm', react2angular(PlanFormWrapper, ['action', 'plan', 'onError', 'onSuccess', 'uiRouter']));

View File

@ -21,11 +21,14 @@
/**
* Controller used in the plan creation form
*/
Application.Controllers.controller('NewPlanController', ['$scope', '$uibModal', 'groups', 'prices', 'partners', 'CSRF', '$state', 'growl', '_t', 'planCategories',
function ($scope, $uibModal, groups, prices, partners, CSRF, $state, growl, _t, planCategories) {
Application.Controllers.controller('NewPlanController', ['$scope', '$uibModal', 'groups', 'prices', 'partners', 'CSRF', '$state', 'growl', '_t', '$uiRouter',
function ($scope, $uibModal, groups, prices, partners, CSRF, $state, growl, _t, $uiRouter) {
// protection against request forgery
CSRF.setMetaTags();
// the following item is used by the UnsavedFormAlert component to detect a page change
$scope.uiRouter = $uiRouter;
/**
* Shows an error message forwarded from a child component
*/
@ -46,13 +49,16 @@ Application.Controllers.controller('NewPlanController', ['$scope', '$uibModal',
/**
* Controller used in the plan edition form
*/
Application.Controllers.controller('EditPlanController', ['$scope', 'groups', 'plans', 'planPromise', 'machines', 'spaces', 'prices', 'partners', 'CSRF', '$state', '$transition$', 'growl', '$filter', '_t', 'Plan', 'planCategories',
function ($scope, groups, plans, planPromise, machines, spaces, prices, partners, CSRF, $state, $transition$, growl, $filter, _t, Plan, planCategories) {
Application.Controllers.controller('EditPlanController', ['$scope', 'groups', 'plans', 'planPromise', 'machines', 'spaces', 'prices', 'partners', 'CSRF', '$state', '$transition$', 'growl', '$filter', '_t', '$uiRouter',
function ($scope, groups, plans, planPromise, machines, spaces, prices, partners, CSRF, $state, $transition$, growl, $filter, _t, $uiRouter) {
// protection against request forgery
CSRF.setMetaTags();
$scope.suscriptionPlan = cleanPlan(planPromise);
// the following item is used by the UnsavedFormAlert component to detect a page change
$scope.uiRouter = $uiRouter;
/**
* Shows an error message forwarded from a child component
*/

View File

@ -44,7 +44,7 @@ export interface Plan {
partnership?: boolean,
partners?: Array<Partner>,
advanced_accounting_attributes?: AdvancedAccounting,
plan_limitations_attributes: Array<PlanLimitation>
plan_limitations_attributes?: Array<PlanLimitation>
}
export interface PlansDuration {

View File

@ -13,4 +13,4 @@
</div>
</section>
<plan-form action="'update'" plan="suscriptionPlan" on-error="onError" on-success="onSuccess"></plan-form>
<plan-form action="'update'" plan="suscriptionPlan" on-error="onError" on-success="onSuccess" ui-router="uiRouter"></plan-form>

View File

@ -14,4 +14,4 @@
</div>
</section>
<plan-form action="'create'" on-error="onError" on-success="onSuccess"></plan-form>
<plan-form action="'create'" on-error="onError" on-success="onSuccess" ui-router="uiRouter"></plan-form>

View File

@ -7,6 +7,7 @@ import userEvent from '@testing-library/user-event';
import plans from '../../__fixtures__/plans';
import machines from '../../__fixtures__/machines';
import { tiptapEvent } from '../../__lib__/tiptap';
import { uiRouter } from '../../__lib__/ui-router';
describe('PlanForm', () => {
const onError = jest.fn();
@ -14,7 +15,7 @@ describe('PlanForm', () => {
const beforeSubmit = jest.fn();
test('render create PlanForm', async () => {
render(<PlanForm action="create" onError={onError} onSuccess={onSuccess} />);
render(<PlanForm action="create" onError={onError} onSuccess={onSuccess} uiRouter={uiRouter} />);
await waitFor(() => screen.getByRole('combobox', { name: /app.admin.plan_form.group/ }));
expect(screen.getByLabelText(/app.admin.plan_form.name/)).toBeInTheDocument();
expect(screen.getByLabelText(/app.admin.plan_form.transversal/)).toBeInTheDocument();
@ -35,7 +36,7 @@ describe('PlanForm', () => {
});
test('create new plan', async () => {
render(<PlanForm action="create" onError={onError} onSuccess={onSuccess} beforeSubmit={beforeSubmit} />);
render(<PlanForm action="create" onError={onError} onSuccess={onSuccess} beforeSubmit={beforeSubmit} uiRouter={uiRouter} />);
await waitFor(() => screen.getByRole('combobox', { name: /app.admin.plan_form.group/ }));
const user = userEvent.setup();
// base_name
@ -98,7 +99,7 @@ describe('PlanForm', () => {
test('render update PlanForm with partner', async () => {
const plan = plans[1];
render(<PlanForm action="update" plan={plan} onError={onError} onSuccess={onSuccess} />);
render(<PlanForm action="update" plan={plan} onError={onError} onSuccess={onSuccess} uiRouter={uiRouter} />);
await waitFor(() => screen.getByRole('combobox', { name: /app.admin.plan_pricing_form.copy_prices_from/ }));
expect(screen.getByLabelText(/app.admin.plan_form.name/)).toBeInTheDocument();
expect(screen.queryByLabelText(/app.admin.plan_form.transversal/)).toBeNull();
@ -123,14 +124,14 @@ describe('PlanForm', () => {
});
test('selecting transversal plan disables group select', async () => {
render(<PlanForm action="create" onError={onError} onSuccess={onSuccess} />);
render(<PlanForm action="create" onError={onError} onSuccess={onSuccess} uiRouter={uiRouter} />);
await waitFor(() => screen.getByRole('combobox', { name: /app.admin.plan_form.group/ }));
fireEvent.click(screen.getByRole('switch', { name: /app.admin.plan_form.transversal/ }));
expect(screen.queryByRole('combobox', { name: /app.admin.plan_form.group/ })).toBeNull();
});
test('selecting partner plan shows partner selection', async () => {
render(<PlanForm action="create" onError={onError} onSuccess={onSuccess} />);
render(<PlanForm action="create" onError={onError} onSuccess={onSuccess} uiRouter={uiRouter} />);
await waitFor(() => screen.getByRole('combobox', { name: /app.admin.plan_form.group/ }));
fireEvent.click(screen.getByRole('switch', { name: /app.admin.plan_form.partner_plan/ }));
expect(screen.getByLabelText(/app.admin.plan_form.notified_partner/));
@ -138,7 +139,7 @@ describe('PlanForm', () => {
});
test('creating a new partner selects him by default', async () => {
render(<PlanForm action="create" onError={onError} onSuccess={onSuccess} />);
render(<PlanForm action="create" onError={onError} onSuccess={onSuccess} uiRouter={uiRouter} />);
await waitFor(() => screen.getByRole('combobox', { name: /app.admin.plan_form.group/ }));
fireEvent.click(screen.getByRole('switch', { name: /app.admin.plan_form.partner_plan/ }));
fireEvent.click(screen.getByRole('button', { name: /app.admin.plan_form.new_user/ }));
@ -157,7 +158,7 @@ describe('PlanForm', () => {
test('update plan prices', async () => {
const plan = plans[1];
const machine = machines[1];
render(<PlanForm action="update" plan={plan} onError={onError} onSuccess={onSuccess} beforeSubmit={beforeSubmit} />);
render(<PlanForm action="update" plan={plan} onError={onError} onSuccess={onSuccess} beforeSubmit={beforeSubmit} uiRouter={uiRouter} />);
await waitFor(() => screen.getByLabelText(new RegExp(machine.name)));
// update machine price
fireEvent.change(screen.getByLabelText(new RegExp(machine.name)), { target: { value: 42.42 } });