add actions
This commit is contained in:
@ -9,3 +9,4 @@ webpack.config.js
|
|||||||
jest.config.js
|
jest.config.js
|
||||||
babel.config.js
|
babel.config.js
|
||||||
/scripts
|
/scripts
|
||||||
|
server.js
|
||||||
266
src/core/blocks/entity-sidebar/EntitySidebar.tsx
Normal file
266
src/core/blocks/entity-sidebar/EntitySidebar.tsx
Normal file
@ -0,0 +1,266 @@
|
|||||||
|
import {Atom} from '@reatom/core';
|
||||||
|
import {useAtom} from '@reatom/react';
|
||||||
|
import {Button, Checkbox as CheckboxInput, Drawer, Input, Select as SelectInput} from 'antd';
|
||||||
|
import {CheckboxChangeEvent} from 'antd/lib/checkbox';
|
||||||
|
import {SelectValue} from 'antd/lib/select';
|
||||||
|
import React, {FC, Fragment, memo, SyntheticEvent, useCallback, useEffect, useMemo} from 'react';
|
||||||
|
import {createUseStyles} from 'react-jss';
|
||||||
|
import {queryParsers} from '../../../pages/users/utils';
|
||||||
|
import {useQuery} from '../../hooks/useQuery';
|
||||||
|
import {CrudService} from '../../services/CrudService';
|
||||||
|
import {EntityMode} from '../../types/EntityModes';
|
||||||
|
|
||||||
|
export enum FormInputType {
|
||||||
|
Text = 'text',
|
||||||
|
Checkbox = 'checkobx',
|
||||||
|
Select = 'select',
|
||||||
|
}
|
||||||
|
|
||||||
|
type SelectOption = {
|
||||||
|
value: string;
|
||||||
|
label: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type FormOption = {
|
||||||
|
name: string;
|
||||||
|
label: string;
|
||||||
|
type?: FormInputType;
|
||||||
|
options?: SelectOption[];
|
||||||
|
checkboxLabel?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type Options<T> = {
|
||||||
|
entityFormAtom: Atom<T>;
|
||||||
|
service: CrudService<T>;
|
||||||
|
formOptions: FormOption[];
|
||||||
|
entityName: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const AVAILABLE_CLOSE_MODES = [EntityMode.Show];
|
||||||
|
const DISABLED_FORM_MODES = [EntityMode.Show];
|
||||||
|
|
||||||
|
const useStyles = createUseStyles({
|
||||||
|
button: {
|
||||||
|
marginRight: '8px',
|
||||||
|
},
|
||||||
|
input: {
|
||||||
|
marginBottom: '16px',
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const createEntitySidebar = function <T> ({
|
||||||
|
entityFormAtom,
|
||||||
|
service,
|
||||||
|
formOptions,
|
||||||
|
entityName,
|
||||||
|
}: Options<T>): FC {
|
||||||
|
return memo(() => {
|
||||||
|
const {mode, id} = useQuery(queryParsers);
|
||||||
|
const form = useAtom(entityFormAtom);
|
||||||
|
const classes = useStyles();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
service.loadEntity(id);
|
||||||
|
}, [id, mode]);
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
service.navigate();
|
||||||
|
};
|
||||||
|
|
||||||
|
const onChangeInput = (event: SyntheticEvent<HTMLInputElement>) => {
|
||||||
|
const {name, value} = event.currentTarget;
|
||||||
|
service.loadEntityForm({
|
||||||
|
...form,
|
||||||
|
[name]: value,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onChangeCheckbox = (event: CheckboxChangeEvent) => {
|
||||||
|
const {name, checked} = event.target;
|
||||||
|
service.loadEntityForm({
|
||||||
|
...form,
|
||||||
|
[name!]: checked,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onChangeSelect = (name: string) => (value: SelectValue) => {
|
||||||
|
if (!Array.isArray(value)) {
|
||||||
|
service.loadEntityForm({
|
||||||
|
...form,
|
||||||
|
[name]: value,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const disabled = useMemo(() => !mode || DISABLED_FORM_MODES.includes(mode), [mode]);
|
||||||
|
|
||||||
|
const handleCreateUser = useCallback(() => {
|
||||||
|
service.createEntity(form);
|
||||||
|
}, [form]);
|
||||||
|
|
||||||
|
const handleSaveUser = useCallback(() => {
|
||||||
|
if (id) {
|
||||||
|
service.updateEntity({
|
||||||
|
...form,
|
||||||
|
id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [form, id]);
|
||||||
|
|
||||||
|
const handleCopy = useCallback(() => {
|
||||||
|
service.navigate(EntityMode.Copy, id);
|
||||||
|
}, [id]);
|
||||||
|
|
||||||
|
const handleEdit = useCallback(() => {
|
||||||
|
service.navigate(EntityMode.Edit, id);
|
||||||
|
}, [id]);
|
||||||
|
|
||||||
|
const handleDelete = useCallback(() => {
|
||||||
|
service.removeEntity(id);
|
||||||
|
}, [id]);
|
||||||
|
|
||||||
|
const handleBackdrop = useCallback(() => {
|
||||||
|
if (mode && AVAILABLE_CLOSE_MODES.includes(mode)) {
|
||||||
|
handleClose();
|
||||||
|
}
|
||||||
|
}, [mode]);
|
||||||
|
|
||||||
|
const title = useMemo(() => {
|
||||||
|
switch (mode) {
|
||||||
|
case EntityMode.Create:
|
||||||
|
return `Creating a ${entityName}`;
|
||||||
|
case EntityMode.Copy:
|
||||||
|
return `Coping ${entityName} "${id}"`;
|
||||||
|
case EntityMode.Edit:
|
||||||
|
return `Editing ${entityName} "${id}"`;
|
||||||
|
case EntityMode.Show:
|
||||||
|
return `Viewing ${entityName} "${id}"`;
|
||||||
|
default:
|
||||||
|
return `Mode "${mode}" not supported for ${entityName} form`;
|
||||||
|
}
|
||||||
|
}, [mode, id]);
|
||||||
|
|
||||||
|
const primaryButton = useMemo(() => {
|
||||||
|
switch (mode) {
|
||||||
|
case EntityMode.Create:
|
||||||
|
case EntityMode.Copy:
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
className={classes.button}
|
||||||
|
onClick={handleCreateUser}
|
||||||
|
type="primary"
|
||||||
|
>
|
||||||
|
Create
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
case EntityMode.Edit:
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
className={classes.button}
|
||||||
|
onClick={handleSaveUser}
|
||||||
|
type="primary"
|
||||||
|
>
|
||||||
|
Save
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
case EntityMode.Show:
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
className={classes.button}
|
||||||
|
onClick={handleEdit}
|
||||||
|
type="primary"
|
||||||
|
>
|
||||||
|
Edit
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}, [mode, classes, handleEdit, handleCreateUser, handleSaveUser]);
|
||||||
|
|
||||||
|
const renderFooter = useMemo(() => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{primaryButton}
|
||||||
|
{mode === EntityMode.Show && (
|
||||||
|
<Fragment>
|
||||||
|
<Button
|
||||||
|
className={classes.button}
|
||||||
|
onClick={handleCopy}
|
||||||
|
>
|
||||||
|
Copy
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
className={classes.button}
|
||||||
|
onClick={handleDelete}
|
||||||
|
>
|
||||||
|
Delete
|
||||||
|
</Button>
|
||||||
|
</Fragment>
|
||||||
|
)}
|
||||||
|
<Button onClick={handleClose}>Cancel</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}, [primaryButton, mode, classes, handleCopy, handleDelete]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Drawer
|
||||||
|
visible={!!mode}
|
||||||
|
closable={false}
|
||||||
|
onClose={handleBackdrop}
|
||||||
|
width="600"
|
||||||
|
title={title}
|
||||||
|
footer={renderFooter}
|
||||||
|
>
|
||||||
|
<form>
|
||||||
|
{formOptions.map(({name, label, type = FormInputType.Text, options, checkboxLabel}) => {
|
||||||
|
return (
|
||||||
|
<div key={name}>
|
||||||
|
<label>{label}:</label>
|
||||||
|
{type === FormInputType.Checkbox && (
|
||||||
|
<CheckboxInput
|
||||||
|
name={name}
|
||||||
|
className={classes.input}
|
||||||
|
disabled={disabled}
|
||||||
|
value={(form as any)[name]}
|
||||||
|
onChange={onChangeCheckbox}
|
||||||
|
type="checkbox"
|
||||||
|
>
|
||||||
|
{checkboxLabel ?? label}
|
||||||
|
</CheckboxInput>
|
||||||
|
)}
|
||||||
|
{type === FormInputType.Select && (
|
||||||
|
<SelectInput
|
||||||
|
className={classes.input}
|
||||||
|
disabled={disabled}
|
||||||
|
value={(form as any)[name]}
|
||||||
|
onChange={onChangeSelect(name)}
|
||||||
|
>
|
||||||
|
{(options ?? []).map(option => (
|
||||||
|
<SelectInput.Option
|
||||||
|
value={option.value}
|
||||||
|
key={option.value}
|
||||||
|
>
|
||||||
|
{option.label}
|
||||||
|
</SelectInput.Option>
|
||||||
|
))}
|
||||||
|
</SelectInput>
|
||||||
|
)}
|
||||||
|
{type === FormInputType.Text && (
|
||||||
|
<Input
|
||||||
|
name={name}
|
||||||
|
className={classes.input}
|
||||||
|
disabled={disabled}
|
||||||
|
value={(form as any)[name]}
|
||||||
|
onChange={onChangeInput}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</form>
|
||||||
|
</Drawer>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
};
|
||||||
1
src/core/blocks/entity-sidebar/index.ts
Normal file
1
src/core/blocks/entity-sidebar/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './EntitySidebar';
|
||||||
@ -7,15 +7,15 @@ import {CrudService} from '../../services/CrudService';
|
|||||||
import {EntityMode} from '../../types/EntityModes';
|
import {EntityMode} from '../../types/EntityModes';
|
||||||
import {EntityWithId} from '../../api/CrudAPI';
|
import {EntityWithId} from '../../api/CrudAPI';
|
||||||
|
|
||||||
type Props<T> = {
|
type Options<T> = {
|
||||||
entityListAtom: Atom<T[]>;
|
entityListAtom: Atom<T[]>;
|
||||||
service: CrudService<T>;
|
service: CrudService<T>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const createEntityTable = function <T extends EntityWithId<unknown>> ({
|
export const createEntityTable = function <T> ({
|
||||||
entityListAtom,
|
entityListAtom,
|
||||||
service,
|
service,
|
||||||
}: Props<T>): FC {
|
}: Options<T>): FC {
|
||||||
return memo(() => {
|
return memo(() => {
|
||||||
const entityList = useAtom(entityListAtom);
|
const entityList = useAtom(entityListAtom);
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ export const createEntityTable = function <T extends EntityWithId<unknown>> ({
|
|||||||
}, [entityList]);
|
}, [entityList]);
|
||||||
|
|
||||||
const dataSource = useMemo(() => {
|
const dataSource = useMemo(() => {
|
||||||
return entityList.map(entity => {
|
return entityList.map((entity: any) => {
|
||||||
return {
|
return {
|
||||||
...entity,
|
...entity,
|
||||||
key: entity.id,
|
key: entity.id,
|
||||||
|
|||||||
@ -7,11 +7,13 @@ export const ROUTES = {
|
|||||||
CURRENCIES: '/currencies',
|
CURRENCIES: '/currencies',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const PROTOCOL = location.protocol;
|
||||||
|
|
||||||
export const ENDPOINT = {
|
export const ENDPOINT = {
|
||||||
AUTH: 'https://localhost:3189/api/auth',
|
AUTH: `${PROTOCOL}//localhost:3189/api/auth`,
|
||||||
USERS: 'https://localhost:3189/api/users',
|
USERS: `${PROTOCOL}//localhost:3189/api/users`,
|
||||||
ACTIONS: 'https://localhost:3189/api/bot/actions',
|
ACTIONS: `${PROTOCOL}//localhost:3189/api/bot/actions`,
|
||||||
CONDITIONS: 'https://localhost:3189/api/bot/conditions',
|
CONDITIONS: `${PROTOCOL}//localhost:3189/api/bot/conditions`,
|
||||||
GRAPHS: 'https://localhost:3189/api/bot/graphs',
|
GRAPHS: `${PROTOCOL}//localhost:3189/api/bot/graphs`,
|
||||||
CURRENCIES: 'https://localhost:3189/api/bot/currencies',
|
CURRENCIES: `${PROTOCOL}//localhost:3189/api/bot/currencies`,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
import {declareAction, declareAtom} from '@reatom/core';
|
import {declareAction, declareAtom} from '@reatom/core';
|
||||||
import {EntityWithId} from '../../api/CrudAPI';
|
|
||||||
import {store} from './store';
|
import {store} from './store';
|
||||||
|
|
||||||
export const createEntityAtoms = <T>(initEntity: T) => {
|
export const createEntityAtoms = <T>(initEntity: T) => {
|
||||||
const INIT_ENTITY_LIST: EntityWithId<T>[] = [];
|
const INIT_ENTITY_LIST: T[] = [];
|
||||||
|
|
||||||
const loadEntityList = declareAction<typeof INIT_ENTITY_LIST>();
|
const loadEntityList = declareAction<typeof INIT_ENTITY_LIST>();
|
||||||
const loadEntityForm = declareAction<T>();
|
const loadEntityForm = declareAction<T>();
|
||||||
|
|||||||
@ -20,6 +20,10 @@ export class CrudService<T> {
|
|||||||
this.route = route;
|
this.route = route;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loadEntityForm(form: T) {
|
||||||
|
this.actions.loadEntityForm(form);
|
||||||
|
}
|
||||||
|
|
||||||
loadEntityList() {
|
loadEntityList() {
|
||||||
return this.api
|
return this.api
|
||||||
.request()
|
.request()
|
||||||
|
|||||||
@ -1,4 +0,0 @@
|
|||||||
import {ENDPOINT} from '_consts/common';
|
|
||||||
import {CrudAPI} from '../../../core/api/CrudAPI';
|
|
||||||
|
|
||||||
export const actionsAPI = new CrudAPI(ENDPOINT.ACTIONS);
|
|
||||||
@ -1,11 +1,74 @@
|
|||||||
|
import {Button, Layout} from 'antd';
|
||||||
|
import moment from 'moment';
|
||||||
import React, {FC, memo} from 'react';
|
import React, {FC, memo} from 'react';
|
||||||
import {actionsAPI} from '../../api/ActionsAPI';
|
import {createUseStyles} from 'react-jss';
|
||||||
|
import {createEntityAtoms} from '_infrastructure/atom/createEntityAtoms';
|
||||||
|
import {createEntitySidebar, FormInputType} from '../../../../core/blocks/entity-sidebar';
|
||||||
|
import {createEntityTable} from '../../../../core/blocks/entity-table';
|
||||||
|
import {ENDPOINT, ROUTES} from '../../../../core/consts/common';
|
||||||
|
import {CrudService} from '../../../../core/services/CrudService';
|
||||||
|
import {EntityMode} from '../../../../core/types/EntityModes';
|
||||||
|
import {ActionModel} from '../../types';
|
||||||
|
|
||||||
actionsAPI.request();
|
const {entityListAtom, entityFormAtom, bindedActions} = createEntityAtoms<ActionModel>({
|
||||||
|
createAt: moment().toISOString(),
|
||||||
|
closedAt: moment().toISOString(),
|
||||||
|
type: '',
|
||||||
|
login: '',
|
||||||
|
isExperiment: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const service = new CrudService<ActionModel>(ROUTES.ACTIONS, ENDPOINT.ACTIONS, bindedActions);
|
||||||
|
|
||||||
|
const TYPE_SELECT_OPTIONS = [
|
||||||
|
{value: 'up', label: 'Up'},
|
||||||
|
{value: 'down', label: 'Down'},
|
||||||
|
];
|
||||||
|
|
||||||
|
const formOptions = [
|
||||||
|
{name: 'createAt', label: 'Create at'},
|
||||||
|
{name: 'closedAt', label: 'Close at'},
|
||||||
|
{name: 'type', label: 'Type', type: FormInputType.Select, options: TYPE_SELECT_OPTIONS},
|
||||||
|
{name: 'login', label: 'Login'},
|
||||||
|
{name: 'isExperiment', label: 'Is experiment', type: FormInputType.Checkbox, checkboxLabel: 'Enabled experiment'},
|
||||||
|
];
|
||||||
|
|
||||||
|
const EntityTable = createEntityTable({entityListAtom, service});
|
||||||
|
const EntitySidebar = createEntitySidebar({
|
||||||
|
entityFormAtom,
|
||||||
|
service,
|
||||||
|
formOptions,
|
||||||
|
entityName: 'Action'
|
||||||
|
});
|
||||||
|
|
||||||
|
const useStyles = createUseStyles({
|
||||||
|
header: {
|
||||||
|
backgroundColor: '#fff',
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleClickNewEntity = () => {
|
||||||
|
service.navigate(EntityMode.Create);
|
||||||
|
};
|
||||||
|
|
||||||
const Page: FC = () => {
|
const Page: FC = () => {
|
||||||
|
const classes = useStyles();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>actions</div>
|
<Layout>
|
||||||
|
<Layout.Header className={classes.header}>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
onClick={handleClickNewEntity}
|
||||||
|
>
|
||||||
|
New action
|
||||||
|
</Button>
|
||||||
|
</Layout.Header>
|
||||||
|
<Layout.Content>
|
||||||
|
<EntityTable />
|
||||||
|
<EntitySidebar />
|
||||||
|
</Layout.Content>
|
||||||
|
</Layout>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
7
src/pages/actions/types.ts
Normal file
7
src/pages/actions/types.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
export type ActionModel = {
|
||||||
|
createAt: string;
|
||||||
|
closedAt: string;
|
||||||
|
type: string;
|
||||||
|
login: string;
|
||||||
|
isExperiment: boolean;
|
||||||
|
};
|
||||||
@ -1,8 +1,55 @@
|
|||||||
|
import {Button, Layout} from 'antd';
|
||||||
import React, {FC, memo} from 'react';
|
import React, {FC, memo} from 'react';
|
||||||
|
import {createUseStyles} from 'react-jss';
|
||||||
|
import {createEntitySidebar} from '../../../../core/blocks/entity-sidebar';
|
||||||
|
import {createEntityTable} from '../../../../core/blocks/entity-table';
|
||||||
|
import {ENDPOINT, ROUTES} from '../../../../core/consts/common';
|
||||||
|
import {createEntityAtoms} from '../../../../core/infrastructure/atom/createEntityAtoms';
|
||||||
|
import {CrudService} from '../../../../core/services/CrudService';
|
||||||
|
import {EntityMode} from '../../../../core/types/EntityModes';
|
||||||
|
import {CurrencyModel} from '../../types';
|
||||||
|
|
||||||
|
const {entityListAtom, entityFormAtom, bindedActions} = createEntityAtoms<CurrencyModel>({
|
||||||
|
name: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
const service = new CrudService<CurrencyModel>(ROUTES.GRAPHS, ENDPOINT.GRAPHS, bindedActions);
|
||||||
|
|
||||||
|
const formOptions = [
|
||||||
|
{name: 'name', label: 'Name'},
|
||||||
|
];
|
||||||
|
|
||||||
|
const EntityTable = createEntityTable({entityListAtom, service});
|
||||||
|
const EntitySidebar = createEntitySidebar({entityFormAtom, service, formOptions, entityName: 'Currency'});
|
||||||
|
|
||||||
|
const useStyles = createUseStyles({
|
||||||
|
header: {
|
||||||
|
backgroundColor: '#fff',
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleClickNewEntity = () => {
|
||||||
|
service.navigate(EntityMode.Create);
|
||||||
|
};
|
||||||
|
|
||||||
const Page: FC = () => {
|
const Page: FC = () => {
|
||||||
|
const classes = useStyles();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>conditions</div>
|
<Layout>
|
||||||
|
<Layout.Header className={classes.header}>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
onClick={handleClickNewEntity}
|
||||||
|
>
|
||||||
|
New currency
|
||||||
|
</Button>
|
||||||
|
</Layout.Header>
|
||||||
|
<Layout.Content>
|
||||||
|
<EntityTable />
|
||||||
|
<EntitySidebar />
|
||||||
|
</Layout.Content>
|
||||||
|
</Layout>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
3
src/pages/conditions/types.ts
Normal file
3
src/pages/conditions/types.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export type CurrencyModel = {
|
||||||
|
name: string;
|
||||||
|
};
|
||||||
@ -1,8 +1,55 @@
|
|||||||
|
import {Button, Layout} from 'antd';
|
||||||
import React, {FC, memo} from 'react';
|
import React, {FC, memo} from 'react';
|
||||||
|
import {createUseStyles} from 'react-jss';
|
||||||
|
import {createEntitySidebar} from '../../../../core/blocks/entity-sidebar';
|
||||||
|
import {createEntityTable} from '../../../../core/blocks/entity-table';
|
||||||
|
import {ENDPOINT, ROUTES} from '../../../../core/consts/common';
|
||||||
|
import {createEntityAtoms} from '../../../../core/infrastructure/atom/createEntityAtoms';
|
||||||
|
import {CrudService} from '../../../../core/services/CrudService';
|
||||||
|
import {EntityMode} from '../../../../core/types/EntityModes';
|
||||||
|
import {CurrencyModel} from '../../types';
|
||||||
|
|
||||||
|
const {entityListAtom, entityFormAtom, bindedActions} = createEntityAtoms<CurrencyModel>({
|
||||||
|
name: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
const service = new CrudService<CurrencyModel>(ROUTES.CURRENCIES, ENDPOINT.CURRENCIES, bindedActions);
|
||||||
|
|
||||||
|
const formOptions = [
|
||||||
|
{name: 'name', label: 'Name'},
|
||||||
|
];
|
||||||
|
|
||||||
|
const EntityTable = createEntityTable({entityListAtom, service});
|
||||||
|
const EntitySidebar = createEntitySidebar({entityFormAtom, service, formOptions, entityName: 'Currency'});
|
||||||
|
|
||||||
|
const useStyles = createUseStyles({
|
||||||
|
header: {
|
||||||
|
backgroundColor: '#fff',
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleClickNewEntity = () => {
|
||||||
|
service.navigate(EntityMode.Create);
|
||||||
|
};
|
||||||
|
|
||||||
const Page: FC = () => {
|
const Page: FC = () => {
|
||||||
|
const classes = useStyles();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>currencies</div>
|
<Layout>
|
||||||
|
<Layout.Header className={classes.header}>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
onClick={handleClickNewEntity}
|
||||||
|
>
|
||||||
|
New currency
|
||||||
|
</Button>
|
||||||
|
</Layout.Header>
|
||||||
|
<Layout.Content>
|
||||||
|
<EntityTable />
|
||||||
|
<EntitySidebar />
|
||||||
|
</Layout.Content>
|
||||||
|
</Layout>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
5
src/pages/currencies/types.ts
Normal file
5
src/pages/currencies/types.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
type Currency = {
|
||||||
|
name: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type CurrencyModel = Record<keyof Currency, string>;
|
||||||
@ -1,6 +1,7 @@
|
|||||||
import {Button, Layout} from 'antd';
|
import {Button, Layout} from 'antd';
|
||||||
import React, {FC, memo} from 'react';
|
import React, {FC, memo} from 'react';
|
||||||
import {createUseStyles} from 'react-jss';
|
import {createUseStyles} from 'react-jss';
|
||||||
|
import {createEntitySidebar} from '../../../../core/blocks/entity-sidebar';
|
||||||
import {createEntityTable} from '../../../../core/blocks/entity-table';
|
import {createEntityTable} from '../../../../core/blocks/entity-table';
|
||||||
import {ENDPOINT, ROUTES} from '../../../../core/consts/common';
|
import {ENDPOINT, ROUTES} from '../../../../core/consts/common';
|
||||||
import {createEntityAtoms} from '../../../../core/infrastructure/atom/createEntityAtoms';
|
import {createEntityAtoms} from '../../../../core/infrastructure/atom/createEntityAtoms';
|
||||||
@ -8,16 +9,24 @@ import {CrudService} from '../../../../core/services/CrudService';
|
|||||||
import {EntityMode} from '../../../../core/types/EntityModes';
|
import {EntityMode} from '../../../../core/types/EntityModes';
|
||||||
import {GraphModel} from '../../types';
|
import {GraphModel} from '../../types';
|
||||||
|
|
||||||
const {entityListAtom, bindedActions} = createEntityAtoms<GraphModel>({
|
const {entityListAtom, entityFormAtom, bindedActions} = createEntityAtoms<GraphModel>({
|
||||||
type: '',
|
type: '',
|
||||||
graphName: '',
|
graphName: '',
|
||||||
from: '',
|
from: '',
|
||||||
to: '',
|
to: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
const service = new CrudService(ROUTES.GRAPHS, ENDPOINT.GRAPHS, bindedActions);
|
const service = new CrudService<GraphModel>(ROUTES.GRAPHS, ENDPOINT.GRAPHS, bindedActions);
|
||||||
|
|
||||||
|
const formOptions = [
|
||||||
|
{name: 'type', label: 'Type'},
|
||||||
|
{name: 'graphName', label: 'Graph name'},
|
||||||
|
{name: 'from', label: 'From'},
|
||||||
|
{name: 'to', label: 'To'},
|
||||||
|
];
|
||||||
|
|
||||||
const EntityTable = createEntityTable({entityListAtom, service});
|
const EntityTable = createEntityTable({entityListAtom, service});
|
||||||
|
const EntitySidebar = createEntitySidebar({entityFormAtom, service, formOptions, entityName: 'Graph'});
|
||||||
|
|
||||||
const useStyles = createUseStyles({
|
const useStyles = createUseStyles({
|
||||||
header: {
|
header: {
|
||||||
@ -44,6 +53,7 @@ const Page: FC = () => {
|
|||||||
</Layout.Header>
|
</Layout.Header>
|
||||||
<Layout.Content>
|
<Layout.Content>
|
||||||
<EntityTable />
|
<EntityTable />
|
||||||
|
<EntitySidebar />
|
||||||
</Layout.Content>
|
</Layout.Content>
|
||||||
</Layout>
|
</Layout>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -26,7 +26,6 @@ module.exports = {
|
|||||||
compress: true,
|
compress: true,
|
||||||
open: true,
|
open: true,
|
||||||
port: 3189,
|
port: 3189,
|
||||||
http2: true,
|
|
||||||
proxy: {
|
proxy: {
|
||||||
'/api/users': {
|
'/api/users': {
|
||||||
target: 'http://vigdorov.ru:3011',
|
target: 'http://vigdorov.ru:3011',
|
||||||
|
|||||||
Reference in New Issue
Block a user