Skip to content

Commit

Permalink
Merge pull request #768 from Financial-Times/ELES-1039-changes-to-the…
Browse files Browse the repository at this point in the history
…-share-modal-web-for-b-2-b-users-with-advanced-sharing

ElES-1039 changes to the share modal web
  • Loading branch information
asugar13 authored Mar 12, 2024
2 parents 5148360 + 414e118 commit fc9d7ea
Show file tree
Hide file tree
Showing 34 changed files with 658 additions and 172 deletions.
18 changes: 3 additions & 15 deletions components/x-gift-article/__tests__/x-gift-article.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const articleUrlRedeemed = 'https://gift-url-redeemed'
const nonGiftArticleUrl = `${articleUrl}?shareType=nongift`

const baseArgs = {
title: 'Share this article:',
title: 'Share this article with:',
isFreeArticle: false,
article: {
id: articleId,
Expand Down Expand Up @@ -49,6 +49,7 @@ describe('x-gift-article', () => {
})
.get('path:/v1/users/me/allowance', {
limit: 120,
budget: 100,
hasCredits: true
})
.post('path:/v1/shares', {
Expand All @@ -64,20 +65,6 @@ describe('x-gift-article', () => {
fetchMock.reset()
})

it('displays the article title', async () => {
const args = {
...baseArgs
}

args.article.title = 'A given test article title'

const subject = mount(<ShareArticleModal {...args} />)

expect(subject.find('.share-article-dialog__header-article-title').text()).toEqual(
'A given test article title'
)
})

it('should call correct endpoints on activate', async () => {
mount(<ShareArticleModal {...baseArgs} actionsRef={(a) => Object.assign(actions, a)} />)

Expand Down Expand Up @@ -244,6 +231,7 @@ describe('x-gift-article', () => {

await actions.activate()

await actions.showNonGiftUrlSection()
await actions.shortenNonGiftUrl()

subject.update()
Expand Down
34 changes: 25 additions & 9 deletions components/x-gift-article/src/AdvancedSharingOptions.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { h } from '@financial-times/x-engine'
import { ShareType } from './lib/constants'
import { NoCreditAlert } from './NoCreditAlert'
import { ReceivedHighlightsAlert } from './ReceivedHighlightsAlert'

export const AdvancedSharingOptions = (props) => {
const { shareType, actions, enterpriseHasCredits, giftCredits, showHighlightsRecipientMessage } = props
const { shareType, actions, enterpriseHasCredits, giftCredits } = props

const onValueChange = (event) => {
if (event.target.value === ShareType.enterprise) {
actions.showEnterpriseUrlSection(event)
Expand All @@ -13,12 +13,15 @@ export const AdvancedSharingOptions = (props) => {
}
}

return (
return giftCredits || enterpriseHasCredits ? (
<div>
<div
className="o-forms-field o-forms-field--optional o-forms-field--professional share-article-dialog__advanced-sharing-options"
role="group"
>
<h3 className="share-article-dialog__header">
<span className="share-article-dialog__header-share-article-title">Share using:</span>
</h3>
<span className="o-forms-input o-forms-input--radio-round">
<span className="o-forms-input--radio-round__container">
<label htmlFor="share-with-multiple-people-radio">
Expand All @@ -31,7 +34,14 @@ export const AdvancedSharingOptions = (props) => {
onChange={onValueChange}
disabled={!enterpriseHasCredits}
/>
<span className="o-forms-input__label">Multiple people</span>
<div className="o-forms-input__label share-article-dialog__advanced-sharing-options--element">
<span className="share-article-dialog__advanced-sharing-options--element-title">
Advanced Sharing
</span>
<span className="share-article-dialog__advanced-sharing-options--element-description">
Lets you share with multiple non-subscribers
</span>
</div>
</label>
<label htmlFor="share-with-one-person-radio">
<input
Expand All @@ -43,18 +53,24 @@ export const AdvancedSharingOptions = (props) => {
onChange={onValueChange}
disabled={!giftCredits}
/>
<span className="o-forms-input__label">One person</span>
<div className="o-forms-input__label share-article-dialog__advanced-sharing-options--element">
<span className="share-article-dialog__advanced-sharing-options--element-title">
Gift article
</span>
<span className="share-article-dialog__advanced-sharing-options--element-description">
Gift up to 20 articles per month to single non-subscribers. You have {giftCredits} articles
left this month.
</span>
</div>
</label>
</span>
</span>
</div>
{(!giftCredits || !enterpriseHasCredits) && (
<NoCreditAlert>
One of the non-subscriber choices is not available because you’ve run out of credits. Please use the
other option.
One of the choices is not available because you’ve run out of credits. Please use the other option.
</NoCreditAlert>
)}
{showHighlightsRecipientMessage && <ReceivedHighlightsAlert {...props} />}
</div>
)
) : null
}
11 changes: 9 additions & 2 deletions components/x-gift-article/src/CreateLinkButton.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import { h } from '@financial-times/x-engine'
import { ShareType } from './lib/constants'
import oShare from '@financial-times/o-share/main'
import { canShareWithNonSubscribers, isNonSubscriberOption } from './lib/highlightsHelpers'

export const CreateLinkButton = (props) => {
const { shareType, actions, enterpriseEnabled, isFreeArticle } = props

const _canShareWithNonSubscribers = canShareWithNonSubscribers(props)
const _isNonSubscriberOption = isNonSubscriberOption(props)

export const CreateLinkButton = ({ shareType, actions, enterpriseEnabled }) => {
const createLinkHandler = async () => {
switch (shareType) {
case ShareType.gift:
Expand All @@ -20,14 +26,15 @@ export const CreateLinkButton = ({ shareType, actions, enterpriseEnabled }) => {
}
return (
<button
disabled={!_canShareWithNonSubscribers && _isNonSubscriberOption && !isFreeArticle}
id="create-link-button"
className={`o-buttons o-buttons--big o-buttons--primary share-article-dialog__create-link-button ${
enterpriseEnabled ? 'o-buttons--professional' : ''
}`}
data-trackable={shareType + 'Link'}
onClick={createLinkHandler}
>
Share
Get sharing link
</button>
)
}
40 changes: 19 additions & 21 deletions components/x-gift-article/src/FooterMessage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,30 +12,20 @@ export const FooterMessage = ({
enterpriseRequestAccess,
includeHighlights,
isFreeArticle,
showFreeArticleAlert
showFreeArticleAlert,
advancedSharingArticlesBudget,
isRegisteredUser
}) => {
// if the share link button has not been clicked yet
if (!(isGiftUrlCreated || isNonGiftUrlShortened)) {
// when the user is b2b and has advanced sharing enabled
if (enterpriseEnabled && !enterpriseRequestAccess) {
return (
<div className="share-article-dialog__footer-message">
<a
className="o-typography-professional o-typography-link share-article-dialog__footer-message"
href="https://enterprise.ft.com/ft-enterprise-sharing-trial"
target="_blank"
rel="noreferrer"
data-trackable="learn-more"
>
Tell me more about Advanced Sharing
</a>
</div>
)
return null
}

return enterpriseEnabled ? ( // when the user is b2b
<p className="share-article-dialog__footer-message">
Send to multiple people with{' '}
Share with multiple non-subscribers via{' '}
<a
className="o-typography-professional o-typography-link"
href="https://professional.ft.com/advanced-sharing-request-access"
Expand All @@ -50,22 +40,26 @@ export const FooterMessage = ({
}

// when the share link has been created
if (isRegisteredUser) {
return null
}

if (isFreeArticle) {
return !showFreeArticleAlert ? (
<p className="share-article-dialog__footer-message-shared-link">
Anyone will be able to see the full article using this link.
Anyone will be able to see the full article using this link.{' '}
{includeHighlights ? 'Your highlights will be visible to recipients.' : ''}
</p>
) : null
}

if (shareType === ShareType.gift) {
const redemptionLimitUnit = redemptionLimit === 1 ? 'time' : 'times'
const creditUnit = giftCredits === 1 ? 'credit' : 'credits'
const creditUnit = giftCredits === 1 ? 'article' : 'articles'
const redemptionLimitMessage = `Link can be viewed ${redemptionLimit} ${redemptionLimitUnit} and is valid for 90 days. ${
includeHighlights ? 'Your highlights will be visible to recipients.' : ''
}`
const creditsMessage = `You still have ${giftCredits} ${creditUnit} left this month.`
const creditsMessage = `You now have ${giftCredits} gift ${creditUnit} remaining this month.`

return (
<div className="share-article-dialog__footer-message-shared-link">
Expand All @@ -80,21 +74,25 @@ export const FooterMessage = ({
includeHighlights ? 'Your highlights will be visible to recipients.' : ''
}`
return (
<p className="share-article-dialog__footer-message-shared-link">{advancedSharingFTsubscribersOnlyMessage}</p>
<p className="share-article-dialog__footer-message-shared-link">
{advancedSharingFTsubscribersOnlyMessage}
</p>
)
}

if (shareType === ShareType.enterprise) {
const advancedSharingLimitUnit = enterpriseLimit === 1 ? 'time' : 'times'
const advancedSharingLimitMessage = `Link can be viewed ${enterpriseLimit} ${advancedSharingLimitUnit}. ${
const advancedSharingLimitMessage = `Because you used Advanced Sharing, this shared article can be viewed ${enterpriseLimit} ${advancedSharingLimitUnit}. ${
includeHighlights ? 'Your highlights will be visible to recipients.' : ''
}`

return (
<div className="share-article-dialog__footer-message-shared-link">
<p>{advancedSharingLimitMessage}</p>
<p>
We’ve added this link to your list.{' '}
Your organisation can still share {advancedSharingArticlesBudget} articles via Advanced Sharing.
</p>
<p>
<a
className="o-typography-professional o-typography-link"
href="https://enterprise-sharing-dashboard.ft.com"
Expand Down
28 changes: 23 additions & 5 deletions components/x-gift-article/src/GiftArticle.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ const withGiftFormActions = withActions(
return updaters.showGiftEnterpriseSection
},

showNonSubscriberSharingOptions() {
return updaters.showNonSubscriberSharingOptions
},

showNonGiftUrlSection() {
return updaters.showNonGiftUrlSection
},
Expand All @@ -40,8 +44,8 @@ const withGiftFormActions = withActions(
return updaters.showAdvancedSharingOptions
},

hideAdvancedSharingOptions() {
return updaters.hideAdvancedSharingOptions
hideNonSubscriberSharingOptions() {
return updaters.hideNonSubscriberSharingOptions
},

async createGiftUrl() {
Expand Down Expand Up @@ -175,13 +179,25 @@ const withGiftFormActions = withActions(

activate() {
return async (state) => {
const { enabled, limit, hasCredits, requestAccess } =
const { enabled, limit, hasCredits, requestAccess, budget, isRegisteredUser } =
await enterpriseApi.getEnterpriseArticleAllowance()

const advancedSharingEnabled = enabled && !requestAccess

const enterpriseState = {
enterpriseLimit: limit,
isRegisteredUser: isRegisteredUser,
enterpriseHasCredits: hasCredits,
enterpriseRequestAccess: requestAccess
enterpriseRequestAccess: requestAccess,
showAdvancedSharingOptions: advancedSharingEnabled,
showNonSubscriberOptions: !advancedSharingEnabled,
advancedSharingArticlesBudget: budget,
shareType:
initialProps.isFreeArticle || isRegisteredUser
? ShareType.nonGift
: advancedSharingEnabled && hasCredits
? ShareType.enterprise
: ShareType.gift
}

if (enabled) {
Expand All @@ -208,6 +224,7 @@ const withGiftFormActions = withActions(
Object.assign(freeArticleState, updaters.setShortenedNonGiftUrl(url)(state))
freeArticleState.showFreeArticleAlert = true
}

return freeArticleState
} else {
const { giftCredits, monthlyAllowance, nextRenewalDate } = await api.getGiftArticleAllowance()
Expand Down Expand Up @@ -288,7 +305,7 @@ const withGiftFormActions = withActions(
userIsAHighlightsRecipient && userHasNotYetSavedSharedAnnotations && highlightsHaveNotBeenRemoved

const initialState = {
title: 'Share this article:',
title: 'Share this article with:',
giftCredits: undefined,
monthlyAllowance: undefined,
showCopyButton: isCopySupported,
Expand All @@ -297,6 +314,7 @@ const withGiftFormActions = withActions(
isNonGiftUrlShortened: false,
includeHighlights: false,
showAdvancedSharingOptions: false,
showNonSubscriberOptions: false,
hasHighlights: false,
showHighlightsRecipientMessage,
showHighlightsSuccessMessage: false,
Expand Down
14 changes: 13 additions & 1 deletion components/x-gift-article/src/GiftLinkSection.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,17 @@ import { ShareType } from './lib/constants'
import { UrlSection } from './UrlSection'
import { CreateLinkButton } from './CreateLinkButton'
import { FreeArticleAlert } from './FreeArticleAlert'
import { ReceivedHighlightsAlert } from './ReceivedHighlightsAlert'
import { IncludeHighlights } from './IncludeHighlights'

export const GiftLinkSection = (props) => {
const { isGiftUrlCreated, shareType, isNonGiftUrlShortened, showFreeArticleAlert } = props
const {
isGiftUrlCreated,
shareType,
isNonGiftUrlShortened,
showFreeArticleAlert,
showHighlightsRecipientMessage
} = props

// when the gift url is created or the non-gift url is shortened, show the url section
if (
Expand All @@ -20,6 +28,10 @@ export const GiftLinkSection = (props) => {
<div>
{showFreeArticleAlert && <FreeArticleAlert />}
{!showFreeArticleAlert && <SharedLinkTypeSelector {...props} />}
{showHighlightsRecipientMessage && <ReceivedHighlightsAlert {...props} />}

<IncludeHighlights {...props} />

<CreateLinkButton {...props} />
</div>
)
Expand Down
12 changes: 2 additions & 10 deletions components/x-gift-article/src/Header.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
import { h } from '@financial-times/x-engine'
import { ShareType } from './lib/constants'

export const Header = ({
title,
article,
isGiftUrlCreated,
shareType,
isNonGiftUrlShortened,
showFreeArticleAlert
}) => {
export const Header = (props) => {
const { title, isGiftUrlCreated, shareType, isNonGiftUrlShortened, showFreeArticleAlert } = props
// when a gift link is created or shortened, the title is "Sharing link"
if (
isGiftUrlCreated ||
Expand All @@ -21,12 +15,10 @@ export const Header = ({
)
}

// when a gift link is not created, the title should be "Share this article:"
return (
<header>
<h3 className="share-article-dialog__header">
<span className="share-article-dialog__header-share-article-title">{title}</span>
<span className="share-article-dialog__header-article-title">{article.title}</span>
</h3>
</header>
)
Expand Down
Loading

0 comments on commit fc9d7ea

Please sign in to comment.