From 67aa15e006580c1de98c6ecc10c4a33d915a72b9 Mon Sep 17 00:00:00 2001 From: Katalina Okano Date: Sat, 13 Mar 2021 04:03:42 -0500 Subject: [PATCH] feat(web): add picker saves --- packages/web/src/pages/picker.tsx | 31 +++++++++++++++++-- .../web/src/utils/roleTransactions.spec.ts | 0 packages/web/src/utils/roleTransactions.ts | 30 ++++++++++++++++++ 3 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 packages/web/src/utils/roleTransactions.spec.ts create mode 100644 packages/web/src/utils/roleTransactions.ts diff --git a/packages/web/src/pages/picker.tsx b/packages/web/src/pages/picker.tsx index 2f23666..2d51c59 100644 --- a/packages/web/src/pages/picker.tsx +++ b/packages/web/src/pages/picker.tsx @@ -1,7 +1,8 @@ import { RolePickerTemplate } from '@roleypoly/design-system/templates/role-picker'; -import { PresentableGuild, UserGuildPermissions } from '@roleypoly/types'; +import { PresentableGuild, RoleUpdate, UserGuildPermissions } from '@roleypoly/types'; import * as React from 'react'; import { useSessionContext } from '../session-context/SessionContext'; +import { makeRoleTransactions } from '../utils/roleTransactions'; type PickerProps = { serverID: string; @@ -11,6 +12,7 @@ const Picker = (props: PickerProps) => { const { session, authedFetch } = useSessionContext(); const [pickerData, setPickerData] = React.useState(null); + const [pending, setPending] = React.useState(false); React.useEffect(() => { const fetchPickerData = async () => { @@ -27,6 +29,31 @@ const Picker = (props: PickerProps) => { return
Loading...
; } + const onSubmit = async (submittedRoles: string[]) => { + if (pending === true) { + return; + } + + setPending(true); + const updatePayload: RoleUpdate = { + knownState: pickerData.member.roles, + transactions: makeRoleTransactions(pickerData.member.roles, submittedRoles), + }; + + const response = await authedFetch(`/update-roles/${props.serverID}`, { + method: 'PATCH', + body: JSON.stringify(updatePayload), + }); + if (response.status === 200) { + setPickerData({ + ...pickerData, + member: { ...pickerData.member, roles: (await response.json()).roles }, + }); + } + + setPending(false); + }; + return ( { guildData={pickerData.data} member={pickerData.member} roles={pickerData.roles} - onSubmit={(args) => console.log('onSubmit', ...args)} editable={pickerData.guild.permissionLevel > UserGuildPermissions.User} + onSubmit={onSubmit} /> ); }; diff --git a/packages/web/src/utils/roleTransactions.spec.ts b/packages/web/src/utils/roleTransactions.spec.ts new file mode 100644 index 0000000..e69de29 diff --git a/packages/web/src/utils/roleTransactions.ts b/packages/web/src/utils/roleTransactions.ts new file mode 100644 index 0000000..174b181 --- /dev/null +++ b/packages/web/src/utils/roleTransactions.ts @@ -0,0 +1,30 @@ +import { Role, RoleTransaction, TransactionType } from '@roleypoly/types'; + +export const makeRoleTransactions = ( + oldRoles: Role['id'][], + newRoles: Role['id'][] +): RoleTransaction[] => { + const transactions: RoleTransaction[] = []; + + // Removes: old roles not in new roles + for (let oldID of oldRoles) { + if (!newRoles.includes(oldID)) { + transactions.push({ + id: oldID, + action: TransactionType.Remove, + }); + } + } + + // Adds: new roles not in old roles + for (let newID of newRoles) { + if (!oldRoles.includes(newID)) { + transactions.push({ + id: newID, + action: TransactionType.Add, + }); + } + } + + return transactions; +};