Skip to content

Commit

Permalink
Merge pull request #997 from MahtabBukhari/Currently-the-boutnies-ass…
Browse files Browse the repository at this point in the history
…ociated-with-a-phase-are-not-showing-in-the-Phase-Form-on-a-feature-view

Currently the boutnies associated with a phase are not showing in the Phase Form on a feature view
  • Loading branch information
humansinstitute authored Jan 31, 2025
2 parents 8ad0276 + 6a4dcb3 commit affcea0
Show file tree
Hide file tree
Showing 4 changed files with 223 additions and 9 deletions.
96 changes: 93 additions & 3 deletions src/people/widgetViews/WidgetSwitchViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ function WidgetSwitchViewer(props: any) {
isBountyLandingPage,
activeWorkspace,
uuid,
featureUuid,
phaseUuid,
orgQueryLimit
} = props;

Expand All @@ -109,7 +111,7 @@ function WidgetSwitchViewer(props: any) {
justifyContent: 'center'
};

const { peoplePosts, peopleBounties, peopleOffers } = main;
const { peoplePosts, peopleBounties, phaseBounties, peopleOffers } = main;
const { selectedWidget, onPanelClick, org_uuid } = props;

const featuredBountyIds = bountyStore
Expand Down Expand Up @@ -137,6 +139,12 @@ function WidgetSwitchViewer(props: any) {
offer: peopleOffers
};

const phaseListSource = {
post: peoplePosts,
bounties: selectedWidget === 'bounties' ? sortBounties(phaseBounties) : phaseBounties,
offer: peopleOffers
};

const activeList = [...listSource[selectedWidget]].filter(({ body }: any) => {
const value = { ...body };
if (org_uuid) {
Expand All @@ -145,6 +153,14 @@ function WidgetSwitchViewer(props: any) {
return value;
});

const activePhaseList = [...phaseListSource[selectedWidget]].filter(({ body }: any) => {
const value = { ...body };
if (org_uuid) {
return value.org_uuid === org_uuid;
}
return value;
});

const foundDynamicSchema = widgetConfigs[selectedWidget]?.schema?.find(
(f: any) => f.dynamicSchemas
);
Expand Down Expand Up @@ -238,7 +254,81 @@ function WidgetSwitchViewer(props: any) {
}
: {};

// if this person has entries for this widget
return (
<Panel
color={color}
isMobile={isMobile}
key={person?.owner_pubkey + i + body?.created}
isAssignee={!!body.assignee}
style={{
...panelStyles,
...conditionalStyles,
cursor: 'pointer',
padding: isFeatured ? '2px' : 0,
overflow: 'hidden',
background: 'transparent',
minHeight: !isMobile ? '160px' : '',
maxHeight: 'auto',
boxShadow: 'none'
}}
>
{selectedWidget === 'post' ? (
<PostView
showName
key={`${i + person.owner_pubkey}pview`}
person={person}
{...body}
/>
) : selectedWidget === 'offer' ? (
<OfferView
showName
key={`${i + person.owner_pubkey}oview`}
person={person}
{...body}
/>
) : selectedWidget === 'bounties' ? (
<WantedView
showName
onPanelClick={() => {
if (onPanelClick) onPanelClick(activeWorkspace, body);
}}
person={person}
showModal={showModal}
isBountyLandingPage={isBountyLandingPage}
setDeletePayload={setDeletePayload}
fromBountyPage={props.fromBountyPage}
activeWorkspace={activeWorkspace}
{...body}
{...organization}
/>
) : null}
</Panel>
);
})
) : (
<NoResults loaded={!!languageString} />
);

