theming
This commit is contained in:
@@ -1,7 +1,9 @@
|
|||||||
<script>
|
<script>
|
||||||
import Preview from "../files/Preview.svelte";
|
import Preview from "../files/Preview.svelte";
|
||||||
import {fileurl} from "../files/imageserver"
|
import {fileurl} from "../files/imageserver"
|
||||||
|
import {getContext} from "svelte"
|
||||||
|
|
||||||
|
const channel = getContext("channel");
|
||||||
export let record;
|
export let record;
|
||||||
export let schema;
|
export let schema;
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import {friendlyDate} from "../../helpers";
|
import {friendlyDate} from "../../helpers";
|
||||||
import Avatar from "../account/Avatar.svelte";
|
import Avatar from "../account/Avatar.svelte";
|
||||||
import {usernameById} from "../account/users";
|
import {usernameById} from "../account/users";
|
||||||
import {isEqual, sortBy} from "lodash";
|
import {isEqual} from "lodash";
|
||||||
import Icon from "../common/Icon.svelte";
|
import Icon from "../common/Icon.svelte";
|
||||||
import RevisionCell from "./revisions/RevisionCell.svelte";
|
import RevisionCell from "./revisions/RevisionCell.svelte";
|
||||||
import {getContext} from "svelte";
|
import {getContext} from "svelte";
|
||||||
@@ -123,19 +123,19 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="lx-card mt-4">
|
<div class="revisions">
|
||||||
{#if schema.revisions > 0}
|
{#if schema.revisions > 0}
|
||||||
<div class="header-small mb-3">Revisions</div>
|
<div class="header-small mb-3">Revisions</div>
|
||||||
{#each revisions as revision}
|
{#each revisions as revision}
|
||||||
{#if revision._sys.version != record._sys.version}
|
{#if revision._sys.version !== record._sys.version}
|
||||||
<div
|
<div
|
||||||
class="row p-2 rounded"
|
class="revision"
|
||||||
class:active={revision._sys.version ===
|
class:active={revision._sys.version ===
|
||||||
selectedRevision?._sys.version}
|
selectedRevision?._sys.version}
|
||||||
>
|
>
|
||||||
|
|
||||||
<div class="col-2">version {revision._sys.version}</div>
|
<div class="version">
|
||||||
<div class="col-5">
|
<span>version {revision._sys.version}</span>
|
||||||
<Avatar
|
<Avatar
|
||||||
name={usernameById(users, revision._sys.updatedBy)}
|
name={usernameById(users, revision._sys.updatedBy)}
|
||||||
side={24}
|
side={24}
|
||||||
@@ -147,7 +147,7 @@
|
|||||||
<button
|
<button
|
||||||
disabled={revision._sys.version ===
|
disabled={revision._sys.version ===
|
||||||
selectedRevision?._sys.version}
|
selectedRevision?._sys.version}
|
||||||
class="btn btn-sm btn-outline-primary"
|
class="button"
|
||||||
on:click={(e) => compare(e, revision)}
|
on:click={(e) => compare(e, revision)}
|
||||||
>Compare
|
>Compare
|
||||||
</button
|
</button
|
||||||
@@ -164,14 +164,14 @@
|
|||||||
</div>
|
</div>
|
||||||
<div bind:this={revisionSection}>
|
<div bind:this={revisionSection}>
|
||||||
{#if selectedRevision}
|
{#if selectedRevision}
|
||||||
<div class="mt-4">
|
<div class="selected-revision">
|
||||||
{#if fieldsWithDiff.length > 0}
|
{#if fieldsWithDiff.length > 0}
|
||||||
<p class="text-center fw-bold mb-3 mt-5">
|
<p class="text-center fw-bold mb-3 mt-5">
|
||||||
If you choose to rollback to this revision
|
If you choose to rollback to this revision
|
||||||
</p>
|
</p>
|
||||||
<button
|
<button
|
||||||
on:click={rollback}
|
on:click={rollback}
|
||||||
class="btn btn-primary mb-5 d-block mx-auto"
|
class="button"
|
||||||
>
|
>
|
||||||
Rollback to version {selectedRevision._sys.version}
|
Rollback to version {selectedRevision._sys.version}
|
||||||
</button>
|
</button>
|
||||||
@@ -189,29 +189,25 @@
|
|||||||
{field.label}
|
{field.label}
|
||||||
</div> -->
|
</div> -->
|
||||||
<div
|
<div
|
||||||
class="lx-card row p-4 mb-4 w-100"
|
class="revision-field"
|
||||||
style="overflow:hidden"
|
style="overflow:hidden"
|
||||||
>
|
>
|
||||||
<div class="col-5">
|
<div class="compare-left">
|
||||||
<RevisionCell
|
<RevisionCell
|
||||||
{field}
|
{field}
|
||||||
side={record.data[field.name]}
|
side={record.data[field.name]}
|
||||||
colorClass="text-danger"
|
colorClass="text-danger"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-2">
|
<div class="compare-center">
|
||||||
<div
|
<span class="me-1">{field.label}</span>
|
||||||
class="h-100 d-flex align-items-center justify-content-center text-secondary"
|
<Icon
|
||||||
>
|
icon="angle-right"
|
||||||
<span class="me-1">{field.label}</span>
|
width="12"
|
||||||
<Icon
|
height="12"
|
||||||
icon="angle-right"
|
/>
|
||||||
width="12"
|
|
||||||
height="12"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-5">
|
<div class="compare-right">
|
||||||
<RevisionCell
|
<RevisionCell
|
||||||
edges={selectedRevision._edges}
|
edges={selectedRevision._edges}
|
||||||
{field}
|
{field}
|
||||||
@@ -235,22 +231,25 @@
|
|||||||
</p>
|
</p>
|
||||||
{#each Object.entries(edgeFieldsDiff) as [field, edges]}
|
{#each Object.entries(edgeFieldsDiff) as [field, edges]}
|
||||||
<div
|
<div
|
||||||
class="lx-card row p-4 mb-4 w-100"
|
class="revision-references"
|
||||||
style="overflow:hidden"
|
style="overflow:hidden"
|
||||||
>
|
>
|
||||||
<div class="col-4">
|
<div class="reference-field">
|
||||||
{field}:
|
{field}:
|
||||||
</div>
|
</div>
|
||||||
<div class="col-8">
|
<div class="reference-compare">
|
||||||
<p class="mb-2 text-danger">Record</p>
|
|
||||||
|
<p class="">Record</p>
|
||||||
{#each edges.record as edge}
|
{#each edges.record as edge}
|
||||||
<RevisionEdgeRow {edge} />
|
<RevisionEdgeRow {edge}/>
|
||||||
{:else}
|
{:else}
|
||||||
<p>No references</p>
|
<p>No references</p>
|
||||||
{/each}
|
{/each}
|
||||||
<p class="mt-4 mb-2 text-success">Revision</p>
|
</div>
|
||||||
|
<div class="reference-compare">
|
||||||
|
<p class="text-success">Revision</p>
|
||||||
{#each edges.revision as edge}
|
{#each edges.revision as edge}
|
||||||
<RevisionEdgeRow {edge} />
|
<RevisionEdgeRow {edge}/>
|
||||||
{:else}
|
{:else}
|
||||||
<p>No references</p>
|
<p>No references</p>
|
||||||
{/each}
|
{/each}
|
||||||
@@ -263,17 +262,3 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
|
||||||
.label {
|
|
||||||
width: 180px;
|
|
||||||
margin-right: 10px;
|
|
||||||
margin-bottom: 4px;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.active {
|
|
||||||
background-color: #eee;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import {stripHtml} from "../../helpers";
|
|||||||
|
|
||||||
export function previewTitle(schemas, record, graph) {
|
export function previewTitle(schemas, record, graph) {
|
||||||
let schema = schemas.find((aSchema) => aSchema.name === record?.schema);
|
let schema = schemas.find((aSchema) => aSchema.name === record?.schema);
|
||||||
|
|
||||||
if (!schema?.titleTemplate) {
|
if (!schema?.titleTemplate) {
|
||||||
return noTemplate(schema, record);
|
return noTemplate(schema, record);
|
||||||
}
|
}
|
||||||
@@ -16,17 +15,17 @@ export function previewTitle(schemas, record, graph) {
|
|||||||
.map((segment) => segment[1]) // map to fieldNames
|
.map((segment) => segment[1]) // map to fieldNames
|
||||||
.filter(fieldName => { // keep only references
|
.filter(fieldName => { // keep only references
|
||||||
let schemaField = schema.fields.find(f => f.name === fieldName)
|
let schemaField = schema.fields.find(f => f.name === fieldName)
|
||||||
return schemaField?.info.name === "reference";
|
return ["reference","file"].includes(schemaField?.info.name);
|
||||||
}).reduce((carry, field) => { // map to records
|
}).reduce((carry, field) => { // map to records
|
||||||
let edge = graph.edges.find(edge => edge.source === record.id && edge.field === field)
|
let edge = graph?.edges.find(edge => edge.source === record.id && edge.field === field)
|
||||||
let referenceRecord = graph.records.find(rec => rec.id === edge?.target)
|
let referenceRecord = graph?.records.find(rec => rec.id === edge?.target)
|
||||||
carry[field] = previewTitle(schemas, referenceRecord, graph);
|
carry[field] = previewTitle(schemas, referenceRecord, graph);
|
||||||
return carry;
|
return carry;
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
recordData = {...recordData, ...referencePreviews}
|
recordData = {...recordData, ...referencePreviews}
|
||||||
|
|
||||||
let render = Mustache.render(schema.titleTemplate, recordData);
|
let render = Mustache.render(schema.titleTemplate, recordData);
|
||||||
|
|
||||||
if (!render || render === "") {
|
if (!render || render === "") {
|
||||||
return noTemplate(schema, record);
|
return noTemplate(schema, record);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,6 +62,7 @@
|
|||||||
{#each references as reference (reference.id)}
|
{#each references as reference (reference.id)}
|
||||||
<div>
|
<div>
|
||||||
<PreviewReference
|
<PreviewReference
|
||||||
|
{graph}
|
||||||
record={reference}
|
record={reference}
|
||||||
hasDelete={true}
|
hasDelete={true}
|
||||||
on:remove={removeReference}
|
on:remove={removeReference}
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
import Dialog from "../../dialog/Dialog.svelte";
|
import Dialog from "../../dialog/Dialog.svelte";
|
||||||
import DialogRecord from "../../dialog/DialogRecord.svelte";
|
import DialogRecord from "../../dialog/DialogRecord.svelte";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
import Dropdown from "../../common/Dropdown.svelte";
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
const channel = getContext("channel");
|
const channel = getContext("channel");
|
||||||
export let schemas;
|
export let schemas;
|
||||||
@@ -56,43 +58,31 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if schemas.length > 1}
|
{#if schemas.length > 1}
|
||||||
<button
|
<div
|
||||||
type="button"
|
style="display: flex;align-items: center;gap:4px"
|
||||||
class:is-first={!recordId}
|
|
||||||
class="button"
|
|
||||||
on:click|preventDefault={(e) => (showOptions = !showOptions)}
|
|
||||||
>
|
>
|
||||||
<Icon width={24} height={24} icon="circle-plus"/>
|
{#each schemas as schema}
|
||||||
</button>
|
<Dropdown>
|
||||||
|
<div slot="button" class:is-first={!recordId}>
|
||||||
{#if showOptions}
|
{schema.label}
|
||||||
<div class="bg-light lx-card d-flex">
|
|
||||||
{#each schemas as schema}
|
|
||||||
<div
|
|
||||||
class="lx-card p-4 text-center me-4"
|
|
||||||
style="max-width: 250px;"
|
|
||||||
>
|
|
||||||
<p>{schema.label}</p>
|
|
||||||
|
|
||||||
<div class="mb-2">
|
|
||||||
<button
|
|
||||||
class="btn btn-sm btn-primary"
|
|
||||||
on:click={(e) =>
|
|
||||||
createInlineReference(e, schema.name)}
|
|
||||||
>New
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="btn btn-sm btn-outline-primary"
|
|
||||||
on:click={(e) => openBrowseModal(e, schema.name)}
|
|
||||||
>
|
|
||||||
<Icon icon="magnifying-glass"/>
|
|
||||||
</button
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
<button
|
||||||
</div>
|
class=" button"
|
||||||
{/if}
|
on:click={(e) =>
|
||||||
|
createInlineReference(e, schema.name)}
|
||||||
|
>Create New Record
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="button"
|
||||||
|
on:click={(e) => openBrowseModal(e, schema.name)}
|
||||||
|
>
|
||||||
|
<Icon icon="magnifying-glass"/>
|
||||||
|
Search
|
||||||
|
</button
|
||||||
|
>
|
||||||
|
</Dropdown>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
<div style="display:flex;align-items: center;gap: 4px">
|
<div style="display:flex;align-items: center;gap: 4px">
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -114,7 +114,7 @@
|
|||||||
on:click={(e) => insert(e, option)}
|
on:click={(e) => insert(e, option)}
|
||||||
on:keypress={(e) => insert(e, option)}
|
on:keypress={(e) => insert(e, option)}
|
||||||
>
|
>
|
||||||
{previewTitle(channel.schemas, option)}
|
{previewTitle(channel.schemas, option ,graph)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{:else}
|
{:else}
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
<script>
|
<script>
|
||||||
import Preview from "../../files/Preview.svelte";
|
|
||||||
import PreviewCardSmall from "../PreviewCardSmall.svelte";
|
|
||||||
import {getContext} from "svelte";
|
import {getContext} from "svelte";
|
||||||
|
|
||||||
const channel = getContext("channel")
|
const channel = getContext("channel")
|
||||||
|
|||||||
@@ -64,4 +64,10 @@
|
|||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor-field{
|
||||||
|
.dropdown-menu {
|
||||||
|
background: var(--p30);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
.revisions{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 5px;
|
||||||
|
.revision{
|
||||||
|
justify-content: space-between;
|
||||||
|
display: flex;
|
||||||
|
gap: 20px;
|
||||||
|
align-items: center;
|
||||||
|
background: var(--p20);
|
||||||
|
padding: 12px;
|
||||||
|
border-radius: 12px;
|
||||||
|
|
||||||
|
.version{
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active{
|
||||||
|
background: var(--p30);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected-revision{
|
||||||
|
margin-top: 30px;
|
||||||
|
align-items: center;
|
||||||
|
background: var(--p20);
|
||||||
|
padding: 12px;
|
||||||
|
border-radius: 12px;
|
||||||
|
|
||||||
|
.button{
|
||||||
|
background: var(--p30);
|
||||||
|
}
|
||||||
|
|
||||||
|
.revision-field{
|
||||||
|
display: flex;
|
||||||
|
gap: 20px;
|
||||||
|
align-items: center;
|
||||||
|
padding: 20px 0;
|
||||||
|
border-bottom: 1px solid var(--p30);
|
||||||
|
flex: 1;
|
||||||
|
.compare-left{
|
||||||
|
width: 45%;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 20px;
|
||||||
|
background: var(--p30);
|
||||||
|
}
|
||||||
|
.compare-right{
|
||||||
|
width: 45%;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 20px;
|
||||||
|
background: var(--p30);
|
||||||
|
}
|
||||||
|
.compare-center{
|
||||||
|
|
||||||
|
width: 10%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
gap: 20px;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
.reference-field{
|
||||||
|
width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.revision-references{
|
||||||
|
display: flex;
|
||||||
|
gap: 20px;
|
||||||
|
align-items: center;
|
||||||
|
padding: 20px 0;
|
||||||
|
border-bottom: 1px solid var(--p30);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reference-compare{
|
||||||
|
|
||||||
|
width: 45%;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 20px;
|
||||||
|
background: var(--p30);
|
||||||
|
}
|
||||||
@@ -68,6 +68,7 @@
|
|||||||
@import "./autocomplete";
|
@import "./autocomplete";
|
||||||
@import "./reference-tags";
|
@import "./reference-tags";
|
||||||
@import "./members";
|
@import "./members";
|
||||||
|
@import "./revisions";
|
||||||
|
|
||||||
body {
|
body {
|
||||||
background-color: var(--p10);
|
background-color: var(--p10);
|
||||||
|
|||||||
Reference in New Issue
Block a user