commit
31ec8322ae
|
@ -155,9 +155,13 @@ Cypress.Commands.add("navigateToFrontend", () => {
|
|||
Cypress.Commands.add("createScreen", (screenName, route) => {
|
||||
cy.contains("Create New Screen").click()
|
||||
cy.get(".modal").within(() => {
|
||||
cy.get("input:first").type(screenName)
|
||||
cy.get("input")
|
||||
.eq(0)
|
||||
.type(screenName)
|
||||
if (route) {
|
||||
cy.get("input:last").type(route)
|
||||
cy.get("input")
|
||||
.eq(1)
|
||||
.type(route)
|
||||
}
|
||||
cy.contains("Create Screen").click()
|
||||
})
|
||||
|
|
|
@ -27,7 +27,9 @@ import {
|
|||
regenerateCssForScreen,
|
||||
generateNewIdsForComponent,
|
||||
getComponentDefinition,
|
||||
findChildComponentType,
|
||||
} from "../storeUtils"
|
||||
|
||||
export const getStore = () => {
|
||||
const initial = {
|
||||
apps: [],
|
||||
|
@ -56,6 +58,7 @@ export const getStore = () => {
|
|||
store.setCurrentScreen = setCurrentScreen(store)
|
||||
store.deleteScreens = deleteScreens(store)
|
||||
store.setCurrentPage = setCurrentPage(store)
|
||||
store.createLink = createLink(store)
|
||||
store.createScreen = createScreen(store)
|
||||
store.addStylesheet = addStylesheet(store)
|
||||
store.removeStylesheet = removeStylesheet(store)
|
||||
|
@ -190,6 +193,58 @@ const createScreen = store => async screen => {
|
|||
await savePromise
|
||||
}
|
||||
|
||||
const createLink = store => async (url, title) => {
|
||||
let savePromise
|
||||
store.update(state => {
|
||||
// Try to extract a nav component from the master screen
|
||||
const nav = findChildComponentType(
|
||||
state.pages.main,
|
||||
"@budibase/standard-components/Navigation"
|
||||
)
|
||||
if (nav) {
|
||||
let newLink
|
||||
|
||||
// Clone an existing link if one exists
|
||||
if (nav._children && nav._children.length) {
|
||||
// Clone existing link style
|
||||
newLink = cloneDeep(nav._children[0])
|
||||
|
||||
// Manipulate IDs to ensure uniqueness
|
||||
generateNewIdsForComponent(newLink, state, false)
|
||||
|
||||
// Set our new props
|
||||
newLink._instanceName = `${title} Link`
|
||||
newLink.url = url
|
||||
newLink.text = title
|
||||
} else {
|
||||
// Otherwise create vanilla new link
|
||||
const component = getComponentDefinition(
|
||||
state,
|
||||
"@budibase/standard-components/link"
|
||||
)
|
||||
const instanceId = get(backendUiStore).selectedDatabase._id
|
||||
newLink = createProps(component, {
|
||||
url,
|
||||
text: title,
|
||||
_instanceName: `${title} Link`,
|
||||
_instanceId: instanceId,
|
||||
}).props
|
||||
}
|
||||
|
||||
// Save page and regenerate all CSS because otherwise weird things happen
|
||||
nav._children = [...nav._children, newLink]
|
||||
setCurrentPage("main")
|
||||
regenerateCssForScreen(state.pages.main)
|
||||
for (let screen of state.pages.main._screens) {
|
||||
regenerateCssForScreen(screen)
|
||||
}
|
||||
savePromise = _savePage(state)
|
||||
}
|
||||
return state
|
||||
})
|
||||
await savePromise
|
||||
}
|
||||
|
||||
const setCurrentScreen = store => screenName => {
|
||||
store.update(s => {
|
||||
const screen = getExactComponent(s.screens, screenName, true)
|
||||
|
|
|
@ -84,7 +84,9 @@ export const regenerateCssForScreen = screen => {
|
|||
}
|
||||
|
||||
export const regenerateCssForCurrentScreen = state => {
|
||||
regenerateCssForScreen(state.currentPreviewItem)
|
||||
if (state.currentPreviewItem) {
|
||||
regenerateCssForScreen(state.currentPreviewItem)
|
||||
}
|
||||
return state
|
||||
}
|
||||
|
||||
|
@ -96,3 +98,33 @@ export const generateNewIdsForComponent = (c, state, changeName = true) =>
|
|||
|
||||
export const getComponentDefinition = (state, name) =>
|
||||
name.startsWith("##") ? getBuiltin(name) : state.components[name]
|
||||
|
||||
export const findChildComponentType = (node, typeToFind) => {
|
||||
// Stop recursion if invalid props
|
||||
if (!node || !typeToFind) {
|
||||
return null
|
||||
}
|
||||
|
||||
// Stop recursion if this element matches
|
||||
if (node._component === typeToFind) {
|
||||
return node
|
||||
}
|
||||
|
||||
// Otherwise check if any children match
|
||||
// Stop recursion if no valid children to process
|
||||
const children = node._children || (node.props && node.props._children)
|
||||
if (!children || !children.length) {
|
||||
return null
|
||||
}
|
||||
|
||||
// Recurse and check each child component
|
||||
for (let child of children) {
|
||||
const childResult = findChildComponentType(child, typeToFind)
|
||||
if (childResult) {
|
||||
return childResult
|
||||
}
|
||||
}
|
||||
|
||||
// If we reach here then no children were valid
|
||||
return null
|
||||
}
|
||||
|
|
|
@ -38,21 +38,21 @@
|
|||
}
|
||||
|
||||
async function saveTable() {
|
||||
// Create table
|
||||
const table = await backendUiStore.actions.tables.save({
|
||||
name,
|
||||
schema: dataImport.schema || {},
|
||||
dataImport,
|
||||
})
|
||||
notifier.success(`Table ${name} created successfully.`)
|
||||
$goto(`./table/${table._id}`)
|
||||
analytics.captureEvent("Table Created", { name })
|
||||
|
||||
// Create auto screens
|
||||
const screens = screenTemplates($store, [table])
|
||||
.filter(template => defaultScreens.includes(template.id))
|
||||
.map(template => template.create())
|
||||
|
||||
for (let screen of screens) {
|
||||
// record the table that created this screen so we can link it later
|
||||
// Record the table that created this screen so we can link it later
|
||||
screen.autoTableId = table._id
|
||||
try {
|
||||
await store.createScreen(screen)
|
||||
|
@ -65,6 +65,15 @@
|
|||
// we should remove this after this has been released
|
||||
}
|
||||
}
|
||||
|
||||
// Create autolink to newly created list page
|
||||
const listPage = screens.find(screen =>
|
||||
screen.props._instanceName.endsWith("List")
|
||||
)
|
||||
await store.createLink(listPage.route, table.name)
|
||||
|
||||
// Navigate to new table
|
||||
$goto(`./table/${table._id}`)
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,7 +1,14 @@
|
|||
<script>
|
||||
import { goto } from "@sveltech/routify"
|
||||
import { store, backendUiStore } from "builderStore"
|
||||
import { Input, Button, Spacer, Select, ModalContent } from "@budibase/bbui"
|
||||
import {
|
||||
Input,
|
||||
Button,
|
||||
Spacer,
|
||||
Select,
|
||||
ModalContent,
|
||||
Toggle,
|
||||
} from "@budibase/bbui"
|
||||
import getTemplates from "builderStore/store/screenTemplates"
|
||||
import { some } from "lodash/fp"
|
||||
import analytics from "analytics"
|
||||
|
@ -13,6 +20,7 @@
|
|||
let baseComponent = CONTAINER
|
||||
let templateIndex
|
||||
let draftScreen
|
||||
let createLink = true
|
||||
|
||||
$: templates = getTemplates($store, $backendUiStore.tables)
|
||||
|
||||
|
@ -46,7 +54,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
const save = () => {
|
||||
const save = async () => {
|
||||
if (!route) {
|
||||
routeError = "Url is required"
|
||||
} else {
|
||||
|
@ -63,7 +71,10 @@
|
|||
draftScreen.props._component = baseComponent
|
||||
draftScreen.route = route
|
||||
|
||||
store.createScreen(draftScreen)
|
||||
await store.createScreen(draftScreen)
|
||||
if (createLink) {
|
||||
await store.createLink(route, name)
|
||||
}
|
||||
|
||||
if (templateIndex !== undefined) {
|
||||
const template = templates[templateIndex]
|
||||
|
@ -108,4 +119,6 @@
|
|||
error={routeError}
|
||||
bind:value={route}
|
||||
on:change={routeChanged} />
|
||||
|
||||
<Toggle text="Create link in navigation bar" bind:checked={createLink} />
|
||||
</ModalContent>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<script>
|
||||
import { onMount } from "svelte"
|
||||
import { params, leftover } from "@sveltech/routify"
|
||||
import { params, leftover, goto } from "@sveltech/routify"
|
||||
import { store } from "builderStore"
|
||||
|
||||
// Get any leftover params not caught by Routifys params store.
|
||||
|
@ -8,17 +8,30 @@
|
|||
|
||||
// It's a screen, set it to that screen
|
||||
if ($params.screen !== "page-layout") {
|
||||
store.setCurrentScreen(decodeURI($params.screen))
|
||||
const currentScreenName = decodeURI($params.screen)
|
||||
const validScreen =
|
||||
$store.screens.findIndex(
|
||||
screen => screen.props._instanceName === currentScreenName
|
||||
) !== -1
|
||||
|
||||
// There are leftover stuff, like IDs, so navigate the components and find the ID and select it.
|
||||
if ($leftover) {
|
||||
// Get the correct screen children.
|
||||
const screenChildren = $store.pages[$params.page]._screens.find(
|
||||
screen =>
|
||||
screen.props._instanceName === $params.screen ||
|
||||
screen.props._instanceName === decodeURIComponent($params.screen)
|
||||
).props._children
|
||||
findComponent(componentIds, screenChildren)
|
||||
if (!validScreen) {
|
||||
// Go to main layout if URL set to invalid screen
|
||||
store.setCurrentPage("main")
|
||||
$goto("../../main")
|
||||
} else {
|
||||
// Otherwise proceed to set screen
|
||||
store.setCurrentScreen(currentScreenName)
|
||||
|
||||
// There are leftover stuff, like IDs, so navigate the components and find the ID and select it.
|
||||
if ($leftover) {
|
||||
// Get the correct screen children.
|
||||
const screenChildren = $store.pages[$params.page]._screens.find(
|
||||
screen =>
|
||||
screen.props._instanceName === $params.screen ||
|
||||
screen.props._instanceName === decodeURIComponent($params.screen)
|
||||
).props._children
|
||||
findComponent(componentIds, screenChildren)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// It's a page, so set the screentype to page.
|
||||
|
|
Loading…
Reference in New Issue