Fix huge amount of bugs with data UI state, URL parameters and state/URL sync

This commit is contained in:
Andrew Kingston 2021-09-27 18:25:19 +01:00
parent 2ec7ff72ad
commit 6109a2983b
6 changed files with 76 additions and 37 deletions

View File

@ -1,9 +1,9 @@
<script> <script>
import { onMount } from "svelte" import { onMount } from "svelte"
import { get } from "svelte/store" import { get } from "svelte/store"
import { goto } from "@roxi/routify" import { goto, params } from "@roxi/routify"
import { BUDIBASE_INTERNAL_DB } from "constants" import { BUDIBASE_INTERNAL_DB } from "constants"
import { database, datasources, queries, tables } from "stores/backend" import { database, datasources, queries, tables, views } from "stores/backend"
import EditDatasourcePopover from "./popovers/EditDatasourcePopover.svelte" import EditDatasourcePopover from "./popovers/EditDatasourcePopover.svelte"
import EditQueryPopover from "./popovers/EditQueryPopover.svelte" import EditQueryPopover from "./popovers/EditQueryPopover.svelte"
import NavItem from "components/common/NavItem.svelte" import NavItem from "components/common/NavItem.svelte"
@ -11,16 +11,27 @@
import ICONS from "./icons" import ICONS from "./icons"
let openDataSources = [] let openDataSources = []
$: enrichedDataSources = $datasources.list.map(datasource => ({ $: enrichedDataSources = $datasources.list.map(datasource => {
...datasource, const selected = $datasources.selected === datasource._id
open: const open = openDataSources.includes(datasource._id)
openDataSources.includes(datasource._id) || const containsSelected = containsActiveEntity(datasource)
containsActiveTable(datasource), return {
selected: $datasources.selected === datasource._id, ...datasource,
})) selected,
open: selected || open || containsSelected,
}
})
$: openDataSource = enrichedDataSources.find(x => x.open)
$: {
// Ensure the open data source is always included in the list of open
// data sources
if (openDataSource) {
openNode(openDataSource)
}
}
function selectDatasource(datasource) { function selectDatasource(datasource) {
toggleNode(datasource) openNode(datasource)
datasources.select(datasource._id) datasources.select(datasource._id)
$goto(`./datasource/${datasource._id}`) $goto(`./datasource/${datasource._id}`)
} }
@ -30,12 +41,22 @@
$goto(`./datasource/${query.datasourceId}/${query._id}`) $goto(`./datasource/${query.datasourceId}/${query._id}`)
} }
function closeNode(datasource) {
openDataSources = openDataSources.filter(id => datasource._id !== id)
}
function openNode(datasource) {
if (!openDataSources.includes(datasource._id)) {
openDataSources = [...openDataSources, datasource._id]
}
}
function toggleNode(datasource) { function toggleNode(datasource) {
const isOpen = openDataSources.includes(datasource._id) const isOpen = openDataSources.includes(datasource._id)
if (isOpen) { if (isOpen) {
openDataSources = openDataSources.filter(id => datasource._id !== id) closeNode(datasource)
} else { } else {
openDataSources = [...openDataSources, datasource._id] openNode(datasource)
} }
} }
@ -44,16 +65,35 @@
queries.fetch() queries.fetch()
}) })
const containsActiveTable = datasource => { const containsActiveEntity = datasource => {
const activeTableId = get(tables).selected?._id // If we're view a query then the data source ID is in the URL
if ($params.selectedDatasource === datasource._id) {
return true
}
// If there are no entities it can't contain anything
if (!datasource.entities) { if (!datasource.entities) {
return false return false
} }
let tableOptions = datasource.entities
if (!Array.isArray(tableOptions)) { // Get a list of table options
tableOptions = Object.values(tableOptions) let options = datasource.entities
if (!Array.isArray(options)) {
options = Object.values(options)
} }
return tableOptions.find(x => x._id === activeTableId) != null
// Check for a matching table
if ($params.selectedTable) {
const selectedTable = get(tables).selected?._id
return options.find(x => x._id === selectedTable) != null
}
// Check for a matching view
const selectedView = get(views).selected?.name
const table = options.find(table => {
return table.views?.[selectedView] != null
})
return table != null
} }
</script> </script>

View File

@ -1 +1,13 @@
<script>
import { params } from "@roxi/routify"
import { queries } from "stores/backend"
if ($params.query) {
const query = $queries.list.find(q => q._id === $params.query)
if (query) {
queries.select(query)
}
}
</script>
<slot /> <slot />

View File

@ -2,7 +2,7 @@
import { params } from "@roxi/routify" import { params } from "@roxi/routify"
import { datasources } from "stores/backend" import { datasources } from "stores/backend"
if ($params.selectedDatasource) { if ($params.selectedDatasource && !$params.query) {
const datasource = $datasources.list.find( const datasource = $datasources.list.find(
m => m._id === $params.selectedDatasource m => m._id === $params.selectedDatasource
) )

View File

@ -1,14 +1 @@
<script>
import { datasources } from "stores/backend"
import { goto, leftover } from "@roxi/routify"
import { onMount } from "svelte"
onMount(async () => {
// navigate to first datasource in list, if not already selected
if (!$leftover && $datasources.list.length > 0 && !$datasources.selected) {
$goto(`./${$datasources.list[0]._id}`)
}
})
</script>
<slot /> <slot />

View File

@ -1,5 +1,5 @@
import { writable, get } from "svelte/store" import { writable, get } from "svelte/store"
import { datasources, integrations, tables } from "./" import { datasources, integrations, tables, views } from "./"
import api from "builderStore/api" import api from "builderStore/api"
export function createQueriesStore() { export function createQueriesStore() {
@ -55,10 +55,9 @@ export function createQueriesStore() {
}, },
select: query => { select: query => {
update(state => ({ ...state, selected: query._id })) update(state => ({ ...state, selected: query._id }))
tables.update(state => ({ views.unselect()
...state, tables.unselect()
selected: null, datasources.unselect()
}))
}, },
unselect: () => { unselect: () => {
update(state => ({ ...state, selected: null })) update(state => ({ ...state, selected: null }))

View File

@ -16,6 +16,7 @@ export function createViewsStore() {
...state, ...state,
selected: view, selected: view,
})) }))
tables.unselect()
queries.unselect() queries.unselect()
datasources.unselect() datasources.unselect()
}, },