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:
parent
fcdc357f89
commit
870de2b421
@ -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']));
|
||||
|
@ -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 });
|
||||
}
|
||||
}
|
||||
]);
|
||||
|
||||
|
@ -135,7 +135,7 @@
|
||||
&.disabled {
|
||||
opacity: 0.5;
|
||||
|
||||
.machine-actions > button.show-button {
|
||||
.machine-actions > span {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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"
|
||||
|
Loading…
x
Reference in New Issue
Block a user