Compare commits

..

115 Commits

Author SHA1 Message Date
773b4f804f nodejs: request for a document when opening on client 2025-09-26 11:33:27 +07:00
cfb6dc9b41 fix(nodejs): correct formidable 4 filepath in forcesave 2025-09-22 15:13:07 +03:00
bcd2693a7f fix(nodejs): saving file from buffer forceSave 2025-09-22 15:13:07 +03:00
116d4fa8d8 fix(nodejs): onSaveDocument only when file is opened from buffer 2025-09-22 15:13:06 +03:00
c1059c6e9a fix(nodejs): using formidable to get opened from buffer file data 2025-09-22 15:13:06 +03:00
335946e983 feat(nodejs): saving files opened from buffer with forcesave endpoint 2025-09-22 15:12:55 +03:00
0e72234625 feat(nodejs): opening and saving document from buffer 2025-09-22 14:54:02 +03:00
58331f3dd1 Merge pull request 'fix-vulnerabilities' from fix-vulnerabilities into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/document-server-integration/pulls/78
2025-09-18 13:48:34 +00:00
6b802c6f26 build(ruby): update rails to 7.1.5.2 2025-09-18 17:25:48 +07:00
fe77403dc5 build(ruby): bump rexml from 3.3.9 to 3.4.2 2025-09-18 17:14:08 +07:00
c675df5815 format changelog 2025-09-16 09:14:48 +03:00
27560f6423 Merge pull request 'feature/new-mobile-main-page' from feature/new-mobile-main-page into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/document-server-integration/pulls/77
2025-09-16 06:13:26 +00:00
360ddb8cf6 fix(nodejs): context menu reaction to click 2025-09-12 15:53:35 +07:00
a426825655 feat(php-laravel): mobile index page view 2025-09-12 15:51:25 +07:00
2080e737cc feat(ruby): new mobile index page view 2025-09-12 15:51:25 +07:00
0ff8cc7811 feat(python): new mobile index page view 2025-09-12 15:51:24 +07:00
ea5cdaf13d feat(php): new mobile index page view 2025-09-12 15:51:24 +07:00
6378eab0a8 feat(java-spring): new mobile index page view 2025-09-12 15:51:24 +07:00
6f7935137f feat(java): new mobile index page view 2025-09-12 15:51:24 +07:00
6794460bd4 feat(go): new mobile index page view 2025-09-12 15:51:24 +07:00
bbc48eb30b feat(csharp-mvc): new mobile index page view 2025-09-12 15:51:24 +07:00
348336ba3e feat(csharp): new mobile index page view 2025-09-12 15:51:04 +07:00
8aebdbbb29 feat(nodejs): new mobile index wopi page 2025-09-09 13:02:48 +07:00
106187bc70 feat(nodejs): new mobile index page view 2025-09-09 12:39:00 +07:00
276afb0915 Merge remote-tracking branch 'remotes/origin/feature/update-icons' into develop 2025-09-08 13:41:08 +03:00
53e3e8f198 changelog: update icons 2025-09-02 12:47:14 +07:00
1be72a0375 ruby: update icons 2025-09-02 12:44:02 +07:00
9f62cdd91b python: update icons 2025-09-02 12:44:02 +07:00
2f42f768f0 php-laravel: update icons 2025-09-02 12:44:02 +07:00
8966581561 php: update icons 2025-09-02 12:44:02 +07:00
24f2dc4839 java-spring: update icons 2025-09-02 12:44:01 +07:00
57f2a9e558 java: update icons 2025-09-02 12:44:01 +07:00
594baad685 go: update icons 2025-09-02 12:44:01 +07:00
ac34f63a63 csharp-mvc: update icons 2025-09-02 12:43:56 +07:00
d7621c2289 csharp: update icons 2025-09-02 12:39:13 +07:00
31251fc06b Merge branch 'feature/display-modes-by-actions' into develop 2025-08-15 12:02:29 +03:00
2b162f403a nodejs: update icons 2025-08-14 14:04:57 +03:00
4af1d5c591 php-laravel: 5 editor icons on index page 2025-08-14 17:58:01 +07:00
074db3060a java-spring: 5 editor icons on index page 2025-08-14 17:22:31 +07:00
252753b9d9 ruby: fix index page and styles for display by action 2025-08-14 16:45:49 +07:00
2a27a4029a python: fix index page and styles for display by action 2025-08-14 16:45:49 +07:00
d382788123 php: fix index page and styles for display by action 2025-08-14 16:45:49 +07:00
2aaef3167b java: fix index page and styles for display by action 2025-08-14 16:45:49 +07:00
04079938bc feat(go): display mode buttons by actions 2025-08-14 16:45:49 +07:00
fe4ad09d88 fix(go): correct handling of formats and actions 2025-08-14 16:45:49 +07:00
4124ca10bc csharp-mvc: fix index page and styles for display by action 2025-08-14 16:45:43 +07:00
a947941986 csharp: fix index page and styles for display by action 2025-08-14 16:45:12 +07:00
569e6bc474 nodejs: fix styles for display by action 2025-08-12 14:03:28 +07:00
2eba416116 nodejs: remove not used wopi params 2025-08-06 13:45:29 +03:00
622638c06f nodejs: display comment mode by actions 2025-08-06 13:33:49 +03:00
be31e8bf0c nodejs: change action buttons 2025-08-06 13:09:50 +03:00
3349545979 nodejs: display fill modes by actions 2025-08-06 13:08:41 +03:00
f68177b4fb nodejs: remove filling only for oform (8e60c60e46) 2025-08-06 12:26:05 +03:00
82f0e1318a nodejs: filling on mobile 2025-08-06 12:24:04 +03:00
1d6b4c746c nodejs: support lossy-edit 2025-08-06 11:39:56 +03:00
978d9d405a Merge pull request 'fix(nodejs): replace deprecated fs.F_OK with fs.constants.F_OK' from nodejs-deprecated-F_OK into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/document-server-integration/pulls/76
2025-08-05 13:13:06 +00:00
6e8a9c118a nodejs: wopi UserCanOnlyComment (For Bug 75894) 2025-08-05 16:08:35 +03:00
c138c653f0 Merge pull request '1.15 bugfix' from release-1.15-bugfix into release/1.15.0 (fix 9faf628fba)
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/document-server-integration/pulls/75
2025-08-05 12:08:30 +00:00
e5891b93fc fix(nodejs): replace deprecated fs.F_OK with fs.constants.F_OK 2025-08-05 18:39:18 +07:00
9d3c4a83f4 fix(nodejs): correct token params for wopi user id. Fix Bug 76144 2025-08-05 17:56:05 +07:00
f503a3a094 feat: display mode buttons by actions to changelog 2025-08-05 17:29:50 +07:00
aa2bc06652 feat(ruby): display mode buttons by actions 2025-08-05 17:25:54 +07:00
08dddec917 feat(python): display mode buttons by actions 2025-08-05 16:57:59 +07:00
6974f4205e feat(php): display mode buttons by actions 2025-08-05 16:21:05 +07:00
5ecb980d00 feat(java): display mode buttons by actions 2025-08-05 15:51:06 +07:00
bd405b926d feat(go): display review and filter modes by actions 2025-08-05 15:51:06 +07:00
9645a5b594 feat(csharp-mvc): display review and filter modes by actions 2025-08-05 15:50:58 +07:00
e9f58da424 feat(csharp): display review and filter modes by actions 2025-08-05 15:50:15 +07:00
21804e3236 feat(nodejs): display mode buttons by actions 2025-08-05 15:49:39 +07:00
24d2f595da Merge pull request 'update dependencies with vulnerabilities' from release-1.15-vulnerabilities into release/1.15.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/document-server-integration/pulls/73
2025-08-04 08:32:53 +00:00
c9717c402b build(java): update dependencies with vulnerabilities 2025-08-04 12:28:55 +07:00
2e5cf3580c update formats 2025-08-01 16:07:51 +03:00
ef54a2899b build(go): update go version to 1.23.10 2025-08-01 14:12:19 +07:00
564a077cdb build(go): use jwt/v5 2025-08-01 13:51:24 +07:00
01786b3059 build(php-laravel): update dependencies with vulnerabilities 2025-08-01 12:46:26 +07:00
9947c96266 build(nodejs): update dependencies with vulnerabilities 2025-08-01 11:08:33 +07:00
d2bea39ada build(ruby): update dependencies with vulnerabilities 2025-08-01 11:04:04 +07:00
b269edf116 Merge remote-tracking branch 'remotes/origin/master' into develop 2025-07-31 10:39:48 +03:00
591e38ddac channge release action 2025-07-31 10:38:12 +03:00
34e0c4fc92 fix typo 2025-07-30 16:26:03 +03:00
55fbdf7ba2 1.15.0 2025-07-30 15:55:15 +03:00
f483c9a71d nodejs: fix goback url (Fix Bug 71214) 2025-07-30 14:59:29 +03:00
3a4b300c64 nodejs: interactive-widget=resizes-content for mobile only (b759c8ba53) (For Bug 72802) 2025-07-17 11:36:48 +03:00
4f87ac132c build(java-spring): update com.onlyoffice.docs-integration-sdk to v1.6.0 2025-07-17 11:27:54 +03:00
5e4f1de764 fix typo 2025-07-15 16:09:24 +03:00
10ce2da945 Merge pull request 'feature/new-index-page-text' from feature/new-index-page-text into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/document-server-integration/pulls/72
2025-07-15 13:03:17 +00:00
835679183d Merge pull request 'build(java-spring): update jackson-core to 2.15.0' from dependabot-update-jackson-core into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/document-server-integration/pulls/71
2025-07-15 12:46:19 +00:00
057af70f2e fix typo 2025-07-15 15:45:32 +03:00
f9272eb4e7 Merge pull request 'feature/fillforms-roles' from feature/fillforms-roles into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/document-server-integration/pulls/58
2025-07-15 12:45:06 +00:00
5b8a3519a6 fix changelog 2025-07-15 15:42:10 +03:00
43d2887bd8 Merge remote-tracking branch 'remotes/origin/develop' into feature/fillforms-roles 2025-07-15 15:41:05 +03:00
5a1329f12e nodejs: fix lint (3eae49253f) 2025-07-15 15:40:14 +03:00
8ed8e99eaa feat(ruby): new text on empty main page 2025-07-14 11:37:47 +07:00
9367a682a8 feat(python): new text on empty main page 2025-07-14 11:37:46 +07:00
3345549436 feat(php-laravel): new text on empty main page 2025-07-14 11:37:46 +07:00
e1d5c9a91b feat(php): new text on empty main page 2025-07-14 11:37:46 +07:00
c858c4fdce feat(java-spring): new text on empty main page 2025-07-14 11:37:46 +07:00
fbec8b4d19 feat(java): new text on empty main page 2025-07-14 11:37:32 +07:00
9906960c69 feat(go): new text on empty main page 2025-07-14 11:37:14 +07:00
9c1d998384 feat(csharp-mvc): new text on empty main page 2025-07-14 11:36:53 +07:00
cfe9b8b386 feat(csharp): new text on empty main page 2025-07-14 11:36:28 +07:00
90a0124eb5 feat(nodejs): new text on empty main wopi page 2025-07-14 10:51:32 +07:00
135aa85046 feat(nodejs): new text on empty main page 2025-07-11 17:02:10 +07:00
48eb9ed2e6 build(java-spring): update jackson-core to 2.15.0 2025-07-09 15:32:11 +07:00
79419537ea feat(java-spring): add start filling events and user roles 2025-07-09 14:58:21 +07:00
a11f1a27e2 build(java-spring): update docs-integration-sdk to 1.4.4-SNAPSHOT 2025-07-09 14:57:08 +07:00
8086cb8e33 feat(php-laravel): add start filling events and user roles 2025-07-09 13:10:57 +07:00
728d5720bd feat(ruby): add start filling events and user roles 2025-07-09 13:06:35 +07:00
add2ca8ba0 feat(python): add start filling events and user roles 2025-07-09 13:05:07 +07:00
183f7edd70 feat(php): add start filling events and user roles 2025-07-09 13:04:05 +07:00
a9627feb27 feat(java): add start filling events and user roles 2025-07-09 13:02:51 +07:00
48da865ce3 feat(go): add start filling events and user roles 2025-07-09 13:01:33 +07:00
911f3e9723 feat(csharp-mvc): add start filling events and user roles 2025-07-09 12:59:59 +07:00
a8b23d82d9 feat(csharp): add start filling events and user roles 2025-07-09 12:58:48 +07:00
0df21c3f8e Revert "nodejs: hasOwnProperty() used instead of hasOwn() for NodeJS v.14"
This reverts commit 35798a7916.
2025-07-07 16:04:41 +03:00
286 changed files with 5286 additions and 3849 deletions

View File

@ -21,7 +21,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.21'
go-version: '1.23.10'
- name: Lint Golangci
run: |

View File

@ -3,7 +3,7 @@ name: Release
on:
push:
tags:
- 'v*'
- 'v[0-9]+.[0-9]+.[0-9]+'
permissions:
contents: write

View File