const phaseListItems =
activePhaseList && activePhaseList.length ? (
activePhaseList.slice(0, currentItems).map((item: any, i: number) => {
const { person, body, organization } = item;
person.img = person.img || main.getUserAvatarPlaceholder(person.owner_pubkey);

const isFeatured = featuredBountyIds.includes(body.id.toString());

const conditionalStyles = body?.paid
? {
border: isMobile ? `2px 0 0 0 solid ${color.grayish.G600}` : '',
boxShadow: 'none'
}
: isFeatured
? {
border: '',
borderRadius: '12px'
}
: {};

return (
<Panel
color={color}
Expand Down Expand Up @@ -299,7 +389,7 @@ function WidgetSwitchViewer(props: any) {

return (
<>
{listItems}
{featureUuid && phaseUuid ? phaseListItems : listItems}
<Spacer key={'spacer2'} />
{showDeleteModal && (
<DeleteTicketModal closeModal={closeModal} confirmDelete={confirmDelete} />
Expand Down
3 changes: 2 additions & 1 deletion src/people/widgetViews/__tests__/WidgetSwitchViewer.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ describe('WidgetSwitchViewer Component', () => {
getSpecificWorkspaceBounties: jest.fn(() => Promise.resolve()),
peopleBounties: [],
peopleOffers: [],
peoplePosts: []
peoplePosts: [],
phaseBounties: []
}
});
});
Expand Down
123 changes: 120 additions & 3 deletions src/people/widgetViews/workspace/WorkspacePhase.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useMemo, useState } from 'react';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { EuiSpacer, EuiTabbedContentProps, EuiTabbedContentTab } from '@elastic/eui';
import { Button } from 'components/common';
import MaterialIcon from '@material/react-material-icon';
Expand All @@ -18,11 +18,14 @@ import {
StyledEuiTabbedContent,
TabContent,
PostABounty,
TabContentOptions
TabContentOptions,
DisplayBounties
} from '../workspace/style';
import addBounty from '../../../pages/tickets/workspace/workspaceHeader/Icons/addBounty.svg';
import { userCanManageBounty } from '../../../helpers';
import { PostModal } from '../postBounty/PostModal';
import WidgetSwitchViewer from '../WidgetSwitchViewer';
import { BountyStatus, phaseBountyLimit } from '../../../store/interface';
import { Phase, PhaseOperationMessage, PhaseOperationType, Toast } from './interface';
import { AddPhaseModal, DeletePhaseModal, EditPhaseModal } from './WorkspacePhasingModals';

Expand Down Expand Up @@ -114,13 +117,43 @@ const WorkspacePhasingTabs = (props: WorkspacePhaseProps) => {
const [phaseName, setPhaseName] = useState<string>('');
const [isPostBountyModalOpen, setIsPostBountyModalOpen] = useState(false);
const [canPostBounty, setCanPostBounty] = useState(false);
const [loading, setLoading] = useState(true);
const [page, setPage] = useState<number>(1);
const [currentItems, setCurrentItems] = useState<number>(phaseBountyLimit);
const [totalBounties, setTotalBounties] = useState(0);

const checkboxIdToSelectedMap: BountyStatus = useMemo(
() => ({
Open: true,
Assigned: true,
Completed: true,
Paid: true,
Pending: true,
Failed: true
}),
[]
);

const checkboxIdToSelectedMapLanguage = {};
const languageString = '';

const selectedWidget = 'bounties';

const history = useHistory();

const handleTabClick = (selectedTab: EuiTabbedContentTab) => {
setSelectedIndex(parseInt(selectedTab.id));
setPhaseName(phases[selectedIndex]?.name);
setPage(1);
setCurrentItems(phaseBountyLimit);
};

const onPanelClick = (activeWorkspace?: string, bounty?: any) => {
if (bounty?.id) {
history.push(`/bounty/${bounty.id}`);
} else {
history.push(`/feature/${props.workspace_uuid}`);
}
};

const handleAddPhaseClick = () => {
Expand Down Expand Up @@ -154,6 +187,45 @@ const WorkspacePhasingTabs = (props: WorkspacePhaseProps) => {
}
};

const getTotalBounties = useCallback(
async (statusData: any) => {
if (phases[selectedIndex]) {
const totalBounties = await main.getTotalPhaseBountyCount(
phases[selectedIndex].feature_uuid,
phases[selectedIndex].uuid,
statusData.Open,
statusData.Assigned,
statusData.Paid
);
setTotalBounties(totalBounties);
}
},
[phases, selectedIndex, main]
);

useEffect(() => {
if (phases[selectedIndex]) {
(async () => {
setLoading(true);

await main.getPhaseBounties(
phases[selectedIndex].feature_uuid,
phases[selectedIndex].uuid,
{
page: 1,
resetPage: true,
...checkboxIdToSelectedMap,
languages: languageString
}
);

await getTotalBounties(checkboxIdToSelectedMap);

setLoading(false);
})();
}
}, [phases, selectedIndex, main, checkboxIdToSelectedMap, languageString, getTotalBounties]);

const handlePhaseNameChange = (name: string) => setPhaseName(name);

const createOrUpdateFeaturePhase = async (op: PhaseOperationType) => {
Expand Down Expand Up @@ -264,10 +336,55 @@ const WorkspacePhasingTabs = (props: WorkspacePhaseProps) => {
</>
)}
</PostABounty>
<DisplayBounties>
<div
style={{
width: '100%',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
height: '100%',
overflowY: 'auto'
}}
>
{totalBounties > 0 ? (
<WidgetSwitchViewer
onPanelClick={onPanelClick}
checkboxIdToSelectedMap={checkboxIdToSelectedMap}
checkboxIdToSelectedMapLanguage={checkboxIdToSelectedMapLanguage}
fromBountyPage={true}
selectedWidget={selectedWidget}
loading={loading}
currentItems={currentItems}
setCurrentItems={setCurrentItems}
page={page}
setPage={setPage}
languageString={languageString}
phaseTotalBounties={totalBounties}
featureUuid={phases[selectedIndex].feature_uuid}
phaseUuid={phases[selectedIndex].uuid}
/>
) : (
<p>No Bounties Yet!</p>
)}
</div>
</DisplayBounties>
</TabContent>
)
})),
[phases, canPostBounty, selectedIndex]
[
phases,
canPostBounty,
handlePhasePlannerClick,
totalBounties,
onPanelClick,
checkboxIdToSelectedMap,
checkboxIdToSelectedMapLanguage,
loading,
currentItems,
page,
selectedIndex
]
);

const selectedTab = useMemo(() => tabs[selectedIndex], [selectedIndex, tabs]);
Expand Down
10 changes: 8 additions & 2 deletions src/store/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,12 @@ export class MainStore {
this.peopleBounties = bounties;
}

@persist('list')
phaseBounties: PersonBounty[] = [];
@action setPhaseBounties(bounties: PersonBounty[]) {
this.phaseBounties = bounties;
}

@persist('object')
bountiesStatus: BountyStatus = defaultBountyStatus;
@action setBountiesStatus(status: BountyStatus) {
Expand Down Expand Up @@ -826,7 +832,7 @@ export class MainStore {

// for search always reset page
if (queryParams && queryParams.resetPage) {
this.setPeopleBounties(ps3);
this.setPhaseBounties(ps3);
uiStore.setPeopleBountiesPageNumber(1);
} else {
// all other cases, merge
Expand All @@ -837,7 +843,7 @@ export class MainStore {
queryParams,
'bounties'
);
this.setPeopleBounties(wanteds);
this.setPhaseBounties(wanteds);
}

return ps3;
Expand Down

0 comments on commit affcea0

Please sign in to comment.