Skip to content
This repository has been archived by the owner on Oct 16, 2024. It is now read-only.

Check for version control, display notice #145

Merged
merged 39 commits into from
May 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
8021294
Create `get-version-control` wp-module
mike-day Apr 20, 2023
70ac8a1
Hydrate `app` using `check_for_git_in_theme`
mike-day Apr 20, 2023
cbd407c
Update global type with `themename`, `versionControl`
mike-day Apr 20, 2023
e352cc8
Create VersionControlNotice component
mike-day Apr 20, 2023
c92dcae
Remove margin-right for notice__content
mike-day Apr 20, 2023
8ca4bc5
Use `VersionControlNotice` in `Patterns`
mike-day Apr 20, 2023
e8e2c71
Update AppTest
mike-day Apr 20, 2023
a8dbda1
Remove unused check for git in theme root
mike-day Apr 20, 2023
1527f1c
Setup a test-theme fixture
mike-day Apr 20, 2023
f3b450c
Create unit tests for get-verison-control (not passing)
mike-day Apr 20, 2023
3e22e49
Simplify the phpunit tests, delete unneeded fixture theme files
mike-day Apr 20, 2023
8031eec
Use a param for main vc checker function so testing is easier
mike-day Apr 20, 2023
d3f6d6b
Make the notice dismissible; adjust notice style to go full-width
mike-day Apr 20, 2023
f52085a
Remove invalid max-width property
mike-day Apr 21, 2023
ba16aca
Use `info` status for notice; adjust styles after talking through UX
mike-day Apr 21, 2023
7379ab4
Try a `warning` status for the notice
mike-day Apr 21, 2023
dbe4758
Tweak the verbiage in notice; linting for component
mike-day Apr 27, 2023
2c7f9c0
Add the update-dismissed-themes endpoint
mike-day Apr 27, 2023
c4b39f7
Hydrate app with new endpoint, query for dismissedThemes
mike-day Apr 27, 2023
7db5b54
Update types
mike-day Apr 27, 2023
36641de
Add a new `useVersionControl` hook
mike-day Apr 27, 2023
ae0d0aa
Call the new hook, then add to context provider
mike-day Apr 27, 2023
c8e0b03
Simplify VersionControlNotice; use the updated context in `Patterns`
mike-day Apr 27, 2023
1697e26
Update ApiDataTest
mike-day Apr 27, 2023
3a394e2
Update AppTest
mike-day Apr 27, 2023
d785692
Move getting of usermeta to get-version-control, return empty array i…
mike-day Apr 27, 2023
e96e8a1
Add empty array test for get_dismissed_themes
mike-day Apr 27, 2023
a9b9ef6
Translate the notification message
mike-day Apr 27, 2023
4e8188e
Merge branch 'main' of https://github.com/studiopress/pattern-manager…
mike-day Apr 27, 2023
126e83f
Pass themeName in PatternProps
mike-day Apr 27, 2023
06172f2
Pass versionControl bool, handler as props in Patterns instead of usi…
mike-day Apr 27, 2023
b50b045
Add get_current_user_id() to setUp, tearDown in unit test
mike-day Apr 27, 2023
af0ada1
Pass `Notice` as an optional prop to `Patterns`
mike-day Apr 27, 2023
37afb1a
Simplify the logic and just hydrate with a boolean to show or hide no…
mike-day Apr 27, 2023
54f8656
Bugfix from sending empty `themeName`; remove the POST body
mike-day Apr 27, 2023
1463614
Tweak the notice message, add space
mike-day Apr 28, 2023
fff8336
Add more test assertions for GetVersionControlTest
mike-day May 1, 2023
19437ed
Delete testing usermeta, user on tearDown
mike-day May 1, 2023
6c3907c
Remove the link to `Git Guide` in the notice message
mike-day May 1, 2023
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
32 changes: 32 additions & 0 deletions wp-modules/api-data/api-data.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

use WP_REST_Request;
use WP_REST_Response;
use function \PatternManager\GetVersionControl\get_dismissed_themes;
use function \PatternManager\GetVersionControl\get_version_control_meta_key;

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
Expand Down Expand Up @@ -67,6 +69,16 @@ function register_routes() {
),
)
);

register_rest_route(
$namespace,
'/update-dismissed-themes',
array(
'methods' => 'POST',
'callback' => __NAMESPACE__ . '\update_dismissed_themes',
'permission_callback' => __NAMESPACE__ . '\permission_check',
)
);
}
add_action( 'rest_api_init', __NAMESPACE__ . '\register_routes', 11 );

Expand Down Expand Up @@ -107,6 +119,26 @@ function delete_pattern( $request ) {
: new WP_REST_Response( $is_success, 400 );
}

