Compare commits

..

117 Commits

Author SHA1 Message Date
238cf93a22 Merge pull request 'resolve release/1.15.0 to develop merge conflict' from 1.15-conflict into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/document-server-integration/pulls/92
2026-02-13 13:45:16 +00:00
10bc689f13 Merge remote-tracking branch 'remotes/origin/release/1.15.0' into 1.15-conflict 2026-02-13 16:02:58 +03:00
d532f3d8de nodejs: fix lint 2026-02-13 16:01:14 +03:00
59a8e2f63d fix(go): merge lossy-edit bugfix and new formats handling 2026-02-13 16:35:15 +07:00
0bdaa40036 Merge pull request 'bugfix-1.15' from bugfix-1.15 into release/1.15.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/document-server-integration/pulls/91
2026-02-13 09:03:33 +00:00
a60fd14daf increase default upload file size to 100 MB. Fix Bug 79567 2026-02-12 13:49:42 +07:00
f55196a1b2 fix(ruby): resolve fillform urls with proxy. Fix Bug 79584 2026-02-12 13:01:28 +07:00
bc434dea55 fix(ruby): correct platforms in gemfile.lock 2026-02-11 16:08:37 +07:00
af895ee2e6 Merge pull request 'update-deps' from update-deps into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/document-server-integration/pulls/90
2026-02-11 06:51:53 +00:00
8c725214af fix: files list height. Fix Bug 71461 2026-02-10 17:35:30 +07:00
dd513194bb build(php-laravel): bump psy/psysh to 0.12.19 2026-02-10 14:41:15 +07:00
6069c017c0 build(php-laravel): bump phpunit/phpunit to 11.5.50 2026-02-10 14:27:34 +07:00
fbc3d47607 build(nodejs): bump fast-xml-parser to 5.3.4 2026-02-10 14:17:24 +07:00
f8222b1052 build(php): bump phpunit/phpunit to 10.5.62 2026-02-10 14:14:50 +07:00
4c331d56d7 Merge pull request 'bugfix-1.15' from bugfix-1.15 into release/1.15.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/document-server-integration/pulls/89
2026-02-06 12:12:22 +00:00
ea3667174f fix(java-spring): correct roles for named users. Fix Bug 79808 2026-02-06 18:34:27 +07:00
ada17c99f7 fix(nodejs): use path module to get file basename. Fix Bug 79810 2026-02-06 17:39:09 +07:00
7a1cc7cbdc fix(go): move anonymous to the end of users list. Fix Bug 79785 2026-02-06 13:09:18 +07:00
9a7350e169 Merge pull request 'bugfix-release-1.15' from bugfix-release-1.15 into release/1.15.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/document-server-integration/pulls/88
2026-02-02 11:47:23 +00:00
0c33288120 fix(go): allow edit files with lossy-edit action. Fix Bug 79626 2026-02-02 16:26:18 +07:00
aff50cca4a fix(ruby): string forcesavetype check. Fix Bug 79584 2026-02-02 16:26:18 +07:00
7aca0edfed fix(php-laravel): correct conversion of uploaded files with password. Fix Bug 79569 2026-02-02 16:26:18 +07:00
2a3bcc0f67 fix(php-laravel): increase max upload file size and fix env variable. Fix Bug 79567 2026-02-02 16:26:18 +07:00
1da1dec76c fix(go): correct processing of document passwords 2026-02-02 16:25:45 +07:00
701d65dfaf Merge pull request 'build(nodejs): bump qs to 6.14.1' from nodejs-bump-qs into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/document-server-integration/pulls/86
2026-01-27 07:09:23 +00:00
5fa447b489 build(nodejs): bump qs to 6.14.1 2026-01-27 13:07:17 +07:00
c092db2566 Merge pull request 'fix(java): correct dataInsertImage object' from java-fix-data-insert-image into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/document-server-integration/pulls/85
2026-01-20 12:34:35 +00:00
873692e038 fix(java): correct dataInsertImage object 2026-01-20 17:40:21 +07:00
9dadd4cb28 Merge remote-tracking branch 'remotes/origin/release/1.15.0' into develop
# Conflicts:
#	web/documentserver-example/go/utils/format.go
2026-01-15 15:05:23 +03:00
8ea1f2c296 Merge pull request 'nodejs: update jws and js-yaml packages' from nodejs-audit-fix into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/document-server-integration/pulls/84
2025-12-12 07:19:26 +00:00
d4c41ed9c5 nodejs: update jws and js-yaml packages 2025-12-12 11:40:12 +07:00
614219f5fc feat: added approve msgspec to python/.check-licenses.yml 2025-12-09 13:11:13 +03:00
b1191be00d extend directurl description (Fix Bug 79000) 2025-12-08 17:17:33 +03:00
5361a94c57 nodejs: wopi CopyPasteRestrictions for anonymous 2025-11-27 17:54:43 +03:00
33ad23a08c nodejs: get fileType 2025-11-25 18:42:56 +03:00
e28f8df721 Merge remote-tracking branch 'remotes/origin/release/1.15.0' into develop 2025-11-21 16:58:54 +03:00
464f2ff503 Merge branch 'release/1.15.0' into develop 2025-11-21 16:54:34 +03:00
be9203ffc1 Merge pull request 'correct API methods are in each example's own readme' from readme-api-methods into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/document-server-integration/pulls/82
2025-10-31 07:07:49 +00:00
1be558eebc docs: correct API methods are in each example's own readme 2025-10-28 16:16:52 +07:00
1b2befb814 Merge pull request 'feature/insert-image' from feature/insert-image into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/document-server-integration/pulls/81
2025-10-21 09:30:10 +00:00
e63770f0d2 ruby: lint fix 2025-10-21 14:42:20 +07:00
9c8a766a81 nodejs: fix lint 2025-10-15 11:36:02 +03:00
f340aa4a97 Merge remote-tracking branch 'remotes/origin/release/1.15.0' into develop
# Conflicts:
#	web/documentserver-example/csharp-mvc/assets/document-formats
#	web/documentserver-example/csharp/assets/document-formats
#	web/documentserver-example/go/static/assets/document-formats
#	web/documentserver-example/java/src/main/resources/assets/document-formats
#	web/documentserver-example/nodejs/public/assets/document-formats
#	web/documentserver-example/php/assets/document-formats
#	web/documentserver-example/python/assets/document-formats
#	web/documentserver-example/ruby/assets/document-formats
2025-10-15 10:49:25 +03:00
81ee94866e Merge pull request 'build(ruby): update rack to 2.2.19' from ruby-bump-rack-2-2-19 into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/document-server-integration/pulls/79
2025-10-09 09:17:20 +00:00
5464d4ecc3 build(ruby): update rack to 2.2.19 2025-10-09 14:25:34 +07:00
8d0baf9661 update insertImage formats to changelog 2025-10-09 14:07:36 +07:00
5466ebf523 ruby: wrap data-insert-image with images array 2025-10-09 14:06:25 +07:00
9cf63d12ef python: wrap data-insert-image with images array 2025-10-09 14:06:25 +07:00
b16a9afddd php-laravel: wrap data-insert-image with images array 2025-10-09 14:06:25 +07:00
584cc9cc18 php: wrap data-insert-image with images array 2025-10-09 14:06:25 +07:00
6f8db52854 java-spring: wrap data-insert-image with images array 2025-10-09 14:06:25 +07:00
60e847568a java: wrap data-insert-image with images array 2025-10-09 14:06:25 +07:00
e481368cbc go: wrap data-insert-image with images array 2025-10-09 14:06:25 +07:00
fa3886c46b csharp-mvc: wrap data-insert-image with images array 2025-10-09 14:06:25 +07:00
ae6c07c5b2 csharp: wrap data-insert-image with images array 2025-10-09 14:06:25 +07:00
c90514e184 nodejs: update insertImage format 2025-10-07 16:47:48 +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
e5891b93fc fix(nodejs): replace deprecated fs.F_OK with fs.constants.F_OK 2025-08-05 18:39:18 +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
2e5cf3580c update formats 2025-08-01 16:07:51 +03:00
253 changed files with 5909 additions and 4158 deletions

