122 lines
3.4 KiB
Svelte
122 lines
3.4 KiB
Svelte
<script>
|
|
import { createEventDispatcher } from "svelte"
|
|
import { tables, rows } from "stores/backend"
|
|
import { roles } from "stores/backend"
|
|
import { notifications } from "@budibase/bbui"
|
|
import RowFieldControl from "../RowFieldControl.svelte"
|
|
import { API } from "api"
|
|
import { ModalContent, Select } from "@budibase/bbui"
|
|
import ErrorsBox from "components/common/ErrorsBox.svelte"
|
|
|
|
export let row = {}
|
|
|
|
const dispatch = createEventDispatcher()
|
|
let errors = []
|
|
|
|
$: creating = row?._id == null
|
|
$: table = row.tableId
|
|
? $tables.list.find(table => table._id === row?.tableId)
|
|
: $tables.selected
|
|
$: tableSchema = getUserSchema(table)
|
|
$: customSchemaKeys = getCustomSchemaKeys(tableSchema)
|
|
$: if (!row.status) row.status = "active"
|
|
|
|
const getUserSchema = table => {
|
|
let schema = table?.schema ?? {}
|
|
if (schema.username) {
|
|
schema.username.name = "Username"
|
|
}
|
|
return schema
|
|
}
|
|
|
|
const getCustomSchemaKeys = schema => {
|
|
let customSchema = { ...schema }
|
|
delete customSchema["email"]
|
|
delete customSchema["roleId"]
|
|
delete customSchema["status"]
|
|
delete customSchema["firstName"]
|
|
delete customSchema["lastName"]
|
|
return Object.entries(customSchema)
|
|
}
|
|
|
|
const saveRow = async () => {
|
|
errors = []
|
|
|
|
// Do some basic front end validation first
|
|
if (!row.email) {
|
|
errors = [...errors, { message: "Email is required" }]
|
|
}
|
|
if (!row.roleId) {
|
|
errors = [...errors, { message: "Role is required" }]
|
|
}
|
|
if (errors.length) {
|
|
return false
|
|
}
|
|
|
|
try {
|
|
await API.saveRow({ ...row, tableId: table._id })
|
|
notifications.success("User saved successfully")
|
|
rows.save()
|
|
dispatch("updaterows")
|
|
} catch (error) {
|
|
if (error.handled) {
|
|
const response = error.json
|
|
if (response?.errors) {
|
|
if (Array.isArray(response.errors)) {
|
|
errors = response.errors.map(error => ({ message: error }))
|
|
} else {
|
|
errors = Object.entries(response.errors)
|
|
.map(([key, error]) => ({ dataPath: key, message: error }))
|
|
.flat()
|
|
}
|
|
} else if (error.status === 400) {
|
|
errors = [{ message: response?.message || "Unknown error" }]
|
|
}
|
|
} else {
|
|
notifications.error("Error saving user")
|
|
}
|
|
// Prevent closing the modal on errors
|
|
return false
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<ModalContent
|
|
title={creating ? "Create User" : "Edit User"}
|
|
confirmText={creating ? "Create User" : "Save User"}
|
|
onConfirm={saveRow}
|
|
>
|
|
<ErrorsBox {errors} />
|
|
<RowFieldControl
|
|
meta={{ ...tableSchema.email, name: "Email" }}
|
|
bind:value={row.email}
|
|
readonly={!creating}
|
|
/>
|
|
<RowFieldControl
|
|
meta={{ ...tableSchema.firstName, name: "First Name" }}
|
|
bind:value={row.firstName}
|
|
readonly={!creating}
|
|
/>
|
|
<RowFieldControl
|
|
meta={{ ...tableSchema.lastName, name: "Last Name" }}
|
|
bind:value={row.lastName}
|
|
readonly={!creating}
|
|
/>
|
|
<!-- Defer rendering this select until roles load, otherwise the initial
|
|
selection is always undefined -->
|
|
<Select
|
|
label="Role"
|
|
data-cy="roleId-select"
|
|
bind:value={row.roleId}
|
|
options={$roles}
|
|
getOptionLabel={role => role.name}
|
|
getOptionValue={role => role._id}
|
|
disabled={!creating}
|
|
/>
|
|
{#each customSchemaKeys as [key, meta]}
|
|
{#if !meta.autocolumn}
|
|
<RowFieldControl {meta} bind:value={row[key]} {creating} />
|
|
{/if}
|
|
{/each}
|
|
</ModalContent>
|