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 705088362b
commit f5f8e25c9f
6 changed files with 76 additions and 37 deletions

View File

@ -1,9 +1,9 @@
<script>
import { onMount } from "svelte"
import { get } from "svelte/store"
import { goto } from "@roxi/routify"
import { goto, params } from "@roxi/routify"
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 EditQueryPopover from "./popovers/EditQueryPopover.svelte"
import NavItem from "components/common/NavItem.svelte"
@ -11,16 +11,27 @@
import ICONS from "./icons"
let openDataSources = []
$: enrichedDataSources = $datasources.list.map(datasource => ({
...datasource,
open:
openDataSources.includes(datasource._id) ||
containsActiveTable(datasource),
selected: $datasources.selected === datasource._id,
}))
$: enrichedDataSources = $datasources.list.map(datasource => {
const selected = $datasources.selected === datasource._id
const open = openDataSources.includes(datasource._id)
const containsSelected = containsActiveEntity(datasource)
return {
...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) {
toggleNode(datasource)
openNode(datasource)
datasources.select(datasource._id)
$goto(`./datasource/${datasource._id}`)
}
@ -30,12 +41,22 @@
$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) {
const isOpen = openDataSources.includes(datasource._id)
if (isOpen) {
openDataSources = openDataSources.filter(id => datasource._id !== id)
closeNode(datasource)
} else {
openDataSources = [...openDataSources, datasource._id]
openNode(datasource)
}
}
@ -44,16 +65,35 @@
queries.fetch()
})
const containsActiveTable = datasource => {
const activeTableId = get(tables).selected?._id
const containsActiveEntity = datasource => {
// 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) {
return false
}
let tableOptions = datasource.entities
if (!Array.isArray(tableOptions)) {
tableOptions = Object.values(tableOptions)
// Get a list of table options
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>

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 />

View File

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

View File

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

View File

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