Частичная реализация (front)

This commit is contained in:
Katerina881 2023-03-21 11:36:54 +04:00
parent 19473c157c
commit ab6afea43b
7 changed files with 240 additions and 0 deletions

View File

@ -0,0 +1,52 @@
import Button from 'react-bootstrap/Button';
import Table from "../commons/Table.jsx";
import { useState} from 'react';
import styles from './Catalog.module.css';
import ModalForm from '../commons/ModalForm.jsx';
import { Container } from 'react-bootstrap';
// это абстрактный компонент для всех справочников
export default function Catalog(props) {
const [show, setShow] = useState(false);
const [modalTitle, setModalTitle] = useState("");
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
function handleAdd() {
setModalTitle("Добавление");
props.onBtnAdd();
handleShow();
}
function handleEdit(itemId) {
setModalTitle("Редактирование");
props.onEdit(itemId);
handleShow();
}
function handleRemove(item) {
props.onDelete(item);
}
function changeData(event) {
props.onFormChanged(event);
}
return <>
<div className={`${styles.catalogName}`}>{props.name}</div>
<Button variant="success" onClick={handleAdd}>Добавить</Button>
<Table
headers={props.headers}
items={props.items}
onEdit={handleEdit}
onDelete={handleRemove}
/>
<ModalForm
show={show}
onClose={handleClose}
modalTitle={modalTitle}
// onSubmit={submitForm}
onChange={changeData}
form={props.form}
/></>
}

View File

@ -0,0 +1,101 @@
import Employee from "../models/Employee";
export default function Employees(props) {
const headers = [
{name: 'surname', label: "Фамилия"},
{name: 'name', label: "Имя"},
{name: 'phoneNumber', label: "Номер телефона"},
];
const nameCatalog = "Сотрудники";
const [items, setItems] = useState([]);
const url = 'employee/';
const [data, setData] = useState(new Employee());
useEffect(() => {
loadItems();
}, []);
function loadItems() {
DataService.readAll(url, (data) => new Employee(data))
.then(data => setItems(data));
}
function handleAdd() {
DataService.create(url, data).then(() => loadItems());
}
function handleEdit(editedId) {
DataService.read(url + editedId, (e) => new Employee(e))
.then(data => {
setData(new Employee(data));
});
}
function handleEditIsDone() {
DataService.update(url + data.id, data).then(() => loadItems());
}
function handleDelete(item) {
if (window.confirm('Удалить выбранный элемент?')) {
const promises = [];
promises.push(DataService.delete(url + item));
Promise.all(promises).then(() => {
loadItems();
});
}
}
// при каждом изменении поля формы происходит вызов этого метода, обновляя данные объекта
function handleFormChange(event) {
setData({ ...data, [event.target.id]: event.target.value });
}
// определяет действия формы по нажатию Отправить
function submitForm() {
if (!isEditing) {
// если добавление элемента
handleAdd();
} else {
// если редактирование элемента;
handleEditIsDone();
setEditing(false);
}
}
// вызывается при закрытии модального окна или по нажатию кнопки Добавить и очищает данные объекта
function reset() {
console.log("Очистка формыыы");
setData(new Employee());
setEditing(false);
}
// для каждого типа сущности своя форма,
// которая передается дальше в абстрактный компонент Catalog в качестве props.form
const form = <Form onSubmit={submitForm}>
<Form.Group className="mb-3" controlId="name">
<Form.Label>Фамилия</Form.Label>
<Form.Control value={data.surname} type="input" placeholder="Enter text" onChange={handleFormChange} required/>
<Form.Label>Имя</Form.Label>
<Form.Control value={data.name} type="input" placeholder="Enter text" onChange={handleFormChange} required/>
<Form.Label>Номер телефона</Form.Label>
<Form.Control value={data.phoneNumber} type="input" placeholder="Enter text" onChange={handleFormChange} required/>
</Form.Group>
<Button variant="primary" type="submit">
Отправить
</Button>
</Form>
return <div className="container-lg pt-5 min-vh-100">
<Catalog name={nameCatalog}
headers={headers}
items={items}
onAdd={handleAdd}
onEdit={handleEdit}
onDelete={handleDelete}
onClose={reset}
onBtnAdd={reset}
form={form}>
</Catalog>
</div>
}

View File

View File

@ -0,0 +1,25 @@
import { NavLink } from 'react-router-dom';
import Container from 'react-bootstrap/Container';
import Nav from 'react-bootstrap/Nav';
import Navbar from 'react-bootstrap/Navbar';
export default function Header(props) {
return (
<Navbar collapseOnSelect expand="lg" bg="dark" variant="dark">
<Container className='lg justify-content-center'>
<Navbar.Toggle aria-controls="responsive-navbar-nav" />
<Navbar.Collapse id="responsive-navbar-nav">
<Nav className="me-auto">
{
props.links.map(route =>
<NavLink key={route.path} className="nav-link" to={route.path}>
<div>{route.label}</div>
</NavLink>
)
}
</Nav>
</Navbar.Collapse>
</Container>
</Navbar>
);
}

View File

@ -0,0 +1,18 @@
import Button from 'react-bootstrap/Button';
export default function ItemTable(props) {
function edit() {
props.onEdit(props.item.id);
}
function remove() {
props.onDelete(props.item.id);
}
return <tr key={props.item.id}>
{
props.headers.map((header) => <td key={`${header.name}_${props.item.id}`}>{props.item[header.name]}</td>)
}
{props.isOnlyView || <td key={`controls_${props.item.id}`}>
<Button variant="info" onClick={edit}>Редактировать</Button>
<Button variant="danger" onClick={remove}>Удалить</Button></td>}
</tr>
}

View File

@ -0,0 +1,36 @@
import ItemTable from './ItemTable';
import styles from './Table.module.css';
export default function Table(props) {
function edit(itemId) {
props.onEdit(itemId)
}
function remove(itemId) {
props.onDelete(itemId);
}
console.log(props.items);
return <div className={`${styles.wrapper}`}>
<table className={`table table-hover ${styles.table}`}>
<thead>
<tr>
{
props.headers.map((header) => <th key={header.name}>{header.label}</th>)
}
{props.isOnlyView || <th key='controls'>Элементы управления</th>}
</tr>
</thead>
<tbody>
{
props.items.map((item, index) =>
<ItemTable
key={index}
headers={props.headers}
item={item}
onDelete={remove}
onEdit={edit}
isOnlyView={props.isOnlyView}/>)
}
</tbody>
</table>
</div>
}

View File

@ -0,0 +1,8 @@
export default class Employee {
constructor(data) {
this.id = data?.id;
this.surname = data?.surname || '';
this.name = data?.name || '';
this.phoneNumber = data?.phoneNumber || '';
}
}