moving more backend stuff into other store actions file

This commit is contained in:
Martin McKeaveney 2020-03-22 11:35:35 +00:00
parent b474f8a600
commit 266c36f079
12 changed files with 166 additions and 221 deletions

View File

@ -34,7 +34,7 @@ export const getBackendUiStore = () => {
store.actions = {
navigate: name => store.update(state => ({ ...state, leftNavItem: name })),
database: {
select: db => store.update(state => ({ ...state, selectedDatabase: db })),
select: state => store.update(state => ({ ...state, selectedDatabase: state })),
},
records: {
delete: record => store.update(state => {
@ -96,8 +96,7 @@ export const newRecord = (store, useRoot) => () => {
export const selectExistingNode = store => nodeId => {
store.update(state => {
const shadowHierarchy = createShadowHierarchy(state.hierarchy)
state.currentNode = getNode(shadowHierarchy, nodeId)
state.currentNode = getNode(state.hierarchy, nodeId)
state.currentNodeIsNew = false
state.errors = []
return state
@ -179,42 +178,32 @@ export const deleteCurrentNode = store => () => {
node => node.nodeId === nodeToDelete.nodeId
)
// if (hierarchyFunctions.isRecord(nodeToDelete)) {
// nodeToDelete.parent().children = filter(
// c => c.nodeId !== nodeToDelete.nodeId
// )(nodeToDelete.parent().children)
// } else {
// nodeToDelete.parent().indexes = remove(
// nodeToDelete.parent().indexes,
// node => node.nodeId === nodeToDelete.nodeId
// )
// }
state.errors = []
saveBackend(state)
return state
})
}
export const saveField = databaseStore => field => {
databaseStore.update(db => {
db.currentNode.fields = filter(f => f.name !== field.name)(
db.currentNode.fields
)
export const saveField = store => field => {
store.update(state => {
state.currentNode.fields = state.currentNode.fields.filter(f => f.name !== field.name)
templateApi(db.hierarchy).addField(db.currentNode, field)
return db
templateApi(state.hierarchy).addField(state.currentNode, field)
return state
})
}
export const deleteField = databaseStore => field => {
databaseStore.update(db => {
db.currentNode.fields = db.currentNode.fields.filter(f => f.name !== field.name)
return db
export const deleteField = store => field => {
store.update(state => {
state.currentNode.fields = state.currentNode.fields.filter(f => f.name !== field.name)
return state
})
}
const incrementAccessLevelsVersion = state =>
(state.accessLevels.version = (state.accessLevels.version || 0) + 1)
const incrementAccessLevelsVersion = state => {
state.accessLevels.version = state.accessLevels.version ? state.accessLevels.version + 1 : 1
return state
}
export const saveLevel = store => (newLevel, isNew, oldLevel = null) => {
store.update(state => {
@ -247,3 +236,52 @@ export const deleteLevel = store => level => {
return state
})
}
export const saveAction = store => (newAction, isNew, oldAction = null) => {
store.update(s => {
const existingAction = isNew
? null
: find(a => a.name === oldAction.name)(s.actions)
if (existingAction) {
s.actions = s.actions.map(action => action === existingAction ? newAction : action)
} else {
s.actions.push(newAction)
}
saveBackend(s)
return s
})
}
export const deleteAction = store => action => {
store.update(state => {
state.actions = state.actions.filter(a => a.name !== action.name);
saveBackend(state);
return state;
})
}
export const saveTrigger = store => (newTrigger, isNew, oldTrigger = null) => {
store.update(s => {
const existingTrigger = isNew
? null
: find(a => a.name === oldTrigger.name)(s.triggers)
if (existingTrigger) {
s.triggers = pipe(s.triggers, [
map(a => (a === existingTrigger ? newTrigger : a)),
])
} else {
s.triggers.push(newTrigger)
}
saveBackend(s)
return s
})
}
export const deleteTrigger = store => trigger => {
store.update(s => {
s.triggers = filter(t => t.name !== trigger.name)(s.triggers)
return s
})
}

View File

@ -1,10 +1,8 @@
import {
filter,
cloneDeep,
map,
last,
concat,
find,
isEmpty,
values,
} from "lodash/fp"
@ -76,12 +74,12 @@ export const getStore = () => {
store.saveLevel = backendStoreActions.saveLevel(store)
store.deleteLevel = backendStoreActions.deleteLevel(store)
store.createDatabaseForApp = backendStoreActions.createDatabaseForApp(store)
store.saveAction = backendStoreActions.saveAction(store)
store.deleteAction = backendStoreActions.deleteAction(store)
store.saveTrigger = backendStoreActions.saveTrigger(store)
store.deleteTrigger = backendStoreActions.deleteTrigger(store)
store.importAppDefinition = importAppDefinition(store)
store.saveAction = saveAction(store)
store.deleteAction = deleteAction(store)
store.saveTrigger = saveTrigger(store)
store.deleteTrigger = deleteTrigger(store)
store.saveScreen = saveScreen(store)
store.addComponentLibrary = addComponentLibrary(store)
store.renameScreen = renameScreen(store)
@ -154,10 +152,6 @@ const initialise = (store, initial) => async () => {
}
initial.appname = appname
initial.pages = pkg.pages
initial.currentInstanceId =
pkg.application.instances && pkg.application.instances.length > 0
? pkg.application.instances[0].id
: ""
initial.hasAppPackage = true
initial.hierarchy = pkg.appDefinition.hierarchy
initial.accessLevels = pkg.accessLevels
@ -174,8 +168,9 @@ const initialise = (store, initial) => async () => {
if (!!initial.hierarchy && !isEmpty(initial.hierarchy)) {
initial.hierarchy = constructHierarchy(initial.hierarchy)
const shadowHierarchy = createShadowHierarchy(initial.hierarchy)
if (initial.currentNode !== null)
if (initial.currentNode !== null) {
initial.currentNode = getNode(shadowHierarchy, initial.currentNode.nodeId)
}
}
store.set(initial)
@ -191,7 +186,7 @@ const showSettings = store => () => {
const useAnalytics = store => () => {
store.update(state => {
state.useAnalytics = !s.useAnalytics
state.useAnalytics = !state.useAnalytics
return state
})
}
@ -211,56 +206,6 @@ const importAppDefinition = store => appDefinition => {
})
}
const saveAction = store => (newAction, isNew, oldAction = null) => {
store.update(s => {
const existingAction = isNew
? null
: find(a => a.name === oldAction.name)(s.actions)
if (existingAction) {
s.actions = pipe(s.actions, [
map(a => (a === existingAction ? newAction : a)),
])
} else {
s.actions.push(newAction)
}
saveBackend(s)
return s
})
}
const deleteAction = store => action => {
store.update(state => {
state.actions = state.actions.filter(a => a.name !== action.name);
saveBackend(state);
return state;
})
}
const saveTrigger = store => (newTrigger, isNew, oldTrigger = null) => {
store.update(s => {
const existingTrigger = isNew
? null
: find(a => a.name === oldTrigger.name)(s.triggers)
if (existingTrigger) {
s.triggers = pipe(s.triggers, [
map(a => (a === existingTrigger ? newTrigger : a)),
])
} else {
s.triggers.push(newTrigger)
}
saveBackend(s)
return s
})
}
const deleteTrigger = store => trigger => {
store.update(s => {
s.triggers = filter(t => t.name !== trigger.name)(s.triggers)
return s
})
}
const createShadowHierarchy = hierarchy =>
constructHierarchy(JSON.parse(JSON.stringify(hierarchy)))

View File

@ -1,45 +0,0 @@
<script>
export let data = []
export let headers = []
</script>
<table class="uk-table">
<thead>
<tr>
<th>Edit</th>
{#each headers as header}
<th>{header}</th>
{/each}
</tr>
</thead>
<tbody>
{#each data as row}
<tr>
<td>
<div class="uk-inline">
<i class="ri-more-line" />
<div uk-dropdown="mode: click">
<ul class="uk-nav uk-dropdown-nav">
<li>
<div>View</div>
</li>
<li>
<div>Edit</div>
</li>
<li>
<div on:click={() => (deleteRecordModal = true)}>Delete</div>
</li>
<li>
<div>Duplicate</div>
</li>
</ul>
</div>
</div>
</td>
{#each headers as header}
<td>{row[header]}</td>
{/each}
</tr>
{/each}
</tbody>
</table>

View File

@ -25,6 +25,6 @@
<style>
textarea {
width: 300px;
height: 200px;
height: 100px;
}
</style>

View File

@ -31,6 +31,7 @@
$: viewOpen = $backendUiStore.visibleModal === "VIEW"
$: databaseOpen = $backendUiStore.visibleModal === "DATABASE"
$: deleteRecordOpen = $backendUiStore.visibleModal === "DELETE_RECORD"
$: breadcrumbs = $store.currentNode
</script>
<Modal isOpen={!!$backendUiStore.visibleModal} {onClosed}>
@ -47,7 +48,7 @@
<CreateDatabaseModal {onClosed} />
{/if}
{#if deleteRecordOpen}
<DeleteRecordModal record={selectedRecord} />
<DeleteRecordModal record={selectedRecord} {onClosed} />
{/if}
</Modal>
@ -57,17 +58,19 @@
<div class="database-actions">
<div class="budibase__label--big">
{#if $backendUiStore.selectedDatabase.name}
{$backendUiStore.selectedDatabase.name} / {$store.currentNode}
{$backendUiStore.selectedDatabase.name} {breadcrumbs}
{/if}
</div>
<ActionButton
primary
on:click={() => {
selectedRecord = null
backendUiStore.actions.modals.show("RECORD")
}}>
Create new record
</ActionButton>
{#if $backendUiStore.selectedDatabase.id}
<ActionButton
primary
on:click={() => {
selectedRecord = null
backendUiStore.actions.modals.show("RECORD")
}}>
Create new record
</ActionButton>
{/if}
</div>
<ModelDataTable {selectRecord} />
</div>

View File

@ -27,9 +27,9 @@
hierarchyFunctions.getFlattenedHierarchy,
filter(hierarchyFunctions.isDecendant(index.parent())),
filter(hierarchyFunctions.isRecord),
map(n => ({
node: n,
isallowed: some(id => n.nodeId === id)(index.allowedRecordNodeIds),
map(node => ({
node,
isallowed: index.allowedRecordNodeIds.some(id => node.nodeId === id),
})),
]
)
@ -37,19 +37,17 @@
const toggleAllowedRecord = record => {
if (record.isallowed) {
index.allowedRecordNodeIds = filter(id => id !== record.node.nodeId)(
index.allowedRecordNodeIds
)
index.allowedRecordNodeIds = index.allowedRecordNodeIds.filter(id => id !== record.node.nodeId)
} else {
index.allowedRecordNodeIds.push(record.node.nodeId)
}
}
</script>
<h3 class="budibase__title--3">
<i class="ri-eye-line" />
Create / Edit View
</h3>
<heading>
<i class="ri-eye-line button--toggled" />
<h3 class="budibase__title--3">Create / Edit View</h3>
</heading>
<form class="uk-form-stacked root">
<h4 class="budibase__label--big">Settings</h4>
<div class="uk-grid-small" uk-grid>
@ -70,10 +68,11 @@
</div>
{#each indexableRecords as rec}
<input
class="uk-checkbox"
type="checkbox"
checked={rec.isallowed}
on:change={() => toggleAllowedRecord(rec)} />
<span>{rec.node.name}</span>
<span class="checkbox-model-label">{rec.node.name}</span>
{/each}
</div>
@ -118,4 +117,17 @@
.highlighted {
opacity: 1;
}
.checkbox-model-label {
text-transform: capitalize;
}
h3 {
margin: 0 0 0 10px;
}
heading {
display: flex;
align-items: center;
}
</style>

View File

@ -10,7 +10,7 @@
export let selectRecord
const ITEMS_PER_PAGE = 2
const ITEMS_PER_PAGE = 10
let selectedView = ""
let modalOpen = false
@ -21,12 +21,13 @@
$: views = $store.hierarchy.indexes
$: currentAppInfo = {
appname: $store.appname,
instanceId: $store.currentInstanceId,
instanceId: $backendUiStore.selectedDatabase.id
}
$: data = $backendUiStore.selectedView.records.slice(
currentPage * ITEMS_PER_PAGE,
currentPage * ITEMS_PER_PAGE + ITEMS_PER_PAGE
)
$: showTable = currentAppInfo.instanceId && views.length > 0
const getSchema = getIndexSchema($store.hierarchy)
@ -42,13 +43,13 @@
}
onMount(async () => {
if (views.length > 0) {
if (showTable) {
await fetchRecordsForView(views[0].name, currentAppInfo)
}
})
</script>
{#if views.length > 0}
{#if showTable}
<section>
<div class="table-controls">
<h4 class="budibase__title--3">{$backendUiStore.selectedDatabase.name || ""}</h4>
@ -80,6 +81,14 @@
<i class="ri-more-line" />
<div uk-dropdown="mode: click">
<ul class="uk-nav uk-dropdown-nav">
<li>
<div
on:click={async () => {
// fetch the child records for that particular row
}}>
View
</div>
</li>
<li
on:click={() => {
selectRecord(row)
@ -98,8 +107,8 @@
</li>
<li>
<div
on:click={() => {
console.log("DUPLICATION")
on:click={async () => {
const response = await api.saveRecord(row)
}}>
Duplicate
</div>
@ -118,7 +127,7 @@
<TablePagination bind:currentPage pageItemCount={data.length} {ITEMS_PER_PAGE} />
</section>
{:else}
Please create a model to get started.
Please select a database.
{/if}

View File

@ -21,10 +21,7 @@
if (record.collectionName) {
const collectionKey = `/${record.collectionName}`
recordBase = getNewRecord(recordBase, collectionKey)
// overwrite the new record template values
for (let key in recordBase) {
if (record[key]) recordBase[key] = record[key]
}
recordBase = overwritePresentProperties(recordBase, record)
}
const SAVE_RECORDS_URL = `/_builder/instance/${appname}/${instanceId}/api/record/`
@ -32,11 +29,32 @@
return await response.json()
}
export async function duplicateRecord(record, { appname, instanceId }) {
let recordBase = { ...record }
delete recordBase.id
recordBase = getNewRecord(recordBase, recordBase.key)
recordBase = overwritePresentProperties(recordBase, record)
const SAVE_RECORDS_URL = `/_builder/instance/${appname}/${instanceId}/api/record/`
const response = await api.post(SAVE_RECORDS_URL, recordBase)
return await response.json()
}
export async function fetchDataForView(viewName, { appname, instanceId }) {
const FETCH_RECORDS_URL = `/_builder/instance/${appname}/${instanceId}/api/listRecords/${viewName}`;
// TODO: Error handling
const response = await api.get(FETCH_RECORDS_URL);
return await response.json();
}
function overwritePresentProperties(baseObj, overwrites) {
const base = { ...baseObj }
for (let key in base) {
if (overwrites[key]) base[key] = overwrites[key]
}
return base;
}

View File

@ -14,8 +14,8 @@
let selectedModel
$: currentAppInfo = {
instanceId: $store.currentInstanceId,
appname: $store.appname,
instanceId: $backendUiStore.selectedDatabase.id
}
$: recordFields = record ? Object.keys(record) : []
$: models = $store.hierarchy.children
@ -66,7 +66,6 @@
<div class="actions">
<ActionButton alert on:click={onClosed}>Cancel</ActionButton>
<ActionButton
disabled={false}
on:click={async () => {
const recordResponse = await api.saveRecord(record || selectedModel, currentAppInfo)
backendUiStore.update(state => {

View File

@ -7,8 +7,8 @@
export let record
$: currentAppInfo = {
instanceId: $store.currentInstanceId,
appname: $store.appname,
instanceId: $backendUiStore.selectedDatabase.id
}
function onClosed() {

View File

@ -91,15 +91,15 @@
<heading>
{#if !editingField}
<i class="ri-list-settings-line button--toggled" />
<h4 class="budibase__title--3">Create / Edit Model</h4>
<h3 class="budibase__title--3">Create / Edit Model</h3>
{:else}
<i class="ri-file-list-line button--toggled" />
<h4 class="budibase__title--3">Create / Edit Field</h4>
<h3 class="budibase__title--3">Create / Edit Field</h3>
{/if}
</heading>
{#if !editingField}
<h4 class="budibase__label--big">Settings</h4>
<form class="uk-form-stacked">
<h3 class="budibase__label--big">Settings</h3>
<Textbox label="Name" bind:text={record.name} on:change={nameChanged} />
@ -204,7 +204,7 @@
align-items: center;
}
h4 {
h3 {
margin: 0 0 0 10px;
}
</style>

View File

@ -6,47 +6,19 @@
import NavItem from "./NavItem.svelte"
import getIcon from "../common/icon"
const defaultNewChildActions = [
{
label: "New Root Record",
onclick: store.newRootRecord,
},
{
label: "New Root Index",
onclick: store.newRootIndex,
},
]
let newChildActions = defaultNewChildActions
const setActiveNav = name => () => {
store.setActiveNav(name)
function newModel() {
if ($store.currentNode) {
store.newChildRecord()
} else {
store.newRootRecord()
}
backendUiStore.actions.modals.show("MODEL")
}
store.subscribe(db => {
if (!db.currentNode || hierarchyFunctions.isIndex(db.currentNode)) {
newChildActions = defaultNewChildActions
} else {
newChildActions = [
{
label: "New Root Record",
onclick: store.newRootRecord,
},
{
label: "New Root Index",
onclick: store.newRootIndex,
},
{
label: `New Child Record of ${db.currentNode.name}`,
onclick: store.newChildRecord,
},
{
label: `New Index on ${db.currentNode.name}`,
onclick: store.newChildIndex,
},
]
}
})
function newView() {
store.newRootIndex()
backendUiStore.actions.modals.show("VIEW")
}
</script>
<div class="items-root">
@ -60,18 +32,12 @@
<ul class="uk-nav uk-dropdown-nav">
<li
class="hoverable"
on:click={() => {
store.newRootRecord()
backendUiStore.actions.modals.show('MODEL')
}}>
on:click={newModel}>
Model
</li>
<li
class="hoverable"
on:click={() => {
store.newRootIndex()
backendUiStore.actions.modals.show('VIEW')
}}>
on:click={newView}>
View
</li>
</ul>