@ -505,7 +505,7 @@ jquery-rails - This gem provides jQuery and the jQuery-ujs driver for your Rail
License: MIT
License File: jquery-rails.license
mimemagic - А library to detect the mime type of a file by extension or by content. (https://github.com/mimemagicrb/mimemagic/blob/master/LICENSE)
mimemagic - A library to detect the mime type of a file by extension or by content. (https://github.com/mimemagicrb/mimemagic/blob/master/LICENSE)
License: MIT
License File: mimemagic.license

View File

@ -1,12 +1,29 @@
# Change Log
- new mobile index page view
- update action icons
- php-laravel: 5 editor icons on index page
- java-spring: 5 editor icons on index page
- ruby: display mode buttons by actions
- python: display mode buttons by actions
- php: display mode buttons by actions
- java: display mode buttons by actions
- go: display mode buttons by actions
- csharp-mvc: display mode buttons by actions
- csharp: display mode buttons by actions
- nodejs: display mode buttons by actions
- nodejs: wopi UserCanOnlyComment
## 1.15.0
- php-laravel: fix custom jwt header
- user role
- start filling
- update demo files
- set users by parts
- open the conversion dialog box with a gray check mark on the type selection step
- preload frame moved from uploading popap
- preload frame moved from uploading popup
- change tab title on rename
- change uploaded file name in popap if converted
- php-laravel: fix custom jwt header
- change uploaded file name in popup if converted
- features tips for anonymous
- view odg, md
- edit xlsb
@ -14,7 +31,7 @@
## 1.14.0
- nodejs: set users by parts
- nodejs: preload frame moved from uploading popap
- nodejs: preload frame moved from uploading popup
- nodejs: view odg, md
- nodejs: edit xlsb
- nodejs: support vsdx in diagram editor

View File

@ -51,8 +51,8 @@
.tableHeader td:last-child, .tableRow td:last-child {
width: 10%;
text-align: center;
padding: 0 !important;
text-align: right;
display: revert;
}
.tableHeader {
@ -81,6 +81,11 @@ menu.links {
.scroll-table-body {
overflow-y: auto;
width: 100%;
}
.scroll-table-body td {
padding: 0 !important;
}
.stored-list {

View File

@ -1,3 +0,0 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M19 6H5L5 15H19V6ZM5 4C3.89543 4 3 4.89543 3 6V15C3 16.1046 3.89543 17 5 17H10V18H6V20H18V18H14V17H19C20.1046 17 21 16.1046 21 15V6C21 4.89543 20.1046 4 19 4H5Z" fill="#444444"/>
</svg>

Before

Width:  |  Height:  |  Size: 331 B

View File

Before

Width:  |  Height:  |  Size: 316 B

After

Width:  |  Height:  |  Size: 316 B

View File

@ -1,5 +0,0 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="4" y="6" width="16" height="13" rx="1" stroke="#444444" stroke-width="2"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.148 8.69651C13.8858 8.43384 13.4601 8.43384 13.1979 8.69651V8.69651C12.9362 8.95858 12.9362 9.38302 13.1979 9.64509L15.3401 11.7908C15.7296 12.1809 15.7299 12.8126 15.3409 13.2031L13.1967 15.3554C12.9357 15.6173 12.9357 16.041 13.1967 16.3029V16.3029C13.4591 16.5663 13.8855 16.5663 14.1478 16.3029L17.3302 13.1086V13.1086C17.668 12.7702 17.668 12.2222 17.3302 11.8838L14.148 8.69651Z" fill="#444444"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.85199 16.3035C10.1142 16.5662 10.5399 16.5662 10.8021 16.3035V16.3035C11.0638 16.0414 11.0638 15.617 10.8021 15.3549L8.65987 13.2092C8.2704 12.8191 8.27006 12.1874 8.65911 11.7969L10.8033 9.64461C11.0643 9.38266 11.0643 8.959 10.8033 8.69706V8.69706C10.5409 8.43371 10.1145 8.43371 9.85218 8.69706L6.66983 11.8914V11.8914C6.33201 12.2298 6.33201 12.7778 6.66983 13.1162L9.85199 16.3035Z" fill="#444444"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 379 B

After

Width:  |  Height:  |  Size: 379 B

View File

@ -1,5 +1,3 @@
<svg width="20" height="14" viewBox="0 0 20 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="20" height="2" rx="1" fill="white"/>
<rect y="6" width="20" height="2" rx="1" fill="white"/>
<rect y="12" width="20" height="2" rx="1" fill="white"/>
</svg>
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M16 5C17.6569 5 19 6.34315 19 8V16C19 17.6569 17.6569 19 16 19H8C6.34315 19 5 17.6569 5 16V8C5 6.34315 6.34315 5 8 5H16ZM11 7V17H16L16.1025 16.9951C16.573 16.9472 16.9472 16.573 16.9951 16.1025L17 16V8C17 7.48232 16.6067 7.05621 16.1025 7.00488L16 7H11Z" fill="#EFEFEF"/>
</svg>

Before

Width:  |  Height:  |  Size: 278 B

After

Width:  |  Height:  |  Size: 383 B

View File

@ -1,3 +0,0 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 3C6.89543 3 6 3.89543 6 5V19C6 20.1046 6.89543 21 8 21H16C17.1046 21 18 20.1046 18 19V5C18 3.89543 17.1046 3 16 3H8ZM16.8462 6H7.15385V18H16.8462V6ZM10.3846 4H13.6154V5H10.3846V4ZM12 20C12.2974 20 12.5385 19.7761 12.5385 19.5C12.5385 19.2239 12.2974 19 12 19C11.7026 19 11.4615 19.2239 11.4615 19.5C11.4615 19.7761 11.7026 20 12 20Z" fill="#444444"/>
</svg>

Before

Width:  |  Height:  |  Size: 506 B

View File

Before

Width:  |  Height:  |  Size: 638 B

After

Width:  |  Height:  |  Size: 638 B

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.33331 10C4.22665 10 3.33331 10.8933 3.33331 12C3.33331 13.1067 4.22665 14 5.33331 14C6.43998 14 7.33331 13.1067 7.33331 12C7.33331 10.8933 6.43998 10 5.33331 10ZM18.6666 10C17.56 10 16.6666 10.8933 16.6666 12C16.6666 13.1067 17.56 14 18.6666 14C19.7733 14 20.6666 13.1067 20.6666 12C20.6666 10.8933 19.7733 10 18.6666 10ZM12 10C10.8933 10 9.99998 10.8933 9.99998 12C9.99998 13.1067 10.8933 14 12 14C13.1066 14 14 13.1067 14 12C14 10.8933 13.1066 10 12 10Z" fill="#808080"/>
</svg>

After

Width:  |  Height:  |  Size: 588 B

View File

Before

Width:  |  Height:  |  Size: 838 B

After

Width:  |  Height:  |  Size: 838 B

View File

@ -34,15 +34,15 @@
}
.tableHeaderCellFileName {
width: 25%;
width: 29%;
}
.tableHeaderCellEditors {
width: 13%;
width: 12%;
}
.tableHeaderCellViewers {
width: 18%;
width: 15%;
text-align: right;
}
@ -84,6 +84,7 @@
}
.tableRow,
.storedHeader,
menu.links {
width: 90%;
}
@ -182,9 +183,14 @@
@media (max-width: 715px) {
.tableRow,
.storedHeader,
menu.links {
width: 45%;
}
.storedHeaderClearAll {
padding-right: 24px;
}
}
@media (max-width: 670px) and (min-width: 620px){
.main-panel{
@ -220,15 +226,15 @@
.tableRow td:first-child {
flex-grow: 0;
width: 15%;
width: 26%;
}
.tableHeaderCellFileName {
width: 9%;
width: 15%;
}
.tableHeaderCellEditors {
width: 13%;
width: 3%;
}
.tableHeaderCellViewers {
@ -253,12 +259,12 @@
}
.tableHeaderCellEditors {
width: 15%;
width: 13%;
text-align: left;
}
.tableHeaderCellFileName {
width: 28%;
width: 29%;
}
.tableHeaderCellViewers {
@ -281,6 +287,7 @@
}
.tableRow,
.storedHeader,
menu.links {
width: 75%;
}
@ -302,6 +309,10 @@
.firstContentCellViewers {
margin-left: 0;
}
.storedHeaderClearAll {
padding-right: 39px;
}
}
@media (max-width: 890px) and (min-width: 769px ) {
@ -317,6 +328,7 @@
}
.tableRow,
.storedHeader,
menu.links {
width: 95%;
}
@ -337,7 +349,7 @@
}
.tableHeaderCellFileName {
width: 20%;
width: 22%;
}
.tableHeaderCellEditors {
@ -346,18 +358,22 @@
}
.tableHeaderCellViewers {
width: 19%;
width: 15%;
}
.tableHeaderCellAction {
width: 19%;
padding-right: 45px;
}
.storedHeaderClearAll {
padding-right: 30px;
}
}
@media (max-width: 890px) {
.tableRow td:first-child {
max-width: 17%;
max-width: 22%;
}
#portal-info {
max-width: 60vw;
@ -436,61 +452,6 @@
padding: 16px 0 6px;
}
.tableRow,
menu.links {
width: 40%;
}
.tableRow td {
border: none;
}
.firstContentCellShift {
border: none;
flex-basis: 10%;
flex-grow: 1;
}
.downloadContentCellShift {
max-width: 7%;
margin-right: 24px;
margin-left: 0;
}
.contentCells-icon {
width: 13%;
}
.tableRow td:last-child {
width: 7%;
padding-right: 0px;
border: none;
}
.contentCells-shift {
padding-right: 0px;
}
.downloadContentCellShift:after {
width: 85%;
}
.firstContentCellViewers {
margin-left: 0;
border-bottom: 1px solid #e5e5e5 !important;
}
.firstContentCellViewers ~ td {
border-bottom: 1px solid #e5e5e5;
}
.tableRow td:first-child{
border: none;
width: 85%;
}
.contentCellsEmpty{
display: none;
width: 1%;
}
/* Mobile Upload*/
.blockUI.blockMsg.blockPage.ui-dialog.ui-widget.ui-corner-all.ui-widget-content.ui-draggable {
width: 344px !important;
@ -565,104 +526,7 @@
}
}
@media (max-width: 560px) and (min-width: 510px) {
.contentCells-icon {
width: 13%;
}
.downloadContentCellShift {
padding-right: 16px;
max-width: 4%;
}
}
@media (max-width: 510px) and (min-width: 470px) {
.tableRow,
menu.links {
width: 35%;
}
.tableRow td:first-child{
width: 83%;
}
.contentCells-icon {
width: 13%;
}
.downloadContentCellShift {
max-width: 6%;
padding-right: 6px;
}
.firstContentCellShift {
flex-basis: 9%;
}
.tableRow td:last-child {
padding-right: 28px;
}
}
@media (max-width: 470px) and (min-width: 420px) {
.tableRow,
menu.links {
width: 30%;
}
.tableRow td:first-child{
width: 85%;
}
.contentCells-icon {
width: 11%;
}
.downloadContentCellShift {
max-width: 3%;
padding-right: 0px;
padding-left: 0;
}
.firstContentCellShift {
margin-left: 2px;
flex-basis: 14%;
}
.tableRow td:last-child {
width: 5%;
padding-right: 63px;
}
.firstContentCellViewers{
padding-right: 2px;
width: 12%;
}
.contentCellsEmpty{
display: none;
}
}
@media (max-width: 420px) {
.tableRow,
menu.links {
width: 25%;
}
.tableRow td:last-child {
width: 6%;
padding-right: 16px;
}
.downloadContentCellShift {
max-width: 4%;
margin-right: 18px;
margin-left: -1px;
}
.firstContentCellShift {
flex-basis: 2%;
}
.contentCells-icon{
width: 12%;
}
footer table td {
margin: 0;
padding-right: 5px;
@ -673,10 +537,6 @@
padding-right: 5px;
margin: 0;
}
.firstContentCellViewers{
padding-right: 2px;
width: 11%;
}
}
@media (max-width: 1160px) {
@ -685,20 +545,15 @@
}
}
@media (min-width: 593px) {
.contentCellsEmpty {
display: none;
}
}
@media (max-width: 769px) and (min-width: 715px){
.tableRow,
.storedHeader,
menu.links {
width: 50%;
}
}
@media (max-width: 510px) {
.tableRow td:first-child{
flex-grow: 0;
.storedHeaderClearAll {
padding-right: 26px;
}
}
@media (max-width: 1100px) and (min-width: 890px){
@ -782,8 +637,8 @@
margin: 0;
position: fixed;
left: 0;
height: calc(100% - 124px);
z-index:99;
height: calc(100% - 44px);
z-index: 101;
}
.left-panel.active {
@ -901,16 +756,37 @@
.tableRow {
border-bottom: 1px solid #e5e5e5;
padding: 16px 0;
padding: 12px 0;
width: 100%;
flex-wrap: nowrap;
}
.tableRow td:first-child {
width: 100%;
}
.tableRow td:last-child {
display: block;
width: 24px;
}
.contentCells {
padding: 0;
font-size: 13px;
}
.contentCells-icon {
width: auto;
display: none;
}
.stored-edit {
height: 12px;
padding: 6px 0 6px 34px;
}
.stored-edit span {
font-size: 14px;
font-size: 13px;
}
.header-list {
@ -918,7 +794,7 @@
}
.firstContentCellViewers {
border-bottom: none !important;
margin: 0;
}
.firstContentCellViewers ~ td {
@ -953,4 +829,19 @@
.user-block-table {
height: auto;
}
.upload-panel {
padding: 12px 0;
}
.user-block-table td select {
height: 48px;
padding-left: 12px;
border-radius: 6px;
border-color: #aaaaaa;
}
.user-block-table tr:last-child {
display: none;
}
}

View File

@ -752,7 +752,6 @@ footer table tr td:first-child {
.contentCells {
display: block;
border-bottom: 1px solid #EFEFEF;
font-family: 'Open Sans', sans-serif;
font-size: 16px;
padding: 4px;
@ -915,18 +914,18 @@ html {
position: relative;
}
.tableRow td:first-child {
display: flex;
flex-grow: 1;
max-width: 25%;
}
.tableRow td:first-child {
display: flex;
flex-grow: 1;
max-width: 29%;
}
.tableHeaderCellFileName {
width: 20%;
width: 24%;
}
.tableHeaderCellEditors {
width: 20%;
width: 24%;
}
.tableHeaderCellViewers {
@ -984,3 +983,103 @@ html {
top: 50%;
transform: translate(-50%, -50%);
}
.tableRow td:last-child {
display: none;
}
#mobileContextMenu {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100vh;
background-color: rgba(51, 51, 51, 0.3);
display: flex;
justify-content: center;
align-items: flex-end;
z-index: 100;
opacity: 0;
visibility: hidden;
transition: opacity 0.3s ease, visibility 0s linear 0.4s;
}
#mobileContextMenu.active {
visibility: visible;
opacity: 1;
transition: opacity 0.3s ease;
}
#mobileContextMenu .context-body {
width: 100%;
max-height: 100%;
transform: translateY(100%);
transition: transform 0.4s cubic-bezier(0.25, 0.8, 0.25, 1);
overflow-y: auto;
overflow-x: hidden;
scrollbar-width: none;
}
#mobileContextMenu.active .context-body {
transform: translateY(0);
}
#mobileContextMenu table {
background-color: white;
width: 100%;
margin-top: 150px;
padding-bottom: 96px;
}
#mobileContextMenu thead {
padding: 12px 16px 0;
height: 48px;
position: sticky;
top: -1px;
display: flex;
align-items: center;
background-color: white;
}
#mobileContextMenu thead:not(.is-pinned)::after {
content: '';
position: absolute;
left: 16px;
right: 16px;
bottom: 0px;
height: 1px;
background: #e2e2e2;
}
#mobileContextMenu thead.is-pinned {
box-shadow: 0px 4px 6px 0px #CCCCCC4D;
transition: all 0.4s ease-out;
}
#mobileContextMenu tbody {
padding: 0 16px;
display: block
}
#mobileContextMenu tr {
display: block;
padding: 12px;
}
.context-section {
padding: 24px 0 6px !important;
font-size: 13px;
font-weight: 600;
color: #808080;
}
#mobileContextMenu a:not(.stored-edit) {
display: flex;
flex-direction: row;
align-items: center;
text-decoration: none;
}
#mobileContextMenu img {
margin-right: 8px;
}

View File

@ -33,7 +33,9 @@ namespace OnlineEditorsExampleMVC.Helpers
"This file isn't marked as favorite",
"Can create files from templates using data from the editor",
"Has an avatar",
"Can submit forms"
"Can submit forms",
"Has no roles",
"Can start filling"
};
static List<string> descr_user_2 = new List<string>()
@ -45,7 +47,9 @@ namespace OnlineEditorsExampleMVC.Helpers
"This file is marked as favorite",
"Can create new files from the editor",
"Has an avatar",
"Can't submit forms"
"Can't submit forms",
"Has role 'Anyone'",
"Can start filling"
};
static List<string> descr_user_3 = new List<string>()
@ -61,7 +65,9 @@ namespace OnlineEditorsExampleMVC.Helpers
"Can create new files from the editor",
"Can't submit forms",
"Can't close history",
"Can't restore the file version"
"Can't restore the file version",
"Has role 'role'",
"Can start filling"
};
static List<string> descr_user_0 = new List<string>()
@ -80,7 +86,9 @@ namespace OnlineEditorsExampleMVC.Helpers
"View file without collaboration",
"Can't refresh outdated file",
"Can't submit forms",
"Tour of tips when opening a document"
"Tour of tips when opening a document",
"Has empty role",
"Can't start filling"
};
private static List<User> users = new List<User>() {
@ -98,7 +106,8 @@ namespace OnlineEditorsExampleMVC.Helpers
true,
true,
new Goback(null, false),
new Close(null, false)
new Close(null, false),
null
),
new User(
"uid-2",
@ -119,7 +128,8 @@ namespace OnlineEditorsExampleMVC.Helpers
false,
true,
new Goback("Go to Documents", null),
new Close(null, true)
new Close(null, true),
new List<string>() { "Anyone" }
),
new User(
"uid-3",
@ -140,7 +150,8 @@ namespace OnlineEditorsExampleMVC.Helpers
false,
false,
null,
new Close(null, true)
new Close(null, true),
new List<string>() { "role" }
),
new User(
"uid-0",
@ -156,7 +167,8 @@ namespace OnlineEditorsExampleMVC.Helpers
false,
false,
null,
null
null,
new List<string>()
)
};
@ -249,8 +261,9 @@ namespace OnlineEditorsExampleMVC.Helpers
public Goback goback;
public Close close;
public List<string> roles;
public User(string id, string name, string email, string group, List<string> reviewGroups, Dictionary<string, object> commentGroups, List<string> userInfoGroups, bool? favorite, List<string> deniedPermissions, List<string> descriptions, bool templates, bool avatar, Goback goback, Close close)
public User(string id, string name, string email, string group, List<string> reviewGroups, Dictionary<string, object> commentGroups, List<string> userInfoGroups, bool? favorite, List<string> deniedPermissions, List<string> descriptions, bool templates, bool avatar, Goback goback, Close close, List<string> roles)
{
this.id = id;
this.name = name;
@ -266,6 +279,7 @@ namespace OnlineEditorsExampleMVC.Helpers
this.avatar = avatar;
this.goback = goback;
this.close = close;
this.roles = roles;
}
}

View File

@ -190,6 +190,7 @@ namespace OnlineEditorsExampleMVC.Models
{
{ "id", !user.id.Equals("uid-0") ? user.id : null },
{ "name", user.name },
{ "roles", user.roles },
{ "group", user.group },
{ "image", user.avatar ? DocManagerHelper.GetServerUrl(false) + "/Content/images/" + user.id + ".png" : null}
}

View File

