Skip to content

Commit

Permalink
Merge branch 'dev' for release 5.8.0
Browse files Browse the repository at this point in the history
  • Loading branch information
sylvainbx committed Mar 3, 2023
2 parents 2d83e7a + f7c37a5 commit 4228b44
Show file tree
Hide file tree
Showing 60 changed files with 464 additions and 109 deletions.
21 changes: 20 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,29 @@
# Changelog Fab-manager

## v5.8.0 2023 March 03

- OpenAPI events endpoint returns category, theme and age_range
- OpenAPI reservation endpoint will return details for the reserved slots
- Display info messages if the user cannot buy prepaid packs
- Fix a bug: some OpenAPI endpoints struggle and expire with timeout
- Fix a bug: OpenAPI events endpoint documentation does not refect the returned data
- Fix a bug: members can't change/cancel their reservations
- Fix a bug: admin events view should default to the list tab
- Fix a bug: event creation form should not allow setting multiple times the same price category
- Fix a bug: MAX_SIZE env varibles should not be quoted (#438)
- Fix a bug: unable to add OIDC scopes without discovery
- [BREAKING CHANGE] GET `open_api/v1/events` will necessarily be paginated
- [BREAKING CHANGE] GET `open_api/v1/invoices` will necessarily be paginated
- [BREAKING CHANGE] GET `open_api/v1/reservations` will necessarily be paginated
- [BREAKING CHANGE] GET `open_api/v1/users` will necessarily be paginated
- [BREAKING CHANGE] GET `open_api/v1/subscriptions` won't return `total_count`, `total_pages`, `page` or `page_siez` anymore. RFC-5988 headers (*Link*, *Total* and *Per-Page*) will continue to provide these same data.
- [BREAKING CHANGE] GET `open_api/v1/subscriptions` will return a `subscriptions` array instead of a `data` array.

## v5.7.2 2023 February 24

- Fix a bug: unable to update recurrent events
- Fix a bug: invalid border color for slots
- Fix a bug: members can change/cancel their reservations
- Fix a bug: members can't change/cancel their reservations

## v5.7.1 2023 February 20

Expand Down
8 changes: 5 additions & 3 deletions app/controllers/open_api/v1/events_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,16 @@ def index

@events = @events.where(id: may_array(params[:id])) if params[:id].present?

return if params[:page].blank?

@events = @events.page(params[:page]).per(per_page)
@events = @events.page(page).per(per_page)
paginate @events, per_page: per_page
end

private

def page
params[:page] || 1
end

def per_page
params[:per_page] || 20
end
Expand Down
4 changes: 1 addition & 3 deletions app/controllers/open_api/v1/invoices_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,11 @@ class OpenAPI::V1::InvoicesController < OpenAPI::V1::BaseController

def index
@invoices = Invoice.order(created_at: :desc)
.includes(invoicing_profile: :user)
.includes(:payment_gateway_object, :invoicing_profile)
.references(:invoicing_profiles)

@invoices = @invoices.where(invoicing_profiles: { user_id: may_array(params[:user_id]) }) if params[:user_id].present?

return if params[:page].blank?

@invoices = @invoices.page(params[:page]).per(per_page)
paginate @invoices, per_page: per_page
end
Expand Down
10 changes: 6 additions & 4 deletions app/controllers/open_api/v1/reservations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,14 @@ class OpenAPI::V1::ReservationsController < OpenAPI::V1::BaseController

def index
@reservations = Reservation.order(created_at: :desc)
.includes(statistic_profile: :user)
.includes(slots_reservations: :slot, statistic_profile: :user)
.references(:statistic_profiles)

@reservations = @reservations.where(statistic_profiles: { user_id: may_array(params[:user_id]) }) if params[:user_id].present?
@reservations = @reservations.where(reservable_type: format_type(params[:reservable_type])) if params[:reservable_type].present?
@reservations = @reservations.where(reservable_id: may_array(params[:reservable_id])) if params[:reservable_id].present?

return if params[:page].blank?

@reservations = @reservations.page(params[:page]).per(per_page)
@reservations = @reservations.page(page).per(per_page)
paginate @reservations, per_page: per_page
end

Expand All @@ -27,6 +25,10 @@ def format_type(type)
type.singularize.classify
end

def page
params[:page] || 1
end

def per_page
params[:per_page] || 20
end
Expand Down
11 changes: 0 additions & 11 deletions app/controllers/open_api/v1/subscriptions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ def index
@subscriptions = @subscriptions.where(statistic_profiles: { user_id: may_array(params[:user_id]) }) if params[:user_id].present?

@subscriptions = @subscriptions.page(page).per(per_page)
@pageination_meta = pageination_meta
paginate @subscriptions, per_page: per_page
end

Expand All @@ -30,14 +29,4 @@ def page
def per_page
params[:per_page] || 20
end

def pageination_meta
total_count = Subscription.count
{
total_count: total_count,
total_pages: (total_count / per_page.to_f).ceil,
page: page.to_i,
page_size: per_page.to_i
}
end
end
6 changes: 5 additions & 1 deletion app/controllers/open_api/v1/users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,16 @@ def index

return if params[:page].blank?

@users = @users.page(params[:page]).per(per_page)
@users = @users.page(page).per(per_page)
paginate @users, per_page: per_page
end

private

def page
params[:page] || 1
end

def per_page
params[:per_page] || 20
end
Expand Down
29 changes: 26 additions & 3 deletions app/doc/open_api/v1/events_doc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class OpenAPI::V1::EventsDoc < OpenAPI::V1::BaseDoc
param_group :pagination
param :id, [Integer, Array], optional: true, desc: 'Scope the request to one or various events.'
param :upcoming, [FalseClass, TrueClass], optional: true, desc: 'Scope for the upcoming events.'
description 'Events index. Order by *created_at* desc.'
description 'Events index, pagniated. Ordered by *created_at* desc.'
example <<-EVENTS
# /open_api/v1/events?page=1&per_page=2
{
Expand All @@ -29,12 +29,21 @@ class OpenAPI::V1::EventsDoc < OpenAPI::V1::BaseDoc
"created_at": "2016-04-25T10:49:40.055+02:00",
"nb_total_places": 18,
"nb_free_places": 16,
"start_at": "2016-05-02T18:00:00.000+02:00",
"end_at": "2016-05-02T22:00:00.000+02:00",
"category": "Openlab",
"event_image": {
"large_url": "https://example.com/uploads/event_image/3454/large_event_image.jpg",
"medium_url": "https://example.com/uploads/event_image/3454/medium_event_image.jpg",
"small_url": "https://example.com/uploads/event_image/3454/small_event_image.jpg"
},
"prices": {
"normal": {
"name": "Plein tarif",
"amount": 0
}
}
},
"url": "https://example.com/#!/events/183"
},
{
"id": 182,
Expand All @@ -44,6 +53,19 @@ class OpenAPI::V1::EventsDoc < OpenAPI::V1::BaseDoc
"created_at": "2016-04-11T17:40:15.146+02:00",
"nb_total_places": 8,
"nb_free_places": 0,
"start_at": "2016-05-02T18:00:00.000+01:00",
"end_at": "2026-05-02T22:00:00.000+01:00",
"category": "Atelier",
"themes": [
"DIY",
"Sport"
],
"age_range": "14 - 18 ans",
"event_image": {
"large_url": "https://example.com/uploads/event_image/3453/large_event_image.jpg",
"medium_url": "https://example.com/uploads/event_image/3453/medium_event_image.jpg",
"small_url": "https://example.com/uploads/event_image/3453/small_event_image.jpg"
},
"prices": {
"normal": {
"name": "Plein tarif",
Expand All @@ -53,7 +75,8 @@ class OpenAPI::V1::EventsDoc < OpenAPI::V1::BaseDoc
"name": "Tarif réduit",
"amount": 4000
},
}
},
"url": "https://example.com/#!/events/182"
}
]
}
Expand Down
2 changes: 1 addition & 1 deletion app/doc/open_api/v1/invoices_doc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class OpenAPI::V1::InvoicesDoc < OpenAPI::V1::BaseDoc

