Skip to content

Commit

Permalink
fix:(ActionFooter): delete + add edge case (#8)
Browse files Browse the repository at this point in the history
* feat(api): add actions

* feat(utils): add isEmpty and getTrad

- remove hasResponseData

* feat(trad): add en translation

* feat(hooks): add useReactQuery

* refactor(components): use react-query for state

- fixes delete/add edge case

* chore(assets): add new images for redesign
  • Loading branch information
ComfortablyCoding authored Feb 22, 2022
1 parent 1891b2d commit 3eb7525
Show file tree
Hide file tree
Showing 19 changed files with 357 additions and 135 deletions.
51 changes: 51 additions & 0 deletions admin/src/api/actions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { requestPluginEndpoint } from '../utils/requestPluginEndpoint';

const fetchEntityActions = ({ entitySlug, entityId, mode }) => {
let params = {
'filters[entitySlug][$eq]': entitySlug,
'filters[mode][$eq]': mode,
};
if (entityId) {
params['filters[entityId][$eq]'] = entityId;
}
return requestPluginEndpoint('actions', {
params,
});
};

const createEntityAction = ({ entitySlug, entityId, mode, executeAt }) => {
let body = {
executeAt,
mode,
entitySlug,
};

if (entityId) {
body.entityId = entityId;
}

return requestPluginEndpoint('actions', {
method: 'POST',
body,
});
};

const updateEntityAction = ({ id, executeAt }) => {
let body = {
executeAt,
id,
};

return requestPluginEndpoint(`actions/${id}`, {
method: 'PUT',
body,
});
};

const deleteEntityAction = ({ id }) => {
return requestPluginEndpoint(`actions/${id}`, {
method: 'DELETE',
});
};

export { fetchEntityActions, createEntityAction, updateEntityAction, deleteEntityAction };
20 changes: 13 additions & 7 deletions admin/src/components/Action/ActionContent/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,31 @@ import React from 'react';
import PropTypes from 'prop-types';
import { DateTimePicker } from '@strapi/helper-plugin';

const ActionContent = ({ dateValue, updateDateValue, disable }) => {
const ActionContent = ({ action, setAction, isDisabled }) => {
const handleDateChange = (date) => {
updateDateValue(date);
setAction((prev) => ({
...prev,
executeAt: date,
}));
};

return (
<DateTimePicker
ariaLabel="datetime picker"
onChange={handleDateChange}
value={dateValue}
disabled={disable}
value={action.executeAt}
disabled={isDisabled}
/>
);
};

ActionContent.propTypes = {
dateValue: PropTypes.string,
updateDateValue: PropTypes.func.isRequired,
disable: PropTypes.bool.isRequired,
action: PropTypes.shape({
id: PropTypes.number,
executeAt: PropTypes.string,
}),
setAction: PropTypes.func.isRequired,
isDisabled: PropTypes.bool.isRequired,
};

export { ActionContent };
121 changes: 65 additions & 56 deletions admin/src/components/Action/ActionFooter/index.js
Original file line number Diff line number Diff line change
@@ -1,69 +1,64 @@
import React from 'react';
import { useIntl } from 'react-intl';
import PropTypes from 'prop-types';
import { useReactQuery } from '../../../hooks/useReactQuery';
import { getTrad } from '../../../utils/getTrad';
import { Button } from '@strapi/design-system/Button';
import { Stack } from '@strapi/design-system/Stack';
import Check from '@strapi/icons/Check';
import Cross from '@strapi/icons/Cross';
import Write from '@strapi/icons/Write';
import Pencil from '@strapi/icons/Pencil';
import Trash from '@strapi/icons/Trash';
import { requestPluginEndpoint } from '../../../utils/requestPluginEndpoint';

const ActionFooter = ({
isVisible,
disable,
toggleDisable,
toggleIsVisible,
entitySlug,
entityId,
dateValue,
record,
mode,
entityId,
entitySlug,
action,
isDisabled,
setIsDisabled,
isVisible,
setIsVisible,
}) => {
const buildRequestOptions = () => {
const endpoint = record ? `actions/${record.id}` : 'actions';
let options = {
method: record ? 'PUT' : 'POST',
body: {
executeAt: dateValue,
mode,
},
};
const { formatMessage } = useIntl();
const { actionMutations } = useReactQuery();

if (record) {
options.body.id = record.id;
} else {
options.body.entitySlug = entitySlug;
if (entityId) {
options.body.entityId = entityId;
// action handlers
const handleActionSave = async () => {
try {
if (action.id) {
await actionMutations.update.mutate(action);
} else {
await actionMutations.create.mutate({
mode,
entityId,
entitySlug,
...action,
});
}
setIsDisabled(true);
} catch (error) {
console.error(error);
}

return { endpoint, options };
};

const handleActionSave = () => {
if (dateValue) {
const { endpoint, options } = buildRequestOptions();
requestPluginEndpoint(endpoint, options);
}
toggleDisable();
};

const handleActionEdit = () => {
toggleDisable();
setIsDisabled(false);
};

const handleActionAdd = () => {
toggleIsVisible();
setIsVisible(true);
};

const handleActionDelete = () => {
requestPluginEndpoint(`actions/${record.id}`, {
method: 'DELETE',
});
toggleDisable();
toggleIsVisible();
const handleActionDelete = async () => {
try {
await actionMutations.delete.mutate(action);
setIsVisible(false);
setIsDisabled(false);
} catch (error) {
console.error(error);
}
};

// add action
Expand All @@ -77,20 +72,29 @@ const ActionFooter = ({
onClick={handleActionAdd}
startIcon={addActionButtonIcon}
>
Add a {mode} date
{formatMessage({
id: getTrad(`action.footer.${mode}.button.add`),
defaultMessage: `Add a ${mode} date`,
})}
</Button>
);
}

// edit/delete action
if (disable) {
if (isDisabled) {
return (
<Stack size={2}>
<Button fullWidth variant="tertiary" onClick={handleActionEdit} startIcon={<Pencil />}>
Edit {mode} date
{formatMessage({
id: getTrad(`action.footer.${mode}.button.edit`),
defaultMessage: `Edit ${mode} date`,
})}
</Button>
<Button fullWidth variant="danger-light" onClick={handleActionDelete} startIcon={<Trash />}>
Delete {mode} date
{formatMessage({
id: getTrad(`action.footer.${mode}.button.delete`),
defaultMessage: `Delete ${mode} date`,
})}
</Button>
</Stack>
);
Expand All @@ -102,24 +106,29 @@ const ActionFooter = ({
fullWidth
variant="success-light"
onClick={handleActionSave}
disabled={!dateValue}
disabled={!action.executeAt}
startIcon={<Write />}
>
Save {mode} date
{formatMessage({
id: getTrad(`action.footer.${mode}.button.save`),
defaultMessage: `Save ${mode} date`,
})}
</Button>
);
};

ActionFooter.propTypes = {
isVisible: PropTypes.bool.isRequired,
disable: PropTypes.bool.isRequired,
toggleDisable: PropTypes.func.isRequired,
toggleIsVisible: PropTypes.func.isRequired,
entitySlug: PropTypes.string.isRequired,
entityId: PropTypes.number,
dateValue: PropTypes.string,
record: PropTypes.object,
mode: PropTypes.string.isRequired,
entityId: PropTypes.number,
entitySlug: PropTypes.string.isRequired,
isDisabled: PropTypes.bool.isRequired,
setIsDisabled: PropTypes.func.isRequired,
isVisible: PropTypes.bool.isRequired,
setIsVisible: PropTypes.func.isRequired,
action: PropTypes.shape({
id: PropTypes.number,
executeAt: PropTypes.string,
}),
};

export { ActionFooter };
9 changes: 8 additions & 1 deletion admin/src/components/Action/ActionHeader/index.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
import React from 'react';
import { useIntl } from 'react-intl';
import PropTypes from 'prop-types';
import { getTrad } from '../../../utils/getTrad';
import { Typography } from '@strapi/design-system/Typography';

const ActionHeader = ({ mode }) => {
const { formatMessage } = useIntl();

return (
<Typography variant="sigma" textColor="neutral600" merginBottom={1}>
{mode} Date
{formatMessage({
id: getTrad(`action.header.${mode}.title`),
defaultMessage: `${mode} Date`,
})}
</Typography>
);
};
Expand Down
Loading

0 comments on commit 3eb7525

Please sign in to comment.