github.com/minio/console@v1.4.1/web-app/src/screens/Console/Common/ObjectManager/ObjectHandled.tsx (about) 1 // This file is part of MinIO Console Server 2 // Copyright (c) 2021 MinIO, Inc. 3 // 4 // This program is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Affero General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // This program is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Affero General Public License for more details. 13 // 14 // You should have received a copy of the GNU Affero General Public License 15 // along with this program. If not, see <http://www.gnu.org/licenses/>. 16 17 import React, { Fragment } from "react"; 18 import { IFileItem } from "../../ObjectBrowser/types"; 19 import ProgressBarWrapper from "../ProgressBarWrapper/ProgressBarWrapper"; 20 import { 21 Box, 22 CancelledIcon, 23 DisabledIcon, 24 DownloadStatIcon, 25 EnabledIcon, 26 UploadStatIcon, 27 Tooltip, 28 } from "mds"; 29 import clsx from "clsx"; 30 import { callForObjectID } from "../../ObjectBrowser/transferManager"; 31 import styled from "styled-components"; 32 import get from "lodash/get"; 33 34 interface IObjectHandled { 35 objectToDisplay: IFileItem; 36 deleteFromList: (instanceID: string) => void; 37 } 38 39 const ObjectHandledCloseButton = styled.button(({ theme }) => ({ 40 backgroundColor: "transparent", 41 border: 0, 42 right: 0, 43 top: 5, 44 marginTop: 15, 45 position: "absolute", 46 cursor: "pointer", 47 "& .closeIcon": { 48 backgroundColor: get(theme, "buttons.regular.hover.background", "#E6EAEB"), 49 display: "block", 50 width: 18, 51 height: 18, 52 borderRadius: "100%", 53 "&:hover": { 54 backgroundColor: get(theme, "mutedText", "#E9EDEE"), 55 }, 56 "&::before": { 57 width: 1, 58 height: 9, 59 top: "50%", 60 content: "' '", 61 position: "absolute", 62 transform: "translate(-50%, -50%) rotate(45deg)", 63 borderLeft: `${get(theme, "fontColor", "#000")} 2px solid`, 64 }, 65 "&::after": { 66 width: 1, 67 height: 9, 68 top: "50%", 69 content: "' '", 70 position: "absolute", 71 transform: "translate(-50%, -50%) rotate(-45deg)", 72 borderLeft: `${get(theme, "fontColor", "#000")} 2px solid`, 73 }, 74 }, 75 })); 76 77 const ObjectInformation = styled.div(({ theme }) => ({ 78 display: "flex", 79 alignItems: "center", 80 width: "100%", 81 "span.headItem": { 82 fontSize: 14, 83 fontWeight: "bold", 84 width: 270, 85 whiteSpace: "nowrap", 86 textOverflow: "ellipsis", 87 overflow: "hidden", 88 }, 89 "& .iconContainer": { 90 paddingTop: 5, 91 marginRight: 5, 92 "& svg": { 93 width: 16, 94 height: 16, 95 }, 96 }, 97 "& .completedSuccess": { 98 color: get(theme, "signalColors.good", "#4CCB92"), 99 }, 100 "& .inProgress": { 101 color: get(theme, "signalColors.main", "#2781B0"), 102 }, 103 "& .completedError": { 104 color: get(theme, "signalColors.danger", "#C83B51"), 105 }, 106 "& .cancelledAction": { 107 color: get(theme, "signalColors.warning", "#FFBD62"), 108 }, 109 })); 110 111 const ObjectHandled = ({ objectToDisplay, deleteFromList }: IObjectHandled) => { 112 const prefix = `${objectToDisplay.prefix}`; 113 return ( 114 <Fragment> 115 <Box 116 sx={{ 117 borderBottom: "#E2E2E2 1px solid", 118 padding: "15px 5px", 119 margin: "0 30px", 120 position: "relative", 121 "& .showOnHover": { 122 opacity: 1, 123 transitionDuration: "0.2s", 124 }, 125 "&:hover": { 126 "& .showOnHover": { 127 opacity: 1, 128 }, 129 }, 130 }} 131 className={objectToDisplay.percentage !== 100 ? "inProgress" : ""} 132 > 133 <Box 134 sx={{ 135 "& .closeButton": { 136 backgroundColor: "transparent", 137 border: 0, 138 right: 0, 139 top: 5, 140 marginTop: 15, 141 position: "absolute", 142 }, 143 }} 144 > 145 <ObjectHandledCloseButton 146 onClick={() => { 147 if (!objectToDisplay.done) { 148 const call = callForObjectID(objectToDisplay.ID); 149 if (call) { 150 call.abort(); 151 } 152 } else { 153 deleteFromList(objectToDisplay.instanceID); 154 } 155 }} 156 className={`closeButton hideOnProgress`} 157 > 158 <span className={"closeIcon"} /> 159 </ObjectHandledCloseButton> 160 </Box> 161 <Box 162 sx={{ 163 display: "flex", 164 alignItems: "center", 165 }} 166 > 167 <Box 168 sx={{ 169 width: 295, 170 "& .bucketName": { 171 fontSize: 12, 172 }, 173 }} 174 > 175 <Tooltip tooltip={prefix} placement="top"> 176 <ObjectInformation> 177 <span 178 className={clsx("iconContainer", { 179 inProgress: 180 !objectToDisplay.done && 181 !objectToDisplay.failed && 182 !objectToDisplay.cancelled, 183 completedSuccess: 184 objectToDisplay.done && 185 !objectToDisplay.failed && 186 !objectToDisplay.cancelled, 187 completedError: objectToDisplay.failed, 188 cancelledAction: objectToDisplay.cancelled, 189 })} 190 > 191 {objectToDisplay.cancelled ? ( 192 <CancelledIcon /> 193 ) : ( 194 <Fragment> 195 {objectToDisplay.failed ? ( 196 <DisabledIcon /> 197 ) : ( 198 <Fragment> 199 {objectToDisplay.done ? ( 200 <EnabledIcon /> 201 ) : ( 202 <Fragment> 203 {objectToDisplay.type === "download" ? ( 204 <DownloadStatIcon /> 205 ) : ( 206 <UploadStatIcon /> 207 )} 208 </Fragment> 209 )} 210 </Fragment> 211 )} 212 </Fragment> 213 )} 214 </span> 215 <span 216 className={`headItem ${ 217 objectToDisplay.failed ? "completedError" : "" 218 }`} 219 > 220 {prefix} 221 </span> 222 </ObjectInformation> 223 </Tooltip> 224 <Box className={"muted bucketName"}> 225 <strong>Bucket: </strong> 226 {objectToDisplay.bucketName} 227 </Box> 228 </Box> 229 </Box> 230 <Box 231 sx={{ 232 marginTop: 5, 233 }} 234 > 235 {objectToDisplay.waitingForFile ? ( 236 <ProgressBarWrapper indeterminate value={0} ready={false} /> 237 ) : ( 238 <ProgressBarWrapper 239 value={objectToDisplay.percentage} 240 ready={objectToDisplay.done} 241 error={objectToDisplay.failed} 242 cancelled={objectToDisplay.cancelled} 243 withLabel 244 notificationLabel={ 245 objectToDisplay.errorMessage !== "" 246 ? objectToDisplay.errorMessage 247 : "" 248 } 249 /> 250 )} 251 </Box> 252 </Box> 253 </Fragment> 254 ); 255 }; 256 257 export default ObjectHandled;