mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2024-11-28 09:24:24 +01:00
optimized the load time of the payment schedules list
From now, we no longer retrieve the client_secret directly from the API/list but from a specialized component which ask API/get_item. This highly decrease the laod time needed to fetch API/list
This commit is contained in:
parent
bfb1a1c3f9
commit
effe5c7ba9
@ -1,6 +1,7 @@
|
||||
# Changelog Fab-manager
|
||||
|
||||
- Updated caniuse db
|
||||
- Optimized the load time of the payment schedules list
|
||||
|
||||
# v5.3.0 2021 December 29
|
||||
|
||||
|
@ -4,8 +4,9 @@
|
||||
class API::PaymentSchedulesController < API::ApiController
|
||||
before_action :authenticate_user!
|
||||
before_action :set_payment_schedule, only: %i[download cancel]
|
||||
before_action :set_payment_schedule_item, only: %i[cash_check refresh_item pay_item]
|
||||
before_action :set_payment_schedule_item, only: %i[show_item cash_check refresh_item pay_item]
|
||||
|
||||
# retrieve all payment schedules for the current user, paginated
|
||||
def index
|
||||
@payment_schedules = PaymentSchedule.where('invoicing_profile_id = ?', current_user.invoicing_profile.id)
|
||||
.includes(:invoicing_profile, :payment_schedule_items, :payment_schedule_objects)
|
||||
@ -15,6 +16,7 @@ class API::PaymentSchedulesController < API::ApiController
|
||||
.per(params[:size])
|
||||
end
|
||||
|
||||
# retrieve all payment schedules for all users. Filtering is supported
|
||||
def list
|
||||
authorize PaymentSchedule
|
||||
|
||||
@ -62,6 +64,11 @@ class API::PaymentSchedulesController < API::ApiController
|
||||
end
|
||||
end
|
||||
|
||||
def show_item
|
||||
authorize @payment_schedule_item.payment_schedule
|
||||
render json: @payment_schedule_item, status: :ok
|
||||
end
|
||||
|
||||
def cancel
|
||||
authorize @payment_schedule
|
||||
|
||||
|
@ -4,7 +4,7 @@ import {
|
||||
CancelScheduleResponse,
|
||||
CashCheckResponse, PayItemResponse,
|
||||
PaymentSchedule,
|
||||
PaymentScheduleIndexRequest, RefreshItemResponse
|
||||
PaymentScheduleIndexRequest, PaymentScheduleItem, RefreshItemResponse
|
||||
} from '../models/payment-schedule';
|
||||
|
||||
export default class PaymentScheduleAPI {
|
||||
@ -23,6 +23,11 @@ export default class PaymentScheduleAPI {
|
||||
return res?.data;
|
||||
}
|
||||
|
||||
static async getItem (paymentScheduleItemId: number): Promise<PaymentScheduleItem> {
|
||||
const res: AxiosResponse = await apiClient.get(`/api/payment_schedules/items/${paymentScheduleItemId}`);
|
||||
return res?.data;
|
||||
}
|
||||
|
||||
static async refreshItem (paymentScheduleItemId: number): Promise<RefreshItemResponse> {
|
||||
const res: AxiosResponse = await apiClient.post(`/api/payment_schedules/items/${paymentScheduleItemId}/refresh_item`);
|
||||
return res?.data;
|
||||
|
@ -11,6 +11,7 @@ import { User, UserRole } from '../../models/user';
|
||||
import { PaymentSchedule, PaymentScheduleItem, PaymentScheduleItemState } from '../../models/payment-schedule';
|
||||
import PaymentScheduleAPI from '../../api/payment-schedule';
|
||||
import FormatLib from '../../lib/format';
|
||||
import { StripeConfirmModal } from '../payment/stripe/stripe-confirm-modal';
|
||||
|
||||
interface PaymentSchedulesTableProps {
|
||||
paymentSchedules: Array<PaymentSchedule>,
|
||||
@ -412,14 +413,10 @@ const PaymentSchedulesTableComponent: React.FC<PaymentSchedulesTableProps> = ({
|
||||
{t('app.shared.schedules_table.confirm_cancel_subscription')}
|
||||
</FabModal>
|
||||
<StripeElements>
|
||||
<FabModal title={t('app.shared.schedules_table.resolve_action')}
|
||||
isOpen={showResolveAction}
|
||||
{tempDeadline && <StripeConfirmModal isOpen={showResolveAction}
|
||||
toggleModal={toggleResolveActionModal}
|
||||
onConfirm={afterAction}
|
||||
confirmButton={t('app.shared.schedules_table.ok_button')}
|
||||
preventConfirm={isConfirmActionDisabled}>
|
||||
{tempDeadline && <StripeConfirm clientSecret={tempDeadline.client_secret} onResponse={toggleConfirmActionButton} />}
|
||||
</FabModal>
|
||||
onSuccess={afterAction}
|
||||
paymentScheduleItemId={tempDeadline.id} />}
|
||||
{tempSchedule && <UpdateCardModal isOpen={showUpdateCard}
|
||||
toggleModal={toggleUpdateCardModal}
|
||||
operator={operator}
|
||||
|
@ -0,0 +1,55 @@
|
||||
import { StripeConfirm } from './stripe-confirm';
|
||||
import { FabModal } from '../../base/fab-modal';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import PaymentScheduleAPI from '../../../api/payment-schedule';
|
||||
import { PaymentScheduleItem } from '../../../models/payment-schedule';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
interface StripeConfirmModalProps {
|
||||
isOpen: boolean,
|
||||
toggleModal: () => void,
|
||||
onSuccess: () => void,
|
||||
paymentScheduleItemId: number,
|
||||
}
|
||||
|
||||
/**
|
||||
* Modal dialog that trigger a 3D secure confirmation for the given payment schedule item (deadline for a payment schedule).
|
||||
*/
|
||||
export const StripeConfirmModal: React.FC<StripeConfirmModalProps> = ({ isOpen, toggleModal, onSuccess, paymentScheduleItemId }) => {
|
||||
const { t } = useTranslation('shared');
|
||||
|
||||
const [item, setItem] = useState<PaymentScheduleItem>(null);
|
||||
const [isPending, setIsPending] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
PaymentScheduleAPI.getItem(paymentScheduleItemId).then(data => {
|
||||
setItem(data);
|
||||
});
|
||||
}, [paymentScheduleItemId]);
|
||||
|
||||
/**
|
||||
* Callback triggered when the confirm button was clicked in the modal.
|
||||
*/
|
||||
const onConfirmed = (): void => {
|
||||
togglePending();
|
||||
onSuccess();
|
||||
};
|
||||
|
||||
/**
|
||||
* Enable/disable the confirm button of the "action" modal
|
||||
*/
|
||||
const togglePending = (): void => {
|
||||
setIsPending(!isPending);
|
||||
};
|
||||
|
||||
return (
|
||||
<FabModal title={t('app.shared.schedules_table.resolve_action')}
|
||||
isOpen={isOpen}
|
||||
toggleModal={toggleModal}
|
||||
onConfirm={onConfirmed}
|
||||
confirmButton={t('app.shared.schedules_table.ok_button')}
|
||||
preventConfirm={isPending}>
|
||||
{item && <StripeConfirm clientSecret={item.client_secret} onResponse={togglePending} />}
|
||||
</FabModal>
|
||||
);
|
||||
};
|
@ -35,7 +35,7 @@ const EditPlanCategoryComponent: React.FC<EditPlanCategoryProps> = ({ onSuccess,
|
||||
|
||||
/**
|
||||
* The edit has been confirmed by the user.
|
||||
* Call the API to trigger the update of the temporary set plan-category
|
||||
* Call the API to trigger the update of the temporary set plan-category.
|
||||
*/
|
||||
const onEditConfirmed = (): void => {
|
||||
PlanCategoryAPI.update(tempCategory).then((updatedCategory) => {
|
||||
|
@ -14,9 +14,10 @@ class PaymentScheduleItem < Footprintable
|
||||
|
||||
def payment_intent
|
||||
return unless payment_gateway_object
|
||||
return unless payment_gateway_object.gateway_object.gateway == 'Stripe'
|
||||
|
||||
stp_invoice = payment_gateway_object.gateway_object.retrieve
|
||||
Stripe::PaymentIntent.retrieve(stp_invoice.payment_intent, api_key: Setting.get('stripe_secret_key')) # FIXME, maybe this is only used for stripe?
|
||||
Stripe::PaymentIntent.retrieve(stp_invoice.payment_intent, api_key: Setting.get('stripe_secret_key'))
|
||||
end
|
||||
|
||||
def self.columns_out_of_footprint
|
||||
|
@ -8,7 +8,7 @@ class PaymentSchedulePolicy < ApplicationPolicy
|
||||
end
|
||||
end
|
||||
|
||||
%w[refresh_item? download? pay_item?].each do |action|
|
||||
%w[refresh_item? download? pay_item? show_item?].each do |action|
|
||||
define_method action do
|
||||
user.admin? || user.manager? || (record.invoicing_profile.user_id == user.id)
|
||||
end
|
||||
|
@ -24,7 +24,5 @@ if payment_schedule.gateway_subscription
|
||||
end
|
||||
end
|
||||
json.items payment_schedule.payment_schedule_items do |item|
|
||||
json.extract! item, :id, :due_date, :state, :invoice_id, :payment_method
|
||||
json.amount item.amount / 100.00
|
||||
json.client_secret item.payment_intent.client_secret if item.payment_gateway_object && item.state == 'requires_action'
|
||||
json.partial! 'api/payment_schedules/payment_schedule_item', item: item
|
||||
end
|
||||
|
@ -0,0 +1,4 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
json.extract! item, :id, :due_date, :state, :invoice_id, :payment_method
|
||||
json.amount item.amount / 100.00
|
6
app/views/api/payment_schedules/show_item.json.jbuilder
Normal file
6
app/views/api/payment_schedules/show_item.json.jbuilder
Normal file
@ -0,0 +1,6 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
json.partial! 'api/payment_schedules/payment_schedule_item', item: @payment_schedule_item
|
||||
if @payment_schedule_item.payment_gateway_object && @payment_schedule_item.state == 'requires_action'
|
||||
json.client_secret @payment_schedule_item.payment_intent.client_secret
|
||||
end
|
@ -123,6 +123,7 @@ Rails.application.routes.draw do
|
||||
post 'list', action: 'list', on: :collection
|
||||
put 'cancel', on: :member
|
||||
get 'download', on: :member
|
||||
get 'items/:id', action: 'show_item', on: :collection
|
||||
post 'items/:id/cash_check', action: 'cash_check', on: :collection
|
||||
post 'items/:id/refresh_item', action: 'refresh_item', on: :collection
|
||||
post 'items/:id/pay_item', action: 'pay_item', on: :collection
|
||||
|
@ -29,5 +29,9 @@ class Payment::Item
|
||||
false
|
||||
end
|
||||
|
||||
def gateway
|
||||
klass[/^(PayZen|Stripe)::/, 1]
|
||||
end
|
||||
|
||||
def retrieve(_id = nil, *_args); end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user