Skip to content

Commit 1298e69

Browse files
authored
Merge pull request #8833 from marmelab/create-admin-app
Add create-react-admin
2 parents bb9c53c + 146d444 commit 1298e69

41 files changed

Lines changed: 1584 additions & 3 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Makefile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,11 @@ build-data-generator:
112112
@echo "Transpiling data-generator files...";
113113
@cd ./examples/data-generator && yarn build
114114

115-
build: build-ra-core build-ra-ui-materialui build-ra-data-fakerest build-ra-data-json-server build-ra-data-localforage build-ra-data-localstorage build-ra-data-simple-rest build-ra-data-graphql build-ra-data-graphql-simple build-ra-i18n-polyglot build-ra-input-rich-text build-data-generator build-ra-language-english build-ra-language-french build-react-admin build-ra-no-code ## compile ES6 files to JS
115+
build-create-react-admin:
116+
@echo "Transpiling create-react-admin files...";
117+
@cd ./packages/create-react-admin && yarn build
118+
119+
build: build-ra-core build-ra-ui-materialui build-ra-data-fakerest build-ra-data-json-server build-ra-data-localforage build-ra-data-localstorage build-ra-data-simple-rest build-ra-data-graphql build-ra-data-graphql-simple build-ra-i18n-polyglot build-ra-input-rich-text build-data-generator build-ra-language-english build-ra-language-french build-react-admin build-ra-no-code build-create-react-admin ## compile ES6 files to JS
116120