/**
* Updates the list of theme names that should not show version control notifications.
*
* @param WP_REST_Request $request Full data about the request.
* @return WP_REST_Response
*/
function update_dismissed_themes( $request ) {
$dismissed_themes = array_merge( get_dismissed_themes(), (array) wp_get_theme()->get( 'Name' ) );
$is_success = update_user_meta( get_current_user_id(), get_version_control_meta_key(), $dismissed_themes );

return $is_success
? new WP_REST_Response(
array(
'message' => __( 'Version control notifications dismissed for this theme.', 'pattern-manager' ),
),
200
)
: new WP_REST_Response( $is_success, 400 );
}

/**
* Check the permissions required to take this action.
*
Expand Down
1 change: 1 addition & 0 deletions wp-modules/api-data/tests/ApiDataTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ public function test_register_routes_authorized() {
'/pattern-manager/v1',
'/pattern-manager/v1/get-pattern-names',
'/pattern-manager/v1/delete-pattern',
'/pattern-manager/v1/update-dismissed-themes',
],
array_keys( rest_get_server()->get_routes( 'pattern-manager/v1' ) )
);
Expand Down
18 changes: 11 additions & 7 deletions wp-modules/app/app.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

namespace PatternManager\App;

use function PatternManager\GetVersionControl\check_version_control_notice_should_show;

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
Expand All @@ -21,14 +23,16 @@
*/
function get_app_state() {
return array(
'patterns' => \PatternManager\PatternDataHandlers\get_theme_patterns_with_editor_links(),
'patternCategories' => \WP_Block_Pattern_Categories_Registry::get_instance()->get_all_registered(),
'apiNonce' => wp_create_nonce( 'wp_rest' ),
'apiEndpoints' => array(
'deletePatternEndpoint' => get_rest_url( false, 'pattern-manager/v1/delete-pattern/' ),
'patterns' => \PatternManager\PatternDataHandlers\get_theme_patterns_with_editor_links(),
'patternCategories' => \WP_Block_Pattern_Categories_Registry::get_instance()->get_all_registered(),
'apiNonce' => wp_create_nonce( 'wp_rest' ),
'apiEndpoints' => array(
'deletePatternEndpoint' => get_rest_url( false, 'pattern-manager/v1/delete-pattern/' ),
'updateDismissedThemesEndpoint' => get_rest_url( false, 'pattern-manager/v1/update-dismissed-themes/' ),
),
'siteUrl' => get_bloginfo( 'url' ),
'adminUrl' => admin_url(),
'siteUrl' => get_bloginfo( 'url' ),
'adminUrl' => admin_url(),
'showVersionControlNotice' => check_version_control_notice_should_show( wp_get_theme()->get( 'Name' ) ),
);
}

Expand Down
16 changes: 16 additions & 0 deletions wp-modules/app/js/src/components/App/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,22 @@ html body.toplevel_page_pattern-manager {
}
}

.patternmanager-version-control-notice {
margin-left: auto;
margin-right: auto;
margin-bottom: 3rem;
padding-right: 12px;
padding-left: 12px;

.components-notice__content {
margin-right: 0;

span {
font-weight: 600;
}
}
}

