Skip to content

Commit

Permalink
Merge branch 'v3-ui' into feature/automation-branching-ux
Browse files Browse the repository at this point in the history
  • Loading branch information
aptkingston authored Oct 29, 2024
2 parents 3a8dc18 + 7d7dd31 commit bc406e1
Show file tree
Hide file tree
Showing 19 changed files with 704 additions and 998 deletions.
Original file line number Diff line number Diff line change
@@ -1,20 +1,144 @@
<script>
import { ActionButton, Modal } from "@budibase/bbui"
import ExportModal from "../modals/ExportModal.svelte"
import {
ActionButton,
Select,
notifications,
Body,
Button,
} from "@budibase/bbui"
import download from "downloadjs"
import { API } from "api"
import { ROW_EXPORT_FORMATS } from "constants/backend"
import DetailPopover from "components/common/DetailPopover.svelte"
export let view
export let filters
export let sorting
export let disabled = false
export let selectedRows
export let formats
let modal
const FORMATS = [
{
name: "CSV",
key: ROW_EXPORT_FORMATS.CSV,
},
{
name: "JSON",
key: ROW_EXPORT_FORMATS.JSON,
},
{
name: "JSON with Schema",
key: ROW_EXPORT_FORMATS.JSON_WITH_SCHEMA,
},
]
let popover
let exportFormat
let loading = false
$: options = FORMATS.filter(format => {
if (formats && !formats.includes(format.key)) {
return false
}
return true
})
$: if (options && !exportFormat) {
exportFormat = Array.isArray(options) ? options[0]?.key : []
}
const openPopover = () => {
loading = false
popover.show()
}
function downloadWithBlob(data, filename) {
download(new Blob([data], { type: "text/plain" }), filename)
}
const exportAllData = async () => {
return await API.exportView({
viewName: view,
format: exportFormat,
})
}
const exportFilteredData = async () => {
let payload = {
tableId: view,
format: exportFormat,
search: {
paginate: false,
},
}
if (selectedRows?.length) {
payload.rows = selectedRows.map(row => row._id)
}
if (sorting) {
payload.search.sort = sorting.sortColumn
payload.search.sortOrder = sorting.sortOrder
}
return await API.exportRows(payload)
}
const exportData = async () => {
try {
loading = true
let data
if (selectedRows?.length || sorting) {
data = await exportFilteredData()
} else {
data = await exportAllData()
}
notifications.success("Export successful")
downloadWithBlob(data, `export.${exportFormat}`)
popover.hide()
} catch (error) {
console.error(error)
notifications.error("Error exporting data")
} finally {
loading = false
}
}
</script>
<ActionButton {disabled} icon="DataDownload" quiet on:click={modal.show}>
Export
</ActionButton>
<Modal bind:this={modal}>
<ExportModal {view} {filters} {sorting} {selectedRows} {formats} />
</Modal>
<DetailPopover title="Export data" bind:this={popover}>
<svelte:fragment slot="anchor" let:open>
<ActionButton
icon="DataDownload"
quiet
on:click={openPopover}
{disabled}
selected={open}
>
Export
</ActionButton>
</svelte:fragment>
{#if selectedRows?.length}
<Body size="S">
<span data-testid="exporting-n-rows">
<strong>{selectedRows?.length}</strong>
{`row${selectedRows?.length > 1 ? "s" : ""} will be exported.`}
</span>
</Body>
{:else}
<Body size="S">
<span data-testid="export-all-rows">
Exporting <strong>all</strong> rows.
</span>
</Body>
{/if}
<span data-testid="format-select">
<Select
label="Format"
bind:value={exportFormat}
{options}
placeholder={null}
getOptionLabel={x => x.name}
getOptionValue={x => x.key}
/>
</span>
<div>
<Button cta disabled={loading} on:click={exportData}>Export</Button>
</div>
</DetailPopover>
Original file line number Diff line number Diff line change
@@ -1,17 +1,81 @@
<script>
import { ActionButton, Modal } from "@budibase/bbui"
import ImportModal from "../modals/ImportModal.svelte"
import { ActionButton, Button, Body, notifications } from "@budibase/bbui"
import DetailPopover from "components/common/DetailPopover.svelte"
import ExistingTableDataImport from "components/backend/TableNavigator/ExistingTableDataImport.svelte"
import { createEventDispatcher } from "svelte"
import { API } from "api"
export let tableId
export let tableType
export let disabled
let modal
const dispatch = createEventDispatcher()
let popover
let rows = []
let allValid = false
let displayColumn = null
let identifierFields = []
let loading = false
const openPopover = () => {
rows = []
allValid = false
displayColumn = null
identifierFields = []
loading = false
popover.show()
}
const importData = async () => {
try {
loading = true
await API.importTableData({
tableId,
rows,
identifierFields,
})
notifications.success("Rows successfully imported")
popover.hide()
} catch (error) {
console.error(error)
notifications.error("Unable to import data")
} finally {
loading = false
}
// Always refresh rows just to be sure
dispatch("importrows")
}
</script>

<ActionButton icon="DataUpload" quiet on:click={modal.show} {disabled}>
Import
</ActionButton>
<Modal bind:this={modal}>
<ImportModal {tableId} {tableType} on:importrows />
</Modal>
<DetailPopover title="Import data" bind:this={popover}>
<svelte:fragment slot="anchor" let:open>
<ActionButton
icon="DataUpload"
quiet
on:click={openPopover}
{disabled}
selected={open}
>
Import
</ActionButton>
</svelte:fragment>
<Body size="S">
Import rows to an existing table from a CSV or JSON file. Only columns from
the file which exist in the table will be imported.
</Body>
<ExistingTableDataImport
{tableId}
{tableType}
bind:rows
bind:allValid
bind:displayColumn
bind:identifierFields
/>
<div>
<Button cta disabled={loading || !allValid} on:click={importData}>
Import
</Button>
</div>
</DetailPopover>
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
<script>
import { createEventDispatcher } from "svelte"
import { ActionButton, Drawer, DrawerContent, Button } from "@budibase/bbui"
import { ActionButton, Button } from "@budibase/bbui"
import FilterBuilder from "components/design/settings/controls/FilterEditor/FilterBuilder.svelte"
import { getUserBindings } from "dataBinding"
import { makePropSafe } from "@budibase/string-templates"
import { search } from "@budibase/frontend-core"
import { tables } from "stores/builder"
import DetailPopover from "components/common/DetailPopover.svelte"
export let schema
export let filters
Expand All @@ -14,7 +15,7 @@
const dispatch = createEventDispatcher()
let drawer
let popover
$: localFilters = filters
$: schemaFields = search.getFields(
Expand All @@ -39,45 +40,44 @@
},
...getUserBindings(),
]
const openPopover = () => {
localFilters = filters
popover.show()
}
</script>
<ActionButton
icon="Filter"
quiet
{disabled}
on:click={drawer.show}
selected={filterCount > 0}
accentColor="#004EA6"
>
{filterCount ? `Filter: ${filterCount}` : "Filter"}
</ActionButton>
<DetailPopover bind:this={popover} title="Configure filters" width={800}>
<svelte:fragment slot="anchor" let:open>
<ActionButton
icon="Filter"
quiet
{disabled}
on:click={openPopover}
selected={open || filterCount > 0}
accentColor="#004EA6"
>
{filterCount ? `Filter: ${filterCount}` : "Filter"}
</ActionButton>
</svelte:fragment>
<Drawer
bind:this={drawer}
title="Filtering"
on:drawerHide
on:drawerShow={() => {
localFilters = filters
}}
forceModal
>
<Button
cta
slot="buttons"
on:click={() => {
dispatch("change", localFilters)
drawer.hide()
}}
>
Save
</Button>
<DrawerContent slot="body">
<FilterBuilder
filters={localFilters}
{schemaFields}
datasource={{ type: "table", tableId }}
on:change={e => (localFilters = e.detail)}
{bindings}
/>
</DrawerContent>
</Drawer>
<FilterBuilder
filters={localFilters}
{schemaFields}
datasource={{ type: "table", tableId }}
on:change={e => (localFilters = e.detail)}
{bindings}
/>
<div>
<Button
cta
slot="buttons"
on:click={() => {
dispatch("change", localFilters)
popover.hide()
}}
>
Save
</Button>
</div>
</DetailPopover>
Loading

0 comments on commit bc406e1

Please sign in to comment.