Skip to content
Snippets Groups Projects
Commit 8435913c authored by Andy's avatar Andy
Browse files

Merge branch 'codingweekendfs18' of gitlab.ethz.ch:amiv/amiv-admintool into codingweekendfs18

parents 7ce8967f 67190e73
No related branches found
No related tags found
No related merge requests found
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
<!--link href="//cdn.rawgit.com/noelboss/featherlight/1.7.10/release/featherlight.min.css" type="text/css" rel="stylesheet" /--> <!--link href="//cdn.rawgit.com/noelboss/featherlight/1.7.10/release/featherlight.min.css" type="text/css" rel="stylesheet" /-->
<link href="lib/cust/main.css" rel="stylesheet"> <!--link href="lib/cust/main.css" rel="stylesheet"-->
</head> </head>
<body> <body>
......
...@@ -84,10 +84,12 @@ body { ...@@ -84,10 +84,12 @@ body {
width: 100%; width: 100%;
} }
.wrapper-content { .wrapper-content {
padding: 3em;
height: 100vh; height: 100vh;
grid-column: 2; grid-column: 2;
background: #eee; background: #eee;
overflow: hidden; overflow: hidden;
width: 100%;
} }
/* /*
......
source diff could not be displayed: it is too large. Options to address this: view the blob.
...@@ -186,7 +186,9 @@ export class ResourceHandler { ...@@ -186,7 +186,9 @@ export class ResourceHandler {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
getSession().then((api) => { getSession().then((api) => {
api.post(this.resource, item).then((response) => { api.post(this.resource, item).then((response) => {
if (response.status >= 400) { if (response.status === 422) {
reject(response.data);
} else if (response.status >= 400) {
resetSession(); resetSession();
reject(); reject();
} else { } else {
...@@ -212,7 +214,9 @@ export class ResourceHandler { ...@@ -212,7 +214,9 @@ export class ResourceHandler {
headers: { 'If-Match': item._etag }, headers: { 'If-Match': item._etag },
data: submitData, data: submitData,
}).then((response) => { }).then((response) => {
if (response.status >= 400) { if (response.status === 422) {
reject(response.data);
} else if (response.status >= 400) {
resetSession(); resetSession();
reject(); reject();
} else { } else {
......
import m from 'mithril';
import {
TextField,
Button,
Card
} from 'polythene-mithril';
import EditView from '../views/editView';
export default class eventWithExport extends EditView {
constructor(vnode) {
super(vnode, 'events');
}
view() {
// Editable by event creator.
const fieldTitleEn = m(TextField, {
label: 'Event Title [EN]',
required: true,
floatingLabel: true,
dense: true,
});
const fieldDescriptionEn = m(TextField, {
label: 'Description [EN]',
required: true,
floatingLabel: true,
dense: true,
multiLine: true,
rows: 6,
});
const creatorButton = m(Button, {
label: 'EXPORT'
// label: 'Create a hyperlink string describing your project.'
});
// Needs administrator (Kulturi).
const fieldLocation = m(TextField, {
label: 'Location:',
floatingLabel: true,
required: true,
});
return m('div', [
m('h1', 'For the event creator:', fieldTitleEn, fieldDescriptionEn, 'For the AMIV administrator:', fieldLocation, creatorButton),
]);
}
}
\ No newline at end of file
import m from 'mithril'; import m from 'mithril';
import ItemView from '../views/itemView'; import ItemView from '../views/itemView';
import {Button, Card, IconButton, Toolbar, ToolbarTitle } from "polythene-mithril"
import { icons } from '../views/elements';
export default class viewEvent extends ItemView { export default class viewEvent extends ItemView {
constructor() { constructor() {
super('events'); super('events');
} this.details = false;
this.participants = false;
this.waitlist = false;
this.emailAdresses = false;
}
view() {
if (!this.data) return '';
console.log(Object.keys(this));
console.log(this['data']);
let displayCatchphraseDe = null;
let displayCatchphraseEn = null;
let displayDescriptionDe = null;
let displayDescriptionEn = null;
let displayPriority = null;
if(this.data.catchphrase_de) {
displayCatchphraseDe = m("t3", {class: "text"}, this.data.catchphrase_de);
}
if(this.data.catchphrase_en) {
displayCatchphraseEn = m("t3", {class: "text"}, this.data.catchphrase_en);
}
if(this.data.description_de) {
displayDescriptionDe = m("t3", {class: "text"}, this.data.description_de);
}
if(this.data.description_en) {
displayDescriptionEn = m("t3", {class: "text"}, this.data.description_en);
}
if(this.data.priority) {
displayPriority = m("t3", {class: "text"}, this.data.priority);
}
let displayDetailsButton = m(Toolbar, { compact: true, events: { onclick: () => this.details = !this.details } }, [
m(IconButton, { icon: { svg: m.trust(icons.ArrowRight) } }),
m(ToolbarTitle, { text: "details" }),
]);
let displayParticipantsButton = m(Toolbar, { compact: true, events: { onclick: () => this.participants = !this.participants } }, [
m(IconButton, { icon: { svg: m.trust(icons.ArrowRight) } }),
m(ToolbarTitle, { text: "participants" }),
]);
let displayWaitlistButton = m(Toolbar, { compact: true, events: { onclick: () => this.waitlist = !this.waitlist } }, [
m(IconButton, { icon: { svg: m.trust(icons.ArrowRight) } }),
m(ToolbarTitle, { text: "waitlist" }),
]);
let displayEmailAdressesButton = m(Toolbar, { compact: true, events: { onclick: () => this.emailAdresses = !this.emailAdresses } }, [
m(IconButton, { icon: { svg: m.trust(icons.ArrowRight) } }),
m(ToolbarTitle, { text: "email adresses" }),
]);
let displayDetails = null;
let displayParticipants = null;
let displayWaitlist = null;
let displayEmailAdresses = null;
if (this.details) {
displayDetailsButton = m(Toolbar, { compact: true, events: { onclick: () => this.details = !this.details } }, [
m(IconButton, { icon: { svg: m.trust(icons.ArrowDown) } }),
m(ToolbarTitle, { text: "details" }),
]);
displayDetails = m(Card, {
content: [
{
primary: {
title: "Catchphrase DE",
subtitle: displayCatchphraseDe
}
},
{
primary: {
title: "Catchphrase EN",
subtitle: displayCatchphraseEn
}
},
{
primary: {
title: "Description DE",
subtitle: displayDescriptionDe
}
},
{
primary: {
title: "Description EN",
subtitle: displayDescriptionEn
}
},
{
primary: {
title: "Priority",
subtitle: displayPriority
}
},
{
actions: {
content: [
m(Button, {
label: "Action 1"
}),
m(Button, {
label: "Action 2"
})
]
}
},
{
text: {
content: "More text"
}
}
]
})
}
if (this.participants) {
displayParticipantsButton = m(Toolbar, { compact: true, events: { onclick: () => this.participants = !this.participants } }, [
m(IconButton, { icon: { svg: m.trust(icons.ArrowDown) } }),
m(ToolbarTitle, { text: "participants" }),
]);
displayParticipants = m(Card, {
content: [
{
primary: {
title: "Primary title",
subtitle: "Subtitle"
}
},
{
actions: {
content: [
m(Button, {
label: "Action 1"
}),
m(Button, {
label: "Action 2"
})
]
}
},
{
text: {
content: "More text"
}
}
]
})
}
if (this.waitlist) {
displayWaitlistButton = m(Toolbar, { compact: true, events: { onclick: () => this.waitlist = !this.waitlist } }, [
m(IconButton, { icon: { svg: m.trust(icons.ArrowDown) } }),
m(ToolbarTitle, { text: "waitlist" }),
]);
displayWaitlist = m(Card, {
content: [
{
primary: {
title: "Primary title",
subtitle: "Subtitle"
}
},
{
actions: {
content: [
m(Button, {
label: "Action 1"
}),
m(Button, {
label: "Action 2"
})
]
}
},
{
text: {
content: "More text"
}
}
]
})
}
if (this.emailAdresses) {
displayEmailAdressesButton = m(Toolbar, { compact: true, events: { onclick: () => this.emailAdresses = !this.emailAdresses } }, [
m(IconButton, { icon: { svg: m.trust(icons.ArrowDown) } }),
m(ToolbarTitle, { text: "email adresses" }),
]);
displayEmailAdresses = m(Card, {
content: [
{
primary: {
title: "Primary title",
subtitle: "Subtitle"
}
},
{
actions: {
content: [
m(Button, {
label: "Action 1"
}),
m(Button, {
label: "Action 2"
})
]
}
},
{
text: {
content: "More text"
}
}
]
})
}
return m("div", {
style: { height: '100%', 'overflow-y': 'scroll'}
},[
m("h1", {class: "title"}, this.data.title_de),
m(Button, {element: 'div', label: "Update Event"}),
displayDetailsButton,
displayDetails,
displayParticipantsButton,
displayParticipants,
displayWaitlistButton,
displayWaitlist,
displayEmailAdressesButton,
displayEmailAdresses,
])
}
view() {
return m('h1', 'Hello World');
}
} }
...@@ -7,7 +7,9 @@ import EventTable from './events/table'; ...@@ -7,7 +7,9 @@ import EventTable from './events/table';
import newEvent from './events/newEvent'; import newEvent from './events/newEvent';
import viewEvent from './events/viewEvent'; import viewEvent from './events/viewEvent';
import eventDraft from './events/eventDraft'; import eventDraft from './events/eventDraft';
import eventWithExport from './events/eventWithExport';
import Sidebar from './sidebar'; import Sidebar from './sidebar';
import Layout from './layout';
// import AnnounceTool from './announceTool'; // import AnnounceTool from './announceTool';
import './style'; import './style';
...@@ -16,15 +18,6 @@ document.body.appendChild(main); ...@@ -16,15 +18,6 @@ document.body.appendChild(main);
const root = main; const root = main;
class Layout {
view(vnode) {
return m('div.wrapper-main.smooth', [
m(Sidebar),
m('div.wrapper-content', vnode.children),
]);
}
}
function layoutWith(view) { function layoutWith(view) {
return { return {
view() { view() {
...@@ -42,6 +35,7 @@ m.route(root, '/users', { ...@@ -42,6 +35,7 @@ m.route(root, '/users', {
'/events/:id': layoutWith(viewEvent), '/events/:id': layoutWith(viewEvent),
'/newevent': layoutWith(newEvent), '/newevent': layoutWith(newEvent),
'/draftevent': layoutWith(eventDraft), '/draftevent': layoutWith(eventDraft),
'/eventwithexport': layoutWith(eventWithExport),
'/groups': layoutWith({ '/groups': layoutWith({
view() { view() {
return m(TableView, { return m(TableView, {
......
import m from 'mithril';
import '@material/drawer';
import { List, ListTile, Icon, Toolbar, ToolbarTitle } from 'polythene-mithril';
import { styler } from 'polythene-core-css';
import { icons } from './views/elements';
const layoutStyle = [
{
body: {
padding: 0,
margin: 0,
},
'.wrapper-main': {
height: '100%',
width: '100%',
display: 'grid',
'grid-template-columns': '200px auto',
},
'.wrapper-sidebar': {
'grid-column': 1,
height: '100%',
'overflow-y': 'auto',
position: 'fixed',
background: '#cccccc',
color: 'white',
},
'.wrapper-content': {
height: '100vh',
'grid-column': 2,
background: '#eee',
overflow: 'hidden',
},
},
];
styler.add('layout', layoutStyle);
class Menupoint {
view({ attrs: { title, href, icon = null } }) {
return m(ListTile, {
url: {
href,
oncreate: m.route.link,
},
front: icon ? m(Icon, {
avatar: true,
svg: m.trust(icon),
}) : '',
title,
});
}
}
export default class Layout {
view({ children }) {
return m('div', [
m(Toolbar, {
style: {
backgroundColor: '#1f2d54',
color: '#fff',
height: '72px',
},
}, [
m(ToolbarTitle, { text: 'AMIV Admintools' }),
]),
m('div.wrapper-main.smooth', [
m(
'nav.mdc-drawer.mdc-drawer--permanent.mdc-typography.wrapper-sidebar',
{ style: { width: '200px' } },
m(List, {
className: 'drawer-menu',
header: {
title: 'Menu',
},
tiles: [
m(Menupoint, {
href: '/users',
icon: icons.iconUsersSVG,
title: 'Users',
}),
m(Menupoint, {
href: '/events',
icon: icons.iconEventSVG,
title: 'Events',
}),
m(Menupoint, {
href: '/groups',
title: 'Groups',
}),
m(Menupoint, {
href: '/announce',
title: 'Announce',
}),
],
}),
),
m('div.wrapper-content', children),
]),
/*return m('div.wrapper-sidebar.smooth', m('div.container-fluid', [
m('a[href=/]', { oncreate: m.route.link }, [
m('img.sidebar-logo[src="res/logo/main.svg"]'),
]),
m('ul.nav.nav-pills.nav-stacked.nav-sidebar', [
]),
]));*/
]);
}
}
const m = require('mithril');
class Button {
view(vnode) {
return m('li', m('a', { href: vnode.attrs.href, oncreate: m.route.link }, [
m('span.glyphicon', { class: `glyphicon-${vnode.attrs.glyph}` }),
m.trust(` ${vnode.attrs.title}`),
]));
}
}
export default class Sidebar {
view() {
return m('div.wrapper-sidebar.smooth', m('div.container-fluid', [
m('a[href=/]', { oncreate: m.route.link }, [
m('img.sidebar-logo[src="res/logo/main.svg"]'),
]),
m('ul.nav.nav-pills.nav-stacked.nav-sidebar', [
m(Button, { href: '/users', glyph: 'list-alt', title: 'Users' }),
m(Button, { href: '/events', glyph: 'calendar', title: 'Events' }),
m(Button, { href: '/groups', glyph: 'blackboard', title: 'Groups' }),
m(Button, { href: '/announce', glyph: 'bullhorn', title: 'Announce' }),
]),
]));
}
}
...@@ -46,10 +46,9 @@ export default class EditView extends ItemView { ...@@ -46,10 +46,9 @@ export default class EditView extends ItemView {
oninit() { oninit() {
if (this.id) { if (this.id) {
// load data for item // load data for item
getSession().then((apiSession) => { this.handler.getItem(this.id, this.embedded).then((item) => {
this.loadItemData(apiSession); this.data = item;
}).catch(() => { m.redraw();
m.route.set('/login');
}); });
} }
// load schema // load schema
...@@ -99,48 +98,33 @@ export default class EditView extends ItemView { ...@@ -99,48 +98,33 @@ export default class EditView extends ItemView {
return boundFormelement; return boundFormelement;
} }
submit(method, fields) { submit(method) {
return () => { return () => {
if (this.changed) { if (this.changed) {
getSession().then((apiSession) => { let request;
// build request if (method === 'POST') {
const request = { method }; request = this.handler.post(this.data);
if (method === 'POST' || method === 'PATCH') { } else if (method === 'PATCH') {
// fields like `_id` are not post/patchable request = this.handler.patch(this.data);
// We therefore only send patchable fields }
const submitData = {}; request.then((response) => {
fields.forEach((key) => { this.callback(response);
submitData[key] = this.data[key]; }).catch((error) => {
console.log(error);
// Process the API error
const { response } = error;
if (response.status === 422) {
// there are problems with some fields, display them
Object.keys(response.data._issues).forEach((field) => {
this.errors[field] = [response.data._issues[field]];
}); });
request.data = submitData; m.redraw();
} } else if (response.status === 403) {
// Unauthorized
// if request is PATCH or DELETE, add If-Match header and set url m.route.set('/login');
if (method === 'PATCH' || method === 'DELETE') {
request.headers = { 'If-Match': this.data._etag };
request.url = `${this.resource}/${this.id}`;
} else { } else {
request.url = this.resource; console.log(error);
} }
apiSession(request).then((response) => {
this.callback(response);
}).catch((error) => {
// Process the API error
const { response } = error;
if (response.status === 422) {
// there are problems with some fields, display them
Object.keys(response.data._issues).forEach((field) => {
this.errors[field] = [response.data._issues[field]];
});
m.redraw();
} else if (response.status === 403) {
// Unauthorized
m.route.set('/login');
} else {
console.log(error);
}
});
}); });
} else { } else {
this.callback(); this.callback();
......
...@@ -57,6 +57,10 @@ export const icons = { ...@@ -57,6 +57,10 @@ export const icons = {
iconSearchSVG: '<svg width="24" height="24" viewBox="0 0 24 24"><path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/></svg>', iconSearchSVG: '<svg width="24" height="24" viewBox="0 0 24 24"><path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/></svg>',
iconBackSVG: '<svg width="24" height="24" viewBox="0 0 24 24"><path d="M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z"/></svg>', iconBackSVG: '<svg width="24" height="24" viewBox="0 0 24 24"><path d="M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z"/></svg>',
iconClearSVG: '<svg width="24" height="24" viewBox="0 0 24 24"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>', iconClearSVG: '<svg width="24" height="24" viewBox="0 0 24 24"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>',
ArrowRight: '<svg fill="#000000" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"/><path d="M0-.25h24v24H0z" fill="none"/></svg>',
ArrowDown: '<svg fill="#000000" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M7.41 7.84L12 12.42l4.59-4.58L18 9.25l-6 6-6-6z"/><path d="M0-.75h24v24H0z" fill="none"/></svg>',
iconUsersSVG: '<svg fill="#000000" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M3 5v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2H5c-1.11 0-2 .9-2 2zm12 4c0 1.66-1.34 3-3 3s-3-1.34-3-3 1.34-3 3-3 3 1.34 3 3zm-9 8c0-2 4-3.1 6-3.1s6 1.1 6 3.1v1H6v-1z"/><path d="M0 0h24v24H0z" fill="none"/></svg>',
iconEventSVG: '<svg fill="#000000" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M9 11H7v2h2v-2zm4 0h-2v2h2v-2zm4 0h-2v2h2v-2zm2-7h-1V2h-2v2H8V2H6v2H5c-1.11 0-1.99.9-1.99 2L3 20c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 16H5V9h14v11z"/><path d="M0 0h24v24H0z" fill="none"/></svg>',
}; };
export const BackButton = { export const BackButton = {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment