diff --git a/src/models/groups.js b/src/models/groups.js new file mode 100644 index 0000000000000000000000000000000000000000..b33be04aa5cc589d28ad8f2df5da8dd1575a3d21 --- /dev/null +++ b/src/models/groups.js @@ -0,0 +1,97 @@ +import { apiUrl } from './config'; +import { getToken, getUserId } from './auth'; +import { error } from './log'; + +const m = require('mithril'); + +let querySaved = ''; + +export function getList() { + if (this.groups === undefined) { + return []; + } + return this.groups; +} + +export function getMemberships() { + if (this.memberships === undefined) { + return []; + } + return this.memberships; +} + +export function enroll(groupId) { + return m.request({ + method: 'POST', + url: `${apiUrl}/groupmemberships`, + headers: getToken() ? { + Authorization: `Token ${getToken()}`, + } : {}, + data: { group: groupId, user: getUserId() }, + }).then((result) => { + const membership = result; + const group = this.groups.find(item => item._id === membership.group); + if (group === undefined) { + membership.group = membership.group; + } else { + membership.group = group; + } + this.memberships.push(membership); + }).catch((e) => { + error(e.message); + }); +} + +export function withdraw(groupMembershipId, etag) { + return m.request({ + method: 'DELETE', + url: `${apiUrl}/groupmemberships/${groupMembershipId}`, + headers: getToken() ? { + Authorization: `Token ${getToken()}`, + 'If-Match': etag, + } : { 'If-Match': etag }, + }).then(() => { + this.memberships = this.memberships.filter(item => item._id !== groupMembershipId); + }).catch((e) => { + error(e.message); + }); +} + +export function load(query = {}) { + const queryEncoded = m.buildQueryString({ where: JSON.stringify(query) }); + querySaved = query; + + return m.request({ + method: 'GET', + url: `${apiUrl}/groups?${queryEncoded}`, + headers: getToken() ? { + Authorization: `Token ${getToken()}`, + } : {}, + }).then((result) => { + this.groups = result._items; + }).catch((e) => { + error(e.message); + }); +} + +export function loadMemberships() { + const queryEncoded = m.buildQueryString({ + where: JSON.stringify({ user: getUserId() }), + embedded: JSON.stringify({ group: 1 }), + }); + return m.request({ + method: 'GET', + url: `${apiUrl}/groupmemberships?${queryEncoded}`, + headers: getToken() ? { + Authorization: `Token ${getToken()}`, + } : {}, + }).then((result) => { + this.memberships = result._items; + }).catch((e) => { + error(e.message); + }); +} + +export function reload() { + return load(querySaved); +} diff --git a/src/views/profile.js b/src/views/profile.js index e43e85b82dfe4c2efe494d46f7b74f69b5a40b76..6a3866c8ab70c8c8af1c56bb35ed22ab9b1e4999 100644 --- a/src/views/profile.js +++ b/src/views/profile.js @@ -1,5 +1,6 @@ import { isLoggedIn } from '../models/auth'; import * as user from '../models/user'; +import * as groups from '../models/groups'; import { log } from '../models/log'; const m = require('mithril'); @@ -94,6 +95,33 @@ class announceSubscriptionForm { } } +// shows group memberships and allows to withdraw and enroll for selected groups. +class groupMemberships { + static oninit() { + groups.load({ allow_self_enrollment: true }); + groups.loadMemberships(); + } + + static view() { + return m('div', [ + m('div', groups.getMemberships().map(membership => m('div', [ + m('span', membership.group.name), + membership.expiry === undefined ? undefined : m('span', `(expires on ${membership.expiry})`), + m('button', { onclick: () => groups.withdraw(membership._id, membership._etag) }, 'withdraw'), + ]))), + m('div', groups.getList().map((group) => { + if (groups.getMemberships().some(element => element.group._id === group._id)) { + return undefined; + } + return m('div', [ + m('span', group.name), + m('button', { onclick: () => groups.enroll(group._id) }, 'enroll'), + ]); + })), + ]); + } +} + // shows all submodules defined above export default class profile { static oninit() { @@ -108,6 +136,7 @@ export default class profile { m(showUserInfo), m(rfidForm), m(announceSubscriptionForm), + m(groupMemberships), ]); } }