Skip to content

Commit

Permalink
Merge pull request #3852 from DaleMcGrew/Dale_WebApp_Mar2-2024
Browse files Browse the repository at this point in the history
Added standard LinkToAdminTools, so we don't have to deal with voter object directly in the components that need a link to administration tools. MERGE READY
  • Loading branch information
DaleMcGrew authored Mar 9, 2024
2 parents 72e3e19 + a568cee commit f33d965
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 70 deletions.
67 changes: 67 additions & 0 deletions src/js/common/components/Widgets/LinkToAdminTools.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import PropTypes from 'prop-types';
import React, { Component, Suspense } from 'react';
import styled from 'styled-components';
import { isCordova } from '../../utils/isCordovaOrWebApp';
import VoterStore from '../../../stores/VoterStore';

const OpenExternalWebSite = React.lazy(() => import(/* webpackChunkName: 'OpenExternalWebSite' */ './OpenExternalWebSite'));

class LinkToAdminTools extends Component {
constructor (props) {
super(props);
this.state = {
voter: null,
};
}

componentDidMount () {
this.onVoterStoreChange();
this.voterStoreListener = VoterStore.addListener(this.onVoterStoreChange.bind(this));
}

componentWillUnmount () {
this.voterStoreListener.remove();
}

onVoterStoreChange = () => {
this.setState({
voter: VoterStore.getVoter(),
});
};

render () {
const { adminToolsUrl, linkId, linkTextNode } = this.props;
const { voter } = this.state;
return (
<LinkToAdminToolsWrapper>
{/* Show links to this candidate in the admin tools */}
{(voter && (voter.is_admin || voter.is_political_data_manager || voter.is_verified_volunteer)) && (
<span className="u-wrap-links d-print-none">
Admin only:
<Suspense fallback={<></>}>
<OpenExternalWebSite
linkIdAttribute={linkId || 'linkToAdminTools'}
url={adminToolsUrl}
target="_blank"
className="open-web-site open-web-site__no-right-padding"
body={linkTextNode || <span>edit</span>}
/>
</Suspense>
</span>
)}
</LinkToAdminToolsWrapper>
);
}
}
LinkToAdminTools.propTypes = {
linkId: PropTypes.string,
linkTextNode: PropTypes.node,
adminToolsUrl: PropTypes.string.isRequired,
};

const LinkToAdminToolsWrapper = styled('div')`
margin-top: ${() => (isCordova() ? '100px' : '20px')};
padding-bottom: ${() => (isCordova() ? '100px' : '20px')};
`;

export default LinkToAdminTools;
8 changes: 8 additions & 0 deletions src/js/common/pages/Politician/PoliticianDetailsPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { EditIndicator, ElectionInPast, IndicatorButtonWrapper, IndicatorRow } f
import { CandidateCampaignListDesktop, CandidateCampaignListMobile, CandidateCampaignWrapper, OfficeHeldNameDesktop, OfficeHeldNameMobile, PoliticianImageDesktop, PoliticianImageDesktopPlaceholder, PoliticianImageMobile, PoliticianImageMobilePlaceholder, PoliticianNameDesktop, PoliticianNameMobile, PoliticianNameOuterWrapperDesktop } from '../../components/Style/PoliticianDetailsStyles';
import { PageWrapper } from '../../components/Style/stepDisplayStyles';
import DelayedLoad from '../../components/Widgets/DelayedLoad';
import LinkToAdminTools from '../../components/Widgets/LinkToAdminTools';
import OfficeHeldNameText from '../../components/Widgets/OfficeHeldNameText';
import SearchOnGoogle from '../../components/Widgets/SearchOnGoogle';
import ViewOnBallotpedia from '../../components/Widgets/ViewOnBallotpedia';
Expand Down Expand Up @@ -491,6 +492,7 @@ class PoliticianDetailsPage extends Component {
voterCanEditThisPolitician, voterSupportsThisPolitician,
wikipediaUrl, // youtubeUrl,
} = this.state;
const campaignAdminEditUrl = `${webAppConfig.WE_VOTE_SERVER_ROOT_URL}campaign/${linkedCampaignXWeVoteId}/summary`;

