feat: deploy to cloud homepage widget (#25774)

Co-authored-by: mathildeleg <82765709+mathildeleg@users.noreply.github.com>
This commit is contained in:
Simon Norris
2026-04-21 17:09:51 +02:00
committed by GitHub
parent e66251a30c
commit df2c928d0e
10 changed files with 101 additions and 11 deletions
+14 -1
View File
@@ -1,7 +1,7 @@
import * as React from 'react';
import { darkTheme, lightTheme } from '@strapi/design-system';
import { Clock, User, TrendUp } from '@strapi/icons';
import { Cloud, Clock, User, TrendUp } from '@strapi/icons';
import invariant from 'invariant';
import isFunction from 'lodash/isFunction';
import merge from 'lodash/merge';
@@ -347,6 +347,19 @@ class StrapiApp {
id: 'key-statistics',
roles: ['strapi-super-admin'],
},
{
icon: Cloud,
title: {
id: 'widget.deploy-now.title',
defaultMessage: 'Deploy',
},
component: async () => {
const { DeployNowWidget } = await import('./components/Widgets');
return DeployNowWidget;
},
pluginId: 'admin',
id: 'deploy-now',
},
]);
Object.keys(this.appPlugins).forEach((plugin) => {
@@ -1,6 +1,17 @@
import { useAuth, useTracking } from '@strapi/admin/strapi-admin';
import { Avatar, Badge, Box, Flex, Typography } from '@strapi/design-system';
import { Earth, Images, User, Key, Files, Layout, Graph, Webhooks } from '@strapi/icons';
import { Avatar, Badge, Box, Flex, LinkButton, Typography } from '@strapi/design-system';
import {
Cloud,
CloudUpload,
Earth,
Images,
User,
Key,
Files,
Layout,
Graph,
Webhooks,
} from '@strapi/icons';
import { useIntl } from 'react-intl';
import { Link } from 'react-router-dom';
import { styled } from 'styled-components';
@@ -248,4 +259,35 @@ const KeyStatisticsWidget = () => {
);
};
export { ProfileWidget, KeyStatisticsWidget };
/* -------------------------------------------------------------------------------------------------
* DeployNowWidget
* -----------------------------------------------------------------------------------------------*/
const DeployNowWidget = () => {
const { formatMessage } = useIntl();
return (
<Flex direction="column" gap={4} height="100%" alignItems="center" justifyContent="center">
<CloudUpload width="3.2rem" height="3.2rem" />
<Flex direction="column" gap={2}>
<Typography variant="beta" textAlign="center">
{formatMessage({
id: 'HomePage.widget.deploy-now.title',
defaultMessage: 'Ready to go live ?',
})}
</Typography>
<Typography variant="omega" textColor="neutral600" textAlign="center">
{formatMessage({
id: 'HomePage.widget.deploy-now.description',
defaultMessage: 'Deploy with Strapi Cloud',
})}
</Typography>
</Flex>
<LinkButton href="https://cloud.strapi.io/login" isExternal size="L" startIcon={<Cloud />}>
{formatMessage({ id: 'HomePage.widget.deploy-now.button', defaultMessage: 'Deploy Now' })}
</LinkButton>
</Flex>
);
};
export { ProfileWidget, KeyStatisticsWidget, DeployNowWidget };
@@ -768,5 +768,8 @@
"Usecase.title": "تخبرنا أكثر قليلا عن نفسك",
"Users.components.List.empty": "لا يوجد مستخدمون ...",
"Users.components.List.empty.withFilters": "لا يوجد مستخدمون لديهم عوامل التصفية المطبقة ...",
"Users.components.List.empty.withSearch": "لا يوجد مستخدمون مطابقون للبحث({search})..."
"Users.components.List.empty.withSearch": "لا يوجد مستخدمون مطابقون للبحث({search})...",
"HomePage.widget.deploy-now.title": "هل أنت مستعد للنشر؟",
"HomePage.widget.deploy-now.description": "انشر مشروعك.",
"HomePage.widget.deploy-now.button": "انشر الآن"
}
@@ -842,5 +842,8 @@
"HomePage.addWidget.noWidgetsAvailable": "Keine Widgets zum Hinzufügen verfügbar",
"HomePage.addWidget.button": "Widget hinzufügen",
"HomePage.widget.delete": "Löschen",
"HomePage.widget.drag": "Ziehen zum Verschieben"
"HomePage.widget.drag": "Ziehen zum Verschieben",
"HomePage.widget.deploy-now.title": "Bereit zum Veröffentlichen?",
"HomePage.widget.deploy-now.description": "Stellen Sie Ihr Projekt bereit.",
"HomePage.widget.deploy-now.button": "Jetzt deployen"
}
@@ -844,5 +844,8 @@
"HomePage.addWidget.noWidgetsAvailable": "No widgets available to add",
"HomePage.addWidget.button": "Add Widget",
"HomePage.widget.delete": "Delete",
"HomePage.widget.drag": "Drag to move"
"HomePage.widget.drag": "Drag to move",
"HomePage.widget.deploy-now.title": "Ready to go live?",
"HomePage.widget.deploy-now.description": "Deploy with Strapi Cloud",
"HomePage.widget.deploy-now.button": "Deploy Now"
}
@@ -799,5 +799,8 @@
"widget.key-statistics.list.entries": "Entradas",
"widget.key-statistics.list.locales": "Idiomas",
"widget.key-statistics.list.webhooks": "Webhooks",
"widget.profile.title": "Perfil"
"widget.profile.title": "Perfil",
"HomePage.widget.deploy-now.title": "¿Listo para publicar?",
"HomePage.widget.deploy-now.description": "Despliega tu proyecto.",
"HomePage.widget.deploy-now.button": "Desplegar ahora"
}
@@ -692,5 +692,8 @@
"notification.success.apitokencreated": "Jeton d'API créé avec succès",
"notification.success.apitokenedited": "Jeton d'API édité avec succès",
"notification.success.transfertokencreated": "Jeton de transfert créé avec succès",
"notification.success.transfertokenedited": "Jeton de transfert édité avec succès"
"notification.success.transfertokenedited": "Jeton de transfert édité avec succès",
"HomePage.widget.deploy-now.title": "Prêt à mettre en ligne ?",
"HomePage.widget.deploy-now.description": "Déployez votre projet.",
"HomePage.widget.deploy-now.button": "Déployer maintenant"
}
@@ -875,5 +875,8 @@
"widget.last-edited.single-type": "Tipo singolo",
"widget.last-edited.no-data": "Nessun elemento modificato",
"widget.last-published.title": "Ultimi elementi pubblicati",
"widget.last-published.no-data": "Nessun elemento pubblicato"
"widget.last-published.no-data": "Nessun elemento pubblicato",
"HomePage.widget.deploy-now.title": "Pronto per andare in produzione?",
"HomePage.widget.deploy-now.description": "Distribuisci il tuo progetto.",
"HomePage.widget.deploy-now.button": "Distribuisci ora"
}
@@ -650,5 +650,8 @@
"request.error.model.unknown": "此模型不存在",
"selectButtonTitle": "选择",
"skipToContent": "跳至内容",
"submit": "提交"
"submit": "提交",
"HomePage.widget.deploy-now.title": "准备上线了吗?",
"HomePage.widget.deploy-now.description": "部署您的项目。",
"HomePage.widget.deploy-now.button": "立即部署"
}
+14
View File
@@ -284,6 +284,14 @@ test.describe('Home as super admin', () => {
await waitForRestart(page);
}
});
test('a super admin should see the deploy now widget', async ({ page }) => {
const deployWidget = page.getByLabel(/Deploy/i, { exact: true });
await expect(deployWidget).toBeVisible();
await expect(deployWidget.getByText('Ready to go live')).toBeVisible();
await expect(deployWidget.getByText('Deploy with Strapi Cloud')).toBeVisible();
await expect(deployWidget.getByRole('link', { name: /deploy now/i })).toBeVisible();
});
});
test.describe('Home as editor', () => {
@@ -299,4 +307,10 @@ test.describe('Home as editor', () => {
const keyStatisticsWidget = page.getByLabel(/project statistics/i, { exact: true });
await expect(keyStatisticsWidget).not.toBeVisible();
});
test('a user should see the deploy now widget regardless of their role', async ({ page }) => {
const deployWidget = page.getByLabel(/Deploy/i, { exact: true });
await expect(deployWidget).toBeVisible();
await expect(deployWidget.getByRole('link', { name: /deploy now/i })).toBeVisible();
});
});