WIP uploading files
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
import Icon from "../../common/Icon.svelte";
|
||||
import SortFields from "./SortFields.svelte";
|
||||
import AppliedFilter from "./AppliedFilter.svelte";
|
||||
import {createEventDispatcher, getContext} from "svelte";
|
||||
import { createEventDispatcher, getContext } from "svelte";
|
||||
import Dropdown from "../../common/Dropdown.svelte";
|
||||
import AppliedFilterNotLinked from "./AppliedFilterNotLinked.svelte";
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
} else {
|
||||
window.location = url;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function uploadComplete(e) {
|
||||
@@ -51,110 +50,94 @@
|
||||
|
||||
<div class="toolbar">
|
||||
<div class="toolbar-filters">
|
||||
|
||||
<SortFields
|
||||
{schema}
|
||||
{sortParam}
|
||||
{sortField}
|
||||
{systemFields}
|
||||
{inModal}
|
||||
{modalUrl}
|
||||
on:refresh
|
||||
{schema}
|
||||
{sortParam}
|
||||
{sortField}
|
||||
{systemFields}
|
||||
{inModal}
|
||||
{modalUrl}
|
||||
on:refresh
|
||||
/>
|
||||
|
||||
|
||||
<FilterFields
|
||||
bind:schema
|
||||
{systemFields}
|
||||
{operators}
|
||||
{filter}
|
||||
{inModal}
|
||||
{modalUrl}
|
||||
on:refresh
|
||||
bind:schema
|
||||
{systemFields}
|
||||
{operators}
|
||||
{filter}
|
||||
{inModal}
|
||||
{modalUrl}
|
||||
on:refresh
|
||||
/>
|
||||
|
||||
<form method="GET" on:submit={search}>
|
||||
<input type="search" name="filter[search_regex]" placeholder="Search"
|
||||
class="search" required>
|
||||
<input
|
||||
type="search"
|
||||
name="filter[search_regex]"
|
||||
placeholder="Search"
|
||||
class="search"
|
||||
required
|
||||
/>
|
||||
</form>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div style="display:flex;align-items: center;gap:4px">
|
||||
{#if schema.type === "collection"}
|
||||
{#if !inModal && isWritable}
|
||||
<a
|
||||
href="{channel.lucentUrl}/records/new?schema={schema.name}"
|
||||
class="button"
|
||||
>
|
||||
New Record
|
||||
</a>
|
||||
{/if}
|
||||
{:else }
|
||||
<div>
|
||||
<Uploader {schema} on:uploadComplete={uploadComplete}/>
|
||||
</div>
|
||||
{#if !inModal && isWritable}
|
||||
<a
|
||||
href="{channel.lucentUrl}/records/new?schema={schema.name}"
|
||||
class="button"
|
||||
>
|
||||
New Record
|
||||
</a>
|
||||
{/if}
|
||||
|
||||
{#if !inModal}
|
||||
<Dropdown orientation="right">
|
||||
<div slot="button">
|
||||
<Icon icon="ellipsis-vertical"/>
|
||||
<Icon icon="ellipsis-vertical" />
|
||||
</div>
|
||||
{#if filter["status_in"] === "trashed"}
|
||||
{#if isWritable}
|
||||
<a
|
||||
class="dropdown-item"
|
||||
href="{channel.lucentUrl}/content/{schema.name}/emptyTrash"
|
||||
class="dropdown-item"
|
||||
href="{channel.lucentUrl}/content/{schema.name}/emptyTrash"
|
||||
>
|
||||
Empty trash
|
||||
</a>
|
||||
{/if}
|
||||
{:else}
|
||||
|
||||
<a class="dropdown-item" href={csvUrl}>Export to CSV</a>
|
||||
<a
|
||||
class="dropdown-item"
|
||||
href={csvUrl}
|
||||
>Export to CSV</a
|
||||
class="dropdown-item"
|
||||
href="{channel.lucentUrl}/content/{schema.name}?filter[status_in]=trashed"
|
||||
>View trashed records</a
|
||||
>
|
||||
<a
|
||||
class="dropdown-item"
|
||||
href="{channel.lucentUrl}/content/{schema.name}?filter[status_in]=trashed"
|
||||
>View trashed records</a
|
||||
>
|
||||
<a
|
||||
class="dropdown-item"
|
||||
href="{channel.lucentUrl}/content/{schema.name}?notlinked=*"
|
||||
>View unlinked records</a
|
||||
class="dropdown-item"
|
||||
href="{channel.lucentUrl}/content/{schema.name}?notlinked=*"
|
||||
>View unlinked records</a
|
||||
>
|
||||
{/if}
|
||||
</Dropdown>
|
||||
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="applied-filters">
|
||||
<AppliedFilterNotLinked
|
||||
{inModal}
|
||||
{modalUrl}
|
||||
on:refresh
|
||||
<AppliedFilterNotLinked {inModal} {modalUrl} on:refresh
|
||||
></AppliedFilterNotLinked>
|
||||
{#if Object.entries(filter).length > 0}
|
||||
{#each Object.entries(filter) as [k, v]}
|
||||
<AppliedFilter
|
||||
{schema}
|
||||
{operators}
|
||||
key={k}
|
||||
value={v}
|
||||
{inModal}
|
||||
{modalUrl}
|
||||
{graph}
|
||||
on:refresh
|
||||
{schema}
|
||||
{operators}
|
||||
key={k}
|
||||
value={v}
|
||||
{inModal}
|
||||
{modalUrl}
|
||||
{graph}
|
||||
on:refresh
|
||||
/>
|
||||
{/each}
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
<script>
|
||||
import { createEventDispatcher, getContext } from "svelte";
|
||||
import Icon from "../common/Icon.svelte";
|
||||
import Index from "../content/Index.svelte";
|
||||
import axios from "axios";
|
||||
|
||||
let dialogEl;
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
const channel = getContext("channel");
|
||||
$: data = {};
|
||||
let selectedRecords = [];
|
||||
// onMount(() => {
|
||||
// load();
|
||||
// });
|
||||
|
||||
export function close(e) {
|
||||
if (e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
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",
|
||||
schema: data.schema.name,
|
||||
});
|
||||
}
|
||||
|
||||
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="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>
|
||||
|
||||
<div class="dialog-body">
|
||||
<Index {...data} bind:selected={selectedRecords}></Index>
|
||||
</div>
|
||||
{/if}
|
||||
</dialog>
|
||||
@@ -1,10 +1,10 @@
|
||||
<script>
|
||||
import {createEventDispatcher, getContext} from "svelte";
|
||||
import { createEventDispatcher, getContext } from "svelte";
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
const channel = getContext("channel");
|
||||
export let schema;
|
||||
export let recordId;
|
||||
let mimeTypes = "";
|
||||
let files = [];
|
||||
let isLoading = false;
|
||||
@@ -17,39 +17,43 @@
|
||||
files = e.target.files ? [...e.target.files] : [];
|
||||
let formData = new FormData();
|
||||
|
||||
formData.append("schema", schema.name);
|
||||
formData.append("recordId", recordId);
|
||||
Array.from(files).forEach(function (file) {
|
||||
formData.append("files[]", file);
|
||||
});
|
||||
dispatch("beforeUpload", files);
|
||||
axios
|
||||
.post(channel.lucentUrl + "/files/upload", formData, {
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data",
|
||||
},
|
||||
})
|
||||
.then((response) => {
|
||||
if (response.data.error) {
|
||||
dispatch("uploadError", response.data.error);
|
||||
fetch(channel.lucentUrl + "/files/upload", {
|
||||
method: "POST",
|
||||
body: formData,
|
||||
headers: {
|
||||
"X-CSRF-TOKEN": document.querySelector(
|
||||
'meta[name="csrf-token"]',
|
||||
).content,
|
||||
},
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
if (data.error) {
|
||||
dispatch("uploadError", data.error);
|
||||
} else {
|
||||
dispatch("uploadComplete", response.data);
|
||||
dispatch("uploadComplete", data);
|
||||
}
|
||||
isLoading = false;
|
||||
})
|
||||
.catch((error) => {
|
||||
isLoading = false;
|
||||
console.log(error.response.data);
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<fieldset class="upload-button" disabled={isLoading}>
|
||||
<label class="button primary btn-spinner ">
|
||||
<span
|
||||
class="spinner-border spinner-border-sm"
|
||||
role="status"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<fieldset class="upload-button" disabled={isLoading}>
|
||||
<label class="button primary btn-spinner">
|
||||
<span
|
||||
class="spinner-border spinner-border-sm"
|
||||
role="status"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
Upload file
|
||||
|
||||
<input
|
||||
|
||||
@@ -1,31 +1,24 @@
|
||||
<script>
|
||||
import {sortByField} from "../../edges/sortEdges";
|
||||
import { sortByField } from "../../edges/sortEdges";
|
||||
import Sortable from "../../libs/Sortable.svelte";
|
||||
import PreviewFile from "../previews/PreviewFile.svelte";
|
||||
import Dropdown from "../../common/Dropdown.svelte";
|
||||
import Dialog from "../../dialog/Dialog.svelte";
|
||||
import {insertEdges} from "./reference.js";
|
||||
import {getContext} from "svelte";
|
||||
import { insertEdges } from "./reference.js";
|
||||
import { getContext } from "svelte";
|
||||
import FileDialog from "../../dialog/FileDialog.svelte";
|
||||
import Uploader from "../../files/Uploader.svelte";
|
||||
|
||||
const channel = getContext("channel");
|
||||
export let field;
|
||||
export let record;
|
||||
export let graph
|
||||
export let graph;
|
||||
let browseModal;
|
||||
$: references = graph?.edges
|
||||
.filter((edge) => edge.field === field.name)
|
||||
.map((edge) => {
|
||||
return graph.records.find((increc) => increc.id === edge.target && record.id === edge.source);
|
||||
}).filter((rec) => (rec?.id ? true : false)) ?? [];
|
||||
|
||||
let collections = channel.schemas.filter((aschema) =>
|
||||
field.collections.includes(aschema.name)
|
||||
);
|
||||
|
||||
function removeReference(e) {
|
||||
e.preventDefault();
|
||||
graph.edges = graph.edges.filter(
|
||||
(edge) => !(edge.target === e.detail && edge.field === field.name)
|
||||
(edge) => !(edge.target === e.detail && edge.field === field.name),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -35,50 +28,56 @@
|
||||
}
|
||||
|
||||
async function reorder(e) {
|
||||
|
||||
graph.edges = await sortByField(e.detail.source, e.detail.target, graph.edges, field.name, references);
|
||||
|
||||
graph.edges = await sortByField(
|
||||
e.detail.source,
|
||||
e.detail.target,
|
||||
graph.edges,
|
||||
field.name,
|
||||
references,
|
||||
);
|
||||
}
|
||||
|
||||
function insert(e) {
|
||||
e.preventDefault();
|
||||
browseModal.close();
|
||||
graph = insertEdges(graph, record, e.detail.records, field.name, e.detail.action);
|
||||
graph = insertEdges(
|
||||
graph,
|
||||
record,
|
||||
e.detail.records,
|
||||
field.name,
|
||||
e.detail.action,
|
||||
);
|
||||
}
|
||||
|
||||
function uploadComplete(e) {
|
||||
records = e.detail;
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="mb-0">
|
||||
{#if field.collections.length === 1}
|
||||
<button
|
||||
class="button"
|
||||
on:click={(e) => openBrowseModal(e, collections[0].name)}
|
||||
>
|
||||
Browse
|
||||
</button>
|
||||
{:else}
|
||||
<Dropdown>
|
||||
<div slot="button">
|
||||
Browse
|
||||
</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
|
||||
>
|
||||
{/each}
|
||||
</Dropdown>
|
||||
{/if}
|
||||
<!-- <button
|
||||
class="button"
|
||||
on:click={(e) => openFileModal(e, collections[0].name)}
|
||||
>
|
||||
Browse
|
||||
</button> -->
|
||||
|
||||
<div>
|
||||
<Uploader recordId={record.id} on:uploadComplete={uploadComplete} />
|
||||
</div>
|
||||
</div>
|
||||
{#if references.length > 0}
|
||||
<!-- {#if references.length > 0}
|
||||
<Sortable sortableClass="mt-3" on:update={reorder}>
|
||||
{#each references as reference (reference.id)}
|
||||
<!--This div helps the sorting thing-->
|
||||
<div>
|
||||
<PreviewFile record={reference} hasDelete={true} on:remove={removeReference}></PreviewFile>
|
||||
<!-- <div>
|
||||
<PreviewFile
|
||||
record={reference}
|
||||
hasDelete={true}
|
||||
on:remove={removeReference}
|
||||
></PreviewFile>
|
||||
</div>
|
||||
{/each}
|
||||
</Sortable>
|
||||
{/if}
|
||||
<Dialog bind:this={browseModal} on:insert={insert}></Dialog>
|
||||
{/if} -->
|
||||
<!-- <FileDialog bind:this={browseModal} on:insert={insert}></FileDialog> -->
|
||||
|
||||
Reference in New Issue
Block a user