diff --git a/app/Http/Controllers/FileController.php b/app/Http/Controllers/FileController.php index 9421c0d..c548237 100644 --- a/app/Http/Controllers/FileController.php +++ b/app/Http/Controllers/FileController.php @@ -54,10 +54,10 @@ class FileController extends Controller public function convert(): JsonResponse { $mdFileContent = request()->input('content'); - $tmpFileId = (string) Str::uuid(); + $fileId = request()->input('file_id'); - Storage::disk('local')->put('tmp/' . $tmpFileId . '.md', $mdFileContent); - $tmpMdFilePath = Storage::path('tmp/' . $tmpFileId . '.md'); + Storage::disk('local')->put('tmp/' . $fileId . '.md', $mdFileContent); + $tmpMdFilePath = Storage::path('tmp/' . $fileId . '.md'); $pandoc = new Process([ 'pandoc', @@ -75,10 +75,10 @@ class FileController extends Controller } $odtFileContent = $pandoc->getOutput(); - Storage::disk('local')->put('tmp/' . $tmpFileId . '.odt', $odtFileContent); + Storage::disk('local')->put('tmp/' . $fileId . '.odt', $odtFileContent); return response()->json([ - 'path' => 'tmp/' . $tmpFileId . '.odt' + 'path' => 'tmp/' . $fileId . '.odt' ]); } @@ -91,4 +91,20 @@ class FileController extends Controller { return Storage::download($path); } + + /** + * Delete a file currently in progress + * + * @param string $id + * @return JsonResponse + */ + public function delete(string $id): JsonResponse + { + $success = Storage::delete([ + "tmp/{$id}.md", + "tmp/{$id}.odt", + "contracts/{$id}.md", + ]); + return response()->json(['success' => $success]); + } } diff --git a/public/js/app.js b/public/js/app.js index 7c04006..95f9226 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -3130,12 +3130,17 @@ var AppHeader = /*#__PURE__*/function (_Vue) { }, { key: "onRouteChange", value: function onRouteChange(url) { + var el = document.body; + setTimeout(function () { + el.classList.remove('p-overflow-hidden'); + }, 10); + this.$confirm.require({ message: 'You will lose any progress on the current uploaded document. Are you sure you want to proceed?', header: 'Confirmation', icon: 'pi pi-exclamation-triangle', + blockScroll: false, accept: function accept() { - console.log("ACCEPT!"); window.location.href = url; }, reject: function reject() {// TODO: Show a message to the user that the action was cancelled. @@ -3533,17 +3538,17 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var vue_property_decorator__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! vue-property-decorator */ "./node_modules/vue-property-decorator/lib/vue-property-decorator.js"); function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } +function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } +function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } -function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } +function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } -function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } -function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } -function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } -function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } +function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } @@ -3617,7 +3622,37 @@ var ProcessFile = /*#__PURE__*/function (_Vue) { _createClass(ProcessFile, [{ key: "created", value: function created() { + var _this2 = this; + this.intervalId = setInterval(this.waitForFile, 3000); + window.addEventListener('beforeunload', /*#__PURE__*/function () { + var _ref = _asyncToGenerator( /*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default().mark(function _callee(event) { + var response; + return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default().wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + // Cancel the event as stated by the standard. + event.preventDefault(); + _context.next = 3; + return _this2.$api.discardFile(_this2.file.id); + + case 3: + response = _context.sent; + return _context.abrupt("return", event); + + case 5: + case "end": + return _context.stop(); + } + } + }, _callee); + })); + + return function (_x) { + return _ref.apply(this, arguments); + }; + }()); } /** * MD-to-HTML compiled file content @@ -3716,24 +3751,26 @@ var ProcessFile = /*#__PURE__*/function (_Vue) { }, { key: "uploadFile", value: function () { - var _uploadFile = _asyncToGenerator( /*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default().mark(function _callee(event) { - var _this2 = this; + var _uploadFile = _asyncToGenerator( /*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default().mark(function _callee2(event) { + var _this3 = this; - return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default().wrap(function _callee$(_context) { + return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default().wrap(function _callee2$(_context2) { while (1) { - switch (_context.prev = _context.next) { + switch (_context2.prev = _context2.next) { case 0: this.$confirm.require({ message: 'You will lose any progress on the current uploaded document. Are you sure you want to proceed?', header: 'Confirmation', icon: 'pi pi-exclamation-triangle', accept: function accept() { - _this2.fileContent = _this2.processedFileContent = ''; + _this3.fileContent = _this3.processedFileContent = ''; var file = event.files[0]; - _this2.toggleUploadDialog(false); + _this3.toggleUploadDialog(false); + + _this3.$api.discardFile(_this3.file.id); - _this2.$emit('newFile', file); + _this3.$emit('newFile', file); }, reject: function reject() {// TODO: Show a message to the user that the action was cancelled. } @@ -3741,13 +3778,13 @@ var ProcessFile = /*#__PURE__*/function (_Vue) { case 1: case "end": - return _context.stop(); + return _context2.stop(); } } - }, _callee, this); + }, _callee2, this); })); - function uploadFile(_x) { + function uploadFile(_x2) { return _uploadFile.apply(this, arguments); } @@ -3760,17 +3797,17 @@ var ProcessFile = /*#__PURE__*/function (_Vue) { }, { key: "waitForFile", value: function () { - var _waitForFile = _asyncToGenerator( /*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default().mark(function _callee2() { + var _waitForFile = _asyncToGenerator( /*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default().mark(function _callee3() { var response; - return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default().wrap(function _callee2$(_context2) { + return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default().wrap(function _callee3$(_context3) { while (1) { - switch (_context2.prev = _context2.next) { + switch (_context3.prev = _context3.next) { case 0: - _context2.next = 2; + _context3.next = 2; return this.$api.getFileData(this.file.id); case 2: - response = _context2.sent; + response = _context3.sent; if (response.content !== null) { if (response.ingest_status === 'fail') { @@ -3794,10 +3831,10 @@ var ProcessFile = /*#__PURE__*/function (_Vue) { case 4: case "end": - return _context2.stop(); + return _context3.stop(); } } - }, _callee2, this); + }, _callee3, this); })); function waitForFile() { @@ -3828,13 +3865,13 @@ var ProcessFile = /*#__PURE__*/function (_Vue) { }, { key: "runSearchers", value: function () { - var _runSearchers = _asyncToGenerator( /*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default().mark(function _callee3() { - var _this3 = this; + var _runSearchers = _asyncToGenerator( /*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default().mark(function _callee4() { + var _this4 = this; var searchers, response; - return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default().wrap(function _callee3$(_context3) { + return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default().wrap(function _callee4$(_context4) { while (1) { - switch (_context3.prev = _context3.next) { + switch (_context4.prev = _context4.next) { case 0: this.processing = true; this.processedFileContent = ''; @@ -3842,14 +3879,14 @@ var ProcessFile = /*#__PURE__*/function (_Vue) { Object.values(this.selectedSearchers).forEach(function (searcher) { searchers.push({ 'key': searcher.id, - 'replace_with': _this3.searchersOptions[searcher.id] || '' + 'replace_with': _this4.searchersOptions[searcher.id] || '' }); }); - _context3.next = 6; + _context4.next = 6; return this.$api.filterDocument(this.fileContent, searchers); case 6: - response = _context3.sent; + response = _context4.sent; this.processedFileContent = response.content; this.documentDiffIndexes = response.indexes; this.createDiffPreview(); @@ -3857,10 +3894,10 @@ var ProcessFile = /*#__PURE__*/function (_Vue) { case 11: case "end": - return _context3.stop(); + return _context4.stop(); } } - }, _callee3, this); + }, _callee4, this); })); function runSearchers() { @@ -3903,25 +3940,25 @@ var ProcessFile = /*#__PURE__*/function (_Vue) { }, { key: "downloadOdt", value: function () { - var _downloadOdt = _asyncToGenerator( /*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default().mark(function _callee4() { + var _downloadOdt = _asyncToGenerator( /*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default().mark(function _callee5() { var response; - return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default().wrap(function _callee4$(_context4) { + return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default().wrap(function _callee5$(_context5) { while (1) { - switch (_context4.prev = _context4.next) { + switch (_context5.prev = _context5.next) { case 0: - _context4.next = 2; - return this.$api.convertFile(this.processedFileContent); + _context5.next = 2; + return this.$api.convertFile(this.processedFileContent, this.file.id); case 2: - response = _context4.sent; + response = _context5.sent; window.open("".concat(window.location.origin, "/file/download/") + response.path); case 4: case "end": - return _context4.stop(); + return _context5.stop(); } } - }, _callee4, this); + }, _callee5, this); })); function downloadOdt() { @@ -4032,6 +4069,7 @@ var ApiService = /*#__PURE__*/function () { this.apiRoutes = { file: this.baseUrl + '/api/file', fileDownload: this.baseUrl + '/api/file/convert', + fileDiscard: this.baseUrl + '/api/file/', searchAndDisplace: this.baseUrl + '/search-and-displace' }; } @@ -4182,10 +4220,19 @@ var ApiService = /*#__PURE__*/function () { return filterDocument; }() + /** + * Convert a file from MD to ODT + * + * @param {string} content + * @param {string} fileId + * + * @returns + */ + }, { key: "convertFile", value: function () { - var _convertFile = _asyncToGenerator( /*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default().mark(function _callee4(content) { + var _convertFile = _asyncToGenerator( /*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default().mark(function _callee4(content, fileId) { var response; return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default().wrap(function _callee4$(_context4) { while (1) { @@ -4194,6 +4241,7 @@ var ApiService = /*#__PURE__*/function () { _context4.prev = 0; _context4.next = 3; return axios__WEBPACK_IMPORTED_MODULE_1___default().post(this.apiRoutes.fileDownload, { + 'file_id': fileId, 'content': content }); @@ -4214,12 +4262,54 @@ var ApiService = /*#__PURE__*/function () { }, _callee4, this, [[0, 7]]); })); - function convertFile(_x5) { + function convertFile(_x5, _x6) { return _convertFile.apply(this, arguments); } return convertFile; }() + /** + * Discard a file in progress + * + * @param {string} fileId + */ + + }, { + key: "discardFile", + value: function () { + var _discardFile = _asyncToGenerator( /*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default().mark(function _callee5(fileId) { + var response; + return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default().wrap(function _callee5$(_context5) { + while (1) { + switch (_context5.prev = _context5.next) { + case 0: + _context5.prev = 0; + _context5.next = 3; + return axios__WEBPACK_IMPORTED_MODULE_1___default().delete(this.apiRoutes.fileDiscard + fileId); + + case 3: + response = _context5.sent; + return _context5.abrupt("return", response.data); + + case 7: + _context5.prev = 7; + _context5.t0 = _context5["catch"](0); + throw _context5.t0; + + case 10: + case "end": + return _context5.stop(); + } + } + }, _callee5, this, [[0, 7]]); + })); + + function discardFile(_x7) { + return _discardFile.apply(this, arguments); + } + + return discardFile; + }() }]); return ApiService; @@ -4870,7 +4960,7 @@ __webpack_require__.r(__webpack_exports__); var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0___default()(function(i){return i[1]}); // Module -___CSS_LOADER_EXPORT___.push([module.id, ".file-card {\n flex: 0 1 49%;\n}\n.p-overlaypanel {\n min-width: 450px;\n}\n.p-toolbar-group-right button {\n margin-left: 10px;\n}\n.p-sidebar-content .p-toolbar {\n margin-top: 32px;\n}\n.p-card-header .p-toolbar {\n border: unset;\n border-radius: unset;\n border-bottom: 1px solid #dee2e6;\n padding: 0.5rem;\n}\nbutton.add-searchers {\n height: 100%;\n}\n.p-button.sidebar-toggle-button {\n position: absolute;\n left: calc(-16px - 2.357rem);\n top: 50px;\n border-radius: 3px 0 0 3px;\n}\n.p-col.sidebar-title {\n display: flex;\n align-content: flex-start;\n justify-content: flex-start;\n}\nlabel.switch-label {\n padding-right: 10px;\n}\n.md-viewer {\n text-align: start !important;\n}\n.md-viewer h1, .md-viewer h2, .md-viewer h3, .md-viewer h4, .md-viewer h5 {\n font-size: initial;\n}", ""]); +___CSS_LOADER_EXPORT___.push([module.id, ".file-card {\n flex: 0 1 49%;\n}\n.p-overlaypanel {\n min-width: 450px;\n}\n.p-toolbar-group-right button {\n margin-left: 10px;\n}\n.p-sidebar-content .p-toolbar {\n margin-top: 32px;\n}\n.p-card-header .p-toolbar {\n border: unset;\n border-radius: unset;\n border-bottom: 1px solid #dee2e6;\n padding: 0.5rem;\n}\nbutton.add-searchers {\n height: 100%;\n}\n.p-button.sidebar-toggle-button {\n position: absolute;\n left: calc(-16px - 2.357rem);\n top: 50px;\n border-radius: 3px 0 0 3px;\n}\n.p-col.sidebar-title {\n display: flex;\n align-content: flex-start;\n justify-content: flex-start;\n}\nlabel.switch-label {\n padding-right: 10px;\n}\n.md-viewer {\n text-align: start !important;\n}\n.md-viewer h1, .md-viewer h2, .md-viewer h3, .md-viewer h4, .md-viewer h5 {\n font-size: initial;\n}\n@media only screen and (max-width: 1680px) {\n.p-card-header .p-toolbar {\n flex-flow: column;\n align-items: start;\n}\n}", ""]); // Exports /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); @@ -30568,51 +30658,58 @@ var render = function() { var _vm = this var _h = _vm.$createElement var _c = _vm._self._c || _h - return _c("div", { staticClass: "header" }, [ - _c( - "div", - { staticClass: "left" }, - [ - _c("Button", { - staticClass: "p-button-primary", - attrs: { label: "Search and Displace" }, - on: { - click: function($event) { - return _vm.onRouteChange("/") + return _c( + "div", + { staticClass: "header" }, + [ + _c( + "div", + { staticClass: "left" }, + [ + _c("Button", { + staticClass: "p-button-primary", + attrs: { label: "Search and Displace" }, + on: { + click: function($event) { + return _vm.onRouteChange("/") + } } - } - }) - ], - 1 - ), - _vm._v(" "), - _c( - "div", - { staticClass: "right" }, - [ - _c("Button", { - staticClass: "p-button-primary fc-button", - attrs: { label: "Add regex" }, - on: { - click: function($event) { - return _vm.onRouteChange("/regex/create") + }) + ], + 1 + ), + _vm._v(" "), + _c( + "div", + { staticClass: "right" }, + [ + _c("Button", { + staticClass: "p-button-primary fc-button", + attrs: { label: "Add regex" }, + on: { + click: function($event) { + return _vm.onRouteChange("/regex/create") + } } - } - }), - _vm._v(" "), - _c("Button", { - staticClass: "p-button-primary fc-button", - attrs: { label: "Searchers" }, - on: { - click: function($event) { - return _vm.onRouteChange("/searchers") + }), + _vm._v(" "), + _c("Button", { + staticClass: "p-button-primary fc-button", + attrs: { label: "Searchers" }, + on: { + click: function($event) { + return _vm.onRouteChange("/searchers") + } } - } - }) - ], - 1 - ) - ]) + }) + ], + 1 + ), + _vm._v(" "), + _c("ConfirmDialog", { attrs: { blockScroll: false } }) + ], + 1 + ) } var staticRenderFns = [] render._withStripped = true diff --git a/resources/js/components/ProcessFile/ProcessFile.scss b/resources/js/components/ProcessFile/ProcessFile.scss index 68642b4..fbf1a8d 100644 --- a/resources/js/components/ProcessFile/ProcessFile.scss +++ b/resources/js/components/ProcessFile/ProcessFile.scss @@ -56,3 +56,11 @@ label.switch-label { font-size: initial; } } + + +@media only screen and (max-width: 1680px) { + .p-card-header .p-toolbar { + flex-flow: column; + align-items: start; + } +} \ No newline at end of file diff --git a/resources/js/components/ProcessFile/ProcessFile.ts b/resources/js/components/ProcessFile/ProcessFile.ts index 0348cbb..277d975 100644 --- a/resources/js/components/ProcessFile/ProcessFile.ts +++ b/resources/js/components/ProcessFile/ProcessFile.ts @@ -70,6 +70,15 @@ export default class ProcessFile extends Vue { */ created() { this.intervalId = setInterval(this.waitForFile, 3000); + + window.addEventListener('beforeunload', async (event) => { + // Cancel the event as stated by the standard. + event.preventDefault(); + + const response = await this.$api.discardFile(this.file.id); + + return event; + }); } /** @@ -154,6 +163,7 @@ export default class ProcessFile extends Vue { this.fileContent = this.processedFileContent = ''; let file = event.files[0]; this.toggleUploadDialog(false); + this.$api.discardFile(this.file.id); this.$emit('newFile', file); }, reject: () => { @@ -265,7 +275,7 @@ export default class ProcessFile extends Vue { * Download the document in ODT format */ private async downloadOdt() { - let response = await this.$api.convertFile(this.processedFileContent); + let response = await this.$api.convertFile(this.processedFileContent, this.file.id); window.open(`${window.location.origin}/file/download/` + response.path); } diff --git a/resources/js/components/layout/Header.vue b/resources/js/components/layout/Header.vue index 2a1f28f..a2443ef 100644 --- a/resources/js/components/layout/Header.vue +++ b/resources/js/components/layout/Header.vue @@ -20,7 +20,7 @@ label="Searchers" /> - + @@ -35,12 +35,16 @@ export default class AppHeader extends Vue { } onRouteChange(url: string) { + const el = document.body; + setTimeout(() => { + el.classList.remove('p-overflow-hidden'); + }, 10); this.$confirm.require({ message: 'You will lose any progress on the current uploaded document. Are you sure you want to proceed?', header: 'Confirmation', icon: 'pi pi-exclamation-triangle', + blockScroll: false, accept: () => { - console.log("ACCEPT!"); window.location.href = url; }, reject: () => { diff --git a/resources/js/services/ApiService.ts b/resources/js/services/ApiService.ts index 81dbb70..2429565 100644 --- a/resources/js/services/ApiService.ts +++ b/resources/js/services/ApiService.ts @@ -10,7 +10,8 @@ export default class ApiService { private readonly apiRoutes = { file: this.baseUrl + '/api/file', fileDownload: this.baseUrl + '/api/file/convert', - searchAndDisplace: this.baseUrl + '/search-and-displace' + fileDiscard: this.baseUrl + '/api/file/', + searchAndDisplace: this.baseUrl + '/search-and-displace', }; constructor() { @@ -89,11 +90,20 @@ export default class ApiService { } - public async convertFile(content: string) { + /** + * Convert a file from MD to ODT + * + * @param {string} content + * @param {string} fileId + * + * @returns + */ + public async convertFile(content: string, fileId: string) { try { let response = await axios.post( this.apiRoutes.fileDownload, { + 'file_id': fileId, 'content': content } ); @@ -103,4 +113,21 @@ export default class ApiService { throw err; } } + + /** + * Discard a file in progress + * + * @param {string} fileId + */ + public async discardFile(fileId: string) { + try { + let response = await axios.delete( + this.apiRoutes.fileDiscard + fileId + ); + + return response.data; + } catch (err) { + throw err; + } + } } diff --git a/routes/api.php b/routes/api.php index 717f26a..b85dd27 100644 --- a/routes/api.php +++ b/routes/api.php @@ -30,6 +30,11 @@ Route::name('file.')->prefix('file')->group( FileController::class, 'convert' ])->name('convert'); + + Route::delete('/{id}', [ + FileController::class, + 'delete' + ]); } );