Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/tired-toys-grab.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@frameless/strapi-plugin-env-label": major
"@frameless/dashboard": major
---

Migrate `@frameless/env-albel` to Strapi version 5
6 changes: 6 additions & 0 deletions apps/dashboard/config/plugins.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
export default ({ env }) => ({
'env-label': {
enabled: true,
config: {
env_label: env('STRAPI_ENV_LABEL'),
},
},
'preview-button': {
enabled: true,
config: {
Expand Down
1 change: 1 addition & 0 deletions apps/dashboard/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"dependencies": {
"@_sh/strapi-plugin-ckeditor": "6.0.3",
"@frameless/preview-button": "workspace:*",
"@frameless/strapi-plugin-env-label": "workspace:*",
"@strapi/design-system": "2.1.2",
"@strapi/plugin-graphql": "5.33.4",
"@strapi/plugin-users-permissions": "5.33.4",
Expand Down
13 changes: 13 additions & 0 deletions packages/strapi-plugin-env-label/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# @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)


### Features

* **deps:** upgrade `@utrecht/` packages ([a835ad6](https://github.com/frameless/strapi/commit/a835ad66a0095e8d1d762677b380e89010225070))

# @frameless/strapi-plugin-env-label 1.0.0 (2024-05-02)


### Features

* **strap-plugin-env-label:** create strap-plugin-env-label ([f8a3a22](https://github.com/frameless/strapi/commit/f8a3a228476edc41c5b98af5565eb4e730c4f235))
33 changes: 33 additions & 0 deletions packages/strapi-plugin-env-label/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# @frameless/strapi-plugin-env-label

A Strapi plugin designed to visually represent the current environment.

## Installation

To install the plugin, navigate to your Strapi dashboard and execute the following command in your terminal:

```shell
yarn add @frameless/strapi-plugin-env-label
# or
npm install @frameless/strapi-plugin-env-label

```

## Configuration

Update the `your-strapi-directory/config/plugin.ts` file by adding the following code:

```ts

export default ({ env }) => ({
'env-label': {
enabled: true,
config: {
env_label: // use env('USE_ENV_VARIABLE') or put the value here, // accepted values: development|acceptance
},
},
});

```

After making these changes, rebuild your Strapi dashboard and start the dashboard server.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { useEffect, useRef } from 'react';

import { PLUGIN_ID } from '../../pluginId';

type InitializerProps = {
setPlugin: (id: string) => void;
};

const Initializer = ({ setPlugin }: InitializerProps) => {
const ref = useRef(setPlugin);

useEffect(() => {
ref.current(PLUGIN_ID);
}, []);

return null;
};

export { Initializer };
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { Box } from '@strapi/design-system';
import { StatusBadge as UtrechtStatusBadge } from '@utrecht/component-library-react';
import type { StatusBadgeProps as UtrechtStatusBadgeProps } from '@utrecht/component-library-react';
import { forwardRef } from 'react';
import type { ForwardedRef, PropsWithChildren } from 'react';
import { useIntl } from 'react-intl';
import styled from 'styled-components';

import usePluginConfig from '../../hooks/use-plugin-config';
import { getTranslation } from '../../utils/getTranslation';

interface StatusBadgeProps extends UtrechtStatusBadgeProps {
gap?: boolean;
}

const StyledStatusBadge = styled(UtrechtStatusBadge)`
max-inline-size: 100%;
inline-size: 100%;
`;

export const StatusBadge = forwardRef(
({ gap, ...resProps }: PropsWithChildren<StatusBadgeProps>, ref: ForwardedRef<HTMLSpanElement>) => {
const { formatMessage } = useIntl();
const { config } = usePluginConfig();

const regex = /^(development|acceptance)$/;

if (!config?.env_label || !regex.test(config.env_label)) return null;

return (
<Box
display="flex"
width="100%"
textAlign="center"
className="utrecht-theme test"
marginTop={gap ? 5 : undefined}
marginBottom={gap ? 5 : undefined}
>
<StyledStatusBadge ref={ref} status="warning" {...resProps}>
{formatMessage({
id: getTranslation(`${config?.env_label}-env-label-message`),
defaultMessage: `${config?.env_label}`,
})}
</StyledStatusBadge>
</Box>
);
},
);

StatusBadge.displayName = 'StatusBadge';
3 changes: 3 additions & 0 deletions packages/strapi-plugin-env-label/admin/src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { PLUGIN_ID } from './pluginId';

export const RESOLVE_CONFIG = `${PLUGIN_ID}/resolve-config`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { useNotification, useFetchClient } from '@strapi/strapi/admin';
import { useIntl } from 'react-intl';
import { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';

import { RESOLVE_CONFIG } from '../constants';
import { PLUGIN_ID } from '../pluginId';
import { getTranslation } from '../utils/getTranslation';

const usePluginConfig = () => {
const dispatch = useDispatch();
const { toggleNotification } = useNotification();
const { formatMessage } = useIntl();
const { isLoading, config } = useSelector((state: any) => state[`${PLUGIN_ID}_config`]);
const client = useFetchClient();

useEffect(() => {
// Do nothing if we have already loaded the config data.
if (!isLoading && !!config) {
return;
}
const abortController = new AbortController();

const fetchData = async () => {
try {
const endpoint = `/${PLUGIN_ID}/config`;
const { data } = await client.get(endpoint, {
signal: abortController.signal,
});

return data ?? {};
} catch (err) {
// eslint-disable-next-line no-console
console.error(err);

if (!abortController.signal.aborted) {
toggleNotification({
type: 'warning',
message: formatMessage({
id: getTranslation('notification.error'),
defaultMessage: 'An error occurred while fetching data',
}),
});

return err;
}
return null;
}
};
fetchData().then((data) => dispatch({ type: RESOLVE_CONFIG, data }));

// eslint-disable-next-line consistent-return
return () => abortController.abort();
}, [client, config, dispatch, isLoading, toggleNotification, formatMessage]);

return { config, isLoading };
};

export default usePluginConfig;
62 changes: 62 additions & 0 deletions packages/strapi-plugin-env-label/admin/src/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { Initializer } from './components/Initializer';
import { StatusBadge } from './components/StatusBadge';
import { PLUGIN_ID } from './pluginId';
import reducers from './reducers';
import '@utrecht/component-library-css';
import '@utrecht/design-tokens/dist/index.css';

type TranslateOptions = Record<string, string>;

const prefixPluginTranslations = (translate: TranslateOptions, pluginId: string): TranslateOptions => {
if (!pluginId) {
throw new TypeError("pluginId can't be empty");
}
return Object.keys(translate).reduce((acc, current) => {
acc[`${pluginId}.${current}`] = translate[current];
return acc;
}, {} as TranslateOptions);
};
export default {
register(app: any) {
app.addReducers(reducers);
app.registerPlugin({
id: PLUGIN_ID,
initializer: Initializer,
isReady: true,
name: PLUGIN_ID,
});
},

bootstrap(app: any) {
app.getPlugin('content-manager').injectComponent('listView', 'actions', {
name: 'env-label',
Component: StatusBadge,
});
app.getPlugin('content-manager').injectComponent('editView', 'right-links', {
name: 'env-label',
Component: StatusBadge,
});
},

async registerTrads({ locales }: { locales: string[] }) {
const importedTranslations = await Promise.all(
locales.map((locale: any) => {
return import(`./translations/${locale}.json`)
.then(({ default: data }) => {
return {
data: prefixPluginTranslations(data, PLUGIN_ID),
locale,
};
})
.catch(() => {
return {
data: {},
locale,
};
});
}),
);

return Promise.resolve(importedTranslations);
},
};
1 change: 1 addition & 0 deletions packages/strapi-plugin-env-label/admin/src/pluginId.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const PLUGIN_ID = 'env-label';
25 changes: 25 additions & 0 deletions packages/strapi-plugin-env-label/admin/src/reducers/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { produce } from 'immer';

import { RESOLVE_CONFIG } from '../constants';

const initialState = {
isLoading: true,
config: {},
};

const configReducer = produce((state = initialState, action) => {
switch (action.type) {
case RESOLVE_CONFIG: {
state.isLoading = false;
state.config = action.data;
break;
}

default:
return state;
}

return state;
});

export default configReducer;
9 changes: 9 additions & 0 deletions packages/strapi-plugin-env-label/admin/src/reducers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { PLUGIN_ID } from '../pluginId';

import config from './config';

const reducers = {
[`${PLUGIN_ID}_config`]: config,
};

export default reducers;
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"development-env-label-message": "Development",
"acceptance-env-label-message": "Acceptance"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"development-env-label-message": "Ontwikkeling",
"acceptance-env-label-message": "Acceptatie"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { PLUGIN_ID } from '../pluginId';

export const getTranslation = (id: string) => `${PLUGIN_ID}.${id}`;
4 changes: 4 additions & 0 deletions packages/strapi-plugin-env-label/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/* eslint-disable no-undef */
module.exports = {
presets: [['@babel/preset-env', { targets: { node: 'current' } }], '@babel/preset-react', '@babel/preset-typescript'],
};
4 changes: 4 additions & 0 deletions packages/strapi-plugin-env-label/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { reactConfig } from "@frameless/eslint-config/react-internal";

/** @type {import("eslint").Linter.Config} */
export default reactConfig;
31 changes: 31 additions & 0 deletions packages/strapi-plugin-env-label/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import type { Config } from 'jest';

const config: Config = {
preset: 'ts-jest',
moduleNameMapper: {
'\\.(css|scss)$': 'identity-obj-proxy',
'^.+\\.svg': '<rootDir>/tests/mocks/svgMock.tsx',
},
setupFilesAfterEnv: ['<rootDir>/tests/setupTests.ts'],
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
modulePaths: ['<rootDir>'],
testEnvironment: 'jsdom',

transform: {
'^.+\\.(ts|tsx)$': [
'ts-jest',
{
tsconfig: {
jsx: 'react',
esModuleInterop: true,
allowSyntheticDefaultImports: true,
skipLibCheck: true,
strict: false,
},
},
],
'^.+\\.(js|jsx)$': 'babel-jest',
},
};

export default config;
Loading