From 4ae32afae690d749379b111d88ddcd1a3ccc39d7 Mon Sep 17 00:00:00 2001 From: GotPPay Date: Wed, 23 May 2018 18:05:41 +0200 Subject: [PATCH] remove react-dialog as package and include as part of the project --- package.json | 3 + .../Shared/ValidationErrorsInfoDialog.js | 4 +- .../Shared/draggable-dialog/DialogBody.js | 18 ++ .../Shared/draggable-dialog/DialogFooter.js | 43 +++++ .../Shared/draggable-dialog/DialogTitle.js | 65 +++++++ .../Shared/draggable-dialog/css/img/close.png | Bin 0 -> 403 bytes .../draggable-dialog/css/img/maximize.png | Bin 0 -> 310 bytes .../draggable-dialog/css/img/minimize.png | Bin 0 -> 156 bytes .../draggable-dialog/css/img/restore.png | Bin 0 -> 300 bytes .../Shared/draggable-dialog/css/index.css | 150 +++++++++++++++ .../Shared/draggable-dialog/index.js | 171 ++++++++++++++++++ 11 files changed, 452 insertions(+), 2 deletions(-) create mode 100644 src/components/Shared/draggable-dialog/DialogBody.js create mode 100644 src/components/Shared/draggable-dialog/DialogFooter.js create mode 100644 src/components/Shared/draggable-dialog/DialogTitle.js create mode 100644 src/components/Shared/draggable-dialog/css/img/close.png create mode 100644 src/components/Shared/draggable-dialog/css/img/maximize.png create mode 100644 src/components/Shared/draggable-dialog/css/img/minimize.png create mode 100644 src/components/Shared/draggable-dialog/css/img/restore.png create mode 100644 src/components/Shared/draggable-dialog/css/index.css create mode 100644 src/components/Shared/draggable-dialog/index.js diff --git a/package.json b/package.json index ee5092c..4191c69 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,7 @@ "react-data-components": "^1.1.1", "react-dialog": "^1.0.2", "react-dom": "^15.5.4", + "react-draggable": "^2.2.6", "react-geosuggest": "^2.5.0", "react-geosuggest-sw": "^1.4.13", "react-google-maps": "^7.2.0", @@ -67,8 +68,10 @@ "react-imgix": "^7.1.1", "react-jquery-datatables": "^0.7.1", "react-materialui-notifications": "^0.5.1", + "react-onclickoutside": "^5.10.0", "react-places-autocomplete": "^5.4.2", "react-redux": "^5.0.5", + "react-resizable": "^1.7.1", "react-router": "^3.0.4", "react-router-redux": "^4.0.8", "react-tap-event-plugin": "^2.0.1", diff --git a/src/components/Shared/ValidationErrorsInfoDialog.js b/src/components/Shared/ValidationErrorsInfoDialog.js index 9251358..1bb9b85 100644 --- a/src/components/Shared/ValidationErrorsInfoDialog.js +++ b/src/components/Shared/ValidationErrorsInfoDialog.js @@ -1,8 +1,8 @@ import React, { Component } from 'react'; import FlatButton from 'material-ui/FlatButton'; -import Dialog from 'react-dialog' +import Dialog from './draggable-dialog'; -import 'react-dialog/css/index.css'; +import './draggable-dialog/css/index.css'; export class ValidationErrorsInfoDialog extends React.Component { diff --git a/src/components/Shared/draggable-dialog/DialogBody.js b/src/components/Shared/draggable-dialog/DialogBody.js new file mode 100644 index 0000000..455e04a --- /dev/null +++ b/src/components/Shared/draggable-dialog/DialogBody.js @@ -0,0 +1,18 @@ +import React from "react"; +import PropTypes from "prop-types"; + +class DialogBody extends React.Component { + render() { + return ( +
+ {this.props.children} +
+ ); + } +} + +DialogBody.propTypes = { + children: PropTypes.oneOfType([PropTypes.array, PropTypes.object]) +}; + +export default DialogBody; \ No newline at end of file diff --git a/src/components/Shared/draggable-dialog/DialogFooter.js b/src/components/Shared/draggable-dialog/DialogFooter.js new file mode 100644 index 0000000..6fe70d5 --- /dev/null +++ b/src/components/Shared/draggable-dialog/DialogFooter.js @@ -0,0 +1,43 @@ +import React from "react"; +import PropTypes from "prop-types"; +import cs from "classnames"; + +const DialogFooter = (props) => { + const buttons = props.buttons; + if (!buttons || buttons.length == 0) { + return false; + } + + const dialogButtons = buttons.map(function (button, index) { + if (React.isValidElement(button)) { + return button; + } + + const { text, onClick, className } = button; + + return ( + + ); + }, this); + + return ( +
+
+ {dialogButtons} +
+
+ ); +}; + +DialogFooter.propTypes = { + buttons: PropTypes.array, + onClose: PropTypes.func.isRequired +}; + +export default DialogFooter; \ No newline at end of file diff --git a/src/components/Shared/draggable-dialog/DialogTitle.js b/src/components/Shared/draggable-dialog/DialogTitle.js new file mode 100644 index 0000000..66c7f0b --- /dev/null +++ b/src/components/Shared/draggable-dialog/DialogTitle.js @@ -0,0 +1,65 @@ +import React from "react"; +import PropTypes from "prop-types"; + +const DialogTitle = ({ title, hasCloseIcon, onClose, allowMinimize, isMinimized, onMinimize, allowMaximize, isMaximized, onMaximize, onRestore }) => { + let closeIcon; + if (hasCloseIcon !== false) { + closeIcon = ( + + ); + } + + let minimizeIcon; + if (allowMinimize) { + if (isMinimized) { + minimizeIcon = ( + + ); + } else { + minimizeIcon = ( + + ); + } + } + + let maximizeIcon; + if (allowMaximize) { + if (isMaximized) { + maximizeIcon = ( + + ); + } else { + maximizeIcon = ( + + ); + } + } + + return ( +
+
+ {title} +
+
+ {minimizeIcon} + {maximizeIcon} + {closeIcon} +
+
+ ); +}; + +DialogTitle.propTypes = { + hasCloseIcon: PropTypes.bool, + allowMinimize: PropTypes.bool, + allowMaximize: PropTypes.bool, + isMinimized: PropTypes.bool, + isMaximized: PropTypes.bool, + title: PropTypes.oneOfType([PropTypes.string, PropTypes.element]), + onClose: PropTypes.func.isRequired, + onMinimize: PropTypes.func, + onMaximize: PropTypes.func, + onRestore: PropTypes.func +}; + +export default DialogTitle; \ No newline at end of file diff --git a/src/components/Shared/draggable-dialog/css/img/close.png b/src/components/Shared/draggable-dialog/css/img/close.png new file mode 100644 index 0000000000000000000000000000000000000000..c06b0944514a7c22cbc810c964cdc7057056a905 GIT binary patch literal 403 zcmV;E0c`$>P)+SRN(+jH)H{Vkoae26)ADvvt`fc%uUU{EDQWK%?^s? zj9osDMxR+(79i03q!=F$N)j_;Ux}~==nVi+G1rc*RLr#o+_4pB?90Uq4T-yO4T*>F zloGw+DI^BNV@i0#V@L$ULnNZXeI%m8he#xY_mM~r?~(|Cldpt;HUwFmgmNORAeevs z{(SiS&#T&%2wnCk-+?EgynQB;yzASp%6tZ$^Lz!toJh6;+Nj+pZf!WV`$X4nPcG5t zs3nsaa?Ybm_%xYl5+NNfSRzJm_m+qmEQ2Ldq*`x@l#%*SLL<-bN~m2XZb)R#*d-Cx xT6unGn%$%rAKL(fo0`4G%&)6ru4in&{{gFE&G**7a325w002ovPDHLkV1n0lrY!&f literal 0 HcmV?d00001 diff --git a/src/components/Shared/draggable-dialog/css/img/maximize.png b/src/components/Shared/draggable-dialog/css/img/maximize.png new file mode 100644 index 0000000000000000000000000000000000000000..174953707c9a578ebfd3f3b793ca24bd3987f70a GIT binary patch literal 310 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdzmSQK*5Dp-y;YjHK@;M7UB8wRq zxP?KOkzv*x383H&PZ!6Kh}O5$e7Twp1l;0Rto{~c>nOPE?WxI6bi}qdnZGDqwb!X$ z%yfd6No0!A>^cK!(R<9LpBiJ%9bm3le}?5s(;wd*vkTQVHn8_iOy`@#WPU)!qa!`x zw`s>R#<(aZ%>u(lfj^vIR9UV)nErF$*LC;3568aYvCllN@Ox--{pamhHmb=HSB-p96vuV!q&|Lv7Zmz>V&CW9$0?JU!j>o%-7 zl+3i(#76Bw{fsQ8M?%3(4&T1LTF!Qi!zR1>>u1KBVtYA^dH!(%{m9_y>gTe~DWM4f D6+L(s literal 0 HcmV?d00001 diff --git a/src/components/Shared/draggable-dialog/css/img/minimize.png b/src/components/Shared/draggable-dialog/css/img/minimize.png new file mode 100644 index 0000000000000000000000000000000000000000..a763cbb837cdb15c2c1998df15e4c33be2fb1c3a GIT binary patch literal 156 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdzmSQK*5Dp-y;YjHK@;M7UB8wRq zxP?KOkzv*x380{zr;B4qMC;pg8#x&icw8>(Tg>skxx4@N%GSLT^b$VDSGMeKQ1Se= xhUF(i)Te7Kzof4{s9;q8**N!(y62>#m8{!PC{xWt~$(69BfrF$Mqt literal 0 HcmV?d00001 diff --git a/src/components/Shared/draggable-dialog/css/img/restore.png b/src/components/Shared/draggable-dialog/css/img/restore.png new file mode 100644 index 0000000000000000000000000000000000000000..6823ec30c64b0c72520587b68678a3de9982339c GIT binary patch literal 300 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdzmSQK*5Dp-y;YjHK@;M7UB8wRq zxP?KOkzv*x383IPPZ!6Kh}O5)4ZD~OCE6YykL8|i+a^}kz!=TH!2Lpz|CY7p1$+1#`G0`kMg}b zn8I&A!!^%{lVz8L%eB-WZgo2ic9=yn?sWL}n2|Ss63Zk9ArGecj&_e4T#wpH&q$6g zoUgv5^&#`Go(q4ZTiQ41{+nLKUt6+{^AESD0;fu&O2B@J^hfvEERVU$S>7)&OmVy$ s>%Upm%r%c|-F1#-H>Usi*J{bAZzWmhyM6mBpwAdQUHx3vIVCg!0BbXE5C8xG literal 0 HcmV?d00001 diff --git a/src/components/Shared/draggable-dialog/css/index.css b/src/components/Shared/draggable-dialog/css/index.css new file mode 100644 index 0000000..879b079 --- /dev/null +++ b/src/components/Shared/draggable-dialog/css/index.css @@ -0,0 +1,150 @@ +body { + width: 100%; + min-height: 700px; +} + +a { + cursor: pointer; + text-decoration: underline; +} + +.ui-dialog-overlay { + background: #aaaaaa; + opacity: .3; + filter: Alpha(Opacity=30); + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 100; +} + +.ui-dialog { + position: fixed; + top: 50%; + left: 50%; + outline: 0 none; + padding: 0 !important;; + z-index: 101; + background-color: white; + border: 1px solid #f6f6f6; +} + +.ui-dialog.maximized{ + position: fixed; + top: 0; + left: 0; + width: 100% !important; + height: 100% !important; +} + +.ui-dialog.minimized{ + position: fixed; + bottom: 0; + right: 0; +} + +.ui-dialog .ui-dialog-titlebar { + position: relative; + font-size: 1em; + border-radius: 3px; + padding: 0.5em; + height: 35px; + border-bottom: 1px solid #f6f6f6; +} + +.ui-dialog.react-draggable .ui-dialog-titlebar { + cursor: move; +} + +.ui-dialog .ui-dialog-titlebar .action-items { + float: right; + position: relative; +} + +.ui-dialog .ui-dialog-titlebar .title { + float: left; + margin-right: .5em; + font-family: Arial, Helvetica, sans-serif; + font-size: 1.5em; +} + +.icon { + width: 24px; + height: 24px; + display: block; + float: left; + margin: 5px; + cursor: pointer; + background-size: cover; +} + +.icon.icon-close { + width: 20px; + height: 20px; + background-image: url("./img/close.png"); +} + +.icon.icon-minimize { + background-image: url("./img/minimize.png"); +} + +.icon.icon-maximize { + background-image: url("./img/maximize.png"); +} + +.icon.icon-restore { + background-image: url("./img/restore.png"); +} + +.ui-dialog .ui-dialog-content { + background: none repeat scroll 0 0 transparent; + border: 0 none; + overflow: auto; + position: relative; + padding: 0.5em; +} + +.ui-dialog .ui-dialog-buttonpane { + position: absolute; + width: 100%; + bottom: 0; + text-align: right; + border-width: 1px 0 0 0; + border-top: 1px solid #f6f6f6; +} + +.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{ + padding: 0.5em; +} + +.ui-dialog .ui-dialog-buttonpane button { + margin: 0 .5em 0 .5em; + cursor: pointer; + background-color: #f6f6f6; + padding: 0.5em 1em; + outline: none; + border: 1px solid #CCCCCC; + border-radius: 3px; +} + +.ui-dialog .ui-dialog-buttonpane button:hover{ + background-color: #CCCCCC; + border: 1px solid #BBBBBB; +} + +.ui-dialog .react-resizable-handle { + position: absolute; + width: 20px; + height: 20px; + bottom: 0; + right: 0; + background: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2IDYiIHN0eWxlPSJiYWNrZ3JvdW5kLWNvbG9yOiNmZmZmZmYwMCIgeD0iMHB4IiB5PSIwcHgiIHdpZHRoPSI2cHgiIGhlaWdodD0iNnB4Ij48ZyBvcGFjaXR5PSIwLjMwMiI+PHBhdGggZD0iTSA2IDYgTCAwIDYgTCAwIDQuMiBMIDQgNC4yIEwgNC4yIDQuMiBMIDQuMiAwIEwgNiAwIEwgNiA2IEwgNiA2IFoiIGZpbGw9IiMwMDAwMDAiLz48L2c+PC9zdmc+'); + background-position: bottom right; + padding: 0 3px 3px 0; + background-repeat: no-repeat; + background-origin: content-box; + box-sizing: border-box; + cursor: se-resize; +} \ No newline at end of file diff --git a/src/components/Shared/draggable-dialog/index.js b/src/components/Shared/draggable-dialog/index.js new file mode 100644 index 0000000..30a66bd --- /dev/null +++ b/src/components/Shared/draggable-dialog/index.js @@ -0,0 +1,171 @@ +import React from "react"; +import PropTypes from "prop-types"; +import cs from "classnames"; +import Draggable from "react-draggable"; +import { Resizable } from "react-resizable"; +import DialogTitle from "./DialogTitle"; +import DialogBody from "./DialogBody"; +import DialogFooter from "./DialogFooter"; +import EventStack from "active-event-stack"; + +class Dialog extends React.Component { + constructor(props) { + super(props); + + this.state = { + height: props.height, + width: props.width, + isMinimized: false, + isMaximized: false + }; + } + + componentWillMount() { + /** + * This is done in the componentWillMount instead of the componentDidMount + * because this way, a modal that is a child of another will have register + * for events after its parent + */ + this.eventToken = EventStack.addListenable([ + ["keydown", this.handleGlobalKeydown] + ]); + } + + componentWillUnmount = () => { + EventStack.removeListenable(this.eventToken); + } + + handleGlobalKeydown = (e) => { + if (this.props.closeOnEscape && e.keyCode == 27) { + e.stopPropagation(); + this.onClose(); + } + + return false; + } + + onClose = () => { + if (this.props.onClose) { + this.props.onClose(); + } + } + + onMinimize = () => { + this.setState({ isMinimized: true, isMaximized: false }); + } + + onMaximize = () => { + this.setState({ isMinimized: false, isMaximized: true }); + } + + onRestore = () => { + this.setState({ isMinimized: false, isMaximized: false }); + } + + onResize = (event, { element, size }) => { + this.setState({ width: size.width, height: size.height }); + } + + getDialogTitle = () => { + return ( + + ); + } + + render() { + const { height, width, isMinimized, isMaximized } = this.state; + const { modal, isDraggable, isResizable, buttons, children, position } = this.props; + const { x = -width / 2, y = -height / 2 } = position; + + let dialog = ( +
+ {this.getDialogTitle()} + { + !isMinimized && {children} + } + { + !isMinimized && + } + +
+ ); + + if (!isMinimized && !isMaximized && isResizable) { + dialog = ( + + {dialog} + + ); + } + + if (!isMinimized && !isMaximized && isDraggable !== false) { + dialog = ( + + {dialog} + + ); + } + + return ( +
+ {dialog} + {modal &&
} +
+ ); + } +} + +Dialog.propTypes = { + height: PropTypes.number, + width: PropTypes.number, + modal: PropTypes.bool, + position: PropTypes.shape({ + x: PropTypes.number, + y: PropTypes.number + }), + hasCloseIcon: PropTypes.bool, + allowMinimize: PropTypes.bool, + allowMaximize: PropTypes.bool, + isResizable: PropTypes.bool, + title: PropTypes.oneOfType([PropTypes.string, PropTypes.element]), + closeOnEscape: PropTypes.bool, + onClose: PropTypes.func, + children: PropTypes.oneOfType([PropTypes.string, PropTypes.array, PropTypes.element]).isRequired, + buttons: PropTypes.oneOfType([ + PropTypes.arrayOf(PropTypes.shape({ + text: PropTypes.string, + onClick: PropTypes.func + })), + PropTypes.arrayOf(PropTypes.element) + ]) +}; + +Dialog.defaultProps = { + height: 300, + width: 500, + modal: false, + closeOnEscape: true, + isDraggable: false, + isResizable: false, + title: '', + hasCloseIcon: true, + allowMinimize: false, + allowMaximize: false, + onClose: null, + buttons: null, + position: { x: -250, y: -150 } +}; + +export default Dialog; \ No newline at end of file