Attached Files | dragScroll_core2.diff [^] (16,740 bytes) 2021-02-04 16:18 [Show Content] [Hide Content]diff --git a/web-jspack/org.openbravo.core2/src/components/BaseGridLayout/BaseGridLayout.jsx b/web-jspack/org.openbravo.core2/src/components/BaseGridLayout/BaseGridLayout.jsx
index f0255a92..a51f014f 100644
--- a/web-jspack/org.openbravo.core2/src/components/BaseGridLayout/BaseGridLayout.jsx
+++ b/web-jspack/org.openbravo.core2/src/components/BaseGridLayout/BaseGridLayout.jsx
@@ -13,6 +13,8 @@ import PropTypes from 'prop-types';
import './BaseGridLayout.css';
import Registry from '../../core/Registry';
import useUserAction from '../../core/user-action/useUserAction';
+import ScrollDrag from '../ScrollDrag/ScrollDrag';
+// import ScrollContainer from '../ScrollDrag/OtherDrag';
/**
* @fileoverview component to create a basic grid layout. It handles things like:
@@ -96,6 +98,14 @@ const BaseGridLayout = ({
};
};
+ const isTouchDevice = () => {
+ return (
+ 'ontouchstart' in window ||
+ navigator.maxTouchPoints > 0 ||
+ navigator.msMaxTouchPoints > 0
+ );
+ };
+
const generateElementInstance = ({
variantClassName = null,
id,
@@ -104,6 +114,34 @@ const BaseGridLayout = ({
componentProperties,
componentChildren
}) => {
+ if (
+ !isTouchDevice() &&
+ componentProperties &&
+ componentProperties.requiresScroll
+ ) {
+ return (
+ <ScrollDrag
+ key={id}
+ variantClass={`obc2BaseGridLayout-item ${variantClassName || ''}`}
+ variantStyle={generateElementLayout(layout)}
+ >
+ {generateComponent(component, componentProperties, componentChildren)}
+ </ScrollDrag>
+ );
+ // return (
+ // <ScrollContainer
+ // key={id}
+ // className={`obc2BaseGridLayout-item ${variantClassName || ''}`}
+ // style={generateElementLayout(layout)}
+ // vertical
+ // horizontal={false}
+ // activationDistance={1}
+ // >
+ // {generateComponent(component, componentProperties, componentChildren)}
+ // </ScrollContainer>
+ // );
+ }
+
return (
<div
key={id}
@@ -212,7 +250,6 @@ const BaseGridLayout = ({
</div>
);
};
-
BaseGridLayout.propTypes = {
columnCustomSizes: PropTypes.objectOf(PropTypes.string),
rowCustomSizes: PropTypes.objectOf(PropTypes.string),
diff --git a/web-jspack/org.openbravo.core2/src/components/ConfigurableLayout/ConfigurableLayout.jsx b/web-jspack/org.openbravo.core2/src/components/ConfigurableLayout/ConfigurableLayout.jsx
index 21ab6d94..eb1e8ecc 100644
--- a/web-jspack/org.openbravo.core2/src/components/ConfigurableLayout/ConfigurableLayout.jsx
+++ b/web-jspack/org.openbravo.core2/src/components/ConfigurableLayout/ConfigurableLayout.jsx
@@ -44,7 +44,6 @@ const ConfigurableLayout = ({
/>
);
};
-
ConfigurableLayout.defaultProps = {
variantClass: '',
variantStyle: {},
diff --git a/web-jspack/org.openbravo.core2/src/components/ScrollDrag/OtherDrag.css b/web-jspack/org.openbravo.core2/src/components/ScrollDrag/OtherDrag.css
new file mode 100644
index 00000000..48fa29ea
--- /dev/null
+++ b/web-jspack/org.openbravo.core2/src/components/ScrollDrag/OtherDrag.css
@@ -0,0 +1,45 @@
+.indiana-scroll-container {
+ overflow: auto;
+}
+
+.indiana-scroll-container-dragging {
+ pointer-events: none;
+ cursor: grab;
+}
+
+.indiana-scroll-container-dragging_hide-scrollbars {
+ overflow: hidden;
+ overflow: -moz-scrollbars-none;
+ -ms-overflow-style: none;
+ scrollbar-width: none;
+ /* display: none !important;
+ height: 0 !important;
+ width: 0 !important;
+ background: transparent !important;
+ -webkit-appearance: none !important; */
+}
+
+.indiana-scroll-container-dragging_native-scroll {
+ overflow: auto;
+}
+
+
+ /* &--dragging {
+ > * {
+
+ }
+ }
+ &--hide-scrollbars {
+
+ &::-webkit-scrollbar {
+
+ }
+ }
+ &--native-scroll {
+
+ }
+} */
+
+.indiana-dragging {
+ cursor: grab !important;
+}
diff --git a/web-jspack/org.openbravo.core2/src/components/ScrollDrag/OtherDrag.jsx b/web-jspack/org.openbravo.core2/src/components/ScrollDrag/OtherDrag.jsx
new file mode 100644
index 00000000..6292937e
--- /dev/null
+++ b/web-jspack/org.openbravo.core2/src/components/ScrollDrag/OtherDrag.jsx
@@ -0,0 +1,387 @@
+/* eslint-disable react/require-default-props */
+import React, { PureComponent } from 'react';
+import PropTypes from 'prop-types';
+import _ from 'lodash';
+
+import './OtherDrag.css';
+
+const SCROLL_END_DEBOUNCE = 300;
+
+class ScrollContainer extends PureComponent {
+ constructor(props) {
+ super(props);
+ this.container = React.createRef();
+ this.onEndScroll = _.debounce(this.onEndScroll, SCROLL_END_DEBOUNCE);
+
+ // Is container scrolling now (for example by inertia)
+ this.scrolling = false;
+ // Is scrolling started
+ this.started = false;
+ // Is touch active or mouse pressed down
+ this.pressed = false;
+
+ // Bind callbacks
+ this.getRef = this.getRef.bind(this);
+ }
+
+ componentDidMount() {
+ const { nativeMobileScroll } = this.props;
+ const container = this.container.current;
+
+ window.addEventListener('mouseup', this.onMouseUp);
+ window.addEventListener('mousemove', this.onMouseMove);
+ window.addEventListener('touchmove', this.onTouchMove, { passive: false });
+ window.addEventListener('touchend', this.onTouchEnd);
+
+ // due to https://github.com/facebook/react/issues/9809#issuecomment-414072263
+ container.addEventListener('touchstart', this.onTouchStart, {
+ passive: false
+ });
+ container.addEventListener('mousedown', this.onMouseDown, {
+ passive: false
+ });
+
+ if (nativeMobileScroll) {
+ // We should check if it's the mobile device after page was loaded
+ // to prevent breaking SSR
+ this.isMobile = this.isMobileDevice();
+
+ // If it's the mobile device, we should rerender to change styles
+ if (this.isMobile) {
+ this.forceUpdate();
+ }
+ }
+ }
+
+ componentWillUnmount() {
+ window.removeEventListener('mouseup', this.onMouseUp);
+ window.removeEventListener('mousemove', this.onMouseMove);
+ window.removeEventListener('touchmove', this.onTouchMove);
+ window.removeEventListener('touchend', this.onTouchEnd);
+ }
+
+ getElement() {
+ return this.container.current;
+ }
+
+ // Simulate 'onEndScroll' event that fires when scrolling is stopped
+ onEndScroll = () => {
+ this.scrolling = false;
+ if (!this.pressed && this.started) {
+ this.processEnd();
+ }
+ };
+
+ onScroll = e => {
+ const container = this.container.current;
+ // Ignore the internal scrolls
+ if (
+ container.scrollLeft !== this.scrollLeft ||
+ container.scrollTop !== this.scrollTop
+ ) {
+ this.scrolling = true;
+ this.processScroll(e);
+ this.onEndScroll();
+ }
+ };
+
+ onTouchStart = e => {
+ const { nativeMobileScroll, stopPropagation } = this.props;
+ if (this.isDraggable(e.target)) {
+ if (nativeMobileScroll && this.scrolling) {
+ this.pressed = true;
+ } else {
+ const touch = e.touches[0];
+ this.processClick(e, touch.clientX, touch.clientY);
+ if (!nativeMobileScroll && stopPropagation) {
+ e.stopPropagation();
+ }
+ }
+ }
+ };
+
+ onTouchEnd = () => {
+ const { nativeMobileScroll } = this.props;
+ if (this.pressed) {
+ if (this.started && (!this.scrolling || !nativeMobileScroll)) {
+ this.processEnd();
+ } else {
+ this.pressed = false;
+ }
+ this.forceUpdate();
+ }
+ };
+
+ onTouchMove = e => {
+ const { nativeMobileScroll, stopPropagation } = this.props;
+ if (this.pressed && (!nativeMobileScroll || !this.isMobile)) {
+ const touch = e.touches[0];
+ if (touch) {
+ this.processMove(e, touch.clientX, touch.clientY);
+ }
+ e.preventDefault();
+ if (stopPropagation) {
+ e.stopPropagation();
+ }
+ }
+ };
+
+ onMouseDown = e => {
+ if (this.isDraggable(e.target) && this.isScrollable()) {
+ this.processClick(e, e.clientX, e.clientY);
+ e.preventDefault();
+ const { stopPropagation } = this.props;
+ if (stopPropagation) {
+ e.stopPropagation();
+ }
+ }
+ };
+
+ onMouseMove = e => {
+ if (this.pressed) {
+ this.processMove(e, e.clientX, e.clientY);
+ e.preventDefault();
+ const { stopPropagation } = this.props;
+ if (stopPropagation) {
+ e.stopPropagation();
+ }
+ }
+ };
+
+ onMouseUp = e => {
+ if (this.pressed) {
+ if (this.started) {
+ this.processEnd();
+ } else {
+ this.pressed = false;
+ this.forceUpdate();
+ const { onClick } = this.props;
+ if (onClick) {
+ onClick(e);
+ }
+ }
+ e.preventDefault();
+ const { stopPropagation } = this.props;
+ if (stopPropagation) {
+ e.stopPropagation();
+ }
+ }
+ };
+
+ getRef(el) {
+ const { innerRef } = this.props;
+ [this.container, innerRef].forEach(ref => {
+ if (ref) {
+ if (typeof ref === 'function') {
+ ref(el);
+ } else {
+ // eslint-disable-next-line no-param-reassign
+ ref.current = el;
+ }
+ }
+ });
+ }
+
+ generateClassNames = (className, hideScrollbars) => {
+ return `indiana-scroll-container ${className} ${
+ this.pressed ? 'indiana-scroll-container-dragging' : ''
+ } ${
+ this.pressed && hideScrollbars
+ ? 'indiana-scroll-container-dragging_hide-scrollbars'
+ : ''
+ } ${
+ this.pressed && this.isMobile
+ ? 'indiana-scroll-container-dragging_native-scroll'
+ : ''
+ }`;
+ };
+
+ processClick(e, clientX, clientY) {
+ const container = this.container.current;
+ this.scrollLeft = container.scrollLeft;
+ this.scrollTop = container.scrollTop;
+ this.clientX = clientX;
+ this.clientY = clientY;
+ this.pressed = true;
+ }
+
+ processStart(e, changeCursor = true) {
+ const { onStartScroll } = this.props;
+ const container = this.container.current;
+
+ this.started = true;
+
+ // Add the class to change displayed cursor
+ if (changeCursor) {
+ document.body.classList.add('indiana-dragging');
+ }
+
+ if (onStartScroll) {
+ onStartScroll(
+ container.scrollLeft,
+ container.scrollTop,
+ container.scrollWidth,
+ container.scrollHeight
+ );
+ }
+ this.forceUpdate();
+ }
+
+ // Process native scroll (scrollbar, mobile scroll)
+ processScroll(e) {
+ if (this.started) {
+ const { onScroll } = this.props;
+ const container = this.container.current;
+ if (onScroll) {
+ onScroll(
+ container.scrollLeft,
+ container.scrollTop,
+ container.scrollWidth,
+ container.scrollHeight
+ );
+ }
+ } else {
+ this.processStart(e, false);
+ }
+ }
+
+ // Process non-native scroll
+ processMove(e, newClientX, newClientY) {
+ const { horizontal, vertical, activationDistance, onScroll } = this.props;
+ const container = this.container.current;
+
+ if (!this.started) {
+ if (
+ (horizontal &&
+ Math.abs(newClientX - this.clientX) > activationDistance) ||
+ (vertical && Math.abs(newClientY - this.clientY) > activationDistance)
+ ) {
+ this.clientX = newClientX;
+ this.clientY = newClientY;
+ this.processStart();
+ }
+ } else {
+ if (horizontal) {
+ container.scrollLeft -= newClientX - this.clientX;
+ }
+ if (vertical) {
+ container.scrollTop -= newClientY - this.clientY;
+ }
+ if (onScroll) {
+ onScroll(
+ container.scrollLeft,
+ container.scrollTop,
+ container.scrollWidth,
+ container.scrollHeight
+ );
+ }
+ this.clientX = newClientX;
+ this.clientY = newClientY;
+ this.scrollLeft = container.scrollLeft;
+ this.scrollTop = container.scrollTop;
+ }
+ }
+
+ processEnd() {
+ const { onEndScroll } = this.props;
+ const container = this.container.current;
+
+ this.pressed = false;
+ this.started = false;
+ this.scrolling = false;
+
+ if (container && onEndScroll) {
+ onEndScroll(
+ container.scrollLeft,
+ container.scrollTop,
+ container.scrollWidth,
+ container.scrollHeight
+ );
+ }
+ document.body.classList.remove('indiana-dragging');
+ this.forceUpdate();
+ }
+
+ isMobileDevice() {
+ return (
+ typeof window.orientation !== 'undefined' ||
+ navigator.userAgent.indexOf('IEMobile') !== -1
+ );
+ }
+
+ isDraggable(target) {
+ const { ignoreElements } = this.props;
+ if (ignoreElements) {
+ const closest = target.closest(ignoreElements);
+ return closest === null || closest.contains(this.getElement());
+ }
+ return true;
+ }
+
+ isScrollable() {
+ const container = this.container.current;
+ return (
+ container &&
+ (container.scrollWidth > container.clientWidth ||
+ container.scrollHeight > container.clientHeight)
+ );
+ }
+
+ render() {
+ const {
+ children,
+ className,
+ style,
+ hideScrollbars,
+ component: Component
+ } = this.props;
+
+ return (
+ <Component
+ className={this.generateClassNames(className, hideScrollbars)}
+ style={style}
+ ref={this.getRef}
+ onScroll={this.onScroll}
+ >
+ {children}
+ </Component>
+ );
+ }
+}
+
+ScrollContainer.propTypes = {
+ vertical: PropTypes.bool,
+ horizontal: PropTypes.bool,
+ hideScrollbars: PropTypes.bool,
+ activationDistance: PropTypes.number,
+ children: PropTypes.node,
+ onStartScroll: PropTypes.func,
+ onScroll: PropTypes.func,
+ onEndScroll: PropTypes.func,
+ onClick: PropTypes.func,
+ className: PropTypes.string,
+ // eslint-disable-next-line react/forbid-prop-types
+ style: PropTypes.object,
+ ignoreElements: PropTypes.string,
+ nativeMobileScroll: PropTypes.bool,
+ stopPropagation: PropTypes.bool,
+ component: PropTypes.string,
+ innerRef: PropTypes.oneOfType([
+ PropTypes.func,
+ // eslint-disable-next-line react/forbid-prop-types
+ PropTypes.shape({ current: PropTypes.any })
+ ])
+};
+
+ScrollContainer.defaultProps = {
+ nativeMobileScroll: true,
+ hideScrollbars: true,
+ activationDistance: 10,
+ vertical: true,
+ horizontal: true,
+ stopPropagation: false,
+ style: {},
+ component: 'div'
+};
+
+export default ScrollContainer;
diff --git a/web-jspack/org.openbravo.core2/src/components/ScrollDrag/ScrollDrag.jsx b/web-jspack/org.openbravo.core2/src/components/ScrollDrag/ScrollDrag.jsx
new file mode 100644
index 00000000..5fb01d3a
--- /dev/null
+++ b/web-jspack/org.openbravo.core2/src/components/ScrollDrag/ScrollDrag.jsx
@@ -0,0 +1,71 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+class ScrollDrag extends React.Component {
+ constructor(props) {
+ super(props);
+ this.container = React.createRef();
+ this.state = {
+ isScrolling: false,
+ clientY: 0,
+ scrollY: 0
+ };
+ }
+
+ onMouseDown = e => {
+ this.setState(prevState => ({
+ ...prevState,
+ isScrolling: true,
+ clientY: e.clientY
+ }));
+ };
+
+ onMouseUp = () => {
+ this.setState(prevState => ({ ...prevState, isScrolling: false }));
+ };
+
+ onMouseMove = e => {
+ const { isScrolling, clientY, scrollY } = this.state;
+ if (isScrolling) {
+ this.container.scrollTop = scrollY + e.clientY - clientY;
+ this.state.scrollY = scrollY + e.clientY - clientY;
+ this.state.clientY = e.clientY;
+ }
+ };
+
+ render() {
+ const { key, variantClass, variantStyle, children } = this.props;
+ return (
+ // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
+ <div
+ key={key}
+ // eslint-disable-next-line no-return-assign
+ ref={el => (this.container = el)}
+ onMouseDown={this.onMouseDown}
+ onMouseUp={this.onMouseUp}
+ onMouseMove={this.onMouseMove}
+ role="group"
+ className={variantClass}
+ style={variantStyle}
+ >
+ {children}
+ </div>
+ );
+ }
+}
+
+ScrollDrag.defaultProps = {
+ key: null,
+ variantClass: '',
+ variantStyle: {},
+ children: null
+};
+
+ScrollDrag.propTypes = {
+ key: PropTypes.string,
+ variantClass: PropTypes.string,
+ variantStyle: PropTypes.objectOf(PropTypes.string),
+ children: PropTypes.node
+};
+
+export default ScrollDrag;
dragScroll_pos2.diff [^] (629 bytes) 2021-02-04 16:18 [Show Content] [Hide Content]diff --git a/web-jspack/org.openbravo.pos2/src/components/Ticket/TicketArea/TicketArea.config.json b/web-jspack/org.openbravo.pos2/src/components/Ticket/TicketArea/TicketArea.config.json
index 8d190f2e..a824ce07 100644
--- a/web-jspack/org.openbravo.pos2/src/components/Ticket/TicketArea/TicketArea.config.json
+++ b/web-jspack/org.openbravo.pos2/src/components/Ticket/TicketArea/TicketArea.config.json
@@ -19,6 +19,7 @@
"rowSpan": 1
},
"properties": {
+ "requiresScroll": true,
"testId":"obpos2TicketArea-ticketLines"
},
"variantClass": "obpos2TicketAreaLines"
|