devextreme-cli 1.10.0 → 1.11.0-alpha.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 (78) hide show
  1. package/package.json +4 -3
  2. package/src/applications/application.angular.js +32 -7
  3. package/src/applications/application.react.js +30 -24
  4. package/src/applications/application.vue.js +23 -6
  5. package/src/templates/react/application/src/App.tsx +0 -1
  6. package/src/templates/react/application/src/components/change-password-form/ChangePasswordForm.tsx +2 -2
  7. package/src/templates/react/application/src/components/create-account-form/CreateAccountForm.scss +0 -2
  8. package/src/templates/react/application/src/components/create-account-form/CreateAccountForm.tsx +2 -2
  9. package/src/templates/react/application/src/components/footer/Footer.tsx +0 -1
  10. package/src/templates/react/application/src/components/header/Header.tsx +0 -1
  11. package/src/templates/react/application/src/components/login-form/LoginForm.scss +0 -2
  12. package/src/templates/react/application/src/components/login-form/LoginForm.tsx +2 -2
  13. package/src/templates/react/application/src/components/reset-password-form/ResetPasswordForm.scss +0 -2
  14. package/src/templates/react/application/src/components/reset-password-form/ResetPasswordForm.tsx +2 -2
  15. package/src/templates/react/application/src/components/side-navigation-menu/SideNavigationMenu.scss +3 -3
  16. package/src/templates/react/application/src/components/side-navigation-menu/SideNavigationMenu.tsx +1 -1
  17. package/src/templates/react/application/src/components/theme-switcher/ThemeSwitcher.tsx +1 -1
  18. package/src/templates/react/application/src/components/user-panel/UserPanel.tsx +1 -1
  19. package/src/templates/react/application/src/dx-styles.scss +2 -0
  20. package/src/templates/react/application/src/layouts/side-nav-inner-toolbar/side-nav-inner-toolbar.tsx +11 -5
  21. package/src/templates/react/application/src/layouts/side-nav-outer-toolbar/side-nav-outer-toolbar.tsx +11 -5
  22. package/src/templates/react/application/src/layouts/single-card/single-card.scss +0 -2
  23. package/src/templates/react/application/src/layouts/single-card/single-card.tsx +0 -1
  24. package/src/templates/react/application/src/types.tsx +1 -2
  25. package/src/templates/react/application/src/utils/media-query.tsx +3 -1
  26. package/src/templates/react/application/src/utils/patches.scss +4 -4
  27. package/src/templates/react/sample-pages/home/home.scss +0 -2
  28. package/src/templates/react/sample-pages/home/home.tsx +1 -1
  29. package/src/templates/react/sample-pages/tasks/tasks.tsx +4 -4
  30. package/src/templates/vue-v3/sample-pages/tasks-page.vue +1 -1
  31. package/src/utility/extract-deps-version-tag.js +13 -0
  32. package/src/utility/latest-versions.js +4 -3
  33. package/src/utility/prompts/transpiler.js +17 -0
  34. package/src/utility/typescript-extension.js +1 -1
  35. package/src/templates/cra-template/LICENSE +0 -21
  36. package/src/templates/cra-template/README.md +0 -10
  37. package/src/templates/cra-template/package.json +0 -26
  38. package/src/templates/cra-template/template/README.md +0 -70
  39. package/src/templates/cra-template/template/gitignore +0 -23
  40. package/src/templates/cra-template/template/public/favicon.ico +0 -0
  41. package/src/templates/cra-template/template/public/index.html +0 -43
  42. package/src/templates/cra-template/template/public/logo192.png +0 -0
  43. package/src/templates/cra-template/template/public/logo512.png +0 -0
  44. package/src/templates/cra-template/template/public/manifest.json +0 -25
  45. package/src/templates/cra-template/template/public/robots.txt +0 -3
  46. package/src/templates/cra-template/template/src/App.css +0 -38
  47. package/src/templates/cra-template/template/src/App.js +0 -25
  48. package/src/templates/cra-template/template/src/App.test.js +0 -9
  49. package/src/templates/cra-template/template/src/index.css +0 -12
  50. package/src/templates/cra-template/template/src/index.js +0 -17
  51. package/src/templates/cra-template/template/src/logo.svg +0 -1
  52. package/src/templates/cra-template/template/src/reportWebVitals.js +0 -13
  53. package/src/templates/cra-template/template/src/setupTests.js +0 -5
  54. package/src/templates/cra-template/template.json +0 -14
  55. package/src/templates/cra-template-typescript/LICENSE +0 -21
  56. package/src/templates/cra-template-typescript/README.md +0 -20
  57. package/src/templates/cra-template-typescript/package.json +0 -27
  58. package/src/templates/cra-template-typescript/template/README.md +0 -46
  59. package/src/templates/cra-template-typescript/template/gitignore +0 -23
  60. package/src/templates/cra-template-typescript/template/public/index.html +0 -43
  61. package/src/templates/cra-template-typescript/template/src/App.css +0 -38
  62. package/src/templates/cra-template-typescript/template/src/App.test.tsx +0 -10
  63. package/src/templates/cra-template-typescript/template/src/App.tsx +0 -26
  64. package/src/templates/cra-template-typescript/template/src/index.tsx +0 -19
  65. package/src/templates/cra-template-typescript/template/src/logo.svg +0 -1
  66. package/src/templates/cra-template-typescript/template/src/reportWebVitals.ts +0 -13
  67. package/src/templates/cra-template-typescript/template/src/setupTests.ts +0 -5
  68. package/src/templates/cra-template-typescript/template.json +0 -19
  69. package/src/templates/react/application/src/App.test.tsx +0 -13
  70. package/src/templates/react/application/src/matchMediaMock.tsx +0 -14
  71. package/src/templates/react/application/src/polyfills.tsx +0 -2
  72. package/src/utility/extract-tooling-version.js +0 -13
  73. /package/src/templates/{cra-template-typescript/template → react/application}/public/favicon.ico +0 -0
  74. /package/src/templates/{cra-template-typescript/template → react/application}/public/logo192.png +0 -0
  75. /package/src/templates/{cra-template-typescript/template → react/application}/public/logo512.png +0 -0
  76. /package/src/templates/{cra-template-typescript/template → react/application}/public/manifest.json +0 -0
  77. /package/src/templates/{cra-template-typescript/template → react/application}/public/robots.txt +0 -0
  78. /package/src/templates/{cra-template-typescript/template → react/application}/src/index.css +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devextreme-cli",
