Merge branch 'master' of github.com:Budibase/budibase into new-data-ui
This commit is contained in:
commit
1bbbeab25b
|
@ -65,7 +65,7 @@ Budibase is open-source - licensed as GPL v3. This should fill you with confiden
|
|||
<br /><br />
|
||||
|
||||
### Load data or start from scratch
|
||||
Budibase pulls data from multiple sources, including MongoDB, CouchDB, PostgreSQL, MySQL, Airtable, S3, DynamoDB, or a REST API. And unlike other platforms, with Budibase you can start from scratch and create business apps with no data sources. [Request new datasources](https://github.com/Budibase/budibase/discussions?discussions_q=category%3AIdeas).
|
||||
Budibase pulls data from multiple sources, including MongoDB, CouchDB, PostgreSQL, MariaDB, MySQL, Airtable, S3, DynamoDB, or a REST API. And unlike other platforms, with Budibase you can start from scratch and create business apps with no data sources. [Request new datasources](https://github.com/Budibase/budibase/discussions?discussions_q=category%3AIdeas).
|
||||
|
||||
<p align="center">
|
||||
<img alt="Budibase data" src="https://res.cloudinary.com/daog6scxm/image/upload/v1680281798/ui/data_klbuna.png">
|
||||
|
|
|
@ -153,7 +153,7 @@
|
|||
$: builderInteractive =
|
||||
$builderStore.inBuilder && insideScreenslot && !isBlock && !instance.static
|
||||
$: devToolsInteractive = $devToolsStore.allowSelection && !isBlock
|
||||
$: interactive = !isRoot && (builderInteractive || devToolsInteractive)
|
||||
$: interactive = builderInteractive || devToolsInteractive
|
||||
$: editing = editable && selected && $builderStore.editMode
|
||||
$: draggable =
|
||||
!inDragPath &&
|
||||
|
@ -189,12 +189,6 @@
|
|||
// Scroll the selected element into view
|
||||
$: selected && scrollIntoView()
|
||||
|
||||
// When dragging and dropping, pad components to allow dropping between
|
||||
// nested layers. Only reset this when dragging stops.
|
||||
let pad = false
|
||||
$: pad = pad || (interactive && hasChildren && inDndPath)
|
||||
$: $dndIsDragging, (pad = false)
|
||||
|
||||
// Themes
|
||||
$: currentTheme = $context?.device?.theme
|
||||
$: darkMode = !currentTheme?.includes("light")
|
||||
|
@ -206,8 +200,10 @@
|
|||
}
|
||||
|
||||
// Metadata to pass into grid action to apply CSS
|
||||
const insideGrid =
|
||||
parent?._component.endsWith("/container") && parent?.layout === "grid"
|
||||
const checkGrid = x =>
|
||||
x?._component.endsWith("/container") && x?.layout === "grid"
|
||||
$: insideGrid = checkGrid(parent)
|
||||
$: isGrid = checkGrid(instance)
|
||||
$: gridMetadata = {
|
||||
insideGrid,
|
||||
ignoresLayout: definition?.ignoresLayout === true,
|
||||
|
@ -219,6 +215,12 @@
|
|||
errored: errorState,
|
||||
}
|
||||
|
||||
// When dragging and dropping, pad components to allow dropping between
|
||||
// nested layers. Only reset this when dragging stops.
|
||||
let pad = false
|
||||
$: pad = pad || (!isGrid && interactive && hasChildren && inDndPath)
|
||||
$: $dndIsDragging, (pad = false)
|
||||
|
||||
// Update component context
|
||||
$: store.set({
|
||||
id,
|
||||
|
@ -231,12 +233,14 @@
|
|||
empty: emptyState,
|
||||
selected,
|
||||
interactive,
|
||||
isRoot,
|
||||
draggable,
|
||||
editable,
|
||||
isBlock,
|
||||
},
|
||||
empty: emptyState,
|
||||
selected,
|
||||
isRoot,
|
||||
inSelectedPath,
|
||||
name,
|
||||
editing,
|
||||
|
@ -672,6 +676,7 @@
|
|||
class:parent={hasChildren}
|
||||
class:block={isBlock}
|
||||
class:error={errorState}
|
||||
class:root={isRoot}
|
||||
data-id={id}
|
||||
data-name={name}
|
||||
data-icon={icon}
|
||||
|
|
|
@ -18,9 +18,11 @@
|
|||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
align-items: flex-start;
|
||||
color: var(--spectrum-global-color-gray-600);
|
||||
font-size: var(--font-size-s);
|
||||
gap: var(--spacing-s);
|
||||
grid-column: 1 / -1;
|
||||
grid-row: 1 / -1;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
align-items: center;
|
||||
gap: var(--spacing-s);
|
||||
flex: 1 1 auto;
|
||||
grid-column: 1 / -1;
|
||||
grid-row: 1 / -1;
|
||||
}
|
||||
.placeholder :global(.spectrum-Button) {
|
||||
margin-top: var(--spacing-m);
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
$: availableRows = Math.floor(height / GridRowHeight)
|
||||
$: rows = Math.max(requiredRows, availableRows)
|
||||
$: mobile = $context.device.mobile
|
||||
$: empty = $component.empty
|
||||
$: colSize = width / GridColumns
|
||||
$: styles.set({
|
||||
...$component.styles,
|
||||
|
@ -40,7 +39,6 @@
|
|||
"--col-size": colSize,
|
||||
"--row-size": GridRowHeight,
|
||||
},
|
||||
empty: false,
|
||||
})
|
||||
|
||||
// Calculates the minimum number of rows required to render all child
|
||||
|
@ -145,9 +143,7 @@
|
|||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Only render the slot if not empty, as we don't want the placeholder -->
|
||||
{#if !empty && mounted}
|
||||
{#if mounted}
|
||||
<slot />
|
||||
{/if}
|
||||
</div>
|
||||
|
|
|
@ -6,8 +6,11 @@
|
|||
let left, top, height, width
|
||||
|
||||
const updatePosition = () => {
|
||||
const node =
|
||||
document.getElementsByClassName(DNDPlaceholderID)[0]?.childNodes[0]
|
||||
let node = document.getElementsByClassName(DNDPlaceholderID)[0]
|
||||
const insideGrid = node?.dataset.insideGrid === "true"
|
||||
if (!insideGrid) {
|
||||
node = document.getElementsByClassName(`${DNDPlaceholderID}-dom`)[0]
|
||||
}
|
||||
if (!node) {
|
||||
height = 0
|
||||
width = 0
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
newId = e.target.dataset.id
|
||||
} else {
|
||||
// Handle normal components
|
||||
const element = e.target.closest(".interactive.component")
|
||||
const element = e.target.closest(".interactive.component:not(.root)")
|
||||
newId = element?.dataset?.id
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { writable } from "svelte/store"
|
||||
import { computed } from "../utils/computed.js"
|
||||
import { derivedMemo } from "@budibase/frontend-core"
|
||||
|
||||
const createDndStore = () => {
|
||||
const initialState = {
|
||||
|
@ -78,11 +78,11 @@ export const dndStore = createDndStore()
|
|||
// performance by deriving any state that needs to be externally observed.
|
||||
// By doing this and using primitives, we can avoid invalidating other stores
|
||||
// or components which depend on DND state unless values actually change.
|
||||
export const dndParent = computed(dndStore, x => x.drop?.parent)
|
||||
export const dndIndex = computed(dndStore, x => x.drop?.index)
|
||||
export const dndBounds = computed(dndStore, x => x.source?.bounds)
|
||||
export const dndIsDragging = computed(dndStore, x => !!x.source)
|
||||
export const dndIsNewComponent = computed(
|
||||
export const dndParent = derivedMemo(dndStore, x => x.drop?.parent)
|
||||
export const dndIndex = derivedMemo(dndStore, x => x.drop?.index)
|
||||
export const dndBounds = derivedMemo(dndStore, x => x.source?.bounds)
|
||||
export const dndIsDragging = derivedMemo(dndStore, x => !!x.source)
|
||||
export const dndIsNewComponent = derivedMemo(
|
||||
dndStore,
|
||||
x => x.source?.newComponentType != null
|
||||
)
|
||||
|
|
|
@ -92,6 +92,8 @@ const createScreenStore = () => {
|
|||
width: `${$dndBounds?.width || 400}px`,
|
||||
height: `${$dndBounds?.height || 200}px`,
|
||||
opacity: 0,
|
||||
"--default-width": $dndBounds?.width || 400,
|
||||
"--default-height": $dndBounds?.height || 200,
|
||||
},
|
||||
},
|
||||
static: true,
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
import { writable } from "svelte/store"
|
||||
|
||||
/**
|
||||
* Extension of Svelte's built in "derived" stores, which the addition of deep
|
||||
* comparison of non-primitives. Falls back to using shallow comparison for
|
||||
* primitive types to avoid performance penalties.
|
||||
* Useful for instances where a deep comparison is cheaper than an additional
|
||||
* store invalidation.
|
||||
* @param store the store to observer
|
||||
* @param deriveValue the derivation function
|
||||
* @returns {Writable<*>} a derived svelte store containing just the derived value
|
||||
*/
|
||||
export const computed = (store, deriveValue) => {
|
||||
const initialValue = deriveValue(store)
|
||||
const computedStore = writable(initialValue)
|
||||
let lastKey = getKey(initialValue)
|
||||
|
||||
store.subscribe(state => {
|
||||
const value = deriveValue(state)
|
||||
const key = getKey(value)
|
||||
if (key !== lastKey) {
|
||||
lastKey = key
|
||||
computedStore.set(value)
|
||||
}
|
||||
})
|
||||
|
||||
return computedStore
|
||||
}
|
||||
|
||||
// Helper function to serialise any value into a primitive which can be cheaply
|
||||
// and shallowly compared
|
||||
const getKey = value => {
|
||||
if (value == null || typeof value !== "object") {
|
||||
return value
|
||||
} else {
|
||||
return JSON.stringify(value)
|
||||
}
|
||||
}
|
|
@ -92,8 +92,12 @@ export const gridLayout = (node, metadata) => {
|
|||
}
|
||||
|
||||
// Determine default width and height of component
|
||||
let width = errored ? 500 : definition?.size?.width || 200
|
||||
let height = errored ? 60 : definition?.size?.height || 200
|
||||
let width = styles["--default-width"] ?? definition?.size?.width ?? 200
|
||||
let height = styles["--default-height"] ?? definition?.size?.height ?? 200
|
||||
if (errored) {
|
||||
width = 500
|
||||
height = 60
|
||||
}
|
||||
width += 2 * GridSpacing
|
||||
height += 2 * GridSpacing
|
||||
let vars = {
|
||||
|
|
|
@ -93,7 +93,7 @@ export const styleable = (node, styles = {}) => {
|
|||
node.addEventListener("mouseout", applyNormalStyles)
|
||||
|
||||
// Add builder preview click listener
|
||||
if (newStyles.interactive) {
|
||||
if (newStyles.interactive && !newStyles.isRoot) {
|
||||
node.addEventListener("click", selectComponent, false)
|
||||
node.addEventListener("dblclick", editComponent, false)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue