Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update event triggers for moped personnel and personnel roles #964

Merged
merged 14 commits into from Feb 2, 2023
Merged
93 changes: 80 additions & 13 deletions moped-database/metadata/tables.yaml
Expand Up @@ -3065,24 +3065,45 @@
insert:
columns: '*'
update:
columns:
- is_deleted
- notes
- project_id
- project_personnel_id
- date_added
- added_by
- user_id
columns: '*'
retry_conf:
interval_sec: 10
num_retries: 0
timeout_sec: 60
webhook_from_env: MOPED_API_EVENTS_URL
webhook_from_env: HASURA_ENDPOINT
headers:
- name: MOPED_API_APIKEY
value_from_env: MOPED_API_APIKEY
- name: MOPED_API_EVENT_NAME
value: activity_log
- name: x-hasura-admin-secret
value_from_env: ACTIVITY_LOG_API_SECRET
request_transform:
body:
action: transform
template: |-
{
"query": "mutation InsertActivity($object: moped_activity_log_insert_input!, $project_id:Int!, $updated_at:timestamptz ) { insert_moped_activity_log_one(object: $object) { activity_id } update_moped_project_by_pk(pk_columns: {project_id: $project_id}, _set: {updated_at: $updated_at}) { updated_at }}",
"variables": {
"object": {
"record_id": {{ $body.event.data.new.project_personnel_id }},
"record_type": {{ $body.table.name }},
"activity_id": {{ $body.id }},
"record_project_id": {{ $body.event.data.new.project_id }},
"record_data": { "event": {{ $body.event }}},
"description": [{"newSchema": "true"}],
"operation_type": {{ $body.event.op }},
"updated_by_user_id": {{ $session_variables?['x-hasura-user-db-id'] ?? 1}}
},
"updated_at": {{$body.created_at}},
"project_id": {{$body.event.data.new.project_id}}
}
}
template_engine: Kriti
version: 2
cleanup_config:
batch_size: 10000
clean_invocation_logs: false
clear_older_than: 168
paused: true
schedule: 0 0 * * *
timeout: 60
- table:
name: moped_proj_personnel_roles
schema: public
Expand Down Expand Up @@ -3150,6 +3171,52 @@
- project_role_id
filter: {}
check: null
event_triggers:
- name: activity_log_moped_proj_personnel_roles
definition:
delete:
columns: '*'
enable_manual: false
insert:
columns: '*'
update:
columns: '*'
retry_conf:
interval_sec: 10
num_retries: 0
timeout_sec: 60
webhook_from_env: HASURA_ENDPOINT
headers:
- name: x-hasura-admin-secret
value_from_env: ACTIVITY_LOG_API_SECRET
request_transform:
body:
action: transform
template: |-
{
"query": "mutation InsertActivity($object: moped_activity_log_insert_input!) { insert_moped_activity_log_one(object: $object) { activity_id } }",
"variables": {
"object": {
"record_id": {{ $body.event.data.new.project_personnel_id }},
"record_type": {{ $body.table.name }},
"activity_id": {{ $body.id }},
"record_data": { "event": {{ $body.event }}},
"record_project_id": null,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moped_proj_personnel_roles does not have a column for the project_id, so this is null. This also means that while we are tracking these activities, they will not show up in our activity log query since we query on project_id

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is great—thanks for getting the tracking in place.

i also want to point out that, because we don't have the project ID here, we cannot update the project's modified date through this mutation. that's frustrating because i think user's should be able to expect that any project edit will update the project's modified date. if we wanted to get clever, we could mutate the moped_proj_personnel record from here, which would then fire off another event which would mutate the parent project's modified date. that would require us adding some mutable field on moped_proj_personnel like an updated_at timestamp.

just throwing it out there—i don't necessarily think this is a good idea. i believe we're also going to encounter this problem when we set up tracking for project features.

"description": [{"newSchema": "true"}],
"operation_type": {{ $body.event.op }},
"updated_by_user_id": {{ $session_variables?['x-hasura-user-db-id'] ?? 1}}
}
}
}
template_engine: Kriti
version: 2
cleanup_config:
batch_size: 10000
clean_invocation_logs: false
clear_older_than: 168
paused: true
schedule: 0 0 * * *
timeout: 60
- table:
name: moped_proj_phases
schema: public
Expand Down
@@ -0,0 +1,52 @@
import PeopleOutlineIcon from "@material-ui/icons/PeopleOutline";

export const formatPersonnelActivity = (change, userList) => {
let changeIcon = <PeopleOutlineIcon />;

const changeData = change.record_data.event.data;

// Adding a new person to project team
if (change.description.length === 0) {
return {
changeIcon,
changeText: [
{ text: "Added ", style: null },
{ text: userList[changeData.new.user_id], style: "boldText" },
{ text: " to the team", style: null },
],
};
}

if (change.description[0].field === "user_id") {
return {
changeIcon,
changeText: [
{ text: "Replaced team member " },
{ text: userList[changeData.old.user_id], style: "boldText" },
{ text: " with ", style: null },
{ text: userList[changeData.new.user_id], style: "boldText" },
],
};
}

// remove a person from the team
if (change.description[0].field === "is_deleted") {
return {
changeIcon,
changeText: [
{ text: "Removed ", style: null },
{ text: userList[changeData.old.user_id], style: "boldText" },
{ text: " from the team", style: null },
],
};
}

// currently 'notes' is the only other editable field on this table
return {
changeIcon,
changeText: [
{ text: "Updated team member notes for " },
{ text: userList[changeData.new.user_id], style: "boldText" },
],
};
};
Expand Up @@ -95,7 +95,6 @@ export const formatProjectActivity = (change, lookupList) => {
],
};
}
console.log(changeData.new[changedField])
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😬


