Skip to content

Commit

Permalink
✨ organization memberships are now displayed
Browse files Browse the repository at this point in the history
  • Loading branch information
MattMoony committed May 9, 2024
1 parent d70f3e2 commit 151afcf
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 41 deletions.
12 changes: 12 additions & 0 deletions core/src/controllers/organization.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Request, Response } from 'express';

import Organization from '../models/Organization';
import Membership from '../models/Membership';

/**
* Parses the organization ID from the request parameters to
Expand Down Expand Up @@ -85,3 +86,14 @@ export const remove = async (req: Request, res: Response): Promise<void> => {
await organization.remove();
res.send({ 'success': true, });
}

/**
* Gets the members of an organization.
* @param req The request object.
* @param res The response object (with `res.locals.organization`).
*/
export const getMembers = async (req: Request, res: Response): Promise<void> => {
const organization = res.locals.organization as Organization;
const members = await Membership.get(organization);
res.send({ 'success': true, 'members': members.map(member => ({ ...member.json(), organization: undefined, })), });
}
7 changes: 6 additions & 1 deletion core/src/models/Membership.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import OrganSource from './OrganSource';
import Role from './Role';
import Organization from './Organization';
import MembershipSource from './MembershipSource';
import Person from './Person';

/**
* Represents a membership in an organization.
Expand Down Expand Up @@ -177,7 +178,11 @@ class Membership {
client.release();
const memberships = [];
for (const row of res.rows) {
const organ = await Organ.get(row.organ);
let organ: Person|Organization|null = await Person.get(row.organ);
if (!organ)
organ = await Organization.get(row.organ);
if (!organ)
continue;
const role = await Role.get(row.role);
if (!organ || !role) continue;
memberships.push(new Membership(organ, v, role, row.since, row.until));
Expand Down
2 changes: 2 additions & 0 deletions core/src/routes/organization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@ router.get('/:oid', controller.parseOid, controller.get);
router.patch('/:oid', controller.parseOid, controller.update);
router.delete('/:oid', controller.parseOid, controller.remove);

router.get('/:oid/members', controller.parseOid, controller.getMembers);

export default router;
85 changes: 47 additions & 38 deletions glass-pane.postman_collection.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,13 @@
"method": "GET",
"header": [],
"url": {
"raw": "{{baseURL}}/organ/{{new_organ}}/memberships",
"raw": "{{baseURL}}/organ/{{new_person}}/memberships",
"host": [
"{{baseURL}}"
],
"path": [
"organ",
"{{new_organ}}",
"{{new_person}}",
"memberships"
]
}
Expand Down Expand Up @@ -120,13 +120,13 @@
}
},
"url": {
"raw": "{{baseURL}}/organ/{{new_organ}}/memberships",
"raw": "{{baseURL}}/organ/{{new_person}}/memberships",
"host": [
"{{baseURL}}"
],
"path": [
"organ",
"{{new_organ}}",
"{{new_person}}",
"memberships"
]
}
Expand All @@ -148,13 +148,13 @@
}
},
"url": {
"raw": "{{baseURL}}/organ/{{new_organ}}/memberships",
"raw": "{{baseURL}}/organ/{{new_person}}/memberships",
"host": [
"{{baseURL}}"
],
"path": [
"organ",
"{{new_organ}}",
"{{new_person}}",
"memberships"
]
}
Expand All @@ -176,13 +176,13 @@
}
},
"url": {
"raw": "{{baseURL}}/organ/{{new_organ}}/memberships",
"raw": "{{baseURL}}/organ/{{new_person}}/memberships",
"host": [
"{{baseURL}}"
],
"path": [
"organ",
"{{new_organ}}",
"{{new_person}}",
"memberships"
]
}
Expand Down Expand Up @@ -269,16 +269,13 @@
}
},
"url": {
"raw": "http://localhost:8888/api/organ//sources",
"protocol": "http",
"raw": "{{baseURL}}/organ/{{new_organ}}/sources",
"host": [
"localhost"
"{{baseURL}}"
],
"port": "8888",
"path": [
"api",
"organ",
"",
"{{new_organ}}",
"sources"
]
}
Expand Down Expand Up @@ -413,14 +410,11 @@
"method": "POST",
"header": [],
"url": {
"raw": "http://localhost:8888/api/organ/new",
"protocol": "http",
"raw": "{{baseURL}}/organ/new",
"host": [
"localhost"
"{{baseURL}}"
],
"port": "8888",
"path": [
"api",
"organ",
"new"
]
Expand Down Expand Up @@ -514,16 +508,13 @@
"method": "GET",
"header": [],
"url": {
"raw": "http://localhost:8888/api/organ/364",
"protocol": "http",
"raw": "{{baseURL}}/organ/{{$randomInt}}",
"host": [
"localhost"
"{{baseURL}}"
],
"port": "8888",
"path": [
"api",
"organ",
"364"
"{{$randomInt}}"
]
}
},
Expand Down Expand Up @@ -756,7 +747,7 @@
"header": [],
"body": {
"mode": "raw",
"raw": "{\r\n \"to\": {{relative}},\r\n \"since\": \"{{relation_since}}\",\r\n \"url\": \"new source here\"\r\n}",
"raw": "{\r\n \"other\": {{relative}},\r\n \"since\": \"{{relation_since}}\",\r\n \"url\": \"new source here\"\r\n}",
"options": {
"raw": {
"language": "json"
Expand Down Expand Up @@ -1048,14 +1039,11 @@
}
},
"url": {
"raw": "http://localhost:8888/api/person/new",
"protocol": "http",
"raw": "{{baseURL}}/person/new",
"host": [
"localhost"
"{{baseURL}}"
],
"port": "8888",
"path": [
"api",
"person",
"new"
]
Expand Down Expand Up @@ -1104,7 +1092,7 @@
]
},
{
"name": "search persons",
"name": "search people",
"request": {
"method": "GET",
"header": [],
Expand Down Expand Up @@ -1149,16 +1137,13 @@
"method": "GET",
"header": [],
"url": {
"raw": "http://localhost:8888/api/person/",
"protocol": "http",
"raw": "{{baseURL}}/person/{{new_person}}",
"host": [
"localhost"
"{{baseURL}}"
],
"port": "8888",
"path": [
"api",
"person",
""
"{{new_person}}"
]
}
},
Expand Down Expand Up @@ -1377,6 +1362,30 @@
{
"name": "organizations",
"item": [
{
"name": "members",
"item": [
{
"name": "get members",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseURL}}/organization/{{new_organization}}/members",
"host": [
"{{baseURL}}"
],
"path": [
"organization",
"{{new_organization}}",
"members"
]
}
},
"response": []
}
]
},
{
"name": "create organization",
"event": [
Expand Down
19 changes: 19 additions & 0 deletions web/src/api/organ.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,25 @@ export interface OrganMembership {
until?: Date;
}

export interface OrganizationMember {
/**
* The organ that is a member of the organization.
*/
organ: Organ;
/**
* The role that the person has in the organization.
*/
role: Role;
/**
* The date that the person became a member of the organization.
*/
since: Date;
/**
* The date that the person stopped being a member of the organization.
*/
until?: Date;
}

