mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-01-22 11:52:21 +01:00
(wip) add event type
This commit is contained in:
parent
6888f00036
commit
aed5d1fc1b
@ -96,7 +96,7 @@ class API::EventsController < API::APIController
|
||||
# handle general properties
|
||||
event_preparams = params.required(:event).permit(:title, :description, :start_date, :start_time, :end_date, :end_time,
|
||||
:amount, :nb_total_places, :availability_id, :all_day, :recurrence,
|
||||
:recurrence_end_at, :category_id, :event_theme_ids, :age_range_id, :booking_nominative,
|
||||
:recurrence_end_at, :category_id, :event_theme_ids, :age_range_id, :event_type,
|
||||
event_theme_ids: [],
|
||||
event_image_attributes: %i[id attachment],
|
||||
event_files_attributes: %i[id attachment _destroy],
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import * as React from 'react';
|
||||
import { SubmitHandler, useFieldArray, useForm, useWatch } from 'react-hook-form';
|
||||
import { Event, EventDecoration, EventPriceCategoryAttributes, RecurrenceOption } from '../../models/event';
|
||||
import { Event, EventDecoration, EventPriceCategoryAttributes, RecurrenceOption, EventType } from '../../models/event';
|
||||
import EventAPI from '../../api/event';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { FormInput } from '../form/form-input';
|
||||
@ -40,7 +40,7 @@ interface EventFormProps {
|
||||
* Form to edit or create events
|
||||
*/
|
||||
export const EventForm: React.FC<EventFormProps> = ({ action, event, onError, onSuccess }) => {
|
||||
const { handleSubmit, register, control, setValue, formState } = useForm<Event>({ defaultValues: { ...event } });
|
||||
const { handleSubmit, register, control, setValue, formState } = useForm<Event>({ defaultValues: Object.assign({ event_type: 'standard' }, event) });
|
||||
const output = useWatch<Event>({ control });
|
||||
const { fields, append, remove } = useFieldArray({ control, name: 'event_price_categories_attributes' });
|
||||
|
||||
@ -168,6 +168,17 @@ export const EventForm: React.FC<EventFormProps> = ({ action, event, onError, on
|
||||
];
|
||||
};
|
||||
|
||||
/**
|
||||
* This method provides event type options
|
||||
*/
|
||||
const buildEventTypeOptions = (): Array<SelectOption<EventType>> => {
|
||||
return [
|
||||
{ label: t('app.admin.event_form.event_types.standard'), value: 'standard' },
|
||||
{ label: t('app.admin.event_form.event_types.nominative'), value: 'nominative' },
|
||||
{ label: t('app.admin.event_form.event_types.family'), value: 'family' }
|
||||
];
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="event-form">
|
||||
<header>
|
||||
@ -203,6 +214,12 @@ export const EventForm: React.FC<EventFormProps> = ({ action, event, onError, on
|
||||
label={t('app.admin.event_form.description')}
|
||||
limit={null}
|
||||
heading bulletList blockquote link video image />
|
||||
<FormSelect id="event_type"
|
||||
control={control}
|
||||
formState={formState}
|
||||
label={t('app.admin.event_form.event_type')}
|
||||
options={buildEventTypeOptions()}
|
||||
rules={{ required: true }} />
|
||||
<FormSelect id="category_id"
|
||||
control={control}
|
||||
formState={formState}
|
||||
@ -290,11 +307,6 @@ export const EventForm: React.FC<EventFormProps> = ({ action, event, onError, on
|
||||
label={t('app.admin.event_form.seats_available')}
|
||||
type="number"
|
||||
tooltip={t('app.admin.event_form.seats_help')} />
|
||||
<FormSwitch control={control}
|
||||
id="booking_nominative"
|
||||
label={t('app.admin.event_form.booking_nominative')}
|
||||
formState={formState}
|
||||
tooltip={t('app.admin.event_form.booking_nominative_help')} />
|
||||
<FormInput register={register}
|
||||
type="number"
|
||||
id="amount"
|
||||
|
@ -689,7 +689,7 @@ Application.Controllers.controller('ShowEventController', ['$scope', '$state', '
|
||||
}
|
||||
}
|
||||
|
||||
if (event.booking_nominative) {
|
||||
if (event.event_type === 'nominative' || event.event_type === 'family') {
|
||||
for (const key of Object.keys($scope.reserve.bookingUsers)) {
|
||||
for (const user of $scope.reserve.bookingUsers[key]) {
|
||||
reservation.booking_users_attributes.push({
|
||||
|
@ -11,6 +11,7 @@ export interface EventPriceCategoryAttributes {
|
||||
}
|
||||
|
||||
export type RecurrenceOption = 'none' | 'day' | 'week' | 'month' | 'year';
|
||||
export type EventType = 'standard' | 'nominative' | 'family';
|
||||
|
||||
export interface Event {
|
||||
id?: number,
|
||||
@ -64,7 +65,7 @@ export interface Event {
|
||||
recurrence: RecurrenceOption,
|
||||
recurrence_end_at: Date,
|
||||
advanced_accounting_attributes?: AdvancedAccounting,
|
||||
booking_nominative: boolean,
|
||||
event_type: EventType,
|
||||
}
|
||||
|
||||
export interface EventDecoration {
|
||||
|
@ -119,7 +119,7 @@
|
||||
<select ng-model="reserve.nbReservePlaces" ng-change="changeNbPlaces('normal')" ng-options="i for i in reserve.nbPlaces.normal">
|
||||
</select> {{ 'app.public.events_show.ticket' | translate:{NUMBER:reserve.nbReservePlaces} }}
|
||||
</div>
|
||||
<div class="col-sm-12 m-b" ng-if="event.booking_nominative && reserve.nbReservePlaces > 0">
|
||||
<div class="col-sm-12 m-b" ng-if="event.event_type === 'nominative' && reserve.nbReservePlaces > 0">
|
||||
<div ng-repeat="user in reserve.bookingUsers.normal">
|
||||
<label class="" translate>{{ 'app.public.events_show.last_name_and_first_name '}}</label>
|
||||
<input type="text" class="form-control" ng-model="user.name">
|
||||
@ -132,7 +132,7 @@
|
||||
<select ng-model="reserve.tickets[price.id]" ng-change="changeNbPlaces(price.id)" ng-options="i for i in reserve.nbPlaces[price.id]">
|
||||
</select> {{ 'app.public.events_show.ticket' | translate:{NUMBER:reserve.tickets[price.id]} }}
|
||||
</div>
|
||||
<div class="col-sm-12 m-b" ng-if="event.booking_nominative && reserve.tickets[price.id] > 0">
|
||||
<div class="col-sm-12 m-b" ng-if="event.event_type === 'nominative' && reserve.tickets[price.id] > 0">
|
||||
<div ng-repeat="user in reserve.bookingUsers[price.id]">
|
||||
<label class="" translate>{{ 'app.public.events_show.last_name_and_first_name '}}</label>
|
||||
<input type="text" class="form-control" ng-model="user.name">
|
||||
|
@ -33,6 +33,8 @@ class Event < ApplicationRecord
|
||||
|
||||
has_many :cart_item_event_reservations, class_name: 'CartItem::EventReservation', dependent: :destroy
|
||||
|
||||
validates :event_type, inclusion: { in: %w[standard nominative family] }, presence: true
|
||||
|
||||
attr_accessor :recurrence, :recurrence_end_at
|
||||
|
||||
before_save :update_nb_free_places
|
||||
|
@ -1,6 +1,6 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
json.extract! event, :id, :title, :description, :booking_nominative
|
||||
json.extract! event, :id, :title, :description, :event_type
|
||||
if event.event_image
|
||||
json.event_image_attributes do
|
||||
json.id event.event_image.id
|
||||
|
@ -139,8 +139,6 @@ en:
|
||||
event_themes: "Event themes"
|
||||
age_range: "Age range"
|
||||
add_price: "Add a price"
|
||||
booking_nominative: "Nominative booking"
|
||||
booking_nominative_help: "If you check this option, the members will have to enter the names of the participants when booking."
|
||||
save: "Save"
|
||||
create_success: "The event was created successfully"
|
||||
events_updated: "{COUNT, plural, =1{One event was} other{{COUNT} Events were}} successfully updated"
|
||||
@ -153,6 +151,11 @@ en:
|
||||
every_week: "Every week"
|
||||
every_month: "Every month"
|
||||
every_year: "Every year"
|
||||
event_type: "Event type"
|
||||
event_types:
|
||||
standard: "Event standard"
|
||||
nominative: "Event nominative"
|
||||
family: "Event family"
|
||||
plan_form:
|
||||
ACTION_title: "{ACTION, select, create{New} other{Update the}} plan"
|
||||
tab_settings: "Settings"
|
||||
|
@ -139,8 +139,6 @@ fr:
|
||||
event_themes: "Thèmes de l'événement"
|
||||
age_range: "Tranche d'âge"
|
||||
add_price: "Ajouter un tarif"
|
||||
booking_nominative: "Réservation nominative"
|
||||
booking_nominative_help: "Si cette option est activée, les réservations seront nominatives. Les participants devront s'identifier pour réserver."
|
||||
save: "Enregistrer"
|
||||
create_success: "L'événement a bien été créé"
|
||||
events_updated: "{COUNT, plural, one {}=1{Un événement à été} other{{COUNT} événements ont été}} mis à jour avec succès"
|
||||
@ -153,6 +151,11 @@ fr:
|
||||
every_week: "Chaque semaine"
|
||||
every_month: "Chaque mois"
|
||||
every_year: "Chaque année"
|
||||
event_type: "Type d'événement"
|
||||
event_types:
|
||||
standard: "Evénement standard"
|
||||
nominative: "Evénement nominatif"
|
||||
family: "Evénement famille"
|
||||
plan_form:
|
||||
ACTION_title: "{ACTION, select, create{Nouvelle} other{Mettre à jour la}} formule d'abonnement"
|
||||
tab_settings: "Paramètres"
|
||||
|
@ -1,8 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# add booking_nominative to event
|
||||
class AddBookingNominativeToEvent < ActiveRecord::Migration[7.0]
|
||||
def change
|
||||
add_column :events, :booking_nominative, :boolean, default: false
|
||||
end
|
||||
end
|
@ -5,7 +5,8 @@ class CreateCartItemEventReservationBookingUsers < ActiveRecord::Migration[7.0]
|
||||
def change
|
||||
create_table :cart_item_event_reservation_booking_users do |t|
|
||||
t.string :name
|
||||
t.belongs_to :cart_item_event_reservation, foreign_key: true, index: { name: 'index_cart_item_booking_users_on_cart_item_event_reservation' }
|
||||
t.belongs_to :cart_item_event_reservation, foreign_key: true,
|
||||
index: { name: 'index_cart_item_booking_users_on_cart_item_event_reservation' }
|
||||
t.references :event_price_category, foreign_key: true, index: { name: 'index_cart_item_booking_users_on_event_price_category' }
|
||||
t.references :booked, polymorphic: true
|
||||
|
||||
|
10
db/migrate/20230511081018_add_event_type_to_event.rb
Normal file
10
db/migrate/20230511081018_add_event_type_to_event.rb
Normal file
@ -0,0 +1,10 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Add event_type to event model, to be able to create standard/nominative/family events
|
||||
class AddEventTypeToEvent < ActiveRecord::Migration[7.0]
|
||||
def change
|
||||
add_column :events, :event_type, :string, default: 'standard'
|
||||
Event.reset_column_information
|
||||
Event.update_all(event_type: 'standard')
|
||||
end
|
||||
end
|
@ -1243,7 +1243,7 @@ CREATE TABLE public.events (
|
||||
age_range_id integer,
|
||||
category_id integer,
|
||||
deleted_at timestamp without time zone,
|
||||
booking_nominative boolean DEFAULT false
|
||||
event_type character varying DEFAULT 'standard'::character varying
|
||||
);
|
||||
|
||||
|
||||
@ -8927,6 +8927,8 @@ INSERT INTO "schema_migrations" (version) VALUES
|
||||
('20230331132506'),
|
||||
('20230509121907'),
|
||||
('20230509161557'),
|
||||
('20230510141305');
|
||||
('20230510141305'),
|
||||
('20230511080650'),
|
||||
('20230511081018');
|
||||
|
||||
|
||||
|
1
test/fixtures/history_values.yml
vendored
1
test/fixtures/history_values.yml
vendored
@ -858,5 +858,4 @@ history_value_101:
|
||||
value: 'false'
|
||||
created_at: '2023-03-31 14:38:40.000421'
|
||||
updated_at: '2023-03-31 14:38:40.000421'
|
||||
footprint:
|
||||
invoicing_profile_id: 1
|
||||
|
@ -15,6 +15,7 @@ describe('EventForm', () => {
|
||||
expect(screen.getByLabelText(/app.admin.event_form.title/)).toBeInTheDocument();
|
||||
expect(screen.getByLabelText(/app.admin.event_form.matching_visual/)).toBeInTheDocument();
|
||||
expect(screen.getByLabelText(/app.admin.event_form.description/)).toBeInTheDocument();
|
||||
expect(screen.getByLabelText(/app.admin.event_form.event_type/)).toBeInTheDocument();
|
||||
expect(screen.getByLabelText(/app.admin.event_form.event_category/)).toBeInTheDocument();
|
||||
expect(screen.getByLabelText(/app.admin.event_form.event_themes/)).toBeInTheDocument();
|
||||
expect(screen.getByLabelText(/app.admin.event_form.age_range/)).toBeInTheDocument();
|
||||
@ -27,7 +28,6 @@ describe('EventForm', () => {
|
||||
expect(screen.getByLabelText(/app.admin.event_form._and_ends_on/)).toBeInTheDocument();
|
||||
expect(screen.getByLabelText(/app.admin.event_form.seats_available/)).toBeInTheDocument();
|
||||
expect(screen.getByLabelText(/app.admin.event_form.standard_rate/)).toBeInTheDocument();
|
||||
expect(screen.getByLabelText(/app.admin.event_form.booking_nominative/)).toBeInTheDocument();
|
||||
expect(screen.getByRole('button', { name: /app.admin.event_form.add_price/ })).toBeInTheDocument();
|
||||
expect(screen.getByRole('button', { name: /app.admin.event_form.add_a_new_file/ })).toBeInTheDocument();
|
||||
expect(screen.getByLabelText(/app.admin.advanced_accounting_form.code/)).toBeInTheDocument();
|
||||
|
@ -22,6 +22,7 @@ class Events::AsAdminTest < ActionDispatch::IntegrationTest
|
||||
end_date: 1.week.from_now.utc,
|
||||
end_time: 1.week.from_now.utc.change(hour: 20),
|
||||
category_id: Category.first.id,
|
||||
event_type: 'standard',
|
||||
amount: 0
|
||||
}
|
||||
}.to_json,
|
||||
|
Loading…
x
Reference in New Issue
Block a user