dialog wip

This commit is contained in:
2024-08-15 22:11:26 +03:00
parent 113533408d
commit 2429d4acb5
19 changed files with 364 additions and 112 deletions
+3
View File
@@ -8,6 +8,8 @@
import HomeIndex from "./home/Index.svelte";
import BuildReport from "./build/Report.svelte";
import Header from "./layout/Header.svelte";
import BrowseModal from "./records/elements/BrowseModal.svelte";
import Dialog from "./dialog/Dialog.svelte";
const components = {
members: Members,
@@ -48,3 +50,4 @@
</div>
+16 -10
View File
@@ -76,7 +76,7 @@
path: '<path d="M447.1 224c0-12.56-4.781-25.13-14.35-34.76l-174.9-174.9C249.1 4.786 236.5 0 223.1 0C211.4 0 198.9 4.786 189.2 14.35L14.35 189.2C4.783 198.9-.0011 211.4-.0011 223.1c0 12.56 4.785 25.17 14.35 34.8l174.9 174.9c9.625 9.562 22.19 14.35 34.75 14.35s25.13-4.783 34.75-14.35l174.9-174.9C443.2 249.1 447.1 236.6 447.1 224zM96 248c-13.25 0-23.1-10.75-23.1-23.1s10.75-23.1 23.1-23.1S120 210.8 120 224S109.3 248 96 248zM224 376c-13.25 0-23.1-10.75-23.1-23.1s10.75-23.1 23.1-23.1s23.1 10.75 23.1 23.1S237.3 376 224 376zM224 248c-13.25 0-23.1-10.75-23.1-23.1s10.75-23.1 23.1-23.1S248 210.8 248 224S237.3 248 224 248zM224 120c-13.25 0-23.1-10.75-23.1-23.1s10.75-23.1 23.1-23.1s23.1 10.75 23.1 23.1S237.3 120 224 120zM352 248c-13.25 0-23.1-10.75-23.1-23.1s10.75-23.1 23.1-23.1s23.1 10.75 23.1 23.1S365.3 248 352 248zM591.1 192l-118.7 0c4.418 10.27 6.604 21.25 6.604 32.23c0 20.7-7.865 41.38-23.63 57.14l-136.2 136.2v46.37C320 490.5 341.5 512 368 512h223.1c26.5 0 47.1-21.5 47.1-47.1V240C639.1 213.5 618.5 192 591.1 192zM479.1 376c-13.25 0-23.1-10.75-23.1-23.1s10.75-23.1 23.1-23.1s23.1 10.75 23.1 23.1S493.2 376 479.1 376z"/>',
viewBox: "0 0 640 512",
},
"triangle-exclamation": {
path: '<path d="M506.3 417l-213.3-364c-16.33-28-57.54-28-73.98 0l-213.2 364C-10.59 444.9 9.849 480 42.74 480h426.6C502.1 480 522.6 445 506.3 417zM232 168c0-13.25 10.75-24 24-24S280 154.8 280 168v128c0 13.25-10.75 24-23.1 24S232 309.3 232 296V168zM256 416c-17.36 0-31.44-14.08-31.44-31.44c0-17.36 14.07-31.44 31.44-31.44s31.44 14.08 31.44 31.44C287.4 401.9 273.4 416 256 416z"/>',
viewBox: "0 0 512 512",
@@ -105,7 +105,13 @@
path: '<path d="M438.6 105.4C451.1 117.9 451.1 138.1 438.6 150.6L182.6 406.6C170.1 419.1 149.9 419.1 137.4 406.6L9.372 278.6C-3.124 266.1-3.124 245.9 9.372 233.4C21.87 220.9 42.13 220.9 54.63 233.4L159.1 338.7L393.4 105.4C405.9 92.88 426.1 92.88 438.6 105.4H438.6z"/>',
viewBox: "0 0 448 512",
},
"close": {
path: '<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18 17.94 6M18 18 6.06 6"/>',
viewBox: "0 0 24 24",
},
};
export let width = 16;
export let height = 16;
export let icon = "";
@@ -116,15 +122,15 @@
</script>
<svg
class="bi"
xmlns="http://www.w3.org/2000/svg"
{width}
{height}
viewBox={selectedIcon.viewBox}
aria-labelledby={icon}
role="presentation"
{stroke}
{fill}
class="bi"
xmlns="http://www.w3.org/2000/svg"
{width}
{height}
viewBox={selectedIcon.viewBox}
aria-labelledby={icon}
role="presentation"
{stroke}
{fill}
>
{@html selectedIcon.path}
@@ -37,47 +37,45 @@
<div style="display: flex;align-items: center; gap: 8px">
<span class="me-2">{selected.length} records selected</span>
<div class="btn-group " role="group" aria-label="Basic example">
<button
<button
on:click|preventDefault={(e) => changeStatus(e, "published")}
type="button"
class="button">Publish
</button
>
<button
</button
>
<button
on:click|preventDefault={(e) => changeStatus(e, "draft")}
type="button"
class="button">Make Draft
</button
>
{#if filter["status_in"] === "trashed"}
<button
</button
>
{#if filter["status_in"] === "trashed"}
<button
on:click|preventDefault={(e) => changeStatus(e, "published")}
type="button"
class="button">Publish
</button
>
{#if schema.hasDrafts}
<button
</button
>
{#if schema.hasDrafts}
<button
on:click|preventDefault={(e) => changeStatus(e, "draft")}
type="button"
class="button">Make Draft
</button
>
{/if}
<button
on:click|preventDefault={deleteRecords}
type="button"
class="button">Delete forever
</button
>
{:else}
<button
type="button"
on:click|preventDefault={(e) => changeStatus(e, "trashed")}
class="button">Move to trash
</button
>
{/if}
</div>
<button
on:click|preventDefault={deleteRecords}
type="button"
class="button">Delete forever
</button
>
{:else}
<button
type="button"
on:click|preventDefault={(e) => changeStatus(e, "trashed")}
class="button">Move to trash
</button
>
{/if}
</div>
+14 -1
View File
@@ -39,6 +39,7 @@
limit = response.data.limit;
total = response.data.total;
modalUrl = response.data.modalUrl;
document.querySelector("dialog h3").scrollIntoView();
})
.catch((error) => {
console.log(error);
@@ -84,12 +85,24 @@
bind:selected
/>
{:else}
<Grid
<Table
{records}
{graph}
{schema}
{sortParam}
{sortField}
{systemFields}
{inModal}
{users}
{isWritable}
bind:selected
/>
<!-- <Grid-->
<!-- {records}-->
<!-- {schema}-->
<!-- {isWritable}-->
<!-- bind:selected-->
<!-- />-->
{/if}
</div>
+5 -5
View File
@@ -23,7 +23,7 @@
<RenderField {record} {schema} {graph} {field}/>
</td>
{/each}
{#if schema.visible.includes("status")}
{#if schema.visible?.includes("status")}
<td
class="text-center"
class:is-sort={"-status" == sortParam || "status" == sortParam}
@@ -31,7 +31,7 @@
<Status status={record.status}/>
</td>
{/if}
{#if schema.visible.includes("_sys.createdBy")}
{#if schema.visible?.includes("_sys.createdBy")}
<td
class="text-center"
class:is-sort={"-_sys.createdBy" == sortParam || "_sys.createdBy" == sortParam}
@@ -39,7 +39,7 @@
<Avatar name={usernameById(users, record._sys.createdBy)} side={24}/>
</td>
{/if}
{#if schema.visible.includes("_sys.updatedBy")}
{#if schema.visible?.includes("_sys.updatedBy")}
<td
class="text-center"
class:is-sort={"-_sys.updatedBy" == sortParam || "_sys.updatedBy" == sortParam}
@@ -47,12 +47,12 @@
<Avatar name={usernameById(users, record._sys.updatedBy)} side={24}/>
</td>
{/if}
{#if schema.visible.includes("_sys.createdAt")}
{#if schema.visible?.includes("_sys.createdAt")}
<td class:is-sort={"-_sys.createdAt" == sortParam || "_sys.createdAt" == sortParam}>
{friendlyDate(record._sys.createdAt)}
</td>
{/if}
{#if schema.visible.includes("_sys.updatedAt")}
{#if schema.visible?.includes("_sys.updatedAt")}
<td class:is-sort={"-_sys.updatedAt" == sortParam || "_sys.updatedAt" == sortParam}>
{friendlyDate(record._sys.updatedAt)}
</td>
+14 -8
View File
@@ -6,6 +6,7 @@
import Avatar from "../account/Avatar.svelte";
import {selectRecord, toggleAll} from "./functions/recordSelect.js";
import Checkbox from "../common/Checkbox.svelte";
import Preview from "../files/Preview.svelte";
const channel = getContext("channel");
@@ -28,7 +29,7 @@
selected = selectRecord(record, selected)
}
$: visibleColumns = schema.fields.filter(c => schema.visible.includes(c.name))
$: visibleColumns = schema.fields.filter(c => schema.visible?.includes(c.name) ?? [])
</script>
@@ -39,6 +40,7 @@
{#if isWritable}
<th>
<Checkbox
value=""
on:change={eventToggleAll}
indeterminate={selected.length > 0 && selected.length < records.length}
checked={selected.length === records.length}
@@ -53,10 +55,10 @@
class:is-sort={field.name === sortField.name}
scope="col"
title={field.help}
>{field.label}</th
>{field.label}</th
>
{/each}
{#each systemFields.filter(c => schema.visible.includes(c.name)) as sysField}
{#each systemFields.filter(c => schema.visible?.includes(c.name)) as sysField}
<th class:is-sort={sysField.name === sortField.name}>{sysField.label}</th>
{/each}
<th></th>
@@ -78,7 +80,9 @@
</Checkbox>
{/if}
{#if record._file?.path}
<Preview record={record} size="medium"/>
{/if}
<a
class="me-2 text-decoration-none text-dark fs-6"
href="{channel.lucentUrl}/records/{record.id}"
@@ -98,13 +102,15 @@
{sortField}
{users}
/>
<td> <Avatar
name={usernameById(
<td>
<Avatar
name={usernameById(
users,
record._sys.updatedBy
)}
side={24}
/></td>
side={24}
/>
</td>
</tr>
{/each}
</tbody>
+97
View File
@@ -0,0 +1,97 @@
<script>
import {createEventDispatcher, getContext, onMount} from "svelte";
import Icon from "../common/Icon.svelte";
import Index from "../content/Index.svelte";
let dialogEl;
const dispatch = createEventDispatcher();
const channel = getContext("channel");
$: data = {};
let selectedRecords = [];
// onMount(() => {
// load();
// });
export function close() {
dialogEl.close()
selectedRecords = [];
}
function load(schema) {
axios
.get(channel.lucentUrl + "/content/" + schema)
.then((response) => {
data = response.data;
})
.catch((error) => console.log(error));
}
function insert(e) {
e.preventDefault();
dispatch("insert", {
records: selectedRecords,
action: "insert",
});
}
function replace(e) {
e.preventDefault();
dispatch("insert", {
records: selectedRecords,
action: "replace",
});
}
export function open(schema) {
dialogEl.showModal()
load(schema);
}
</script>
<dialog bind:this={dialogEl}>
{#if data.schema}
<div class="dialog-header">
<button
type="button"
class="btn btn-primary me-1"
on:click={insert}
disabled={selectedRecords.length === 0}
>
Insert
</button>
<button
type="button"
class="btn btn-outline-primary me-3"
on:click={replace}
disabled={selectedRecords.length === 0}
>
Replace
</button>
{#if selectedRecords.length > 0}
<span class="">
{selectedRecords.length} records selected
</span>
{/if}
</div>
<button
on:click|preventDefault={close}
type="button"
class="button close"
aria-label="Close"
>
<Icon icon="close"></Icon>
</button>
<div class="dialog-body">
<Index {...data} bind:selected={selectedRecords}></Index>
</div>
{/if}
</dialog>
+3 -2
View File
@@ -1,6 +1,6 @@
<script>
import Icon from "../common/Icon.svelte";
import {imgurl} from "../files/imageserver";
import {imgurl} from "./imageserver.js";
import {getContext} from "svelte";
export let record;
@@ -35,7 +35,7 @@
<!-- href={imgurl(record)} -->
<a
href="{channel.lucentUrl}/records/{record.id}"
title={record._file.path}
title={record._file.originalName}
style="width:{imageSide}px;height:{imageSide}px"
>
<img
@@ -76,6 +76,7 @@
.file-preview-small{
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 2px;
border-radius: 12px;
+18 -20
View File
@@ -153,34 +153,34 @@
<div class="record-edit">
<div class="tools-header">
<!-- <Manager managerRecords={recordHistory} {graph}/>-->
{#if isCreateMode}
<button
class="button btn-spinner"
on:click={save}
>
<!-- <Manager managerRecords={recordHistory} {graph}/>-->
{#if isCreateMode}
<button
class="button primary btn-spinner"
on:click={save}
>
<span
class="spinner-border spinner-border-sm"
role="status"
aria-hidden="true"
/>
Create
</button>
{:else if hasUnsavedData}
<button
type="button"
class="button ms-2 btn btn-primary btn-spinner"
on:click={save}
>
Create
</button>
{:else if hasUnsavedData}
<button
type="button"
class="button primary ms-2 btn btn-primary btn-spinner"
on:click={save}
>
<span
class="spinner-border spinner-border-sm"
role="status"
aria-hidden="true"
/>
Save
</button>
{/if}
<EditHeader {schema} bind:record {isCreateMode} {graph} bind:activeContentTab/>
Save
</button>
{/if}
<EditHeader {schema} bind:record {isCreateMode} {graph} bind:activeContentTab/>
</div>
<Title {schema} {record} {isCreateMode}/>
@@ -195,7 +195,6 @@
/>
{#if !["_graph", "_info"].includes(activeContentTab)}
<FilePreview {record} {schema}/>
<!-- <fieldset disabled="disabled"> -->
{#each activeFields as field (field.name)}
{#if activeContentTab === field.group}
<FormField
@@ -209,7 +208,6 @@
/>
{/if}
{/each}
<!-- </fieldset> -->
{:else if activeContentTab === "_graph"}
<Graph {graph} {record}/>
{:else if activeContentTab === "_info"}
+23 -33
View File
@@ -1,16 +1,17 @@
<script>
import {getContext} from "svelte";
import {createEventDispatcher, getContext} from "svelte";
import {uniqBy} from "lodash";
import {sortByField} from "../../edges/sortEdges";
import PreviewCard from "../PreviewCard.svelte";
import Sortable from "../../libs/Sortable.svelte";
import BrowseModal from "./BrowseModal.svelte";
import PreviewFile from "../previews/PreviewFile.svelte";
import Dropdown from "../../common/Dropdown.svelte";
import Dialog from "../../dialog/Dialog.svelte";
const channel = getContext("channel");
export let field;
export let record;
export let graph
const dispatch = createEventDispatcher();
let browseModal;
$: references = graph?.edges
.filter((edge) => edge.field === field.name)
@@ -32,6 +33,7 @@
function openBrowseModal(e, schema) {
e.preventDefault();
browseModal.open(schema);
}
async function reorder(e) {
@@ -69,49 +71,37 @@
<div class="mb-0">
{#if field.collections.length === 1}
<button
class="btn btn-outline-primary"
class="button"
on:click={(e) => openBrowseModal(e, collections[0].name)}
>
Browse
</button>
{:else}
<div class="dropdown d-inline-block">
<button
class="btn btn-outline-primary btn-sm"
type="button"
data-bs-toggle="dropdown"
aria-expanded="false"
>
<Dropdown>
<div slot="button">
Browse
</button>
<ul class="dropdown-menu">
{#each collections as collection}
<li>
<!-- {`${channelurl}/content/${collection.name}?parent=${record.id}&parentfield=${field.name}`} -->
<a
class="dropdown-item"
on:click={(e) =>
</div>
{#each collections as collection}
<!-- {`${channelurl}/content/${collection.name}?parent=${record.id}&parentfield=${field.name}`} -->
<a
class="dropdown-item"
on:click={(e) =>
openBrowseModal(e, collection.name)}
href="/">{collection.label}</a
>
</li>
{/each}
</ul>
</div>
href="/">{collection.label}</a
>
{/each}
</Dropdown>
{/if}
</div>
{#if references.length > 0}
<Sortable sortableClass="row row-cols-3 mt-3" on:update={reorder}>
{#each references as reference (reference.id)}
<div class="col mb-3">
<PreviewCard
classes="h-100"
record={reference}
hasDelete={true}
on:remove={removeReference}
/>
<PreviewFile record={reference} hasDelete={true} on:remove={removeReference}></PreviewFile>
</div>
{/each}
</Sortable>
{/if}
<BrowseModal bind:this={browseModal} on:insert={insert}/>
<Dialog bind:this={browseModal} on:insert={insert}></Dialog>
<!--<BrowseModal bind:this={browseModal} on:insert={insert}/>-->
@@ -0,0 +1,57 @@
<script>
import Icon from "../../common/Icon.svelte";
import {createEventDispatcher, getContext} from "svelte";
import Preview from "../../files/Preview.svelte";
import {previewTitle} from "./../Preview";
import Status from "./../Status.svelte";
const dispatch = createEventDispatcher();
const channel = getContext("channel");
export let record;
export let hasDelete = false;
let schema = channel.schemas.find((aschema) => aschema.name === record.schema);
let cardTitle = previewTitle(channel.schemas, record);
function remove(e) {
e.preventDefault();
dispatch("remove", record.id);
}
</script>
<div class="preview-file">
<div class="image">
<Preview {record} size="small"/>
</div>
<div class="title">
<div>
<a
class="record-title"
href="{channel.lucentUrl}/records/{record.id}"
>
{cardTitle}
</a>
<small class="d-block">
from {schema.label}
{#if record.status === "draft"}
<Status status={record.status}/>
{/if}
</small>
</div>
</div>
{#if hasDelete}
<div class="trash-action">
<button
class="button"
on:click={remove}
>
<Icon icon="trash-can"/>
</button>
</div>
{/if}
</div>
+8
View File
@@ -10,6 +10,14 @@
display: flex;
align-items: center;
gap: 4px;
&.secondary{
background: var(--secondary);
}
&.primary{
background: var(--primary);
}
&:focus {
filter: brightness(94%);
}
+4 -1
View File
@@ -1,5 +1,8 @@
.dropdown {
position: relative;
z-index: 20;
overflow: visible;
}
.dropdown-button > div {
@@ -15,7 +18,7 @@
overflow: visible;
position: absolute;
border-radius: 12px;
z-index: 9;
z-index: 20;
background: var(--background);
filter: brightness(97%);
transition: 600ms;
+35
View File
@@ -0,0 +1,35 @@
//
//:modal {
// background-color: beige;
// border: 2px solid burlywood;
// border-radius: 5px;
//}
body:has(dialog[open]) {
overflow: hidden;
}
dialog{
margin: 10px auto;
background-color: #fff;
padding: 34px;
border: none;
border-radius: 5px;
overflow: auto;
position: relative;
.close{
position: absolute;
top: 20px;
right: 20px;
}
.dialog-body{
width: fit-content;
}
}
dialog::backdrop {
backdrop-filter: blur(3px);
}
+28
View File
@@ -0,0 +1,28 @@
.preview-file{
display: flex;
align-items: center;
gap: 10px;
background: var(--background);
border-radius: 12px;
.image{
display: flex;
}
.trash-action{
display: none;
}
&:hover{
filter: brightness(95%);
.trash-action{
display: block;
}
}
}
.sortable-ghost{
border: 2px dashed var(--primary);
}
+7 -1
View File
@@ -21,11 +21,17 @@
align-items: center;
gap: 10px;
font-size: 14px;
position: relative;
z-index: 20;
padding: 10px;
border-radius: 12px;
background: var(--background);
filter: brightness(90%);
}
.editor-field {
background: var(--background);
filter: brightness(98%);
filter: brightness(97%);
padding: 18px;
border-radius: 12px;
margin: 6px 0;
+3 -3
View File
@@ -34,9 +34,9 @@
overflow: hidden;
img{
width: 48px;
}
//img{
// width: 48px;
//}
.status{
color:var(--accent);
+1
View File
@@ -4,6 +4,7 @@
gap: 5px;
justify-content: space-between;
input.search{
border-radius: 12px;
background: var(--background);
+2
View File
@@ -151,6 +151,8 @@ $themes: (
@import "./record-edit";
@import "./tabs";
@import "./switch";
@import "./preview";
@import "./modal";
body {
background-color: var(--background);