Permalink
Browse files

Featured experiments (#3114)

* Pontoon: Update Czech (cs) localization of Test Pilot Website

Localization authors:
- Michal Stanke <mstanke@mozilla.cz>

* setup structural html for featured experiments

* add news feed page, more styling for featured experiment

- created newsFeedPage including boilerplate files for tests and stories
- updated header to include news feed link
- little more work on featured experiment css and layout

* Featured Experiment style/layout tweaks, privacy note, install btn

* more css updates, platforms tweaks and componentize Measurements
- pull Measurments section into it's own component
- fix experiment platform selector
- add white icons for platform selector in featured experiments
- more css tweaks to featured experiment and update list

* manage/feedback buttons and news feed experiment icon colors

* set cookie when visiting the news feed page

* add "new" flag to updates, tweak css, add active state to header link

* add featured experiment selectors, yml prop ref etc..

* minor cleanups for wip pr

* Add legal modal

* wip add tour dialog to featured experiments

* Breaking featuredButton and featuredStatus out into components

* Finish adding tour dialog to feature experiment component

* Get tests to pass

* Update mobile views, Add stories, Add tests, cleanup

* remove excess experimentTourDialog from experimentpage folder (borked in rebase

* modify newsFeedActive check in header for some tests

* add back failOnError option to watching linter

* remove extra image and commented CSP for dev

* remove accidental added dependency and package-lock

* fix flowtype errors

* Pontoon: Update Georgian (ka) localization of Test Pilot Website

Localization authors:
- Georgianizator <georgianization@outlook.com>

* Pontoon: Update Georgian (ka) localization of Test Pilot Website

Localization authors:
- Georgianizator <georgianization@outlook.com>

* fix .secondary button background after recent color changes

* Pontoon: Update Albanian (sq) localization of Test Pilot Website

Localization authors:
- Besnik Bleta <besnik@programeshqip.org>

* Pontoon: Update Albanian (sq) localization of Test Pilot Website

Localization authors:
- Besnik Bleta <besnik@programeshqip.org>

* Pontoon: Update Albanian (sq) localization of Test Pilot Website

Localization authors:
- Besnik Bleta <besnik@programeshqip.org>

* Pontoon: Update Albanian (sq) localization of Test Pilot Website

Localization authors:
- Besnik Bleta <besnik@programeshqip.org>

* Pontoon: Update Albanian (sq) localization of Test Pilot Website

Localization authors:
- Besnik Bleta <besnik@programeshqip.org>

* Pontoon: Update Albanian (sq) localization of Test Pilot Website

Localization authors:
- Besnik Bleta <besnik@programeshqip.org>

* Pontoon: Update Albanian (sq) localization of Test Pilot Website

Localization authors:
- Besnik Bleta <besnik@programeshqip.org>

* Pontoon: Update Albanian (sq) localization of Test Pilot Website

Localization authors:
- Besnik Bleta <besnik@programeshqip.org>

* Pontoon: Update Albanian (sq) localization of Test Pilot Website

Localization authors:
- Besnik Bleta <besnik@programeshqip.org>

* Pontoon: Update Albanian (sq) localization of Test Pilot Website

Localization authors:
- Besnik Bleta <besnik@programeshqip.org>

* Pontoon: Update Albanian (sq) localization of Test Pilot Website

Localization authors:
- Besnik Bleta <besnik@programeshqip.org>

* Pontoon: Update Albanian (sq) localization of Test Pilot Website

Localization authors:
- Besnik Bleta <besnik@programeshqip.org>

* Pontoon: Update Albanian (sq) localization of Test Pilot Website

Localization authors:
- Besnik Bleta <besnik@programeshqip.org>

* Pontoon: Update Turkish (tr) localization of Test Pilot Website

Localization authors:
- Selim Şumlu <selim@sum.lu>

* Pontoon: Update Turkish (tr) localization of Test Pilot Website

Localization authors:
- Selim Şumlu <selim@sum.lu>

* Pontoon: Update Turkish (tr) localization of Test Pilot Website

Localization authors:
- Selim Şumlu <selim@sum.lu>
- Ali Demirtaş <alidemirtas94@gmail.com>

* Pontoon: Update Turkish (tr) localization of Test Pilot Website

Localization authors:
- Selim Şumlu <selim@sum.lu>

* Pontoon: Update Norwegian Nynorsk (nn-NO) localization of Test Pilot Website

Localization authors:
- Bjørn I. <bjorn.svindseth@online.no>

* Pontoon: Update Norwegian Nynorsk (nn-NO) localization of Test Pilot Website

Localization authors:
- Bjørn I. <bjorn.svindseth@online.no>

* Address nits from pr review...

- pull justLaunched and justUpdated out into their own file to keep
things DRY.
- remove setExperiementLastSeen and getExperimentLastSeen and all
references.
- added more tests

* Address issue with enabled label on tour header

- refs #3149

* update is_featured code snippet from reference.md

* update is_featured code snippet from reference.md

* fixall the styles (#3155)

* setup structural html for featured experiments

* add news feed page, more styling for featured experiment

- created newsFeedPage including boilerplate files for tests and stories
- updated header to include news feed link
- little more work on featured experiment css and layout

* Featured Experiment style/layout tweaks, privacy note, install btn

* more css updates, platforms tweaks and componentize Measurements
- pull Measurments section into it's own component
- fix experiment platform selector
- add white icons for platform selector in featured experiments
- more css tweaks to featured experiment and update list

* manage/feedback buttons and news feed experiment icon colors

* set cookie when visiting the news feed page

* add "new" flag to updates, tweak css, add active state to header link

* add featured experiment selectors, yml prop ref etc..

* minor cleanups for wip pr

* Add legal modal

* wip add tour dialog to featured experiments

* Breaking featuredButton and featuredStatus out into components

* Finish adding tour dialog to feature experiment component

* Get tests to pass

* Update mobile views, Add stories, Add tests, cleanup

* remove excess experimentTourDialog from experimentpage folder (borked in rebase

* modify newsFeedActive check in header for some tests

* add back failOnError option to watching linter

* remove extra image and commented CSP for dev

* remove accidental added dependency and package-lock

* fix flowtype errors

* fix .secondary button background after recent color changes

* Address nits from pr review...

- pull justLaunched and justUpdated out into their own file to keep
things DRY.
- remove setExperiementLastSeen and getExperimentLastSeen and all
references.
- added more tests

* Address issue with enabled label on tour header

- refs #3149

* update is_featured code snippet from reference.md

* update is_featured code snippet from reference.md

* fixall the styles (#3155)
  • Loading branch information...
meandavejustice authored and johngruen committed Dec 21, 2017
1 parent 396101f commit 17c86e7b049c78b8cbebdfef1fa46801d99183f4
Showing with 2,066 additions and 557 deletions.
  1. +1 −0 .gitignore
  2. +8 −0 docs/content/reference.md
  3. +1 −1 docs/content/template.yaml
  4. +3 −3 frontend/src/app/components/Banner/index.scss
  5. +4 −6 frontend/src/app/components/Copter/index.scss
  6. +1 −1 frontend/src/app/components/EmailDialog/index.scss
  7. +0 −1 frontend/src/app/components/ExperimentCardList/stories.js
  8. +0 −1 frontend/src/app/components/ExperimentCardList/tests.js
  9. +0 −1 frontend/src/app/components/ExperimentPlatforms/index.scss
  10. +10 −40 frontend/src/app/components/ExperimentRowCard/index.js
  11. +19 −17 frontend/src/app/components/ExperimentRowCard/index.scss
  12. +0 −3 frontend/src/app/components/ExperimentRowCard/stories.js
  13. +2 −17 frontend/src/app/components/ExperimentRowCard/tests.js
  14. +7 −13 ...pp/{containers/ExperimentPage/ExperimentTourDialog.js → components/ExperimentTourDialog/index.js}
  15. +104 −0 frontend/src/app/components/ExperimentTourDialog/stories.js
  16. +116 −0 frontend/src/app/components/ExperimentTourDialog/tests.js
  17. +135 −0 frontend/src/app/components/FeaturedExperiment/FeaturedButton.js
  18. +42 −0 frontend/src/app/components/FeaturedExperiment/FeaturedStatus.js
  19. +4 −0 frontend/src/app/components/FeaturedExperiment/img/experiment-type-addon-white.svg
  20. +4 −0 frontend/src/app/components/FeaturedExperiment/img/experiment-type-mobile-white.svg
  21. +3 −0 frontend/src/app/components/FeaturedExperiment/img/experiment-type-web-white.svg
  22. +114 −0 frontend/src/app/components/FeaturedExperiment/index.js
  23. +307 −0 frontend/src/app/components/FeaturedExperiment/index.scss
  24. +119 −0 frontend/src/app/components/FeaturedExperiment/stories.js
  25. +268 −0 frontend/src/app/components/FeaturedExperiment/tests.js
  26. +2 −2 frontend/src/app/components/Footer/index.scss
  27. +13 −13 frontend/src/app/components/GraduatedNotice/index.scss
  28. +12 −0 frontend/src/app/components/Header/index.js
  29. +11 −5 frontend/src/app/components/Header/index.scss
  30. +5 −0 frontend/src/app/components/Header/tests.js
  31. +40 −16 frontend/src/app/components/MainInstallButton/index.js
  32. +1 −1 frontend/src/app/components/MainInstallButton/index.scss
  33. +2 −12 frontend/src/app/components/MainInstallButton/tests.js
  34. +79 −0 frontend/src/app/components/Measurements/index.js
  35. +4 −3 frontend/src/app/components/Modal/index.js
  36. +22 −18 frontend/src/app/components/Modal/index.scss
  37. +2 −3 frontend/src/app/components/NewsUpdatesDialog/index.scss
  38. +10 −7 frontend/src/app/components/NewsletterFooter/index.scss
  39. +24 −15 frontend/src/app/components/NewsletterForm/index.scss
  40. +0 −1 frontend/src/app/components/PastExperiments/stories.js
  41. +1 −1 frontend/src/app/components/RetireConfirmationDialog/index.js
  42. +10 −10 frontend/src/app/components/StepModal/index.scss
  43. +24 −7 frontend/src/app/components/UpdateList/index.js
  44. +57 −38 frontend/src/app/components/UpdateList/index.scss
  45. +3 −1 frontend/src/app/components/types.js
  46. +5 −15 frontend/src/app/containers/App/index.js
  47. +1 −1 frontend/src/app/containers/ExperimentPage/DetailsDescription.js
  48. +2 −70 frontend/src/app/containers/ExperimentPage/DetailsOverview.js
  49. +1 −6 frontend/src/app/containers/ExperimentPage/index.js
  50. +16 −15 frontend/src/app/containers/ExperimentPage/index.scss
  51. +0 −15 frontend/src/app/containers/ExperimentPage/stories.js
  52. +0 −114 frontend/src/app/containers/ExperimentPage/tests.js
  53. +0 −7 frontend/src/app/containers/ExperimentPage/types.js
  54. +36 −13 frontend/src/app/containers/HomePageNoAddon.js
  55. +32 −10 frontend/src/app/containers/HomePageWithAddon.js
  56. +1 −1 frontend/src/app/containers/LegacyPage/index.scss
  57. +41 −0 frontend/src/app/containers/NewsFeedPage/index.js
  58. +80 −0 frontend/src/app/containers/NewsFeedPage/index.scss
  59. +27 −0 frontend/src/app/containers/NewsFeedPage/stories.js
  60. +39 −0 frontend/src/app/containers/NewsFeedPage/tests.js
  61. +2 −2 frontend/src/app/containers/NotFoundPage.js
  62. +1 −1 frontend/src/app/containers/RetirePage/index.js
  63. +2 −2 frontend/src/app/containers/RetirePage/index.scss
  64. +8 −6 frontend/src/app/containers/SharePage/index.scss
  65. +3 −1 frontend/src/app/index.js
  66. +8 −7 frontend/src/app/lib/InstallManager.js
  67. +28 −0 frontend/src/app/lib/experiment.js
  68. +10 −1 frontend/src/app/selectors/experiment.js
  69. +20 −0 frontend/src/images/star.svg
  70. +8 −0 frontend/src/pages/news.js
  71. +4 −5 frontend/src/styles/_buttons.scss
  72. +12 −0 frontend/src/styles/_theme.scss
  73. +1 −0 frontend/tasks/styles.js
  74. +10 −0 frontend/test/app/containers/HomePageNoAddon-test.js
  75. +15 −4 frontend/test/app/containers/HomePageWithAddon-test.js
  76. +43 −0 frontend/test/app/lib/experiment-test.js
  77. +12 −1 frontend/test/app/selectors/experiment-test.js
  78. +4 −3 locales/en-US/app.ftl
View
@@ -34,3 +34,4 @@ addon/locale/
addon/*.rdf
addon/*.xpi
legal-copy/*html
@@ -111,6 +111,14 @@ The order in which the experiment will appear. Lower numbers appear first. Requi
order: 0
```
## `is_featured`
Determines whether the experiment will be featured on the home page. Optional.
```yaml
is_featured: false
```
## `description`
A short description of the experiment, used for search engines, social media shares, and in the experiment card. Localized, required, HTML not allowed.
@@ -3,7 +3,7 @@ slug: experiment-name
title: 'Experiment Name'
subtitle: 'Powered by a Yellow Submarine'
order: 0
is_featured: false
platforms: ['addon']
web_url: https://example.com/web-experiment
@@ -25,8 +25,8 @@
}
font-size: $font-unit * 1.833;
line-height: $font-unit * 2.583;
font-weight: 200;
line-height: $font-unit * 2.583;
}
.banner__title {
@@ -41,9 +41,9 @@
}
font-size: $grid-unit * 2;
line-height: $grid-unit * 2.3;
font-style: oblique;
font-weight: 300;
line-height: $grid-unit * 2.3;
}
.banner__subtitle {
@@ -92,7 +92,7 @@
}
.banner--expanded {
padding: $grid-unit * 2 64px;
padding: $grid-unit * 2 0;
.banner__title {
@include respond-to('small') {
@@ -21,8 +21,6 @@
}
.copter__inner {
background-image: url('./img/copter.png');
background-size: 250px 201px;
@include respond-to ('big') {
height: 265px;
width: 345px;
@@ -40,8 +38,10 @@
width: 183px;
}
background-image: url('./img/copter.png');
background-position: center center;
background-repeat: no-repeat;
background-size: 250px 201px;
margin: 0 auto;
position: relative;
top: 0;
@@ -71,9 +71,6 @@
}
.copter__inner {
background-image: url('./img/copter.png');
background-size: auto $grid-unit * 10;
@include respond-to('not-small') {
height: $grid-unit * 10;
width: $grid-unit * 12.5;
@@ -85,9 +82,10 @@
width: 184px;
}
background-image: url('./img/copter.png');
background-position: center center;
background-repeat: no-repeat;
background-size: $grid-unit * 12.5 $grid-unit * 10;
background-size: auto $grid-unit * 10;
filter: drop-shadow(0 0 20px $transparent-black-1);
margin: 0 auto;
@@ -1,6 +1,6 @@
.envelope {
background-image: url('../../../images/envelope.svg');
background-repeat: no-repeat;
background-repeat: no-repeat;
background-size: contain;
height: 80px;
margin: 30px auto 20px;
@@ -32,7 +32,6 @@ const baseProps = {
isFirefox: true,
isMinFirefox: true,
eventCategory: 'storybook',
getExperimentLastSeen: () => Date.now(),
isAfterCompletedDate: () => false,
isExperimentEnabled: (e) => e.enabled === true,
sendToGA: action('sendToGA'),
@@ -19,7 +19,6 @@ describe('app/components/ExperimentCardList', () => {
// required by ExperimentRowCard {...this.props}
hasAddon: true,
eventCategory: 'test category',
getExperimentLastSeen: sinon.spy(),
sendToGA: sinon.spy(),
navigateTo: sinon.spy()
};
@@ -38,4 +38,3 @@
background-image: url('./img/experiment-type-mobile.svg');
}
}
@@ -5,6 +5,7 @@ import { Localized } from 'fluent-react/compat';
import React from 'react';
import { buildSurveyURL, experimentL10nId } from '../../lib/utils';
import { justUpdated, justLaunched } from '../../lib/experiment';
import './index.scss';
@@ -14,8 +15,6 @@ import ExperimentPlatforms from '../ExperimentPlatforms';
const ONE_DAY = 24 * 60 * 60 * 1000;
const ONE_WEEK = 7 * ONE_DAY;
const MAX_JUST_LAUNCHED_PERIOD = 2 * ONE_WEEK;
const MAX_JUST_UPDATED_PERIOD = 2 * ONE_WEEK;
type ExperimentRowCardProps = {
experiment: Object,
@@ -26,7 +25,6 @@ type ExperimentRowCardProps = {
installed: InstalledExperiments,
clientUUID: ?string,
eventCategory: string,
getExperimentLastSeen: Function,
sendToGA: Function,
navigateTo: Function,
isAfterCompletedDate: Function
@@ -46,23 +44,28 @@ export default class ExperimentRowCard extends React.Component {
const { description, title, subtitle, slug } = experiment;
const isCompleted = isAfterCompletedDate(experiment);
// enabled trumps justUpdated
const updated = enabled ? false : justUpdated(experiment);
// justUpdated and enabled trump justLaunched
const launched = (enabled || updated) ? false : justLaunched(experiment);
return (
<a href={`/experiments/${slug}`} onClick={() => this.openDetailPage()}
className={classnames('experiment-summary', {
enabled,
'just-launched': this.justLaunched(),
'just-updated': this.justUpdated(),
'just-launched': launched,
'just-updated': updated,
'has-addon': hasAddon
})}
>
<div className="experiment-actions">
{enabled && <Localized id="experimentListEnabledTab">
<div className="tab enabled-tab">Enabled</div>
</Localized>}
{this.justLaunched() && <Localized id="experimentListJustLaunchedTab">
{launched && <Localized id="experimentListJustLaunchedTab">
<div className="tab just-launched-tab">Just Launched</div>
</Localized>}
{this.justUpdated() && <Localized id="experimentListJustUpdatedTab">
{updated && <Localized id="experimentListJustUpdatedTab">
<div className="tab just-updated-tab">Just Updated</div>
</Localized>}
</div>
@@ -148,39 +151,6 @@ export default class ExperimentRowCard extends React.Component {
);
}
justUpdated() {
const { experiment, enabled, getExperimentLastSeen } = this.props;
// Enabled trumps launched.
if (enabled) { return false; }
// If modified awhile ago, don't consider it "just" updated.
const now = Date.now();
const modified = (new Date(experiment.modified)).getTime();
if ((now - modified) > MAX_JUST_UPDATED_PERIOD) { return false; }
// If modified since the last time seen, *do* consider it updated.
if (modified > getExperimentLastSeen(experiment)) { return true; }
// All else fails, don't consider it updated.
return false;
}
justLaunched() {
const { experiment, enabled } = this.props;
// Enabled & updated trumps launched.
if (enabled || this.justUpdated()) { return false; }
// If created awhile ago, don't consider it "just" launched.
const now = Date.now();
const created = (new Date(experiment.created)).getTime();
if ((now - created) > MAX_JUST_LAUNCHED_PERIOD) { return false; }
// All else fails, don't consider it launched.
return true;
}
statusMsg() {
const { experiment } = this.props;
@@ -1,6 +1,8 @@
@import '~photon-colors/colors.scss';
@import '../../../styles/_utils';
$tab-border-color: rgb(58, 133, 36);
.experiment-summary {
@include flex-container(column, flex-start, stretch);
@@ -22,7 +24,7 @@
margin-left: auto;
margin-right: auto;
max-width: 100%;
min-width: 300px;
min-width: 280px;
width: 98%;
}
@@ -89,9 +91,9 @@
}
p {
color: $grey-90;
flex: 1;
font-size: 14px;
color: $grey-90;
line-height: 22px;
margin: 0 0 $grid-unit * .5;
}
@@ -118,22 +120,22 @@
}
.tab {
border-style: solid;
border-width: 1px;
border-color: rgb(58, 133, 36);
border-color: $tab-border-color;
border-radius: $small-border-radius;
border-style: solid;
border-width: 1px;
display: inline-block;
font-weight: 600;
font-size: 11px;
font-weight: 600;
height: $grid-unit * 1.2;
top: -5px;
left: -5px;
line-height: $grid-unit * 1.2;
outline: none;
padding: 0 7px;
position: absolute;
text-align: center;
text-decoration: none;
top: -5px;
transition: background 150ms;
white-space: nowrap;
z-index: 99999;
@@ -146,14 +148,14 @@
.enabled-tab::before {
background-image: url('./img/check.svg');
background-position: center 2px;
background-repeat: no-repeat;
background-size: contain;
content: '';
display: inline-block;
height: 14px;
width: 14px;
margin-right: 5px;
background-size: contain;
background-position: center 2px;
background-repeat: no-repeat;
width: 14px;
}
.just-launched-tab {
@@ -163,13 +165,13 @@
.just-launched-tab::before {
background-image: url('./img/star.svg');
position: relative;
top: 2px;
content: '';
display: inline-block;
height: 16px;
width: 16px;
margin-right: 4px;
position: relative;
top: 2px;
width: 16px;
}
.just-updated-tab {
@@ -179,13 +181,13 @@
.just-updated-tab::before {
background-image: url('./img/star.svg');
position: relative;
top: 2px;
content: '';
display: inline-block;
height: 16px;
width: 16px;
margin-right: 4px;
position: relative;
top: 2px;
width: 16px;
}
}
@@ -27,7 +27,6 @@ const baseProps = {
isMinFirefox: true,
experiment: experiment,
eventCategory: 'storybook',
getExperimentLastSeen: () => Date.now(),
isAfterCompletedDate: () => false,
sendToGA: action('sendToGA'),
navigateTo: action('navigateTo'),
@@ -63,14 +62,12 @@ storiesOf('ExperimentRowCard', module)
<ExperimentRowCard
{...baseProps}
experiment={{ ...experiment, created: Date.now() }}
getExperimentLastSeen={() => 0}
/>
)
.add('just updated', () =>
<ExperimentRowCard
{...baseProps}
experiment={{ ...experiment, created: Date.now(), modified: Date.now() }}
getExperimentLastSeen={() => 0}
/>
)
.add('has addon & enabled', () =>
Oops, something went wrong.

0 comments on commit 17c86e7

Please sign in to comment.