diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 6bee948be8..82cb946a0e 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -4,6 +4,8 @@ updates:
directory: /
schedule:
interval: weekly
+ day: sunday
+ time: '22:00'
versioning-strategy: increase
ignore:
# Only allow patch as minor babel versions need to be upgraded all together
@@ -24,6 +26,8 @@ updates:
directory: /
schedule:
interval: weekly
+ day: sunday
+ time: '22:00'
labels:
- 'source: dependencies'
- 'pr: chore'
diff --git a/docs/docs/core/admin/ee/intro.md b/docs/docs/core/admin/ee/intro.md
new file mode 100644
index 0000000000..12a3ff99bb
--- /dev/null
+++ b/docs/docs/core/admin/ee/intro.md
@@ -0,0 +1,17 @@
+---
+title: Introduction
+slug: /admin/ee
+tags:
+ - enterprise-edition
+---
+
+# Admin Enterprise Edition
+
+This section is an overview of all the features related to the Enterprise Edition in Admin:
+
+```mdx-code-block
+import DocCardList from '@theme/DocCardList';
+import { useCurrentSidebarCategory } from '@docusaurus/theme-common';
+
+
+```
diff --git a/docs/docs/core/admin/ee/review-workflows.md b/docs/docs/core/admin/ee/review-workflows.md
new file mode 100644
index 0000000000..fdd7fdd91f
--- /dev/null
+++ b/docs/docs/core/admin/ee/review-workflows.md
@@ -0,0 +1,140 @@
+---
+title: Review Workflows
+slug: /admin/ee/review-workflows
+description: Review workflow technical design
+tags:
+ - review-workflows
+ - implementation
+ - tech design
+---
+
+# Review Workflows
+
+## Summary
+
+The review workflow feature is only available in the Enterprise Edition.
+That is why, in part, it is completely decoupled from the code of the Community Edition.
+
+The purpose of this feature is to allow users to assign a tag to the various entities of their Strapi project. This tag is called a 'stage' and is available within what we will call a workflow.
+
+## Detailed backend design
+
+The Review Workflow feature have been built with one main consideration, to be decoupled from the Community Edition. As so, the implementation can relate a lot to how a plugin would be built.
+
+All the backend code related to Review Workflow can be found in `packages/core/admin/ee`.
+This code is separated into several elements:
+
+- Two content-types
+ - _strapi_workflows_: `packages/core/admin/ee/server/content-types/workflow/index.js`
+ - _strapi_workflows_stages_: `packages/core/admin/ee/server/content-types/workflow-stage/index.js`
+- Two controllers
+ - _workflows_: `packages/core/admin/ee/server/controllers/workflows/index.js`
+ - _stages_: `packages/core/admin/ee/server/controllers/workflows/stages/index.js`
+- One middleware
+ - _contentTypeMiddleware_: `packages/core/admin/ee/server/middlewares/review-workflows.js`
+- Routes
+ - `packages/core/admin/ee/server/routes/index.js`
+- Four services
+ - _review-workflows_: `packages/core/admin/ee/server/services/review-workflows/review-workflows.js`
+ - _workflows_: `packages/core/admin/ee/server/services/review-workflows/workflows.js`
+ - _stages_: `packages/core/admin/ee/server/services/review-workflows/stages.js`
+ - _metrics_: `packages/core/admin/ee/server/services/review-workflows/metrics.js`
+- One decorator
+ - _EntityService_ decorator: `packages/core/admin/ee/server/services/review-workflows/entity-service-decorator.js`
+- One utils file
+ - _Review workflows utils_: `packages/core/admin/ee/server/utils/review-workflows.js`
+- A bootstrap and a register part
+ - `packages/core/admin/ee/server/bootstrap.js`
+ - `packages/core/admin/ee/server/register.js`
+
+### Content types
+
+#### strapi_workflows
+
+This content type stores the workflow information and is responsible for holding all the information about stages and their order. In MVP, only one workflow is stored inside the Strapi database.
+
+#### strapi_workflows_stages
+
+This content type store the stage information such as its name.
+
+### Controllers
+
+#### workflows
+
+Used to interact with the `strapi_workflows` content-type.
+
+#### stages
+
+Used to interact with the `strapi_workflows_stages` content-type.
+
+### Middlewares
+
+#### contentTypeMiddleware
+
+In order to properly manage the options for content-type in the root level of the object, it is necessary to relocate the `reviewWorkflows` option within the `options` object located inside the content-type data. By doing so, we can ensure that all options are consistently organized and easily accessible within their respective data structures. This will also make it simpler to maintain and update the options as needed, providing a more streamlined and efficient workflow for developers working with the system. Therefore, it is recommended to move the reviewWorkflows option to its appropriate location within the options object inside the content-type data before sending it to the admin API.
+
+### Routes
+
+The Admin API of the Enterprise Edition includes several routes related to the Review Workflow feature. Here is a list of those routes:
+
+#### GET `/review-workflows/workflows`
+
+This route returns a list of all workflows.
+
+#### GET `/review-workflows/workflows/:id`
+
+This route returns the details of a specific workflow identified by the id parameter.
+
+#### GET `/review-workflows/workflows/:workflow_id/stages`
+
+This route returns a list of all stages associated with a specific workflow identified by the workflow_id parameter.
+
+#### GET `/review-workflows/workflows/:workflow_id/stages/:id`
+
+This route returns the details of a specific stage identified by the id parameter and associated with the workflow identified by the workflow_id parameter.
+
+#### PUT `/review-workflows/workflows/:workflow_id/stages`
+
+This route updates the stages associated with a specific workflow identified by the workflow_id parameter. The updated stages are passed in the request body.
+
+#### PUT `/content-manager/(collection|single)-types/:model_uid/:id/stage`
+
+This route updates the stage of a specific entity identified by the id parameter and belonging to a specific collection identified by the model_uid parameter. The new stage value is passed in the request body.
+
+### Services
+
+The Review Workflow feature of the Enterprise Edition includes several services to manipulate workflows and stages. Here is a list of those services:
+
+#### review-workflows
+
+This service is used during the bootstrap and register phases of Strapi. Its primary responsibility is to migrate data on entities as needed and add the stage field to the entity schemas.
+
+#### workflows
+
+This service is used to manipulate the workflows entities. It provides functionalities to create, retrieve, and update workflows.
+
+#### stages
+
+This service is used to manipulate the stages entities and to update stages on other entities. It provides functionalities to create, retrieve, update, and delete stages.
+
+#### metrics
+
+This is the telemetry service used to gather information on the usage of this feature. It provides information on the number of workflows and stages created, as well as the frequency of stage updates on entities.
+
+### Decorators
+
+#### Entity Service
+
+The entity service is decorated so that entities can be linked to a default stage upon creation. This allows the entities to be automatically associated with a specific workflow stage when they are created.
+
+## Alternatives
+
+The Review Workflow feature is currently included as a core feature within the Strapi repository. However, there has been discussion about potentially moving it to a plugin in the future. While no decision has been made on this subject yet, it is possible that it may happen at some point in the future.
+
+## Resources
+
+- https://docs.strapi.io/user-docs/settings/review-workflows
+- https://docs.strapi.io/user-docs/content-type-builder/creating-new-content-type#creating-a-new-content-type
+- https://docs.strapi.io/user-docs/users-roles-permissions/configuring-administrator-roles#plugins-and-settings
+- [Content manager](/content-manager/review-workflows)
+- [Content type builder](/content-type-builder/review-workflows)
diff --git a/docs/docs/core/admin/intro.md b/docs/docs/core/admin/intro.md
new file mode 100644
index 0000000000..123c42af8d
--- /dev/null
+++ b/docs/docs/core/admin/intro.md
@@ -0,0 +1,17 @@
+---
+title: Introduction
+slug: /admin
+tags:
+ - admin
+---
+
+# Admin
+
+This section is an overview of all the features related to admin:
+
+```mdx-code-block
+import DocCardList from '@theme/DocCardList';
+import { useCurrentSidebarCategory } from '@docusaurus/theme-common';
+
+
+```
diff --git a/docs/sidebars.js b/docs/sidebars.js
index 0c85976892..8a7c391a5f 100644
--- a/docs/sidebars.js
+++ b/docs/sidebars.js
@@ -16,17 +16,6 @@ const sidebars = {
// By default, Docusaurus generates a sidebar from the docs folder structure
docs: [
'index',
- {
- type: 'category',
- label: 'Admin',
- items: [
- {
- type: 'doc',
- label: 'Link Strapi Design System',
- id: 'core/admin/link-strapi-design-system',
- },
- ],
- },
{
type: 'category',
label: 'Core',
@@ -38,7 +27,26 @@ const sidebars = {
{
type: 'category',
label: 'Admin',
+ link: {
+ type: 'doc',
+ id: 'core/admin/intro',
+ },
items: [
+ {
+ type: 'category',
+ label: 'Enterprise Edition',
+ link: {
+ type: 'doc',
+ id: 'core/admin/ee/intro',
+ },
+ items: [
+ {
+ type: 'doc',
+ label: 'Review Workflows',
+ id: 'core/admin/ee/review-workflows',
+ },
+ ],
+ },
{
type: 'doc',
label: 'Link Strapi Design System',
diff --git a/packages/core/admin/admin/src/components/DragLayer/DragLayer.js b/packages/core/admin/admin/src/components/DragLayer/DragLayer.js
new file mode 100644
index 0000000000..6a4e1ea60e
--- /dev/null
+++ b/packages/core/admin/admin/src/components/DragLayer/DragLayer.js
@@ -0,0 +1,53 @@
+import * as React from 'react';
+import PropTypes from 'prop-types';
+import { useDragLayer } from 'react-dnd';
+import { Box } from '@strapi/design-system';
+
+function getStyle(initialOffset, currentOffset, mouseOffset) {
+ if (!initialOffset || !currentOffset) {
+ return { display: 'none' };
+ }
+
+ const { x, y } = mouseOffset;
+
+ return {
+ transform: `translate(${x}px, ${y}px)`,
+ };
+}
+
+export function DragLayer({ renderItem }) {
+ const { itemType, isDragging, item, initialOffset, currentOffset, mouseOffset } = useDragLayer(
+ (monitor) => ({
+ item: monitor.getItem(),
+ itemType: monitor.getItemType(),
+ initialOffset: monitor.getInitialSourceClientOffset(),
+ currentOffset: monitor.getSourceClientOffset(),
+ isDragging: monitor.isDragging(),
+ mouseOffset: monitor.getClientOffset(),
+ })
+ );
+
+ if (!isDragging) {
+ return null;
+ }
+
+ return (
+
+
+ {renderItem({ type: itemType, item })}
+
+
+ );
+}
+
+DragLayer.propTypes = {
+ renderItem: PropTypes.func.isRequired,
+};
diff --git a/packages/core/admin/admin/src/components/DragLayer/index.js b/packages/core/admin/admin/src/components/DragLayer/index.js
new file mode 100644
index 0000000000..c3e27fec39
--- /dev/null
+++ b/packages/core/admin/admin/src/components/DragLayer/index.js
@@ -0,0 +1 @@
+export * from './DragLayer';
diff --git a/packages/core/admin/admin/src/content-manager/components/DragLayer/ComponentDragPreview.js b/packages/core/admin/admin/src/content-manager/components/DragLayer/ComponentDragPreview.js
deleted file mode 100644
index 05610a6f3c..0000000000
--- a/packages/core/admin/admin/src/content-manager/components/DragLayer/ComponentDragPreview.js
+++ /dev/null
@@ -1,83 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import styled from 'styled-components';
-import { pxToRem } from '@strapi/helper-plugin';
-import { Box, Flex, Typography, IconButton } from '@strapi/design-system';
-import { Trash, Drag, CarretDown } from '@strapi/icons';
-
-const DragPreviewBox = styled(Box)`
- border: 1px solid ${({ theme }) => theme.colors.neutral200};
-`;
-
-const DropdownIconWrapper = styled(Box)`
- height: ${32 / 16}rem;
- width: ${32 / 16}rem;
- border-radius: 50%;
- display: flex;
- align-items: center;
- justify-content: center;
-
- svg {
- height: ${6 / 16}rem;
- width: ${11 / 16}rem;
- > path {
- fill: ${({ theme }) => theme.colors.neutral600};
- }
- }
-`;
-
-const ToggleButton = styled.button`
- border: none;
- background: transparent;
- display: block;
- width: 100%;
- text-align: unset;
- padding: 0;
-`;
-
-const DragPreview = ({ displayedValue }) => {
- return (
-
-
-
-
-
-
-
-
-
- {displayedValue}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
-};
-
-DragPreview.propTypes = {
- displayedValue: PropTypes.string.isRequired,
-};
-
-export default DragPreview;
diff --git a/packages/core/admin/admin/src/content-manager/components/DragLayer/index.js b/packages/core/admin/admin/src/content-manager/components/DragLayer/index.js
deleted file mode 100644
index 68433948b5..0000000000
--- a/packages/core/admin/admin/src/content-manager/components/DragLayer/index.js
+++ /dev/null
@@ -1,85 +0,0 @@
-import React from 'react';
-import { useDragLayer } from 'react-dnd';
-import LayoutDndProvider from '../LayoutDndProvider';
-
-import ItemTypes from '../../utils/ItemTypes';
-import CardPreview from '../../pages/ListSettingsView/components/CardPreview';
-
-import ComponentPreview from './ComponentDragPreview';
-import { RelationDragPreview } from './RelationDragPreview';
-
-const layerStyles = {
- position: 'fixed',
- pointerEvents: 'none',
- zIndex: 100,
- left: 0,
- top: 0,
- width: '100%',
- height: '100%',
-};
-
-function getItemStyles(initialOffset, currentOffset, mouseOffset) {
- if (!initialOffset || !currentOffset) {
- return { display: 'none' };
- }
-
- const { x, y } = mouseOffset;
- // TODO adjust
- const transform = `translate(${x}px, ${y}px)`;
-
- return {
- transform,
- WebkitTransform: transform,
- };
-}
-
-const CustomDragLayer = () => {
- const { itemType, isDragging, item, initialOffset, currentOffset, mouseOffset } = useDragLayer(
- (monitor) => ({
- item: monitor.getItem(),
- itemType: monitor.getItemType(),
- initialOffset: monitor.getInitialSourceClientOffset(),
- currentOffset: monitor.getSourceClientOffset(),
- isDragging: monitor.isDragging(),
- mouseOffset: monitor.getClientOffset(),
- })
- );
-
- if (!isDragging) {
- return null;
- }
-
- /**
- * Because a user may have multiple relations / dynamic zones / repeable fields in the same content type,
- * we append the fieldName for the item type to make them unique, however, we then want to extract that
- * first type to apply the correct preview.
- */
- const [actualType] = itemType.split('_');
-
- return (
-
-