devextreme-cli 1.8.0 → 1.9.1-1.11.0-alpha.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/package.json +6 -5
  2. package/src/applications/application.angular.js +32 -7
  3. package/src/applications/application.react.js +31 -24
  4. package/src/applications/application.vue.js +23 -6
  5. package/src/templates/react/application/public/favicon.ico +0 -0
  6. package/src/templates/react/application/public/logo192.png +0 -0
  7. package/src/templates/react/application/public/logo512.png +0 -0
  8. package/src/templates/react/application/public/manifest.json +25 -0
  9. package/src/templates/react/application/public/robots.txt +3 -0
  10. package/src/templates/react/application/src/App.tsx +0 -1
  11. package/src/templates/react/application/src/components/change-password-form/ChangePasswordForm.tsx +2 -2
  12. package/src/templates/react/application/src/components/create-account-form/CreateAccountForm.scss +4 -5
  13. package/src/templates/react/application/src/components/create-account-form/CreateAccountForm.tsx +5 -7
  14. package/src/templates/react/application/src/components/footer/Footer.tsx +0 -1
  15. package/src/templates/react/application/src/components/header/Header.scss +1 -1
  16. package/src/templates/react/application/src/components/header/Header.tsx +0 -1
  17. package/src/templates/react/application/src/components/login-form/LoginForm.scss +2 -8
  18. package/src/templates/react/application/src/components/login-form/LoginForm.tsx +12 -14
  19. package/src/templates/react/application/src/components/reset-password-form/ResetPasswordForm.scss +3 -4
  20. package/src/templates/react/application/src/components/reset-password-form/ResetPasswordForm.tsx +5 -7
  21. package/src/templates/react/application/src/components/side-navigation-menu/SideNavigationMenu.scss +3 -3
  22. package/src/templates/react/application/src/components/side-navigation-menu/SideNavigationMenu.tsx +2 -2
  23. package/src/templates/react/application/src/components/theme-switcher/ThemeSwitcher.tsx +2 -2
  24. package/src/templates/react/application/src/components/user-panel/UserPanel.tsx +1 -1
  25. package/src/templates/react/application/src/dx-styles.scss +6 -3
  26. package/src/templates/react/application/src/index.css +12 -0
  27. package/src/templates/react/application/src/layouts/side-nav-inner-toolbar/side-nav-inner-toolbar.tsx +11 -5
  28. package/src/templates/react/application/src/layouts/side-nav-outer-toolbar/side-nav-outer-toolbar.tsx +11 -5
  29. package/src/templates/react/application/src/layouts/single-card/single-card.scss +10 -7
  30. package/src/templates/react/application/src/layouts/single-card/single-card.tsx +0 -1
  31. package/src/templates/react/application/src/theme.tsx +1 -1
  32. package/src/templates/react/application/src/types.tsx +1 -2
  33. package/src/templates/react/application/src/utils/media-query.tsx +3 -1
  34. package/src/templates/react/application/src/utils/patches.scss +4 -4
  35. package/src/templates/react/application/src/variables.scss +32 -16
  36. package/src/templates/react/sample-pages/home/home.scss +0 -2
  37. package/src/templates/react/sample-pages/home/home.tsx +1 -1
  38. package/src/templates/react/sample-pages/tasks/tasks.tsx +4 -4
  39. package/src/templates/vue-v3/application/src/App.vue +1 -0
  40. package/src/templates/vue-v3/application/src/components/header-toolbar.vue +1 -1
  41. package/src/templates/vue-v3/application/src/components/side-nav-menu.vue +2 -2
  42. package/src/templates/vue-v3/application/src/dx-styles.scss +3 -3
  43. package/src/templates/vue-v3/application/src/layouts/single-card.vue +10 -5
  44. package/src/templates/vue-v3/application/src/variables.scss +30 -14
  45. package/src/templates/vue-v3/application/src/views/create-account-form.vue +21 -24
  46. package/src/templates/vue-v3/application/src/views/login-form.vue +18 -25
  47. package/src/templates/vue-v3/application/src/views/reset-password-form.vue +6 -9
  48. package/src/templates/vue-v3/sample-pages/tasks-page.vue +1 -1
  49. package/src/utility/extract-deps-version-tag.js +13 -0
  50. package/src/utility/latest-versions.js +4 -3
  51. package/src/utility/prompts/transpiler.js +17 -0
  52. package/src/utility/typescript-extension.js +1 -1
  53. package/src/templates/react/application/src/App.test.tsx +0 -12
  54. package/src/templates/react/application/src/matchMediaMock.tsx +0 -14
  55. package/src/templates/react/application/src/polyfills.tsx +0 -2
  56. package/src/utility/extract-tooling-version.js +0 -13
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devextreme-cli",
3
- "version": "1.8.0",
3
+ "version": "1.9.1-1.11.0-alpha.0.0",
4
4
  "description": "DevExtreme CLI",
