cherry: import element_data_store_v2.svelte from wip-modal-fix-attempt

This commit is contained in:
Scott Idem
2026-03-17 10:32:39 -04:00
parent 1156e02e48
commit cedf76344b

View File

@@ -0,0 +1,889 @@
<script lang="ts">
import { run, preventDefault } from 'svelte/legacy';
import { browser } from '$app/environment';
import { onMount } from 'svelte';
// import { liveQuery } from "dexie"; // Use this in the future???
import { api } from '$lib/api/api';
import { ae_loc, ae_sess, ae_api, slct, slct_trigger, ae_trig } from '$lib/stores/ae_stores';
import { ae_util } from '$lib/ae_utils/ae_utils';
import type { key_val } from '$lib/stores/ae_stores';
import Element_modal_v1 from '$lib/elements/element_modal_v1.svelte';
onMount(() => {
console.log(
`ae_e_data_store ${ds_code} account_id=${$ae_loc.account_id} for_type=${for_type} for_id=${for_id}`
);
});
// export let store: string = 'local';
let ae_promises: key_val = {};
// let ae_tmp: key_val = {};
// let ae_triggers: key_val = {};
let ds_get_results: Promise<any> | key_val = $state();
let ds_submit_results: Promise<any> | key_val = $state();
let val_json: key_val;
let val_html: key_val;
let val_md: key_val;
interface Props {
log_lvl?: number;
expire_minutes?: number;
mount_reload_sec?: number;
ds_code: string;
ds_name?: null | string;
ds_type?: string;
for_type?: null | string;
for_id?: null | string;
// export let display: string = 'block'; // Avoid; Use class list instead
class_li?: string; // : string[] = [];
try_cache?: boolean;
hide?: boolean; // Hide the entire element
show_edit?: boolean;
show_edit_btn?: boolean; // You must still be at least an admin (vs a manager).
show_view?: boolean;
// export let show_delete_btn: boolean = false;
ds_loaded?: boolean;
debug?: boolean;
ds_loading_status?: string;
val_sql?: null | key_val;
}
let {
log_lvl = 0,
expire_minutes = 15,
mount_reload_sec = 0,
ds_code,
ds_name = null,
ds_type = 'text',
for_type = null,
for_id = null,
class_li = '',
try_cache = true,
hide = false,
show_edit = $bindable(false),
show_edit_btn = false,
show_view = $bindable(true),
ds_loaded = $bindable(false),
debug = false,
ds_loading_status = $bindable('starting'),
val_sql = $bindable(null)
}: Props = $props();
let val_text: string;
let ds_code_obj = {
id: null,
account_id: null,
code: ds_code,
name: ds_name,
type: ds_type,
for_type: null, // for_type
for_id: null, // for_id
access_read: null, // 'super', 'manager', 'administrator', 'trusted', 'authenticated', 'anonymous'
access_write: null, // 'super', 'manager', 'administrator', 'trusted', 'authenticated', 'anonymous'
access_delete: null, // 'super', 'manager', 'administrator', 'trusted', 'authenticated', 'anonymous'
html: null,
json: null,
md: null,
text: null,
updated_on: null,
chk_account_id: null
};
let ae_ds_tmp: key_val = $state();
if (browser && try_cache && localStorage.getItem(`ae_ds__${ds_code}`)) {
if (log_lvl) {
console.log(`ae_e_data_store: Found cached data for ${ds_code}`);
}
ae_ds_tmp = JSON.parse(localStorage.getItem(`ae_ds__${ds_code}`) ?? '{}');
if (log_lvl) {
console.log(
`ae_e_data_store cached: ${ds_code} account_id=${$ae_loc.account_id}`,
ae_ds_tmp
);
}
} else {
ae_ds_tmp = ds_code_obj;
ds_loading_status = 'loading';
}
$ae_sess.ds.submit_status = null;
$ae_sess.ds.create_status = null;
$ae_sess.ds.update_status = null;
let trigger: null | string = $state(null);
// This is a quick check to make sure the data store is not stale. If it is, then we need to trigger a reload.
if (
browser &&
ae_ds_tmp &&
ae_ds_tmp.loaded_on &&
ae_ds_tmp.chk_account_id == $ae_loc.account_id
) {
console.log(`ae_e_data_store ${ds_code} loaded_on: ${ae_ds_tmp.loaded_on}`);
let loaded_on = new Date(ae_ds_tmp.loaded_on);
let now = new Date();
let diff = now.getTime() - loaded_on.getTime();
let diff_minutes = diff / (1000 * 60);
if (diff_minutes > expire_minutes) {
console.log(
`ae_e_data_store: Data Store ${ds_code} stale. Last loaded on: ${loaded_on.toISOString()}`
);
// Wait for random number of milliseconds to avoid all data stores being reloaded at the same time.
let random_ms = Math.floor(Math.random() * 500);
console.log(`ae_e_data_store: Random number of milliseconds: ${random_ms}`);
setTimeout(() => {
trigger = 'load__ds__code';
}, random_ms);
}
} else if (browser) {
console.log(
'ae_e_data_store: No loaded_on date found and or the account_id check failed. Need to trigger reload.'
);
trigger = 'load__ds__code';
}
// This is a secondary check... The account_id should either be null or match the current account_id.
if (!ae_ds_tmp || !ae_ds_tmp.account_id === null || $ae_loc.account_id == $ae_loc.account_id) {
trigger = 'load__ds__code';
}
if (browser && mount_reload_sec) {
// Wait for random number of milliseconds to avoid all data stores being reloaded at the same time.
let random_ms = Math.floor(Math.random() * mount_reload_sec * 1000);
if (log_lvl) {
console.log(`ae_e_data_store: Random number of milliseconds: ${random_ms}`);
}
setTimeout(() => {
trigger = 'load__ds__code';
}, random_ms);
}
async function load_data_store({
code,
type = 'text',
for_type = null,
for_id = null,
try_cache = true,
log_lvl = 0
}: {
code: string;
type?: string;
for_type?: string | null;
for_id?: string | null;
try_cache?: boolean;
log_lvl?: number;
}) {
// let ds_code_val = await api.get_data_store_obj_w_code({
ds_get_results = api
.get_data_store_obj_w_code({
api_cfg: $ae_api,
data_store_code: code,
data_type: type,
log_lvl: log_lvl
})
.then(function (ds_results) {
// console.log(`ae_ Data Store ${code} = `, ds_results);
if (ds_results) {
if (log_lvl) {
console.log(`ae_e_data_store: Got a result for code ${code}`);
}
if (!ds_results.data_store_id_random) {
console.log('Something went wrong? No data store ID found.');
return false;
}
ds_loaded = true;
ds_loading_status = 'loaded';
// Set the loaded_on datetime to the current time for reference later. This will be used to determine if the data store is stale.
ae_ds_tmp.loaded_on = new Date().toISOString();
// Set the chk_account_id as a backup check to make sure the data store belongs to the account for the current site. This should not be needed, but here we are...
ae_ds_tmp.chk_account_id = $ae_loc.account_id;
ae_ds_tmp.id = ds_results.data_store_id_random;
ae_ds_tmp.account_id = ds_results.account_id_random;
ae_ds_tmp.code = ds_results.code; // This will overwrite whatever was passed in.
ae_ds_tmp.name = ds_results.name;
ae_ds_tmp.type = ds_results.type; // This will overwrite whatever was passed in.
if (type == 'html') {
ae_ds_tmp.html = ds_results.text;
val_html = ds_results.text;
return ds_results.html;
} else if (type == 'json') {
ae_ds_tmp.json = ds_results.json;
val_json = ds_results.json;
return ds_results.json;
} else if (type == 'md') {
ae_ds_tmp.text = ds_results.text;
val_md = ds_results.text;
return ds_results.text;
} else if (type == 'sql') {
ae_ds_tmp.text = ds_results.text;
val_sql = ds_results.text;
return ds_results.text;
} else {
ae_ds_tmp.text = ds_results.text;
val_text = ds_results.text;
return ds_results.text;
}
} else {
ds_loaded = false;
ds_loading_status = 'not found';
}
})
.then(function () {
if (browser && try_cache) {
if (log_lvl) {
console.log(`ae_e_data_store: Caching data store ${code} in localStorage.`);
}
localStorage.setItem(`ae_ds__${code}`, JSON.stringify(ae_ds_tmp));
} else {
// console.log(`ae_e_data_store: Not in browser. Not caching.`);
}
})
.catch(function (error: any) {
console.log(`Something went wrong. for code ${code}`);
console.log(error);
ds_loading_status = 'error';
return false;
});
// .finally(function (ds_val_result) {
// console.log(`ae_ ds_code_val = `, ds_val_result);
// ae_ds_loc.set(ds_val_result);
// localStorage.setItem(ds_code, ds_val_result);
// sessionStorage.setItem(ds_code, ds_val_result);
// return ds_val_result;
// });
// console.log(`ae_ ds_code_val = `, ds_code_val);
}
async function handle_submit_form(event: any) {
// console.log('*** handle_submit_form() ***');
$ae_sess.ds.submit_status = 'processing';
// Data in
let form_data = new FormData(event.target);
// console.log(form_data);
let data_store_di: key_val = ae_util.extract_prefixed_form_data({
prefix: null,
form_data: form_data,
trim_values: true,
bool_tf_str: true,
log_lvl: 0
});
// console.log(data_store_di);
// Data out
let data_store_do: key_val = {};
if (typeof data_store_di.ds_id_random !== 'undefined') {
data_store_do['data_store_id_random'] = data_store_di.ds_id_random;
}
// if (!$slct.data_store_id) {
if (!ae_ds_tmp.id) {
data_store_do['account_id_random'] = $ae_loc.account_id;
}
if (
typeof data_store_di.ds_account_id !== 'undefined' &&
data_store_di.ds_account_id &&
data_store_di.ds_use_account_id
) {
data_store_do['account_id_random'] = data_store_di.ds_account_id;
} else if (data_store_di.ds_use_account_id && $ae_loc.account_id) {
data_store_do['account_id_random'] = $ae_loc.account_id;
} else {
data_store_do['account_id_random'] = null;
}
if (typeof data_store_di.ds_code !== 'undefined') {
data_store_do['code'] = data_store_di.ds_code;
} else {
data_store_do['code'] = ds_code;
}
if (typeof data_store_di.ds_name !== 'undefined') {
data_store_do['name'] = data_store_di.ds_name;
} else {
data_store_do['name'] = ds_name;
}
if (typeof data_store_di.ds_type !== 'undefined') {
data_store_do['type'] = data_store_di.ds_type;
} else {
data_store_do['type'] = ds_type;
}
if (typeof data_store_di.ds_for_type !== 'undefined' && data_store_di.ds_for_type) {
data_store_do['for_type'] = data_store_di.ds_for_type;
} else {
data_store_do['for_type'] = null;
}
if (typeof data_store_di.ds_for_id !== 'undefined' && data_store_di.ds_for_id) {
data_store_do['for_id_random'] = data_store_di.ds_for_id;
} else {
data_store_do['for_id_random'] = null;
}
if (typeof data_store_di.ds_access_read !== 'undefined') {
data_store_do['access_read'] = data_store_di.ds_access_read;
}
if (typeof data_store_di.ds_access_write !== 'undefined') {
data_store_do['access_write'] = data_store_di.ds_access_write;
}
if (typeof data_store_di.ds_access_delete !== 'undefined') {
data_store_do['access_delete'] = data_store_di.ds_access_delete;
}
if (typeof data_store_di.ds_value !== 'undefined') {
if (data_store_di.ds_type == 'html') {
data_store_do['text'] = data_store_di.ds_value;
} else if (data_store_di.ds_type == 'json') {
data_store_do['json'] = data_store_di.ds_value;
} else if (data_store_di.ds_type == 'md') {
data_store_do['text'] = data_store_di.ds_value;
} else if (data_store_di.ds_type == 'sql') {
data_store_do['text'] = data_store_di.ds_value;
} else {
data_store_do['text'] = data_store_di.ds_value;
}
}
if (typeof data_store_di.ds_enable !== 'undefined') {
data_store_do['enable'] = data_store_di.ds_enable;
} else {
data_store_do['enable'] = true;
}
if (log_lvl) {
console.log(`ae_ Data Store data out:`, data_store_do);
}
if (!ae_ds_tmp.id) {
// Create
console.log(`ae_ Data Store Create:`, data_store_do);
ds_submit_results = handle_create__data_store({
obj_type: 'data_store',
data: data_store_do
})
.then(function (ds_results) {
console.log(`ae_ Data Store Create Results:`, ds_results);
if (ds_results) {
ae_ds_tmp.id = ds_results.data_store_id_random;
ae_ds_tmp.updated_on = ds_results.updated_on;
}
return ds_results;
})
.finally(function (ds_val_result) {
console.log(`ae_ ds_val_result = `, ds_val_result);
trigger = 'load__ds__code';
$ae_sess.ds.submit_status = 'created';
});
} else {
// Update
console.log(`ae_ Data Store Update:`, data_store_do);
ds_submit_results = handle_update__data_store({
obj_type: 'data_store',
obj_id: ae_ds_tmp.id,
data: data_store_do
})
.then(function (ds_results) {
console.log(`ae_ Data Store Update Results:`, ds_results);
if (ds_results) {
ae_ds_tmp.updated_on = ds_results.updated_on;
}
return ds_results;
// })
// .finally(function (ds_val_result) {
// // console.log(`ae_ ds_code_val = `, ds_val_result);
})
.finally(function () {
// console.log(`ae_ ds_val_result = `, ds_val_result);
console.log(
`ae_ load__ds__code: ${ds_code} ${ds_type} ${for_type} ${for_id} ${try_cache}`
);
trigger = 'load__ds__code';
$ae_sess.ds.submit_status = 'updated';
});
}
}
async function handle_create__data_store({
obj_type,
data
}: {
obj_type: string;
data: key_val;
}) {
if (log_lvl) {
console.log('*** handle_create__data_store() ***');
}
$ae_sess.ds.create_status = 'starting';
ae_promises.api_create__data_store_obj = api
.create_ae_obj_crud({
api_cfg: $ae_api,
obj_type: obj_type,
fields: data,
key: $ae_api.api_crud_super_key,
log_lvl: log_lvl
})
.then(async function (create__obj_result) {
if (!create__obj_result) {
console.log('The result was null or false.');
return false;
}
return create__obj_result;
})
.catch(function (error: any) {
console.log('Something went wrong.');
console.log(error);
return false;
})
.finally(function (create__obj_result) {
$ae_sess.ds.create_status = 'finished';
return create__obj_result;
});
return ae_promises.api_create__data_store_obj;
}
async function handle_update__data_store({
obj_type,
obj_id,
data
}: {
obj_type: string;
obj_id: string;
data: key_val;
}) {
if (log_lvl) {
console.log('*** handle_update__data_store() ***');
}
$ae_sess.ds.update_status = 'starting';
ae_promises.update__data_store_obj = api
.update_ae_obj_id_crud({
api_cfg: $ae_api,
obj_type: obj_type,
obj_id: obj_id,
fields: data,
key: $ae_api.api_crud_super_key,
log_lvl: log_lvl
})
.then(async function (update__obj_result) {
if (!update__obj_result) {
console.log('The result was null or false.');
return false;
}
return update__obj_result;
})
.catch(function (error: any) {
console.log('Something went wrong.');
console.log(error);
return false;
})
.finally(function (update__obj_result) {
$ae_sess.ds.update_status = 'finished';
return update__obj_result;
});
return ae_promises.update__data_store_obj;
}
run(() => {
if (trigger == 'load__ds__code' && ds_code && ds_type) {
if (log_lvl) {
console.log(
`ae_e_data_store: ae_ load__ds__code: ${ds_code} ds_type=${ds_type} for_type=${for_type} for_id=${for_id} ${try_cache}`
);
}
trigger = null;
load_data_store({
code: ds_code,
type: ds_type,
for_type: for_type,
for_id: for_id,
try_cache: try_cache
});
}
});
</script>
<div class="ae__elem__data_store relative {class_li}" class:hidden={hide}>
{#if ae_ds_tmp}
{#if debug || $ae_loc.debug == 'debug'}
<pre>
id: {ae_ds_tmp.id},
code: {ae_ds_tmp.code},
type: {ae_ds_tmp.type},
for_type: {ae_ds_tmp.for_type},
for_id: {ae_ds_tmp.for_id},
access_read: {ae_ds_tmp.access_read},
access_write: {ae_ds_tmp.access_write},
access_delete: {ae_ds_tmp.access_delete},
name: {ae_ds_tmp.name},
html: {ae_ds_tmp.html},
json: {ae_ds_tmp.json},
md: {ae_ds_tmp.md},
text: {ae_ds_tmp.text},
updated_on: {ae_ds_tmp.updated_on},
</pre>
{/if}
<!-- {#if show_edit} -->
<!-- <section class="edit z-50"> -->
{#if show_edit}
<Element_modal_v1
title={ae_ds_tmp.name + ' - ' + ae_ds_tmp.code}
bind:open={show_edit}
autoclose={false}
size="xl"
placement="top-center"
class_li="
bg-white dark:bg-gray-800 text-gray-800 dark:text-gray-200 rounded-lg border-gray-200 dark:border-gray-700 divide-gray-200 dark:divide-gray-700 shadow-md
relative flex flex-col
mx-auto divide-y
w-full
max-w-6xl
"
>
<form class="flex flex-col gap-1" onsubmit={preventDefault(handle_submit_form)}>
<input type="hidden" name="ds_id_random" value={ae_ds_tmp.id} />
<div class="flex flex-row gap-1">
{#if $ae_loc.trusted_access}
<label for="ds_use_account_id" class="label text-xs inline"
>Use Account ID
<input
type="checkbox"
name="ds_use_account_id"
class="checkbox"
value="true"
checked={ae_ds_tmp.account_id ? true : false}
/>
</label>
{/if}
{#if $ae_loc.manager_access}
<input
type="text"
name="ds_account_id"
class="input max-w-48 text-xs"
placeholder="Account ID"
value={ae_ds_tmp.account_id}
/>
<input
type="text"
name="ds_code"
class="input text-xs"
placeholder="Data store code"
value={ae_ds_tmp.code}
required
/>
{/if}
</div>
<div class="flex flex-row gap-1">
{#if $ae_loc.trusted_access}
<input
type="text"
name="ds_name"
class="input text-xs"
placeholder="Data store name"
value={ae_ds_tmp.name}
required
/>
{/if}
</div>
<div class="flex flex-row gap-1">
{#if $ae_loc.manager_access}
<input
type="text"
name="ds_type"
class="input max-w-48 text-xs"
placeholder="Data store type (html, json, md, sql, text)"
value={ae_ds_tmp.type}
required
/>
<input
type="text"
name="ds_for_type"
class="input max-w-48 text-xs"
placeholder="Data store For Type"
value={ae_ds_tmp.for_type}
/>
<input
type="text"
name="ds_for_id"
class="input max-w-48 text-xs"
placeholder="Data store For ID"
value={ae_ds_tmp.for_id}
/>
<input
type="text"
name="ds_access_read"
class="input max-w-48 text-xs"
placeholder="Access read"
value={ae_ds_tmp.access_read}
/>
<input
type="text"
name="ds_access_write"
class="input max-w-48 text-xs"
placeholder="Access write"
value={ae_ds_tmp.access_write}
/>
<input
type="text"
name="ds_access_delete"
class="input max-w-48 text-xs"
placeholder="Access delete"
value={ae_ds_tmp.access_delete}
/>
{:else}
Code: {ae_ds_tmp.code}
<!-- Name: {ae_ds_tmp.name} -->
Type: {ae_ds_tmp.type}
{/if}
</div>
<div class="">
<!-- Handle HTML type -->
{#if ae_ds_tmp.type == 'html' || ae_ds_tmp.type == null}
<textarea
name="ds_value"
class="textarea type_html font-mono text-sm"
cols="75"
rows="25"
placeholder="Enter the HTML here"
>{ae_ds_tmp.type == 'html' && ae_ds_tmp.html
? ae_ds_tmp.html
: ''}</textarea
>
<!-- Handle SQL type -->
{:else if ae_ds_tmp.type == 'sql'}
<textarea
name="ds_value"
class="textarea type_sql font-mono text-sm"
cols="75"
rows="25"
placeholder="Enter the SQL here"
>{ae_ds_tmp.type == 'sql' && ae_ds_tmp.text
? ae_ds_tmp.text
: ''}</textarea
>
<!-- Handle text type -->
{:else if ae_ds_tmp.type == 'text'}
<textarea
name="ds_value"
class="textarea type_text"
cols="70"
rows="10"
placeholder="Enter the text here"
>{ae_ds_tmp.type == 'text' ? ae_ds_tmp.text : ''}</textarea
>
{/if}
</div>
<div class="flex flex-row gap-1 justify-center justify-evenly items-center">
<button
type="button"
class="btn preset-tonal-warning"
onclick={() => {
if (confirm('Are you sure you want to delete this data store?')) {
trigger = 'delete__ds__code';
// $slct_trigger = 'delete__ds__code';
}
show_edit = false;
show_view = true;
}}
>
<span class="fas fa-trash mx-1"></span>
Delete
</button>
<button
type="submit"
class="btn preset-tonal-primary border border-primary-500"
disabled={ds_submit_results instanceof Promise && !ds_submit_results}
onclick={() => {
trigger = 'save__ds__code';
// $slct_trigger = 'save__ds__code';
}}
>
<span class="fas fa-save mx-1"></span>
Save
</button>
{#await ds_submit_results}
<div class="modal-loading">
<span class="fas fa-spinner fa-spin"></span>
<span class="loading-text"> Saving... </span>
</div>
{:then ds_submit_results}
{#if ds_submit_results}
<div>
<span class="fas fa-check text-green-500"></span>
<span class="saved-text"> Saved </span>
</div>
{/if}
{/await}
<div class="ae_debug" class:hidden={!debug && $ae_loc.debug != 'debug'}>
submit: {$ae_sess.ds.submit_status}
create: {$ae_sess.ds.create_status}
update: {$ae_sess.ds.update_status}
</div>
</div>
</form>
{#snippet footer()}
<div class="text-center w-full">
<button
type="button"
onclick={() => {
console.log('Close modal edit data store.');
show_edit = false;
show_view = true;
}}
class="btn btn-sm preset-tonal-warning hover:preset-tonal-warning border border-warning-500"
>
<span class="fas fa-times mx-1"></span>
Close
</button>
</div>
{/snippet}
</Element_modal_v1>
{/if}
<!-- </section> -->
<!-- {/if} -->
<!-- {#if mode == 'view'} -->
{#if !ae_ds_tmp.type && !ae_ds_tmp.html && !ae_ds_tmp.json && !ae_ds_tmp.md && !ae_ds_tmp.text}
{#if $ae_loc.manager_access}
<span class="preset-tonal-warning"
>No data found! Is the data store correct or new?</span
>
{:else}
<!-- <span class="variant-soft">loading</span> -->
{/if}
{/if}
{#if ae_ds_tmp.type == 'html' && ae_ds_tmp.html}
<!-- TODO: Review for XSS vulnerability: ae_ds_tmp.html -->
{:else if ae_ds_tmp.type == 'html'}
{#if $ae_loc.manager_access}
<span class="preset-tonal-warning"
>No HTML found! Is the data store type correct?</span
>
{:else}
<!-- <span class="variant-soft">loading</span> -->
{/if}
{/if}
{#if ae_ds_tmp.type == 'text' && ae_ds_tmp.text}
{ae_ds_tmp.text}
{:else if ae_ds_tmp.type == 'text'}
{#if $ae_loc.manager_access}
<span class="preset-tonal-warning"
>No text found! Is the data store type correct?</span
>
{:else}
<!-- <span class="variant-soft">loading</span> -->
{/if}
{/if}
<button
type="button"
class="ae_btn_edit__ds btn hover:preset-tonal-warning text-xs absolute top-0 right-0 opacity-30 hover:opacity-100 transition delay-700 hover:delay-200 p-1 z-50"
class:opacity-5={!$ae_loc.manager_access}
class:hidden={!(
($ae_loc.manager_access && $ae_loc.edit_mode) ||
(show_edit_btn && $ae_loc.administrator_access && $ae_loc.edit_mode)
)}
ondblclick={() => {
trigger = 'load__ds__code';
show_edit = true;
show_view = false;
}}
title="Double click to edit data store: {ds_code} with {ae_ds_tmp.account_id
? `account ID=${ae_ds_tmp.account_id}`
: 'no account ID'}"
>
<span class="fas fa-edit mx-1"></span>
Edit
</button>
<!-- {/if} -->
{:else}
<!-- Nothing to see yet -->
{/if}
<!-- Text:
<pre>
{val_text}
</pre> -->
<!-- JSON:
<pre>
{val_json}
</pre> -->
{#await ds_get_results}
<div
class="modal-loading text-xs absolute bottom-0 left-0 opacity-30 hover:opacity-100 transition delay-700 hover:delay-200"
>
<span class="fas fa-spinner fa-spin"></span>
<span class="loading-text"> Loading... </span>
</div>
{/await}
<!-- {ds_loading_status} -->
</div>
<style lang="postcss">
/* .ae_btn_edit__ds {
opacity: .5;
} */
/* The section.edit should be above the rest of the content and centered on the page */
/*
section.edit {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 100;
background-color: hsla(0, 0%, 100%, .95);
padding: 1rem;
border-radius: .5rem;
box-shadow: 0 0 1rem hsla(0, 0%, 0%, .5);
min-width: 80%;
}
*/
/* .hide {
display: none;
} */
</style>