Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce Site Review to the Onboarding Wizard #6596

Merged
merged 68 commits into from
Sep 29, 2021
Merged
Show file tree
Hide file tree
Changes from 67 commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
5331957
Update "Welcome" step copy
delawski Aug 18, 2021
9e51bb0
Update plugin name copy and color
delawski Aug 18, 2021
8386e12
Determine active page index based on current page kept in state
delawski Aug 18, 2021
a01a728
Combine Summary and Done steps of Wizard into single step
delawski Aug 18, 2021
a08ada3
Use uniform name for Review (final) step in Onboarding Wizard
delawski Aug 18, 2021
bad4a5d
Remove unused code
delawski Aug 18, 2021
4e055c2
Ensure saving message is displayed as long as there are unsaved options
delawski Aug 19, 2021
0fb717d
Use grid layout for review step and update content hierarchy
delawski Aug 19, 2021
0f8e477
Add preview page and mode selector to Review step
delawski Aug 19, 2021
f43b496
Extract preview to separate component; add loading state
delawski Aug 19, 2021
223ebbb
Refactor `RadioGroup` into stand-alone component
delawski Aug 20, 2021
ce7355b
Improve Review site Onboarding step styles
delawski Aug 23, 2021
3adf5e8
Add links to "Need help" section in "Review" step
delawski Aug 23, 2021
d9514fd
Update "Review" step E2E test specs
delawski Aug 23, 2021
9e18a60
Update copy and typography
delawski Aug 26, 2021
2abc53a
Replace radio buttons with toggle for preview mode
delawski Aug 26, 2021
fd7bf06
Update `RadioGroup` typography
delawski Aug 26, 2021
56251e4
Update E2E tests
delawski Aug 26, 2021
26adfde
Add "Review" section to Settings page
delawski Aug 26, 2021
33a3fb1
Update unit tests
delawski Aug 26, 2021
19221b2
Use more specific name for `SiteReview` component
delawski Sep 2, 2021
d300c58
Add "Browse Site" button to AMP Settings page
delawski Sep 2, 2021
13d25db
Prevent nesting HTML headings
delawski Sep 2, 2021
b39d1fb
Add E2E test for Review section on Settings page
delawski Sep 2, 2021
9cf7955
Add basic dismiss functionality to site Review section
delawski Sep 2, 2021
aeed6b1
Add user meta and REST field for Review panel `is_dismissed` state
delawski Sep 3, 2021
2643dc8
Remove rebase artifact
delawski Sep 3, 2021
d9986e0
Use Review panel dismiss state from user meta on Settings screen
delawski Sep 3, 2021
b19ddd2
Move "Review" panel dismissal logic to client-side
delawski Sep 3, 2021
ed5ffa0
Add E2E tests for "Review" panel on AMP settings page
delawski Sep 6, 2021
3f19a16
Make Review panel dismissal state property optional
delawski Sep 6, 2021
af4ae27
Clean up and add unit tests
delawski Sep 6, 2021
675d471
Remove unused components
delawski Sep 6, 2021
1a2b37e
Update copy and styles
delawski Sep 7, 2021
4bfcd7c
Rename "Review" step to "Done" in OW and update copy
delawski Sep 7, 2021
cfed267
Fix E2E tests
delawski Sep 7, 2021
1c64c94
Ensure stroke width is proportional to icon size
delawski Sep 8, 2021
f3dc3db
Convert `RadioGroup` into `NavMenu`
delawski Sep 8, 2021
3319a69
Update snapshots
delawski Sep 8, 2021
a981978
Update copy in Review panel on AMP Settings screen
delawski Sep 8, 2021
208c7ab
Use constants for checking theme support / template mode
delawski Sep 8, 2021
b36aefb
Fix PHPCS issues
delawski Sep 8, 2021
09495f4
Fix stylelint issues
delawski Sep 8, 2021
1ad8dda
Move User REST extension to separate file; add tests
delawski Sep 8, 2021
dc0c57c
Ensure site Review panel shows up before proceeding
delawski Sep 8, 2021
f27c3f8
Fix phpcs issues
delawski Sep 8, 2021
7a788c6
Try fixing flaky E2E test
delawski Sep 15, 2021
5801497
Delete amp_review_panel_dismissed_for_template_mode usermeta at unins…
westonruter Sep 28, 2021
4ea2c30
Let UserRESTEndpointExtension be Delayed
westonruter Sep 28, 2021
7359d55
Apply suggestions from code review
delawski Sep 28, 2021
28b4583
Bump selector specificity so that no space is reserved for admin bar
delawski Sep 28, 2021
680b746
Use `enum` for review panel dismissed for template mode REST param va…
delawski Sep 28, 2021
eca7274
Determine preview pages labels on backend
delawski Sep 28, 2021
8797e8d
Bring back ability to clear review panel dismissed for template mode …
delawski Sep 28, 2021
19fccbf
Update E2E tests
delawski Sep 28, 2021
6cea324
Update unit test
delawski Sep 28, 2021
c53e449
Update unit test
delawski Sep 28, 2021
308cd1f
Fix PHPCS issues
delawski Sep 28, 2021
7f82ec9
Apply suggestions from code review
delawski Sep 29, 2021
d4ff14b
Unify code style
delawski Sep 29, 2021
16f6707
Fix E2E test
delawski Sep 29, 2021
9ed10ff
Remove extraneous cap checks and update tests to use request dispatching
westonruter Sep 29, 2021
adb6c0b
Add test assertion for enum
westonruter Sep 29, 2021
dcff59a
Fix phpdoc for get_review_panel_dismissed_for_template_mode return value
westonruter Sep 29, 2021
a1f7683
Remove extraneous edit_user cap check
westonruter Sep 29, 2021
128e491
Fix phpdoc for update_review_panel_dismissed_for_template_mode after …
westonruter Sep 29, 2021
2e61d15
Verify that editor user cannot access another user
westonruter Sep 29, 2021
ce6c456
Remove unused PHP import
westonruter Sep 29, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .phpstorm.meta.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
'admin.paired_browsing' => \AmpProject\AmpWP\Admin\PairedBrowsing::class,
'admin.plugin_row_meta' => \AmpProject\AmpWP\Admin\PluginRowMeta::class,
'admin.polyfills' => \AmpProject\AmpWP\Admin\Polyfills::class,
'admin.user_rest_endpoint_extension' => \AmpProject\AmpWP\Admin\UserRESTEndpointExtension::class,
'admin.validation_counts' => \AmpProject\AmpWP\Admin\ValidationCounts::class,
'amp_slug_customization_watcher' => \AmpProject\AmpWP\AmpSlugCustomizationWatcher::class,
'background_task_deactivator' => \AmpProject\AmpWP\BackgroundTask\BackgroundTaskDeactivator::class,
Expand Down
19 changes: 17 additions & 2 deletions assets/src/components/amp-setting-toggle/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* External dependencies
*/
import PropTypes from 'prop-types';
import classnames from 'classnames';