@ -239,6 +239,13 @@ namespace OnlineEditorsExampleMVC.Models
return cachedFormats;
}
public static List<string> GetFormatActions(string extension)
{
return All()
.Find(format => format.Extension() == extension)
.Actions;
}
private static string GetPath()
{
string path = Path.Combine(GetDirectory(), "onlyoffice-docs-formats.json");

View File

@ -130,18 +130,18 @@
<Content Include="Content\images\close.svg" />
<Content Include="Content\images\comment.svg" />
<Content Include="Content\images\delete.svg" />
<Content Include="Content\images\desktop.svg" />
<Content Include="Content\images\done.svg" />
<Content Include="Content\images\download.svg" />
<Content Include="Content\images\embeded.svg" />
<Content Include="Content\images\edit.svg" />
<Content Include="Content\images\embedview.svg" />
<Content Include="Content\images\error.svg" />
<Content Include="Content\images\file_docx.svg" />
<Content Include="Content\images\file_docxf.svg" />
<Content Include="Content\images\file_pptx.svg" />
<Content Include="Content\images\file_upload.svg" />
<Content Include="Content\images\file_xlsx.svg" />
<Content Include="Content\images\fill-forms.svg" />
<Content Include="Content\images\filter.svg" />
<Content Include="Content\images\formsubmit.svg" />
<Content Include="Content\images\home.svg" />
<Content Include="Content\images\icon_docx.svg" />
<Content Include="Content\images\icon_pptx.svg" />
@ -150,12 +150,14 @@
<Content Include="Content\images\loader16.gif" />
<Content Include="Content\images\logo.svg" />
<Content Include="Content\images\mobile-fill-forms.svg" />
<Content Include="Content\images\mobile.svg" />
<Content Include="Content\images\mobileEdit.svg" />
<Content Include="Content\images\mobileView.svg" />
<Content Include="Content\images\notdone.svg" />
<Content Include="Content\images\review.svg" />
<Content Include="Content\images\slide.ico" />
<Content Include="Content\images\uid-1.png" />
<Content Include="Content\images\uid-2.png" />
<Content Include="Content\images\view.svg" />
<Content Include="Content\images\word.ico" />
<Content Include="Content\jquery-ui.css" />
<Content Include="Content\media.css" />

View File

@ -24,7 +24,7 @@ where the **documentserver** is the name of the server with the ONLYOFFICE Docum
If you want to experiment with the editor configuration, modify the [parameters](https://api.onlyoffice.com/docs/docs-api/usage-api/advanced-parameters/) in the *DocEditor.aspx* file.
## Step 3. Install the prerequisites
Сheck if your system meets the system requirements:
Check if your system meets the system requirements:
* **Microsoft .NET Framework**: version 4.5 (download it from the [official Microsoft website](https://www.microsoft.com/en-US/download/details.aspx?id=30653));
* **Internet Information Services**: version 7 or later.

View File

@ -562,3 +562,75 @@ function toggleUserDescr(event) {
else list.classList.add("active");
}
}
function toggleContextMenu(event) {
let contextMenu = document.querySelector("#mobileContextMenu");
let target = event.currentTarget.parentNode.parentNode.cloneNode(true);
const closeContextMenu = () => {
contextMenu.classList.remove("active");
}
if (contextMenu.classList.contains("active") || !target.classList.contains("tableRow")) {
if (event.target.id == "mobileContextMenuBody") closeContextMenu();
return;
}
let contextBody = document.querySelector("#mobileContextMenuBody");
contextBody.innerHTML = "";
let startY = 0;
let startScroll = 0;
contextBody.addEventListener('touchstart', (e) => {
startY = e.touches[0].clientY;
startScroll = contextBody.scrollTop;
});
contextBody.addEventListener('touchmove', (e) => {
const currentY = e.touches[0].clientY;
const diff = currentY - startY;
if (diff > 10 && (contextBody.scrollTop === 0 || contextBody.scrollTop === startScroll)) {
closeContextMenu();
}
});
let thead = document.createElement("thead");
thead.appendChild(target.children[0]);
const observer = new IntersectionObserver(
([e]) => e.target.classList.toggle("is-pinned", e.intersectionRatio < 1),
{ threshold: [1] }
);
observer.observe(thead);
let tbody = document.createElement("tbody");
for (let td of Array.from(target.children).slice(0, -1)){
if (td.getAttribute("data-section")){
let section = document.createElement("tr");
section.innerText = td.getAttribute("data-section");
section.classList.add("context-section");
tbody.appendChild(section);
}
if (td.children.length == 0) continue;
let action = document.createElement("div");
action.innerText = td.children[0].children[0].getAttribute("title");
td.children[0].appendChild(action);
td.children[0].onclick = () => {
setTimeout(() => window.location.reload(), 0);
}
td.style.display = "block";
td.classList.remove("downloadContentCellShift");
td.classList.remove("firstContentCellViewers");
let tr = document.createElement("tr");
tr.appendChild(td);
tbody.appendChild(tr);
}
let table = document.createElement("table");
table.appendChild(thead);
table.appendChild(tbody);
contextBody.appendChild(table);
contextMenu.classList.add("active");
}

View File

@ -397,6 +397,18 @@
innerAlert("onRequestSendNotify: " + data);
};
var onRequestStartFilling = function(event) {
var data = event.data;
var submit = confirm("Start filling?\n" + JSON.stringify(data));
if (submit) {
docEditor.startFilling(true);
}
};
var onStartFilling = function(event) {
innerAlert("The form is ready to fill out.");
};
config = <%= Model.GetDocConfig(Request, Url) %>;
config.width = "100%";
@ -417,6 +429,8 @@
if (config.editorConfig.user.id) {
config.events['onRequestRefreshFile'] = onRequestRefreshFile;
config.events['onRequestStartFilling'] = onRequestStartFilling;
config.events['onStartFilling'] = onStartFilling;
config.events['onRequestClose'] = onRequestClose;
// the user is trying to show the document version history
config.events['onRequestHistory'] = onRequestHistory;
@ -448,7 +462,7 @@
config.events['onRequestReferenceSource'] = onRequestReferenceSource;
}
var сonnectEditor = function () {
var connectEditor = function () {
docEditor = new DocsAPI.DocEditor("iframeEditor", config);
};
@ -460,9 +474,9 @@
};
if (window.addEventListener) {
window.addEventListener("load", сonnectEditor);
window.addEventListener("load", connectEditor);
} else if (window.attachEvent) {
window.attachEvent("load", сonnectEditor);
window.attachEvent("load", connectEditor);
}
</script>

View File

@ -48,13 +48,13 @@
</div>
<menu class="responsive-nav">
<li>
<a href="#" onclick="toggleSidePanel(event)">
<img src="content/images/mobile-menu.svg" alt="ONLYOFFICE" />
<a href="./">
<img src ="content/images/mobile-logo.svg" alt="ONLYOFFICE" />
</a>
</li>
<li>
<a href="./">
<img src ="content/images/mobile-logo.svg" alt="ONLYOFFICE" />
<a href="#" onclick="toggleSidePanel(event)">
<img src="content/images/mobile-menu.svg" alt="ONLYOFFICE" />
</a>
</li>
</menu>
@ -154,13 +154,18 @@
</menu>
<% var storedFiles = DocManagerHelper.GetStoredFiles(); %>
<div id="portal-info" style="display: <%= storedFiles.Any() ? "none" : "table-cell" %>">
<span class="portal-name">ONLYOFFICE Document Editors Welcome!</span>
<span class="portal-name">Welcome to ONLYOFFICE Docs!</span>
<span class="portal-descr">Get started with a live demo of ONLYOFFICE Docs, a powerful open-source office suite for your browser.</span>
<span class="portal-descr">
Get started with a demo-sample of ONLYOFFICE Document Editors, the first html5-based editors.
<br /> You may upload your own documents for testing using the "<b>Upload file</b>" button and <b>selecting</b> the necessary files on your PC.
You can test editing features in real-time and explore multi-user collaboration:
<ul>
<li>Create a new Document, Spreadsheet, Presentation, or PDF Form or use the sample files</li>
<li>Upload your own files to test using the Upload file button</li>
<li>Select your username and language to simulate different users and environments</li>
<li>Try real-time collaboration by opening the same document using different users in different Web browser sessions</li>
</ul>
</span>
<span class="portal-descr">Please do NOT use this integration example on your own server without proper code modifications, it is intended for testing purposes only. In case you enabled this test example, disable it before going for production.</span>
<span class="portal-descr">You can open the same document using different users in different Web browser sessions, so you can check out multi-user editing functions.</span>
<span class="portal-descr">⚠️ This example is intended for testing purposes only. Do not use it on a production server without proper code modifications. If you have enabled this test demo, please disable it before deploying the editors in production.</span>
<% foreach (User user in Users.getAllUsers())
{ %>
<div class="user-descr" onclick="toggleUserDescr(event)">
@ -199,131 +204,136 @@
<div class="scroll-table-body">
<table cellspacing="0" cellpadding="0" width="100%">
<tbody>
<% foreach (var storedFile in storedFiles)
{
var isEnabledDirectUrl = DocManagerHelper.GetDirectUrl();
var editUrl = "doceditor.aspx?fileID=" + HttpUtility.UrlEncode(storedFile.Name);
var docType = FileUtility.GetFileType(storedFile.Name).ToString().ToLower();
var ext = Path.GetExtension(storedFile.Name).ToLower();
var canEdit = DocManagerHelper.EditedExts.Contains(ext);
var isFillFormDoc = DocManagerHelper.FillFormExts.Contains(ext);
%>
<% foreach (var storedFile in storedFiles) {
var isEnabledDirectUrl = DocManagerHelper.GetDirectUrl();
var editUrl = "doceditor.aspx?fileID=" + HttpUtility.UrlEncode(storedFile.Name);
var docType = FileUtility.GetFileType(storedFile.Name).ToString().ToLower();
var ext = Path.GetExtension(storedFile.Name).ToLower();
var actions = FormatManager.GetFormatActions(ext);
%>
<tr class="tableRow" title="<%= storedFile.Name %> [<%= DocManagerHelper.GetFileVersion(storedFile.Name, HttpContext.Current.Request.UserHostAddress.Replace(':', '_')) %>]">
<td class="contentCells">
<a class="stored-edit <%= docType %>" href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, directUrl = isEnabledDirectUrl }) %>" target="_blank">
<span><%= storedFile.Name %></span>
</a>
</td>
<tr class="tableRow" title="<%= storedFile.Name %> [<%= DocManagerHelper.GetFileVersion(storedFile.Name, HttpContext.Current.Request.UserHostAddress.Replace(':', '_')) %>]">
<td class="contentCells">
<a class="stored-edit <%= docType %>" href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, directUrl = isEnabledDirectUrl }) %>" target="_blank">
<span><%= storedFile.Name %></span>
</a>
<!-- 1-2 -->
<% if (actions.Contains("edit") || actions.Contains("lossy-edit")) { %>
<td class="contentCells contentCells-icon" data-section="EDITOR">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "edit", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/edit.svg" alt="Open for full size screens" title="Open for full size screens"/>
</a>
</td>
<td class="contentCells contentCells-icon">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "mobile", editorsMode = "edit", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/mobileEdit.svg" alt="Open for mobile devices" title="Open for mobile devices"/>
</a>
</td>
<% } else { %>
<td class="contentCells contentCells-icon" data-section="EDITOR"></td>
<td class="contentCells contentCells-icon"></td>
<% } %>
<!-- 3 -->
<% if (actions.Contains("comment")) { %>
<td class="contentCells contentCells-icon">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "comment", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/comment.svg" alt="Open for comment" title="Open for comment"/>
</a>
</td>
<% } else { %>
<td class="contentCells contentCells-icon"></td>
<% } %>
<!-- 4-5 -->
<% if (actions.Contains("fill")) { %>
<td class="contentCells contentCells-icon">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "fillForms", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/formsubmit.svg" alt="Open for filling in forms" title="Open for filling in forms"/>
</a>
</td>
<td class="contentCells contentCells-icon contentCells-shift firstContentCellShift">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "mobile", editorsMode = "fillForms", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/mobile-fill-forms.svg" alt="Open for filling in forms for mobile devices" title="Open for filling in forms for mobile devices"/>
</a>
</td>
<% } else { %>
<!-- 4 -->
<% if (actions.Contains("review")) { %>
<td class="contentCells contentCells-icon">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "review", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/review.svg" alt="Open for review" title="Open for review"/>
</a>
</td>
<% } else if (actions.Contains("customfilter")) { %>
<td class="contentCells contentCells-icon">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "filter", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/filter.svg" alt="Open without access to change the filter" title="Open without access to change the filter" />
</a>
</td>
<% if (canEdit) { %>
<td class="contentCells contentCells-icon">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "edit", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/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="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "mobile", editorsMode = "edit", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/mobile.svg" alt="Open in editor for mobile devices" title="Open in editor for mobile devices"/>
</a>
</td>
<% if (docType != "pdf") { %>
<td class="contentCells contentCells-icon">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "comment", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/comment.svg" alt="Open in editor for comment" title="Open in editor for comment"/>
</a>
</td>
<% } %>
<% if (docType == "word") { %>
<td class="contentCells contentCells-icon">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "review", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/review.svg" alt="Open in editor for review" title="Open in editor for review"/>
</a>
</td>
<% } else if (docType == "cell") { %>
<td class="contentCells contentCells-icon">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "filter", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/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>
<% } %>
<% if (docType == "word") { %>
<td class="contentCells contentCells-icon">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "blockcontent", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/block-content.svg" alt="Open in editor without content control modification" title="Open in editor without content control modification"/>
</a>
</td>
<% } else { %>
<td class="contentCells contentCells-icon"></td>
<% } %>
<% if (docType != "word" && docType != "cell") { %>
<td class="contentCells contentCells-icon "></td>
<% } %>
<% if (isFillFormDoc) { %>
<td class="contentCells contentCells-shift contentCells-icon firstContentCellShift">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "fillForms", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/fill-forms.svg" alt="Open in editor for filling in forms" title="Open in editor for filling in forms"/>
</a>
</td>
<% } else { %>
<td class="contentCells contentCells-shift contentCells-icon firstContentCellShift"></td>
<% } %>
<% } else if (isFillFormDoc) { %>
<td class="contentCells contentCells-icon "></td>
<td class="contentCells contentCells-icon">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "mobile", editorsMode = "fillForms", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/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>
<td class="contentCells contentCells-icon "></td>
<td class="contentCells contentCells-icon "></td>
<td class="contentCells contentCells-icon "></td>
<td class="contentCells contentCells-shift contentCells-icon firstContentCellShift">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "fillForms", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/fill-forms.svg" alt="Open in editor for filling in forms" title="Open in editor for filling in forms"/>
</a>
</td>
<% } else { %>
<td class="contentCells contentCells-shift contentCells-icon contentCellsEmpty" colspan="6"></td>
<% } %>
<td class="contentCells contentCells-icon firstContentCellViewers">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "view", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/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="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "mobile", editorsMode = "view", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/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="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "embedded", editorsMode = "embedded", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/embeded.svg" alt="Open in embedded mode" title="Open in embedded mode"/>
</a>
</td>
<% if (docType != null ) { %>
<td class="contentCells contentCells-icon">
<a class="convert-file" data="<%= storedFile.Name %>" data-type="<%= docType %>">
<img class="icon-action" src="content/images/convert.svg" alt="Convert" title="Convert" /></a>
</td>
<% } else { %>
<td class="contentCells contentCells-icon downloadContentCellShift"></td>
<% } %>
<td class="contentCells contentCells-icon downloadContentCellShift">
<a href="webeditor.ashx?type=download&fileName=<%= HttpUtility.UrlEncode(storedFile.Name) %>">
<img class="icon-download" src="content/images/download.svg" alt="Download" title="Download" />
</a>
</td>
<td class="contentCells contentCells-icon contentCells-shift">
<a class="delete-file" data-filename="<%= storedFile.Name %>">
<img class="icon-action" src="content/images/delete.svg" alt="Delete" title="Delete" />
</a>
</td>
</tr>
<% } %>
</tbody>
</table>
</div>
<% } else {%>
<td class="contentCells contentCells-icon"></td>
<% } %>
<!-- 5 -->
<% if (docType == "word") { %>
<td class="contentCells contentCells-icon contentCells-shift">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "blockcontent", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/block-content.svg" alt="Open without content control modification" title="Open without content control modification"/>
</a>
</td>
<% } else { %>
<td class="contentCells contentCells-icon contentCells-shift"></td>
<% } %>
<% } %>
<td class="contentCells contentCells-icon firstContentCellViewers" data-section="VIEWERS">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "view", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/view.svg" alt="Open for full size screens" title="Open for full size screens"/>
</a>
</td>
<td class="contentCells contentCells-icon">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "mobile", editorsMode = "view", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/mobileView.svg" alt="Open for mobile devices" title="Open for mobile devices"/>
</a>
</td>
<td class="contentCells contentCells-icon contentCells-shift">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "embedded", editorsMode = "embedded", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/embedview.svg" alt="Open in embedded mode" title="Open in embedded mode"/>
</a>
</td>
<% if (docType != null ) { %>
<td class="contentCells contentCells-icon" data-section="ACTIONS">
<a class="convert-file" data="<%= storedFile.Name %>" data-type="<%= docType %>">
<img class="icon-action" src="content/images/convert.svg" alt="Convert" title="Convert" /></a>
</td>
<% } else { %>
<td class="contentCells contentCells-icon downloadContentCellShift" data-section="ACTIONS"></td>
<% } %>
<td class="contentCells contentCells-icon downloadContentCellShift">
<a href="webeditor.ashx?type=download&fileName=<%= HttpUtility.UrlEncode(storedFile.Name) %>">
<img class="icon-download" src="content/images/download.svg" alt="Download" title="Download" />
</a>
</td>
<td class="contentCells contentCells-icon contentCells-shift">
<a class="delete-file" data-filename="<%= storedFile.Name %>">
<img class="icon-action" src="content/images/delete.svg" alt="Delete" title="Delete" />
</a>
</td>
<td class="contentCells contentCells-icon">
<a href="#" onclick="toggleContextMenu(event)">
<img src="content/images/open-context.svg" alt="Open context menu" title="Open context menu" />
</a>
</td>
</tr>
<% } %>
</tbody>
</table>
</div>
</div>
<% } %>
</div>
</td>
@ -429,6 +439,11 @@
</div>
</footer>
<div id="mobileContextMenu" onclick="toggleContextMenu(event)">
<div class="context-body" id="mobileContextMenuBody">
</div>
</div>
<%: Scripts.Render("~/bundles/jquery", "~/bundles/scripts") %>
<script language="javascript" type="text/javascript">

View File

@ -1,7 +1,7 @@
<?xml version="1.0"?>
<appSettings>
<clear />
<add key="version" value="1.14.0"/>
<add key="version" value="1.15.0"/>
<add key="filesize-max" value="52428800"/>
<add key="storage-path" value=""/>

View File

