1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2025-02-20 14:54:15 +01:00

reserve machine button in show machine page

This commit is contained in:
Sylvain 2021-06-18 16:40:39 +02:00
parent fcdc357f89
commit 870de2b421
5 changed files with 68 additions and 103 deletions

View File

@ -1,9 +1,15 @@
import React, { BaseSyntheticEvent, useEffect, useState } from 'react';
import React, { useEffect, useState } from 'react';
import { PendingTrainingModal } from './pending-training-modal';
import MachineAPI from '../../api/machine';
import { Machine } from '../../models/machine';
import { User } from '../../models/user';
import { RequiredTrainingModal } from './required-training-modal';
import { react2angular } from 'react2angular';
import { IApplication } from '../../models/application';
import { useTranslation } from 'react-i18next';
import { Loader } from '../base/loader';
declare var Application: IApplication;
interface ReserveButtonProps {
currentUser?: User,
@ -11,7 +17,7 @@ interface ReserveButtonProps {
onLoadingStart?: () => void,
onLoadingEnd?: () => void,
onError: (message: string) => void,
onReserveMachine: (machineId: number) => void,
onReserveMachine: (machine: Machine) => void,
onLoginRequested: () => Promise<User>,
onEnrollRequested: (trainingId: number) => void,
className?: string
@ -20,7 +26,8 @@ interface ReserveButtonProps {
/**
* Button component that makes the training verification before redirecting the user to the reservation calendar
*/
export const ReserveButton: React.FC<ReserveButtonProps> = ({ currentUser, machineId, onLoginRequested, onLoadingStart, onLoadingEnd, onError, onReserveMachine, onEnrollRequested, className, children }) => {
const ReserveButtonComponent: React.FC<ReserveButtonProps> = ({ currentUser, machineId, onLoginRequested, onLoadingStart, onLoadingEnd, onError, onReserveMachine, onEnrollRequested, className, children }) => {
const { t } = useTranslation('shared');
const [machine, setMachine] = useState<Machine>(null);
const [user, setUser] = useState<User>(currentUser);
@ -93,7 +100,7 @@ export const ReserveButton: React.FC<ReserveButtonProps> = ({ currentUser, machi
// Moreover, if all associated trainings are disabled, let the user reserve too.
if (machine.current_user_is_trained || machine.trainings.length === 0 ||
machine.trainings.map(t => t.disabled).reduce((acc, val) => acc && val, true)) {
return onReserveMachine(machineId);
return onReserveMachine(machine);
}
// if the currently logged user booked a training for this machine, tell him that he must wait
@ -109,8 +116,9 @@ export const ReserveButton: React.FC<ReserveButtonProps> = ({ currentUser, machi
return (
<span>
<button onClick={handleClick} className={className}>
{children}
<button onClick={handleClick} className={className ? className : ''}>
{children && children}
{!children && <span>{t('app.shared.reserve_button.book_this_machine')}</span>}
</button>
<PendingTrainingModal isOpen={pendingTraining}
toggleModal={togglePendingTrainingModal}
@ -124,3 +132,15 @@ export const ReserveButton: React.FC<ReserveButtonProps> = ({ currentUser, machi
);
}
export const ReserveButton: React.FC<ReserveButtonProps> = ({ currentUser, machineId, onLoginRequested, onLoadingStart, onLoadingEnd, onError, onReserveMachine, onEnrollRequested, className, children }) => {
return (
<Loader>
<ReserveButtonComponent currentUser={currentUser} machineId={machineId} onError={onError} onLoadingStart={onLoadingStart} onLoadingEnd={onLoadingEnd} onReserveMachine={onReserveMachine} onLoginRequested={onLoginRequested} onEnrollRequested={onEnrollRequested} className={className}>
{children}
</ReserveButtonComponent>
</Loader>
);
}
Application.Components.component('reserveButton', react2angular(ReserveButton, ['currentUser', 'machineId', 'onLoadingStart', 'onLoadingEnd', 'onError', 'onReserveMachine', 'onLoginRequested', 'onEnrollRequested', 'className']));

View File

@ -95,93 +95,11 @@ class MachinesController {
}
}
/**
* Manages the transition when a user clicks on the reservation button.
* According to the status of user currently logged into the system, redirect him to the reservation page,
* or display a modal window asking him to complete a training before he can book a machine reservation.
* @param machine {{id:number}} An object containg the id of the machine to book,
* the object will be completed before the fonction returns.
* @param e {Object} see https://docs.angularjs.org/guide/expression#-event-
*/
const _reserveMachine = function (machine, e) {
const _this = this;
e.preventDefault();
e.stopPropagation();
// retrieve the full machine object
return machine = _this.Machine.get({ id: machine.id }, function () {
// if the currently logged'in user has completed the training for this machine, or this machine does not require
// a prior training, just redirect him to the machine's booking page
if (machine.current_user_is_trained || (machine.trainings.length === 0)) {
return _this.$state.go('app.logged.machines_reserve', { id: machine.slug });
} else {
// otherwise, if a user is authenticated ...
if (_this.$scope.isAuthenticated()) {
// ... and have booked a training for this machine, tell him that he must wait for an admin to validate
// the training before he can book the reservation
if (machine.current_user_next_training_reservation) {
return _this.$uibModal.open({
templateUrl: '/machines/training_reservation_modal.html',
controller: ['$scope', '$uibModalInstance', function ($scope, $uibModalInstance) {
$scope.machine = machine;
return $scope.cancel = function () { $uibModalInstance.dismiss('cancel'); };
}]
});
// ... but does not have booked the training, tell him to register for a training session first
// unless all associated trainings are disabled
} else {
// if all trainings are disabled, just redirect the user to the reservation calendar
if (machine.trainings.map(function (t) { return t.disabled; }).reduce(function (acc, val) { return acc && val; }, true)) {
return _this.$state.go('app.logged.machines_reserve', { id: machine.slug });
// otherwise open the information modal
} else {
return _this.$uibModal.open({
templateUrl: '/machines/request_training_modal.html',
controller: ['$scope', '$uibModalInstance', '$state', function ($scope, $uibModalInstance, $state) {
$scope.machine = machine;
$scope.member = _this.$scope.currentUser;
// transform the name of the trainings associated with the machine to integrate them in a sentence
$scope.humanizeTrainings = function () {
let text = '';
angular.forEach($scope.machine.trainings, function (training) {
if (text.length > 0) {
text += _this._t('app.public.machines_list._or_the_');
}
return text += training.name.substr(0, 1).toLowerCase() + training.name.substr(1);
});
return text;
};
// modal is closed with validation
$scope.ok = function () {
$state.go('app.logged.trainings_reserve', { id: $scope.machine.trainings[0].id });
return $uibModalInstance.close(machine);
};
// modal is closed with escaping
return $scope.cancel = function (e) {
e.preventDefault();
return $uibModalInstance.dismiss('cancel');
};
}
] });
}
}
// if the user is not logged, open the login modal window
} else {
return _this.$scope.login();
}
}
});
};
/**
* Controller used in the public listing page, allowing everyone to see the list of machines
*/
Application.Controllers.controller('MachinesController', ['$scope', '$state', '_t', 'AuthService', 'Machine', '$uibModal', 'machinesPromise', 'settingsPromise', 'Member', 'uiTourService', 'growl',
function ($scope, $state, _t, AuthService, Machine, $uibModal, machinesPromise, settingsPromise, Member, uiTourService, growl) {
Application.Controllers.controller('MachinesController', ['$scope', '$state', '_t', 'AuthService', 'Machine', '$uibModal', 'settingsPromise', 'Member', 'uiTourService', 'growl',
function ($scope, $state, _t, AuthService, Machine, $uibModal, settingsPromise, Member, uiTourService, growl) {
/* PUBLIC SCOPE */
/**
@ -386,16 +304,36 @@ Application.Controllers.controller('ShowMachineController', ['$scope', '$state',
}
};
/**
* Shows an error message forwarded from a child component
*/
$scope.onError = function (message) {
growl.error(message);
}
/**
* Open the modal dialog to log the user and resolves the returned promise when the logging process
* was successfully completed.
*/
$scope.onLoginRequest = function (e) {
return new Promise((resolve, _reject) => {
$scope.login(e, resolve);
});
}
/**
* Redirect the user to the training reservation page
*/
$scope.onEnrollRequest = function (trainingId) {
$state.go('app.logged.trainings_reserve', { id: trainingId });
}
/**
* Callback to book a reservation for the current machine
*/
return $scope.reserveMachine = _reserveMachine.bind({
$scope,
$state,
_t,
$uibModal,
Machine
});
$scope.reserveMachine = function (machine) {
$state.go('app.logged.machines_reserve', { id: machine.slug });
}
}
]);

View File

@ -135,7 +135,7 @@
&.disabled {
opacity: 0.5;
.machine-actions > button.show-button {
.machine-actions > span {
width: 100%;
}
}

View File

@ -15,11 +15,15 @@
<div class="col-xs-12 col-sm-12 col-md-4 b-t hide-b-md">
<section class="heading-actions wrapper">
<a ng-click="reserveMachine(machine, $event)"
class="btn btn-lg btn-warning bg-white b-2x rounded m-t-xs"
ng-if="!isAuthorized('admin')"
ng-hide="machine.disabled"
translate>{{ 'app.public.machines_show.book_this_machine' }}</a>
<reserve-button ng-hide="machine.disabled"
class-name="'btn btn-lg btn-warning bg-white b-2x rounded m-t-xs'"
current-user="currentUser"
machine-id="machine.id"
on-error="onError"
on-reserve-machine="reserveMachine"
on-login-requested="onLoginRequest"
on-enroll-requested="onEnrollRequest">
</reserve-button>
<a ui-sref="app.admin.machines_edit({id: machine.id})" ng-if="isAuthorized('admin')" class="btn btn-lg btn-warning bg-white b-2x rounded m-t-xs"><i class="fa fa-edit"></i> {{ 'app.shared.buttons.edit' | translate }}</a>
<a ng-click="delete(machine)" ng-if="isAuthorized('admin')" class="btn btn-lg btn-danger b-2x rounded no-b m-t-xs"><i class="fa fa-trash-o"></i></a>

View File

@ -106,6 +106,9 @@ en:
add_an_attachment: "Add an attachment"
disable_machine: "Disable machine"
validate_your_machine: "Validate your machine"
#button to book a machine reservation
reserve_button:
book_this_machine: "Book this machine"
#frame to select a plan to subscribe
plan_subscribe:
subscribe_online: "subscribe online"