filters and sidebar
This commit is contained in:
@@ -30,3 +30,23 @@ export function stripHtml(html = "") {
|
|||||||
export function randomId(length = 10) {
|
export function randomId(length = 10) {
|
||||||
return Math.random().toString(36).substring(2, length + 2);
|
return Math.random().toString(36).substring(2, length + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function clickOutside(node) {
|
||||||
|
|
||||||
|
const handleClick = event => {
|
||||||
|
if (node && !node.contains(event.target) && !event.defaultPrevented) {
|
||||||
|
node.dispatchEvent(
|
||||||
|
new CustomEvent('click_outside', node)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('click', handleClick, true);
|
||||||
|
|
||||||
|
return {
|
||||||
|
destroy() {
|
||||||
|
document.removeEventListener('click', handleClick, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,9 +4,10 @@
|
|||||||
import RecordEdit from "./records/Edit.svelte";
|
import RecordEdit from "./records/Edit.svelte";
|
||||||
import ContentIndex from "./content/Index.svelte";
|
import ContentIndex from "./content/Index.svelte";
|
||||||
import {setContext} from "svelte";
|
import {setContext} from "svelte";
|
||||||
import Navbar from "./Navbar.svelte";
|
import Navbar from "./layout/Navbar.svelte";
|
||||||
import HomeIndex from "./home/Index.svelte";
|
import HomeIndex from "./home/Index.svelte";
|
||||||
import BuildReport from "./build/Report.svelte";
|
import BuildReport from "./build/Report.svelte";
|
||||||
|
import Header from "./layout/Header.svelte";
|
||||||
|
|
||||||
const components = {
|
const components = {
|
||||||
members: Members,
|
members: Members,
|
||||||
@@ -35,7 +36,15 @@
|
|||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Navbar schema={data.schema}/>
|
|
||||||
|
|
||||||
<svelte:component this={components[view]} {title} {...data}/>
|
<div class="main-wrapper">
|
||||||
|
<div class="sidebar-content">
|
||||||
|
<Navbar schema={data.schema}/>
|
||||||
|
</div>
|
||||||
|
<div class="main-content">
|
||||||
|
<Header />
|
||||||
|
<svelte:component this={components[view]} {title} {...data}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,126 +0,0 @@
|
|||||||
<script>
|
|
||||||
import Avatar from "./account/Avatar.svelte";
|
|
||||||
import NavbarMenu from "./NavbarMenu.svelte";
|
|
||||||
import {getContext} from "svelte";
|
|
||||||
|
|
||||||
export let schema;
|
|
||||||
const channel = getContext("channel");
|
|
||||||
const readableSchemas = getContext("readableSchemas");
|
|
||||||
const user = getContext("user");
|
|
||||||
|
|
||||||
let contentIsOpen = false;
|
|
||||||
const fileSchemas = readableSchemas.filter((sc) => sc.type === "files");
|
|
||||||
const otherSchemas = readableSchemas.filter((sc) => !sc.isEntry && sc.type === "collection");
|
|
||||||
|
|
||||||
let filesIsActive = false;
|
|
||||||
let otherIsActive = false;
|
|
||||||
if(schema){
|
|
||||||
filesIsActive = fileSchemas.filter(s => s.name === schema.name).length > 0;
|
|
||||||
otherIsActive = otherSchemas.filter(s => s.name === schema.name).length > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<nav class="lx-nav">
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<button on:click={(e) => contentIsOpen = true} class="btn btn-primary btn-sm d-xxl-none">« Content</button>
|
|
||||||
</div>
|
|
||||||
<div class="d-flex align-items-center ">
|
|
||||||
<a class="nav-item" href="{channel.lucentUrl}">{channel.name}</a>
|
|
||||||
<a class="nav-item" href="{channel.lucentUrl}/members">Members</a>
|
|
||||||
|
|
||||||
{#if channel.generateCommand}
|
|
||||||
<a href="{channel.lucentUrl}/build-report" class="btn btn-outline-primary btn-sm d-">Build website</a>
|
|
||||||
{/if}
|
|
||||||
<!-- <div>-->
|
|
||||||
<!-- <form method="GET">-->
|
|
||||||
<!-- <input type="search" name="filter[search_regex]" placeholder="Search"-->
|
|
||||||
<!-- class="form-control" required/>-->
|
|
||||||
<!-- </form>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<a class="nav-item" href="{channel.lucentUrl}/profile">
|
|
||||||
<Avatar side="28" name={user.name}/>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<div class="offcanvas offcanvas-start d-xxl-block show border-0 bg-light-subtle" class:d-none={!contentIsOpen}
|
|
||||||
style="padding-top:36px " data-bs-scroll="true"
|
|
||||||
data-bs-backdrop="false"
|
|
||||||
tabindex="-1" aria-labelledby="offcanvasScrollingLabel">
|
|
||||||
<!-- <div class="offcanvas-header">-->
|
|
||||||
<!-- <h5 class="offcanvas-title" id="offcanvasScrollingLabel">Content</h5>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<div class="offcanvas-body">
|
|
||||||
<button on:click={(e) => contentIsOpen = false} class="btn btn-primary btn-sm d-xxl-none mb-4">« close</button>
|
|
||||||
<div class="accordion">
|
|
||||||
<div class="accordion-item">
|
|
||||||
<h2 class="accordion-header" id="panelsStayOpen-headingMain">
|
|
||||||
<button class="accordion-button" type="button" data-bs-toggle="collapse"
|
|
||||||
data-bs-target="#panelsStayOpen-collapseMain" aria-expanded="true"
|
|
||||||
aria-controls="panelsStayOpen-collapseMain">
|
|
||||||
Main
|
|
||||||
</button>
|
|
||||||
</h2>
|
|
||||||
<div id="panelsStayOpen-collapseMain" class="accordion-collapse collapse show"
|
|
||||||
aria-labelledby="panelsStayOpen-headingMain">
|
|
||||||
<div class="accordion-body">
|
|
||||||
<NavbarMenu
|
|
||||||
schemas={ readableSchemas.filter((sc) => sc.isEntry)}
|
|
||||||
schema={schema}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{#if otherSchemas.length > 0}
|
|
||||||
<div class="accordion-item">
|
|
||||||
<h2 class="accordion-header" id="panelsStayOpen-headingOther">
|
|
||||||
<button class="accordion-button" class:collapsed={!otherIsActive} type="button" data-bs-toggle="collapse"
|
|
||||||
data-bs-target="#panelsStayOpen-collapseOther" aria-expanded={otherIsActive}
|
|
||||||
aria-controls="panelsStayOpen-collapseOther">
|
|
||||||
Other
|
|
||||||
</button>
|
|
||||||
</h2>
|
|
||||||
<div id="panelsStayOpen-collapseOther" class="accordion-collapse collapse"
|
|
||||||
class:show={otherIsActive}
|
|
||||||
aria-labelledby="panelsStayOpen-headingOther">
|
|
||||||
<div class="accordion-body">
|
|
||||||
<NavbarMenu
|
|
||||||
schemas={ otherSchemas}
|
|
||||||
schema={schema}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
{#if fileSchemas.length > 0}
|
|
||||||
<div class="accordion-item">
|
|
||||||
<h2 class="accordion-header" id="panelsStayOpen-headingFS">
|
|
||||||
<button class="accordion-button " class:collapsed={!filesIsActive} type="button" data-bs-toggle="collapse"
|
|
||||||
data-bs-target="#panelsStayOpen-collapseFS" aria-expanded={filesIsActive}
|
|
||||||
aria-controls="panelsStayOpen-collapseFS">
|
|
||||||
Filesystem
|
|
||||||
</button>
|
|
||||||
</h2>
|
|
||||||
<div id="panelsStayOpen-collapseFS" class="accordion-collapse collapse" class:show={filesIsActive}
|
|
||||||
aria-labelledby="panelsStayOpen-headingFS">
|
|
||||||
<div class="accordion-body">
|
|
||||||
<NavbarMenu
|
|
||||||
schemas={ fileSchemas}
|
|
||||||
schema={schema}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
<script>
|
|
||||||
import {getContext} from "svelte";
|
|
||||||
|
|
||||||
const channel = getContext("channel");
|
|
||||||
export let schemas;
|
|
||||||
export let schema;
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="list-group list-group-flush">
|
|
||||||
|
|
||||||
{#each schemas as aschema}
|
|
||||||
<a class="list-group-item list-group-item-action" class:active={aschema.name === schema?.name}
|
|
||||||
aria-current="page"
|
|
||||||
href="{channel.lucentUrl}/content/{aschema.name}">{aschema.label}</a>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
@@ -1,23 +1,29 @@
|
|||||||
<script>
|
<script>
|
||||||
|
import {clickOutside} from "../../helpers.js";
|
||||||
|
|
||||||
|
let dropdownMenu;
|
||||||
|
export let orientation = "left";
|
||||||
|
|
||||||
|
export function open() {
|
||||||
|
dropdownMenu.classList.remove("hide")
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleClickOutside() {
|
||||||
|
dropdownMenu.classList.add("hide")
|
||||||
|
}
|
||||||
|
|
||||||
export let width = "300";
|
|
||||||
let dropdownMenu;
|
|
||||||
export function hide(){
|
|
||||||
dropdownMenu.classList.remove("show")
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
<div class="dropdown">
|
||||||
|
<button
|
||||||
|
class="button dropdown-button"
|
||||||
|
type="button"
|
||||||
|
on:click={open}
|
||||||
|
aria-expanded="false"
|
||||||
|
>
|
||||||
|
<slot name="button">Dropdown</slot>
|
||||||
|
</button>
|
||||||
|
<div bind:this={dropdownMenu} class="dropdown-menu hide orientation-{orientation}" use:clickOutside on:click_outside={handleClickOutside}>
|
||||||
|
<slot/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<button
|
</div>
|
||||||
|
|
||||||
class="btn btn-sm btn-outline-primary dropdown-toggle d-flex align-items-center"
|
|
||||||
type="button"
|
|
||||||
data-bs-toggle="dropdown"
|
|
||||||
data-bs-auto-close="outside"
|
|
||||||
aria-expanded="false"
|
|
||||||
>
|
|
||||||
<slot name="button">Dropdown</slot>
|
|
||||||
</button>
|
|
||||||
<div bind:this={dropdownMenu} class="dropdown-menu" style="width:{width}px;">
|
|
||||||
<slot/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@@ -125,6 +125,7 @@
|
|||||||
role="presentation"
|
role="presentation"
|
||||||
{stroke}
|
{stroke}
|
||||||
{fill}
|
{fill}
|
||||||
|
|
||||||
>
|
>
|
||||||
{@html selectedIcon.path}
|
{@html selectedIcon.path}
|
||||||
</svg>
|
</svg>
|
||||||
@@ -132,5 +133,6 @@
|
|||||||
<style>
|
<style>
|
||||||
svg {
|
svg {
|
||||||
vertical-align: text-top;
|
vertical-align: text-top;
|
||||||
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -46,8 +46,8 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="wrapper-large transparent ">
|
<div class="">
|
||||||
<div class="lx-card mb-4 {inModal ? 'mt-0' : 'mt-5'}">
|
<div class="{inModal ? 'mt-0' : 'mt-5'}">
|
||||||
<h3 class="header-normal mb-5 ">
|
<h3 class="header-normal mb-5 ">
|
||||||
{schema.label}
|
{schema.label}
|
||||||
</h3>
|
</h3>
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="lx-table rounded">
|
<div class="table">
|
||||||
<table class="">
|
<table class="">
|
||||||
<thead class="table-light">
|
<thead class="table-light">
|
||||||
<tr>
|
<tr>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import Icon from "../../common/Icon.svelte";
|
import Icon from "../../common/Icon.svelte";
|
||||||
import {createEventDispatcher} from "svelte";
|
import {createEventDispatcher} from "svelte";
|
||||||
|
import Dropdown from "../../common/Dropdown.svelte";
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
export let schema;
|
export let schema;
|
||||||
@@ -31,101 +32,91 @@
|
|||||||
|
|
||||||
function sortAsc(e, field) {
|
function sortAsc(e, field) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
let prefix = systemFields.map((el) => el.name).includes(field.name) ? "" : "data.";
|
let prefix = systemFields.map((el) => el.name).includes(field.name) ? "" : "data.";
|
||||||
return triggerSortField(prefix + field.name);
|
return triggerSortField(prefix + field.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
function sortDesc(e, field) {
|
function sortDesc(e, field) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
let prefix = systemFields.map((el) => el.name).includes(field.name) ? "" : "data.";
|
let prefix = systemFields.map((el) => el.name).includes(field.name) ? "" : "data.";
|
||||||
return triggerSortField("-" + prefix + field.name);
|
return triggerSortField("-" + prefix + field.name);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class=" ">
|
|
||||||
<button
|
<Dropdown>
|
||||||
class="btn btn-sm btn-outline-primary dropdown-toggle d-flex align-items-center"
|
<div slot="button">
|
||||||
type="button"
|
|
||||||
data-bs-toggle="dropdown"
|
|
||||||
data-bs-auto-close="outside"
|
|
||||||
aria-expanded="false"
|
|
||||||
>
|
|
||||||
{#if sortParam.startsWith("-")}
|
{#if sortParam.startsWith("-")}
|
||||||
<Icon icon="arrow-down-wide-short"/>
|
<Icon icon="arrow-down-wide-short"/>
|
||||||
{:else}
|
{:else}
|
||||||
<Icon icon="arrow-up-short-wide"/>
|
<Icon icon="arrow-up-short-wide"/>
|
||||||
{/if}
|
{/if}
|
||||||
<span class="ms-1">{sortField.label}</span>
|
<span class="ms-1">{sortField.label}</span>
|
||||||
</button>
|
|
||||||
<div class="dropdown-menu" style="width:auto;max-width:800px;">
|
|
||||||
<div class="row">
|
|
||||||
{#each sortableFields as field}
|
|
||||||
<div class="col-4 px-3 py-1 d-flex align-items-center">
|
|
||||||
<div class="btn-group w-100">
|
|
||||||
<button
|
|
||||||
on:click={(e) => sortAsc(e, field)}
|
|
||||||
title="Sort Ascending"
|
|
||||||
class="btn btn-sm {field.name == sortField.name && !sortParam.startsWith("-")
|
|
||||||
? 'btn-primary'
|
|
||||||
: 'btn-outline-primary'} "
|
|
||||||
>
|
|
||||||
<Icon icon="arrow-up-short-wide"/>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
on:click={(e) => sortDesc(e, field)}
|
|
||||||
title="Sort Descending"
|
|
||||||
class="btn btn-sm {field.name == sortField.name && sortParam.startsWith("-")
|
|
||||||
? 'btn-primary'
|
|
||||||
: 'btn-outline-primary'} "
|
|
||||||
>
|
|
||||||
<Icon icon="arrow-down-wide-short"/>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
title="Sort Ascending"
|
|
||||||
on:click={(e) => sortAsc(e, field)}
|
|
||||||
class="btn btn-sm btn-outline-primary w-100 text-nowrap"
|
|
||||||
style="overflow: hidden;"
|
|
||||||
>
|
|
||||||
{field.label}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
<h6 class="dropdown-header px-0">System</h6>
|
|
||||||
<div class="row">
|
|
||||||
{#each systemFieldsFiltered as field}
|
|
||||||
<div class="col-4 px-3 py-1 d-flex align-items-center">
|
|
||||||
<div class="btn-group w-100">
|
|
||||||
<button
|
|
||||||
on:click={(e) => sortAsc(e, field)}
|
|
||||||
title="Sort Ascending"
|
|
||||||
class="btn btn-sm {field.name == sortParam
|
|
||||||
? 'btn-primary'
|
|
||||||
: 'btn-outline-primary'} "
|
|
||||||
>
|
|
||||||
<Icon icon="arrow-up-short-wide"/>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
on:click={(e) => sortDesc(e, field)}
|
|
||||||
title="Sort Descending"
|
|
||||||
class="btn btn-sm {'-' + field.name == sortParam
|
|
||||||
? 'btn-primary'
|
|
||||||
: 'btn-outline-primary'} "
|
|
||||||
>
|
|
||||||
<Icon icon="arrow-down-wide-short"/>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
title="Sort Ascending"
|
|
||||||
on:click={(e) => sortAsc(e, field)}
|
|
||||||
class="btn btn-sm btn-outline-primary w-100 text-nowrap"
|
|
||||||
style="overflow: hidden;"
|
|
||||||
>
|
|
||||||
{field.label}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div>
|
||||||
|
{#each sortableFields as field}
|
||||||
|
<div class="dropdown-item">
|
||||||
|
<button
|
||||||
|
on:click={(e) => sortAsc(e, field)}
|
||||||
|
title="Sort Ascending"
|
||||||
|
class="button button-icon {field.name == sortField.name && !sortParam.startsWith("-")
|
||||||
|
? 'active'
|
||||||
|
: ''} "
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
<Icon icon="arrow-up-short-wide"/>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
on:click={(e) => sortDesc(e, field)}
|
||||||
|
title="Sort Descending"
|
||||||
|
class="button button-icon {field.name == sortField.name && sortParam.startsWith("-")
|
||||||
|
? 'active'
|
||||||
|
: ''} "
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
<Icon icon="arrow-down-wide-short"/>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
title="Sort Ascending"
|
||||||
|
on:click={(e) => sortAsc(e, field)}
|
||||||
|
class="button"
|
||||||
|
>
|
||||||
|
{field.label}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
<h6 class="dropdown-header">System</h6>
|
||||||
|
{#each systemFieldsFiltered as field}
|
||||||
|
<div class="dropdown-item">
|
||||||
|
|
||||||
|
<button
|
||||||
|
on:click={(e) => sortAsc(e, field)}
|
||||||
|
title="Sort Ascending"
|
||||||
|
class="button button-icon {field.name == sortParam
|
||||||
|
? 'active'
|
||||||
|
: ''} "
|
||||||
|
>
|
||||||
|
<Icon icon="arrow-up-short-wide"/>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
on:click={(e) => sortDesc(e, field)}
|
||||||
|
title="Sort Descending"
|
||||||
|
class="button button-icon {'-' + field.name == sortParam
|
||||||
|
? 'active'
|
||||||
|
: ''} "
|
||||||
|
>
|
||||||
|
<Icon icon="arrow-down-wide-short"/>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
title="Sort Ascending"
|
||||||
|
on:click={(e) => sortAsc(e, field)}
|
||||||
|
class="button"
|
||||||
|
>
|
||||||
|
{field.label}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
</Dropdown>
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
import Icon from "../../common/Icon.svelte";
|
import Icon from "../../common/Icon.svelte";
|
||||||
import SortFields from "./SortFields.svelte";
|
import SortFields from "./SortFields.svelte";
|
||||||
import AppliedFilter from "./AppliedFilter.svelte";
|
import AppliedFilter from "./AppliedFilter.svelte";
|
||||||
import {getContext, createEventDispatcher} from "svelte";
|
import {createEventDispatcher, getContext} from "svelte";
|
||||||
|
import Dropdown from "../../common/Dropdown.svelte";
|
||||||
|
|
||||||
const channel = getContext("channel");
|
const channel = getContext("channel");
|
||||||
|
|
||||||
@@ -47,8 +48,8 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="mb-3 d-flex align-items-center justify-content-between">
|
<div class="toolbar">
|
||||||
<div class=" d-flex align-items-center">
|
<div class="toolbar-filters">
|
||||||
|
|
||||||
<SortFields
|
<SortFields
|
||||||
{schema}
|
{schema}
|
||||||
@@ -72,19 +73,19 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<form method="GET" on:submit={search}>
|
<form method="GET" on:submit={search}>
|
||||||
<input type="search" name="filter[search_regex]" placeholder="Search"
|
<input type="search" name="filter[search_regex]" placeholder="Search"
|
||||||
class="form-control" required>
|
class="form-control" required>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="d-flex align-items-center ">
|
<div style="display:flex;align-items: center">
|
||||||
{#if schema.type === "collection"}
|
{#if schema.type === "collection"}
|
||||||
{#if !inModal && isWritable}
|
{#if !inModal && isWritable}
|
||||||
<a
|
<a
|
||||||
href="{channel.lucentUrl}/records/new?schema={schema.name}"
|
href="{channel.lucentUrl}/records/new?schema={schema.name}"
|
||||||
class="btn btn-sm btn-primary"
|
class="button"
|
||||||
>
|
>
|
||||||
New Record
|
New Record
|
||||||
</a>
|
</a>
|
||||||
@@ -95,48 +96,34 @@
|
|||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
{#if !inModal}
|
{#if !inModal}
|
||||||
<div class="dropdown d-inline-block">
|
<Dropdown orientation="right">
|
||||||
<button
|
<div slot="button">
|
||||||
class="btn btn-link btn-sm"
|
|
||||||
type="button"
|
|
||||||
data-bs-toggle="dropdown"
|
|
||||||
aria-expanded="false"
|
|
||||||
>
|
|
||||||
<Icon icon="ellipsis-vertical"/>
|
<Icon icon="ellipsis-vertical"/>
|
||||||
</button>
|
</div>
|
||||||
|
{#if filter["status_in"] === "trashed"}
|
||||||
<ul class="dropdown-menu">
|
{#if isWritable}
|
||||||
{#if filter["status_in"] === "trashed"}
|
<a
|
||||||
{#if isWritable}
|
class="dropdown-item"
|
||||||
<li>
|
href="{channel.lucentUrl}/content/{schema.name}/emptyTrash"
|
||||||
<a
|
>
|
||||||
class="dropdown-item"
|
Empty trash
|
||||||
href="{channel.lucentUrl}/content/{schema.name}/emptyTrash"
|
</a>
|
||||||
>
|
|
||||||
Empty trash
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{/if}
|
|
||||||
{:else}
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<a
|
|
||||||
class="dropdown-item"
|
|
||||||
href={csvUrl}
|
|
||||||
>Export to CSV</a
|
|
||||||
>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a
|
|
||||||
class="dropdown-item"
|
|
||||||
href="{channel.lucentUrl}/content/{schema.name}?filter[status_in]=trashed"
|
|
||||||
>View trashed records</a
|
|
||||||
>
|
|
||||||
</li>
|
|
||||||
{/if}
|
{/if}
|
||||||
|
{:else}
|
||||||
|
|
||||||
|
<a
|
||||||
|
class="dropdown-item"
|
||||||
|
href={csvUrl}
|
||||||
|
>Export to CSV</a
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
class="dropdown-item"
|
||||||
|
href="{channel.lucentUrl}/content/{schema.name}?filter[status_in]=trashed"
|
||||||
|
>View trashed records</a
|
||||||
|
>
|
||||||
|
{/if}
|
||||||
|
</Dropdown>
|
||||||
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -28,41 +28,58 @@
|
|||||||
fontSize = "13";
|
fontSize = "13";
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
<div style="display: flex;align-items: center;gap: 5px;">
|
||||||
|
{#if record}
|
||||||
|
|
||||||
{#if record}
|
{#if record._file.mime.startsWith("image")}
|
||||||
{#if record._file.mime.startsWith("image")}
|
<!-- href={imgurl(record)} -->
|
||||||
<!-- href={imgurl(record)} -->
|
<a
|
||||||
<a
|
href="{channel.lucentUrl}/records/{record.id}"
|
||||||
href="{channel.lucentUrl}/records/{record.id}"
|
title={record._file.path}
|
||||||
title={record._file.path}
|
style="width:{imageSide}px;height:{imageSide}px"
|
||||||
class="d-flex align-items-center justify-content-center "
|
|
||||||
style="width:{imageSide}px;height:{imageSide}px"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
class="rounded w-100"
|
|
||||||
src={imgurl(record)}
|
|
||||||
alt={record._file.path}
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
{:else}
|
|
||||||
<a
|
|
||||||
href="{channel.lucentUrl}/records/{record.id}"
|
|
||||||
title={record._file.path}
|
|
||||||
class="btn btn-outline-primary btn-sm d-flex align-items-center justify-content-center"
|
|
||||||
style="width:{imageSide}px;height:{imageSide}px"
|
|
||||||
>
|
|
||||||
<Icon icon="file" width={fileSide} height={fileSide}/>
|
|
||||||
<span class="ms-2" style="font-size:{fontSize}px"
|
|
||||||
>.{record._file.path.split(".").pop()}</span
|
|
||||||
>
|
>
|
||||||
</a>
|
<img
|
||||||
|
class="rounded w-100"
|
||||||
|
src={imgurl(record)}
|
||||||
|
alt={record._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"
|
||||||
|
>
|
||||||
|
<Icon icon="file" width={fileSide} height={fileSide}/>
|
||||||
|
<span class="ms-2"
|
||||||
|
>.{record._file.path.split(".").pop()}</span
|
||||||
|
>
|
||||||
|
</a>
|
||||||
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
{/if}
|
{#if showFilename}
|
||||||
{#if showFilename}
|
<a
|
||||||
<a
|
href="{channel.lucentUrl}/records/{record.id}"
|
||||||
href="{channel.lucentUrl}/records/{record.id}"
|
title={record._file.path}
|
||||||
title={record._file.path}
|
class="preview-file-filename lx-small-text text-decoration-none"
|
||||||
class="preview-file-filename lx-small-text text-decoration-none"
|
>{record._file.path}</a
|
||||||
>{record._file.path}</a
|
>
|
||||||
>
|
{/if}
|
||||||
{/if}
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
img{
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 4px;
|
||||||
|
}
|
||||||
|
.file-preview-small{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 2px;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 4px;
|
||||||
|
background: var(--background);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -21,24 +21,21 @@
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="wrapper-normal transparent">
|
|
||||||
|
|
||||||
<h3 class="header-small mb-4 mt-5">Latest Content changes</h3>
|
<h3 class="header-small mb-4 mt-5">Latest Content changes</h3>
|
||||||
{#if records.length > 0}
|
{#if records.length > 0}
|
||||||
<div class="lx-card mb-4">
|
|
||||||
<div class="lx-table p-0">
|
|
||||||
<table class="">
|
|
||||||
<tbody>
|
|
||||||
{#each records as record (record.id)}
|
|
||||||
<tr>
|
|
||||||
<RecordRow {graph} {record} {users}/>
|
|
||||||
</tr>
|
|
||||||
{/each}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/if}
|
<div class="table">
|
||||||
|
<table class="">
|
||||||
|
<tbody>
|
||||||
|
{#each records as record (record.id)}
|
||||||
|
<tr>
|
||||||
|
<RecordRow {graph} {record} {users}/>
|
||||||
|
</tr>
|
||||||
|
{/each}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/if}
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import {formatDistanceToNow, parseJSON} from "date-fns";
|
import {formatDistanceToNow, parseJSON} from "date-fns";
|
||||||
import Avatar from "../account/Avatar.svelte";
|
import Avatar from "../account/Avatar.svelte";
|
||||||
import Status from "../records/Status.svelte";
|
|
||||||
import {previewTitle} from "../records/Preview";
|
import {previewTitle} from "../records/Preview";
|
||||||
import Preview from "../files/Preview.svelte";
|
import Preview from "../files/Preview.svelte";
|
||||||
import {usernameById} from "../account/users";
|
import {usernameById} from "../account/users";
|
||||||
@@ -19,29 +18,30 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
|
<div class="row-name">
|
||||||
|
{#if record.status === "draft"}
|
||||||
|
<span class="status">DRAFT</span>
|
||||||
|
{/if}
|
||||||
{#if schema.type === "files"}
|
{#if schema.type === "files"}
|
||||||
<Preview {record} size="tiny"/>
|
<Preview {record} size="tiny" showFilename={true}/>
|
||||||
{:else}
|
{:else}
|
||||||
<a
|
<a
|
||||||
href="{channel.lucentUrl}/records/{record.id}"
|
href="{channel.lucentUrl}/records/{record.id}"
|
||||||
class="text-decoration-none text-dark d-block"
|
|
||||||
>
|
>
|
||||||
{previewTitle(channel.schemas, record, graph)}
|
{previewTitle(channel.schemas, record, graph)}
|
||||||
</a>
|
</a>
|
||||||
{/if}
|
{/if}
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td><a
|
<td><a
|
||||||
class="text-decoration-none lx-small-text"
|
href="{channel.lucentUrl}/content/{schema.name}">{schema.label}</a
|
||||||
href="{channel.lucentUrl}/content/{schema.name}">{schema.label}</a
|
|
||||||
>
|
>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td class="text-center">
|
|
||||||
<Status status={record.status}/>
|
|
||||||
</td>
|
|
||||||
<td>
|
<td>
|
||||||
<div class="d-flex">
|
<div style="display: flex;gap: 14px">
|
||||||
<Avatar name={usernameById(users, record._sys.updatedBy)} side={24}/>
|
<Avatar name={usernameById(users, record._sys.updatedBy)} side={24}/>
|
||||||
<div class="ms-2">
|
<div class="ms-2">
|
||||||
{frieldlyUpdatedAt}
|
{frieldlyUpdatedAt}
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<script>
|
||||||
|
import Avatar from "../account/Avatar.svelte";
|
||||||
|
import {getContext} from "svelte";
|
||||||
|
|
||||||
|
const channel = getContext("channel");
|
||||||
|
const user = getContext("user");
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="top-nav ">
|
||||||
|
<a class="top-nav-item" href="{channel.lucentUrl}/members">Members</a>
|
||||||
|
|
||||||
|
{#if channel.generateCommand}
|
||||||
|
<a href="{channel.lucentUrl}/build-report" class="top-nav-item">Build website</a>
|
||||||
|
{/if}
|
||||||
|
<!-- <div>-->
|
||||||
|
<!-- <form method="GET">-->
|
||||||
|
<!-- <input type="search" name="filter[search_regex]" placeholder="Search"-->
|
||||||
|
<!-- class="form-control" required/>-->
|
||||||
|
<!-- </form>-->
|
||||||
|
<!-- </div>-->
|
||||||
|
<a href="{channel.lucentUrl}/profile">
|
||||||
|
<Avatar side="28" name={user.name}/>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
<script>
|
||||||
|
import NavbarMenu from "./NavbarMenu.svelte";
|
||||||
|
import {getContext} from "svelte";
|
||||||
|
import Avatar from "../account/Avatar.svelte";
|
||||||
|
|
||||||
|
export let schema;
|
||||||
|
const channel = getContext("channel");
|
||||||
|
const readableSchemas = getContext("readableSchemas");
|
||||||
|
const user = getContext("user");
|
||||||
|
|
||||||
|
const fileSchemas = readableSchemas.filter((sc) => sc.type === "files");
|
||||||
|
const otherSchemas = readableSchemas.filter((sc) => !sc.isEntry && sc.type === "collection");
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<div class="sidebar-top">
|
||||||
|
<a class="logo" href="{channel.lucentUrl}">{channel.name}</a>
|
||||||
|
<a class="nav-item" href="{channel.lucentUrl}/profile">
|
||||||
|
<Avatar side="28" name={user.name}/>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="sidebar">
|
||||||
|
|
||||||
|
|
||||||
|
<NavbarMenu
|
||||||
|
title="Content"
|
||||||
|
schemas={ readableSchemas.filter((sc) => sc.isEntry)}
|
||||||
|
schema={schema}
|
||||||
|
expanded={true}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<NavbarMenu
|
||||||
|
title="Files"
|
||||||
|
schemas={ fileSchemas}
|
||||||
|
schema={schema}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<NavbarMenu
|
||||||
|
title="Other"
|
||||||
|
schemas={ otherSchemas}
|
||||||
|
schema={schema}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
<script>
|
||||||
|
import {getContext} from "svelte";
|
||||||
|
import Icon from "../common/Icon.svelte";
|
||||||
|
|
||||||
|
const channel = getContext("channel");
|
||||||
|
export let schemas;
|
||||||
|
export let title;
|
||||||
|
export let schema;
|
||||||
|
export let expanded = false;
|
||||||
|
|
||||||
|
if(schemas.find(s => s.name === schema?.name)){
|
||||||
|
expanded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleExpand(){
|
||||||
|
expanded = !expanded;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="sidebar-header" role="button" tabindex="0" on:click={toggleExpand}>
|
||||||
|
{title}
|
||||||
|
{#if expanded}
|
||||||
|
<Icon icon="circle-chevron-up"></Icon>
|
||||||
|
{:else}
|
||||||
|
<Icon icon="circle-chevron-down"></Icon>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{#if expanded}
|
||||||
|
{#each schemas as aschema}
|
||||||
|
<a class="sidebar-item" class:active={aschema.name === schema?.name}
|
||||||
|
aria-current="page"
|
||||||
|
href="{channel.lucentUrl}/content/{aschema.name}">{aschema.label}</a>
|
||||||
|
{/each}
|
||||||
|
{/if}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
.button{
|
||||||
|
border-radius: 12px;
|
||||||
|
background: var(--background);
|
||||||
|
padding: 3px 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
filter: brightness(97%);
|
||||||
|
border: none;
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
filter: brightness(94%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
filter: brightness(94%);
|
||||||
|
}
|
||||||
|
&.active {
|
||||||
|
filter: brightness(74%);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
.dropdown {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-button > div {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 10px;
|
||||||
|
overflow: visible;
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 12px;
|
||||||
|
z-index: 9;
|
||||||
|
background: var(--background);
|
||||||
|
filter: brightness(97%);
|
||||||
|
transition: 600ms;
|
||||||
|
flex-grow: 1;
|
||||||
|
|
||||||
|
&.orientation-right {
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.orientation-left {
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
min-width: max-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-header, .dropdown-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 3px;
|
||||||
|
text-wrap: nowrap;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-header {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-item {
|
||||||
|
font-size: 14px;
|
||||||
|
padding: 3px 10px;
|
||||||
|
&:hover{
|
||||||
|
background: var(--background);
|
||||||
|
filter: brightness(97%);
|
||||||
|
border-radius: 12px;
|
||||||
|
}
|
||||||
|
.button-icon {
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,7 +12,7 @@ input{
|
|||||||
}
|
}
|
||||||
input,textarea{
|
input,textarea{
|
||||||
background: var(--input-bg);
|
background: var(--input-bg);
|
||||||
border: 1px solid $border-color;
|
border: 1px solid var(--border-color);
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
padding: 5px 7px;
|
padding: 5px 7px;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
|
|||||||
@@ -29,7 +29,10 @@
|
|||||||
.gap-5{gap: 20px}
|
.gap-5{gap: 20px}
|
||||||
|
|
||||||
.hide{
|
.hide{
|
||||||
display: none;
|
display: none!important;
|
||||||
|
}
|
||||||
|
.hidden{
|
||||||
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.d-block{
|
.d-block{
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
.sidebar {
|
.sidebar-content{
|
||||||
|
min-width: 300px;
|
||||||
|
max-width: 400px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-content {
|
.main-content {
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
.notice {
|
.notice {
|
||||||
background-color: $background;
|
background-color: var(--background);
|
||||||
padding: 25px 14px 14px;
|
padding: 25px 14px 14px;
|
||||||
margin: 2rem 0;
|
margin: 2rem 0;
|
||||||
filter: brightness(1.03);
|
filter: brightness(1.03);
|
||||||
position: relative;
|
position: relative;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
border: 3px solid $border-color;
|
border: 3px solid var(--border-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.notice .title {
|
.notice .title {
|
||||||
content: "NOTE";
|
content: "NOTE";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
background: $background;
|
background: var(--background);
|
||||||
min-width: 90px;
|
min-width: 90px;
|
||||||
border: 3px solid $border-color;
|
border: 3px solid var(--border-color);
|
||||||
color: $text;
|
color: var(--text);
|
||||||
display: block;
|
display: block;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
left: 14px;
|
left: 14px;
|
||||||
@@ -25,8 +25,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.notice.success{
|
.notice.success{
|
||||||
border-color: $success;
|
border-color: var(--success);
|
||||||
& .title{
|
& .title{
|
||||||
border-color: $success;
|
border-color: var(--success);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+57
-17
@@ -1,49 +1,89 @@
|
|||||||
|
.sidebar-top{
|
||||||
|
|
||||||
|
font-size: 18px;
|
||||||
|
padding: 20px 20px ;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
background: var(--background);
|
||||||
|
filter: brightness(97%);
|
||||||
|
margin-bottom: 15px;
|
||||||
|
border-radius: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
.sidebar {
|
.sidebar {
|
||||||
border: 1px solid $border-color;
|
border: 0px solid var(--border-color);
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
min-height: 100vh;
|
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
line-height: 28px;
|
line-height: 28px;
|
||||||
min-width: 300px;
|
padding: 20px;
|
||||||
max-width: 400px;
|
background: var(--background);
|
||||||
background: $background;
|
filter: brightness(97%);
|
||||||
filter: brightness(104%);
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-header {
|
.sidebar-header {
|
||||||
background: $background;
|
display: flex;
|
||||||
|
cursor: pointer;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
background: var(--background);
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
padding: 12px 12px 6px;
|
padding: 3px 12px 6px;
|
||||||
color: $text;
|
color: var(--text);
|
||||||
filter: brightness(94%);
|
filter: brightness(94%);
|
||||||
|
border-bottom: 0px solid var(--border-color);
|
||||||
|
border-radius: 12px;
|
||||||
|
&:hover {
|
||||||
|
background: var(--secondary);
|
||||||
|
}
|
||||||
|
|
||||||
&:first-child {
|
&:first-child {
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
border-radius: 12px 12px 0 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-item {
|
.sidebar-item {
|
||||||
|
|
||||||
color: $text;
|
color: var(--text);
|
||||||
display: block;
|
display: block;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
padding: 6px 12px;
|
padding: 3px 12px;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
border-bottom: 1px solid $border-color;
|
border-bottom: 0px solid var(--border-color);
|
||||||
transition: 600ms;
|
transition: 600ms;
|
||||||
|
border-radius: 12px;
|
||||||
&:last-child {
|
&:last-child {
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
border-radius: 0 0 12px 12px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: $secondary;
|
background: var(--secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
background: $secondary;
|
background: var(--secondary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.top-nav{
|
||||||
|
display: flex;
|
||||||
|
justify-content: end;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
.top-nav-item{
|
||||||
|
border-radius: 12px;
|
||||||
|
font-size: 14px;
|
||||||
|
filter: brightness(97%);
|
||||||
|
background: var(--background);
|
||||||
|
padding: 3px 10px ;
|
||||||
|
&:hover {
|
||||||
|
background: var(--secondary);
|
||||||
|
}
|
||||||
|
}
|
||||||
+22
-5
@@ -1,8 +1,12 @@
|
|||||||
.lx-table {
|
.table {
|
||||||
min-width: 600px;
|
min-width: 600px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 20px;
|
||||||
|
background: var(--background);
|
||||||
|
filter: brightness(97%);
|
||||||
table {
|
table {
|
||||||
min-width: 600px;
|
width: 100%;
|
||||||
|
|
||||||
}
|
}
|
||||||
th {
|
th {
|
||||||
@@ -13,7 +17,6 @@
|
|||||||
// height: 34px;
|
// height: 34px;
|
||||||
padding: 8px 16px;
|
padding: 8px 16px;
|
||||||
// border-bottom: 1px solid #ccc;
|
// border-bottom: 1px solid #ccc;
|
||||||
background: #eee;
|
|
||||||
&.is-sort {
|
&.is-sort {
|
||||||
background-color: rgba($primary, 0.1);
|
background-color: rgba($primary, 0.1);
|
||||||
}
|
}
|
||||||
@@ -26,20 +29,34 @@
|
|||||||
max-width: 400px;
|
max-width: 400px;
|
||||||
height: 48px;
|
height: 48px;
|
||||||
padding: 4px 16px;
|
padding: 4px 16px;
|
||||||
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
&.is-sort {
|
&.is-sort {
|
||||||
background-color: rgba($primary, 0.1);
|
background-color: rgba($primary, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
img{
|
||||||
|
width: 48px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status{
|
||||||
|
color:var(--accent);
|
||||||
|
font-size: 80%;
|
||||||
|
}
|
||||||
|
.row-name{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
tr {
|
tr {
|
||||||
background-color: #fff;
|
|
||||||
&:hover {
|
&:hover {
|
||||||
box-shadow: inset 0em 0em 0em 10em rgba(0, 0, 0, 0.1);
|
box-shadow: inset 0em 0em 0em 10em rgba(0, 0, 0, 0.1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tr:nth-child(odd) {
|
tr:nth-child(odd) {
|
||||||
background-color: #f9f9f9;
|
//background-color: #f9f9f9;
|
||||||
}
|
}
|
||||||
|
|
||||||
td:nth-child(odd) {
|
td:nth-child(odd) {
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
.toolbar{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 5px;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.toolbar-filters{ display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 5px;}
|
||||||
@@ -116,10 +116,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.header-normal {
|
.header-normal {
|
||||||
text-align: center;
|
text-align: left;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-small {
|
.header-small {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
font-size: 26px;
|
font-weight: 400;
|
||||||
|
font-size: 20px;
|
||||||
}
|
}
|
||||||
|
|||||||
+29
-22
@@ -90,9 +90,7 @@ $success: #80c671;
|
|||||||
$background: #f4f6fa;
|
$background: #f4f6fa;
|
||||||
$table-striped-bg-factor: 0.03;
|
$table-striped-bg-factor: 0.03;
|
||||||
$dropdown-bg: rgb(206, 223, 210);
|
$dropdown-bg: rgb(206, 223, 210);
|
||||||
$border-color: #000;
|
|
||||||
$text: #04060b;
|
|
||||||
$accent: #80c671;
|
|
||||||
|
|
||||||
//https://www.realtimecolors.com/?colors=04060b-f4f6fa-5b86be-d9cca1-80c671&fonts=Anek Telugu-Anek Telugu
|
//https://www.realtimecolors.com/?colors=04060b-f4f6fa-5b86be-d9cca1-80c671&fonts=Anek Telugu-Anek Telugu
|
||||||
$themes: (
|
$themes: (
|
||||||
@@ -111,7 +109,25 @@ $themes: (
|
|||||||
accent: #488e39,
|
accent: #488e39,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
:root{
|
||||||
|
--linearPrimarySecondary: linear-gradient(#5b86be, #d9cca1);
|
||||||
|
--linearPrimaryAccent: linear-gradient(#5b86be, #80c671);
|
||||||
|
--linearSecondaryAccent: linear-gradient(#d9cca1, #80c671);
|
||||||
|
--radialPrimarySecondary: radial-gradient(#5b86be, #d9cca1);
|
||||||
|
--radialPrimaryAccent: radial-gradient(#5b86be, #80c671);
|
||||||
|
--radialSecondaryAccent: radial-gradient(#d9cca1, #80c671);
|
||||||
|
--border-color: #000;
|
||||||
|
--main-font: ‘Open Sans‘, Arial, Helvetica, sans-serif;
|
||||||
|
--main-font-color: #444;
|
||||||
|
--input-bg: rgb(245,245,249);
|
||||||
|
--text: #010b05;
|
||||||
|
--background: #f7fefa;
|
||||||
|
--primary: #1ce776;
|
||||||
|
--secondary: #7bc8f1;
|
||||||
|
--accent: #5086ed;
|
||||||
|
--success: #80c671;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//@import "../node_modules/bootstrap/scss/bootstrap";
|
//@import "../node_modules/bootstrap/scss/bootstrap";
|
||||||
@@ -130,25 +146,17 @@ $themes: (
|
|||||||
@import "./card";
|
@import "./card";
|
||||||
@import "./files";
|
@import "./files";
|
||||||
@import "./revisions";
|
@import "./revisions";
|
||||||
|
@import "./toolbar";
|
||||||
|
@import "./dropdown";
|
||||||
|
@import "./button";
|
||||||
|
|
||||||
:root{
|
|
||||||
--linearPrimarySecondary: linear-gradient(#5b86be, #d9cca1);
|
|
||||||
--linearPrimaryAccent: linear-gradient(#5b86be, #80c671);
|
|
||||||
--linearSecondaryAccent: linear-gradient(#d9cca1, #80c671);
|
|
||||||
--radialPrimarySecondary: radial-gradient(#5b86be, #d9cca1);
|
|
||||||
--radialPrimaryAccent: radial-gradient(#5b86be, #80c671);
|
|
||||||
--radialSecondaryAccent: radial-gradient(#d9cca1, #80c671);
|
|
||||||
--border-color: $border-color;
|
|
||||||
--main-font: ‘Open Sans‘, Arial, Helvetica, sans-serif;
|
|
||||||
--main-font-color: #444;
|
|
||||||
--input-bg: rgb(245,245,249);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
body {
|
body {
|
||||||
background-color: $background;
|
background-color: var(--background);
|
||||||
|
font-family: var(--main-font), sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-spinner .spinner-border {
|
.btn-spinner .spinner-border {
|
||||||
@@ -168,9 +176,8 @@ body {
|
|||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-menu {
|
|
||||||
border: 0;
|
a{
|
||||||
border-radius: 15px;
|
color: var(--text);
|
||||||
box-shadow: 0 0 4px #ccc;
|
text-decoration: none;
|
||||||
padding: 30px 15px;
|
}
|
||||||
}
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<div class="d-flex align-items-center ">
|
<div class="d-flex align-items-center ">
|
||||||
<a class="nav-item" href="/lucent">{{$channel->name}}</a>
|
|
||||||
<a class="nav-item" href="{channel.lucentUrl}/members">Members</a>
|
<a class="nav-item" href="{channel.lucentUrl}/members">Members</a>
|
||||||
|
|
||||||
@if($channel->generateCommand)
|
@if($channel->generateCommand)
|
||||||
|
|||||||
@@ -23,13 +23,11 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
@include("lucent::includes.header")
|
|
||||||
<div class="main-wrapper">
|
|
||||||
@include("lucent::sidebar.sidebar")
|
@yield('content')
|
||||||
<div class="main-content">
|
|
||||||
@yield('content')
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
$schema = $schemas->where("name",$record->schema)->first();
|
$schema = $schemas->where("name",$record->schema)->first();
|
||||||
@endphp
|
@endphp
|
||||||
<td>
|
<td>
|
||||||
{{-- {#if schema.type === "files"}--}}
|
@if($schema->type === "files")
|
||||||
{{-- <Preview {record} size="tiny"/>--}}
|
<Preview {record} size="tiny"/>
|
||||||
{{-- {:else}--}}
|
@else
|
||||||
<a
|
<a
|
||||||
href="/lucent/records/{{$record->id}}"
|
href="/lucent/records/{{$record->id}}"
|
||||||
class="text-decoration-none text-dark d-block"
|
class="text-decoration-none text-dark d-block"
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
</a>
|
</a>
|
||||||
|
|
||||||
{{$record->status->value === "draft" ? "Draft" : ""}}
|
{{$record->status->value === "draft" ? "Draft" : ""}}
|
||||||
{{-- {/if}--}}
|
@endif
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
<td><a
|
<td><a
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
|
<a class="nav-item" href="/lucent">{{$channel->name}}</a>
|
||||||
<div class="sidebar">
|
<div class="sidebar">
|
||||||
|
|
||||||
<div class="sidebar-header">
|
<div class="sidebar-header">
|
||||||
Content
|
Content
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -21,36 +21,14 @@ class HomeController extends Controller
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public function home(Request $request): View
|
public function home(): View
|
||||||
{
|
{
|
||||||
$urlParams = $request->all();
|
|
||||||
$users = $this->accountService->all();
|
|
||||||
|
|
||||||
$sort = data_get($urlParams, "sort") ?? "-_sys.updatedAt";
|
|
||||||
$filter = data_get($urlParams, "filter") ?? [];
|
|
||||||
$arguments = array_merge([
|
|
||||||
"schema_in" => $this->accountService->currentReadableSchemas(),
|
|
||||||
"status_in" => ["draft", "published"]
|
|
||||||
], $filter);
|
|
||||||
|
|
||||||
$limit = 10;
|
|
||||||
|
|
||||||
$graph = $this->query
|
|
||||||
->filter($arguments)
|
|
||||||
->limit($limit)
|
|
||||||
->childrenDepth(1)
|
|
||||||
->parentsDepth(0)
|
|
||||||
->sort($sort)
|
|
||||||
->run();
|
|
||||||
|
|
||||||
|
|
||||||
return view("lucent::home", [
|
|
||||||
"users" => $users,
|
|
||||||
"records" => $graph->getRootRecords(),
|
|
||||||
"graph" => toArray($graph),
|
|
||||||
"modalUrl" => $request->fullUrl(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
|
return $this->svelte->render(
|
||||||
|
layout: "channel",
|
||||||
|
view: "homeIndex",
|
||||||
|
title: "Records",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function records(Request $request): Response
|
public function records(Request $request): Response
|
||||||
@@ -65,7 +43,7 @@ class HomeController extends Controller
|
|||||||
"status_in" => ["draft", "published"]
|
"status_in" => ["draft", "published"]
|
||||||
], $filter);
|
], $filter);
|
||||||
|
|
||||||
$limit = 30;
|
$limit = 20;
|
||||||
|
|
||||||
$graph = $this->query
|
$graph = $this->query
|
||||||
->filter($arguments)
|
->filter($arguments)
|
||||||
|
|||||||
Reference in New Issue
Block a user