Browse Source

Initial commit

master
topaLE 4 years ago
commit
f08746f666
  1. 2
      .gitattributes
  2. 21
      LICENSE
  3. 52
      README.md
  4. BIN
      Saira Font.zip
  5. BIN
      Screenshots/screen-1.png
  6. BIN
      Screenshots/screen-2.png
  7. BIN
      Screenshots/screen-3.png
  8. BIN
      Screenshots/screen-4.png
  9. BIN
      Screenshots/screen-5.png
  10. BIN
      Screenshots/screen-6.png
  11. BIN
      Screenshots/screen-7.png
  12. BIN
      Screenshots/screen-8.png
  13. BIN
      custom/custom-logo.png
  14. 954
      custom/custom.css
  15. BIN
      custom/favicon.ico
  16. 266
      custom/templates/base.html
  17. 124
      custom/templates/home_base.html
  18. 1030
      custom/templates/js/sysadmin-templates.html
  19. 170
      custom/templates/registration/login.html
  20. 13
      custom/templates/registration/logout.html
  21. 110
      custom/templates/registration/registration_form.html
  22. 151
      custom/templates/sysadmin/base.html
  23. 362
      custom/templates/sysadmin/settings.html
  24. 62
      custom/templates/sysadmin/sys_inst_info_admins.html
  25. 182
      custom/templates/sysadmin/sys_inst_info_user.html
  26. 62
      custom/templates/sysadmin/sys_inst_search_user.html
  27. 61
      custom/templates/sysadmin/sys_org_info_library.html
  28. 253
      custom/templates/sysadmin/sys_org_info_user.html
  29. 54
      custom/templates/sysadmin/sys_useradmin_ldap.html
  30. 165
      custom/templates/sysadmin/useradmin_table.html
  31. BIN
      img/folder-192.png
  32. BIN
      img/login-bg.jpg

2
.gitattributes

@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto

21
LICENSE

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 topaLE
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

52
README.md

@ -0,0 +1,52 @@
# seafile-Blue-Dark-Theme
For the cloud software <strong>seafile</strong> a custom theme in Dark Blue ;-)
<h2>Usage / Installation</h2>
Switch to user <code>seafile</code> and create the folder <strong>custom</strong> and folder <strong>img</strong>:
<br><br>
<pre>
<code>sudo su seafile</code>
<code>cd</code>
<code>mkdir /home/seafile/sea-hub/custom</code>
<code>mkdir /home/seafile/seahub-data/img</code>
</pre>
<h2>Create Symlinks</h2>
ln -s /home/seafile/seahub-data/custom /home/seafile/seafile-server-latest/seahub/media/custom
<br>
ln -s /home/seafile/seahub-data/img /home/seafile/seafile-server-latest/seahub/media/images
<br><br>
<h2>Procedure</h2>
Copy the entire contents of the <code>custom</code> and <code>img</code> folder to the <strong>seahub-data/custom</strong> and <strong>seahub-data/img</strong>. The Owner of these folders and files must be seafile.
<br><br>
Edit the File: <strong>conf/seahub_settings.py</strong>
<pre>
<code>BRANDING_CSS = 'custom/custom.css'</code>
<code>FILE_SERVER_ROOT = 'https://your_ip_adresse_or_dyndns.com/seafhttp'</code>
<code>FAVICON_PATH = 'custom/favicon.png'</code>
<code>LOGO_PATH = 'custom/custom-logo.png'</code>
<code>LOGO_WIDTH = 160</code>
<code>LOGO_HEIGHT = 40</code>
</pre>
Optionally you can use the logo/favicon or login background or your own picture. Alternatively, you can use the folder file <code>folder-192.png</code> and copy from /img to:
<pre><code>/home/seafile/seafile-server-latest/seahub/media/img/</code></pre>
Then the Seafile server and Seahub must be restarted.
<pre>
<code>sudo systemctl restart seafile.service</code>
<code>sudo systemctl restart seahub.service</code>
</pre>
Have Fun ;-)
<h2>Screenshots</h2>
<img src="https://github.com/topa-LE/seafile-Blue-Dark-Theme/blob/master/Screenshots/screen-2.png?raw=true" alt="Folder" style="max-width:100%;" width="400">
<img src="https://github.com/topa-LE/seafile-Blue-Dark-Theme/blob/master/Screenshots/screen-4.png?raw=true" alt="Folder" style="max-width:100%;" width="400">
<img src="https://github.com/topa-LE/seafile-Blue-Dark-Theme/blob/master/Screenshots/screen-6.png?raw=true" alt="Folder" style="max-width:100%;" width="400">
<pre>You can find more screens in the folder: <a href="https://github.com/topa-LE/seafile-Blue-Dark-Theme/tree/master/Screenshots">Screenshots</a></pre>

BIN
Saira Font.zip

Binary file not shown.

BIN
Screenshots/screen-1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 451 KiB

BIN
Screenshots/screen-2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

BIN
Screenshots/screen-3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

BIN
Screenshots/screen-4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

BIN
Screenshots/screen-5.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

BIN
Screenshots/screen-6.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

BIN
Screenshots/screen-7.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

BIN
Screenshots/screen-8.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

BIN
custom/custom-logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

954
custom/custom.css

