Commit 36dcc986 authored by Hermann's avatar Hermann Committed by Sandro Lutz
Browse files

Updating admintools to make use of new web-ui-components repository

parent f78eb60a
......@@ -18,6 +18,7 @@
"@material/drawer": "^0.30.0",
"@material/select": "^0.35.1",
"ajv": "^5.5.0",
"amiv-web-ui-components": "git+https://git@gitlab.ethz.ch/amiv/web-ui-components.git",
"axios": "^0.17.1",
"client-oauth2": "^4.2.0",
"mithril": "^1.1.6",
......@@ -32,7 +33,7 @@
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-preset-env": "^1.6.1",
"babel-preset-env": "^1.7.0",
"compression-webpack-plugin": "^1.1.11",
"css-loader": "^0.28.11",
"eslint": "^4.10.0",
......@@ -41,7 +42,7 @@
"eslint-plugin-import": "^2.9.0",
"file-loader": "^1.1.5",
"style-loader": "^0.19.0",
"webpack": "^3.8.1",
"webpack": "^3.12.0",
"webpack-dev-server": "^2.9.5"
}
}
import m from 'mithril';
import { RaisedButton, RadioGroup, Slider, Switch } from 'polythene-mithril';
import { RaisedButton, RadioGroup, Switch } from 'polythene-mithril';
import { fileInput } from 'amiv-web-ui-components';
import { styler } from 'polythene-core-css';
// eslint-disable-next-line import/extensions
import { apiUrl } from 'networkConfig';
import EditView from '../views/editView';
import { fileInput } from '../views/elements';
const style = [
{
......@@ -19,33 +20,33 @@ export default class newEvent extends EditView {
constructor(vnode) {
super(vnode);
this.currentpage = 1;
if (!this.data.priority) this.data.priority = 1;
if (!this.form.data.priority) this.form.data.priority = 1;
// read additional_fields to make it editable
if (this.data.additional_fields) {
const copy = JSON.parse(this.data.additional_fields);
this.data.add_fields_sbb = 'SBB_Abo' in copy.properties;
this.data.add_fields_food = 'Food' in copy.properties;
this.data.additional_fields = {};
if (this.form.data.additional_fields) {
const copy = JSON.parse(this.form.data.additional_fields);
this.form.data.add_fields_sbb = 'SBB_Abo' in copy.properties;
this.form.data.add_fields_food = 'Food' in copy.properties;
this.form.data.additional_fields = {};
}
// price can either not be set or set to null
// if it is 0 however, that would mean that there actually is a price that
// you can edit
this.hasprice = 'price' in this.data && this.data.price !== null;
this.hasregistration = 'time_advertising_start' in this.data;
this.hasprice = 'price' in this.form.data && this.form.data.price !== null;
this.hasregistration = 'time_advertising_start' in this.form.data;
}
beforeSubmit() {
// Collect images seperate from everything else
const images = {};
['thumbnail', 'banner', 'infoscreen', 'poster'].forEach((key) => {
if (this.data[`new_${key}`]) {
images[`img_${key}`] = this.data[`new_${key}`];
delete this.data[`new_${key}`];
if (this.form.data[`new_${key}`]) {
images[`img_${key}`] = this.form.data[`new_${key}`];
delete this.form.data[`new_${key}`];
}
if (this.data[`img_${key}`]) {
delete this.data[`img_${key}`];
if (this.form.data[`img_${key}`]) {
delete this.form.data[`img_${key}`];
}
});
......@@ -58,7 +59,7 @@ export default class newEvent extends EditView {
properties: {},
required: [],
};
if (this.data.add_fields_sbb) {
if (this.form.data.add_fields_sbb) {
additionalFields.properties.SBB_Abo = {
type: 'string',
enum: ['None', 'GA', 'Halbtax', 'Gleis 7'],
......@@ -66,7 +67,7 @@ export default class newEvent extends EditView {
additionalFields.required.push('SBB_Abo');
}
if (this.data.add_fields_food) {
if (this.form.data.add_fields_food) {
additionalFields.properties.Food = {
type: 'string',
enum: ['Omnivor', 'Vegi', 'Vegan', 'Other'],
......@@ -76,31 +77,31 @@ export default class newEvent extends EditView {
};
additionalFields.required.push('Food');
}
if ('add_fields_sbb' in this.data) delete this.data.add_fields_sbb;
if ('add_fields_food' in this.data) delete this.data.add_fields_food;
if ('add_fields_sbb' in this.form.data) delete this.form.data.add_fields_sbb;
if ('add_fields_food' in this.form.data) delete this.form.data.add_fields_food;
// if the properties are empty, we null the whole field, otherwise we send a json string
// of the additional fields object
if (Object.keys(additionalFields.properties).length > 0) {
this.data.additional_fields = JSON.stringify(additionalFields);
this.form.data.additional_fields = JSON.stringify(additionalFields);
} else {
this.data.additional_fields = null;
this.form.data.additional_fields = null;
}
// if spots is not set, also remove 'allow_email_signup'
if (!('spots' in this.data) && 'allow_email_signup' in this.data
&& !this.data.allow_email_signup) {
delete this.data.allow_email_signup;
if (!('spots' in this.form.data) && 'allow_email_signup' in this.form.data
&& !this.form.data.allow_email_signup) {
delete this.form.data.allow_email_signup;
}
console.log(this.data);
console.log(this.form.data);
if (Object.keys(images).length > 0) {
images._id = this.data._id;
images._etag = this.data._etag;
images._id = this.form.data._id;
images._etag = this.form.data._etag;
// first upload the images as formData, then the rest as JSON
this.controller.handler.patch(images, true).then(({ _etag }) => {
this.data._etag = _etag;
this.form.data._etag = _etag;
this.submit();
});
} else {
......@@ -143,8 +144,8 @@ export default class newEvent extends EditView {
],
onChange: (state) => {
this.selection_strategy = state.value;
this.data.selection_strategy = state.value;
console.log(this.data); // Temp proof of concept.
this.form.data.selection_strategy = state.value;
console.log(this.form.data); // Temp proof of concept.
},
value: this.selection_strategy,
});
......@@ -162,7 +163,7 @@ export default class newEvent extends EditView {
m('br'),
m('div', {
style: { display: (this.currentpage === 1) ? 'block' : 'none' },
}, this.renderPage({
}, this.form.renderPage({
title_en: { type: 'text', label: 'English Event Title' },
catchphrase_en: { type: 'text', label: 'English Catchphrase' },
description_en: {
......@@ -182,7 +183,7 @@ export default class newEvent extends EditView {
})),
m('div', {
style: { display: (this.currentpage === 2) ? 'block' : 'none' },
}, this.renderPage({
}, this.form.renderPage({
time_start: { type: 'datetime', label: 'Event Start Time' },
time_end: { type: 'datetime', label: 'Event End Time' },
location: { type: 'text', label: 'Location' },
......@@ -198,12 +199,12 @@ export default class newEvent extends EditView {
this.hasprice = checked;
if (!checked) {
// if it originally had a price, set to null, otherwise delete
if (this.controller.data.price) this.data.price = null;
else delete this.data.price;
if (this.controller.data.price) this.form.data.price = null;
else delete this.form.data.price;
}
},
}),
...this.hasprice && this.renderPage({
...this.hasprice && this.form.renderPage({
price: { type: 'number', label: 'Price', min: 0, step: 0.01 },
}),
m('br'),
......@@ -213,17 +214,17 @@ export default class newEvent extends EditView {
onChange: ({ checked }) => {
this.hasregistration = checked;
if (!checked) {
delete this.data.spots;
delete this.data.time_register_start;
delete this.data.time_register_end;
delete this.data.add_fields_sbb;
delete this.data.add_fields_food;
delete this.data.allow_email_signup;
delete this.data.selection_strategy;
delete this.form.data.spots;
delete this.form.data.time_register_start;
delete this.form.data.time_register_end;
delete this.form.data.add_fields_sbb;
delete this.form.data.add_fields_food;
delete this.form.data.allow_email_signup;
delete this.form.data.selection_strategy;
}
},
}),
...this.hasregistration && this.renderPage({
...this.hasregistration && this.form.renderPage({
spots: {
type: 'number',
label: 'Number of Spots',
......@@ -237,7 +238,7 @@ export default class newEvent extends EditView {
add_fields_sbb: { type: 'checkbox', label: 'SBB Abbonement' },
}),
m('br'),
...this.hasregistration && this.renderPage({
...this.hasregistration && this.form.renderPage({
allow_email_signup: { type: 'checkbox', label: 'Allow Email Signup' },
}),
this.hasregistration && radioButtonSelectionMode,
......@@ -245,7 +246,7 @@ export default class newEvent extends EditView {
m('div', {
style: { display: (this.currentpage === 4) ? 'block' : 'none' },
}, [
...this.renderPage({
...this.form.renderPage({
time_advertising_start: {
type: 'datetime',
label: 'Start of Advertisement',
......@@ -257,15 +258,17 @@ export default class newEvent extends EditView {
required: true,
},
}),
m.trust('Priority<br>'),
// TODO is deactivated now
/*m.trust('Priority<br>'),
m(Slider, {
min: 1,
max: 10,
stepSize: 1,
// value: this.data.priority || 1,
// onChange: ({ value }) => { this.data.priority = value; },
}),
...this.renderPage({
}),*/
...this.form.renderPage({
show_website: { type: 'checkbox', label: 'Advertise on Website' },
show_announce: { type: 'checkbox', label: 'Advertise in Announce' },
show_infoscreen: {
......@@ -278,11 +281,11 @@ export default class newEvent extends EditView {
style: { display: (this.currentpage === 5) ? 'block' : 'none' },
}, [
['thumbnail', 'banner', 'poster', 'infoscreen'].map(key => [
this.data[`img_${key}`] ? m('img', {
src: `${apiUrl}${this.data[`img_${key}`].file}`,
this.form.data[`img_${key}`] ? m('img', {
src: `${apiUrl}${this.form.data[`img_${key}`].file}`,
style: { 'max-height': '50px', 'max-width': '100px' },
}) : m('div', `currently no ${key} image set`),
m(fileInput, this.bind({
m(fileInput, this.form.bind({
name: `new_${key}`,
label: `New ${key} Image`,
accept: 'image/png, image/jpeg',
......
import m from 'mithril';
import { DatalistController } from 'amiv-web-ui-components';
import { events as config } from '../resourceConfig.json';
import TableView from '../views/tableView';
import DatalistController from '../listcontroller';
import { dateFormatter } from '../utils';
import { ResourceHandler } from '../auth';
/* Table of all Events
......@@ -13,7 +14,8 @@ import { dateFormatter } from '../utils';
export default class EventTable {
constructor() {
this.ctrl = new DatalistController('events', {}, config.tableKeys);
this.handler = new ResourceHandler('events', config.tableKeys);
this.ctrl = new DatalistController((query, search) => this.handler.get({ search, ...query }));
}
getItemData(data) {
......
......@@ -7,6 +7,7 @@ import {
TextField,
} from 'polythene-mithril';
import { styler } from 'polythene-core-css';
import { DropdownCard } from 'amiv-web-ui-components';
// eslint-disable-next-line import/extensions
import { apiUrl } from 'networkConfig';
import ItemView from '../views/itemView';
......@@ -14,7 +15,7 @@ import { eventsignups as signupConfig } from '../resourceConfig.json';
import TableView from '../views/tableView';
import RelationlistController from '../relationlistcontroller';
import { dateFormatter } from '../utils';
import { icons, DropdownCard, Property, chip } from '../views/elements';
import { icons, Property, chip } from '../views/elements';
import { ResourceHandler } from '../auth';
const viewLayout = [
......
import m from 'mithril';
import { TextField } from 'polythene-mithril';
import { ListSelect, DatalistController } from 'amiv-web-ui-components';
// eslint-disable-next-line import/extensions
import { apiUrl } from 'networkConfig';
import SelectList from '../views/selectList';
import { ResourceHandler } from '../auth';
import { MDCSelect } from '../views/selectOption';
import DatalistController from '../listcontroller';
import EditView from '../views/editView';
......@@ -78,23 +78,21 @@ class PermissionEditor {
export default class NewGroup extends EditView {
constructor(vnode) {
super(vnode);
this.userController = new DatalistController(
'users', {},
['firstname', 'lastname', 'email', 'nethz'],
);
console.log(this.data);
this.userHandler = new ResourceHandler('users', ['firstname', 'lastname', 'email', 'nethz']);
this.userController = new DatalistController((query, search) =>
this.userHandler.get({ search, ...query }));
}
beforeSubmit() {
// exchange moderator object with string of id
const { moderator } = this.data;
if (moderator) { this.data.moderator = `${moderator._id}`; }
const { moderator } = this.form.data;
if (moderator) { this.form.data.moderator = `${moderator._id}`; }
this.submit();
}
view() {
return this.layout([
...this.renderPage({
...this.form.renderPage({
name: { type: 'text', label: 'Group Name' },
allow_self_enrollment: {
type: 'checkbox',
......@@ -107,17 +105,17 @@ export default class NewGroup extends EditView {
}),
m('div', { style: { display: 'flex' } }, [
m(TextField, { label: 'Group Moderator: ', disabled: true, style: { width: '160px' } }),
m('div', { style: { 'flex-grow': 1 } }, m(SelectList, {
m('div', { style: { 'flex-grow': 1 } }, m(ListSelect, {
controller: this.userController,
selection: this.data.moderator,
selection: this.form.data.moderator,
listTileAttrs: user => Object.assign({}, { title: `${user.firstname} ${user.lastname}` }),
selectedText: user => `${user.firstname} ${user.lastname}`,
onSelect: (data) => { this.data.moderator = data; },
onSelect: (data) => { console.log('data'); this.form.data.moderator = data; },
})),
]),
m(PermissionEditor, {
permissions: this.data.permissions,
onChange: (newPermissions) => { this.data.permissions = newPermissions; },
permissions: this.form.data.permissions,
onChange: (newPermissions) => { this.form.data.permissions = newPermissions; },
}),
]);
}
......
import m from 'mithril';
import { Card } from 'polythene-mithril';
import DatalistController from '../listcontroller';
import { DatalistController } from 'amiv-web-ui-components';
import { loadingScreen } from '../layout';
import { ResourceHandler } from '../auth';
class GroupListItem {
......@@ -18,7 +19,11 @@ class GroupListItem {
export default class GroupList {
constructor() {
this.ctrl = new DatalistController('groups', { sort: [['name', 1]] }, ['name']);
this.handler = new ResourceHandler('groups', ['name']);
this.ctrl = new DatalistController(
(query, search) => this.handler.get({ search, ...query }),
{ sort: [['name', 1]] },
);
this.data = [];
this.ctrl.getFullList().then((list) => { this.data = list; m.redraw(); });
}
......
......@@ -7,14 +7,13 @@ import {
TextField,
Icon,
} from 'polythene-mithril';
import { icons, Property, DropdownCard, chip } from '../views/elements';
import { DatalistController, ListSelect, DropdownCard } from 'amiv-web-ui-components';
import { icons, Property, chip } from '../views/elements';
import { colors } from '../style';
import ItemView from '../views/itemView';
import TableView from '../views/tableView';
import DatalistController from '../listcontroller';
import RelationlistController from '../relationlistcontroller';
import SelectList from '../views/selectList';
import { ResourceHandler } from '../auth';
......@@ -26,10 +25,9 @@ class MembersTable {
this.ctrl = new RelationlistController('groupmemberships', 'users', { where: { group } });
// true while in the modus of adding a member
this.addmode = false;
this.userController = new DatalistController(
'users', {},
['firstname', 'lastname', 'email', 'nethz'],
);
this.userHandler = new ResourceHandler('users');
this.userController = new DatalistController((query, search) =>
this.userHandler.get({ search, ...query }));
}
itemRow(data) {
......@@ -59,7 +57,7 @@ class MembersTable {
return m(Card, {
style: { height: '500px' },
content: m('div', [
this.addmode ? m(SelectList, {
this.addmode ? m(ListSelect, {
controller: this.userController,
listTileAttrs: user => Object.assign({}, { title: `${user.firstname} ${user.lastname}` }),
selectedText: user => `${user.firstname} ${user.lastname}`,
......@@ -181,7 +179,6 @@ class EmailTable {
}
export default class viewGroup extends ItemView {
oninit() {
// load the number of members in this group
const handler = new ResourceHandler('groupmemberships');
......
......@@ -6,7 +6,7 @@ export default class newJob extends EditView {
view() {
return this.layout([
m('h3', 'Add a New Job Offer'),
...this.renderPage({
...this.form.renderPage({
title_de: { type: 'text', label: 'German Title' },
}),
]);
......
import m from 'mithril';
import { DatalistController } from 'amiv-web-ui-components';
import { joboffers as config } from '../resourceConfig.json';
import TableView from '../views/tableView';
import DatalistController from '../listcontroller';
import { dateFormatter } from '../utils';
import { ResourceHandler } from '../auth';
/* Table of all current Jobs
......@@ -13,7 +14,8 @@ import { dateFormatter } from '../utils';
export default class JobTable {
constructor() {
this.ctrl = new DatalistController('joboffers', {}, config.tableKeys);
this.handler = new ResourceHandler('joboffers', config.tableKeys);
this.ctrl = new DatalistController((query, search) => this.handler.get({ search, ...query }));
}
getItemData(data) {
......
import m from 'mithril';
//import * as mdc from 'material-components-web';
//import "@material/drawer";
import {
List,
ListTile,
......@@ -66,7 +64,7 @@ const layoutStyle = [
width: '100%',
height: '100%',
background: '#000000aa',
'z-index': 100000000
'z-index': 100000000,
},
},
];
......
......@@ -6,7 +6,7 @@ import EditView from '../views/editView';
export default class UserEdit extends EditView {
view() {
return this.layout([
...this.renderPage({
...this.form.renderPage({
lastname: { type: 'text', label: 'Last Name' },
firstname: { type: 'text', label: 'First Name' },
email: { type: 'text', label: 'Email' },
......@@ -19,41 +19,41 @@ export default class UserEdit extends EditView {
{
value: 'none',
label: 'No Member',
defaultChecked: this.data.membership === 'none',
defaultChecked: this.form.data.membership === 'none',
},
{
value: 'regular',
label: 'Regular AMIV Member',
defaultChecked: this.data.membership === 'regular',
defaultChecked: this.form.data.membership === 'regular',
},
{
value: 'extraordinary',
label: 'Extraordinary Member',
defaultChecked: this.data.membership === 'extraordinary',
defaultChecked: this.form.data.membership === 'extraordinary',
},
{
value: 'honorary',
label: 'Honorary Member',
defaultChecked: this.data.membership === 'honorary',
defaultChecked: this.form.data.membership === 'honorary',
},
],
onChange: ({ value }) => { this.data.membership = value; },
onChange: ({ value }) => { this.form.data.membership = value; },
}),
m(RadioGroup, {
name: 'Sex',
buttons: [
{ value: 'female', label: 'Female', defaultChecked: this.data.gender === 'female' },
{ value: 'male', label: 'Male', defaultChecked: this.data.gender === 'male' },
{ value: 'male', label: 'Male', defaultChecked: this.form.data.gender === 'male' },
],
onChange: ({ value }) => { console.log(value); this.data.gender = value; },
onChange: ({ value }) => { console.log(value); this.form.data.gender = value; },
}),
m(RadioGroup, {
name: 'Departement',
buttons: [
{ value: 'itet', label: 'ITET', defaultChecked: this.data.department === 'itet' },
{ value: 'mavt', label: 'MAVT', defaultChecked: this.data.department === 'mavt' },
{ value: 'itet', label: 'ITET', defaultChecked: this.form.data.department === 'itet' },
{ value: 'mavt', label: 'MAVT', defaultChecked: this.form.data.department === 'mavt' },
],
onChange: ({ value }) => { this.data.department = value; },
onChange: ({ value }) => { this.form.data.department = value; },
}),
]);
}
......
import m from 'mithril';
import { DatalistController } from 'amiv-web-ui-components';
import EditUser from './editUser';
import ViewUser from './viewUser';
import TableView from '../views/tableView';
import { users as config } from '../resourceConfig.json';
import DatalistController from '../listcontroller';
import ItemController from '../itemcontroller';
import { loadingScreen } from '../layout';
import { ResourceHandler } from '../auth';
export class UserItem {
constructor() {
......@@ -21,7 +22,11 @@ export class UserItem {
export class UserTable {
constructor() {
this.ctrl = new DatalistController('users', { sort: [['lastname', 1]] });
this.handler = new ResourceHandler('users');
this.ctrl = new DatalistController(
(query, search) => this.handler.get({ search, ...query }),
{ sort: [['lastname', 1]] },
);
}
view() {
return m(TableView, {
......
import m from 'mithril';
import { Card, Toolbar, ToolbarTitle, Button } from 'polythene-mithril';
import { ListSelect, DatalistController } from 'amiv-web-ui-components';
import ItemView from '../views/itemView';
import TableView from '../views/tableView';
import SelectList from '../views/selectList';
import DatalistController from '../listcontroller';
import RelationlistController from '../relationlistcontroller';
import { ResourceHandler } from '../auth';
import { chip, icons, Property } from '../views/elements';