Skip to content

Commit

Permalink
Updated people assignment document structure and fixed the bug
Browse files Browse the repository at this point in the history
  • Loading branch information
alneberg committed Jan 17, 2025
1 parent 3a418f1 commit 274a94c
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 50 deletions.
6 changes: 4 additions & 2 deletions run_dir/static/js/projects_components.js
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,9 @@ export const vProjectPeopleAssignments = {
},
methods: {
initials(identifier) {
if (this.$root.all_users[identifier] == undefined) {
return identifier
}
if (this.$root.all_users[identifier]['initials'] != '') {
return this.$root.all_users[identifier]['initials']
} else {
Expand All @@ -645,7 +648,6 @@ export const vProjectPeopleAssignments = {
}
},
remove_from_project(person_id) {
console.log('Removing person from project')
this.$root.removePersonFromProject(this.project_id, person_id)
},
add_to_project(person_id) {
Expand Down Expand Up @@ -687,7 +689,7 @@ export const vProjectPeopleAssignments = {
<template v-if="people_menu_open">
<h3>
<template v-for="person_id in people">
<span class="badge rounded-pill bg-success mr-1" @click="togglePeopleMenu">
<span class="badge rounded-pill bg-success mr-1">
{{ name(person_id) }}
<button type="button" class="btn btn-lg m-0" @click="remove_from_project(person_id)"><i class="fa-regular fa-trash-can text-white"></i></button>
</span>
Expand Down
5 changes: 3 additions & 2 deletions run_dir/static/js/projects_main_vue.js
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ const vProjectsStatus = {
.then(response => {
let data = response.data
if (data !== null) {

this.project_people_assignments = Object.assign({}, this.project_people_assignments, data);
}
})
Expand All @@ -301,7 +302,7 @@ const vProjectsStatus = {
.then(response => {
let data = response.data
if ((data !== null) && (data[project_id] !== null)) {
this.project_people_assignments[project_id] = data['people'];
this.project_people_assignments[project_id] = data[project_id];
}
})
.catch(error => {
Expand All @@ -316,7 +317,7 @@ const vProjectsStatus = {
.then(response => {
let data = response.data
if ((data !== null) && (data[project_id] !== null)) {
this.project_people_assignments[project_id] = data['people'];
this.project_people_assignments[project_id] = data[project_id];
}
})
.catch(error => {
Expand Down
181 changes: 135 additions & 46 deletions status/people_assignments.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,118 @@
import datetime

import tornado
from ibm_cloud_sdk_core.api_exception import ApiException

from status.util import SafeHandler


class PeopleAssignmentFormatHelper:
"""Document structure is as follows:
{
"_id": "entity_id",
"people": {
"person_id": [
{
"tags": {
#TBD
},
"added_timestamp_utc": "ISO8601",
"removed_timestamp_utc": "ISO8601",
"removed": true/false
},
{
"tags": {
#TBD
},
"added_timestamp_utc": "ISO8601",
"removed_timestamp_utc": "ISO8601",
"removed": true/false
}
]
}
}
Only the last entry in the list is the current assignment, so all others should have "removed": true.
"""

def __init__(self, entity_id, cloudant, current_user):
self.entity_id = entity_id
self.doc = None
self.cloudant = cloudant
self.current_user = current_user

def get_current_assignment(self):
try:
self.doc = self.cloudant.get_document(
db="people_assignments", doc_id=self.entity_id
).get_result()
except ApiException as e:
if e.status_code == 404:
self.doc = {
"_id": self.entity_id,
"people": {},
}
if "people" not in self.doc:
# This should not happen, but just in case
self.doc["people"] = {}

def check_is_assigned(self, person_id) -> bool:
if person_id not in self.doc["people"]:
return False
else:
# A person is assigned if they have been assigned and not removed
return (
self.doc["people"][person_id] != []
and not self.doc["people"][person_id][-1]["removed"]
)

def assign_person(self, person_id):
if self.check_is_assigned(person_id):
# Already assigned, do nothing
return

if person_id not in self.doc["people"]:
self.doc["people"][person_id] = []

entry = {
"tags": {},
"added_timestamp_utc": datetime.datetime.now().isoformat(),
"added_by": self.current_user.email,
"removed_by": None,
"removed_timestamp_utc": None,
"removed": False,
}
self.doc["people"][person_id].append(entry)
self.save()

def unassign_person(self, person_id):
if not self.check_is_assigned(person_id):
# Not assigned, do nothing
return

self.doc["people"][person_id][-1]["removed_timestamp_utc"] = (
datetime.datetime.now().isoformat()
)
self.doc["people"][person_id][-1]["removed_by"] = self.current_user.email
self.doc["people"][person_id][-1]["removed"] = True
self.save()

def save(self):
self.cloudant.put_document(
db="people_assignments", doc_id=self.entity_id, document=self.doc
)

def current_assignments(self):
"""Made to mimic the view results for the list of all people assignments"""
assigned_people = [
person for person in self.doc["people"] if self.check_is_assigned(person)
]
return_dict = {}
return_dict[self.doc["_id"]] = assigned_people

return return_dict


class PeopleAssignmentsDataHandler(SafeHandler):
"""Serves the people assignments for multiple projects.
Expand All @@ -17,19 +127,19 @@ def post(self):

project_ids = data["project_ids"]

people_assignments_rows = self.application.cloudant.post_bulk_get(
db="people_assignments", docs=[{"id": doc_id} for doc_id in project_ids]
people_assignments_view_result = self.application.cloudant.post_view(
db="people_assignments",
ddoc="current",
view="assignments",
keys=project_ids,
).get_result()

people_assignments = {}
for data in people_assignments_rows["results"]:
for data_row in data["docs"]:
# Filter out the "not found" documents
if "ok" in data_row:
people_assignments[data_row["ok"]["_id"]] = data_row["ok"]["people"]
result_dict = {}
for row in people_assignments_view_result.get("rows", []):
result_dict[row["id"]] = row["value"]

self.set_header("Content-type", "application/json")
self.write(people_assignments)
self.write(result_dict)


class ProjectPeopleAssignmentDataHandler(SafeHandler):
Expand All @@ -41,26 +151,16 @@ def put(self, project_id, person_id):
self.set_status(400)
return self.write("Error: no person_id supplied")

people_assignments = self.application.cloudant.get_document(
db="people_assignments", doc_id=project_id
).get_result()

# TODO Handle the case if the document doesn't exist here

if "people" not in people_assignments:
people_assignments["people"] = []

if person_id in people_assignments["people"]:
# Should be nice enough to tolerate double assignments
pass
else:
people_assignments["people"].append(person_id)
self.application.cloudant.put_document(
db="people_assignments", doc_id=project_id, document=people_assignments
)
people_assignment = PeopleAssignmentFormatHelper(
project_id,
cloudant=self.application.cloudant,
current_user=self.get_current_user(),
)
people_assignment.get_current_assignment()
people_assignment.assign_person(person_id)

self.set_header("Content-type", "application/json")
self.write(people_assignments)
self.write(people_assignment.current_assignments())

def delete(self, project_id, person_id):
if not project_id:
Expand All @@ -70,24 +170,13 @@ def delete(self, project_id, person_id):
self.set_status(400)
return self.write("Error: no person_id supplied")

people_assignments = self.application.cloudant.get_document(
db="people_assignments", doc_id=project_id
).get_result()

# TODO handle the case if the document doesn't exist here

if "people" not in people_assignments:
people_assignments["people"] = []
elif person_id not in people_assignments["people"]:
# Should be nice enough to tolerate double assignments
pass
else:
people_assignments["people"].remove(person_id)
self.application.cloudant.put_document(
db="people_assignments",
doc_id=project_id,
document=people_assignments,
)
people_assignment = PeopleAssignmentFormatHelper(
project_id,
cloudant=self.application.cloudant,
current_user=self.get_current_user(),
)
people_assignment.get_current_assignment()
people_assignment.unassign_person(person_id)

self.set_header("Content-type", "application/json")
self.write(people_assignments)
self.write(people_assignment.current_assignments())

0 comments on commit 274a94c

Please sign in to comment.