Skip to content

Commit

Permalink
Merge branch 'master' into admin-ui-list-config-cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
timleslie authored May 5, 2020
2 parents b0de050 + c3270e5 commit 8dbeddc
Show file tree
Hide file tree
Showing 22 changed files with 341 additions and 296 deletions.
7 changes: 7 additions & 0 deletions .changeset/beige-dragons-jump.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@keystonejs/list-plugins': patch
---

Tweaked hooks and utility function.
* Renamed `composeResolveInput` utility function to `composeHook` to indicate right use by name, this can also be used in other hook type and not just `resolveInput` hook.
* Switch to use of `operation` param to hook for detecting if this is `create` or `update` operation instead of existingItem being `undefined`.
5 changes: 5 additions & 0 deletions .changeset/dirty-cougars-smoke.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@keystonejs/app-admin-ui': patch
---

Converted ResizeHandler and ScrollQuery components to custom hooks.
6 changes: 6 additions & 0 deletions .changeset/eighty-boxes-remember.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@keystonejs/keystone': patch
'@keystonejs/utils': patch
---

Converted some stray promise chains to async/await.
10 changes: 10 additions & 0 deletions .changeset/long-adults-travel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'@keystonejs/cypress-project-access-control': patch
'@keystonejs/cypress-project-basic': patch
'@keystonejs/cypress-project-client-validation': patch
'@keystonejs/cypress-project-login': patch
'@keystonejs/keystone': major
'@keystonejs/session': major
---

The `cookieSecret` option no longer defaults to a static value. It is now required in production mode. In development mode, if undefined, a random new value is generated each time the server is started.
5 changes: 5 additions & 0 deletions .changeset/tasty-numbers-turn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@keystonejs/app-admin-ui': major
---

Removed the method `AdminUIApp.getAdminMeta()` in favour of the more complete `AdminUIApp.getAdminUIMeta(keystone)`.
179 changes: 96 additions & 83 deletions packages/app-admin-ui/client/components/Nav/ResizeHandler.js
Original file line number Diff line number Diff line change
@@ -1,115 +1,128 @@
import { Component } from 'react';
import { useState, useRef, useEffect } from 'react';
import raf from 'raf-schd';

import { withKeyboardConsumer } from '../KeyboardShortcuts';
import { useKeyboardManager } from '../KeyboardShortcuts';

const LS_KEY = 'KEYSTONE_NAVIGATION_STATE';
const DEFAULT_STATE = { isCollapsed: false, width: 280 };
const MIN_WIDTH = 140;
const MAX_WIDTH = 800;

export const KEYBOARD_SHORTCUT = '[';

