From a8fec53ff38ed9305ed85c4d8b1d7496c47492c2 Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Fri, 20 Mar 2020 18:47:01 +0000 Subject: [PATCH] adding, deleting and editing records working --- packages/builder/rollup.config.js | 1 + packages/builder/src/BackendRoot.svelte | 16 +- packages/builder/src/builderStore/index.js | 4 +- .../builder/src/builderStore/store/backend.js | 170 +++++++++++++----- .../builder/src/builderStore/store/index.js | 96 +--------- packages/builder/src/common/Modal.svelte | 26 +-- .../builder/src/database/ActionsHeader.svelte | 14 +- .../builder/src/database/DatabaseRoot.svelte | 58 ++++-- .../builder/src/database/HierarchyRow.svelte | 42 ----- .../ModelDataTable/ModelDataTable.svelte | 34 ++-- .../ModelDataTable/TablePagination.svelte | 6 +- .../src/database/ModelDataTable/api.js | 25 ++- .../modals/CreateDatabase.svelte | 17 ++ .../modals/CreateEditField.svelte | 2 +- .../modals/CreateEditModel.svelte | 21 +-- .../modals/CreateEditRecord.svelte | 19 +- .../modals/CreateEditView.svelte | 22 +-- .../ModelDataTable/modals/DeleteRecord.svelte | 16 +- .../database/ModelDataTable/modals/index.js | 4 +- .../builder/src/database/ModelView.svelte | 30 ++-- packages/builder/src/nav/BackendNav.svelte | 60 +------ packages/builder/src/nav/DatabasesList.svelte | 20 +-- packages/builder/src/nav/HierarchyRow.svelte | 32 ++-- packages/builder/src/nav/NavItem.svelte | 10 +- .../src/nav/SchemaManagementDrawer.svelte | 46 +++-- packages/server/middleware/routers.js | 7 +- 26 files changed, 375 insertions(+), 423 deletions(-) delete mode 100644 packages/builder/src/database/HierarchyRow.svelte create mode 100644 packages/builder/src/database/ModelDataTable/modals/CreateDatabase.svelte diff --git a/packages/builder/rollup.config.js b/packages/builder/rollup.config.js index bbc1d3c5fc..8eccb73402 100644 --- a/packages/builder/rollup.config.js +++ b/packages/builder/rollup.config.js @@ -103,6 +103,7 @@ const lodash_fp_exports = [ "toNumber", "takeRight", "toPairs", + "remove" ] const lodash_exports = [ diff --git a/packages/builder/src/BackendRoot.svelte b/packages/builder/src/BackendRoot.svelte index 9d4d8bcfae..d37e774a96 100644 --- a/packages/builder/src/BackendRoot.svelte +++ b/packages/builder/src/BackendRoot.svelte @@ -7,10 +7,7 @@ import AccessLevels from "./accessLevels/AccessLevelsRoot.svelte" import ComingSoon from "./common/ComingSoon.svelte" - import { store } from "./builderStore" - import { setContext } from "svelte" - - let activeNav = "database" + import { store, backendUiStore } from "./builderStore"
@@ -18,13 +15,14 @@
- -
- + {/if} + diff --git a/packages/builder/src/builderStore/index.js b/packages/builder/src/builderStore/index.js index e3bc0b089c..97f2627a0b 100644 --- a/packages/builder/src/builderStore/index.js +++ b/packages/builder/src/builderStore/index.js @@ -1,7 +1,9 @@ -import getStore from "./store" +import { getStore } from "./store" +import { getBackendUiStore } from "./store/backend" import LogRocket from "logrocket"; export const store = getStore() +export const backendUiStore = getBackendUiStore() export const initialise = async () => { try { diff --git a/packages/builder/src/builderStore/store/backend.js b/packages/builder/src/builderStore/store/backend.js index f9adaad606..5d4ef90107 100644 --- a/packages/builder/src/builderStore/store/backend.js +++ b/packages/builder/src/builderStore/store/backend.js @@ -1,9 +1,12 @@ +import { writable } from "svelte/store"; import api from "../api" import { filter, cloneDeep, sortBy, - find + map, + find, + remove } from "lodash/fp" import { hierarchy as hierarchyFunctions } from "../../../../core/src" import { @@ -13,10 +16,47 @@ import { constructHierarchy, templateApi, } from "../../common/core" -import { store } from "../index"; -export const createShadowHierarchy = hierarchy => - constructHierarchy(JSON.parse(JSON.stringify(hierarchy))) +export const getBackendUiStore = () => { + const INITIAL_BACKEND_UI_STATE = { + leftNavItem: "DATABASE", + selectedView: { + records: [], + name: "" + }, + selectedRecord: {}, + selectedDatabase: {}, + selectedModel: {}, + } + + const store = writable(INITIAL_BACKEND_UI_STATE) + + store.actions = { + navigate: name => store.update(state => ({ ...state, leftNavItem: name })), + database: { + select: db => store.update(state => ({ ...state, selectedDatabase: db })), + }, + records: { + delete: record => store.update(state => { + state.selectedView.records = remove(state.selectedView.records, { key: record.key }); + return state + }), + }, + modals: { + show: modal => store.update(state => ({ ...state, visibleModal: modal })), + hide: () => store.update(state => ({ ...state, visibleModal: null })) + } + } + + return store +}; + +// Store Actions +export const createShadowHierarchy = hierarchy => { + const hi = constructHierarchy(JSON.parse(JSON.stringify(hierarchy))) + console.log(hi) + return hi +} export const saveBackend = async state => { await api.post(`/_builder/api/${state.appname}/backend`, { @@ -30,58 +70,57 @@ export const saveBackend = async state => { } export const newRecord = (store, useRoot) => () => { - store.update(s => { - s.currentNodeIsNew = true - const shadowHierarchy = createShadowHierarchy(s.hierarchy) + store.update(state => { + state.currentNodeIsNew = true + const shadowHierarchy = createShadowHierarchy(state.hierarchy) const parent = useRoot ? shadowHierarchy - : getNode(shadowHierarchy, s.currentNode.nodeId) - s.errors = [] - s.currentNode = templateApi(shadowHierarchy).getNewRecordTemplate( + : getNode(shadowHierarchy, state.currentNode.nodeId) + state.errors = [] + state.currentNode = templateApi(shadowHierarchy).getNewRecordTemplate( parent, "", true ) - return s + return state }) } export const selectExistingNode = store => nodeId => { - store.update(s => { - const shadowHierarchy = createShadowHierarchy(s.hierarchy) - s.currentNode = getNode(shadowHierarchy, nodeId) - s.currentNodeIsNew = false - s.errors = [] - return s + store.update(state => { + const shadowHierarchy = createShadowHierarchy(state.hierarchy) + state.currentNode = getNode(shadowHierarchy, nodeId) + state.currentNodeIsNew = false + state.errors = [] + return state }) } export const newIndex = (store, useRoot) => () => { - store.update(s => { - s.currentNodeIsNew = true - s.errors = [] - const shadowHierarchy = createShadowHierarchy(s.hierarchy) + store.update(state => { + state.currentNodeIsNew = true + state.errors = [] + const shadowHierarchy = createShadowHierarchy(state.hierarchy) const parent = useRoot ? shadowHierarchy - : getNode(shadowHierarchy, s.currentNode.nodeId) + : getNode(shadowHierarchy, state.currentNode.nodeId) - s.currentNode = templateApi(shadowHierarchy).getNewIndexTemplate(parent) - return s + state.currentNode = templateApi(shadowHierarchy).getNewIndexTemplate(parent) + return state }) } -// TODO: ONLY SEEMS TO BE CALLED BY THE BACKEND export const saveCurrentNode = store => () => { - store.update(s => { - const errors = validate.node(s.currentNode) - s.errors = errors - if (errors.length > 0) { - return s + store.update(state => { + const errors = validate.node(state.currentNode) + state.errors = errors + if (errorstate.length > 0) { + return state } - const parentNode = getNode(s.hierarchy, s.currentNode.parent().nodeId) + const parentNode = getNode(state.hierarchy, state.currentNode.parent().nodeId) - const existingNode = getNode(s.hierarchy, s.currentNode.nodeId) + const existingNode = getNode(state.hierarchy, state.currentNode.nodeId) let index = parentNode.children.length if (existingNode) { @@ -93,8 +132,8 @@ export const saveCurrentNode = store => () => { } // should add node into existing hierarchy - const cloned = cloneDeep(s.currentNode) - templateApi(s.hierarchy).constructNode(parentNode, cloned) + const cloned = cloneDeep(state.currentNode) + templateApi(state.hierarchy).constructNode(parentNode, cloned) const newIndexOfChild = child => { if (child === cloned) return index @@ -104,29 +143,29 @@ export const saveCurrentNode = store => () => { parentNode.children = pipe(parentNode.children, [sortBy(newIndexOfChild)]) - if (!existingNode && s.currentNode.type === "record") { - const defaultIndex = templateApi(s.hierarchy).getNewIndexTemplate( + if (!existingNode && state.currentNode.type === "record") { + const defaultIndex = templateApi(state.hierarchy).getNewIndexTemplate( cloned.parent() ) defaultIndex.name = `all_${cloned.collectionName}` defaultIndex.allowedRecordNodeIds = [cloned.nodeId] } - s.currentNodeIsNew = false + state.currentNodeIsNew = false - saveBackend(s) + saveBackend(state) - return s + return state }) } export const deleteCurrentNode = store => () => { - store.update(s => { - const nodeToDelete = getNode(s.hierarchy, s.currentNode.nodeId) - s.currentNode = hierarchyFunctions.isRoot(nodeToDelete.parent()) - ? find(n => n != s.currentNode)(s.hierarchy.children) + store.update(state => { + const nodeToDelete = getNode(state.hierarchy, state.currentNode.nodeId) + state.currentNode = hierarchyFunctionstate.isRoot(nodeToDelete.parent()) + ? find(n => n != state.currentNode)(state.hierarchy.children) : nodeToDelete.parent() - if (hierarchyFunctions.isRecord(nodeToDelete)) { + if (hierarchyFunctionstate.isRecord(nodeToDelete)) { nodeToDelete.parent().children = filter( c => c.nodeId !== nodeToDelete.nodeId )(nodeToDelete.parent().children) @@ -135,9 +174,9 @@ export const deleteCurrentNode = store => () => { c => c.nodeId !== nodeToDelete.nodeId )(nodeToDelete.parent().indexes) } - s.errors = [] - saveBackend(s) - return s + state.errors = [] + saveBackend(state) + return state }) } @@ -160,4 +199,41 @@ export const deleteField = databaseStore => field => { return db }) +} + +const incrementAccessLevelsVersion = state => + (state.accessLevelstate.version = (state.accessLevelstate.version || 0) + 1) + +export const saveLevel = store => (newLevel, isNew, oldLevel = null) => { + store.update(state => { + const levels = state.accessLevelstate.levels + + const existingLevel = isNew + ? null + : find(a => a.name === oldLevel.name)(levels) + + if (existingLevel) { + state.accessLevelstate.levels = pipe(levels, [ + map(a => (a === existingLevel ? newLevel : a)), + ]) + } else { + state.accessLevelstate.levelstate.push(newLevel) + } + + incrementAccessLevelsVersion(s) + + saveBackend(state) + return state + }) +} + +export const deleteLevel = store => level => { + store.update(state => { + state.accessLevelstate.levels = filter(t => t.name !== level.name)( + state.accessLevelstate.levels + ) + incrementAccessLevelsVersion(s) + saveBackend(state) + return state + }) } \ No newline at end of file diff --git a/packages/builder/src/builderStore/store/index.js b/packages/builder/src/builderStore/store/index.js index 381b26164b..5bf35f7770 100644 --- a/packages/builder/src/builderStore/store/index.js +++ b/packages/builder/src/builderStore/store/index.js @@ -65,61 +65,6 @@ export const getStore = () => { const store = writable(initial) - // store.api = { - // appDefinition: { - // create: () => {}, - // }, - // records: { - // create: () => {}, - // update: () => {}, - // delete: () => {}, - // }, - // indexes: { - // create: () => {}, - // update: () => {}, - // delete: () => {}, - // }, - // pages: { - // create: () => {}, - // update: () => {}, - // delete: () => {}, - // }, - // screens: { - // create: () => {}, - // select: () => {}, - // rename: () => {} - // }, - // accessLevels: { - // create: () => {}, - // update: () => {}, - // delete: () => {}, - // }, - // users: { - // create: () => {}, - // update: () => {}, - // delete: () => {}, - // }, - // actions: { - // update: () => {}, - // delete: () => {} - // }, - // triggers: { - // create: () => {}, - // update: () => {}, - // delete: () => {}, - // }, - // stylesheets: { - // create: () => {}, - // update: () => {}, - // delete: () => {}, - // }, - // components: { - // create: () => {}, - // update: () => {}, - // delete: () => {}, - // } - // } - store.initialise = initialise(store, initial) store.newChildRecord = backendStoreActions.newRecord(store, false) @@ -131,14 +76,14 @@ export const getStore = () => { store.deleteCurrentNode = backendStoreActions.deleteCurrentNode(store) store.saveField = backendStoreActions.saveField(store) store.deleteField = backendStoreActions.deleteField(store) + store.saveLevel = backendStoreActions.saveLevel(store) + store.deleteLevel = backendStoreActions.deleteLevel(store) store.importAppDefinition = importAppDefinition(store) store.saveAction = saveAction(store) store.deleteAction = deleteAction(store) store.saveTrigger = saveTrigger(store) store.deleteTrigger = deleteTrigger(store) - store.saveLevel = saveLevel(store) - store.deleteLevel = deleteLevel(store) store.saveScreen = saveScreen(store) store.addComponentLibrary = addComponentLibrary(store) store.renameScreen = renameScreen(store) @@ -319,43 +264,6 @@ const deleteTrigger = store => trigger => { }) } -const incrementAccessLevelsVersion = s => - (s.accessLevels.version = (s.accessLevels.version || 0) + 1) - -const saveLevel = store => (newLevel, isNew, oldLevel = null) => { - store.update(s => { - const levels = s.accessLevels.levels - - const existingLevel = isNew - ? null - : find(a => a.name === oldLevel.name)(levels) - - if (existingLevel) { - s.accessLevels.levels = pipe(levels, [ - map(a => (a === existingLevel ? newLevel : a)), - ]) - } else { - s.accessLevels.levels.push(newLevel) - } - - incrementAccessLevelsVersion(s) - - saveBackend(s) - return s - }) -} - -const deleteLevel = store => level => { - store.update(s => { - s.accessLevels.levels = filter(t => t.name !== level.name)( - s.accessLevels.levels - ) - incrementAccessLevelsVersion(s) - saveBackend(s) - return s - }) -} - const createShadowHierarchy = hierarchy => constructHierarchy(JSON.parse(JSON.stringify(hierarchy))) diff --git a/packages/builder/src/common/Modal.svelte b/packages/builder/src/common/Modal.svelte index 09aac1a8bb..ceeae22aa5 100644 --- a/packages/builder/src/common/Modal.svelte +++ b/packages/builder/src/common/Modal.svelte @@ -3,7 +3,7 @@ import ActionButton from "../common/ActionButton.svelte" export let isOpen = false - export let onClosed = () => {} + export let onClosed export let id = "" export let title @@ -27,19 +27,21 @@
-
- {#if title} -
-

{title}

-
- {/if} -
- {#if onClosed} -
-
+ {/if} diff --git a/packages/builder/src/database/HierarchyRow.svelte b/packages/builder/src/database/HierarchyRow.svelte deleted file mode 100644 index 8523839227..0000000000 --- a/packages/builder/src/database/HierarchyRow.svelte +++ /dev/null @@ -1,42 +0,0 @@ - - -
-
store.selectExistingNode(node.nodeId)} - style="padding-left: {20 + level * 20}px"> - {node.name} -
- {#if node.children} - {#each node.children as child} - - {/each} - {/if} -
- - diff --git a/packages/builder/src/database/ModelDataTable/ModelDataTable.svelte b/packages/builder/src/database/ModelDataTable/ModelDataTable.svelte index 80c764c18f..a442da0792 100644 --- a/packages/builder/src/database/ModelDataTable/ModelDataTable.svelte +++ b/packages/builder/src/database/ModelDataTable/ModelDataTable.svelte @@ -1,6 +1,6 @@ - +
@@ -46,7 +54,6 @@ icon="ri-eye-line" on:change={e => fetchRecordsForView(e.target.value)}> {#each views as view} - {/each} @@ -62,7 +69,7 @@ {#each data as row} - +
@@ -78,8 +85,8 @@
  • { - deleteRecordModal = true selectedRecord = row + backendUiStore.actions.modals.show("DELETE_RECORD") }}> Delete
    @@ -98,7 +105,7 @@ {/each} - +
  • \ No newline at end of file + diff --git a/packages/builder/src/database/ModelDataTable/api.js b/packages/builder/src/database/ModelDataTable/api.js index 6d6ed0be35..5848bbaab0 100644 --- a/packages/builder/src/database/ModelDataTable/api.js +++ b/packages/builder/src/database/ModelDataTable/api.js @@ -2,18 +2,27 @@ import { getNewRecord } from "../../common/core" export async function deleteRecord(record, { appname, instanceId }) { - const DELETE_RECORDS_URL = `/_builder/instance/${appname}/${instanceId}/api/record/${record.name}/${record.id}` - const response = await api.delete({ - url: DELETE_RECORDS_URL - }); + const DELETE_RECORDS_URL = `/_builder/instance/${appname}/${instanceId}/api/record${record.key}` + const response = await api.delete(DELETE_RECORDS_URL); return response; } export async function saveRecord(record, { appname, instanceId }) { - const SAVE_RECORDS_URL = `/_builder/instance/${appname}/${instanceId}/api/record` - const updatedRecord = getNewRecord(record, "") - const response = await api.post(SAVE_RECORDS_URL, updatedRecord) - return response + let recordBase = { ...record } + + // brand new record + 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] + } + } + + 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 }) { diff --git a/packages/builder/src/database/ModelDataTable/modals/CreateDatabase.svelte b/packages/builder/src/database/ModelDataTable/modals/CreateDatabase.svelte new file mode 100644 index 0000000000..9b8ef77b1d --- /dev/null +++ b/packages/builder/src/database/ModelDataTable/modals/CreateDatabase.svelte @@ -0,0 +1,17 @@ + + + + CREATE A NEW DATABASE FROM HERE +
    + Cancel + Save +
    +
    diff --git a/packages/builder/src/database/ModelDataTable/modals/CreateEditField.svelte b/packages/builder/src/database/ModelDataTable/modals/CreateEditField.svelte index 695a0b1903..dd8fbf5123 100644 --- a/packages/builder/src/database/ModelDataTable/modals/CreateEditField.svelte +++ b/packages/builder/src/database/ModelDataTable/modals/CreateEditField.svelte @@ -10,7 +10,7 @@ const onClosed = () => (modalOpen = false) - +
    Cancel diff --git a/packages/builder/src/database/ModelDataTable/modals/CreateEditModel.svelte b/packages/builder/src/database/ModelDataTable/modals/CreateEditModel.svelte index 9cd993a30d..16f88c9395 100644 --- a/packages/builder/src/database/ModelDataTable/modals/CreateEditModel.svelte +++ b/packages/builder/src/database/ModelDataTable/modals/CreateEditModel.svelte @@ -1,27 +1,22 @@ - -

    Create / Edit Model

    + +

    + + Create / Edit Model +

    -
    diff --git a/packages/builder/src/database/ModelDataTable/modals/CreateEditRecord.svelte b/packages/builder/src/database/ModelDataTable/modals/CreateEditRecord.svelte index 1f58658497..c79e1ebc02 100644 --- a/packages/builder/src/database/ModelDataTable/modals/CreateEditRecord.svelte +++ b/packages/builder/src/database/ModelDataTable/modals/CreateEditRecord.svelte @@ -1,13 +1,15 @@

    Create / Edit Record

    - {console.log('record', record)} - {console.log('selectedModel', selectedModel)} - {console.log('recordFields', recordFields)}
    {#if !record}
    @@ -70,7 +68,14 @@ Cancel api.saveRecord(record || selectedModel, currentAppInfo)}> + on:click={async () => { + const recordResponse = await api.saveRecord(record || selectedModel, currentAppInfo) + backendUiStore.update(state => { + state.selectedView.records.push(recordResponse) + return state + }) + onClosed() + }}> Save
    diff --git a/packages/builder/src/database/ModelDataTable/modals/CreateEditView.svelte b/packages/builder/src/database/ModelDataTable/modals/CreateEditView.svelte index 6e9449149b..09b88faf6d 100644 --- a/packages/builder/src/database/ModelDataTable/modals/CreateEditView.svelte +++ b/packages/builder/src/database/ModelDataTable/modals/CreateEditView.svelte @@ -1,23 +1,25 @@ - + + + -
    + diff --git a/packages/builder/src/database/ModelDataTable/modals/DeleteRecord.svelte b/packages/builder/src/database/ModelDataTable/modals/DeleteRecord.svelte index 8dd8cc35aa..86ec8f0bc4 100644 --- a/packages/builder/src/database/ModelDataTable/modals/DeleteRecord.svelte +++ b/packages/builder/src/database/ModelDataTable/modals/DeleteRecord.svelte @@ -1,15 +1,24 @@ - +

    Delete Record

    Are you sure you want to delete this record? All of your data will be permanently removed. This action cannot be undone.