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'
+ ]);
}
);