1
0
Fork 0
mirror of https://github.com/Kozea/Radicale.git synced 2025-06-26 16:45:52 +00:00

New Web UI

Updated web UI to a more modern interface while keeping the HTML structure as similar to the original as possible.

New features include:
-Mobile view compatibility
-New light color scheme using primary colors based off Radicale's official colors
-Dialog theme for most sections
-Floating Action Buttons (FAB's) for creating and uploading a new collection
-Commands to edit/delete a collection have become buttons that only show on hover.
-Improved loading screen
-New loading circle with consistent color scheme
-More explanation for dialog text
-Added warning to delete screen
This commit is contained in:
Matthew Hana 2023-08-31 20:42:41 +10:00 committed by MatthewHana
parent 32050ef117
commit b45c97d5a5
12 changed files with 645 additions and 89 deletions

View file

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg width="24px" height="24px" viewBox="0 0 24 24" stroke-width="1.5" fill="none" xmlns="http://www.w3.org/2000/svg" color="#000000"><path d="M20 9l-1.995 11.346A2 2 0 0116.035 22h-8.07a2 2 0 01-1.97-1.654L4 9M21 6h-5.625M3 6h5.625m0 0V4a2 2 0 012-2h2.75a2 2 0 012 2v2m-6.75 0h6.75" stroke="#000000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></svg>

After

Width:  |  Height:  |  Size: 418 B

View file

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg width="24px" height="24px" stroke-width="1.5" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" color="#000000"><path d="M6 20h12M12 4v12m0 0l3.5-3.5M12 16l-3.5-3.5" stroke="#000000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></svg>

After

Width:  |  Height:  |  Size: 322 B

View file

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg width="24px" height="24px" viewBox="0 0 24 24" stroke-width="1.5" fill="none" xmlns="http://www.w3.org/2000/svg" color="#000000"><path d="M14.363 5.652l1.48-1.48a2 2 0 012.829 0l1.414 1.414a2 2 0 010 2.828l-1.48 1.48m-4.243-4.242l-9.616 9.615a2 2 0 00-.578 1.238l-.242 2.74a1 1 0 001.084 1.085l2.74-.242a2 2 0 001.24-.578l9.615-9.616m-4.243-4.242l4.243 4.242" stroke="#000000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></svg>

After

Width:  |  Height:  |  Size: 499 B

View file

@ -0,0 +1,55 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="margin: auto; display: block;" width="264px" height="264px" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
<g transform="rotate(0 50 50)">
<rect x="45.5" y="32" rx="0" ry="0" width="9" height="4" fill="#4e9a06">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.8695652173913042s" begin="-0.8026755852842808s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(27.692307692307693 50 50)">
<rect x="45.5" y="32" rx="0" ry="0" width="9" height="4" fill="#71cc1a">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.8695652173913042s" begin="-0.7357859531772575s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(55.38461538461539 50 50)">
<rect x="45.5" y="32" rx="0" ry="0" width="9" height="4" fill="#8ce139">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.8695652173913042s" begin="-0.6688963210702341s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(83.07692307692308 50 50)">
<rect x="45.5" y="32" rx="0" ry="0" width="9" height="4" fill="#cdff9c">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.8695652173913042s" begin="-0.6020066889632106s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(110.76923076923077 50 50)">
<rect x="45.5" y="32" rx="0" ry="0" width="9" height="4" fill="#cdf7a6">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.8695652173913042s" begin="-0.5351170568561873s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(138.46153846153845 50 50)">
<rect x="45.5" y="32" rx="0" ry="0" width="9" height="4" fill="#fcfcfc">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.8695652173913042s" begin="-0.46822742474916385s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(166.15384615384616 50 50)">
<rect x="45.5" y="32" rx="0" ry="0" width="9" height="4" fill="#fefefe">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.8695652173913042s" begin="-0.4013377926421404s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(193.84615384615384 50 50)">
<rect x="45.5" y="32" rx="0" ry="0" width="9" height="4" fill="#f4f4f4">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.8695652173913042s" begin="-0.33444816053511706s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(221.53846153846155 50 50)">
<rect x="45.5" y="32" rx="0" ry="0" width="9" height="4" fill="#ffd6d6">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.8695652173913042s" begin="-0.26755852842809363s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(249.23076923076923 50 50)">
<rect x="45.5" y="32" rx="0" ry="0" width="9" height="4" fill="#f86f6f">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.8695652173913042s" begin="-0.2006688963210702s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(276.9230769230769 50 50)">
<rect x="45.5" y="32" rx="0" ry="0" width="9" height="4" fill="#e73c3c">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.8695652173913042s" begin="-0.13377926421404682s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(304.61538461538464 50 50)">
<rect x="45.5" y="32" rx="0" ry="0" width="9" height="4" fill="#da2121">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.8695652173913042s" begin="-0.06688963210702341s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(332.3076923076923 50 50)">
<rect x="45.5" y="32" rx="0" ry="0" width="9" height="4" fill="#a40000">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.8695652173913042s" begin="0s" repeatCount="indefinite"></animate>
</rect>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="200" height="300" xmlns="http://www.w3.org/2000/svg">
<path fill="#a40000" d="M 186,188 C 184,98 34,105 47,192 C 59,279 130,296 130,296 C 130,296 189,277 186,188 z" />
<path fill="#ffffff" d="M 73,238 C 119,242 140,241 177,222 C 172,270 131,288 131,288 C 131,288 88,276 74,238 z" />
<g fill="none" stroke="#4e9a06" stroke-width="15">
<path d="M 103,137 C 77,69 13,62 13,62" />
<path d="M 105,136 C 105,86 37,20 37,20" />
<path d="M 105,135 C 112,73 83,17 83,17" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 564 B

View file

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg width="24px" height="24px" stroke-width="1.5" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" color="#000000"><path d="M6 12h6m6 0h-6m0 0V6m0 6v6" stroke="#000000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></svg>

After

Width:  |  Height:  |  Size: 305 B

View file

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg width="24px" height="24px" stroke-width="1.5" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" color="#000000"><path d="M6 20h12M12 16V4m0 0l3.5 3.5M12 4L8.5 7.5" stroke="#000000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></svg>

After

Width:  |  Height:  |  Size: 320 B

View file

@ -0,0 +1,55 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="margin: auto; display: block;" width="264px" height="264px" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
<g transform="rotate(0 50 50)">
<rect x="45.5" y="32" rx="0" ry="0" width="9" height="4" fill="#4e9a06">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.8695652173913042s" begin="-0.8026755852842808s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(27.692307692307693 50 50)">
<rect x="45.5" y="32" rx="0" ry="0" width="9" height="4" fill="#71cc1a">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.8695652173913042s" begin="-0.7357859531772575s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(55.38461538461539 50 50)">
<rect x="45.5" y="32" rx="0" ry="0" width="9" height="4" fill="#8ce139">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.8695652173913042s" begin="-0.6688963210702341s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(83.07692307692308 50 50)">
<rect x="45.5" y="32" rx="0" ry="0" width="9" height="4" fill="#cdff9c">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.8695652173913042s" begin="-0.6020066889632106s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(110.76923076923077 50 50)">
<rect x="45.5" y="32" rx="0" ry="0" width="9" height="4" fill="#cdf7a6">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.8695652173913042s" begin="-0.5351170568561873s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(138.46153846153845 50 50)">
<rect x="45.5" y="32" rx="0" ry="0" width="9" height="4" fill="#fcfcfc">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.8695652173913042s" begin="-0.46822742474916385s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(166.15384615384616 50 50)">
<rect x="45.5" y="32" rx="0" ry="0" width="9" height="4" fill="#fefefe">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.8695652173913042s" begin="-0.4013377926421404s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(193.84615384615384 50 50)">
<rect x="45.5" y="32" rx="0" ry="0" width="9" height="4" fill="#f4f4f4">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.8695652173913042s" begin="-0.33444816053511706s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(221.53846153846155 50 50)">
<rect x="45.5" y="32" rx="0" ry="0" width="9" height="4" fill="#ffd6d6">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.8695652173913042s" begin="-0.26755852842809363s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(249.23076923076923 50 50)">
<rect x="45.5" y="32" rx="0" ry="0" width="9" height="4" fill="#f86f6f">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.8695652173913042s" begin="-0.2006688963210702s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(276.9230769230769 50 50)">
<rect x="45.5" y="32" rx="0" ry="0" width="9" height="4" fill="#e73c3c">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.8695652173913042s" begin="-0.13377926421404682s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(304.61538461538464 50 50)">
<rect x="45.5" y="32" rx="0" ry="0" width="9" height="4" fill="#da2121">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.8695652173913042s" begin="-0.06688963210702341s" repeatCount="indefinite"></animate>
</rect>
</g><g transform="rotate(332.3076923076923 50 50)">
<rect x="45.5" y="32" rx="0" ry="0" width="9" height="4" fill="#a40000">
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="0.8695652173913042s" begin="0s" repeatCount="indefinite"></animate>
</rect>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="200" height="300" xmlns="http://www.w3.org/2000/svg">
<path fill="#a40000" d="M 186,188 C 184,98 34,105 47,192 C 59,279 130,296 130,296 C 130,296 189,277 186,188 z" />
<path fill="#ffffff" d="M 73,238 C 119,242 140,241 177,222 C 172,270 131,288 131,288 C 131,288 88,276 74,238 z" />
<g fill="none" stroke="#4e9a06" stroke-width="15">
<path d="M 103,137 C 77,69 13,62 13,62" />
<path d="M 105,136 C 105,86 37,20 37,20" />
<path d="M 105,135 C 112,73 83,17 83,17" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 564 B

View file

@ -1 +1,395 @@
body{background:#e4e9f6;color:#424247;display:flex;flex-direction:column;font-family:sans;font-size:14pt;line-height:1.4;margin:0;min-height:100vh}a{color:inherit}nav,footer{background:#a40000;color:#fff;padding:0 20%}nav ul,footer ul{display:flex;flex-wrap:wrap;margin:0;padding:0}nav ul li,footer ul li{display:block;padding:0 1em 0 0}nav ul li a,footer ul li a{color:inherit;display:block;padding:1em .5em 1em 0;text-decoration:inherit;transition:.2s}nav ul li a:hover,nav ul li a:focus,footer ul li a:hover,footer ul li a:focus{color:#000;outline:none}header{background:url(logo.svg),linear-gradient(to bottom right, #050a02, #000);background-position:22% 45%;background-repeat:no-repeat;color:#efdddd;font-size:1.5em;min-height:250px;overflow:auto;padding:3em 22%;text-shadow:.2em .2em .2em rgba(0,0,0,0.5)}header>*{padding-left:220px}header h1{font-size:2.5em;font-weight:lighter;margin:.5em 0}main{flex:1}section{padding:0 20% 2em}section:not(:last-child){border-bottom:1px dashed #ccc}section h1{background:linear-gradient(to bottom right, #050a02, #000);color:#e5dddd;font-size:2.5em;margin:0 -33.33% 1em;padding:1em 33.33%}section h2,section h3,section h4{font-weight:lighter;margin:1.5em 0 1em}article{border-top:1px solid transparent;position:relative;margin:3em 0}article aside{box-sizing:border-box;color:#aaa;font-size:.8em;right:-30%;top:.5em;position:absolute}article:before{border-top:1px dashed #ccc;content:"";display:block;left:-33.33%;position:absolute;right:-33.33%}pre{border-radius:3px;background:#000;color:#d3d5db;margin:0 -1em;overflow-x:auto;padding:1em}table{border-collapse:collapse;font-size:.8em;margin:auto}table td{border:1px solid #ccc;padding:.5em}dl dt{margin-bottom:.5em;margin-top:1em}p>code,li>code,dt>code{background:#d1daf0}@media (max-width: 800px){body{font-size:12pt}header,section{padding-left:2em;padding-right:2em}nav,footer{padding-left:0;padding-right:0}nav ul,footer ul{justify-content:center}nav ul li,footer ul li{padding:0 .5em}nav ul li a,footer ul li a{padding:1em 0}header{background-position:50% 30px,0 0;padding-bottom:0;padding-top:330px;text-align:center}header>*{margin:0;padding-left:0}section h1{margin:0 -.8em 1.3em;padding:.5em 0;text-align:center}article aside{top:.5em;right:-1.5em}article:before{left:-2em;right:-2em}}
body{
background: #ffffff;
color: #424247;
font-family: sans-serif;
font-size: 14pt;
margin: 0;
min-height: 100vh;
display: flex;
flex-wrap: wrap;
flex-direction: row;
align-content: center;
align-items: flex-start;
justify-content: space-around;
}
.container{
height: auto;
min-height: 450px;
width: 350px;
transition: .2s;
overflow: hidden;
padding: 20px 40px;
background: #fff;
border: 1px solid #dadce0;
border-radius: 8px;
display: block;
flex-shrink: 0;
margin: 0 auto;
}
.container h1{
margin: 0;
width: 100%;
text-align: center;
color: #484848;
}
#loginscene input{
}
#loginscene .logocontainer{
width: 100%;
text-align: center;
}
#loginscene .logocontainer img{
width: 75px;
}
#loginscene h1{
text-align: center;
font-family: sans-serif;
font-weight: normal;
}
#loginscene button{
float: right;
}
#loadingscene{
width: 100%;
height: 100%;
background: rgb(237 237 237);
position: absolute;
top: 0;
left: 0;
display: flex;
flex-wrap: nowrap;
justify-content: center;
align-items: center;
flex-direction: column;
overflow: hidden;
z-index: 999;
}
#loadingscene span{
font-size: 2em;
font-weight: bold;
}
#logoutview{
width: 100%;
display: block;
background: white;
text-align: center;
padding: 10px 0px;
color: #666;
border-bottom: 2px solid #dadce0;
position: fixed;
}
#logoutview span{
width: calc(100% - 60px);
display: inline-block;
}
#logoutview a{
color: white;
text-decoration: none;
padding: 3px 10px;
position: absolute;
right: 25px;
border-radius: 4px;
}
#collectionsscene{
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-content: flex-start;
align-items: center;
margin-top: 50px;
width: 100%;
height: calc(100vh - 50px);
}
#collectionsscene article{
width: 250px;
background: rgb(250, 250, 250);
border-radius: 8px;
box-shadow: 2px 2px 3px #0000001a;
border: 1px solid #dadce0;
padding: 5px 10px;
padding-top: 0;
margin: 10px;
float: left;
height: 350px;
overflow: hidden;
}
#collectionsscene article .colorbar{
width: 500%;
height: 15px;
margin: 0px -100%;
background: #000000;
}
#collectionsscene article .title{
width: 100%;
text-align: center;
font-size: 1.5em;
display: block;
padding: 10px 0;
}
#collectionsscene article small{
font-size: 15px;
float: left;
font-weight: normal;
font-style: italic;
padding-bottom: 10px;
width: 100%;
text-align: center;
}
#collectionsscene article input[type=text]{
margin-bottom: 0 !important;
}
#collectionsscene article p{
font-size: 1em;
max-height: 130px;
overflow: overlay;
}
#collectionsscene article:hover ul{
display: flex !important;
}
#collectionsscene ul{
display: none;
justify-content: space-evenly;
width: 60%;
margin: 0 20%;
padding: 0;
}
#collectionsscene li{
list-style: none;
display: block;
}
#collectionsscene li a{
text-decoration: none !important;
padding: 5px;
float: left;
border-radius: 5px;
width: 25px;
height: 25px;
text-align: center;
}
#editcollectionscene p span{
word-wrap:break-word;
font-weight: bold;
color: #4e9a06;
}
#deletecollectionscene p span{
word-wrap:break-word;
font-weight: bold;
color: #a40000;
}
#uploadcollectionscene ul{
margin: 10px -30px;
max-height: 600px;
overflow: overlay;
}
#uploadcollectionscene li{
border-bottom: 1px dashed #d5d5d5;
margin-bottom: 10px;
padding-bottom: 10px;
}
#uploadcollectionscene .successmessage{
color: #4e9a06;
width: 100%;
text-align: center;
display: block;
margin-top: 15px;
}
.fabcontainer{
display: flex;
flex-direction: column-reverse;
position: fixed;
bottom: 5px;
right: 0;
}
.fabcontainer a{
width: 30px;
height: 30px;
text-decoration: none;
color: white;
border: none !important;
border-radius: 100%;
margin: 5px 10px;
background: black;
text-align: center;
display: flex;
align-content: center;
justify-content: center;
align-items: center;
font-size: 30px;
padding: 10px;
box-shadow: 2px 2px 7px #000000d6;
}
.hidden{
display: none !important;
}
.title{
word-wrap: break-word;
font-weight: bold;
}
.icon{
width: 100%;
height: 100%;
filter: invert(1);
}
.smalltext{
font-size: 75% !important;
}
.error{
width: 100%;
display: block;
text-align: center;
color: rgb(217,48,37);
font-family: sans-serif;
clear: both;
padding-top: 15px;
}
.error::before{
content: "!";
height: 1em;
color: white;
background: rgb(217,48,37);
font-weight: bold;
border-radius: 100%;
display: inline-block;
width: 1.1em;
margin-right: 5px;
font-size: 1em;
text-align: center;
}
button{
font-size: 1em;
padding: 7px 21px;
color: white;
border-radius: 4px;
float: right;
margin-left: 10px;
background: black;
}
input, select{
width: 100%;
height: 3em;
border-style: solid;
border-color: #e6e6e6;
border-width: 1px;
border-radius: 7px;
margin-bottom: 25px;
padding-left: 15px;
padding-right: 15px;
outline: none !important;
}
input[type=text], input[type=password]{
width: calc(100% - 30px);
}
input:active, input:focus, input:focus-visible{
border-color: #2494fe !important;
border-width: 1px !important;
}
p.red, span.red{
color: #b50202;
}
button.red, a.red{
background: #b50202;
border: 1px solid #a40000;
}
button.red:hover, a.red:hover{
background: #a40000;
}
button.red:active, a.red:active{
background: #8f0000;
}
button.green, a.green{
background: #4e9a06;
border: 1px solid #377200;
}
button.green:hover, a.green:hover{
background: #377200;
}
button.green:active, a.green:active{
background: #285200;
}
button.blue, a.blue{
background: #2494fe;
border: 1px solid #055fb5;
}
button.blue:hover, a.blue:hover{
background: #1578d6;
cursor: pointer !important;
}
button.blue:active, a.blue:active{
background: #055fb5;
cursor: pointer !important;
}
@media only screen and (max-width: 600px) {
#collectionsscene{
flex-direction: column !important;
flex-wrap: nowrap;
}
#collectionsscene article{
height: auto;
min-height: 350px;
}
.container{
max-width: 280px !important;
}
#collectionsscene ul{
display: flex !important;
}
#logoutview span{
text-align: left;
}
}