function getCache() {
if (typeof localStorage !== 'undefined') {
const getCache = () => {
if (localStorage !== undefined) {
const stored = localStorage.getItem(LS_KEY);
return stored ? JSON.parse(stored) : DEFAULT_STATE;

if (stored) {
return JSON.parse(stored);
}
}

return DEFAULT_STATE;
}
function setCache(state) {
if (typeof localStorage !== 'undefined') {
};

const setCache = state => {
if (localStorage !== undefined) {
localStorage.setItem(LS_KEY, JSON.stringify(state));
}
}
};

class ResizeHandler extends Component {
state = getCache();
export const useResizeHandler = () => {
// TODO: should we be calling this in the function body?
const { width: cachedWidth, isCollapsed: cachedIsCollapsed } = getCache();

componentDidMount() {
this.props.keyManager.subscribe(KEYBOARD_SHORTCUT, this.toggleCollapse);
}
componentWillUnmount() {
this.props.keyManager.unsubscribe(KEYBOARD_SHORTCUT);
}
// These should trigger renders
const [width, setWidth] = useState(cachedWidth);
const [isCollapsed, setIsCollapsed] = useState(cachedIsCollapsed);
const [isMouseDown, setIsMouseDown] = useState(false);
const [isDragging, setIsDragging] = useState(false);

storeState = s => {
// only keep the `isCollapsed` and `width` properties in locals storage
const isCollapsed = s.isCollapsed !== undefined ? s.isCollapsed : this.state.isCollapsed;
const width = s.width !== undefined ? s.width : this.state.width;
// Internal state tracking
const initialX = useRef();
const initialWidth = useRef();

setCache({ isCollapsed, width });
const { addBinding, removeBinding } = useKeyboardManager();

this.setState(s);
};
useEffect(() => {
addBinding(KEYBOARD_SHORTCUT, toggleCollapse);
return () => {
removeBinding(KEYBOARD_SHORTCUT);
};
}, []);

useEffect(() => {
const handleResize = raf(event => {
// on occasion a mouse move event occurs before the event listeners have a chance to detach
if (!isMouseDown) return;

// initialize dragging
if (!isDragging) {
setIsDragging(true);
initialWidth.current = width;
return;
}

// allow the product nav to be 75% of the available page width
const adjustedMax = MAX_WIDTH - initialWidth.current;
const adjustedMin = MIN_WIDTH - initialWidth.current;

const newDelta = Math.max(Math.min(event.pageX - initialX.current, adjustedMax), adjustedMin);
const newWidth = initialWidth.current + newDelta;

setWidth(newWidth);
});

const handleResizeEnd = () => {
// reset non-width states
setIsDragging(false);
setIsMouseDown(false);
};

window.addEventListener('mousemove', handleResize, { passive: true });
window.addEventListener('mouseup', handleResizeEnd, { passive: true });

return () => {
window.removeEventListener('mousemove', handleResize, { passive: true });
window.removeEventListener('mouseup', handleResizeEnd, { passive: true });
};
}, [isMouseDown, isDragging]);

// Only keep the `isCollapsed` and `width` properties in locals storage
useEffect(() => {
setCache({ isCollapsed, width });
}, [isCollapsed, width]);

handleResizeStart = (event: MouseEvent) => {
const handleResizeStart = event => {
// bail if not "left click"
if (event.button && event.button > 0) return;

// initialize resize gesture
this.setState({ initialX: event.pageX, mouseIsDown: true });

// attach handlers (handleResizeStart is a bound to onMouseDown)
window.addEventListener('mousemove', this.handleResize);
window.addEventListener('mouseup', this.handleResizeEnd);
initialX.current = event.pageX;
setIsMouseDown(true);
};

initializeDrag = () => {
let initialWidth = this.state.width;

this.setState({ initialWidth, isDragging: true });
const toggleCollapse = () => {
setIsCollapsed(prevCollapsed => !prevCollapsed);
};

handleResize = raf((event: MouseEvent) => {
const { initialX, initialWidth, isDragging, mouseIsDown } = this.state;

// on occasion a mouse move event occurs before the event listeners
// have a chance to detach
if (!mouseIsDown) return;

// initialize dragging
if (!isDragging) {
this.initializeDrag(event);
return;
}

// allow the product nav to be 75% of the available page width
const adjustedMax = MAX_WIDTH - initialWidth;
const adjustedMin = MIN_WIDTH - initialWidth;

const delta = Math.max(Math.min(event.pageX - initialX, adjustedMax), adjustedMin);
const width = initialWidth + delta;

this.setState({ delta, width });
});
handleResizeEnd = () => {
// reset non-width states
this.setState({ delta: 0, isDragging: false, mouseIsDown: false });

// store the width
this.storeState({ width: this.state.width });

// cleanup
window.removeEventListener('mousemove', this.handleResize);
window.removeEventListener('mouseup', this.handleResizeEnd);
};
toggleCollapse = () => {
const isCollapsed = !this.state.isCollapsed;
this.storeState({ isCollapsed });
const resizeProps = {
title: 'Drag to Resize',
onMouseDown: handleResizeStart,
};

render() {
const resizeProps = {
title: 'Drag to Resize',
onMouseDown: this.handleResizeStart,
};
const clickProps = {
onClick: this.toggleCollapse,
};
const snapshot = this.state;
const clickProps = {
onClick: toggleCollapse,
};

return this.props.children(resizeProps, clickProps, snapshot);
}
}
const snapshot = {
width,
isCollapsed,
isMouseDown,
isDragging,
initialX: initialX.current,
initialWidth: initialWidth.current,
};

export default withKeyboardConsumer(ResizeHandler);
return { resizeProps, clickProps, snapshot };
};
Loading

0 comments on commit 8dbeddc

Please sign in to comment.