Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Copy Paste Data #2928

Merged
merged 17 commits into from
Dec 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/zui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"start:main": "yarn build:main --watch",
"start:renderer": "next dev -p 4567",
"start:electron": "nodemon --watch dist ../../node_modules/electron/cli.js .",
"start:production": "node ../../node_modules/electron/cli.js .",
"watch-code": "run-p start:main start:renderer",
"build": "run-p -l 'build:**'",
"build:main": "node scripts/esbuild.mjs",
Expand Down
35 changes: 35 additions & 0 deletions apps/zui/src/app/routes/app-wrapper/data-dropzone-controller.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import {previewLoadFiles, quickLoadFiles} from "src/domain/loads/handlers"

export class DataDropzoneController {
constructor(
private shift: boolean,
private previewing: boolean,
private poolId: string
) {}

// prettier-ignore
get title() {
if (this.previewing) return (<>Add <em>Files</em></>)
if (this.shift) return (<>Quick Load <em>Data</em></>)
return <>Preview & Load <em>Data</em></>
}

// prettier-ignore
get note() {
if (this.previewing) return null
if (this.shift) return <>Release <b>{"Shift"}</b> to preview data first.</>
return <>Hold <b>{"Shift"}</b> to quick load into new pool with defaults.</>
}

onDrop(fileObjects: File[]) {
const files = fileObjects.map((f) => f.path)
const poolId = this.poolId
if (this.previewing) {
previewLoadFiles({files, poolId})
} else if (this.shift) {
quickLoadFiles({files})
} else {
previewLoadFiles({files, poolId})
}
}
}
34 changes: 19 additions & 15 deletions apps/zui/src/app/routes/app-wrapper/data-dropzone.module.css
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
.dropzone {
position: relative;
position: relative;
}

.overlay {
width: 100%;
height: 100%;
z-index: 3;
width: 100vw;
height: 100vh;
max-width: none;
max-height: none;
border: none;
background: var(--orange);
position: absolute;
position: fixed;
top: 0;
left:0;
right:0;
bottom:0;
left: 0;
right: 0;
bottom: 0;
display: flex;
align-items: center;
justify-content: center;
Expand All @@ -24,16 +26,16 @@
flex-direction: column;
gap: 1em;
animation:
700ms popup cubic-bezier(0.16, 1, 0.3, 1) forwards,
300ms fade-opacity ease-in forwards;
700ms popup cubic-bezier(0.16, 1, 0.3, 1) forwards,
300ms fade-opacity ease-in forwards;
}

.title {
font-size: 60px;
font-weight: 900;
text-align: center;
color: white;

margin: 0;
}

Expand All @@ -58,11 +60,12 @@
border-radius: 3px;
margin: 0 0.2em;
border: 1px solid rgba(255, 255, 255, 0.2);
box-shadow: 0 1px 1px 0 rgba(0,0,0,0.1);
box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1);
text-transform: uppercase;
font-size: 0.85em;
font-weight: 500;
letter-spacing: 1px;;
letter-spacing: 1px;
;

}

Expand All @@ -72,7 +75,6 @@
height: 3rem;
margin: 0;
animation: 700ms margin-in cubic-bezier(0.16, 1, 0.3, 1) forwards

}

