diff --git a/loan-custom/caosdb-server/caosdb-webui/build.properties.d/51_box_loan.properties b/loan-custom/caosdb-server/caosdb-webui/build.properties.d/51_box_loan.properties index 09b7cf8881f5723ad9901d0d5ca5badc271e0382..b2bfa0eb800f4d641e0937609a65d66973b1de89 100644 --- a/loan-custom/caosdb-server/caosdb-webui/build.properties.d/51_box_loan.properties +++ b/loan-custom/caosdb-server/caosdb-webui/build.properties.d/51_box_loan.properties @@ -1 +1,6 @@ BUILD_MODULE_BOX_LOAN=ENABLED +BUILD_MODULE_EXT_LOAN_BORROW_BOOKMARKED=ENABLED +MODULE_DEPENDENCIES+=( + box_loan_config.js + box_loan.js +) diff --git a/loan-custom/caosdb-server/caosdb-webui/src/ext/html/forms/loan-forms/borrow_all_bookmarked.html b/loan-custom/caosdb-server/caosdb-webui/src/ext/html/forms/loan-forms/borrow_all_bookmarked.html new file mode 100644 index 0000000000000000000000000000000000000000..71fd0ccdfbebe60dc14baa09ca5248bf31d6d3d7 --- /dev/null +++ b/loan-custom/caosdb-server/caosdb-webui/src/ext/html/forms/loan-forms/borrow_all_bookmarked.html @@ -0,0 +1,95 @@ +<!DOCTYPE html> +<html> + +<body> + <div id="caosdb-form"> + <div class="row" id="checkout-form-{boxid}" style="margin:0px"> + <div id="caosdb-f-borrow-all-form-modal" class="modal fade" aria-labelledby="borrow-all-modal" aria-hidden="true"> + <div class="modal-dialog" style="max-width:900px" > + <div class="modal-content"> + <div class="modal-header"> + <h4 class="modal-title">Borrow all bookmaked items</h4> + </div> + <div class="modal-body "> + <form class="borrow-all-form" autocomplete="on"> + <div> + Please enter your full name and your email address. If you are doing this for the first time, a + new user record will be created. + </div> + <div class="row caosdb-form-row"> + <div class="col-sm-4"> + <div class="form-group"> + <label>First Name: + <input name="first-name" type="name" class="form-control" id="first-name" + placeholder="Enter name" required="required" value="{first_name}" /> + </label> + </div> + </div> + <div class="col-sm-4"> + <div class="form-group"> + <label>Last Name: + <input name="last-name" type="name" class="form-control" id="last-name" placeholder="Enter name" + required="required" value="{last_name}" /> + </label> + </div> + </div> + <div class="col-sm-4"> + <div class="form-group"> + <label>Email: + <input name="email" type="email" class="form-control" id="email" placeholder="Enter email" + required="required" value="{email}" /> + </label> + </div> + </div> + </div> + <div class="row caosdb-form-row"> + <div class="col-sm-4"> + <div class="form-group"> + <label>Expected Return Date: + <input name="expectedreturn" min="{mindate}" type="date" class="form-control" + id="expected-return" required="required" value="{expected_return_date}" /> + </label> + </div> + </div> + <div class="col-sm-4"> + <div class="form-group"> + <label>Destination: + <input id="loan-destination" required="required" /> + </label> + </div> + </div> + </div> + <div class="row caosdb-form-row"> + <div class="col-sm-12"> + <div class="form-group"> + <label for="loan-comment" style="margin-bottom:0px">Purpose: + <textarea id="loan-comment" class="form-control" rows="4" style="width:100%" + placeholder="Please indicate the purpose of the loan.">{purpose}</textarea> + </label> + </div> + </div> + </div> + <div class="row caosdb-form-row"> + <div class="col-sm-12"> + <div class="form-check"> + <label class="form-check-label">Are you going to completely exhaust the contents of this box? + <input type="checkbox" class="form-check-input" id="exhaust-contents" value="no" /> + </label> + </div> + </div> + </div> + </form> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button> + <button type="submit" class="btn btn-primary" form="borrow-all-form">Submit</button> + </div> + </div> + </div> + + </div> + </div> + </div> +</body> + +</html> \ No newline at end of file diff --git a/loan-custom/caosdb-server/caosdb-webui/src/ext/html/forms/loan-forms/borrow_checkout.html b/loan-custom/caosdb-server/caosdb-webui/src/ext/html/forms/loan-forms/borrow_checkout.html index f183fb0ca89dffddc57bab612d52465eac2896b8..ff419c740cdcd6d4e210b2cb31f77c9577105d46 100644 --- a/loan-custom/caosdb-server/caosdb-webui/src/ext/html/forms/loan-forms/borrow_checkout.html +++ b/loan-custom/caosdb-server/caosdb-webui/src/ext/html/forms/loan-forms/borrow_checkout.html @@ -1,79 +1,95 @@ <!DOCTYPE html> <html> - <body> - <div id="caosdb-form"> - <div class="row" id="checkout-form-{boxid}" style="margin:0px"> - <div class="col-lg-12"> - <h2>Borrow Box</h2> - <form class="caosdb-awi-box-checkout-form" autocomplete="on"> - <div> - <h5>Please enter your full name and your email address. If you are doing this for the first time, a new user record will be created.</h5> - </div> - <div class="row caosdb-form-row"> - <div class="col-sm-4"> - <div class="form-group"> - <label>First Name: - <input name="first-name" type="name" class="form-control" id="first-name" placeholder="Enter name" required="required" value="{first_name}" /> - </label> - </div> - </div> - <div class="col-sm-4"> - <div class="form-group"> - <label>Last Name: - <input name="last-name" type="name" class="form-control" id="last-name" placeholder="Enter name" required="required" value="{last_name}" /> - </label> - </div> - </div> - <div class="col-sm-4"> - <div class="form-group"> - <label>Email: - <input name="email" type="email" class="form-control" id="email" placeholder="Enter email" required="required" value="{email}" /> - </label> - </div> - </div> - </div> - <div class="row caosdb-form-row"> - <div class="col-sm-4"> - <div class="form-group"> - <label>Expected Return Date: - <input name="expectedreturn" min="{mindate}" type="date" class="form-control" id="expected-return" required="required" value="{expected_return_date}" /> - </label> - </div> - </div> - <div class="col-sm-4"> - <div class="form-group"> - <label>Destination: - <input id="loan-destination" required="required"/> - </label> - </div> + +<body> + <div id="caosdb-form"> + <div class="row" id="checkout-form-{boxid}" style="margin:0px"> + <div id="caosdb-f-borrow-all-form-modal" class="modal fade" style="max-width:900px" role="dialog"> + <div class="modal-dialog"> + <div class="modal-content"> + <div class="modal-header"> + <h4 class="modal-title">Borrow all bookmarked items</h4> </div> - </div> - <div class="row caosdb-form-row"> - <div class="col-sm-12"> - <div class="form-group"> - <label for="loan-comment" style="margin-bottom:0px">Purpose: - <textarea id="loan-comment" class="form-control" rows="4" style="width:100%" - placeholder="Please indicate the purpose of the loan.">{purpose}</textarea> - </label> - </div> + <div class="modal-body "> + <form class="caosdb-awi-box-checkout-form" autocomplete="on"> + <div> + Please enter your full name and your email address. If you are doing this for the first time, a + new user record will be created. + </div> + <div class="row caosdb-form-row"> + <div class="col-sm-4"> + <div class="form-group"> + <label>First Name: + <input name="first-name" type="name" class="form-control" id="first-name" + placeholder="Enter name" required="required" value="{first_name}" /> + </label> + </div> + </div> + <div class="col-sm-4"> + <div class="form-group"> + <label>Last Name: + <input name="last-name" type="name" class="form-control" id="last-name" placeholder="Enter name" + required="required" value="{last_name}" /> + </label> + </div> + </div> + <div class="col-sm-4"> + <div class="form-group"> + <label>Email: + <input name="email" type="email" class="form-control" id="email" placeholder="Enter email" + required="required" value="{email}" /> + </label> + </div> + </div> + </div> + <div class="row caosdb-form-row"> + <div class="col-sm-4"> + <div class="form-group"> + <label>Expected Return Date: + <input name="expectedreturn" min="{mindate}" type="date" class="form-control" + id="expected-return" required="required" value="{expected_return_date}" /> + </label> + </div> + </div> + <div class="col-sm-4"> + <div class="form-group"> + <label>Destination: + <input id="loan-destination" required="required" /> + </label> + </div> + </div> + </div> + <div class="row caosdb-form-row"> + <div class="col-sm-12"> + <div class="form-group"> + <label for="loan-comment" style="margin-bottom:0px">Purpose: + <textarea id="loan-comment" class="form-control" rows="4" style="width:100%" + placeholder="Please indicate the purpose of the loan.">{purpose}</textarea> + </label> + </div> + </div> + </div> + <div class="row caosdb-form-row"> + <div class="col-sm-12"> + <div class="form-check"> + <label class="form-check-label">Are you going to completely exhaust the contents of this box? + <input type="checkbox" class="form-check-input" id="exhaust-contents" value="no" /> + </label> + </div> + </div> + </div> + </form> </div> - </div> - <div class="row caosdb-form-row"> - <div class="col-sm-12"> - <div class="form-check"> - <label class="form-check-label">Are you going to completely exhaust the contents of this box? - <input type="checkbox" class="form-check-input" id="exhaust-contents" value="no" /> - </label> - </div> + <div class="modal-footer"> + <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button> + <button type="submit" class="btn btn-secondary" form="borrow-all-form">Submit</button> </div> </div> - <div class="text-right"> - <button type="submit" class="btn btn-secondary">Submit</button> - </div> - </form> - </div> + </div> + </div> </div> - </body> -</html> + </div> +</body> +</html> \ No newline at end of file diff --git a/loan-custom/caosdb-server/caosdb-webui/src/ext/js/box_loan.js b/loan-custom/caosdb-server/caosdb-webui/src/ext/js/box_loan.js index f48b25e347ad05091ec3338f127b45f1fe3a20c0..f91a7f2045ade59678d0fcf35f6cd0617e1e3276 100644 --- a/loan-custom/caosdb-server/caosdb-webui/src/ext/js/box_loan.js +++ b/loan-custom/caosdb-server/caosdb-webui/src/ext/js/box_loan.js @@ -19,6 +19,9 @@ * */ + + + /** * Return the formatted date of today. */ @@ -49,6 +52,8 @@ var box_loan = function(logger, box_loan_config) { const datamodel = box_loan_config.datamodel; + + const _dismiss_button = '<button class="btn btn-secondary box-loan-btn">OK</button>' const _server_did_not_respond = "The server did not respond. Please reload the page."; const _return_box_button = `<a title="Return ${datamodel.box}." class="btn btn-link box-loan-btn">Return ${datamodel.box}</a>`; @@ -143,8 +148,8 @@ var box_loan = function(logger, box_loan_config) { * Query for a Loan entity which references the box and which has no * `returned` property. */ - var get_active_loans = async function(box) { - return await query(`FIND ${datamodel.loan} WITH ${datamodel.box} -> ${box.id} AND WHICH DOES NOT HAVE A ${datamodel.returned}`); + var get_active_loans = async function(boxid) { + return await query(`FIND ${datamodel.loan} WITH ${datamodel.box} -> ${boxid} AND WHICH DOES NOT HAVE A ${datamodel.returned}`); } /** @@ -155,7 +160,7 @@ var box_loan = function(logger, box_loan_config) { loan: undefined, state: undefined, }; - const loan = (await get_active_loans(box))[0]; + const loan = (await get_active_loans(box.id))[0]; if (typeof loan === "undefined") { // no loan found return loan_state; @@ -272,7 +277,10 @@ var box_loan = function(logger, box_loan_config) { } var _add_form = async function(box, form_generator, submit_callback) { - const form = $(await form_generator(box)); + const form = $(await form_generator(getEntityID(box))); + if (typeof form === "undefined") { + return; + } form.insertAfter($(box).find('.caosdb-entity-actions-panel')).hide(); form.submit(() => { submit_callback(form[0], box); @@ -309,7 +317,10 @@ var box_loan = function(logger, box_loan_config) { */ var add_return_button = async function(box) { const but = $(_return_box_button); - + const form = await _add_form(box, generate_return_form, return_function); + if (typeof form === "undefined") { + return; + } get_actions_panel(box).append(but); const config = { @@ -321,7 +332,7 @@ var box_loan = function(logger, box_loan_config) { make_desc: getEntityName, } const dd = form_elements.make_form_field(config); - const form = await _add_form(box, generate_return_form, return_function); + $(dd).find(".col-sm-9").removeClass("col-sm-9"); $(dd).find(".col-sm-3").removeClass("col-sm-3"); $(form).find("#current-location").replaceWith(dd); @@ -420,7 +431,7 @@ var box_loan = function(logger, box_loan_config) { const actions_panel = get_actions_panel(box); $(actions_panel).append(wait).find('btn').hide() - const loan = (await get_active_loans(box))[0]; + const loan = (await get_active_loans(box.id))[0]; const accept_loan_request = { loan: getEntityID(loan), @@ -438,7 +449,7 @@ var box_loan = function(logger, box_loan_config) { const actions_panel = get_actions_panel(box); $(actions_panel).append(wait).find('btn').hide() - const loan = (await get_active_loans(box))[0]; + const loan = (await get_active_loans(box.id))[0]; const manual_return_request = { loan: getEntityID(loan), @@ -488,7 +499,7 @@ var box_loan = function(logger, box_loan_config) { const actions_panel = get_actions_panel(box); $(actions_panel).append(wait).find('btn').hide() - const loan = (await get_active_loans(box))[0]; + const loan = (await get_active_loans(box.id))[0]; const confirm_loan_request = { loan: getEntityID(loan), @@ -545,7 +556,7 @@ var box_loan = function(logger, box_loan_config) { const actions_panel = get_actions_panel(box); $(actions_panel).append(wait).find('btn').hide() - const loan = (await get_active_loans(box))[0]; + const loan = (await get_active_loans(box.id))[0]; const accept_return_request = { loan: getEntityID(loan), @@ -564,7 +575,7 @@ var box_loan = function(logger, box_loan_config) { const actions_panel = get_actions_panel(box); $(actions_panel).append(wait).find('btn').hide() - const loan = (await get_active_loans(box))[0]; + const loan = (await get_active_loans(box.id))[0]; const reject_return_request = { loan: getEntityID(loan), @@ -635,7 +646,7 @@ var box_loan = function(logger, box_loan_config) { const return_request = get_request_data(form); - const loan = (await get_active_loans(box))[0]; + const loan = (await get_active_loans(box.id))[0]; $.extend(return_request, { @@ -649,6 +660,49 @@ var box_loan = function(logger, box_loan_config) { show_result(actions_panel, result, box); } + var add_menu_entry = async function () { + + if ($("#caosdb-f-bookmarks-borrow-all").length > 0) { + return; + } + + const config = { + type: "reference_drop_down", + name: "destination", + label: "", + required: true, + query: `FIND Record ${datamodel.location}`, + make_desc: getEntityName, + } + const dd = form_elements.make_form_field(config); + $(dd).find(".col-sm-9").removeClass("col-sm-9"); + $(dd).find(".col-sm-3").removeClass("col-sm-3"); + var modal = $(await generate_form_borrow_checkout(undefined, "loan-forms/borrow_all_bookmarked")).find(".modal"); + + $(modal).find("#loan-destination").replaceWith(dd); + $(modal).find("label").css("display", "block"); + + $('body').append(modal); + modal.on('show.bs.modal', function() { + modal.find(".modal-footer").show(); + }); + + + modal.find('.btn-primary').on('click', async function() { + var loan_request = get_request_data(modal.find("form")[0]); + // TODO this is a dependency that cannot be expressed by adding the module to the call of this module + // because the ext_bookmarks module is initialized too late + loan_request["box"] = ext_bookmarks.get_bookmarks(); + const result = await run_script("loan_management/request_loan.py", loan_request); + show_result(modal.find(".modal-body"), result, {}); + modal.find(".modal-footer").hide(); + modal.find(".box-loan-btn").attr("data-bs-dismiss", "modal") + }); + + _init_validator(modal[0]); + const borrow_btn = $('<li class="disabled" id="caosdb-f-bookmarks-borrow-all" data-bs-toggle="modal" data-bs-target="#caosdb-f-borrow-all-form-modal" title="Borrow all bookmarked items"> <a class="dropdown-item">Borrow all</a></li>'); + $("#caosdb-f-bookmarks-clear").parent().append(borrow_btn); + } /** * Add buttons for borrowing boxes. @@ -680,7 +734,7 @@ var box_loan = function(logger, box_loan_config) { * selectform can be used to generate the form for multiple boxes. * In case selectform is true, box will be ignored. */ - var generate_form_borrow_checkout = async function(box) { + var generate_form_borrow_checkout = async function(boxid, formhtml) { const email = window.localStorage["borrower_email"]; const firstname = window.localStorage["borrower_first_name"]; const lastname = window.localStorage["borrower_last_name"]; @@ -689,10 +743,10 @@ var box_loan = function(logger, box_loan_config) { if (exp_return < Date.now()) { exp_return = ""; } - - - return getHTMLForm("loan-forms/borrow_checkout", { - boxid: getEntityID(box), + formhtml = formhtml || 'loan-forms/borrow_checkout'; + console.log("formhtml", formhtml); + return getHTMLForm(formhtml, { + boxid: boxid, first_name: firstname, last_name: lastname, email: email, @@ -715,9 +769,21 @@ var box_loan = function(logger, box_loan_config) { * comment */ var generate_return_form = async function(box) { - const loan = (await get_active_loans(box))[0]; - const borrower = (await retrieve(getProperty(loan, "Borrower", case_sensitive = false)))[0]; + const loan = (await get_active_loans(box.id))[0]; + if (typeof loan === "undefined") { + // no loan found + console.log(loan); + console.log(box); + logger.error("No loan found for box", box); + return ; + } + const borrower = (await retrieve(getProperty(loan, "Borrower", case_sensitive = false)))[0]; + if (typeof borrower === "undefined") { + // no loan found + logger.error("No borrower found for loan", loan); + return ; + } var email = getProperty(borrower, datamodel.email, case_sensitive = false); var first_name = getProperty(borrower, datamodel.firstName, case_sensitive = false); @@ -738,6 +804,8 @@ var box_loan = function(logger, box_loan_config) { }); } + + var init = function(boxes) { const init_boxes = boxes || $(".caosdb-entity-panel") .not("[data-version-successor]") @@ -745,8 +813,14 @@ var box_loan = function(logger, box_loan_config) { return $(this).find(".caosdb-parent-name").text().trim() === datamodel.box; }) .toArray(); + add_menu_entry(); add_buttons(init_boxes); } + const is_authorized = function() { + // return true //for testing + return isAuthenticated() //&& (userHasRole("stockmanager") || userHasRole("administration")) + } + return { init: init, diff --git a/loan-custom/caosdb-server/caosdb-webui/src/ext/js/a_box_loan_config.js b/loan-custom/caosdb-server/caosdb-webui/src/ext/js/box_loan_config.js similarity index 100% rename from loan-custom/caosdb-server/caosdb-webui/src/ext/js/a_box_loan_config.js rename to loan-custom/caosdb-server/caosdb-webui/src/ext/js/box_loan_config.js