You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
bandolier-website/admin/pages/ReadUpdate.svelte

151 lines
4.2 KiB

<script>
import { push, link } from 'svelte-spa-router';
import { onMount } from 'svelte';
import Layout from "$/admin/Layout.svelte";
import Icon from "$/client/components/Icon.svelte";
import Modal from "$/client/components/Modal.svelte";
import Form from "$/client/components/Form.svelte";
import api from "$/client/api.js";
import { log } from "$/client/logging.js";
import { defer } from "$/client/helpers.js";
import Toasts from "$/client/components/Toasts.svelte";
export let params = {};
let send_toast;
let form_data = {_errors: {}, _valid: false};
let delete_confirm = false;
let load_promise = defer();
let schema = {};
const delete_record = async () => {
let [status, data] = await api.del(`/api/admin/table?name=${params.table}&row_id=${params.row_id}`);
if(status === 200) {
form_data = data;
form_data._errors = {}; // setup for errors later
push(`/table/${params.table}/`);
} else if(status == 401) {
window.location = "/client/#/login";
} else {
send_toast("Failed to delete.");
}
}
const update_record = async () => {
let [status, data] = await api.post(`/api/admin/table?name=${params.table}&row_id=${params.row_id}`, form_data);
log.debug("update record results", data);
if(status == 200) {
send_toast("Update successful.");
} else if(status == 401) {
window.location = "/client/#/login";
} else {
send_toast("Update failed.");
form_data = Object.assign(form_data, data);
}
}
const json_copy = () => {
const text = JSON.stringify(form_data, null, 4);
navigator.clipboard.writeText(text).then(() => {
send_toast("JSON data copied to clipboard");
}, () => {
send_toast("Failed copying to clipboard.");
});
}
onMount(async () => {
schema = await api.schema(params.table);
if(schema === undefined) {
send_toast("Failed to load schema.");
load_promise.reject();
} else {
let [status, data] = await api.get('/api/admin/table', {
name: params.table, row_id: params.row_id
});
if(status == 200) {
form_data = data;
load_promise.resolve();
} else if(status == 401) {
window.location = "/client/#/login";
} else {
sent_toast("Failed to load table data.");
load_promise.reject();
}
}
});
</script>
<style>
card {
background-color: var(--color-bg);
}
card top {
text-align: center;
}
card middle {
padding: 1rem;
}
</style>
<Layout authenticated={ true } testid="page-admin-readupdate">
{#await load_promise}
<!-- form already has a spinner -->
{:then}
<Form data={form_data} table={params.table} schema={ schema }>
<a href="/table/{ params.table }" data-testid="button-back" use:link>
<Icon name="arrow-left-circle" tooltip="Back to table." size="48" />
</a>
<span data-testid="button-copy" on:click={ json_copy }>
<Icon name="copy" tooltip="Copy JSON." size="48" />
</span>
<span data-testid="button-update" on:click={ update_record }>
<Icon name="save" tooltip="Update." size="48" />
</span>
<span data-testid="button-delete" on:click={ () => delete_confirm = true }>
<Icon name="trash" tooltip="Delete!" size="48" />
</span>
</Form>
{:catch}
<callout class="error">
<p>Return to the table:
<a href="/table/{ params.table }" data-testid="button-back" use:link>
<Icon name="arrow-left-circle" tooltip="Back to table." size="48" />
</a>
</p>
</callout>
{/await}
</Layout>
<Toasts bind:send_toast orientation="bottom right"/>
{#if delete_confirm}
<Modal on:close={() => delete_confirm = false }>
<card>
<top>
<h1>Really Delete?</h1>
</top>
<middle>
<p>This action is permanent to make sure it's what you want.</p>
</middle>
<bottom>
<button-group>
<button type="button" data-testid="button-delete-no" on:click={() => delete_confirm = false }>Cancel</button>
<button data-testid="button-delete-yes" on:click={ delete_record }>DELETE</button>
</button-group>
</bottom>
</card>
</Modal>
{/if}