View file

@ -28,7 +28,7 @@ const SERVER = location.origin;
* @const
* @type {string}
*/
const ROOT_PATH = (new URL("..", location.href)).pathname;
const ROOT_PATH = location.pathname.replace(new RegExp("/+[^/]+/*(/index\\.html?)?$"), "") + '/';
/**
* Regex to match and normalize color
@ -495,7 +495,12 @@ function LoginScene() {
function fill_form() {
user_form.value = user;
password_form.value = "";
error_form.textContent = error ? "Error: " + error : "";
if(error){
error_form.textContent = "Error: " + error;
error_form.classList.remove("hidden");
}else{
error_form.classList.add("hidden");
}
}
function onlogin() {
@ -507,7 +512,7 @@ function LoginScene() {
// setup logout
logout_view.classList.remove("hidden");
logout_btn.onclick = onlogout;
logout_user_form.textContent = user;
logout_user_form.textContent = user + "'s Collections";
// Fetch principal
let loading_scene = new LoadingScene();
push_scene(loading_scene, false);
@ -683,10 +688,9 @@ function CollectionsScene(user, password, collection, onerror) {
let color_form = node.querySelector("[data-name=color]");
let delete_btn = node.querySelector("[data-name=delete]");
let edit_btn = node.querySelector("[data-name=edit]");
let download_btn = node.querySelector("[data-name=download]");
if (collection.color) {
color_form.style.color = collection.color;
} else {
color_form.classList.add("hidden");
color_form.style.background = collection.color;
}
let possible_types = [CollectionType.ADDRESSBOOK];
[CollectionType.CALENDAR, ""].forEach(function(e) {
@ -704,10 +708,16 @@ function CollectionsScene(user, password, collection, onerror) {
}
});
title_form.textContent = collection.displayname || collection.href;
if(title_form.textContent.length > 30){
title_form.classList.add("smalltext");
}
description_form.textContent = collection.description;
if(description_form.textContent.length > 150){
description_form.classList.add("smalltext");
}
let href = SERVER + collection.href;
url_form.href = href;
url_form.textContent = href;
url_form.value = href;
download_btn.href = href;
delete_btn.onclick = function() {return ondelete(collection);};
edit_btn.onclick = function() {return onedit(collection);};
node.classList.remove("hidden");
@ -945,9 +955,15 @@ function DeleteCollectionScene(user, password, collection) {
scene_index = scene_stack.length - 1;
html_scene.classList.remove("hidden");
title_form.textContent = collection.displayname || collection.href;
error_form.textContent = error ? "Error: " + error : "";
delete_btn.onclick = ondelete;
cancel_btn.onclick = oncancel;
if(error){
error_form.textContent = "Error: " + error;
error_form.classList.remove("hidden");
}else{
error_form.classList.add("hidden");
}
};
this.hide = function() {
html_scene.classList.add("hidden");
@ -1031,7 +1047,11 @@ function CreateEditCollectionScene(user, password, collection) {
description_form.value = description;
type_form.value = type;
color_form.value = color;
error_form.textContent = error ? "Error: " + error : "";
if(error){
error_form.textContent = "Error: " + error;
error_form.classList.remove("hidden");
}
error_form.classList.add("hidden");
}
function onsubmit() {

View file

@ -1,68 +1,73 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<script src="fn.js"></script>
<title>Radicale Web Interface</title>
<link href="css/main.css" media="screen" rel="stylesheet">
<link href="css/icon.png" type="image/png" rel="icon">
<style>
.hidden {display:none;}
</style>
</head>
<link href="css/icon.png" type="image/png" rel="shortcut icon">
<body>
<nav>
<ul>
<li id="logoutview" class="hidden"><a href="" data-name="link">Logout [<span data-name="user" style="word-wrap:break-word;"></span>]</a></li>
</ul>
<nav id="logoutview" class="hidden">
<span data-name="user" style="word-wrap:break-word;"></span>
<a href="" class="red" data-name="link" title="Logout">Logout</a>
</nav>
<main>
<section id="loadingscene">
<h1>Loading</h1>
<img src="css/loading.svg" />
<span>Loading</span>
<p>Please wait...</p>
<noscript>JavaScript is required</noscript>
</section>
<section id="loginscene" class="hidden">
<h1>Login</h1>
<section id="loginscene" class="container hidden">
<div class="logocontainer">
<img src="css/logo.svg" />
</div>
<h1>Sign in</h1><br />
<form data-name="form">
<input data-name="user" type="text" placeholder="Username"><br>
<input data-name="password" type="password" placeholder="Password"><br>
<span style="color: #A40000;" data-name="error"></span><br>
<button type="submit">Next</button>
<input data-name="user" type="text" placeholder="Username">
<input data-name="password" type="password" placeholder="Password">
<button class="green" type="submit">Next</button>
<span class="error" data-name="error"></span>
</form>
</section>
<section id="collectionsscene" class="hidden">
<h1>Collections</h1>
<ul>
<li><a href="" data-name="new">Create new addressbook or calendar</a></li>
<li><a href="" data-name="upload">Upload addressbook or calendar</a></li>
</ul>
<div class="fabcontainer">
<a href="" class="green" data-name="new" title="Create a new addressbook or calendar"><img src="css/icons/new.svg" class="icon" alt=""></a></a>
<a href="" class="blue" data-name="upload" title="Upload an addressbook or calendar"><img src="css/icons/upload.svg" class="icon" alt="⬆️"></a></a>
</div>
<article data-name="collectiontemplate" class="hidden">
<h2><span data-name="color"></span><span data-name="title" style="word-wrap:break-word;">Title</span> <small>[<span data-name="ADDRESSBOOK">addressbook</span><span data-name="CALENDAR_JOURNAL_TASKS">calendar, journal and tasks</span><span data-name="CALENDAR_JOURNAL">calendar and journal</span><span data-name="CALENDAR_TASKS">calendar and tasks</span><span data-name="JOURNAL_TASKS">journal and tasks</span><span data-name="CALENDAR">calendar</span><span data-name="JOURNAL">journal</span><span data-name="TASKS">tasks</span>]</small></h2>
<span data-name="description" style="word-wrap:break-word;">Description</span>
<div class="colorbar" data-name="color"></div>
<span class="title" data-name="title">Title</span>
</h2>
<small>
<span data-name="ADDRESSBOOK">Address book</span>
<span data-name="CALENDAR_JOURNAL_TASKS">Calendar, journal and tasks</span>
<span data-name="CALENDAR_JOURNAL">Calendar and journal</span>
<span data-name="CALENDAR_TASKS">Calendar and tasks</span>
<span data-name="JOURNAL_TASKS">Journal and tasks</span>
<span data-name="CALENDAR">Calendar</span>
<span data-name="JOURNAL">Journal</span>
<span data-name="TASKS">Tasks</span>
</small>
<input type="text" data-name="url" value="" readonly="" onfocus="this.setSelectionRange(0, 99999);">
<p data-name="description" style="word-wrap:break-word;">Description</p>
<ul>
<li>URL: <a data-name="url" style="word-wrap:break-word;">url</a></li>
<li><a href="" data-name="edit">Edit</a></li>
<li><a href="" data-name="delete">Delete</a></li>
<li><a href="" title="Download" class="green" data-name="download"><img src="css/icons/download.svg" class="icon" alt="🔗"></a></li>
<li><a href="" title="Edit" class="blue" data-name="edit"><img src="css/icons/edit.svg" class="icon" alt="✏️"></a></li>
<li><a href="" title="Delete" class="red" data-name="delete"><img src="css/icons/delete.svg" class="icon" alt="❌"></a></li>
</ul>
</article>
</section>
<section id="editcollectionscene" class="hidden">
<h1>Edit collection</h1>
<h2>Edit <span data-name="title" style="word-wrap:break-word;font-weight:bold;">title</span>:</h2>
<section id="editcollectionscene" class="container hidden">
<h1>Edit Collection</h1>
<p>Editing collection <span class="title" data-name="title">title</span></p>
<form>
Title:<br>
<input data-name="displayname" type="text"><br>
Description:<br>
<input data-name="description" type="text"><br>
Type:<br>
<select data-name="type">
<option value="ADDRESSBOOK">addressbook</option>
@ -74,65 +79,67 @@
<option value="JOURNAL">journal</option>
<option value="TASKS">tasks</option>
</select><br>
Color:<br>
<input data-name="color" type="color"><br>
<span style="color: #A40000;" data-name="error"></span><br>
<button type="submit" data-name="submit">Save</button>
<button type="button" data-name="cancel">Cancel</button>
</form>
</section>
<section id="createcollectionscene" class="hidden">
<h1>Create new collection</h1>
<form>
Title:<br>
<input data-name="displayname" type="text"><br>
Description:<br>
<input data-name="description" type="text"><br>
Type:<br>
<select data-name="type">
<option value="ADDRESSBOOK">addressbook</option>
<option value="CALENDAR_JOURNAL_TASKS">calendar, journal and tasks</option>
<option value="CALENDAR_JOURNAL">calendar and journal</option>
<option value="CALENDAR_TASKS">calendar and tasks</option>
<option value="JOURNAL_TASKS">journal and tasks</option>
<option value="CALENDAR">calendar</option>
<option value="JOURNAL">journal</option>
<option value="TASKS">tasks</option>
</select><br>
Color:<br>
<input data-name="color" type="color"><br>
<span style="color: #A40000;" data-name="error"></span><br>
<button type="submit" data-name="submit">Create</button>
<button type="button" data-name="cancel">Cancel</button>
<span class="error hidden" data-name="error"></span><br>
<button type="submit" class="green" data-name="submit">Save</button>
<button type="button" class="red" data-name="cancel">Cancel</button>
</form>
</section>
<section id="uploadcollectionscene" class="hidden">
<h1>Upload collection</h1>
<section id="createcollectionscene" class="container hidden">
<h1>Create a new Collection</h1>
<p>Enter the details of your new collection.</p>
<form>
Type:<br>
<select data-name="type">
<option value="ADDRESSBOOK">Address book</option>
<option value="CALENDAR_JOURNAL_TASKS">Calendar, journal and tasks</option>
<option value="CALENDAR_JOURNAL">Calendar and journal</option>
<option value="CALENDAR_TASKS">Calendar and tasks</option>
<option value="JOURNAL_TASKS">Journal and tasks</option>
<option value="CALENDAR">Calendar</option>
<option value="JOURNAL">Journal</option>
<option value="TASKS">Tasks</option>
</select><br>
Title:<br>
<input data-name="displayname" type="text"><br>
Description:<br>
<input data-name="description" type="text"><br>
Color:<br>
<input data-name="color" type="color"><br>
<span class="error" data-name="error"></span><br>
<button type="submit" class="green" data-name="submit">Create</button>
<button type="button" class="red" data-name="cancel">Cancel</button>
</form>
</section>
<section id="uploadcollectionscene" class="container hidden">
<h1>Upload Collection</h1>
<ul>
<li data-name="filetemplate" class="hidden">
Upload <span data-name="name" style="word-wrap:break-word;font-weight:bold;">name</span>:<br>
<span data-name="pending">Please wait...</span>
<span style="color: #00A400;" data-name="success">Finished</span>
<span style="color: #A40000;" data-name="error"></span>
Uploading <span data-name="name">name</span><br>
<img data-name="pending" src="css/loading.svg" alt="Please wait..."/>
<span clas="successmessage";" data-name="success">Uploaded Successfully!</span>
<span class="error" data-name="error"></span>
</li>
</ul>
<form>
<button type="button" data-name="close">Close</button>
<button type="button" class="red" data-name="close">Close</button>
</form>
</section>
<section id="deletecollectionscene" class="hidden">
<h1>Delete collection</h1>
<h2>Delete <span data-name="title" style="word-wrap:break-word;font-weight:bold;">title</span>?</h2>
<span style="color: #A40000;" data-name="error"></span><br>
<section id="deletecollectionscene" class="container hidden">
<h1>Delete Collection</h1>
<p>Do you want to delete the collection <span class="title" data-name="title">title</span>?</p>
<p class="red">Warning: This action cannot be reversed.</p>
<form>
<button type="button" data-name="delete">Yes</button>
<button type="button" data-name="cancel">No</button>
<button type="button" class="red" data-name="delete">Delete</button>
<button type="button" class="blue" data-name="cancel">Cancel</button>
</form>
<span class="error hidden" data-name="error"></span><br>
</section>
</main>
</body>
</html>