5
.gitmodules vendored
View File

@ -5,11 +5,6 @@
[submodule "web/documentserver-example/nodejs/public/assets/document-formats"]
path = web/documentserver-example/nodejs/public/assets/document-formats
url = https://github.com/ONLYOFFICE/document-formats
branch = release/v9.3.0
[submodule "web/documentserver-example/nodejs/public/assets/plugin-aiautofill"]
path = web/documentserver-example/nodejs/public/assets/plugin-aiautofill
url = https://github.com/ONLYOFFICE/plugin-aiautofill.git
branch = develop
[submodule "web/documentserver-example/csharp-mvc/assets/document-templates"]
path = web/documentserver-example/csharp-mvc/assets/document-templates
url = https://github.com/ONLYOFFICE/document-templates

View File

@ -1,6 +1,20 @@
# Change Log
- nodejs: support tsv
- nodejs: wopi CopyPasteRestrictions for anonymous
- update insertImage formats
- 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

View File

@ -21,56 +21,6 @@ You should change `http://documentserver` to your server address in these files:
More information on how to use these examples can be found here: [https://api.onlyoffice.com/docs/docs-api/samples/language-specific-examples/](https://api.onlyoffice.com/docs/docs-api/samples/language-specific-examples/)
## API methods for test examples
The methods described below are available for all of the test examples.
### POST `/upload`
| | |
| ---------------------- | ------------------------------------------------------------ |
| **Summary** | Upload file to test example via request |
| **URL** | /upload |
| **Method** | POST |
| **Request<br>Headers** | `Content-Type: multipart/form-data` |
| **Request<br>Body** | `uploadedFile=@<filepath>`<br> `filepath` - file for uploading<br />Multipart body with the file binary contents |
| **Response** | **Code:** 200 OK <br />**Content on success:**<br /> `{ "filename": <filename>}`<br />**Content on error:**<br /> `{ "error": "Uploaded file not found" }` <br /> Or <br /> `{ "error": "File size is incorrect" }` |
| **Sample** | `curl -X POST -F uploadedFile=@filename.docx http://localhost/upload` |
### DELETE `/file`
| | |
| ------------------ | ------------------------------------------------------------ |
| **Summary** | Delete one file or all files |
| **URL** | /file |
| **Method** | DELETE |
| ****URL Params**** | **Optional:**<br /> `filename=[string]` - file for deleting. <br /> *WARNING! Without this parameter, all files will be deleted* |
| **Response** | **Code:** 200 OK <br /> **Success:**<br /> `{ "success": true }` |
| **Sample** | **Delete one file:**<br />`curl -X DELETE http://localhost/file?filename=filename.docx`<br />**Delete all files:**<br />`curl -X DELETE http://localhost/file`<br /> |
### GET `/files`
| | |
| ------------------ | ------------------------------------------------------------ |
| **Summary** | Get information about all files |
| **URL** | /files |
| **Method** | GET |
| **Response** | **Code:** 200 OK <br /> **Success:**<br /> `[{ "version": <file_version>, "id": <file_id>, "contentLength": <file_size_in_kilobytes>, "pureContentLength": <file_size_in_bytes>, "title": <file_name>, "updated": <last_change_date>}, ..., {...}]` |
| **Sample** | `curl -X GET http://localhost/files/` |
### GET `/files/file/{fileId}`
| | |
| ------------------ | ------------------------------------------------------------ |
| **Summary** | Get information about a file by file id |
| **URL** | /files/file/{fileId} |
| **Method** | GET |
| **Response** | **Code:** 200 OK <br />**Content on success:**<br /> `[{ "version": <file_version>, "id": <file_id>, "contentLength": <file_size_in_kilobytes>, "pureContentLength": <file_size_in_bytes>, "title": <file_name>, "updated": <last_change_date>}]`<br />**Content on error:**<br /> `"File not found"` |
| **Sample** | `curl -X GET http://localhost/files/{fileId}` |
## Important security info
Please keep in mind the following security aspects when you are using test examples:

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%;
}
@ -142,6 +143,7 @@
.scroll-table-body {
top: 31px;
height: calc(100% - 34px);
}
footer {
@ -182,9 +184,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 +227,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 +260,12 @@
}
.tableHeaderCellEditors {
width: 15%;
width: 13%;
text-align: left;
}
.tableHeaderCellFileName {
width: 28%;
width: 29%;
}
.tableHeaderCellViewers {
@ -281,6 +288,7 @@
}
.tableRow,
.storedHeader,
menu.links {
width: 75%;
}
@ -302,6 +310,10 @@
.firstContentCellViewers {
margin-left: 0;
}
.storedHeaderClearAll {
padding-right: 39px;
}
}
@media (max-width: 890px) and (min-width: 769px ) {
@ -317,6 +329,7 @@
}
.tableRow,
.storedHeader,
menu.links {
width: 95%;
}
@ -337,7 +350,7 @@
}
.tableHeaderCellFileName {
width: 20%;
width: 22%;
}
.tableHeaderCellEditors {
@ -346,18 +359,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 +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;
@ -565,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;
@ -673,10 +538,6 @@
padding-right: 5px;
margin: 0;
}
.firstContentCellViewers{
padding-right: 2px;
width: 11%;
}
}
@media (max-width: 1160px) {
@ -685,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){
@ -782,8 +638,8 @@
margin: 0;
position: fixed;
left: 0;
height: calc(100% - 124px);
z-index:99;
height: calc(100% - 44px);
z-index: 101;
}
.left-panel.active {
@ -893,6 +749,7 @@
.scroll-table-body {
top: 36px;
height: calc(100% - 34px);
}
.scroll-table-body tr:first-child {
@ -901,16 +758,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 +796,7 @@
}
.firstContentCellViewers {
border-bottom: none !important;
margin: 0;
}
.firstContentCellViewers ~ td {
@ -953,4 +831,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;
@ -845,6 +844,7 @@ footer table tr td:first-child {
position: absolute;
right: 0;
top: 71px;
height: calc(100% - 130px);
scrollbar-color: #D0D5DA transparent;
scrollbar-width: thin;
}
@ -915,18 +915,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 +984,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

@ -327,13 +327,18 @@ namespace OnlineEditorsExampleMVC.Models
logoConfig.Add("directUrl", directMailMergeUrl.ToString());
}
var result = new Dictionary<string, object>
{
{ "images", new List<Dictionary<string, object>>{logoConfig} }
};
if (JwtManager.Enabled) // if the secret key to generate token exists
{
var token = JwtManager.Encode(logoConfig); // encode logoConfig into the token
logoConfig.Add("token", token); // and add it to the logo config
var token = JwtManager.Encode(result); // encode logoConfig into the token
result.Add("token", token); // and add it to the logo config
}
logoUrl = jss.Serialize(logoConfig).Replace("{", "").Replace("}", "");
logoUrl = jss.Serialize(result).Replace("{", "").Replace("}", "");
}
// get a mail merge config

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