@ -51,8 +51,8 @@
.tableHeader td:last-child, .tableRow td:last-child {
width: 10%;
text-align: center;
padding: 0 !important;
text-align: right;
display: revert;
}
.tableHeader {
@ -81,6 +81,11 @@ menu.links {
.scroll-table-body {
overflow-y: auto;
width: 100%;
}
.scroll-table-body td {
padding: 0 !important;
}
.stored-list {

View File

@ -1,3 +0,0 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M19 6H5L5 15H19V6ZM5 4C3.89543 4 3 4.89543 3 6V15C3 16.1046 3.89543 17 5 17H10V18H6V20H18V18H14V17H19C20.1046 17 21 16.1046 21 15V6C21 4.89543 20.1046 4 19 4H5Z" fill="#444444"/>
</svg>

Before

Width:  |  Height:  |  Size: 331 B

View File

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M5 19H8.11111L8.84845 18.2627L5.73734 15.1516L5 15.8889V19ZM10.2627 16.8484L19 8.11111V6.55556H17.4444V5H15.8889L7.15155 13.7373L10.2627 16.8484Z" fill="#444444"/>
</svg>

After

Width:  |  Height:  |  Size: 316 B

View File

@ -1,5 +0,0 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="4" y="6" width="16" height="13" rx="1" stroke="#444444" stroke-width="2"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.148 8.69651C13.8858 8.43384 13.4601 8.43384 13.1979 8.69651V8.69651C12.9362 8.95858 12.9362 9.38302 13.1979 9.64509L15.3401 11.7908C15.7296 12.1809 15.7299 12.8126 15.3409 13.2031L13.1967 15.3554C12.9357 15.6173 12.9357 16.041 13.1967 16.3029V16.3029C13.4591 16.5663 13.8855 16.5663 14.1478 16.3029L17.3302 13.1086V13.1086C17.668 12.7702 17.668 12.2222 17.3302 11.8838L14.148 8.69651Z" fill="#444444"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.85199 16.3035C10.1142 16.5662 10.5399 16.5662 10.8021 16.3035V16.3035C11.0638 16.0414 11.0638 15.617 10.8021 15.3549L8.65987 13.2092C8.2704 12.8191 8.27006 12.1874 8.65911 11.7969L10.8033 9.64461C11.0643 9.38266 11.0643 8.959 10.8033 8.69706V8.69706C10.5409 8.43371 10.1145 8.43371 9.85218 8.69706L6.66983 11.8914V11.8914C6.33201 12.2298 6.33201 12.7778 6.66983 13.1162L9.85199 16.3035Z" fill="#444444"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,6 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M14.326 18.6739C13.8912 18.2391 13.8912 17.5342 14.326 17.0994L20.0993 11.3261C20.5341 10.8913 21.239 10.8913 21.6738 11.3261C22.1086 11.7609 22.1086 12.4658 21.6738 12.9006L15.9006 18.6739C15.4658 19.1087 14.7608 19.1087 14.326 18.6739Z" fill="#444444"/>
<path d="M14.326 5.3261C14.7608 4.8913 15.4658 4.8913 15.9006 5.3261L21.6738 11.0994C22.1086 11.5342 22.1086 12.2391 21.6738 12.6739C21.239 13.1087 20.5341 13.1087 20.0993 12.6739L14.326 6.90063C13.8912 6.46583 13.8912 5.76089 14.326 5.3261Z" fill="#444444"/>
<path d="M9.67385 5.3261C10.1086 5.76089 10.1086 6.46583 9.67385 6.90063L3.90061 12.6739C3.46582 13.1087 2.76088 13.1087 2.32609 12.6739C1.8913 12.2391 1.8913 11.5342 2.32609 11.0994L8.09933 5.3261C8.53412 4.8913 9.23905 4.8913 9.67385 5.3261Z" fill="#444444"/>
<path d="M9.67385 18.6739C9.23905 19.1087 8.53412 19.1087 8.09933 18.6739L2.32609 12.9006C1.8913 12.4658 1.8913 11.7609 2.32609 11.3261C2.76088 10.8913 3.46582 10.8913 3.90061 11.3261L9.67385 17.0994C10.1086 17.5342 10.1086 18.2391 9.67385 18.6739Z" fill="#444444"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 379 B

After

Width:  |  Height:  |  Size: 379 B

View File

@ -1,5 +1,3 @@
<svg width="20" height="14" viewBox="0 0 20 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="20" height="2" rx="1" fill="white"/>
<rect y="6" width="20" height="2" rx="1" fill="white"/>
<rect y="12" width="20" height="2" rx="1" fill="white"/>
</svg>
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M16 5C17.6569 5 19 6.34315 19 8V16C19 17.6569 17.6569 19 16 19H8C6.34315 19 5 17.6569 5 16V8C5 6.34315 6.34315 5 8 5H16ZM11 7V17H16L16.1025 16.9951C16.573 16.9472 16.9472 16.573 16.9951 16.1025L17 16V8C17 7.48232 16.6067 7.05621 16.1025 7.00488L16 7H11Z" fill="#EFEFEF"/>
</svg>

Before

Width:  |  Height:  |  Size: 278 B

After

Width:  |  Height:  |  Size: 383 B

View File

@ -1,3 +0,0 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 3C6.89543 3 6 3.89543 6 5V19C6 20.1046 6.89543 21 8 21H16C17.1046 21 18 20.1046 18 19V5C18 3.89543 17.1046 3 16 3H8ZM16.8462 6H7.15385V18H16.8462V6ZM10.3846 4H13.6154V5H10.3846V4ZM12 20C12.2974 20 12.5385 19.7761 12.5385 19.5C12.5385 19.2239 12.2974 19 12 19C11.7026 19 11.4615 19.2239 11.4615 19.5C11.4615 19.7761 11.7026 20 12 20Z" fill="#444444"/>
</svg>

Before

Width:  |  Height:  |  Size: 506 B

View File

@ -0,0 +1,4 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 5C4 3.89543 4.89543 3 6 3H15C16.1046 3 17 3.89543 17 5V7H16V6H5V18H16V17H17V19C17 20.1046 16.1046 21 15 21H6C4.89543 21 4 20.1046 4 19V5ZM12 4H9V5H12V4ZM11 19.5C11 19.7761 10.7761 20 10.5 20C10.2239 20 10 19.7761 10 19.5C10 19.2239 10.2239 19 10.5 19C10.7761 19 11 19.2239 11 19.5Z" fill="#444444"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 16H14L14.6464 15.3536L12.6464 13.3536L12 14V16ZM15.3536 14.6464L21 9V8H20V7H19L13.3536 12.6464L15.3536 14.6464Z" fill="#444444"/>
</svg>

After

Width:  |  Height:  |  Size: 638 B

View File

@ -0,0 +1,4 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 5C4 3.89543 4.89543 3 6 3H15C16.1046 3 17 3.89543 17 5V7H16V6H5V18H16V17H17V19C17 20.1046 16.1046 21 15 21H6C4.89543 21 4 20.1046 4 19V5ZM12 4H9V5H12V4ZM11 19.5C11 19.7761 10.7761 20 10.5 20C10.2239 20 10 19.7761 10 19.5C10 19.2239 10.2239 19 10.5 19C10.7761 19 11 19.2239 11 19.5Z" fill="#444444"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M14 8C11.3252 8 8.89946 9.40288 7.10954 11.6815C6.96349 11.8682 6.96349 12.129 7.10954 12.3157C8.89946 14.5971 11.3252 16 14 16C16.6748 16 19.1005 14.5971 20.8905 12.3185C21.0365 12.1318 21.0365 11.871 20.8905 11.6843C19.1005 9.40288 16.6748 8 14 8ZM14.1955 14.9939C12.3863 15.1077 10.8923 13.6166 11.0061 11.8045C11.0995 10.3105 12.3105 9.09949 13.8045 9.00611C15.6137 8.89231 17.1077 10.3834 16.9939 12.1955C16.8976 13.6866 15.6866 14.8976 14.1955 14.9939ZM14.0641 12.998C13.4609 13.0359 12.9625 12.5392 13.0022 11.9359C13.0329 11.4373 13.4375 11.0346 13.9359 11.002C14.5391 10.9641 15.0375 11.4608 14.9978 12.0641C14.9653 12.5645 14.5607 12.9673 14.0641 12.998Z" fill="#444444"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.33331 10C4.22665 10 3.33331 10.8933 3.33331 12C3.33331 13.1067 4.22665 14 5.33331 14C6.43998 14 7.33331 13.1067 7.33331 12C7.33331 10.8933 6.43998 10 5.33331 10ZM18.6666 10C17.56 10 16.6666 10.8933 16.6666 12C16.6666 13.1067 17.56 14 18.6666 14C19.7733 14 20.6666 13.1067 20.6666 12C20.6666 10.8933 19.7733 10 18.6666 10ZM12 10C10.8933 10 9.99998 10.8933 9.99998 12C9.99998 13.1067 10.8933 14 12 14C13.1066 14 14 13.1067 14 12C14 10.8933 13.1066 10 12 10Z" fill="#808080"/>
</svg>

After

Width:  |  Height:  |  Size: 588 B

View File

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 6C8.17879 6 4.71351 8.10432 2.15649 11.5223C1.94784 11.8023 1.94784 12.1935 2.15649 12.4736C4.71351 15.8957 8.17879 18 12 18C15.8212 18 19.2865 15.8957 21.8435 12.4777C22.0522 12.1977 22.0522 11.8065 21.8435 11.5264C19.2865 8.10432 15.8212 6 12 6ZM12.2607 15.9919C9.84844 16.1436 7.8564 14.1554 8.00813 11.7393C8.13264 9.74729 9.74728 8.13265 11.7393 8.00815C14.1516 7.85641 16.1436 9.84456 15.9919 12.2607C15.8635 14.2488 14.2488 15.8635 12.2607 15.9919ZM12.1282 13.9959C10.9219 14.0718 9.92498 13.0783 10.0044 11.8718C10.0658 10.8747 10.8749 10.0691 11.8718 10.0041C13.0781 9.92821 14.075 10.9217 13.9956 12.1282C13.9305 13.1289 13.1215 13.9345 12.1282 13.9959Z" fill="#444444"/>
</svg>

After

Width:  |  Height:  |  Size: 838 B

View File

@ -34,15 +34,15 @@
}
.tableHeaderCellFileName {
width: 25%;
width: 29%;
}
.tableHeaderCellEditors {
width: 13%;
width: 12%;
}
.tableHeaderCellViewers {
width: 18%;
width: 15%;
text-align: right;
}
@ -84,6 +84,7 @@
}
.tableRow,
.storedHeader,
menu.links {
width: 90%;
}
@ -182,9 +183,14 @@
@media (max-width: 715px) {
.tableRow,
.storedHeader,
menu.links {
width: 45%;
}
.storedHeaderClearAll {
padding-right: 24px;
}
}
@media (max-width: 670px) and (min-width: 620px){
.main-panel{
@ -220,15 +226,15 @@
.tableRow td:first-child {
flex-grow: 0;
width: 15%;
width: 26%;
}
.tableHeaderCellFileName {
width: 9%;
width: 15%;
}
.tableHeaderCellEditors {
width: 13%;
width: 3%;
}
.tableHeaderCellViewers {
@ -253,12 +259,12 @@
}
.tableHeaderCellEditors {
width: 15%;
width: 13%;
text-align: left;
}
.tableHeaderCellFileName {
width: 28%;
width: 29%;
}
.tableHeaderCellViewers {
@ -281,6 +287,7 @@
}
.tableRow,
.storedHeader,
menu.links {
width: 75%;
}
@ -302,6 +309,10 @@
.firstContentCellViewers {
margin-left: 0;
}
.storedHeaderClearAll {
padding-right: 39px;
}
}
@media (max-width: 890px) and (min-width: 769px ) {
@ -317,6 +328,7 @@
}
.tableRow,
.storedHeader,
menu.links {
width: 95%;
}
@ -337,7 +349,7 @@
}
.tableHeaderCellFileName {
width: 20%;
width: 22%;
}
.tableHeaderCellEditors {
@ -346,18 +358,22 @@
}
.tableHeaderCellViewers {
width: 19%;
width: 15%;
}
.tableHeaderCellAction {
width: 19%;
padding-right: 45px;
}
.storedHeaderClearAll {
padding-right: 30px;
}
}
@media (max-width: 890px) {
.tableRow td:first-child {
max-width: 17%;
max-width: 22%;
}
#portal-info {
max-width: 60vw;
@ -436,61 +452,6 @@
padding: 16px 0 6px;
}
.tableRow,
menu.links {
width: 40%;
}
.tableRow td {
border: none;
}
.firstContentCellShift {
border: none;
flex-basis: 10%;
flex-grow: 1;
}
.downloadContentCellShift {
max-width: 7%;
margin-right: 24px;
margin-left: 0;
}
.contentCells-icon {
width: 13%;
}
.tableRow td:last-child {
width: 7%;
padding-right: 0px;
border: none;
}
.contentCells-shift {
padding-right: 0px;
}
.downloadContentCellShift:after {
width: 85%;
}
.firstContentCellViewers {
margin-left: 0;
border-bottom: 1px solid #e5e5e5 !important;
}
.firstContentCellViewers ~ td {
border-bottom: 1px solid #e5e5e5;
}
.tableRow td:first-child{
border: none;
width: 85%;
}
.contentCellsEmpty{
display: none;
width: 1%;
}
/* Mobile Upload*/
.blockUI.blockMsg.blockPage.ui-dialog.ui-widget.ui-corner-all.ui-widget-content.ui-draggable {
width: 344px !important;
@ -565,104 +526,7 @@
}
}
@media (max-width: 560px) and (min-width: 510px) {
.contentCells-icon {
width: 13%;
}
.downloadContentCellShift {
padding-right: 16px;
max-width: 4%;
}
}
@media (max-width: 510px) and (min-width: 470px) {
.tableRow,
menu.links {
width: 35%;
}
.tableRow td:first-child{
width: 83%;
}
.contentCells-icon {
width: 13%;
}
.downloadContentCellShift {
max-width: 6%;
padding-right: 6px;
}
.firstContentCellShift {
flex-basis: 9%;
}
.tableRow td:last-child {
padding-right: 28px;
}
}
@media (max-width: 470px) and (min-width: 420px) {
.tableRow,
menu.links {
width: 30%;
}
.tableRow td:first-child{
width: 85%;
}
.contentCells-icon {
width: 11%;
}
.downloadContentCellShift {
max-width: 3%;
padding-right: 0px;
padding-left: 0;
}
.firstContentCellShift {
margin-left: 2px;
flex-basis: 14%;
}
.tableRow td:last-child {
width: 5%;
padding-right: 63px;
}
.firstContentCellViewers{
padding-right: 2px;
width: 12%;
}
.contentCellsEmpty{
display: none;
}
}
@media (max-width: 420px) {
.tableRow,
menu.links {
width: 25%;
}
.tableRow td:last-child {
width: 6%;
padding-right: 16px;
}
.downloadContentCellShift {
max-width: 4%;
margin-right: 18px;
margin-left: -1px;
}
.firstContentCellShift {
flex-basis: 2%;
}
.contentCells-icon{
width: 12%;
}
footer table td {
margin: 0;
padding-right: 5px;
@ -673,10 +537,6 @@
padding-right: 5px;
margin: 0;
}
.firstContentCellViewers{
padding-right: 2px;
width: 11%;
}
}
@media (max-width: 1160px) {
@ -685,20 +545,15 @@
}
}
@media (min-width: 593px) {
.contentCellsEmpty {
display: none;
}
}
@media (max-width: 769px) and (min-width: 715px){
.tableRow,
.storedHeader,
menu.links {
width: 50%;
}
}
@media (max-width: 510px) {
.tableRow td:first-child{
flex-grow: 0;
.storedHeaderClearAll {
padding-right: 26px;
}
}
@media (max-width: 1100px) and (min-width: 890px){
@ -782,8 +637,8 @@
margin: 0;
position: fixed;
left: 0;
height: calc(100% - 124px);
z-index:99;
height: calc(100% - 44px);
z-index: 101;
}
.left-panel.active {
@ -901,16 +756,37 @@
.tableRow {
border-bottom: 1px solid #e5e5e5;
padding: 16px 0;
padding: 12px 0;
width: 100%;
flex-wrap: nowrap;
}
.tableRow td:first-child {
width: 100%;
}
.tableRow td:last-child {
display: block;
width: 24px;
}
.contentCells {
padding: 0;
font-size: 13px;
}
.contentCells-icon {
width: auto;
display: none;
}
.stored-edit {
height: 12px;
padding: 6px 0 6px 34px;
}
.stored-edit span {
font-size: 14px;
font-size: 13px;
}
.header-list {
@ -918,7 +794,7 @@
}
.firstContentCellViewers {
border-bottom: none !important;
margin: 0;
}
.firstContentCellViewers ~ td {
@ -953,4 +829,19 @@
.user-block-table {
height: auto;
}
.upload-panel {
padding: 12px 0;
}
.user-block-table td select {
height: 48px;
padding-left: 12px;
border-radius: 6px;
border-color: #aaaaaa;
}
.user-block-table tr:last-child {
display: none;
}
}

View File

@ -756,7 +756,6 @@ footer a:hover {
.contentCells {
display: block;
border-bottom: 1px solid #EFEFEF;
font-family: 'Open Sans', sans-serif;
font-size: 16px;
padding: 4px;
@ -919,18 +918,18 @@ html {
position: relative;
}
.tableRow td:first-child {
display: flex;
flex-grow: 1;
max-width: 25%;
}
.tableRow td:first-child {
display: flex;
flex-grow: 1;
max-width: 29%;
}
.tableHeaderCellFileName {
width: 20%;
width: 24%;
}
.tableHeaderCellEditors {
width: 20%;
width: 17%;
}
.tableHeaderCellViewers {
@ -988,3 +987,103 @@ html {
top: 50%;
transform: translate(-50%, -50%);
}
.tableRow td:last-child {
display: none;
}
#mobileContextMenu {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100vh;
background-color: rgba(51, 51, 51, 0.3);
display: flex;
justify-content: center;
align-items: flex-end;
z-index: 100;
opacity: 0;
visibility: hidden;
transition: opacity 0.3s ease, visibility 0s linear 0.4s;
}
#mobileContextMenu.active {
visibility: visible;
opacity: 1;
transition: opacity 0.3s ease;
}
#mobileContextMenu .context-body {
width: 100%;
max-height: 100%;
transform: translateY(100%);
transition: transform 0.4s cubic-bezier(0.25, 0.8, 0.25, 1);
overflow-y: auto;
overflow-x: hidden;
scrollbar-width: none;
}
#mobileContextMenu.active .context-body {
transform: translateY(0);
}
#mobileContextMenu table {
background-color: white;
width: 100%;
margin-top: 150px;
padding-bottom: 96px;
}
#mobileContextMenu thead {
padding: 12px 16px 0;
height: 48px;
position: sticky;
top: -1px;
display: flex;
align-items: center;
background-color: white;
}
#mobileContextMenu thead:not(.is-pinned)::after {
content: '';
position: absolute;
left: 16px;
right: 16px;
bottom: 0px;
height: 1px;
background: #e2e2e2;
}
#mobileContextMenu thead.is-pinned {
box-shadow: 0px 4px 6px 0px #CCCCCC4D;
transition: all 0.4s ease-out;
}
#mobileContextMenu tbody {
padding: 0 16px;
display: block
}
#mobileContextMenu tr {
display: block;
padding: 12px;
}
.context-section {
padding: 24px 0 6px !important;
font-size: 13px;
font-weight: 600;
color: #808080;
}
#mobileContextMenu a:not(.stored-edit) {
display: flex;
flex-direction: row;
align-items: center;
text-decoration: none;
}
#mobileContextMenu img {
margin-right: 8px;
}

View File

@ -52,13 +52,13 @@
</div>
<menu class="responsive-nav">
<li>
<a href="#" onclick="toggleSidePanel(event)">
<img src="app_themes/images/mobile-menu.svg" alt="ONLYOFFICE" />
<a href="./">
<img src ="app_themes/images/mobile-logo.svg" alt="ONLYOFFICE" />
</a>
</li>
<li>
<a href="./">
<img src ="app_themes/images/mobile-logo.svg" alt="ONLYOFFICE" />
<a href="#" onclick="toggleSidePanel(event)">
<img src="app_themes/images/mobile-menu.svg" alt="ONLYOFFICE" />
</a>
</li>
</menu>
@ -156,13 +156,18 @@
<% } %>
</menu>
<div id="portal-info" style="display: <%= storedFiles.Any() ? "none" : "table-cell" %>">
<span class="portal-name">ONLYOFFICE Document Editors Welcome!</span>
<span class="portal-name">Welcome to ONLYOFFICE Docs!</span>
<span class="portal-descr">Get started with a live demo of ONLYOFFICE Docs, a powerful open-source office suite for your browser.</span>
<span class="portal-descr">
Get started with a demo-sample of ONLYOFFICE Document Editors, the first html5-based editors.
<br /> You may upload your own documents for testing using the "<b>Upload file</b>" button and <b>selecting</b> the necessary files on your PC.
You can test editing features in real-time and explore multi-user collaboration:
<ul>
<li>Create a new Document, Spreadsheet, Presentation, or PDF Form or use the sample files</li>
<li>Upload your own files to test using the Upload file button</li>
<li>Select your username and language to simulate different users and environments</li>
<li>Try real-time collaboration by opening the same document using different users in different Web browser sessions</li>
</ul>
</span>
<span class="portal-descr">Please do NOT use this integration example on your own server without proper code modifications, it is intended for testing purposes only. In case you enabled this test example, disable it before going for production.</span>
<span class="portal-descr">You can open the same document using different users in different Web browser sessions, so you can check out multi-user editing functions.</span>
<span class="portal-descr">⚠️ This example is intended for testing purposes only. Do not use it on a production server without proper code modifications. If you have enabled this test demo, please disable it before deploying the editors in production.</span>
<% foreach (User user in Users.getAllUsers())
{ %>
<div class="user-descr" onclick="toggleUserDescr(event)">
@ -207,8 +212,7 @@
var editUrl = "doceditor.aspx?fileID=" + HttpUtility.UrlEncode(storedFile.Name) + directUrlParam;
var ext = Path.GetExtension(storedFile.Name).ToLower();
var docType = DocumentType(storedFile.Name);
var canEdit = EditedExts.Contains(ext);
var isFillFormDoc = FillFormsExts.Contains(ext);
var actions = FormatManager.GetFormatActions(ext);
%>
<tr class="tableRow" title="<%= storedFile.Name %> [<%= GetFileVersion(storedFile.Name, HttpContext.Current.Request.UserHostAddress.Replace(':','_')) %>]">
@ -217,98 +221,101 @@
<span><%= storedFile.Name %></span>
</a>
</td>
<% if (canEdit) { %>
<td class="contentCells contentCells-icon">
<!-- 1-2 -->
<% if (actions.Contains("edit") || actions.Contains("lossy-edit")) { %>
<td class="contentCells contentCells-icon" data-section="EDITOR">
<a href="<%= editUrl + "&editorsType=desktop&editorsMode=edit" %>" target="_blank">
<img src="app_themes/images/desktop.svg" alt="Open in editor for full size screens" title="Open in editor for full size screens"/>
<img src="app_themes/images/edit.svg" alt="Open for full size screens" title="Open for full size screens"/>
</a>
</td>
<td class="contentCells contentCells-icon">
<a href="<%= editUrl + "&editorsType=mobile&editorsMode=edit" %>" target="_blank">
<img src="app_themes/images/mobile.svg" alt="Open in editor for mobile devices" title="Open in editor for mobile devices"/>
<img src="app_themes/images/mobileEdit.svg" alt="Open for mobile devices" title="Open for mobile devices"/>
</a>
</td>
<% if (docType != "pdf") { %>
<td class="contentCells contentCells-icon">
<a href="<%= editUrl + "&editorsType=desktop&editorsMode=comment" %>" target="_blank">
<img src="app_themes/images/comment.svg" alt="Open in editor for comment" title="Open in editor for comment"/>
</a>
</td>
<% } %>
<% if (docType == "word") { %>
<% } else { %>
<td class="contentCells contentCells-icon" data-section="EDITOR"></td>
<td class="contentCells contentCells-icon"></td>
<% } %>
<!-- 3 -->
<% if (actions.Contains("comment")) { %>
<td class="contentCells contentCells-icon">
<a href="<%= editUrl + "&editorsType=desktop&editorsMode=comment" %>" target="_blank">
<img src="app_themes/images/comment.svg" alt="Open for comment" title="Open for comment"/>
</a>
</td>
<% } else { %>
<td class="contentCells contentCells-icon"></td>
<% } %>
<!-- 4-5 -->
<% if (actions.Contains("fill")) { %>
<td class="contentCells contentCells-icon firstContentCellShift">
<a href="<%= editUrl + "&editorsType=desktop&editorsMode=fillForms" %>" target="_blank">
<img src="app_themes/images/formsubmit.svg" alt="Open for filling in forms" title="Open for filling in forms"/>
</a>
</td>
<td class="contentCells contentCells-icon contentCells-shift">
<a href="<%= editUrl + "&editorsType=mobile&editorsMode=fillForms" %>" target="_blank">
<img src="app_themes/images/mobile-fill-forms.svg" alt="Open for filling in forms for mobile devices" title="Open for filling in forms for mobile devices"/>
</a>
</td>
<% } else { %>
<!-- 4 -->
<% if (actions.Contains("review")) { %>
<td class="contentCells contentCells-icon">
<a href="<%= editUrl + "&editorsType=desktop&editorsMode=review" %>" target="_blank">
<img src="app_themes/images/review.svg" alt="Open in editor for review" title="Open in editor for review"/>
<img src="app_themes/images/review.svg" alt="Open for review" title="Open for review"/>
</a>
</td>
<% } else if (docType == "cell") { %>
<% } else if (actions.Contains("customfilter")) { %>
<td class="contentCells contentCells-icon">
<a href="<%= editUrl + "&editorsType=desktop&editorsMode=filter" %>" target="_blank">
<img src="app_themes/images/filter.svg" alt="Open in editor without access to change the filter" title="Open in editor without access to change the filter" />
<img src="app_themes/images/filter.svg" alt="Open without access to change the filter" title="Open without access to change the filter" />
</a>
</td>
<% } %>
<% if (docType == "word") { %>
<td class="contentCells contentCells-icon">
<a href="<%= editUrl + "&editorsType=desktop&editorsMode=blockcontent" %>" target="_blank">
<img src="app_themes/images/block-content.svg" alt="Open in editor without content control modification" title="Open in editor without content control modification"/>
</a>
</td>
<% } else{%>
<td class="contentCells contentCells-icon"></td>
<%} %>
<%if (docType != "word" && docType != "cell"){%>
<td class="contentCells contentCells-icon "></td>
<% } %>
<% if (isFillFormDoc) { %>
<td class="contentCells contentCells-shift contentCells-icon firstContentCellShift">
<a href="<%= editUrl + "&editorsType=desktop&editorsMode=fillForms" %>" target="_blank">
<img src="app_themes/images/fill-forms.svg" alt="Open in editor for filling in forms" title="Open in editor for filling in forms"/>
</a>
</td>
<% } else { %>
<td class="contentCells contentCells-shift contentCells-icon firstContentCellShift"></td>
<td class="contentCells contentCells-icon"></td>
<% } %>
<% } else if (isFillFormDoc) { %>
<td class="contentCells contentCells-icon "></td>
<td class="contentCells contentCells-icon">
<a href="<%= editUrl + "&editorsType=mobile&editorsMode=fillForms" %>" target="_blank">
<img src="app_themes/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"/>
<!-- 5 -->
<% if (actions.Contains("edit") && docType == "word") { %>
<td class="contentCells contentCells-icon contentCells-shift">
<a href="<%= editUrl + "&editorsType=desktop&editorsMode=blockcontent" %>" target="_blank">
<img src="app_themes/images/block-content.svg" alt="Open without content control modification" title="Open without content control modification"/>
</a>
</td>
<td class="contentCells contentCells-icon "></td>
<td class="contentCells contentCells-icon "></td>
<td class="contentCells contentCells-icon "></td>
<td class="contentCells contentCells-shift contentCells-icon firstContentCellShift">
<a href="<%= editUrl + "&editorsType=desktop&editorsMode=fillForms" %>" target="_blank">
<img src="app_themes/images/fill-forms.svg" alt="Open in editor for filling in forms" title="Open in editor for filling in forms"/>
</a>
</td>
<% } else { %>
<td class="contentCells contentCells-shift contentCells-icon contentCellsEmpty" colspan="6"></td>
<% } else { %>
<td class="contentCells contentCells-icon contentCells-shift"></td>
<% } %>
<% } %>
<td class="contentCells contentCells-icon firstContentCellViewers">
<td class="contentCells contentCells-icon firstContentCellViewers" data-section="VIEWERS">
<a href="<%= editUrl + "&editorsType=desktop&editorsMode=view" %>" target="_blank">
<img src="app_themes/images/desktop.svg" alt="Open in viewer for full size screens" title="Open in viewer for full size screens"/>
<img src="app_themes/images/view.svg" alt="Open for full size screens" title="Open for full size screens"/>
</a>
</td>
<td class="contentCells contentCells-icon">
<a href="<%= editUrl + "&editorsType=mobile&editorsMode=view" %>" target="_blank">
<img src="app_themes/images/mobile.svg" alt="Open in viewer for mobile devices" title="Open in viewer for mobile devices"/>
<img src="app_themes/images/mobileView.svg" alt="Open for mobile devices" title="Open for mobile devices"/>
</a>
</td>
<td class="contentCells contentCells-icon contentCells-shift">
<a href="<%= editUrl + "&editorsType=embedded&editorsMode=embedded" %>" target="_blank">
<img src="app_themes/images/embeded.svg" alt="Open in embedded mode" title="Open in embedded mode"/>
<img src="app_themes/images/embedview.svg" alt="Open in embedded mode" title="Open in embedded mode"/>
</a>
</td>
<% if (docType != null ) { %>
<td class="contentCells contentCells-icon">
<td class="contentCells contentCells-icon" data-section="ACTION">
<a class="convert-file" data="<%= storedFile.Name %>" data-type="<%= docType %>">
<img class="icon-action" src="app_themes/images/convert.svg" alt="Convert" title="Convert" /></a>
</td>
<% } else { %>
<td class="contentCells contentCells-icon downloadContentCellShift"></td>
<td class="contentCells contentCells-icon downloadContentCellShift" data-section="ACTION"></td>
<% } %>
<td class="contentCells contentCells-icon downloadContentCellShift">
<a href="webeditor.ashx?type=download&fileName=<%= HttpUtility.UrlEncode(storedFile.Name) %>">
@ -320,6 +327,11 @@
<img class="icon-action" src="app_themes/images/delete.svg" alt="Delete" title="Delete" />
</a>
</td>
<td class="contentCells contentCells-icon">
<a href="#" onclick="toggleContextMenu(event)">
<img src="app_themes/images/open-context.svg" alt="Open context menu" title="Open context menu" />
</a>
</td>
</tr>
<% } %>
</tbody>
@ -432,6 +444,11 @@
</footer>
</form>
<div id="mobileContextMenu" onclick="toggleContextMenu(event)">
<div class="context-body" id="mobileContextMenuBody">
</div>
</div>
<script language="javascript" type="text/javascript" src="script/jquery-3.6.4.min.js"></script>
<script language="javascript" type="text/javascript" src="script/jquery-migrate-3.4.1.min.js"></script>
<script language="javascript" type="text/javascript" src="script/jquery-ui.min.js"></script>

View File

@ -362,6 +362,18 @@
innerAlert("onRequestSendNotify: " + data);
};
var onRequestStartFilling = function(event) {
var data = event.data;
var submit = confirm("Start filling?\n" + JSON.stringify(data));
if (submit) {
docEditor.startFilling(true);
}
};
var onStartFilling = function(event) {
innerAlert("The form is ready to fill out.");
};
config = <%= DocConfig %>;
config.width = "100%";
@ -383,6 +395,8 @@
if (config.editorConfig.user.id) {
config.events['onRequestRefreshFile'] = onRequestRefreshFile;
config.events['onRequestClose'] = onRequestClose;
config.events['onRequestStartFilling'] = onRequestStartFilling;
config.events['onStartFilling'] = onStartFilling;
config.events['onRequestHistory'] = function (event) { // the user is trying to show the document version history
let xhr = new XMLHttpRequest();
@ -448,7 +462,7 @@
config.events['onRequestReferenceSource'] = onRequestReferenceSource;
}
var сonnectEditor = function () {
var connectEditor = function () {
docEditor = new DocsAPI.DocEditor("iframeEditor", config);
};
@ -460,9 +474,9 @@
};
if (window.addEventListener) {
window.addEventListener("load", сonnectEditor);
window.addEventListener("load", connectEditor);
} else if (window.attachEvent) {
window.attachEvent("load", сonnectEditor);
window.attachEvent("load", connectEditor);
}
</script>

View File

@ -257,6 +257,7 @@ namespace OnlineEditorsExample
{
{ "id", !user.id.Equals("uid-0") ? user.id : null },
{ "name", user.name },
{ "roles", user.roles },
{ "group", user.group },
{ "image", user.avatar ? _Default.GetServerUrl(false) + "/App_Themes/images/"+ user.id + ".png" : null }
}

View File

@ -198,6 +198,13 @@ namespace OnlineEditorsExample
return cachedFormats;
}
public static List<string> GetFormatActions(string extension)
{
return All()
.Find(format => format.Extension() == extension)
.Actions;
}
private static string GetPath()
{
string path = Path.Combine(GetDirectory(), "onlyoffice-docs-formats.json");

View File

@ -83,18 +83,18 @@
<Content Include="App_Themes\images\close.svg" />
<Content Include="App_Themes\images\comment.svg" />
<Content Include="App_Themes\images\delete.svg" />
<Content Include="App_Themes\images\desktop.svg" />
<Content Include="App_Themes\images\done.svg" />
<Content Include="App_Themes\images\download.svg" />
<Content Include="App_Themes\images\embeded.svg" />
<Content Include="App_Themes\images\edit.svg" />
<Content Include="App_Themes\images\embedview.svg" />
<Content Include="App_Themes\images\error.svg" />
<Content Include="App_Themes\images\file_docx.svg" />
<Content Include="App_Themes\images\file_docxf.svg" />
<Content Include="App_Themes\images\file_pptx.svg" />
<Content Include="App_Themes\images\file_upload.svg" />
<Content Include="App_Themes\images\file_xlsx.svg" />
<Content Include="App_Themes\images\fill-forms.svg" />
<Content Include="App_Themes\images\filter.svg" />
<Content Include="App_Themes\images\formsubmit.svg" />
<Content Include="App_Themes\images\home.svg" />
<Content Include="App_Themes\images\icon_docx.svg" />
<Content Include="App_Themes\images\icon_pptx.svg" />
@ -102,12 +102,14 @@
<Content Include="App_Themes\images\info.svg" />
<Content Include="App_Themes\images\logo.svg" />
<Content Include="App_Themes\images\mobile-fill-forms.svg" />
<Content Include="App_Themes\images\mobile.svg" />
<Content Include="App_Themes\images\mobileEdit.svg" />
<Content Include="App_Themes\images\mobileView.svg" />
<Content Include="App_Themes\images\notdone.svg" />
<Content Include="App_Themes\images\review.svg" />
<Content Include="App_Themes\images\slide.ico" />
<Content Include="App_Themes\images\uid-1.png" />
<Content Include="App_Themes\images\uid-2.png" />
<Content Include="App_Themes\images\view.svg" />
<Content Include="App_Themes\images\word.ico" />
<Content Include="App_Themes\media.css" />
<Content Include="Forgotten.aspx" />

View File

@ -32,7 +32,9 @@ namespace OnlineEditorsExample
"This file isn't marked as favorite",
"Can create files from templates using data from the editor",
"Has an avatar",
"Can submit forms"
"Can submit forms",
"Has no roles",
"Can start filling"
};
static List<string> descr_user_2 = new List<string>()
@ -44,7 +46,9 @@ namespace OnlineEditorsExample
"This file is marked as favorite",
"Can create new files from the editor",
"Has an avatar",
"Can't submit forms"
"Can't submit forms",
"Has role 'Anyone'",
"Can start filling"
};
static List<string> descr_user_3 = new List<string>()
@ -60,7 +64,9 @@ namespace OnlineEditorsExample
"Can create new files from the editor",
"Can't close history",
"Can't restore the file version",
"Can't submit forms"
"Can't submit forms",
"Has role 'role'",
"Can start filling"
};
static List<string> descr_user_0 = new List<string>()
@ -79,7 +85,9 @@ namespace OnlineEditorsExample
"View file without collaboration",
"Can't refresh outdated file",
"Can't submit forms",
"Tour of tips when opening a document"
"Tour of tips when opening a document",
"Has empty role",
"Can't start filling"
};
private static List<User> users = new List<User>() {
@ -97,7 +105,8 @@ namespace OnlineEditorsExample
true,
true,
new Goback(null, false),
new Close(null, false)
new Close(null, false),
null
),
new User(
"uid-2",
@ -118,7 +127,8 @@ namespace OnlineEditorsExample
false,
true,
new Goback("Go to Documents",null),
new Close(null, true)
new Close(null, true),
new List<string>() { "Anyone" }
),
new User(
"uid-3",
@ -139,7 +149,8 @@ namespace OnlineEditorsExample
false,
false,
null,
new Close(null, true)
new Close(null, true),
new List<string>() { "role" }
),
new User(
"uid-0",
@ -155,7 +166,8 @@ namespace OnlineEditorsExample
false,
false,
null,
null
null,
new List<string>()
)
};
@ -249,8 +261,9 @@ namespace OnlineEditorsExample
public bool avatar;
public Goback goback;
public Close close;
public List<string> roles;
public User(string id, string name, string email, string group, List<string> reviewGroups, Dictionary<string, object> commentGroups, List<string> userInfoGroups, bool? favorite, List<string> deniedPermissions, List<string> descriptions, bool templates, bool avatar, Goback goback, Close close)
public User(string id, string name, string email, string group, List<string> reviewGroups, Dictionary<string, object> commentGroups, List<string> userInfoGroups, bool? favorite, List<string> deniedPermissions, List<string> descriptions, bool templates, bool avatar, Goback goback, Close close, List<string> roles)
{
this.id = id;
this.name = name;
@ -266,6 +279,7 @@ namespace OnlineEditorsExample
this.avatar = avatar;
this.goback = goback;
this.close = close;
this.roles = roles;
}
}

