mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-02-19 13:54:25 +01:00
(quality) delete a plan limitation
This commit is contained in:
parent
25cbf63b48
commit
7ad1f8da3f
@ -1,6 +1,7 @@
|
||||
# Changelog Fab-manager
|
||||
|
||||
- [TODO DEPLOY] `rails db:seed`
|
||||
- [TODO DEPLOY] `rails fablab:maintenance:rebuild_stylesheet`
|
||||
|
||||
## v5.8.2 2023 March 13
|
||||
|
||||
|
@ -1,12 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# API Controller for resources of type PlanLimitation
|
||||
# PlanLimitation allows to restrict bookings of resources for the subscribers of that plan.
|
||||
class API::PlanLimitationsController < API::ApiController
|
||||
def destroy
|
||||
@limitation = PlanLimitation.find(params[:id])
|
||||
authorize @limitation
|
||||
@limitation.destroy
|
||||
head :no_content
|
||||
end
|
||||
end
|
@ -1,9 +0,0 @@
|
||||
import apiClient from './clients/api-client';
|
||||
import { AxiosResponse } from 'axios';
|
||||
|
||||
export default class PlanLimitationAPI {
|
||||
static async destroy (id: number): Promise<void> {
|
||||
const res: AxiosResponse<void> = await apiClient.delete(`/api/plan_limitations/${id}`);
|
||||
return res?.data;
|
||||
}
|
||||
}
|
@ -6,28 +6,33 @@ import { FabButton } from './fab-button';
|
||||
import { FabModal } from './fab-modal';
|
||||
|
||||
type EditDestroyButtonsCommon = {
|
||||
onDeleteSuccess: (message: string) => void,
|
||||
onError: (message: string) => void,
|
||||
onEdit: () => void,
|
||||
itemId: number,
|
||||
apiDestroy: (itemId: number) => Promise<void>,
|
||||
destroy: (itemId: number) => Promise<void>,
|
||||
className?: string,
|
||||
iconSize?: number,
|
||||
showEditButton?: boolean,
|
||||
}
|
||||
|
||||
type EditDestroyButtonsMessages =
|
||||
{ itemType: string, confirmationTitle?: string, confirmationMessage?: string|ReactNode, deleteSuccessMessage?: string } |
|
||||
{ itemType?: never, confirmationTitle: string, confirmationMessage: string|ReactNode, deleteSuccessMessage: string}
|
||||
type DeleteSuccess =
|
||||
{ onDeleteSuccess: (message: string) => void, deleteSuccessMessage: string } |
|
||||
{ onDeleteSuccess?: never, deleteSuccessMessage?: never }
|
||||
|
||||
type EditDestroyButtonsProps = EditDestroyButtonsCommon & EditDestroyButtonsMessages;
|
||||
type DestroyMessages =
|
||||
({ showDestroyConfirmation?: true } &
|
||||
({ itemType: string, confirmationTitle?: string, confirmationMessage?: string|ReactNode } |
|
||||
{ itemType?: never, confirmationTitle: string, confirmationMessage: string|ReactNode })) |
|
||||
{ showDestroyConfirmation: false, itemType?: never, confirmationTitle?: never, confirmationMessage?: never };
|
||||
|
||||
type EditDestroyButtonsProps = EditDestroyButtonsCommon & DeleteSuccess & DestroyMessages;
|
||||
|
||||
/**
|
||||
* This component shows a group of two buttons.
|
||||
* Destroy : shows a modal dialog to ask the user for confirmation about the deletion of the provided item.
|
||||
* Edit : triggers the provided function.
|
||||
*/
|
||||
export const EditDestroyButtons: React.FC<EditDestroyButtonsProps> = ({ onDeleteSuccess, onError, onEdit, itemId, itemType, apiDestroy, confirmationTitle, confirmationMessage, deleteSuccessMessage, className, iconSize = 20, showEditButton = true }) => {
|
||||
export const EditDestroyButtons: React.FC<EditDestroyButtonsProps> = ({ onDeleteSuccess, onError, onEdit, itemId, itemType, destroy, confirmationTitle, confirmationMessage, deleteSuccessMessage, className, iconSize = 20, showEditButton = true, showDestroyConfirmation = true }) => {
|
||||
const { t } = useTranslation('admin');
|
||||
|
||||
const [deletionModal, setDeletionModal] = useState<boolean>(false);
|
||||
@ -39,17 +44,28 @@ export const EditDestroyButtons: React.FC<EditDestroyButtonsProps> = ({ onDelete
|
||||
setDeletionModal(!deletionModal);
|
||||
};
|
||||
|
||||
/**
|
||||
* Triggered when the user clicks on the 'destroy' button
|
||||
*/
|
||||
const handleDestroyRequest = (): void => {
|
||||
if (showDestroyConfirmation) {
|
||||
toggleDeletionModal();
|
||||
} else {
|
||||
onDeleteConfirmed();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The deletion has been confirmed by the user.
|
||||
* Call the API to trigger the deletion of the given item
|
||||
*/
|
||||
const onDeleteConfirmed = (): void => {
|
||||
apiDestroy(itemId).then(() => {
|
||||
onDeleteSuccess(deleteSuccessMessage || t('app.admin.edit_destroy_buttons.deleted', { TYPE: itemType }));
|
||||
destroy(itemId).then(() => {
|
||||
typeof onDeleteSuccess === 'function' && onDeleteSuccess(deleteSuccessMessage || t('app.admin.edit_destroy_buttons.deleted'));
|
||||
}).catch((error) => {
|
||||
onError(t('app.admin.edit_destroy_buttons.unable_to_delete') + error);
|
||||
});
|
||||
toggleDeletionModal();
|
||||
setDeletionModal(false);
|
||||
};
|
||||
|
||||
return (
|
||||
@ -58,7 +74,7 @@ export const EditDestroyButtons: React.FC<EditDestroyButtonsProps> = ({ onDelete
|
||||
{showEditButton && <FabButton className='edit-btn' onClick={onEdit}>
|
||||
<PencilSimple size={iconSize} weight="fill" />
|
||||
</FabButton>}
|
||||
<FabButton type='button' className='delete-btn' onClick={toggleDeletionModal}>
|
||||
<FabButton type='button' className='delete-btn' onClick={handleDestroyRequest}>
|
||||
<Trash size={iconSize} weight="fill" />
|
||||
</FabButton>
|
||||
</div>
|
||||
|
@ -124,7 +124,7 @@ export const MachineCategoriesList: React.FC<MachineCategoriesListProps> = ({ on
|
||||
onEdit={editMachineCategory(category)}
|
||||
itemId={category.id}
|
||||
itemType={t('app.admin.machine_categories_list.machine_category')}
|
||||
apiDestroy={MachineCategoryAPI.destroy} />
|
||||
destroy={MachineCategoryAPI.destroy} />
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -333,7 +333,6 @@ export const PlanForm: React.FC<PlanFormProps> = ({ action, plan, onError, onSuc
|
||||
register={register}
|
||||
formState={formState}
|
||||
onError={onError}
|
||||
onSuccess={onSuccess}
|
||||
getValues={getValues}
|
||||
resetField={resetField} />
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { ReactNode, useEffect, useState } from 'react';
|
||||
import React, { ReactNode, useEffect, useState } from 'react';
|
||||
import { Control, FormState, UseFormGetValues, UseFormResetField } from 'react-hook-form/dist/types/form';
|
||||
import { FormSwitch } from '../form/form-switch';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@ -12,14 +12,13 @@ import MachineAPI from '../../api/machine';
|
||||
import MachineCategoryAPI from '../../api/machine-category';
|
||||
import { FormUnsavedList } from '../form/form-unsaved-list';
|
||||
import { EditDestroyButtons } from '../base/edit-destroy-buttons';
|
||||
import PlanLimitationAPI from '../../api/plan-limitation';
|
||||
import { X } from 'phosphor-react';
|
||||
|
||||
interface PlanLimitFormProps<TContext extends object> {
|
||||
register: UseFormRegister<Plan>,
|
||||
control: Control<Plan, TContext>,
|
||||
formState: FormState<Plan>,
|
||||
onError: (message: string) => void,
|
||||
onSuccess: (message: string) => void,
|
||||
getValues: UseFormGetValues<Plan>,
|
||||
resetField: UseFormResetField<Plan>
|
||||
}
|
||||
@ -27,7 +26,7 @@ interface PlanLimitFormProps<TContext extends object> {
|
||||
/**
|
||||
* Form tab to manage a subscription's usage limit
|
||||
*/
|
||||
export const PlanLimitForm = <TContext extends object> ({ register, control, formState, onError, onSuccess, getValues, resetField }: PlanLimitFormProps<TContext>) => {
|
||||
export const PlanLimitForm = <TContext extends object> ({ register, control, formState, onError, getValues, resetField }: PlanLimitFormProps<TContext>) => {
|
||||
const { t } = useTranslation('admin');
|
||||
const { fields, append, remove, update } = useFieldArray<Plan, 'plan_limitations_attributes'>({ control, name: 'plan_limitations_attributes' });
|
||||
const limiting = useWatch<Plan>({ control, name: 'limiting' });
|
||||
@ -89,16 +88,24 @@ export const PlanLimitForm = <TContext extends object> ({ register, control, for
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback triggered when a previously-saved limitation was deleted. Return a callback accepting a message.
|
||||
* Callback triggered when a saved limitation is requested to be deleted
|
||||
*/
|
||||
const onLimitationDeleted = (index: number): (message: string) => void => {
|
||||
return (message: string) => {
|
||||
onSuccess(message);
|
||||
remove(index);
|
||||
// This have a little drowback: remove(index) will set the form as "dirty", and trigger the "unsaved form alert", even if clicking on save or not
|
||||
// won't change anything to the deleted item. To improve this we could do the following: do not destroy the limitation through the API and instead
|
||||
// set {_destroy: true} and destroy the limitation when saving the form, but we need some UI for items about to be deleted
|
||||
// update(index, { ...getValues(`plan_limitations_attributes.${index}`), _destroy: true });
|
||||
const handleLimitationDelete = (index: number): () => Promise<void> => {
|
||||
return () => {
|
||||
return new Promise<void>((resolve) => {
|
||||
update(index, { ...getValues(`plan_limitations_attributes.${index}`), _destroy: true });
|
||||
resolve();
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Triggered when the user clicks on "cancel" for a limitated previsouly marked as deleted
|
||||
*/
|
||||
const cancelDeletion = (index: number): (event: React.MouseEvent<HTMLParagraphElement, MouseEvent>) => void => {
|
||||
return (event) => {
|
||||
event.preventDefault();
|
||||
update(index, { ...getValues(`plan_limitations_attributes.${index}`), _destroy: false });
|
||||
};
|
||||
};
|
||||
|
||||
@ -178,7 +185,7 @@ export const PlanLimitForm = <TContext extends object> ({ register, control, for
|
||||
if (limitation.limitable_type !== 'MachineCategory' || limitation._modified) return false;
|
||||
|
||||
return (
|
||||
<div className="plan-limit-item" key={limitation.id}>
|
||||
<div className={`plan-limit-item ${limitation._destroy ? 'is-destroying' : ''}`} key={limitation.id}>
|
||||
<div className="grp">
|
||||
<div>
|
||||
<span>{t('app.admin.plan_limit_form.category')}</span>
|
||||
@ -191,14 +198,11 @@ export const PlanLimitForm = <TContext extends object> ({ register, control, for
|
||||
</div>
|
||||
|
||||
<div className='actions'>
|
||||
<EditDestroyButtons onDeleteSuccess={onLimitationDeleted(index)}
|
||||
onError={onError}
|
||||
<EditDestroyButtons onError={onError}
|
||||
onEdit={onEditLimitation(limitation, index)}
|
||||
itemId={getValues(`plan_limitations_attributes.${index}.id`)}
|
||||
deleteSuccessMessage={t('app.admin.plan_limit_form.delete_success')}
|
||||
confirmationTitle={t('app.admin.plan_limit_form.confirmation_title')}
|
||||
confirmationMessage={t('app.admin.plan_limit_form.confirmation_message')}
|
||||
apiDestroy={PlanLimitationAPI.destroy} />
|
||||
showDestroyConfirmation={false}
|
||||
destroy={handleLimitationDelete(index)} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@ -213,7 +217,7 @@ export const PlanLimitForm = <TContext extends object> ({ register, control, for
|
||||
if (limitation.limitable_type !== 'Machine' || limitation._modified) return false;
|
||||
|
||||
return (
|
||||
<div className="plan-limit-item" key={limitation.id}>
|
||||
<div className={`plan-limit-item ${limitation._destroy ? 'is-destroying' : ''}`} key={limitation.id}>
|
||||
<div className="grp">
|
||||
<div>
|
||||
<span>{t('app.admin.plan_limit_form.machine')}</span>
|
||||
@ -223,17 +227,20 @@ export const PlanLimitForm = <TContext extends object> ({ register, control, for
|
||||
<span>{t('app.admin.plan_limit_form.max_hours_per_day')}</span>
|
||||
<p>{limitation.limit}</p>
|
||||
</div>
|
||||
{limitation._destroy && <div className="marker">{t('app.admin.plan_limit_form.ongoing_deletion')}</div>}
|
||||
</div>
|
||||
|
||||
<div className='actions'>
|
||||
<EditDestroyButtons onDeleteSuccess={onLimitationDeleted(index)}
|
||||
onError={onError}
|
||||
{(limitation._destroy &&
|
||||
<p className="cancel-action" onClick={cancelDeletion(index)}>
|
||||
{t('app.admin.plan_limit_form.cancel_deletion')}
|
||||
<X size={14} />
|
||||
</p>) ||
|
||||
<EditDestroyButtons onError={onError}
|
||||
onEdit={onEditLimitation(limitation, index)}
|
||||
itemId={getValues(`plan_limitations_attributes.${index}.id`)}
|
||||
confirmationTitle={t('app.admin.plan_limit_form.confirmation_title')}
|
||||
confirmationMessage={t('app.admin.plan_limit_form.confirmation_message')}
|
||||
deleteSuccessMessage={t('app.admin.plan_limit_form.delete_success')}
|
||||
apiDestroy={PlanLimitationAPI.destroy} />
|
||||
showDestroyConfirmation={false}
|
||||
destroy={handleLimitationDelete(index)} />}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -114,7 +114,7 @@ export const ConfigurePacksButton: React.FC<ConfigurePacksButtonProps> = ({ pack
|
||||
onEdit={() => handleRequestEdit(p)}
|
||||
itemId={p.id}
|
||||
itemType={t('app.admin.configure_packs_button.pack')}
|
||||
apiDestroy={PrepaidPackAPI.destroy}/>
|
||||
destroy={PrepaidPackAPI.destroy}/>
|
||||
<FabModal isOpen={isOpen}
|
||||
toggleModal={toggleModal}
|
||||
title={t('app.admin.configure_packs_button.edit_pack')}
|
||||
|
@ -78,7 +78,7 @@ export const ProductItem: React.FC<ProductItemProps> = ({ product, onEdit, onDel
|
||||
onEdit={editProduct(product)}
|
||||
itemId={product.id}
|
||||
itemType={t('app.admin.store.product_item.product')}
|
||||
apiDestroy={ProductAPI.destroy} />
|
||||
destroy={ProductAPI.destroy} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -199,7 +199,7 @@ export const Trainings: React.FC<TrainingsProps> = ({ onError, onSuccess }) => {
|
||||
onEdit={() => toTrainingEdit(training)}
|
||||
itemId={training.id}
|
||||
itemType={t('app.admin.trainings.training')}
|
||||
apiDestroy={TrainingAPI.destroy}/>
|
||||
destroy={TrainingAPI.destroy}/>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
|
@ -58,6 +58,27 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.is-destroying {
|
||||
background-color: var(--main-lightest);
|
||||
.marker {
|
||||
text-align: center;
|
||||
font-weight: 500;
|
||||
color: var(--main-dark);
|
||||
margin: auto;
|
||||
}
|
||||
.actions > .cancel-action {
|
||||
font-weight: normal;
|
||||
svg {
|
||||
vertical-align: middle;
|
||||
margin-left: 1rem;
|
||||
}
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Check the access policies for API::PlanLimitationsController
|
||||
class PlanLimitationPolicy < ApplicationPolicy
|
||||
def destroy?
|
||||
user.admin?
|
||||
end
|
||||
end
|
@ -2,7 +2,7 @@ de:
|
||||
app:
|
||||
admin:
|
||||
edit_destroy_buttons:
|
||||
deleted: "The {TYPE} was successfully deleted."
|
||||
deleted: "Successfully deleted."
|
||||
unable_to_delete: "Unable to delete: "
|
||||
delete_item: "Delete the {TYPE}"
|
||||
confirm_delete: "Delete"
|
||||
@ -24,7 +24,7 @@ de:
|
||||
save: "Save"
|
||||
successfully_saved: "Your banner was successfully saved."
|
||||
machine_categories_list:
|
||||
machine_categories: "Machines categories"
|
||||
machine_categories: "Maschinen-Kategorien"
|
||||
add_a_machine_category: "Add a machine category"
|
||||
name: "Name"
|
||||
machines_number: "Number of machines"
|
||||
@ -57,7 +57,7 @@ de:
|
||||
disabled_help: "When disabled, the machine won't be reservable and won't appear by default in the machines list."
|
||||
reservable: "Can this machine be reserved?"
|
||||
reservable_help: "When disabled, the machine will be shown in the default list of machines, but without the reservation button. If you already have created some availability slots for this machine, you may want to remove them: do it from the admin agenda."
|
||||
save: "Save"
|
||||
save: "Speichern"
|
||||
create_success: "The machine was created successfully"
|
||||
update_success: "The machine was updated successfully"
|
||||
training_form:
|
||||
@ -74,7 +74,7 @@ de:
|
||||
associated_machines_help: "If you associate a machine to this training, the members will need to successfully pass this training before being able to reserve the machine."
|
||||
default_seats: "Default number of seats"
|
||||
public_page: "Show in training lists"
|
||||
public_help: "When unchecked, this option will prevent the training from appearing in the trainings list."
|
||||
public_help: "Wenn diese Option deaktiviert ist, wird verhindert, dass das Training in der Trainingliste erscheint."
|
||||
disable_training: "Disable the training"
|
||||
disabled_help: "When disabled, the training won't be reservable and won't appear by default in the trainings list."
|
||||
automatic_cancellation: "Automatic cancellation"
|
||||
@ -90,39 +90,39 @@ de:
|
||||
validation_rule_info: "Define a rule that cancel an authorisation if the machines associated with the training are not reserved for a specific period of time. This rule prevails over the authorisations validity period."
|
||||
validation_rule_switch: "Activate the validation rule"
|
||||
validation_rule_period: "Time limit in months"
|
||||
save: "Save"
|
||||
create_success: "The training was created successfully"
|
||||
update_success: "The training was updated successfully"
|
||||
save: "Speichern"
|
||||
create_success: "Die Schulung wurde erfolgreich erstellt"
|
||||
update_success: "Die Schulung wurde erfolgreich aktualisiert"
|
||||
space_form:
|
||||
ACTION_title: "{ACTION, select, create{New} other{Update the}} space"
|
||||
watch_out_when_creating_a_new_space_its_prices_are_initialized_at_0_for_all_subscriptions: "Watch out! When creating a new space, its prices are initialized at 0 for all subscriptions."
|
||||
consider_changing_its_prices_before_creating_any_reservation_slot: "Consider changing its prices before creating any reservation slot."
|
||||
ACTION_title: "{ACTION, select, create{Neu} other{Aktualisiere den}} Raum"
|
||||
watch_out_when_creating_a_new_space_its_prices_are_initialized_at_0_for_all_subscriptions: "Achtung! Beim Erstellen eines neuen Raums wird sein Preis für alle Abonnements mit 0 angelegt."
|
||||
consider_changing_its_prices_before_creating_any_reservation_slot: "Ändern Sie ggf. die Preise, bevor Sie Reservierungs-Slots erstellen."
|
||||
name: "Name"
|
||||
illustration: "Illustration"
|
||||
description: "Description"
|
||||
characteristics: "Characteristics"
|
||||
attachments: "Attachments"
|
||||
attached_files_pdf: "Attached files (pdf)"
|
||||
add_an_attachment: "Add an attachment"
|
||||
settings: "Settings"
|
||||
default_seats: "Default number of seats"
|
||||
disable_space: "Disable the space"
|
||||
disabled_help: "When disabled, the space won't be reservable and won't appear by default in the spaces list."
|
||||
save: "Save"
|
||||
create_success: "The space was created successfully"
|
||||
update_success: "The space was updated successfully"
|
||||
illustration: "Abbildung"
|
||||
description: "Beschreibung"
|
||||
characteristics: "Eigenschaften"
|
||||
attachments: "Dateianhänge"
|
||||
attached_files_pdf: "Angehängte Dateien (pdf)"
|
||||
add_an_attachment: "Anhang hinzufügen"
|
||||
settings: "Einstellungen"
|
||||
default_seats: "Standardanzahl der Sitze"
|
||||
disable_space: "Raum deaktivieren"
|
||||
disabled_help: "Wenn deaktiviert, ist der Raum nicht reservierbar und erscheint standardmäßig nicht in der Liste der Leerzeichen."
|
||||
save: "Speichern"
|
||||
create_success: "Der Raum wurde erfolgreich erstellt"
|
||||
update_success: "Der Raum wurde erfolgreich aktualisiert"
|
||||
event_form:
|
||||
ACTION_title: "{ACTION, select, create{New} other{Update the}} event"
|
||||
title: "Title"
|
||||
ACTION_title: "{ACTION, select, create{Neue} other{Aktualisiere die}} Veranstaltung"
|
||||
title: "Titel"
|
||||
matching_visual: "Matching visual"
|
||||
description: "Description"
|
||||
attachments: "Attachments"
|
||||
attached_files_pdf: "Attached files (pdf)"
|
||||
add_a_new_file: "Add a new file"
|
||||
event_category: "Event category"
|
||||
event_category: "Veranstaltungskategorie"
|
||||
dates_and_opening_hours: "Dates and opening hours"
|
||||
all_day: "All day"
|
||||
all_day_help: "Will the event last all day or do you want to set times?"
|
||||
all_day_help: "Wird das Ereignis den ganzen Tag dauern oder möchtest du Zeiten festlegen?"
|
||||
start_date: "Start date"
|
||||
end_date: "End date"
|
||||
start_time: "Start time"
|
||||
@ -135,33 +135,33 @@ de:
|
||||
fare_class: "Fare class"
|
||||
price: "Price"
|
||||
seats_available: "Seats available"
|
||||
seats_help: "If you leave this field empty, this event will be available without reservations."
|
||||
event_themes: "Event themes"
|
||||
seats_help: "Wenn sie dieses Feld leer lassen, ist diese Veranstaltung ohne Reservierung."
|
||||
event_themes: "Veranstaltungsthemen"
|
||||
age_range: "Age range"
|
||||
add_price: "Add a price"
|
||||
save: "Save"
|
||||
create_success: "The event was created successfully"
|
||||
events_updated: "{COUNT, plural, =1{One event was} other{{COUNT} Events were}} successfully updated"
|
||||
events_not_updated: "{TOTAL, plural, =1{The event was} other{On {TOTAL} events {COUNT, plural, =1{one was} other{{COUNT} were}}}} not updated."
|
||||
error_deleting_reserved_price: "Unable to remove the requested price because it is associated with some existing reservations"
|
||||
other_error: "An unexpected error occurred while updating the event"
|
||||
create_success: "Die Veranstaltung wurde erfolgreich erstellt"
|
||||
events_updated: "{COUNT, plural, one {}=1{Eine Veranstaltung wurde} other{{COUNT} Veranstaltungen wurden}} erfolgreich aktualisiert"
|
||||
events_not_updated: "{TOTAL, plural, =1{Die Veranstaltung war} other{Auf {TOTAL} Veranstaltungen {COUNT, plural, =1{eins war} other{{COUNT} waren}}}} nicht aktualisiert."
|
||||
error_deleting_reserved_price: "Der angeforderte Preis konnte nicht gelöscht werden, da er mit einigen Reservierungen verknüpft ist"
|
||||
other_error: "Beim Aktualisieren der Veranstaltung ist ein unerwarteter Fehler aufgetreten"
|
||||
recurring:
|
||||
none: "None"
|
||||
every_days: "Every days"
|
||||
every_week: "Every week"
|
||||
every_month: "Every month"
|
||||
every_year: "Every year"
|
||||
every_days: "Täglich"
|
||||
every_week: "Wöchentlich"
|
||||
every_month: "Monatlich"
|
||||
every_year: "Jährlich"
|
||||
plan_form:
|
||||
ACTION_title: "{ACTION, select, create{New} other{Update the}} plan"
|
||||
tab_settings: "Settings"
|
||||
tab_settings: "Einstellungen"
|
||||
tab_usage_limits: "Usage limits"
|
||||
description: "Description"
|
||||
general_settings: "General settings"
|
||||
description: "Beschreibung"
|
||||
general_settings: "Generelle Einstellungen"
|
||||
general_settings_info: "Determine to which group this subscription is dedicated. Also set its price and duration in periods."
|
||||
activation_and_payment: "Subscription activation and payment"
|
||||
name: "Name"
|
||||
name_max_length: "Name length must be less than 24 characters."
|
||||
group: "Group"
|
||||
group: "Gruppe"
|
||||
transversal: "Transversal plan"
|
||||
transversal_help: "If this option is checked, a copy of this plan will be created for each currently enabled groups."
|
||||
display: "Display"
|
||||
@ -208,9 +208,8 @@ de:
|
||||
ongoing_limitations: "Ongoing limitations"
|
||||
saved_limitations: "Saved limitations"
|
||||
cancel: "Cancel this limitation"
|
||||
confirmation_title: "Delete the limitation"
|
||||
confirmation_message: "Are you sure you want to delete this limitation? This will take effect immediately and cannot be undone."
|
||||
delete_success: "The limitation was successfully deleted."
|
||||
cancel_deletion: "Cancel"
|
||||
ongoing_deletion: "Ongoing deletion"
|
||||
plan_limit_modal:
|
||||
title: "Manage limitation of use"
|
||||
limit_reservations: "Limit reservations"
|
||||
@ -237,10 +236,10 @@ de:
|
||||
spaces: "Spaces"
|
||||
update_recurrent_modal:
|
||||
title: "Periodic event update"
|
||||
edit_recurring_event: "You're about to update a periodic event. What do you want to update?"
|
||||
edit_this_event: "Only this event"
|
||||
edit_recurring_event: "Sie bearbeiten eine wiederkehrende Veranstaltung. Was möchten Sie ändern?"
|
||||
edit_this_event: "Nur diese Veranstaltung"
|
||||
edit_this_and_next: "This event and the followings"
|
||||
edit_all: "All events"
|
||||
edit_all: "Alle Veranstaltungen"
|
||||
date_wont_change: "Warning: you have changed the event date. This modification won't be propagated to other occurrences of the periodic event."
|
||||
confirm: "Update the {MODE, select, single{event} other{events}}"
|
||||
advanced_accounting_form:
|
||||
@ -262,7 +261,7 @@ de:
|
||||
subscriptions: "Subscriptions"
|
||||
machine: "Machine reservation"
|
||||
training: "Training reservation"
|
||||
event: "Event reservation"
|
||||
event: "Veranstaltungsreservierung"
|
||||
space: "Space reservation"
|
||||
prepaid_pack: "Pack of prepaid-hours"
|
||||
product: "Product of the store"
|
||||
@ -621,13 +620,13 @@ de:
|
||||
events_settings:
|
||||
title: "Settings"
|
||||
generic_text_block: "Editorial text block"
|
||||
generic_text_block_info: "Displays an editorial block above the list of events visible to members."
|
||||
generic_text_block_info: "Zeigt einen redaktionellen Block oberhalb der für Mitglieder sichtbaren Veranstaltungsliste."
|
||||
generic_text_block_switch: "Display editorial block"
|
||||
cta_switch: "Display a button"
|
||||
cta_label: "Button label"
|
||||
cta_url: "url"
|
||||
save: "Save"
|
||||
update_success: "The events settings were successfully updated"
|
||||
update_success: "Die Einstellungen wurden erfolgreich aktualisiert"
|
||||
#subscriptions, prices, credits and coupons management
|
||||
pricing:
|
||||
pricing_management: "Preisverwaltung"
|
||||
@ -2322,8 +2321,8 @@ de:
|
||||
low_stock: "Low stock"
|
||||
threshold_level: "Minimum threshold level"
|
||||
threshold_alert: "Notify me when the threshold is reached"
|
||||
events_history: "Events history"
|
||||
event_type: "Events:"
|
||||
events_history: "Veranstaltungsverlauf"
|
||||
event_type: "Veranstaltungen:"
|
||||
reason: "Reason"
|
||||
stocks: "Stock:"
|
||||
internal: "Private stock"
|
||||
@ -2420,7 +2419,7 @@ de:
|
||||
VAT_rate_machine: "Machine reservation"
|
||||
VAT_rate_space: "Space reservation"
|
||||
VAT_rate_training: "Training reservation"
|
||||
VAT_rate_event: "Event reservation"
|
||||
VAT_rate_event: "Veranstaltungsreservierung"
|
||||
VAT_rate_subscription: "Subscription"
|
||||
VAT_rate_product: "Products (store)"
|
||||
multi_VAT_notice: "<strong>Please note</strong>: The current general rate is {RATE}%. You can define different VAT rates for each category.<br><br>For example, you can override this value, only for machine reservations, by filling in the corresponding field beside. If you don't fill any value, the general rate will apply."
|
||||
|
@ -2,7 +2,7 @@ en:
|
||||
app:
|
||||
admin:
|
||||
edit_destroy_buttons:
|
||||
deleted: "The {TYPE} was successfully deleted."
|
||||
deleted: "Successfully deleted."
|
||||
unable_to_delete: "Unable to delete: "
|
||||
delete_item: "Delete the {TYPE}"
|
||||
confirm_delete: "Delete"
|
||||
@ -208,9 +208,8 @@ en:
|
||||
ongoing_limitations: "Ongoing limitations"
|
||||
saved_limitations: "Saved limitations"
|
||||
cancel: "Cancel this limitation"
|
||||
confirmation_title: "Delete the limitation"
|
||||
confirmation_message: "Are you sure you want to delete this limitation? This will take effect immediately and cannot be undone."
|
||||
delete_success: "The limitation was successfully deleted."
|
||||
cancel_deletion: "Cancel"
|
||||
ongoing_deletion: "Ongoing deletion"
|
||||
plan_limit_modal:
|
||||
title: "Manage limitation of use"
|
||||
limit_reservations: "Limit reservations"
|
||||
|
@ -2,7 +2,7 @@ es:
|
||||
app:
|
||||
admin:
|
||||
edit_destroy_buttons:
|
||||
deleted: "The {TYPE} was successfully deleted."
|
||||
deleted: "Successfully deleted."
|
||||
unable_to_delete: "Unable to delete: "
|
||||
delete_item: "Delete the {TYPE}"
|
||||
confirm_delete: "Delete"
|
||||
@ -208,9 +208,8 @@ es:
|
||||
ongoing_limitations: "Ongoing limitations"
|
||||
saved_limitations: "Saved limitations"
|
||||
cancel: "Cancel this limitation"
|
||||
confirmation_title: "Delete the limitation"
|
||||
confirmation_message: "Are you sure you want to delete this limitation? This will take effect immediately and cannot be undone."
|
||||
delete_success: "The limitation was successfully deleted."
|
||||
cancel_deletion: "Cancel"
|
||||
ongoing_deletion: "Ongoing deletion"
|
||||
plan_limit_modal:
|
||||
title: "Manage limitation of use"
|
||||
limit_reservations: "Limit reservations"
|
||||
|
@ -208,9 +208,8 @@ fr:
|
||||
ongoing_limitations: "Limites en cours"
|
||||
saved_limitations: "Limites enregistrées"
|
||||
cancel: "Annuler cette limite"
|
||||
confirmation_title: "Supprimer la limite"
|
||||
confirmation_message: "Êtes-vous sûr de vouloir supprimer cette limite ? Cela prendra effet immédiatement et ne sera pas résersible."
|
||||
delete_success: "La limite a bien été supprimée."
|
||||
cancel_deletion: "Annuler"
|
||||
ongoing_deletion: "Suppression en cours"
|
||||
plan_limit_modal:
|
||||
title: "Gérer la limite d'usage"
|
||||
limit_reservations: "Limiter les réservations"
|
||||
|
@ -2,7 +2,7 @@
|
||||
app:
|
||||
admin:
|
||||
edit_destroy_buttons:
|
||||
deleted: "The {TYPE} was successfully deleted."
|
||||
deleted: "Successfully deleted."
|
||||
unable_to_delete: "Unable to delete: "
|
||||
delete_item: "Delete the {TYPE}"
|
||||
confirm_delete: "Delete"
|
||||
@ -208,9 +208,8 @@
|
||||
ongoing_limitations: "Ongoing limitations"
|
||||
saved_limitations: "Saved limitations"
|
||||
cancel: "Cancel this limitation"
|
||||
confirmation_title: "Delete the limitation"
|
||||
confirmation_message: "Are you sure you want to delete this limitation? This will take effect immediately and cannot be undone."
|
||||
delete_success: "The limitation was successfully deleted."
|
||||
cancel_deletion: "Cancel"
|
||||
ongoing_deletion: "Ongoing deletion"
|
||||
plan_limit_modal:
|
||||
title: "Manage limitation of use"
|
||||
limit_reservations: "Limit reservations"
|
||||
|
@ -2,7 +2,7 @@ pt:
|
||||
app:
|
||||
admin:
|
||||
edit_destroy_buttons:
|
||||
deleted: "The {TYPE} was successfully deleted."
|
||||
deleted: "Successfully deleted."
|
||||
unable_to_delete: "Unable to delete: "
|
||||
delete_item: "Delete the {TYPE}"
|
||||
confirm_delete: "Delete"
|
||||
@ -208,9 +208,8 @@ pt:
|
||||
ongoing_limitations: "Ongoing limitations"
|
||||
saved_limitations: "Saved limitations"
|
||||
cancel: "Cancel this limitation"
|
||||
confirmation_title: "Delete the limitation"
|
||||
confirmation_message: "Are you sure you want to delete this limitation? This will take effect immediately and cannot be undone."
|
||||
delete_success: "The limitation was successfully deleted."
|
||||
cancel_deletion: "Cancel"
|
||||
ongoing_deletion: "Ongoing deletion"
|
||||
plan_limit_modal:
|
||||
title: "Manage limitation of use"
|
||||
limit_reservations: "Limit reservations"
|
||||
|
@ -2,7 +2,7 @@ zu:
|
||||
app:
|
||||
admin:
|
||||
edit_destroy_buttons:
|
||||
deleted: "crwdns36793:0{TYPE}crwdne36793:0"
|
||||
deleted: "crwdns36793:0crwdne36793:0"
|
||||
unable_to_delete: "crwdns36795:0crwdne36795:0"
|
||||
delete_item: "crwdns36797:0{TYPE}crwdne36797:0"
|
||||
confirm_delete: "crwdns36799:0crwdne36799:0"
|
||||
@ -208,9 +208,8 @@ zu:
|
||||
ongoing_limitations: "crwdns37433:0crwdne37433:0"
|
||||
saved_limitations: "crwdns37435:0crwdne37435:0"
|
||||
cancel: "crwdns37437:0crwdne37437:0"
|
||||
confirmation_title: "crwdns37439:0crwdne37439:0"
|
||||
confirmation_message: "crwdns37441:0crwdne37441:0"
|
||||
delete_success: "crwdns37443:0crwdne37443:0"
|
||||
cancel_deletion: "crwdns37487:0crwdne37487:0"
|
||||
ongoing_deletion: "crwdns37489:0crwdne37489:0"
|
||||
plan_limit_modal:
|
||||
title: "crwdns37445:0crwdne37445:0"
|
||||
limit_reservations: "crwdns37447:0crwdne37447:0"
|
||||
|
@ -116,7 +116,6 @@ Rails.application.routes.draw do
|
||||
patch 'cancel', on: :member
|
||||
end
|
||||
resources :plan_categories
|
||||
resources :plan_limitations, only: [:destroy]
|
||||
resources :plans do
|
||||
get 'durations', on: :collection
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user