|
1 | 1 | import { setFieldValues } from 'set-field-values'; |
2 | 2 | import AutosaveBase from './autosaveBase'; |
3 | | -import { fromJson } from "util/common"; |
4 | | -import { InfoAlert } from "components/alert/lib/infoAlert"; |
5 | | -import { RenderableButton } from "components/button/lib/RenderableButton"; |
| 3 | +import { fromJson } from 'util/common'; |
| 4 | +import { InfoAlert } from 'components/alert/lib/infoAlert'; |
| 5 | +import { RenderableButton } from 'components/button/lib/RenderableButton'; |
6 | 6 |
|
7 | 7 | /** |
8 | 8 | * A modal that allows the user to restore autosaved values. |
@@ -33,135 +33,135 @@ class AutosaveModal extends AutosaveBase { |
33 | 33 |
|
34 | 34 | let errored = false; |
35 | 35 |
|
36 | | - let $list = $("<ul></ul>"); |
37 | | - const $body = $modal.find(".modal-body"); |
38 | | - $body |
39 | | - .html("<p>Restoring values...</p><p><strong>Please be aware that linked records may take a moment to finish restoring.<strong><p>") |
40 | | - .append($list); |
41 | | - // Convert the fields to promise functions (using the fields) that are run in parallel |
42 | | - // This is only done because various parts of the codebase use the fields in different ways dependent on types (i.e. curval) |
43 | | - await Promise.all($form.find('.linkspace-field').map(async (_, field) => { |
44 | | - const $field = $(field); |
45 | | - // This was originally a bunch of promises, but as the code is async, we can await things here |
46 | | - try { |
47 | | - const json = await this.storage.getItem(this.columnKey($field)) |
48 | | - let values = json ? JSON.parse(json) : undefined; |
49 | | - // If the value can't be parsed, ignore it |
50 | | - if (!values) return; |
51 | | - // If we are in view mode and we need to switch to edit mode, do that |
52 | | - const $editButton = $field.closest('.card--topic').find('.btn-js-edit'); |
53 | | - if ($editButton && $editButton.length) $editButton.trigger('click'); |
54 | | - if (Array.isArray(values)) { |
55 | | - const name = $field.data("name"); |
56 | | - const type = $field.data("column-type"); |
57 | | - if (type === "curval") { |
58 | | - // Curvals need to work event-driven - this is because the modal doesn't always load fully, |
59 | | - // meaning the setvalue doesn't work correctly for dropdowns (mainly) |
60 | | - $field.off("validationFailed"); |
61 | | - $field.off("validationPassed"); |
62 | | - $field.on("validationFailed", (e) => { |
63 | | - // Decrement the curval count |
64 | | - curvalCount--; |
65 | | - const $li = $(`<li class="li-error">Error restoring ${name}, please check these values before submission<ul><li class="warning">${e.message}</li></ul></li>`); |
66 | | - $list.append($li); |
67 | | - // If we've done all fields, turn off the recovery flag |
68 | | - if (!curvalCount) { |
69 | | - // Hide the restore button and show the close button |
70 | | - $modal.find(".modal-footer").find(".btn-cancel").text("Close").show(); |
71 | | - this.storage.removeItem('recovering'); |
| 36 | + let $list = $('<ul></ul>'); |
| 37 | + const $body = $modal.find('.modal-body'); |
| 38 | + $body |
| 39 | + .html('<p>Restoring values...</p><p><strong>Please be aware that linked records may take a moment to finish restoring.<strong><p>') |
| 40 | + .append($list); |
| 41 | + // Convert the fields to promise functions (using the fields) that are run in parallel |
| 42 | + // This is only done because various parts of the codebase use the fields in different ways dependent on types (i.e. curval) |
| 43 | + await Promise.all($form.find('.linkspace-field').map(async (_, field) => { |
| 44 | + const $field = $(field); |
| 45 | + // This was originally a bunch of promises, but as the code is async, we can await things here |
| 46 | + try { |
| 47 | + const json = await this.storage.getItem(this.columnKey($field)); |
| 48 | + let values = json ? JSON.parse(json) : undefined; |
| 49 | + // If the value can't be parsed, ignore it |
| 50 | + if (!values) return; |
| 51 | + // If we are in view mode and we need to switch to edit mode, do that |
| 52 | + const $editButton = $field.closest('.card--topic').find('.btn-js-edit'); |
| 53 | + if ($editButton && $editButton.length) $editButton.trigger('click'); |
| 54 | + if (Array.isArray(values)) { |
| 55 | + const name = $field.data('name'); |
| 56 | + const type = $field.data('column-type'); |
| 57 | + if (type === 'curval') { |
| 58 | + // Curvals need to work event-driven - this is because the modal doesn't always load fully, |
| 59 | + // meaning the setvalue doesn't work correctly for dropdowns (mainly) |
| 60 | + $field.off('validationFailed'); |
| 61 | + $field.off('validationPassed'); |
| 62 | + $field.on('validationFailed', (e) => { |
| 63 | + // Decrement the curval count |
| 64 | + curvalCount--; |
| 65 | + const $li = $(`<li class="li-error">Error restoring ${name}, please check these values before submission<ul><li class="warning">${e.message}</li></ul></li>`); |
| 66 | + $list.append($li); |
| 67 | + // If we've done all fields, turn off the recovery flag |
| 68 | + if (!curvalCount) { |
| 69 | + // Hide the restore button and show the close button |
| 70 | + $modal.find('.modal-footer').find('.btn-cancel').text('Close').show(); |
| 71 | + this.storage.removeItem('recovering'); |
| 72 | + } |
| 73 | + }); |
| 74 | + $field.on('validationPassed', () => { |
| 75 | + // Decrement the curval count |
| 76 | + curvalCount--; |
| 77 | + const $li = $(`<li class="li-success">Restored ${name}</li>`); |
| 78 | + $list.append($li); |
| 79 | + // If we've done all fields, turn off the recovery flag |
| 80 | + if (!curvalCount) { |
| 81 | + // Hide the restore button and show the close button |
| 82 | + $modal.find('.modal-footer').find('.btn-cancel').text('Close').show(); |
| 83 | + this.storage.removeItem('recovering'); |
| 84 | + } |
| 85 | + }); |
| 86 | + } |
| 87 | + setFieldValues($field, values); |
| 88 | + if (type !== 'curval') { |
| 89 | + const $li = $(`<li class="li-success">Restored ${name}</li>`); |
| 90 | + $list.append($li); |
| 91 | + } |
| 92 | + $field.addClass('field--changed'); |
| 93 | + } |
| 94 | + } catch (e) { |
| 95 | + // Catch anything within the mapped promises |
| 96 | + const name = $field.data('name'); |
| 97 | + const $li = $(`<li class="li-error">Failed to restore ${name}<ul><li class="warning">${e.message}</li></ul></li>`); |
| 98 | + console.error(e); |
| 99 | + $list.append($li); |
| 100 | + errored = true; |
72 | 101 | } |
73 | | - }); |
74 | | - $field.on("validationPassed", () => { |
75 | | - // Decrement the curval count |
76 | | - curvalCount--; |
77 | | - const $li = $(`<li class="li-success">Restored ${name}</li>`); |
78 | | - $list.append($li); |
79 | | - // If we've done all fields, turn off the recovery flag |
80 | | - if (!curvalCount) { |
81 | | - // Hide the restore button and show the close button |
82 | | - $modal.find(".modal-footer").find(".btn-cancel").text("Close").show(); |
83 | | - this.storage.removeItem('recovering'); |
| 102 | + })).then(() => { |
| 103 | + // If there are errors, show an appropriate message, otherwise show a success message |
| 104 | + $body.append(`<p>${errored ? 'Values restored with errors.' : 'All values restored.'} Please check that all field values are as expected.</p>`); |
| 105 | + }).catch(e => { |
| 106 | + // If there are any errors that can't be handled in the mapped promises, show a critical error message |
| 107 | + $body.append(`<div class="alert alert-danger"><h4>Critical error restoring values</h4><p>${e}</p></div>`); |
| 108 | + }).finally(() => { |
| 109 | + // Only allow to close once recovery is finished |
| 110 | + if (!curvalCount || errored) { |
| 111 | + // Show the close button |
| 112 | + $modal.find('.modal-footer').find('.btn-cancel').text('Close').show(); |
| 113 | + this.storage.removeItem('recovering'); |
84 | 114 | } |
85 | | - }); |
86 | | - } |
87 | | - setFieldValues($field, values); |
88 | | - if (type !== "curval") { |
89 | | - const $li = $(`<li class="li-success">Restored ${name}</li>`); |
90 | | - $list.append($li); |
91 | | - } |
92 | | - $field.addClass("field--changed"); |
93 | | - } |
94 | | - } catch (e) { |
95 | | - // Catch anything within the mapped promises |
96 | | - const name = $field.data("name"); |
97 | | - const $li = $(`<li class="li-error">Failed to restore ${name}<ul><li class="warning">${e.message}</li></ul></li>`); |
98 | | - console.error(e); |
99 | | - $list.append($li); |
100 | | - errored = true; |
101 | | - } |
102 | | - })).then(() => { |
103 | | - // If there are errors, show an appropriate message, otherwise show a success message |
104 | | - $body.append(`<p>${errored ? "Values restored with errors." : "All values restored."} Please check that all field values are as expected.</p>`); |
105 | | - }).catch(e => { |
106 | | - // If there are any errors that can't be handled in the mapped promises, show a critical error message |
107 | | - $body.append(`<div class="alert alert-danger"><h4>Critical error restoring values</h4><p>${e}</p></div>`); |
108 | | - }).finally(() => { |
109 | | - // Only allow to close once recovery is finished |
110 | | - if (!curvalCount || errored) { |
111 | | - // Show the close button |
112 | | - $modal.find(".modal-footer").find(".btn-cancel").text("Close").show(); |
113 | | - this.storage.removeItem('recovering'); |
114 | | - } |
115 | | - }); |
116 | | - }); |
| 115 | + }); |
| 116 | + }); |
117 | 117 |
|
118 | 118 | // Do we need to run an autorecover? |
119 | 119 | const item = await this.storage.getItem(this.table_key); |
120 | 120 |
|
121 | | - // If there is no item, or there are already alerts, do not show the alert |
122 | | - if ($('.alert-danger').text() || $('.alert-warning').text() || !item) return; |
123 | | - const alert = new InfoAlert("There are unsaved values from the last time you edited this record. Would you like to preview the changes?"); |
124 | | - const alertElement = alert.render(); |
| 121 | + // If there is no item, or there are already alerts, do not show the alert |
| 122 | + if ($('.alert-danger').text() || $('.alert-warning').text() || !item) return; |
| 123 | + const alert = new InfoAlert('There are unsaved values from the last time you edited this record. Would you like to preview the changes?'); |
| 124 | + const alertElement = alert.render(); |
125 | 125 |
|
126 | | - alertElement.classList.add('alert-restore'); |
| 126 | + alertElement.classList.add('alert-restore'); |
127 | 127 |
|
128 | | - const restoreButton = new RenderableButton("Preview", () => { |
129 | | - const $display = $modal.find(".modal-autosave") |
130 | | - const list = $("<li></li>"); |
131 | | - // Get a list of the field values to restore |
132 | | - Promise.all($form.find('.linkspace-field').map(async (_, field)=>{ |
133 | | - const $field = $(field); |
134 | | - const key = this.columnKey($field); |
135 | | - const value = await this.storage.getItem(key) |
136 | | - if(!value) return; |
137 | | - const fieldName = $field.data('name'); |
138 | | - const li = $(`<li>${fieldName}</li>`) |
139 | | - list.append(li); |
140 | | - })).then(()=> { |
141 | | - // Append the list to the modal display |
142 | | - $display.append(list) |
143 | | - }).then(()=>{ |
144 | | - // Show the modal |
145 | | - $modal.modal('show'); |
146 | | - alert.hide(); |
147 | | - }); |
148 | | - }, 'btn-primary', 'btn-inverted', 'btn-alert-restore'); |
149 | | - const restoreButtonElement = restoreButton.render(); |
| 128 | + const restoreButton = new RenderableButton('Preview', () => { |
| 129 | + const $display = $modal.find('.modal-autosave'); |
| 130 | + const list = $('<li></li>'); |
| 131 | + // Get a list of the field values to restore |
| 132 | + Promise.all($form.find('.linkspace-field').map(async (_, field)=>{ |
| 133 | + const $field = $(field); |
| 134 | + const key = this.columnKey($field); |
| 135 | + const value = await this.storage.getItem(key); |
| 136 | + if(!value) return; |
| 137 | + const fieldName = $field.data('name'); |
| 138 | + const li = $(`<li>${fieldName}</li>`); |
| 139 | + list.append(li); |
| 140 | + })).then(()=> { |
| 141 | + // Append the list to the modal display |
| 142 | + $display.append(list); |
| 143 | + }).then(()=>{ |
| 144 | + // Show the modal |
| 145 | + $modal.modal('show'); |
| 146 | + alert.hide(); |
| 147 | + }); |
| 148 | + }, 'btn-primary', 'btn-inverted', 'btn-alert-restore'); |
| 149 | + const restoreButtonElement = restoreButton.render(); |
150 | 150 |
|
151 | | - const cancelButton = new RenderableButton("Cancel", () => { |
152 | | - alert.hide(); |
153 | | - }, 'btn-secondary', 'btn-inverted', 'btn-alert-restore-cancel'); |
154 | | - const cancelButtonElement = cancelButton.render(); |
| 151 | + const cancelButton = new RenderableButton('Cancel', () => { |
| 152 | + alert.hide(); |
| 153 | + }, 'btn-secondary', 'btn-inverted', 'btn-alert-restore-cancel'); |
| 154 | + const cancelButtonElement = cancelButton.render(); |
155 | 155 |
|
156 | | - const buttonDiv = document.createElement('div'); |
157 | | - buttonDiv.className = 'button-group d-flex justify-content-end'; |
158 | | - buttonDiv.appendChild(restoreButtonElement); |
159 | | - buttonDiv.appendChild(cancelButtonElement); |
| 156 | + const buttonDiv = document.createElement('div'); |
| 157 | + buttonDiv.className = 'button-group d-flex justify-content-end'; |
| 158 | + buttonDiv.appendChild(restoreButtonElement); |
| 159 | + buttonDiv.appendChild(cancelButtonElement); |
160 | 160 |
|
161 | | - alertElement.appendChild(buttonDiv); |
| 161 | + alertElement.appendChild(buttonDiv); |
162 | 162 |
|
163 | | - $('.content-block').prepend(alertElement); |
164 | | - } |
| 163 | + $('.content-block').prepend(alertElement); |
| 164 | + } |
165 | 165 | } |
166 | 166 |
|
167 | 167 | export default AutosaveModal; |
0 commit comments