/**
* WordPress dependencies
Expand All @@ -19,14 +20,27 @@ import './style.css';
*
* @param {Object} props Component props.
* @param {boolean} props.checked Whether the toggle is on.
* @param {boolean} props.compact Whether the toggle is compact/small.
* @param {boolean} props.disabled Whether the toggle is disabled.
* @param {Function} props.onChange Change handler.
* @param {string} props.text Toggle text.
* @param {Object|string} props.title Toggle title.
*/
export function AMPSettingToggle( { checked, disabled = false, onChange, text, title } ) {
export function AMPSettingToggle( {
checked,
compact = false,
disabled = false,
onChange,
text,
title,
} ) {
return (
<div className={ `amp-setting-toggle ${ disabled ? 'amp-setting-toggle--disabled' : '' }` }>
<div
className={ classnames( 'amp-setting-toggle', {
'amp-setting-toggle--disabled': disabled,
'amp-setting-toggle--compact': compact,
} ) }
>
<ToggleControl
checked={ ! disabled && checked }
label={ (
Expand Down Expand Up @@ -55,6 +69,7 @@ export function AMPSettingToggle( { checked, disabled = false, onChange, text, t
}
AMPSettingToggle.propTypes = {
checked: PropTypes.bool.isRequired,
compact: PropTypes.bool,
disabled: PropTypes.bool,
onChange: PropTypes.func.isRequired,
text: PropTypes.string,
Expand Down
11 changes: 11 additions & 0 deletions assets/src/components/amp-setting-toggle/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,14 @@
.amp-setting-toggle--disabled .components-toggle-control__label {
pointer-events: none;
}

.amp .amp-setting-toggle--compact .components-form-toggle {

@media (min-width: 783px) {
margin-right: 1rem;
}
}

.amp .amp-setting-toggle--compact .amp-setting-toggle__label-text p {
margin: 0;
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

54 changes: 54 additions & 0 deletions assets/src/components/nav-menu/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
* External dependencies
*/
import PropTypes from 'prop-types';
import classnames from 'classnames';

/**
* Internal dependencies
*/
import './style.scss';
import { Selectable } from '../selectable';

/**
* Nav menu.
*
* @param {Object} props Component props.
* @param {Array} props.links List of links.
* @param {Function} props.onClick Click handler that receives the original event and a clicked link object.
*/
export function NavMenu( { links = [], onClick } ) {
return (
<Selectable
ElementName="nav"
className="nav-menu"
>
<ul className="nav-menu__list">
{ links.map( ( link ) => (
<li key={ link.url } className="nav-menu__item">
<a
className={ classnames( 'nav-menu__link', {
'nav-menu__link--active': link.isActive,
} ) }
href={ link.url }
onClick={ ( event ) => onClick( event, link ) }
>
{ link.label }
</a>
</li>
) ) }
</ul>
</Selectable>
);
}

NavMenu.propTypes = {
links: PropTypes.arrayOf(
PropTypes.shape( {
url: PropTypes.string,
label: PropTypes.string,
isActive: PropTypes.bool,
} ),
),
onClick: PropTypes.func,
};
64 changes: 64 additions & 0 deletions assets/src/components/nav-menu/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
.nav-menu__item {
margin: 0;

& + & {
border-top: 1px solid var(--amp-settings-color-border);
}
}

.amp .nav-menu__link {
align-items: center;
color: var(--amp-settings-color-muted);
display: flex;
flex-flow: row nowrap;
font-size: 14px;
justify-content: space-between;
padding: 0.75rem 1rem;
text-decoration: none;
transition: background-color 120ms ease;

&.nav-menu__link--active,
&:hover {
background-color: var(--very-light-gray);
color: var(--amp-settings-color-muted);
}

&:focus {
box-shadow: none;
}

&::after {
border: 2px solid;
border-bottom: none;
border-left: none;
content: "";
display: block;
flex: 0 0 auto;
height: 8px;
margin-left: 1rem;
transform: rotateZ(45deg);
width: 8px;
}
}

// Nav menu as a selectable component.
.nav-menu.selectable {
padding: 0;

.nav-menu__list {
margin: 0;
padding: 0 1rem;
}

.nav-menu__link {
margin: 0 -1rem;
}

.nav-menu__item:first-child .nav-menu__link {
border-radius: 8px 8px 0 0;
}

.nav-menu__item:last-child .nav-menu__link {
border-radius: 0 0 8px 8px;
}
}
34 changes: 34 additions & 0 deletions assets/src/components/nav-menu/test/__snapshots__/nav-menu.js.snap

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

101 changes: 101 additions & 0 deletions assets/src/components/nav-menu/test/nav-menu.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@

/**
* External dependencies
*/
import { act } from 'react-dom/test-utils';
import { create } from 'react-test-renderer';

/**
* WordPress dependencies
*/
import { render } from '@wordpress/element';

/**
* Internal dependencies
*/
import { NavMenu } from '../index';

let container;

const links = [
{
url: 'https://example.com/foo',
label: 'Foo',
isActive: false,
},
{
url: 'https://example.com/bar',
label: 'Bar',
isActive: true,
},
];

describe( 'NavMenu', () => {
beforeEach( () => {
container = document.createElement( 'div' );
document.body.appendChild( container );
} );

afterEach( () => {
document.body.removeChild( container );
container = null;
} );

it( 'matches the snapshot', () => {
const wrapper = create( <NavMenu links={ links } /> );

expect( wrapper.toJSON() ).toMatchSnapshot();
} );

it( 'renders a nav menu with a list of links', () => {
act( () => {
render(
<NavMenu links={ links } />,
container,
);
} );

expect( container.querySelector( 'nav' ) ).not.toBeNull();
expect( container.querySelector( 'ul' ) ).not.toBeNull();
expect( container.querySelectorAll( 'li' ) ).toHaveLength( 2 );
} );

it( 'contains correct links', () => {
act( () => {
render(
<NavMenu links={ links } />,
container,
);
} );

expect( container.querySelector( 'nav' ).textContent ).toBe( 'FooBar' );
expect( container.querySelectorAll( 'a' ) ).toHaveLength( 2 );
expect( container.querySelectorAll( 'a[href="https://example.com/foo"]' ) ).toHaveLength( 1 );
expect( container.querySelectorAll( 'a[href="https://example.com/bar"]' ) ).toHaveLength( 1 );
expect( container.querySelectorAll( 'a[class*="--active"]' ) ).toHaveLength( 1 );
expect( container.querySelector( 'a[class*="--active"]' ).getAttribute( 'href' ) ).toBe( 'https://example.com/bar' );
} );

it( 'calls the handler function on click', () => {
const handler = jest.fn();

act( () => {
render(
<NavMenu links={ links } onClick={ handler } />,
container,
);
} );

act(
() => {
container.querySelector( 'a' ).click();
},
);

expect( handler ).toHaveBeenCalledTimes( 1 );

const [ event, link ] = handler.mock.calls[ 0 ];
expect( event.type ).toBe( 'click' );
expect( link ).toBe( links[ 0 ] );
} );
} );
16 changes: 11 additions & 5 deletions assets/src/components/phone/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,22 @@ import PropTypes from 'prop-types';
* Internal dependencies
*/
import './style.css';
import { Loading } from '../loading';

/**
* Component resembling a phone with a screen.
*
* @param {Object} props Component props.
* @param {any} props.children The elements to display in the screen.
* @param {Object} props Component props.
* @param {any} props.children The elements to display in the screen.
* @param {boolean} props.isLoading Flag indicating if the content is loading.
*/
export function Phone( { children } ) {
export function Phone( { children, isLoading = false } ) {
return (
<div className="phone">
<div className="phone-inner">
<div className={ `phone ${ isLoading ? 'is-loading' : '' }` }>
<div className="phone__inner">
<div className="phone__overlay">
<Loading />
</div>
{ children }
</div>
</div>
Expand All @@ -26,4 +31,5 @@ export function Phone( { children } ) {

Phone.propTypes = {
children: PropTypes.any,
isLoading: PropTypes.bool,
};
Loading