5
5
  "keywords": [
6
6
  "devexpress",
@@ -43,7 +43,7 @@
43
43
  "minimist": "^1.2.8",
44
44
  "mustache": "^3.2.1",
45
45
  "prompts": "^2.4.2",
46
- "sass": "^1.77.6",
46
+ "sass": "^1.85.1",
47
47
  "semver": "^5.7.2",
48
48
  "strip-bom": "^4.0.0"
49
49
  },
@@ -51,6 +51,7 @@
51
51
  "@typescript-eslint/eslint-plugin": "^4.33.0",
52
52
  "@typescript-eslint/parser": "^4.33.0",
53
53
  "babel-eslint": "^10.1.0",
54
+ "create-vite": "6.3.1",
54
55
  "cross-env": "^5.2.1",
55
56
  "eslint": "^7.32.0",
56
57
  "eslint-config-angular": "^0.5.0",
@@ -58,8 +59,8 @@
58
59
  "eslint-plugin-angular": "^4.1.0",
59
60
  "eslint-plugin-jest": "^22.21.0",
60
61
  "eslint-plugin-prettier": "^4.2.1",
61
- "eslint-plugin-react": "^7.33.2",
62
- "eslint-plugin-react-hooks": "^4.6.0",
62
+ "eslint-plugin-react": "^7.37.4",
63
+ "eslint-plugin-react-hooks": "^4.6.2",
63
64
  "eslint-plugin-unused-imports": "^1.1.5",
64
65
  "eslint-plugin-vue": "^7.20.0",
65
66
  "eslint-stylish": "^0.2.0",
@@ -72,5 +73,5 @@
72
73
  "typescript": "^4.0.2",
73
74
  "typescript-eslint-parser": "^22.0.0"
74
75
  },
75
- "gitHead": "b1e11fb858e65b9b506bd0da0b1ec689d267c0e7"
76
+ "gitHead": "d1f6fa7bed054c3df8baec671e91ca9dea1e4a38"
76
77
  }
@@ -7,7 +7,9 @@ const fs = require('fs');
7
7
  const dasherize = require('../utility/string').dasherize;
8
8
  const ngVersion = require('../utility/ng-version');
9
9
  const latestVersions = require('../utility/latest-versions');
10
- const { extractToolingVersion, toolingVersionOptionName } = require('../utility/extract-tooling-version');
10
+ const { extractDepsVersionTag, depsVersionTagOptionName } = require('../utility/extract-deps-version-tag');
11
+ const { getPackageJsonPath } = require('../utility/package-json-utils');
12
+ const modifyJson = require('../utility/modify-json-file');
11
13
  const schematicsVersion = latestVersions['devextreme-schematics'] || 'latest';
12
14
 
13
15
  const minNgCliVersion = new semver('17.0.0');
@@ -27,7 +29,7 @@ async function runSchematicCommand(schematicCommand, options, evaluatingOptions)
27
29
 
28
30
  const commandArguments = ['g', `${collectionName}:${schematicCommand}`];
29
31
 
30
- const { [toolingVersionOptionName]: _, ...optionsToArguments } = options; // eslint-disable-line no-unused-vars
32
+ const { [depsVersionTagOptionName]: _, ...optionsToArguments } = options; // eslint-disable-line no-unused-vars
31
33
  for(let option in optionsToArguments) {
32
34
  commandArguments.push(`--${dasherize(option)}=${options[option]}`);
33
35
  }
@@ -37,12 +39,13 @@ async function runSchematicCommand(schematicCommand, options, evaluatingOptions)
37
39
 
38
40
  async function runNgCommand(commandArguments, commandOptions, commandConfig) {
39
41
  const hasNg = await hasSutableNgCli();
40
- const toolingVersion = extractToolingVersion(commandOptions);
41
- const npmCommandName = hasNg && !toolingVersion ? 'ng' : 'npx';
42
+ const depsVersionTag = extractDepsVersionTag(commandOptions);
43
+ const npmCommandName = hasNg && !depsVersionTag ? 'ng' : 'npx';
42
44
  const [minCliLtsVersion] = minNgCliVersion.version.split('.');
43
- const ngCommandArguments = hasNg && !toolingVersion
45
+
46
+ const ngCommandArguments = hasNg && !depsVersionTag
44
47
  ? []
45
- : ['-p', `@angular/cli@v${minCliLtsVersion}-lts`, 'ng'];
48
+ : ['-p', `@angular/cli@${depsVersionTag || `v${minCliLtsVersion}-lts`}`, 'ng'];
46
49
 
47
50
  ngCommandArguments.push(...commandArguments);
48
51
  return runCommand(npmCommandName, ngCommandArguments, commandConfig);
@@ -74,8 +77,26 @@ const install = async(options) => {
74
77
  });
75
78
  };
76
79
 
80
+ const bumpAngular = (appPath, versionTag) => {
81
+ modifyJson(getPackageJsonPath(appPath), ({ dependencies, devDependencies, ...rest }) => {
82
+ const bump = (section) => {
83
+ for(const depName in section) {
84
+ section[depName] = depName.startsWith('@angular') ? versionTag : section[depName];
85
+ }
86
+ };
87
+
88
+ return {
89
+ dependencies: bump(dependencies),
90
+ devDependencies: bump(devDependencies),
91
+ ...rest,
92
+ };
93
+ });
94
+
95
+ };
96
+
77
97
  const create = async(appName, options) => {
78
98
  const layout = await getLayoutInfo(options.layout);
99
+ const depsVersionTag = extractDepsVersionTag(options);
79
100
 
80
101
  const commandArguments = [
81
102
  'new',
@@ -92,6 +113,10 @@ const create = async(appName, options) => {
92
113
 
93
114
  const appPath = path.join(process.cwd(), appName);
94
115
 
116
+ if(depsVersionTag) {
117
+ bumpAngular(appPath, depsVersionTag);
118
+ }
119
+
95
120
  options.resolveConflicts = 'override';
96
121
  options.updateBudgets = true;
97
122
  options.layout = layout;
@@ -125,7 +150,7 @@ const changeMainTs = (appPath) => {
125
150
  moduleWorker.insertImport(filePath, 'devextreme/ui/themes', 'themes', true);
126
151
 
127
152
  const fileContent = fs.readFileSync(filePath).toString();
128
- const bootstrapPattern = /platformBrowserDynamic\(\)\.bootstrapModule\(\s*AppModule\s*(?:,\s*\{[^}]*\})?\s*\)/;
153
+ const bootstrapPattern = /platformBrowser(?:Dynamic)?\(\)\.bootstrapModule\(\s*AppModule\s*(?:,\s*\{[^}]*\})?\s*\)/;
129
154
  const firstChaptStr = fileContent.match(bootstrapPattern)[0];
130
155
  const lastChaptStr = '.catch(err => console.error(err));';
131
156
 
@@ -3,6 +3,7 @@ const path = require('path');
3
3
  const fs = require('fs');
4
4
  const getLayoutInfo = require('../utility/prompts/layout');
5
5
  const getTemplateTypeInfo = require('../utility/prompts/typescript');
6
+ const getTranspilerTypeInfo = require('../utility/prompts/transpiler');
6
7
  const templateCreator = require('../utility/template-creator');
7
8
  const packageManager = require('../utility/package-manager');
8
9
  const packageJsonUtils = require('../utility/package-json-utils');
@@ -13,13 +14,13 @@ const stringUtils = require('../utility/string');
13
14
  const typescriptUtils = require('../utility/typescript-extension');
14
15
  const removeFile = require('../utility/file-operations').remove;
15
16
  const latestVersions = require('../utility/latest-versions');
16
- const { extractToolingVersion } = require('../utility/extract-tooling-version');
17
+ const { extractDepsVersionTag } = require('../utility/extract-deps-version-tag');
17
18
  const defaultStyles = [
18
19
  'devextreme/dist/css/dx.light.css'
19
20
  ];
20
21
 
21
22
  const getExtension = (appPath) => {
22
- return fs.existsSync(path.join(appPath, 'src', 'App.tsx')) ? '.tsx' : '.js';
23
+ return fs.existsSync(path.join(appPath, 'src', 'App.tsx')) ? '.tsx' : '.jsx';
23
24
  };
24
25
 
25
26
  const pathToPagesIndex = () => {
@@ -27,9 +28,9 @@ const pathToPagesIndex = () => {
27
28
  return path.join(process.cwd(), 'src', 'pages', `index${extension}`);
28
29
  };
29
30
 
30
- const preparePackageJsonForTemplate = (appPath, appName, isTypeScript) => {
31
+ const preparePackageJsonForTemplate = (appPath, appName) => {
31
32
  const dependencies = [
32
- { name: 'sass', version: '^1.34.1' },
33
+ { name: 'sass-embedded', version: '^1.85.1' },
33
34
  { name: 'devextreme-cli', version: latestVersions['devextreme-cli'], dev: true },
34
35
  { name: 'react-router-dom', version: '^6.3.0' },
35
36
  ];
@@ -51,8 +52,20 @@ const updateJsonPropName = (path, name) => {
51
52
  });
52
53
  };
53
54
 
55
+ const bumpReact = (appPath, versionTag) => {
56
+ const dependencies = [
57
+ { name: 'react', version: versionTag },
58
+ { name: 'react-dom', version: versionTag },
59
+ { name: '@types/react', version: versionTag, dev: true },
60
+ { name: '@types/react-dom', version: versionTag, dev: true },
61
+ ];
62
+
63
+ packageJsonUtils.addDependencies(appPath, dependencies);
64
+ };
65
+
54
66
  const create = async(appName, options) => {
55
67
  const templateType = await getTemplateTypeInfo(options.template);
68
+ const transpiler = await getTranspilerTypeInfo(options.transpiler);
56
69
  const layoutType = await getLayoutInfo(options.layout);
57
70
 
58
71
  const templateOptions = Object.assign({}, options, {
@@ -60,26 +73,30 @@ const create = async(appName, options) => {
60
73
  layout: stringUtils.classify(layoutType),
61
74
  isTypeScript: typescriptUtils.isTypeScript(templateType)
62
75
  });
63
- const toolingVersion = extractToolingVersion(options);
64
- const commandArguments = [`-p=create-react-app${toolingVersion}`, 'create-react-app', appName];
76
+ const depsVersionTag = extractDepsVersionTag(options);
65
77
 
66
- if(templateOptions.isTypeScript) {
67
- commandArguments.push('--template typescript');
68
- }
78
+ const commandArguments = [`-p=create-vite@${depsVersionTag || latestVersions['create-vite']}`, 'create-vite', appName];
79
+
80
+ commandArguments.push(`--template react${transpiler === 'swc' ? '-swc' : ''}${templateOptions.isTypeScript ? '-ts' : ''}`);
69
81
 
70
82
  await runCommand('npx', commandArguments);
71
83
 
72
84
  const appPath = path.join(process.cwd(), appName);
73
85
 
74
86
  modifyIndexHtml(appPath, templateOptions.project);
87
+
88
+ if(depsVersionTag) {
89
+ bumpReact(appPath, depsVersionTag);
90
+ }
91
+
75
92
  addTemplate(appPath, appName, templateOptions);
76
93
  };
77
94
 
78
95
  const modifyIndexHtml = (appPath, appName) => {
79
- const indexHtmlPath = path.join(appPath, 'public', 'index.html');
96
+ const indexHtmlPath = path.join(appPath, 'index.html');
80
97
 
81
98
  let htmlContent = fs.readFileSync(indexHtmlPath).toString();
82
- htmlContent = htmlContent.replace(/<title>(\w+\s*)+<\/title>/, `<title>${appName}<\/title>`);
99
+ htmlContent = htmlContent.replace(/<title>[^<]+<\/title>/, `<title>${appName}<\/title>`);
83
100
  htmlContent = htmlContent.replace('<body>', '<body class="dx-viewport">');
84
101
 
85
102
  fs.writeFileSync(indexHtmlPath, htmlContent);
@@ -96,7 +113,6 @@ const addTemplate = (appPath, appName, templateOptions) => {
96
113
  );
97
114
 
98
115
  const manifestPath = path.join(appPath, 'public', 'manifest.json');
99
- const indexPath = path.join(appPath, 'src', templateOptions.isTypeScript ? 'index.tsx' : 'index.js');
100
116
 
101
117
  const styles = [
102
118
  './themes/generated/theme.additional.css',
@@ -107,15 +123,15 @@ const addTemplate = (appPath, appName, templateOptions) => {
107
123
  ];
108
124
 
109
125
  templateCreator.moveTemplateFilesToProject(applicationTemplatePath, appPath, templateOptions, getCorrectPath);
110
- removeFile(path.join(appPath, 'src', 'App.css'));
111
- !templateOptions.isTypeScript && removeFile(path.join(appPath, 'src', 'types.js'));
126
+
127
+ !templateOptions.isTypeScript && removeFile(path.join(appPath, 'src', 'types.jsx'));
128
+
112
129
  if(!templateOptions.empty) {
113
130
  addSamplePages(appPath, templateOptions);
114
131
  }
115
132
 
116
133
  preparePackageJsonForTemplate(appPath, appName, templateOptions.isTypeScript);
117
134
  updateJsonPropName(manifestPath, appName);
118
- addPolyfills(packageJsonUtils.getPackageJsonPath(), indexPath);
119
135
  install({}, appPath, styles);
120
136
  };
121
137
 
@@ -129,15 +145,6 @@ const install = (options, appPath, styles) => {
129
145
  packageManager.runInstall({ cwd: appPath });
130
146
  };
131
147
 
132
- const addPolyfills = (packagePath, indexPath) => {
133
- const packages = [
134
- { name: 'react-app-polyfill', version: '^1.0.0' }
135
- ];
136
-
137
- packageJsonUtils.addDependencies(packagePath, packages);
138
- moduleUtils.insertImport(indexPath, './polyfills');
139
- };
140
-
141
148
  const addStylesToApp = (filePath, styles) => {
142
149
  styles.forEach(style => {
143
150
  moduleUtils.insertImport(filePath, style);
@@ -9,7 +9,7 @@ const insertItemToArray = require('../utility/file-content').insertItemToArray;
9
9
  const moduleUtils = require('../utility/module');
10
10
  const stringUtils = require('../utility/string');
11
11
  const latestVersions = require('../utility/latest-versions');
12
- const { toolingVersionOptionName, extractToolingVersion } = require('../utility/extract-tooling-version');
12
+ const { depsVersionTagOptionName, extractDepsVersionTag } = require('../utility/extract-deps-version-tag');
13
13
  const defaultStyles = [
14
14
  'devextreme/dist/css/dx.light.css'
15
15
  ];
@@ -37,25 +37,42 @@ const preparePackageJsonForTemplate = (appPath, appName) => {
37
37
  packageJsonUtils.updateName(appPath, appName);
38
38
  };
39
39
 
40
- async function createVueApp(name, templateOptions) {
41
- const toolingVersion = extractToolingVersion(templateOptions);
42
- const argList = ['-p', `@vue/cli${toolingVersion}`, 'vue', 'create', name, '--registry', 'https://registry.npmjs.org/', '-p "Default (Vue 3)"'];
40
+ async function createVueApp(name, depsVersionTag) {
41
+ const argList = ['-p', `@vue/cli@${depsVersionTag}`, 'vue', 'create', name, '--registry', 'https://registry.npmjs.org/', '-p "Default (Vue 3)"'];
43
42
 
44
43
  return runCommand('npx', argList);
45
44
  }
46
45
 
46
+ const bumpVue = (appPath, versionTag) => {
47
+ const dependencies = [
48
+ { name: 'vue', version: versionTag },
49
+ { name: 'vue-router', version: versionTag },
50
+ { name: '@vue/cli-plugin-babel', version: versionTag, dev: true },
51
+ { name: '@vue/cli-plugin-eslint', version: versionTag, dev: true },
52
+ { name: '@vue/cli-service', version: versionTag, dev: true },
53
+ ];
54
+
55
+ packageJsonUtils.addDependencies(appPath, dependencies);
56
+ };
57
+
47
58
  const create = async(appName, options) => {
48
59
  const layout = await getLayoutInfo(options.layout);
60
+ const depsVersionTag = extractDepsVersionTag(options);
49
61
 
50
62
  const templateOptions = {
51
63
  project: stringUtils.humanize(appName),
52
64
  layout: layout,
53
- [toolingVersionOptionName]: options[toolingVersionOptionName]
65
+ [depsVersionTagOptionName]: options[depsVersionTagOptionName]
54
66
  };
55
67
 
56
- await createVueApp(appName, templateOptions);
68
+ await createVueApp(appName, depsVersionTag);
57
69
 
58
70
  const appPath = path.join(process.cwd(), appName);
71
+
72
+ if(depsVersionTag) {
73
+ bumpVue(appPath, depsVersionTag);
74
+ }
75
+
59
76
  modifyIndexHtml(appPath, templateOptions.project);
60
77
  addTemplate(appPath, appName, templateOptions);
61
78
  };
@@ -0,0 +1,25 @@
1
+ {
2
+ "short_name": "React App",
3
+ "name": "Create React App Sample",
4
+ "icons": [
5
+ {
6
+ "src": "favicon.ico",
7
+ "sizes": "64x64 32x32 24x24 16x16",
8
+ "type": "image/x-icon"
9
+ },
10
+ {
11
+ "src": "logo192.png",
12
+ "type": "image/png",
13
+ "sizes": "192x192"
14
+ },
15
+ {
16
+ "src": "logo512.png",
17
+ "type": "image/png",
18
+ "sizes": "512x512"
19
+ }
20
+ ],
21
+ "start_url": ".",
22
+ "display": "standalone",
23
+ "theme_color": "#000000",
24
+ "background_color": "#ffffff"
25
+ }
@@ -0,0 +1,3 @@
1
+ # https://www.robotstxt.org/robotstxt.html
2
+ User-agent: *
3
+ Disallow:
@@ -1,4 +1,3 @@
1
- import React from 'react';
2
1
  import { HashRouter as Router } from 'react-router-dom';
3
2
  import './dx-styles.scss';
4
3
  import LoadPanel from 'devextreme-react/load-panel';
@@ -1,4 +1,4 @@
1
- import React, { useState, useRef, useCallback } from 'react';
1
+ import <%=#isTypeScript%>React, <%=/isTypeScript%>{ useState, useRef, useCallback } from 'react';
2
2
  import { useNavigate, useParams } from 'react-router-dom';
3
3
  import Form, {
4
4
  Item,
@@ -19,7 +19,7 @@ export default function ChangePasswordForm() {
19
19
  const formData = useRef({ password: '' });
20
20
  const { recoveryCode } = useParams();
21
21
 
22
- const onSubmit = useCallback(async (e<%=#isTypeScript%>: any<%=/isTypeScript%>) => {
22
+ const onSubmit = useCallback(async (e<%=#isTypeScript%>: React.FormEvent<HTMLFormElement><%=/isTypeScript%>) => {
23
23
  e.preventDefault();
24
24
  const { password } = formData.current;
25
25
  setLoading(true);
@@ -1,10 +1,7 @@
1
- @import "../../themes/generated/variables.base.scss";
2
-
3
1
  .create-account-form {
4
2
  .policy-info {
5
- margin: 10px 0;
6
3
  color: var(--base-text-color-alpha-7);
7
- font-size: 14px;
4
+ font-size: 12px;
8
5
  font-style: normal;
9
6
 
10
7
  a {
@@ -14,7 +11,9 @@
14
11
 
15
12
  .login-link {
16
13
  color: var(--base-accent);
17
- font-size: 16px;
14
+ font-size: 12px;
18
15
  text-align: center;
16
+ padding: 6px 0 32px 0;
17
+ border-bottom: 1px solid var(--border-color);
19
18
  }
20
19
  }
@@ -1,4 +1,4 @@
1
- import React, { useState, useRef, useCallback } from 'react';
1
+ import <%=#isTypeScript%>React, <%=/isTypeScript%>{ useState, useRef, useCallback } from 'react';
2
2
  import { Link, useNavigate } from 'react-router-dom';
3
3
  import Form, {
4
4
  Item,
@@ -20,7 +20,7 @@ export default function CreateAccountForm() {
20
20
  const [loading, setLoading] = useState(false);
21
21
  const formData = useRef({ email: '', password: '' });
22
22
 
23
- const onSubmit = useCallback(async (e<%=#isTypeScript%>: any<%=/isTypeScript%>) => {
23
+ const onSubmit = useCallback(async (e<%=#isTypeScript%>: React.FormEvent<HTMLFormElement><%=/isTypeScript%>) => {
24
24
  e.preventDefault();
25
25
  const { email, password } = formData.current;
26
26
  setLoading(true);
@@ -92,12 +92,10 @@ export default function CreateAccountForm() {
92
92
  </span>
93
93
  </ButtonOptions>
94
94
  </ButtonItem>
95
- <Item>
96
- <div className={'login-link'}>
97
- Have an account? <Link to={'/login'}>Sign In</Link>
98
- </div>
99
- </Item>
100
95
  </Form>
96
+ <div className={'login-link'}>
97
+ Have an account? <Link to={'/login'}>Sign In</Link>
98
+ </div>
101
99
  </form>
102
100
  );
103
101
  }
@@ -1,4 +1,3 @@
1
- import React from 'react';
2
1
  import './Footer.scss';
3
2
 
4
3
  export default function Footer({ ...rest }) {
@@ -1,4 +1,4 @@
1
- @import "../../dx-styles.scss";
1
+ @use "../../dx-styles.scss" as *;
2
2
 
3
3
  header {
4
4
  background-color: var(--base-bg);
@@ -1,4 +1,3 @@
1
- import React from 'react';
2
1
  import Toolbar, { Item } from 'devextreme-react/toolbar';
3
2
  import Button from 'devextreme-react/button';
4
3
  import UserPanel from '../user-panel/UserPanel';
@@ -1,18 +1,12 @@
1
- @import "../../themes/generated/variables.base.scss";
2
-
3
1
  .login-form {
4
2
  .link {
5
3
  text-align: center;
6
- font-size: 16px;
4
+ font-size: 12px;
7
5
  font-style: normal;
8
-
9
- a {
10
- text-decoration: none;
11
- }
6
+ margin: 6px 0 50px;
12
7
  }
13
8
 
14
9
  .form-text {
15
- margin: 10px 0;
16
10
  color: var(--base-text-color-alpha-7);
17
11
  }
18
12
  }
@@ -1,4 +1,4 @@
1
- import React, { useState, useRef, useCallback } from 'react';
1
+ import <%=#isTypeScript%>React, <%=/isTypeScript%>{ useState, useRef, useCallback } from 'react';
2
2
  import { Link, useNavigate } from 'react-router-dom';
3
3
  import Form, {
4
4
  Item,
@@ -9,6 +9,7 @@ import Form, {
9
9
  EmailRule
10
10
  } from 'devextreme-react/form';
11
11
  import LoadIndicator from 'devextreme-react/load-indicator';
12
+ import Button from 'devextreme-react/button';
12
13
  import notify from 'devextreme/ui/notify';
13
14
  import { useAuth } from '../../contexts/auth';
14
15
 
@@ -20,7 +21,7 @@ export default function LoginForm() {
20
21
  const [loading, setLoading] = useState(false);
21
22
  const formData = useRef({ email: '', password: '' });
22
23
 
23
- const onSubmit = useCallback(async (e<%=#isTypeScript%>: any<%=/isTypeScript%>) => {
24
+ const onSubmit = useCallback(async (e<%=#isTypeScript%>: React.FormEvent<HTMLFormElement><%=/isTypeScript%>) => {
24
25
  e.preventDefault();
25
26
  const { email, password } = formData.current;
26
27
  setLoading(true);
@@ -78,19 +79,16 @@ export default function LoginForm() {
78
79
  </span>
79
80
  </ButtonOptions>
80
81
  </ButtonItem>
81
- <Item>
82
- <div className={'link'}>
83
- <Link to={'/reset-password'}>Forgot password?</Link>
84
- </div>
85
- </Item>
86
- <ButtonItem>
87
- <ButtonOptions
88
- text={'Create an account'}
89
- width={'100%'}
90
- onClick={onCreateAccountClick}
91
- />
92
- </ButtonItem>
93
82
  </Form>
83
+ <div className={'link'}>
84
+ <Link to={'/reset-password'}>Forgot password?</Link>
85
+ </div>
86
+ <Button
87
+ text={'Create an account'}
88
+ stylingMode={ 'outlined' }
89
+ width={'100%'}
90
+ onClick={onCreateAccountClick}
91
+ />
94
92
  </form>
95
93
  );
96
94
  }
@@ -1,13 +1,12 @@
1
- @import "../../themes/generated/variables.base.scss";
2
-
3
1
  .reset-password-form {
4
2
  .submit-button {
5
- margin-top: 10px;
3
+ margin-top: 18px;
6
4
  }
7
5
 
8
6
  .login-link {
9
7
  color: var(--base-accent);
10
- font-size: 16px;
8
+ font-size: 12px;
11
9
  text-align: center;
10
+ margin-top: 6px;
12
11
  }
13
12
  }
@@ -1,4 +1,4 @@
1
- import React, { useState, useRef, useCallback } from 'react';
1
+ import <%=#isTypeScript%>React, <%=/isTypeScript%>{ useState, useRef, useCallback } from 'react';
2
2
  import { Link, useNavigate } from "react-router-dom";
3
3
  import Form, {
4
4
  Item,
@@ -20,7 +20,7 @@ export default function ResetPasswordForm() {
20
20
  const [loading, setLoading] = useState(false);
21
21
  const formData = useRef({ email: '', password: '' });
22
22
 
23
- const onSubmit = useCallback(async (e<%=#isTypeScript%>: any<%=/isTypeScript%>) => {
23
+ const onSubmit = useCallback(async (e<%=#isTypeScript%>: React.FormEvent<HTMLFormElement><%=/isTypeScript%>) => {
24
24
  e.preventDefault();
25
25
  const { email } = formData.current;
26
26
  setLoading(true);
@@ -64,12 +64,10 @@ export default function ResetPasswordForm() {
64
64
  </span>
65
65
  </ButtonOptions>
66
66
  </ButtonItem>
67
- <Item>
68
- <div className={'login-link'}>
69
- Return to <Link to={'/login'}>Sign In</Link>
70
- </div>
71
- </Item>
72
67
  </Form>
68
+ <div className={'login-link'}>
69
+ Return to <Link to={'/login'}>Sign In</Link>
70
+ </div>
73
71
  </form>
74
72
  );
75
73
  }
@@ -1,4 +1,5 @@
1
- @import "../../dx-styles.scss";
1
+ @use "../../dx-styles" as *;
2
+ @use "../../utils/patches";
2
3
 
3
4
  .dx-swatch-additional, .dx-swatch-additional-dark {
4
5
  &.side-navigation-menu {
@@ -71,6 +72,5 @@
71
72
  }
72
73
 
73
74
  .dx-drawer-overlap.pre-init-blink-fix {
74
- @import "../../utils/patches.scss";
75
- @include menu-pre-init-patch;
75
+ @include patches.menu-pre-init-patch;
76
76
  }
@@ -1,6 +1,6 @@
1
1
  import React, { useEffect, useRef, useCallback, useMemo, useContext } from 'react';
2
2
  import { TreeView<%=#isTypeScript%>, TreeViewRef<%=/isTypeScript%> } from 'devextreme-react/tree-view';
3
- import * as events from 'devextreme/events';
3
+ import * as events from 'devextreme-react/common/core/events';
4
4
  import { navigation } from '../../app-navigation';
5
5
  import { useNavigation } from '../../contexts/navigation';
6
6
  import { useScreenSize } from '../../utils/media-query';
@@ -35,7 +35,7 @@ export default function SideNavigationMenu(props<%=#isTypeScript%>: React.PropsW
35
35
  const { navigationData: { currentPath } } = useNavigation();
36
36
 
37
37
  const treeViewRef = useRef<%=#isTypeScript%><TreeViewRef><%=/isTypeScript%>(null);
38
- const wrapperRef = useRef<%=#isTypeScript%><HTMLDivElement><%=/isTypeScript%>();
38
+ const wrapperRef = useRef<%=#isTypeScript%><HTMLDivElement><%=/isTypeScript%>(null);
39
39
  const getWrapperRef = useCallback((element<%=#isTypeScript%>: HTMLDivElement<%=/isTypeScript%>) => {
40
40
  const prevElement = wrapperRef.current;
41
41
  if (prevElement) {
@@ -1,4 +1,4 @@
1
- import React, { useCallback, useContext } from 'react';
1
+ import { useCallback, useContext } from 'react';
2
2
  import Button from 'devextreme-react/button';
3
3
  import { ThemeContext } from '../../theme';
4
4
 
@@ -7,7 +7,7 @@ export const ThemeSwitcher = () => {
7
7
 
8
8
  const onButtonClick = useCallback(() => {
9
9
  themeContext?.switchTheme();
10
- }, []);
10
+ }, [themeContext]);
11
11
 
12
12
  return <div>
13
13
  <Button
@@ -1,4 +1,4 @@
1
- import React, { useMemo, useCallback } from 'react';
1
+ import { useMemo, useCallback } from 'react';
2
2
  import { useNavigate } from "react-router-dom";
3
3
  import DropDownButton from 'devextreme-react/drop-down-button';
4
4
  import List from 'devextreme-react/list';
@@ -1,3 +1,5 @@
1
+ @use "variables.scss" as *;
2
+
1
3
  $side-panel-min-width: 60px;
2
4
 
3
5
  html,
@@ -25,6 +27,7 @@ body {
25
27
  display: flex;
26
28
  height: 100%;
27
29
  width: 100%;
30
+ min-width: 320px;
28
31
  }
29
32
 
30
33
  .content {
@@ -37,10 +40,10 @@ body {
37
40
  margin: 0;
38
41
  line-height: 40px;
39
42
  }
43
+ }
40
44
 
41
- .screen-x-small & {
42
- padding: 20px;
43
- }
45
+ .screen-x-small :not(.dx-card).content {
46
+ padding: 20px;
44
47
  }
45
48
 
46
49
  .container {