forked from tsai/budibase
13 changed files with 116 additions and 130 deletions
@ -1,64 +1,92 @@ |
|||||
<script> |
<script> |
||||
|
import { onMount } from "svelte" |
||||
|
import { get } from "svelte/store" |
||||
import { params, leftover, goto } from "@sveltech/routify" |
import { params, leftover, goto } from "@sveltech/routify" |
||||
import { FrontendTypes } from "constants" |
import { FrontendTypes } from "constants" |
||||
import { store, allScreens } from "builderStore" |
import { store, allScreens, currentAsset } from "builderStore" |
||||
|
import { findComponent, findComponentPath } from "builderStore/storeUtils" |
||||
|
|
||||
// Get any leftover params not caught by Routifys params store. |
let initialised = false |
||||
const componentIds = $leftover.split("/").filter(id => id !== "") |
|
||||
|
|
||||
const currentAssetId = decodeURI($params.asset) |
// Hydrate state from query param on mount |
||||
|
onMount(() => { |
||||
|
const assetId = decodeURI($params.asset) |
||||
|
let assetList |
||||
|
let actions |
||||
|
|
||||
let assetList |
// Determine screens or layouts based on the URL |
||||
let actions |
if ($params.assetType === FrontendTypes.SCREEN) { |
||||
|
assetList = $allScreens |
||||
|
actions = store.actions.screens |
||||
|
} else { |
||||
|
assetList = $store.layouts |
||||
|
actions = store.actions.layouts |
||||
|
} |
||||
|
|
||||
// Determine screens or layouts based on the URL |
// Find and select the current asset |
||||
if ($params.assetType === FrontendTypes.SCREEN) { |
const asset = assetList.find(asset => asset._id === assetId) |
||||
assetList = $allScreens |
if (asset) { |
||||
actions = store.actions.screens |
actions.select(assetId) |
||||
} else { |
|
||||
assetList = $store.layouts |
|
||||
actions = store.actions.layouts |
|
||||
} |
|
||||
|
|
||||
// select the screen or layout in the UI |
|
||||
actions.select(currentAssetId) |
|
||||
|
|
||||
// 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 assetChildren = |
|
||||
assetList.find( |
|
||||
asset => |
|
||||
asset._id === $params.asset || |
|
||||
asset._id === decodeURIComponent($params.asset) |
|
||||
)?.props._children ?? [] |
|
||||
findComponent(componentIds, assetChildren) |
|
||||
} |
|
||||
// } |
|
||||
|
|
||||
// Find Component with ID and continue |
|
||||
function findComponent(ids, children) { |
|
||||
// Setup stuff |
|
||||
let componentToSelect |
|
||||
let currentChildren = children |
|
||||
|
|
||||
// Loop through each ID |
// Select the component ID if one is present in the URL |
||||
ids.forEach(id => { |
const selectedComponentId = $leftover.split("/").pop() |
||||
// Find ID |
if (selectedComponentId) { |
||||
const component = currentChildren.find(child => child._id === id) |
const component = findComponent(asset.props, selectedComponentId) |
||||
|
if (component) { |
||||
|
store.actions.components.select(component) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
// If it does not exist, ignore (use last valid route) |
initialised = true |
||||
if (!component) return |
}) |
||||
|
|
||||
componentToSelect = component |
// Updates the route params in the URL to the specified values |
||||
|
const updateParams = (assetType, asset, componentId) => { |
||||
|
// Wait until the initial state rehydration to avoid a wasted update |
||||
|
if (!initialised) { |
||||
|
return |
||||
|
} |
||||
|
|
||||
// Update childrens array to selected components children |
// Extract current URL params |
||||
currentChildren = componentToSelect._children |
const currentParams = get(params) |
||||
}) |
const currentLeftover = get(leftover) |
||||
|
const paramAssetType = currentParams.assetType |
||||
|
const paramAssetId = currentParams.asset |
||||
|
const paramComponentId = currentLeftover.split("/").pop() |
||||
|
|
||||
// Select Component! |
// Only update params if the params actually changed |
||||
if (componentToSelect) store.actions.components.select(componentToSelect) |
if ( |
||||
|
assetType !== paramAssetType || |
||||
|
asset?._id !== paramAssetId || |
||||
|
componentId !== paramComponentId |
||||
|
) { |
||||
|
// Build and navigate to a valid URL |
||||
|
let url = "../../" |
||||
|
if ([FrontendTypes.SCREEN, FrontendTypes.LAYOUT].includes(assetType)) { |
||||
|
url += `${assetType}` |
||||
|
if (asset?._id) { |
||||
|
url += `/${asset._id}` |
||||
|
if (componentId) { |
||||
|
const componentPath = findComponentPath(asset.props, componentId) |
||||
|
const componentURL = componentPath |
||||
|
.slice(1) |
||||
|
.map(comp => comp._id) |
||||
|
.join("/") |
||||
|
url += `/${componentURL}` |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
$goto(url) |
||||
|
} |
||||
} |
} |
||||
|
|
||||
|
// Automatically keep URL up to date with state |
||||
|
$: updateParams( |
||||
|
$store.currentFrontEndType, |
||||
|
$currentAsset, |
||||
|
$store.selectedComponentId |
||||
|
) |
||||
</script> |
</script> |
||||
|
|
||||
<slot /> |
<slot /> |
||||
|
|||||
@ -1,37 +1,45 @@ |
|||||
<script> |
<script> |
||||
|
import { onMount } from "svelte" |
||||
|
import { goto } from "@sveltech/routify" |
||||
import { store, allScreens } from "builderStore" |
import { store, allScreens } from "builderStore" |
||||
import { FrontendTypes } from "constants" |
import { FrontendTypes } from "constants" |
||||
import { goto, params } from "@sveltech/routify" |
import { params } from "@sveltech/routify" |
||||
|
|
||||
// Go to first layout |
onMount(() => { |
||||
if ($params.assetType === FrontendTypes.LAYOUT) { |
|
||||
// Try to use previously selected layout first |
|
||||
let id |
let id |
||||
if ( |
|
||||
$store.selectedLayoutId && |
// Get valid asset type |
||||
$store.layouts.find(layout => layout._id === $store.selectedLayoutId) |
let assetType = $params.assetType |
||||
) { |
if (![FrontendTypes.LAYOUT, FrontendTypes.SCREEN].includes(assetType)) { |
||||
id = $store.selectedLayoutId |
assetType = FrontendTypes.SCREEN |
||||
} else { |
|
||||
id = $store.layouts[0]?._id |
|
||||
} |
} |
||||
$goto(`../${id}`) |
|
||||
} |
|
||||
|
|
||||
// Go to first screen |
// Get ID or first correct asset type |
||||
if ($params.assetType === FrontendTypes.SCREEN) { |
if (assetType === FrontendTypes.LAYOUT) { |
||||
// Try to use previously selected layout first |
if ( |
||||
let id |
$store.selectedLayoutId && |
||||
if ( |
$store.layouts.find(layout => layout._id === $store.selectedLayoutId) |
||||
$store.selectedScreenId && |
) { |
||||
$allScreens.find(screen => screen._id === $store.selectedScreenId) |
id = $store.selectedLayoutId |
||||
) { |
} else { |
||||
id = $store.selectedScreenId |
id = $store.layouts[0]?._id |
||||
} else { |
} |
||||
id = $allScreens[0]?._id |
} else if (assetType === FrontendTypes.SCREEN) { |
||||
|
if ( |
||||
|
$store.selectedScreenId && |
||||
|
$allScreens.find(screen => screen._id === $store.selectedScreenId) |
||||
|
) { |
||||
|
id = $store.selectedScreenId |
||||
|
} else { |
||||
|
id = $allScreens[0]?._id |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Send correct URL which will then update state |
||||
|
if (id) { |
||||
|
$goto(`../../${assetType}/${id}`) |
||||
} |
} |
||||
$goto(`../${id}`) |
}) |
||||
} |
|
||||
</script> |
</script> |
||||
|
|
||||
<!-- routify:options index=false --> |
<!-- routify:options index=false --> |
||||
|
|||||
Loading…
Reference in new issue