@ -98,18 +98,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" />
@ -118,12 +118,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

@ -79,6 +79,45 @@ In case the example and Document Server are installed on different computers, ma
Make sure that the Document Server has access to the server with the example installed with the address which you specify instead of **example.com** in the configuration files.
## File API methods used in this example
The methods described below are available for .Net (C# MVC) test example.
### POST `/webeditor.ashx?type=upload`
| | |
| ---------------------- | ------------------------------------------------------------ |
| **Summary** | Upload file to test example via request |
| **URL** | /webeditor.ashx?type=upload |
| **Method** | POST |
| **Request<br>Headers** | `Content-Type: multipart/form-data` |
| **Request<br>Body** | `uploadedFile=@<filepath>`<br> `filepath` - file for uploading<br />Multipart body with the file binary contents |
| **Response** | **Code:** 200 OK <br />**Content on success:**<br /> `{ "filename": <filename>}`<br />**Content on error:**<br /> `{ "error": "File type is not supported" }` <br /> Or <br /> `{ "error": "File size is incorrect" }` |
| **Sample** | `curl -X POST -F uploadedFile=@filename.docx http://localhost/webeditor.ashx?type=upload` |
### GET `/webeditor.ashx?type=remove`
| | |
| ------------------ | ------------------------------------------------------------ |
| **Summary** | Delete one file or all files |
| **URL** | /webeditor.ashx?type=remove |
| **Method** | GET |
| ****URL Params**** | **Optional:**<br /> `filename=[string]` - file for deleting. <br /> *WARNING! Without this parameter, all files will be deleted* |
| **Response** | **Code:** 200 OK <br /> **Success:**<br /> `{ "success": true }` |
| **Sample** | **Delete one file:**<br />`curl -X GET http://localhost/webeditor.ashx?type=remove&filename=filename.docx`<br />**Delete all files:**<br />`curl -X GET http://localhost/webeditor.ashx?type=remove`<br /> |
### GET `/webeditor.ashx?type=files`
| | |
| ------------------ | ------------------------------------------------------------ |
| **Summary** | Get information about all files |
| **URL** | /webeditor.ashx?type=files |
| **Method** | GET |
| **Response** | **Code:** 200 OK <br /> **Success:**<br /> `[{ "version": <file_version>, "id": <file_id>, "contentLength": <file_size_in_kilobytes>, "pureContentLength": <file_size_in_bytes>, "title": <file_name>, "updated": <last_change_date>}, ..., {...}]` |
| **Sample** | `curl -X GET http://localhost/webeditor.ashx?type=files` |
## Important security info
Please keep in mind the following security aspects when you are using test examples:

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

@ -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>
@ -127,7 +127,7 @@
<td valign="middle">
<label class="side-option">
<input id="directUrl" type="checkbox" class="checkbox" />Try opening on client
<img id="directUrlInfo" class="info info-tooltip" data-id="directUrlInfo" data-tooltip="Some files can be opened in the user's browser without connecting to the document server." src="content/images/info.svg" />
<img id="directUrlInfo" class="info info-tooltip" data-id="directUrlInfo" data-tooltip="Some files can be opened in the user's browser without connecting to the document server. Open each file in only one way." src="content/images/info.svg" />
</label>
</td>
</tr>
@ -204,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>
@ -434,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

@ -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%;
}
@ -142,6 +143,7 @@
.scroll-table-body {
top: 31px;
height: calc(100% - 34px);
}
footer {
@ -182,9 +184,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 +227,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 +260,12 @@
}
.tableHeaderCellEditors {
width: 15%;
width: 13%;
text-align: left;
}
.tableHeaderCellFileName {
width: 28%;
width: 29%;
}
.tableHeaderCellViewers {
@ -281,6 +288,7 @@
}
.tableRow,
.storedHeader,
menu.links {
width: 75%;
}
@ -302,6 +310,10 @@
.firstContentCellViewers {
margin-left: 0;
}
.storedHeaderClearAll {
padding-right: 39px;
}
}
@media (max-width: 890px) and (min-width: 769px ) {
@ -317,6 +329,7 @@
}
.tableRow,
.storedHeader,
menu.links {
width: 95%;
}
@ -337,7 +350,7 @@
}
.tableHeaderCellFileName {
width: 20%;
width: 22%;
}
.tableHeaderCellEditors {
@ -346,18 +359,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 +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;
@ -565,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;
@ -673,10 +538,6 @@
padding-right: 5px;
margin: 0;
}
.firstContentCellViewers{
padding-right: 2px;
width: 11%;
}
}
@media (max-width: 1160px) {
@ -685,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){
@ -782,8 +638,8 @@
margin: 0;
position: fixed;
left: 0;
height: calc(100% - 124px);
z-index:99;
height: calc(100% - 44px);
z-index: 101;
}
.left-panel.active {
@ -893,6 +749,7 @@
.scroll-table-body {
top: 36px;
height: calc(100% - 34px);
}
.scroll-table-body tr:first-child {
@ -901,16 +758,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 +796,7 @@
}
.firstContentCellViewers {
border-bottom: none !important;
margin: 0;
}
.firstContentCellViewers ~ td {
@ -953,4 +831,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;
@ -849,6 +848,7 @@ footer a:hover {
position: absolute;
right: 0;
top: 71px;
height: calc(100% - 130px);
scrollbar-color: #D0D5DA transparent;
scrollbar-width: thin;
}
@ -919,18 +919,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 +988,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>
@ -129,7 +129,7 @@
<td valign="middle">
<label class="side-option">
<input id="directUrl" type="checkbox" class="checkbox" />Try opening on client
<img id="directUrlInfo" class="info info-tooltip" data-id="directUrlInfo" data-tooltip="Some files can be opened in the user's browser without connecting to the document server." src="app_themes/images/info.svg" />
<img id="directUrlInfo" class="info info-tooltip" data-id="directUrlInfo" data-tooltip="Some files can be opened in the user's browser without connecting to the document server. Open each file in only one way." src="app_themes/images/info.svg" />
</label>
</td>
</tr>
@ -212,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(':','_')) %>]">
@ -222,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) %>">
@ -325,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>
@ -437,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