if (politicianDataNotFound) {
return (
Expand Down Expand Up @@ -985,6 +987,12 @@ class PoliticianDetailsPage extends Component {
</CampaignDescriptionDesktopWrapper>
{positionListTeaserHtml}
{commentListTeaserHtml}
{/* Show links to this campaign in the admin tools */}
<LinkToAdminTools
adminToolsUrl={campaignAdminEditUrl}
linkId="editCampaign"
linkTextNode={<span>edit campaign</span>}
/>
</ColumnTwoThirds>
<ColumnOneThird>
<Suspense fallback={<span>&nbsp;</span>}>
Expand Down
36 changes: 13 additions & 23 deletions src/js/pages/Ballot/Candidate.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { renderLog } from '../../common/utils/logging';
import { convertToInteger } from '../../common/utils/textFormat';
import toTitleCase from '../../common/utils/toTitleCase';
import CandidateStickyHeader from '../../components/Ballot/CandidateStickyHeader';
import LinkToAdminTools from '../../common/components/Widgets/LinkToAdminTools';
import { PageContentContainer } from '../../components/Style/pageLayoutStyles';
import SearchOnGoogle from '../../common/components/Widgets/SearchOnGoogle';
import SnackNotifier from '../../common/components/Widgets/SnackNotifier';
Expand All @@ -33,7 +34,6 @@ import VoterStore from '../../stores/VoterStore';
const CampaignSupportThermometer = React.lazy(() => import(/* webpackChunkName: 'CampaignSupportThermometer' */ '../../common/components/CampaignSupport/CampaignSupportThermometer'));
const CandidateItem = React.lazy(() => import(/* webpackChunkName: 'CandidateItem' */ '../../components/Ballot/CandidateItem'));
const DelayedLoad = React.lazy(() => import(/* webpackChunkName: 'DelayedLoad' */ '../../common/components/Widgets/DelayedLoad'));
const OpenExternalWebSite = React.lazy(() => import(/* webpackChunkName: 'OpenExternalWebSite' */ '../../common/components/Widgets/OpenExternalWebSite'));
const PositionList = React.lazy(() => import(/* webpackChunkName: 'PositionList' */ '../../components/Ballot/PositionList'));
const ShareButtonDesktopTablet = React.lazy(() => import(/* webpackChunkName: 'ShareButtonDesktopTablet' */ '../../components/Share/ShareButtonDesktopTablet'));
const ViewUpcomingBallotButton = React.lazy(() => import(/* webpackChunkName: 'ViewUpcomingBallotButton' */ '../../components/Ready/ViewUpcomingBallotButton'));
Expand Down Expand Up @@ -252,7 +252,7 @@ class Candidate extends Component {

onVoterGuideStoreChange () {
// console.log('Candidate onVoterGuideStoreChange');
// Trigger an update of the candidate so we can get an updated position_list
// Trigger an update of the candidate, so we can get an updated position_list
// CandidateActions.candidateRetrieve(this.state.candidateWeVoteId);
// CandidateActions.positionListForBallotItemPublic(this.state.candidateWeVoteId);
}
Expand Down Expand Up @@ -315,7 +315,6 @@ class Candidate extends Component {
const candidateName = toTitleCase(candidate.ballot_item_display_name);
const titleText = `${candidateName} - WeVote`;
const descriptionText = `Information about ${candidateName}, candidate for ${candidate.contest_office_name}`;
const voter = VoterStore.getVoter();
const candidateAdminEditUrl = `${webAppConfig.WE_VOTE_SERVER_ROOT_URL}c/${candidate.id}/edit/?google_civic_election_id=${VoterStore.electionId()}&state_code=`;

// TODO When we remove expandIssuesByDefault from CandidateItem, the page is pushed very wide. This needs to be fixed.
Expand Down Expand Up @@ -419,26 +418,17 @@ class Candidate extends Component {
*/}
<br />
{/* Show links to this candidate in the admin tools */}
{ (voter.is_admin || voter.is_verified_volunteer) && (
<span className="u-wrap-links d-print-none">
Admin only:
<Suspense fallback={<></>}>
<OpenExternalWebSite
linkIdAttribute="candidateAdminEdit"
url={candidateAdminEditUrl}
target="_blank"
className="open-web-site open-web-site__no-right-padding"
body={(
<span>
edit
{' '}
{candidateName}
</span>
)}
/>
</Suspense>
</span>
)}
<LinkToAdminTools
adminToolsUrl={candidateAdminEditUrl}
linkId="candidateAdminEdit"
linkTextNode={(
<span>
edit
{' '}
{candidateName}
</span>
)}
/>
</PageWrapper>
</PageContentContainer>
);
Expand Down
37 changes: 13 additions & 24 deletions src/js/pages/Ballot/Measure.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import toTitleCase from '../../common/utils/toTitleCase';
import MeasureStickyHeader from '../../components/Ballot/MeasureStickyHeader';
import { PageContentContainer } from '../../components/Style/pageLayoutStyles';
import EndorsementCard from '../../components/Widgets/EndorsementCard';
import LinkToAdminTools from '../../common/components/Widgets/LinkToAdminTools';
import SearchOnGoogle from '../../common/components/Widgets/SearchOnGoogle';
import SnackNotifier from '../../common/components/Widgets/SnackNotifier';
import ViewOnBallotpedia from '../../common/components/Widgets/ViewOnBallotpedia';
Expand All @@ -30,7 +31,6 @@ import { cordovaBallotFilterTopMargin } from '../../utils/cordovaOffsets';

const DelayedLoad = React.lazy(() => import(/* webpackChunkName: 'DelayedLoad' */ '../../common/components/Widgets/DelayedLoad'));
const MeasureItem = React.lazy(() => import(/* webpackChunkName: 'MeasureItem' */ '../../components/Ballot/MeasureItem'));
const OpenExternalWebSite = React.lazy(() => import(/* webpackChunkName: 'OpenExternalWebSite' */ '../../common/components/Widgets/OpenExternalWebSite'));
const PositionList = React.lazy(() => import(/* webpackChunkName: 'PositionList' */ '../../components/Ballot/PositionList'));
const ShareButtonDesktopTablet = React.lazy(() => import(/* webpackChunkName: 'ShareButtonDesktopTablet' */ '../../components/Share/ShareButtonDesktopTablet'));

Expand Down Expand Up @@ -296,8 +296,6 @@ class Measure extends Component {
const measureName = toTitleCase(ballotItemDisplayName);
const titleText = `${measureName} - WeVote`;
const descriptionText = `Information about ${measureName}`;
const voter = VoterStore.getVoter();
const { is_admin: isAdmin, is_verified_volunteer: isVerifiedVolunteer } = voter;
const measureAdminEditUrl = `${webAppConfig.WE_VOTE_SERVER_ROOT_URL}m/${measureId}/edit/?google_civic_election_id=${VoterStore.electionId()}&state_code=`;

return (
Expand Down Expand Up @@ -371,27 +369,18 @@ class Measure extends Component {
text={`Are there endorsements for ${measureName} that you expected to see?`}
/>
<br />
{/* Show links to this candidate in the admin tools */}
{ (isAdmin || isVerifiedVolunteer) && (
<span className="u-wrap-links d-print-none">
Admin only:
<Suspense fallback={<></>}>
<OpenExternalWebSite
linkIdAttribute="measureAdminEdit"
url={measureAdminEditUrl}
target="_blank"
className="open-web-site open-web-site__no-right-padding"
body={(
<span>
edit
{' '}
{measureName}
</span>
)}
/>
</Suspense>
</span>
)}
{/* Show links to this measure in the admin tools */}
<LinkToAdminTools
adminToolsUrl={measureAdminEditUrl}
linkId="measureAdminEdit"
linkTextNode={(
<span>
edit
{' '}
{measureName}
</span>
)}
/>
</PageContentContainer>
</Suspense>
</>
Expand Down
36 changes: 13 additions & 23 deletions src/js/pages/VoterGuide/OrganizationVoterGuideCandidate.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import toTitleCase from '../../common/utils/toTitleCase';
import OrganizationVoterGuideCandidateItem from '../../components/VoterGuide/OrganizationVoterGuideCandidateItem';
import { PageContentContainer } from '../../components/Style/pageLayoutStyles';
import EndorsementCard from '../../components/Widgets/EndorsementCard';
import LinkToAdminTools from '../../common/components/Widgets/LinkToAdminTools';
import SnackNotifier from '../../common/components/Widgets/SnackNotifier';
import ThisIsMeAction from '../../components/Widgets/ThisIsMeAction';
import webAppConfig from '../../config';
Expand All @@ -25,7 +26,6 @@ import CandidateStore from '../../stores/CandidateStore';
import VoterGuideStore from '../../stores/VoterGuideStore';
import VoterStore from '../../stores/VoterStore';

const OpenExternalWebSite = React.lazy(() => import(/* webpackChunkName: 'OpenExternalWebSite' */ '../../common/components/Widgets/OpenExternalWebSite'));
const PositionList = React.lazy(() => import(/* webpackChunkName: 'PositionList' */ '../../components/Ballot/PositionList'));
const ViewUpcomingBallotButton = React.lazy(() => import(/* webpackChunkName: 'ViewUpcomingBallotButton' */ '../../components/Ready/ViewUpcomingBallotButton'));

Expand Down Expand Up @@ -114,7 +114,7 @@ class OrganizationVoterGuideCandidate extends Component {
onVoterGuideStoreChange () {
// console.log('Candidate onVoterGuideStoreChange');
const { candidateWeVoteId } = this.state;
// When the voterGuidesToFollowForLatestBallotItem changes, trigger an update of the candidate so we can get an updated position_list
// When the voterGuidesToFollowForLatestBallotItem changes, trigger an update of the candidate, so we can get an updated position_list
// CandidateActions.candidateRetrieve(candidateWeVoteId);
CandidateActions.positionListForBallotItemPublic(candidateWeVoteId);
CandidateActions.positionListForBallotItemFromFriends(candidateWeVoteId);
Expand Down Expand Up @@ -153,7 +153,6 @@ class OrganizationVoterGuideCandidate extends Component {
const candidateName = toTitleCase(candidate.ballot_item_display_name);
const titleText = `${candidateName} - WeVote`;
const descriptionText = `Information about ${candidateName}, candidate for ${candidate.contest_office_name}`;
const voter = VoterStore.getVoter();
const candidateAdminEditUrl = `${webAppConfig.WE_VOTE_SERVER_ROOT_URL}c/${candidate.id}/edit/?google_civic_election_id=${VoterStore.electionId()}&state_code=`;

return (
Expand Down Expand Up @@ -235,26 +234,17 @@ class OrganizationVoterGuideCandidate extends Component {
</EndorsementCardWrapper>
<br />
{/* Show links to this candidate in the admin tools */}
{ (voter.is_admin || voter.is_verified_volunteer) && (
<span className="u-wrap-links d-print-none">
Admin only:
<Suspense fallback={<></>}>
<OpenExternalWebSite
linkIdAttribute="candidateAdminEdit"
url={candidateAdminEditUrl}
target="_blank"
className="open-web-site open-web-site__no-right-padding"
body={(
<span>
edit
{' '}
{candidateName}
</span>
)}
/>
</Suspense>
</span>
)}
<LinkToAdminTools
adminToolsUrl={candidateAdminEditUrl}
linkId="candidateAdminEdit"
linkTextNode={(
<span>
edit
{' '}
{candidateName}
</span>
)}
/>
</PageContentContainer>
);
}
Expand Down

0 comments on commit f33d965

Please sign in to comment.