Compare commits

...

8 Commits

8 changed files with 424 additions and 4 deletions

View File

@ -0,0 +1,10 @@
<td class="contentCells contentCells-icon contentCells-shift downloadContentCellShift">
<a href="download?fileName=">
<img class="icon-download" src="assets/images/download.svg" alt="Download" title="Download">
</a>
</td>
<td class="contentCells contentCells-icon contentCells-shift">
<a class="delete-file">
<img class="icon-delete" src="assets/images/delete.svg" alt="Delete" title="Delete">
</a>
</td>

View File

@ -0,0 +1,54 @@
<template id="action-editable">
<td class="contentCells contentCells-icon">
<a href="&action=edit&type=desktop" target="_blank">
<img src="assets/images/desktop.svg" alt="Open in editor for full size screens"
title="Open in editor for full size screens">
</a>
</td>
<td class="contentCells contentCells-icon">
<a href="&action=edit&type=mobile" target="_blank">
<img src="assets/images/mobile.svg" alt="Open in editor for mobile devices"
title="Open in editor for mobile devices">
</a>
</td>
<td class="contentCells contentCells-icon">
<a href="&action=comment&type=desktop" target="_blank">
<img src="assets/images/comment.svg" alt="Open in editor for comment" title="Open in editor for comment">
</a>
</td>
</template>
<template id="type-word">
<td class="contentCells contentCells-icon">
<a href="&action=review&type=desktop" target="_blank">
<img src="assets/images/review.svg" alt="Open in editor for review" title="Open in editor for review">
</a>
</td>
<td class="contentCells contentCells-icon">
<a href="&action=blockcontent&type=desktop" target="_blank">
<img src="assets/images/block-content.svg" alt="Open in editor without content control modification"
title="Open in editor without content control modification">
</a>
</td>
</template>
<template id="type-cell">
<td class="contentCells contentCells-icon">
<a href="&action=filter&type=desktop" target="_blank">
<img src="assets/images/filter.svg" alt="Open in editor without access to change the filter"
title="Open in editor without access to change the filter">
</a>
</td>
</template>
<template id="action-fillable">
<td class="contentCells contentCells-icon firstContentCellShift contentCells-shift">
<a href="&action=fillForms&type=desktop" target="_blank">
<img src="assets/images/fill-forms.svg" alt="Open in editor for filling in forms"
title="Open in editor for filling in forms">
</a>
</td>
<td class="contentCells contentCells-icon">
<a href="&action=fillForms&type=desktop" target="_blank">
<img src="assets/images/mobile-fill-forms.svg" alt="Open in editor for filling in forms for mobile devices"
title="Open in editor for filling in forms for mobile devices">
</a>
</td>
</template>

View File