@ -0,0 +1,954 @@
/** Seafile Themes Blue Dark
*** Developer tpDEsign 2020
*/
/*
@import url('https://fonts.googleapis.com/css?family=Play&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Saira+Condensed:wght@300&display=swap');
*/
body {
margin: 0;
font-family: 'Saira Condensed', 'Play', Roboto, "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 0.9995rem;
font-weight: 300 !important;
line-height: 1.5;
color: #212529;
text-align: left;
background-color: #0e1621;
}
a:focus, a:hover {
color: #f6964c;
}
a {
color: #f3f3f3;
}
.grid-item:hover a {
color: #fb9e56;
}
.grid-file-name-link {
color: #fff;
font-size: 15px;
}
.grid-selected-active {
background-color:#0e1621;
}
.grid-item:hover .grid-file-img-link {
background:#0e1621;
}
.grid-drop-show {
background:#0e1621;
}
#header {
background: #0e1621;
width: 100%;
height: 55px;
font-size: 15px;
padding: 8px 16px 4px;
display: flex;
justify-content: space-between;
flex-shrink: 0;
border-bottom: none !important;
border-radius: 5px !important;
margin: 5px;
}
.shared-file-view-md-header {
background: #0e1621;
height: 55px;
border-bottom: none !important;
padding: 8px 16px 4px;
-ms-flex-pack: justify;
justify-content: space-between;
}
.shared-file-view-md-main {
height: calc(100% - 55px);
}
.shared-file-view-head h2 {
color: #fb9e56;
font-size: 20px;
}
.shared-file-view-head .share-by {
color: #fff;
}
#viewerContainer {
background: #16212f;
}
.top-header {
background: #0e1621;
width: 100%;
height: 55px;
font-size: 15px;
padding: .5rem 1rem;
-ms-flex-negative: 0;
flex-shrink: 0;
border-bottom: none !important;
}
.hide {
display: none !important;
}
.side-panel-north {
background: #0e1621;
border-bottom: none !important;
}
.main-panel-north {
background: #0e1621;
border-bottom: none !important;
}
.border-left-show:before {
position:absolute;
top:10px;
left:0;
width:0px;
height:30px;
content:"";
background-color:#0e1621;
}
/* Navbar */
.side-panel-center {
background-color: #16212f !important;
margin: 10px;
border-radius: 5px !important;
border-right: none !important;
}
.side-panel.o-auto {
background-color: #16212f !important;
margin: 10px 10px 10px 10px;
border-radius: 5px !important;
border-right: none !important;
}
.side-panel-footer {
border-right: none !important;
}
.side-nav-footer {
padding: 12px 20px 16px;
background: #0e1621;
border-top: none !important;
font-size: 16px;
}
.side-nav-footer .item {
color: #fb9e56 !important;
font-weight: normal;
margin-right: 11px;
}
.side-panel {
background-color: #0e1621;
border-right: none !important;
}
.side-nav-con {
padding: 15px;
color: #fff !important;
background-color: #16212f !important;
margin: 10px;
border-radius: 5px !important;
border-right: none !important;
}
.side-textnav-tabs .tab-cur a, .side-textnav-tabs .tab a:hover {
color: #fb9e56;
text-decoration: none;
}
.side-textnav-tabs .tab a {
border-bottom: 1px solid #0e1621;
margin-bottom: 3px;
}
.nav-pills .nav-item .nav-link.active {
background-color: #212d3d !important;
color: #fff;
border: none;
}
.nav-pills .nav-item .nav-link:hover {
color: #fff;
background-color: #212d3d;
}
.side-nav-con .nav .nav-item, .side-nav-con .nav .nav-item .nav-link {
color: #fff;
}
.side-tabnav-tabs .tab a:hover {
background-color: #0e1621;
text-decoration: none;
}
.side-nav-con [class^="sf2-icon-"], .side-nav-con [class^="sf3-font-"] {
color: #fb9e56;
}
.share-dialog .nav .nav-item .nav-link {
padding: .3125rem 1rem .3125rem .25rem;
color: #fb9e56;
}
.side-nav {
padding: 0;
overflow: hidden;
border-right: 0px solid #eee;
}
.side-textnav .hd,
.side-info .hd {
padding:4px;
background: #0e1621;
border-bottom: none !important;
margin-bottom:1em;
border-radius: 3px;
}
.tp-side-nav-sys {
background-color: #16212f !important;
margin: 10px;
border-radius: 5px !important;
border-right: none !important;
}
.side-nav-con .sub-nav .nav-link {
padding: 0;
display: block;
font-size: 0.875rem;
line-height: 1.5rem;
}
.side-tabnav-tabs .tab a {
display: block;
font-size: 19px;
padding: 4px 4px 4px 0;
color: #fff;
font-weight: normal;
}
.side-tabnav-tabs .tab-cur a, .side-tabnav-tabs .tab-cur a:hover {
background-color: #0e1621;
}
/* Navbar */
.add-tag-link:hover {
color: #fff;
background: #293749;
}
p.tip {
color: #fff;
}
.group-list-panel .group-item-empty-tip {
text-align: center;
padding: 4px 0;
border-bottom: 1px solid #12151e;
}
.group-list-panel .group-item-heading {
font-size: 1rem;
font-weight: 400;
padding: .25rem;
border-bottom: 1px solid #12151e;
margin: .75rem 0 0;
}
.account-popup .sf-popover-con {
padding: 0;
font-size: 16px;
background-color: #e0e9f7;
}
/* Login */
.login-panel {
background: #0e1621;
border-radius: 4px;
padding: 20px 60px;
width: 390px;
margin: 0 auto;
/* box-shadow: 0 0 8px #a7a6a9; */
box-shadow: 0 0 8px #f6964c;
}
.login-panel-hd {
font-size: 20px;
color: #fff;
}
span.vam {
color: #fff;
}
.text-logout-color {
font-size: 22px;
color: #fff;
}
.tp-reg-label {
color: #fff;
}
/* Login */
.btn-primary:hover {
color: #fff;
background-color: #e6904e;
border-color: #ed7b16;
}
.btn-primary {
color: #fff;
background-color: #f6964c;
border-color: #f6964c;
}
.btn {
font-weight: 600;
letter-spacing: 0.06em;
font-size: 18px;
min-width: 6.375rem;
}
.btn-outline-primary {
color: #f6964c;
background-color: #0e1621;
background-image: none;
border-color: #fbc79a;
}
.btn-white {
height: 35px;
font-size: 19px;
}
.sf-heading {
font-size: 20px;
color: #fb9e56;
font-weight: normal;
line-height: 1.5;
}
.block-tp-settings-layout {
background-color: #16212f !important;
padding: 10px;
border-radius: 5px !important;
}
.cur-view-path {
padding: 8px 16px;
max-height: 40px;
background: #16212f !important;
margin: 8px;
border-radius: 5px !important;
position:inherit;
}
.cur-view-content {
background: #16212f !important;
margin: 8px;
padding: 8px;
border-radius: 5px !important;
}
.cur-view-container .fa-star.fas {
color: #fb9e56;
}
.dir-content-nav {
background-color: #16212f;
border-right: 1px solid #0e1621;
}
.tree-node-inner .tree-node-text {
font-size: 18px;
color: #fff;
}
.tree-node-inner-hover {
background-color:#0e1621;
}
.uploader-list-header {
background-color: #0e1621;
padding: .375rem .625rem;
font-size: 19px;
line-height: 1.5;
color: #fb9e56;
display: -ms-flexbox;
display: flex;
-ms-flex-pack: justify;
justify-content: space-between;
min-height: 2.25rem;
}
.uploader-list-view {
display: -ms-flexbox;
display: flex;
-ms-flex-direction: column;
flex-direction: column;
position: fixed;
right: 50px;
bottom: 50px;
width: 720px;
height: 20rem;
border: 1px solid #0c0c0b;
border-radius: 3px;
-webkit-box-shadow: 0 0 6px #fb9e56;
box-shadow: 0 0 6px #171614;
background-color: #0e1621;
z-index: 1050;
}
.uploader-list-content {
padding: 0 1rem 1.25rem;
background-color: #111a26;
overflow: auto;
}
.upload-operation .saving {
color: #fb9e56;
}
.file-chooser-item .item-active {
background:#fb9e56 !important;
color:#fff;
}
.file-chooser-item .item-info:hover {
background:#fb9e56;
}
.list-view-header:hover {
background-color: #16212f;
color: #fff;
}
table thead tr {
height: 3.0rem;
}
table td {
padding: 0.5rem 0.1875rem;
padding-left: 0.1875rem;
border-bottom: 1px solid #0e1621;
color: #fff;
font-size: 18px;
word-break: break-all;
}
table th {
padding: 0.3125rem 0.1875rem;
border-bottom: 1px solid #16212f;
text-align: left;
font-weight: normal;
font-size: 20px;
line-height: 1.7;
color: #9c9c9c;
}
.tr-active {
background-color: #0e1621 !important;
}
.tr-highlight {
background-color: #0e1621;
}
.empty-tip {
margin: 5.5em 1em;
border: 2px solid #0b1319;
border-radius: 8px;
padding: 28px;
background-color: #151d28;
text-align: center;
}
.empty-tip h2 {
font-size: 1.325rem;
text-align: center;
color: #fb9e56;
font-weight: bold;
}
.empty-tip p {
color: #fff;
}
#notifications .sf2-icon-bell {
font-size: 24px;
line-height: 1;
color: #fb9e56;
}
.nav .nav-item .nav-link.active {
color: #fb9e56;
text-decoration: none;
border-bottom: none;
}
.nav .nav-item .nav-link {
padding: 0.5rem 2;
margin-right: 0.5rem;
color: #f3f3f3;
}
.tabnav {
padding: 8px 10px;
padding-bottom: 3px;
background: #16212f;
margin-bottom: .5em;
border-radius: 3px;
border: 1px solid #3c3f43;
}
.tabnav-tab-cur a, .tabnav-tab a:hover {
color: #fb9e56;
text-decoration: none;
border-bottom-color: #fb9e56;
font-size: 18px;
}
.tabnav button {
height: 29px;
background: #fff;
line-height: 17px;
font-size: 17px;
}
.tabnav-tab-cur a, .tabnav-tab a {
color: #f3f3f3;
font-size: 18px;
}
button {
font-size: 16px;
}
.input, .textarea {
width: 300px;
padding: 2px 3px;
border-radius: 2px;
margin-bottom: 5px;
}
.input-tip {
padding-top: calc(.375rem + 1px);
color: #a6a4a4;
font-size: 17px;
}
.hl {
background-color: #131d29;
}
.file-title {
color: #fff;
}
#paginator {
text-align: center;
font-size: 17px;
color: #fb9e56;
}
.side-tabnav h3.hd {
font-size: 19px;
color: #fb9e56;
font-weight: normal;
}
.meta-info {
font-size: 15px;
color: #fff;
}
.header-bar {
padding: 9px 10px;
padding-bottom: 9px;
background: #16212f;
margin-bottom: .5em;
border-radius: 3px;
border: 1px solid #3c3f43;
padding-bottom: 0;
height: 48px;
overflow: hidden;
}
dd {
margin-bottom: .8em;
color: #fb9e56;
}
dt {
color: #c1c6cc;
margin: 24px 0 2px;
font-weight: normal;
font-size: 20px;
}
#right-panel .hd {
background: #16212f;
margin-bottom: .5em;
border-radius: 3px;
border: 1px solid #3c3f43;
}
#right-panel .hd .ui-state-active .a, #right-panel .hd .a:hover {
color: #fb9e56;
text-decoration: none;
border-bottom-color: #fb9e56;
font-size: 20px;
}
#right-panel .hd .a {
font-size: 20px;
color: #fff;
}
#right-panel .hd, .tabnav, .wiki-top {
padding-bottom: 0;
height: 62px;
}
#right-panel .hd h3, #right-panel h3.hd {
line-height: 41px;
margin-bottom: 0;
}
.tp-font-settings {
font-size: 17px !important;
color: #fff !important;
text-align: justify !important;
margin-top: 5px;
margin-bottom: 5px;
}
.side-search-form .input {
width: calc(100% - 12px);
padding: 3px 6px;
background: #f3f3f3;
box-shadow: inset 0 1px 2px rgba(0,0,0,0.075);
font-size: 18px;
}
h2 {
color: #fff !important;
font-weight: 300 !important;
}
h3 {
font-size: 20px;
color: #f3f3f3;
font-weight: normal;
}
h4 {
font-size: 17px;
color: #f3f3f3 !important;
}
h5 {
font-size: 19px;
}
li {
color: #fff;
}
.op-bar {
padding: 9px 10px;
background: #16212f;
border-radius: 2px;
}
.op-target {
color: #fb9e56;
word-wrap: break-word;
}
p.m-0 {
color: #fff;
font-size: 18px;
}
.messages .success {
padding: 7px;
background: #569D27;
margin: 0;
}
.web-setting-name {
width: 200px;
padding: 0 10px;
vertical-align: top;
font-weight: normal;
line-height: 28px;
color: #fff;
}
.web-setting-name, .web-setting-input .input {
margin: 0;
font-size: 19px;
}
.block-tp-settings-untertext {
font-size: 15px;
color: #fff;
}
.seahub-web-settings h4 {
background: #16212f;
margin-bottom: .5em;
border-radius: 3px;
border: 1px solid #3c3f43;
color: #fff;
}
.side-tabnav-tabs .tab [class^="sf2-icon-"] {
display: inline-block;
width: 42px;
margin-right: 5px;
text-align: center;
vertical-align: middle;
font-size: 24px;
line-height: 1;
color: #fb9e56;
}
#main p {
font-size: 18px;
color: #fb9e56;
}
.sf-popover {
width: 250px;
background: #e0e9f7;
border: 1px solid #c9c9c9;
border-radius: 3px;
box-shadow: 0 0 4px #ccc;
position: absolute;
z-index: 20;
}
.up-outer-caret .inner-caret {
border-bottom-color: #e0e9f7;
top: 1px;
left: -10px;
}
#notice-popover .view-all {
display: block;
padding: 7px 0;
text-align: center;
color: #fb9e56;
}
label {
display: inline-block;
margin: 4px 0px;
}
.uploader-list-header {
background-color: #0e1621;
padding: .375rem .625rem;
font-size: 19px;
line-height: 1.5;
color: #fb9e56;
display: -ms-flexbox;
display: flex;
-ms-flex-pack: justify;
justify-content: space-between;
min-height: 2.25rem;
}
.file-view-content {
padding: 30px 0;
background: #16212f;
border-right: 4px solid transparent;
}
.file-view-header {
padding: 4px 10px;
border-bottom: 2px solid #fb9e56;
}
.modal-content {
background-color: #e0e9f7;
background-clip: padding-box;
/* border: 1px solid rgba(0, 0, 0, 0.2); */
border: 2px solid #16212f;
border-radius: 4px;
}
.modal-content a {
color: #fb9e56;
}
.modal-title {
margin-bottom: 0;
line-height: 1.5;
color: #16212f;
font-size: 20px;
font-weight: 200;
}
.tip {
color: #16212f;
}
.file-star:focus, .file-star:hover {
text-decoration: none;
color: #fb9e56;
}
.seafile-comment {
border-left: 1px solid #16212f;
}
.path-container {
color: #fff;
}
.path-link {
color: #fb9e56 !important;
}
.path-toolbar .toolbar-item a:hover {
color: #fb9e56;
}
.path-toolbar .toolbar-item a {
color: #f3f3f3;
}
.detail-container {
border-left: 2px solid #0e1621;
background: #16212f !important;
}
.dirent-table-container th {
font-size: 14px;
text-align: left;
font-weight: 400;
color: #f3f3f3;
}
.dirent-table-container td {
font-size: 16px;
color: #fb9e56;
word-break: break-all;
}
.detail-header {
background-color: #0e1621;
border-bottom: 1px solid #0e1621;
height: 40px;
}
.detail-header .detail-title .name {
margin: 0 .5rem 0 .25rem;
line-height: 1.5rem;
vertical-align: middle;
font-size: 18px;
color: #fb9e56;
}
.user-setting-nav .nav-item .nav-link {
color: #fff;
font-size: 19px;
}
.user-setting-nav .nav-item.active .nav-link {
color: #fb9e56;
border-color: #fb9e56;
}
.user-setting-nav .nav-item .nav-link:hover {
color: #fb9e56;
}
.heading {
padding: 8px 16px;
background: #16212f !important;
margin: 8px;
border-radius: 5px !important;
font-size: 20px;
color: #fff;
font-weight: 400;
line-height: 1.5;
}
.content.position-relative {
background: #16212f !important;
margin: 10px;
border-radius: 5px !important;
font-size: 20px;
color: #fb9e56;
width: 97%;
}
.setting-item-heading {
font-size: 19px;
color: #f3f3f3;
font-weight: 200;
padding-bottom: .2em;
border-bottom: none !important;
}
#quota-bar {
display: block;
height: 1em;
border: 1px solid #1d2939;
margin: 5px 0;
border-radius: 2px;
overflow: hidden;
}
.old-history-main .file-name {
color: #fb9e56;
word-wrap: break-word;
}
.old-history-main h2 {
font-size: 1.5em;
color: #f3f3f3;
font-weight: 200;
line-height: 1.5;
}
.old-history-main .commit-list .username {
vertical-align: middle;
color: #fb9e56;
text-decoration: none;
font-weight: 700;
}
#right-panel.help-con .hd {
font-weight: normal;
margin-bottom: 15px;
color: #fff;
}
.col-form-label {
font-size: 17px;
}

BIN
custom/favicon.ico

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

266
custom/templates/base.html

