Added new background pattern to automation screen with some UI tweaks
This commit is contained in:
parent
d3cda128cb
commit
89e8e1e2ad
|
@ -7,6 +7,7 @@
|
||||||
onDestroy,
|
onDestroy,
|
||||||
tick,
|
tick,
|
||||||
} from "svelte"
|
} from "svelte"
|
||||||
|
import Logo from "assets/bb-emblem.svg?raw"
|
||||||
import { Utils } from "@budibase/frontend-core"
|
import { Utils } from "@budibase/frontend-core"
|
||||||
import { selectedAutomation, automationStore } from "stores/builder"
|
import { selectedAutomation, automationStore } from "stores/builder"
|
||||||
import { memo } from "@budibase/frontend-core"
|
import { memo } from "@budibase/frontend-core"
|
||||||
|
@ -15,17 +16,19 @@
|
||||||
viewToFocusEle()
|
viewToFocusEle()
|
||||||
}
|
}
|
||||||
|
|
||||||
export function zoomIn() {
|
export async function zoomIn() {
|
||||||
const scale = parseFloat(Math.min($view.scale + 0.1, 1.5).toFixed(2))
|
const newScale = parseFloat(Math.min($view.scale + 0.1, 1.5).toFixed(2))
|
||||||
|
if ($view.scale === 1.5) return
|
||||||
|
|
||||||
view.update(state => ({
|
view.update(state => ({
|
||||||
...state,
|
...state,
|
||||||
scale,
|
scale: newScale,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
export function zoomOut() {
|
export function zoomOut() {
|
||||||
const scale = parseFloat(Math.max($view.scale - 0.1, 0.1).toFixed(2))
|
const scale = parseFloat(Math.max($view.scale - 0.1, 0.1).toFixed(2))
|
||||||
|
if ($view.scale === 0.1) return
|
||||||
|
|
||||||
view.update(state => ({
|
view.update(state => ({
|
||||||
...state,
|
...state,
|
||||||
|
@ -45,6 +48,8 @@
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
}))
|
}))
|
||||||
|
offsetX = 0
|
||||||
|
offsetY = 0
|
||||||
view.update(state => ({
|
view.update(state => ({
|
||||||
...state,
|
...state,
|
||||||
scale: 1,
|
scale: 1,
|
||||||
|
@ -82,6 +87,7 @@
|
||||||
scrollX: 0,
|
scrollX: 0,
|
||||||
scrollY: 0,
|
scrollY: 0,
|
||||||
}))
|
}))
|
||||||
|
offsetY = parseInt(0 + adjustedY)
|
||||||
}
|
}
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
@ -110,10 +116,6 @@
|
||||||
})
|
})
|
||||||
setContext("contentPos", contentPos)
|
setContext("contentPos", contentPos)
|
||||||
|
|
||||||
$: if ($view || contentDims) {
|
|
||||||
window.testValues = { ...$view, contentDims }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Elements
|
// Elements
|
||||||
let mainContent
|
let mainContent
|
||||||
let viewPort
|
let viewPort
|
||||||
|
@ -140,17 +142,31 @@
|
||||||
// Auto scroll
|
// Auto scroll
|
||||||
let scrollInterval
|
let scrollInterval
|
||||||
|
|
||||||
let zoomOrigin = []
|
|
||||||
|
|
||||||
// Used to track where the draggable item is scrolling into
|
// Used to track where the draggable item is scrolling into
|
||||||
let scrollZones
|
let scrollZones
|
||||||
|
|
||||||
|
// Used to track the movements of the dragged content
|
||||||
|
// This allows things like the background to have their own starting coords
|
||||||
|
let offsetX = 0
|
||||||
|
let offsetY = 0
|
||||||
|
|
||||||
// Focus element details. Used to move the viewport
|
// Focus element details. Used to move the viewport
|
||||||
let focusElement = memo()
|
let focusElement = memo()
|
||||||
|
|
||||||
// Memo Focus
|
// Memo Focus
|
||||||
$: focusElement.set($view.focusEle)
|
$: focusElement.set($view.focusEle)
|
||||||
|
|
||||||
|
// Background pattern
|
||||||
|
let bgDim = 24
|
||||||
|
|
||||||
|
// Scale prop for the icon
|
||||||
|
let dotDefault = 0.006
|
||||||
|
|
||||||
|
$: bgSize = Math.max(bgDim * $view.scale, 10)
|
||||||
|
$: bgWidth = bgSize
|
||||||
|
$: bgHeight = bgSize
|
||||||
|
$: dotSize = Math.max(dotDefault * $view.scale, dotDefault)
|
||||||
|
|
||||||
const onScale = async () => {
|
const onScale = async () => {
|
||||||
dispatch("zoom", $view.scale)
|
dispatch("zoom", $view.scale)
|
||||||
await getDims()
|
await getDims()
|
||||||
|
@ -184,10 +200,9 @@
|
||||||
return { x: Math.max(x, 0), y: Math.max(y, 0) }
|
return { x: Math.max(x, 0), y: Math.max(y, 0) }
|
||||||
}
|
}
|
||||||
|
|
||||||
const buildWrapStyles = (pos, scale, dims, contentCursor) => {
|
const buildWrapStyles = (pos, scale, dims) => {
|
||||||
const { x, y } = pos
|
const { x, y } = pos
|
||||||
const { w, h } = dims
|
const { w, h } = dims
|
||||||
const [cursorContentX, cursorContentY] = contentCursor
|
|
||||||
return `
|
return `
|
||||||
--posX: ${x}px; --posY: ${y}px;
|
--posX: ${x}px; --posY: ${y}px;
|
||||||
--scale: ${scale};
|
--scale: ${scale};
|
||||||
|
@ -216,6 +231,8 @@
|
||||||
}
|
}
|
||||||
: {}),
|
: {}),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
offsetX = offsetX - xBump
|
||||||
} else if (e.ctrlKey || e.metaKey) {
|
} else if (e.ctrlKey || e.metaKey) {
|
||||||
// Scale the content on scrolling
|
// Scale the content on scrolling
|
||||||
let updatedScale
|
let updatedScale
|
||||||
|
@ -242,6 +259,7 @@
|
||||||
}
|
}
|
||||||
: {}),
|
: {}),
|
||||||
}))
|
}))
|
||||||
|
offsetY = offsetY - yBump
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,6 +282,8 @@
|
||||||
x: x - dragOffset[0],
|
x: x - dragOffset[0],
|
||||||
y: y - dragOffset[1],
|
y: y - dragOffset[1],
|
||||||
}))
|
}))
|
||||||
|
offsetX = x - dragOffset[0]
|
||||||
|
offsetY = y - dragOffset[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
const clearScrollInterval = () => {
|
const clearScrollInterval = () => {
|
||||||
|
@ -310,6 +330,8 @@
|
||||||
scrollX: state.scrollX + xInterval,
|
scrollX: state.scrollX + xInterval,
|
||||||
scrollY: state.scrollY + yInterval,
|
scrollY: state.scrollY + yInterval,
|
||||||
}))
|
}))
|
||||||
|
offsetX = offsetX + xInterval
|
||||||
|
offsetY = offsetY + yInterval
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,8 +420,6 @@
|
||||||
if (!viewPort) {
|
if (!viewPort) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Update viewDims to get the latest viewport dimensions
|
|
||||||
viewDims = viewPort.getBoundingClientRect()
|
|
||||||
|
|
||||||
if ($view.moveStep && $view.dragging === false) {
|
if ($view.moveStep && $view.dragging === false) {
|
||||||
view.update(state => ({
|
view.update(state => ({
|
||||||
|
@ -499,12 +519,7 @@
|
||||||
|
|
||||||
// Content mouse pos and scale to css variables.
|
// Content mouse pos and scale to css variables.
|
||||||
// The wrap is set to match the content size
|
// The wrap is set to match the content size
|
||||||
$: wrapStyles = buildWrapStyles(
|
$: wrapStyles = buildWrapStyles($contentPos, $view.scale, contentDims)
|
||||||
$contentPos,
|
|
||||||
$view.scale,
|
|
||||||
contentDims,
|
|
||||||
zoomOrigin
|
|
||||||
)
|
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
// As the view/browser resizes, ensure the stored view is up to date
|
// As the view/browser resizes, ensure the stored view is up to date
|
||||||
|
@ -535,6 +550,20 @@
|
||||||
on:mousemove={Utils.domDebounce(onMouseMove)}
|
on:mousemove={Utils.domDebounce(onMouseMove)}
|
||||||
style={`--dragPadding: ${contentDragPadding}px;`}
|
style={`--dragPadding: ${contentDragPadding}px;`}
|
||||||
>
|
>
|
||||||
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
|
<svg class="draggable-background" style={`--dotSize: ${dotSize};`}>
|
||||||
|
<!-- Small 2px offset to tuck the points under the viewport on load-->
|
||||||
|
<pattern
|
||||||
|
id="dot-pattern"
|
||||||
|
width={bgWidth}
|
||||||
|
height={bgHeight}
|
||||||
|
patternUnits="userSpaceOnUse"
|
||||||
|
patternTransform={`translate(${offsetX - 2}, ${offsetY - 2})`}
|
||||||
|
>
|
||||||
|
{@html Logo}
|
||||||
|
</pattern>
|
||||||
|
<rect x="0" y="0" width="100%" height="100%" fill="url(#dot-pattern)" />
|
||||||
|
</svg>
|
||||||
<!-- svelte-ignore a11y-mouse-events-have-key-events -->
|
<!-- svelte-ignore a11y-mouse-events-have-key-events -->
|
||||||
<div
|
<div
|
||||||
class="draggable-view"
|
class="draggable-view"
|
||||||
|
@ -582,6 +611,7 @@
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
.content {
|
.content {
|
||||||
|
transform-origin: 50% 50%;
|
||||||
transform: scale(var(--scale));
|
transform: scale(var(--scale));
|
||||||
user-select: none;
|
user-select: none;
|
||||||
padding: var(--dragPadding);
|
padding: var(--dragPadding);
|
||||||
|
@ -602,13 +632,22 @@
|
||||||
cursor: grabbing;
|
cursor: grabbing;
|
||||||
}
|
}
|
||||||
|
|
||||||
.debug {
|
.draggable-background {
|
||||||
display: flex;
|
position: absolute;
|
||||||
align-items: center;
|
width: 100%;
|
||||||
gap: 8px;
|
height: 100%;
|
||||||
position: fixed;
|
top: 0;
|
||||||
padding: var(--spacing-l);
|
left: 0;
|
||||||
z-index: 2;
|
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
z-index: -1;
|
||||||
|
background-color: var(--spectrum-global-color-gray-50);
|
||||||
|
}
|
||||||
|
|
||||||
|
.draggable-background :global(svg g path) {
|
||||||
|
fill: #91919a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.draggable-background :global(svg g) {
|
||||||
|
transform: scale(var(--dotSize));
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
import ConfirmDialog from "components/common/ConfirmDialog.svelte"
|
import ConfirmDialog from "components/common/ConfirmDialog.svelte"
|
||||||
import TestDataModal from "./TestDataModal.svelte"
|
import TestDataModal from "./TestDataModal.svelte"
|
||||||
import {
|
import {
|
||||||
Icon,
|
|
||||||
notifications,
|
notifications,
|
||||||
Modal,
|
Modal,
|
||||||
Toggle,
|
Toggle,
|
||||||
|
@ -100,15 +99,18 @@
|
||||||
Run test
|
Run test
|
||||||
</Button>
|
</Button>
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<Icon disabled={!$automationStore.testResults} size="M" name="Multiple" />
|
{#if !$automationStore.showTestPanel && $automationStore.testResults}
|
||||||
<div
|
<Button
|
||||||
class:disabled={!$automationStore.testResults}
|
secondary
|
||||||
on:click={() => {
|
icon={"Multiple"}
|
||||||
$automationStore.showTestPanel = true
|
disabled={!$automationStore.testResults}
|
||||||
}}
|
on:click={() => {
|
||||||
>
|
$automationStore.showTestPanel = true
|
||||||
Test details
|
}}
|
||||||
</div>
|
>
|
||||||
|
Test details
|
||||||
|
</Button>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{#if !isRowAction}
|
{#if !isRowAction}
|
||||||
<div class="toggle-active setting-spacing">
|
<div class="toggle-active setting-spacing">
|
||||||
|
@ -168,9 +170,6 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
max-height: 100%;
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-left {
|
.header-left {
|
||||||
|
@ -210,15 +209,26 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding-left: var(--spacing-l);
|
padding: var(--spacing-l);
|
||||||
transition: background 130ms ease-out;
|
|
||||||
flex: 0 0 60px;
|
flex: 0 0 60px;
|
||||||
padding-right: var(--spacing-xl);
|
padding-right: var(--spacing-xl);
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header > * {
|
||||||
|
pointer-events: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.controls {
|
.controls {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: var(--spacing-xl);
|
gap: var(--spacing-l);
|
||||||
|
}
|
||||||
|
|
||||||
|
.controls .toggle-active :global(.spectrum-Switch-label) {
|
||||||
|
margin-right: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.buttons {
|
.buttons {
|
||||||
|
@ -232,11 +242,6 @@
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.disabled {
|
|
||||||
pointer-events: none;
|
|
||||||
color: var(--spectrum-global-color-gray-500) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.group {
|
.group {
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
Loading…
Reference in New Issue