doc_for :index do
api :GET, "/#{API_VERSION}/invoices", 'Invoices index'
description "Index of users' invoices, with optional pagination. Order by *created_at* descendant."
description 'Index of invoices, paginated. Ordered by *created_at* descendant.'
param_group :pagination
param :user_id, [Integer, Array], optional: true, desc: 'Scope the request to one or various users.'
example <<-INVOICES
Expand Down
29 changes: 25 additions & 4 deletions app/doc/open_api/v1/reservations_doc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class OpenAPI::V1::ReservationsDoc < OpenAPI::V1::BaseDoc

doc_for :index do
api :GET, "/#{API_VERSION}/reservations", 'Reservations index'
description 'Index of reservations made by users, with optional pagination. Order by *created_at* descendant.'
description 'Index of reservations made by users, paginated. Ordered by *created_at* descendant.'
param_group :pagination
param :user_id, [Integer, Array], optional: true, desc: 'Scope the request to one or various users.'
param :reservable_type, %w[Event Machine Space Training], optional: true, desc: 'Scope the request to a specific type of reservable.'
Expand Down Expand Up @@ -42,7 +42,14 @@ class OpenAPI::V1::ReservationsDoc < OpenAPI::V1::BaseDoc
"description": "A partir de 15 ans : \r\n\r\nDécouvrez le Fab Lab, familiarisez-vous avec les découpeuses laser, les imprimantes 3D, la découpeuse vinyle ... ! Fabriquez un objet simple, à ramener chez vous ! \r\n\r\nAdoptez la Fab Lab attitude !",
"updated_at": "2016-03-21T15:55:56.306+01:00",
"created_at": "2016-03-21T15:55:56.306+01:00"
}
},
"reserved_slots": [
{
"canceled_at": "2016-05-20T09:40:12.201+01:00",
"start_at": "2016-06-03T14:00:00.000+01:00",
"end_at": "2016-06-03T15:00:00.000+01:00"
}
]
},
{
"id": 3252,
Expand All @@ -63,7 +70,14 @@ class OpenAPI::V1::ReservationsDoc < OpenAPI::V1::BaseDoc
"description": "A partir de 15 ans : \r\n\r\nDécouvrez le Fab Lab, familiarisez-vous avec les découpeuses laser, les imprimantes 3D, la découpeuse vinyle ... ! Fabriquez un objet simple, à ramener chez vous ! \r\n\r\nAdoptez la Fab Lab attitude !",
"updated_at": "2016-05-03T13:53:47.172+02:00",
"created_at": "2016-03-07T15:58:14.113+01:00"
}
},
"reserved_slots": [
{
"canceled_at": null,
"start_at": "2016-06-02T16:00:00.000+01:00",
"end_at": "2016-06-02T17:00:00.000+01:00"
}
]
},
{
"id": 3251,
Expand All @@ -84,7 +98,14 @@ class OpenAPI::V1::ReservationsDoc < OpenAPI::V1::BaseDoc
"description": "A partir de 15 ans : \r\n\r\nDécouvrez le Fab Lab, familiarisez-vous avec les découpeuses laser, les imprimantes 3D, la découpeuse vinyle ... ! Fabriquez un objet simple, à ramener chez vous ! \r\n\r\nAdoptez la Fab Lab attitude !",
"updated_at": "2016-03-21T15:55:56.306+01:00",
"created_at": "2016-03-21T15:55:56.306+01:00"
}
},
"reserved_slots": [
{
"canceled_at": null,
"start_at": "2016-06-03T14:00:00.000+01:00",
"end_at": "2016-06-03T15:00:00.000+01:00"
}
]
}
]
}
Expand Down
10 changes: 3 additions & 7 deletions app/doc/open_api/v1/subscriptions_doc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ class OpenAPI::V1::SubscriptionsDoc < OpenAPI::V1::BaseDoc

