wip upload files and select

This commit is contained in:
2026-05-05 19:21:59 +03:00
parent bd01e5c32c
commit 16e50e2d49
13 changed files with 439 additions and 208 deletions
@@ -42,10 +42,6 @@
window.location = url;
}
}
function uploadComplete(e) {
records = e.detail;
}
</script>
<div class="toolbar">
+44 -48
View File
@@ -1,15 +1,14 @@
<script>
import { createEventDispatcher, getContext } from "svelte";
import Icon from "../common/Icon.svelte";
import Index from "../content/Index.svelte";
import axios from "axios";
import FileIndex from "./FileIndex.svelte";
let dialogEl;
const dispatch = createEventDispatcher();
const channel = getContext("channel");
$: data = {};
let selectedRecords = [];
$: files = [];
$: selectedRecords = [];
// onMount(() => {
// load();
// });
@@ -23,11 +22,11 @@
selectedRecords = [];
}
function load(schema) {
axios
.get(channel.lucentUrl + "/content/" + schema)
.then((response) => {
data = response.data;
function load(recordId) {
fetch(channel.lucentUrl + "/records/files/?recordId=" + recordId)
.then((response) => response.json())
.then((json) => {
files = json;
})
.catch((error) => console.log(error));
}
@@ -37,7 +36,6 @@
dispatch("insert", {
records: selectedRecords,
action: "insert",
schema: data.schema.name,
});
}
@@ -49,49 +47,47 @@
});
}
export function open(schema) {
export function open(recordId) {
dialogEl.showModal();
load(schema);
load(recordId);
}
</script>
<dialog bind:this={dialogEl}>
{#if data.schema}
<div class="dialog-header">
<button
type="button"
class="button"
on:click={insert}
disabled={selectedRecords.length === 0}
>
Insert
</button>
<button
type="button"
class="button"
on:click={replace}
disabled={selectedRecords.length === 0}
>
Replace
</button>
{#if selectedRecords.length > 0}
<span class="">
{selectedRecords.length} records selected
</span>
{/if}
<div class="dialog-header">
<button
type="button"
class="button"
on:click={insert}
disabled={selectedRecords.length === 0}
>
Insert
</button>
<button
type="button"
class="button"
on:click={replace}
disabled={selectedRecords.length === 0}
>
Replace
</button>
{#if selectedRecords.length > 0}
<span class="">
{selectedRecords.length} records selected
</span>
{/if}
<button
on:click|preventDefault={close}
type="button"
class="button close"
aria-label="Close"
>
<Icon icon="close"></Icon>
</button>
</div>
<button
on:click|preventDefault={close}
type="button"
class="button close"
aria-label="Close"
>
<Icon icon="close"></Icon>
</button>
</div>
<div class="dialog-body">
<Index {...data} bind:selected={selectedRecords}></Index>
</div>
{/if}
<div class="dialog-body">
<FileIndex {files} bind:selected={selectedRecords}></FileIndex>
</div>
</dialog>
+119
View File
@@ -0,0 +1,119 @@
<script>
import { getContext } from "svelte";
import Icon from "../common/Icon.svelte";
import Checkbox from "../common/Checkbox.svelte";
import Preview from "../files/Preview.svelte";
import { fileurl } from "../files/imageserver";
const channel = getContext("channel");
export let files = [];
export let selected = [];
export let isWritable = true;
function eventToggleAll(e) {
selected = toggleAll(e, files, selected);
}
function select(file) {
selected = selectFile(file, selected);
}
export const toggleAll = (e, files, selected) => {
if (selected.length === files.length) {
return [];
}
e.currentTarget.checked = selected.length > 0;
return files;
};
export const selectFile = (file, selected) => {
let fileExists = selected.find((r) => r.id === file.id);
if (fileExists) {
return selected.filter((r) => r.id !== file.id);
}
return [...selected, file];
};
</script>
<div class="table mt-5">
<table>
<thead>
<tr>
{#if isWritable}
<th>
<Checkbox
value=""
on:change={eventToggleAll}
indeterminate={selected.length > 0 &&
selected.length < files.length}
checked={selected.length === files.length}
></Checkbox>
</th>
{/if}
<th></th>
</tr>
</thead>
<tbody>
{#each files as file (file.id)}
<tr>
<td class="title-td">
<div class="title-td-contents">
{#if isWritable}
<Checkbox
on:change={() => select(file)}
checked={selected.find(
(s) => s.id === file.id,
)}
value={file}
></Checkbox>
{/if}
<div class="file-table-row">
<Preview
{file}
size={file.width > 0 ? "medium" : "small"}
/>
<div>
{file.filename}
<span
>{(file.size / 1024).toFixed(1)}kB</span
>
{#if file.width > 0}
<span
>{file.width +
"x" +
file.height}</span
>
{/if}
<a
href={fileurl(channel, file)}
target="_blank"
>
Download
</a>
</div>
</div>
</div>
</td>
<!-- <RecordRow
{record}
{graph}
{schema}
{visibleColumns}
{sortParam}
{sortField}
{users}
/> -->
<!-- <td>
<Avatar
name={usernameById(users, record._sys.updatedBy)}
side={24}
/>
</td> -->
</tr>
{/each}
</tbody>
</table>
</div>
+25 -26
View File
@@ -1,9 +1,9 @@
<script>
import Icon from "../common/Icon.svelte";
import {imgurl} from "./imageserver.js";
import {getContext} from "svelte";
import { imgurl } from "./imageserver.js";
import { getContext } from "svelte";
export let record;
export let file;
const channel = getContext("channel");
export let size = "small";
export let showFilename = false;
@@ -28,50 +28,49 @@
fontSize = "13";
}
</script>
<div style="display: flex;align-items: center;gap: 5px;">
{#if record}
{#if record._file.mime.startsWith("image")}
<div style="display: flex;align-items: center;gap: 5px;">
{#if file}
{#if file.mime.startsWith("image")}
<!-- href={imgurl(record)} -->
<a
href="{channel.lucentUrl}/records/{record.id}"
title={record._file.originalName}
style="width:{imageSide}px;height:{imageSide}px"
href="{channel.lucentUrl}/files/{file.id}"
title={file.filename}
style="width:{imageSide}px;height:{imageSide}px"
>
<img
class="rounded w-100"
src={imgurl(channel,record)}
alt={record._file.path}
class="rounded w-100"
src={imgurl(channel, file)}
alt={file.path}
/>
</a>
{:else}
<a
href="{channel.lucentUrl}/records/{record.id}"
title={record._file.path}
class="file-preview-small"
style="width:{imageSide}px;height:{imageSide}px"
href="{channel.lucentUrl}/files/{file.id}"
title={file.path}
class="file-preview-small"
style="width:{imageSide}px;height:{imageSide}px"
>
<Icon icon="file" width={fileSide} height={fileSide}/>
<Icon icon="file" width={fileSide} height={fileSide} />
<span class="ms-2"
>.{record._file.path.split(".").pop().toLowerCase()}</span
>.{file.path.split(".").pop().toLowerCase()}</span
>
</a>
{/if}
{/if}
{#if showFilename}
<a
href="{channel.lucentUrl}/records/{record.id}"
title={record._file.path}
class="preview-file-filename lx-small-text text-decoration-none"
>{record._file.path} </a
>
href="{channel.lucentUrl}/files/{file.id}"
title={file.path}
class="preview-file-filename lx-small-text text-decoration-none"
>{file.path}
</a>
{/if}
</div>
<style>
img{
img {
border-radius: 12px;
padding: 4px;
}
</style>
</style>
+27 -28
View File
@@ -1,30 +1,29 @@
export function imgurl(channel, record) {
if (record._file.mime === "image/svg+xml") {
return fileurl(channel, record);
export function imgurl(channel, file) {
if (file.mime === "image/svg+xml") {
return fileurl(channel, file);
}
return channel.filesUrl + `/thumbs/${file.path}`;
}
export function fileurl(channel, file) {
return channel.filesUrl + `/${file.path}`;
}
export function htmlurl(channel, file, preset) {
let html = "";
let url = fileurl(channel, file);
if (file.width > 0) {
let presetUrl = url;
if (preset) {
presetUrl = channel.filesUrl + `/templates/${preset}/${file.path}`;
}
return channel.disks[record._file.disk] + `/thumbs/${record._file.path}`;
}
export function fileurl(channel, record) {
return channel.disks[record._file.disk] + `/${record._file.path}`;
}
export function htmlurl(channel, record, preset) {
let html = "";
let url = fileurl(channel, record)
if (record._file.width > 0) {
let presetUrl = url;
if (preset) {
presetUrl = channel.disks[record._file.disk] + `/templates/${preset}/${record._file.path}`;
}
html = `<img src="${presetUrl}" alt="${record._file.path}" />`
} else if (record._file.mime === "image/svg+xml") {
html = `<img src="${url}" alt="${record._file.path}"/>`
} else {
html = `<a href="${url}">${record._file.originalName}</a>`
}
return html;
html = `<img src="${presetUrl}" alt="${file.path}" />`;
} else if (file.mime === "image/svg+xml") {
html = `<img src="${url}" alt="${file.path}"/>`;
} else {
html = `<a href="${url}">${file.originalName}</a>`;
}
return html;
}
+7 -12
View File
@@ -22,11 +22,6 @@
);
}
function openBrowseModal(e, schema) {
e.preventDefault();
browseModal.open(schema);
}
async function reorder(e) {
graph.edges = await sortByField(
e.detail.source,
@@ -52,15 +47,15 @@
function uploadComplete(e) {
records = e.detail;
}
function openBrowseModal(e) {
e.preventDefault();
browseModal.open(record.id);
}
</script>
<div class="mb-0">
<!-- <button
class="button"
on:click={(e) => openFileModal(e, collections[0].name)}
>
Browse
</button> -->
<button class="button" on:click={openBrowseModal}> Browse </button>
<div>
<Uploader recordId={record.id} on:uploadComplete={uploadComplete} />
@@ -80,4 +75,4 @@
{/each}
</Sortable>
{/if} -->
<!-- <FileDialog bind:this={browseModal} on:insert={insert}></FileDialog> -->
<FileDialog bind:this={browseModal} on:insert={insert}></FileDialog>