forked from CITKParus/P8-Panels
		
	
		
			
				
	
	
		
			183 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			183 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /*
 | |
|     Парус 8 - Панели мониторинга - УДП - Доски задач
 | |
|     Компонент: Карточка статуса событий
 | |
| */
 | |
| 
 | |
| //---------------------
 | |
| //Подключение библиотек
 | |
| //---------------------
 | |
| 
 | |
| import React, { useState } from "react"; //Классы React
 | |
| import PropTypes from "prop-types"; //Контроль свойств компонента
 | |
| import { Card, CardHeader, CardContent, Button, IconButton, Icon, Typography, Stack } from "@mui/material"; //Интерфейсные компоненты
 | |
| import { TaskCard } from "./task_card.js"; //Компонент Карточка события
 | |
| import { StatusCardSettings } from "./status_card_settings.js"; //Компонент Диалог настройки карточки событий
 | |
| import { APP_STYLES } from "../../../../app.styles"; //Типовые стили
 | |
| import { COLORS } from "../layouts.js"; //Цвета статусов
 | |
| import { APP_BAR_HEIGHT } from "../../../components/p8p_app_workspace"; //Заголовок страницы
 | |
| 
 | |
| //---------
 | |
| //Константы
 | |
| //---------
 | |
| 
 | |
| //Нижний отступ заголовка
 | |
| const TITLE_PADDING_BOTTOM = "16px";
 | |
| 
 | |
| //Высота фильтра
 | |
| const FILTER_HEIGHT = "56px";
 | |
| 
 | |
| //Стили
 | |
| const STYLES = {
 | |
|     STATUS_BLOCK: statusColor => {
 | |
|         return {
 | |
|             width: "350px",
 | |
|             height: `calc(100vh - ${APP_BAR_HEIGHT} - ${TITLE_PADDING_BOTTOM} - ${FILTER_HEIGHT} - 8px)`,
 | |
|             backgroundColor: statusColor,
 | |
|             padding: "8px"
 | |
|         };
 | |
|     },
 | |
|     BLOCK_OPACITY: isAvailable => {
 | |
|         return isAvailable ? { opacity: 1 } : { opacity: 0.5 };
 | |
|     },
 | |
|     CARD_HEADER_TITLE: {
 | |
|         textAlign: "left",
 | |
|         textOverflow: "ellipsis",
 | |
|         overflow: "hidden",
 | |
|         display: "-webkit-box",
 | |
|         hyphens: "auto",
 | |
|         WebkitBoxOrient: "vertical",
 | |
|         WebkitLineClamp: 1,
 | |
|         maxWidth: "calc(300px)",
 | |
|         width: "-webkit-fill-available",
 | |
|         fontSize: "1.2rem",
 | |
|         cursor: "default"
 | |
|     },
 | |
|     CARD_HEADER: { padding: 0 },
 | |
|     CARD_CONTENT: {
 | |
|         padding: 0,
 | |
|         paddingRight: "5px",
 | |
|         paddingBottom: "5px !important",
 | |
|         overflowY: "auto",
 | |
|         maxHeight: `calc(100vh - ${APP_BAR_HEIGHT} - ${TITLE_PADDING_BOTTOM} - ${FILTER_HEIGHT} - 85px)`,
 | |
|         ...APP_STYLES.SCROLL
 | |
|     }
 | |
| };
 | |
| 
 | |
| //---------------
 | |
| //Тело компонента
 | |
| //---------------
 | |
| 
 | |
| //Карточка статуса события
 | |