doc_for :index do
api :GET, "/#{API_VERSION}/subscriptions", 'Subscriptions index'
description "Index of users' subscriptions, with optional pagination. Order by *created_at* descendant."
description "Index of users' subscriptions, paginated. Order by *created_at* descendant."
param_group :pagination
param :user_id, [Integer, Array], optional: true, desc: 'Scope the request to one or various users.'
param :plan_id, [Integer, Array], optional: true, desc: 'Scope the request to one or various plans.'
example <<-SUBSCRIPTIONS
# /open_api/v1/subscriptions?user_id=211&page=1&per_page=3
{
"data": [
"subscriptions": [
{
"id": 2809,
"user_id": 211,
Expand All @@ -45,11 +45,7 @@ class OpenAPI::V1::SubscriptionsDoc < OpenAPI::V1::BaseDoc
"canceled_at": null,
"plan_id": 1
}
],
"total_pages": 3,
"total_count": 9,
"page": 1,
"page_siez": 3
]
}
SUBSCRIPTIONS
end
Expand Down
2 changes: 1 addition & 1 deletion app/doc/open_api/v1/users_doc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class OpenAPI::V1::UsersDoc < OpenAPI::V1::BaseDoc

doc_for :index do
api :GET, "/#{API_VERSION}/users", 'Users index'
description 'Users index, with optional pagination. Order by *created_at* descendant.'
description 'Users index, paginated. Ordered by *created_at* descendant.'
param_group :pagination
param :email, [String, Array], optional: true, desc: 'Filter users by *email* using strict matching.'
param :user_id, [Integer, Array], optional: true, desc: 'Filter users by *id* using strict matching.'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import * as React from 'react';
import { User } from '../../../models/user';
import PrepaidPackAPI from '../../../api/prepaid-pack';
import { PrepaidPack } from '../../../models/prepaid-pack';
import { HtmlTranslate } from '../../base/html-translate';

interface PrepaidPacksPanelProps {
user: User,
Expand Down Expand Up @@ -159,7 +160,10 @@ const PrepaidPacksPanel: React.FC<PrepaidPacksPanelProps> = ({ user, onError })
onDecline={togglePacksModal}
onSuccess={onPackBoughtSuccess} />}
</div>}

{packs.length === 0 && <p>{t('app.logged.dashboard.reservations_dashboard.prepaid_packs_panel.no_packs')}</p>}
{(packsForSubscribers && user.subscribed_plan == null && packs.length > 0) &&
<HtmlTranslate trKey={'app.logged.dashboard.reservations_dashboard.prepaid_packs_panel.reserved_for_subscribers_html'} options={{ LINK: '#!/plans' }} />
}
</FabPanel>
);
};
Expand Down
41 changes: 29 additions & 12 deletions app/frontend/src/javascript/components/events/event-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,19 @@ export const EventForm: React.FC<EventFormProps> = ({ action, event, onError, on
SettingAPI.get('advanced_accounting').then(res => setIsActiveAccounting(res.value === 'true')).catch(onError);
}, []);

useEffect(() => {
// When a new custom price is added to the current event, we mark it as disabled to prevent setting the same category twice
const selectedCategoriesId = output.event_price_categories_attributes
?.filter(epc => !epc._destroy && epc.price_category_id)
?.map(epc => epc.price_category_id) || [];
setPriceCategoriesOptions(priceCategoriesOptions?.map(pco => {
return {
...pco,
disabled: selectedCategoriesId.includes(pco.value)
};
}));
}, [output.event_price_categories_attributes]);

/**
* Callback triggered when the user clicks on the 'remove' button, in the additional prices area
*/
Expand Down Expand Up @@ -278,12 +291,14 @@ export const EventForm: React.FC<EventFormProps> = ({ action, event, onError, on
type="number"
tooltip={t('app.admin.event_form.seats_help')} />
<FormInput register={register}
id="amount"
formState={formState}
rules={{ required: true }}
label={t('app.admin.event_form.standard_rate')}
tooltip={t('app.admin.event_form.0_equal_free')}
addOn={FormatLib.currencySymbol()} />
type="number"
id="amount"
formState={formState}
rules={{ required: true, min: 0 }}
nullable
label={t('app.admin.event_form.standard_rate')}
tooltip={t('app.admin.event_form.0_equal_free')}
addOn={FormatLib.currencySymbol()} />

{priceCategoriesOptions && <div className="additional-prices">
{fields.map((price, index) => (
Expand All @@ -293,14 +308,16 @@ export const EventForm: React.FC<EventFormProps> = ({ action, event, onError, on
id={`event_price_categories_attributes.${index}.price_category_id`}
rules={{ required: true }}
formState={formState}
disabled={() => index < fields.length - 1}
label={t('app.admin.event_form.fare_class')} />
<FormInput id={`event_price_categories_attributes.${index}.amount`}
register={register}
type="number"
rules={{ required: true }}
formState={formState}
label={t('app.admin.event_form.price')}
addOn={FormatLib.currencySymbol()} />
register={register}
type="number"
rules={{ required: true, min: 0 }}
nullable
formState={formState}
label={t('app.admin.event_form.price')}
addOn={FormatLib.currencySymbol()} />
<FabButton className="remove-price is-main" onClick={() => handlePriceRemove(price, index)} icon={<Trash size={20} />} />
</div>
))}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ export const FormMultiSelect = <TFieldValues extends FieldValues, TContext exten
if (creatable) {
Object.assign(selectProps, {
formatCreateLabel,
onCreateOption: inputValue => handleCreate(inputValue, value, rhfOnChange)
onCreateOption: inputValue => handleCreate(inputValue, value || [], rhfOnChange)
});
}

Expand Down
Loading

0 comments on commit 4228b44

Please sign in to comment.