/**
* Represents a membership of an organ in an organization.
* A membership is identified by its `organ`, `organization`,
Expand Down
25 changes: 24 additions & 1 deletion web/src/api/organization.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { API, jreq } from './index';
import type { APIResponse } from './index';
import type { Organ } from './organ';
import type { Organ, OrganizationMember } from './organ';
import type { Person } from './person';

/**
* Represents an organization.
Expand Down Expand Up @@ -38,6 +39,13 @@ export interface OrganizationsResponse extends APIResponse {
organizations: Organization[];
}

/**
* Represents a response from the API for the members of an organization.
*/
export interface OrganizationMembersResponse extends APIResponse {
members: OrganizationMember[];
}

/**
* Creates a new organization.
* @param name The name of the organization.
Expand Down Expand Up @@ -118,3 +126,18 @@ export const update = async (
export const remove = async (oid: number): Promise<APIResponse> => {
return await jreq(`${API}/organization/${oid}`, { method: 'DELETE' }) as APIResponse;
};

export const members = async (oid: number): Promise<OrganizationMembersResponse> => {
const res = await jreq(`${API}/organization/${oid}/members`) as OrganizationMembersResponse;
res.members.forEach(m => {
const person = m.organ as Person;
if (person.birthdate !== undefined) person.birthdate = new Date(person.birthdate);
if (person.deathdate !== undefined) person.deathdate = new Date(person.deathdate);
const organization = m.organ as Organization;
if (organization.established !== undefined) organization.established = new Date(organization.established);
if (organization.dissolved !== undefined) organization.dissolved = new Date(organization.dissolved);
m.since = new Date(m.since);
m.until = m.until ? new Date(m.until) : undefined;
});
return res;
};
1 change: 1 addition & 0 deletions web/src/components/OrganizationNetwork.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const refreshNetwork = async () => {
if (!props.organization) return;
memberships.value = await Membership.get(new Organ(props.organization.id, props.organization.bio));
members.value = await Membership.get(props.organization);
console.log(members.value);
};
watch(() => props.organization, refreshNetwork, { immediate: true });
Expand Down
32 changes: 31 additions & 1 deletion web/src/models/Membership.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import * as organ from '@/api/organ';
import * as organization from '@/api/organization';
import * as person from '@/api/person';
import Organ from './Organ';
import Organization from './Organization';
import Person from './Person';
import Role from './Role';

/**
Expand Down Expand Up @@ -82,7 +85,34 @@ class Membership {
*/
public static async get (organ: Organ, organization: Organization, role: Role, since: Date): Promise<Membership[]>;
public static async get (v: Organ|Organization, v2?: Organization, v3?: Role, v4?: Date): Promise<Membership[]> {
if (v instanceof Organization) return [];
if (v instanceof Organization) {
const res = await organization.members(v.id);
return res.members.map((m: any) => new Membership(
(m.organ as person.Person).firstname !== undefined
? new Person(
m.organ.id,
m.organ.bio,
m.organ.firstname,
m.organ.lastname,
m.organ.birthdate,
m.organ.deathdate
)
: new Organization(
m.organ.id,
m.organ.bio,
m.organ.name,
m.organ.established,
m.organ.dissolved
),
v,
new Role(
m.role.id,
m.role.name
),
new Date(m.since),
m.until ? new Date(m.until) : undefined
));
}
else if (v instanceof Organ) {
const res = await organ.memberships(v.id);
return res.memberships.map((m: any) => new Membership(
Expand Down

0 comments on commit 151afcf

Please sign in to comment.