Skip to content

Commit

Permalink
Dashboard: RTL support and dynamic story creation URL (#696)
Browse files Browse the repository at this point in the history
* Include dashboard in code coverage reports

* Lint fixes

* Rename variable for stories editor config

* Pass server-side config to dashboard app

* Update button to create new story, add RTL support
  • Loading branch information
swissspidy authored Mar 22, 2020
1 parent 5c78622 commit 897c8ea
Show file tree
Hide file tree
Showing 15 changed files with 195 additions and 33 deletions.
39 changes: 39 additions & 0 deletions assets/src/dashboard/app/config/configProvider.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* External dependencies
*/
import PropTypes from 'prop-types';

/**
* Internal dependencies
*/
import Context from './context';

function ConfigProvider({ config, children }) {
return <Context.Provider value={config}>{children}</Context.Provider>;
}

ConfigProvider.propTypes = {
children: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.node),
PropTypes.node,
]).isRequired,
config: PropTypes.object.isRequired,
};

export default ConfigProvider;
22 changes: 22 additions & 0 deletions assets/src/dashboard/app/config/context.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* External dependencies
*/
import { createContext } from 'react';

export default createContext({ api: {} });
18 changes: 18 additions & 0 deletions assets/src/dashboard/app/config/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

export { default as ConfigProvider } from './configProvider';
export { default as useConfig } from './useConfig';
31 changes: 31 additions & 0 deletions assets/src/dashboard/app/config/useConfig.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* External dependencies
*/
import { useContext } from 'react';

/**
* Internal dependencies
*/
import Context from './context';

function useConfig() {
return useContext(Context);
}

export default useConfig;
43 changes: 30 additions & 13 deletions assets/src/dashboard/app/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,30 +17,47 @@
/**
* External dependencies
*/
import { ThemeProvider } from 'styled-components';
import { StyleSheetManager, ThemeProvider } from 'styled-components';
import stylisRTLPlugin from 'stylis-plugin-rtl';
import PropTypes from 'prop-types';

/**
* Internal dependencies
*/
import theme, { GlobalStyle } from '../theme';
import KeyboardOnlyOutline from '../utils/keyboardOnlyOutline';
import { NavigationBar } from '../components';
import { Route, RouterProvider } from './router';
import { useRouteHistory, Route, RouterProvider } from './router';
import { useConfig, ConfigProvider } from './config';
import { MyStoriesView, TemplatesGalleryView, MyBookmarksView } from './views';

