2022-07-07 05:19:05 +08:00
|
|
|
<script>
|
|
|
|
import { SchemaField } from "pocketbase";
|
|
|
|
import FieldAccordion from "@/components/collections/FieldAccordion.svelte";
|
|
|
|
|
|
|
|
export let collection = {};
|
|
|
|
|
2022-10-30 16:28:14 +08:00
|
|
|
const baseReservedNames = [
|
|
|
|
"id",
|
|
|
|
"created",
|
|
|
|
"updated",
|
|
|
|
"collectionId",
|
|
|
|
"collectionName",
|
|
|
|
"expand",
|
|
|
|
"true",
|
|
|
|
"false",
|
|
|
|
"null",
|
|
|
|
];
|
|
|
|
|
|
|
|
let reservedNames = [];
|
|
|
|
|
|
|
|
$: if (collection.isAuth) {
|
|
|
|
reservedNames = baseReservedNames.concat([
|
|
|
|
"username",
|
|
|
|
"email",
|
|
|
|
"emailVisibility",
|
|
|
|
"verified",
|
|
|
|
"tokenKey",
|
|
|
|
"passwordHash",
|
|
|
|
"lastResetSentAt",
|
|
|
|
"lastVerificationSentAt",
|
|
|
|
"password",
|
|
|
|
"passwordConfirm",
|
|
|
|
"oldPassword",
|
|
|
|
]);
|
|
|
|
} else {
|
|
|
|
reservedNames = baseReservedNames.slice(0);
|
|
|
|
}
|
|
|
|
|
2022-07-07 05:19:05 +08:00
|
|
|
$: if (typeof collection?.schema === "undefined") {
|
|
|
|
collection = collection || {};
|
|
|
|
collection.schema = [];
|
|
|
|
}
|
|
|
|
|
|
|
|
function removeField(fieldIndex) {
|
|
|
|
if (collection.schema[fieldIndex]) {
|
|
|
|
collection.schema.splice(fieldIndex, 1);
|
|
|
|
collection.schema = collection.schema;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function newField() {
|
|
|
|
const field = new SchemaField({
|
|
|
|
name: getUniqueFieldName(),
|
|
|
|
});
|
|
|
|
|
|
|
|
collection.schema.push(field);
|
|
|
|
collection.schema = collection.schema;
|
|
|
|
}
|
|
|
|
|
|
|
|
function getUniqueFieldName(base = "field") {
|
|
|
|
let counter = "";
|
|
|
|
|
|
|
|
while (hasFieldWithName(base + counter)) {
|
|
|
|
++counter;
|
|
|
|
}
|
|
|
|
|
|
|
|
return base + counter;
|
|
|
|
}
|
|
|
|
|
|
|
|
function hasFieldWithName(name) {
|
|
|
|
return !!collection.schema.find((field) => field.name === name);
|
|
|
|
}
|
|
|
|
|
|
|
|
function getSiblingsFieldNames(currentField) {
|
|
|
|
let result = [];
|
|
|
|
|
2022-07-18 21:26:37 +08:00
|
|
|
if (currentField.toDelete) {
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2022-07-07 05:19:05 +08:00
|
|
|
for (let field of collection.schema) {
|
2022-07-18 21:26:37 +08:00
|
|
|
if (field === currentField || field.toDelete) {
|
|
|
|
continue; // skip current and deleted fields
|
2022-07-07 05:19:05 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
result.push(field.name);
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
2022-10-30 16:28:14 +08:00
|
|
|
|
|
|
|
// ---------------------------------------------------------------
|
|
|
|
// fields drag&drop handling
|
|
|
|
// ---------------------------------------------------------------
|
|
|
|
|
|
|
|
function onFieldDrag(event, i) {
|
|
|
|
if (!event) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
event.dataTransfer.effectAllowed = "move";
|
|
|
|
event.dataTransfer.dropEffect = "move";
|
|
|
|
event.dataTransfer.setData("text/plain", i);
|
|
|
|
}
|
|
|
|
|
|
|
|
function onFieldDrop(event, target) {
|
|
|
|
if (!event) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
event.dataTransfer.dropEffect = "move";
|
|
|
|
|
|
|
|
const start = parseInt(event.dataTransfer.getData("text/plain"));
|
|
|
|
const newSchema = collection.schema;
|
|
|
|
|
|
|
|
if (start < target) {
|
|
|
|
newSchema.splice(target + 1, 0, newSchema[start]);
|
|
|
|
newSchema.splice(start, 1);
|
|
|
|
} else {
|
|
|
|
newSchema.splice(target, 0, newSchema[start]);
|
|
|
|
newSchema.splice(start + 1, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
collection.schema = newSchema;
|
|
|
|
}
|
2022-07-07 05:19:05 +08:00
|
|
|
</script>
|
|
|
|
|
2022-10-30 16:28:14 +08:00
|
|
|
<div class="block m-b-25">
|
|
|
|
<p class="txt-sm">
|
|
|
|
System fields:
|
|
|
|
<code class="txt-sm">id</code> ,
|
|
|
|
<code class="txt-sm">created</code> ,
|
|
|
|
<code class="txt-sm">updated</code>
|
|
|
|
{#if collection.isAuth}
|
|
|
|
,
|
|
|
|
<code class="txt-sm">username</code> ,
|
|
|
|
<code class="txt-sm">email</code> ,
|
|
|
|
<code class="txt-sm">emailVisibility</code> ,
|
|
|
|
<code class="txt-sm">verified</code>
|
|
|
|
{/if}
|
|
|
|
.
|
|
|
|
</p>
|
|
|
|
</div>
|
2022-07-07 05:19:05 +08:00
|
|
|
<div class="accordions">
|
2022-10-30 16:28:14 +08:00
|
|
|
{#each collection.schema as field, i (i + field.id)}
|
2022-07-07 05:19:05 +08:00
|
|
|
<FieldAccordion
|
|
|
|
bind:field
|
|
|
|
key={i}
|
|
|
|
excludeNames={reservedNames.concat(getSiblingsFieldNames(field))}
|
|
|
|
on:remove={() => removeField(i)}
|
2022-10-30 16:28:14 +08:00
|
|
|
on:dragstart={(e) => onFieldDrag(e?.detail, i)}
|
|
|
|
on:drop={(e) => onFieldDrop(e?.detail, i)}
|
2022-07-07 05:19:05 +08:00
|
|
|
/>
|
|
|
|
{/each}
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="clearfix m-t-xs" />
|
|
|
|
|
|
|
|
<button
|
|
|
|
type="button"
|
2022-11-16 21:13:04 +08:00
|
|
|
class="btn btn-block {collection?.isAuth || collection.schema?.length ? 'btn-secondary' : 'btn-warning'}"
|
2022-07-07 05:19:05 +08:00
|
|
|
on:click={newField}
|
|
|
|
>
|
|
|
|
<i class="ri-add-line" />
|
|
|
|
<span class="txt">New field</span>
|
|
|
|
</button>
|