Cleanup and change routes
Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
|
@ -24,12 +24,14 @@
|
|||
return [
|
||||
'routes' => [
|
||||
['name' => 'page#index', 'url' => '/', 'verb' => 'GET'],
|
||||
['name' => 'page#goto_form', 'url' => '/form/{hash}', 'verb' => 'GET'],
|
||||
|
||||
['name' => 'page#create_form', 'url' => '/new', 'verb' => 'GET'],
|
||||
['name' => 'page#edit_form', 'url' => '/edit/{hash}', 'verb' => 'GET'],
|
||||
['name' => 'page#clone_form', 'url' => '/clone/{hash}', 'verb' => 'GET'],
|
||||
['name' => 'page#getResult', 'url' => '/results/{id}', 'verb' => 'GET'],
|
||||
// Before /{hash} to avoid conflict
|
||||
['name' => 'page#createForm', 'url' => '/new', 'verb' => 'GET'],
|
||||
['name' => 'page#editForm', 'url' => '/{hash}/edit/', 'verb' => 'GET'],
|
||||
['name' => 'page#cloneForm', 'url' => '/{hash}/clone/', 'verb' => 'GET'],
|
||||
['name' => 'page#getResult', 'url' => '/{hash}/results/', 'verb' => 'GET'],
|
||||
|
||||
['name' => 'page#goto_form', 'url' => '/{hash}', 'verb' => 'GET'],
|
||||
|
||||
['name' => 'page#delete_form', 'url' => '/delete', 'verb' => 'POST'],
|
||||
['name' => 'page#insert_vote', 'url' => '/insert/vote', 'verb' => 'POST'],
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
$bg-no: #ffede9;
|
||||
$bg-maybe: #fcf7e1;
|
||||
$bg-unvoted: #fff4c8;
|
||||
$bg-yes: #ebf5d6;
|
||||
$bg-information: #b19c3e;
|
||||
|
||||
$fg-no: #f45573;
|
||||
$fg-maybe: #f0db98;
|
||||
$fg-unvoted: #f0db98;
|
||||
$fg-yes: #49bc49;
|
||||
|
||||
// Icon definitions
|
||||
@include icon-black-white('app', 'forms', 2);
|
||||
|
||||
.icon-yes {
|
||||
@include icon-color('checkmark', 'actions', $fg-yes, 1, true);
|
||||
}
|
||||
|
||||
.icon-comment-yes {
|
||||
@include icon-color('comment', 'actions', $fg-yes, 1, true);
|
||||
}
|
||||
|
||||
.icon-comment-no {
|
||||
@include icon-color('comment', 'actions', $fg-no, 1, true);
|
||||
}
|
||||
|
||||
.icon-no {
|
||||
@include icon-color('close', 'actions', $fg-no, 1, true);
|
||||
}
|
||||
|
||||
.icon-maybe {
|
||||
@include icon-color('maybe-vote-variant', 'forms', $fg-maybe);
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
/**
|
||||
* @copyright Copyright (c) 2020 John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
@import 'icons'
|
|
@ -0,0 +1,24 @@
|
|||
|
||||
// Icon definitions
|
||||
@include icon-black-white('forms', 'forms', 3);
|
||||
@include icon-black-white('clone', 'forms', 1);
|
||||
|
||||
.icon-yes {
|
||||
@include icon-color('checkmark', 'actions', $color-success, 1, true);
|
||||
}
|
||||
|
||||
.icon-comment-yes {
|
||||
@include icon-color('comment', 'actions', $color-success, 1, true);
|
||||
}
|
||||
|
||||
.icon-comment-no {
|
||||
@include icon-color('comment', 'actions', $color-error, 1, true);
|
||||
}
|
||||
|
||||
.icon-no {
|
||||
@include icon-color('close', 'actions', $color-error, 1, true);
|
||||
}
|
||||
|
||||
.icon-maybe {
|
||||
@include icon-color('maybe-vote-variant', 'forms', $color-warning);
|
||||
}
|
214
css/sidebar.scss
|
@ -1,214 +0,0 @@
|
|||
@import 'colors.scss';
|
||||
|
||||
$border_current_user: 2px solid;
|
||||
$border_user: 1px solid var(--color-border-dark);
|
||||
$user-column-width: 265px;
|
||||
|
||||
#forms-sidebar {
|
||||
width: 520px;
|
||||
flex-grow: 0;
|
||||
flex-shrink: 1;
|
||||
min-width: 300px;
|
||||
border-left: 1px solid var(--color-border);
|
||||
transition: margin-right 300ms;
|
||||
z-index: 500;
|
||||
> div,
|
||||
> ul {
|
||||
padding: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.authorRow {
|
||||
align-items: center;
|
||||
.author {
|
||||
margin-left: 8px;
|
||||
opacity: 0.5;
|
||||
flex-grow: 1;
|
||||
&.external {
|
||||
margin-right: 33px;
|
||||
opacity: 1;
|
||||
> input {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.detailsView {
|
||||
z-index: 1000 !important;
|
||||
.close.flex-row {
|
||||
justify-content: flex-end;
|
||||
margin: 8px 8px 0 0;
|
||||
}
|
||||
|
||||
.header.flex-row {
|
||||
flex-direction: row;
|
||||
flex-grow: 0;
|
||||
align-items: flex-start;
|
||||
margin-left: 0;
|
||||
margin-top: 0;
|
||||
padding: 0 17px;
|
||||
}
|
||||
|
||||
.formInformation {
|
||||
width: 220px;
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
padding-right: 15px;
|
||||
|
||||
.authorRow {
|
||||
.leftLabel {
|
||||
margin-right: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.cloud {
|
||||
margin: 4px 0;
|
||||
|
||||
> span {
|
||||
color: var(--color-primary-text);
|
||||
margin: 2px;
|
||||
padding: 2px 4px;
|
||||
border-radius: var(--border-radius);
|
||||
float: left;
|
||||
text-shadow: 1px 1px var(--color-box-shadow);
|
||||
background-color: var(--color-loading-light);
|
||||
}
|
||||
.open {
|
||||
background-color: $fg-yes;
|
||||
}
|
||||
.expired {
|
||||
background-color: $fg-no;
|
||||
}
|
||||
.information {
|
||||
background-color: $bg-information;
|
||||
}
|
||||
}
|
||||
}
|
||||
#expired_info {
|
||||
margin: 0 15px;
|
||||
}
|
||||
|
||||
.formActions {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-right: 15px;
|
||||
|
||||
.close {
|
||||
margin: 15px;
|
||||
background-position: right top;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
> ul > li {
|
||||
&:focus,
|
||||
&:hover,
|
||||
&.active,
|
||||
a.selected {
|
||||
&,
|
||||
> a {
|
||||
opacity: 1;
|
||||
box-shadow: inset 4px 0 var(--color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
> a[class*='icon-'],
|
||||
> ul > li > a[class*='icon-'],
|
||||
> a[style*='background-image'],
|
||||
> ul > li > a[style*='background-image'] {
|
||||
padding-left: 44px;
|
||||
}
|
||||
|
||||
> a,
|
||||
> ul > li > a {
|
||||
background-size: 16px 16px;
|
||||
background-position: 14px center;
|
||||
background-repeat: no-repeat;
|
||||
display: block;
|
||||
justify-content: space-between;
|
||||
line-height: 44px;
|
||||
min-height: 44px;
|
||||
padding: 0 12px;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
color: var(--color-main-text);
|
||||
opacity: 0.57;
|
||||
flex: 1 1 0;
|
||||
z-index: 100;
|
||||
}
|
||||
a,
|
||||
.app-navigation-entry-deleted {
|
||||
padding-left: 44px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
#configurationsTabView {
|
||||
.configBox {
|
||||
padding: 8px 8px;
|
||||
|
||||
> .title {
|
||||
font-weight: bold;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
> div {
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
input.hasDatepicker {
|
||||
margin-left: 17px;
|
||||
}
|
||||
&.oneline {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
#commentsTabView {
|
||||
.newCommentForm div.message:empty:before {
|
||||
content: attr(data-placeholder);
|
||||
color: grey;
|
||||
}
|
||||
#commentBox {
|
||||
border: 1px solid var(--color-border-dark);
|
||||
border-radius: var(--border-radius);
|
||||
padding: 7px 6px;
|
||||
margin: 3px 3px 3px 40px;
|
||||
cursor: text;
|
||||
}
|
||||
.comment {
|
||||
margin-bottom: 30px;
|
||||
|
||||
.date {
|
||||
right: 0;
|
||||
top: 5px;
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
.message {
|
||||
margin-left: 40px;
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
}
|
||||
|
||||
.new-comment {
|
||||
.submitComment {
|
||||
align-self: last baseline;
|
||||
width: 30px;
|
||||
margin: 0;
|
||||
padding: 7px 9px;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.icon-loading-small {
|
||||
float: left;
|
||||
margin-top: 10px;
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Двоичные данные
img/app.png
До Ширина: | Высота: | Размер: 196 B |
|
@ -1 +1,8 @@
|
|||
<svg width="32" height="32" version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"><path d="m5 3a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3zm7 1c-0.554 0-1 0.446-1 1v2c0 0.554 0.446 1 1 1h16c0.554 0 1-0.446 1-1v-2c0-0.554-0.446-1-1-1h-16zm-7 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3zm7 1c-0.554 0-1 0.446-1 1v2c0 0.554 0.446 1 1 1h16c0.554 0 1-0.446 1-1v-2c0-0.554-0.446-1-1-1h-16zm-7 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3zm7 1c-0.554 0-1 0.446-1 1v2c0 0.554 0.446 1 1 1h16c0.554 0 1-0.446 1-1v-2c0-0.554-0.446-1-1-1h-16z" fill="#fff" style="paint-order:markers fill stroke"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32">
|
||||
<circle cx="6" cy="6" r="3" fill="#fff"/>
|
||||
<circle cx="6" cy="16" r="3" fill="#fff"/>
|
||||
<circle cx="6" cy="26" r="3" fill="#fff"/>
|
||||
<rect width="18" height="4" x="11" y="4" rx="1" ry="1" fill="#fff"/>
|
||||
<rect width="18" height="4" x="11" y="14" rx="1" ry="1" fill="#fff"/>
|
||||
<rect width="18" height="4" x="11" y="24" rx="1" ry="1" fill="#fff"/>
|
||||
</svg>
|
||||
|
|
До Ширина: | Высота: | Размер: 647 B После Ширина: | Высота: | Размер: 420 B |
|
@ -0,0 +1 @@
|
|||
<svg width="16" height="16" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M11.8 13.8H2.2V4.2h9.6m1.2 0c0-.67-.53-1.2-1.2-1.2H2.2C1.53 3 1 3.53 1 4.2v9.6c0 .67.53 1.2 1.2 1.2h9.6c.67 0 1.2-.53 1.2-1.2"/><path d="m4.2 1c-0.67 0-1.2 0.54-1.2 1.2h10.8v10.8c0.67 0 1.2-0.53 1.2-1.2v-9.6c0-0.67-0.53-1.2-1.2-1.2z"/></svg>
|
После Ширина: | Высота: | Размер: 327 B |
|
@ -1,45 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
id="svg10"
|
||||
viewBox="0 0 32 32"
|
||||
x="0px"
|
||||
y="0px"
|
||||
enable-background="new 0 0 595.275 311.111"
|
||||
width="32"
|
||||
height="32"
|
||||
xml:space="preserve"
|
||||
version="1.1"
|
||||
sodipodi:docname="favicon-mask.svg"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1046"
|
||||
id="namedview15"
|
||||
showgrid="false"
|
||||
inkscape:zoom="3.6875"
|
||||
inkscape:cx="11.825118"
|
||||
inkscape:cy="3.2468217"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="34"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg10" /><metadata
|
||||
id="metadata16"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs14" /><path
|
||||
d="M 5 0 C 2.23 0 0 2.23 0 5 L 0 27 C 0 29.77 2.23 32 5 32 L 27 32 C 29.77 32 32 29.77 32 27 L 32 5 C 32 2.23 29.77 0 27 0 L 5 0 z M 5 3 A 3 3 0 0 1 8 6 A 3 3 0 0 1 5 9 A 3 3 0 0 1 2 6 A 3 3 0 0 1 5 3 z M 12 4 L 28 4 C 28.554 4 29 4.446 29 5 L 29 7 C 29 7.554 28.554 8 28 8 L 12 8 C 11.446 8 11 7.554 11 7 L 11 5 C 11 4.446 11.446 4 12 4 z M 5 13 A 3 3 0 0 1 8 16 A 3 3 0 0 1 5 19 A 3 3 0 0 1 2 16 A 3 3 0 0 1 5 13 z M 12 14 L 28 14 C 28.554 14 29 14.446 29 15 L 29 17 C 29 17.554 28.554 18 28 18 L 12 18 C 11.446 18 11 17.554 11 17 L 11 15 C 11 14.446 11.446 14 12 14 z M 5 23 A 3 3 0 0 1 8 26 A 3 3 0 0 1 5 29 A 3 3 0 0 1 2 26 A 3 3 0 0 1 5 23 z M 12 24 L 28 24 C 28.554 24 29 24.446 29 25 L 29 27 C 29 27.554 28.554 28 28 28 L 12 28 C 11.446 28 11 27.554 11 27 L 11 25 C 11 24.446 11.446 24 12 24 z "
|
||||
id="rect2" /></svg>
|
До Ширина: | Высота: | Размер: 2.3 KiB |
Двоичные данные
img/favicon-touch.png
До Ширина: | Высота: | Размер: 10 KiB |
|
@ -1 +0,0 @@
|
|||
<svg width="128" height="128" enable-background="new 0 0 595.275 311.111" version="1.1" viewBox="0 0 128 128" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><rect width="128" height="128" rx="20" ry="20" fill="#0082c9"/><path d="m20 12a12 12 0 0 0-12 12 12 12 0 0 0 12 12 12 12 0 0 0 12-12 12 12 0 0 0-12-12zm28 4c-2.216 0-4 1.784-4 4v8c0 2.216 1.784 4 4 4h64c2.216 0 4-1.784 4-4v-8c0-2.216-1.784-4-4-4zm-28 36a12 12 0 0 0-12 12 12 12 0 0 0 12 12 12 12 0 0 0 12-12 12 12 0 0 0-12-12zm28 4c-2.216 0-4 1.784-4 4v8c0 2.216 1.784 4 4 4h64c2.216 0 4-1.784 4-4v-8c0-2.216-1.784-4-4-4zm-28 36a12 12 0 0 0-12 12 12 12 0 0 0 12 12 12 12 0 0 0 12-12 12 12 0 0 0-12-12zm28 4c-2.216 0-4 1.784-4 4v8c0 2.216 1.784 4 4 4h64c2.216 0 4-1.784 4-4v-8c0-2.216-1.784-4-4-4z" fill="#fff" style="paint-order:markers fill stroke"/></svg>
|
До Ширина: | Высота: | Размер: 824 B |
Двоичные данные
img/favicon.ico
До Ширина: | Высота: | Размер: 4.2 KiB |
Двоичные данные
img/favicon.png
До Ширина: | Высота: | Размер: 313 B |
|
@ -1 +0,0 @@
|
|||
<svg width="32" height="32" enable-background="new 0 0 595.275 311.111" version="1.1" viewBox="0 0 32 32" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><rect width="32" height="32" rx="5" ry="5" fill="#0082c9"/><path d="m5 3a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3zm7 1c-0.554 0-1 0.446-1 1v2c0 0.554 0.446 1 1 1h16c0.554 0 1-0.446 1-1v-2c0-0.554-0.446-1-1-1zm-7 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3zm7 1c-0.554 0-1 0.446-1 1v2c0 0.554 0.446 1 1 1h16c0.554 0 1-0.446 1-1v-2c0-0.554-0.446-1-1-1zm-7 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3zm7 1c-0.554 0-1 0.446-1 1v2c0 0.554 0.446 1 1 1h16c0.554 0 1-0.446 1-1v-2c0-0.554-0.446-1-1-1z" fill="#fff" style="paint-order:markers fill stroke"/></svg>
|
До Ширина: | Высота: | Размер: 759 B |
|
@ -0,0 +1,8 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32">
|
||||
<circle cx="6" cy="6" r="3" fill="#fff"/>
|
||||
<circle cx="6" cy="16" r="3" fill="#fff"/>
|
||||
<circle cx="6" cy="26" r="3" fill="#fff"/>
|
||||
<rect width="18" height="4" x="11" y="4" rx="1" ry="1" fill="#fff"/>
|
||||
<rect width="18" height="4" x="11" y="14" rx="1" ry="1" fill="#fff"/>
|
||||
<rect width="18" height="4" x="11" y="24" rx="1" ry="1" fill="#fff"/>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 420 B |
|
@ -7,6 +7,7 @@
|
|||
* @author Inigo Jiron <ijiron@terpmail.umd.edu>
|
||||
* @author Natalie Gilbert
|
||||
* @author Affan Hussain
|
||||
* @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
|
@ -86,40 +87,63 @@ class PageController extends Controller {
|
|||
}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*
|
||||
* @return TemplateResponse
|
||||
*/
|
||||
public function index(): TemplateResponse {
|
||||
return new TemplateResponse('forms', 'forms.tmpl',
|
||||
['urlGenerator' => $this->urlGenerator]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
*/
|
||||
public function createForm(): TemplateResponse {
|
||||
return new TemplateResponse('forms', 'forms.tmpl',
|
||||
['urlGenerator' => $this->urlGenerator]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
*/
|
||||
public function cloneForm(): TemplateResponse {
|
||||
return new TemplateResponse('forms', 'forms.tmpl',
|
||||
['urlGenerator' => $this->urlGenerator]);
|
||||
Util::addScript($this->appName, 'forms');
|
||||
Util::addStyle($this->appName, 'icons');
|
||||
return new TemplateResponse($this->appName, 'main');
|
||||
}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @param string $hash
|
||||
* @NoCSRFRequired
|
||||
*
|
||||
* @return TemplateResponse
|
||||
*/
|
||||
public function editForm($hash): TemplateResponse {
|
||||
return new TemplateResponse('forms', 'forms.tmpl', [
|
||||
'urlGenerator' => $this->urlGenerator,
|
||||
'hash' => $hash
|
||||
]);
|
||||
public function createForm(): TemplateResponse {
|
||||
Util::addScript($this->appName, 'forms');
|
||||
Util::addStyle($this->appName, 'icons');
|
||||
return new TemplateResponse($this->appName, 'main');
|
||||
}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*
|
||||
* @return TemplateResponse
|
||||
*/
|
||||
public function cloneForm(): TemplateResponse {
|
||||
Util::addScript($this->appName, 'forms');
|
||||
Util::addStyle($this->appName, 'icons');
|
||||
return new TemplateResponse($this->appName, 'main');
|
||||
}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*
|
||||
* @return TemplateResponse
|
||||
*/
|
||||
public function editForm(): TemplateResponse {
|
||||
Util::addScript($this->appName, 'forms');
|
||||
Util::addStyle($this->appName, 'icons');
|
||||
return new TemplateResponse($this->appName, 'main');
|
||||
}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*
|
||||
* @return TemplateResponse
|
||||
*/
|
||||
public function getResult(): TemplateResponse {
|
||||
Util::addScript($this->appName, 'forms');
|
||||
Util::addStyle($this->appName, 'icons');
|
||||
return new TemplateResponse($this->appName, 'main');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -402,13 +426,4 @@ class PageController extends Controller {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @param int $id
|
||||
* @return TemplateResponse
|
||||
*/
|
||||
public function getResult(int $id): TemplateResponse {
|
||||
return new TemplateResponse('forms', 'forms.tmpl');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1668,6 +1668,22 @@
|
|||
"integrity": "sha512-f+sKpdLZXkODV+OY39K1M+Spmd4RgxmtEXmNn4Bviv4R7uBFHXuw+JX9ZdfDeOryfHjJ/TRQxQEp0GMpBwZFUw==",
|
||||
"dev": true
|
||||
},
|
||||
"@nextcloud/dialogs": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@nextcloud/dialogs/-/dialogs-1.2.2.tgz",
|
||||
"integrity": "sha512-N8A8J8UKSvz/hqNcm7gwpm70uAAsx0wurjhdYZ989jaMho+H/Hinjd2jkbV8UnsYYw0x/vWvEX5t6Lwbv08K0g==",
|
||||
"requires": {
|
||||
"core-js": "3.6.4",
|
||||
"toastify-js": "^1.7.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"core-js": {
|
||||
"version": "3.6.4",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.4.tgz",
|
||||
"integrity": "sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@nextcloud/eslint-config": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@nextcloud/eslint-config/-/eslint-config-1.0.0.tgz",
|
||||
|
@ -10977,6 +10993,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"toastify-js": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/toastify-js/-/toastify-js-1.7.0.tgz",
|
||||
"integrity": "sha512-GmPy4zJ/ulCfmCHlfCtgcB+K2xhx2AXW3T/ZZOSjyjaIGevhz+uvR8HSCTay/wBq4tt2mUnBqlObP1sSWGlsnQ=="
|
||||
},
|
||||
"tough-cookie": {
|
||||
"version": "2.4.3",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
|
||||
|
|
|
@ -70,7 +70,9 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@nextcloud/axios": "^1.3.2",
|
||||
"@nextcloud/dialogs": "^1.2.2",
|
||||
"@nextcloud/moment": "^1.1.0",
|
||||
"@nextcloud/router": "^1.0.2",
|
||||
"@nextcloud/vue": "^1.4.1",
|
||||
"json2csv": "5.0.0",
|
||||
"vue": "^2.6.11",
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
<!--
|
||||
- @copyright Copyright (c) 2018 René Gieling <github@dartcafe.de>
|
||||
-
|
||||
- @author René Gieling <github@dartcafe.de>
|
||||
- @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
-
|
||||
- @license GNU AGPL version 3 or any later version
|
||||
-
|
||||
- This program is free software: you can redistribute it and/or modify
|
||||
- it under the terms of the GNU Affero General Public License as
|
||||
- published by the Free Software Foundation, either version 3 of the
|
||||
- License, or (at your option) any later version.
|
||||
-
|
||||
- This program is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
- GNU Affero General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Affero General Public License
|
||||
- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-
|
||||
-->
|
||||
|
||||
<template>
|
||||
<Content app-name="forms">
|
||||
<AppNavigation>
|
||||
<AppNavigationNew button-class="icon-add" :text="t('forms', 'New form')" @click="onNewForm" />
|
||||
<AppNavigationForm v-for="form in formattedForms" :key="form.id" :form="form" />
|
||||
</AppNavigation>
|
||||
|
||||
<!-- No forms & loading emptycontents -->
|
||||
<AppContent v-if="loading || noForms || !hash">
|
||||
<EmptyContent v-if="loading" icon="icon-loading">
|
||||
{{ t('forms', 'Loading forms …') }}
|
||||
</EmptyContent>
|
||||
<EmptyContent v-else-if="noForms">
|
||||
{{ t('forms', 'No forms in here') }}
|
||||
<template #desc>
|
||||
<button class="primary" @click="onNewForm">
|
||||
{{ t('forms', 'Create a new one') }}
|
||||
</button>
|
||||
</template>
|
||||
</EmptyContent>
|
||||
|
||||
<EmptyContent v-else>
|
||||
{{ t('forms', 'Please select a form') }}
|
||||
</EmptyContent>
|
||||
</AppContent>
|
||||
|
||||
<!-- No errors show router content -->
|
||||
<router-view v-else />
|
||||
</Content>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { showError } from '@nextcloud/dialogs'
|
||||
import axios from '@nextcloud/axios'
|
||||
|
||||
import AppContent from '@nextcloud/vue/dist/Components/AppContent'
|
||||
import AppNavigation from '@nextcloud/vue/dist/Components/AppNavigation'
|
||||
import AppNavigationNew from '@nextcloud/vue/dist/Components/AppNavigationNew'
|
||||
import Content from '@nextcloud/vue/dist/Components/Content'
|
||||
|
||||
import AppNavigationForm from './components/AppNavigationForm'
|
||||
import EmptyContent from './components/EmptyContent'
|
||||
|
||||
import { formatForm } from './utils/FormsUtils'
|
||||
|
||||
export default {
|
||||
name: 'Forms',
|
||||
|
||||
components: {
|
||||
AppNavigationForm,
|
||||
AppContent,
|
||||
AppNavigation,
|
||||
AppNavigationNew,
|
||||
Content,
|
||||
EmptyContent,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
forms: [],
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
noForms() {
|
||||
return this.forms && this.forms.length === 0
|
||||
},
|
||||
|
||||
formattedForms() {
|
||||
return this.forms.map(formatForm)
|
||||
},
|
||||
|
||||
hash() {
|
||||
return this.$route.params.hash
|
||||
},
|
||||
},
|
||||
|
||||
beforeMount() {
|
||||
this.loadForms()
|
||||
},
|
||||
|
||||
methods: {
|
||||
/**
|
||||
* Initial forms load
|
||||
*/
|
||||
async loadForms() {
|
||||
this.loading = true
|
||||
try {
|
||||
const response = await axios.get(OC.generateUrl('apps/forms/get/forms'))
|
||||
this.forms = response.data
|
||||
} catch (error) {
|
||||
showError(t('forms', 'An error occured while loading the forms list'))
|
||||
console.error(error)
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
onNewForm() {
|
||||
this.$router.push({ name: 'create' })
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,79 @@
|
|||
<!--
|
||||
- @copyright Copyright (c) 2020 John Molakvoæ <skjnldsv@protonmail.com>
|
||||
-
|
||||
- @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
-
|
||||
- @license GNU AGPL version 3 or any later version
|
||||
-
|
||||
- This program is free software: you can redistribute it and/or modify
|
||||
- it under the terms of the GNU Affero General Public License as
|
||||
- published by the Free Software Foundation, either version 3 of the
|
||||
- License, or (at your option) any later version.
|
||||
-
|
||||
- This program is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
- GNU Affero General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Affero General Public License
|
||||
- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-
|
||||
-->
|
||||
|
||||
<template>
|
||||
<AppNavigationItem
|
||||
:exact="true"
|
||||
:title="form.title"
|
||||
:to="{ name: 'edit', params: { hash: form.hash } }">
|
||||
<template #actions>
|
||||
<ActionRouter :close-after-click="true"
|
||||
:exact="true"
|
||||
icon="icon-checkmark"
|
||||
:to="{ name: 'results', params: { hash: form.hash } }">
|
||||
{{ t('forms', 'Show results') }}
|
||||
</ActionRouter>
|
||||
<ActionRouter :close-after-click="true"
|
||||
:exact="true"
|
||||
icon="icon-clone"
|
||||
:to="{ name: 'clone', params: { hash: form.hash } }">
|
||||
{{ t('forms', 'Clone form') }}
|
||||
</ActionRouter>
|
||||
<ActionSeparator />
|
||||
<ActionButton :close-after-click="true" icon="icon-delete" @click="deleteForm">
|
||||
{{ t('forms', 'Delete form') }}
|
||||
</ActionButton>
|
||||
</template>
|
||||
</AppNavigationItem>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AppNavigationItem from '@nextcloud/vue/dist/Components/AppNavigationItem'
|
||||
import ActionButton from '@nextcloud/vue/dist/Components/ActionButton'
|
||||
import ActionRouter from '@nextcloud/vue/dist/Components/ActionRouter'
|
||||
import ActionSeparator from '@nextcloud/vue/dist/Components/ActionSeparator'
|
||||
|
||||
export default {
|
||||
name: 'AppNavigationForm',
|
||||
|
||||
components: {
|
||||
AppNavigationItem,
|
||||
ActionButton,
|
||||
ActionRouter,
|
||||
ActionSeparator,
|
||||
},
|
||||
|
||||
props: {
|
||||
form: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
async deleteForm() {
|
||||
|
||||
},
|
||||
},
|
||||
|
||||
}
|
||||
</script>
|
|
@ -1,7 +1,7 @@
|
|||
<!--
|
||||
- @copyright Copyright (c) 2018 René Gieling <github@dartcafe.de>
|
||||
- @copyright Copyright (c) 2020 John Molakvoæ <skjnldsv@protonmail.com>
|
||||
-
|
||||
- @author René Gieling <github@dartcafe.de>
|
||||
- @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
-
|
||||
- @license GNU AGPL version 3 or any later version
|
||||
-
|
||||
|
@ -12,34 +12,40 @@
|
|||
-
|
||||
- This program is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
- GNU Affero General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Affero General Public License
|
||||
- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div id="app-forms">
|
||||
<router-view />
|
||||
<div class="emptycontent" role="note">
|
||||
<div :class="icon" role="img" />
|
||||
<h2><slot /></h2>
|
||||
<p v-show="$slots.desc">
|
||||
<slot name="desc" />
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'App',
|
||||
name: 'EmptyContent',
|
||||
|
||||
props: {
|
||||
icon: {
|
||||
type: String,
|
||||
default: 'icon-forms',
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
#app-forms {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
.emptycontent {
|
||||
margin-top: 20vh;
|
||||
}
|
||||
|
||||
#app-content {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
}
|
||||
</style>
|
|
@ -1,4 +1,3 @@
|
|||
/* jshint esversion: 6 */
|
||||
/**
|
||||
* @copyright Copyright (c) 2018 René Gieling <github@dartcafe.de>
|
||||
*
|
||||
|
@ -23,7 +22,7 @@
|
|||
|
||||
import Vue from 'vue'
|
||||
import router from './router'
|
||||
import App from './App'
|
||||
import Forms from './Forms'
|
||||
|
||||
import VueClipboard from 'vue-clipboard2'
|
||||
import Tooltip from '@nextcloud/vue/dist/Directives/Tooltip'
|
||||
|
@ -51,7 +50,7 @@ __webpack_public_path__ = OC.linkTo('forms', 'js/')
|
|||
|
||||
/* eslint-disable-next-line no-new */
|
||||
new Vue({
|
||||
el: '#app-forms',
|
||||
el: '#content',
|
||||
router: router,
|
||||
render: h => h(App),
|
||||
render: h => h(Forms),
|
||||
})
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* @copyright Copyright (c) 2020 John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
export default {
|
||||
props: {
|
||||
hash: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
/* jshint esversion: 6 */
|
||||
// we need our modal component
|
||||
import ModalDialog from './ModalDialog'
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
/* jshint esversion: 6 */
|
||||
/**
|
||||
* @copyright Copyright (c) 2018 Julius Härtl <jus@bitgrid.net>
|
||||
* @copyright Copyright (c) 2018 John Molakvoæ <skjnldsv@protonmail.com>
|
||||
|
@ -22,59 +21,56 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
import Vue from 'vue'
|
||||
import Router from 'vue-router'
|
||||
import { generateUrl } from '@nextcloud/router'
|
||||
|
||||
import Create from './views/Create'
|
||||
import Results from './views/Results'
|
||||
|
||||
// Dynamic loading
|
||||
const Create = () => import('./views/Create')
|
||||
const List = () => import('./views/List')
|
||||
const Results = () => import('./views/Results')
|
||||
Vue.use(Router)
|
||||
|
||||
export default new Router({
|
||||
mode: 'history',
|
||||
base: OC.generateUrl(''),
|
||||
|
||||
// if index.php is in the url AND we got this far, then it's working:
|
||||
// let's keep using index.php in the url
|
||||
base: generateUrl('/apps/forms', ''),
|
||||
linkActiveClass: 'active',
|
||||
|
||||
routes: [
|
||||
{
|
||||
path: '/:index(index.php/)?apps/forms/',
|
||||
components: {
|
||||
default: List,
|
||||
},
|
||||
props: false,
|
||||
name: 'list',
|
||||
path: '/',
|
||||
name: 'root',
|
||||
},
|
||||
{
|
||||
path: '/:index(index.php/)?apps/forms/edit/:hash',
|
||||
components: {
|
||||
default: Create,
|
||||
},
|
||||
props: true,
|
||||
name: 'edit',
|
||||
},
|
||||
{
|
||||
path: '/:index(index.php/)?apps/forms/results/:hash',
|
||||
components: {
|
||||
default: Results,
|
||||
},
|
||||
props: false,
|
||||
name: 'results',
|
||||
},
|
||||
{
|
||||
path: '/:index(index.php/)?apps/forms/clone/:hash',
|
||||
components: {
|
||||
default: Create,
|
||||
},
|
||||
props: true,
|
||||
name: 'clone',
|
||||
},
|
||||
{
|
||||
path: '/:index(index.php/)?apps/forms/new',
|
||||
components: {
|
||||
default: Create,
|
||||
},
|
||||
props: false,
|
||||
path: '/new',
|
||||
component: Create,
|
||||
name: 'create',
|
||||
},
|
||||
{
|
||||
path: '/:hash',
|
||||
name: 'fill',
|
||||
props: true,
|
||||
},
|
||||
{
|
||||
path: '/:hash/edit',
|
||||
component: Create,
|
||||
name: 'edit',
|
||||
props: true,
|
||||
},
|
||||
{
|
||||
path: '/:hash/results',
|
||||
component: Results,
|
||||
name: 'results',
|
||||
props: true,
|
||||
},
|
||||
{
|
||||
path: '/:hash/clone',
|
||||
component: Create,
|
||||
name: 'clone',
|
||||
props: true,
|
||||
},
|
||||
],
|
||||
})
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
/**
|
||||
* @copyright Copyright (c) 2019 John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import axios from '@nextcloud/axios'
|
||||
|
||||
/**
|
||||
* Get the forms list
|
||||
*
|
||||
* @returns {Array}
|
||||
*/
|
||||
const getForms = async function() {
|
||||
try {
|
||||
const response = await axios.get(OC.generateUrl('apps/forms/get/forms'))
|
||||
return response.data
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
throw Error(t('forms', 'Unable to fetch the forms list'))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a form
|
||||
*
|
||||
* @param {int} id the form id to delete
|
||||
*/
|
||||
const deleteForm = async function(id) {
|
||||
try {
|
||||
axios.delete(OC.generateUrl('apps/forms/forms/{id}', { id }))
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
throw Error(t('forms', 'Unable to delete the form'))
|
||||
}
|
||||
}
|
||||
|
||||
export { deleteForm, getForms }
|
|
@ -0,0 +1,44 @@
|
|||
/**
|
||||
* @copyright Copyright (c) 2020 John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Format a form object prior to forms v2.0
|
||||
*
|
||||
* @param {Object} form the form raw object
|
||||
* @returns {Object} properly formatted form object
|
||||
*/
|
||||
const formatForm = function(form) {
|
||||
// clone form
|
||||
const newForm = Object.assign({}, form, form.event)
|
||||
|
||||
// migrate object architecture
|
||||
Object.assign(newForm, {
|
||||
questions: form.options.formQuizQuestions,
|
||||
})
|
||||
|
||||
// cleanup
|
||||
delete newForm.options
|
||||
delete newForm.event
|
||||
|
||||
return newForm
|
||||
}
|
||||
|
||||
export { formatForm }
|
|
@ -26,7 +26,7 @@
|
|||
-->
|
||||
|
||||
<template>
|
||||
<div id="app-content">
|
||||
<AppContent>
|
||||
<Controls :intitle="title">
|
||||
<template slot="after">
|
||||
<button :disabled="writingForm" class="button btn primary" @click="writeForm(form.mode)">
|
||||
|
@ -202,14 +202,16 @@
|
|||
@remove-share="removeShare" />
|
||||
</SideBar>
|
||||
<LoadingOverlay v-if="loadingForm" />
|
||||
</div>
|
||||
</AppContent>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from '@nextcloud/axios'
|
||||
import DatetimePicker from '@nextcloud/vue/dist/Components/DatetimePicker'
|
||||
import moment from '@nextcloud/moment'
|
||||
|
||||
import AppContent from '@nextcloud/vue/dist/Components/AppContent'
|
||||
import DatetimePicker from '@nextcloud/vue/dist/Components/DatetimePicker'
|
||||
|
||||
import Controls from '../components/_base-Controls'
|
||||
import LoadingOverlay from '../components/_base-LoadingOverlay'
|
||||
import QuizFormItem from '../components/quizFormItem'
|
||||
|
@ -217,9 +219,12 @@ import ShareDiv from '../components/shareDiv'
|
|||
import SideBar from '../components/_base-SideBar'
|
||||
import UserDiv from '../components/_base-UserDiv'
|
||||
|
||||
import ViewsMixin from '../mixins/ViewsMixin'
|
||||
|
||||
export default {
|
||||
name: 'Create',
|
||||
components: {
|
||||
AppContent,
|
||||
Controls,
|
||||
DatetimePicker,
|
||||
LoadingOverlay,
|
||||
|
@ -229,6 +234,8 @@ export default {
|
|||
UserDiv,
|
||||
},
|
||||
|
||||
mixins: [ViewsMixin],
|
||||
|
||||
data() {
|
||||
return {
|
||||
move: {
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
<!--
|
||||
- @copyright Copyright (c) 2020 John Molakvoæ <skjnldsv@protonmail.com>
|
||||
-
|
||||
- @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
-
|
||||
- @license GNU AGPL version 3 or any later version
|
||||
-
|
||||
- This program is free software: you can redistribute it and/or modify
|
||||
- it under the terms of the GNU Affero General Public License as
|
||||
- published by the Free Software Foundation, either version 3 of the
|
||||
- License, or (at your option) any later version.
|
||||
-
|
||||
- This program is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
- GNU Affero General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Affero General Public License
|
||||
- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-
|
||||
-->
|
||||
|
||||
<template>
|
||||
<span>TODO</span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Fill',
|
||||
}
|
||||
</script>
|
|
@ -22,15 +22,7 @@
|
|||
-->
|
||||
|
||||
<template>
|
||||
<div id="app-content">
|
||||
<Controls>
|
||||
<router-link :to="{ name: 'create'}" class="button">
|
||||
<span class="symbol icon-add" />
|
||||
<span class="hidden-visually">
|
||||
{{ t('forms', 'New') }}
|
||||
</span>
|
||||
</router-link>
|
||||
</Controls>
|
||||
<AppContent>
|
||||
<div v-if="noForms" class="">
|
||||
<div class="icon-forms" />
|
||||
<h2> {{ t('No existing forms.') }} </h2>
|
||||
|
@ -56,54 +48,69 @@
|
|||
</transition-group>
|
||||
<LoadingOverlay v-if="loading" />
|
||||
<modal-dialog />
|
||||
</div>
|
||||
</AppContent>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { showError } from '@nextcloud/dialogs'
|
||||
import axios from '@nextcloud/axios'
|
||||
|
||||
import AppContent from '@nextcloud/vue/dist/Components/AppContent'
|
||||
|
||||
import FormListItem from '../components/formListItem'
|
||||
import Controls from '../components/_base-Controls'
|
||||
import axios from '@nextcloud/axios'
|
||||
import LoadingOverlay from '../components/_base-LoadingOverlay'
|
||||
import ViewsMixin from '../mixins/ViewsMixin'
|
||||
|
||||
export default {
|
||||
name: 'List',
|
||||
|
||||
components: {
|
||||
Controls,
|
||||
AppContent,
|
||||
FormListItem,
|
||||
LoadingOverlay,
|
||||
},
|
||||
|
||||
mixins: [ViewsMixin],
|
||||
|
||||
data() {
|
||||
return {
|
||||
noForms: false,
|
||||
loading: true,
|
||||
forms: [],
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.indexPage = OC.generateUrl('apps/forms/')
|
||||
computed: {
|
||||
noForms() {
|
||||
return this.forms && this.forms.length > 0
|
||||
},
|
||||
},
|
||||
|
||||
beforeMount() {
|
||||
this.loadForms()
|
||||
},
|
||||
|
||||
methods: {
|
||||
loadForms() {
|
||||
/**
|
||||
* Initial forms load
|
||||
*/
|
||||
async loadForms() {
|
||||
this.loading = true
|
||||
axios.get(OC.generateUrl('apps/forms/get/forms'))
|
||||
.then((response) => {
|
||||
this.forms = response.data
|
||||
this.loading = false
|
||||
}, (error) => {
|
||||
/* eslint-disable-next-line no-console */
|
||||
console.log(error.response)
|
||||
this.loading = false
|
||||
})
|
||||
try {
|
||||
const response = await axios.get(OC.generateUrl('apps/forms/get/forms'))
|
||||
this.forms = response.data
|
||||
} catch (error) {
|
||||
showError(t('forms', 'An error occured while loading the forms list'))
|
||||
console.error(error)
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Open the help page
|
||||
*/
|
||||
helpPage() {
|
||||
window.open('https://github.com/affan98/forms/blob/master/Forms_Support.md')
|
||||
window.open('https://github.com/nextcloud/forms/blob/master/Forms_Support.md')
|
||||
},
|
||||
|
||||
viewFormResults(index, event, name) {
|
||||
this.$router.push({
|
||||
name: name,
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
-->
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<AppContent>
|
||||
<div>
|
||||
<button class="button btn primary" @click="download">
|
||||
<span>{{ "Export to CSV" }}</span>
|
||||
|
@ -51,7 +51,7 @@
|
|||
<LoadingOverlay v-if="loading" />
|
||||
<modal-dialog />
|
||||
</div>
|
||||
</div>
|
||||
</AppContent>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -59,15 +59,20 @@ import ResultItem from '../components/resultItem'
|
|||
import json2csvParser from 'json2csv'
|
||||
import axios from '@nextcloud/axios'
|
||||
import LoadingOverlay from '../components/_base-LoadingOverlay'
|
||||
import ViewsMixin from '../mixins/ViewsMixin'
|
||||
|
||||
import AppContent from '@nextcloud/vue/dist/Components/AppContent'
|
||||
export default {
|
||||
name: 'Results',
|
||||
|
||||
components: {
|
||||
AppContent,
|
||||
ResultItem,
|
||||
LoadingOverlay,
|
||||
},
|
||||
|
||||
mixins: [ViewsMixin],
|
||||
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2020 John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
?>
|
||||
|
||||
<div id="content"></div>
|