diff --git a/packages/core/admin/admin/src/pages/Roles/ListPage/index.js b/packages/core/admin/admin/src/pages/Roles/ListPage/index.js
index bdf4743e71b..b4ef24d995b 100644
--- a/packages/core/admin/admin/src/pages/Roles/ListPage/index.js
+++ b/packages/core/admin/admin/src/pages/Roles/ListPage/index.js
@@ -105,14 +105,14 @@ const RoleListPage = () => {
}>
{formatMessage({
id: 'Settings.roles.list.button.add',
defaultMessage: 'Add new role',
})}
- )}
+ }
title={formatMessage({
id: 'Settings.roles.title',
defaultMessage: 'roles',
@@ -126,14 +126,14 @@ const RoleListPage = () => {
}>
{formatMessage({
id: 'Settings.roles.list.button.add',
defaultMessage: 'Add new role',
})}
- )}
+ }
>
diff --git a/packages/core/admin/admin/src/pages/Webhooks/ListView/index.js b/packages/core/admin/admin/src/pages/Webhooks/ListView/index.js
index f52fc13a5ed..b5d06590bc2 100644
--- a/packages/core/admin/admin/src/pages/Webhooks/ListView/index.js
+++ b/packages/core/admin/admin/src/pages/Webhooks/ListView/index.js
@@ -6,25 +6,37 @@
import React, { useEffect, useReducer, useRef, useState } from 'react';
import { useHistory, useLocation } from 'react-router-dom';
-import { Header, List } from '@buffetjs/custom';
-import { Button } from '@buffetjs/core';
-import { Plus } from '@buffetjs/icons';
-import { omit } from 'lodash';
import { useIntl } from 'react-intl';
import {
request,
- ListButton,
PopUpWarning,
useRBAC,
LoadingIndicatorPage,
- EmptyState,
useNotification,
+ useFocusWhenNavigate,
} from '@strapi/helper-plugin';
-import adminPermissions from '../../../permissions';
-import PageTitle from '../../../components/SettingsPageTitle';
-import { ListRow } from '../../../components/Webhooks';
-import Wrapper from './Wrapper';
+
+import { HeaderLayout, Layout, ContentLayout } from '@strapi/parts/Layout';
+import { EmptyStateLayout } from '@strapi/parts/EmptyStateLayout';
+import { Row } from '@strapi/parts/Row';
+import { Stack } from '@strapi/parts/Stack';
+import { IconButton } from '@strapi/parts/IconButton';
+import { BaseCheckbox } from '@strapi/parts/BaseCheckbox';
+import { Table, Thead, Tr, Th, Tbody, Td, TFooter } from '@strapi/parts/Table';
+import { Text, TableLabel } from '@strapi/parts/Text';
+import { Button } from '@strapi/parts/Button';
+import { VisuallyHidden } from '@strapi/parts/VisuallyHidden';
+import { Switch } from '@strapi/parts/Switch';
+import { Main } from '@strapi/parts/Main';
+import { LinkButton } from '@strapi/parts/LinkButton';
+import { notifyStatus } from '@strapi/parts/LiveRegions';
+import AddIcon from '@strapi/icons/AddIcon';
+import EditIcon from '@strapi/icons/EditIcon';
+import DeleteIcon from '@strapi/icons/DeleteIcon';
+import EmptyStateDocument from '@strapi/icons/EmptyStateDocument';
import reducer, { initialState } from './reducer';
+import PageTitle from '../../../components/SettingsPageTitle';
+import adminPermissions from '../../../permissions';
function ListView() {
const {
@@ -35,12 +47,16 @@ function ListView() {
const isMounted = useRef(true);
const { formatMessage } = useIntl();
const [showModal, setShowModal] = useState(false);
- const [{ webhooks, webhooksToDelete, webhookToDelete }, dispatch] = useReducer(
+ const [{ webhooks, webhooksToDelete, webhookToDelete, loadingWebhooks }, dispatch] = useReducer(
reducer,
initialState
);
+
+ useFocusWhenNavigate();
const { push } = useHistory();
const { pathname } = useLocation();
+ const rowsCount = webhooks.length;
+ const getWebhookIndex = id => webhooks.findIndex(webhook => webhook.id === id);
useEffect(() => {
isMounted.current = true;
@@ -52,81 +68,12 @@ function ListView() {
useEffect(() => {
if (canRead) {
- fetchData();
+ fetchWebHooks();
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [canRead]);
- const getWebhookIndex = id => webhooks.findIndex(webhook => webhook.id === id);
-
- // New button
- const addBtnLabel = formatMessage({
- id: 'Settings.webhooks.list.button.add',
- });
-
- const newButtonProps = {
- label: addBtnLabel,
- onClick: () => handleGoTo('create'),
- color: 'primary',
- type: 'button',
- icon: ,
- Component: props => {
- if (canCreate) {
- return ;
- }
-
- return null;
- },
- };
-
- // Header props
- const actions = [
- {
- ...newButtonProps,
- icon: true,
- style: {
- paddingLeft: 15,
- paddingRight: 15,
- },
- },
- ];
-
- const headerProps = {
- title: {
- label: formatMessage({ id: 'Settings.webhooks.title' }),
- },
- content: formatMessage({ id: 'Settings.webhooks.list.description' }),
- actions,
- };
-
- // List props
- const rowsCount = webhooks.length;
- const titleLabel = `${
- rowsCount > 1
- ? formatMessage({ id: 'Settings.webhooks.title' })
- : formatMessage({ id: 'Settings.webhooks.singular' })
- }`;
- const title = `${rowsCount} ${titleLabel}`;
-
- /* eslint-disable indent */
- const deleteButtonProps = canDelete
- ? {
- color: 'delete',
- disabled: !(webhooksToDelete.length > 0),
- label: formatMessage({ id: 'app.utils.delete' }),
- onClick: () => setShowModal(true),
- type: 'button',
- }
- : null;
- /* eslint-enable indent */
-
- const listProps = {
- title,
- button: deleteButtonProps,
- items: webhooks,
- };
-
- const fetchData = async () => {
+ const fetchWebHooks = async () => {
try {
const { data } = await request('/admin/webhooks', {
method: 'GET',
@@ -137,6 +84,7 @@ function ListView() {
type: 'GET_DATA_SUCCEEDED',
data,
});
+ notifyStatus('webhooks have been loaded');
}
} catch (err) {
if (isMounted.current) {
@@ -146,18 +94,13 @@ function ListView() {
message: { id: 'notification.error' },
});
}
+ dispatch({
+ type: 'TOGGLE_LOADING',
+ });
}
}
};
- const handleChange = (value, id) => {
- dispatch({
- type: 'SET_WEBHOOKS_TO_DELETE',
- value,
- id,
- });
- };
-
const handleConfirmDelete = () => {
if (webhookToDelete) {
handleConfirmDeleteOne();
@@ -227,7 +170,6 @@ function ListView() {
const handleEnabledChange = async (value, id) => {
const webhookIndex = getWebhookIndex(id);
-
const initialWebhookProps = webhooks[webhookIndex];
const keys = [webhookIndex, 'isEnabled'];
@@ -267,56 +209,188 @@ function ListView() {
}
};
+ const handleSelectAllCheckbox = () => {
+ dispatch({
+ type: 'SET_ALL_WEBHOOKS_TO_DELETE',
+ });
+ };
+
+ const handleSelectOneCheckbox = (value, id) => {
+ dispatch({
+ type: 'SET_WEBHOOKS_TO_DELETE',
+ value,
+ id,
+ });
+ };
+
const handleGoTo = to => {
push(`${pathname}/${to}`);
};
- if (isLoading) {
- return ;
- }
-
return (
-
+
-
- {canRead && (
-
- {rowsCount > 0 ? (
-
{
- return (
-
- );
- }}
- />
+
+ <>
+ } variant="default" to={`${pathname}/create`}>
+ {formatMessage({ id: 'Settings.webhooks.list.button.add' })}
+
+ )
+ }
+ />
+ {isLoading || loadingWebhooks ? (
+
) : (
-
+
+ <>
+ {rowsCount > 0 ? (
+ (canCreate ? handleGoTo('create') : {})}
+ icon={}
+ >
+ {formatMessage({ id: 'Settings.webhooks.list.field.add' })}
+
+ }
+ >
+
+
+
+ 0 && webhooksToDelete.length < rowsCount
+ }
+ value={webhooksToDelete.length === rowsCount}
+ onValueChange={handleSelectAllCheckbox}
+ />
+ |
+
+
+ {formatMessage({ id: 'Settings.webhooks.form.name' })}
+
+ |
+
+
+ {formatMessage({ id: 'Settings.webhooks.form.url' })}
+
+ |
+
+
+ {formatMessage({ id: 'Settings.webhooks.list.th.status' })}
+
+ |
+
+
+ {formatMessage({ id: 'Settings.webhooks.list.th.actions' })}
+
+ |
+
+
+
+ {webhooks.map(webhook => (
+
+
+ handleSelectOneCheckbox(value, webhook.id)}
+ id="select"
+ name="select"
+ />
+ |
+
+
+ {webhook.name}
+
+ |
+
+ {webhook.url}
+ |
+
+
+ handleEnabledChange(!webhook.isEnabled, webhook.id)}
+ visibleLabels
+ />
+
+ |
+
+
+ {canUpdate && (
+ {
+ handleGoTo(webhook.id);
+ }}
+ label={formatMessage({ id: 'Settings.webhooks.events.update' })}
+ icon={}
+ noBorder
+ />
+ )}
+ {canDelete && (
+ handleDeleteClick(webhook.id)}
+ label={formatMessage({ id: 'Settings.webhooks.events.delete' })}
+ icon={}
+ noBorder
+ />
+ )}
+
+ |
+
+ ))}
+
+
+ ) : (
+ }
+ content={formatMessage({ id: 'Settings.webhooks.list.empty.description' })}
+ action={
+ }
+ onClick={() => (canCreate ? handleGoTo('create') : {})}
+ >
+ {formatMessage({ id: 'Settings.webhooks.list.button.add' })}
+
+ }
+ />
+ )}
+ >
+
)}
- {canCreate && }
-
- )}
+ >
+
setShowModal(!showModal)}
popUpWarningType="danger"
onConfirm={handleConfirmDelete}
/>
-
+
);
}
diff --git a/packages/core/admin/admin/src/pages/Webhooks/ListView/reducer.js b/packages/core/admin/admin/src/pages/Webhooks/ListView/reducer.js
index fbcd417c97f..7b268b2e49e 100644
--- a/packages/core/admin/admin/src/pages/Webhooks/ListView/reducer.js
+++ b/packages/core/admin/admin/src/pages/Webhooks/ListView/reducer.js
@@ -5,6 +5,7 @@ const initialState = {
webhooks: [],
webhooksToDelete: [],
webhookToDelete: null,
+ loadingWebhooks: true,
};
const reducer = (state, action) =>
@@ -13,6 +14,12 @@ const reducer = (state, action) =>
switch (action.type) {
case 'GET_DATA_SUCCEEDED': {
draftState.webhooks = action.data;
+ draftState.loadingWebhooks = false;
+ break;
+ }
+
+ case 'TOGGLE_LOADING': {
+ draftState.loadingWebhooks = !state.loadingWebhooks;
break;
}
@@ -34,6 +41,15 @@ const reducer = (state, action) =>
break;
}
+ case 'SET_ALL_WEBHOOKS_TO_DELETE': {
+ if (state.webhooksToDelete.length === 0) {
+ draftState.webhooksToDelete = state.webhooks.map(webhook => webhook.id);
+ } else {
+ draftState.webhooksToDelete = [];
+ }
+
+ break;
+ }
case 'WEBHOOKS_DELETED': {
draftState.webhooks = state.webhooks.filter(
webhook => !state.webhooksToDelete.includes(webhook.id)
diff --git a/packages/core/admin/admin/src/pages/Webhooks/ListView/tests/reducer.test.js b/packages/core/admin/admin/src/pages/Webhooks/ListView/tests/reducer.test.js
index 6805746df03..663e62f9b02 100644
--- a/packages/core/admin/admin/src/pages/Webhooks/ListView/tests/reducer.test.js
+++ b/packages/core/admin/admin/src/pages/Webhooks/ListView/tests/reducer.test.js
@@ -287,5 +287,83 @@ describe('Admin | containers | Webhooks | ListView | reducer', () => {
expect(reducer(state, action)).toEqual(expectedState);
});
+
+ it('should clear webhooksToDelete when webhooksToDelete length > 0', () => {
+ const webhooks = [
+ {
+ id: 3,
+ name: 'webhook 1',
+ url: 'http://localhost:5000',
+ headers: {},
+ events: ['entry.create', 'entry.update', 'entry.delete'],
+ isEnabled: true,
+ },
+ {
+ id: 4,
+ name: 'webhook 2',
+ url: 'http://localhost:4000',
+ headers: {},
+ events: ['media.create', 'media.update'],
+ isEnabled: false,
+ },
+ {
+ id: 5,
+ name: 'webhook 2',
+ url: 'http://localhost:4000',
+ headers: {},
+ events: ['media.create', 'media.update'],
+ isEnabled: false,
+ },
+ ];
+
+ const state = { ...initialState, webhooks, webhooksToDelete: [3] };
+
+ const action = {
+ type: 'SET_ALL_WEBHOOKS_TO_DELETE',
+ };
+
+ const expectedState = { ...state, webhooks, webhooksToDelete: [] };
+
+ expect(reducer(state, action)).toEqual(expectedState);
+ });
+
+ it('should add all webhooks in webhooksToDelete when webhooksToDelete length === 0', () => {
+ const webhooks = [
+ {
+ id: 3,
+ name: 'webhook 1',
+ url: 'http://localhost:5000',
+ headers: {},
+ events: ['entry.create', 'entry.update', 'entry.delete'],
+ isEnabled: true,
+ },
+ {
+ id: 4,
+ name: 'webhook 2',
+ url: 'http://localhost:4000',
+ headers: {},
+ events: ['media.create', 'media.update'],
+ isEnabled: false,
+ },
+ {
+ id: 5,
+ name: 'webhook 2',
+ url: 'http://localhost:4000',
+ headers: {},
+ events: ['media.create', 'media.update'],
+ isEnabled: false,
+ },
+ ];
+
+ const state = { ...initialState, webhooks, webhooksToDelete: [] };
+
+ const action = {
+ type: 'SET_ALL_WEBHOOKS_TO_DELETE',
+ };
+
+ const expectedState = { ...state, webhooks, webhooksToDelete: [3, 4, 5] };
+
+ expect(reducer(state, action)).toEqual(expectedState);
+ });
});
});
diff --git a/packages/core/admin/admin/src/translations/en.json b/packages/core/admin/admin/src/translations/en.json
index 8a3d8522172..d3d3c1a993f 100644
--- a/packages/core/admin/admin/src/translations/en.json
+++ b/packages/core/admin/admin/src/translations/en.json
@@ -159,17 +159,23 @@
"Settings.webhooks.enabled": "Enabled",
"Settings.webhooks.event.publish-tooltip": "This event only exists for contents with Draft/Publish system enabled",
"Settings.webhooks.events.create": "Create",
+ "Settings.webhooks.events.delete": "Delete",
"Settings.webhooks.events.update": "Update",
"Settings.webhooks.form.events": "Events",
"Settings.webhooks.form.headers": "Headers",
"Settings.webhooks.form.name": "Name",
"Settings.webhooks.form.url": "Url",
"Settings.webhooks.key": "Key",
+ "Settings.webhooks.list.all-entries.select": "Select all entries",
"Settings.webhooks.list.button.add": "Add new webhook",
"Settings.webhooks.list.description": "Get POST changes notifications.",
"Settings.webhooks.list.empty.description": "Add your first one to this list.",
"Settings.webhooks.list.empty.link": "See our documentation",
"Settings.webhooks.list.empty.title": "There are no webhooks yet",
+ "Settings.webhooks.list.field.add": "Add another field to this collection type",
+ "Settings.webhooks.list.select": "Select",
+ "Settings.webhooks.list.th.actions": "actions",
+ "Settings.webhooks.list.th.status": "status",
"Settings.webhooks.singular": "webhook",
"Settings.webhooks.title": "Webhooks",
"Settings.webhooks.trigger": "Trigger",
diff --git a/packages/core/admin/ee/admin/pages/Roles/CreatePage/index.js b/packages/core/admin/ee/admin/pages/Roles/CreatePage/index.js
index 89e64a9a17f..ef311da534f 100644
--- a/packages/core/admin/ee/admin/pages/Roles/CreatePage/index.js
+++ b/packages/core/admin/ee/admin/pages/Roles/CreatePage/index.js
@@ -146,11 +146,11 @@ const CreatePage = () => {
<>
}>Add an entry}
- secondaryAction={(
+ secondaryAction={
}>
Edit
- )}
+ }
title="Other CT"
subtitle="36 entries found"
as="h1"
diff --git a/packages/core/admin/package.json b/packages/core/admin/package.json
index 8c2aaae12d6..cd5c8294aaf 100644
--- a/packages/core/admin/package.json
+++ b/packages/core/admin/package.json
@@ -41,8 +41,8 @@
"@strapi/babel-plugin-switch-ee-ce": "1.0.0",
"@strapi/helper-plugin": "3.6.6",
"@strapi/utils": "3.6.6",
- "@strapi/icons": "0.0.1-alpha.11",
- "@strapi/parts": "0.0.1-alpha.11",
+ "@strapi/icons": "0.0.1-alpha.15",
+ "@strapi/parts": "0.0.1-alpha.15",
"axios": "^0.21.1",
"babel-loader": "8.2.2",
"babel-plugin-styled-components": "1.12.0",
diff --git a/yarn.lock b/yarn.lock
index 662826e10cd..f1d9ab6ccc1 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3497,15 +3497,15 @@
tslib "^2.0.0"
upath "2.0.1"
-"@strapi/icons@0.0.1-alpha.11":
- version "0.0.1-alpha.11"
- resolved "https://registry.yarnpkg.com/@strapi/icons/-/icons-0.0.1-alpha.11.tgz#a92b27f8f3fd6081249c07c6acc6e4aefe38bd68"
- integrity sha512-BTl/2bGzCaVqhwj/vcmicL4Ya19J6NZ4A3O8MDDogoRwaDfHceLT1RpzKsID4x4kfXasopbNST1GzrJ2pvz9mw==
-
-"@strapi/parts@0.0.1-alpha.11":
- version "0.0.1-alpha.11"
- resolved "https://registry.yarnpkg.com/@strapi/parts/-/parts-0.0.1-alpha.11.tgz#ad42d40d979cabe73df4815faf2c65629a9b497d"
- integrity sha512-tyPPZm0QIPh/hSMvtei0hum2S2XM3WmFALOXNGI8rSOyGLYnRzWf+phlyUNOYYuyxwEeNIR3vU+w3n7xpRpXiQ==
+"@strapi/icons@0.0.1-alpha.15":
+ version "0.0.1-alpha.15"
+ resolved "https://registry.yarnpkg.com/@strapi/icons/-/icons-0.0.1-alpha.15.tgz#32fc824b732b4a21d5282f84696d6207ac5cbea1"
+ integrity sha512-FIczXDSEBPXTfptgqR6Hjh65Fpf4XF+kEm3o53PQX8G0GZ0Udpcbspqf2Kieeocg8TePgRkTI/oU6KS1aJbXrg==
+
+"@strapi/parts@0.0.1-alpha.15":
+ version "0.0.1-alpha.15"
+ resolved "https://registry.yarnpkg.com/@strapi/parts/-/parts-0.0.1-alpha.15.tgz#250cc29be0fa4cc2b91c8c0be49e1c2070a25450"
+ integrity sha512-VF4gp6xrowpnHBe3qJf0BHljZEXT8Y+oMk7XbW9HJ6w7Fxrm6SmmBfGb3LGFLxkzMj+5Log7FXD+ANER298r+A==
dependencies:
"@internationalized/number" "^3.0.2"
compute-scroll-into-view "^1.0.17"