2019-07-13 21:35:57 +12:00
|
|
|
<script>
|
2020-02-03 22:50:30 +13:00
|
|
|
import Textbox from "../common/Textbox.svelte"
|
|
|
|
import Button from "../common/Button.svelte"
|
|
|
|
import getIcon from "../common/icon"
|
|
|
|
import FieldView from "./FieldView.svelte"
|
|
|
|
import Modal from "../common/Modal.svelte"
|
|
|
|
import { map, join, filter, some, find, keys, isDate } from "lodash/fp"
|
|
|
|
import { store } from "../builderStore"
|
|
|
|
import { common, hierarchy as h } from "../../../core/src"
|
|
|
|
import { templateApi, pipe, validate } from "../common/core"
|
|
|
|
|
|
|
|
let record
|
|
|
|
let getIndexAllowedRecords
|
|
|
|
let editingField = false
|
|
|
|
let fieldToEdit
|
|
|
|
let isNewField = false
|
|
|
|
let newField
|
|
|
|
let editField
|
|
|
|
let deleteField
|
|
|
|
let onFinishedFieldEdit
|
|
|
|
let editIndex
|
|
|
|
|
|
|
|
store.subscribe($store => {
|
|
|
|
record = $store.currentNode
|
|
|
|
const flattened = h.getFlattenedHierarchy($store.hierarchy)
|
|
|
|
getIndexAllowedRecords = index =>
|
|
|
|
pipe(index.allowedRecordNodeIds, [
|
|
|
|
filter(id => some(n => n.nodeId === id)(flattened)),
|
|
|
|
map(id => find(n => n.nodeId === id)(flattened).name),
|
|
|
|
join(", "),
|
|
|
|
])
|
2019-07-13 21:35:57 +12:00
|
|
|
|
|
|
|
newField = () => {
|
2020-02-03 22:50:30 +13:00
|
|
|
isNewField = true
|
|
|
|
fieldToEdit = templateApi($store.hierarchy).getNewField("string")
|
|
|
|
editingField = true
|
2019-07-13 21:35:57 +12:00
|
|
|
}
|
|
|
|
|
2020-02-03 22:50:30 +13:00
|
|
|
onFinishedFieldEdit = field => {
|
|
|
|
if (field) {
|
|
|
|
store.saveField(field)
|
|
|
|
}
|
|
|
|
editingField = false
|
2019-07-13 21:35:57 +12:00
|
|
|
}
|
|
|
|
|
2020-02-03 22:50:30 +13:00
|
|
|
editField = field => {
|
|
|
|
isNewField = false
|
|
|
|
fieldToEdit = field
|
|
|
|
editingField = true
|
2019-07-13 21:35:57 +12:00
|
|
|
}
|
|
|
|
|
2020-02-03 22:50:30 +13:00
|
|
|
deleteField = field => {
|
|
|
|
store.deleteField(field)
|
2019-07-13 21:35:57 +12:00
|
|
|
}
|
|
|
|
|
|
|
|
editIndex = index => {
|
2020-02-03 22:50:30 +13:00
|
|
|
store.selectExistingNode(index.nodeId)
|
2019-07-13 21:35:57 +12:00
|
|
|
}
|
2020-02-03 22:50:30 +13:00
|
|
|
})
|
|
|
|
|
|
|
|
let getTypeOptionsValueText = value => {
|
|
|
|
if (
|
|
|
|
value === Number.MAX_SAFE_INTEGER ||
|
|
|
|
value === Number.MIN_SAFE_INTEGER ||
|
|
|
|
new Date(value).getTime() === new Date(8640000000000000).getTime() ||
|
|
|
|
new Date(value).getTime() === new Date(-8640000000000000).getTime()
|
|
|
|
)
|
|
|
|
return "(any)"
|
|
|
|
|
|
|
|
if (value === null) return "(not set)"
|
|
|
|
return value
|
|
|
|
}
|
|
|
|
|
|
|
|
let getTypeOptions = typeOptions =>
|
2019-08-03 01:54:10 +12:00
|
|
|
pipe(typeOptions, [
|
2020-02-03 22:50:30 +13:00
|
|
|
keys,
|
|
|
|
map(
|
|
|
|
k =>
|
|
|
|
`<span style="color:var(--slate)">${k}: </span>${getTypeOptionsValueText(
|
|
|
|
typeOptions[k]
|
|
|
|
)}`
|
|
|
|
),
|
|
|
|
join("<br>"),
|
|
|
|
])
|
|
|
|
|
|
|
|
const nameChanged = ev => {
|
|
|
|
const pluralName = n => `${n}s`
|
|
|
|
if (record.collectionName === "") {
|
|
|
|
record.collectionName = pluralName(ev.target.value)
|
2019-10-31 22:25:26 +13:00
|
|
|
}
|
2020-02-03 22:50:30 +13:00
|
|
|
}
|
2019-07-13 21:35:57 +12:00
|
|
|
</script>
|
|
|
|
|
|
|
|
<div class="root">
|
|
|
|
|
2020-02-03 22:50:30 +13:00
|
|
|
<form class="uk-form-horizontal">
|
2020-02-25 04:00:48 +13:00
|
|
|
<h3 class="budibase__title--3">Settings</h3>
|
2020-02-03 22:50:30 +13:00
|
|
|
|
|
|
|
<Textbox label="Name:" bind:text={record.name} on:change={nameChanged} />
|
|
|
|
{#if !record.isSingle}
|
|
|
|
<Textbox label="Collection Name:" bind:text={record.collectionName} />
|
2020-02-26 04:21:23 +13:00
|
|
|
<Textbox
|
|
|
|
label="Estimated Record Count:"
|
|
|
|
bind:text={record.estimatedRecordCount} />
|
2019-07-13 21:35:57 +12:00
|
|
|
{/if}
|
2020-02-03 22:50:30 +13:00
|
|
|
<div class="recordkey">{record.nodeKey()}</div>
|
|
|
|
|
|
|
|
</form>
|
2020-02-25 04:00:48 +13:00
|
|
|
<h3 class="budibase__title--3">
|
2020-02-03 22:50:30 +13:00
|
|
|
Fields
|
|
|
|
<span class="add-field-button" on:click={newField}>
|
|
|
|
{@html getIcon('plus')}
|
|
|
|
</span>
|
|
|
|
</h3>
|
2019-07-13 21:35:57 +12:00
|
|
|
|
2020-02-03 22:50:30 +13:00
|
|
|
{#if record.fields.length > 0}
|
|
|
|
<table class="fields-table uk-table">
|
|
|
|
<thead>
|
|
|
|
<tr>
|
|
|
|
<th>Name</th>
|
|
|
|
<th>Type</th>
|
|
|
|
<th>Options</th>
|
|
|
|
<th />
|
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
{#each record.fields as field}
|
|
|
|
<tr>
|
|
|
|
<td>
|
|
|
|
<div class="field-label">{field.label}</div>
|
|
|
|
<div style="font-size: 0.8em; color: var(--slate)">
|
|
|
|
{field.name}
|
|
|
|
</div>
|
|
|
|
</td>
|
|
|
|
<td>{field.type}</td>
|
|
|
|
<td>
|
|
|
|
{@html getTypeOptions(field.typeOptions)}
|
|
|
|
</td>
|
|
|
|
<td>
|
|
|
|
<span class="edit-button" on:click={() => editField(field)}>
|
|
|
|
{@html getIcon('edit')}
|
|
|
|
</span>
|
|
|
|
<span class="edit-button" on:click={() => deleteField(field)}>
|
|
|
|
{@html getIcon('trash')}
|
|
|
|
</span>
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
{/each}
|
|
|
|
</tbody>
|
|
|
|
</table>
|
|
|
|
{:else}(no fields added){/if}
|
|
|
|
|
|
|
|
{#if editingField}
|
|
|
|
<Modal
|
2020-02-25 05:41:02 +13:00
|
|
|
title="Manage Index Fields"
|
2020-02-03 22:50:30 +13:00
|
|
|
bind:isOpen={editingField}
|
|
|
|
onClosed={() => onFinishedFieldEdit(false)}>
|
|
|
|
<FieldView
|
|
|
|
field={fieldToEdit}
|
|
|
|
onFinished={onFinishedFieldEdit}
|
|
|
|
allFields={record.fields}
|
|
|
|
store={$store} />
|
2019-07-13 21:35:57 +12:00
|
|
|
</Modal>
|
2020-02-03 22:50:30 +13:00
|
|
|
{/if}
|
2019-07-13 21:35:57 +12:00
|
|
|
|
2020-02-25 04:00:48 +13:00
|
|
|
<h3 class="budibase__title--3">Indexes</h3>
|
2019-07-13 21:35:57 +12:00
|
|
|
|
2020-02-03 22:50:30 +13:00
|
|
|
{#each record.indexes as index}
|
2019-07-13 21:35:57 +12:00
|
|
|
<div class="index-container">
|
2020-02-03 22:50:30 +13:00
|
|
|
<div class="index-name">
|
|
|
|
{index.name}
|
|
|
|
<span style="margin-left: 7px" on:click={() => editIndex(index)}>
|
|
|
|
{@html getIcon('edit')}
|
|
|
|
</span>
|
|
|
|
</div>
|
|
|
|
<div class="index-field-row">
|
|
|
|
<span class="index-label">records indexed:</span>
|
|
|
|
<span>{getIndexAllowedRecords(index)}</span>
|
|
|
|
<span class="index-label" style="margin-left: 15px">type:</span>
|
|
|
|
<span>{index.indexType}</span>
|
|
|
|
</div>
|
|
|
|
<div class="index-field-row">
|
|
|
|
<span class="index-label">map:</span>
|
|
|
|
<code class="index-mapfilter">{index.map}</code>
|
|
|
|
</div>
|
|
|
|
{#if index.filter}
|
2019-07-13 21:35:57 +12:00
|
|
|
<div class="index-field-row">
|
2020-02-03 22:50:30 +13:00
|
|
|
<span class="index-label">filter:</span>
|
|
|
|
<code class="index-mapfilter">{index.filter}</code>
|
2019-07-13 21:35:57 +12:00
|
|
|
</div>
|
2020-02-03 22:50:30 +13:00
|
|
|
{/if}
|
2019-09-19 06:16:11 +12:00
|
|
|
</div>
|
2020-02-03 22:50:30 +13:00
|
|
|
{:else}
|
|
|
|
<div class="no-indexes">No indexes added.</div>
|
|
|
|
{/each}
|
2019-07-13 21:35:57 +12:00
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<style>
|
2020-02-03 22:50:30 +13:00
|
|
|
.root {
|
2019-07-13 21:35:57 +12:00
|
|
|
height: 100%;
|
2019-09-19 06:16:11 +12:00
|
|
|
padding: 2rem;
|
2020-02-03 22:50:30 +13:00
|
|
|
}
|
2019-09-19 06:16:11 +12:00
|
|
|
|
2020-02-03 22:50:30 +13:00
|
|
|
.recordkey {
|
2019-09-19 06:16:11 +12:00
|
|
|
font-size: 14px;
|
|
|
|
font-weight: 600;
|
|
|
|
color: var(--primary100);
|
2020-02-03 22:50:30 +13:00
|
|
|
}
|
2019-07-13 21:35:57 +12:00
|
|
|
|
2020-02-03 22:50:30 +13:00
|
|
|
.fields-table {
|
2019-09-19 06:16:11 +12:00
|
|
|
margin: 1rem 1rem 0rem 0rem;
|
2020-02-03 22:50:30 +13:00
|
|
|
border-collapse: collapse;
|
|
|
|
}
|
2019-07-13 21:35:57 +12:00
|
|
|
|
2020-02-03 22:50:30 +13:00
|
|
|
.add-field-button {
|
|
|
|
cursor: pointer;
|
|
|
|
}
|
2019-07-13 21:35:57 +12:00
|
|
|
|
2020-02-03 22:50:30 +13:00
|
|
|
.edit-button {
|
|
|
|
cursor: pointer;
|
2019-09-20 06:47:18 +12:00
|
|
|
color: var(--secondary25);
|
2020-02-03 22:50:30 +13:00
|
|
|
}
|
2019-07-13 21:35:57 +12:00
|
|
|
|
2020-02-03 22:50:30 +13:00
|
|
|
.edit-button:hover {
|
|
|
|
cursor: pointer;
|
2019-07-13 21:35:57 +12:00
|
|
|
color: var(--secondary75);
|
2020-02-03 22:50:30 +13:00
|
|
|
}
|
2019-07-13 21:35:57 +12:00
|
|
|
|
2020-02-03 22:50:30 +13:00
|
|
|
th {
|
|
|
|
text-align: left;
|
|
|
|
}
|
2019-07-13 21:35:57 +12:00
|
|
|
|
2020-02-03 22:50:30 +13:00
|
|
|
td {
|
2019-09-19 06:16:11 +12:00
|
|
|
padding: 1rem 5rem 1rem 0rem;
|
2020-02-03 22:50:30 +13:00
|
|
|
margin: 0;
|
2019-09-24 09:22:57 +12:00
|
|
|
font-size: 14px;
|
|
|
|
font-weight: 500;
|
2020-02-03 22:50:30 +13:00
|
|
|
}
|
2019-09-24 09:22:57 +12:00
|
|
|
|
2020-02-03 22:50:30 +13:00
|
|
|
.field-label {
|
|
|
|
font-size: 14px;
|
|
|
|
font-weight: 500;
|
|
|
|
}
|
2019-07-13 21:35:57 +12:00
|
|
|
|
2020-02-03 22:50:30 +13:00
|
|
|
thead > tr {
|
2019-07-13 21:35:57 +12:00
|
|
|
border-width: 0px 0px 1px 0px;
|
|
|
|
border-style: solid;
|
|
|
|
border-color: var(--secondary75);
|
|
|
|
margin-bottom: 20px;
|
2020-02-03 22:50:30 +13:00
|
|
|
}
|
2019-07-13 21:35:57 +12:00
|
|
|
|
2020-02-03 22:50:30 +13:00
|
|
|
tbody > tr {
|
2019-07-13 21:35:57 +12:00
|
|
|
border-width: 0px 0px 1px 0px;
|
|
|
|
border-style: solid;
|
|
|
|
border-color: var(--primary10);
|
2020-02-03 22:50:30 +13:00
|
|
|
}
|
2019-07-13 21:35:57 +12:00
|
|
|
|
2020-02-03 22:50:30 +13:00
|
|
|
tbody > tr:hover {
|
2019-07-13 21:35:57 +12:00
|
|
|
background-color: var(--primary10);
|
2020-02-03 22:50:30 +13:00
|
|
|
}
|
2019-07-13 21:35:57 +12:00
|
|
|
|
2020-02-03 22:50:30 +13:00
|
|
|
tbody > tr:hover .edit-button {
|
2019-07-13 21:35:57 +12:00
|
|
|
color: var(--secondary75);
|
2020-02-03 22:50:30 +13:00
|
|
|
}
|
2019-07-13 21:35:57 +12:00
|
|
|
|
2020-02-03 22:50:30 +13:00
|
|
|
.index-container {
|
2019-07-13 21:35:57 +12:00
|
|
|
border-style: solid;
|
|
|
|
border-width: 0 0 1px 0;
|
|
|
|
border-color: var(--secondary25);
|
|
|
|
padding: 10px;
|
|
|
|
margin-bottom: 5px;
|
2020-02-03 22:50:30 +13:00
|
|
|
}
|
2019-07-13 21:35:57 +12:00
|
|
|
|
2020-02-03 22:50:30 +13:00
|
|
|
.index-label {
|
2019-07-13 21:35:57 +12:00
|
|
|
color: var(--slate);
|
2020-02-03 22:50:30 +13:00
|
|
|
}
|
2019-07-13 21:35:57 +12:00
|
|
|
|
2020-02-03 22:50:30 +13:00
|
|
|
.index-name {
|
2019-07-13 21:35:57 +12:00
|
|
|
font-weight: bold;
|
|
|
|
color: var(--primary100);
|
2020-02-03 22:50:30 +13:00
|
|
|
}
|
2019-07-13 21:35:57 +12:00
|
|
|
|
2020-02-03 22:50:30 +13:00
|
|
|
.index-container code {
|
2019-07-13 21:35:57 +12:00
|
|
|
margin: 0;
|
|
|
|
display: inline;
|
|
|
|
background-color: var(--primary10);
|
|
|
|
color: var(--secondary100);
|
2020-02-03 22:50:30 +13:00
|
|
|
padding: 3px;
|
|
|
|
}
|
2019-07-13 21:35:57 +12:00
|
|
|
|
2020-02-03 22:50:30 +13:00
|
|
|
.index-field-row {
|
2019-09-19 06:16:11 +12:00
|
|
|
margin: 1rem 0rem 0rem 0rem;
|
2020-02-03 22:50:30 +13:00
|
|
|
}
|
2019-07-13 21:35:57 +12:00
|
|
|
|
2020-02-03 22:50:30 +13:00
|
|
|
.no-indexes {
|
2019-09-19 06:16:11 +12:00
|
|
|
margin: 1rem 0rem 0rem 0rem;
|
|
|
|
font-family: var(--fontnormal);
|
|
|
|
font-size: 14px;
|
2020-02-03 22:50:30 +13:00
|
|
|
}
|
|
|
|
</style>
|