View File

@ -561,4 +561,76 @@ function toggleUserDescr(event) {
if (list.classList.contains("active")) list.classList.remove("active");
else list.classList.add("active");
}
}
function toggleContextMenu(event) {
let contextMenu = document.querySelector("#mobileContextMenu");
let target = event.currentTarget.parentNode.parentNode.cloneNode(true);
const closeContextMenu = () => {
contextMenu.classList.remove("active");
}
if (contextMenu.classList.contains("active") || !target.classList.contains("tableRow")) {
if (event.target.id == "mobileContextMenuBody") closeContextMenu();
return;
}
let contextBody = document.querySelector("#mobileContextMenuBody");
contextBody.innerHTML = "";
let startY = 0;
let startScroll = 0;
contextBody.addEventListener('touchstart', (e) => {
startY = e.touches[0].clientY;
startScroll = contextBody.scrollTop;
});
contextBody.addEventListener('touchmove', (e) => {
const currentY = e.touches[0].clientY;
const diff = currentY - startY;
if (diff > 10 && (contextBody.scrollTop === 0 || contextBody.scrollTop === startScroll)) {
closeContextMenu();
}
});
let thead = document.createElement("thead");
thead.appendChild(target.children[0]);
const observer = new IntersectionObserver(
([e]) => e.target.classList.toggle("is-pinned", e.intersectionRatio < 1),
{ threshold: [1] }
);
observer.observe(thead);
let tbody = document.createElement("tbody");
for (let td of Array.from(target.children).slice(0, -1)){
if (td.getAttribute("data-section")){
let section = document.createElement("tr");
section.innerText = td.getAttribute("data-section");
section.classList.add("context-section");
tbody.appendChild(section);
}
if (td.children.length == 0) continue;
let action = document.createElement("div");
action.innerText = td.children[0].children[0].getAttribute("title");
td.children[0].appendChild(action);
td.children[0].onclick = () => {
setTimeout(() => window.location.reload(), 0);
}
td.style.display = "block";
td.classList.remove("downloadContentCellShift");
td.classList.remove("firstContentCellViewers");
let tr = document.createElement("tr");
tr.appendChild(td);
tbody.appendChild(tr);
}
let table = document.createElement("table");
table.appendChild(thead);
table.appendChild(tbody);
contextBody.appendChild(table);
contextMenu.classList.add("active");
}

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" ?>
<appSettings>
<clear />
<add key="version" value="1.14.0"/>
<add key="version" value="1.15.0"/>
<add key="filesize-max" value="52428800"/>
<add key="storage-path" value=""/>

View File

