feat: Add plugin structure

Näser 3 years ago committed by Sébastien Näser
parent 57109fb783
commit 11b6200a3a

@ -20,6 +20,10 @@ module.exports = ({env}) => ({
},
'import-export-entries': {
enabled: true
}
},
'vendors': {
enabled: true,
resolve: './src/plugins/vendors'
},
// ...
});

4932
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -13,18 +13,17 @@
"generate:staging": "node scripts/strapi/build-staging.js"
},
"dependencies": {
"@strapi/plugin-i18n": "4.6.0",
"@strapi/plugin-users-permissions": "4.6.0",
"@strapi/provider-email-nodemailer": "4.5.6",
"@strapi/strapi": "^4.6.0",
"@strapi/utils": "4.5.6",
"better-sqlite3": "7.4.6",
"@strapi/plugin-i18n": "4.10.2",
"@strapi/plugin-users-permissions": "4.10.2",
"@strapi/provider-email-nodemailer": "4.10.2",
"@strapi/strapi": "4.10.2",
"@strapi/utils": "4.10.2",
"better-sqlite3": "8.3.0",
"mysql": "2.18.1",
"pg": "8.8.0",
"strapi-plugin-import-export-entries": "1.18.0",
"strapi-plugin-meilisearch": "^0.9.1",
"strapi-plugin-menus": "1.2.1",
"strapi-plugin-populate-deep": "1.1.2"
"pg": "8.10.0",
"strapi-plugin-import-export-entries": "1.19.1",
"strapi-plugin-menus": "1.4.1",
"strapi-plugin-populate-deep": "2.0.0"
},
"author": {
"name": "A Strapi developer"
@ -36,5 +35,8 @@
"node": ">=14.19.1 <=18.x.x",
"npm": ">=6.0.0"
},
"license": "MIT"
"license": "MIT",
"devDependencies": {
"request": "^2.88.2"
}
}

@ -0,0 +1,3 @@
# Strapi plugin vendors
A quick description of vendors.

@ -0,0 +1,24 @@
/**
*
* Initializer
*
*/
import { useEffect, useRef } from 'react';
import pluginId from '../../pluginId';
type InitializerProps = {
setPlugin: (id: string) => void;
};
const Initializer = ({ setPlugin }: InitializerProps) => {
const ref = useRef(setPlugin);
useEffect(() => {
ref.current(pluginId);
}, []);
return null;
};
export default Initializer;

@ -0,0 +1,12 @@
/**
*
* PluginIcon
*
*/
import React from 'react';
import { Puzzle } from '@strapi/icons';
const PluginIcon = () => <Puzzle />;
export default PluginIcon;

@ -0,0 +1,139 @@
/**
*
* This component is the skeleton around the actual pages, and should only
* contain code that should be seen on all pages. (e.g. navigation bar)
*
*/
import React, {useState} from 'react';
import {
SubNavLink,
SubNav,
SubNavHeader,
SubNavSections,
SubNavSection,
TextButton,
SubNavLinkSection,
Box
} from '@strapi/design-system';
import {Apps, ExclamationMarkCircle, Plus} from "@strapi/icons";
import './index.css';
const SubMenu = () => {
const [search, setSearch] = useState('');
const catalog = [
{
id: 1,
label: 'Products',
icon: <ExclamationMarkCircle/>,
to: '/catalog/products',
active: false,
},
{
id: 2,
label: 'Categories',
to: '/catalog/categories',
active: false,
},
{
id: 2,
label: 'Filters',
to: '/catalog/filters',
active: false,
},
];
const customers = [
{
id: 1,
label: 'Orders',
icon: <ExclamationMarkCircle/>,
to: '/customers/orders',
active: false,
},
{
id: 2,
label: 'Coupons',
to: '/customers/coupons',
active: false,
},
];
const parameters = [
{
id: 1,
label: 'General',
icon: <ExclamationMarkCircle/>,
to: '/settings/general',
active: false,
},
{
id: 2,
label: 'Products',
to: '/settings/products',
active: false,
},
{
id: 3,
label: 'Shipping',
icon: <Apps/>,
to: '/settings/shipping',
active: true
},
{
id: 4,
label: 'Payments',
to: '/settings/payments',
active: false,
},
{
id: 4,
label: 'Accounts & Privacy',
to: '/settings/accounts',
active: false,
},
{
id: 4,
label: 'Emails',
to: '/settings/emails',
active: false,
},
{
id: 4,
label: 'Integration',
to: '/settings/integration',
active: false,
},
{
id: 4,
label: 'Advanced',
to: '/settings/advanced',
active: false,
}
];
return (
<SubNav ariaLabel="Builder sub nav">
<SubNavHeader searchable value={search} onClear={() => setSearch('')}
onChange={e => setSearch(e.target.value)} label="Vendors admin" searchLabel="Search..."/>
<SubNavSections>
<SubNavSection label="Catalog" collapsable badgeLabel={parameters.length.toString()}>
{catalog.map(link => <SubNavLink to={link.to} active={link.active} key={link.id}>
{link.label}
</SubNavLink>)}
</SubNavSection>
<SubNavSection label="Customers" collapsable badgeLabel={parameters.length.toString()}>
{customers.map(link => <SubNavLink to={link.to} active={link.active} key={link.id}>
{link.label}
</SubNavLink>)}
</SubNavSection>
<SubNavSection label="Parameters" collapsable badgeLabel={parameters.length.toString()}>
{parameters.map(link => <SubNavLink to={link.to} isSubSectionChild key={link.id}>
{link.label}
</SubNavLink>)}
</SubNavSection>
</SubNavSections>
</SubNav>
);
};
export default SubMenu;

@ -0,0 +1,67 @@
import { prefixPluginTranslations } from '@strapi/helper-plugin';
import pluginPkg from '../../package.json';
import pluginId from './pluginId';
import Initializer from './components/Initializer';
import PluginIcon from './components/PluginIcon';
const name = pluginPkg.strapi.name;
export default {
register(app: any) {
app.addMenuLink({
to: `/plugins/${pluginId}`,
icon: PluginIcon,
intlLabel: {
id: `${pluginId}.plugin.name`,
defaultMessage: name,
},
Component: async () => {
const component = await import(/* webpackChunkName: "[request]" */ './pages/App');
return component;
},
permissions: [
// Uncomment to set the permissions of the plugin here
// {
// action: '', // the action name should be plugin::plugin-name.actionType
// subject: null,
// },
],
});
const plugin = {
id: pluginId,
initializer: Initializer,
isReady: false,
name,
};
app.registerPlugin(plugin);
},
bootstrap(app: any) {},
async registerTrads(app: any) {
const { locales } = app;
const importedTrads = await Promise.all(
(locales as any[]).map((locale) => {
return import(`./translations/${locale}.json`)
.then(({ default: data }) => {
return {
data: prefixPluginTranslations(data, pluginId),
locale,
};
})
.catch(() => {
return {
data: {},
locale,
};
});
})
);
return Promise.resolve(importedTrads);
},
};

@ -0,0 +1,5 @@
.vendors-container {
display: grid;
grid-template-columns: 14.5rem 1fr;
grid-template-rows: 1fr;
}

@ -0,0 +1,34 @@
/**
*
* This component is the skeleton around the actual pages, and should only
* contain code that should be seen on all pages. (e.g. navigation bar)
*
*/
import React, {useState} from 'react';
import {Switch, Route} from 'react-router-dom';
import {AnErrorOccurred} from '@strapi/helper-plugin';
import SubMenu from "../../components/SubMenu";
import pluginId from '../../pluginId';
import HomePage from '../HomePage';
import './index.css';
const App = () => {
return (
<div className='vendors-container'>
<aside>
<SubMenu/>
</aside>
<Switch>
<Route path={`/plugins/${pluginId}`} component={HomePage} exact/>
<Route component={AnErrorOccurred}/>
</Switch>
</div>
);
};
export default App;

@ -0,0 +1,19 @@
/*
*
* HomePage
*
*/
import React from 'react';
import pluginId from '../../../pluginId';
const CatalogCategoriesPage = () => {
return (
<div>
<h1>{pluginId}&apos;s Category's Page</h1>
<p>Happy coding</p>
</div>
);
};
export default CatalogCategoriesPage;

@ -0,0 +1,19 @@
/*
*
* HomePage
*
*/
import React from 'react';
import pluginId from '../../../pluginId';
const CatalogFiltersPage = () => {
return (
<div>
<h1>{pluginId}&apos;s Filter's Page</h1>
<p>Happy coding</p>
</div>
);
};
export default CatalogFiltersPage;

@ -0,0 +1,19 @@
/*
*
* HomePage
*
*/
import React from 'react';
import pluginId from '../../../pluginId';
const CatalogProductsPage = () => {
return (
<div>
<h1>{pluginId}&apos;s Products's Page</h1>
<p>Happy coding</p>
</div>
);
};
export default CatalogProductsPage;

@ -0,0 +1,19 @@
/*
*
* HomePage
*
*/
import React from 'react';
import pluginId from '../../../pluginId';
const CustomersCouponsPage = () => {
return (
<div>
<h1>{pluginId}&apos;s Coupon's page</h1>
<p>Happy coding</p>
</div>
);
};
export default CustomersCouponsPage;

@ -0,0 +1,19 @@
/*
*
* HomePage
*
*/
import React from 'react';
import pluginId from '../../../pluginId';
const CustomersOrdersPage = () => {
return (
<div>
<h1>{pluginId}&apos;s Order's Page</h1>
<p>Happy coding</p>
</div>
);
};
export default CustomersOrdersPage;

@ -7,7 +7,7 @@
import React from 'react';
import pluginId from '../../pluginId';
const DashboardPage: React.VoidFunctionComponent = () => {
const HomePage = () => {
return (
<div>
<h1>{pluginId}&apos;s HomePage</h1>
@ -16,4 +16,4 @@ const DashboardPage: React.VoidFunctionComponent = () => {
);
};
export default DashboardPage;
export default HomePage;

@ -0,0 +1,19 @@
/*
*
* HomePage
*
*/
import React from 'react';
import pluginId from '../../../pluginId';
const ParametersAccountsPage = () => {
return (
<div>
<h1>{pluginId}&apos;s Shipping's parameter Page</h1>
<p>Happy coding</p>
</div>
);
};
export default ParametersAccountsPage;

@ -0,0 +1,19 @@
/*
*
* HomePage
*
*/
import React from 'react';
import pluginId from '../../../pluginId';
const ParametersAdvancedPage = () => {
return (
<div>
<h1>{pluginId}&apos;s Shipping's parameter Page</h1>
<p>Happy coding</p>
</div>
);
};
export default ParametersAdvancedPage;

@ -0,0 +1,19 @@
/*
*
* HomePage
*
*/
import React from 'react';
import pluginId from '../../../pluginId';
const ParametersEmailsPage = () => {
return (
<div>
<h1>{pluginId}&apos;s Shipping's parameter Page</h1>
<p>Happy coding</p>
</div>
);
};
export default ParametersEmailsPage;

@ -0,0 +1,19 @@
/*
*
* HomePage
*
*/
import React from 'react';
import pluginId from '../../../pluginId';
const ParametersGeneralPage = () => {
return (
<div>
<h1>{pluginId}&apos;s General's parameter Page</h1>
<p>Happy coding</p>
</div>
);
};
export default ParametersGeneralPage;

@ -0,0 +1,19 @@
/*
*
* HomePage
*
*/
import React from 'react';
import pluginId from '../../../pluginId';
const ParametersIntegrationPage = () => {
return (
<div>
<h1>{pluginId}&apos;s Shipping's parameter Page</h1>
<p>Happy coding</p>
</div>
);
};
export default ParametersIntegrationPage;

@ -0,0 +1,19 @@
/*
*
* HomePage
*
*/
import React from 'react';
import pluginId from '../../../pluginId';
const ParametersPaymentsPage = () => {
return (
<div>
<h1>{pluginId}&apos;s Shipping's parameter Page</h1>
<p>Happy coding</p>
</div>
);
};
export default ParametersPaymentsPage;

@ -0,0 +1,19 @@
/*
*
* HomePage
*
*/
import React from 'react';
import pluginId from '../../../pluginId';
const ParametersProductsPage = () => {
return (
<div>
<h1>{pluginId}&apos;s Product's parameter Page</h1>
<p>Happy coding</p>
</div>
);
};
export default ParametersProductsPage;

@ -0,0 +1,19 @@
/*
*
* HomePage
*
*/
import React from 'react';
import pluginId from '../../../pluginId';
const ParametersShippingPage = () => {
return (
<div>
<h1>{pluginId}&apos;s Shipping's parameter Page</h1>
<p>Happy coding</p>
</div>
);
};
export default ParametersShippingPage;

@ -0,0 +1,5 @@
import pluginPkg from '../../package.json';
const pluginId = pluginPkg.name.replace(/^(@[^-,.][\w,-]+\/|strapi-)plugin-/i, '');
export default pluginId;

@ -0,0 +1,5 @@
import pluginId from '../pluginId';
const getTrad = (id: string) => `${pluginId}.${id}`;
export default getTrad;

@ -0,0 +1,5 @@
declare module '@strapi/design-system/*';
declare module '@strapi/design-system';
declare module '@strapi/icons';
declare module '@strapi/icons/*';
declare module '@strapi/helper-plugin';

@ -0,0 +1,51 @@
{
"name": "vendors",
"version": "0.0.0",
"description": "This is the description of the plugin.",
"strapi": {
"name": "vendors",
"description": "Description of vendors plugin",
"kind": "plugin"
},
"dependencies": {
"@strapi/design-system": "^1.6.3",
"@strapi/helper-plugin": "^4.6.0",
"@strapi/icons": "^1.6.3",
"prop-types": "^15.7.2"
},
"devDependencies": {
"@strapi/typescript-utils": "^4.6.0",
"@types/react": "^17.0.53",
"@types/react-dom": "^17.0.18",
"@types/react-router-dom": "^5.3.3",
"@types/styled-components": "^5.1.26",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-router-dom": "^5.3.4",
"styled-components": "^5.3.6",
"typescript": "5.0.4"
},
"peerDependencies": {
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-router-dom": "^5.3.4",
"styled-components": "^5.3.6"
},
"author": {
"name": "A Strapi developer"
},
"maintainers": [
{
"name": "A Strapi developer"
}
],
"engines": {
"node": ">=14.19.1 <=18.x.x",
"npm": ">=6.0.0"
},
"scripts": {
"develop": "tsc -p tsconfig.server.json -w",
"build": "tsc -p tsconfig.server.json"
},
"license": "MIT"
}

@ -0,0 +1,5 @@
import { Strapi } from '@strapi/strapi';
export default ({ strapi }: { strapi: Strapi }) => {
// bootstrap phase
};

@ -0,0 +1,4 @@
export default {
default: {},
validator() {},
};

@ -0,0 +1,5 @@
import myController from './my-controller';
export default {
myController,
};

@ -0,0 +1,10 @@
import { Strapi } from '@strapi/strapi';
export default ({ strapi }: { strapi: Strapi }) => ({
index(ctx) {
ctx.body = strapi
.plugin('vendors')
.service('myService')
.getWelcomeMessage();
},
});

@ -0,0 +1,5 @@
import { Strapi } from '@strapi/strapi';
export default ({ strapi }: { strapi: Strapi }) => {
// destroy phase
};

@ -0,0 +1,23 @@
import register from './register';
import bootstrap from './bootstrap';
import destroy from './destroy';
import config from './config';
import contentTypes from './content-types';
import controllers from './controllers';
import routes from './routes';
import middlewares from './middlewares';
import policies from './policies';
import services from './services';
export default {
register,
bootstrap,
destroy,
config,
controllers,
routes,
services,
contentTypes,
policies,
middlewares,
};

@ -0,0 +1 @@
export default {};

@ -0,0 +1,5 @@
import { Strapi } from '@strapi/strapi';
export default ({ strapi }: { strapi: Strapi }) => {
// registeration phase
};

@ -0,0 +1,10 @@
export default [
{
method: 'GET',
path: '/',
handler: 'myController.index',
config: {
policies: [],
},
},
];

@ -0,0 +1,5 @@
import myService from './my-service';
export default {
myService,
};

@ -0,0 +1,7 @@
import { Strapi } from '@strapi/strapi';
export default ({ strapi }: { strapi: Strapi }) => ({
getWelcomeMessage() {
return 'Welcome to Strapi 🚀';
},
});

@ -0,0 +1,3 @@
'use strict';
module.exports = require('./admin/src').default;

@ -0,0 +1,3 @@
'use strict';
module.exports = require('./dist/server');

@ -0,0 +1,20 @@
{
"extends": "@strapi/typescript-utils/tsconfigs/admin",
"compilerOptions": {
"target": "ESNext",
"strict": true
},
"include": ["admin", "custom.d.ts"],
"exclude": [
"node_modules/",
"dist/",
// Do not include server files in the server compilation
"server/",
// Do not include test files
"**/*.test.ts"
]
}

@ -0,0 +1,25 @@
{
"extends": "@strapi/typescript-utils/tsconfigs/server",
"compilerOptions": {
"outDir": "dist",
"rootDir": "."
},
"include": [
// Include the root directory
"server",
// Force the JSON files in the src folder to be included
"server/**/*.json"
],
"exclude": [
"node_modules/",
"dist/",
// Do not include admin files in the server compilation
"admin/",
// Do not include test files
"**/*.test.ts"
]
}

File diff suppressed because it is too large Load Diff

10154
yarn.lock

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save