@ -0,0 +1,266 @@
{% load seahub_tags avatar_tags group_avatar_tags i18n staticfiles %}
<!DOCTYPE html>
<html lang="{{ LANGUAGE_CODE }}">
<head>
<title>{% block sub_title %}{% endblock %}{{ site_title }}</title>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="keywords" content="{% trans "File Collaboration Team Organization" %}" />
{% block viewport %}
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
{% endblock %}
<meta http-equiv="x-ua-compatible" content="ie=edge" />
<link rel="shortcut icon" href="{{ MEDIA_URL }}{{ favicon_path }}" />
{% block extra_base_style %}
<link rel="stylesheet" type="text/css" href="{% static "css/bootstrap.min.css" %}"/>
{% endblock %}
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/jstree_default_theme/style.min.css" />
<link rel="stylesheet" type="text/css" href="{% static "css/magnific-popup.css" %}" />
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/seahub.css?t=1398068110" />
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/sf_font3/iconfont.css" />
<!-- tpDEsign -->
<link href="https://fonts.googleapis.com/css2?family=Saira+Condensed:wght@300&display=swap" rel="stylesheet" />
<!-- tpDEsign -->
{% block extra_style %}{% endblock %}
{% if branding_css != '' %}<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}{{ branding_css }}" />{% endif %}
{% if enable_branding_css %}<link rel="stylesheet" type="text/css" href="{% url 'custom_css' %}" />{% endif %}
</head>
<body>
<div id="wrapper" class="{{ LANGUAGE_CODE }} d-flex fd-col h100">
{% block info_bar_message %}
{% if request.user.is_authenticated and request.cur_note %}
<div id="info-bar">
<p id="info-bar-info">{{ request.cur_note.message|urlize }}</p>
<span class="close sf2-icon-x1 op-icon" data="{{ request.cur_note.id }}" title="{% trans "Close" %}"></span>
</div>
{% endif %}
{% endblock info_bar_message %}
<div id="header" class="{% block header_css_class %}d-flex{% endblock %}">
<a href="{{ SITE_ROOT }}" id="logo">
{% if seacloud_mode %}
<img src="{{ MEDIA_URL }}img/seacloud_logo.png?t=1398068110" title="Seacloud" alt="logo" width="186" height="31" />
{% else %}
<img src="{{ MEDIA_URL }}{{ logo_path }}" title="{{ site_title }}" alt="logo" width="{{logo_width}}" height="{{logo_height}}" />
{% endif %}
</a>
<span class="sf2-icon-menu side-nav-toggle hidden-md-up hide" title="{% trans "Side Nav Menu" %}" id="js-toggle-side-nav" aria-label="{% trans "Side Nav Menu" %}"></span>
{% block header_right %}
{% if request.user.is_authenticated %}
<div class="d-flex">
{% block top_search %}
{% if has_file_search %}
{% include 'snippets/search_form.html' %}
{% endif %}
{% endblock %}
<div id="account">
<a id="my-info" href="#" class="account-toggle no-deco hidden-sm-down" aria-label="{% trans "View profile and more" %}">
{% avatar request.user 32 %} <span class="icon-caret-down vam"></span>
</a>
<span class="account-toggle sf2-icon-more mobile-icon hidden-md-up" aria-label="{% trans "View profile and more" %}"></span>
<div id="user-info-popup" class="account-popup sf-popover hide">
<div class="outer-caret up-outer-caret"><div class="inner-caret"></div></div>
<div class="sf-popover-con">
<div class="item ovhd">
{% avatar request.user 36 %}
<div class="txt">
{{ request.user.username|email2nickname }}
</div>
</div>
<span class="loading-icon loading-tip"></span>
<div id="space-traffic" class="hide" data-url="{% url 'space_and_traffic' %}"></div>
<a class="item" href="{{ SITE_ROOT }}profile/">{% trans "Settings" %}</a>
{% block admin_link %}
{% if request.user.is_staff %}
<a href="{% url 'sys_useradmin' %}" title="{% trans "System Admin" %}" class="item">{% trans "System Admin" %}</a>
{% endif %}
{% if request.user.org and request.user.org.is_staff %}
<a href="{% url 'org_user_admin'%}" title="{% trans "Admin" %}" class="item">{% trans "Organization Admin" %}</a>
{% endif %}
{% if request.user.inst_admin %}
<a href="{% url "institutions:useradmin" %}" title="{% trans "Admin" %}" class="item">{% trans "Admin" %}</a>
{% endif %}
{% endblock %}
<a href="{{ SITE_ROOT }}accounts/logout/" class="item" id="logout">{% trans "Log out" %}</a>
</div>
</div>
</div>
</div>
{% else %} {# for non-logged-in user #}
<div id="lang">
<a href="#" id="lang-context" data-lang="{{ LANGUAGE_CODE }}">{{ LANGUAGE_CODE|language_name_local|capfirst }} <span class="icon-caret-down"></span></a>
<div id="lang-context-selector" class="sf-popover hide">
<ul class="sf-popover-con">
{% for LANG in LANGUAGES %}
<li><a href="{% url 'i18n' %}?lang={{ LANG.0 }}">{{ LANG.1 }}</a></li>
{% endfor %}
</ul>
</div>
</div>
{% endif %}
{% endblock %}
</div>
<div id="main" class="container-fluid w100 flex-auto {% block main_class %}ov-auto{% endblock %}">{# since #wrapper is `d-flex`, 'w100' is necessary here. #}
{% block main_content %}
<div class="row">
<div id="main-panel" class="w100 ovhd">
{% block main_panel %}{% endblock %}
</div>
</div>
{% endblock %}
</div>
{% if messages %}
<ul class="messages hide">
{% for message in messages %}
<li class="{{ message.tags }}">
{% if 'safe' in message.tags %}
{{ message|safe }}
{% else %}
{{ message }}
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
<div id="confirm-popup" class="hide">
<div id="confirm-con"></div>
<button id="confirm-yes">{% trans "Yes" %}</button>
<button class="simplemodal-close">{% trans "No" %}</button>
</div>
</div><!-- wrapper -->
<script type="text/javascript">
var SEAFILE_GLOBAL = {
csrfCookieName: '{{ CSRF_COOKIE_NAME }}'
};
var app = {
ui : {
currentDropdown: false,
currentHighlightedItem: false,
freezeItemHightlight: false
}
}
</script>
<script type="text/javascript" src="{% static "scripts/lib/jquery.min.js" %}" id="jquery"></script>{# 'id="jquery"' is for pdf file view with pdf2html #}
<script type="text/javascript" src="{% static "scripts/lib/jquery.simplemodal.js" %}"></script>
<script type="text/javascript" src="{% static "scripts/lib/jstree.min.js" %}"></script>
<script type="text/javascript" src="{{ MEDIA_URL }}js/jq.min.js"></script>
<script type="text/javascript" src="{{ MEDIA_URL }}js/base.js?t=1536127546642"></script>
<script type="text/javascript">
function prepareAjaxErrorMsg(xhr) {
var error_msg;
if (xhr.responseText) {
var parsed_resp = JSON.parse(xhr.responseText);
// use `HTMLescape` for msgs which contain variable like 'path'
error_msg = HTMLescape(parsed_resp.error ||
parsed_resp.error_msg || parsed_resp.detail);
} else {
error_msg = gettext("Failed. Please check the network.");
}
return error_msg;
}
function ajaxErrorHandler(xhr, textStatus, errorThrown) {
var error_msg = prepareAjaxErrorMsg(xhr);
feedback(error_msg, 'error');
}
{% if request.user.is_authenticated %}
{% if request.cur_note %}
$('#info-bar .close').on('click', function() {
$('#info-bar').addClass('hide');
if (navigator.cookieEnabled) {
var date = new Date(),
cookies = document.cookie.split('; '),
info_id_exist = false,
new_info_id = $(this).attr('data') + '_';
date.setTime(date.getTime() + 14*24*60*60*1000);
new_info_id += '; expires=' + date.toGMTString() + '; path=' + '{{ SITE_ROOT }}';
for (var i = 0, len = cookies.length; i < len; i++) {
if (cookies[i].split('=')[0] == 'info_id') {
info_id_exist = true;
document.cookie = 'info_id=' + cookies[i].split('=')[1] + new_info_id;
break;
}
}
if (!info_id_exist) {
document.cookie = 'info_id=' + new_info_id;
}
}
});
{% endif %}
{% if has_file_search %}
{% include 'snippets/search_js.html' %}
{% endif %}
{% else %} {# for non-logged-in user #}
(function() {
var lang_context = $('#lang-context'),
lang_selector = $('#lang-context-selector');
lang_context.parent().css({'position':'relative'});
if ($('#header').is(':visible')) { // for login page
lang_selector.css({
'top': lang_context.position().top + lang_context.height() + 5,
'right': 0
});
}
var setLangSelectorMaxHeight = function() {
if ($('#header').is(':visible')) { // for login page
$('.sf-popover-con', lang_selector).css({
'max-height': $(window).height() - lang_selector.offset().top - 12
});
}
};
$(window).on('resize', function() {
if (lang_selector.is(':visible')) {
setLangSelectorMaxHeight();
}
});
lang_context.on('click', function() {
lang_selector.toggleClass('hide');
if (lang_selector.is(':visible')) {
setLangSelectorMaxHeight();
}
return false;
});
$(document).on('click', function(e) {
var element = e.target || e.srcElement;
if (element.id != 'lang-context-selector' && element.id != 'lang-context') {
lang_selector.addClass('hide');
}
});
})();
{% endif %}
if ($('.side-nav').length) {
$('#logo').addClass('hidden-sm-down');
$('#js-toggle-side-nav').removeClass('hide');
}
$('#js-toggle-side-nav').on('click', function() {
$('.side-nav').addClass('side-nav-shown');
$('').modal({
overlayClose: true,
onClose: function() {
$('.side-nav').removeClass('side-nav-shown');
$.modal.close();
}});
$('#simplemodal-container').css({'display':'none'});
return false;
});
$('.js-close-side-nav').on('click', function() {
$('.side-nav').removeClass('side-nav-shown');
return false;
});
</script>
{% block extra_script %}{% endblock %}
</body>
</html>

124
custom/templates/home_base.html

@ -0,0 +1,124 @@
{% extends "base.html" %}
{% load i18n %}
{% block main_class %}d-flex ovhd{% endblock %}
{% block main_content %}
<div class="row flex-1 d-flex w100 ovhd"> {# 'ovhd' is for Firefox #}
<div id="side-nav" class="side-nav side-tabnav col-md-3">
<a href="#" title="{% trans "Close" %}" aria-label="{% trans "Close" %}" class="sf2-icon-x1 sf-popover-close op-icon hidden-md-up js-close-side-nav fright"></a>
{% block left_panel %}
<h3 class="hd">{% trans "Files" %}</h3>
<ul class="side-tabnav-tabs">
{% if user.permissions.can_add_repo %}
<li class="tab"><a href="{{ SITE_ROOT }}my-libs/" class="ellipsis" title="{% trans "My Libraries" %}"><span class="sf2-icon-user" aria-hidden="true"></span>{% trans "My Libraries" %}</a></li>
{% endif %}
<li class="tab"><a href="{{ SITE_ROOT }}shared-libs/" class="ellipsis" title="{% trans "Shared with me" %}"><span class="sf2-icon-share" aria-hidden="true"></span>{% trans "Shared with me" %}</a></li>
{% if user.permissions.can_view_org %}
<li class="tab"><a href="{{ SITE_ROOT }}#org/" class="ellipsis" title="{% trans "Shared with all" %}"><span class="sf2-icon-organization" aria-hidden="true"></span>{% trans "Shared with all" %}</a></li>
{% endif %}
<li class="tab" id="group-nav">
<a href="#" class="ellipsis" title="{% trans "Shared with groups" %}"><span class="toggle-icon icon-caret-left fright" aria-hidden="true"></span><span class="sf2-icon-group" aria-hidden="true"></span>{% trans "Shared with groups" %}</a>
<ul class="grp-list hide">
<li>
<a href="{{ SITE_ROOT }}groups/"><span class="sharp" aria-hidden="true">#</span>{% trans "All Groups" %}</a>
</li>
{% for grp in grps %}
<li>
<a class="ellipsis" href="{{SITE_ROOT}}group/{{ grp.id }}/" title="{{ grp.group_name }}"><span class="sharp" aria-hidden="true">#</span>{{ grp.group_name }}</a>
</li>
{% endfor %}
</ul>
</li>
</ul>
<div class="hd w100 ovhd">
<h3 class="fleft">{% trans "Tools" %}</h3>
</div>
<ul class="side-tabnav-tabs">
<li class="tab"><a href="{{ SITE_ROOT }}starred/"><span class="sf2-icon-star" aria-hidden="true"></span>{% trans "Favorites" %}</a></li>
{% if events_enabled %}
<li class="tab"><a href="{{ SITE_ROOT }}dashboard/"><span class="sf2-icon-clock" aria-hidden="true"></span>{% trans "Activities" %}</a></li>
{% endif %}
{% for mod in request.user.mods_enabled %}
{% if mod == 'personal wiki' %}
<li class="tab {% block cur_personal_wiki %}{% endblock %}"><a href="{% url 'wiki:list' %}"><span class="sf2-icon-wiki" aria-hidden="true"></span>{% trans "Wikis" %}</a></li>
{% endif %}
{% endfor %}
<li class="tab"><a href="{{ SITE_ROOT }}#devices/" class="ellipsis" title="{% trans "Linked Devices" %}"><span class="sf2-icon-monitor" aria-hidden="true"></span>{% trans "Linked Devices" %}</a></li>
{% if enable_guest_invitation and user.permissions.can_invite_guest %}
<li class="tab">
<a href="{{ SITE_ROOT }}#invitations/"><span aria-hidden="true" class="sf2-icon-invite"></span>{% trans "Invite People" %}</a>
</li>
{% endif %}
<li class="tab"><a href="{{ SITE_ROOT }}drafts/"><span class="sf2-icon-edit2" aria-hidden="true"></span>{% trans "Drafts" %}</a></li>
<li class="tab" id="share-admin-nav">
<a href="#" class="ellipsis" title="{% trans "Share Admin" %}"><span class="toggle-icon icon-caret-left fright" aria-hidden="true"></span><span aria-hidden="true" class="sf2-icon-wrench"></span>{% trans "Share Admin" %}</a>
<ul class="hide">
{% if user.permissions.can_add_repo %}
<li>
<a href="{{ SITE_ROOT }}share-admin-libs/"><span aria-hidden="true" class="sharp">#</span>{% trans "Libraries" %}</a>
</li>
<li>
<a href="{{ SITE_ROOT }}share-admin-folders/"><span aria-hidden="true" class="sharp">#</span>{% trans "Folders" %}</a>
</li>
{% endif %}
{% if user.permissions.can_generate_share_link %}
<li>
<a href="{{ SITE_ROOT }}share-admin-share-links/"><span aria-hidden="true" class="sharp">#</span>{% trans "Links" %}</a>
</li>
{% elif user.permissions.can_generate_upload_link %}
<li>
<a href="{{ SITE_ROOT }}share-admin-upload-links/"><span aria-hidden="true" class="sharp">#</span>{% trans "Links" %}</a>
</li>
{% endif %}
</ul>
</li>
</ul>
{% endblock %}
</div>
<div id="right-panel" class="col-md-9 ov-auto flex-1">
{% block right_panel %}{% endblock %}
</div>
{% if user.permissions.can_add_repo %}
<form id="mods-enable-form" method="post" action="{% url 'toggle_modules' %}" class="hide">{% csrf_token%}
<h3>{% trans "Enable Modules"%}</h3>
<ul>
{% for mod in request.user.mods_available %}
{% if mod == 'personal wiki' %}
<li>
<label class="checkbox-label">
<input type="checkbox" name="personal_wiki" class="vam" {%if mod in request.user.mods_enabled%}checked="checked"{% endif%} />
<span class="checkbox-option vam">{% trans "Personal Wiki" %}</span>
</label>
</li>
{% endif %}
{% endfor %}
</ul>
<input type="submit" id="mods-enable-submit" value="{% trans "Submit"%}" class="submit" />
</form>
{% endif %}
</div>
{% endblock %}
{% block extra_script %}
<script type="text/javascript">
$('#group-nav a:first').on('click', function() {
$('#group-nav .toggle-icon').toggleClass('icon-caret-left icon-caret-down');
$('#group-nav .grp-list').slideToggle();
return false;
});
$('#share-admin-nav').on('click', 'a:first', function() {
var $shareAdmin = $('#share-admin-nav');
$('.toggle-icon', $shareAdmin).toggleClass('icon-caret-left icon-caret-down');
$('ul', $shareAdmin).slideToggle(250);
return false;
});
</script>
{% endblock %}

1030
custom/templates/js/sysadmin-templates.html

File diff suppressed because it is too large

170
custom/templates/registration/login.html

@ -0,0 +1,170 @@
{% extends "base.html" %}
{% load i18n %}
{% block sub_title %}{% trans "Log In" %} - {% endblock %}
{% block header_css_class %}hide{% endblock %}
{% block extra_base_style %}
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/seafile-ui.css" />
{% endblock %}
{% block extra_style %}
<style type="text/css">
html, body, #wrapper { height:100%; }
#wrapper {
/* background: url('{{ MEDIA_URL }}{{login_bg_image_path}}') center top no-repeat scroll; */
/* neu tpDEsign */
background: url('/media/images/login-bg.jpg') center top no-repeat scroll;
background-size: cover;
padding-top:1px;
}
#lang {
margin:0;
}
#lang-context {
font-weight:normal;
}
#lang-context-selector {
text-align:left;
}
</style>
{% endblock %}
{% block main_content %}
<div class="login-panel-outer-container vh">
<div class="login-panel">
<h1 class="login-panel-hd">{% trans "Log In" %}</h1>
<form action="" method="post" id="login-form">{% csrf_token %}
<input type="text" name="login" placeholder="{% trans "Email or Username" %}" aria-label="{% trans "Email or Username" %}" title="{% trans "Email or Username" %}" value="" class="input name-input" /><br />
<input type="password" name="password" placeholder="{% trans "Password" %}" aria-label="{% trans "Password" %}" title="{% trans "Password" %}" value="" class="input passwd-input" autocomplete="off" />
{% if form.captcha %}
<div class="ovhd">
<span id="refresh-captcha" title="{% trans "Refresh" %}" class="icon-refresh op-icon fright"></span>
{{ form.captcha }}
</div>
{% endif %}
<input type="hidden" name="next" value="{% if next %}{{ next|escape }}{% else %}{{ SITE_ROOT }}{% endif %}" />
{% if form.errors %}
{% if form.captcha.errors %}
{{ form.captcha.errors}}
{% elif form.errors.freeze_account %}
<p class="error">{{ form.errors.freeze_account }}</p>
{% elif form.errors.inactive %}
<p class="error">{{ form.errors.inactive }}</p>
{% elif form.errors.not_found %}
<p class="error">{{ form.errors.not_found }}</p>
{% else %}
<p class="error">{% trans "Incorrect email or password" %}</p>
{% endif %}
{% else %}
<p class="error hide"></p>
{% endif %}
<label class="checkbox-label remember">
<input type="checkbox" name="remember_me" class="vam remember-input" />
<span class="vam">{% blocktrans %}Remember me for {{remember_days}} days {% endblocktrans %}</span>
</label>
<a href="{{ SITE_ROOT }}accounts/password/reset/" class="normal forgot-passwd">{% trans "Forgot password?" %}</a>
<button type="submit" class="submit btn btn-primary btn-block">{% trans "Log In" %}</button>
</form>
{% if enable_sso %}
<a id="sso" href="#" class="normal">{% trans "Single Sign-On" %}</a>
{% endif %}
<div class="login-panel-bottom-container">
{% if enable_signup %}
<a href="{{ signup_url }}" class="normal fleft" id="sign-up">{% trans "Signup" %}</a>
{% endif %}
</div>
</div>
</div>
{% endblock %}
{% block extra_script %}
<script type="text/javascript">
$('.login-panel-outer-container').prepend($($('#logo').html()).attr({'height': 40}).addClass('login-panel-logo'));
$('.login-panel-bottom-container').append($('#lang').removeClass('fright'));
var $el = $('.login-panel-outer-container');
var elHeight = $el.outerHeight();
var wdHeight = $(window).height();
if (wdHeight > elHeight) {
$el.css({'margin-top': (wdHeight - elHeight)/2});
}
$('#lang').css({'margin-left': $('#sign-up').outerWidth() + 10});
$el.removeClass('vh');
$('#lang-context').on('click', function() {
var langTop = $('#lang').offset().top;
var langSelectorTop;
var langSelectorHeight = $('#lang-context-selector .sf-popover-con').outerHeight();
if (langSelectorHeight > langTop) {
langSelectorTop = '-' + (langTop - 5) + 'px';
} else {
langSelectorTop = '-' + (langSelectorHeight + 5) + 'px';
}
$('#lang-context-selector').css({
'top': langSelectorTop,
'right': 0
});
$('#lang-context-selector .sf-popover-con').css({
'max-height': $('#lang').offset().top - 10
});
});
$('[name="login"]').trigger('focus');
function setCaptchaInputWidth() {
$('#id_captcha_1').outerWidth($('.input').outerWidth() - $('.captcha').width() - $('#refresh-captcha').outerWidth(true) - 10);
}
$(window).on('load', setCaptchaInputWidth);
$('.captcha').on('load', setCaptchaInputWidth);
$('#refresh-captcha').on('click', function() {
$.ajax({
url: '{% url 'captcha-refresh' %}',
dataType:'json',
cache:false,
success: function(data) {
$('.captcha').attr('src', data['image_url']);
$('#id_captcha_0').val(data['key']);
},
error: function() {
$('.error').removeClass('hide').html("{% trans "Failed to refresh the CAPTCHA, please try again later." %}");
}
});
return false;
});
$('#login-form').on('submit', function(){
if (!$.trim($('input[name="login"]').val())) {
$('.error').removeClass('hide').html("{% trans "Email or username cannot be blank" %}");
return false;
}
if (!$.trim($('input[name="password"]').val())) {
$('.error').removeClass('hide').html("{% trans "Password cannot be blank" %}");
return false;
}
});
// set tabindex
$(function() {
$('input:not([type="hidden"])').each(function(index) {
$(this).attr('tabindex', index + 1);
});
});
{% if enable_sso %}
$(function() {
$('#sso').on('click', function() {
window.location = "{% url 'sso' %}{% if next %}?next={{ next|escape }}{% endif %}" + encodeURIComponent(document.location.hash);
return false;
});
});
{% endif %}
</script>
{% endblock %}

13
custom/templates/registration/logout.html

@ -0,0 +1,13 @@
{% extends "base.html" %}
{% load i18n %}
{% block sub_title %}{% trans "Log Out" %} - {% endblock %}
{% block main_content %}
<div class="text-panel">
<!-- tpDEsign -->
<p class="text-logout-color">{% trans "Thanks for your participation! " %}</p>
<br>
<a href="{{ SITE_ROOT }}accounts/login/">{% trans "Log in again" %}</a>
</div>
{% endblock %}

110
custom/templates/registration/registration_form.html

@ -0,0 +1,110 @@
{% extends "registration/login.html" %}
{% load i18n %}
{% block sub_title %}{% trans "Signup" %} - {% endblock %}
{% block extra_style %}{{block.super}}
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/bootstrap.popover.min.css" />
{% endblock %}
{% block main_content %}
<div class="login-panel-outer-container vh">
<div class="login-panel">
<h1 class="login-panel-hd">{% trans "Signup" %}</h1>
{% if request.user.is_authenticated %}
<p>{% trans "Welcome back, you are already signed in." %}</p>
{% else %}
<form action="" method="post" id="signup-form">{% csrf_token %}
{% if form.name.field.required %}
<label class="tp-reg-label" for="id_name">{% trans "Name" %}</label>
{{ form.name }} {{ form.name.errors }}
{% endif %}
<label class="tp-reg-label" for="id_email">{% trans "Email" %}</label>
{{ form.email }} {{ form.email.errors }}
<label class="tp-reg-label" for="id_password1">{% trans "Password" %}</label>
{{ form.password1 }} {{ form.password1.errors }}
<div id="pwd_strength"></div>
<label class="tp-reg-label" for="id_password2">{% trans "Confirm Password" %}</label>
{{ form.password2 }} {{ form.password2.errors }}
{% if form.department.field.required %}
<label class="tp-reg-label" for="id_department">{% trans "Department" %}</label>
{{ form.department }} {{ form.department.errors }}
{% endif %}
{% if form.telephone.field.required %}
<label class="tp-reg-label" for="id_telephone">{% trans "Telephone" %}</label>
{{ form.telephone }} {{ form.telephone.errors }}
{% endif %}
{% if form.note.field.required %}
<label class="tp-reg-label" for="id_note">{% trans "Note" %}</label>
{{ form.note }} {{ form.note.errors }}
{% endif %}
<p class="error hide"></p>
<button type="submit" class="submit btn btn-primary btn-block">{% trans "Sign Up" %}</button>
</form>
<div class="login-panel-bottom-container">
{# language will be shown here #}
</div>
{% endif %}
</div>
</div>
{% endblock %}
{% block extra_script %}{{ block.super }}
<script type="text/javascript" src="{{MEDIA_URL}}js/bootstrap.min.js"></script>
<script type="text/javascript">
{% if strong_pwd_required %}
{% include "snippets/password_strength_js.html" %}
var passwd_tip = "{% blocktrans %}Passwords must have at least {{min_len}} characters and contain {{level}} of the following: uppercase letters, lowercase letters, numbers, and symbols.{% endblocktrans%}";
$("#id_password1")
.popover({ // bootstrap plugin 'popover'
container: 'body',
content: passwd_tip,
template: '<div class="popover" role="tooltip"><div class="arrow"></div><div class="popover-content"></div></div>',
trigger: 'focus'
})
.on('keyup', function() {
var pwd = $(this).val();
if ($.trim(pwd)) {
var level = getStrengthLevel(pwd);
showStrength(level);
} else {
$("#pwd_strength").html("");
}
});
{% endif %}
$('#signup-form').on('submit', function(){
var email = $.trim($('input[name="email"]').val()),
pwd1 = $.trim($('input[name="password1"]').val()),
pwd2 = $.trim($('input[name="password2"]').val());
level = getStrengthLevel(pwd1);
if (!email) {
$('.error').html("{% trans "Email cannot be blank" %}").removeClass('hide');
return false;
}
if (!pwd1) {
$('.error').html("{% trans "Password cannot be blank" %}").removeClass('hide');
return false;
}
if (!pwd2) {
$('.error').html("{% trans "Please enter the password again" %}").removeClass('hide');
return false;
}
if (pwd1 != pwd2) {
$('.error').html("{% trans "Passwords don't match" %}").removeClass('hide');
return false;
}
{% if strong_pwd_required %}
if (level < {{level}}) {
$('.error').html(passwd_tip).removeClass('hide');
return false;
}
{% endif %}
});
</script>
{% endblock %}

151
custom/templates/sysadmin/base.html

@ -0,0 +1,151 @@
{% extends "base.html" %}
{% load i18n %}
{% block top_search %}{% endblock %} {# no 'file search' for system admin pages #}
{% block main_class %}d-flex ovhd{% endblock %}
{% block admin_link %}
<a href="{{ SITE_ROOT }}" title="{% trans "Exit System Admin" %}" class="item">{% trans "Exit System Admin" %}</a>
{% endblock %}
{% block main_content %}
<div class="row flex-1 d-flex">
<div id="side-nav" class="side-nav side-tabnav col-md-3 tp-side-nav-sys">
<div class="hidden-md-up logo-container">
<a href="{{ SITE_ROOT }}">
{% if seacloud_mode %}
<img src="{{ MEDIA_URL }}img/seacloud_logo.png?t=1398068110" title="Seacloud" alt="logo" width="186" height="31" />
{% else %}
<img src="{{ MEDIA_URL }}{{ logo_path }}" title="{{ site_title }}" alt="logo" width="{{logo_width}}" height="{{logo_height}}" />
{% endif %}
</a>
</div>
<div class="side-nav-con">
{% block left_panel %}
<h3 class="hd">{% trans "System Admin" %}</h3>
<ul class="side-tabnav-tabs">
{% if user.admin_permissions.can_view_system_info %}
<li class="tab">
<a href="{{ SITE_ROOT }}sysadmin/#dashboard/"><span class="sf2-icon-info"></span>{% trans "Info" %}</a>
</li>
{% endif %}
{% if is_pro and user.admin_permissions.can_view_statistic %}
<li class="tab {% block cur_statistic %}{% endblock %}">
<a href="{% url "sys_statistic_file" %}"><span class="sf2-icon-histogram"></span>{% trans "Statistic" %}</a>
</li>
{% endif %}
{% if is_default_admin %}
<li class="tab">
<a href="{{ SITE_ROOT }}sysadmin/#desktop-devices/"><span class="sf2-icon-monitor"></span>{% trans "Devices" %}</a>
</li>
{% endif %}
{% if constance_enabled and user.admin_permissions.can_config_system %}
<li class="tab {% block cur_settings %}{% endblock %}">
<a href="{% url "sys_settings" %}"><span class="sf2-icon-cog2"></span>{% trans "Settings" %}</a>
</li>
{% endif %}
{% if user.admin_permissions.can_manage_library %}
<li class="tab {% block cur_repo %}{% endblock %}">
<a href="{{ SITE_ROOT }}sysadmin/#all-libs/"><span class="sf2-icon-library"></span>{% trans "Libraries" %}</a>
</li>
{% endif %}
{% if user.admin_permissions.can_manage_user %}
<li class="tab {% block cur_users %}{% endblock %}">
<a href="{{ SITE_ROOT }}sys/useradmin/"><span class="sf2-icon-user"></span>{% trans "Users" %}</a>
</li>
{% endif %}
{% if user.admin_permissions.can_manage_group %}
<li class="tab {% block cur_groups %}{% endblock %}">
<a href="{{ SITE_ROOT }}sysadmin/#groups/"><span class="sf2-icon-group"></span>{% trans "Groups" %}</a>
</li>
{% endif %}
{% if is_pro and user.admin_permissions.can_manage_group %}
<li class="tab">
<a href="{{ SITE_ROOT }}sysadmin/#address-book/"><span class="sf2-icon-organization"></span>{% trans "Departments" context "address book" %}</a>
</li>
{% endif %}
{% if multi_tenancy and is_default_admin %}
<li class="tab {% block cur_org %}{% endblock %}">
<a href="{{ SITE_ROOT }}sys/orgadmin/"><span class="sf2-icon-organization"></span>{% trans "Organizations" %}</a>
</li>
{% endif %}
{% if multi_institution and is_default_admin %}
<li class="tab {% block cur_inst %}{% endblock %}">
<a href="{{ SITE_ROOT }}sys/instadmin/"><span class="sf2-icon-organization"></span>{% trans "Institutions" %}</a>
</li>
{% endif %}
{% if is_default_admin %}
<li class="tab {% block cur_notice %}{% endblock %}">
<a href="{{ SITE_ROOT }}sys/notificationadmin/"><span class="sf2-icon-msgs"></span>{% trans "Notifications" %}</a>
</li>
{% endif %}
{% if is_default_admin %}
<li class="tab {% block cur_links %}{% endblock %}">
<a href="{{ SITE_ROOT }}sys/publinkadmin/"><span class="sf2-icon-link"></span>{% trans "Links" %}</a>
</li>
{% endif %}
{% if sysadmin_extra_enabled and user.admin_permissions.can_view_user_log %}
<li class="tab {% block cur_log %}{% endblock %}">
<a href="{{ SITE_ROOT }}sys/loginadmin/"><span class="sf2-icon-clock"></span>{% trans "Logs" %}</a>
</li>
{% endif %}
{% if is_pro and is_default_admin and enable_file_scan %}
<li class="tab {% block cur_file_scan %}{% endblock %}">
<a href="{{ SITE_ROOT }}sys/file-scan-records/"><span class="sf2-icon-security"></span>{% trans "File Scan" %}</a>
</li>
{% endif %}
{% if is_pro and is_default_admin %}
<li class="tab {% block cur_virus_scan %}{% endblock %}">
<a href="{{ SITE_ROOT }}sys/virus_scan_records/"><span class="sf2-icon-security"></span>{% trans "Virus Scan" %}</a>
</li>
{% endif %}
{% if enable_guest_invitation and is_default_admin %}
<li class="tab {% block cur_invitations %}{% endblock %}">
<a href="{{ SITE_ROOT }}sys/invitationadmin/"><span class="sf2-icon-invite"></span>{% trans "Invitations" %}</a>
</li>
{% endif %}
{% if is_default_admin %}
<li class="tab tc {% if not enable_terms_and_conditions %} hide {% endif %} {% block cur_tc %}{% endblock %}">
<a href="{{ SITE_ROOT }}sys/termsadmin/"><span class="sf2-icon-wiki"></span>{% trans "Terms and Conditions" %}</a>
</li>
{% endif %}
{% if is_pro and user.admin_permissions.can_view_admin_log %}
<li class="tab">
<a href="{{ SITE_ROOT }}sysadmin/#admin-operation-logs/"><span class="sf2-icon-admin-log"></span>{% trans "Admin Logs" %}</a>
</li>
{% endif %}
{% if is_default_admin and enable_work_weixin %}
<li class="tab">
<a href="{{ SITE_ROOT }}sys/work-weixin/departments/"><span class="sf3-font-enterprise-wechat sf3-font"></span>企业微信集成</a>
</li>
{% endif %}
</ul>
{% endblock %}
</div>
</div>
<div id="right-panel" class="col-md-9 ov-auto flex-1">
{% block right_panel %}{% endblock %}
</div>
</div>
{% endblock %}

362
custom/templates/sysadmin/settings.html

@ -0,0 +1,362 @@
{% extends "sysadmin/base.html" %}
{% load seahub_tags i18n %}
{% block cur_settings %}tab-cur{% endblock %}
{% block right_panel %}
<h3 class="hd">{% trans "Settings" %}</h3>
<div class="seahub-web-settings">
<div class="tp-font-settings">
{% trans "Note: Settings via web interface are saved in database table (seahub-db/constance_config). They have a higher priority over the settings in config files." %}</div>
<h4>URL Definitionen</h4>
{% with type="input" setting_display_name="SERVICE_URL" setting_name="SERVICE_URL" setting_val=config_dict.SERVICE_URL %}
{% trans "The URL of the server, like https://seafile.example.com or http://192.168.1.2:8000" as help_tip %}
{% include "snippets/web_settings_form.html" %}
{% endwith %}
{% with type="input" setting_display_name="FILE_SERVER_ROOT" setting_name="FILE_SERVER_ROOT" setting_val=config_dict.FILE_SERVER_ROOT %}
{% trans "The internal URL for downloading/uploading files. Users will not be able to download/upload files if this is not set correctly. If you config Seafile behind Nginx/Apache, it should be SERVICE_URL/seafhttp, like https://seafile.example.com/seafhttp ." as help_tip %}
{% include "snippets/web_settings_form.html" %}
{% endwith %}
<h4>{% trans "Branding" %}</h4>
{% with type="input" setting_display_name="SITE_TITLE" setting_name="SITE_TITLE" setting_val=config_dict.SITE_TITLE %}
{% trans "Site title shown in a browser tab" as help_tip %}
{% include "snippets/web_settings_form.html" %}
{% endwith %}
{% with type="input" setting_display_name="SITE_NAME" setting_name="SITE_NAME" setting_val=config_dict.SITE_NAME %}
{% trans "Site name used in email sending" as help_tip %}
{% include "snippets/web_settings_form.html" %}
{% endwith %}
{% with type="file" setting_display_name="Logo" setting_name="logo" file_path=logo_path file_width=256 file_height=64 help_tip="logo.png, 256px * 64px" %}
{% include "snippets/web_settings_form.html" %}
{% endwith %}
{% with type="file" setting_display_name="Favicon" setting_name="favicon" file_path=favicon_path file_width=32 file_height=32 help_tip="favicon.ico, 32px * 32px" %}
{% include "snippets/web_settings_form.html" %}
{% endwith %}
{% with type="file" setting_name="login_bg_image" file_path=login_bg_image_path file_width=240 file_height=160 help_tip="login-bg.jpg, 2400px * 1600px" %}
{% trans "Login Background Image" as setting_display_name %}
{% include "snippets/web_settings_form.html" %}
{% endwith %}
{% with type="checkbox" setting_name="ENABLE_BRANDING_CSS" setting_val=config_dict.ENABLE_BRANDING_CSS %}
{% trans "ENABLE_BRANDING_CSS" as setting_display_name %}
{% trans "Use custom CSS" as help_tip %}
{% include "snippets/web_settings_form.html" %}
{% endwith %}
{% with type="code-textarea" setting_name="CUSTOM_CSS" setting_val=config_dict.CUSTOM_CSS %}
{% trans "Custom CSS" as setting_display_name %}
{% include "snippets/web_settings_form.html" %}
{% endwith %}
<h4>{% trans "User" %}</h4>
{% with type="checkbox" setting_name="ENABLE_SIGNUP" setting_val=config_dict.ENABLE_SIGNUP %}
{% trans "allow new registrations" as setting_display_name %}
{% trans "Allow new user registrations. Uncheck this to prevent anyone from creating a new account." as help_tip %}
{% include "snippets/web_settings_form.html" %}
{% endwith %}
{% with type="checkbox" setting_name="ACTIVATE_AFTER_REGISTRATION" setting_val=config_dict.ACTIVATE_AFTER_REGISTRATION %}
{% trans "activate after registration" as setting_display_name %}
{% trans "Activate user immediately after registration. If unchecked, a user need to be activated by administrator or via activation email" as help_tip %}
{% include "snippets/web_settings_form.html" %}
{% endwith %}
{% with type="checkbox" setting_name="REGISTRATION_SEND_MAIL" setting_val=config_dict.REGISTRATION_SEND_MAIL %}
{% trans "send activation email" as setting_display_name %}
{% trans "Send activation Email after user registration." as help_tip %}
{% include "snippets/web_settings_form.html" %}
{% endwith %}
{% with type="input" setting_name="LOGIN_REMEMBER_DAYS" setting_val=config_dict.LOGIN_REMEMBER_DAYS %}
{% trans "keep sign in" as setting_display_name %}
{% trans "Number of days that keep user sign in." as help_tip %}
{% include "snippets/web_settings_form.html" %}
{% endwith %}
{% with type="input" setting_display_name="LOGIN_ATTEMPT_LIMIT" setting_name="LOGIN_ATTEMPT_LIMIT" setting_val=config_dict.LOGIN_ATTEMPT_LIMIT %}
{% trans "The maximum number of failed login attempts before showing CAPTCHA." as help_tip %}
{% include "snippets/web_settings_form.html" %}
{% endwith %}
{% with type="checkbox" setting_display_name="FREEZE_USER_ON_LOGIN_FAILED" setting_name="FREEZE_USER_ON_LOGIN_FAILED" setting_val=config_dict.FREEZE_USER_ON_LOGIN_FAILED %}
{% trans "Freeze user account when failed login attempts exceed limit." as help_tip %}
{% include "snippets/web_settings_form.html" %}
{% endwith %}
<h4>{% trans "Groups" %}</h4>
{% with type="checkbox" setting_display_name="ENABLE_SHARE_TO_ALL_GROUPS" setting_name="ENABLE_SHARE_TO_ALL_GROUPS" setting_val=config_dict.ENABLE_SHARE_TO_ALL_GROUPS %}
{% trans "Enable users to share libraries to any groups in the system." as help_tip %}
{% include "snippets/web_settings_form.html" %}
{% endwith %}
<h4>{% trans "Password" %}</h4>
{% with type="checkbox" setting_name="USER_STRONG_PASSWORD_REQUIRED" setting_val=config_dict.USER_STRONG_PASSWORD_REQUIRED %}
{% trans "strong password" as setting_display_name %}
{% trans "Force user to use a strong password when sign up or change password." as help_tip %}
{% include "snippets/web_settings_form.html" %}
{% endwith %}
{% with type="checkbox" setting_name="FORCE_PASSWORD_CHANGE" setting_val=config_dict.FORCE_PASSWORD_CHANGE %}
{% trans "force password change" as setting_display_name %}
{% trans "Force user to change password when account is newly added or reset by admin" as help_tip %}
{% include "snippets/web_settings_form.html" %}
{% endwith %}
{% with type="input" setting_name="USER_PASSWORD_MIN_LENGTH" setting_val=config_dict.USER_PASSWORD_MIN_LENGTH %}
{% trans "password minimum length" as setting_display_name %}
{% trans "The least number of characters an account password should include." as help_tip %}
{% include "snippets/web_settings_form.html" %}
{% endwith %}
{% with type="input" setting_name="USER_PASSWORD_STRENGTH_LEVEL" setting_val=config_dict.USER_PASSWORD_STRENGTH_LEVEL %}
{% trans "password strength level" as setting_display_name %}
{% trans "The level(1-4) of an account password's strength. For example, '3' means password must have at least 3 of the following: num, upper letter, lower letter and other symbols" as help_tip %}
{% include "snippets/web_settings_form.html" %}
{% endwith %}
{% with type="checkbox" setting_name="ENABLE_TWO_FACTOR_AUTH" setting_val=config_dict.ENABLE_TWO_FACTOR_AUTH %}
{% trans "enable two factor authentication" as setting_display_name %}
{% trans "Enable two factor authentication" as help_tip %}
{% include "snippets/web_settings_form.html" %}
{% endwith %}
<h4>{% trans "Library" %}</h4>
{% with type="checkbox" setting_name="ENABLE_REPO_HISTORY_SETTING" setting_val=config_dict.ENABLE_REPO_HISTORY_SETTING %}
{% trans "library history" as setting_display_name %}
{% trans "Allow user to change library history settings" as help_tip %}
{% include "snippets/web_settings_form.html" %}
{% endwith %}
{% with type="checkbox" setting_name="ENABLE_ENCRYPTED_LIBRARY" setting_val=config_dict.ENABLE_ENCRYPTED_LIBRARY %}
{% trans "encrypted library" as setting_display_name %}
{% trans "Allow user to create encrypted libraries" as help_tip %}
{% include "snippets/web_settings_form.html" %}
{% endwith %}
{% with type="input" setting_name="REPO_PASSWORD_MIN_LENGTH" setting_val=config_dict.REPO_PASSWORD_MIN_LENGTH %}
{% trans "library password minimum length" as setting_display_name %}
{% trans "The least number of characters an encrypted library password should include." as help_tip %}
{% include "snippets/web_settings_form.html" %}
{% endwith %}
{% with type="input" setting_name="SHARE_LINK_PASSWORD_MIN_LENGTH" setting_val=config_dict.SHARE_LINK_PASSWORD_MIN_LENGTH %}
{% trans "download/upload link password minimum length" as setting_display_name %}
{% trans "The least number of characters a download/upload link password should include." as help_tip %}
{% include "snippets/web_settings_form.html" %}
{% endwith %}
{% with type="checkbox" setting_display_name="ENABLE_USER_CREATE_ORG_REPO" setting_name="ENABLE_USER_CREATE_ORG_REPO" setting_val=config_dict.ENABLE_USER_CREATE_ORG_REPO %}
{% trans "Allow user to add organization libraries. Otherwise, only system admin can add organization libraries." as help_tip %}
{% include "snippets/web_settings_form.html" %}
{% endwith %}
{% with type="checkbox" setting_display_name="ENABLE_USER_CLEAN_TRASH" setting_name="ENABLE_USER_CLEAN_TRASH" setting_val=config_dict.ENABLE_USER_CLEAN_TRASH %}
{% trans "Allow user to clean library trash" as help_tip %}
{% include "snippets/web_settings_form.html" %}
{% endwith %}
<h4>{% trans "Online Preview" %}</h4>
{% with type="textarea" setting_name="TEXT_PREVIEW_EXT" setting_val=config_dict.TEXT_PREVIEW_EXT %}
{% trans "text file extensions" as setting_display_name %}
{% trans "Extensions of text files that can be online previewed, each suffix is separated by a comma." as help_tip %}
{% include "snippets/web_settings_form.html" %}
{% endwith %}
<h4>{% trans "Sync" %}</h4>
{% with type="checkbox" setting_display_name="DISABLE_SYNC_WITH_ANY_FOLDER" setting_name="DISABLE_SYNC_WITH_ANY_FOLDER" setting_val=config_dict.DISABLE_SYNC_WITH_ANY_FOLDER %}
{% trans "If turn on, the desktop clients will not be able to sync a folder outside the default Seafile folder." as help_tip %}
{% include "snippets/web_settings_form.html" %}
{% endwith %}
<h4>{% trans "Terms" %}</h4>
{% with type="checkbox" setting_display_name="ENABLE_TERMS_AND_CONDITIONS" setting_name="ENABLE_TERMS_AND_CONDITIONS" setting_val=config_dict.ENABLE_TERMS_AND_CONDITIONS %}
{% trans "Enable system admin to add Terms and Conditions, and all users will have to accept the terms." as help_tip %}
{% include "snippets/web_settings_form.html" %}
{% endwith %}
</div>
{% endblock %}
{% block extra_script %}
<script type="text/javascript">
$('.input, .textarea', $('.web-setting-form')).on('focus', function() {
var $otherFormSubmit = $('.web-setting-form .submit:visible');
if ($otherFormSubmit.length > 0) {
$otherFormSubmit.siblings('.cancel').trigger('click');
}
var $form = $(this).closest('form');
$('.submit, .cancel', $form).show();
});
$('.web-setting-form .cancel').on('click', function() {
var $form = $(this).closest('form');
$('.error, .submit, .cancel', $form).hide();
var $input = $('.input, .textarea', $form);
$input.val($input.attr('data-cur'));
});
$(document).on('click', function(e) {
var target = e.target || event.srcElement;
var $op = $('.web-setting-form .submit:visible');
if ($op.length && !$('.input, .textarea, .submit, .cancel', $op.closest('form')).is(target)) {
$('.cancel', $op.closest('form')).trigger('click');
}
});
$('.web-setting-checkbox').on('change', function() {
var checkbox = $(this),
value,
key = checkbox.attr('name');
if (checkbox.prop('checked')) {
value = 1;
} else {
value = 0;
}
$.ajax({
url: "{% url 'sys_settings' %}",
type: 'POST',
dataType: 'json',
cache: false,
beforeSend: prepareCSRFToken,
data: { 'key': key, 'value': value },
success: function() {
feedback("{% trans "Success" %}", 'success');
// for 'terms'
if (key == 'ENABLE_TERMS_AND_CONDITIONS') {
if (value == 1) {
$('.tc').removeClass('hide');
} else {
$('.tc').addClass('hide');
}
}
},
error: ajaxErrorHandler
});
});
$('.web-input-setting-form, .web-textarea-setting-form').on('submit', function() {
var $form = $(this),
$error = $form.find('.error'),
$input = $form.hasClass('web-input-setting-form') ? $('.input', $form) : $('.textarea', $form),
$sb_btn = $('.submit', $form),
$cancel_btn = $('.cancel', $form),
key = $input.attr('name'),
value = $.trim($input.val());
if (!value) {
$error.html("{% trans "It is required." %}").show();
return false;
}
if (value == $input.attr('data-cur')) { // no change
$cancel_btn.trigger('click');
return false;
}
disable($sb_btn);
$.ajax({
url: "{% url 'sys_settings' %}",
type: 'POST',
dataType: 'json',
beforeSend: prepareCSRFToken,
data: { 'key': key, 'value': value },
success: function() {
$input.val(value).attr('data-cur', value);
$error.html('').hide();
enable($sb_btn);
$sb_btn.hide();
$cancel_btn.hide();
feedback("{% trans "Success" %}", 'success');
},
error: function(xhr, textStatus, errorThrown) {
var error_msg = prepareAjaxErrorMsg(xhr);
$error.html(error_msg).show();
enable($sb_btn);
}
});
return false;
});
$('.web-setting-file-upload-btn').on('click', function() {
var $container = $(this).closest('.web-setting-file-upload');
$('.web-setting-file-upload-input', $container).trigger('click');
});
$('.web-setting-file-upload-input').on('change', function() {
var $input = $(this);
var file;
if ($input[0].files) {
file = $input[0].files[0];
} else {
return;
}
var input_name = $input.attr('name');
var fd = new FormData();
var url;
switch(input_name) {
case 'logo': url = '{% url 'api-v2.1-admin-logo' %}'; break;
case 'favicon': url = '{% url 'api-v2.1-admin-favicon' %}'; break;
case 'login_bg_image': url = '{% url 'api-v2.1-admin-login-background-image' %}'; break;
}
fd.append(input_name, file);
$.ajax({
url: url,
type: 'POST',
data: fd,
processData: false,
contentType: false,
beforeSend: prepareCSRFToken,
success: function(){
location.reload(true);
},
error: ajaxErrorHandler
});
});
</script>
{% endblock %}

62
custom/templates/sysadmin/sys_inst_info_admins.html

@ -0,0 +1,62 @@
{% extends "sysadmin/sys_inst_info_base.html" %}
{% load i18n seahub_tags %}
{% block right_panel %}
<div class="tabnav">
<ul class="tabnav-tabs">
<li class="tabnav-tab"><a href="{% url 'sys_inst_info_users' inst.pk %}">{% trans "Members" %}</a></li>
<li class="tabnav-tab tabnav-tab-cur"><a href="{% url 'sys_inst_info_admins' inst.pk %}">{% trans "Admins" %}</a></li>
</ul>
</div>
{% if admins %}
<table>
<tr>
<th width="25%">{% trans "Email" %}</th>
<th width="10%">{% trans "Status" %}</th>
<th width="20%">{% trans "Space Used" %}</th>
<th width="25%">{% trans "Create At / Last Login" %}</th>
<th width="20%">{% trans "Operations" %}</th>
</tr>
{% for user in admins %}
<tr data-userid="{{user.email}}">
<td><a href="{% url 'user_info' user.email %}">{{ user.email }}</a></td>
<td>
<div class="user-status">
{% if user.is_active %}
<span class="user-status-cur-value">{% trans "Active" %}</span>
{% else %}
<span class="user-status-cur-value">{% trans "Inactive" %}</span>
{% endif %}
</div>
</td>
<td style="font-size:14px;">
<p> {{ user.space_usage|seahub_filesizeformat }} {% if user.space_quota > 0 %} / {{ user.space_quota|seahub_filesizeformat }} {% endif %} </p>
</td>
<td style="font-size:14px;">
{{ user.ctime|tsstr_sec }} / {% if user.last_login %}{{user.last_login|translate_seahub_time}} {% else %} -- {% endif %}
</td>
<td>
<a href="#" class="js-toggle-admin op vh" data-url="{% url 'sys_inst_toggle_admin' inst.pk user.email %}" data-target="{{ user.email }}">{% trans "Revoke Admin" %}</a>
</td>
</tr>
{% endfor %}
</table>
{% else %}
<p>{% trans "Empty" %}</p>
{% endif %}
{% endblock %}
{% block extra_script %}{{ block.super }}
<script type="text/javascript">
addConfirmTo($('.js-toggle-admin'), {
'title': "Toggle Admin",
'con': "Sure ?",
'post': true
});
</script>
{% endblock %}

182
custom/templates/sysadmin/sys_inst_info_user.html

@ -0,0 +1,182 @@
{% extends "sysadmin/sys_inst_info_base.html" %}
{% load i18n seahub_tags %}
{% load staticfiles %}
{% block extra_style %}
<link rel="stylesheet" type="text/css" href="{% static "css/select2-3.5.2.css" %}" />
<link rel="stylesheet" type="text/css" href="{% static "css/select2.custom.css" %}" />
{% endblock %}
{% block right_panel %}
<div class="tabnav">
<ul class="tabnav-tabs">
<li class="tabnav-tab tabnav-tab-cur"><a href="{% url 'sys_inst_info_users' inst.pk %}">{% trans "Members" %}</a></li>
<li class="tabnav-tab"><a href="{% url 'sys_inst_info_admins' inst.pk %}">{% trans "Admins" %}</a></li>
</ul>
<div class="js-op-for-all fright">
<button id="add-member-btn">{% trans "Add Members" %}</button>
</div>
</div>
<form id="add-member-form" action="" method="" class="hide">
<h3>{% trans "Add Members" %}</h3>
<label>{% trans "Email" %}</label><br />
<input type="hidden" name="emails" /><br />
<p class="error hide"></p>
<button type="submit" class="submit">{% trans "Submit" %}</button>
</form>
{% if users %}
<table>
<tr>
<th width="25%">{% trans "Email" %}</th>
<th width="10%">{% trans "Status" %}</th>
<th width="20%">{% trans "Space Used" %}</th>
<th width="25%">{% trans "Create At / Last Login" %}</th>
<th width="20%">{% trans "Operations" %}</th>
</tr>
{% for user in users %}
<tr data-userid="{{user.email}}">
<td><a href="{% url 'user_info' user.email %}">{{ user.email }}</a></td>
<td>
<div class="user-status">
{% if user.is_active %}
<span class="user-status-cur-value">{% trans "Active" %}</span>
{% else %}
<span class="user-status-cur-value">{% trans "Inactive" %}</span>
{% endif %}
</div>
</td>
<td style="font-size:14px;">
{{ user.space_usage|seahub_filesizeformat }} {% if user.space_quota > 0 %} / {{ user.space_quota|seahub_filesizeformat }} {% endif %}
</td>
<td style="font-size:14px;">
{{ user.ctime|tsstr_sec }} / {% if user.last_login %}{{user.last_login|translate_seahub_time}} {% else %} -- {% endif %}
</td>
<td>
<a href="#" class="js-toggle-admin op vh" data-url="{% url 'sys_inst_toggle_admin' inst.pk user.email %}" data-target="{{ user.email }}">{% if user.inst_admin %}{% trans "Revoke Admin" %}{% else %}{% trans "Set Admin" %}{% endif %}</a>
</td>
</tr>
{% endfor %}
</table>
{% include "snippets/admin_paginator.html" %}
{% else %}
<p>{% trans "Empty" %}</p>
{% endif %}
<div id="activate-msg" class="hide">
<p>{% trans "Activating..., please wait" %}</p>
</div>
{% endblock %}
{% block extra_script %}{{ block.super }}
<script type="text/javascript" src= "{% static "scripts/lib/select2-3.5.2.js" %}"></script>
<script type="text/javascript">
addConfirmTo($('.js-toggle-admin'), {
'title': "Toggle Admin",
'con': "Sure ?",
'post': true
});
$('.user-status-edit-icon').on('click', function() {
$(this).parent().addClass('hide');
$(this).parent().next().removeClass('hide'); // show 'select'
});
$('.user-status-select').on('change', function() {
var select = $(this),
select_val = select.val(),
uid = select.parents('tr').attr('data-userid'),
url = "{{ SITE_ROOT }}useradmin/toggle_status/" + uid + "/?s=" + select_val;
$.ajax({
url: url,
type: 'GET',
dataType: 'json',
cache: false,
beforeSend: function() {
if (select_val == 1) {
// show activating popup
$('#activate-msg').modal();
$('#simplemodal-container').css({'height':'auto'});
}
},
success: function(data) {
if (data['email_sent']) {
feedback("{% trans "Edit succeeded, an email has been sent." %}", 'success');
} else if (data['email_sent'] === false) {
feedback("{% trans "Edit succeeded, but failed to send email, please check your email configuration." %}", 'success');
} else {
feedback("{% trans "Edit succeeded" %}", 'success');
}
select.prev().children('span').html(select.children('option[value="' +select.val() + '"]').text());
select.addClass('hide');
select.prev().removeClass('hide');
$.modal.close();
},
error: function() {
feedback("{% trans "Edit failed." %}", 'error');
select.addClass('hide');
select.prev().removeClass('hide');
$.modal.close();
}
});
});
$(document).on('click', function(e) {
var target = e.target || event.srcElement;
// target can't be edit-icon
if (!$('.user-status-edit-icon, .user-status-select').is(target)) {
$('.user-status').removeClass('hide');
$('.user-status-select').addClass('hide');
}
});
// add members
$('#add-member-btn').on('click', function(){
var $form = $('#add-member-form');
$form.modal({focus: false});
$('#simplemodal-container').css({'width':'auto', 'height':'auto'});
$('[name="emails"]', $form).select2($.extend({
width: '280px',
placeholder: "{% trans "Search user or enter email and press Enter" %}",
formatInputTooShort: "{% trans "Please enter 1 or more character" %}",
formatNoMatches: "{% trans "No matches" %}",
formatSearching: "{% trans "Searching..." %}",
formatAjaxError: "{% trans "Loading failed" %}"
}, userInputOPtionsForSelect2('{% url 'search-user' %}')));
});
$('#add-member-form').on('submit', function(){
var $form = $(this);
var $error = $('.error', $form);
var $submit = $('[type="submit"]', $form);
var emails = $('[name="emails"]', $form).select2('val');
if (!emails.length) {
$error.html("{% trans "It is required." %}").show();
return false;
}
disable($submit);
$.ajax({
url: "{% url 'sys_inst_add_user' inst.id %}",
type: 'POST',
dataType: 'json',
data: {
'emails': emails.join(',')
},
beforeSend: prepareCSRFToken,
success: function(data) {
location.reload(true);
},
error: function(xhr, textStatus, errorThrown) {
var error_msg = prepareAjaxErrorMsg(xhr);
$error.html(error_msg).show();
enable($submit);
}
});
return false;
});
</script>
{% endblock %}

62
custom/templates/sysadmin/sys_inst_search_user.html

@ -0,0 +1,62 @@
{% extends "sysadmin/sys_inst_info_base.html" %}
{% load i18n seahub_tags %}
{% block right_panel %}
<h3>{% trans "Search User"%}</h3>
<form id="search-user-form" method="get" action=".">
<label>{% trans "Email" %}</label><br />
<input type="text" name="q" class="input" value="{{q}}" /><br />
<input type="submit" value="{% trans "Submit" %}" class="submit" />
</form>
<h3>{% trans "Result"%}</h3>
{% if users %}
<table>
<tr>
<th width="25%">{% trans "Email" %}</th>
<th width="10%">{% trans "Status" %}</th>
<th width="20%">{% trans "Space Used" %}</th>
<th width="25%">{% trans "Create At / Last Login" %}</th>
<th width="20%">{% trans "Operations" %}</th>
</tr>
{% for user in users %}
<tr data-userid="{{user.email}}">
<td><a href="{% url 'user_info' user.email %}">{{ user.email }}</a></td>
<td>
<div class="user-status">
{% if user.is_active %}
<span class="user-status-cur-value">{% trans "Active" %}</span>
{% else %}
<span class="user-status-cur-value">{% trans "Inactive" %}</span>
{% endif %}
</div>
</td>
<td style="font-size:14px;">
<p> {{ user.space_usage|seahub_filesizeformat }} {% if user.space_quota > 0 %} / {{ user.space_quota|seahub_filesizeformat }} {% endif %} </p>
</td>
<td style="font-size:14px;">
{{ user.ctime|tsstr_sec }} / {% if user.last_login %}{{user.last_login|translate_seahub_time}} {% else %} -- {% endif %}
</td>
<td>
<a href="#" class="js-toggle-admin op vh" data-url="{% url 'sys_inst_toggle_admin' inst.pk user.email %}" data-target="{{ user.email }}">{% if user.inst_admin %}{% trans "Revoke Admin" %}{% else %}{% trans "Set Admin" %}{% endif %}</a>
</td>
</tr>
{% endfor %}
</table>
{% else %}
<p>{% trans "No result" %}</p>
{% endif %}
{% endblock %}
{% block extra_script %}
<script type="text/javascript">
addConfirmTo($('.js-toggle-admin'), {
'title': "Toggle Admin",
'con': "Sure ?",
'post': true
});
</script>
{% endblock %}

61
custom/templates/sysadmin/sys_org_info_library.html

@ -0,0 +1,61 @@
{% extends "sysadmin/sys_org_info_base.html" %}
{% load i18n seahub_tags %}
{% block right_panel %}
<div class="tabnav">
{% with cur_tab='library' %}
{% include 'sysadmin/snippets/sys_org_info_nav.html' %}
{% endwith %}
</div>
{% if org_repos %}
<table class="repo-list">
<tr>
<th width="4%"><!--icon--></th>
<th width="31%">{% trans "Name" %}</th>
<th width="25%">ID</th>
<th width="25%">{% trans "Owner" %}</th>
<th width="15%">{% trans "Operations" %}</th>
</tr>
{% for repo in org_repos %}
<tr>
{% if repo.encrypted %}
<td><img src="{{MEDIA_URL}}img/lib/48/lib-encrypted.png" width="24" title="{% trans "Encrypted"%}" alt="{% trans "library icon" %}" /></td>
{% else %}
<td><img src="{{MEDIA_URL}}img/lib/48/lib.png" width="24" title="{% trans "Read-Write"%}" alt="{% trans "library icon" %}" /></td>
{% endif %}
<td>{{ repo.name }}</td>
<td style="font-size:14px;">{{ repo.id }}</td>
<td>
{% if repo.owner %}
<a href="{{ SITE_ROOT }}useradmin/info/{{ repo.owner }}/">{{ repo.owner}}</a>
{% else %}
--
{% endif %}
</td>
<td>
<div>
<a href="#" data-url="{% url "sys_repo_delete" repo.id %}" data-target="{{ repo.name }}" class="repo-delete-btn op vh">{% trans "Delete" %}</a>
</div>
</td>
</tr>
{% endfor %}
</table>
{% else %}
<div class="empty-tips">
<h2 class="alc">{% trans "This organization doesn't have any libraries" %}</h2>
</div>
{% endif %}
{% endblock %}
{% block extra_script %}
<script type="text/javascript">
{% include 'sysadmin/sys_org_set_quota_js.html' %}
addConfirmTo($('.repo-delete-btn'), {
'title': "{% trans "Delete Library" %}",
'con': "{% trans "Are you sure you want to delete %s ?" %}",
'post': true
});
</script>
{% endblock %}

253
custom/templates/sysadmin/sys_org_info_user.html

@ -0,0 +1,253 @@
{% extends "sysadmin/sys_org_info_base.html" %}
{% load i18n seahub_tags %}
{% block right_panel %}
<div class="tabnav">
{% with cur_tab='user' %}
{% include 'sysadmin/snippets/sys_org_info_nav.html' %}
{% endwith %}
<div class="fright">
<button id="add-user-btn">{% trans "Add user" %}</button>
</div>
</div>
<table>
<tr>
<th width="25%">{% trans "Email" %}</th>
<th width="10%">{% trans "Status" %}</th>
<th width="20%">{% trans "Space Used" %}</th>
<th width="25%">{% trans "Create At / Last Login" %}</th>
<th width="20%">{% trans "Operations" %}</th>
</tr>
{% for user in users %}
<tr data-userid="{{user.email}}" data-url="{% url 'api-v2.1-admin-org-user' org.org_id user.email %}">
<td><a href="{% url 'user_info' user.email %}">{{ user.email }}</a></td>
<td>
<div class="user-status">
{% if user.is_active %}
<span class="user-status-cur-value">{% trans "Active" %}</span>
{% else %}
<span class="user-status-cur-value">{% trans "Inactive" %}</span>
{% endif %}
<span title="{% trans "Edit" %}" class="user-status-edit-icon op-icon sf2-icon-edit vh"></span>
</div>
<select name="permission" class="user-status-select hide">
<option value="true" {% if user.is_active %}selected="selected"{% endif %}>{% trans "Active" %}</option>
<option value="false" {% if not user.is_active %}selected="selected"{% endif %}>{% trans "Inactive" %}</option>
</select>
</td>
<td>
{{ user.self_usage|seahub_filesizeformat }} {% if user.quota > 0 %} / {{ user.quota|seahub_filesizeformat }} {% endif %}
</td>
<td style="font-size:14px;">
{{ user.ctime|tsstr_sec }} / {% if user.last_login %}{{user.last_login|translate_seahub_time}} {% else %} -- {% endif %}
</td>
<td>
{% if not user.is_self %}
<a href="#" class="remove-user-btn op vh">{% trans "Delete" %}</a>
<a href="#" class="reset-user-btn op vh" data-url="{% url 'user_reset' user.email %}" data-target="{{ user.email }}">{% trans "ResetPwd" %}</a>
{% endif %}
</td>
</tr>
{% endfor %}
</table>
<div id="activate-msg" class="hide">
<p>{% trans "Activating..., please wait" %}</p>
</div>
<form id="add-user-form" action="" method="post" class="hide">{% csrf_token %}
<h3>{% trans "Add user" %}</h3>
<label for="id_email">{% trans "Email" %}</label><br />
<input type="text" name="email" id="id_email" class="input" /><br />
<label for="id_name">{% trans "Name(optional)" %}</label><br />
<input type="text" name="name" id="id_name" class="input" /><br />
<label for="id_password1">{% trans "Password" %}</label>
<div class="passwd-wrapper">
<input type="password" name="password1" id="id_password1" class="passwd input" />
<span title="{% trans "Show" %}" class="icon-eye show-or-hide-password cspt"></span>
<span title="{% trans "Generate a random password" %}" class="icon-magic generate-random-password cspt"></span>
</div>
<label for="id_password2">{% trans "Confirm Password" %}</label><br />
<input type="password" name="password2" id="id_password2" class="input" /><br />
<p class="error hide"></p>
<button type="submit" class="submit">{% trans "Submit" %}</button>
</form>
{% endblock %}
{% block extra_script %}
<script type="text/javascript">
{% include 'sysadmin/sys_org_set_quota_js.html' %}
$('#add-user-btn').on('click', function() {
$('#add-user-form').modal();
$('#simplemodal-container').css({'width':'auto', 'height':'auto'});
});
$('#add-user-form .show-or-hide-password').on('click', function() {
var icon = $(this),
passwd_input = $('input[name=password1], input[name=password2]', $('#add-user-form'));
icon.toggleClass('icon-eye icon-eye-slash');
if (icon.hasClass('icon-eye')) {
icon.attr('title', "{% trans "Show" %}");
passwd_input.prop('type', 'password');
} else {
icon.attr('title', "{% trans "Hide" %}");
passwd_input.prop('type', 'text');
}
});
$('#add-user-form .generate-random-password').on('click', function() {
var form = $('#add-user-form');
var random_password = '';
var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz0123456789';
for (var i = 0; i < 8; i++) {
random_password += possible.charAt(Math.floor(Math.random() * possible.length));
}
$('input[name=password1], input[name=password2]', form).prop('type', 'text').val(random_password);
$('.show-or-hide-password', form)
.attr('title', "{% trans "Hide" %}")
.removeClass('icon-eye').addClass('icon-eye-slash');
});
$('#add-user-form').on('submit', function() {
var form = $(this),
form_id = $(this).attr('id'),
org_id = {{ org.org_id }},
email = $.trim(form.children('[name="email"]').val()),
name = $.trim($('[name="name"]', form).val()),
pwd1 = $.trim(form.find('[name="password1"]').val()),
pwd2 = $.trim(form.children('[name="password2"]').val());
if (!email) {
apply_form_error(form_id, "{% trans "Email cannot be blank" %}");
return false;
}
if (!pwd1) {
apply_form_error(form_id, "{% trans "Password cannot be blank" %}");
return false;
}
if (!pwd2) {
apply_form_error(form_id, "{% trans "Please enter the password again" %}");
return false;
}
if (pwd1 != pwd2) {
apply_form_error(form_id, "{% trans "Passwords do not match" %}");
return false;
}
var submit_btn = $(this).find('[type="submit"]');
var url = "{% url 'api-v2.1-admin-org-users' org.org_id %}";
disable(submit_btn);
$.ajax({
url: url,
type: 'POST',
datatype: 'json',
cache: false,
beforeSend: prepareCSRFToken,
data: {
'email': email,
'name': name,
'password': pwd1
},
success: function(data) {
location.reload(true);
},
error: function(xhr, textStatus, errorThrown) {
var error_msg = prepareAjaxErrorMsg(xhr);
apply_form_error(form_id, error_msg);
enable(submit_btn);
}
});
return false;
});
$('.remove-user-btn').on('click', function() {
var _this = $(this),
uid = _this.parents('tr').attr('data-userid'),
url = _this.parents('tr').attr('data-url'),
popupTitle = "{% trans "Delete User" %}",
popupContent = "{% trans "Are you sure you want to delete %s ?" %}".replace('%s', '<span class="op-target ellipsis ellipsis-op-target" title="' + HTMLescape(uid) + '">' + HTMLescape(uid) + '</span>');
var yesCallback = function() {
$.ajax({
url: url,
type: 'DELETE',
dataType: 'json',
cache: false,
beforeSend: prepareCSRFToken,
success: function() {
_this.closest('tr').remove();
feedback("{% trans "Successfully deleted 1 item." %}", 'success');
},
error: ajaxErrorHandler,
complete: function() {
$.modal.close();
}
});
};
showConfirm(popupTitle, popupContent, yesCallback);
return false;
});
addConfirmTo($('.reset-user-btn'), {
'title':"{% trans "Password Reset" %}",
'con':"{% trans "Are you sure you want to reset the password of %s ?" %}",
'post': true // post request
});
$('.user-status-edit-icon').on('click', function() {
$(this).parent().addClass('hide');
$(this).parent().next().removeClass('hide'); // show 'select'
});
$('.user-status-select').on('change', function() {
var select = $(this),
select_val = select.val(),
uid = select.parents('tr').attr('data-userid'),
url = select.parents('tr').attr('data-url'),
$select_prev = $(this).prev('.user-status'); // .user-status, .user-role
if (select_val == 'true') {
// show activating popup
$('#activate-msg').modal();
$('#simplemodal-container').css({'height':'auto'});
}
$.ajax({
url: url,
type: 'PUT',
data: {'active': select_val},
dataType: 'json',
cache: false,
beforeSend: prepareCSRFToken,
success: function(data) {
feedback("{% trans "Edit succeeded" %}", 'success');
$('.user-status-cur-value', $select_prev).html(select.children('option[value="' +select.val() + '"]').text());
select.addClass('hide');
$select_prev.removeClass('hide');
$.modal.close();
},
error: function() {
feedback("{% trans 'Edit failed.' %}", 'error');
select.addClass('hide');
select.prev().removeClass('hide');
$.modal.close();
}
});
});
$(document).on('click', function(e) {
var target = e.target || event.srcElement;
// target can't be edit-icon
if (!$('.user-status-edit-icon, .user-status-select').is(target)) {
$('.user-status').removeClass('hide');
$('.user-status-select').addClass('hide');
}
});
</script>
{% endblock %}

54
custom/templates/sysadmin/sys_useradmin_ldap.html

@ -0,0 +1,54 @@
{% extends "sysadmin/base.html" %}
{% load seahub_tags i18n %}
{% block cur_users %}tab-cur{% endblock %}
{% block left_panel %}{{block.super}}
<form action="{% url 'user_search' %}" method="get" class="side-search-form">
<input type="text" name="email" class="input" value="" placeholder="{% trans "Search users..." %}" />
</form>
{% endblock %}
{% block right_panel %}
<div class="tabnav">
<ul class="tabnav-tabs">
<li class="tabnav-tab"><a href="{% url 'sys_useradmin' %}">{% trans "Database" %}</a></li>
<li class="tabnav-tab tabnav-tab-cur"><a href="{% url 'sys_useradmin_ldap' %}">{% trans "LDAP" %}</a></li>
<li class="tabnav-tab"><a href="{% url 'sys_useradmin_ldap_imported' %}">{% trans "LDAP(imported)" %}</a></li>
{% if is_default_admin %}
<li class="tabnav-tab"><a href="{% url 'sys_useradmin_admins' %}">{% trans "Admins" %}</a></li>
{% endif %}
</ul>
</div>
<table>
<tr>
<th width="40%">{% trans "Email" %}</th>
<th width="25%">{% trans "Space Used / Quota" %}</th>
<th width="35%">{% trans "Create At / Last Login" %}</th>
</tr>
{% for user in users %}
<tr>
<td data="{{user.id}}"><a href="{{ SITE_ROOT }}useradmin/info/{{ user.props.email }}/">{{ user.email }}</a></td>
<td style="font-size:14px;">
{{ user.space_usage|seahub_filesizeformat }} /
{% if user.space_quota > 0 %}
{{ user.space_quota|seahub_filesizeformat }}
{% else %}
--
{% endif %}
</td>
<td> -- / {% if user.last_login %}{{user.last_login|translate_seahub_time}} {% else %} -- {% endif %}</td>
</tr>
{% endfor %}
</table>
{% include "sysadmin/useradmin_paginator.html" %}
{% endblock %}
{% block extra_script %}
<script type="text/javascript">
</script>
{% endblock %}

165
custom/templates/sysadmin/useradmin_table.html

@ -0,0 +1,165 @@
{% load seahub_tags i18n %}
<table>
<tr>
<th width="3%"><input type="checkbox" /></th>
{% if is_pro %}
<th width="21%">ID / {% trans "Name" %} / {% trans "Contact Email" %}</th>
<th width="9%">{% trans "Status" %}</th>
<th width="15%">{% trans "Role" %}</th>
{% else %}
<th width="33%">ID / {% trans "Name" %} / {% trans "Contact Email" %}</th>
<th width="12%">{% trans "Status" %}</th>
{% endif %}
{% if show_institution %}
<th width="14%">{% trans "Space Used / Quota" %}</th>
<th width="10%">{% trans "Institution" %}</th>
<th width="18%">{% trans "Create At / Last Login" %}</th>
<th width="10%"></th>
{% else %}
<th width="16%">{% trans "Space Used / Quota" %}</th>
<th width="22%">{% trans "Create At / Last Login" %}</th>
<th width="14%"></th>
{% endif %}
</tr>
{% for user in users %}
<tr data-userid="{{user.email}}">
<td><input type="checkbox" /></td>
<td>
<a href="{% url 'user_info' user.email %}">{{ user.email|email2nickname }}</a>
{% if user.contact_email %}<br />{{ user.contact_email }}{% endif %}
{% if not is_admin_page %}
{% if user.org %}
<p style="font-size:14px;"><a href="{% url 'sys_org_info_user' user.org.org_id %}">({{user.org.org_name}})</a></p>
{% endif %}
{% if user.trial_info %}
<p style="font-size:14px;">(Trial &nbsp;<a href="#" class="unset-trial" data-target="{{ user.email }}" data-url="{% url 'remove_trial' user.email %}">X</a>)</p>
{% endif %}
{% endif %}
</td>
<td>
<div class="user-status">
{% if user.is_active %}
<span class="user-status-cur-value">{% trans "Active" %}</span>
{% else %}
<span class="user-status-cur-value">{% trans "Inactive" %}</span>
{% endif %}
<span title="{% trans "Edit"%}" class="user-status-edit-icon sf2-icon-edit op-icon vh"></span>
</div>
<select name="permission" class="user-status-select hide">
<option value="1" {%if user.is_active %}selected="selected"{% endif %}>{% trans "Active" %}</option>
<option value="0" {%if not user.is_active %}selected="selected"{% endif %}>{% trans "Inactive"%}</option>
</select>
</td>
{% if is_pro %}
<td>
{% if not is_admin_page %}
<div class="user-role">
{% if user.is_guest %}
<span class="user-role-cur-value">{% trans "Guest" %}</span>
{% elif user.is_default %}
<span class="user-role-cur-value">{% trans "Default" %}</span>
{% else %}
<span class="user-role-cur-value">{{user.role}}</span>
{% endif %}
<span title="{% trans "Edit"%}" class="user-role-edit-icon sf2-icon-edit op-icon vh"></span>
</div>
<select name="role" class="user-role-select hide">
<option value={{default_user}} {%if user.is_default %}selected="selected"{% endif %}>{% trans "Default" %}</option>
<option value={{guest_user}} {%if user.is_guest %}selected="selected"{% endif %}>{% trans "Guest"%}</option>
{% for role in extra_user_roles %}
<option value={{role}} {%if user.role == role %}selected="selected"{% endif %}>{{ role }}</option>
{% endfor %}
</select>
{% else %} {# else for `if not is_admin_page` #}
<div class="admin-role">
{% if user.admin_role == default_admin %}
<span class="admin-role-cur-value">{% trans "Default Admin" context "Default Administrator" %}</span>
{% elif user.admin_role == system_admin %}
<span class="admin-role-cur-value">{% trans "System Admin" context "System Administrator" %}</span>
{% elif user.admin_role == daily_admin %}
<span class="admin-role-cur-value">{% trans "Daily Admin" context "Daily Administrator" %}</span>
{% elif user.admin_role == audit_admin %}
<span class="admin-role-cur-value">{% trans "Audit Admin" context "Audit Administrator" %}</span>
{% else %}
<span class="admin-role-cur-value">{{user.admin_role}}</span>
{% endif %}
<span title="{% trans "Edit"%}" class="admin-role-edit-icon sf2-icon-edit op-icon vh"></span>
</div>
<select name="role" class="admin-role-select hide">
<option value="{{ default_admin }}"{% if user.admin_role == default_admin %} selected="selected"{% endif %}>{% trans "Default Admin" context "Default Administrator" %}</option>
<option value="{{ system_admin }}"{% if user.admin_role == system_admin %} selected="selected"{% endif %}>{% trans "System Admin" context "System Administrator" %}</option>
<option value="{{ daily_admin }}"{% if user.admin_role == daily_admin %} selected="selected"{% endif %}>{% trans "Daily Admin" context "Daily Administrator" %}</option>
<option value="{{ audit_admin }}"{% if user.admin_role == audit_admin %} selected="selected"{% endif %}>{% trans "Audit Admin" context "Audit Administrator" %}</option>
{% for role in extra_admin_roles %}
<option value="{{ role }}"{% if user.admin_role == role %} selected="selected"{% endif %}>{{ role }}</option>
{% endfor %}
</select>
{% endif %}
</td>
{% endif %}
<td style="font-size:15px;">
{{ user.space_usage|seahub_filesizeformat }} /
<span class="user-space-quota">
{% if user.space_quota >= 0 %}
{{ user.space_quota|seahub_filesizeformat }}
{% elif user.space_quota == -2 %}
--
{% else %}
<span class="error">{% trans "Error" %}</span>
{% endif %}
</span>
<span title="{% trans "Edit Quota" %}" class="quota-edit-icon sf2-icon-edit op-icon vh"></span>
</td>
{% if show_institution %}
<td>
<div class="user-institution">
<span class="user-institution-cur-value">{{ user.institution }}</span>
<span title="{% trans "Edit"%}" class="user-institution-edit-icon sf2-icon-edit op-icon vh"></span>
</div>
<select name="institution" class="user-institution-select hide">
<option value="" {% if user.institution == "" %} selected="selected"{% endif %}></option>
{% for inst in institutions %}
<option value="{{inst}}" {% if user.institution == inst %} selected="selected"{% endif %}>{{inst}}</option>
{% endfor %}
</select>
</td>
{% endif %}
<td>
{% if user.source == "DB" %}
{{ user.ctime|tsstr_sec }} /<br />
{% else %}
-- /
{% endif %}
{% if user.last_login %}{{user.last_login|translate_seahub_time}} {% else %} -- {% endif %}
</td>
<td>
{% if not user.is_self %}
<a href="#" class="remove-user-btn op vh" data-url="{% url 'user_remove' user.email %}" data-target="{{ user.email }}">{% trans "Delete" %}</a>
<br />
{% if user.source == "DB" %}
<a href="#" class="reset-user-btn op vh" data-url="{% url 'user_reset' user.email %}" data-target="{{ user.email }}">{% trans "ResetPwd" %}</a>
{% endif %}
<br />
{% if is_admin_page %}
<a href="#" data-url="{% url 'user_remove_admin' user.email %}" data-target="{{ user.email }}" class="revoke-admin-btn op vh">{% trans "Revoke Admin" %}</a>
{% endif %}
{% endif %}
</td>
</tr>
{% endfor %}
</table>
<form id="set-quota-form" method="post" action="" class="hide">{% csrf_token %}
<h3>{% trans "Set quota" %}</h3>
<input type="text" name="space_quota" class="input" /> MB
<p class="tip">
<span>{% trans "An integer that is greater than or equal to 0." %}</span><br />
<span>{% trans "Tip: 0 means default limit" %}</span>
</p>
<p class="error hide"></p>
<input type="submit" value="{% trans "Submit" %}" class="submit" />
</form>

BIN
img/folder-192.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

BIN
img/login-bg.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 456 KiB

Loading…
Cancel
Save