devextreme-cli 1.12.1 → 1.13.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.
- package/index.js +1 -1
- package/package.json +8 -5
- package/src/application.js +1 -1
- package/src/applications/application.angular.js +2 -2
- package/src/applications/application.nextjs.js +1 -0
- package/src/applications/application.react.js +1 -1
- package/src/applications/application.vue.js +1 -6
- package/src/commands.json +5 -5
- package/src/templates/nextjs/application/src/components/change-password-form/ChangePasswordForm.tsx +20 -8
- package/src/templates/nextjs/application/src/components/create-account-form/CreateAccountForm.tsx +20 -8
- package/src/templates/nextjs/application/src/components/login-form/LoginForm.tsx +18 -6
- package/src/templates/nextjs/application/src/components/reset-password-form/ResetPasswordForm.tsx +18 -6
- package/src/templates/nextjs/application/src/index.css +0 -3
- package/src/templates/nextjs/application/src/{middleware.ts → proxy.ts} +1 -1
- package/src/templates/react/application/src/components/change-password-form/ChangePasswordForm.tsx +20 -8
- package/src/templates/react/application/src/components/create-account-form/CreateAccountForm.tsx +20 -8
- package/src/templates/react/application/src/components/login-form/LoginForm.tsx +18 -6
- package/src/templates/react/application/src/components/reset-password-form/ResetPasswordForm.tsx +18 -6
- package/src/templates/react/application/src/index.css +0 -3
- package/src/utility/latest-versions.js +6 -6
- package/src/utility/ng-version.js +2 -2
package/index.js
CHANGED
|
@@ -41,7 +41,7 @@ const run = async(commands, options) => {
|
|
|
41
41
|
await application.run(commands, options, devextremeConfig.read());
|
|
42
42
|
} else if(application.isMigrationCommand(commands[0])) {
|
|
43
43
|
if(!commands[1]) {
|
|
44
|
-
console.error('Please specify a
|
|
44
|
+
console.error('Please specify a migration command.');
|
|
45
45
|
printHelp('migrate');
|
|
46
46
|
return;
|
|
47
47
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "devextreme-cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.13.0",
|
|
4
4
|
"description": "DevExtreme CLI",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"devexpress",
|
|
@@ -43,14 +43,13 @@
|
|
|
43
43
|
"minimist": "^1.2.8",
|
|
44
44
|
"mustache": "^3.2.1",
|
|
45
45
|
"prompts": "^2.4.2",
|
|
46
|
-
"sass": "^1.
|
|
46
|
+
"sass": "^1.97.1",
|
|
47
47
|
"semver": "^5.7.2",
|
|
48
48
|
"strip-bom": "^4.0.0"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@typescript-eslint/eslint-plugin": "^4.33.0",
|
|
52
52
|
"@typescript-eslint/parser": "^4.33.0",
|
|
53
|
-
"babel-eslint": "^10.1.0",
|
|
54
53
|
"create-vite": "7.1.3",
|
|
55
54
|
"cross-env": "^5.2.1",
|
|
56
55
|
"eslint": "^7.32.0",
|
|
@@ -70,9 +69,13 @@
|
|
|
70
69
|
"rimraf": "^2.7.1",
|
|
71
70
|
"tree-kill": "^1.2.2",
|
|
72
71
|
"tree-kill-promise": "^1.0.12",
|
|
73
|
-
"typescript": "^4.
|
|
72
|
+
"typescript": "^4.9.5",
|
|
74
73
|
"typescript-eslint-parser": "^22.0.0",
|
|
75
74
|
"wait-on": "8.0.5"
|
|
76
75
|
},
|
|
77
|
-
"
|
|
76
|
+
"overrides": {
|
|
77
|
+
"@babel/traverse@<7.23.2": ">=7.23.2",
|
|
78
|
+
"braces@<3.0.3": ">=3.0.3"
|
|
79
|
+
},
|
|
80
|
+
"gitHead": "51bbc8d2fbfa40b741792c6921e27429cdb04c6f"
|
|
78
81
|
}
|
package/src/application.js
CHANGED
|
@@ -19,7 +19,7 @@ const handleWrongAppType = (appType, command) => {
|
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
const handleWrongChangeName = (changeName, command) => {
|
|
22
|
-
console.error(`
|
|
22
|
+
console.error(`Invalid migration command: ${changeName}`);
|
|
23
23
|
printHelp(command);
|
|
24
24
|
};
|
|
25
25
|
|
|
@@ -194,7 +194,7 @@ const migrateConfigComponents = async(options = {}) => {
|
|
|
194
194
|
if(!collectionPath) {
|
|
195
195
|
const prompts = require('prompts');
|
|
196
196
|
|
|
197
|
-
console.log(`\
|
|
197
|
+
console.log(`\nRequired package is missing: '${collectionName}'`);
|
|
198
198
|
|
|
199
199
|
const response = await prompts({
|
|
200
200
|
type: 'confirm',
|
|
@@ -204,7 +204,7 @@ const migrateConfigComponents = async(options = {}) => {
|
|
|
204
204
|
});
|
|
205
205
|
|
|
206
206
|
if(!response.install) {
|
|
207
|
-
console.log('Migration
|
|
207
|
+
console.log('Migration was canceled.');
|
|
208
208
|
process.exit(1);
|
|
209
209
|
}
|
|
210
210
|
}
|
|
@@ -82,7 +82,7 @@ const create = async(appName, options) => {
|
|
|
82
82
|
|
|
83
83
|
const commandArguments = [`-p=create-vite@${depsVersionTag || latestVersions['create-vite']}`, 'create-vite', appName];
|
|
84
84
|
|
|
85
|
-
commandArguments.push(`--template react${transpiler === 'swc' ? '-swc' : ''}${templateOptions.isTypeScript ? '-ts' : ''}`);
|
|
85
|
+
commandArguments.push(`--template react${transpiler === 'swc' ? '-swc' : ''}${templateOptions.isTypeScript ? '-ts' : ''} --no-rolldown --no-interactive`);
|
|
86
86
|
|
|
87
87
|
await runCommand('npx', commandArguments);
|
|
88
88
|
|
|
@@ -17,15 +17,10 @@ const defaultStyles = [
|
|
|
17
17
|
const preparePackageJsonForTemplate = (appPath, appName) => {
|
|
18
18
|
const dependencies = [
|
|
19
19
|
{ name: 'sass-embedded', version: '^1.85.1' },
|
|
20
|
-
{ name: 'vue-router', version: '^
|
|
20
|
+
{ name: 'vue-router', version: '^4.0.1' },
|
|
21
21
|
{ name: 'devextreme-cli', version: latestVersions['devextreme-cli'], dev: true }
|
|
22
22
|
];
|
|
23
23
|
|
|
24
|
-
const nameDepends = dependencies.map(d => d.name);
|
|
25
|
-
const indexVueRouter = nameDepends.indexOf('vue-router');
|
|
26
|
-
|
|
27
|
-
dependencies[indexVueRouter].version = '^4.0.1';
|
|
28
|
-
|
|
29
24
|
const scripts = [
|
|
30
25
|
{ name: 'build-themes', value: 'devextreme build' },
|
|
31
26
|
{ name: 'postinstall', value: 'npm run build-themes' }
|
package/src/commands.json
CHANGED
|
@@ -51,19 +51,19 @@
|
|
|
51
51
|
}, {
|
|
52
52
|
"name": "migrate",
|
|
53
53
|
"description": "Migration commands for DevExtreme applications",
|
|
54
|
-
"usage": "devextreme migrate <
|
|
54
|
+
"usage": "devextreme migrate <migration command> [options]",
|
|
55
55
|
"arguments": [{
|
|
56
56
|
"name": "angular-config-components",
|
|
57
|
-
"description": "
|
|
57
|
+
"description": "Migrates DevExtreme Angular applications to named configuration components.",
|
|
58
58
|
"options": [{
|
|
59
59
|
"name": "--include",
|
|
60
|
-
"description": "Template file glob patterns to include (default: **/*.html). You can pass multiple patterns as a comma-separated string (
|
|
60
|
+
"description": "Template file glob patterns to include (default: **/*.html). You can pass multiple patterns as a comma-separated string (\"**/a.html,**/b.html\") or as an array ([\"**/a.html\",\"**/b.html\"])."
|
|
61
61
|
}, {
|
|
62
62
|
"name": "--script-include",
|
|
63
|
-
"description": "TypeScript/JavaScript file glob patterns to scan for inline templates (default: **/*.ts,**/*.js). You can pass multiple patterns as a comma-separated string or as an array. Pass an empty value ('' or [])
|
|
63
|
+
"description": "TypeScript/JavaScript file glob patterns to scan for inline templates (default: **/*.ts,**/*.js). You can pass multiple patterns as a comma-separated string or as an array. Pass an empty value to disable ('' or [])."
|
|
64
64
|
}, {
|
|
65
65
|
"name": "--dry",
|
|
66
|
-
"description": "Run in dry mode to preview changes
|
|
66
|
+
"description": "Run in dry mode to preview changes."
|
|
67
67
|
}]
|
|
68
68
|
}]
|
|
69
69
|
}, {
|
package/src/templates/nextjs/application/src/components/change-password-form/ChangePasswordForm.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
'use client'
|
|
2
|
-
import <%=#isTypeScript%>React, <%=/isTypeScript%>{ useState,
|
|
2
|
+
import <%=#isTypeScript%>React, <%=/isTypeScript%>{ useState, useCallback } from 'react';
|
|
3
3
|
import { useRouter } from 'next/navigation';
|
|
4
4
|
import Form, {
|
|
5
5
|
Item,
|
|
@@ -7,7 +7,8 @@ import Form, {
|
|
|
7
7
|
ButtonItem,
|
|
8
8
|
ButtonOptions,
|
|
9
9
|
RequiredRule,
|
|
10
|
-
CustomRule
|
|
10
|
+
CustomRule,<%=#isTypeScript%>
|
|
11
|
+
type FormTypes,<%=/isTypeScript%>
|
|
11
12
|
} from 'devextreme-react/form';
|
|
12
13
|
import LoadIndicator from 'devextreme-react/load-indicator';
|
|
13
14
|
import notify from 'devextreme/ui/notify';
|
|
@@ -17,11 +18,22 @@ import { changePassword } from '@/app/actions/auth';
|
|
|
17
18
|
export default function ChangePasswordForm() {
|
|
18
19
|
const router = useRouter();
|
|
19
20
|
const [loading, setLoading] = useState(false);
|
|
20
|
-
const formData =
|
|
21
|
+
const [formData, setFormData] = useState({ password: '' });
|
|
22
|
+
|
|
23
|
+
const onFieldDataChanged = useCallback((e<%=#isTypeScript%>: FormTypes.FieldDataChangedEvent<%=/isTypeScript%>) => {
|
|
24
|
+
const { dataField, value } = e;
|
|
25
|
+
|
|
26
|
+
if (dataField) {
|
|
27
|
+
setFormData(formData => ({
|
|
28
|
+
...formData,
|
|
29
|
+
[dataField]: value,
|
|
30
|
+
}));
|
|
31
|
+
}
|
|
32
|
+
}, []);
|
|
21
33
|
|
|
22
34
|
const onSubmit = useCallback(async (e<%=#isTypeScript%>: React.FormEvent<HTMLFormElement><%=/isTypeScript%>) => {
|
|
23
35
|
e.preventDefault();
|
|
24
|
-
const { password } = formData
|
|
36
|
+
const { password } = formData;
|
|
25
37
|
setLoading(true);
|
|
26
38
|
|
|
27
39
|
const result = await changePassword(password);
|
|
@@ -32,16 +44,16 @@ export default function ChangePasswordForm() {
|
|
|
32
44
|
} else {
|
|
33
45
|
notify(result.message, 'error', 2000);
|
|
34
46
|
}
|
|
35
|
-
}, [router]);
|
|
47
|
+
}, [router, formData]);
|
|
36
48
|
|
|
37
49
|
const confirmPassword = useCallback(
|
|
38
|
-
({ value }<%=#isTypeScript%>: ValidationCallbackData<%=/isTypeScript%>) => value === formData.
|
|
39
|
-
[]
|
|
50
|
+
({ value }<%=#isTypeScript%>: ValidationCallbackData<%=/isTypeScript%>) => value === formData.password,
|
|
51
|
+
[formData]
|
|
40
52
|
);
|
|
41
53
|
|
|
42
54
|
return (
|
|
43
55
|
<form onSubmit={onSubmit}>
|
|
44
|
-
<Form formData={formData
|
|
56
|
+
<Form formData={formData} disabled={loading} onFieldDataChanged={onFieldDataChanged}>
|
|
45
57
|
<Item
|
|
46
58
|
dataField={'password'}
|
|
47
59
|
editorType={'dxTextBox'}
|
package/src/templates/nextjs/application/src/components/create-account-form/CreateAccountForm.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
'use client'
|
|
2
|
-
import <%=#isTypeScript%>React, <%=/isTypeScript%>{ useState,
|
|
2
|
+
import <%=#isTypeScript%>React, <%=/isTypeScript%>{ useState, useCallback } from 'react';
|
|
3
3
|
import { useRouter } from 'next/navigation';
|
|
4
4
|
import Link from 'next/link';
|
|
5
5
|
import Form, {
|
|
@@ -9,7 +9,8 @@ import Form, {
|
|
|
9
9
|
ButtonOptions,
|
|
10
10
|
RequiredRule,
|
|
11
11
|
CustomRule,
|
|
12
|
-
EmailRule
|
|
12
|
+
EmailRule,<%=#isTypeScript%>
|
|
13
|
+
type FormTypes,<%=/isTypeScript%>
|
|
13
14
|
} from 'devextreme-react/form';
|
|
14
15
|
import notify from 'devextreme/ui/notify';
|
|
15
16
|
import LoadIndicator from 'devextreme-react/load-indicator';
|
|
@@ -20,11 +21,22 @@ import './CreateAccountForm.scss';
|
|
|
20
21
|
export default function CreateAccountForm() {
|
|
21
22
|
const router = useRouter();
|
|
22
23
|
const [loading, setLoading] = useState(false);
|
|
23
|
-
const formData =
|
|
24
|
+
const [formData, setFormData] = useState({ email: '', password: '' });
|
|
25
|
+
|
|
26
|
+
const onFieldDataChanged = useCallback((e<%=#isTypeScript%>: FormTypes.FieldDataChangedEvent<%=/isTypeScript%>) => {
|
|
27
|
+
const { dataField, value } = e;
|
|
28
|
+
|
|
29
|
+
if (dataField) {
|
|
30
|
+
setFormData(formData => ({
|
|
31
|
+
...formData,
|
|
32
|
+
[dataField]: value,
|
|
33
|
+
}));
|
|
34
|
+
}
|
|
35
|
+
}, []);
|
|
24
36
|
|
|
25
37
|
const onSubmit = useCallback(async (e<%=#isTypeScript%>: React.FormEvent<HTMLFormElement><%=/isTypeScript%>) => {
|
|
26
38
|
e.preventDefault();
|
|
27
|
-
const { email, password } = formData
|
|
39
|
+
const { email, password } = formData;
|
|
28
40
|
setLoading(true);
|
|
29
41
|
|
|
30
42
|
const result = await signUp(email, password);
|
|
@@ -35,16 +47,16 @@ export default function CreateAccountForm() {
|
|
|
35
47
|
} else {
|
|
36
48
|
notify(result.message, 'error', 2000);
|
|
37
49
|
}
|
|
38
|
-
}, [router]);
|
|
50
|
+
}, [router, formData]);
|
|
39
51
|
|
|
40
52
|
const confirmPassword = useCallback(
|
|
41
|
-
({ value }<%=#isTypeScript%>: ValidationCallbackData<%=/isTypeScript%>) => value === formData.
|
|
42
|
-
[]
|
|
53
|
+
({ value }<%=#isTypeScript%>: ValidationCallbackData<%=/isTypeScript%>) => value === formData.password,
|
|
54
|
+
[formData]
|
|
43
55
|
);
|
|
44
56
|
|
|
45
57
|
return (
|
|
46
58
|
<form className={'create-account-form'} onSubmit={onSubmit}>
|
|
47
|
-
<Form formData={formData
|
|
59
|
+
<Form formData={formData} disabled={loading} onFieldDataChanged={onFieldDataChanged}>
|
|
48
60
|
<Item
|
|
49
61
|
dataField={'email'}
|
|
50
62
|
editorType={'dxTextBox'}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
'use client'
|
|
2
|
-
import <%=#isTypeScript%>React, <%=/isTypeScript%>{ useState,
|
|
2
|
+
import <%=#isTypeScript%>React, <%=/isTypeScript%>{ useState, useCallback } from 'react';
|
|
3
3
|
import { useRouter } from 'next/navigation';
|
|
4
4
|
import Link from 'next/link';
|
|
5
5
|
import Form, {
|
|
@@ -8,7 +8,8 @@ import Form, {
|
|
|
8
8
|
ButtonItem,
|
|
9
9
|
ButtonOptions,
|
|
10
10
|
RequiredRule,
|
|
11
|
-
EmailRule
|
|
11
|
+
EmailRule,<%=#isTypeScript%>
|
|
12
|
+
type FormTypes,<%=/isTypeScript%>
|
|
12
13
|
} from 'devextreme-react/form';
|
|
13
14
|
import LoadIndicator from 'devextreme-react/load-indicator';
|
|
14
15
|
import Button from 'devextreme-react/button';
|
|
@@ -20,11 +21,22 @@ import './LoginForm.scss';
|
|
|
20
21
|
export default function LoginForm() {
|
|
21
22
|
const router = useRouter();
|
|
22
23
|
const [loading, setLoading] = useState(false);
|
|
23
|
-
const formData =
|
|
24
|
+
const [formData, setFormData] = useState({ email: '', password: '' });
|
|
25
|
+
|
|
26
|
+
const onFieldDataChanged = useCallback((e<%=#isTypeScript%>: FormTypes.FieldDataChangedEvent<%=/isTypeScript%>) => {
|
|
27
|
+
const { dataField, value } = e;
|
|
28
|
+
|
|
29
|
+
if (dataField) {
|
|
30
|
+
setFormData(formData => ({
|
|
31
|
+
...formData,
|
|
32
|
+
[dataField]: value,
|
|
33
|
+
}));
|
|
34
|
+
}
|
|
35
|
+
}, []);
|
|
24
36
|
|
|
25
37
|
const onSubmit = useCallback(async (e<%=#isTypeScript%>: React.FormEvent<HTMLFormElement><%=/isTypeScript%>) => {
|
|
26
38
|
e.preventDefault();
|
|
27
|
-
const { email, password } = formData
|
|
39
|
+
const { email, password } = formData;
|
|
28
40
|
setLoading(true);
|
|
29
41
|
|
|
30
42
|
const result = await signIn(email, password);
|
|
@@ -34,7 +46,7 @@ export default function LoginForm() {
|
|
|
34
46
|
} else {
|
|
35
47
|
router.push('/');
|
|
36
48
|
}
|
|
37
|
-
}, [router]);
|
|
49
|
+
}, [router, formData]);
|
|
38
50
|
|
|
39
51
|
const onCreateAccountClick = useCallback(() => {
|
|
40
52
|
router.push('/auth/create-account');
|
|
@@ -42,7 +54,7 @@ export default function LoginForm() {
|
|
|
42
54
|
|
|
43
55
|
return (
|
|
44
56
|
<form className={'login-form'} onSubmit={onSubmit}>
|
|
45
|
-
<Form formData={formData
|
|
57
|
+
<Form formData={formData} disabled={loading} onFieldDataChanged={onFieldDataChanged}>
|
|
46
58
|
<Item
|
|
47
59
|
dataField={'email'}
|
|
48
60
|
editorType={'dxTextBox'}
|
package/src/templates/nextjs/application/src/components/reset-password-form/ResetPasswordForm.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
'use client'
|
|
2
|
-
import <%=#isTypeScript%>React, <%=/isTypeScript%>{ useState,
|
|
2
|
+
import <%=#isTypeScript%>React, <%=/isTypeScript%>{ useState, useCallback } from 'react';
|
|
3
3
|
import { useRouter } from 'next/navigation';
|
|
4
4
|
import Link from 'next/link';
|
|
5
5
|
import Form, {
|
|
@@ -8,7 +8,8 @@ import Form, {
|
|
|
8
8
|
ButtonItem,
|
|
9
9
|
ButtonOptions,
|
|
10
10
|
RequiredRule,
|
|
11
|
-
EmailRule
|
|
11
|
+
EmailRule,<%=#isTypeScript%>
|
|
12
|
+
type FormTypes,<%=/isTypeScript%>
|
|
12
13
|
} from 'devextreme-react/form';
|
|
13
14
|
import LoadIndicator from 'devextreme-react/load-indicator';
|
|
14
15
|
import notify from 'devextreme/ui/notify';
|
|
@@ -20,11 +21,22 @@ const notificationText = 'We\'ve sent a link to reset your password. Check your
|
|
|
20
21
|
export default function ResetPasswordForm() {
|
|
21
22
|
const router = useRouter();
|
|
22
23
|
const [loading, setLoading] = useState(false);
|
|
23
|
-
const formData =
|
|
24
|
+
const [formData, setFormData] = useState({ email: '', password: '' });
|
|
25
|
+
|
|
26
|
+
const onFieldDataChanged = useCallback((e<%=#isTypeScript%>: FormTypes.FieldDataChangedEvent<%=/isTypeScript%>) => {
|
|
27
|
+
const { dataField, value } = e;
|
|
28
|
+
|
|
29
|
+
if (dataField) {
|
|
30
|
+
setFormData(formData => ({
|
|
31
|
+
...formData,
|
|
32
|
+
[dataField]: value,
|
|
33
|
+
}));
|
|
34
|
+
}
|
|
35
|
+
}, []);
|
|
24
36
|
|
|
25
37
|
const onSubmit = useCallback(async (e<%=#isTypeScript%>: React.FormEvent<HTMLFormElement><%=/isTypeScript%>) => {
|
|
26
38
|
e.preventDefault();
|
|
27
|
-
const { email } = formData
|
|
39
|
+
const { email } = formData;
|
|
28
40
|
setLoading(true);
|
|
29
41
|
|
|
30
42
|
const result = await resetPassword(email);
|
|
@@ -36,11 +48,11 @@ export default function ResetPasswordForm() {
|
|
|
36
48
|
} else {
|
|
37
49
|
notify(result.message, 'error', 2000);
|
|
38
50
|
}
|
|
39
|
-
}, [router]);
|
|
51
|
+
}, [router, formData]);
|
|
40
52
|
|
|
41
53
|
return (
|
|
42
54
|
<form className={'reset-password-form'} onSubmit={onSubmit}>
|
|
43
|
-
<Form formData={formData
|
|
55
|
+
<Form formData={formData} disabled={loading} onFieldDataChanged={onFieldDataChanged}>
|
|
44
56
|
<Item
|
|
45
57
|
dataField={'email'}
|
|
46
58
|
editorType={'dxTextBox'}
|
|
@@ -19,7 +19,7 @@ async function _DEMO_logIn() {
|
|
|
19
19
|
// return NextResponse.redirect(new URL('/auth/login', req.nextUrl))
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
export default async function
|
|
22
|
+
export default async function proxy(req<%=#isTypeScript%>: NextRequest<%=/isTypeScript%>) {
|
|
23
23
|
const path = req.nextUrl.pathname;
|
|
24
24
|
|
|
25
25
|
if (!isProtectedRoute(path)) {
|
package/src/templates/react/application/src/components/change-password-form/ChangePasswordForm.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import <%=#isTypeScript%>React, <%=/isTypeScript%>{ useState,
|
|
1
|
+
import <%=#isTypeScript%>React, <%=/isTypeScript%>{ useState, useCallback } from 'react';
|
|
2
2
|
import { useNavigate, useParams } from 'react-router-dom';
|
|
3
3
|
import Form, {
|
|
4
4
|
Item,
|
|
@@ -6,7 +6,8 @@ import Form, {
|
|
|
6
6
|
ButtonItem,
|
|
7
7
|
ButtonOptions,
|
|
8
8
|
RequiredRule,
|
|
9
|
-
CustomRule
|
|
9
|
+
CustomRule,<%=#isTypeScript%>
|
|
10
|
+
type FormTypes,<%=/isTypeScript%>
|
|
10
11
|
} from 'devextreme-react/form';
|
|
11
12
|
import LoadIndicator from 'devextreme-react/load-indicator';
|
|
12
13
|
import notify from 'devextreme/ui/notify';
|
|
@@ -16,12 +17,23 @@ import { changePassword } from '../../api/auth';
|
|
|
16
17
|
export default function ChangePasswordForm() {
|
|
17
18
|
const navigate = useNavigate();
|
|
18
19
|
const [loading, setLoading] = useState(false);
|
|
19
|
-
const formData =
|
|
20
|
+
const [formData, setFormData] = useState({ password: '' });
|
|
20
21
|
const { recoveryCode } = useParams();
|
|
21
22
|
|
|
23
|
+
const onFieldDataChanged = useCallback((e<%=#isTypeScript%>: FormTypes.FieldDataChangedEvent<%=/isTypeScript%>) => {
|
|
24
|
+
const { dataField, value } = e;
|
|
25
|
+
|
|
26
|
+
if (dataField) {
|
|
27
|
+
setFormData(formData => ({
|
|
28
|
+
...formData,
|
|
29
|
+
[dataField]: value,
|
|
30
|
+
}));
|
|
31
|
+
}
|
|
32
|
+
}, []);
|
|
33
|
+
|
|
22
34
|
const onSubmit = useCallback(async (e<%=#isTypeScript%>: React.FormEvent<HTMLFormElement><%=/isTypeScript%>) => {
|
|
23
35
|
e.preventDefault();
|
|
24
|
-
const { password } = formData
|
|
36
|
+
const { password } = formData;
|
|
25
37
|
setLoading(true);
|
|
26
38
|
|
|
27
39
|
const result = await changePassword(password, recoveryCode);
|
|
@@ -32,16 +44,16 @@ export default function ChangePasswordForm() {
|
|
|
32
44
|
} else {
|
|
33
45
|
notify(result.message, 'error', 2000);
|
|
34
46
|
}
|
|
35
|
-
}, [navigate, recoveryCode]);
|
|
47
|
+
}, [navigate, recoveryCode, formData]);
|
|
36
48
|
|
|
37
49
|
const confirmPassword = useCallback(
|
|
38
|
-
({ value }<%=#isTypeScript%>: ValidationCallbackData<%=/isTypeScript%>) => value === formData.
|
|
39
|
-
[]
|
|
50
|
+
({ value }<%=#isTypeScript%>: ValidationCallbackData<%=/isTypeScript%>) => value === formData.password,
|
|
51
|
+
[formData]
|
|
40
52
|
);
|
|
41
53
|
|
|
42
54
|
return (
|
|
43
55
|
<form onSubmit={onSubmit}>
|
|
44
|
-
<Form formData={formData
|
|
56
|
+
<Form formData={formData} disabled={loading} onFieldDataChanged={onFieldDataChanged}>
|
|
45
57
|
<Item
|
|
46
58
|
dataField={'password'}
|
|
47
59
|
editorType={'dxTextBox'}
|
package/src/templates/react/application/src/components/create-account-form/CreateAccountForm.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import <%=#isTypeScript%>React, <%=/isTypeScript%>{ useState,
|
|
1
|
+
import <%=#isTypeScript%>React, <%=/isTypeScript%>{ useState, useCallback } from 'react';
|
|
2
2
|
import { Link, useNavigate } from 'react-router-dom';
|
|
3
3
|
import Form, {
|
|
4
4
|
Item,
|
|
@@ -7,7 +7,8 @@ import Form, {
|
|
|
7
7
|
ButtonOptions,
|
|
8
8
|
RequiredRule,
|
|
9
9
|
CustomRule,
|
|
10
|
-
EmailRule
|
|
10
|
+
EmailRule,<%=#isTypeScript%>
|
|
11
|
+
type FormTypes,<%=/isTypeScript%>
|
|
11
12
|
} from 'devextreme-react/form';
|
|
12
13
|
import notify from 'devextreme/ui/notify';
|
|
13
14
|
import LoadIndicator from 'devextreme-react/load-indicator';
|
|
@@ -18,11 +19,22 @@ import './CreateAccountForm.scss';
|
|
|
18
19
|
export default function CreateAccountForm() {
|
|
19
20
|
const navigate = useNavigate();
|
|
20
21
|
const [loading, setLoading] = useState(false);
|
|
21
|
-
const formData =
|
|
22
|
+
const [formData, setFormData] = useState({ email: '', password: '' });
|
|
23
|
+
|
|
24
|
+
const onFieldDataChanged = useCallback((e<%=#isTypeScript%>: FormTypes.FieldDataChangedEvent<%=/isTypeScript%>) => {
|
|
25
|
+
const { dataField, value } = e;
|
|
26
|
+
|
|
27
|
+
if (dataField) {
|
|
28
|
+
setFormData(formData => ({
|
|
29
|
+
...formData,
|
|
30
|
+
[dataField]: value,
|
|
31
|
+
}));
|
|
32
|
+
}
|
|
33
|
+
}, []);
|
|
22
34
|
|
|
23
35
|
const onSubmit = useCallback(async (e<%=#isTypeScript%>: React.FormEvent<HTMLFormElement><%=/isTypeScript%>) => {
|
|
24
36
|
e.preventDefault();
|
|
25
|
-
const { email, password } = formData
|
|
37
|
+
const { email, password } = formData;
|
|
26
38
|
setLoading(true);
|
|
27
39
|
|
|
28
40
|
const result = await createAccount(email, password);
|
|
@@ -33,16 +45,16 @@ export default function CreateAccountForm() {
|
|
|
33
45
|
} else {
|
|
34
46
|
notify(result.message, 'error', 2000);
|
|
35
47
|
}
|
|
36
|
-
}, [navigate]);
|
|
48
|
+
}, [navigate, formData]);
|
|
37
49
|
|
|
38
50
|
const confirmPassword = useCallback(
|
|
39
|
-
({ value }<%=#isTypeScript%>: ValidationCallbackData<%=/isTypeScript%>) => value === formData.
|
|
40
|
-
[]
|
|
51
|
+
({ value }<%=#isTypeScript%>: ValidationCallbackData<%=/isTypeScript%>) => value === formData.password,
|
|
52
|
+
[formData]
|
|
41
53
|
);
|
|
42
54
|
|
|
43
55
|
return (
|
|
44
56
|
<form className={'create-account-form'} onSubmit={onSubmit}>
|
|
45
|
-
<Form formData={formData
|
|
57
|
+
<Form formData={formData} disabled={loading} onFieldDataChanged={onFieldDataChanged}>
|
|
46
58
|
<Item
|
|
47
59
|
dataField={'email'}
|
|
48
60
|
editorType={'dxTextBox'}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import <%=#isTypeScript%>React, <%=/isTypeScript%>{ useState,
|
|
1
|
+
import <%=#isTypeScript%>React, <%=/isTypeScript%>{ useState, useCallback } from 'react';
|
|
2
2
|
import { Link, useNavigate } from 'react-router-dom';
|
|
3
3
|
import Form, {
|
|
4
4
|
Item,
|
|
@@ -6,7 +6,8 @@ import Form, {
|
|
|
6
6
|
ButtonItem,
|
|
7
7
|
ButtonOptions,
|
|
8
8
|
RequiredRule,
|
|
9
|
-
EmailRule
|
|
9
|
+
EmailRule,<%=#isTypeScript%>
|
|
10
|
+
type FormTypes,<%=/isTypeScript%>
|
|
10
11
|
} from 'devextreme-react/form';
|
|
11
12
|
import LoadIndicator from 'devextreme-react/load-indicator';
|
|
12
13
|
import Button from 'devextreme-react/button';
|
|
@@ -19,11 +20,22 @@ export default function LoginForm() {
|
|
|
19
20
|
const navigate = useNavigate();
|
|
20
21
|
const { signIn } = useAuth();
|
|
21
22
|
const [loading, setLoading] = useState(false);
|
|
22
|
-
const formData =
|
|
23
|
+
const [formData, setFormData] = useState({ email: '', password: '' });
|
|
24
|
+
|
|
25
|
+
const onFieldDataChanged = useCallback((e<%=#isTypeScript%>: FormTypes.FieldDataChangedEvent<%=/isTypeScript%>) => {
|
|
26
|
+
const { dataField, value } = e;
|
|
27
|
+
|
|
28
|
+
if (dataField) {
|
|
29
|
+
setFormData(formData => ({
|
|
30
|
+
...formData,
|
|
31
|
+
[dataField]: value,
|
|
32
|
+
}));
|
|
33
|
+
}
|
|
34
|
+
}, []);
|
|
23
35
|
|
|
24
36
|
const onSubmit = useCallback(async (e<%=#isTypeScript%>: React.FormEvent<HTMLFormElement><%=/isTypeScript%>) => {
|
|
25
37
|
e.preventDefault();
|
|
26
|
-
const { email, password } = formData
|
|
38
|
+
const { email, password } = formData;
|
|
27
39
|
setLoading(true);
|
|
28
40
|
|
|
29
41
|
const result = await signIn(email, password);
|
|
@@ -31,7 +43,7 @@ export default function LoginForm() {
|
|
|
31
43
|
setLoading(false);
|
|
32
44
|
notify(result.message, 'error', 2000);
|
|
33
45
|
}
|
|
34
|
-
}, [signIn]);
|
|
46
|
+
}, [signIn, formData]);
|
|
35
47
|
|
|
36
48
|
const onCreateAccountClick = useCallback(() => {
|
|
37
49
|
navigate('/create-account');
|
|
@@ -39,7 +51,7 @@ export default function LoginForm() {
|
|
|
39
51
|
|
|
40
52
|
return (
|
|
41
53
|
<form className={'login-form'} onSubmit={onSubmit}>
|
|
42
|
-
<Form formData={formData
|
|
54
|
+
<Form formData={formData} disabled={loading} onFieldDataChanged={onFieldDataChanged}>
|
|
43
55
|
<Item
|
|
44
56
|
dataField={'email'}
|
|
45
57
|
editorType={'dxTextBox'}
|
package/src/templates/react/application/src/components/reset-password-form/ResetPasswordForm.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import <%=#isTypeScript%>React, <%=/isTypeScript%>{ useState,
|
|
1
|
+
import <%=#isTypeScript%>React, <%=/isTypeScript%>{ useState, useCallback } from 'react';
|
|
2
2
|
import { Link, useNavigate } from "react-router-dom";
|
|
3
3
|
import Form, {
|
|
4
4
|
Item,
|
|
@@ -6,7 +6,8 @@ import Form, {
|
|
|
6
6
|
ButtonItem,
|
|
7
7
|
ButtonOptions,
|
|
8
8
|
RequiredRule,
|
|
9
|
-
EmailRule
|
|
9
|
+
EmailRule,<%=#isTypeScript%>
|
|
10
|
+
type FormTypes,<%=/isTypeScript%>
|
|
10
11
|
} from 'devextreme-react/form';
|
|
11
12
|
import LoadIndicator from 'devextreme-react/load-indicator';
|
|
12
13
|
import notify from 'devextreme/ui/notify';
|
|
@@ -18,11 +19,22 @@ const notificationText = 'We\'ve sent a link to reset your password. Check your
|
|
|
18
19
|
export default function ResetPasswordForm() {
|
|
19
20
|
const navigate = useNavigate();
|
|
20
21
|
const [loading, setLoading] = useState(false);
|
|
21
|
-
const formData =
|
|
22
|
+
const [formData, setFormData] = useState({ email: '', password: '' });
|
|
23
|
+
|
|
24
|
+
const onFieldDataChanged = useCallback((e<%=#isTypeScript%>: FormTypes.FieldDataChangedEvent<%=/isTypeScript%>) => {
|
|
25
|
+
const { dataField, value } = e;
|
|
26
|
+
|
|
27
|
+
if (dataField) {
|
|
28
|
+
setFormData(formData => ({
|
|
29
|
+
...formData,
|
|
30
|
+
[dataField]: value,
|
|
31
|
+
}));
|
|
32
|
+
}
|
|
33
|
+
}, []);
|
|
22
34
|
|
|
23
35
|
const onSubmit = useCallback(async (e<%=#isTypeScript%>: React.FormEvent<HTMLFormElement><%=/isTypeScript%>) => {
|
|
24
36
|
e.preventDefault();
|
|
25
|
-
const { email } = formData
|
|
37
|
+
const { email } = formData;
|
|
26
38
|
setLoading(true);
|
|
27
39
|
|
|
28
40
|
const result = await resetPassword(email);
|
|
@@ -34,11 +46,11 @@ export default function ResetPasswordForm() {
|
|
|
34
46
|
} else {
|
|
35
47
|
notify(result.message, 'error', 2000);
|
|
36
48
|
}
|
|
37
|
-
}, [navigate]);
|
|
49
|
+
}, [navigate, formData]);
|
|
38
50
|
|
|
39
51
|
return (
|
|
40
52
|
<form className={'reset-password-form'} onSubmit={onSubmit}>
|
|
41
|
-
<Form formData={formData
|
|
53
|
+
<Form formData={formData} disabled={loading} onFieldDataChanged={onFieldDataChanged}>
|
|
42
54
|
<Item
|
|
43
55
|
dataField={'email'}
|
|
44
56
|
editorType={'dxTextBox'}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
const packageJson = require('../../package.json');
|
|
2
2
|
module.exports = {
|
|
3
|
-
'devextreme': '25.
|
|
4
|
-
'devextreme-react': '25.
|
|
5
|
-
'devextreme-vue': '25.
|
|
6
|
-
'create-vite': '
|
|
3
|
+
'devextreme': '25.2.3',
|
|
4
|
+
'devextreme-react': '25.2.3',
|
|
5
|
+
'devextreme-vue': '25.2.3',
|
|
6
|
+
'create-vite': '8.2.0',
|
|
7
7
|
'create-vue': '3.17.0',
|
|
8
|
-
'create-next-app': '
|
|
9
|
-
'jose': '6.
|
|
8
|
+
'create-next-app': '16.1.0',
|
|
9
|
+
'jose': '6.1.3',
|
|
10
10
|
'devextreme-cli': packageJson.version,
|
|
11
11
|
'devextreme-schematics': 'latest'
|
|
12
12
|
};
|
|
@@ -2,12 +2,12 @@ const semver = require('semver').SemVer;
|
|
|
2
2
|
const execSync = require('child_process').execSync;
|
|
3
3
|
|
|
4
4
|
function parseNgCliVersion(stdout) {
|
|
5
|
-
return
|
|
5
|
+
return stdout.trim();
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
const getLocalNgVersion = () => {
|
|
9
9
|
try {
|
|
10
|
-
const version = parseNgCliVersion(execSync('ng
|
|
10
|
+
const version = parseNgCliVersion(execSync('ng --version').toString());
|
|
11
11
|
return new semver(version);
|
|
12
12
|
} catch(e) {
|
|
13
13
|
return '';
|