forked from mozilla/testpilot
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Issue mozilla#2807: Progress toward extracting DetailsOverview and De…
…tailsDescription
- Loading branch information
Showing
4 changed files
with
550 additions
and
254 deletions.
There are no files selected for viewing
119 changes: 119 additions & 0 deletions
119
frontend/src/app/containers/ExperimentPage/DetailsDescription.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
import React from 'react'; | ||
import parser from 'html-react-parser'; | ||
import { Localized } from 'fluent-react/compat'; | ||
import LocalizedHtml from '../../components/LocalizedHtml'; | ||
|
||
import Warning from '../../components/Warning'; | ||
|
||
import GraduatedNotice from '../../components/GraduatedNotice'; | ||
import EolBlock from './EolBlock'; | ||
import IncompatibleAddons from './IncompatibleAddons'; | ||
import { MeasurementsSection } from './DetailsOverview'; | ||
|
||
export default function DetailsDescription({ | ||
experiment, | ||
graduated, | ||
locale, | ||
hasAddon, | ||
installedAddons, | ||
highlightMeasurementPanel, | ||
l10nId | ||
}) { | ||
const { | ||
introduction, | ||
warning, | ||
details, | ||
measurements, | ||
video_url, | ||
graduation_url, | ||
completed | ||
} = experiment; | ||
return ( | ||
<div className="details-description"> | ||
{completed && !graduated && <EolBlock experiment={experiment} />} | ||
<IncompatibleAddons {...{ experiment, installedAddons }} /> | ||
<LocaleWarning {...{ experiment, locale, hasAddon }} /> | ||
{graduated && <GraduatedNotice {...{ graduated, graduation_url }} />} | ||
|
||
{video_url && | ||
<iframe | ||
width="100%" | ||
height="360" | ||
src={video_url} | ||
frameBorder="0" | ||
allowFullScreen | ||
className="experiment-video" | ||
/>} | ||
<div> | ||
{!!introduction && | ||
<section className="introduction"> | ||
{!!warning && | ||
<div className="warning"> | ||
<Localized id={l10nId('warning')}> | ||
<strong> | ||
{warning} | ||
</strong> | ||
</Localized> | ||
</div>} | ||
<LocalizedHtml id={l10nId('introduction')}> | ||
<div> | ||
{parser(introduction)} | ||
</div> | ||
</LocalizedHtml> | ||
</section>} | ||
</div> | ||
<div className="details-list"> | ||
{details.map(({ image, copy, headline }, idx) => | ||
<div key={idx}> | ||
<div className="details-image"> | ||
<img width="680" src={image} /> | ||
<p className="caption"> | ||
{headline && | ||
<Localized id={l10nId(['details', idx, 'headline'])}> | ||
<strong> | ||
{headline} | ||
</strong> | ||
</Localized>} | ||
{copy && | ||
<Localized id={l10nId(['details', idx, 'copy'])}> | ||
<span> | ||
{parser(copy)} | ||
</span> | ||
</Localized>} | ||
</p> | ||
</div> | ||
</div> | ||
)} | ||
</div> | ||
{hasAddon && | ||
!graduated && | ||
measurements && | ||
<div> | ||
<MeasurementsSection | ||
{...{ ...experiment, highlightMeasurementPanel, l10nId }} | ||
/> | ||
</div>} | ||
</div> | ||
); | ||
} | ||
|
||
export const LocaleWarning = ({ experiment, locale, hasAddon }) => { | ||
const { locales, locale_blocklist } = experiment; | ||
if ( | ||
hasAddon !== null && | ||
locale && | ||
((locales && !locales.includes(locale)) || | ||
(locale_blocklist && locale_blocklist.includes(locale))) | ||
) { | ||
return ( | ||
<Warning | ||
titleL10nId="localeNotTranslatedWarningTitle" | ||
titleL10nArgs={JSON.stringify({ locale_code: locale })} | ||
title="This experiment has not been translated to your language (en)." | ||
subtitleL10nId="localeWarningSubtitle" | ||
subtitle="You can still enable it if you like." | ||
/> | ||
); | ||
} | ||
return null; | ||
}; |
234 changes: 234 additions & 0 deletions
234
frontend/src/app/containers/ExperimentPage/DetailsOverview.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,234 @@ | ||
import React from 'react'; | ||
import classnames from 'classnames'; | ||
import { Localized } from 'fluent-react/compat'; | ||
import LocalizedHtml from '../../components/LocalizedHtml'; | ||
import { experimentL10nId, formatDate } from '../../lib/utils'; | ||
|
||
export default function DetailsOverview({ | ||
experiment, | ||
graduated, | ||
highlightMeasurementPanel, | ||
showTour | ||
}) { | ||
const { slug, thumbnail, measurements } = experiment; | ||
const l10nId = pieces => experimentL10nId(experiment, pieces); | ||
|
||
return ( | ||
<div className="details-overview"> | ||
<div | ||
className={`experiment-icon-wrapper-${slug} experiment-icon-wrapper`} | ||
> | ||
<img className="experiment-icon" src={thumbnail} /> | ||
</div> | ||
<div className="details-sections"> | ||
<section className="user-count"> | ||
<LaunchStatus {...{ experiment, graduated }} /> | ||
</section> | ||
{!graduated && <StatsSection {...{ experiment, showTour }} />} | ||
<ContributorsSection {...{ experiment, l10nId }} /> | ||
{!graduated && | ||
measurements && | ||
<MeasurementsSection | ||
{...{ experiment, l10nId, highlightMeasurementPanel }} | ||
/>} | ||
</div> | ||
</div> | ||
); | ||
} | ||
|
||
export const LaunchStatus = ({ experiment, graduated }) => { | ||
const { created, completed } = experiment; | ||
|
||
const completedDate = formatDate(completed); | ||
if (graduated) { | ||
return ( | ||
<LocalizedHtml id="completedDateLabel" $completedDate={completedDate}> | ||
<span> | ||
Experiment End Date: <b>{completedDate}</b> | ||
</span> | ||
</LocalizedHtml> | ||
); | ||
} | ||
|
||
const startedDate = formatDate(created); | ||
return ( | ||
<LocalizedHtml id="startedDateLabel" $startedDate={startedDate}> | ||
<span> | ||
Experiment Start Date: <b>{startedDate}</b> | ||
</span> | ||
</LocalizedHtml> | ||
); | ||
}; | ||
|
||
export const StatsSection = ({ | ||
showTour, | ||
experiment: { | ||
title, | ||
web_url, | ||
changelog_url, | ||
contribute_url, | ||
bug_report_url, | ||
discourse_url | ||
} | ||
}) => | ||
<div> | ||
<section className="stats-section"> | ||
{!web_url && | ||
<p> | ||
<Localized id="tourLink"> | ||
<a className="showTour" onClick={showTour} href="#"> | ||
Launch Tour | ||
</a> | ||
</Localized> | ||
</p>} | ||
<dl> | ||
{changelog_url && | ||
<Localized id="changelog"> | ||
<dt>Changelog</dt> | ||
</Localized>} | ||
{changelog_url && | ||
<dd> | ||
<a href={changelog_url}> | ||
{changelog_url} | ||
</a> | ||
</dd>} | ||
<Localized id="contribute"> | ||
<dt>Contribute</dt> | ||
</Localized> | ||
<dd> | ||
<a href={contribute_url}> | ||
{contribute_url} | ||
</a> | ||
</dd> | ||
|
||
<Localized id="bugReports"> | ||
<dt>Bug Reports</dt> | ||
</Localized> | ||
<dd> | ||
<a href={bug_report_url}> | ||
{bug_report_url} | ||
</a> | ||
</dd> | ||
|
||
<Localized id="discussExperiment" $title={title}> | ||
<dt> | ||
{title} | ||
</dt> | ||
</Localized> | ||
<dd> | ||
<a href={discourse_url}> | ||
{discourse_url} | ||
</a> | ||
</dd> | ||
</dl> | ||
</section> | ||
</div>; | ||
|
||
export const ContributorsSection = ({ | ||
experiment: { contributors, contributors_extra, contributors_extra_url }, | ||
l10nId | ||
}) => | ||
<section className="contributors-section"> | ||
<Localized id="contributorsHeading"> | ||
<h3>Brought to you by</h3> | ||
</Localized> | ||
<ul className="contributors"> | ||
{contributors.map((contributor, idx) => | ||
<li key={idx}> | ||
<img | ||
className="avatar" | ||
width="56" | ||
height="56" | ||
src={contributor.avatar} | ||
/> | ||
<div className="contributor"> | ||
<p className="name"> | ||
{contributor.display_name} | ||
</p> | ||
{contributor.title && | ||
<Localized id={l10nId(['contributors', idx, 'title'])}> | ||
<p className="title"> | ||
{contributor.title} | ||
</p> | ||
</Localized>} | ||
</div> | ||
</li> | ||
)} | ||
</ul> | ||
{contributors_extra && | ||
<p className="disclaimer"> | ||
<Localized id={l10nId('contributors_extra')}> | ||
<span> | ||
{contributors_extra} | ||
</span> | ||
</Localized> | ||
{contributors_extra_url && | ||
<span> | ||
| ||
<Localized id="contributorsExtraLearnMore"> | ||
<a | ||
href={contributors_extra_url} | ||
target="_blank" | ||
rel="noopener noreferrer" | ||
> | ||
Learn more | ||
</a> | ||
</Localized> | ||
. | ||
</span>} | ||
</p>} | ||
</section>; | ||
|
||
const EXPERIMENT_MEASUREMENT_URLS = [ | ||
null, | ||
null, | ||
null, | ||
'https://www.mozilla.org/privacy/websites' | ||
]; | ||
|
||
export const MeasurementsSection = ({ | ||
experiment: { title, privacy_preamble, privacy_notice_url, measurements }, | ||
highlightMeasurementPanel, | ||
l10nId | ||
}) => | ||
<section | ||
className={classnames('measurements', { | ||
highlight: highlightMeasurementPanel | ||
})} | ||
> | ||
<Localized id="measurements"> | ||
<h3>Your privacy</h3> | ||
</Localized> | ||
<div data-hook="measurements-html" className="measurement"> | ||
{privacy_preamble && | ||
<Localized id={l10nId('privacy_preamble')}> | ||
<p> | ||
{privacy_preamble} | ||
</p> | ||
</Localized>} | ||
<LocalizedHtml id="experimentMeasurementIntro" $experimentTitle={title}> | ||
<p> | ||
In addition to the <a href="/privacy">data</a> collected by all Test | ||
Pilot experiments, here are the key things you should know about what | ||
is happening when you use {title}: | ||
</p> | ||
</LocalizedHtml> | ||
<ul> | ||
{measurements.map((note, idx) => | ||
<LocalizedHtml key={idx} id={l10nId(['measurements', idx])}> | ||
<li> | ||
{EXPERIMENT_MEASUREMENT_URLS[idx] === null | ||
? null | ||
: <a href={EXPERIMENT_MEASUREMENT_URLS[idx]} />} | ||
</li> | ||
</LocalizedHtml> | ||
)} | ||
</ul> | ||
</div> | ||
{privacy_notice_url && | ||
<Localized id="experimentPrivacyNotice" $title={title}> | ||
<a className="privacy-policy" href={privacy_notice_url}> | ||
You can learn more about the data collection for {title} here. | ||
</a> | ||
</Localized>} | ||
</section>; |
Oops, something went wrong.