.patternmanager-pattern-editor-columns {
width: 100%;
height: calc(100vh - 64px - 32px);
Expand Down
11 changes: 11 additions & 0 deletions wp-modules/app/js/src/components/App/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,25 @@ import PatternManagerContext from '../../contexts/PatternManagerContext';

// Hooks
import usePatterns from '../../hooks/usePatterns';
import useVersionControl from '../../hooks/useVersionControl';

// Components
import Header from '../Header';
import Patterns from '../Patterns';
const PatternGridActions: PatternGridActionsType = loadable(
async () => import( '../Patterns/PatternGridActions' )
);
import VersionControlNotice from '../VersionControlNotice';

// Types
import type { InitialContext } from '../../types';
import { PatternGridActionsType } from '../Patterns/PatternGridActions';

export default function App() {
const patterns = usePatterns( patternManager.patterns );
const versionControl = useVersionControl(
Boolean( patternManager.showVersionControlNotice )
);

const providerValue: InitialContext = {
patterns,
Expand All @@ -38,6 +43,12 @@ export default function App() {
<PatternManagerContext.Provider value={ providerValue }>
<Header />
<Patterns
Notice={
<VersionControlNotice
isVisible={ versionControl.displayNotice }
handleDismiss={ versionControl.updateDismissedThemes }
/>
}
PatternActions={ PatternGridActions }
patternCategories={ patternManager.patternCategories }
patterns={ patterns.data }
Expand Down
2 changes: 2 additions & 0 deletions wp-modules/app/js/src/components/Patterns/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import type { PatternsProps } from '../../types';

export default function Patterns( {
onSelectPattern,
Notice,
PatternActions,
patternCategories,
patterns,
Expand All @@ -45,6 +46,7 @@ export default function Patterns( {
return (
<div className="pattern-manager-theme-patterns">
<div className="patterns-container-inner">
{ Notice }
{ ! Object.entries( patterns ?? {} ).length ? (
<div className="grid-empty">
{ createInterpolateElement(
Expand Down
28 changes: 28 additions & 0 deletions wp-modules/app/js/src/components/VersionControlNotice/index.tsx
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With a light refactor to pass in versionControl and themeName as props, this component could be a good candidate for moving to common if we do something like #141.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea!

Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// WP dependencies
import { __ } from '@wordpress/i18n';
import { Notice } from '@wordpress/components';

type Props = {
isVisible: boolean;
handleDismiss: () => void;
};

/** Display a notice if no version control is detected in the theme. */
export default function VersionControlNotice( {
isVisible,
handleDismiss,
}: Props ) {
return isVisible ? (
<Notice
className="patternmanager-version-control-notice"
isDismissible
status="warning"
onRemove={ handleDismiss }
>
{ __(
'No version control detected for this theme. We recommend adding version control so you do not lose your patterns during theme updates.',
'pattern-manager'
) }
</Notice>
) : null;
}
28 changes: 28 additions & 0 deletions wp-modules/app/js/src/hooks/useVersionControl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { useState } from '@wordpress/element';
import { patternManager } from '../globals';
import getHeaders from '../utils/getHeaders';
import type { Theme } from '../types';

export default function useVersionControl(
initialVersionControlNotice: boolean
) {
const [ displayNotice, setDisplayNotice ] = useState(
initialVersionControlNotice
);

function updateDismissedThemes() {
setDisplayNotice( false );
return fetch(
patternManager.apiEndpoints.updateDismissedThemesEndpoint,
{
method: 'POST',
headers: getHeaders(),
}
);
}

return {
displayNotice,
updateDismissedThemes,
};
}
9 changes: 9 additions & 0 deletions wp-modules/app/js/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import usePatterns from './hooks/usePatterns';
import versionControl from './hooks/useVersionControl';

export type PatternManagerViews = 'theme_patterns' | 'pattern_editor';

Expand All @@ -10,11 +11,14 @@ export type InitialPatternManager = {
adminUrl: string;
apiEndpoints: {
deletePatternEndpoint: string;
updateDismissedThemesEndpoint: string;
};
apiNonce: string;
patternCategories: QueriedCategories;
patterns: Patterns;
siteUrl: string;
themeName: string;
showVersionControlNotice: boolean;
};

export type Pattern = {
Expand Down Expand Up @@ -42,9 +46,14 @@ export type PatternsProps = {
patternCategories: InitialPatternManager[ 'patternCategories' ];
PatternActions?: ( props: { patternData: Pattern } ) => JSX.Element;
siteUrl: string;
Notice?: JSX.Element;
};

export type QueriedCategories = {
label: string;
name: string;
}[];

export type Theme = {
name: string;
};
1 change: 1 addition & 0 deletions wp-modules/app/tests/AppTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public function test_get_app_state() {
'apiEndpoints',
'siteUrl',
'adminUrl',
'showVersionControlNotice',
],
array_keys( get_app_state() )
);
Expand Down
62 changes: 62 additions & 0 deletions wp-modules/get-version-control/get-version-control.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php
/**
* Module Name: Get Version Control
* Description: Checks the current theme directory for version control.
* Namespace: GetVersionControl
*
* @package pattern-manager
*/

declare(strict_types=1);

namespace PatternManager\GetVersionControl;

/**
* Gets the meta key for storing version control notice dismissals.
*
* @return string
*/
function get_version_control_meta_key() {
return 'patternmanager_version_control_notice_dismissed_themes';
}

/**
* Gets the list of themes that have had version control notices dismissed by the user.
*
* @return array
*/
function get_dismissed_themes() {
$dismissed_themes = get_user_meta( get_current_user_id(), get_version_control_meta_key(), true );
return ! empty( $dismissed_themes ) ? $dismissed_themes : [];
mike-day marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* Determines if the version control notice should be displayed.
*
* @param string $theme_name The theme name to check against previously dismissed notices.
* @param string $version_control The version control directory to check.
* @return boolean
*/
function check_version_control_notice_should_show( $theme_name, $version_control = '/.git' ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea for this, it's a very flat function.

return ! check_theme_name_dismissed( $theme_name ) && ! check_for_version_control_in_theme( $version_control );
}

/**
* Checks for a version control folder in the current theme.
*
* @param string $version_control The version control directory to check.
* @return boolean
*/
function check_for_version_control_in_theme( $version_control ) {
return file_exists( get_template_directory() . $version_control );
}

/**
* Checks if the version control notice has already been dismissed for a given theme.
*
* @param string $theme_name The theme name.
* @return boolean
*/
function check_theme_name_dismissed( $theme_name ) {
return in_array( $theme_name, get_dismissed_themes(), true );
}
Loading