.hair div:first-child {
Expand Down Expand Up @@ -119,6 +121,7 @@
from {
opacity: 0;
}

to {
opacity: 1;
}
Expand All @@ -137,7 +140,8 @@
@keyframes margin-in {
from {
margin: 0;
}
}

to {
margin: 10vmin;
}
Expand Down
72 changes: 18 additions & 54 deletions apps/zui/src/app/routes/app-wrapper/data-dropzone.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,22 @@
import styles from "./data-dropzone.module.css"
import {useFilesDrop} from "src/util/hooks/use-files-drop"
import usePoolId from "src/app/router/hooks/use-pool-id"
import {previewLoadFiles, quickLoadFiles} from "src/domain/loads/handlers"
import useListener from "src/js/components/hooks/useListener"
import {useEffect, useState} from "react"
import {Dialog} from "src/components/dialog"
import LoadDataForm from "src/js/state/LoadDataForm"
import {useSelector} from "react-redux"
import {DataDropzoneController} from "./data-dropzone-controller"

export function DataDropzone({children}) {
const poolId = usePoolId()
const [shiftKey, setShiftKey] = useState(false)
const onDrop = async (webFiles: File[]) => {
const files = webFiles.map((f) => f.path)
if (shiftKey) {
quickLoadFiles({files})
} else {
previewLoadFiles({files, poolId})
}
}

let [props, ref] = useFilesDrop({onDrop})
const previewing = useSelector(LoadDataForm.getShow)
const dropzone = new DataDropzoneController(shiftKey, previewing, poolId)
let [props, ref] = useFilesDrop({onDrop: (files) => dropzone.onDrop(files)})

useListener(document.body, "dragover", (e: KeyboardEvent) => {
if (!props.isOver) return
setShiftKey(e.shiftKey)
if (props.isOver) setShiftKey(e.shiftKey)
})

useEffect(() => {
Expand All @@ -32,49 +27,18 @@ export function DataDropzone({children}) {
<div className={styles.dropzone} ref={ref}>
{children}
{props.isOver && (
<div className={styles.overlay}>
<div className={styles.hair}>
<div />
<div />
</div>
<div className={styles.hair}>
<div />
<div />
</div>
<div className={styles.hair}>
<div />
<div />
</div>
<div className={styles.hair}>
<div />
<div />
</div>
<Dialog modal isOpen className={styles.overlay}>
{[1, 2, 3, 4].map((i) => (
<div className={styles.hair} key={i}>
<div />
<div />
</div>
))}
<div className={styles.message}>
<h1 className={styles.title}>
{shiftKey ? (
<>
Quick Load <em>Data</em>
</>
) : (
<>
Preview & Load <em>Data</em>
</>
)}
</h1>
<p className={styles.note}>
{shiftKey ? (
<>
Release <b>{"Shift"}</b> to preview data first.
</>
) : (
<>
Hold <b>{"Shift"}</b> to quick load into new pool with
defaults.
</>
)}
</p>
<h1 className={styles.title}>{dropzone.title}</h1>
<p className={styles.note}>{dropzone.note}</p>
</div>
</div>
</Dialog>
)}
</div>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import {HTMLAttributes, MouseEventHandler} from "react"
import {usePosition} from "./use-position"
import {useOpener} from "./use-opener"
import {useOutsideClick} from "./use-outside-click"
import useCallbackRef from "src/js/components/hooks/useCallbackRef"
import {omit} from "lodash"
import {call} from "src/util/call"
import {useFixedPosition} from "src/util/hooks/use-fixed-position"

export type DialogProps = {
isOpen: boolean
onClose: () => void
onClose?: () => void
onCancel?: () => void
modal?: boolean
onOutsideClick?: (e: globalThis.MouseEvent) => void
onClick?: MouseEventHandler<HTMLDialogElement>
Expand All @@ -34,21 +36,33 @@ const nonHTMLProps: (keyof DialogProps)[] = [

export function Dialog(props: DialogProps) {
const [node, setNode] = useCallbackRef<HTMLDialogElement>()
const style = usePosition(node, props)

useOpener(node, props)
useOpener(node, props) // Make sure we open it before positioning it
useOutsideClick(node, props)
const style = useFixedPosition({
anchor: props.anchor,
anchorPoint: props.anchorPoint,
target: node && props.isOpen ? node : null,
targetPoint: props.dialogPoint,
targetMargin: props.dialogMargin,
keepOnScreen: props.keepOnScreen,
})

function onClose(e) {
e.preventDefault()
props.onClose()
call(props.onClose)
}

function onCancel(e) {
e.preventDefault()
call(props.onCancel)
call(props.onClose)
}

return (
<dialog
// @ts-ignore
onClose={onClose}
onCancel={onClose}
onCancel={onCancel}
ref={setNode}
style={style}
{...omit(props, ...nonHTMLProps)}
Expand Down
27 changes: 0 additions & 27 deletions apps/zui/src/components/dialog/parse-margin.ts

This file was deleted.

14 changes: 0 additions & 14 deletions apps/zui/src/components/dialog/parse-point.ts

This file was deleted.

2 changes: 1 addition & 1 deletion apps/zui/src/components/dialog/use-opener.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {useLayoutEffect} from "react"
import {DialogProps} from "./dialog"
import {DialogProps} from "."

export function useOpener(dialog: HTMLDialogElement, props: DialogProps) {
useLayoutEffect(() => {
Expand Down
2 changes: 1 addition & 1 deletion apps/zui/src/components/dialog/use-outside-click.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {useEffect, useRef} from "react"
import {clickIsWithinElement} from "./click-is-within-element"
import {DialogProps} from "./dialog"
import {DialogProps} from "."

export function useOutsideClick(dialog: HTMLDialogElement, props: DialogProps) {
const callback = useRef<(e: globalThis.MouseEvent) => void>(() => {})
Expand Down
Loading
Loading