Unify saving button behavior with WP post editor

[MAILPOET-4968]
This commit is contained in:
Jan Jakes
2023-08-08 16:42:33 +02:00
committed by Aschepikov
parent db713f4db8
commit bd0158fe86
6 changed files with 63 additions and 4 deletions

View File

@@ -0,0 +1,22 @@
/* See: https://github.com/WordPress/gutenberg/blob/0b4ad0072a5c3dd4832081ed00d4e27389ae88c8/packages/editor/src/components/post-saved-state/index.js */
.mailpoet-automation-editor-saved-state {
align-items: center;
color: #757575;
display: flex;
overflow: hidden;
white-space: nowrap;
&.is-saving[aria-disabled='true'],
&.is-saving[aria-disabled='true']:hover,
&.is-saved[aria-disabled='true'],
&.is-saved[aria-disabled='true']:hover {
background: transparent;
color: #757575;
}
svg {
display: inline-block;
fill: currentColor;
flex: 0 0 auto;
}
}

View File

@@ -13,6 +13,7 @@
@import './empty-automation'; @import './empty-automation';
@import './errors'; @import './errors';
@import './panel'; @import './panel';
@import './saved-state';
@import './separator'; @import './separator';
@import './status'; @import './status';
@import './step'; @import './step';

View File

@@ -1,4 +1,4 @@
import { useState } from 'react'; import { useMemo, useState } from 'react';
import { import {
Button, Button,
NavigableMenu, NavigableMenu,
@@ -6,6 +6,7 @@ import {
Tooltip, Tooltip,
} from '@wordpress/components'; } from '@wordpress/components';
import { dispatch, useDispatch, useSelect } from '@wordpress/data'; import { dispatch, useDispatch, useSelect } from '@wordpress/data';
import { Icon, check, cloud } from '@wordpress/icons';
import { PinnedItems } from '@wordpress/interface'; import { PinnedItems } from '@wordpress/interface';
import { __ } from '@wordpress/i18n'; import { __ } from '@wordpress/i18n';
import { ErrorBoundary } from 'common'; import { ErrorBoundary } from 'common';
@@ -106,11 +107,36 @@ function UpdateButton(): JSX.Element {
} }
function SaveDraftButton(): JSX.Element { function SaveDraftButton(): JSX.Element {
const savedState = useSelect(
(select) => select(storeName).getSavedState(),
[],
);
const { save } = useDispatch(storeName); const { save } = useDispatch(storeName);
const label = useMemo(() => {
if (savedState === 'saving') {
return __('Saving', 'mailpoet');
}
if (savedState === 'saved') {
return __('Saved', 'mailpoet');
}
return __('Save draft', 'mailpoet');
}, [savedState]);
const isDisabled = savedState === 'saving' || savedState === 'saved';
// use single Button instance for all states so that focus is not lost
return ( return (
<Button variant="tertiary" onClick={save}> <Button
{__('Save draft', 'mailpoet')} className={`mailpoet-automation-editor-saved-state is-${savedState}`}
variant="tertiary"
label={label}
disabled={isDisabled}
aria-disabled={isDisabled}
onClick={save}
>
{savedState === 'saving' && <Icon icon={cloud} />}
{savedState === 'saved' && <Icon icon={check} />}
</Button> </Button>
); );
} }

View File

@@ -89,6 +89,11 @@ export function setAutomationName(name) {
export function* save() { export function* save() {
const automation = select(storeName).getAutomationData(); const automation = select(storeName).getAutomationData();
yield {
type: 'SAVING',
};
const data = yield apiFetch({ const data = yield apiFetch({
path: `/automations/${automation.id}`, path: `/automations/${automation.id}`,
method: 'PUT', method: 'PUT',

View File

@@ -58,6 +58,11 @@ export function reducer(state: State, action): State {
automationData: action.automation, automationData: action.automation,
savedState: 'saved', savedState: 'saved',
}; };
case 'SAVING':
return {
...state,
savedState: 'saving',
};
case 'REGISTER_STEP_TYPE': case 'REGISTER_STEP_TYPE':
return { return {
...state, ...state,

View File

@@ -92,7 +92,7 @@ export type Errors = {
}; };
export type State = { export type State = {
savedState: 'unsaved' | 'saved'; savedState: 'unsaved' | 'saving' | 'saved';
registry: Registry; registry: Registry;
context: Context; context: Context;
stepTypes: Record<string, StepType>; stepTypes: Record<string, StepType>;