This commit is contained in:
2023-10-17 18:56:37 +03:00
parent d9736b29a4
commit 4b9e9cb4f6
13 changed files with 4 additions and 432 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
<script>
export let name;
export let side = "48";
export let side = 48;
const colors = [
"#00AA55",
"#009FD4",
+1 -5
View File
@@ -1,10 +1,6 @@
<script>
import {getContext, onMount} from "svelte";
import SpinnerButton from "../common/SpinnerButton.svelte";
import ErrorAlert from "../common/ErrorAlert.svelte";
import MemberSettingsCard from "../members/MemberSettingsCard.svelte";
import SuccessAlert from "../common/SuccessAlert.svelte";
import Radio from "../forms/Radio.svelte";
const channel = getContext("channel");
export let title;
-25
View File
@@ -1,25 +0,0 @@
<script>
import Icon from "./Icon.svelte";
export let label = "";
export let show = false;
</script>
<button
class="btn btn-link p-0 text-decoration-none d-flex align-items-center mb-2 "
on:click|preventDefault={(e) => (show = !show)}
>
<span class="me-1">{label}</span>
{#if !show}
<Icon icon="circle-chevron-down" />
{/if}
{#if show}
<Icon icon="circle-chevron-up" />
{/if}
</button>
{#if show}
<div class="mb-3" style="padding: 22px; background: rgb(249, 249, 249); border-radius: 32px;">
<slot />
</div>
{/if}
+1 -1
View File
@@ -40,7 +40,7 @@
>
<img
class="rounded w-100"
src={imgurl(record, imageSide, imageSide, "crop")}
src={imgurl(record)}
alt={record._file.path}
/>
</a>
+1 -21
View File
@@ -1,31 +1,11 @@
import {getContext} from "svelte";
export function imgurl(record, width = "", height = "", mode = "") {
// let argumentString = "-o";
// if (mode) {
// argumentString += "-mode_fit";
// }
// if (width) {
// argumentString += "-w_" + width;
// }
// if (height) {
// argumentString += "-h_" + height;
// }
// let pathAr = record._file.path.split(".");
// let ext = pathAr.pop();
// let filename = record._file.path.replace("." + ext, "");
// let cache = "cache/"
// if (!mode && !width && !height) {
// argumentString = "";
// cache = "";
// }
export function imgurl(record) {
const channel = getContext("channel")
return channel.filesUrl + `/thumbs/${record._file.path}`;
}
export function fileurl(record) {
const channel = getContext("channel")
return channel.filesUrl + `/${record._file.path}`;
}
-20
View File
@@ -1,20 +0,0 @@
<script>
import { uniqueId } from "lodash";
export let label;
export let value;
let id = uniqueId();
</script>
<div class="form-check">
<input
value=""
class="form-check-input"
type="checkbox"
bind:checked={value}
id={id}
/>
<label class="form-check-label" for={id}>
{label}
</label>
</div>
-23
View File
@@ -1,23 +0,0 @@
<script>
import { uniqueId } from "lodash";
export let label;
export let value;
let id = uniqueId();
</script>
{#if label}
<div class="d-flex justify-content-between">
<label for={id} class="form-label">{label}</label>
</div>
{/if}
<div class="input-group ">
<div style="width:64px;">
<input
type="color"
class="form-control form-control-color"
bind:value
/>
</div>
<input type="text" {id} class="form-control" bind:value />
</div>
-38
View File
@@ -1,38 +0,0 @@
<script>
import { onMount } from "svelte";
import flatpickr from "flatpickr";
import "flatpickr/dist/flatpickr.css";
import "flatpickr/dist/themes/light.css";
import { uniqueId } from "lodash";
export let label;
export let value;
let pickerInput;
let id = uniqueId();
let flatpickrOptions = {
enableTime: false,
allowInput: true,
dateFormat: "Y-m-d",
defaultDate: value,
};
onMount(() => {
flatpickr(pickerInput, flatpickrOptions);
});
</script>
{#if label}
<div class="d-flex justify-content-between">
<label for={id} class="form-label">{label}</label>
</div>
{/if}
<input
type="text"
{id}
class="form-control"
bind:value
bind:this={pickerInput}
autocomplete="off"
/>
@@ -1,179 +0,0 @@
<script>
import { onMount, onDestroy, tick } from "svelte";
import tinymce from "tinymce/tinymce";
import "tinymce/models/dom";
import "tinymce/icons/default";
import "tinymce/themes/silver";
import "tinymce/skins/ui/oxide/skin.css";
import contentUiSkinCss from "tinymce/skins/ui/oxide/content.css";
import "tinymce/plugins/link";
import "tinymce/plugins/code";
import "tinymce/plugins/image";
import "tinymce/plugins/table";
import "tinymce/plugins/codesample";
import "tinymce/plugins/media";
import "tinymce/plugins/lists";
import "tinymce/plugins/autoresize";
import "tinymce/plugins/wordcount";
import BrowseModal from "../records/elements/BrowseModal.svelte";
export let schemas;
export let schema;
export let field;
export let value = "";
export let additionalConfig = {};
let browseModal;
let lastVal = "";
let textareaEl;
let activeEditor;
let editorWrapper;
const plugins = [
"autoresize",
"code",
"image",
"table",
"codesample",
"link",
"lists",
"media",
"wordcount",
];
const toolbar =
"bold italic underline strikethrough removeformat | link image fileManager | subscript superscript bullist numlist media codesample table code wordcount blockquote indent outdent blocks";
onDestroy(() => {
if (activeEditor) {
activeEditor.destroy();
}
});
onMount(() => {
const config = {
target: textareaEl,
toolbar_mode: "sliding",
toolbar_sticky: true,
skin: false,
content_css: false,
content_style: contentUiSkinCss.toString(),
branding: false,
inline: false,
plugins: plugins,
contextmenu: false,
menubar: false,
statusbar: false,
entity_encoding: "raw",
convert_urls: false,
toolbar: toolbar,
image_caption: true,
relative_urls: false,
browser_spellcheck: true,
max_height: 600,
// media_poster: false,
// content_style:
// "body {font-family: 'Averta Std', sans serif; color: #152F77}",
setup: function (editor) {
activeEditor = editor;
editor.on("init", function (e) {
editor.setContent(value ?? "");
});
// editor.on("blur", function (e) {
// let content = setImageDimensions(editor.getContent());
// dispatch("editorBlur", content);
// editorWrapper.classList.remove("editorFocus");
// // return false;
// });
// editor.on("focus", function (e) {
// editorWrapper.classList.add("editorFocus");
// // return false;
// });
editor.on("change input undo redo", function (e) {
lastVal = editor.getContent();
if (lastVal !== value) {
value = lastVal;
}
});
editor.ui.registry.addMenuButton("fileManager", {
icon: "upload",
fetch: (callback) => {
const items = field.collections.map((c) => {
return {
type: "menuitem",
text:
schemas.find((s) => s.name == c).label ??
"Schema missing",
onAction: () => {
openBrowseModal(c);
},
};
});
callback(items);
},
});
},
};
tinymce.init({ ...config, ...additionalConfig });
});
function openBrowseModal(aschema) {
browseModal.open(aschema);
}
async function insert(e) {
e.preventDefault();
const recordsToInsert = e.detail.records;
let fileSchema = schemas.find(
(s) => s.name === recordsToInsert[0]._sys.schema
);
let contentTonInsert = recordsToInsert
.map((r) => {
if (r._file.mime.startsWith("image")) {
let fileUrl =
fileSchema.objectStorageProxy + "/" + r._file.path;
return `<img src="${fileUrl}" alt="${r._file.path}" width="${r._file.width}" height="${r._file.height}" />`;
} else {
let fileUrl =
fileSchema.objectStorageUrl + "/" + r._file.path;
return `<a href="${fileUrl}" title="${r._file.path}">${r._file.path}</a>`;
}
})
.join("<br />");
activeEditor.insertContent(contentTonInsert);
await tick();
browseModal.close();
}
</script>
<div bind:this={editorWrapper} class="tox-wrapper">
<div class="form-control" bind:this={textareaEl}>
{@html value}
</div>
</div>
{#if field && schema}
<BrowseModal bind:this={browseModal} on:insert={insert} />
{/if}
<style>
:global(.tox:not(.tox-tinymce-inline) .tox-editor-header) {
background-color: #fff;
border-bottom: 1px solid #ced4da;
box-shadow: none;
padding: 4px 0;
transition: box-shadow 0.5s;
}
:global(.tox-tinymce) {
border: 1px solid #ced4da;
}
</style>
-27
View File
@@ -1,27 +0,0 @@
<?php
namespace Lucent\Channel;
use Lucent\Validator\Validator;
class PreviewTarget
{
function __construct(
public readonly string $label,
public readonly string $url,
)
{
Validator::single("label", $label, "required|min:2|max:50");
Validator::single("url", $url, "required|url");
}
public static function fromArray(array $data): PreviewTarget
{
return new PreviewTarget(
label: $data["label"],
url: $data["url"],
);
}
}
-16
View File
@@ -1,16 +0,0 @@
<?php
namespace Lucent\Edge;
final class QueryEdge
{
public function __construct(
public string $fromSchema,
public string $from,
public string $schema,
public string $field,
public string $to,
) {
}
}
-38
View File
@@ -1,38 +0,0 @@
<?php
namespace Lucent\Primitive;
use Illuminate\Support\Collection;
/**
* @extends \Illuminate\Support\Collection<int|string, string>
*/
final class StringCollection extends Collection
{
public function __construct(
string ...$array
) {
parent::__construct($array);
}
/**
* @return string[]
**/
public function toArray(): array
{
return collect($this)->values()->toArray();
}
public static function fromArray(array $data): StringCollection
{
return new StringCollection(...$data);
}
public static function fromDB(string $data): StringCollection
{
return new StringCollection(...\json_decode($data,true));
}
}
-38
View File
@@ -1,38 +0,0 @@
<?php
namespace Lucent\Support;
/**
* An in-memory memoizer that keeps the cached values around for the lifetime of this instance.
*/
class Memoize
{
/**
* The saved results
*
* @var array
*/
private array $cache = [];
/**
* $cacheTime is ignored - this will keep the results around for the lifetime of this instance.
*
* @see Memoize::memoizeCallable
*
* @param string $key
* @param callable $compute
*
* @return mixed
*/
public function memoizeCallable(string $key, callable $compute) :mixed
{
if (array_key_exists($key, $this->cache)) {
return $this->cache[$key];
}
$result = $compute();
$this->cache[$key] = $result;
return $result;
}
}