Merge pull request #5010 from Budibase/cheeks-fixes

Miscellaneous fixes
This commit is contained in:
Andrew Kingston 2022-03-24 02:50:04 -07:00 committed by GitHub
commit fead539800
10 changed files with 258 additions and 87 deletions

View File

@ -68,6 +68,7 @@
customTheme: $store.customTheme,
previewDevice: $store.previewDevice,
messagePassing: $store.clientFeatures.messagePassing,
isBudibaseEvent: true
}
$: json = JSON.stringify(previewData)

View File

@ -52,7 +52,7 @@ export default `
console.error("Client received invalid JSON")
// Ignore
}
if (!parsed) {
if (!parsed || !parsed.isBudibaseEvent) {
return
}

View File

@ -36,4 +36,13 @@
div :global(.apexcharts-datalabel) {
fill: var(--spectrum-global-color-gray-800);
}
div :global(.apexcharts-tooltip) {
background-color: var(--spectrum-global-color-gray-200) !important;
border-color: var(--spectrum-global-color-gray-300) !important;
box-shadow: 2px 2px 6px -4px rgba(0, 0, 0, 0.1) !important;
}
div :global(.apexcharts-tooltip-title) {
background-color: var(--spectrum-global-color-gray-100) !important;
border-color: var(--spectrum-global-color-gray-300) !important;
}
</style>

View File

@ -18,16 +18,53 @@
export let palette
export let horizontal
$: options = setUpChart(dataProvider)
$: options = setUpChart(
title,
dataProvider,
labelColumn,
valueColumns,
xAxisLabel,
yAxisLabel,
height,
width,
dataLabels,
animate,
legend,
stacked,
yAxisUnits,
palette,
horizontal
)
const setUpChart = provider => {
const setUpChart = (
title,
dataProvider,
labelColumn,
valueColumns,
xAxisLabel,
yAxisLabel,
height,
width,
dataLabels,
animate,
legend,
stacked,
yAxisUnits,
palette,
horizontal
) => {
console.log("new chart")
const allCols = [labelColumn, ...(valueColumns || [null])]
if (!provider || !provider.rows?.length || allCols.find(x => x == null)) {
if (
!dataProvider ||
!dataProvider.rows?.length ||
allCols.find(x => x == null)
) {
return null
}
// Fetch data
const { schema, rows } = provider
const { schema, rows } = dataProvider
const reducer = row => (valid, column) => valid && row[column] != null
const hasAllColumns = row => allCols.reduce(reducer(row), true)
const data = rows.filter(row => hasAllColumns(row)).slice(0, 100)

View File

@ -16,17 +16,48 @@
export let animate
export let yAxisUnits
$: options = setUpChart(dataProvider)
$: options = setUpChart(
title,
dataProvider,
dateColumn,
openColumn,
highColumn,
lowColumn,
closeColumn,
xAxisLabel,
yAxisLabel,
height,
width,
animate,
yAxisUnits
)
// Fetch data on mount
const setUpChart = provider => {
const setUpChart = (
title,
dataProvider,
dateColumn,
openColumn,
highColumn,
lowColumn,
closeColumn,
xAxisLabel,
yAxisLabel,
height,
width,
animate,
yAxisUnits
) => {
const allCols = [dateColumn, openColumn, highColumn, lowColumn, closeColumn]
if (!provider || !provider.rows?.length || allCols.find(x => x == null)) {
if (
!dataProvider ||
!dataProvider.rows?.length ||
allCols.find(x => x == null)
) {
return null
}
// Fetch data
const { schema, rows } = provider
const { schema, rows } = dataProvider
const reducer = row => (valid, column) => valid && row[column] != null
const hasAllColumns = row => allCols.reduce(reducer(row), true)
const data = rows.filter(row => hasAllColumns(row))

View File

@ -23,17 +23,56 @@
export let stacked
export let gradient
$: options = setUpChart(dataProvider)
$: options = setUpChart(
title,
dataProvider,
labelColumn,
valueColumns,
xAxisLabel,
yAxisLabel,
height,
width,
animate,
dataLabels,
curve,
legend,
yAxisUnits,
palette,
area,
stacked,
gradient
)
// Fetch data on mount
const setUpChart = provider => {
const setUpChart = (
title,
dataProvider,
labelColumn,
valueColumns,
xAxisLabel,
yAxisLabel,
height,
width,
animate,
dataLabels,
curve,
legend,
yAxisUnits,
palette,
area,
stacked,
gradient
) => {
const allCols = [labelColumn, ...(valueColumns || [null])]
if (!provider || !provider.rows?.length || allCols.find(x => x == null)) {
if (
!dataProvider ||
!dataProvider.rows?.length ||
allCols.find(x => x == null)
) {
return null
}
// Fetch, filter and sort data
const { schema, rows } = provider
const { schema, rows } = dataProvider
const reducer = row => (valid, column) => valid && row[column] != null
const hasAllColumns = row => allCols.reduce(reducer(row), true)
const data = rows.filter(row => hasAllColumns(row))

View File

@ -14,16 +14,44 @@
export let donut
export let palette
$: options = setUpChart(dataProvider)
$: options = setUpChart(
title,
dataProvider,
labelColumn,
valueColumn,
height,
width,
dataLabels,
animate,
legend,
donut,
palette
)
// Fetch data on mount
const setUpChart = provider => {
if (!provider || !provider.rows?.length || !labelColumn || !valueColumn) {
const setUpChart = (
title,
dataProvider,
labelColumn,
valueColumn,
height,
width,
dataLabels,
animate,
legend,
donut,
palette
) => {
if (
!dataProvider ||
!dataProvider.rows?.length ||
!labelColumn ||
!valueColumn
) {
return null
}
// Fetch, filter and sort data
const { schema, rows } = provider
const { schema, rows } = dataProvider
const data = rows
.filter(row => row[labelColumn] != null && row[valueColumn] != null)
.slice(0, 100)

View File

@ -4,7 +4,6 @@
Button,
Combobox,
DatePicker,
DrawerContent,
Icon,
Input,
Layout,
@ -12,10 +11,12 @@
} from "@budibase/bbui"
import { generate } from "shortid"
import { LuceneUtils, Constants } from "@budibase/frontend-core"
import { getContext } from "svelte"
export let schemaFields
export let filters = []
const context = getContext("context")
const BannedTypes = ["link", "attachment", "json"]
$: fieldOptions = (schemaFields ?? [])
@ -89,55 +90,55 @@
}
</script>
<DrawerContent>
<div class="container">
<Layout noPadding>
<Body size="S">
{#if !filters?.length}
Add your first filter expression.
{:else}
Results are filtered to only those which match all of the following
constraints.
{/if}
</Body>
{#if filters?.length}
<div class="fields">
{#each filters as filter, idx}
<Select
bind:value={filter.field}
options={fieldOptions}
on:change={e => onFieldChange(filter, e.detail)}
placeholder="Column"
<div class="container" class:mobile={$context.device.mobile}>
<Layout noPadding>
<Body size="S">
{#if !filters?.length}
Add your first filter expression.
{:else}
Results are filtered to only those which match all of the following
constraints.
{/if}
</Body>
{#if filters?.length}
<div class="fields">
{#each filters as filter, idx}
<Select
bind:value={filter.field}
options={fieldOptions}
on:change={e => onFieldChange(filter, e.detail)}
placeholder="Column"
/>
<Select
disabled={!filter.field}
options={LuceneUtils.getValidOperatorsForType(filter.type)}
bind:value={filter.operator}
on:change={e => onOperatorChange(filter, e.detail)}
placeholder={null}
/>
{#if ["string", "longform", "number", "formula"].includes(filter.type)}
<Input disabled={filter.noValue} bind:value={filter.value} />
{:else if ["options", "array"].includes(filter.type)}
<Combobox
disabled={filter.noValue}
options={getFieldOptions(filter.field)}
bind:value={filter.value}
/>
<Select
disabled={!filter.field}
options={LuceneUtils.getValidOperatorsForType(filter.type)}
bind:value={filter.operator}
on:change={e => onOperatorChange(filter, e.detail)}
placeholder={null}
{:else if filter.type === "boolean"}
<Combobox
disabled={filter.noValue}
options={[
{ label: "True", value: "true" },
{ label: "False", value: "false" },
]}
bind:value={filter.value}
/>
{#if ["string", "longform", "number", "formula"].includes(filter.type)}
<Input disabled={filter.noValue} bind:value={filter.value} />
{:else if ["options", "array"].includes(filter.type)}
<Combobox
disabled={filter.noValue}
options={getFieldOptions(filter.field)}
bind:value={filter.value}
/>
{:else if filter.type === "boolean"}
<Combobox
disabled={filter.noValue}
options={[
{ label: "True", value: "true" },
{ label: "False", value: "false" },
]}
bind:value={filter.value}
/>
{:else if filter.type === "datetime"}
<DatePicker disabled={filter.noValue} bind:value={filter.value} />
{:else}
<Input disabled />
{/if}
{:else if filter.type === "datetime"}
<DatePicker disabled={filter.noValue} bind:value={filter.value} />
{:else}
<Input disabled />
{/if}
<div class="controls">
<Icon
name="Duplicate"
hoverable
@ -150,17 +151,17 @@
size="S"
on:click={() => removeFilter(filter.id)}
/>
{/each}
</div>
{/if}
<div>
<Button icon="AddCircle" size="M" secondary on:click={addFilter}>
Add filter
</Button>
</div>
{/each}
</div>
</Layout>
</div>
</DrawerContent>
{/if}
<div>
<Button icon="AddCircle" size="M" secondary on:click={addFilter}>
Add filter
</Button>
</div>
</Layout>
</div>
<style>
.container {
@ -175,4 +176,19 @@
align-items: center;
grid-template-columns: 1fr 120px 1fr auto auto;
}
.controls {
display: contents;
}
.container.mobile .fields {
grid-template-columns: 1fr;
}
.container.mobile .controls {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
padding: var(--spacing-s) 0;
gap: var(--spacing-s);
}
</style>

View File

@ -157,13 +157,9 @@
const { fieldState } = get(existingField)
fieldId = fieldState.fieldId
// Use new default value if default value changed,
// otherwise use the current value if possible
if (defaultValue !== fieldState.defaultValue) {
initialValue = defaultValue
} else {
initialValue = fieldState.value ?? initialValue
}
// Determine the initial value for this field, reusing the current
// value if one exists
initialValue = fieldState.value ?? initialValue
// If this field has already been registered and we previously had an
// error set, then re-run the validator to see if we can unset it

View File

@ -6,12 +6,26 @@ const createAuthStore = () => {
// Fetches the user object if someone is logged in and has reloaded the page
const fetchUser = async () => {
let globalSelf = null
let appSelf = null
// First try and get the global user, to see if we are logged in at all
try {
const user = await API.fetchSelf()
store.set(user)
globalSelf = await API.fetchBuilderSelf()
} catch (error) {
store.set(null)
return
}
// Then try and get the user for this app to provide via context
try {
appSelf = await API.fetchSelf()
} catch (error) {
// Swallow
}
// Use the app self if present, otherwise fallback to the global self
store.set(appSelf || globalSelf || null)
}
const logOut = async () => {