Skip to content

Commit 96b3ee7

Browse files
author
Marwa
committed
feat: migrate @frameless/env-label to Strapi 5
1 parent 8a65518 commit 96b3ee7

File tree

34 files changed

+2084
-151
lines changed

34 files changed

+2084
-151
lines changed

.changeset/tired-toys-grab.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@frameless/strapi-plugin-env-label": major
3+
"@frameless/dashboard": major
4+
---
5+
6+
Migrate `@frameless/env-albel` to Strapi version 5

apps/dashboard/config/plugins.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
export default ({ env }) => ({
2+
'env-label': {
3+
enabled: true,
4+
config: {
5+
env_label: env('STRAPI_ENV_LABEL'),
6+
},
7+
},
28
'preview-button': {
39
enabled: true,
410
config: {

apps/dashboard/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"dependencies": {
2323
"@_sh/strapi-plugin-ckeditor": "6.0.3",
2424
"@frameless/preview-button": "workspace:*",
25+
"@frameless/strapi-plugin-env-label": "workspace:*",
2526
"@strapi/design-system": "2.1.2",
2627
"@strapi/plugin-graphql": "5.33.4",
2728
"@strapi/plugin-users-permissions": "5.33.4",
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# @frameless/strapi-plugin-env-label [1.1.0](https://github.com/frameless/strapi/compare/@frameless/strapi-plugin-env-label@1.0.0...@frameless/strapi-plugin-env-label@1.1.0) (2024-05-02)
2+
3+
4+
### Features
5+
6+
* **deps:** upgrade `@utrecht/` packages ([a835ad6](https://github.com/frameless/strapi/commit/a835ad66a0095e8d1d762677b380e89010225070))
7+
8+
# @frameless/strapi-plugin-env-label 1.0.0 (2024-05-02)
9+
10+
11+
### Features
12+
13+
* **strap-plugin-env-label:** create strap-plugin-env-label ([f8a3a22](https://github.com/frameless/strapi/commit/f8a3a228476edc41c5b98af5565eb4e730c4f235))
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# @frameless/strapi-plugin-env-label
2+
3+
A Strapi plugin designed to visually represent the current environment.
4+
5+
## Installation
6+
7+
To install the plugin, navigate to your Strapi dashboard and execute the following command in your terminal:
8+
9+
```shell
10+
yarn add @frameless/strapi-plugin-env-label
11+
# or
12+
npm install @frameless/strapi-plugin-env-label
13+
14+
```
15+
16+
## Configuration
17+
18+
Update the `your-strapi-directory/config/plugin.ts` file by adding the following code:
19+
20+
```ts
21+
22+
export default ({ env }) => ({
23+
'env-label': {
24+
enabled: true,
25+
config: {
26+
env_label: // use env('USE_ENV_VARIABLE') or put the value here, // accepted values: development|acceptance
27+
},
28+
},
29+
});
30+
31+
```
32+
33+
After making these changes, rebuild your Strapi dashboard and start the dashboard server.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { useEffect, useRef } from 'react';
2+
3+
import { PLUGIN_ID } from '../../pluginId';
4+
5+
type InitializerProps = {
6+
setPlugin: (id: string) => void;
7+
};
8+
9+
const Initializer = ({ setPlugin }: InitializerProps) => {
10+
const ref = useRef(setPlugin);
11+
12+
useEffect(() => {
13+
ref.current(PLUGIN_ID);
14+
}, []);
15+
16+
return null;
17+
};
18+
19+
export { Initializer };
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { Box } from '@strapi/design-system';
2+
import { StatusBadge as UtrechtStatusBadge } from '@utrecht/component-library-react';
3+
import type { StatusBadgeProps as UtrechtStatusBadgeProps } from '@utrecht/component-library-react';
4+
import { forwardRef } from 'react';
5+
import type { ForwardedRef, PropsWithChildren } from 'react';
6+
import { useIntl } from 'react-intl';
7+
8+
import usePluginConfig from '../../hooks/use-plugin-config';
9+
import { getTranslation } from '../../utils/getTranslation';
10+
11+
interface StatusBadgeProps extends UtrechtStatusBadgeProps {
12+
gap?: boolean;
13+
}
14+
15+
export const StatusBadge = forwardRef(
16+
({ gap, ...resProps }: PropsWithChildren<StatusBadgeProps>, ref: ForwardedRef<HTMLSpanElement>) => {
17+
const { formatMessage } = useIntl();
18+
const { config } = usePluginConfig();
19+
20+
const regex = /^(development|acceptance)$/;
21+
22+
if (!config?.env_label || !regex.test(config.env_label)) return null;
23+
24+
return (
25+
<Box className="utrecht-theme" marginTop={gap ? 5 : undefined} marginBottom={gap ? 5 : undefined}>
26+
<UtrechtStatusBadge ref={ref} status="warning" {...resProps}>
27+
{formatMessage({
28+
id: getTranslation(`${config?.env_label}-env-label-message`),
29+
})}
30+
</UtrechtStatusBadge>
31+
</Box>
32+
);
33+
},
34+
);
35+
36+
StatusBadge.displayName = 'StatusBadge';
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { PLUGIN_ID } from './pluginId';
2+
3+
export const RESOLVE_CONFIG = `${PLUGIN_ID}/resolve-config`;
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { useNotification, useFetchClient } from '@strapi/strapi/admin';
2+
import { useIntl } from 'react-intl';
3+
import { useEffect } from 'react';
4+
import { useDispatch, useSelector } from 'react-redux';
5+
6+
import { RESOLVE_CONFIG } from '../constants';
7+
import { PLUGIN_ID } from '../pluginId';
8+
import { getTranslation } from '../utils/getTranslation';
9+
10+
const usePluginConfig = () => {
11+
const dispatch = useDispatch();
12+
const { toggleNotification } = useNotification();
13+
const { formatMessage } = useIntl();
14+
const { isLoading, config } = useSelector((state: any) => state[`${PLUGIN_ID}_config`]);
15+
const client = useFetchClient();
16+
17+
useEffect(() => {
18+
// Do nothing if we have already loaded the config data.
19+
if (!isLoading && !!config) {
20+
return;
21+
}
22+
const abortController = new AbortController();
23+
24+
const fetchData = async () => {
25+
try {
26+
const endpoint = `/${PLUGIN_ID}/config`;
27+
const data = await client.get(endpoint, {
28+
signal: abortController.signal,
29+
});
30+
31+
return data ?? {};
32+
} catch (err) {
33+
// eslint-disable-next-line no-console
34+
console.error(err);
35+
36+
if (!abortController.signal.aborted) {
37+
toggleNotification({
38+
type: 'warning',
39+
message: formatMessage({
40+
id: getTranslation('notification.error'),
41+
defaultMessage: 'An error occurred while fetching data',
42+
}),
43+
});
44+
45+
return err;
46+
}
47+
return null;
48+
}
49+
};
50+
fetchData().then((data) => dispatch({ type: RESOLVE_CONFIG, data }));
51+
52+
// eslint-disable-next-line consistent-return
53+
return () => abortController.abort();
54+
}, [client, config, dispatch, isLoading, toggleNotification, formatMessage]);
55+
56+
return { config, isLoading };
57+
};
58+
59+
export default usePluginConfig;
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import { Initializer } from './components/Initializer';
2+
import { StatusBadge } from './components/StatusBadge';
3+
import { PLUGIN_ID } from './pluginId';
4+
import reducers from './reducers';
5+
import '@utrecht/component-library-css';
6+
import '@utrecht/design-tokens/dist/index.css';
7+
8+
type TranslateOptions = Record<string, string>;
9+
10+
const prefixPluginTranslations = (translate: TranslateOptions, pluginId: string): TranslateOptions => {
11+
if (!pluginId) {
12+
throw new TypeError("pluginId can't be empty");
13+
}
14+
return Object.keys(translate).reduce((acc, current) => {
15+
acc[`${pluginId}.${current}`] = translate[current];
16+
return acc;
17+
}, {} as TranslateOptions);
18+
};
19+
export default {
20+
register(app: any) {
21+
app.addReducers(reducers);
22+
app.registerPlugin({
23+
id: PLUGIN_ID,
24+
initializer: Initializer,
25+
isReady: true,
26+
name: PLUGIN_ID,
27+
});
28+
},
29+
30+
bootstrap(app: any) {
31+
app.getPlugin('content-manager').injectComponent('listView', 'actions', {
32+
name: 'env-label',
33+
Component: StatusBadge,
34+
});
35+
app.getPlugin('content-manager').injectComponent('editView', 'informations', {
36+
name: 'env-label',
37+
Component: StatusBadge,
38+
});
39+
app.getPlugin('content-manager').injectComponent('listView', 'deleteModalAdditionalInfos', {
40+
name: 'env-label',
41+
Component: StatusBadge,
42+
});
43+
},
44+
45+
async registerTranslation({ locales }: { locales: string[] }) {
46+
const importedTranslations = await Promise.all(
47+
locales.map((locale: any) => {
48+
return import(`./translations/${locale}.json`)
49+
.then(({ default: data }) => {
50+
return {
51+
data: prefixPluginTranslations(data, PLUGIN_ID),
52+
locale,
53+
};
54+
})
55+
.catch(() => {
56+
return {
57+
data: {},
58+
locale,
59+
};
60+
});
61+
}),
62+
);
63+
64+
return Promise.resolve(importedTranslations);
65+
},
66+
};

0 commit comments

Comments
 (0)