diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e298d3e..a57c37ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ - csharp: converting function on index page - csharp-mvc: converting function on index page - java: converting function on index page +- java-spring: converting function on index page - editing by default - change reference source - filename in editor page title diff --git a/web/documentserver-example/java-spring/src/main/java/com/onlyoffice/integration/controllers/FileController.java b/web/documentserver-example/java-spring/src/main/java/com/onlyoffice/integration/controllers/FileController.java index 5d37cb5d..6b0d9b7c 100755 --- a/web/documentserver-example/java-spring/src/main/java/com/onlyoffice/integration/controllers/FileController.java +++ b/web/documentserver-example/java-spring/src/main/java/com/onlyoffice/integration/controllers/FileController.java @@ -25,6 +25,7 @@ import com.onlyoffice.integration.documentserver.managers.history.HistoryManager import com.onlyoffice.integration.documentserver.storage.FileStorageMutator; import com.onlyoffice.integration.documentserver.storage.FileStoragePathBuilder; import com.onlyoffice.integration.dto.Converter; +import com.onlyoffice.integration.dto.FormatsList; import com.onlyoffice.integration.dto.Reference; import com.onlyoffice.integration.dto.Rename; import com.onlyoffice.integration.dto.Restore; @@ -133,7 +134,7 @@ public class FileController { storageMutator.createMeta(fullFileName, // create meta information with the user ID and name specified String.valueOf(user.getId()), user.getName()); } - return "{ \"filename\": \"" + fullFileName + "\", \"documentType\": \"" + documentType + "\" }"; + return "{ \"filename\": \"" + fullFileName + "\", \"documentType\": \"" + documentType + "\",\"percent\":100}"; } // download data from the specified file @@ -237,10 +238,11 @@ public class FileController { String filePass = body.getFilePass() != null ? body.getFilePass() : null; // get an auto-conversion extension from the request body or set it to the ooxml extension String conversionExtension = body.getFileExt() != null ? body.getFileExt() : "ooxml"; + Boolean keepOriginal = body.getKeepOriginal() != null ? body.getKeepOriginal() : false; try { // check if the file with such an extension can be converted - if (documentManager.getDefaultConvertExtension(fileName) != null) { + if (documentManager.getDefaultConvertExtension(fileName) != null || body.getFileExt() != null) { ConvertRequest convertRequest = ConvertRequest.builder() .password(filePass) .outputtype(conversionExtension) @@ -257,6 +259,13 @@ public class FileController { String newFileUri = convertResponse.getFileUrl(); String newFileType = convertResponse.getFileType(); + if (!new FormatsList(documentManager.getFormats()).getFormats().stream().anyMatch( + f -> newFileType.equals(f.getName()) && f.getType() != null) + ) { + return "{ \"percent\" : \"100\", \"filename\" : \"" + newFileUri + + "\", \"error\":\"FileTypeIsNotSupported\"}"; + } + /* get a file name of an internal file extension with an index if the file with such a name already exists */ final String oldFileName = fileName; @@ -274,7 +283,9 @@ public class FileController { // remove source file - storageMutator.deleteFile(oldFileName); + if (!keepOriginal) { + storageMutator.deleteFile(oldFileName); + } // create the converted file with input stream storageMutator.createFile(Path.of(storagePathBuilder.getFileLocation(correctedName)), stream); diff --git a/web/documentserver-example/java-spring/src/main/java/com/onlyoffice/integration/dto/Converter.java b/web/documentserver-example/java-spring/src/main/java/com/onlyoffice/integration/dto/Converter.java index 46f331f4..3331559a 100755 --- a/web/documentserver-example/java-spring/src/main/java/com/onlyoffice/integration/dto/Converter.java +++ b/web/documentserver-example/java-spring/src/main/java/com/onlyoffice/integration/dto/Converter.java @@ -27,6 +27,8 @@ import lombok.Setter; @Setter @NoArgsConstructor public class Converter { + @JsonProperty("keepOriginal") + private Boolean keepOriginal; @JsonProperty("filename") private String fileName; @JsonProperty("filePass") diff --git a/web/documentserver-example/java-spring/src/main/resources/static/css/img/convert.svg b/web/documentserver-example/java-spring/src/main/resources/static/css/img/convert.svg new file mode 100644 index 00000000..06d11bc4 --- /dev/null +++ b/web/documentserver-example/java-spring/src/main/resources/static/css/img/convert.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/web/documentserver-example/java-spring/src/main/resources/static/css/media.css b/web/documentserver-example/java-spring/src/main/resources/static/css/media.css index 444fdbe6..9d008679 100644 --- a/web/documentserver-example/java-spring/src/main/resources/static/css/media.css +++ b/web/documentserver-example/java-spring/src/main/resources/static/css/media.css @@ -24,10 +24,14 @@ } .tableHeaderCellViewers { - width: 29%; + width: 18%; text-align: right; } + .tableHeaderCellAction { + width: 23%; + } + .tableHeaderCellDownload { width: 21%; padding-right: 18px; @@ -211,7 +215,7 @@ } .tableHeaderCellFileName { - width: 16%; + width: 9%; } .tableHeaderCellEditors { @@ -220,7 +224,12 @@ .tableHeaderCellViewers { text-align: right; - width: 37%; + width: 9%; + } + + .tableHeaderCellAction{ + width: 11%; + padding-right: 82px; } .tableHeaderCellDownload { @@ -234,19 +243,24 @@ } .tableHeaderCellEditors { - width: 26%; + width: 15%; text-align: left; } .tableHeaderCellFileName { - width: 17%; + width: 28%; } .tableHeaderCellViewers { - width: 27%; + width: 6%; text-align: right; } + .tableHeaderCellAction{ + width: 18%; + padding-right: 54px; + } + .tableHeaderCellDownload { padding-right: 18px; width: 20%; @@ -267,12 +281,17 @@ .tableRow td:first-child { flex-grow: 0; - width: 15%; + width: 25%; + margin-right: auto; } .contentCells-icon { width: 3%; } + + .firstContentCellViewers { + margin-left: 0; + } } @media (max-width: 890px) and (min-width: 769px ) { @@ -280,7 +299,7 @@ width: 100%; } .contentCells-shift { - padding-right: 28px; + padding-right: 27px; } .main-panel { @@ -313,11 +332,16 @@ .tableHeaderCellEditors { text-align: left; - width: 31%; + width: 1%; } .tableHeaderCellViewers { - width: 18%; + width: 19%; + } + + .tableHeaderCellAction { + width: 19%; + padding-right: 45px; } } @@ -416,8 +440,8 @@ .downloadContentCellShift { max-width: 7%; - margin-right: -11px; - margin-left: auto; + margin-right: 24px; + margin-left: 0; } .contentCells-icon { @@ -425,13 +449,13 @@ } .tableRow td:last-child { - width: 12%; - padding-right: 40px; + width: 7%; + padding-right: 0px; border: none; } .contentCells-shift { - padding-right: 35px; + padding-right: 0px; } .downloadContentCellShift:after { @@ -517,6 +541,15 @@ height: 56px; margin-bottom: 24px !important; } + .button.hoar{ + width: 18%; + height: 27px; + margin-bottom: 7px !important; + } + .button.converting{ + width: 126px; + margin-top: 0; + } } @media (max-width: 560px) and (min-width: 510px) { @@ -525,7 +558,7 @@ } .downloadContentCellShift { - padding-right: 45px; + padding-right: 16px; max-width: 4%; } } @@ -545,7 +578,7 @@ .downloadContentCellShift { max-width: 6%; - padding-right: 37px; + padding-right: 6px; } .firstContentCellShift { @@ -571,12 +604,12 @@ .downloadContentCellShift { max-width: 3%; - padding-right: 37px; + padding-right: 0px; padding-left: 0; } .firstContentCellShift { - margin-left: 1px; + margin-left: 2px; flex-basis: 14%; } @@ -606,7 +639,7 @@ .downloadContentCellShift { max-width: 4%; - margin-right: -18px; + margin-right: 18px; margin-left: -1px; } @@ -615,7 +648,7 @@ } .contentCells-icon{ - width: 10%; + width: 12%; } footer table td { margin: 0; diff --git a/web/documentserver-example/java-spring/src/main/resources/static/css/stylesheet.css b/web/documentserver-example/java-spring/src/main/resources/static/css/stylesheet.css index 59e5db69..04b0b0f6 100755 --- a/web/documentserver-example/java-spring/src/main/resources/static/css/stylesheet.css +++ b/web/documentserver-example/java-spring/src/main/resources/static/css/stylesheet.css @@ -238,6 +238,52 @@ label .checkbox { color: #FF6F3D; } +.button.converting { + margin-top: -20px; + padding: 16px 16px; +} + +.button.converting.wide { + padding: 16px 29px; +} + +.button.hoar { + background: #EFEFEF; + border: 1px solid #EFEFEF; + margin-right: 7px; + margin-bottom: 7px; + width: 13%; + padding-left: 0; + padding-right: 0; + font-size: 11px; +} + +.button.hoar.disable { + opacity: 30%; + cursor: default; +} + +.button.hoar:not(.disable):hover { + background: #FF6F3D; + border: 1px solid #FF6F3D; + color: #FFFFFF; +} + +.button.hoar.orange { + background: #FF6F3D; + border: 1px solid #FF6F3D; + color: #FFFFFF; + cursor: default; +} + +.button.hoar.orange.disable { + background: #444444; + border: 1px solid #444444; + color: #FFFFFF; + cursor: default; + opacity: 100%; +} + .button.file-type { font-size: 11px; color: #FFFFFF; @@ -380,6 +426,32 @@ label .checkbox { display: none; } +#convertingProgress { + color: #333333; + display: none; + font-size: 12px; + margin: 30px 35px; +} + +#convertingProgress .convertFileName{ + background-position: left center; + background-repeat: no-repeat; + display: block; + font-size: 14px; + line-height: 160%; + overflow: hidden; + padding-left: 28px; + margin-bottom: 16px; + text-overflow: ellipsis; + white-space: nowrap; +} + +#convertingProgress .describeUpload { + line-height: 150%; + letter-spacing: -0.02em; + padding: 16px 0; +} + .error-message { background: url(img/error.svg) no-repeat scroll 4px 10px; color: #CB0000; @@ -401,6 +473,10 @@ label .checkbox { padding-left: 35px; } +.waiting { + opacity: 30%; +} + .current { background-image: url("img/loader16.gif"); } @@ -413,6 +489,12 @@ label .checkbox { background-image: url("img/notdone.svg"); } +.convertPercent { + color: #FF6F3D; + font-weight: 700; + display: inline; +} + .step-descr { display: block; margin-left: 35px; @@ -420,6 +502,10 @@ label .checkbox { line-height: 188%; } +.step-descr.disable { + display: none; +} + .progress-descr { letter-spacing: -0.02em; line-height: 150%; @@ -524,21 +610,25 @@ footer table tr td:first-child { white-space: nowrap; } +.convertFileName.word, .stored-edit.word, .uploadFileName.word { background-image: url("img/icon_docx.svg"); } +.convertFileName.cell, .stored-edit.cell, .uploadFileName.cell { background-image: url("img/icon_xlsx.svg"); } +.convertFileName.slide, .stored-edit.slide, .uploadFileName.slide { background-image: url("img/icon_pptx.svg"); } +.convertFileName.pdf, .stored-edit.pdf, .uploadFileName.pdf { background-image: url("img/icon_pdf.svg"); @@ -595,6 +685,11 @@ footer table tr td:first-child { visibility: hidden; } +.convertTable { + margin-top: 10px; + margin-left: 35px; +} + .tableRow { background: transparent; -moz-transition: all 0.2s ease-in-out; @@ -641,6 +736,12 @@ footer table tr td:first-child { width: 11%; } +.tableHeaderCellAction{ + width: 13%; + text-align: right; + padding-right: 88px; +} + .tableHeaderCellDownload{ width: 13%; text-align: right; @@ -665,7 +766,7 @@ footer table tr td:first-child { } .contentCells-shift { - padding-right: 44px; + padding-right: 43px; } .contentCells-icon { @@ -729,7 +830,7 @@ footer table tr td:first-child { width: 100%; } -.icon-delete { +.icon-action { cursor: pointer; } @@ -811,6 +912,14 @@ html { position: relative; } +.typeButtonsRow { + width: 100%; + display: flex; + flex-wrap: wrap; + flex-direction: row; + position: relative; +} + .tableRow td:first-child { display: flex; flex-grow: 1; @@ -818,11 +927,11 @@ html { } .tableHeaderCellFileName { - width: 30%; + width: 20%; } .tableHeaderCellEditors { - width: 28%; + width: 20%; } .tableHeaderCellViewers { diff --git a/web/documentserver-example/java-spring/src/main/resources/static/scripts/jscript.js b/web/documentserver-example/java-spring/src/main/resources/static/scripts/jscript.js index d7a47b50..903c21e1 100755 --- a/web/documentserver-example/java-spring/src/main/resources/static/scripts/jscript.js +++ b/web/documentserver-example/java-spring/src/main/resources/static/scripts/jscript.js @@ -284,6 +284,134 @@ if (typeof jQuery !== "undefined") { jq("#embeddedView").attr("src", url); }); + jq(document).on("click", "#beginEditConverted:not(.disable)", function () { + var fileId = encodeURIComponent(jq('#hiddenFileName').attr("data")); + var url = UrlEditor + "?action=edit&fileName=" + fileId; + window.open(url, "_blank"); + jq('#hiddenFileName').val(""); + jq.unblockUI(); + document.location.reload(); + }); + + jq(document).on("click", "#beginViewConverted:not(.disable)", function () { + var fileId = encodeURIComponent(jq('#hiddenFileName').attr("data")); + var url = UrlEditor + "?action=view&fileName=" + fileId; + window.open(url, "_blank"); + jq('#hiddenFileName').val(""); + jq.unblockUI(); + document.location.reload(); + }); + + jq(document).on("click", "#downloadConverted:not(.disable)", function () { + var fileId = jq('#hiddenFileName').attr("data"); + if (jq("#downloadConverted").attr("data") == "fromConverter") window.location.assign(fileId); + else window.open("/download?fileName=" + encodeURIComponent(fileId), "_blank"); + }); + + jq(document).on("click", ".convert-file", function () { + const currentElement = jq(this); + var fileName = currentElement.attr("data"); + var type = currentElement.attr("data-type"); + + jq.blockUI({ + theme: true, + title: "Converting file" + "
", + message: jq("#convertingProgress"), + overlayCSS: { "background-color": "#aaa" }, + themedCSS: { width: "539px", top: "20%", left: "50%", marginLeft: "-269px" } + }); + + jq("#convertFileName").text(decodeURIComponent(fileName)); + jq("#convertFileName").removeClass("word slide cell"); + jq("#convertFileName").addClass(type); + jq("#convTypes").empty(); + + let format = formatManager.findByExtension(fileName.split('.').pop()); + if (format) { + format.convert.forEach(ext => { + jq("#convTypes").append(jq(`${ext}`)); + }); + } + + jq("#hiddenFileName").val(fileName); + jq("#convertStep1").addClass("done"); + jq("#convertStep2").addClass("waiting"); + }); + + jq(document).on("click", "td[name='convertingTypeButton']:not(.disable, .orange)", function () { + const currentElement = jq(this); + let id = currentElement[0].id; + let fileExt = jq(`#${id}`).attr("data"); + jq(`#${id}`).addClass("orange"); + jq("td[name='convertingTypeButton']").addClass("disable"); + jq("#convertStep2").removeClass("waiting").removeClass("done").addClass("current"); + jq("#convertStep2").text('2. File conversion'); + jq("#convert-descr").removeClass("disable"); + jq("#convertPercent").text("0 %"); + jq("#hiddenFileName").attr("placeholder",fileExt); + jq("#downloadConverted").addClass("disable"); + jq("#beginEditConverted").addClass("disable"); + jq("#beginViewConverted").addClass("disable"); + mustReload = true; + + convertFile(); + }); + + function convertFile (filePass) { + let fileName = decodeURIComponent(jq("#hiddenFileName").val()); + let fileExt = jq("#hiddenFileName").attr("placeholder"); + + filePass = filePass ? filePass : null; + if (timer != null) { + clearTimeout(timer); + } + timer = setTimeout(function () { + jq.ajax({ + async: true, + contentType: "application/json", + type: "post", + dataType: "json", + data: JSON.stringify({filename: fileName, filePass: filePass, fileExt: fileExt, keepOriginal: true}), + url: UrlConverter, + complete: function (data) { + try { + var response = jq.parseJSON(data.responseText); + } catch (e) { + response = { error: e }; + } + if (!response.filename && !response.percent && response.error) { + jq("#convertStep2").removeClass("current").addClass("error"); + jq("#convertStep2").text(`2. File conversion to ${fileExt}`); + jq("#convert-error").removeClass("hidden"); + jq("#convert-error").text(`${response.error}`); + jq("td[name='convertingTypeButton']").removeClass("disable orange"); + return; + } + if (response.percent != undefined && response.percent != 100) { + jq("#convertPercent").text(`${response.percent} %`); + convertFile(); + } else { + jq("#convertPercent").text(`${response.percent} %`); + jq("#convertStep2").removeClass("current").addClass("done"); + jq("#convertStep2").text(`2. File conversion to ${fileExt}`); + jq("#downloadConverted").removeClass("disable"); + if (response.error !== "FileTypeIsNotSupported") { + jq("#hiddenFileName").attr("data",response.filename); + jq("#beginEditConverted").removeClass("disable"); + jq("#beginViewConverted").removeClass("disable"); + jq("#downloadConverted").attr("data","fromStorage"); + } else { + let newFilename = fileName.split('.').slice(0,-1).join('.') + jq("#hiddenFileName").attr("data",response.filename.split("&filename=download").join(`&filename=${newFilename}`)); + jq("#downloadConverted").attr("data","fromConverter"); + } + jq("td[name='convertingTypeButton']").removeClass("disable orange"); + } + } + }); + }, 1000); + } + jq(document).on("click", "#cancelEdit, .dialog-close", function () { jq('#hiddenFileName').val(""); jq("#embeddedView").attr("src", ""); diff --git a/web/documentserver-example/java-spring/src/main/resources/templates/index.html b/web/documentserver-example/java-spring/src/main/resources/templates/index.html index 989c66c7..9cd62543 100755 --- a/web/documentserver-example/java-spring/src/main/resources/templates/index.html +++ b/web/documentserver-example/java-spring/src/main/resources/templates/index.html @@ -154,8 +154,7 @@ Filename Editors Viewers - Download - Remove + Action @@ -271,14 +270,18 @@ Open in embedded mode - + + + Convert + + Download - Delete + Delete @@ -346,6 +349,32 @@ +
+
+ + 1. Select a format file to convert + The converting speed depends on file size and additional elements it contains. + + + + +
+
+ 2. File conversion + The file is converted
0 %
+ +
Note the speed of all operations depends on your connection quality and server location.
+ +
+
+
+
DOWNLOAD
+
VIEW
+
EDIT
+
CANCEL
+
+
+