use the presentable prop when displaying relations
This commit is contained in:
parent
26fd3d48df
commit
f0af24d78f
|
@ -216,7 +216,21 @@
|
||||||
text: `Requires the field value NOT to be ${CommonHelper.zeroDefaultStr(
|
text: `Requires the field value NOT to be ${CommonHelper.zeroDefaultStr(
|
||||||
field
|
field
|
||||||
)}.`,
|
)}.`,
|
||||||
position: "right",
|
}}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</Field>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<Field class="form-field form-field-toggle m-0" name="presentable" let:uniqueId>
|
||||||
|
<input type="checkbox" id={uniqueId} bind:checked={field.presentable} />
|
||||||
|
<label for={uniqueId}>
|
||||||
|
<span class="txt">Presentable</span>
|
||||||
|
<i
|
||||||
|
class="ri-information-line link-hint"
|
||||||
|
use:tooltip={{
|
||||||
|
text: `Whether the field should be preferred in the Admin UI relation listings.`,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
|
|
|
@ -21,13 +21,8 @@
|
||||||
{ label: "True", value: true },
|
{ label: "True", value: true },
|
||||||
];
|
];
|
||||||
|
|
||||||
const baseFields = ["id", "created", "updated"];
|
|
||||||
|
|
||||||
const authFields = ["username", "email", "emailVisibility", "verified"];
|
|
||||||
|
|
||||||
let upsertPanel = null;
|
let upsertPanel = null;
|
||||||
let displayFieldsList = [];
|
let displayFieldsList = [];
|
||||||
let oldCollectionId = null;
|
|
||||||
let isSingle = field.options?.maxSelect == 1;
|
let isSingle = field.options?.maxSelect == 1;
|
||||||
let oldIsSingle = isSingle;
|
let oldIsSingle = isSingle;
|
||||||
|
|
||||||
|
@ -50,45 +45,15 @@
|
||||||
|
|
||||||
$: selectedColection = $collections.find((c) => c.id == field.options.collectionId) || null;
|
$: selectedColection = $collections.find((c) => c.id == field.options.collectionId) || null;
|
||||||
|
|
||||||
$: if (oldCollectionId != field.options.collectionId) {
|
|
||||||
oldCollectionId = field.options.collectionId;
|
|
||||||
refreshDisplayFieldsList();
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadDefaults() {
|
function loadDefaults() {
|
||||||
field.options = {
|
field.options = {
|
||||||
maxSelect: 1,
|
maxSelect: 1,
|
||||||
collectionId: null,
|
collectionId: null,
|
||||||
cascadeDelete: false,
|
cascadeDelete: false,
|
||||||
displayFields: [],
|
|
||||||
};
|
};
|
||||||
isSingle = true;
|
isSingle = true;
|
||||||
oldIsSingle = isSingle;
|
oldIsSingle = isSingle;
|
||||||
}
|
}
|
||||||
|
|
||||||
function refreshDisplayFieldsList() {
|
|
||||||
displayFieldsList = baseFields.slice(0);
|
|
||||||
if (!selectedColection) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (selectedColection.type === "auth") {
|
|
||||||
displayFieldsList = displayFieldsList.concat(authFields);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const f of selectedColection.schema) {
|
|
||||||
displayFieldsList.push(f.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
// deselect any missing display field
|
|
||||||
if (field.options?.displayFields?.length > 0) {
|
|
||||||
for (let i = field.options.displayFields.length - 1; i >= 0; i--) {
|
|
||||||
if (!displayFieldsList.includes(field.options.displayFields[i])) {
|
|
||||||
field.options.displayFields.splice(i, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<SchemaField bind:field {key} on:rename on:remove {...$$restProps}>
|
<SchemaField bind:field {key} on:rename on:remove {...$$restProps}>
|
||||||
|
@ -174,29 +139,7 @@
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-12">
|
||||||
<Field class="form-field" name="schema.{key}.options.displayFields" let:uniqueId>
|
|
||||||
<label for={uniqueId}>
|
|
||||||
<span class="txt">Display fields</span>
|
|
||||||
<i
|
|
||||||
class="ri-information-line link-hint"
|
|
||||||
use:tooltip={{
|
|
||||||
text: "Optionally select the field(s) that will be used in the listings UI. Leave empty for auto.",
|
|
||||||
position: "top",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</label>
|
|
||||||
<Select
|
|
||||||
multiple
|
|
||||||
searchable
|
|
||||||
id={uniqueId}
|
|
||||||
selectPlaceholder="Auto"
|
|
||||||
items={displayFieldsList}
|
|
||||||
bind:selected={field.options.displayFields}
|
|
||||||
/>
|
|
||||||
</Field>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-6">
|
|
||||||
<Field class="form-field" name="schema.{key}.options.cascadeDelete" let:uniqueId>
|
<Field class="form-field" name="schema.{key}.options.cascadeDelete" let:uniqueId>
|
||||||
<label for={uniqueId}>
|
<label for={uniqueId}>
|
||||||
<span class="txt">Cascade delete</span>
|
<span class="txt">Cascade delete</span>
|
||||||
|
@ -205,7 +148,7 @@
|
||||||
class="ri-information-line link-hint"
|
class="ri-information-line link-hint"
|
||||||
use:tooltip={{
|
use:tooltip={{
|
||||||
text: [
|
text: [
|
||||||
`Whether on ${selectedColection?.name || "relation"} record deletion to delete also the corresponding current collection record(s).`,
|
`Whether on ${selectedColection?.name || "relation"} record deletion to delete also the current corresponding collection record(s).`,
|
||||||
!isSingle ? `For "Multiple" relation fields the cascade delete is triggered only when all ${selectedColection?.name || "relation"} ids are removed from the corresponding record.` : null
|
!isSingle ? `For "Multiple" relation fields the cascade delete is triggered only when all ${selectedColection?.name || "relation"} ids are removed from the corresponding record.` : null
|
||||||
].filter(Boolean).join("\n\n"),
|
].filter(Boolean).join("\n\n"),
|
||||||
position: "top",
|
position: "top",
|
||||||
|
|
|
@ -89,7 +89,7 @@
|
||||||
{#if expanded.length}
|
{#if expanded.length}
|
||||||
{#each expanded.slice(0, relLimit) as item, i (i + item)}
|
{#each expanded.slice(0, relLimit) as item, i (i + item)}
|
||||||
<span class="label">
|
<span class="label">
|
||||||
<RecordInfo record={item} displayFields={field.options?.displayFields} />
|
<RecordInfo record={item} />
|
||||||
</span>
|
</span>
|
||||||
{/each}
|
{/each}
|
||||||
{:else}
|
{:else}
|
||||||
|
|
|
@ -5,19 +5,14 @@
|
||||||
import RecordFileThumb from "@/components/records/RecordFileThumb.svelte";
|
import RecordFileThumb from "@/components/records/RecordFileThumb.svelte";
|
||||||
|
|
||||||
export let record;
|
export let record;
|
||||||
export let displayFields = [];
|
|
||||||
|
|
||||||
$: collection = $collections?.find((item) => item.id == record?.collectionId);
|
$: collection = $collections?.find((item) => item.id == record?.collectionId);
|
||||||
|
|
||||||
$: fileDisplayFields =
|
$: fileDisplayFields =
|
||||||
displayFields?.filter((name) => {
|
collection?.schema?.filter((f) => f.presentable && f.type == "file")?.map((f) => f.name) || [];
|
||||||
return !!collection?.schema?.find((field) => field.name == name && field.type == "file");
|
|
||||||
}) || [];
|
|
||||||
|
|
||||||
$: textDisplayFields =
|
$: textDisplayFields =
|
||||||
(!fileDisplayFields.length
|
collection?.schema?.filter((f) => f.presentable && f.type != "file")?.map((f) => f.name) || [];
|
||||||
? displayFields
|
|
||||||
: displayFields?.filter((name) => !fileDisplayFields.includes(name))) || [];
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="record-info">
|
<div class="record-info">
|
||||||
|
|
|
@ -32,8 +32,6 @@
|
||||||
|
|
||||||
$: collectionId = field?.options?.collectionId;
|
$: collectionId = field?.options?.collectionId;
|
||||||
|
|
||||||
$: displayFields = field?.options?.displayFields;
|
|
||||||
|
|
||||||
$: collection = $collections.find((c) => c.id == collectionId) || null;
|
$: collection = $collections.find((c) => c.id == collectionId) || null;
|
||||||
|
|
||||||
$: if (typeof filter !== "undefined" && pickerPanel?.isActive()) {
|
$: if (typeof filter !== "undefined" && pickerPanel?.isActive()) {
|
||||||
|
@ -252,7 +250,7 @@
|
||||||
<i class="ri-checkbox-blank-circle-line txt-disabled" />
|
<i class="ri-checkbox-blank-circle-line txt-disabled" />
|
||||||
{/if}
|
{/if}
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<RecordInfo {record} {displayFields} />
|
<RecordInfo {record} />
|
||||||
</div>
|
</div>
|
||||||
{#if !isView}
|
{#if !isView}
|
||||||
<div class="actions nonintrusive">
|
<div class="actions nonintrusive">
|
||||||
|
@ -301,7 +299,7 @@
|
||||||
{#each selected as record, i}
|
{#each selected as record, i}
|
||||||
<Draggable bind:list={selected} index={i} let:dragging let:dragover>
|
<Draggable bind:list={selected} index={i} let:dragging let:dragover>
|
||||||
<span class="label" class:label-danger={dragging} class:label-warning={dragover}>
|
<span class="label" class:label-danger={dragging} class:label-warning={dragover}>
|
||||||
<RecordInfo {record} {displayFields} />
|
<RecordInfo {record} />
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
title="Remove"
|
title="Remove"
|
||||||
|
|
|
@ -149,7 +149,7 @@
|
||||||
>
|
>
|
||||||
<div class="list-item" class:dragging class:dragover>
|
<div class="list-item" class:dragging class:dragover>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<RecordInfo {record} displayFields={field.options?.displayFields} />
|
<RecordInfo {record} />
|
||||||
</div>
|
</div>
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<button
|
<button
|
||||||
|
|
|
@ -62,6 +62,7 @@
|
||||||
left: 4px;
|
left: 4px;
|
||||||
top: 4px;
|
top: 4px;
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
.marker {
|
.marker {
|
||||||
|
|
|
@ -1415,7 +1415,9 @@ export default class CommonHelper {
|
||||||
* Tries to output the first displayable field of the provided model.
|
* Tries to output the first displayable field of the provided model.
|
||||||
*
|
*
|
||||||
* @param {Object} model
|
* @param {Object} model
|
||||||
* @return {Any}
|
* @param {Array<string>} displayFields
|
||||||
|
* @param {String} [missingValue]
|
||||||
|
* @return {String}
|
||||||
*/
|
*/
|
||||||
static displayValue(model, displayFields, missingValue = "N/A") {
|
static displayValue(model, displayFields, missingValue = "N/A") {
|
||||||
model = model || {};
|
model = model || {};
|
||||||
|
@ -1423,8 +1425,8 @@ export default class CommonHelper {
|
||||||
|
|
||||||
let result = [];
|
let result = [];
|
||||||
|
|
||||||
for (const field of displayFields) {
|
for (const prop of displayFields) {
|
||||||
let val = model[field];
|
let val = model[prop];
|
||||||
|
|
||||||
if (typeof val === "undefined") {
|
if (typeof val === "undefined") {
|
||||||
continue
|
continue
|
||||||
|
@ -1445,10 +1447,12 @@ export default class CommonHelper {
|
||||||
"slug",
|
"slug",
|
||||||
"email",
|
"email",
|
||||||
"username",
|
"username",
|
||||||
|
"nickname",
|
||||||
"label",
|
"label",
|
||||||
"heading",
|
"heading",
|
||||||
"message",
|
"message",
|
||||||
"key",
|
"key",
|
||||||
|
"identifier",
|
||||||
"id",
|
"id",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue