Артем Леванов
commited on
Commit
·
41a71fd
1
Parent(s):
06870fc
first commit
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .editorconfig +22 -0
- .eslintrc.cjs +55 -0
- .gitignore +27 -0
- .prettierrc +12 -0
- .storybook/main.ts +25 -0
- .storybook/preview.tsx +45 -0
- index.html +13 -0
- package.json +71 -0
- plop/generation/common/api.js +141 -0
- plop/generation/common/component.js +55 -0
- plop/generation/common/form.js +55 -0
- plop/generation/common/slice.js +55 -0
- plop/generation/common/store.js +45 -0
- plop/generation/entities/entitiesComponent.js +40 -0
- plop/generation/entities/entity.js +75 -0
- plop/generation/features/feature.js +95 -0
- plop/generation/features/featuresComponent.js +40 -0
- plop/generation/pages/page.js +36 -0
- plop/generation/shared/shared.js +40 -0
- plop/generation/widgets/widget.js +40 -0
- plop/plopfile.js +51 -0
- plop/templates/api/createApi.hbs +18 -0
- plop/templates/api/deleteApi.hbs +15 -0
- plop/templates/api/fetchApi.hbs +10 -0
- plop/templates/api/fetchByIdApi.hbs +13 -0
- plop/templates/api/updateApi.hbs +17 -0
- plop/templates/component/component.hbs +16 -0
- plop/templates/component/component.stories.hbs +18 -0
- plop/templates/component/component.style.hbs +5 -0
- plop/templates/component/index.hbs +1 -0
- plop/templates/form/form.hbs +72 -0
- plop/templates/form/form.stories.hbs +18 -0
- plop/templates/form/form.style.hbs +9 -0
- plop/templates/layers/entities/cardUi/cardUi.hbs +31 -0
- plop/templates/layers/entities/cardUi/cardUi.stories.hbs +20 -0
- plop/templates/layers/entities/cardUi/cardUi.style.hbs +20 -0
- plop/templates/layers/entities/rootIndex.hbs +4 -0
- plop/templates/layers/entities/store/store.hbs +10 -0
- plop/templates/layers/entities/types/slice.hbs +4 -0
- plop/templates/layers/entities/types/sliceSchema.hbs +4 -0
- plop/templates/layers/features/createUi/createUi.hbs +30 -0
- plop/templates/layers/features/createUi/createUi.style.hbs +5 -0
- plop/templates/layers/features/deleteUi/deleteUi.hbs +27 -0
- plop/templates/layers/features/deleteUi/deleteUi.style.hbs +5 -0
- plop/templates/layers/features/editUi/editUi.hbs +31 -0
- plop/templates/layers/features/editUi/editUi.style.hbs +5 -0
- plop/templates/layers/features/rootIndex.hbs +4 -0
- plop/templates/layers/features/store/store.hbs +12 -0
- plop/templates/layers/features/types/sliceSchema.hbs +6 -0
- plop/templates/layers/rootIndex/rootIndex.hbs +1 -0
.editorconfig
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Файл с настройками для редактора.
|
2 |
+
#
|
3 |
+
# Если вы разрабатываете в редакторе WebStorm, BBEdit, Coda или SourceLair
|
4 |
+
# этот файл уже поддерживается и не нужно производить никаких дополнительных
|
5 |
+
# действий.
|
6 |
+
#
|
7 |
+
# Если вы ведёте разработку в другом редакторе, зайдите
|
8 |
+
# на https://editorconfig.org и в разделе «Download a Plugin»
|
9 |
+
# скачайте дополнение для вашего редактора.
|
10 |
+
|
11 |
+
root = true
|
12 |
+
|
13 |
+
[*]
|
14 |
+
charset = utf-8
|
15 |
+
end_of_line = lf
|
16 |
+
indent_size = 4
|
17 |
+
indent_style = space
|
18 |
+
insert_final_newline = true
|
19 |
+
trim_trailing_whitespace = true
|
20 |
+
|
21 |
+
[*.{json,md}]
|
22 |
+
indent_size = 2
|
.eslintrc.cjs
ADDED
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
module.exports = {
|
2 |
+
"env": {
|
3 |
+
"browser": true,
|
4 |
+
"es2021": true
|
5 |
+
},
|
6 |
+
"extends": [
|
7 |
+
'plugin:react/recommended',
|
8 |
+
'plugin:@tanstack/eslint-plugin-query/recommended',
|
9 |
+
'plugin:storybook/recommended',
|
10 |
+
'airbnb',
|
11 |
+
'plugin:prettier/recommended'
|
12 |
+
],
|
13 |
+
"overrides": [
|
14 |
+
{
|
15 |
+
"env": {
|
16 |
+
"node": true
|
17 |
+
},
|
18 |
+
"files": [
|
19 |
+
".eslintrc.{js,cjs}"
|
20 |
+
],
|
21 |
+
"parserOptions": {
|
22 |
+
"sourceType": "script"
|
23 |
+
}
|
24 |
+
}
|
25 |
+
],
|
26 |
+
"parser": "@typescript-eslint/parser",
|
27 |
+
"parserOptions": {
|
28 |
+
"ecmaVersion": "latest",
|
29 |
+
"sourceType": "module"
|
30 |
+
},
|
31 |
+
"plugins": [
|
32 |
+
"@typescript-eslint",
|
33 |
+
"react",
|
34 |
+
"@tanstack/query"
|
35 |
+
],
|
36 |
+
"ignorePatterns": ["*.svg", "*.json"],
|
37 |
+
"rules": {
|
38 |
+
"react/jsx-filename-extension": ["error", { "extensions": [".tsx"] }],
|
39 |
+
'import/no-unresolved': 'off',
|
40 |
+
'import/prefer-default-export': 'off',
|
41 |
+
'no-unused-vars': 'warn',
|
42 |
+
'react/require-default-props': 'off',
|
43 |
+
'react/react-in-jsx-scope': 'off',
|
44 |
+
'react/jsx-props-no-spreading': 'warn',
|
45 |
+
'react/function-component-definition': 'off',
|
46 |
+
'no-shadow': 'off',
|
47 |
+
'import/extensions': 'off',
|
48 |
+
'import/no-extraneous-dependencies': 'off',
|
49 |
+
'no-underscore-dangle': 'off',
|
50 |
+
'no-param-reassign': 'off',
|
51 |
+
'no-undef': 'off',
|
52 |
+
"react/jsx-max-props-per-line": ['error', {maximum: 3}],
|
53 |
+
"prettier/prettier": ['error', {arrowParens: 'always'}]
|
54 |
+
}
|
55 |
+
}
|
.gitignore
ADDED
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Logs
|
2 |
+
logs
|
3 |
+
*.log
|
4 |
+
npm-debug.log*
|
5 |
+
yarn-debug.log*
|
6 |
+
yarn-error.log*
|
7 |
+
pnpm-debug.log*
|
8 |
+
lerna-debug.log*
|
9 |
+
|
10 |
+
node_modules
|
11 |
+
dist
|
12 |
+
build
|
13 |
+
package-lock.json
|
14 |
+
dist-ssr
|
15 |
+
*.local
|
16 |
+
.env
|
17 |
+
|
18 |
+
# Editor directories and files
|
19 |
+
.vscode/*
|
20 |
+
!.vscode/extensions.json
|
21 |
+
.idea
|
22 |
+
.DS_Store
|
23 |
+
*.suo
|
24 |
+
*.ntvs*
|
25 |
+
*.njsproj
|
26 |
+
*.sln
|
27 |
+
*.sw?
|
.prettierrc
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"printWidth": 130,
|
3 |
+
"semi": true,
|
4 |
+
"singleQuote": true,
|
5 |
+
"tabWidth": 4,
|
6 |
+
"jsxSingleQuote": false,
|
7 |
+
"bracketSpacing": true,
|
8 |
+
"trailingComma": "es5",
|
9 |
+
"arrowParens": "always",
|
10 |
+
"jsxBracketSameLine": false,
|
11 |
+
"endOfLine": "lf"
|
12 |
+
}
|
.storybook/main.ts
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import type { StorybookConfig } from '@storybook/react-vite';
|
2 |
+
import svgr from 'vite-plugin-svgr';
|
3 |
+
|
4 |
+
const config: StorybookConfig = {
|
5 |
+
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
|
6 |
+
addons: [
|
7 |
+
'@storybook/addon-links',
|
8 |
+
'@storybook/addon-essentials',
|
9 |
+
'@storybook/addon-onboarding',
|
10 |
+
'@storybook/addon-interactions',
|
11 |
+
],
|
12 |
+
framework: {
|
13 |
+
name: '@storybook/react-vite',
|
14 |
+
options: {},
|
15 |
+
},
|
16 |
+
docs: {
|
17 |
+
autodocs: 'tag',
|
18 |
+
},
|
19 |
+
viteFinal: async (config) => {
|
20 |
+
config.plugins.push(svgr());
|
21 |
+
|
22 |
+
return config;
|
23 |
+
},
|
24 |
+
};
|
25 |
+
export default config;
|
.storybook/preview.tsx
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import type { Preview } from '@storybook/react';
|
2 |
+
import { QueryProvider } from '../src/app/providers/QueryProvider';
|
3 |
+
import ThemeProvider from '../src/app/providers/ThemeProviders/ui/ThemeProvider';
|
4 |
+
import { useTheme } from '../src/app/providers/ThemeProviders';
|
5 |
+
import '../src/app/globalStyles/styles.scss';
|
6 |
+
|
7 |
+
const preview: Preview = {
|
8 |
+
parameters: {
|
9 |
+
actions: { argTypesRegex: '^on[A-Z].*' },
|
10 |
+
controls: {
|
11 |
+
matchers: {
|
12 |
+
color: /(background|color)$/i,
|
13 |
+
date: /Date$/i,
|
14 |
+
},
|
15 |
+
},
|
16 |
+
},
|
17 |
+
globalTypes: {
|
18 |
+
theme: {
|
19 |
+
description: 'Выбрать тему',
|
20 |
+
defaultValue: 'light',
|
21 |
+
toolbar: {
|
22 |
+
title: 'Theme',
|
23 |
+
icon: 'circlehollow',
|
24 |
+
items: ['light', 'dark'],
|
25 |
+
dynamicTitle: true,
|
26 |
+
},
|
27 |
+
},
|
28 |
+
},
|
29 |
+
decorators: [
|
30 |
+
(Story, context) => {
|
31 |
+
const { toggleTheme } = useTheme();
|
32 |
+
toggleTheme(context.globals.theme);
|
33 |
+
|
34 |
+
return (
|
35 |
+
<QueryProvider>
|
36 |
+
<ThemeProvider>
|
37 |
+
<Story />
|
38 |
+
</ThemeProvider>
|
39 |
+
</QueryProvider>
|
40 |
+
);
|
41 |
+
},
|
42 |
+
],
|
43 |
+
};
|
44 |
+
|
45 |
+
export default preview;
|
index.html
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!doctype html>
|
2 |
+
<html lang="ru">
|
3 |
+
<head>
|
4 |
+
<meta charset="UTF-8" />
|
5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
6 |
+
<meta name="description" content="Добро пожаловать" />
|
7 |
+
<title>Добро пожаловать!</title>
|
8 |
+
</head>
|
9 |
+
<body>
|
10 |
+
<div id="root"></div>
|
11 |
+
<script type="module" src="/src/main.tsx"></script>
|
12 |
+
</body>
|
13 |
+
</html>
|
package.json
ADDED
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "webrise-vite-start",
|
3 |
+
"description": "node 20.11.0",
|
4 |
+
"private": true,
|
5 |
+
"version": "0.0.0",
|
6 |
+
"scripts": {
|
7 |
+
"dev": "vite",
|
8 |
+
"build": "tsc && vite build",
|
9 |
+
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
10 |
+
"preview": "vite preview",
|
11 |
+
"storybook": "storybook dev -p 6006",
|
12 |
+
"build-storybook": "storybook build",
|
13 |
+
"plop:entity": "plop entity --plopfile ./plop/plopfile.js",
|
14 |
+
"plop:feature": "plop feature --plopfile ./plop/plopfile.js",
|
15 |
+
"plop:page": "plop page --plopfile ./plop/plopfile.js",
|
16 |
+
"plop:shared": "plop shared --plopfile ./plop/plopfile.js",
|
17 |
+
"plop:widget": "plop widget --plopfile ./plop/plopfile.js",
|
18 |
+
"plop:api": "plop api --plopfile ./plop/plopfile.js",
|
19 |
+
"plop:form": "plop form --plopfile ./plop/plopfile.js",
|
20 |
+
"plop:store": "plop store --plopfile ./plop/plopfile.js",
|
21 |
+
"plop:slice": "plop slice --plopfile ./plop/plopfile.js",
|
22 |
+
"plop:component": "plop component --plopfile ./plop/plopfile.js"
|
23 |
+
},
|
24 |
+
"dependencies": {
|
25 |
+
"@hookform/resolvers": "^3.3.4",
|
26 |
+
"@tanstack/react-query": "^5.18.1",
|
27 |
+
"@tanstack/react-query-devtools": "^5.18.1",
|
28 |
+
"axios": "^1.6.7",
|
29 |
+
"inputmask": "^5.0.8",
|
30 |
+
"react": "^18.2.0",
|
31 |
+
"react-dom": "^18.2.0",
|
32 |
+
"react-hook-form": "^7.50.0",
|
33 |
+
"react-router-dom": "^6.22.0",
|
34 |
+
"zod": "^3.22.4",
|
35 |
+
"zustand": "^4.5.0"
|
36 |
+
},
|
37 |
+
"devDependencies": {
|
38 |
+
"@storybook/addon-essentials": "^7.6.14",
|
39 |
+
"@storybook/addon-interactions": "^7.6.14",
|
40 |
+
"@storybook/addon-links": "^7.6.14",
|
41 |
+
"@storybook/addon-onboarding": "^1.0.11",
|
42 |
+
"@storybook/blocks": "^7.6.14",
|
43 |
+
"@storybook/builder-vite": "^7.6.14",
|
44 |
+
"@storybook/react": "^7.6.14",
|
45 |
+
"@storybook/react-vite": "^7.6.14",
|
46 |
+
"@storybook/test": "^7.6.14",
|
47 |
+
"@tanstack/eslint-plugin-query": "^5.18.1",
|
48 |
+
"@types/react": "^18.2.43",
|
49 |
+
"@types/react-dom": "^18.2.17",
|
50 |
+
"@typescript-eslint/eslint-plugin": "^6.19.1",
|
51 |
+
"@typescript-eslint/parser": "^6.19.1",
|
52 |
+
"@vitejs/plugin-react": "^4.2.1",
|
53 |
+
"eslint": "^8.56.0",
|
54 |
+
"eslint-config-airbnb": "^19.0.4",
|
55 |
+
"eslint-config-prettier": "^9.1.0",
|
56 |
+
"eslint-plugin-import": "^2.29.1",
|
57 |
+
"eslint-plugin-jsx-a11y": "^6.8.0",
|
58 |
+
"eslint-plugin-prettier": "^5.1.3",
|
59 |
+
"eslint-plugin-react": "^7.33.2",
|
60 |
+
"eslint-plugin-react-hooks": "^4.6.0",
|
61 |
+
"eslint-plugin-react-refresh": "^0.4.5",
|
62 |
+
"eslint-plugin-storybook": "^0.6.15",
|
63 |
+
"plop": "^4.0.1",
|
64 |
+
"prettier": "^3.2.4",
|
65 |
+
"sass": "^1.70.0",
|
66 |
+
"storybook": "^7.6.14",
|
67 |
+
"typescript": "^5.2.2",
|
68 |
+
"vite": "^5.0.8",
|
69 |
+
"vite-plugin-svgr": "^4.2.0"
|
70 |
+
}
|
71 |
+
}
|
plop/generation/common/api.js
ADDED
@@ -0,0 +1,141 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
const api = (plop) => {
|
2 |
+
plop.setGenerator('api', {
|
3 |
+
description: 'Создает апи',
|
4 |
+
prompts: [
|
5 |
+
{
|
6 |
+
type: 'list',
|
7 |
+
name: 'apiType',
|
8 |
+
message: 'Какой тип запроса?',
|
9 |
+
choices: [
|
10 |
+
{
|
11 |
+
name: 'Запрос списка (fetchNames)',
|
12 |
+
value: 'fetchList',
|
13 |
+
},
|
14 |
+
{
|
15 |
+
name: 'Запрос по id (fetchNameById)',
|
16 |
+
value: 'fetchById',
|
17 |
+
},
|
18 |
+
{
|
19 |
+
name: 'Создание слайса (createName)',
|
20 |
+
value: 'create',
|
21 |
+
},
|
22 |
+
{
|
23 |
+
name: 'Обновление слайса (updateName)',
|
24 |
+
value: 'update',
|
25 |
+
},
|
26 |
+
{
|
27 |
+
name: 'Удаление слайса (deleteName)',
|
28 |
+
value: 'delete',
|
29 |
+
},
|
30 |
+
],
|
31 |
+
},
|
32 |
+
{
|
33 |
+
type: 'list',
|
34 |
+
name: 'layerName',
|
35 |
+
message: 'В какой слой положить?',
|
36 |
+
choices: [
|
37 |
+
{
|
38 |
+
name: 'entities',
|
39 |
+
value: 'entities',
|
40 |
+
},
|
41 |
+
{
|
42 |
+
name: 'features',
|
43 |
+
value: 'features',
|
44 |
+
},
|
45 |
+
{
|
46 |
+
name: 'widgets',
|
47 |
+
value: 'widgets',
|
48 |
+
},
|
49 |
+
],
|
50 |
+
},
|
51 |
+
{
|
52 |
+
type: 'input',
|
53 |
+
name: 'sliceName',
|
54 |
+
message: 'В какой слайс?',
|
55 |
+
},
|
56 |
+
],
|
57 |
+
actions: (data) => {
|
58 |
+
let actionList = [];
|
59 |
+
|
60 |
+
switch (data.apiType) {
|
61 |
+
case 'fetchList':
|
62 |
+
actionList = [
|
63 |
+
{
|
64 |
+
type: 'add',
|
65 |
+
path: '../src/{{layerName}}/{{sliceName}}/api/fetch{{sliceName}}s.ts',
|
66 |
+
templateFile: './templates/api/fetchApi.hbs',
|
67 |
+
},
|
68 |
+
{
|
69 |
+
type: 'add',
|
70 |
+
path: '../src/{{layerName}}/{{sliceName}}/lib/query/useFetch{{sliceName}}s.tsx',
|
71 |
+
templateFile: './templates/query/fetchQuery.hbs',
|
72 |
+
},
|
73 |
+
];
|
74 |
+
break;
|
75 |
+
case 'fetchById':
|
76 |
+
actionList = [
|
77 |
+
{
|
78 |
+
type: 'add',
|
79 |
+
path: '../src/{{layerName}}/{{sliceName}}/api/fetch{{sliceName}}ById.ts',
|
80 |
+
templateFile: './templates/api/fetchByIdApi.hbs',
|
81 |
+
},
|
82 |
+
{
|
83 |
+
type: 'add',
|
84 |
+
path: '../src/{{layerName}}/{{sliceName}}/lib/query/useFetch{{sliceName}}ById.tsx',
|
85 |
+
templateFile: './templates/query/fetchByIdQuery.hbs',
|
86 |
+
},
|
87 |
+
];
|
88 |
+
break;
|
89 |
+
case 'create':
|
90 |
+
actionList = [
|
91 |
+
{
|
92 |
+
type: 'add',
|
93 |
+
path: '../src/{{layerName}}/{{sliceName}}/api/create{{sliceName}}.ts',
|
94 |
+
templateFile: './templates/api/createApi.hbs',
|
95 |
+
},
|
96 |
+
{
|
97 |
+
type: 'add',
|
98 |
+
path: '../src/{{layerName}}/{{sliceName}}/lib/query/useCreate{{sliceName}}.tsx',
|
99 |
+
templateFile: './templates/query/createQuery.hbs',
|
100 |
+
},
|
101 |
+
];
|
102 |
+
break;
|
103 |
+
case 'update':
|
104 |
+
actionList = [
|
105 |
+
{
|
106 |
+
type: 'add',
|
107 |
+
path: '../src/{{layerName}}/{{sliceName}}/api/update{{sliceName}}.ts',
|
108 |
+
templateFile: './templates/api/updateApi.hbs',
|
109 |
+
},
|
110 |
+
{
|
111 |
+
type: 'add',
|
112 |
+
path: '../src/{{layerName}}/{{sliceName}}/lib/query/useUpdate{{sliceName}}.tsx',
|
113 |
+
templateFile: './templates/query/updateQuery.hbs',
|
114 |
+
},
|
115 |
+
];
|
116 |
+
break;
|
117 |
+
case 'delete':
|
118 |
+
actionList = [
|
119 |
+
{
|
120 |
+
type: 'add',
|
121 |
+
path: '../src/{{layerName}}/{{sliceName}}/api/delete{{sliceName}}.ts',
|
122 |
+
templateFile: './templates/api/deleteApi.hbs',
|
123 |
+
},
|
124 |
+
{
|
125 |
+
type: 'add',
|
126 |
+
path: '../src/{{layerName}}/{{sliceName}}/lib/query/useDelete{{sliceName}}.tsx',
|
127 |
+
templateFile: './templates/query/deleteQuery.hbs',
|
128 |
+
},
|
129 |
+
];
|
130 |
+
break;
|
131 |
+
default:
|
132 |
+
console.log('Нет такого типа');
|
133 |
+
break;
|
134 |
+
}
|
135 |
+
|
136 |
+
return actionList;
|
137 |
+
},
|
138 |
+
});
|
139 |
+
};
|
140 |
+
|
141 |
+
module.exports = api;
|
plop/generation/common/component.js
ADDED
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
const component = (plop) => {
|
2 |
+
plop.setGenerator('component', {
|
3 |
+
description: 'Создает стандартный компонент',
|
4 |
+
prompts: [
|
5 |
+
{
|
6 |
+
type: 'list',
|
7 |
+
name: 'layerName',
|
8 |
+
message: 'В какой слой положить?',
|
9 |
+
choices: [
|
10 |
+
{
|
11 |
+
name: 'entities',
|
12 |
+
value: 'entities',
|
13 |
+
},
|
14 |
+
{
|
15 |
+
name: 'features',
|
16 |
+
value: 'features',
|
17 |
+
},
|
18 |
+
{
|
19 |
+
name: 'widgets',
|
20 |
+
value: 'widgets',
|
21 |
+
},
|
22 |
+
],
|
23 |
+
},
|
24 |
+
{
|
25 |
+
type: 'input',
|
26 |
+
name: 'sliceName',
|
27 |
+
message: 'В какой слайс?',
|
28 |
+
},
|
29 |
+
{
|
30 |
+
type: 'input',
|
31 |
+
name: 'name',
|
32 |
+
message: 'Название компонента?',
|
33 |
+
},
|
34 |
+
],
|
35 |
+
actions: [
|
36 |
+
{
|
37 |
+
type: 'add',
|
38 |
+
path: '../src/{{layerName}}/{{sliceName}}/ui/{{name}}/{{name}}.tsx',
|
39 |
+
templateFile: './templates/component/component.hbs',
|
40 |
+
},
|
41 |
+
{
|
42 |
+
type: 'add',
|
43 |
+
path: '../src/{{layerName}}/{{sliceName}}/ui/{{name}}/{{name}}.module.scss',
|
44 |
+
templateFile: './templates/component/component.style.hbs',
|
45 |
+
},
|
46 |
+
{
|
47 |
+
type: 'add',
|
48 |
+
path: '../src/{{layerName}}/{{sliceName}}/ui/{{name}}/{{name}}.stories.tsx',
|
49 |
+
templateFile: './templates/component/component.stories.hbs',
|
50 |
+
},
|
51 |
+
],
|
52 |
+
});
|
53 |
+
};
|
54 |
+
|
55 |
+
module.exports = component;
|
plop/generation/common/form.js
ADDED
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
const form = (plop) => {
|
2 |
+
plop.setGenerator('form', {
|
3 |
+
description: 'Создает стандартную форму',
|
4 |
+
prompts: [
|
5 |
+
{
|
6 |
+
type: 'list',
|
7 |
+
name: 'layerName',
|
8 |
+
message: 'В какой слой положить?',
|
9 |
+
choices: [
|
10 |
+
{
|
11 |
+
name: 'entities',
|
12 |
+
value: 'entities',
|
13 |
+
},
|
14 |
+
{
|
15 |
+
name: 'features',
|
16 |
+
value: 'features',
|
17 |
+
},
|
18 |
+
{
|
19 |
+
name: 'widgets',
|
20 |
+
value: 'widgets',
|
21 |
+
},
|
22 |
+
],
|
23 |
+
},
|
24 |
+
{
|
25 |
+
type: 'input',
|
26 |
+
name: 'sliceName',
|
27 |
+
message: 'В какой слайс?',
|
28 |
+
},
|
29 |
+
{
|
30 |
+
type: 'input',
|
31 |
+
name: 'name',
|
32 |
+
message: 'Название компонента?',
|
33 |
+
},
|
34 |
+
],
|
35 |
+
actions: [
|
36 |
+
{
|
37 |
+
type: 'add',
|
38 |
+
path: '../src/{{layerName}}/{{sliceName}}/ui/{{name}}/{{name}}.tsx',
|
39 |
+
templateFile: './templates/form/form.hbs',
|
40 |
+
},
|
41 |
+
{
|
42 |
+
type: 'add',
|
43 |
+
path: '../src/{{layerName}}/{{sliceName}}/ui/{{name}}/{{name}}.module.scss',
|
44 |
+
templateFile: './templates/form/form.style.hbs',
|
45 |
+
},
|
46 |
+
{
|
47 |
+
type: 'add',
|
48 |
+
path: '../src/{{layerName}}/{{sliceName}}/ui/{{name}}/{{name}}.stories.tsx',
|
49 |
+
templateFile: './templates/form/form.stories.hbs',
|
50 |
+
},
|
51 |
+
],
|
52 |
+
});
|
53 |
+
};
|
54 |
+
|
55 |
+
module.exports = form;
|
plop/generation/common/slice.js
ADDED
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
const slice = (plop) => {
|
2 |
+
plop.setGenerator('slice', {
|
3 |
+
description: 'Создает слайс',
|
4 |
+
prompts: [
|
5 |
+
{
|
6 |
+
type: 'list',
|
7 |
+
name: 'layerName',
|
8 |
+
message: 'В какой слой положить?',
|
9 |
+
choices: [
|
10 |
+
{
|
11 |
+
name: 'entities',
|
12 |
+
value: 'entities',
|
13 |
+
},
|
14 |
+
{
|
15 |
+
name: 'features',
|
16 |
+
value: 'features',
|
17 |
+
},
|
18 |
+
{
|
19 |
+
name: 'widgets',
|
20 |
+
value: 'widgets',
|
21 |
+
},
|
22 |
+
],
|
23 |
+
},
|
24 |
+
{
|
25 |
+
type: 'input',
|
26 |
+
name: 'name',
|
27 |
+
message: 'Название слайса?',
|
28 |
+
},
|
29 |
+
],
|
30 |
+
actions: [
|
31 |
+
{
|
32 |
+
type: 'add',
|
33 |
+
path: '../src/{{layerName}}/{{name}}/ui/{{name}}.tsx',
|
34 |
+
templateFile: './templates/component/component.hbs',
|
35 |
+
},
|
36 |
+
{
|
37 |
+
type: 'add',
|
38 |
+
path: '../src/{{layerName}}/{{name}}/ui/{{name}}.module.scss',
|
39 |
+
templateFile: './templates/component/component.style.hbs',
|
40 |
+
},
|
41 |
+
{
|
42 |
+
type: 'add',
|
43 |
+
path: '../src/{{layerName}}/{{name}}/ui/{{name}}.stories.tsx',
|
44 |
+
templateFile: './templates/component/component.stories.hbs',
|
45 |
+
},
|
46 |
+
{
|
47 |
+
type: 'add',
|
48 |
+
path: '../src/{{layerName}}/{{name}}/index.ts',
|
49 |
+
templateFile: './templates/layers/rootIndex/rootIndex.hbs',
|
50 |
+
},
|
51 |
+
],
|
52 |
+
});
|
53 |
+
};
|
54 |
+
|
55 |
+
module.exports = slice;
|
plop/generation/common/store.js
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
const store = (plop) => {
|
2 |
+
plop.setGenerator('store', {
|
3 |
+
description: 'Создает стор',
|
4 |
+
prompts: [
|
5 |
+
{
|
6 |
+
type: 'list',
|
7 |
+
name: 'layerName',
|
8 |
+
message: 'В какой слой положить?',
|
9 |
+
choices: [
|
10 |
+
{
|
11 |
+
name: 'entities',
|
12 |
+
value: 'entities',
|
13 |
+
},
|
14 |
+
{
|
15 |
+
name: 'features',
|
16 |
+
value: 'features',
|
17 |
+
},
|
18 |
+
{
|
19 |
+
name: 'widgets',
|
20 |
+
value: 'widgets',
|
21 |
+
},
|
22 |
+
],
|
23 |
+
},
|
24 |
+
{
|
25 |
+
type: 'input',
|
26 |
+
name: 'sliceName',
|
27 |
+
message: 'В какой слайс?',
|
28 |
+
},
|
29 |
+
],
|
30 |
+
actions: [
|
31 |
+
{
|
32 |
+
type: 'add',
|
33 |
+
path: '../src/{{layerName}}/{{sliceName}}/model/store/use{{sliceName}}Store.ts',
|
34 |
+
templateFile: './templates/store/store.hbs',
|
35 |
+
},
|
36 |
+
{
|
37 |
+
type: 'add',
|
38 |
+
path: '../src/{{layerName}}/{{sliceName}}/model/types/{{lowerCase sliceName}}Schema.ts',
|
39 |
+
templateFile: './templates/store/storeSchema.hbs',
|
40 |
+
},
|
41 |
+
],
|
42 |
+
});
|
43 |
+
};
|
44 |
+
|
45 |
+
module.exports = store;
|
plop/generation/entities/entitiesComponent.js
ADDED
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
const entitiesComponent = (plop) => {
|
2 |
+
plop.setGenerator('e-component', {
|
3 |
+
description: 'Создает стандартный компонент в сущности',
|
4 |
+
prompts: [
|
5 |
+
{
|
6 |
+
type: 'input',
|
7 |
+
name: 'name',
|
8 |
+
message: 'Название компонента?',
|
9 |
+
},
|
10 |
+
{
|
11 |
+
type: 'input',
|
12 |
+
name: 'sliceName',
|
13 |
+
message: 'Название слайса?',
|
14 |
+
},
|
15 |
+
],
|
16 |
+
actions: (data) => {
|
17 |
+
data.layerName = 'entity';
|
18 |
+
|
19 |
+
return [
|
20 |
+
{
|
21 |
+
type: 'add',
|
22 |
+
path: '../src/entities/{{sliceName}}/ui/{{name}}/{{name}}.tsx',
|
23 |
+
templateFile: './templates/component/component.hbs',
|
24 |
+
},
|
25 |
+
{
|
26 |
+
type: 'add',
|
27 |
+
path: '../src/entities/{{sliceName}}/ui/{{name}}/{{name}}.module.scss',
|
28 |
+
templateFile: './templates/component/component.style.hbs',
|
29 |
+
},
|
30 |
+
{
|
31 |
+
type: 'add',
|
32 |
+
path: '../src/entities/{{sliceName}}/ui/{{name}}/{{name}}.stories.tsx',
|
33 |
+
templateFile: './templates/component/component.stories.hbs',
|
34 |
+
},
|
35 |
+
];
|
36 |
+
},
|
37 |
+
});
|
38 |
+
};
|
39 |
+
|
40 |
+
module.exports = entitiesComponent;
|
plop/generation/entities/entity.js
ADDED
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
const entity = (plop) => {
|
2 |
+
plop.setGenerator('entity', {
|
3 |
+
description: 'Создает слайс в сущности',
|
4 |
+
prompts: [
|
5 |
+
{
|
6 |
+
type: 'input',
|
7 |
+
name: 'sliceName',
|
8 |
+
message: 'Название слайса?',
|
9 |
+
},
|
10 |
+
],
|
11 |
+
actions: (data) => {
|
12 |
+
data.layerName = 'entity';
|
13 |
+
|
14 |
+
return [
|
15 |
+
{
|
16 |
+
type: 'add',
|
17 |
+
path: '../src/entities/{{sliceName}}/ui/{{sliceName}}Card/{{sliceName}}Card.tsx',
|
18 |
+
templateFile: './templates/layers/entities/cardUi/cardUi.hbs',
|
19 |
+
},
|
20 |
+
{
|
21 |
+
type: 'add',
|
22 |
+
path: '../src/entities/{{sliceName}}/ui/{{sliceName}}Card/{{sliceName}}Card.module.scss',
|
23 |
+
templateFile: './templates/layers/entities/cardUi/cardUi.style.hbs',
|
24 |
+
},
|
25 |
+
{
|
26 |
+
type: 'add',
|
27 |
+
path: '../src/entities/{{sliceName}}/ui/{{sliceName}}Card/{{sliceName}}Card.stories.tsx',
|
28 |
+
templateFile: './templates/layers/entities/cardUi/cardUi.stories.hbs',
|
29 |
+
},
|
30 |
+
{
|
31 |
+
type: 'add',
|
32 |
+
path: '../src/entities/{{sliceName}}/model/store/use{{sliceName}}Store.ts',
|
33 |
+
templateFile: './templates/layers/entities/store/store.hbs',
|
34 |
+
},
|
35 |
+
{
|
36 |
+
type: 'add',
|
37 |
+
path: '../src/entities/{{sliceName}}/model/types/{{lowerCase sliceName}}Schema.ts',
|
38 |
+
templateFile: './templates/layers/entities/types/sliceSchema.hbs',
|
39 |
+
},
|
40 |
+
{
|
41 |
+
type: 'add',
|
42 |
+
path: '../src/entities/{{sliceName}}/model/types/{{lowerCase sliceName}}.ts',
|
43 |
+
templateFile: './templates/layers/entities/types/slice.hbs',
|
44 |
+
},
|
45 |
+
{
|
46 |
+
type: 'add',
|
47 |
+
path: '../src/entities/{{sliceName}}/api/fetch{{sliceName}}s.ts',
|
48 |
+
templateFile: './templates/api/fetchApi.hbs',
|
49 |
+
},
|
50 |
+
{
|
51 |
+
type: 'add',
|
52 |
+
path: '../src/entities/{{sliceName}}/lib/query/useFetch{{sliceName}}s.tsx',
|
53 |
+
templateFile: './templates/query/fetchQuery.hbs',
|
54 |
+
},
|
55 |
+
{
|
56 |
+
type: 'add',
|
57 |
+
path: '../src/entities/{{sliceName}}/api/fetch{{sliceName}}ById.ts',
|
58 |
+
templateFile: './templates/api/fetchByIdApi.hbs',
|
59 |
+
},
|
60 |
+
{
|
61 |
+
type: 'add',
|
62 |
+
path: '../src/entities/{{sliceName}}/lib/query/useFetch{{sliceName}}ById.tsx',
|
63 |
+
templateFile: './templates/query/fetchByIdQuery.hbs',
|
64 |
+
},
|
65 |
+
{
|
66 |
+
type: 'add',
|
67 |
+
path: '../src/entities/{{sliceName}}/index.ts',
|
68 |
+
templateFile: './templates/layers/entities/rootIndex.hbs',
|
69 |
+
},
|
70 |
+
];
|
71 |
+
},
|
72 |
+
});
|
73 |
+
};
|
74 |
+
|
75 |
+
module.exports = entity;
|
plop/generation/features/feature.js
ADDED
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
const feature = (plop) => {
|
2 |
+
plop.setGenerator('feature', {
|
3 |
+
description: 'Создает слайс в фиче',
|
4 |
+
prompts: [
|
5 |
+
{
|
6 |
+
type: 'input',
|
7 |
+
name: 'sliceName',
|
8 |
+
message: 'Название слайса?',
|
9 |
+
},
|
10 |
+
],
|
11 |
+
actions: (data) => {
|
12 |
+
data.layerName = 'feature';
|
13 |
+
|
14 |
+
return [
|
15 |
+
{
|
16 |
+
type: 'add',
|
17 |
+
path: '../src/features/{{sliceName}}/ui/Create{{sliceName}}/Create{{sliceName}}.tsx',
|
18 |
+
templateFile: './templates/layers/features/createUi/createUi.hbs',
|
19 |
+
},
|
20 |
+
{
|
21 |
+
type: 'add',
|
22 |
+
path: '../src/features/{{sliceName}}/ui/Create{{sliceName}}/Create{{sliceName}}.module.scss',
|
23 |
+
templateFile: './templates/layers/features/createUi/createUi.style.hbs',
|
24 |
+
},
|
25 |
+
{
|
26 |
+
type: 'add',
|
27 |
+
path: '../src/features/{{sliceName}}/ui/Edit{{sliceName}}/Edit{{sliceName}}.tsx',
|
28 |
+
templateFile: './templates/layers/features/editUi/editUi.hbs',
|
29 |
+
},
|
30 |
+
{
|
31 |
+
type: 'add',
|
32 |
+
path: '../src/features/{{sliceName}}/ui/Edit{{sliceName}}/Edit{{sliceName}}.module.scss',
|
33 |
+
templateFile: './templates/layers/features/editUi/editUi.style.hbs',
|
34 |
+
},
|
35 |
+
{
|
36 |
+
type: 'add',
|
37 |
+
path: '../src/features/{{sliceName}}/ui/Delete{{sliceName}}/Delete{{sliceName}}.tsx',
|
38 |
+
templateFile: './templates/layers/features/deleteUi/deleteUi.hbs',
|
39 |
+
},
|
40 |
+
{
|
41 |
+
type: 'add',
|
42 |
+
path: '../src/features/{{sliceName}}/ui/Delete{{sliceName}}/Delete{{sliceName}}.module.scss',
|
43 |
+
templateFile: './templates/layers/features/deleteUi/deleteUi.style.hbs',
|
44 |
+
},
|
45 |
+
{
|
46 |
+
type: 'add',
|
47 |
+
path: '../src/features/{{sliceName}}/model/store/use{{sliceName}}Store.ts',
|
48 |
+
templateFile: './templates/layers/features/store/store.hbs',
|
49 |
+
},
|
50 |
+
{
|
51 |
+
type: 'add',
|
52 |
+
path: '../src/features/{{sliceName}}/model/types/{{lowerCase sliceName}}Schema.ts',
|
53 |
+
templateFile: './templates/layers/features/types/sliceSchema.hbs',
|
54 |
+
},
|
55 |
+
{
|
56 |
+
type: 'add',
|
57 |
+
path: '../src/features/{{sliceName}}/api/create{{sliceName}}.ts',
|
58 |
+
templateFile: './templates/api/createApi.hbs',
|
59 |
+
},
|
60 |
+
{
|
61 |
+
type: 'add',
|
62 |
+
path: '../src/features/{{sliceName}}/lib/query/useCreate{{sliceName}}.tsx',
|
63 |
+
templateFile: './templates/query/createQuery.hbs',
|
64 |
+
},
|
65 |
+
{
|
66 |
+
type: 'add',
|
67 |
+
path: '../src/features/{{sliceName}}/api/update{{sliceName}}.ts',
|
68 |
+
templateFile: './templates/api/updateApi.hbs',
|
69 |
+
},
|
70 |
+
{
|
71 |
+
type: 'add',
|
72 |
+
path: '../src/features/{{sliceName}}/lib/query/useUpdate{{sliceName}}.tsx',
|
73 |
+
templateFile: './templates/query/updateQuery.hbs',
|
74 |
+
},
|
75 |
+
{
|
76 |
+
type: 'add',
|
77 |
+
path: '../src/features/{{sliceName}}/api/delete{{sliceName}}.ts',
|
78 |
+
templateFile: './templates/api/deleteApi.hbs',
|
79 |
+
},
|
80 |
+
{
|
81 |
+
type: 'add',
|
82 |
+
path: '../src/features/{{sliceName}}/lib/query/useDelete{{sliceName}}.tsx',
|
83 |
+
templateFile: './templates/query/deleteQuery.hbs',
|
84 |
+
},
|
85 |
+
{
|
86 |
+
type: 'add',
|
87 |
+
path: '../src/features/{{sliceName}}/index.ts',
|
88 |
+
templateFile: './templates/layers/features/rootIndex.hbs',
|
89 |
+
},
|
90 |
+
];
|
91 |
+
},
|
92 |
+
});
|
93 |
+
};
|
94 |
+
|
95 |
+
module.exports = feature;
|
plop/generation/features/featuresComponent.js
ADDED
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
const featuresComponent = (plop) => {
|
2 |
+
plop.setGenerator('f-component', {
|
3 |
+
description: 'Создает стандартный компонент в фиче',
|
4 |
+
prompts: [
|
5 |
+
{
|
6 |
+
type: 'input',
|
7 |
+
name: 'name',
|
8 |
+
message: 'Название компонента?',
|
9 |
+
},
|
10 |
+
{
|
11 |
+
type: 'input',
|
12 |
+
name: 'sliceName',
|
13 |
+
message: 'Название слайса?',
|
14 |
+
},
|
15 |
+
],
|
16 |
+
actions: (data) => {
|
17 |
+
data.layerName = 'feature';
|
18 |
+
|
19 |
+
return [
|
20 |
+
{
|
21 |
+
type: 'add',
|
22 |
+
path: '../src/features/{{sliceName}}/ui/{{name}}/{{name}}.tsx',
|
23 |
+
templateFile: './templates/component/component.hbs',
|
24 |
+
},
|
25 |
+
{
|
26 |
+
type: 'add',
|
27 |
+
path: '../src/features/{{sliceName}}/ui/{{name}}/{{name}}.module.scss',
|
28 |
+
templateFile: './templates/component/component.style.hbs',
|
29 |
+
},
|
30 |
+
{
|
31 |
+
type: 'add',
|
32 |
+
path: '../src/features/{{sliceName}}/ui/{{name}}/{{name}}.stories.tsx',
|
33 |
+
templateFile: './templates/component/component.stories.hbs',
|
34 |
+
},
|
35 |
+
];
|
36 |
+
},
|
37 |
+
});
|
38 |
+
};
|
39 |
+
|
40 |
+
module.exports = featuresComponent;
|
plop/generation/pages/page.js
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
const page = (plop) => {
|
2 |
+
plop.setGenerator('page', {
|
3 |
+
description: 'Создает страницу',
|
4 |
+
prompts: [
|
5 |
+
{
|
6 |
+
type: 'input',
|
7 |
+
name: 'name',
|
8 |
+
message: 'Название страницы?',
|
9 |
+
},
|
10 |
+
],
|
11 |
+
actions: [
|
12 |
+
{
|
13 |
+
type: 'add',
|
14 |
+
path: '../src/pages/{{name}}/ui/{{name}}.tsx',
|
15 |
+
templateFile: './templates/page/page.hbs',
|
16 |
+
},
|
17 |
+
{
|
18 |
+
type: 'add',
|
19 |
+
path: '../src/pages/{{name}}/ui/{{name}}.async.tsx',
|
20 |
+
templateFile: './templates/page/page.async.hbs',
|
21 |
+
},
|
22 |
+
{
|
23 |
+
type: 'add',
|
24 |
+
path: '../src/pages/{{name}}/ui/{{name}}.module.scss',
|
25 |
+
templateFile: './templates/page/page.style.hbs',
|
26 |
+
},
|
27 |
+
{
|
28 |
+
type: 'add',
|
29 |
+
path: '../src/pages/{{name}}/index.ts',
|
30 |
+
templateFile: './templates/page/index.hbs',
|
31 |
+
},
|
32 |
+
],
|
33 |
+
});
|
34 |
+
};
|
35 |
+
|
36 |
+
module.exports = page;
|
plop/generation/shared/shared.js
ADDED
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
const shared = (plop) => {
|
2 |
+
plop.setGenerator('shared', {
|
3 |
+
description: 'Создает ui компонент в shared слое',
|
4 |
+
prompts: [
|
5 |
+
{
|
6 |
+
type: 'input',
|
7 |
+
name: 'name',
|
8 |
+
message: 'Название компонента?',
|
9 |
+
},
|
10 |
+
],
|
11 |
+
actions: (data) => {
|
12 |
+
data.layerName = 'shared';
|
13 |
+
|
14 |
+
return [
|
15 |
+
{
|
16 |
+
type: 'add',
|
17 |
+
path: '../src/shared/ui/{{name}}/{{name}}.tsx',
|
18 |
+
templateFile: './templates/component/component.hbs',
|
19 |
+
},
|
20 |
+
{
|
21 |
+
type: 'add',
|
22 |
+
path: '../src/shared/ui/{{name}}/{{name}}.module.scss',
|
23 |
+
templateFile: './templates/component/component.style.hbs',
|
24 |
+
},
|
25 |
+
{
|
26 |
+
type: 'add',
|
27 |
+
path: '../src/shared/ui/{{name}}/{{name}}.stories.tsx',
|
28 |
+
templateFile: './templates/component/component.stories.hbs',
|
29 |
+
},
|
30 |
+
{
|
31 |
+
type: 'add',
|
32 |
+
path: '../src/shared/ui/{{name}}/index.ts',
|
33 |
+
templateFile: './templates/component/index.hbs',
|
34 |
+
},
|
35 |
+
];
|
36 |
+
},
|
37 |
+
});
|
38 |
+
};
|
39 |
+
|
40 |
+
module.exports = shared;
|
plop/generation/widgets/widget.js
ADDED
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
const widget = (plop) => {
|
2 |
+
plop.setGenerator('widget', {
|
3 |
+
description: 'Создает слайс в виджете',
|
4 |
+
prompts: [
|
5 |
+
{
|
6 |
+
type: 'input',
|
7 |
+
name: 'name',
|
8 |
+
message: 'Название слайса?',
|
9 |
+
},
|
10 |
+
],
|
11 |
+
actions: (data) => {
|
12 |
+
data.layerName = 'widgets';
|
13 |
+
|
14 |
+
return [
|
15 |
+
{
|
16 |
+
type: 'add',
|
17 |
+
path: '../src/widgets/{{name}}/ui/{{name}}.tsx',
|
18 |
+
templateFile: './templates/component/component.hbs',
|
19 |
+
},
|
20 |
+
{
|
21 |
+
type: 'add',
|
22 |
+
path: '../src/widgets/{{name}}/ui/{{name}}.module.scss',
|
23 |
+
templateFile: './templates/component/component.style.hbs',
|
24 |
+
},
|
25 |
+
{
|
26 |
+
type: 'add',
|
27 |
+
path: '../src/widgets/{{name}}/ui/{{name}}.stories.tsx',
|
28 |
+
templateFile: './templates/component/component.stories.hbs',
|
29 |
+
},
|
30 |
+
{
|
31 |
+
type: 'add',
|
32 |
+
path: '../src/widgets/{{name}}/index.ts',
|
33 |
+
templateFile: './templates/layers/rootIndex/rootIndex.hbs',
|
34 |
+
},
|
35 |
+
];
|
36 |
+
},
|
37 |
+
});
|
38 |
+
};
|
39 |
+
|
40 |
+
module.exports = widget;
|
plop/plopfile.js
ADDED
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
const api = require('./generation/common/api');
|
2 |
+
const page = require('./generation/pages/page');
|
3 |
+
const form = require('./generation/common/form');
|
4 |
+
const store = require('./generation/common/store');
|
5 |
+
const slice = require('./generation/common/slice');
|
6 |
+
const shared = require('./generation/shared/shared');
|
7 |
+
const widget = require('./generation/widgets/widget');
|
8 |
+
const entity = require('./generation/entities/entity');
|
9 |
+
const feature = require('./generation/features/feature');
|
10 |
+
const component = require('./generation/common/component');
|
11 |
+
const entitiesComponent = require('./generation/entities/entitiesComponent');
|
12 |
+
const featuresComponent = require('./generation/features/featuresComponent');
|
13 |
+
|
14 |
+
const config = (plop) => {
|
15 |
+
// Common
|
16 |
+
api(plop);
|
17 |
+
form(plop);
|
18 |
+
store(plop);
|
19 |
+
slice(plop);
|
20 |
+
component(plop);
|
21 |
+
|
22 |
+
// Entities
|
23 |
+
entity(plop);
|
24 |
+
entitiesComponent(plop);
|
25 |
+
|
26 |
+
// Features
|
27 |
+
feature(plop);
|
28 |
+
featuresComponent(plop);
|
29 |
+
|
30 |
+
// Pages
|
31 |
+
page(plop);
|
32 |
+
|
33 |
+
// Shared
|
34 |
+
shared(plop);
|
35 |
+
|
36 |
+
// Widget
|
37 |
+
widget(plop);
|
38 |
+
|
39 |
+
// Helpers
|
40 |
+
// Первая большая буква
|
41 |
+
plop.setHelper('capitalize', (text) => {
|
42 |
+
return text.charAt(0).toUpperCase() + text.slice(1);
|
43 |
+
});
|
44 |
+
|
45 |
+
// Все с маленькой
|
46 |
+
plop.setHelper('lowerCase', (text) => {
|
47 |
+
return text.toLowerCase();
|
48 |
+
});
|
49 |
+
};
|
50 |
+
|
51 |
+
module.exports = config;
|
plop/templates/api/createApi.hbs
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { $api } from '@/shared/api/axiosInstance';
|
2 |
+
import { {{sliceName}}Type } from '@/entities/{{sliceName}}';
|
3 |
+
|
4 |
+
type Create{{sliceName}}Props = {
|
5 |
+
user_id: number;
|
6 |
+
};
|
7 |
+
|
8 |
+
type Create{{sliceName}}Response = {
|
9 |
+
status: number;
|
10 |
+
message: string;
|
11 |
+
{{lowerCase sliceName}}: {{sliceName}}Type;
|
12 |
+
};
|
13 |
+
|
14 |
+
export const create{{sliceName}} = async (props: Create{{sliceName}}Props) => {
|
15 |
+
const { data } = await $api.post<Create{{sliceName}}Response>(`/{{lowerCase sliceName}}s/create`, props);
|
16 |
+
|
17 |
+
return data;
|
18 |
+
};
|
plop/templates/api/deleteApi.hbs
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { $api } from '@/shared/api/axiosInstance';
|
2 |
+
|
3 |
+
type Delete{{sliceName}}Props = {
|
4 |
+
{{lowerCase sliceName}}_id: number;
|
5 |
+
};
|
6 |
+
type Delete{{sliceName}}Response = {
|
7 |
+
status: number;
|
8 |
+
message: string;
|
9 |
+
};
|
10 |
+
|
11 |
+
export const delete{{sliceName}} = async (props: Delete{{sliceName}}Props) => {
|
12 |
+
const { data } = await $api.post<Delete{{sliceName}}Response>(`/{{lowerCase sliceName}}s/delete`, props);
|
13 |
+
|
14 |
+
return data;
|
15 |
+
};
|
plop/templates/api/fetchApi.hbs
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { {{sliceName}}Type } from '../model/types/{{lowerCase sliceName}}';
|
2 |
+
import { $api } from '@/shared/api/axiosInstance';
|
3 |
+
|
4 |
+
type Fetch{{sliceName}}sResponse = {{sliceName}}Type[];
|
5 |
+
|
6 |
+
export const fetch{{sliceName}}s = async () => {
|
7 |
+
const { data } = await $api.get<Fetch{{sliceName}}sResponse>(`/{{lowerCase sliceName}}s`);
|
8 |
+
|
9 |
+
return data;
|
10 |
+
};
|
plop/templates/api/fetchByIdApi.hbs
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { {{sliceName}}Type } from '../model/types/{{lowerCase sliceName}}';
|
2 |
+
import { $api } from '@/shared/api/axiosInstance';
|
3 |
+
|
4 |
+
type Fetch{{sliceName}}ByIdProps = {
|
5 |
+
{{lowerCase sliceName}}_id: number;
|
6 |
+
};
|
7 |
+
type Fetch{{sliceName}}ByIdResponse = {{sliceName}}Type;
|
8 |
+
|
9 |
+
export const fetch{{sliceName}}ById = async (props: Fetch{{sliceName}}ByIdProps) => {
|
10 |
+
const { data } = await $api.post<Fetch{{sliceName}}ByIdResponse>('/{{lowerCase sliceName}}-by-id', props);
|
11 |
+
|
12 |
+
return data;
|
13 |
+
};
|
plop/templates/api/updateApi.hbs
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { $api } from '@/shared/api/axiosInstance';
|
2 |
+
|
3 |
+
type Update{{sliceName}}Props = {
|
4 |
+
{{lowerCase sliceName}}_id: number;
|
5 |
+
user_id: number;
|
6 |
+
};
|
7 |
+
|
8 |
+
type Update{{sliceName}}Response = {
|
9 |
+
status: number;
|
10 |
+
message: string;
|
11 |
+
};
|
12 |
+
|
13 |
+
export const update{{sliceName}} = async (props: Update{{sliceName}}Props) => {
|
14 |
+
const { data } = await $api.post<Update{{sliceName}}Response>(`/{{lowerCase sliceName}}s/update`, props);
|
15 |
+
|
16 |
+
return data;
|
17 |
+
};
|
plop/templates/component/component.hbs
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { classNames } from '@/shared/lib/classNames/classNames';
|
2 |
+
import cls from './{{name}}.module.scss';
|
3 |
+
|
4 |
+
interface {{name}}Props {
|
5 |
+
className?: string;
|
6 |
+
}
|
7 |
+
|
8 |
+
export const {{name}} = (props: {{name}}Props) => {
|
9 |
+
const { className } = props;
|
10 |
+
|
11 |
+
return (
|
12 |
+
<div className={classNames(cls.{{name}}, {}, [className])}>
|
13 |
+
<p>{{name}}</p>
|
14 |
+
</div>
|
15 |
+
);
|
16 |
+
};
|
plop/templates/component/component.stories.hbs
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import type { Meta, StoryObj } from '@storybook/react';
|
2 |
+
import { {{name}} } from './{{name}}';
|
3 |
+
|
4 |
+
const meta = {
|
5 |
+
title: '{{capitalize layerName}}/{{name}}',
|
6 |
+
component: {{name}},
|
7 |
+
parameters: {
|
8 |
+
layout: 'centered',
|
9 |
+
},
|
10 |
+
tags: ['autodocs'],
|
11 |
+
} satisfies Meta<typeof {{name}}>;
|
12 |
+
|
13 |
+
export default meta;
|
14 |
+
type Story = StoryObj<typeof meta>;
|
15 |
+
|
16 |
+
export const Primary: Story = {
|
17 |
+
args: {},
|
18 |
+
};
|
plop/templates/component/component.style.hbs
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
@import '@/app/globalStyles/config/mixin.scss';
|
2 |
+
|
3 |
+
.{{name}} {
|
4 |
+
display: block;
|
5 |
+
}
|
plop/templates/component/index.hbs
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
export { {{name}} } from './{{name}}';
|
plop/templates/form/form.hbs
ADDED
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { z } from 'zod';
|
2 |
+
import { zodResolver } from '@hookform/resolvers/zod';
|
3 |
+
import { FormProvider, useForm } from 'react-hook-form';
|
4 |
+
import { HInput } from '@/shared/ui/FormComponents';
|
5 |
+
import { classNames } from '@/shared/lib/classNames/classNames';
|
6 |
+
import { Button, ButtonSize, ButtonTheme } from '@/shared/ui/Button';
|
7 |
+
import cls from './{{name}}.module.scss';
|
8 |
+
|
9 |
+
const {{name}}Schema = z.object({
|
10 |
+
title: z //
|
11 |
+
.string()
|
12 |
+
.min(1, { message: 'Заполните поле' })
|
13 |
+
.max(255),
|
14 |
+
body: z //
|
15 |
+
.string()
|
16 |
+
.min(1, { message: 'Заполните поле' })
|
17 |
+
.max(255),
|
18 |
+
});
|
19 |
+
|
20 |
+
type {{name}}Type = z.infer<typeof {{name}}Schema>;
|
21 |
+
|
22 |
+
interface {{name}}Props {
|
23 |
+
className?: string
|
24 |
+
}
|
25 |
+
|
26 |
+
const defaultValues = {
|
27 |
+
first: '',
|
28 |
+
second: '',
|
29 |
+
};
|
30 |
+
|
31 |
+
export const {{name}} = (props: {{name}}Props) => {
|
32 |
+
const { className } = props;
|
33 |
+
|
34 |
+
const methods = useForm<{{name}}Type>({
|
35 |
+
defaultValues,
|
36 |
+
resolver: zodResolver({{name}}Schema),
|
37 |
+
});
|
38 |
+
|
39 |
+
const { handleSubmit } = methods;
|
40 |
+
|
41 |
+
const submitHandler = async (data: {{name}}Type) => {
|
42 |
+
console.log('data: ', data);
|
43 |
+
};
|
44 |
+
|
45 |
+
return (
|
46 |
+
<div className={classNames(cls.{{name}}, {}, [className])}>
|
47 |
+
<FormProvider {...methods}>
|
48 |
+
<form onSubmit={handleSubmit(submitHandler)}>
|
49 |
+
<HInput //
|
50 |
+
className={cls.field}
|
51 |
+
name="first"
|
52 |
+
placeholder="Введите название"
|
53 |
+
/>
|
54 |
+
<HInput //
|
55 |
+
className={cls.field}
|
56 |
+
name="second"
|
57 |
+
placeholder="Введите описание"
|
58 |
+
/>
|
59 |
+
<Button
|
60 |
+
theme={ButtonTheme.PRIMARY}
|
61 |
+
size={ButtonSize.XL}
|
62 |
+
type="submit"
|
63 |
+
// showSpinner={isAddUserLoading}
|
64 |
+
// disabled={isAddUserLoading}
|
65 |
+
>
|
66 |
+
Сохранить
|
67 |
+
</Button>
|
68 |
+
</form>
|
69 |
+
</FormProvider>
|
70 |
+
</div>
|
71 |
+
);
|
72 |
+
};
|
plop/templates/form/form.stories.hbs
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import type { Meta, StoryObj } from '@storybook/react';
|
2 |
+
import { {{name}} } from './{{name}}';
|
3 |
+
|
4 |
+
const meta = {
|
5 |
+
title: '{{capitalize layerName}}/{{name}}',
|
6 |
+
component: {{name}},
|
7 |
+
parameters: {
|
8 |
+
layout: 'centered',
|
9 |
+
},
|
10 |
+
tags: ['autodocs'],
|
11 |
+
} satisfies Meta<typeof {{name}}>;
|
12 |
+
|
13 |
+
export default meta;
|
14 |
+
type Story = StoryObj<typeof meta>;
|
15 |
+
|
16 |
+
export const Primary: Story = {
|
17 |
+
args: {},
|
18 |
+
};
|
plop/templates/form/form.style.hbs
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
@import '@/app/globalStyles/config/mixin.scss';
|
2 |
+
|
3 |
+
.{{name}} {
|
4 |
+
display: block;
|
5 |
+
}
|
6 |
+
|
7 |
+
.field {
|
8 |
+
margin-bottom: 12px;
|
9 |
+
}
|
plop/templates/layers/entities/cardUi/cardUi.hbs
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { ReactNode } from 'react';
|
2 |
+
import { classNames } from '@/shared/lib/classNames/classNames';
|
3 |
+
import { {{sliceName}}Type } from '../../model/types/{{lowerCase sliceName}}';
|
4 |
+
import cls from './{{sliceName}}Card.module.scss';
|
5 |
+
|
6 |
+
interface {{sliceName}}CardProps {
|
7 |
+
className?: string;
|
8 |
+
{{lowerCase sliceName}}: {{sliceName}}Type;
|
9 |
+
editButton?: ReactNode;
|
10 |
+
deleteButton?: ReactNode;
|
11 |
+
}
|
12 |
+
|
13 |
+
export const {{sliceName}}Card = (props: {{sliceName}}CardProps) => {
|
14 |
+
const { className, {{lowerCase sliceName}}, editButton, deleteButton } = props;
|
15 |
+
|
16 |
+
return (
|
17 |
+
<div className={classNames(cls.{{sliceName}}Card, {}, [className])}>
|
18 |
+
<div className={cls.content}>
|
19 |
+
<div className={cls.name}>
|
20 |
+
{
|
21 |
+
{{lowerCase sliceName}}.title
|
22 |
+
}
|
23 |
+
</div>
|
24 |
+
<div className={cls.buttons}>
|
25 |
+
{editButton}
|
26 |
+
{deleteButton}
|
27 |
+
</div>
|
28 |
+
</div>
|
29 |
+
</div>
|
30 |
+
);
|
31 |
+
};
|
plop/templates/layers/entities/cardUi/cardUi.stories.hbs
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import type { Meta, StoryObj } from '@storybook/react';
|
2 |
+
import { {{sliceName}}Card } from './{{sliceName}}Card';
|
3 |
+
|
4 |
+
const meta = {
|
5 |
+
title: '{{capitalize layerName}}/{{sliceName}}Card',
|
6 |
+
component: {{sliceName}}Card,
|
7 |
+
parameters: {
|
8 |
+
layout: 'centered',
|
9 |
+
},
|
10 |
+
tags: ['autodocs'],
|
11 |
+
} satisfies Meta<typeof {{sliceName}}Card>;
|
12 |
+
|
13 |
+
export default meta;
|
14 |
+
type Story = StoryObj<typeof meta>;
|
15 |
+
|
16 |
+
export const Primary: Story = {
|
17 |
+
args: {
|
18 |
+
{{lowerCase sliceName}}: { id: 1, title: 'CardName' },
|
19 |
+
},
|
20 |
+
};
|
plop/templates/layers/entities/cardUi/cardUi.style.hbs
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
@import '@/app/globalStyles/config/mixin.scss';
|
2 |
+
|
3 |
+
.{{sliceName}}Card {
|
4 |
+
display: block;
|
5 |
+
}
|
6 |
+
|
7 |
+
.content {
|
8 |
+
display: flex;
|
9 |
+
justify-content: space-between;
|
10 |
+
align-items: center;
|
11 |
+
padding: 12px;
|
12 |
+
border-radius: 8px;
|
13 |
+
border: 1px solid var(--s-accent-c);
|
14 |
+
}
|
15 |
+
|
16 |
+
.buttons {
|
17 |
+
display: flex;
|
18 |
+
align-items: center;
|
19 |
+
gap: 4px;
|
20 |
+
}
|
plop/templates/layers/entities/rootIndex.hbs
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
export { {{sliceName}}Card } from './ui/{{sliceName}}Card/{{sliceName}}Card';
|
2 |
+
export type { {{sliceName}}Type } from './model/types/post';
|
3 |
+
export { useFetch{{sliceName}}s } from './lib/query/useFetch{{sliceName}}s';
|
4 |
+
export { useFetch{{sliceName}}ById } from './lib/query/useFetch{{sliceName}}ById';
|
plop/templates/layers/entities/store/store.hbs
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { create } from 'zustand';
|
2 |
+
import { devtools } from 'zustand/middleware';
|
3 |
+
import { {{sliceName}}Schema } from '../types/{{lowerCase sliceName}}Schema';
|
4 |
+
|
5 |
+
export const use{{sliceName}}Store = create<{{sliceName}}Schema>()(
|
6 |
+
devtools((set, get) => ({
|
7 |
+
isModalActive: false,
|
8 |
+
toggleModal: () => set({ isModalActive: !get().isModalActive }),
|
9 |
+
}))
|
10 |
+
);
|
plop/templates/layers/entities/types/slice.hbs
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
export interface {{sliceName}}Type {
|
2 |
+
id: number;
|
3 |
+
title: string;
|
4 |
+
}
|
plop/templates/layers/entities/types/sliceSchema.hbs
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
export interface {{sliceName}}Schema {
|
2 |
+
isModalActive: boolean;
|
3 |
+
toggleModal: () => void;
|
4 |
+
}
|
plop/templates/layers/features/createUi/createUi.hbs
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { classNames } from '@/shared/lib/classNames/classNames';
|
2 |
+
import { Button, ButtonSize, ButtonTheme } from '@/shared/ui/Button';
|
3 |
+
import { use{{sliceName}}Store } from '../../model/store/use{{sliceName}}Store';
|
4 |
+
import cls from './Create{{sliceName}}.module.scss';
|
5 |
+
|
6 |
+
interface Create{{sliceName}}Props {
|
7 |
+
className?: string;
|
8 |
+
}
|
9 |
+
|
10 |
+
export const Create{{sliceName}} = (props: Create{{sliceName}}Props) => {
|
11 |
+
const { className } = props;
|
12 |
+
const toggleModal = use{{sliceName}}Store((state) => state.toggleModal);
|
13 |
+
const changingEditable{{sliceName}} = use{{sliceName}}Store((state) => state.changingEditable{{sliceName}});
|
14 |
+
|
15 |
+
const openEdit{{sliceName}}Form = () => {
|
16 |
+
changingEditable{{sliceName}}(undefined);
|
17 |
+
toggleModal();
|
18 |
+
};
|
19 |
+
|
20 |
+
return (
|
21 |
+
<Button
|
22 |
+
className={classNames(cls.Create{{sliceName}}, {}, [className])}
|
23 |
+
theme={ButtonTheme.PRIMARY}
|
24 |
+
size={ButtonSize.XL}
|
25 |
+
onClick={openEdit{{sliceName}}Form}
|
26 |
+
>
|
27 |
+
Создать слайс
|
28 |
+
</Button>
|
29 |
+
);
|
30 |
+
};
|
plop/templates/layers/features/createUi/createUi.style.hbs
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
@import '@/app/globalStyles/config/mixin.scss';
|
2 |
+
|
3 |
+
.Create{{sliceName}} {
|
4 |
+
margin-bottom: 48px;
|
5 |
+
}
|
plop/templates/layers/features/deleteUi/deleteUi.hbs
ADDED
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { classNames } from '@/shared/lib/classNames/classNames';
|
2 |
+
import { Button, ButtonSize, ButtonTheme } from '@/shared/ui/Button';
|
3 |
+
import { useDelete{{sliceName}} } from '../../lib/query/useDelete{{sliceName}}';
|
4 |
+
import cls from './Delete{{sliceName}}.module.scss';
|
5 |
+
|
6 |
+
interface Delete{{sliceName}}Props {
|
7 |
+
className?: string;
|
8 |
+
{{lowerCase sliceName}}Id: number;
|
9 |
+
}
|
10 |
+
|
11 |
+
export const Delete{{sliceName}} = (props: Delete{{sliceName}}Props) => {
|
12 |
+
const { className, {{lowerCase sliceName}}Id } = props;
|
13 |
+
const { mutate: onDelete } = useDelete{{sliceName}}();
|
14 |
+
|
15 |
+
return (
|
16 |
+
<Button
|
17 |
+
className={classNames(cls.Delete{{sliceName}}, {}, [className])}
|
18 |
+
theme={ButtonTheme.PRIMARY}
|
19 |
+
size={ButtonSize.S}
|
20 |
+
onClick={() => onDelete({
|
21 |
+
{{lowerCase sliceName}}_id: {{lowerCase sliceName}}Id
|
22 |
+
})}
|
23 |
+
>
|
24 |
+
Удалить
|
25 |
+
</Button>
|
26 |
+
);
|
27 |
+
};
|
plop/templates/layers/features/deleteUi/deleteUi.style.hbs
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
@import '@/app/globalStyles/config/mixin.scss';
|
2 |
+
|
3 |
+
.Delete{{sliceName}} {
|
4 |
+
display: block;
|
5 |
+
}
|
plop/templates/layers/features/editUi/editUi.hbs
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { classNames } from '@/shared/lib/classNames/classNames';
|
2 |
+
import { Button, ButtonSize, ButtonTheme } from '@/shared/ui/Button';
|
3 |
+
import { use{{sliceName}}Store } from '../../model/store/use{{sliceName}}Store';
|
4 |
+
import cls from './Edit{{sliceName}}.module.scss';
|
5 |
+
|
6 |
+
interface Edit{{sliceName}}Props {
|
7 |
+
className?: string;
|
8 |
+
{{sliceName}}Id: number;
|
9 |
+
}
|
10 |
+
|
11 |
+
export const Edit{{sliceName}} = (props: Edit{{sliceName}}Props) => {
|
12 |
+
const { className, {{sliceName}}Id } = props;
|
13 |
+
const toggleModal = use{{sliceName}}Store((state) => state.toggleModal);
|
14 |
+
const changingEditable{{sliceName}} = use{{sliceName}}Store((state) => state.changingEditable{{sliceName}});
|
15 |
+
|
16 |
+
const openEdit{{sliceName}}Form = (id: number) => {
|
17 |
+
changingEditable{{sliceName}}(id);
|
18 |
+
toggleModal();
|
19 |
+
};
|
20 |
+
|
21 |
+
return (
|
22 |
+
<Button
|
23 |
+
className={classNames(cls.Edit{{sliceName}}, {}, [className])}
|
24 |
+
theme={ButtonTheme.PRIMARY}
|
25 |
+
size={ButtonSize.S}
|
26 |
+
onClick={() => openEdit{{sliceName}}Form({{sliceName}}Id)}
|
27 |
+
>
|
28 |
+
Изменить
|
29 |
+
</Button>
|
30 |
+
);
|
31 |
+
};
|
plop/templates/layers/features/editUi/editUi.style.hbs
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
@import '@/app/globalStyles/config/mixin.scss';
|
2 |
+
|
3 |
+
.Edit{{sliceName}} {
|
4 |
+
display: block;
|
5 |
+
}
|
plop/templates/layers/features/rootIndex.hbs
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
export { Create{{sliceName}} } from './ui/Create{{sliceName}}/Create{{sliceName}}';
|
2 |
+
export { Edit{{sliceName}} } from './ui/Edit{{sliceName}}/Edit{{sliceName}}';
|
3 |
+
export { use{{sliceName}}Store } from './model/store/use{{sliceName}}Store';
|
4 |
+
export { Delete{{sliceName}} } from './ui/Delete{{sliceName}}/Delete{{sliceName}}';
|
plop/templates/layers/features/store/store.hbs
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { create } from 'zustand';
|
2 |
+
import { devtools } from 'zustand/middleware';
|
3 |
+
import { {{sliceName}}Schema } from '../types/{{lowerCase sliceName}}Schema';
|
4 |
+
|
5 |
+
export const use{{sliceName}}Store = create<{{sliceName}}Schema>()(
|
6 |
+
devtools((set, get) => ({
|
7 |
+
isModalActive: false,
|
8 |
+
editable{{sliceName}}: undefined,
|
9 |
+
toggleModal: () => set({ isModalActive: !get().isModalActive }),
|
10 |
+
changingEditable{{sliceName}}: ({{lowerCase sliceName}}Id) => set({ editable{{sliceName}}Id: {{lowerCase sliceName}}Id }),
|
11 |
+
}))
|
12 |
+
);
|
plop/templates/layers/features/types/sliceSchema.hbs
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
export interface {{sliceName}}Schema {
|
2 |
+
isModalActive: boolean;
|
3 |
+
editable{{sliceName}}Id?: number;
|
4 |
+
toggleModal: () => void;
|
5 |
+
changingEditable{{sliceName}}: ({{lowerCase sliceName}}Id?: number) => void;
|
6 |
+
}
|
plop/templates/layers/rootIndex/rootIndex.hbs
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
export { {{name}} } from './ui/{{name}}';
|