@ -1,5 +1,5 @@
{
"VERSION": "1.14.0",
"VERSION": "1.15.0",
"SERVER_ADDRESS" : "",
"SERVER_PORT" : 3000,

View File

@ -22,7 +22,6 @@ import (
"runtime"
"time"
"github.com/ONLYOFFICE/document-server-integration/utils"
"github.com/spf13/viper"
"go.uber.org/fx"
)
@ -47,11 +46,6 @@ type ApplicationConfig struct {
Languages map[string]string `mapstructure:"LANGUAGES"`
}
type SpecificationConfig struct {
Extensions Extensions `mapstructure:"extensions"`
ExtensionTypes ExtensionTypes `mapstructure:"extension_types"`
}
func NewConfiguration() (app_config ApplicationConfig, err error) {
_, b, _, _ := runtime.Caller(0)
basepath := filepath.Dir(b)
@ -76,33 +70,6 @@ func NewConfiguration() (app_config ApplicationConfig, err error) {
return
}
func NewSpecification() (specification SpecificationConfig, err error) {
fm, err := utils.NewFormatManager()
if err != nil {
return SpecificationConfig{}, err
}
exts := Extensions{
fm.GetViewedExtensions(),
fm.GetEditedExtensions(),
fm.GetConvertedExtensions(),
fm.GetFilledExtensions(),
}
extTypes := ExtensionTypes{
fm.GetSpreadsheetExtensions(),
fm.GetPresentationExtensions(),
fm.GetDocumentExtensions(),
fm.GetPdfExtensions(),
fm.GetDiagramExtensions(),
}
specification = SpecificationConfig{
exts,
extTypes,
}
return
}
var ConfigurationModule = fx.Options(
fx.Provide(NewConfiguration),
fx.Provide(NewSpecification),
)

View File

@ -1,9 +1,9 @@
module github.com/ONLYOFFICE/document-server-integration
go 1.21
go 1.23.10
require (
github.com/golang-jwt/jwt v3.2.2+incompatible
github.com/golang-jwt/jwt/v5 v5.3.0
github.com/gorilla/mux v1.8.1
github.com/gorilla/schema v1.4.1
github.com/mitchellh/mapstructure v1.5.0

View File

@ -6,8 +6,8 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=

View File

@ -31,20 +31,18 @@ import (
)
type DefaultServerEndpointsHandler struct {
logger *zap.SugaredLogger
config config.ApplicationConfig
specification config.SpecificationConfig
logger *zap.SugaredLogger
config config.ApplicationConfig
*handlers.CallbackRegistry
*managers.Managers
}
func NewDefaultServerEndpointsHandler(logger *zap.SugaredLogger, config config.ApplicationConfig,
spec config.SpecificationConfig, reg *handlers.CallbackRegistry,
reg *handlers.CallbackRegistry,
managers *managers.Managers) api.ServerEndpointsHandler {
return &DefaultServerEndpointsHandler{
logger,
config,
spec,
reg,
managers,
}
@ -64,6 +62,15 @@ func generateUrl(r *http.Request) string {
}
var decoder = schema.NewDecoder()
var indexTemplate = template.Must(template.ParseFiles("templates/index.html"))
var indexTemplate = template.Must(template.New("index.html").Funcs(template.FuncMap{
"contains": func(slice []string, item string) bool {
for _, s := range slice {
if s == item {
return true
}
}
return false
},
}).ParseFiles("templates/index.html"))
var forgottenTemplate = template.Must(template.ParseFiles("templates/forgotten.html"))
var editorTemplate = template.Must(template.ParseFiles("templates/editor.html"))

View File

@ -27,7 +27,7 @@ import (
"github.com/ONLYOFFICE/document-server-integration/server/managers"
"github.com/ONLYOFFICE/document-server-integration/server/models"
"github.com/ONLYOFFICE/document-server-integration/server/shared"
"github.com/golang-jwt/jwt"
"github.com/golang-jwt/jwt/v5"
)
func (srv *DefaultServerEndpointsHandler) Config(w http.ResponseWriter, r *http.Request) {
@ -73,9 +73,9 @@ func (srv *DefaultServerEndpointsHandler) Config(w http.ResponseWriter, r *http.
),
Mode: "edit",
},
StandardClaims: jwt.StandardClaims{
ExpiresAt: time.Now().Add(time.Minute * srv.config.JwtExpiresIn).Unix(),
IssuedAt: time.Now().Unix(),
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Minute * srv.config.JwtExpiresIn)),
IssuedAt: jwt.NewNumericDate(time.Now()),
},
}

View File

@ -92,8 +92,7 @@ func (srv *DefaultServerEndpointsHandler) Convert(w http.ResponseWriter, r *http
response.Step = 100
supportedExt := true
fm, err := utils.NewFormatManager()
for _, f := range fm.GetFormats() {
for _, f := range srv.FormatManager.GetAllFormats() {
if f.Name == newExt && len(f.Actions) == 0 {
supportedExt = false
break

View File

@ -56,7 +56,7 @@ func (srv *DefaultServerEndpointsHandler) Create(w http.ResponseWriter, r *http.
}
fileExt := utils.GetFileExt(fileName, true)
if strings.TrimSpace(fileExt) == "" || !utils.IsInList(fileExt, srv.specification.Extensions.Viewed) {
if strings.TrimSpace(fileExt) == "" || !srv.FormatManager.HasAction(fileExt, "view") {
srv.logger.Errorf("%s extension is not supported", fileExt)
shared.SendCustomErrorResponse(w, "extension is not supported")
return
@ -106,7 +106,7 @@ func (srv *DefaultServerEndpointsHandler) Create(w http.ResponseWriter, r *http.
query := r.URL.Query()
fileExt, isSample := query.Get("fileExt"), query.Get("sample")
if strings.TrimSpace(fileExt) == "" || !utils.IsInList(fileExt, srv.specification.Extensions.Edited) {
if strings.TrimSpace(fileExt) == "" || !srv.FormatManager.HasAction(fileExt, "edit") {
srv.logger.Errorf("%s extension is not supported", fileExt)
http.Redirect(w, r, "/", http.StatusSeeOther)
return

View File

@ -71,7 +71,7 @@ func (srv *DefaultServerEndpointsHandler) Forgotten(w http.ResponseWriter, r *ht
if err = json.NewDecoder(res.Body).Decode(&file); err != nil {
srv.logger.Errorf("could not parse forgotten file[%s]: %s", file.Key, err.Error())
} else {
file.Type = srv.Managers.ConversionManager.GetFileType(file.Url)
file.Type = srv.FormatManager.GetFileType(file.Url)
files = append(files, file)
}
}

View File

@ -18,21 +18,13 @@
package dapi
import (
"fmt"
"net/http"
"github.com/ONLYOFFICE/document-server-integration/server/shared"
"github.com/ONLYOFFICE/document-server-integration/utils"
)
func (srv *DefaultServerEndpointsHandler) Formats(w http.ResponseWriter, r *http.Request) {
srv.logger.Debug("A new formats call")
fm, err := utils.NewFormatManager()
if err != nil {
srv.logger.Errorf("could not fetch formats: %s", err.Error())
shared.SendCustomErrorResponse(w, fmt.Sprintf("could not fetch formats: %s", err.Error()))
return
}
shared.SendResponse(w, fm.GetFormats())
shared.SendResponse(w, srv.FormatManager.GetAllFormats())
}

View File

@ -29,7 +29,6 @@ func (srv *DefaultServerEndpointsHandler) Index(w http.ResponseWriter, r *http.R
}
data := map[string]interface{}{
"Extensions": srv.specification.Extensions,
"Users": srv.Managers.UserManager.GetUsers(),
"Files": files,
"Preloader": srv.config.DocumentServerHost + srv.config.DocumentServerPreloader,
@ -38,5 +37,8 @@ func (srv *DefaultServerEndpointsHandler) Index(w http.ResponseWriter, r *http.R
"ServerVersion": srv.config.Version,
}
indexTemplate.Execute(w, data) // nolint: errcheck
err = indexTemplate.Execute(w, data)
if err != nil {
srv.logger.Errorf("Could not execute template: %s", err.Error())
}
}

View File

@ -29,7 +29,7 @@ import (
"github.com/ONLYOFFICE/document-server-integration/server/models"
"github.com/ONLYOFFICE/document-server-integration/server/shared"
"github.com/ONLYOFFICE/document-server-integration/utils"
"github.com/golang-jwt/jwt"
"github.com/golang-jwt/jwt/v5"
)
func (srv *DefaultServerEndpointsHandler) Reference(w http.ResponseWriter, r *http.Request) {
@ -97,9 +97,9 @@ func (srv *DefaultServerEndpointsHandler) Reference(w http.ResponseWriter, r *ht
},
Link: remoteAddr + "/editor?filename=" + url.QueryEscape(fileName),
Path: fileName,
StandardClaims: jwt.StandardClaims{
ExpiresAt: time.Now().Add(time.Minute * srv.config.JwtExpiresIn).Unix(),
IssuedAt: time.Now().Unix(),
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Minute * srv.config.JwtExpiresIn)),
IssuedAt: jwt.NewNumericDate(time.Now()),
},
}

View File

@ -22,7 +22,7 @@ import (
"net/http"
"github.com/ONLYOFFICE/document-server-integration/server/models"
"github.com/golang-jwt/jwt"
"github.com/golang-jwt/jwt/v5"
)
type DocumentManager interface {
@ -73,10 +73,7 @@ type JwtManager interface {
}
type ConversionManager interface {
GetFileType(filename string) string
GetInternalExtension(fileType string) string
IsCanConvert(ext string) bool
IsCanFill(ext string) bool
GetConverterUri(docUri, fromExt, toExt, docKey string, isAsync bool, title string) (string, string, error)
}
@ -84,6 +81,15 @@ type CommandManager interface {
CommandRequest(method string, docKey string, meta interface{}) (*http.Response, error)
}
type FormatManager interface {
GetAllFormats() []models.Format
GetFormat(ext string) models.Format
GetActions(ext string) []string
GetTypeByExtension(ext string) string
GetFileType(filename string) string
HasAction(ext string, action string) bool
}
type Managers struct {
DocumentManager
HistoryManager
@ -92,12 +98,13 @@ type Managers struct {
JwtManager
ConversionManager
CommandManager
FormatManager
}
func New(umanager UserManager, smanager StorageManager,
hmanager HistoryManager, dmanager DocumentManager,
jmanager JwtManager, cmanager ConversionManager,
commanager CommandManager) *Managers {
commanager CommandManager, fmanager FormatManager) *Managers {
return &Managers{
HistoryManager: hmanager,
StorageManager: smanager,
@ -106,5 +113,6 @@ func New(umanager UserManager, smanager StorageManager,
JwtManager: jmanager,
ConversionManager: cmanager,
CommandManager: commanager,
FormatManager: fmanager,
}
}

View File

@ -27,7 +27,7 @@ import (
"github.com/ONLYOFFICE/document-server-integration/config"
"github.com/ONLYOFFICE/document-server-integration/server/managers"
"github.com/golang-jwt/jwt"
"github.com/golang-jwt/jwt/v5"
)
type DefaultCommandManager struct {
@ -40,13 +40,13 @@ type CommandPayload struct {
Key string `json:"key"`
Meta interface{} `json:"meta"`
Token string `json:"token"`
jwt.StandardClaims
jwt.RegisteredClaims
}
type CommandRequestHeaderPayload struct {
Query map[string]string `json:"query"`
Payload CommandPayload `json:"payload"`
jwt.StandardClaims
jwt.RegisteredClaims
}
func NewDefaultCommandManager(config config.ApplicationConfig, jmanager managers.JwtManager) managers.CommandManager {
@ -60,9 +60,9 @@ func (cm DefaultCommandManager) CommandRequest(method string, docKey string, met
payload := CommandPayload{
C: method,
Key: docKey,
StandardClaims: jwt.StandardClaims{
ExpiresAt: time.Now().Add(time.Minute * cm.config.JwtExpiresIn).Unix(),
IssuedAt: time.Now().Unix(),
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Minute * cm.config.JwtExpiresIn)),
IssuedAt: jwt.NewNumericDate(time.Now()),
},
}
if meta != nil {
@ -119,9 +119,9 @@ func fillJwtByUrl(uri string, payload CommandPayload, config config.ApplicationC
return CommandRequestHeaderPayload{
Query: queryMap,
Payload: payload,
StandardClaims: jwt.StandardClaims{
ExpiresAt: time.Now().Add(time.Minute * config.JwtExpiresIn).Unix(),
IssuedAt: time.Now().Unix(),
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Minute * config.JwtExpiresIn)),
IssuedAt: jwt.NewNumericDate(time.Now()),
},
}
}

View File

@ -30,51 +30,25 @@ import (
"github.com/ONLYOFFICE/document-server-integration/server/managers"
"github.com/ONLYOFFICE/document-server-integration/server/shared"
"github.com/ONLYOFFICE/document-server-integration/utils"
"github.com/golang-jwt/jwt"
"github.com/golang-jwt/jwt/v5"
"go.uber.org/zap"
)
type DefaultConversionManager struct {
config config.ApplicationConfig
specification config.SpecificationConfig
logger *zap.SugaredLogger
config config.ApplicationConfig
logger *zap.SugaredLogger
managers.JwtManager
}
func NewDefaultConversionManager(config config.ApplicationConfig, spec config.SpecificationConfig,
func NewDefaultConversionManager(config config.ApplicationConfig,
logger *zap.SugaredLogger, jmanager managers.JwtManager) managers.ConversionManager {
return &DefaultConversionManager{
config,
spec,
logger,
jmanager,
}
}
func (cm DefaultConversionManager) GetFileType(filename string) string {
ext := utils.GetFileExt(filename, true)
exts := cm.specification.ExtensionTypes
if utils.IsInList(ext, exts.Pdf) {
return shared.ONLYOFFICE_PDF
}
if utils.IsInList(ext, exts.Document) {
return shared.ONLYOFFICE_DOCUMENT
}
if utils.IsInList(ext, exts.Spreadsheet) {
return shared.ONLYOFFICE_SPREADSHEET
}
if utils.IsInList(ext, exts.Presentation) {
return shared.ONLYOFFICE_PRESENTATION
}
if utils.IsInList(ext, exts.Diagram) {
return shared.ONLYOFFICE_DIAGRAM
}
return shared.ONLYOFFICE_DOCUMENT
}
func (cm DefaultConversionManager) GetInternalExtension(fileType string) string {
switch fileType {
case shared.ONLYOFFICE_DOCUMENT:
@ -88,14 +62,6 @@ func (cm DefaultConversionManager) GetInternalExtension(fileType string) string
}
}
func (cm DefaultConversionManager) IsCanFill(ext string) bool {
return utils.IsInList(ext, cm.specification.Extensions.Filled)
}
func (cm DefaultConversionManager) IsCanConvert(ext string) bool {
return utils.IsInList(ext, cm.specification.Extensions.Converted)
}
func (cm DefaultConversionManager) GetConverterUri(
docUri string,
fromExt string,
@ -115,9 +81,9 @@ func (cm DefaultConversionManager) GetConverterUri(
Title: title,
Key: docKey,
Async: isAsync,
StandardClaims: jwt.StandardClaims{
ExpiresAt: time.Now().Add(time.Minute * cm.config.JwtExpiresIn).Unix(),
IssuedAt: time.Now().Unix(),
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Minute * cm.config.JwtExpiresIn)),
IssuedAt: jwt.NewNumericDate(time.Now()),
},
}
@ -128,9 +94,9 @@ func (cm DefaultConversionManager) GetConverterUri(
if secret != "" && cm.config.JwtEnabled {
headerPayload := managers.ConvertRequestHeaderPayload{
Payload: payload,
StandardClaims: jwt.StandardClaims{
ExpiresAt: time.Now().Add(time.Minute * cm.config.JwtExpiresIn).Unix(),
IssuedAt: time.Now().Unix(),
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Minute * cm.config.JwtExpiresIn)),
IssuedAt: jwt.NewNumericDate(time.Now()),
},
}
headerToken, err = cm.JwtManager.JwtSign(headerPayload, []byte(secret))

View File

@ -28,18 +28,18 @@ import (
"github.com/ONLYOFFICE/document-server-integration/server/managers"
"github.com/ONLYOFFICE/document-server-integration/server/models"
"github.com/ONLYOFFICE/document-server-integration/utils"
"github.com/golang-jwt/jwt"
"github.com/golang-jwt/jwt/v5"
"go.uber.org/zap"
)
type DefaultDocumentManager struct {
config config.ApplicationConfig
specification config.SpecificationConfig
logger *zap.SugaredLogger
config config.ApplicationConfig
logger *zap.SugaredLogger
managers.StorageManager
managers.UserManager
managers.ConversionManager
managers.JwtManager
managers.FormatManager
}
const (
@ -53,17 +53,18 @@ const (
onlyoffice_permission_comment = "comment"
)
func NewDefaultDocumentManager(config config.ApplicationConfig, specification config.SpecificationConfig,
logger *zap.SugaredLogger, smanager managers.StorageManager, umanager managers.UserManager,
cmanager managers.ConversionManager, jmanager managers.JwtManager) managers.DocumentManager {
func NewDefaultDocumentManager(config config.ApplicationConfig, logger *zap.SugaredLogger,
smanager managers.StorageManager, umanager managers.UserManager,
cmanager managers.ConversionManager, jmanager managers.JwtManager,
fmanager managers.FormatManager) managers.DocumentManager {
return &DefaultDocumentManager{
config,
specification,
logger,
smanager,
umanager,
cmanager,
jmanager,
fmanager,
}
}
@ -76,7 +77,8 @@ func (dm DefaultDocumentManager) sanitizeEditorParameters(parameters *managers.E
parameters.PermissionsMode = "edit"
}
parameters.CanEdit = utils.IsInList(utils.GetFileExt(parameters.Filename, true), dm.specification.Extensions.Edited)
actions := dm.FormatManager.GetActions(utils.GetFileExt(parameters.Filename, true))
parameters.CanEdit = slices.Contains(actions, "edit")
if parameters.CanEdit && parameters.PermissionsMode != "view" {
parameters.Mode = "edit"
@ -155,7 +157,7 @@ func (dm DefaultDocumentManager) BuildDocumentConfig(
config := &models.Config{
Type: parameters.Type,
DocumentType: dm.ConversionManager.GetFileType(parameters.Filename),
DocumentType: dm.FormatManager.GetFileType(parameters.Filename),
Document: models.Document{
Title: parameters.Filename,
Url: furi,
@ -227,9 +229,9 @@ func (dm DefaultDocumentManager) BuildDocumentConfig(
},
},
},
StandardClaims: jwt.StandardClaims{
ExpiresAt: time.Now().Add(time.Minute * dm.config.JwtExpiresIn).Unix(),
IssuedAt: time.Now().Unix(),
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Minute * dm.config.JwtExpiresIn)),
IssuedAt: jwt.NewNumericDate(time.Now()),
},
}
@ -245,8 +247,8 @@ func (dm DefaultDocumentManager) BuildDocumentConfig(
func (dm DefaultDocumentManager) IsDocumentConvertable(filename string) bool {
ext := utils.GetFileExt(filename, true)
return utils.IsInList(ext, dm.specification.Extensions.Viewed) ||
utils.IsInList(ext, dm.specification.Extensions.Edited) || utils.IsInList(ext, dm.specification.Extensions.Converted)
actions := dm.FormatManager.GetActions(ext)
return slices.Contains(actions, "view") || slices.Contains(actions, "edit") || slices.Contains(actions, "convert")
}
func (dm DefaultDocumentManager) generateCallbackUrl(filename string, remoteAddress string) string {

View File

@ -0,0 +1,89 @@
/**
*
* (c) Copyright Ascensio System SIA 2025
*
* 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.
*
*/
package dmanager
import (
"encoding/json"
"io"
"os"
"path/filepath"
"runtime"
"slices"
"github.com/ONLYOFFICE/document-server-integration/server/managers"
"github.com/ONLYOFFICE/document-server-integration/server/models"
"github.com/ONLYOFFICE/document-server-integration/utils"
)
type DefaultFormatManager struct {
formats []models.Format
}
func NewDefaultFormatManager() (managers.FormatManager, error) {
_, b, _, _ := runtime.Caller(0)
parentDir := filepath.Dir(filepath.Dir(filepath.Dir(filepath.Dir(b))))
path := filepath.Join(parentDir, "static", "assets", "document-formats", "onlyoffice-docs-formats.json")
fileContent, err := os.Open(path)
if err != nil {
return DefaultFormatManager{}, err
}
defer fileContent.Close()
byteResult, _ := io.ReadAll(fileContent)
var formats []models.Format
err = json.Unmarshal(byteResult, &formats)
if err != nil {
return DefaultFormatManager{}, err
}
return DefaultFormatManager{
formats,
}, err
}
func (fm DefaultFormatManager) GetAllFormats() []models.Format {
return fm.formats
}
func (fm DefaultFormatManager) GetFormat(ext string) models.Format {
for _, f := range fm.formats {
if f.Name == ext {
return f
}
}
return models.Format{}
}
func (fm DefaultFormatManager) GetActions(ext string) []string {
return fm.GetFormat(ext).Actions
}
func (fm DefaultFormatManager) GetTypeByExtension(ext string) string {
return fm.GetFormat(ext).FormatType
}
func (fm DefaultFormatManager) GetFileType(filename string) string {
ext := utils.GetFileExt(filename, true)
return fm.GetTypeByExtension(ext)
}
func (fm DefaultFormatManager) HasAction(ext string, action string) bool {
return slices.Contains(fm.GetActions(ext), action)
}

View File

@ -30,7 +30,7 @@ import (
"github.com/ONLYOFFICE/document-server-integration/server/models"
"github.com/ONLYOFFICE/document-server-integration/server/shared"
"github.com/ONLYOFFICE/document-server-integration/utils"
"github.com/golang-jwt/jwt"
"github.com/golang-jwt/jwt/v5"
"go.uber.org/zap"
)
@ -197,9 +197,9 @@ func (hm DefaultHistoryManager) fetchNextHistoryEntry(
Key: key,
Url: url,
Version: version,
StandardClaims: jwt.StandardClaims{
ExpiresAt: time.Now().Add(time.Minute * hm.config.JwtExpiresIn).Unix(),
IssuedAt: time.Now().Unix(),
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Minute * hm.config.JwtExpiresIn)),
IssuedAt: jwt.NewNumericDate(time.Now()),
},
}
}
@ -267,9 +267,9 @@ func (hm DefaultHistoryManager) GetHistory(
Url: hm.StorageManager.GeneratePublicFileUri(filename, remoteAddress, managers.FileMeta{}),
Version: version,
ChangesUrl: changesUrl,
StandardClaims: jwt.StandardClaims{
ExpiresAt: time.Now().Add(time.Minute * hm.config.JwtExpiresIn).Unix(),
IssuedAt: time.Now().Unix(),
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Minute * hm.config.JwtExpiresIn)),
IssuedAt: jwt.NewNumericDate(time.Now()),
},
}

View File

@ -24,7 +24,7 @@ import (
"github.com/ONLYOFFICE/document-server-integration/config"
"github.com/ONLYOFFICE/document-server-integration/server/managers"
"github.com/ONLYOFFICE/document-server-integration/server/models"
"github.com/golang-jwt/jwt"
"github.com/golang-jwt/jwt/v5"
"github.com/mitchellh/mapstructure"
"go.uber.org/zap"
)

View File

@ -27,4 +27,5 @@ var DefaultManagersModule = fx.Options(
fx.Provide(NewDefaultJwtManager),
fx.Provide(NewDefaultConversionManager),
fx.Provide(NewDefaultCommandManager),
fx.Provide(NewDefaultFormatManager),
)

View File

@ -36,19 +36,19 @@ import (
)
type DefaultStorageManager struct {
config config.ApplicationConfig
specification config.SpecificationConfig
logger *zap.SugaredLogger
config config.ApplicationConfig
logger *zap.SugaredLogger
managers.ConversionManager
managers.FormatManager
}
func NewDefaultStorageManager(config config.ApplicationConfig, specification config.SpecificationConfig,
logger *zap.SugaredLogger, conversionManager managers.ConversionManager) managers.StorageManager {
func NewDefaultStorageManager(config config.ApplicationConfig, logger *zap.SugaredLogger,
conversionManager managers.ConversionManager, formatManager managers.FormatManager) managers.StorageManager {
return &DefaultStorageManager{
config,
specification,
logger,
conversionManager,
formatManager,
}
}
@ -115,11 +115,10 @@ func (sm DefaultStorageManager) GetStoredFiles(remoteAddress string) ([]models.D
}
documents = append(documents, models.Document{
FileType: sm.ConversionManager.GetFileType(filename),
FileType: sm.FormatManager.GetFileType(filename),
Title: filename,
Url: sm.GeneratePublicFileUri(filename, remoteAddress, managers.FileMeta{}),
CanEdit: !sm.ConversionManager.IsCanConvert(utils.GetFileExt(filename, true)),
CanFill: sm.ConversionManager.IsCanFill(utils.GetFileExt(filename, true)),
Actions: sm.FormatManager.GetActions(utils.GetFileExt(filename, true)),
Version: fmt.Sprint(version),
})
}

View File

@ -45,6 +45,7 @@ func NewDefaultUserManager(logger *zap.SugaredLogger) managers.UserManager {
Avatar: false,
Goback: nil,
Close: nil,
Roles: []string{},
},
{
Id: "uid-1",
@ -65,6 +66,7 @@ func NewDefaultUserManager(logger *zap.SugaredLogger) managers.UserManager {
Close: map[string]interface{}{
"visible": false,
},
Roles: nil,
},
{
Id: "uid-2",
@ -89,6 +91,7 @@ func NewDefaultUserManager(logger *zap.SugaredLogger) managers.UserManager {
Close: map[string]interface{}{
"visible": true,
},
Roles: []string{"Anyone"},
},
{
Id: "uid-3",
@ -111,6 +114,7 @@ func NewDefaultUserManager(logger *zap.SugaredLogger) managers.UserManager {
Close: map[string]interface{}{
"visible": true,
},
Roles: []string{"role"},
},
}
return &DefaultUserManager{
@ -135,6 +139,8 @@ var descriptionUser0 []string = []string{
"Can't refresh outdated file",
"Can't submit forms",
"Tour of tips when opening a document",
"Has empty role",
"Can't start filling",
}
var descriptionUser1 []string = []string{
"File author by default",
@ -146,6 +152,8 @@ var descriptionUser1 []string = []string{
"Can create files from templates using data from the editor",
"Can submit forms",
"Has an avatar",
"Has no roles",
"Can start filling",
}
var descriptionUser2 []string = []string{
"Belongs to Group2",
@ -156,6 +164,8 @@ var descriptionUser2 []string = []string{
"Can create new files from the editor",
"Has an avatar",
"Can't submit forms",
"Has role 'Anyone'",
"Can start filling",
}
var descriptionUser3 []string = []string{
"Belongs to Group3",
@ -170,6 +180,8 @@ var descriptionUser3 []string = []string{
"Can't close history",
"Can't restore the file version",
"Can't submit forms",
"Has role 'role'",
"Can start filling",
}
func (um DefaultUserManager) GetUsers() []models.User {
@ -198,6 +210,7 @@ func (um DefaultUserManager) GetUserInfoById(uid string, serverAddress string) m
return models.UserInfo{
Id: user.Id,
Name: user.Username,
Roles: user.Roles,
Email: user.Email,
Image: image,
}

View File

@ -21,7 +21,7 @@ import (
"errors"
"github.com/ONLYOFFICE/document-server-integration/server/models"
"github.com/golang-jwt/jwt"
"github.com/golang-jwt/jwt/v5"
)
var ErrInvalidFilename = errors.New("invalid filename")
@ -39,7 +39,7 @@ type HistorySet struct {
Url string `json:"url"`
Version int `json:"version"`
Token string `json:"token,omitempty"`
jwt.StandardClaims
jwt.RegisteredClaims
}
type HistoryPrevious struct {
@ -99,10 +99,10 @@ type ConvertRequestPayload struct {
Key string `json:"key"`
Async bool `json:"async"`
JwtToken string `json:"token,omitempty"`
jwt.StandardClaims
jwt.RegisteredClaims
}
type ConvertRequestHeaderPayload struct {
Payload ConvertRequestPayload `json:"payload"`
jwt.StandardClaims
jwt.RegisteredClaims
}

View File

@ -17,7 +17,7 @@
*/
package models
import "github.com/golang-jwt/jwt"
import "github.com/golang-jwt/jwt/v5"
type Command int
@ -38,9 +38,9 @@ func (c Command) Ordinal() int {
}
type CommandBody struct {
Command string `json:"c"`
Token string `json:"token,omitempty"`
jwt.StandardClaims `json:"-"`
Command string `json:"c"`
Token string `json:"token,omitempty"`
jwt.RegisteredClaims `json:"-"`
}
type CommandResponse struct {

View File

@ -17,7 +17,7 @@
*/
package models
import "github.com/golang-jwt/jwt"
import "github.com/golang-jwt/jwt/v5"
type Config struct {
Type string `json:"type"`
@ -25,5 +25,5 @@ type Config struct {
DocumentType string `json:"documentType"`
EditorConfig EditorConfig `json:"editorConfig"`
Token string `json:"token,omitempty"`
jwt.StandardClaims
jwt.RegisteredClaims
}

View File

@ -51,6 +51,5 @@ type Document struct {
Version string `json:"version"`
Permissions Permissions `json:"permissions,omitempty"`
ReferenceData ReferenceData `json:"referenceData"`
CanEdit bool
CanFill bool
Actions []string
}

View File

@ -15,19 +15,12 @@
* limitations under the License.
*
*/
package config
package models
type Extensions struct {
Viewed []string `json:"viewed"`
Edited []string `json:"edited"`
Converted []string `json:"converted"`
Filled []string `json:"filled"`
}
type ExtensionTypes struct {
Spreadsheet []string `json:"spreadsheet"`
Presentation []string `json:"presentation"`
Document []string `json:"document"`
Pdf []string `json:"pdf"`
Diagram []string `json:"diagram"`
type Format struct {
Name string `json:"name"`
FormatType string `json:"type"`
Actions []string `json:"actions"`
Convert []string `json:"convert"`
Mime []string `json:"mime"`
}

View File

@ -17,7 +17,7 @@
*/
package models
import "github.com/golang-jwt/jwt"
import "github.com/golang-jwt/jwt/v5"
type ReferenceData struct {
FileKey string `json:"fileKey"`
@ -32,5 +32,5 @@ type Reference struct {
Key string `json:"key"`
Url string `json:"url"`
Token string `json:"token,omitempty"`
jwt.StandardClaims
jwt.RegisteredClaims
}

View File

@ -32,11 +32,13 @@ type User struct {
Avatar bool `json:"avatar"`
Goback map[string]interface{} `json:"goback"`
Close map[string]interface{} `json:"close"`
Roles []string `json:"roles"`
}
type UserInfo struct {
Id string `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
Image string `json:"image"`
Id string `json:"id"`
Name string `json:"name"`
Roles []string `json:"roles"`
Email string `json:"email"`
Image string `json:"image"`
}

View File

@ -30,9 +30,8 @@ import (
)
type Server struct {
Http *http.Server
Config config.ApplicationConfig
ServerSpecification config.SpecificationConfig
Http *http.Server
Config config.ApplicationConfig
*api.ServerAPI
Logger *zap.SugaredLogger
*managers.Managers
@ -40,16 +39,15 @@ type Server struct {
isRunning bool
}
func New(config config.ApplicationConfig, specification config.SpecificationConfig,
func New(config config.ApplicationConfig,
logger *zap.SugaredLogger, managers *managers.Managers, api *api.ServerAPI, reg *handlers.CallbackRegistry) *Server {
srv := Server{
Config: config,
ServerSpecification: specification,
ServerAPI: api,
Logger: logger,
isRunning: false,
Managers: managers,
CallbackRegistry: reg,
Config: config,
ServerAPI: api,
Logger: logger,
isRunning: false,
Managers: managers,
CallbackRegistry: reg,
}
r := srv.configureRouter()

View File

@ -1,3 +0,0 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M19 6H5L5 15H19V6ZM5 4C3.89543 4 3 4.89543 3 6V15C3 16.1046 3.89543 17 5 17H10V18H6V20H18V18H14V17H19C20.1046 17 21 16.1046 21 15V6C21 4.89543 20.1046 4 19 4H5Z" fill="#444444"/>
</svg>

Before

Width:  |  Height:  |  Size: 331 B

View File

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M5 19H8.11111L8.84845 18.2627L5.73734 15.1516L5 15.8889V19ZM10.2627 16.8484L19 8.11111V6.55556H17.4444V5H15.8889L7.15155 13.7373L10.2627 16.8484Z" fill="#444444"/>
</svg>

After

Width:  |  Height:  |  Size: 316 B

View File

@ -1,5 +0,0 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="4" y="6" width="16" height="13" rx="1" stroke="#444444" stroke-width="2"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.148 8.69651C13.8858 8.43384 13.4601 8.43384 13.1979 8.69651V8.69651C12.9362 8.95858 12.9362 9.38302 13.1979 9.64509L15.3401 11.7908C15.7296 12.1809 15.7299 12.8126 15.3409 13.2031L13.1967 15.3554C12.9357 15.6173 12.9357 16.041 13.1967 16.3029V16.3029C13.4591 16.5663 13.8855 16.5663 14.1478 16.3029L17.3302 13.1086V13.1086C17.668 12.7702 17.668 12.2222 17.3302 11.8838L14.148 8.69651Z" fill="#444444"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.85199 16.3035C10.1142 16.5662 10.5399 16.5662 10.8021 16.3035V16.3035C11.0638 16.0414 11.0638 15.617 10.8021 15.3549L8.65987 13.2092C8.2704 12.8191 8.27006 12.1874 8.65911 11.7969L10.8033 9.64461C11.0643 9.38266 11.0643 8.959 10.8033 8.69706V8.69706C10.5409 8.43371 10.1145 8.43371 9.85218 8.69706L6.66983 11.8914V11.8914C6.33201 12.2298 6.33201 12.7778 6.66983 13.1162L9.85199 16.3035Z" fill="#444444"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,6 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M14.326 18.6739C13.8912 18.2391 13.8912 17.5342 14.326 17.0994L20.0993 11.3261C20.5341 10.8913 21.239 10.8913 21.6738 11.3261C22.1086 11.7609 22.1086 12.4658 21.6738 12.9006L15.9006 18.6739C15.4658 19.1087 14.7608 19.1087 14.326 18.6739Z" fill="#444444"/>
<path d="M14.326 5.3261C14.7608 4.8913 15.4658 4.8913 15.9006 5.3261L21.6738 11.0994C22.1086 11.5342 22.1086 12.2391 21.6738 12.6739C21.239 13.1087 20.5341 13.1087 20.0993 12.6739L14.326 6.90063C13.8912 6.46583 13.8912 5.76089 14.326 5.3261Z" fill="#444444"/>
<path d="M9.67385 5.3261C10.1086 5.76089 10.1086 6.46583 9.67385 6.90063L3.90061 12.6739C3.46582 13.1087 2.76088 13.1087 2.32609 12.6739C1.8913 12.2391 1.8913 11.5342 2.32609 11.0994L8.09933 5.3261C8.53412 4.8913 9.23905 4.8913 9.67385 5.3261Z" fill="#444444"/>
<path d="M9.67385 18.6739C9.23905 19.1087 8.53412 19.1087 8.09933 18.6739L2.32609 12.9006C1.8913 12.4658 1.8913 11.7609 2.32609 11.3261C2.76088 10.8913 3.46582 10.8913 3.90061 11.3261L9.67385 17.0994C10.1086 17.5342 10.1086 18.2391 9.67385 18.6739Z" fill="#444444"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 379 B

After

Width:  |  Height:  |  Size: 379 B

View File

@ -1,5 +1,3 @@
<svg width="20" height="14" viewBox="0 0 20 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="20" height="2" rx="1" fill="white"/>
<rect y="6" width="20" height="2" rx="1" fill="white"/>
<rect y="12" width="20" height="2" rx="1" fill="white"/>
</svg>
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M16 5C17.6569 5 19 6.34315 19 8V16C19 17.6569 17.6569 19 16 19H8C6.34315 19 5 17.6569 5 16V8C5 6.34315 6.34315 5 8 5H16ZM11 7V17H16L16.1025 16.9951C16.573 16.9472 16.9472 16.573 16.9951 16.1025L17 16V8C17 7.48232 16.6067 7.05621 16.1025 7.00488L16 7H11Z" fill="#EFEFEF"/>
</svg>

Before

Width:  |  Height:  |  Size: 278 B

After

Width:  |  Height:  |  Size: 383 B

View File

@ -1,3 +0,0 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 3C6.89543 3 6 3.89543 6 5V19C6 20.1046 6.89543 21 8 21H16C17.1046 21 18 20.1046 18 19V5C18 3.89543 17.1046 3 16 3H8ZM16.8462 6H7.15385V18H16.8462V6ZM10.3846 4H13.6154V5H10.3846V4ZM12 20C12.2974 20 12.5385 19.7761 12.5385 19.5C12.5385 19.2239 12.2974 19 12 19C11.7026 19 11.4615 19.2239 11.4615 19.5C11.4615 19.7761 11.7026 20 12 20Z" fill="#444444"/>
</svg>

Before

Width:  |  Height:  |  Size: 506 B

View File

@ -0,0 +1,4 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 5C4 3.89543 4.89543 3 6 3H15C16.1046 3 17 3.89543 17 5V7H16V6H5V18H16V17H17V19C17 20.1046 16.1046 21 15 21H6C4.89543 21 4 20.1046 4 19V5ZM12 4H9V5H12V4ZM11 19.5C11 19.7761 10.7761 20 10.5 20C10.2239 20 10 19.7761 10 19.5C10 19.2239 10.2239 19 10.5 19C10.7761 19 11 19.2239 11 19.5Z" fill="#444444"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 16H14L14.6464 15.3536L12.6464 13.3536L12 14V16ZM15.3536 14.6464L21 9V8H20V7H19L13.3536 12.6464L15.3536 14.6464Z" fill="#444444"/>
</svg>

After

Width:  |  Height:  |  Size: 638 B

View File

@ -0,0 +1,4 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 5C4 3.89543 4.89543 3 6 3H15C16.1046 3 17 3.89543 17 5V7H16V6H5V18H16V17H17V19C17 20.1046 16.1046 21 15 21H6C4.89543 21 4 20.1046 4 19V5ZM12 4H9V5H12V4ZM11 19.5C11 19.7761 10.7761 20 10.5 20C10.2239 20 10 19.7761 10 19.5C10 19.2239 10.2239 19 10.5 19C10.7761 19 11 19.2239 11 19.5Z" fill="#444444"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M14 8C11.3252 8 8.89946 9.40288 7.10954 11.6815C6.96349 11.8682 6.96349 12.129 7.10954 12.3157C8.89946 14.5971 11.3252 16 14 16C16.6748 16 19.1005 14.5971 20.8905 12.3185C21.0365 12.1318 21.0365 11.871 20.8905 11.6843C19.1005 9.40288 16.6748 8 14 8ZM14.1955 14.9939C12.3863 15.1077 10.8923 13.6166 11.0061 11.8045C11.0995 10.3105 12.3105 9.09949 13.8045 9.00611C15.6137 8.89231 17.1077 10.3834 16.9939 12.1955C16.8976 13.6866 15.6866 14.8976 14.1955 14.9939ZM14.0641 12.998C13.4609 13.0359 12.9625 12.5392 13.0022 11.9359C13.0329 11.4373 13.4375 11.0346 13.9359 11.002C14.5391 10.9641 15.0375 11.4608 14.9978 12.0641C14.9653 12.5645 14.5607 12.9673 14.0641 12.998Z" fill="#444444"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.33331 10C4.22665 10 3.33331 10.8933 3.33331 12C3.33331 13.1067 4.22665 14 5.33331 14C6.43998 14 7.33331 13.1067 7.33331 12C7.33331 10.8933 6.43998 10 5.33331 10ZM18.6666 10C17.56 10 16.6666 10.8933 16.6666 12C16.6666 13.1067 17.56 14 18.6666 14C19.7733 14 20.6666 13.1067 20.6666 12C20.6666 10.8933 19.7733 10 18.6666 10ZM12 10C10.8933 10 9.99998 10.8933 9.99998 12C9.99998 13.1067 10.8933 14 12 14C13.1066 14 14 13.1067 14 12C14 10.8933 13.1066 10 12 10Z" fill="#808080"/>
</svg>

After

Width:  |  Height:  |  Size: 588 B

View File

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 6C8.17879 6 4.71351 8.10432 2.15649 11.5223C1.94784 11.8023 1.94784 12.1935 2.15649 12.4736C4.71351 15.8957 8.17879 18 12 18C15.8212 18 19.2865 15.8957 21.8435 12.4777C22.0522 12.1977 22.0522 11.8065 21.8435 11.5264C19.2865 8.10432 15.8212 6 12 6ZM12.2607 15.9919C9.84844 16.1436 7.8564 14.1554 8.00813 11.7393C8.13264 9.74729 9.74728 8.13265 11.7393 8.00815C14.1516 7.85641 16.1436 9.84456 15.9919 12.2607C15.8635 14.2488 14.2488 15.8635 12.2607 15.9919ZM12.1282 13.9959C10.9219 14.0718 9.92498 13.0783 10.0044 11.8718C10.0658 10.8747 10.8749 10.0691 11.8718 10.0041C13.0781 9.92821 14.075 10.9217 13.9956 12.1282C13.9305 13.1289 13.1215 13.9345 12.1282 13.9959Z" fill="#444444"/>
</svg>

After

Width:  |  Height:  |  Size: 838 B

View File

@ -545,4 +545,76 @@ function toggleUserDescr(event) {
if (list.classList.contains("active")) list.classList.remove("active");
else list.classList.add("active");
}
}
function toggleContextMenu(event) {
let contextMenu = document.querySelector("#mobileContextMenu");
let target = event.currentTarget.parentNode.parentNode.cloneNode(true);
const closeContextMenu = () => {
contextMenu.classList.remove("active");
}
if (contextMenu.classList.contains("active") || !target.classList.contains("tableRow")) {
if (event.target.id == "mobileContextMenuBody") closeContextMenu();
return;
}
let contextBody = document.querySelector("#mobileContextMenuBody");
contextBody.innerHTML = "";
let startY = 0;
let startScroll = 0;
contextBody.addEventListener('touchstart', (e) => {
startY = e.touches[0].clientY;
startScroll = contextBody.scrollTop;
});
contextBody.addEventListener('touchmove', (e) => {
const currentY = e.touches[0].clientY;
const diff = currentY - startY;
if (diff > 10 && (contextBody.scrollTop === 0 || contextBody.scrollTop === startScroll)) {
closeContextMenu();
}
});
let thead = document.createElement("thead");
thead.appendChild(target.children[0]);
const observer = new IntersectionObserver(
([e]) => e.target.classList.toggle("is-pinned", e.intersectionRatio < 1),
{ threshold: [1] }
);
observer.observe(thead);
let tbody = document.createElement("tbody");
for (let td of Array.from(target.children).slice(0, -1)){
if (td.getAttribute("data-section")){
let section = document.createElement("tr");
section.innerText = td.getAttribute("data-section");
section.classList.add("context-section");
tbody.appendChild(section);
}
if (td.children.length == 0) continue;
let action = document.createElement("div");
action.innerText = td.children[0].children[0].getAttribute("title");
td.children[0].appendChild(action);
td.children[0].onclick = () => {
setTimeout(() => window.location.reload(), 0);
}
td.style.display = "block";
td.classList.remove("downloadContentCellShift");
td.classList.remove("firstContentCellViewers");
let tr = document.createElement("tr");
tr.appendChild(td);
tbody.appendChild(tr);
}
let table = document.createElement("table");
table.appendChild(thead);
table.appendChild(tbody);
contextBody.appendChild(table);
contextMenu.classList.add("active");
}

View File

@ -51,8 +51,8 @@
.tableHeader td:last-child, .tableRow td:last-child {
width: 10%;
text-align: center;
padding: 0 !important;
text-align: right;
display: revert;
}
.tableHeader {
@ -81,6 +81,11 @@ menu.links {
.scroll-table-body {
overflow-y: auto;
width: 100%;
}
.scroll-table-body td {
padding: 0 !important;
}
.stored-list {

View File

@ -34,15 +34,15 @@
}
.tableHeaderCellFileName {
width: 25%;
width: 29%;
}
.tableHeaderCellEditors {
width: 13%;
width: 12%;
}
.tableHeaderCellViewers {
width: 18%;
width: 15%;
text-align: right;
}
@ -84,6 +84,7 @@
}
.tableRow,
.storedHeader,
menu.links {
width: 90%;
}
@ -182,9 +183,14 @@
@media (max-width: 715px) {
.tableRow,
.storedHeader,
menu.links {
width: 45%;
}
.storedHeaderClearAll{
padding-right: 24px;
}
}
@media (max-width: 670px) and (min-width: 620px){
.main-panel{
@ -220,15 +226,15 @@
.tableRow td:first-child {
flex-grow: 0;
width: 15%;
width: 26%;
}
.tableHeaderCellFileName {
width: 9%;
width: 15%;
}
.tableHeaderCellEditors {
width: 13%;
width: 3%;
}
.tableHeaderCellViewers {
@ -253,12 +259,12 @@
}
.tableHeaderCellEditors {
width: 15%;
width: 13%;
text-align: left;
}
.tableHeaderCellFileName {
width: 28%;
width: 29%;
}
.tableHeaderCellViewers {
@ -281,6 +287,7 @@
}
.tableRow,
.storedHeader,
menu.links {
width: 75%;
}
@ -302,6 +309,10 @@
.firstContentCellViewers {
margin-left: 0;
}
.storedHeaderClearAll {
padding-right: 39px;
}
}
@media (max-width: 890px) and (min-width: 769px ) {
@ -317,6 +328,7 @@
}
.tableRow,
.storedHeader,
menu.links {
width: 95%;
}
@ -337,7 +349,7 @@
}
.tableHeaderCellFileName {
width: 20%;
width: 22%;
}
.tableHeaderCellEditors {
@ -346,18 +358,22 @@
}
.tableHeaderCellViewers {
width: 19%;
width: 15%;
}
.tableHeaderCellAction {
width: 19%;
padding-right: 45px;
}
.storedHeaderClearAll {
padding-right: 29px;
}
}
@media (max-width: 890px) {
.tableRow td:first-child {
max-width: 17%;
max-width: 22%;
}
#portal-info {
@ -437,61 +453,6 @@
padding: 16px 0 6px;
}
.tableRow,
menu.links {
width: 40%;
}
.tableRow td {
border: none;
}
.firstContentCellShift {
border: none;
flex-basis: 10%;
flex-grow: 1;
}
.downloadContentCellShift {
max-width: 7%;
margin-right: 24px;
margin-left: 0;
}
.contentCells-icon {
width: 13%;
}
.tableRow td:last-child {
width: 7%;
padding-right: 0px;
border: none;
}
.contentCells-shift {
padding-right: 0px;
}
.downloadContentCellShift:after {
width: 85%;
}
.firstContentCellViewers {
margin-left: 0;
border-bottom: 1px solid #e5e5e5 !important;
}
.firstContentCellViewers ~ td {
border-bottom: 1px solid #e5e5e5;
}
.tableRow td:first-child{
border: none;
width: 85%;
}
.contentCellsEmpty{
display: none;
width: 1%;
}
/* Mobile Upload*/
.blockUI.blockMsg.blockPage.ui-dialog.ui-widget.ui-corner-all.ui-widget-content.ui-draggable {
width: 344px !important;
@ -566,104 +527,7 @@
}
}
@media (max-width: 560px) and (min-width: 510px) {
.contentCells-icon {
width: 13%;
}
.downloadContentCellShift {
padding-right: 16px;
max-width: 4%;
}
}
@media (max-width: 510px) and (min-width: 470px) {
.tableRow,
menu.links {
width: 35%;
}
.tableRow td:first-child{
width: 83%;
}
.contentCells-icon {
width: 13%;
}
.downloadContentCellShift {
max-width: 6%;
padding-right: 6px;
}
.firstContentCellShift {
flex-basis: 9%;
}
.tableRow td:last-child {
padding-right: 28px;
}
}
@media (max-width: 470px) and (min-width: 420px) {
.tableRow,
menu.links {
width: 30%;
}
.tableRow td:first-child{
width: 85%;
}
.contentCells-icon {
width: 11%;
}
.downloadContentCellShift {
max-width: 3%;
padding-right: 0px;
padding-left: 0;
}
.firstContentCellShift {
margin-left: 2px;
flex-basis: 14%;
}
.tableRow td:last-child {
width: 5%;
padding-right: 63px;
}
.firstContentCellViewers{
padding-right: 2px;
width: 12%;
}
.contentCellsEmpty{
display: none;
}
}
@media (max-width: 420px) {
.tableRow,
menu.links {
width: 25%;
}
.tableRow td:last-child {
width: 6%;
padding-right: 16px;
}
.downloadContentCellShift {
max-width: 4%;
margin-right: 18px;
margin-left: -1px;
}
.firstContentCellShift {
flex-basis: 2%;
}
.contentCells-icon{
width: 12%;
}
footer table td {
margin: 0;
padding-right: 5px;
@ -674,10 +538,6 @@
padding-right: 5px;
margin: 0;
}
.firstContentCellViewers{
padding-right: 2px;
width: 11%;
}
}
@media (max-width: 1160px) {
@ -686,20 +546,15 @@
}
}
@media (min-width: 593px) {
.contentCellsEmpty {
display: none;
}
}
@media (max-width: 769px) and (min-width: 715px){
.tableRow,
.storedHeader,
menu.links {
width: 50%;
}
}
@media (max-width: 510px) {
.tableRow td:first-child{
flex-grow: 0;
.storedHeaderClearAll{
padding-right: 26px;
}
}
@media (max-width: 1100px) and (min-width: 890px){
@ -781,8 +636,8 @@
margin: 0;
position: fixed;
left: 0;
height: calc(100% - 124px);
z-index:99;
height: calc(100% - 44px);
z-index: 101;
}
.left-panel.active {
@ -900,16 +755,37 @@
.tableRow {
border-bottom: 1px solid #e5e5e5;
padding: 16px 0;
padding: 12px 0;
width: 100%;
flex-wrap: nowrap;
}
.tableRow td:first-child {
width: 100%;
}
.tableRow td:last-child {
display: block;
width: 24px;
}
.contentCells {
padding: 0;
font-size: 13px;
}
.contentCells-icon {
width: auto;
display: none;
}
.stored-edit {
height: 12px;
padding: 6px 0 6px 34px;
}
.stored-edit span {
font-size: 14px;
font-size: 13px;
}
.header-list {
@ -917,7 +793,7 @@
}
.firstContentCellViewers {
border-bottom: none !important;
margin: 0;
}
.firstContentCellViewers ~ td {
@ -952,4 +828,19 @@
.user-block-table {
height: auto;
}
.upload-panel {
padding: 12px 0;
}
.user-block-table td select {
height: 48px;
padding-left: 12px;
border-radius: 6px;
border-color: #aaaaaa;
}
.user-block-table tr:last-child {
display: none;
}
}

View File

@ -753,7 +753,6 @@ footer table tr td:first-child {
.contentCells {
display: block;
border-bottom: 1px solid #EFEFEF;
font-family: 'Open Sans', sans-serif;
font-size: 16px;
padding: 4px;
@ -919,15 +918,15 @@ html {
.tableRow td:first-child {
display: flex;
flex-grow: 1;
max-width: 25%;
max-width: 29%;
}
.tableHeaderCellFileName {
width: 20%;
width: 24%;
}
.tableHeaderCellEditors {
width: 20%;
width: 17%;
}
.tableHeaderCellViewers {
@ -984,4 +983,104 @@ html {
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
}
.tableRow td:last-child {
display: none;
}
#mobileContextMenu {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100vh;
background-color: rgba(51, 51, 51, 0.3);
display: flex;
justify-content: center;
align-items: flex-end;
z-index: 100;
opacity: 0;
visibility: hidden;
transition: opacity 0.3s ease, visibility 0s linear 0.4s;
}
#mobileContextMenu.active {
visibility: visible;
opacity: 1;
transition: opacity 0.3s ease;
}
#mobileContextMenu .context-body {
width: 100%;
max-height: 100%;
transform: translateY(100%);
transition: transform 0.4s cubic-bezier(0.25, 0.8, 0.25, 1);
overflow-y: auto;
overflow-x: hidden;
scrollbar-width: none;
}
#mobileContextMenu.active .context-body {
transform: translateY(0);
}
#mobileContextMenu table {
background-color: white;
width: 100%;
margin-top: 150px;
padding-bottom: 96px;
}
#mobileContextMenu thead {
padding: 12px 16px 0;
height: 48px;
position: sticky;
top: -1px;
display: flex;
align-items: center;
background-color: white;
}
#mobileContextMenu thead:not(.is-pinned)::after {
content: '';
position: absolute;
left: 16px;
right: 16px;
bottom: 0px;
height: 1px;
background: #e2e2e2;
}
#mobileContextMenu thead.is-pinned {
box-shadow: 0px 4px 6px 0px #CCCCCC4D;
transition: all 0.4s ease-out;
}
#mobileContextMenu tbody {
padding: 0 16px;
display: block
}
#mobileContextMenu tr {
display: block;
padding: 12px;
}
.context-section {
padding: 24px 0 6px !important;
font-size: 13px;
font-weight: 600;
color: #808080;
}
#mobileContextMenu a:not(.stored-edit) {
display: flex;
flex-direction: row;
align-items: center;
text-decoration: none;
}
#mobileContextMenu img {
margin-right: 8px;
}

View File

@ -404,6 +404,18 @@
innerAlert(xhr.responseText);
docEditor.refreshFile(JSON.parse(xhr.responseText));
};
};
var onRequestStartFilling = function(event) {
var data = event.data;
var submit = confirm("Start filling?\n" + JSON.stringify(data));
if (submit) {
docEditor.startFilling(true);
}
};
var onStartFilling = function(event) {
innerAlert("The form is ready to fill out.");
};
var events = {
@ -424,6 +436,8 @@
if (config.editorConfig.user.id !== "uid-0") {
events["onRequestRefreshFile"] = onRequestRefreshFile;
events['onRequestStartFilling'] = onRequestStartFilling;
events['onStartFilling'] = onStartFilling;
events["onRequestClose"] = onRequestClose;
events["onRequestSendNotify"] = onRequestSendNotify;
events["onRequestEditRights"] = onRequestEditRights;

View File

@ -40,13 +40,13 @@
</div>
<menu class="responsive-nav">
<li>
<a href="#" onclick="toggleSidePanel(event)">
<img src ="static/images/mobile-menu.svg" alt="ONLYOFFICE" />
<a href="./">
<img src ="static/images/mobile-logo.svg" alt="ONLYOFFICE" />
</a>
</li>
<li>
<a href="./">
<img src ="static/images/mobile-logo.svg" alt="ONLYOFFICE" />
<a href="#" onclick="toggleSidePanel(event)">
<img src ="static/images/mobile-menu.svg" alt="ONLYOFFICE" />
</a>
</li>
</menu>
@ -146,13 +146,18 @@
{{ else }}
<div id="portal-info" style="display: table-cell">
{{ end }}
<span class="portal-name">ONLYOFFICE Document Editors Welcome!</span>
<span class="portal-name">Welcome to ONLYOFFICE Docs!</span>
<span class="portal-descr">Get started with a live demo of ONLYOFFICE Docs, a powerful open-source office suite for your browser.</span>
<span class="portal-descr">
Get started with a demo-sample of ONLYOFFICE Document Editors, the first html5-based editors.
<br /> You may upload your own documents for testing using the "<b>Upload file</b>" button and <b>selecting</b> the necessary files on your PC.
You can test editing features in real-time and explore multi-user collaboration:
<ul>
<li>Create a new Document, Spreadsheet, Presentation, or PDF Form or use the sample files</li>
<li>Upload your own files to test using the Upload file button</li>
<li>Select your username and language to simulate different users and environments</li>
<li>Try real-time collaboration by opening the same document using different users in different Web browser sessions</li>
</ul>
</span>
<span class="portal-descr">Please do NOT use this integration example on your own server without proper code modifications, it is intended for testing purposes only. In case you enabled this test example, disable it before going for production.</span>
<span class="portal-descr">You can open the same document using different users in different Web browser sessions, so you can check out multi-user editing functions.</span>
<span class="portal-descr">⚠️ This example is intended for testing purposes only. Do not use it on a production server without proper code modifications. If you have enabled this test demo, please disable it before deploying the editors in production.</span>
{{ range .Users }}
<div class="user-descr" onclick="toggleUserDescr(event)">
<b>{{ if eq .Username "" }} Anonymous {{ else }} {{ .Username }} {{ end }}</b>
@ -194,98 +199,101 @@
<span>{{ .Title }}</span>
</a>
</td>
{{ if .CanEdit }}
<td class="contentCells contentCells-icon">
<!-- 1-2 -->
{{ if or (contains .Actions "edit") (contains .Actions "lossy-edit") }}
<td class="contentCells contentCells-icon" data-section="EDITOR">
<a href="editor?fileName={{ .Title }}&type=desktop&mode=edit" target="_blank">
<img src="static/images/desktop.svg" alt="Open in editor for full size screens" title="Open in editor for full size screens"/>
<img src="static/images/edit.svg" alt="Open for full size screens" title="Open for full size screens"/>
</a>
</td>
<td class="contentCells contentCells-icon">
<a href="editor?fileName={{ .Title }}&type=mobile&mode=edit" target="_blank">
<img src="static/images/mobile.svg" alt="Open in editor for mobile devices" title="Open in editor for mobile devices"/>
</a>
</td>
{{ if ne .FileType "pdf" }}
<td class="contentCells contentCells-icon">
<a href="editor?fileName={{ .Title }}&type=desktop&mode=comment" target="_blank">
<img src="static/images/comment.svg" alt="Open in editor for comment" title="Open in editor for comment"/>
</a>
</td>
{{ end }}
{{ if eq .FileType "word" }}
<td class="contentCells contentCells-icon">
<a href="editor?fileName={{ .Title }}&type=desktop&mode=review" target="_blank">
<img src="static/images/review.svg" alt="Open in editor for review" title="Open in editor for review"/>
</a>
</td>
{{ else if eq .FileType "cell" }}
<td class="contentCells contentCells-icon">
<a href="editor?fileName={{ .Title }}&type=desktop&mode=filter" target="_blank">
<img src="static/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>
{{ end }}
{{ if eq .FileType "word" }}
<td class="contentCells contentCells-icon">
<a href="editor?fileName={{ .Title }}&type=desktop&mode=blockcontent" target="_blank">
<img src="static/images/block-content.svg" alt="Open in editor without content control modification" title="Open in editor without content control modification"/>
</a>
</td>
{{ else }}
<td class="contentCells contentCells-icon"></td>
{{ end }}
{{ if eq .FileType "slide" }}
<td class="contentCells contentCells-icon "></td>
{{ end }}
{{ if .CanFill }}
<td class="contentCells contentCells-shift contentCells-icon firstContentCellShift">
<a href="editor?fileName={{ .Title }}&type=desktop&mode=fillForms" target="_blank">
<img src="static/images/fill-forms.svg" alt="Open in editor for filling in forms" title="Open in editor for filling in forms"/>
</a>
</td>
{{ else }}
<td class="contentCells contentCells-shift contentCells-icon firstContentCellShift"></td>
{{ end }}
{{ else if .CanFill }}
<td class="contentCells contentCells-icon"></td>
<td class="contentCells contentCells-icon">
<a href="editor?fileName={{ .Title }}&type=mobile&mode=fillForms" target="_blank">
<img src="static/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>
<td class="contentCells contentCells-icon"></td>
<td class="contentCells contentCells-icon"></td>
<td class="contentCells contentCells-icon"></td>
<td class="contentCells contentCells-icon">
<a href="editor?fileName={{ .Title }}&type=desktop&mode=fillForms" target="_blank">
<img src="static/images/fill-forms.svg" alt="Open in editor for filling in forms" title="Open in editor for filling in forms"/>
<img src="static/images/mobileEdit.svg" alt="Open for mobile devices" title="Open for mobile devices"/>
</a>
</td>
{{ else }}
<td class="contentCells contentCells-shift contentCells-icon contentCellsEmpty" colspan="6"></td>
<td class="contentCells contentCells-icon" data-section="EDITOR"></td>
<td class="contentCells contentCells-icon"></td>
{{ end }}
<td class="contentCells contentCells-icon firstContentCellViewers">
<!-- 3 -->
{{ if contains .Actions "comment" }}
<td class="contentCells contentCells-icon">
<a href="editor?fileName={{ .Title }}&type=desktop&mode=comment" target="_blank">
<img src="static/images/comment.svg" alt="Open for comment" title="Open for comment"/>
</a>
</td>
{{ else }}
<td class="contentCells contentCells-icon"></td>
{{ end }}
<!-- 4-5 -->
{{ if contains .Actions "fill" }}
<td class="contentCells contentCells-icon">
<a href="editor?fileName={{ .Title }}&type=desktop&mode=fillForms" target="_blank">
<img src="static/images/formsubmit.svg" alt="Open for filling in forms" title="Open for filling in forms"/>
</a>
</td>
<td class="contentCells contentCells-icon contentCells-shift firstContentCellShift">
<a href="editor?fileName={{ .Title }}&type=mobile&mode=fillForms" target="_blank">
<img src="static/images/mobile-fill-forms.svg" alt="Open for filling in forms for mobile devices" title="Open for filling in forms for mobile devices"/>
</a>
</td>
{{ else }}
<!-- 4 -->
{{ if contains .Actions "review" }}
<td class="contentCells contentCells-icon">
<a href="editor?fileName={{ .Title }}&type=desktop&mode=review" target="_blank">
<img src="static/images/review.svg" alt="Open for review" title="Open for review"/>
</a>
</td>
{{ else if contains .Actions "customfilter" }}
<td class="contentCells contentCells-icon">
<a href="editor?fileName={{ .Title }}&type=desktop&mode=filter" target="_blank">
<img src="static/images/filter.svg" alt="Open without access to change the filter" title="Open without access to change the filter" />
</a>
</td>
{{ else }}
<td class="contentCells contentCells-icon"></td>
{{ end }}
<!-- 5 -->
{{ if and (contains .Actions "edit") (eq .FileType "word") }}
<td class="contentCells contentCells-icon contentCells-shift">
<a href="editor?fileName={{ .Title }}&type=desktop&mode=blockcontent" target="_blank">
<img src="static/images/block-content.svg" alt="Open without content control modification" title="Open without content control modification"/>
</a>
</td>
{{ else }}
<td class="contentCells contentCells-icon contentCells-shift firstContentCellShift"></td>
{{ end }}
{{ end }}
<td class="contentCells contentCells-icon firstContentCellViewers" data-section="VIEWERS">
<a href="editor?fileName={{ .Title }}&type=desktop&mode=view" target="_blank">
<img src="static/images/desktop.svg" alt="Open in viewer for full size screens" title="Open in viewer for full size screens"/>
<img src="static/images/view.svg" alt="Open for full size screens" title="Open for full size screens"/>
</a>
</td>
<td class="contentCells contentCells-icon">
<a href="editor?fileName={{ .Title }}&type=mobile&mode=view" target="_blank">
<img src="static/images/mobile.svg" alt="Open in viewer for mobile devices" title="Open in viewer for mobile devices"/>
<img src="static/images/mobileView.svg" alt="Open for mobile devices" title="Open for mobile devices"/>
</a>
</td>
<td class="contentCells contentCells-icon contentCells-shift">
<a href="editor?fileName={{ .Title }}&type=embedded&mode=embedded" target="_blank">
<img src="static/images/embeded.svg" alt="Open in embedded mode" title="Open in embedded mode"/>
<img src="static/images/embedview.svg" alt="Open in embedded mode" title="Open in embedded mode"/>
</a>
</td>
{{ if ne .FileType "" }}
<td class="contentCells contentCells-icon">
<td class="contentCells contentCells-icon" data-section="ACTIONS">
<a class="convert-file" data="{{ .Title }}" data-type="{{ .FileType }}">
<img class="icon-action" src="static/images/convert.svg" alt="Convert" title="Convert" /></a>
</td>
{{ else }}
<td class="contentCells contentCells-icon downloadContentCellShift"></td>
<td class="contentCells contentCells-icon downloadContentCellShift" data-section="ACTIONS"></td>
{{ end }}
<td class="contentCells contentCells-icon downloadContentCellShift">
<a href="download?fileName={{ .Title }}">
@ -297,6 +305,11 @@
<img class="icon-action" src="static/images/delete.svg" alt="Delete" title="Delete" />
</a>
</td>
<td class="contentCells contentCells-icon">
<a href="#" onclick="toggleContextMenu(event)">
<img src="static/images/open-context.svg" alt="Open context menu" title="Open context menu" />
</a>
</td>
</tr>
{{ end }}
</tbody>
@ -407,6 +420,11 @@
</div>
</footer>
<div id="mobileContextMenu" onclick="toggleContextMenu(event)">
<div class="context-body" id="mobileContextMenuBody">
</div>
</div>
<script type="text/javascript" src="static/javascripts/jquery-3.6.4.min.js"></script>
<script type="text/javascript" src="static/javascripts/jquery-migrate-3.4.1.min.js"></script>
<script type="text/javascript" src="static/javascripts/jquery-ui.js"></script>

View File

@ -1,161 +0,0 @@
/**
*
* (c) Copyright Ascensio System SIA 2025
*
* 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.
*
*/
package utils
import (
"encoding/json"
"io"
"os"
"path/filepath"
"runtime"
"slices"
)
type Format struct {
Name string `json:"name"`
FormatType string `json:"type"`
Actions []string `json:"actions"`
Convert []string `json:"convert"`
Mime []string `json:"mime"`
}
type DefaultFormatManager struct {
formats []Format
}
type FormatManager interface {
GetFormats() []Format
GetViewedExtensions() []string
GetEditedExtensions() []string
GetConvertedExtensions() []string
GetFilledExtensions() []string
GetDocumentExtensions() []string
GetSpreadsheetExtensions() []string
GetPresentationExtensions() []string
GetPdfExtensions() []string
GetDiagramExtensions() []string
}
func NewFormatManager() (FormatManager, error) {
_, b, _, _ := runtime.Caller(0)
parentDir := filepath.Dir(filepath.Dir(b))
path := filepath.Join(parentDir, "static", "assets", "document-formats", "onlyoffice-docs-formats.json")
fileContent, err := os.Open(path)
if err != nil {
return DefaultFormatManager{}, err
}
defer fileContent.Close()
byteResult, _ := io.ReadAll(fileContent)
var formats []Format
err = json.Unmarshal(byteResult, &formats)
if err != nil {
return DefaultFormatManager{}, err
}
return DefaultFormatManager{
formats,
}, err
}
func (fm DefaultFormatManager) GetFormats() []Format {
return fm.formats
}
func (fm DefaultFormatManager) GetViewedExtensions() (viewed []string) {
for _, f := range fm.formats {
if slices.Contains(f.Actions, "view") {
viewed = append(viewed, f.Name)
}
}
return
}
func (fm DefaultFormatManager) GetEditedExtensions() (edited []string) {
for _, f := range fm.formats {
if slices.Contains(f.Actions, "edit") {
edited = append(edited, f.Name)
}
}
return
}
func (fm DefaultFormatManager) GetConvertedExtensions() (converted []string) {
for _, f := range fm.formats {
if slices.Contains(f.Actions, "auto-convert") {
converted = append(converted, f.Name)
}
}
return converted
}
func (fm DefaultFormatManager) GetFilledExtensions() (filled []string) {
for _, f := range fm.formats {
if slices.Contains(f.Actions, "fill") {
filled = append(filled, f.Name)
}
}
return filled
}
func (fm DefaultFormatManager) GetDocumentExtensions() (word []string) {
for _, f := range fm.formats {
if f.FormatType == "word" {
word = append(word, f.Name)
}
}
return
}
func (fm DefaultFormatManager) GetSpreadsheetExtensions() (cell []string) {
for _, f := range fm.formats {
if f.FormatType == "cell" {
cell = append(cell, f.Name)
}
}
return
}
func (fm DefaultFormatManager) GetPresentationExtensions() (slide []string) {
for _, f := range fm.formats {
if f.FormatType == "slide" {
slide = append(slide, f.Name)
}
}
return
}
func (fm DefaultFormatManager) GetPdfExtensions() (pdf []string) {
for _, f := range fm.formats {
if f.FormatType == "pdf" {
pdf = append(pdf, f.Name)
}
}
return
}
func (fm DefaultFormatManager) GetDiagramExtensions() (diagram []string) {
for _, f := range fm.formats {
if f.FormatType == "diagram" {
diagram = append(diagram, f.Name)
}
}
return
}

Some files were not shown because too many files have changed in this diff Show More