Commit 29ce4ab5 authored by Sandro Lutz's avatar Sandro Lutz
Browse files

Merge branch 'master' into fix-job-offers-scrolls

parents 33568458 46d0054c
......@@ -3,8 +3,10 @@
background-color: #fff;
border: 2px solid #ddd;
border-radius: 2px;
padding: 11px;
margin: 0;
padding: 4px;
margin-top: 1em;
height: 2.5em;
width: 15em;
}
.dropdown[disabled] {
......
import m from 'mithril';
import './FileInput.less';
export default class FileInputComponent {
constructor() {
this.defaultProps = { type: 'file' };
}
view(vnode) {
return m('input', { ...this.defaultProps, ...vnode.attrs });
}
}
.fileinput {
outline: none;
background-color: #fff;
border: 2px solid #ddd;
border-radius: 2px;
padding: 11px;
margin-top: 3em;
height: 3em;
width: 15em;
}
......@@ -241,19 +241,21 @@ export default class FilterViewComponent {
view() {
const views = [];
this.fields.forEach(field => {
if (field.type === 'text') {
views.push(this._createTextField(field));
} else if (field.type === 'checkbox') {
views.push(this._createCheckboxGroup(field));
} else if (field.type === 'radio') {
views.push(this._createRadioGroup(field));
} else if (field.type === 'dropdown') {
views.push(this._createDropdown(field));
} else if (field.type === 'button') {
views.push(this._createButton(field));
}
});
m('div#filter-page-style', [
this.fields.forEach(field => {
if (field.type === 'text') {
views.push(this._createTextField(field));
} else if (field.type === 'checkbox') {
views.push(this._createCheckboxGroup(field));
} else if (field.type === 'radio') {
views.push(this._createRadioGroup(field));
} else if (field.type === 'dropdown') {
views.push(this._createDropdown(field));
} else if (field.type === 'button') {
views.push(this._createButton(field));
}
}),
]);
return views;
}
......
......@@ -8,3 +8,4 @@ export { default as FilterView } from './FilterView';
export { default as InputGroupForm } from './form/inputGroup';
export { default as JSONSchemaForm } from './form/jsonSchemaForm';
export { default as SelectGroupForm } from './form/selectGroup';
export { default as FileInput } from './FileInput';
......@@ -2,6 +2,7 @@
"values": {
"language.de": "Deutsch",
"language.en": "Englisch",
"close": "Schliessen",
"loading": "Laden...",
"loading_error": "Ein Fehler ist während dem Laden der Daten aufgetreten.",
"load_more": "Mehr laden",
......@@ -59,7 +60,6 @@
"commissions.no_contact_info": "Keine Kontaktinformationen",
"profile.free_beer": "Du bist berechtigt, gratis Bier zu beziehen!",
"profile.set_rfid": "Setze deine RFID unten, um gratis Bier zu erhalten!",
"profile.membership": "Art der Mitgliedschaft",
"profile.change_password": "Passwort ändern",
"profile.revert_to_ldap": "Zu LDAP zurückkehren",
"profile.set_password": "Passwort setzen",
......@@ -106,6 +106,15 @@
"studydocs.upload": "Dokument(e) hochladen",
"studydocs.uploading": "lädt hoch...",
"studydocs.access_denied": "Studienunterlagen sind nur für ETH Studenten verfügbar.",
"studydocs.rule": "Regeln:",
"studydocs.rule_1": "Diese Plattform lebt vom geben und nehmen - investiere also auch mal ein paar Minuten und schaue ob du für andere nützliches Material hast und lade es hoch. Es kostet nicht viel Zeit.",
"studydocs.rule_2": "Die Unterlagenübersicht ist noch im Beta-Stadium. Fehler und Anregungen bitte an unterlagen@amiv.ethz.ch senden.",
"studydocs.rule_3": "Einige der hier zu findenden Daten unterliegen der [BOT](https://rechtssammlung.sp.ethz.ch/_layouts/15/start.aspx#/default.aspx) sowie dem Urheberrecht und dienen zur internen Dokumentation gemäss [Bundesgesetz SR 231.1, Art. 19.1c](https://www.admin.ch/opc/de/classified-compilation/19920251/index.html#a19) und dürfen nicht an Nicht-ETH-Angehörige weitergegeben werden - daher ist der LogIn verpflichtend.",
"studydocs.rule_4": "Plagiate können schwerwiegende Folgen haben. Gib also keine Werke von anderen als dein eigenes aus und lies dir [diese Seite](https://www.ethz.ch/studierende/de/studium/leistungskontrollen/plagiate.html) sowie [dieses Merkblatt der ETH](http://www.lit.ethz.ch/faq/Italienisch/Lehre/box_feeder/PlagioETH_studenti) durch.",
"studydocs.thx": "Wir bedanken uns im Namen aller Studenten bei Allen, die ihre Unterlagen, Zusammenfassungen, und und und hier für andere Studenten zugänglich machen. Danke tausend, Gruss und Kuss.",
"studydocs.oral_ex": "Mündliche Prüfungen",
"studydocs.oral_ex_txt1": "Die Prüfungsprotokolle sind hier bestellbar und können gegen ein Depot von 20.- im AMIV Büro im CAB E37 abgeholt werden. Das Depot erhält man jeweils zurück, wenn man selbst ein Protokoll abgibt. Dies soll gewährleisten, dass es stets aktuelle mündliche Prüfungen im System hat. Wenn du ein Prüfungsprotokoll brauchst oder abgeben willst, schicke eine Mail an pruefungen@amiv.ethz.ch. Ein Prüfungsprotokoll beinhaltet mindestens folgende Infos: Fach, Prof./Prüfer, Stichworte, Was wurde gefragt etc.",
"studydocs.oral_ex_txt2": "Für die Sommersession 2018 können Protokolle (nach erfolgter Anmeldung) zu den folgenden Zeitpunkten abgeholt werden:",
"events.header_open_registration": "Anmeldung offen",
"events.header_upcoming": "Bevorstehende Events",
"events.header_past": "Vergangene Events",
......
......@@ -3,6 +3,7 @@
"language.de": "German",
"language.en": "English",
"loading": "Loading...",
"close": "close",
"loading_error": "Error while loading data.",
"load_more": "Load more",
"load_more_error": "There was an error while loading the data. Try again?",
......@@ -59,7 +60,6 @@
"commissions.no_contact_info": "No contact information.",
"profile.free_beer": "You are allowed to get free beer!",
"profile.set_rfid": "Set your RFID below to get free beer!",
"profile.membership": "Membership type",
"profile.change_password": "Change password",
"profile.revert_to_ldap": "Revert to LDAP",
"profile.set_password": "Set password",
......@@ -106,6 +106,15 @@
"studydocs.upload": "Upload study document(s)",
"studydocs.uploading": "Uploading...",
"studydocs.access_denied": "Study documents are available only for ETH students.",
"studydocs.rule": "Rules:",
"studydocs.rule_1": "This platform is based on a give-and-take principle, so please consider investing a few minutes to see whether you could contribute anything yourself. It does not take much time.",
"studydocs.rule_2": "This overview is still in development. Feedback would be appreciated and can be submitted at unterlagen@amiv.ethz.ch.",
"studydocs.rule_3": "Some of the listed documents are subject to the [BOT](https://rechtssammlung.sp.ethz.ch/_layouts/15/start.aspx#/default.aspx) as well as copyright and serve only as internal documentation according to [Bundesgesetz SR 231.1, Art. 19.1c](https://www.admin.ch/opc/de/classified-compilation/19920251/index.html#a19) and must not be distributed to non-ETH members. For these reasons Login is mandatory.",
"studydocs.rule_4": "Plagiarism may have dire consequences. Do not promote work of others as your own and read [this page](https://www.ethz.ch/studierende/de/studium/leistungskontrollen/plagiate.html) as well as [this ETH guide](http://www.lit.ethz.ch/faq/Italienisch/Lehre/box_feeder/PlagioETH_studenti)",
"studydocs.thx": "On behalf of all students we would like to thank those who contribute with their own documents and summaries – You da real MVP <3",
"studydocs.oral_ex": "Oral Exams",
"studydocs.oral_ex_txt1": "You can order your exam protocols here and get them for a deposit of CHF 20.- at the AMIV Office in CAB E37. You will get your deposit back for providing a protocol yourself. This shall make sure that our system is always up to date. If you need or want to provide an exam protocol, please send an e-mail to pruefungen@amiv.ethz.ch. A protocol includes at least the following content: course, professor/examinator, key words, what was asked and so on…",
"studydocs.oral_ex_txt2": "Protocols for the summer session 2018 can be picked up (upon request) on the following dates:",
"events.header_open_registration": "Open Registration",
"events.header_upcoming": "Upcoming Events",
"events.header_past": "Past Events",
......
......@@ -14,6 +14,10 @@
@import './mediaquery.less';
@import './profile.less';
@import './studydocList.less';
@import './studydocDetails.less';
@import './studydocNew.less';
@import './fileUpload.less';
@import './filterView.less';
html,body {
width: 100%;
......
div#fileUpload-container {
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-gap: 10px;
border: none;
margin-top: 2em;
margin-bottom: 2em;
div#uploader-info {
grid-column: ~'1 / 7';
grid-row: ~'1 / 2';
background-color: #fdfdfd;
margin: 10px;
padding: 10px;
border: 1px solid @color-grey;
}
div#document-info {
grid-column: ~'7 / 13';
grid-row: ~'1 / 2';
background-color: #fdfdfd;
margin: 10px;
padding: 10px;
border: 1px solid @color-grey;
}
#rule-style {
grid-column: ~'1 / 13';
grid-row: ~'2 / 3';
background-color: #fdfdfd;
margin: 10px;
padding: 10px;
border: 2px solid @color-grey;
}
#rules-title {
font-weight: bolder;
padding: .1em;
}
#rules-text {
padding: .1em;
}
}
div#filter-page-style {
padding-right: 5em;
}
......@@ -3,10 +3,10 @@
.filtered-list {
min-height: 100%;
display: grid;
grid-template-columns: 25% 40% auto;
grid-template-columns: 20% auto 25%;
@media @tablet {
grid-template-columns: 40% auto;
grid-template-columns: 20% auto;
}
@media @mobile {
......@@ -185,6 +185,9 @@
width: 100%;
padding: 1em 0;
text-align: center;
border: 2px solid @color-grey;
background-color: #f2f2f2;
font-weight: bold;
&.active {
cursor: pointer;
......
#profile-container {
display: grid;
grid-template-columns: repeat(12, auto);
grid-template-columns: repeat(12, 1fr);
grid-gap: 1.5em;
border: none;
margin-top: 2em;
margin-bottom: 2em;
@media @mobile {
grid-template-columns: repeat(6, 1fr);
}
#info {
grid-column: ~'1 / 13';
grid-row: ~'1 / 2';
background-color: #ddd;
border: 1px solid @color-grey;
background-image: linear-gradient(@color-grey, #fff);
//border: 1px solid @color-grey;
display: flex;
justify-content: space-between;
@media @mobile {
grid-column: ~'1 / 7';
}
}
#user-info {
#info-user {
grid-column: ~'1 / 7';
text-align: left;
padding: .5em;
margin: .5em;
font-size: x-large;
}
#amiv-info {
text-align: end;
padding: .5em;
#info-amiv {
grid-column: ~'8 / 13';
text-align: right;
font-size: large;
padding: 1em;
@media @mobile {
grid-column: ~'1 / 7';
}
}
#sessions-subscriptions {
......@@ -31,11 +50,11 @@
border: 1px solid @color-grey;
.announce-subscription {
padding: 5px;
padding: .1em;
}
.sessions {
padding: 5px;
padding: .1em;
}
}
......@@ -59,20 +78,35 @@
grid-column: ~'7 / 13';
grid-row: ~'2 / 4';
background-color: #fdfdfd;
display: grid;
display: flex;
flex-direction: column;
justify-content: flex-start;
grid-template-columns: repeat(3, 1fr);
padding: 15px;
border: 1px solid @color-grey;
max-height: min-content;
@media @mobile {
grid-column: ~'1 / 7';
grid-row: ~'6 / 8';
}
}
#groups {
grid-column: ~'7 / 13';
grid-row: ~'4 / 6';
background-color: #fdfdfd;
display: grid;
display: flex;
flex-direction: column;
justify-content: flex-start;
grid-template-columns: repeat(3, 1fr);
padding: 15px;
border: 1px solid @color-grey;
@media @mobile {
grid-column: ~'1 / 7';
grid-row: ~'8 / 10';
}
}
}
......@@ -85,6 +119,8 @@
#group-list {
grid-row: ~'2 / 3';
grid-column: ~'1 / -1';
max-height: 13em;
overflow: scroll;
.group-entry {
grid-column: ~'1 / -1';
......
.studydoc-details-table {
.flex-container {
display: flex;
flex-wrap: nowrap;
}
.flex-container > div {
//width: 14em;
padding: 0 5px 5px 0;
text-align: left;
//line-height: 75px;
}
b {
display: inline-block;
width: 8em;
//margin-right: 1em;
padding: 0 5px 5px 0;
}
.button-details-style {
display: inline-block;
width: 8em;
margin-right: 1em;
padding: 0 5px 5px 0;
}
#title-wrap-style {
display: inline-block;
text-align: center;
white-space: nowrap;
max-width: 8em;
overflow: hidden;
text-overflow: ellipsis;
direction: ltr;
}
}
#studydoc-list {
#head-style {
text-align: right;
}
#row-style {
height: 2em;
background-color: #fdfdfd;
border: 1px solid @color-grey;
&:hover {
background-color: #f5f5f5;
}
}
h2 {
display: inline;
text-align: center;
}
.flex-container {
display: flex;
flex-wrap: nowrap;
}
.flex-container > div {
//width: 14em;
padding: 0 5px 5px 0;
text-align: left;
//line-height: 75px;
}
div.list-item {
display: grid;
grid-template-columns: auto 20% 40%;
grid-row-gap: 5px;
grid-template-columns: auto 25% 15%;
grid-row-gap: .5em;
padding: .5em;
&:first-of-type {
font-weight: bold;
border-bottom: solid 1px #000;
border-bottom: solid 2px #000;
}
#title-style {
margin-top: auto;
margin-bottom: auto;
}
#author-style {
margin-top: auto;
margin-bottom: auto;
}
#course_year-style {
margin-top: auto;
margin-bottom: auto;
text-align: right;
}
}
div.list-style {
background-color: #808080;
}
}
#studydoc-new {
.file-style {
height: 10em;
}
}
......@@ -12,9 +12,9 @@ const renderHotCards = (item, index) => {
};
// Render the frontpage cards, with href and imageurl
const renderRowCards = (item, type) => {
const renderRowCards = (item, type = null) => {
const card_item = item;
if (!card_item.href) card_item.href = `${m.route.get() + type}/${card_item._id}`;
if (!card_item.href && type) card_item.href = `${m.route.get() + type}/${card_item._id}`;
return m('div.frontpage-row-card', m(Card, card_item));
};
......@@ -23,7 +23,7 @@ async function getData(state) {
if (events.length < 3) {
const pastEvents = await state.eventController.pastEvents.getPageData(1);
const { length } = events;
for (let i = 0; i < 3 - length; i += 1) events.push(pastEvents[i]);
for (let i = 0; i < Math.min(3 - length, pastEvents.length); i += 1) events.push(pastEvents[i]);
}
const jobs = await state.jobOfferController.getPageData(1);
return { ...{ events }, ...{ jobs } };
......
import m from 'mithril';
import { Dialog } from 'polythene-mithril';
import header from './header';
import footer from './footer';
export default class Layout {
static view(vnode) {
return m('div', [m(header), m('main', vnode.children), m(footer)]);
return m('div', [m(header), m('main', vnode.children), m(footer), m(Dialog)]);
}
}
......@@ -24,11 +24,8 @@ export default class UserInfo {
}
return m('div#info', [
m('div#user-info', [m('b', [user.firstname, ' ', user.lastname]), m('div', user.legi)]),
m('div#amiv-info', [
m('div', [i18n('profile.membership'), ': ', m('b', i18n(`${user.membership}_member`))]),
freeBeerNotice,
]),
m('div#info-user', [m('b', [user.firstname, ' ', user.lastname]), m('div', user.legi)]),
m('div#info-amiv', [m('div', m('b', i18n(`${user.membership}_member`))), freeBeerNotice]),
]);
}
}
......@@ -15,20 +15,60 @@ export default class StudydocDetails {
}
return [
m('table', [
m('tr', [m('td', m('b', i18n('studydocs.title'))), m('td', document.title)]),
m('tr', [m('td', m('b', i18n('studydocs.lecture'))), m('td', document.lecture)]),
m('tr', [m('td', m('b', i18n('studydocs.professor'))), m('td', document.professor)]),
m('tr', [m('td', m('b', i18n('studydocs.semester'))), m('td', document.semester)]),
m('tr', [m('td', m('b', i18n('studydocs.author'))), m('td', document.author)]),
m('tr', [m('td', m('b', i18n('studydocs.department'))), m('td', document.department)]),
m(Button, {
label: 'Download',
events: {
onclick: () => window.open(`${apiUrl}${document.files[0].file}`, '_blank'),
},
}),
m('div.studydoc-details-table', [
m('div.flex-container', [
m('div', m('b', i18n('studydocs.title'))),
m('div', document.title),
]),
m('div.flex-container', [
m('div', m('b', i18n('studydocs.type'))),
m('div', document.type),
]),
m('div.flex-container', [
m('div', m('b', i18n('studydocs.lecture'))),
m('div', document.lecture),
]),
m('div.flex-container', [
m('div', m('b', i18n('studydocs.professor'))),
m('div', document.professor),
]),
m('div.flex-container', [
m('div', m('b', i18n('studydocs.semester'))),
m('div', document.semester),
]),
m('div.flex-container', [
m('div', m('b', i18n('studydocs.author'))),
m('div', document.author),
]),
m('div.flex-container', [
m('div', m('b', i18n('studydocs.department'))),
m('div', document.department),
]),
]),
m(
'div.studydoc-details-table',
document.files.map(item =>
m('div', [
m(
'span.button-details-style',
m(Button, {
label: `Download ${item.name.split('.').pop()}`,
events: {
onclick: () => window.open(`${apiUrl}${item.file}`, '_blank'),
},
})
),
m('span#title-wrap-style', item.name),
])
)
),
];
}
}
import m from 'mithril';
import marked from 'marked';
import { Dialog, Button } from 'polythene-mithril';
import StudydocsController from '../../models/studydocs';
import { lectures } from '../studydocs/lectures';
import { i18n, currentLanguage } from '../../models/language';
......@@ -123,6 +125,27 @@ export default class StudydocList extends FilteredListPage {
{ value: 'exercises', label: i18n('exercises') },
],
},
{
type: 'button',
label: i18n('studydocs.oral_ex'),
className: 'flat-button',
events: {
onclick: () =>
Dialog.show({
title: i18n('studydocs.oral_ex'),
body: m.trust(marked(i18n('studydocs.oral_ex_txt1'))),
modal: true,
backdrop: true,
footerButtons: m(Button, {
label: i18n('close'),
className: 'flat-button',
events: {
onclick: () => Dialog.hide(),
},
}),
}),
},
},
{
type: 'button',
label: i18n('reset'),
......@@ -174,7 +197,11 @@ export default class StudydocList extends FilteredListPage {
}
get _listView() {
const tableHeadings = ['studydocs.title', 'studydocs.author', 'studydocs.type'];
const tableHeadings = [