| const StatusCard = ({
 | |
|     tasks,
 | |
|     status,
 | |
|     statusTitle,
 | |
|     colorRules,
 | |
|     extraData,
 | |
|     filtersType,
 | |
|     isCardAvailable,
 | |
|     onTasksReload,
 | |
|     onDragItemChange,
 | |
|     onTaskDialogOpen,
 | |
|     onNoteDialogOpen,
 | |
|     onStatusColorChange,
 | |
|     placeholder
 | |
| }) => {
 | |
|     //Состояние диалога настройки
 | |
|     const [statusCardSettingsOpen, setStatusCardSettingsOpen] = useState(false);
 | |
| 
 | |
|     //Открыть/закрыть диалог настройки
 | |
|     const handleStatusCardSettingsOpen = () => setStatusCardSettingsOpen(!statusCardSettingsOpen);
 | |
| 
 | |
|     //При изменении цвета статуса
 | |
|     const handleStatusColorChange = newColor => {
 | |
|         onStatusColorChange(status, newColor);
 | |
|     };
 | |
| 
 | |
|     //Генерация содержимого
 | |
|     return (
 | |
|         <div>
 | |
|             {statusCardSettingsOpen ? (
 | |
|                 <StatusCardSettings
 | |
|                     statusColor={status.color}
 | |
|                     availableColors={COLORS.includes(status.color) ? COLORS : [status.color, ...COLORS]}
 | |
|                     onClose={handleStatusCardSettingsOpen}
 | |
|                     onColorChange={handleStatusColorChange}
 | |
|                 />
 | |
|             ) : null}
 | |
|             <Card
 | |
|                 className="statusId-card"
 | |
|                 sx={{
 | |
|                     ...STYLES.STATUS_BLOCK(status.color),
 | |
|                     ...STYLES.BLOCK_OPACITY(isCardAvailable(status.SEVNSTAT_CODE))
 | |
|                 }}
 | |
|             >
 | |
|                 <CardHeader
 | |
|                     action={
 | |
|                         <IconButton aria-label="settings" onClick={handleStatusCardSettingsOpen}>
 | |
|                             <Icon>more_vert</Icon>
 | |
|                         </IconButton>
 | |
|                     }
 | |
|                     title={
 | |
|                         <Typography sx={STYLES.CARD_HEADER_TITLE} title={statusTitle} variant="h5">
 | |
|                             {statusTitle}
 | |
|                         </Typography>
 | |
|                     }
 | |
|                     subheader={
 | |
|                         <Button
 | |
|                             onClick={() => {
 | |
|                                 onDragItemChange(filtersType, status.SEVNSTAT_CODE);
 | |
|                                 onTaskDialogOpen();
 | |
|                             }}
 | |
|                         >
 | |
|                             + Добавить
 | |
|                         </Button>
 | |
|                     }
 | |
|                     sx={STYLES.CARD_HEADER}
 | |
|                 />
 | |
|                 <CardContent sx={STYLES.CARD_CONTENT}>
 | |
|                     <Stack spacing={1}>
 | |
|                         {tasks.rows
 | |
|                             .filter(item => item.sStatus === status.SEVNSTAT_NAME)
 | |
|                             .map((item, index) => (
 | |
|                                 <TaskCard
 | |
|                                     task={item}
 | |
|                                     index={index}
 | |
|                                     onTasksReload={onTasksReload}
 | |
|                                     key={item.id}
 | |
|                                     colorRule={colorRules.selectedColorRule}
 | |
|                                     pointSettings={extraData.evPoints.find(p => p.SEVPOINT === status.SEVNSTAT_CODE)}
 | |
|                                     onOpenNoteDialog={onNoteDialogOpen}
 | |
|                                 />
 | |
|                             ))}
 | |
|                         {placeholder}
 | |
|                     </Stack>
 | |
|                 </CardContent>
 | |
|             </Card>
 | |
|         </div>
 | |
|     );
 | |
| };
 | |
| 
 | |
| //Контроль свойств - Карточка статуса события
 | |
| StatusCard.propTypes = {
 | |
|     tasks: PropTypes.object.isRequired,
 | |
|     status: PropTypes.object.isRequired,
 | |
|     statusTitle: PropTypes.string.isRequired,
 | |
|     colorRules: PropTypes.object.isRequired,
 | |
|     extraData: PropTypes.object.isRequired,
 | |
|     filtersType: PropTypes.string.isRequired,
 | |
|     isCardAvailable: PropTypes.func.isRequired,
 | |
|     onTasksReload: PropTypes.func.isRequired,
 | |
|     onDragItemChange: PropTypes.func.isRequired,
 | |
|     onTaskDialogOpen: PropTypes.func.isRequired,
 | |
|     onNoteDialogOpen: PropTypes.func.isRequired,
 | |
|     onStatusColorChange: PropTypes.func.isRequired,
 | |
|     placeholder: PropTypes.object.isRequired
 | |
| };
 | |
| 
 | |
| //--------------------
 | |
| //Интерфейс компонента
 | |
| //--------------------
 | |
| 
 | |
| export { StatusCard };
 |