@ -0,0 +1,2 @@ |
|||||
|
# Auto detect text files and perform LF normalization |
||||
|
* text=auto |
@ -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. |
@ -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> |
||||
|
|
After Width: | Height: | Size: 451 KiB |
After Width: | Height: | Size: 103 KiB |
After Width: | Height: | Size: 98 KiB |
After Width: | Height: | Size: 54 KiB |
After Width: | Height: | Size: 62 KiB |
After Width: | Height: | Size: 66 KiB |
After Width: | Height: | Size: 139 KiB |
After Width: | Height: | Size: 47 KiB |
After Width: | Height: | Size: 12 KiB |
@ -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; |
||||
|
} |
After Width: | Height: | Size: 3.6 KiB |
@ -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> |
@ -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 %} |
@ -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 %} |
@ -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 %} |
@ -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 %} |
@ -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 %} |
@ -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 %} |
@ -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 %} |
@ -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 %} |
@ -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 %} |
@ -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 %} |
@ -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 %} |
@ -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 %} |
@ -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 <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> |
After Width: | Height: | Size: 4.8 KiB |
After Width: | Height: | Size: 456 KiB |