3
- "version": "1.10.0",
3
+ "version": "1.11.0-alpha.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.86.0",
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",
@@ -72,5 +73,5 @@
72
73
  "typescript": "^4.0.2",
73
74
  "typescript-eslint-parser": "^22.0.0"
74
75
  },
75
- "gitHead": "a29437ade8ce07c75b0d7df33a54b0e42f7f57af"
76
+ "gitHead": "4c13206f0278c88053f62682fd2a6ca0a8ea5866"
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,27 +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
- const templateSuffix = templateOptions.isTypeScript ? '-typescript' : '';
67
- const templatePath = path.resolve(__dirname, `../templates/cra-template${templateSuffix}`);
78
+ const commandArguments = [`-p=create-vite@${depsVersionTag || latestVersions['create-vite']}`, 'create-vite', appName];
68
79
 
69
- commandArguments.push(`--template file:${templatePath}`);
80
+ commandArguments.push(`--template react${transpiler === 'swc' ? '-swc' : ''}${templateOptions.isTypeScript ? '-ts' : ''}`);
70
81
 
71
82
  await runCommand('npx', commandArguments);
72
83
 
73
84
  const appPath = path.join(process.cwd(), appName);
74
85
 
75
86
  modifyIndexHtml(appPath, templateOptions.project);
87
+
88
+ if(depsVersionTag) {
89
+ bumpReact(appPath, depsVersionTag);
90
+ }
91
+
76
92
  addTemplate(appPath, appName, templateOptions);
77
93
  };
78
94
 
79
95
  const modifyIndexHtml = (appPath, appName) => {
80
- const indexHtmlPath = path.join(appPath, 'public', 'index.html');
96
+ const indexHtmlPath = path.join(appPath, 'index.html');
81
97
 
82
98
  let htmlContent = fs.readFileSync(indexHtmlPath).toString();
83
- htmlContent = htmlContent.replace(/<title>(\w+\s*)+<\/title>/, `<title>${appName}<\/title>`);
99
+ htmlContent = htmlContent.replace(/<title>[^<]+<\/title>/, `<title>${appName}<\/title>`);
84
100
  htmlContent = htmlContent.replace('<body>', '<body class="dx-viewport">');
85
101
 
86
102
  fs.writeFileSync(indexHtmlPath, htmlContent);
@@ -97,7 +113,6 @@ const addTemplate = (appPath, appName, templateOptions) => {
97
113
  );
98
114
 
99
115
  const manifestPath = path.join(appPath, 'public', 'manifest.json');
100
- const indexPath = path.join(appPath, 'src', templateOptions.isTypeScript ? 'index.tsx' : 'index.js');
101
116
 
102
117
  const styles = [
103
118
  './themes/generated/theme.additional.css',
@@ -108,15 +123,15 @@ const addTemplate = (appPath, appName, templateOptions) => {
108
123
  ];
109
124
 
110
125
  templateCreator.moveTemplateFilesToProject(applicationTemplatePath, appPath, templateOptions, getCorrectPath);
111
- removeFile(path.join(appPath, 'src', 'App.css'));
112
- !templateOptions.isTypeScript && removeFile(path.join(appPath, 'src', 'types.js'));
126
+
127
+ !templateOptions.isTypeScript && removeFile(path.join(appPath, 'src', 'types.jsx'));
128
+
113
129
  if(!templateOptions.empty) {
114
130
  addSamplePages(appPath, templateOptions);
115
131
  }
116
132
 
117
133
  preparePackageJsonForTemplate(appPath, appName, templateOptions.isTypeScript);
118
134
  updateJsonPropName(manifestPath, appName);
119
- addPolyfills(packageJsonUtils.getPackageJsonPath(), indexPath);
120
135
  install({}, appPath, styles);
121
136
  };
122
137
 
@@ -130,15 +145,6 @@ const install = (options, appPath, styles) => {
130
145
  packageManager.runInstall({ cwd: appPath });
131
146
  };
132
147
 
133
- const addPolyfills = (packagePath, indexPath) => {
134
- const packages = [
135
- { name: 'react-app-polyfill', version: '^1.0.0' }
136
- ];
137
-
138
- packageJsonUtils.addDependencies(packagePath, packages);
139
- moduleUtils.insertImport(indexPath, './polyfills');
140
- };
141
-
142
148
  const addStylesToApp = (filePath, styles) => {
143
149
  styles.forEach(style => {
144
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
  };
@@ -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,5 +1,3 @@
1
- @import "../../themes/generated/variables.base.scss";
2
-
3
1
  .create-account-form {
4
2
  .policy-info {
5
3
  color: var(--base-text-color-alpha-7);
@@ -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);
@@ -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,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,5 +1,3 @@
1
- @import "../../themes/generated/variables.base.scss";
2
-
3
1
  .login-form {
4
2
  .link {
5
3
  text-align: center;
@@ -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,
@@ -21,7 +21,7 @@ export default function LoginForm() {
21
21
  const [loading, setLoading] = useState(false);
22
22
  const formData = useRef({ email: '', password: '' });
23
23
 
24
- const onSubmit = useCallback(async (e<%=#isTypeScript%>: any<%=/isTypeScript%>) => {
24
+ const onSubmit = useCallback(async (e<%=#isTypeScript%>: React.FormEvent<HTMLFormElement><%=/isTypeScript%>) => {
25
25
  e.preventDefault();
26
26
  const { email, password } = formData.current;
27
27
  setLoading(true);
@@ -1,5 +1,3 @@
1
- @import "../../themes/generated/variables.base.scss";
2
-
3
1
  .reset-password-form {
4
2
  .submit-button {
5
3
  margin-top: 18px;
@@ -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);
@@ -1,4 +1,5 @@
1
- @use "../../dx-styles.scss" as *;
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';
@@ -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
 
@@ -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,
@@ -3,7 +3,7 @@ import Drawer from 'devextreme-react/drawer';
3
3
  import { ScrollView<%=#isTypeScript%>, ScrollViewRef<%=/isTypeScript%> } from 'devextreme-react/scroll-view';
4
4
  import Toolbar, { Item } from 'devextreme-react/toolbar';
5
5
  import React, { useState, useCallback, useRef } from 'react';
6
- import { useNavigate } from 'react-router';
6
+ import { useNavigate } from 'react-router-dom';
7
7
  import { Header, SideNavigationMenu, Footer } from '../../components';
8
8
  import './side-nav-inner-toolbar.scss';
9
9
  import { useScreenSize } from '../../utils/media-query';
@@ -84,13 +84,19 @@ export default function SideNavInnerToolbar({ title, children }<%=#isTypeScript%
84
84
  />
85
85
  <ScrollView ref={scrollViewRef} className={'layout-body with-footer'}>
86
86
  <div className={'content'}>
87
- {React.Children.map(children, (item<%=#isTypeScript%>: any<%=/isTypeScript%>) => {
88
- return item.type !== Footer && item;
87
+ {React.Children.map(children, (item) => {
88
+ if (<%=#isTypeScript%>React.isValidElement(item) && <%=/isTypeScript%>item.type !== Footer) {
89
+ return item;
90
+ }
91
+ return null;
89
92
  })}
90
93
  </div>
91
94
  <div className={'content-block'}>
92
- {React.Children.map(children, (item<%=#isTypeScript%>: any<%=/isTypeScript%>) => {
93
- return item.type === Footer && item;
95
+ {React.Children.map(children, (item) => {
96
+ if (<%=#isTypeScript%>React.isValidElement(item) && <%=/isTypeScript%>item.type === Footer) {
97
+ return item;
98
+ }
99
+ return null;
94
100
  })}
95
101
  </div>
96
102
  </ScrollView>
@@ -1,7 +1,7 @@
1
1
  import Drawer from 'devextreme-react/drawer';
2
2
  import { ScrollView<%=#isTypeScript%>, ScrollViewRef<%=/isTypeScript%> } from 'devextreme-react/scroll-view';
3
3
  import React, { useState, useCallback, useRef } from 'react';
4
- import { useNavigate } from 'react-router';
4
+ import { useNavigate } from 'react-router-dom';
5
5
  import { Header, SideNavigationMenu, Footer } from '../../components';
6
6
  import './side-nav-outer-toolbar.scss';
7
7
  import { useScreenSize } from '../../utils/media-query';
@@ -83,13 +83,19 @@ export default function SideNavOuterToolbar({ title, children }<%=#isTypeScript%
83
83
  <div className={'container'}>
84
84
  <ScrollView ref={scrollViewRef} className={'with-footer'}>
85
85
  <div className={'content'}>
86
- {React.Children.map(children, (item<%=#isTypeScript%>: any<%=/isTypeScript%>) => {
87
- return item.type !== Footer && item;
86
+ {React.Children.map(children, (item) => {
87
+ if (<%=#isTypeScript%>React.isValidElement(item) && <%=/isTypeScript%>item.type !== Footer) {
88
+ return item;
89
+ }
90
+ return null;
88
91
  })}
89
92
  </div>
90
93
  <div className={'content-block'}>
91
- {React.Children.map(children, (item<%=#isTypeScript%>: any<%=/isTypeScript%>) => {
92
- return item.type === Footer && item;
94
+ {React.Children.map(children, (item) => {
95
+ if (<%=#isTypeScript%>React.isValidElement(item) && <%=/isTypeScript%>item.type === Footer) {
96
+ return item;
97
+ }
98
+ return null;
93
99
  })}
94
100
  </div>
95
101
  </ScrollView>
@@ -1,5 +1,3 @@
1
- @import "../../themes/generated/variables.base.scss";
2
-
3
1
  .single-card {
4
2
  width: 100%;
5
3
  height: 100%;
@@ -1,4 +1,3 @@
1
- import React from 'react';
2
1
  import ScrollView from 'devextreme-react/scroll-view';
3
2
  import './single-card.scss';
4
3
  <%=#isTypeScript%>import type { SingleCardProps } from '../../types';<%=/isTypeScript%>
@@ -1,6 +1,5 @@
1
1
  import { TreeViewTypes } from 'devextreme-react/tree-view';
2
2
  import { ButtonTypes } from 'devextreme-react/button';
3
- import React from 'react';
4
3
 
5
4
  export interface HeaderProps {
6
5
  menuToggleEnabled: boolean;
@@ -53,4 +52,4 @@ export type NavigationContextType = {
53
52
 
54
53
  export type ValidationType = {
55
54
  value: string;
56
- }
55
+ }
@@ -44,7 +44,9 @@ const largeMedia = window.matchMedia('(min-width: 1280px)');
44
44
 
45
45
  [xSmallMedia, smallMedia, mediumMedia, largeMedia].forEach(media => {
46
46
  media.addListener((e) => {
47
- e.matches && handlers.forEach(handler => handler());
47
+ if(e.matches) {
48
+ handlers.forEach(handler => handler())
49
+ }
48
50
  });
49
51
  });
50
52
 
@@ -1,12 +1,12 @@
1
- @import "../themes/generated/variables.additional.scss";
1
+ @use "../themes/generated/variables.additional.scss" as *;
2
2
 
3
3
  @mixin menu-pre-init-patch {
4
4
  $menuMinSize: 60px;
5
-
5
+
6
6
  .dx-drawer-content {
7
7
  padding-left: $menuMinSize;
8
8
  }
9
-
9
+
10
10
  .dx-drawer-panel-content.dx-overlay::before {
11
11
  content: "";
12
12
  width: $menuMinSize;
@@ -15,7 +15,7 @@
15
15
  position: absolute;
16
16
  background-color: $base-bg;
17
17
  }
18
-
18
+
19
19
  .dx-overlay-content {
20
20
  width: $menuMinSize !important;
21
21
  }
@@ -1,5 +1,3 @@
1
- @use "../../variables.scss" as *;
2
-
3
1
  .logos-container {
4
2
  margin: 0 0 40px 0;
5
3
 
@@ -68,7 +68,7 @@ export default function Home() {
68
68
  <p>Thanks for using the DevExtreme React App Template.</p>
69
69
  <p>
70
70
  <span>This application was built using </span>
71
- <a href={'https://create-react-app.dev/'} target={'_blank'} rel={'noopener noreferrer'}>Create React App</a>
71
+ <a href={'https://vite.dev/guide/'} target={'_blank'} rel={'noopener noreferrer'}>create-vite</a>
72
72
  <span> and </span>
73
73
  <a href={'https://js.devexpress.com/Documentation/Guide/Common/DevExtreme_CLI/'} target={'_blank'} rel={'noopener noreferrer'}>DevExtreme CLI</a>
74
74
  <span> and includes the following DevExtreme components:</span>
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import 'devextreme/data/odata/store';
2
+ import { DataSource } from 'devextreme-react/common/data';
3
3
  import DataGrid, {
4
4
  Column,
5
5
  Pager,
@@ -16,7 +16,7 @@ export default function Task() {
16
16
 
17
17
  <DataGrid
18
18
  className={'dx-card content-block'}
19
- dataSource={dataSource<%=#isTypeScript%> as any<%=/isTypeScript%>}
19
+ dataSource={dataSource}
20
20
  showBorders={false}
21
21
  focusedRowEnabled={true}
22
22
  defaultFocusedRowIndex={0}
@@ -83,7 +83,7 @@ export default function Task() {
83
83
  </React.Fragment>
84
84
  )}
85
85
 
86
- const dataSource = {
86
+ const dataSource = new DataSource({
87
87
  store: {
88
88
  version: 2,
89
89
  type: 'odata',
@@ -101,7 +101,7 @@ const dataSource = {
101
101
  'Task_Completion',
102
102
  'ResponsibleEmployee/Employee_Full_Name'
103
103
  ]
104
- };
104
+ });
105
105
 
106
106
  const priorities = [
107
107
  { name: 'High', value: 4 },