From 5e9979580f4d6803d6fad3de7283ad273da87ff3 Mon Sep 17 00:00:00 2001 From: Mark Volkmann Date: Fri, 26 Apr 2024 14:39:16 -0500 Subject: [PATCH 1/4] Guild Results page now gets settings from query parameters --- .../components/guild-results/GuildResults.jsx | 83 ++++++++++++++++--- .../guild-results/GuildSummaryCard.jsx | 14 +++- .../guild-results/GuildsActions.jsx | 60 -------------- .../guild-results/GuildsActions.test.jsx | 39 --------- 4 files changed, 83 insertions(+), 113 deletions(-) delete mode 100644 web-ui/src/components/guild-results/GuildsActions.jsx delete mode 100644 web-ui/src/components/guild-results/GuildsActions.test.jsx diff --git a/web-ui/src/components/guild-results/GuildResults.jsx b/web-ui/src/components/guild-results/GuildResults.jsx index 24c55dc01d..3ffa78c320 100644 --- a/web-ui/src/components/guild-results/GuildResults.jsx +++ b/web-ui/src/components/guild-results/GuildResults.jsx @@ -1,13 +1,14 @@ -import React, { useContext, useState } from 'react'; - +import PropTypes from 'prop-types'; +import React, { useContext, useEffect, useState } from 'react'; +import GroupIcon from '@mui/icons-material/Group'; +import { Button, TextField } from '@mui/material'; import { styled } from '@mui/material/styles'; -import GuildSummaryCard from './GuildSummaryCard'; + import { AppContext } from '../../context/AppContext'; -import GuildsActions from './GuildsActions'; -import PropTypes from 'prop-types'; -import { TextField } from '@mui/material'; -import './GuildResults.css'; +import AddGuildModal from './EditGuildModal'; +import GuildSummaryCard from './GuildSummaryCard'; import SkeletonLoader from '../skeleton_loader/SkeletonLoader'; +import './GuildResults.css'; const PREFIX = 'GuildResults'; const classes = { @@ -33,10 +34,44 @@ const propTypes = { const displayName = 'GuildResults'; const GuildResults = () => { - const { state } = useContext(AppContext); - const { guilds } = state; + const { dispatch, state } = useContext(AppContext); + const { guilds, userProfile } = state; + const [addOpen, setAddOpen] = useState(false); + const [openedGuildId, setOpenedGuildId] = useState(''); const [searchText, setSearchText] = useState(''); + useEffect(() => { + const url = new URL(location.href); + + const addOpen = url.searchParams.get('addOpen') || ''; + setAddOpen(addOpen === 'true'); + + const guildId = url.searchParams.get('guild') || ''; + setOpenedGuildId(guildId); + + const search = url.searchParams.get('search') || ''; + setSearchText(search); + }, []); + + useEffect(() => { + const url = new URL(location.href); + let newUrl = url.origin + url.pathname; + const params = {}; + if (addOpen) params.addOpen = true; + if (openedGuildId) params.guild = openedGuildId; + if (searchText) params.search = searchText; + if (Object.keys(params).length) { + newUrl += '?' + new URLSearchParams(params).toString(); + } + history.replaceState(params, '', newUrl); + }, [addOpen, openedGuildId, searchText]); + + const handleOpen = () => setAddOpen(true); + + const handleClose = () => setAddOpen(false); + + const isAdmin = userProfile?.role?.includes('ADMIN'); + return (
@@ -49,7 +84,33 @@ const GuildResults = () => { setSearchText(e.target.value); }} /> - +
+ {isAdmin && ( + <> + + { + if (csrf) { + let res = await createGuild(guild, csrf); + let data = + res.payload && res.payload.data && !res.error + ? res.payload.data + : null; + if (data) { + dispatch({ type: ADD_GUILD, payload: data }); + } + handleClose(); + } + }} + headerText="Add A New Guild" + /> + + )} +
{guilds?.length @@ -59,6 +120,8 @@ const GuildResults = () => { key={`guild-summary-${guild.id}`} index={index} guild={guild} + isOpen={guild.id === openedGuildId} + onGuildSelect={setOpenedGuildId} /> ) : null ) diff --git a/web-ui/src/components/guild-results/GuildSummaryCard.jsx b/web-ui/src/components/guild-results/GuildSummaryCard.jsx index b746b863d9..c784beec42 100644 --- a/web-ui/src/components/guild-results/GuildSummaryCard.jsx +++ b/web-ui/src/components/guild-results/GuildSummaryCard.jsx @@ -57,10 +57,10 @@ const propTypes = { const displayName = 'GuildSummaryCard'; -const GuildSummaryCard = ({ guild, index }) => { +const GuildSummaryCard = ({ guild, index, isOpen, onGuildSelect }) => { const { state, dispatch } = useContext(AppContext); const { guilds, userProfile, csrf } = state; - const [open, setOpen] = useState(false); + const [open, setOpen] = useState(isOpen); const [openDelete, setOpenDelete] = useState(false); const [tooltipIsOpen, setTooltipIsOpen] = useState(false); const isAdmin = @@ -80,8 +80,14 @@ const GuildSummaryCard = ({ guild, index }) => { ? false : leads.some(lead => lead.memberId === userProfile.memberProfile.id); - const handleOpen = () => setOpen(true); - const handleClose = () => setOpen(false); + const handleOpen = () => { + setOpen(true); + onGuildSelect(guild.id); + }; + const handleClose = () => { + setOpen(false); + onGuildSelect(''); + }; const handleOpenDeleteConfirmation = () => setOpenDelete(true); const handleCloseDeleteConfirmation = () => setOpenDelete(false); diff --git a/web-ui/src/components/guild-results/GuildsActions.jsx b/web-ui/src/components/guild-results/GuildsActions.jsx deleted file mode 100644 index 9b85031f99..0000000000 --- a/web-ui/src/components/guild-results/GuildsActions.jsx +++ /dev/null @@ -1,60 +0,0 @@ -import React, { useContext, useState } from 'react'; - -import AddGuildModal from './EditGuildModal'; -import { createGuild } from '../../api/guild'; -import { AppContext } from '../../context/AppContext'; -import { ADD_GUILD } from '../../context/actions'; - -import { Button } from '@mui/material'; -import GroupIcon from '@mui/icons-material/Group'; - -import './GuildResults.css'; - -const displayName = 'GuildsActions'; - -const GuildsActions = () => { - const { state, dispatch } = useContext(AppContext); - const [open, setOpen] = useState(false); - - const { csrf, userProfile } = state; - - const handleOpen = () => setOpen(true); - - const handleClose = () => setOpen(false); - - const isAdmin = userProfile?.role?.includes('ADMIN'); - - return ( -
- {isAdmin && ( - <> - - { - if (csrf) { - let res = await createGuild(guild, csrf); - let data = - res.payload && res.payload.data && !res.error - ? res.payload.data - : null; - if (data) { - dispatch({ type: ADD_GUILD, payload: data }); - } - handleClose(); - } - }} - headerText="Add A New Guild" - /> - - )} -
- ); -}; - -GuildsActions.displayName = displayName; - -export default GuildsActions; diff --git a/web-ui/src/components/guild-results/GuildsActions.test.jsx b/web-ui/src/components/guild-results/GuildsActions.test.jsx deleted file mode 100644 index 844df478e8..0000000000 --- a/web-ui/src/components/guild-results/GuildsActions.test.jsx +++ /dev/null @@ -1,39 +0,0 @@ -import React from 'react'; -import GuildsActions from './GuildsActions'; -import { AppContextProvider } from '../../context/AppContext'; - -const initialState = { - state: { - userProfile: { - name: 'holmes', - memberProfile: { - pdlId: '', - title: 'Tester', - workEmail: 'test@tester.com' - }, - role: ['MEMBER'], - imageUrl: - 'https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg' - }, - guilds: [ - { - id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', - name: 'string', - description: 'string' - }, - { - id: '3fa4-5717-4562-b3fc-2c963f66afa6', - name: 'stuff', - description: '' - } - ] - } -}; - -it('renders correctly', () => { - snapshot( - - - - ); -}); From 240ed6dbbf4bfc55172fbf03e27e92a9eead48a3 Mon Sep 17 00:00:00 2001 From: Mark Volkmann Date: Fri, 26 Apr 2024 15:07:52 -0500 Subject: [PATCH 2/4] progress on 2264 --- web-ui/src/components/guild-results/EditGuildModal.jsx | 5 ++++- web-ui/src/components/guild-results/GuildResults.jsx | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/web-ui/src/components/guild-results/EditGuildModal.jsx b/web-ui/src/components/guild-results/EditGuildModal.jsx index 7eb1860b6d..fc17c433ac 100644 --- a/web-ui/src/components/guild-results/EditGuildModal.jsx +++ b/web-ui/src/components/guild-results/EditGuildModal.jsx @@ -187,6 +187,9 @@ const EditGuildModal = ({ guild = {}, open, onSave, onClose, headerText }) => { ? editedGuild.guildMembers.filter(guildMember => guildMember.lead) : [] } + isOptionEqualToValue={(option, value) => + value && option.id === value.memberId + } onChange={onLeadsChange} getOptionLabel={option => option.name} renderInput={params => ( @@ -211,7 +214,7 @@ const EditGuildModal = ({ guild = {}, open, onSave, onClose, headerText }) => { onChange={onGuildMembersChange} getOptionLabel={option => option.name} isOptionEqualToValue={(option, value) => - value ? value.id === option.id : false + value && option.id === value.memberId } renderInput={params => ( { const { dispatch, state } = useContext(AppContext); - const { guilds, userProfile } = state; + const { csrf, guilds, userProfile } = state; const [addOpen, setAddOpen] = useState(false); const [openedGuildId, setOpenedGuildId] = useState(''); const [searchText, setSearchText] = useState(''); @@ -94,6 +96,7 @@ const GuildResults = () => { open={addOpen} onClose={handleClose} onSave={async guild => { + console.log('GuildResults.jsx onSave: guild =', guild); if (csrf) { let res = await createGuild(guild, csrf); let data = From a2a46c2e4e1d41494a8c68b2a3bd9519a3be4c08 Mon Sep 17 00:00:00 2001 From: Mark Volkmann Date: Mon, 29 Apr 2024 14:31:24 -0500 Subject: [PATCH 3/4] GuildResults.jsx now uses useQueryParameters --- .../components/guild-results/GuildResults.jsx | 44 +++++++++---------- 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/web-ui/src/components/guild-results/GuildResults.jsx b/web-ui/src/components/guild-results/GuildResults.jsx index 4f683b67f1..385818a17f 100644 --- a/web-ui/src/components/guild-results/GuildResults.jsx +++ b/web-ui/src/components/guild-results/GuildResults.jsx @@ -10,6 +10,7 @@ import { AppContext } from '../../context/AppContext'; import AddGuildModal from './EditGuildModal'; import GuildSummaryCard from './GuildSummaryCard'; import SkeletonLoader from '../skeleton_loader/SkeletonLoader'; +import { useQueryParameters } from '../../helpers/query-parameters'; import './GuildResults.css'; const PREFIX = 'GuildResults'; @@ -42,31 +43,26 @@ const GuildResults = () => { const [openedGuildId, setOpenedGuildId] = useState(''); const [searchText, setSearchText] = useState(''); - useEffect(() => { - const url = new URL(location.href); - - const addOpen = url.searchParams.get('addOpen') || ''; - setAddOpen(addOpen === 'true'); - - const guildId = url.searchParams.get('guild') || ''; - setOpenedGuildId(guildId); - - const search = url.searchParams.get('search') || ''; - setSearchText(search); - }, []); - - useEffect(() => { - const url = new URL(location.href); - let newUrl = url.origin + url.pathname; - const params = {}; - if (addOpen) params.addOpen = true; - if (openedGuildId) params.guild = openedGuildId; - if (searchText) params.search = searchText; - if (Object.keys(params).length) { - newUrl += '?' + new URLSearchParams(params).toString(); + useQueryParameters([ + { + name: 'addOpen', + default: false, + value: addOpen, + setter: setAddOpen + }, + { + name: 'guild', + default: '', + value: openedGuildId, + setter: setOpenedGuildId + }, + { + name: 'search', + default: '', + value: searchText, + setter: setSearchText } - history.replaceState(params, '', newUrl); - }, [addOpen, openedGuildId, searchText]); + ]); const handleOpen = () => setAddOpen(true); From 2e71426037a273a3439225e2abc62feaffff241d Mon Sep 17 00:00:00 2001 From: Mark Volkmann Date: Mon, 29 Apr 2024 14:36:31 -0500 Subject: [PATCH 4/4] removed a console.log --- web-ui/src/components/guild-results/GuildResults.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/web-ui/src/components/guild-results/GuildResults.jsx b/web-ui/src/components/guild-results/GuildResults.jsx index 385818a17f..9020d26b9c 100644 --- a/web-ui/src/components/guild-results/GuildResults.jsx +++ b/web-ui/src/components/guild-results/GuildResults.jsx @@ -92,7 +92,6 @@ const GuildResults = () => { open={addOpen} onClose={handleClose} onSave={async guild => { - console.log('GuildResults.jsx onSave: guild =', guild); if (csrf) { let res = await createGuild(guild, csrf); let data =