function App() {
function App({ config }) {
const { isRTL } = config;
return (
<ThemeProvider theme={theme}>
<RouterProvider>
<GlobalStyle />
<KeyboardOnlyOutline />
<NavigationBar />
<Route exact path="/" component={<MyStoriesView />} />
<Route path="/templates-gallery" component={<TemplatesGalleryView />} />
<Route path="/my-bookmarks" component={<MyBookmarksView />} />
</RouterProvider>
</ThemeProvider>
<StyleSheetManager stylisPlugins={isRTL ? [stylisRTLPlugin] : []}>
<ThemeProvider theme={theme}>
<ConfigProvider config={config}>
<RouterProvider>
<GlobalStyle />
<KeyboardOnlyOutline />
<NavigationBar />
<Route exact path="/" component={<MyStoriesView />} />
<Route
path="/templates-gallery"
component={<TemplatesGalleryView />}
/>
<Route path="/my-bookmarks" component={<MyBookmarksView />} />
</RouterProvider>
</ConfigProvider>
</ThemeProvider>
</StyleSheetManager>
);
}

App.propTypes = {
config: PropTypes.object.isRequired,
};

export default App;

export { useConfig, useRouteHistory };
2 changes: 2 additions & 0 deletions assets/src/dashboard/components/button/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,14 @@ const StyledButton = styled.button`
min-width: 132px;
opacity: 0.75;
padding: 0;
text-decoration: none;
&:focus,
&:active,
&:hover {
opacity: 1;
outline: none;
color: ${({ theme }) => theme.colors.white};
}
${KEYBOARD_USER_SELECTOR} &:focus {
Expand Down
16 changes: 11 additions & 5 deletions assets/src/dashboard/components/navigation-bar.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ import styled from 'styled-components';
/**
* Internal dependencies
*/
import { useRouteHistory } from '../app/router';
import { useConfig, useRouteHistory } from '../app';
import { ReactComponent as WebStoriesLogoSVG } from '../images/logo.svg';
import { BUTTON_TYPES, NEW_STORY_URL } from '../constants';
import { BUTTON_TYPES } from '../constants';
import Button from './button';
import Dropdown from './dropdown';

Expand Down Expand Up @@ -82,6 +82,10 @@ const LinksContainer = styled.div`
}
`;

const NewStoryLink = styled(Button)`
margin-left: 40px;
`;

const paths = [
{ value: '/', label: __('My Stories', 'web-stories') },
{
Expand All @@ -93,6 +97,7 @@ const paths = [

function NavigationBar() {
const { state, actions } = useRouteHistory();
const { newStoryURL } = useConfig();
return (
<Nav>
<WebStoriesLogo />
Expand All @@ -115,12 +120,13 @@ function NavigationBar() {
{path.label}
</Link>
))}
<Button
<NewStoryLink
forwardedAs="a"
type={BUTTON_TYPES.CTA}
onClick={() => (window.location.href = NEW_STORY_URL)}
href={newStoryURL}
>
{__('Create Story', 'web-stories')}
</Button>
</NewStoryLink>
</LinksContainer>
</Nav>
);
Expand Down
2 changes: 0 additions & 2 deletions assets/src/dashboard/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,3 @@ export const KEYBOARD_USER_SELECTOR = `.${KEYBOARD_USER_CLASS}`;
export const Z_INDEX = {
POPOVER_MENU: 10,
};

export const NEW_STORY_URL = 'post-new.php?post_type=web-story';
20 changes: 14 additions & 6 deletions assets/src/dashboard/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,24 @@ import App from './app';
import './style.css'; // This way the general dashboard styles are loaded before all the component styles.

/**
* Initializes the dashboard screen.
* Initializes the Web Stories dashboard screen.
*
* @param {string} id ID of the root element to render the screen in.
* @param {Object} config Story editor settings.
*/
const initialize = () => {
const appElement = document.getElementById('web-stories-dashboard');
const initialize = (id, config) => {
const appElement = document.getElementById(id);

render(<App config={config} />, appElement);
};

render(<App />, appElement);
const initializeWithConfig = () => {
const { id, config } = window.webStoriesDashboardSettings;
initialize(id, config);
};

if ('loading' === document.readyState) {
document.addEventListener('DOMContentLoaded', initialize);
document.addEventListener('DOMContentLoaded', initializeWithConfig);
} else {
initialize();
initializeWithConfig();
}
2 changes: 1 addition & 1 deletion assets/src/edit-story/app/config/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@
*/
import { createContext } from 'react';

export default createContext({ api: {} });
export default createContext({});
2 changes: 1 addition & 1 deletion assets/src/edit-story/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const initialize = (id, config) => {
};

const initializeWithConfig = () => {
const { id, config } = window.ampStoriesEditSettings;
const { id, config } = window.webStoriesEditorSettings;
initialize(id, config);
};

Expand Down
19 changes: 19 additions & 0 deletions includes/Dashboard.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,25 @@ public function enqueue_assets( $hook_suffix ) {

wp_set_script_translations( self::SCRIPT_HANDLE, 'web-stories' );

$new_story_url = admin_url( add_query_arg(
[
'post_type' => Story_Post_Type::POST_TYPE_SLUG,
],
'post-new.php'
) );

wp_localize_script(
self::SCRIPT_HANDLE,
'webStoriesDashboardSettings',
[
'id' => 'web-stories-dashboard',
'config' => [
'isRTL' => is_rtl(),
'newStoryURL' => $new_story_url,
],
]
);

wp_register_style(
'google-sans-font',
'https://fonts.googleapis.com/css?family=Google+Sans|Google+Sans:b',
Expand Down
8 changes: 4 additions & 4 deletions includes/Story_Post_Type.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,21 @@
*/
class Story_Post_Type {
/**
* The slug of the post type to store URLs that have AMP errors.
* The slug of the stories post type.
*
* @var string
*/
const POST_TYPE_SLUG = 'web-story';

/**
* AMP Stories script handle.
* Web Stories editor script handle.
*
* @var string
*/
const WEB_STORIES_SCRIPT_HANDLE = 'edit-story';

/**
* AMP Stories style handle.
* Web Stories editor style handle.
*
* @var string
*/
Expand Down Expand Up @@ -304,7 +304,7 @@ public static function admin_enqueue_scripts( $hook ) {

wp_localize_script(
self::WEB_STORIES_SCRIPT_HANDLE,
'ampStoriesEditSettings',
'webStoriesEditorSettings',
[
'id' => 'edit-story',
'config' => [
Expand Down
1 change: 1 addition & 0 deletions tests/js/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ module.exports = {
coverageDirectory: '<rootDir>/build/logs',
collectCoverageFrom: [
'<rootDir>/assets/src/edit-story/**/*.js',
'<rootDir>/assets/src/dashboard/**/*.js',
'!**/test/**',
'!**/stories/**',
],
Expand Down
3 changes: 2 additions & 1 deletion tests/js/setup-globals.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
* limitations under the License.
*/

window.ampStoriesEditSettings = {};
window.webStoriesEditorSettings = {};
window.webStoriesDashboardSettings = {};

global.wp = {
media: {
Expand Down

0 comments on commit 897c8ea

Please sign in to comment.