@ -0,0 +1,281 @@
/**
*
* (c) Copyright Ascensio System SIA 2024
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
class FilesList extends HTMLElement {
constructor() {
super();
this.template = null;
}
async connectedCallback() {
if (!this.template) {
await this.initTemplate();
}
}
async initTemplate() {
let templateHtml = await fetch("assets/components/files/template.html")
.then((stream) => stream.text());
this.template = document.createElement("template");
this.template.innerHTML = templateHtml;
const templateContent = this.template.content.cloneNode(true);
this.style.display = "block";
this.classList.add("stored-list");
this.container = templateContent.querySelector("tbody");
this.appendChild(templateContent);
}
render() {
this.files.forEach(file => {
const row = document.createElement("tr", { is: "files-row" })
row.dataset.file = JSON.stringify(file);
row.dataset.user = this.user;
row.dataset.directUrl = this.directUrl;
this.container.appendChild(row);
});
}
static get observedAttributes() {
return ["data"];
}
attributeChangedCallback(name, oldValue, newValue) {
if (name === "data") {
this.container.innerHTML = "";
this.render();
}
}
get data() {
return JSON.parse(this.getAttribute("data")) || {}
}
get files() {
return this.data.files;
}
get user() {
return this.data.user;
}
get encodedUser() {
return encodeURIComponent(this.user);
}
get directUrl() {
return this.data.directUrl;
}
get encodedDirectUrl() {
return encodeURIComponent(this.directUrl);
}
}
class FilesRow extends HTMLTableRowElement {
constructor() {
super();
this.viewersTemplate = null;
this.editorsTemplate = null;
this.actionsTemplate = null;
}
async connectedCallback() {
if (!this.viewersTemplate || !this.editorsTemplate || !this.actionsTemplate)
await this.initTemplates();
this.render();
}
async initTemplates() {
this.viewersTemplate = await fetch("assets/components/files/viewers.html")
.then((stream) => stream.text());
this.editorsTemplate = await fetch("assets/components/files/editors.html")
.then((stream) => stream.text());
this.actionsTemplate = await fetch("assets/components/files/actions.html")
.then((stream) => stream.text());
}
render() {
this.initSelf();
this.appendChild(this.createNameColumn());
let editors = this.createEditorsColumns();
for (let i = 0; i < editors.length; i++) {
this.appendChild(editors[i]);
}
let viewers = this.createViewersColumns();
for (let i = 0; i < viewers.length; i++) {
this.appendChild(viewers[i]);
}
let actions = this.createActionsColumns();
for (let i = 0; i < actions.length; i++) {
this.appendChild(actions[i]);
}
}
initSelf() {
this.classList.add("tableRow");
this.title = this.name;
}
createNameColumn() {
let column = document.createElement("td", { is: "files-name-column" })
column.dataset.type = this.file.type;
column.dataset.url = this.editorUrl;
column.dataset.name = this.file.title;
return column;
}
createEditorsColumns() {
let template = document.createElement("template");
template.innerHTML = this.editorsTemplate;
let columns = [];
if (this.file.editable) {
let container = template.content.querySelector("#action-editable").content.cloneNode(true);
container.querySelectorAll("td").forEach(td => {
container.querySelectorAll("a").forEach(link => {
link.href = this.editorUrl + link.href;
});
columns.push(td);
})
}
if (this.file.type === "word") {
let container = template.content.querySelector("#type-word").content.cloneNode(true);
container.querySelectorAll("td").forEach(td => {
container.querySelectorAll("a").forEach(link => {
link.href = this.editorUrl + link.href;
});
columns.push(td);
})
}
if (this.file.type === "cell") {
let container = template.content.querySelector("#type-cell").content.cloneNode(true);
container.querySelectorAll("td").forEach(td => {
container.querySelectorAll("a").forEach(link => {
link.href = this.editorUrl + link.href;
});
columns.push(td);
})
}
if (this.file.fillable) {
let container = template.content.querySelector("#action-fillable").content.cloneNode(true);
container.querySelectorAll("td").forEach(td => {
container.querySelectorAll("a").forEach(link => {
link.href = this.editorUrl + link.href;
});
columns.push(td);
})
}
return columns;
}
createViewersColumns() {
let template = document.createElement("template");
template.innerHTML = this.viewersTemplate;
let columns = template.content.querySelectorAll("td");
columns.forEach(column => {
let link = column.querySelector("a");
link.href = this.editorUrl + link.href;
});
return columns;
}
createActionsColumns() {
let template = document.createElement("template");
template.innerHTML = this.actionsTemplate;
let columns = template.content.querySelectorAll("td");
columns.forEach(column => {
let link = column.querySelector("a");
let img = link.querySelector("img");
if (img.title === "Download") link.href += this.encodedTitle;
if (img.title === "Delete") link.setAttribute("data", this.file.title);
});
return columns;
}
get file() {
return JSON.parse(this.dataset.file || {});
}
get name() {
return `${this.file.title} ${this.file.version}`;
}
get encodedTitle() {
return encodeURIComponent(this.file.title);
}
get user() {
return this.dataset.user;
}
get encodedUser() {
return encodeURIComponent(this.user);
}
get directUrl() {
return this.dataset.directUrl;
}
get encodedDirectUrl() {
return encodeURIComponent(this.directUrl);
}
get editorUrl() {
return `editor?fileID=${this.encodedTitle}&user=${this.encodedUser}&directUrl=${this.encodedDirectUrl}`;
}
}
class FilesNameColumn extends HTMLTableCellElement {
connectedCallback() {
this.classList.add("contentCells");
let link = document.createElement("a");
link.classList.add("stored-edit", this.type);
link.href = this.url;
link.target = "_blank";
let span = document.createElement("span");
span.innerHTML = this.name;
link.appendChild(span);
this.appendChild(link);
}
get type() {
return this.dataset.type || "";
}
get url() {
return this.dataset.url || "";
}
get name() {
return this.dataset.name || "";
}
}
customElements.define("files-list", FilesList);
customElements.define("files-row", FilesRow, { extends: "tr" });
customElements.define("files-name-column", FilesNameColumn, { extends: "td" });

View File

@ -0,0 +1,27 @@
<span class="header-list">Your documents</span>
<table class="tableHeader" cellspacing="0" cellpadding="0" width="100%">
<thead>
<tr>
<td class="tableHeaderCell tableHeaderCellFileName">
Filename
</td>
<td class="tableHeaderCell tableHeaderCellEditors contentCells-shift">
Editors
</td>
<td class="tableHeaderCell tableHeaderCellViewers">
Viewers
</td>
<td class="tableHeaderCell tableHeaderCellDownload">
Download
</td>
<td class="tableHeaderCell tableHeaderCellRemove">
Remove
</td>
</tr>
</thead>
</table>
<div class="scroll-table-body">
<table cellspacing="0" cellpadding="0" width="100%">
<tbody><tbody>
</table>
</div>

View File

@ -0,0 +1,17 @@
<td class="contentCells contentCells-icon firstContentCellViewers">
<a href="&action=view&type=desktop" target="_blank">
<img src="assets/images/desktop.svg" alt="Open in viewer for full size screens"
title="Open in viewer for full size screens">
</a>
</td>
<td class="contentCells contentCells-icon">
<a href="&action=edit&type=mobile" target="_blank">
<img src="assets/images/mobile.svg" alt="Open in viewer for mobile devices"
title="Open in viewer for mobile devices">
</a>
</td>
<td class="contentCells contentCells-icon contentCells-shift">
<a href="&action=embedded&type=embedded" target="_blank">
<img src="assets/images/embeded.svg" alt="Open in embedded mode" title="Open in embedded mode">
</a>
</td>

View File

@ -19,8 +19,8 @@
var directUrl;
var formatManager;
window.onload = function () {
fetch('formats')
window.onload = async function () {
await fetch('formats')
.then((response) => response.json())
.then((data) => {
if (data.formats) {
@ -37,6 +37,36 @@ window.onload = function () {
formatManager = new FormatManager(formats);
}
})
let files = await fetchFilesList();
displayFilesList(files);
}
function fetchFilesList() {
return fetch('/files')
.then(response => response.json())
.then(files => {
files.forEach((file) => {
let format = this.formatManager.findByExtension(file.title.split('.').pop());
file.editable = format.isEditable();
file.fillable = format.isFillable();
file.type = format.type;
});
files = Array.isArray(files) && files.length ? files : null;
return files;
});
}
function displayFilesList(files) {
let list = document.querySelector("files-list");
if (files) {
list.setAttribute("data", JSON.stringify({
user,
directUrl,
files
}));
} else {
list.style.display = "none";
}
}
if (typeof jQuery != "undefined") {

View File

@ -326,7 +326,7 @@ function files()
try {
@header("Content-Type", "application/json");
$fileId = $_GET["fileId"];
$fileId = isset($_GET["fileName"]) && !empty($_GET["fileName"]) ? $_GET["fileName"] : null;
$result = getFileInfo($fileId);
return $result;

View File

@ -125,7 +125,7 @@
</span>
{userDescr}
</div>
{storedList}
<files-list></files-list>
</div>
</td>
</tr>
@ -221,6 +221,7 @@
<script type="text/javascript" src="assets/js/jquery.fileupload.js"></script>
<script type="text/javascript" src="assets/js/jquery.dropdownToggle.js"></script>
<script type="text/javascript" src="assets/js/formats.js"></script>
<script type="text/javascript" src="assets/components/files/files.js"></script>
<script type="text/javascript" src="assets/js/jscript.js"></script>
</body>
</html>