|
|
@@ -0,0 +1,810 @@
|
|
|
+"use client";
|
|
|
+
|
|
|
+import React, { useMemo, useState, useEffect } from "react";
|
|
|
+import { AgGridReact } from "ag-grid-react";
|
|
|
+import {
|
|
|
+ ClientSideRowModelModule,
|
|
|
+ ColDef,
|
|
|
+ ColGroupDef,
|
|
|
+ ModuleRegistry,
|
|
|
+ ValidationModule,
|
|
|
+ ICellRendererParams,
|
|
|
+ CellClassParams,
|
|
|
+ ValueFormatterParams,
|
|
|
+ CellClickedEvent,
|
|
|
+ ISelectCellEditorParams,
|
|
|
+ SelectEditorModule,
|
|
|
+ CellStyleModule
|
|
|
+} from "ag-grid-community";
|
|
|
+import "ag-grid-community/styles/ag-theme-alpine.css";
|
|
|
+import DateChangeDialog from "./DateChangeDialog";
|
|
|
+import Chat from "./Chat";
|
|
|
+
|
|
|
+// 注册必要的模块
|
|
|
+ModuleRegistry.registerModules([
|
|
|
+ ClientSideRowModelModule,
|
|
|
+ SelectEditorModule,
|
|
|
+ CellStyleModule,
|
|
|
+ ...(process.env.NODE_ENV!== "production"? [ValidationModule] : [])
|
|
|
+]);
|
|
|
+
|
|
|
+// 支店选项
|
|
|
+const branchOptions = [
|
|
|
+ "東京支店",
|
|
|
+ "神奈川支店",
|
|
|
+ "品川営業所",
|
|
|
+ "札幌支店",
|
|
|
+ "福岡支店"
|
|
|
+];
|
|
|
+
|
|
|
+// 事由选项
|
|
|
+const reasonOptions = [
|
|
|
+ "臨時変更",
|
|
|
+ "計画変更",
|
|
|
+ "休日調整",
|
|
|
+ "その他"
|
|
|
+];
|
|
|
+
|
|
|
+const orderInfo = {
|
|
|
+ deliveryPartner: {
|
|
|
+ id: "0311111111",
|
|
|
+ name: "AAA株式会社"
|
|
|
+ },
|
|
|
+ status: {
|
|
|
+ companyCode: "R000001",
|
|
|
+ status: "全承諾",
|
|
|
+ version: 1,
|
|
|
+ instructionDate: "2025/6/25",
|
|
|
+ approvalDate: "2025/6/25"
|
|
|
+ },
|
|
|
+ monthlyInstruction: {
|
|
|
+ versionOptions: ["ver-1", "ver-2", "ver-3", "ver-4", "ver-5"],
|
|
|
+ selectedVersion: "ver-1"
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+const historyData = [
|
|
|
+ {
|
|
|
+ type: '履歴',
|
|
|
+ date: '2025/06/16 10:00',
|
|
|
+ action: '指示書生成'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ type: '履歴',
|
|
|
+ date: '2025/06/16 15:24',
|
|
|
+ action: '指示書編集'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ type: '履歴',
|
|
|
+ date: '2025/06/16 15:24',
|
|
|
+ action: '指示書送付'
|
|
|
+ }
|
|
|
+];
|
|
|
+
|
|
|
+const weekTexts = ["火", "水", "木", "金", "土", "日", "月"];
|
|
|
+
|
|
|
+const GridExample = () => {
|
|
|
+ const containerStyle = useMemo(() => ({ width: "100%" }), []);
|
|
|
+ const gridStyle = useMemo(() => ({ width: "100%" }), []);
|
|
|
+ const [rowData, setRowData] = useState(initializeRowData());
|
|
|
+ const [showDialog, setShowDialog] = useState(false);
|
|
|
+ const [modifiedCells, setModifiedCells] = useState<Set<string>>(new Set());
|
|
|
+ const [selectedCell, setSelectedCell] = useState<{rowIndex: number | null, colId: string, currentValue: string} | null>(null);
|
|
|
+ const [cellReasons, setCellReasons] = useState<Record<string, string>>({});
|
|
|
+ const [showChat, setShowChat] = useState(false); // 控制聊天侧边栏显示的状态
|
|
|
+
|
|
|
+ // 初始化样式
|
|
|
+ useEffect(() => {
|
|
|
+ const style = document.createElement('style');
|
|
|
+ style.textContent = `
|
|
|
+ .ag-theme-alpine .header-center .ag-header-cell-label {
|
|
|
+ justify-content: center !important;
|
|
|
+ text-align: center !important;
|
|
|
+ }
|
|
|
+
|
|
|
+ .ag-theme-alpine .header-center.ag-header-group-cell {
|
|
|
+ text-align: center !important;
|
|
|
+ }
|
|
|
+
|
|
|
+ .ag-theme-alpine .header-center.ag-header-group-cell .ag-header-group-cell-label {
|
|
|
+ justify-content: center !important;
|
|
|
+ display: flex !important;
|
|
|
+ width: 100% !important;
|
|
|
+ }
|
|
|
+
|
|
|
+ // .order-info-container {
|
|
|
+ // margin-bottom: 20px;
|
|
|
+ // padding: 15px;
|
|
|
+ // border: 1px solid #dcdcdc;
|
|
|
+ // border-radius: 4px;
|
|
|
+ // }
|
|
|
+ .order-info-section {
|
|
|
+ margin-bottom: 35px;
|
|
|
+ }
|
|
|
+ .order-info-section h3 {
|
|
|
+ margin: 0 0 5px 0;
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: bold;
|
|
|
+ }
|
|
|
+ .order-info-row {
|
|
|
+ margin: 10px 0 10px 20px;
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+ .status-section {
|
|
|
+ width: 100%;
|
|
|
+ border-collapse: collapse;
|
|
|
+ margin-top: 8px;
|
|
|
+ margin-left: 10px;
|
|
|
+ }
|
|
|
+ .status-section th,
|
|
|
+ .status-section td {
|
|
|
+ padding: 5px 10px;
|
|
|
+ text-align: left;
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .status-section th {
|
|
|
+ font-weight: normal;
|
|
|
+ }
|
|
|
+
|
|
|
+ .version-select-container {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ margin-left: 20px;
|
|
|
+ }
|
|
|
+ .version-select-container label {
|
|
|
+ margin-right: 10px;
|
|
|
+ white-space: nowrap;
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+ .version-select-container select {
|
|
|
+ padding: 5px 35px;
|
|
|
+ font-size: 14px;
|
|
|
+ margin-left: 20px;
|
|
|
+ padding-left: 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .message-btn {
|
|
|
+ float: right;
|
|
|
+ padding: 7px 50px;
|
|
|
+ background-color: #000;
|
|
|
+ color: #fff;
|
|
|
+ border: none;
|
|
|
+ cursor: pointer;
|
|
|
+ position: relative;
|
|
|
+ top: -17px;
|
|
|
+ }
|
|
|
+ .edit-btn {
|
|
|
+ margin-left: auto;
|
|
|
+ padding: 7px 50px;
|
|
|
+ background-color: #000;
|
|
|
+ color: #fff;
|
|
|
+ border: none;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+ .add-row-btn {
|
|
|
+ background: transparent;
|
|
|
+ border: none;
|
|
|
+ color: #0070c0;
|
|
|
+ cursor: pointer;
|
|
|
+ margin-left: 5px;
|
|
|
+ }
|
|
|
+ .action-btn {
|
|
|
+ background-color: #000;
|
|
|
+ color: #fff;
|
|
|
+ border: none;
|
|
|
+ padding: 7px 20px;
|
|
|
+ cursor: pointer;
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+ .history-table-custom {
|
|
|
+ width: 100%;
|
|
|
+ border-collapse: collapse;
|
|
|
+ }
|
|
|
+ .type-td {
|
|
|
+ padding: 5px 20px;
|
|
|
+ }
|
|
|
+ .date-td {
|
|
|
+ padding: 5px 20px;
|
|
|
+ }
|
|
|
+ .action-td {
|
|
|
+ padding: 5px 20px;
|
|
|
+ }
|
|
|
+ .history-title-custom {
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: bold;
|
|
|
+ margin-bottom: 8px;
|
|
|
+ display: block;
|
|
|
+ }
|
|
|
+ .ag-header-cell-resize {
|
|
|
+ &:after {
|
|
|
+ display: none;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .ag-theme-alpine .ag-cell {
|
|
|
+ border-right: 1px solid #dcdcdc;
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+ .ag-theme-alpine .ag-header-cell {
|
|
|
+ border-right: 1px solid #dcdcdc;
|
|
|
+ }
|
|
|
+ .line-group-header {
|
|
|
+ border-right: 1px solid #dcdcdc;
|
|
|
+ }
|
|
|
+ .date-group-header {
|
|
|
+ border-right: 1px solid #dcdcdc !important;
|
|
|
+ }
|
|
|
+ .checkbox{
|
|
|
+ display: none;
|
|
|
+ }
|
|
|
+ .tokyoBranchCol{
|
|
|
+ display: none;
|
|
|
+ }
|
|
|
+ .chat-sidebar {
|
|
|
+ position: fixed;
|
|
|
+ top: 0;
|
|
|
+ right: 0;
|
|
|
+ width: 1060px;
|
|
|
+ height: 100vh;
|
|
|
+ background-color: #fff;
|
|
|
+ box-shadow: -2px 0 10px rgba(0, 0, 0, 0.1);
|
|
|
+ z-index: 1000;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ padding: 20px;
|
|
|
+ box-sizing: border-box;
|
|
|
+ overflow: hidden;
|
|
|
+ }
|
|
|
+ .chat-messages-container {
|
|
|
+ flex: 1;
|
|
|
+ overflow-y: auto;
|
|
|
+ margin-bottom: 16px;
|
|
|
+ }
|
|
|
+ .overlay {
|
|
|
+ position: fixed;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ bottom: 0;
|
|
|
+ background-color: rgba(0, 0, 0, 0.5);
|
|
|
+ z-index: 999;
|
|
|
+ }
|
|
|
+ `;
|
|
|
+ document.head.appendChild(style);
|
|
|
+
|
|
|
+ return () => {
|
|
|
+ document.head.removeChild(style);
|
|
|
+ };
|
|
|
+ }, []);
|
|
|
+
|
|
|
+ // 生成1-31的日期列定义
|
|
|
+ const generateDateColumns = () => {
|
|
|
+ const columns: ColGroupDef[] = [];
|
|
|
+ for (let i = 1; i <= 31; i++) {
|
|
|
+ const weekIndex = (i - 1) % weekTexts.length;
|
|
|
+ const colId = `date_${i}`;
|
|
|
+ columns.push({
|
|
|
+ headerName: i.toString(),
|
|
|
+ headerClass: "header-center date-group-header",
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ field: colId,
|
|
|
+ headerName: weekTexts[weekIndex],
|
|
|
+ headerClass: "header-center",
|
|
|
+ width: 55,
|
|
|
+ cellRenderer: (params: ICellRendererParams) => {
|
|
|
+ const cellValue = params.value || "";
|
|
|
+ const rowIndex = params.node.rowIndex;
|
|
|
+ const cellKey = `${rowIndex}-${colId}`;
|
|
|
+ const reason = cellReasons[cellKey] || "";
|
|
|
+
|
|
|
+ return (
|
|
|
+ <div
|
|
|
+ title={reason? `变更理由:${reason}` : ""}
|
|
|
+ style={{
|
|
|
+ minHeight: '100%',
|
|
|
+ width: '100%',
|
|
|
+ display: 'flex',
|
|
|
+ alignItems: 'center',
|
|
|
+ justifyContent: 'center'
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ {cellValue}
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ },
|
|
|
+ onCellClicked: (params: CellClickedEvent) => {
|
|
|
+ setSelectedCell({
|
|
|
+ rowIndex: params.node.rowIndex,
|
|
|
+ colId: colId,
|
|
|
+ currentValue: params.value as string
|
|
|
+ });
|
|
|
+ setShowDialog(true);
|
|
|
+ },
|
|
|
+ cellStyle: (params: CellClassParams) => {
|
|
|
+ const rowIndex = params.node.rowIndex;
|
|
|
+ const cellKey = `${rowIndex}-${colId}`;
|
|
|
+ const isModified = modifiedCells.has(cellKey);
|
|
|
+ if (isModified) {
|
|
|
+ return { backgroundColor: '#3a8aca' };
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ });
|
|
|
+ }
|
|
|
+ return columns;
|
|
|
+ };
|
|
|
+
|
|
|
+
|
|
|
+ // 初始化行数据
|
|
|
+ function initializeRowData() {
|
|
|
+ return [
|
|
|
+ {
|
|
|
+ "AM": "",
|
|
|
+ "発": "032990",
|
|
|
+ "着": "025990",
|
|
|
+ "系統": "02",
|
|
|
+ "線便名": "大賀10t①",
|
|
|
+ "入庫場所": "羽田CGB",
|
|
|
+ "入庫時間": "21:00",
|
|
|
+ "使用車両(トン)": "13",
|
|
|
+ "checkboxCol": "",
|
|
|
+ "tokyoBranchCol": "東京支店",
|
|
|
+ "approveStatus": "approved",
|
|
|
+ ...Array.from({ length: 31 }, (_, i) => ({
|
|
|
+ [`date_${i + 1}`]: (i + 1) % 3 === 0? "〇" : ""
|
|
|
+ })).reduce((acc, curr) => ({...acc,...curr }), {})
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "AM": "",
|
|
|
+ "発": "032990",
|
|
|
+ "着": "027990",
|
|
|
+ "系統": "23",
|
|
|
+ "線便名": "大賀10t②",
|
|
|
+ "入庫場所": "桜丘",
|
|
|
+ "入庫時間": "19:00",
|
|
|
+ "使用車両(トン)": "13",
|
|
|
+ "checkboxCol": "",
|
|
|
+ "tokyoBranchCol": "神奈川支店",
|
|
|
+ "approveStatus": "unapproved",
|
|
|
+ ...Array.from({ length: 31 }, (_, i) => ({
|
|
|
+ [`date_${i + 1}`]: (i + 1) % 4 === 0? "〇" : ""
|
|
|
+ })).reduce((acc, curr) => ({...acc,...curr }), {})
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "AM": "*",
|
|
|
+ "発": "032990",
|
|
|
+ "着": "027990",
|
|
|
+ "系統": "G8",
|
|
|
+ "線便名": "大賀10t③",
|
|
|
+ "入庫場所": "目黒",
|
|
|
+ "入庫時間": "18:00",
|
|
|
+ "使用車両(トン)": "13",
|
|
|
+ "checkboxCol": "",
|
|
|
+ "tokyoBranchCol": "品川営業所",
|
|
|
+ "approveStatus": "approved",
|
|
|
+ ...Array.from({ length: 31 }, (_, i) => ({
|
|
|
+ [`date_${i + 1}`]: (i + 1) % 5 === 0? "〇" : ""
|
|
|
+ })).reduce((acc, curr) => ({...acc,...curr }), {})
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "AM": "",
|
|
|
+ "発": "032990",
|
|
|
+ "着": "027990",
|
|
|
+ "系統": "G9",
|
|
|
+ "線便名": "西大阪交表",
|
|
|
+ "入庫場所": "羽田CGB",
|
|
|
+ "入庫時間": "21:00",
|
|
|
+ "使用車両(トン)": "13",
|
|
|
+ "checkboxCol": "",
|
|
|
+ "tokyoBranchCol": "札幌支店",
|
|
|
+ "approveStatus": "unapproved",
|
|
|
+ ...Array.from({ length: 31 }, (_, i) => ({
|
|
|
+ [`date_${i + 1}`]: (i + 1) % 2 === 0? "〇" : ""
|
|
|
+ })).reduce((acc, curr) => ({...acc,...curr }), {})
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "AM": "",
|
|
|
+ "発": "061990",
|
|
|
+ "着": "032990",
|
|
|
+ "系統": "06",
|
|
|
+ "線便名": "羽田CG交裏",
|
|
|
+ "入庫場所": "西大阪B",
|
|
|
+ "入庫時間": "19:00",
|
|
|
+ "使用車両(トン)": "10",
|
|
|
+ "checkboxCol": "",
|
|
|
+ "tokyoBranchCol": "福岡支店",
|
|
|
+ "approveStatus": "approved",
|
|
|
+ ...Array.from({ length: 31 }, (_, i) => ({
|
|
|
+ [`date_${i + 1}`]: (i + 1) % 6 === 0? "〇" : ""
|
|
|
+ })).reduce((acc, curr) => ({...acc,...curr }), {})
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "AM": "",
|
|
|
+ "発": "032990",
|
|
|
+ "着": "032990",
|
|
|
+ "系統": "M8",
|
|
|
+ "線便名": "大賀10t⑥",
|
|
|
+ "入庫場所": "羽田CGB",
|
|
|
+ "入庫時間": "21:00",
|
|
|
+ "使用車両(トン)": "13",
|
|
|
+ "checkboxCol": "",
|
|
|
+ "tokyoBranchCol": "東京支店",
|
|
|
+ "approveStatus": "approved",
|
|
|
+ ...Array.from({ length: 31 }, (_, i) => ({
|
|
|
+ [`date_${i + 1}`]: (i + 1) % 3 === 0? "〇" : ""
|
|
|
+ })).reduce((acc, curr) => ({...acc,...curr }), {})
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "AM": "",
|
|
|
+ "発": "032990",
|
|
|
+ "着": "053990",
|
|
|
+ "系統": "06",
|
|
|
+ "線便名": "中部日祝",
|
|
|
+ "入庫場所": "成城",
|
|
|
+ "入庫時間": "19:00",
|
|
|
+ "使用車両(トン)": "13",
|
|
|
+ "checkboxCol": "",
|
|
|
+ "tokyoBranchCol": "神奈川支店",
|
|
|
+ "approveStatus": "unapproved",
|
|
|
+ ...Array.from({ length: 31 }, (_, i) => ({
|
|
|
+ [`date_${i + 1}`]: (i + 1) % 4 === 0? "〇" : ""
|
|
|
+ })).reduce((acc, curr) => ({...acc,...curr }), {})
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "AM": "*",
|
|
|
+ "発": "032990",
|
|
|
+ "着": "027990",
|
|
|
+ "系統": "G8",
|
|
|
+ "線便名": "大賀10t③",
|
|
|
+ "入庫場所": "目黒",
|
|
|
+ "入庫時間": "18:00",
|
|
|
+ "使用車両(トン)": "13",
|
|
|
+ "checkboxCol": "",
|
|
|
+ "tokyoBranchCol": "品川営業所",
|
|
|
+ "approveStatus": "approved",
|
|
|
+ ...Array.from({ length: 31 }, (_, i) => ({
|
|
|
+ [`date_${i + 1}`]: (i + 1) % 5 === 0? "〇" : ""
|
|
|
+ })).reduce((acc, curr) => ({...acc,...curr }), {})
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "AM": "",
|
|
|
+ "発": "032990",
|
|
|
+ "着": "132990",
|
|
|
+ "系統": "02",
|
|
|
+ "線便名": "大賀7t",
|
|
|
+ "入庫場所": "八幡山",
|
|
|
+ "入庫時間": "19:00",
|
|
|
+ "使用車両(トン)": "2",
|
|
|
+ "checkboxCol": "",
|
|
|
+ "tokyoBranchCol": "札幌支店",
|
|
|
+ "approveStatus": "unapproved",
|
|
|
+ ...Array.from({ length: 31 }, (_, i) => ({
|
|
|
+ [`date_${i + 1}`]: (i + 1) % 2 === 0? "〇" : ""
|
|
|
+ })).reduce((acc, curr) => ({...acc,...curr }), {})
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "AM": "",
|
|
|
+ "発": "061990",
|
|
|
+ "着": "032990",
|
|
|
+ "系統": "06",
|
|
|
+ "線便名": "羽田CG交裏",
|
|
|
+ "入庫場所": "西大阪B",
|
|
|
+ "入庫時間": "19:00",
|
|
|
+ "使用車両(トン)": "10",
|
|
|
+ "checkboxCol": "",
|
|
|
+ "tokyoBranchCol": "福岡支店",
|
|
|
+ "approveStatus": "approved",
|
|
|
+ ...Array.from({ length: 31 }, (_, i) => ({
|
|
|
+ [`date_${i + 1}`]: (i + 1) % 6 === 0? "〇" : ""
|
|
|
+ })).reduce((acc, curr) => ({...acc,...curr }), {})
|
|
|
+ },
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 构建列定义
|
|
|
+ const columnDefs: (ColDef | ColGroupDef)[] = [
|
|
|
+ {
|
|
|
+ field: "checkboxCol",
|
|
|
+ headerName: "",
|
|
|
+ width: 50,
|
|
|
+ cellRenderer: (params: ICellRendererParams) => {
|
|
|
+ return <input type="checkbox" />;
|
|
|
+ },
|
|
|
+ headerClass: "header-center checkbox",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ field: "tokyoBranchCol",
|
|
|
+ headerName: "",
|
|
|
+ width: 110,
|
|
|
+ headerClass: "header-center tokyoBranchCol",
|
|
|
+ editable: true,
|
|
|
+ cellEditor: "agSelectCellEditor",
|
|
|
+ cellEditorParams: {
|
|
|
+ values: branchOptions
|
|
|
+ } as ISelectCellEditorParams,
|
|
|
+ valueFormatter: (params: ValueFormatterParams) => params.value || "",
|
|
|
+ cellRenderer: (params: ICellRendererParams) => {
|
|
|
+ return (
|
|
|
+ <div style={{ textAlign: 'left'}}>
|
|
|
+ {params.value || ''}
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ field: "approveStatus",
|
|
|
+ headerName: "",
|
|
|
+ width: 130,
|
|
|
+ cellRenderer: (params: ICellRendererParams) => {
|
|
|
+ const status = params.data?.approveStatus;
|
|
|
+ const content = status === "approved"? (
|
|
|
+ <span>
|
|
|
+ 承認済
|
|
|
+ <a
|
|
|
+ href="#"
|
|
|
+ style={{
|
|
|
+ marginLeft: "5px",
|
|
|
+ color: "#3a8aca"
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ 差戻し
|
|
|
+ </a>
|
|
|
+ </span>
|
|
|
+ ) : status === "unapproved"? (
|
|
|
+ <span>未承認</span>
|
|
|
+ ) : (
|
|
|
+ <span></span>
|
|
|
+ );
|
|
|
+ return (
|
|
|
+ <div style={{ textAlign: 'left'}}>
|
|
|
+ {content}
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ },
|
|
|
+ headerClass: "header-center"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ field: "AM",
|
|
|
+ headerClass: "header-center",
|
|
|
+ width: 60,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ headerName: "線便",
|
|
|
+ headerClass: "header-center line-group-header",
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ field: "発",
|
|
|
+ headerClass: "header-center",
|
|
|
+ width: 85,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ field: "着",
|
|
|
+ headerClass: "header-center",
|
|
|
+ width: 85,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ field: "系統",
|
|
|
+ headerClass: "header-center",
|
|
|
+ width: 65,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ field: "線便名",
|
|
|
+ headerClass: "header-center",
|
|
|
+ width: 120,
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ { field: "入庫場所", headerClass: "header-center", width: 110 },
|
|
|
+ { field: "入庫時間", headerClass: "header-center", width: 90 },
|
|
|
+ {
|
|
|
+ field: "使用車両(トン)",
|
|
|
+ headerClass: "header-center",
|
|
|
+ width: 125,
|
|
|
+ cellRenderer: (params: ICellRendererParams) => {
|
|
|
+ return (
|
|
|
+ <div style={{ textAlign: 'right'}}>
|
|
|
+ {params.value || ''}
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ }
|
|
|
+ },
|
|
|
+ ...generateDateColumns()
|
|
|
+ ];
|
|
|
+
|
|
|
+
|
|
|
+ // 处理对话框确认
|
|
|
+ const handleDialogConfirm = (reason: string, changeValue: string) => {
|
|
|
+ if (!selectedCell || selectedCell.rowIndex === null) return;
|
|
|
+
|
|
|
+ const newRowData = [...rowData];
|
|
|
+ const currentValue = selectedCell.currentValue;
|
|
|
+ const newValue = currentValue === "〇"? "" : "〇";
|
|
|
+ const targetRowIndex = selectedCell.rowIndex;
|
|
|
+ const targetColId = selectedCell.colId;
|
|
|
+
|
|
|
+ newRowData[targetRowIndex] = {
|
|
|
+ ...newRowData[targetRowIndex],
|
|
|
+ [targetColId]: newValue
|
|
|
+ };
|
|
|
+ setRowData(newRowData);
|
|
|
+
|
|
|
+ const cellKey = `${targetRowIndex}-${targetColId}`;
|
|
|
+ setModifiedCells(prev => {
|
|
|
+ const newSet = new Set(prev);
|
|
|
+ newSet.add(cellKey);
|
|
|
+ return newSet;
|
|
|
+ });
|
|
|
+
|
|
|
+ setCellReasons(prev => ({
|
|
|
+ ...prev,
|
|
|
+ [cellKey]: reason
|
|
|
+ }));
|
|
|
+
|
|
|
+ setShowDialog(false);
|
|
|
+ };
|
|
|
+
|
|
|
+ // 处理对话框取消
|
|
|
+ const handleDialogCancel = () => {
|
|
|
+ setShowDialog(false);
|
|
|
+ };
|
|
|
+
|
|
|
+ // 处理消息按钮点击 - 切换聊天侧边栏显示状态
|
|
|
+ const handleMessageClick = () => {
|
|
|
+ setShowChat(true);
|
|
|
+ };
|
|
|
+
|
|
|
+ // 处理编辑按钮点击
|
|
|
+ const handleEditClick = () => {
|
|
|
+ alert('編集按钮被点击');
|
|
|
+ };
|
|
|
+
|
|
|
+ const handleAddRow = () => {
|
|
|
+ const newRow: any = {
|
|
|
+ "AM": "",
|
|
|
+ "発": "",
|
|
|
+ "着": "",
|
|
|
+ "系統": "",
|
|
|
+ "線便名": "",
|
|
|
+ "入庫場所": "",
|
|
|
+ "入庫時間": "",
|
|
|
+ "使用車両(トン)": "",
|
|
|
+ "checkboxCol": "",
|
|
|
+ "tokyoBranchCol": "",
|
|
|
+ "approveStatus": ""
|
|
|
+ };
|
|
|
+ for (let i = 1; i <= 31; i++) {
|
|
|
+ newRow[`date_${i}`] = "";
|
|
|
+ }
|
|
|
+
|
|
|
+ setRowData([...rowData, newRow]);
|
|
|
+ };
|
|
|
+
|
|
|
+ // 关闭聊天侧边栏
|
|
|
+ const closeChatSidebar = () => {
|
|
|
+ setShowChat(false);
|
|
|
+ };
|
|
|
+
|
|
|
+ return (
|
|
|
+ <div style={containerStyle}>
|
|
|
+ <div className="order-info-container">
|
|
|
+ <div className="order-info-section">
|
|
|
+ <div style={{ fontSize: '14px' }}>発注詳細</div>
|
|
|
+ <button className="message-btn" onClick={handleMessageClick}>
|
|
|
+ メッセージ
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div className="order-info-section">
|
|
|
+ <h3>輸送パートナー </h3>
|
|
|
+ <div className="order-info-row">
|
|
|
+ 輸送パートナーID:{orderInfo.deliveryPartner.id}
|
|
|
+ </div>
|
|
|
+ <div className="order-info-row">
|
|
|
+ 輸送パートナー名:{orderInfo.deliveryPartner.name}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div className="order-info-section">
|
|
|
+ <h3>状態</h3>
|
|
|
+ <table className="status-section">
|
|
|
+ <thead>
|
|
|
+ <tr>
|
|
|
+ <th>会社コード</th>
|
|
|
+ <th>ステータス</th>
|
|
|
+ <th>version</th>
|
|
|
+ <th>指示書送付</th>
|
|
|
+ <th>承諾</th>
|
|
|
+ </tr>
|
|
|
+ </thead>
|
|
|
+ <tbody>
|
|
|
+ <tr>
|
|
|
+ <td>{orderInfo.status.companyCode}</td>
|
|
|
+ <td>{orderInfo.status.status}</td>
|
|
|
+ <td>{orderInfo.status.version}</td>
|
|
|
+ <td>{orderInfo.status.instructionDate}</td>
|
|
|
+ <td>{orderInfo.status.approvalDate}</td>
|
|
|
+ </tr>
|
|
|
+ </tbody>
|
|
|
+ </table>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div className="order-info-section">
|
|
|
+ <h3>月間運行指示書</h3>
|
|
|
+ <div className="version-select-container">
|
|
|
+ <label>version選択</label>
|
|
|
+ <select value={orderInfo.monthlyInstruction.selectedVersion}>
|
|
|
+ {orderInfo.monthlyInstruction.versionOptions.map(version => (
|
|
|
+ <option key={version} value={version}>{version}</option>
|
|
|
+ ))}
|
|
|
+ </select>
|
|
|
+ <button className="edit-btn" onClick={handleEditClick}>
|
|
|
+ 編集
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div style={gridStyle} className="ag-theme-alpine">
|
|
|
+ <AgGridReact
|
|
|
+ rowData={rowData}
|
|
|
+ columnDefs={columnDefs}
|
|
|
+ domLayout="autoHeight"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <button className="add-row-btn" onClick={handleAddRow}>
|
|
|
+ +追加
|
|
|
+ </button>
|
|
|
+
|
|
|
+ <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: '30px' }}>
|
|
|
+ <div>
|
|
|
+ <button className="action-btn">変更を保存</button>
|
|
|
+ <button className="action-btn" style={{ marginLeft: '10px' }}>輸送パートナーに送付する</button>
|
|
|
+ </div>
|
|
|
+ <button className="action-btn">代理承諾</button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div style={{ marginTop: '80px' }}>
|
|
|
+ <span className="history-title-custom">状態・アクション履歴</span>
|
|
|
+ <table className="history-table-custom">
|
|
|
+ <tbody>
|
|
|
+ {historyData.map((item, index) => (
|
|
|
+ <tr key={index}>
|
|
|
+ <td className="type-td">{item.type}</td>
|
|
|
+ <td className="date-td">{item.date}</td>
|
|
|
+ <td className="action-td">{item.action}</td>
|
|
|
+ </tr>
|
|
|
+ ))}
|
|
|
+ </tbody>
|
|
|
+ </table>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* 使用封装的对话框组件 */}
|
|
|
+ <DateChangeDialog
|
|
|
+ show={showDialog}
|
|
|
+ onClose={handleDialogCancel}
|
|
|
+ onConfirm={handleDialogConfirm}
|
|
|
+ reasonOptions={reasonOptions}
|
|
|
+ />
|
|
|
+
|
|
|
+ {/* 聊天侧边栏 */}
|
|
|
+ {showChat && (
|
|
|
+ <>
|
|
|
+ {/* 半透明背景遮罩 */}
|
|
|
+ <div className="overlay" onClick={closeChatSidebar}></div>
|
|
|
+
|
|
|
+ {/* 聊天侧边栏容器 */}
|
|
|
+ <div className="chat-sidebar">
|
|
|
+ <Chat onClose={closeChatSidebar} />
|
|
|
+ </div>
|
|
|
+ </>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
+export default GridExample;
|
|
|
+
|