// the update can be rendered as a string
const changeValue =
Expand Down
3 changes: 3 additions & 0 deletions moped-editor/src/utils/activityLogHelpers.js
Expand Up @@ -4,6 +4,7 @@ import { formatFundingActivity } from "./activityLogFormatters/mopedFundingActiv
import { formatPhasesActivity } from "./activityLogFormatters/mopedPhasesActivity";
import { formatMilestonesActivity } from "./activityLogFormatters/mopedMilestonesActivity";
import { formatPartnersActivity } from "./activityLogFormatters/mopedPartnersActivity";
import { formatPersonnelActivity } from "./activityLogFormatters/mopedPersonnelActivity";
import { formatNotesActivity } from "./activityLogFormatters/mopedNotesActivity";
import { formatComponentsActivity } from "./activityLogFormatters/mopedComponentsActivity";
import { formatProjectTypesActivity } from "./activityLogFormatters/mopedProjectTypesActivity";
Expand Down Expand Up @@ -46,6 +47,8 @@ export const formatActivityLogEntry = (change, lookupData) => {
return formatMilestonesActivity(change, lookupData.milestoneList);
case "moped_proj_partners":
return formatPartnersActivity(change, lookupData.entityList);
case "moped_proj_personnel":
return formatPersonnelActivity(change, lookupData.userList);
case "moped_proj_notes":
return formatNotesActivity(change);
case "moped_proj_components":
Expand Down
Expand Up @@ -11,7 +11,7 @@ const useStyles = makeStyles((theme) => ({
indentText: {
paddingLeft: "16px",
display: "block",
}
},
}));

/**
Expand All @@ -26,7 +26,11 @@ const ProjectActivityEntry = ({ changeIcon, changeText }) => {
<Box display="flex" p={0}>
<Box p={0}>{changeIcon}</Box>
<Box p={0} flexGrow={1}>
<Typography variant="body2" className={classes.entryText}>
<Typography
variant="body2"
className={classes.entryText}
component="span"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this fixes an invalid DOM nesting error

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you!!!

>
{
// maps through the array of objects and applies specified style to the text
changeText.map((changeObject, index) => (
Expand Down
Expand Up @@ -321,6 +321,7 @@ const ProjectActivityLog = () => {
"moped_proj_notes",
"moped_proj_components",
"moped_project_types",
"moped_proj_personnel"
].includes(change.record_type) ? (
<ProjectActivityEntry
changeIcon={changeIcon}
Expand Down
Expand Up @@ -261,58 +261,28 @@ export const ProjectActivityLogTableMaps = {
label: "Team",
fields: {
added_by: {
icon: "",
label: "added by",
type: "int4",
},
date_added: {
icon: "",
label: "date added",
type: "timestamptz",
},
project_personnel_id: {
icon: "",
label: "ID",
type: "int4",
},
notes: {
icon: "",
label: "notes",
type: "text",
},
is_deleted: {
icon: "",
label: "is deleted",
type: "boolean",
map: {
true: "Inactive",
false: "Active",
},
},
project_id: {
icon: "",
label: "project ID",
type: "int4",
},
role_id: {
icon: "",
label: "role",
type: "int4",
lookup: {
table: "moped_project_roles",
fieldLabel: "project_role_id",
fieldValues: ["project_role_name"],
},
},
user_id: {
icon: "",
label: "user",
type: "int4",
lookup: {
table: "moped_users",
fieldLabel: "user_id",
fieldValues: ["first_name", "last_name"],
},
},
},
},
Expand Down Expand Up @@ -565,20 +535,6 @@ export const ProjectActivityLogTableMaps = {
};

export const ProjectActivityLogOperationMaps = {
moped_proj_personnel: {
DELETE: {
label: "Removed",
icon: "close",
},
INSERT: {
label: "Added",
icon: "personadd",
},
UPDATE: {
label: "Updated",
icon: "create",
},
},
moped_project_files: {
DELETE: {
label: "Deleted",
Expand Down Expand Up @@ -616,10 +572,6 @@ export const ProjectActivityLogGenericDescriptions = {
};

export const ProjectActivityLogCreateDescriptions = {
moped_proj_personnel: {
label: (record, userList) =>
userList[`${record.record_data.event.data.new.user_id}`] + " to the team",
},
moped_project_files: {
label: (record) =>
`New file '${record.record_data.event.data.new.file_name}'`,
Expand Down
Expand Up @@ -114,7 +114,7 @@ const ProjectSummaryProjectDescription = ({
)}
{!editMode && (
<ProjectSummaryLabel
text={description || " - "}
text={description.trim().length > 0 ? description : " - "}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to fix a bug I found where if you save empty spaces as a project description, you can't edit the description again (ex: https://moped.austinmobility.io/moped/projects/1790) Boolean(" ") is true.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you for fixing this!

we have a snackoo to prevent users from saving an empty description in the first place. we require description on project create but not project edit.

classes={classes}
onClickEdit={() => setEditMode(true)}
/>
Expand Down