@ -372,13 +372,18 @@ namespace OnlineEditorsExample
logoConfig.Add("directUrl", DirectImageUrl.ToString());
}
var result = new Dictionary<string, object>
{
{ "images", new List<Dictionary<string, object>>{logoConfig} }
};
if (JwtManager.Enabled) // if the secret key to generate token exists
{
var insImageToken = JwtManager.Encode(logoConfig); // encode logoConfig into the token
logoConfig.Add("token", insImageToken); // and add it to the logo config
var insImageToken = JwtManager.Encode(result); // encode logoConfig into the token
result.Add("token", insImageToken); // and add it to the logo config
}
return logoConfig;
return result;
}
// get a document which will be compared with the current document

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

@ -66,18 +66,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" />
@ -85,12 +85,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

@ -81,6 +81,45 @@ In case the example and Document Server are installed on different computers, ma
Make sure that the Document Server in its turn has access to the server with the example installed with the address which you specify instead of **example.com** in the configuration files.
## File API methods used in this example
The methods described below are available for .Net (C#) test example.
### POST `/webeditor.ashx?type=upload`
| | |
| ---------------------- | ------------------------------------------------------------ |
| **Summary** | Upload file to test example via request |
| **URL** | /webeditor.ashx?type=upload |
| **Method** | POST |
| **Request<br>Headers** | `Content-Type: multipart/form-data` |
| **Request<br>Body** | `uploadedFile=@<filepath>`<br> `filepath` - file for uploading<br />Multipart body with the file binary contents |
| **Response** | **Code:** 200 OK <br />**Content on success:**<br /> `{ "filename": <filename>}`<br />**Content on error:**<br /> `{ "error": "File type is not supported" }` <br /> Or <br /> `{ "error": "File size is incorrect" }` |
| **Sample** | `curl -X POST -F uploadedFile=@filename.docx http://localhost/webeditor.ashx?type=upload` |
### GET `/webeditor.ashx?type=remove`
| | |
| ------------------ | ------------------------------------------------------------ |
| **Summary** | Delete one file or all files |
| **URL** | /webeditor.ashx?type=remove |
| **Method** | GET |
| ****URL Params**** | **Optional:**<br /> `filename=[string]` - file for deleting. <br /> *WARNING! Without this parameter, all files will be deleted* |
| **Response** | **Code:** 200 OK <br /> **Success:**<br /> `{ "success": true }` |
| **Sample** | **Delete one file:**<br />`curl -X GET http://localhost/webeditor.ashx?type=remove&filename=filename.docx`<br />**Delete all files:**<br />`curl -X GET http://localhost/webeditor.ashx?type=remove`<br /> |
### GET `/webeditor.ashx?type=files`
| | |
| ------------------ | ------------------------------------------------------------ |
| **Summary** | Get information about all files |
| **URL** | /webeditor.ashx?type=files |
| **Method** | GET |
| **Response** | **Code:** 200 OK <br /> **Success:**<br /> `[{ "version": <file_version>, "id": <file_id>, "contentLength": <file_size_in_kilobytes>, "pureContentLength": <file_size_in_bytes>, "title": <file_name>, "updated": <last_change_date>}, ..., {...}]` |
| **Sample** | `curl -X GET http://localhost/webeditor.ashx?type=files` |
## Important security info
Please keep in mind the following security aspects when you are using test examples:

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

@ -79,3 +79,51 @@ Also, [specify the same secret key](https://helpcenter.onlyoffice.com/installati
### Step 7. Check accessibility
In case the example and Document Server are installed on different computers, make sure that your server with the example installed has access to the Document Server with the address which you specify instead of **documentserver** in the configuration files.
## File API methods used in this example
The methods described below are available for Go test example.
### POST `/upload`
| | |
| ---------------------- | ------------------------------------------------------------ |
| **Summary** | Upload file to test example via request |
| **URL** | /upload |
| **Method** | POST |
| **Request<br>Headers** | `Content-Type: multipart/form-data` |
| **Request<br>Body** | `uploadedFile=@<filepath>`<br> `filepath` - file for uploading<br />Multipart body with the file binary contents |
| **Response** | **Code:** 200 OK <br />**Content on success:**<br /> `{ "filename": <filename>}`<br />**Content on error:**<br /> `{ "error": "File type is not supported" }` <br /> Or <br /> `{ "error": "File size is incorrect" }` |
| **Sample** | `curl -X POST -F uploadedFile=@filename.docx http://localhost/upload` |
### GET `/remove`
| | |
| ------------------ | ------------------------------------------------------------ |
| **Summary** | Delete one file |
| **URL** | /remove |
| **Method** | GET |
| ****URL Params**** | `filename=[string]` - file for deleting. |
| **Response** | **Code:** 200 OK <br /> **Success:**<br /> `{ "success": true }` |
| **Sample** | `curl -X GET http://localhost/remove?filename=filename.docx` |
### DELETE `/remove`
| | |
| ------------------ | ------------------------------------------------------------ |
| **Summary** | Delete all files |
| **URL** | /remove |
| **Method** | DELETE |
| **Response** | **Code:** 200 OK <br /> **Success:**<br /> `{ "success": true }` |
| **Sample** |`curl -X DELETE http://localhost/remove` |
### GET `/files`
| | |
| ------------------ | ------------------------------------------------------------ |
| **Summary** | Get information about all files |
| **URL** | /files |
| **Method** | GET |
| **Response** | **Code:** 200 OK <br /> **Success:**<br /> `[{ "version": <file_version>, "id": <file_id>, "contentLength": <file_size_in_kilobytes>, "pureContentLength": <file_size_in_bytes>, "title": <file_name>, "updated": <last_change_date>}, ..., {...}]` |
| **Sample** | `curl -X GET http://localhost/files` |

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

@ -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

@ -79,7 +79,9 @@ func (srv *DefaultServerEndpointsHandler) Convert(w http.ResponseWriter, r *http
return
}
newUrl, newExt, err := srv.ConversionManager.GetConverterUri(fileUrl, fileExt, toExt, key, true, filename)
newUrl, newExt, err := srv.ConversionManager.GetConverterUri(
fileUrl, fileExt, toExt, key, true, filename, payload.Filepass,
)
if err != nil {
response.Error = err.Error()
srv.logger.Errorf("File conversion error: %s", err.Error())
@ -92,8 +94,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

@ -67,8 +67,12 @@ func (srv *DefaultServerEndpointsHandler) Editor(w http.ResponseWriter, r *http.
"usersForMentions": usersForMentions,
"usersInfo": usersInfo,
"dataInsertImage": map[string]interface{}{
"fileType": "svg",
"url": remoteAddr + "/static/images/logo.svg",
"images": []map[string]interface{}{
{
"fileType": "svg",
"url": remoteAddr + "/static/images/logo.svg",
},
},
},
"dataDocument": map[string]interface{}{
"fileType": "docx",

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

@ -73,17 +73,26 @@ 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)
GetConverterUri(
docUri, fromExt, toExt, docKey string,
isAsync bool, title string, filePass string,
) (string, string, error)
}
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 +101,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 +116,6 @@ func New(umanager UserManager, smanager StorageManager,
JwtManager: jmanager,
ConversionManager: cmanager,
CommandManager: commanager,
FormatManager: fmanager,
}
}

View File

@ -35,46 +35,20 @@ import (
)
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,
@ -103,6 +69,7 @@ func (cm DefaultConversionManager) GetConverterUri(
docKey string,
isAsync bool,
title string,
filePass string,
) (string, string, error) {
if fromExt == "" {
fromExt = utils.GetFileExt(docUri, true)
@ -115,6 +82,7 @@ func (cm DefaultConversionManager) GetConverterUri(
Title: title,
Key: docKey,
Async: isAsync,
Password: filePass,
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Minute * cm.config.JwtExpiresIn)),
IssuedAt: jwt.NewNumericDate(time.Now()),

View File

@ -33,13 +33,13 @@ import (
)
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") || slices.Contains(actions, "lossy-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,
@ -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 2026
*
* 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

@ -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

@ -30,23 +30,6 @@ type DefaultUserManager struct {
func NewDefaultUserManager(logger *zap.SugaredLogger) managers.UserManager {
users := []models.User{
{
Id: "uid-0",
Username: "",
Email: "",
Group: "",
ReviewGroups: nil,
CommentGroups: nil,
UserInfoGroups: nil,
Favorite: -1,
DeniedPermissions: []string{"protect"},
Description: descriptionUser0,
Templates: false,
Avatar: false,
Goback: nil,
Close: nil,
Roles: []string{},
},
{
Id: "uid-1",
Username: "John Smith",
@ -116,6 +99,23 @@ func NewDefaultUserManager(logger *zap.SugaredLogger) managers.UserManager {
},
Roles: []string{"role"},
},
{
Id: "uid-0",
Username: "",
Email: "",
Group: "",
ReviewGroups: nil,
CommentGroups: nil,
UserInfoGroups: nil,
Favorite: -1,
DeniedPermissions: []string{"protect"},
Description: descriptionUser0,
Templates: false,
Avatar: false,
Goback: nil,
Close: nil,
Roles: []string{},
},
}
return &DefaultUserManager{
users,
@ -197,7 +197,7 @@ func (um DefaultUserManager) GetUserById(uid string) (models.User, error) {
}
}
return um.users[0], nil
return um.GetUserById("uid-0")
}
func (um DefaultUserManager) GetUserInfoById(uid string, serverAddress string) models.UserInfo {

View File

@ -99,6 +99,7 @@ type ConvertRequestPayload struct {
Key string `json:"key"`
Async bool `json:"async"`
JwtToken string `json:"token,omitempty"`
Password string `json:"password"`
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

@ -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

@ -130,7 +130,7 @@ if (typeof jQuery !== "undefined") {
var responseText = data.responseText;
var response = jq.parseJSON(responseText);
if (response.error) {
if (response.error.includes("Incorrect password")) {
if (response.error.includes("-5")) {
jq(".current").removeClass("current");
jq("#step2").addClass("error");
jq("#blockPassword").show();
@ -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%;
}
@ -142,6 +143,7 @@
.scroll-table-body {
top: 31px;
height: calc(100% - 34px);
}
footer {
@ -182,9 +184,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 +227,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 +260,12 @@
}
.tableHeaderCellEditors {
width: 15%;
width: 13%;
text-align: left;
}
.tableHeaderCellFileName {
width: 28%;
width: 29%;
}
.tableHeaderCellViewers {
@ -281,6 +288,7 @@
}
.tableRow,
.storedHeader,
menu.links {
width: 75%;
}
@ -302,6 +310,10 @@
.firstContentCellViewers {
margin-left: 0;
}
.storedHeaderClearAll {
padding-right: 39px;
}
}
@media (max-width: 890px) and (min-width: 769px ) {
@ -317,6 +329,7 @@
}
.tableRow,
.storedHeader,
menu.links {
width: 95%;
}
@ -337,7 +350,7 @@
}
.tableHeaderCellFileName {
width: 20%;
width: 22%;
}
.tableHeaderCellEditors {
@ -346,18 +359,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 +454,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 +528,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 +539,6 @@
padding-right: 5px;
margin: 0;
}
.firstContentCellViewers{
padding-right: 2px;
width: 11%;
}
}
@media (max-width: 1160px) {
@ -686,20 +547,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 +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 {
@ -892,6 +748,7 @@
.scroll-table-body {
top: 36px;
height: calc(100% - 34px);
}
.scroll-table-body tr:first-child {
@ -900,16 +757,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 +795,7 @@
}
.firstContentCellViewers {
border-bottom: none !important;
margin: 0;
}
.firstContentCellViewers ~ td {
@ -952,4 +830,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;
@ -846,6 +845,7 @@ footer table tr td:first-child {
position: absolute;
right: 0;
top: 71px;
height: calc(100% - 130px);
scrollbar-color: #D0D5DA transparent;
scrollbar-width: thin;
}
@ -919,15 +919,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 +984,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

@ -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>
@ -116,7 +116,7 @@
<td valign="middle">
<label class="side-option">
<input id="directUrl" type="checkbox" class="checkbox" />Try opening on client
<img id="directUrlInfo" class="info info-tooltip" data-id="directUrlInfo" data-tooltip="Some files can be opened in the user's browser without connecting to the document server." src="static/images/info.svg" />
<img id="directUrlInfo" class="info info-tooltip" data-id="directUrlInfo" data-tooltip="Some files can be opened in the user's browser without connecting to the document server. Open each file in only one way." src="static/images/info.svg" />
</label>
</td>
</tr>
@ -199,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 }}">
@ -302,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>
@ -412,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 2026
*
* 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
}

View File

@ -295,6 +295,45 @@ In case the example and Document Server are installed on different computers, ma
Make sure that the Document Server has access to the server with the example installed with the address which you specify instead of **example.com** in the configuration files.
## File API methods used in this example
The methods described below are available for Java (Spring) test example.
### POST `/upload`
| | |
| ---------------------- | ------------------------------------------------------------ |
| **Summary** | Upload file to test example via request |
| **URL** | /upload |
| **Method** | POST |
| **Request<br>Headers** | `Content-Type: multipart/form-data` |
| **Request<br>Body** | `uploadedFile=@<filepath>`<br> `filepath` - file for uploading<br />Multipart body with the file binary contents |
| **Response** | **Code:** 200 OK <br />**Content on success:**<br /> `{ "filename": <filename>}`<br />**Content on error:**<br /> `{ "error": "File type is not supported" }` <br /> Or <br /> `{ "error": "File size is incorrect" }` |
| **Sample** | `curl -X POST -F uploadedFile=@filename.docx http://localhost/upload` |
### POST `/delete`
| | |
| ------------------ | ------------------------------------------------------------ |
| **Summary** | Delete one file or all files |
| **URL** | /delete |
| **Method** | POST |
| ****Body Params**** | **Optional:**<br /> `filename: string` - file for deleting. <br /> *WARNING! Without this parameter, all files will be deleted* |
| **Response** | **Code:** 200 OK <br /> **Success:**<br /> `{ "success": true }` |
| **Sample** | **Delete one file:**<br />`curl -X POST http://localhost/delete -d '{"filename": "filename.docx"}'`<br />**Delete all files:**<br />`curl -X POST http://localhost/delete`<br /> |
### GET `/files`
| | |
| ------------------ | ------------------------------------------------------------ |
| **Summary** | Get information about all files |
| **URL** | /files |
| **Method** | GET |
| **Response** | **Code:** 200 OK <br /> **Success:**<br /> `[{ "version": <file_version>, "id": <file_id>, "contentLength": <file_size_in_kilobytes>, "pureContentLength": <file_size_in_bytes>, "title": <file_name>, "updated": <last_change_date>}, ..., {...}]` |
| **Sample** | `curl -X GET http://localhost/files` |
## Important security info
Please keep in mind the following security aspects when you are using test examples:

View File

@ -68,7 +68,7 @@ public class ExampleData {
"Can view chat",
"Has an avatar",
"Can submit forms",
"Has no roles",
"Has role 'Anyone'",
"Can start filling"
);
@ -85,7 +85,7 @@ public class ExampleData {
"Can view chat",
"Has an avatar",
"Can't submit forms",
"Has role 'Anyone'",
"Has role 'role'",
"Can start filling"
);
@ -105,7 +105,7 @@ public class ExampleData {
"Can't close history",
"Can't restore the file version",
"Can't submit forms",
"Has role 'role'",
"Has no roles",
"Can start filling"
);
@ -114,19 +114,19 @@ public class ExampleData {
"", List.of(FilterState.NULL.toString()), List.of(FilterState.NULL.toString()),
List.of(FilterState.NULL.toString()), List.of(FilterState.NULL.toString()),
List.of(FilterState.NULL.toString()), false, true, true, true,
new Goback(null, false), new Close(null, false), null, true);
new Goback(null, false), new Close(null, false), List.of("Anyone"), true);
// create user 2 with the specified parameters
userService.createUser("Mark Pottato", "pottato@example.com", descriptionUserSecond,
"group-2", List.of("", "group-2"), List.of(FilterState.NULL.toString()),
List.of("group-2", ""), List.of("group-2"), List.of("group-2", ""), true, true,
true, true, new Goback("Go to Documents", null), new Close(null, true), List.of("Anyone"), false);
true, true, new Goback("Go to Documents", null), new Close(null, true), List.of("role"), false);
// create user 3 with the specified parameters
userService.createUser("Hamish Mitchell", null, descriptionUserThird,
"group-3", List.of("group-2"), List.of("group-2", "group-3"), List.of("group-2"),
new ArrayList<>(), List.of("group-2"), null, true, true, false,
null, new Close(null, true), List.of("role"), false);
null, new Close(null, true), null, false);
// create user 0 with the specified parameters
userService.createUser("Anonymous", null, descriptionUserZero, "",

View File

@ -207,8 +207,10 @@ public class EditorController {
@SneakyThrows
private String getInsertImage() { // get an image that will be inserted into the document
Map<String, Object> dataInsertImage = new HashMap<>();
dataInsertImage.put("fileType", "svg");
dataInsertImage.put("url", storagePathBuilder.getServerUrl(true) + "/css/img/logo.svg");
Map<String, Object>[] images = new HashMap[1];
images[0].put("fileType", "svg");
images[0].put("url", storagePathBuilder.getServerUrl(true) + "/css/img/logo.svg");
dataInsertImage.put("images", images);
// check if the document token is enabled
if (settingsManager.isSecurityEnabled()) {

View File

@ -33,8 +33,8 @@ spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
hibernate.ddl-auto
spring.h2.console.enabled=true
spring.h2.console.path=/h2
spring.servlet.multipart.max-file-size=5MB
spring.servlet.multipart.max-request-size=5MB
spring.servlet.multipart.max-file-size=100MB
spring.servlet.multipart.max-request-size=100MB
url.index=/
url.converter=/converter

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

@ -16,15 +16,15 @@
}
.tableHeaderCellFileName {
width: 25%;
width: 29%;
}
.tableHeaderCellEditors {
width: 13%;
width: 12%;
}
.tableHeaderCellViewers {
width: 18%;
width: 15%;
text-align: right;
}
@ -66,6 +66,7 @@
}
.tableRow,
.storedHeader,
menu.links {
width: 90%;
}
@ -129,6 +130,7 @@
.scroll-table-body {
top: 31px;
height: calc(100% - 34px);
}
footer {
@ -173,9 +175,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{*/
@ -211,15 +218,15 @@
.tableRow td:first-child {
flex-grow: 0;
width: 15%;
width: 26%;
}
.tableHeaderCellFileName {
width: 9%;
width: 15%;
}
.tableHeaderCellEditors {
width: 13%;
width: 3%;
}
.tableHeaderCellViewers {
@ -243,12 +250,12 @@
}
.tableHeaderCellEditors {
width: 15%;
width: 13%;
text-align: left;
}
.tableHeaderCellFileName {
width: 28%;
width: 29%;
}
.tableHeaderCellViewers {
@ -271,6 +278,7 @@
}
.tableRow,
.storedHeader,
menu.links {
width: 75%;
}
@ -292,6 +300,10 @@
.firstContentCellViewers {
margin-left: 0;
}
.storedHeaderClearAll {
padding-right: 39px;
}
}
@media (max-width: 890px) and (min-width: 769px ) {
@ -307,6 +319,7 @@
}
.tableRow,
.storedHeader,
menu.links {
width: 95%;
}
@ -327,7 +340,7 @@
}
.tableHeaderCellFileName {
width: 20%;
width: 22%;
}
.tableHeaderCellEditors {
@ -336,18 +349,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%;
}
}
@ -423,61 +440,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;
@ -552,104 +514,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;
@ -660,10 +525,6 @@
padding-right: 5px;
margin: 0;
}
.firstContentCellViewers{
padding-right: 2px;
width: 11%;
}
}
@media (max-width: 1160px) {
@ -672,16 +533,16 @@
}
}
@media (min-width: 593px) {
.contentCellsEmpty {
display: none;
}
}
@media (max-width: 769px) and (min-width: 715px){
.tableRow,
.storedHeader,
menu.links {
width: 50%;
}
.storedHeaderClearAll {
padding-right: 26px;
}
}
@media(max-width: 1080px) and (min-width: 986px){
.tableHeaderCellRemove{
@ -769,8 +630,8 @@
margin: 0;
position: fixed;
left: 0;
height: calc(100% - 124px);
z-index:99;
height: calc(100% - 44px);
z-index: 101;
}
.left-panel.active {
@ -880,6 +741,7 @@
.scroll-table-body {
top: 36px;
height: calc(100% - 34px);
}
.scroll-table-body tr:first-child {
@ -888,16 +750,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 {
@ -905,7 +788,7 @@
}
.firstContentCellViewers {
border-bottom: none !important;
margin: 0;
}
.firstContentCellViewers ~ td {
@ -940,4 +823,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

@ -750,7 +750,6 @@ footer table tr td:first-child {
.contentCells {
display: block;
border-bottom: 1px solid #e5e5e5;
font-family: 'Open Sans', sans-serif;
font-size: 16px;
padding: 4px;
@ -847,6 +846,7 @@ footer table tr td:first-child {
position: absolute;
right: 0;
top: 71px;
height: calc(100% - 130px);
scrollbar-color: #D0D5DA transparent;
scrollbar-width: thin;
}
@ -919,15 +919,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 {
@ -991,3 +991,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

@ -559,4 +559,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

@ -37,13 +37,13 @@
</div>
<menu class="responsive-nav">
<li>
<a href="#" onclick="toggleSidePanel(event)">
<img src="css/img/mobile-menu.svg" alt="ONLYOFFICE" />
</a>
<a href="./">
<img src ="css/img/mobile-logo.svg" alt="ONLYOFFICE" />
</a>
</li>
<li>
<a href="./">
<img src ="css/img/mobile-logo.svg" alt="ONLYOFFICE" />
<a href="#" onclick="toggleSidePanel(event)">
<img src="css/img/mobile-menu.svg" alt="ONLYOFFICE" />
</a>
</li>
</menu>
@ -109,6 +109,7 @@
</select>
</td>
</tr>
<tr></tr>
</tbody>
</table>
</div>
@ -173,109 +174,112 @@
<span th:text="${files[iState.index].getName()}"></span>
</a>
</td>
<!-- 1-2 -->
<th:block th:if="${filesEditable[iState.index]}">
<td class="contentCells contentCells-icon">
<td class="contentCells contentCells-icon" data-section="EDITOR">
<a
th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='edit')}" target="_blank">
<img src="css/img/desktop.svg" alt="Open in editor for full size screens" title="Open in editor for full size screens"/>
<img src="css/img/edit.svg" alt="Open for full size screens" title="Open for full size screens"/>
</a>
</td>
<td class="contentCells contentCells-icon">
<a
th:href="@{/editor(fileName=${files[iState.index].getName()},type='mobile',action='edit')}" target="_blank">
<img src="css/img/mobile.svg" alt="Open in editor for mobile devices" title="Open in editor for mobile devices"/>
<img src="css/img/mobileEdit.svg" alt="Open for mobile devices" title="Open for mobile devices"/>
</a>
</td>
<div th:if="not ${docTypes[iState.index]} eq 'pdf'">
</th:block>
<div th:unless="${filesEditable[iState.index]}">
<td class="contentCells contentCells-icon" data-section="EDITOR"></td>
<td class="contentCells contentCells-icon"></td>
</div>
<!-- 3 -->
<div th:if="${docTypes[iState.index]} != 'pdf'">
<td class="contentCells contentCells-icon">
<a
th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='comment')}" target="_blank">
<img src="css/img/comment.svg" alt="Open for comment" title="Open for comment"/>
</a>
</td>
</div>
<div th:unless="${docTypes[iState.index]} != 'pdf'">
<td class="contentCells contentCells-icon"></td>
</div>
<!-- 4-5 -->
<div th:if="${isFillFormDoc[iState.index]}">
<td class="contentCells contentCells-icon">
<a
th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='fillForms')}" target="_blank">
<img src="css/img/formsubmit.svg" alt="Open for filling in forms" title="Open for filling in forms"/>
</a>
</td>
<td class="contentCells contentCells-icon contentCells-shift">
<a
th:href="@{/editor(fileName=${files[iState.index].getName()},type='mobile',action='fillForms')}" target="_blank">
<img src="css/img/mobile-fill-forms.svg" alt="Open for filling in forms for mobile devices" title="Open for filling in forms for mobile devices" />
</a>
</td>
</div>
<div th:unless="${isFillFormDoc[iState.index]}">
<!-- 4 -->
<div th:if="${docTypes[iState.index]} eq 'word'">
<td class="contentCells contentCells-icon">
<a
th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='comment')}" target="_blank">
<img src="css/img/comment.svg" alt="Open in editor for comment" title="Open in editor for comment"/>
th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='review')}" target="_blank">
<img src="css/img/review.svg" alt="Open for review" title="Open for review"/>
</a>
</td>
</div>
<div th:if="${docTypes[iState.index]} eq 'word'">
<td class="contentCells contentCells-icon">
<a
th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='review')}" target="_blank">
<img src="css/img/review.svg" alt="Open in editor for review" title="Open in editor for review"/>
</a>
</td>
</div>
<div th:if="${docTypes[iState.index]} eq 'cell'">
<td class="contentCells contentCells-icon">
<a
th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='filter')}" target="_blank">
<img src="css/img/filter.svg" alt="Open in editor without access to change the filter" title="Open in editor without access to change the filter" />
</a>
</td>
</div>
<div th:if="${docTypes[iState.index]} eq 'word'">
<td class="contentCells contentCells-icon">
<a
th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='blockcontent')}" target="_blank">
<img src="css/img/block-content.svg" alt="Open in editor without content control modification" title="Open in editor without content control modification"/>
</a>
</td>
</div>
<div th:if="not (${docTypes[iState.index]} eq 'word')">
<td class="contentCells contentCells-icon"></td>
</div>
<div th:if="${docTypes[iState.index]} eq 'slide'">
<td class="contentCells contentCells-icon "></td>
</div>
<div th:if="${isFillFormDoc[iState.index]}">
<td class="contentCells contentCells-shift contentCells-icon firstContentCellShift">
<a
th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='fillForms')}" target="_blank">
<img src="css/img/fill-forms.svg" alt="Open in editor for filling in forms" title="Open in editor for filling in forms"/>
</a>
</td>
</div>
<div th:if="${not isFillFormDoc[iState.index]}">
<td class="contentCells contentCells-shift contentCells-icon firstContentCellShift"></td>
</div>
</th:block>
<th:block th:if="${isFillFormDoc[iState.index] and not filesEditable[iState.index]}">
<td class="contentCells contentCells-icon "></td>
<td class="contentCells contentCells-icon">
<a
th:href="@{/editor(fileName=${files[iState.index].getName()},type='mobile',action='fillForms')}" target="_blank">
<img src="css/img/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
th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='fillForms')}" target="_blank">
<img src="css/img/fill-forms.svg" alt="Open in editor for filling in forms" title="Open in editor for filling in forms"/>
</a>
</td>
</th:block>
<th:block th:if="${not filesEditable[iState.index]}">
<td class="contentCells contentCells-shift contentCells-icon contentCellsEmpty" colspan="6"></td>
</th:block>
<td class="contentCells contentCells-icon firstContentCellViewers">
<div th:if="${docTypes[iState.index]} eq 'cell'">
<td class="contentCells contentCells-icon">
<a
th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='filter')}" target="_blank">
<img src="css/img/filter.svg" alt="Open without access to change the filter" title="Open without access to change the filter" />
</a>
</td>
</div>
<div th:unless="${docTypes[iState.index]} eq 'cell' or ${docTypes[iState.index]} eq 'word'">
<td class="contentCells contentCells-icon"></td>
</div>
<!-- 5 -->
<div th:if="${docTypes[iState.index]} eq 'word'">
<td class="contentCells contentCells-icon contentCells-shift">
<a
th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='blockcontent')}" target="_blank">
<img src="css/img/block-content.svg" alt="Open without content control modification" title="Open without content control modification"/>
</a>
</td>
</div>
<div th:unless="${docTypes[iState.index]} eq 'word'">
<td class="contentCells contentCells-icon contentCells-shift"></td>
</div>
</div>
<td class="contentCells contentCells-icon firstContentCellViewers" data-section="VIEWERS">
<a
th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='view')}" target="_blank">
<img src="css/img/desktop.svg" alt="Open in viewer for full size screens" title="Open in viewer for full size screens"/>
<img src="css/img/view.svg" alt="Open for full size screens" title="Open for full size screens"/>
</a>
</td>
<td class="contentCells contentCells-icon">
<a
th:href="@{/editor(fileName=${files[iState.index].getName()},type='mobile',action='view')}" target="_blank">
<img src="css/img/mobile.svg" alt="Open in viewer for mobile devices" title="Open in viewer for mobile devices"/>
<img src="css/img/mobileView.svg" alt="Open for mobile devices" title="Open for mobile devices"/>
</a>
</td>
<td class="contentCells contentCells-icon contentCells-shift">
<a
th:href="@{/editor(fileName=${files[iState.index].getName()},type='embedded',action='embedded')}" target="_blank">
<img src="css/img/embeded.svg" alt="Open in embedded mode" title="Open in embedded mode"/>
<img src="css/img/embedview.svg" alt="Open in embedded mode" title="Open in embedded mode"/>
</a>
</td>
<td class="contentCells contentCells-icon">
<td class="contentCells contentCells-icon" data-section="ACTIONS">
<a class="convert-file" th:data="${files[iState.index].getName()}" th:data-type="${docTypes[iState.index]}">
<img class="icon-action" src="css/img/convert.svg" alt="Convert" title="Convert" /></a>
</td>
@ -289,6 +293,11 @@
<img class="icon-action" src="css/img/delete.svg" alt="Delete" title="Delete" />
</a>
</td>
<td class="contentCells contentCells-icon">
<a href="#" onclick="toggleContextMenu(event)">
<img src="css/img/open-context.svg" alt="Open context menu" title="Open context menu" />
</a>
</td>
</tr>
</tbody>
</table>
@ -399,6 +408,11 @@
</div>
</footer>
<div id="mobileContextMenu" onclick="toggleContextMenu(event)">
<div class="context-body" id="mobileContextMenuBody">
</div>
</div>
<script type="text/javascript" src="scripts/jquery-3.6.4.min.js"></script>
<script type="text/javascript" src="scripts/jquery-migrate-3.4.1.min.js"></script>
<script type="text/javascript" src="scripts/jquery-ui.js"></script>

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