From 056385bff38d5097dd034b7a802078d57b0d4a82 Mon Sep 17 00:00:00 2001 From: elraphty Date: Thu, 7 Dec 2023 23:50:18 +0100 Subject: [PATCH 1/2] fixed edit and org bounties --- frontend/app/src/pages/tickets/OrgTickets.tsx | 234 ++++++++++++++++++ .../app/src/pages/tickets/TicketModalPage.tsx | 2 +- frontend/app/src/pages/tickets/Tickets.tsx | 108 ++++---- frontend/app/src/pages/tickets/index.tsx | 5 +- .../people/widgetViews/WidgetSwitchViewer.tsx | 1 + .../wantedSummaries/CodingBounty.tsx | 5 +- frontend/app/src/store/main.ts | 1 - 7 files changed, 295 insertions(+), 61 deletions(-) create mode 100644 frontend/app/src/pages/tickets/OrgTickets.tsx diff --git a/frontend/app/src/pages/tickets/OrgTickets.tsx b/frontend/app/src/pages/tickets/OrgTickets.tsx new file mode 100644 index 000000000..b02c96e97 --- /dev/null +++ b/frontend/app/src/pages/tickets/OrgTickets.tsx @@ -0,0 +1,234 @@ +import { EuiGlobalToastList, EuiLoadingSpinner } from '@elastic/eui'; +import { observer } from 'mobx-react-lite'; +import FirstTimeScreen from 'people/main/FirstTimeScreen'; +import BountyHeader from 'people/widgetViews/BountyHeader'; +import WidgetSwitchViewer from 'people/widgetViews/WidgetSwitchViewer'; +import React, { useEffect, useState } from 'react'; +import { useHistory } from 'react-router'; +import { useParams } from 'react-router-dom'; +import styled from 'styled-components'; +import { colors } from '../../config/colors'; +import { useIsMobile } from '../../hooks'; +import { useStores } from '../../store'; + +// avoid hook within callback warning by renaming hooks +const Body = styled.div` + flex: 1; + height: calc(100% - 105px); + width: 100%; + overflow: auto; + display: flex; + flex-direction: column; +`; + +const Backdrop = styled.div` + position: fixed; + z-index: 1; + background: rgba(0, 0, 0, 70%); + top: 0; + bottom: 0; + left: 0; + right: 0; +`; + +export const Spacer = styled.div` + display: flex; + min-height: 10px; + min-width: 100%; + height: 10px; + width: 100%; +`; + +function OrgBodyComponent() { + const { main, ui } = useStores(); + const [loading, setLoading] = useState(true); + const [showDropdown, setShowDropdown] = useState(false); + const selectedWidget = 'wanted'; + const [scrollValue, setScrollValue] = useState(false); + const [checkboxIdToSelectedMap, setCheckboxIdToSelectedMap] = useState({}); + const [checkboxIdToSelectedMapLanguage, setCheckboxIdToSelectedMapLanguage] = useState({}); + const { uuid } = useParams<{ uuid: string; bountyId: string }>(); + + const color = colors['light']; + + const history = useHistory(); + const isMobile = useIsMobile(); + + useEffect(() => { + (async () => { + await main.getOpenGithubIssues(); + await main.getBadgeList(); + await main.getPeople(); + if (uuid) { + await main.getOrganizationBounties(uuid, { page: 1, resetPage: true }); + } + setLoading(false); + })(); + }, [main, uuid]); + + useEffect(() => { + setCheckboxIdToSelectedMap({ + Open: true, + Assigned: false, + Paid: false + }); + }, [loading]); + + useEffect(() => { + if (ui.meInfo) { + main.getTribesByOwner(ui.meInfo.owner_pubkey || ''); + } + }, [main, ui.meInfo]); + + const onChangeStatus = (optionId: any) => { + const newCheckboxIdToSelectedMap = { + ...checkboxIdToSelectedMap, + ...{ + [optionId]: !checkboxIdToSelectedMap[optionId] + } + }; + setCheckboxIdToSelectedMap(newCheckboxIdToSelectedMap); + }; + + const onChangeLanguage = (optionId: any) => { + const newCheckboxIdToSelectedMapLanguage = { + ...checkboxIdToSelectedMapLanguage, + ...{ + [optionId]: !checkboxIdToSelectedMapLanguage[optionId] + } + }; + setCheckboxIdToSelectedMapLanguage(newCheckboxIdToSelectedMapLanguage); + }; + + const onPanelClick = (person: any, item: any) => { + history.push(`/bounty/${item.id}`); + }; + + if (loading) { + return ( + + + + ); + } + + const showFirstTime = ui.meInfo && ui.meInfo.id === 0; + + if (showFirstTime) { + return ; + } + + const toastsEl = ( + ui.setToasts([])} + toastLifeTimeMs={3000} + /> + ); + + if (!loading && isMobile) { + return ( + +
+ +
+ + {showDropdown && setShowDropdown(false)} />} +
+ +
+ + {toastsEl} + + ); + } + + return ( + !loading && ( + { + setScrollValue(e?.currentTarget?.scrollTop >= 20); + }} + style={{ + background: color.grayish.G950, + height: 'calc(100% - 65px)' + }} + > +
+ + + + <> +
+
+ +
+
+ + {toastsEl} + + ) + ); +} + +export default observer(OrgBodyComponent); diff --git a/frontend/app/src/pages/tickets/TicketModalPage.tsx b/frontend/app/src/pages/tickets/TicketModalPage.tsx index d2089c8c0..10ad53551 100644 --- a/frontend/app/src/pages/tickets/TicketModalPage.tsx +++ b/frontend/app/src/pages/tickets/TicketModalPage.tsx @@ -38,6 +38,7 @@ export const TicketModalPage = observer(({ setConnectPerson }: Props) => { const [isDeleted, setisDeleted] = useState(false); const isMobile = useIsMobile(); + const { uuid } = useParams<{ uuid: string }>(); const search = useMemo(() => { const s = new URLSearchParams(location.search); @@ -79,7 +80,6 @@ export const TicketModalPage = observer(({ setConnectPerson }: Props) => { const goBack = async () => { setVisible(false); setisDeleted(false); - await main.getPeopleBounties({ page: 1, resetPage: true }); history.goBack(); }; diff --git a/frontend/app/src/pages/tickets/Tickets.tsx b/frontend/app/src/pages/tickets/Tickets.tsx index a853c6b84..34ff76f00 100644 --- a/frontend/app/src/pages/tickets/Tickets.tsx +++ b/frontend/app/src/pages/tickets/Tickets.tsx @@ -5,7 +5,6 @@ import BountyHeader from 'people/widgetViews/BountyHeader'; import WidgetSwitchViewer from 'people/widgetViews/WidgetSwitchViewer'; import React, { useEffect, useState } from 'react'; import { useHistory } from 'react-router'; -import { useLocation, useParams } from 'react-router-dom'; import styled from 'styled-components'; import { colors } from '../../config/colors'; import { useIsMobile } from '../../hooks'; @@ -47,27 +46,21 @@ function BodyComponent() { const [scrollValue, setScrollValue] = useState(false); const [checkboxIdToSelectedMap, setCheckboxIdToSelectedMap] = useState({}); const [checkboxIdToSelectedMapLanguage, setCheckboxIdToSelectedMapLanguage] = useState({}); - const { uuid } = useParams<{ uuid: string; bountyId: string }>(); const color = colors['light']; const history = useHistory(); const isMobile = useIsMobile(); - const location = useLocation(); useEffect(() => { (async () => { await main.getOpenGithubIssues(); await main.getBadgeList(); await main.getPeople(); - if (uuid) { - await main.getOrganizationBounties(uuid, { page: 1, resetPage: true }); - } else { - await main.getPeopleBounties({ page: 1, resetPage: true }); - } + await main.getPeopleBounties({ page: 1, resetPage: true }); setLoading(false); })(); - }, [main, uuid]); + }, [main]); useEffect(() => { setCheckboxIdToSelectedMap({ @@ -129,7 +122,7 @@ function BodyComponent() { /> ); - if (isMobile) { + if (!loading && isMobile) { return (
); } + return ( - { - setScrollValue(e?.currentTarget?.scrollTop >= 20); - }} - style={{ - background: color.grayish.G950, - height: 'calc(100% - 65px)' - }} - > -
{ + setScrollValue(e?.currentTarget?.scrollTop >= 20); + }} style={{ - minHeight: '32px' + background: color.grayish.G950, + height: 'calc(100% - 65px)' }} - /> - - - - <> + >
+ /> + + + + <>
- +
+ +
-
- - {toastsEl} - + + {toastsEl} + + ) ); } diff --git a/frontend/app/src/pages/tickets/index.tsx b/frontend/app/src/pages/tickets/index.tsx index f46cba185..7f4779e0d 100644 --- a/frontend/app/src/pages/tickets/index.tsx +++ b/frontend/app/src/pages/tickets/index.tsx @@ -1,13 +1,16 @@ import React, { useState } from 'react'; +import { useParams } from 'react-router-dom'; import ConnectCard from 'people/utils/ConnectCard'; import { TicketModalPage } from './TicketModalPage'; import Tickets from './Tickets'; +import OrgTickets from './OrgTickets'; export const TicketsPage = () => { const [connectPerson, setConnectPerson] = useState(null); + const { uuid } = useParams<{ uuid: string }>(); return ( <> - + {uuid ? : } {connectPerson && ( { diff --git a/frontend/app/src/people/widgetViews/summaries/wantedSummaries/CodingBounty.tsx b/frontend/app/src/people/widgetViews/summaries/wantedSummaries/CodingBounty.tsx index 89646e239..2ec53d5c2 100644 --- a/frontend/app/src/people/widgetViews/summaries/wantedSummaries/CodingBounty.tsx +++ b/frontend/app/src/people/widgetViews/summaries/wantedSummaries/CodingBounty.tsx @@ -103,7 +103,6 @@ function MobileView(props: CodingBountiesProps) { const [toasts, setToasts]: any = useState([]); const [updatingPayment, setUpdatingPayment] = useState(false); const [userBountyRole, setUserBountyRole] = useState(false); - const canEdit = ui.meInfo?.owner_pubkey === person.owner_pubkey; const userPubkey = ui.meInfo?.owner_pubkey; @@ -340,6 +339,7 @@ function MobileView(props: CodingBountiesProps) { const getOrganization = useCallback(async () => { if (org_uuid && userPubkey) { const userRoles = await main.getUserRoles(org_uuid, userPubkey); + const organization = await main.getUserOrganizationByUuid(org_uuid); if (organization) { const isOrganizationAdmin = organization.owner_pubkey === userPubkey; @@ -360,6 +360,7 @@ function MobileView(props: CodingBountiesProps) { { ...person }?.owner_alias && ui.meInfo?.owner_alias && { ...person }?.owner_alias === ui.meInfo?.owner_alias; + const hasAccess = isOwner || userBountyRole; const payBountyDisable = !isOwner && !userBountyRole; @@ -450,7 +451,7 @@ function MobileView(props: CodingBountiesProps) {
{nametag}
- {!bountyPaid && canEdit && ( + {!bountyPaid && userBountyRole && (
Date: Fri, 8 Dec 2023 00:05:00 +0100 Subject: [PATCH 2/2] seperated tickets from org tickets --- frontend/app/src/pages/index.tsx | 3 +- frontend/app/src/pages/tickets/Tickets.tsx | 28 +-------------- frontend/app/src/pages/tickets/index.tsx | 5 +-- .../pages/tickets/{ => org}/OrgTickets.tsx | 36 +++---------------- frontend/app/src/pages/tickets/org/index.tsx | 25 +++++++++++++ frontend/app/src/pages/tickets/style.ts | 28 +++++++++++++++ 6 files changed, 61 insertions(+), 64 deletions(-) rename frontend/app/src/pages/tickets/{ => org}/OrgTickets.tsx (89%) create mode 100644 frontend/app/src/pages/tickets/org/index.tsx create mode 100644 frontend/app/src/pages/tickets/style.ts diff --git a/frontend/app/src/pages/index.tsx b/frontend/app/src/pages/index.tsx index ae84c4132..6d207f69e 100644 --- a/frontend/app/src/pages/index.tsx +++ b/frontend/app/src/pages/index.tsx @@ -14,6 +14,7 @@ import { MainLayout } from './MainLayout'; import { Modals } from './Modals'; import { People } from './people'; import { TicketsPage } from './tickets'; +import { OrgTicketsPage } from './tickets/org'; import { LeaderboardPage } from './leaderboard'; const modeDispatchPages: Record React.ReactElement> = { @@ -40,7 +41,7 @@ const modeDispatchPages: Record React.ReactElement> = { - + diff --git a/frontend/app/src/pages/tickets/Tickets.tsx b/frontend/app/src/pages/tickets/Tickets.tsx index 34ff76f00..4fd60dbc5 100644 --- a/frontend/app/src/pages/tickets/Tickets.tsx +++ b/frontend/app/src/pages/tickets/Tickets.tsx @@ -5,38 +5,12 @@ import BountyHeader from 'people/widgetViews/BountyHeader'; import WidgetSwitchViewer from 'people/widgetViews/WidgetSwitchViewer'; import React, { useEffect, useState } from 'react'; import { useHistory } from 'react-router'; -import styled from 'styled-components'; import { colors } from '../../config/colors'; import { useIsMobile } from '../../hooks'; import { useStores } from '../../store'; +import { Body, Backdrop } from './style'; // avoid hook within callback warning by renaming hooks -const Body = styled.div` - flex: 1; - height: calc(100% - 105px); - width: 100%; - overflow: auto; - display: flex; - flex-direction: column; -`; - -const Backdrop = styled.div` - position: fixed; - z-index: 1; - background: rgba(0, 0, 0, 70%); - top: 0; - bottom: 0; - left: 0; - right: 0; -`; - -export const Spacer = styled.div` - display: flex; - min-height: 10px; - min-width: 100%; - height: 10px; - width: 100%; -`; function BodyComponent() { const { main, ui } = useStores(); diff --git a/frontend/app/src/pages/tickets/index.tsx b/frontend/app/src/pages/tickets/index.tsx index 7f4779e0d..f46cba185 100644 --- a/frontend/app/src/pages/tickets/index.tsx +++ b/frontend/app/src/pages/tickets/index.tsx @@ -1,16 +1,13 @@ import React, { useState } from 'react'; -import { useParams } from 'react-router-dom'; import ConnectCard from 'people/utils/ConnectCard'; import { TicketModalPage } from './TicketModalPage'; import Tickets from './Tickets'; -import OrgTickets from './OrgTickets'; export const TicketsPage = () => { const [connectPerson, setConnectPerson] = useState(null); - const { uuid } = useParams<{ uuid: string }>(); return ( <> - {uuid ? : } + {connectPerson && ( { + const [connectPerson, setConnectPerson] = useState(null); + return ( + <> + + + {connectPerson && ( + setConnectPerson(null)} + modalStyle={{ + top: '-64px', + height: 'calc(100% + 64px)' + }} + person={connectPerson} + visible={true} + /> + )} + + ); +}; diff --git a/frontend/app/src/pages/tickets/style.ts b/frontend/app/src/pages/tickets/style.ts new file mode 100644 index 000000000..c8d1565d3 --- /dev/null +++ b/frontend/app/src/pages/tickets/style.ts @@ -0,0 +1,28 @@ +import styled from 'styled-components'; + +export const Body = styled.div` + flex: 1; + height: calc(100% - 105px); + width: 100%; + overflow: auto; + display: flex; + flex-direction: column; +`; + +export const Backdrop = styled.div` + position: fixed; + z-index: 1; + background: rgba(0, 0, 0, 70%); + top: 0; + bottom: 0; + left: 0; + right: 0; +`; + +export const Spacer = styled.div` + display: flex; + min-height: 10px; + min-width: 100%; + height: 10px; + width: 100%; +`;