Commit b60dcec6 authored by emustafa's avatar emustafa
Browse files

Merge branch 'fix/departmentnone' of...

Merge branch 'fix/departmentnone' of https://gitlab.ethz.ch/amiv/amiv-admintool into fix/departmentnone
parents 6bd720c4 f4665597
stages: stages:
- test
- build - build
- deploy - deploy
eslint:
stage: test
image: node:latest
before_script:
- npm install
script:
- npm run lint
build_master_dev: build_master_dev:
stage: build stage: build
image: docker:latest image: docker:latest
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
"start": "webpack-dev-server --hot --inline", "start": "webpack-dev-server --hot --inline",
"build": "webpack -p --config webpack.config.prod.js", "build": "webpack -p --config webpack.config.prod.js",
"build-dev": "webpack -p --config webpack.config.dev.js", "build-dev": "webpack -p --config webpack.config.dev.js",
"lint": "eslint src/**" "lint": "eslint src/**.js"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
......
import tool from 'announcetool';
const m = require('mithril');
export default class AnnounceTool {
oncreate() {
if (tool.wasRenderedOnce()) {
// jQuery catches the first document.ready, but afterwards we have to
// trigger a render
tool.render();
}
}
view() {
return m('div', [
m('div#tableset', [
m('p#events'),
m('div#buttonrow', [
m('button#preview.btn.btn-default', 'Preview'),
m('button#reset.btn.btn-default', 'Reset'),
m('button#send.btn.btn-default', 'Send'),
]),
]),
m('br'),
m('hr'),
m('textarea#target'),
]);
}
}
...@@ -2,6 +2,7 @@ import m from 'mithril'; ...@@ -2,6 +2,7 @@ import m from 'mithril';
import axios from 'axios'; import axios from 'axios';
import ClientOAuth2 from 'client-oauth2'; import ClientOAuth2 from 'client-oauth2';
import { Snackbar } from 'polythene-mithril'; import { Snackbar } from 'polythene-mithril';
// eslint-disable-next-line import/extensions
import { apiUrl, ownUrl, oAuthID } from 'networkConfig'; import { apiUrl, ownUrl, oAuthID } from 'networkConfig';
import * as localStorage from './localStorage'; import * as localStorage from './localStorage';
import config from './resourceConfig.json'; import config from './resourceConfig.json';
...@@ -185,6 +186,9 @@ export class ResourceHandler { ...@@ -185,6 +186,9 @@ export class ResourceHandler {
Snackbar.show({ title: 'Network error, try again.', style: { color: 'red' } }); Snackbar.show({ title: 'Network error, try again.', style: { color: 'red' } });
} }
// in future, we may communicate based on the data available
// therefore, require data already here
// eslint-disable-next-line no-unused-vars
error422(data) { error422(data) {
Snackbar.show({ title: 'Errors in object, please fix.' }); Snackbar.show({ title: 'Errors in object, please fix.' });
} }
...@@ -331,11 +335,11 @@ export class ResourceHandler { ...@@ -331,11 +335,11 @@ export class ResourceHandler {
export class OauthRedirect { export class OauthRedirect {
view() { view() {
oauth.token.getToken(m.route.get()).then((response) => { oauth.token.getToken(m.route.get()).then((auth) => {
APISession.authenticated = true; APISession.authenticated = true;
APISession.token = response.accessToken; APISession.token = auth.accessToken;
localStorage.set('token', response.accessToken); localStorage.set('token', auth.accessToken);
amivapi.get(`sessions/${response.accessToken}`, { amivapi.get(`sessions/${auth.accessToken}`, {
headers: { 'Content-Type': 'application/json', Authorization: APISession.token }, headers: { 'Content-Type': 'application/json', Authorization: APISession.token },
}).then((response) => { }).then((response) => {
console.log(response); console.log(response);
......
import ItemView from './views/itemView';
import EditView from './views/editView';
import { inputGroup, selectGroup, submitButton } from './views/elements';
import TableView from './views/tableView';
import { events as config } from './config.json';
const m = require('mithril');
export class EventView extends ItemView {
constructor() {
super('events');
this.memberships = [];
}
view() {
// do not render anything if there is no data yet
if (!this.data) return m.trust('');
let comissionBadge = m('span.label.label-important', 'Who is resp of this event?');
if (this.data.membership === 'kultur') {
comissionBadge = m('span.label.label-success', 'Kulturi event');
} else if (this.data.membership === 'eestec') {
comissionBadge = m('span.label.label-important', 'EESTEC event');
} else if (this.data.membership === 'limes') {
comissionBadge = m('span.label.label-warning', 'LIMES event');
}
// TODO Question Lio171201:are we missing a "responsible" key?
const detailKeys = [
'title_de',
'rfid',
'location', 'time_start', 'time_end',
'show_website', 'catchphrase',
'time_register_start', 'price', 'allow_email_signup'];
return m('div', [
m('h1', `${this.data.title_de}`),
comissionBadge,
m('table', detailKeys.map(key => m('tr', [
m('td.detail-descriptor', config.keyDescriptors[key]),
m('td', this.data[key] ? this.data[key] : ''),
]))),
m('h2', 'Location'), m('br'),
m(TableView, {
resource: 'events',
keys: ['event.location'],
query: {
where: { user: this.id },
embedded: { group: 1 },
},
}),
m('h2', 'Signups'), m('br'),
m(TableView, {
resource: 'events',
keys: ['event.title_de'],
query: {
where: { user: this.id },
embedded: { event: 1 },
},
}),
]);
}
}
class EventEdit extends EditView {
constructor(vnode) {
super(vnode, 'events');
}
getForm() {
return m('form', [
m('div.row', [
m(inputGroup, this.bind({ title: 'Deutscher Titel', name: 'title_de' })),
m(inputGroup, this.bind({ title: 'English Title', name: 'title_en' })),
m(inputGroup, this.bind({ title: 'Location', name: 'location' })),
// m(inputGroup, this.bind({ title: 'Date-start', name: 'datetimepicker1' })),
// $('#datetimepicker1').datetimepicker();
m(selectGroup, this.bind({
classes: 'col-xs-6',
title: 'May non-AMIV members register?',
name: 'allow_email_signup',
options: [true, false],
})),
m(selectGroup, this.bind({
classes: 'col-xs-6',
title: 'Show on the website?',
name: 'show_website',
options: [true, false],
})),
m(selectGroup, this.bind({
classes: 'col-xs-6',
title: 'Piority from 1 to 10?',
name: 'priority',
// could be done with array.apply:
options: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
})),
]),
m('span', JSON.stringify(this.data)),
m('span', JSON.stringify(this.errors)),
]);
}
view() {
// do not render anything if there is no data yet
if (!this.data) return m.trust('');
return m('form', [
this.getForm(),
m(submitButton, {
active: this.valid,
args: {
onclick: this.submit('PATCH', config.patchableKeys),
class: 'btn-warning',
},
text: 'Update',
}),
]);
}
}
export class NewEvent extends EventEdit {
constructor(vnode) {
super(vnode);
this.data = {
title_de: 'Unvollstaendiges Event',
priority: 7,
show_website: false,
};
this.valid = false;
// if the creation is finished, UI should switch to new Event
this.callback = (response) => { m.route.set(`/events/${response.data._id}`); };
}
view() {
return m('form', [
this.getForm(),
m(submitButton, {
active: this.valid,
args: {
onclick: this.submit('POST', config.patchableKeys),
class: 'btn-warning',
},
text: 'Create',
}),
]);
}
}
export class EventModal {
constructor() {
this.edit = false;
}
view() {
if (this.edit) {
return m(EventEdit, { onfinish: () => { this.edit = false; m.redraw(); } });
}
// else
return m('div', [
m('div.btn.btn-default', { onclick: () => { this.edit = true; } }, 'Edit'),
m('br'),
m(EventView),
]);
}
}
...@@ -3,8 +3,6 @@ import { Card } from 'polythene-mithril'; ...@@ -3,8 +3,6 @@ import { Card } from 'polythene-mithril';
import { DatalistController } from 'amiv-web-ui-components'; import { DatalistController } from 'amiv-web-ui-components';
import { loadingScreen } from '../layout'; import { loadingScreen } from '../layout';
import { ResourceHandler, getCurrentUser } from '../auth'; import { ResourceHandler, getCurrentUser } from '../auth';
import { colors } from '../style';
class GroupListItem { class GroupListItem {
view({ attrs: { name, _id, color = '#ffffff' } }) { view({ attrs: { name, _id, color = '#ffffff' } }) {
...@@ -36,7 +34,7 @@ export default class GroupList { ...@@ -36,7 +34,7 @@ export default class GroupList {
this.ctrl.getFullList().then((moderatedList) => { this.ctrl.getFullList().then((moderatedList) => {
this.moderatedGroups = moderatedList; this.moderatedGroups = moderatedList;
m.redraw(); m.redraw();
}) });
}); });
} }
...@@ -54,13 +52,13 @@ export default class GroupList { ...@@ -54,13 +52,13 @@ export default class GroupList {
m('div', { m('div', {
style: { style: {
'font-size': '20px', 'font-size': '20px',
'margin': '10px 5px' margin: '10px 5px',
}, },
}, 'moderated by you'), }, 'moderated by you'),
m('div', { m('div', {
style: { display: 'flex', 'flex-wrap': 'wrap' } style: { display: 'flex', 'flex-wrap': 'wrap' },
}, this.moderatedGroups.map(item => }, this.moderatedGroups.map(item =>
m(GroupListItem, { ...item } ))), m(GroupListItem, { ...item }))),
]), ]),
m('div.maincontainer', { m('div.maincontainer', {
style: { display: 'flex', 'flex-wrap': 'wrap', 'margin-top': '5px' }, style: { display: 'flex', 'flex-wrap': 'wrap', 'margin-top': '5px' },
...@@ -68,18 +66,18 @@ export default class GroupList { ...@@ -68,18 +66,18 @@ export default class GroupList {
this.moderatedGroups.length > 0 && m('div', { this.moderatedGroups.length > 0 && m('div', {
style: { style: {
'font-size': '20px', 'font-size': '20px',
'margin': '10px 5px' margin: '10px 5px',
}, },
}, 'all groups'), }, 'all groups'),
m('div', { m('div', {
style: { display: 'flex', 'flex-wrap': 'wrap' } style: { display: 'flex', 'flex-wrap': 'wrap' },
}, }, [
this.groups.map(item => m(GroupListItem, item)), this.groups.map(item => m(GroupListItem, item)),
m('div', { m('div', {
style: { 'max-width': '500px', margin: '5px' }, style: { 'max-width': '500px', margin: '5px' },
onclick: () => { m.route.set('/newgroup'); }, onclick: () => { m.route.set('/newgroup'); },
}, m(Card, { content: [{ primary: { title: '+ add' } }] })), }, m(Card, { content: [{ primary: { title: '+ add' } }] })),
), ]),
]), ]),
]); ]);
} }
......
...@@ -3,11 +3,13 @@ import { OauthRedirect } from './auth'; ...@@ -3,11 +3,13 @@ import { OauthRedirect } from './auth';
import GroupList from './groups/list'; import GroupList from './groups/list';
import GroupItem from './groups/item'; import GroupItem from './groups/item';
import { UserItem, UserTable } from './users/userTool'; import { UserItem, UserTable } from './users/userTool';
import { MembershipView } from './membershipTool'; import MembershipView from './membershipTool';
import EventTable from './events/table'; import EventTable from './events/table';
import EventItem from './events/item'; import EventItem from './events/item';
import JobTable from './jobs/table'; import JobTable from './jobs/table';
import JobItem from './jobs/item'; import JobItem from './jobs/item';
import StudydocTable from './studydocs/list';
import studydocItem from './studydocs/item';
import { Layout } from './layout'; import { Layout } from './layout';
import './style'; import './style';
...@@ -38,4 +40,7 @@ m.route(root, '/events', { ...@@ -38,4 +40,7 @@ m.route(root, '/events', {
'/joboffers': layoutWith(JobTable), '/joboffers': layoutWith(JobTable),
'/newjoboffer': layoutWith(JobItem), '/newjoboffer': layoutWith(JobItem),
'/joboffers/:id': layoutWith(JobItem), '/joboffers/:id': layoutWith(JobItem),
'/studydocuments': layoutWith(StudydocTable),
'/studydocuments/:id': layoutWith(studydocItem),
'/newstudydocument': layoutWith(studydocItem),
}); });
...@@ -39,7 +39,7 @@ export default class ItemController { ...@@ -39,7 +39,7 @@ export default class ItemController {
cancel() { cancel() {
if (this.modus === 'edit') this.changeModus('view'); if (this.modus === 'edit') this.changeModus('view');
if (this.modus === 'new') m.route.set(`/${this.resource}`); else m.route.set(`/${this.resource}`);
} }
changeModus(newModus) { changeModus(newModus) {
......
...@@ -5,27 +5,6 @@ import ItemView from '../views/itemView'; ...@@ -5,27 +5,6 @@ import ItemView from '../views/itemView';
import { dateFormatter } from '../utils'; import { dateFormatter } from '../utils';
import { Property } from '../views/elements'; import { Property } from '../views/elements';
// small helper class to display both German and English content together, dependent
// on which content is available.
class DuoLangProperty {
view({ attrs: { title, de, en } }) {
// TODO Lang indicators should be smaller and there should be less margin
// between languages
return m(
Property,
{ title },
de ? m('div', [
m('div', { className: 'propertyLangIndicator' }, 'DE'),
m('p', de),
]) : '',
en ? m('div', [
m('div', { className: 'propertyLangIndicator' }, 'EN'),
m('p', en),
]) : '',
);
}
}
export default class viewJob extends ItemView { export default class viewJob extends ItemView {
view() { view() {
return this.layout([ return this.layout([
......
...@@ -143,8 +143,9 @@ export class Layout { ...@@ -143,8 +143,9 @@ export class Layout {
title: 'Job offers', title: 'Job offers',
}), }),
m(Menupoint, { m(Menupoint, {
href: '/announce', href: '/studydocuments',
title: 'Announce', icon: icons.studydoc,
title: 'Studydocs',
}), }),
], ],
}), }),
......
import m from 'mithril';
import EditView from './views/editView'; import EditView from './views/editView';
import SelectList from './views/selectList';
const m = require('mithril'); export default class MembershipView extends EditView {
export class MembershipView extends EditView {
constructor(vnode) { constructor(vnode) {
super(vnode, 'groupmemberships', { user: 1, group: 1 }); super(vnode, 'groupmemberships', { user: 1, group: 1 });
} }
...@@ -23,17 +21,3 @@ export class MembershipView extends EditView { ...@@ -23,17 +21,3 @@ export class MembershipView extends EditView {
]); ]);
} }
} }
export class NewMembership {
constructor() {
this.selectUser = new SelectList('users', ['firstname', 'lastname'], {
view(vnode) {
return m('span', `${vnode.attrs.firstname} ${vnode.attrs.lastname}`);
},
});
}
view() {
return m(this.selectUser);
}
}
...@@ -117,5 +117,14 @@ ...@@ -117,5 +117,14 @@
}, },
"sessions": { "sessions": {
"searchKeys": [] "searchKeys": []
},
"studydocuments": {
"searchKeys": [
"title",
"lecture",
"professor",
"author",
"uploader"
]
} }
} }
import m from 'mithril';
import { RadioGroup } from 'polythene-mithril';
import EditView from '../views/editView';
export default class editDoc extends EditView {
view() {
return this.layout([
m('h3', 'Add a New Studydocument'),
...this.form.renderPage({
// uploader
author: { type: 'text', label: 'Author' },
files: { type: 'text', label: 'File' }, // buggy only singel file possible
lecture: { type: 'text', label: 'Lecture' },
title: { type: 'text', label: 'Title' },
professor: { type: 'text', label: 'Professor' },
course_year: { type: 'number', lable: 'Year' }, // semester unterscheidung, plausibility
}),
// department //drop-down-list
m('div', 'Semester'), // formatieren
m(RadioGroup, {
name: 'semester',
buttons: [
{ value: '1', label: '1.', defaultChecked: this.form.data.gender === '1' },
{ value: '2', label: '2', defaultChecked: this.form.data.gender === '2' },
{ value: '3', label: '3', defaultChecked: this.form.data.gender === '3' },
{ value: '4', label: '4', defaultChecked: this.form.data.gender === '4' },
{ value: '5', label: '5+', defaultChecked: this.form.data.gender === '5' },
],
onChange: ({ value }) => { console.log(value); this.form.data.gender = value; },
}),
m(RadioGroup, {
name: 'type',
buttons: [{
value: 'exames',
label: 'exames',
defaultChecked: this.form.data.gender === 'exames',
}, {
value: 'cheat_sheet',
label: 'cheat sheet',
defaultChecked: this.form.data.gender === 'cheat_sheet',
}, {
value: 'lecture_documents',
label: 'lecture documents',
defaultChecked: this.form.data.gender === 'lecture_documents',
}, {
value: 'exercise',
label: 'exercise',
defaultChecked: this.form.data.gender === 'exercise',
}],
onChange: ({ value }) => { console.log(value); this.form.data.gender = value; },
}),
]);
}
}
import m from 'mithril';
import viewDoc from './viewDoc';
import editDoc from './editDoc';
import ItemController from '../itemcontroller';
import { loadingScreen } from '../layout';
export default class studydocItem {
constructor() {
this.controller = new ItemController('studydocuments');
}
view() {
if (!this.controller || !this.controller.data) return m(loadingScreen);
if (this.controller.modus !== 'view') return m(editDoc, { controller: this.controller });
return m(viewDoc, { controller: this.controller });
}
}
import m from 'mithril';
import { DatalistController } from 'amiv-web-ui-components';
import { studydocuments as config } from '../resourceConfig.json';