117121
doc: ## compile doc as html and launch doc web server
118122
@yarn doc
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# create-react-admin
2+
3+
A CLI to bootstrap a new react-admin application.
4+
5+
## Usage
6+
7+
```sh
8+
npm create react-admin@latest my-app
9+
# or
10+
yarn create react-admin my-app
11+
```
12+
13+
You'll be asked to choose a data provider (optional), an auth provider (optional). You may also setup the resources you want initially.
14+
15+
## Development
16+
17+
Build the project with the following command at the monorepo root:
18+
19+
```sh
20+
make build-create-react-admin
21+
```
22+
23+
In another directory, run:
24+
25+
```sh
26+
./react-admin/node_modules/.bin/create-react-admin my-admin
27+
```
28+
29+
The above command assume you cloned react-admin in the `react-admin` directory and you are running the command in this directory parent.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"name": "create-react-admin",
3+
"description": "A CLI to quickly start a new react-admin project",
4+
"version": "0.0.1",
5+
"license": "MIT",
6+
"bin": "lib/cli.js",
7+
"authors": [
8+
"Gildas Garcia"
9+
],
10+
"engines": {
11+
"node": ">=16"
12+
},
13+
"scripts": {
14+
"build": "tsc",
15+
"test": "prettier --check . && xo && ava"
16+
},
17+
"files": [
18+
"dist"
19+
],
20+
"dependencies": {
21+
"execa": "^5.1.1",
22+
"fs-extra": "^11.1.1",
23+
"ink": "^3.2.0",
24+
"ink-select-input": "^4.2.2",
25+
"ink-text-input": "^4.0.3",
26+
"meow": "^9.0.0",
27+
"react": "^17.0.0",
28+
"yn": "^5.0.0"
29+
},
30+
"devDependencies": {
31+
"@types/react": ">=17.0.0",
32+
"typescript": "^4.4.0"
33+
}
34+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
export type ProjectConfiguration = {
2+
name: string;
3+
step:
4+
| 'name'
5+
| 'data-provider'
6+
| 'auth-provider'
7+
| 'resources'
8+
| 'generate'
9+
| 'install'
10+
| 'run-install'
11+
| 'finish';
12+
dataProvider: string;
13+
authProvider: string;
14+
resources: string[];
15+
installer: string;
16+
};
17+
18+
export const InitialProjectConfiguration: ProjectConfiguration = {
19+
name: '',
20+
step: 'name',
21+
dataProvider: '',
22+
authProvider: '',
23+
resources: [],
24+
installer: '',
25+
};
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import * as React from 'react';
2+
import { Text } from 'ink';
3+
import { Stack } from './Stack.js';
4+
5+
export type ChoiceType = {
6+
label: string;
7+
value: string;
8+
description?: string;
9+
};
10+
11+
export const SelectInputChoice = ({
12+
isSelected = false,
13+
label,
14+
description,
15+
}: {
16+
isSelected: boolean;
17+
label: string;
18+
description: string;
19+
}) => {
20+
return (
21+
<Stack>
22+
<Text bold={isSelected ? true : false}>{label}</Text>
23+
<Text italic>{description}</Text>
24+
</Stack>
25+
);
26+
};
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import * as React from 'react';
2+
import { ReactNode } from 'react';
3+
import { Box, BoxProps } from 'ink';
4+
5+
export const Stack = (props: { children: ReactNode } & BoxProps) => {
6+
return <Box flexDirection="column" marginBottom={1} {...props} />;
7+
};
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import * as React from 'react';
2+
import { Text } from 'ink';
3+
import SelectInput from 'ink-select-input';
4+
import { ChoiceType, SelectInputChoice } from './SelectInputChoice.js';
5+
import { Stack } from './Stack.js';
6+
7+
const SupportedAuthProviders: ChoiceType[] = [
8+
{
9+
label: 'Hard coded local username/password',
10+
value: 'local-auth-provider',
11+
description: 'Hard coded local username/password',
12+
},
13+
{ label: 'None', value: 'none', description: 'No authProvider' },
14+
];
15+
16+
export const StepAuthProvider = ({
17+
onSubmit,
18+
}: {
19+
onSubmit: (value: string) => void;
20+
}) => {
21+
const handleSelect = (item: ChoiceType) => {
22+
onSubmit(item.value);
23+
};
24+
25+
return (
26+
<Stack>
27+
<Text>
28+
Select the auth provider you want to use, and validate with
29+
Enter:
30+
</Text>
31+
<SelectInput
32+
items={SupportedAuthProviders}
33+
itemComponent={SelectInputChoice}
34+
onSelect={handleSelect}
35+
initialIndex={0}
36+
/>
37+
</Stack>
38+
);
39+
};
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import * as React from 'react';
2+
import { Text } from 'ink';
3+
import SelectInput from 'ink-select-input';
4+
import { ChoiceType, SelectInputChoice } from './SelectInputChoice.js';
5+
import { Stack } from './Stack.js';
6+
7+
const SupportedDataProviders: ChoiceType[] = [
8+
{
9+
label: 'Fakerest',
10+
value: 'ra-data-fakerest',
11+
description:
12+
'A client-side, in-memory data provider that use a JSON object as its initial data.',
13+
},
14+
{
15+
label: 'JSON Server',
16+
value: 'ra-data-json-server',
17+
description:
18+
'A data provider based on the JSON Server API (https://github.com/typicode/json-server)',
19+
},
20+
{
21+
label: 'Simple REST',
22+
value: 'ra-data-simple-rest',
23+
description:
24+
'A Simple REST data provider (https://github.com/marmelab/react-admin/tree/master/packages/ra-data-simple-rest)',
25+
},
26+
{
27+
label: 'None',
28+
value: 'none',
29+
description: "I'll configure the data provider myself.",
30+
},
31+
];
32+
33+
export const StepDataProvider = ({
34+
onSubmit,
35+
}: {
36+
onSubmit: (value: string) => void;
37+
}) => {
38+
const handleSelect = (item: ChoiceType) => {
39+
onSubmit(item.value);
40+
};
41+
42+
return (
43+
<Stack>
44+
<Text>
45+
Select the data provider you want to use, and validate with
46+
Enter:
47+
</Text>
48+
<SelectInput<string>
49+
items={SupportedDataProviders}
50+
itemComponent={SelectInputChoice}
51+
onSelect={handleSelect}
52+
initialIndex={0}
53+
/>
54+
</Stack>
55+
);
56+
};
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import * as React from 'react';
2+
import SelectInput from 'ink-select-input';
3+
import { ChoiceType, SelectInputChoice } from './SelectInputChoice.js';
4+
import { Text } from 'ink';
5+
import { Stack } from './Stack.js';
6+
7+
const choices: ChoiceType[] = [
8+
{
9+
label: 'Using npm',
10+
value: 'npm',
11+
},
12+
{
13+
label: 'Using yarn',
14+
value: 'yarn',
15+
},
16+
{
17+
label: "Don't install dependencies, I'll do it myself.",
18+
value: '',
19+
},
20+
];
21+
22+
export const StepInstall = ({
23+
onSubmit,
24+
}: {
25+
onSubmit: (value: string) => void;
26+
}) => {
27+
const handleSelect = (item: ChoiceType) => {
28+
onSubmit(item.value);
29+
};
30+
return (
31+
<Stack>
32+
<Text>How do you want to install the dependencies?</Text>
33+
<SelectInput<string>
34+
items={choices}
35+
itemComponent={SelectInputChoice}
36+
onSelect={handleSelect}
37+
initialIndex={0}
38+
/>
39+
</Stack>
40+
);
41+
};
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import * as React from 'react';
2+
import { useState } from 'react';
3+
import TextInput from 'ink-text-input';
4+
import { Text } from 'ink';
5+
import { Stack } from './Stack.js';
6+
7+
export const StepName = ({
8+
onSubmit,
9+
initialValue,
10+
}: {
11+
initialValue: string;
12+
onSubmit: (value: string) => void;
13+
}) => {
14+
const [value, setValue] = useState(initialValue || '');
15+
16+
const handleSubmit = (value: string) => {
17+
if (value !== '') {
18+
onSubmit(value);
19+
}
20+
};
21+
return (
22+
<Stack>
23+
<Text>
24+
Enter the name of your application, and validate with Enter:
25+
</Text>
26+
<TextInput
27+
value={value}
28+
onChange={v => setValue(v)}
29+
onSubmit={handleSubmit}
30+
/>
31+
</Stack>
32+
);
33+
};

0 commit comments

Comments
 (0)