formatting

This commit is contained in:
Martin McKeaveney 2020-03-27 16:58:32 +00:00
parent ff73793b4c
commit f82a954666
77 changed files with 629 additions and 634 deletions

View File

@ -107,7 +107,7 @@ const lodash_fp_exports = [
"findIndex",
"compose",
"get",
"tap"
"tap",
]
const lodash_exports = [
@ -164,7 +164,9 @@ export default {
}),
replace({
"process.env.NODE_ENV": JSON.stringify(production ? "production" : "development")
"process.env.NODE_ENV": JSON.stringify(
production ? "production" : "development"
),
}),
svelte({

View File

@ -12,7 +12,6 @@
}
let selectedTab = TABS.BACKEND
</script>
<div class="root">
@ -28,13 +27,13 @@
<span
class:active={selectedTab === TABS.BACKEND}
class="topnavitem"
on:click={() => selectedTab = TABS.BACKEND}>
on:click={() => (selectedTab = TABS.BACKEND)}>
Backend
</span>
<span
class:active={selectedTab === TABS.FRONTEND}
class="topnavitem"
on:click={() => selectedTab = TABS.FRONTEND}>
on:click={() => (selectedTab = TABS.FRONTEND)}>
Frontend
</span>
</div>

View File

@ -15,7 +15,7 @@
backendUiStore.actions.modals.show("ACCESS_LEVELS")
}
}
$: modalOpen = $backendUiStore.visibleModal === 'ACCESS_LEVELS'
$: modalOpen = $backendUiStore.visibleModal === "ACCESS_LEVELS"
let allPermissions = []
store.subscribe(db => {
@ -99,8 +99,7 @@
isNew={editingLevelIsNew}
allLevels={$store.accessLevels.levels}
hierarchy={$store.hierarchy}
actions={$store.actions}
/>
actions={$store.actions} />
</Modal>
</div>

View File

@ -39,7 +39,7 @@ const css_map = {
},
direction: {
name: "flex-direction",
generate: self
generate: self,
},
gridarea: {
name: "grid-area",
@ -113,7 +113,7 @@ const object_to_css_string = [
export const generate_css = ({ layout, position }) => {
let _layout = pipe(layout, object_to_css_string)
if (_layout.length) {
_layout += `\ndisplay: ${_layout.includes("flex") ? "flex" : "grid"};`;
_layout += `\ndisplay: ${_layout.includes("flex") ? "flex" : "grid"};`
}
return {

View File

@ -1,6 +1,6 @@
import { getStore } from "./store"
import { getBackendUiStore } from "./store/backend"
import LogRocket from "logrocket";
import LogRocket from "logrocket"
export const store = getStore()
export const backendUiStore = getBackendUiStore()
@ -8,7 +8,7 @@ export const backendUiStore = getBackendUiStore()
export const initialise = async () => {
try {
if (process.env.NODE_ENV === "production") {
LogRocket.init("knlald/budibase");
LogRocket.init("knlald/budibase")
}
setupRouter(store)
await store.initialise()

View File

@ -1,11 +1,6 @@
import { writable } from "svelte/store";
import { writable } from "svelte/store"
import api from "../api"
import {
cloneDeep,
sortBy,
find,
remove
} from "lodash/fp"
import { cloneDeep, sortBy, find, remove } from "lodash/fp"
import { hierarchy as hierarchyFunctions } from "../../../../core/src"
import {
getNode,
@ -14,7 +9,7 @@ import {
templateApi,
isIndex,
canDeleteIndex,
canDeleteRecord
canDeleteRecord,
} from "../../common/core"
export const getBackendUiStore = () => {
@ -22,7 +17,7 @@ export const getBackendUiStore = () => {
leftNavItem: "DATABASE",
selectedView: {
records: [],
name: ""
name: "",
},
breadcrumbs: [],
selectedDatabase: {},
@ -34,50 +29,57 @@ export const getBackendUiStore = () => {
store.actions = {
navigate: name => store.update(state => ({ ...state, leftNavItem: name })),
database: {
select: db => store.update(state => {
select: db =>
store.update(state => {
state.selectedDatabase = db
state.breadcrumbs = [db.name]
return state
})
}),
},
records: {
delete: () => store.update(state => {
delete: () =>
store.update(state => {
state.selectedView = state.selectedView
return state
}),
view: record => store.update(state => {
view: record =>
store.update(state => {
state.breadcrumbs = [state.selectedDatabase.name, record.id]
return state
}),
select: record => store.update(state => {
select: record =>
store.update(state => {
state.selectedRecord = record
return state
})
}),
},
views: {
select: view => store.update(state => {
select: view =>
store.update(state => {
state.selectedView = view
return state
})
}),
},
modals: {
show: modal => store.update(state => ({ ...state, visibleModal: modal })),
hide: () => store.update(state => ({ ...state, visibleModal: null }))
hide: () => store.update(state => ({ ...state, visibleModal: null })),
},
users: {
create: user => store.update(state => {
create: user =>
store.update(state => {
state.users.push(user)
state.users = state.users
return state
})
}
}),
},
}
return store
};
}
// Store Actions
export const createShadowHierarchy = hierarchy => constructHierarchy(JSON.parse(JSON.stringify(hierarchy)))
export const createShadowHierarchy = hierarchy =>
constructHierarchy(JSON.parse(JSON.stringify(hierarchy)))
export const createDatabaseForApp = store => appInstance => {
store.update(state => {
@ -244,7 +246,9 @@ export const deleteCurrentNode = store => () => {
export const saveField = store => field => {
store.update(state => {
state.currentNode.fields = state.currentNode.fields.filter(f => f.id !== field.id)
state.currentNode.fields = state.currentNode.fields.filter(
f => f.id !== field.id
)
templateApi(state.hierarchy).addField(state.currentNode, field)
return state
@ -253,13 +257,17 @@ export const saveField = store => field => {
export const deleteField = store => field => {
store.update(state => {
state.currentNode.fields = state.currentNode.fields.filter(f => f.name !== field.name)
state.currentNode.fields = state.currentNode.fields.filter(
f => f.name !== field.name
)
return state
})
}
const incrementAccessLevelsVersion = state => {
state.accessLevels.version = state.accessLevels.version ? state.accessLevels.version + 1 : 1
state.accessLevels.version = state.accessLevels.version
? state.accessLevels.version + 1
: 1
return state
}
@ -272,7 +280,9 @@ export const saveLevel = store => (newLevel, isNew, oldLevel = null) => {
: find(a => a.name === oldLevel.name)(levels)
if (existingLevel) {
state.accessLevels.levels = levels.map(level => level === existingLevel ? newLevel : level)
state.accessLevels.levels = levels.map(level =>
level === existingLevel ? newLevel : level
)
} else {
state.accessLevels.levels.push(newLevel)
}
@ -286,7 +296,9 @@ export const saveLevel = store => (newLevel, isNew, oldLevel = null) => {
export const deleteLevel = store => level => {
store.update(state => {
state.accessLevels.levels = state.accessLevels.levels.filter(t => t.name !== level.name)
state.accessLevels.levels = state.accessLevels.levels.filter(
t => t.name !== level.name
)
incrementAccessLevelsVersion(s)
saveBackend(state)
return state
@ -300,7 +312,9 @@ export const saveAction = store => (newAction, isNew, oldAction = null) => {
: find(a => a.name === oldAction.name)(s.actions)
if (existingAction) {
s.actions = s.actions.map(action => action === existingAction ? newAction : action)
s.actions = s.actions.map(action =>
action === existingAction ? newAction : action
)
} else {
s.actions.push(newAction)
}
@ -311,9 +325,9 @@ export const saveAction = store => (newAction, isNew, oldAction = null) => {
export const deleteAction = store => action => {
store.update(state => {
state.actions = state.actions.filter(a => a.name !== action.name);
saveBackend(state);
return state;
state.actions = state.actions.filter(a => a.name !== action.name)
saveBackend(state)
return state
})
}

View File

@ -1,17 +1,6 @@
import {
filter,
cloneDeep,
last,
concat,
isEmpty,
values,
} from "lodash/fp"
import {
pipe,
getNode,
constructHierarchy,
} from "../../common/core"
import * as backendStoreActions from "./backend";
import { filter, cloneDeep, last, concat, isEmpty, values } from "lodash/fp"
import { pipe, getNode, constructHierarchy } from "../../common/core"
import * as backendStoreActions from "./backend"
import { writable } from "svelte/store"
import { defaultPagesObject } from "../../userInterface/pagesParsing/defaultPagesObject"
import api from "../api"
@ -224,20 +213,19 @@ const _saveScreen = async (store, s, screen) => {
screen
)
.then(() => {
if (currentPageScreens.includes(screen)) return
const screens = [
...currentPageScreens,
screen,
]
const screens = [...currentPageScreens, screen]
store.update(innerState => {
innerState.pages[s.currentPageName]._screens = screens
innerState.screens = screens
innerState.currentPreviewItem = screen
const safeProps = makePropsSafe(
getComponentDefinition(innerState.components, screen.props._component),
getComponentDefinition(
innerState.components,
screen.props._component
),
screen.props
)
innerState.currentComponentInfo = safeProps
@ -246,7 +234,6 @@ const _saveScreen = async (store, s, screen) => {
_savePage(innerState)
return innerState
})
})
return s
@ -544,7 +531,9 @@ const addTemplatedComponent = store => props => {
state.currentComponentInfo._children = state.currentComponentInfo._children.concat(
props
)
state.currentPreviewItem._css = generate_screen_css([state.currentPreviewItem.props])
state.currentPreviewItem._css = generate_screen_css([
state.currentPreviewItem.props,
])
setCurrentPageFunctions(state)
_saveCurrentPreviewItem(state)

View File

@ -53,7 +53,6 @@
</div>
<style>
.uk-modal-footer {
background: var(--lightslate);
}
@ -62,5 +61,4 @@
width: 400px;
border-radius: 5px;
}
</style>

View File

@ -7,12 +7,7 @@
{#if hasErrors}
<div uk-alert class="uk-alert-danger">
{#each errors as error}
<div>
{error.field ? `${error.field}: ` : ''}{error.error}
</div>
<div>{error.field ? `${error.field}: ` : ''}{error.error}</div>
{/each}
</div>
{/if}

View File

@ -4,6 +4,9 @@
width="24"
height="24">
<path fill="none" d="M0 0h24v24H0z" />
<path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zM10.622 8.415a.4.4 0 00-.622.332v6.506a.4.4 0 00.622.332l4.879-3.252a.4.4 0 000-.666l-4.88-3.252z"
<path
d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10
10zM10.622 8.415a.4.4 0 00-.622.332v6.506a.4.4 0 00.622.332l4.879-3.252a.4.4
0 000-.666l-4.88-3.252z"
fill="currentColor" />
</svg>

Before

Width:  |  Height:  |  Size: 349 B

After

Width:  |  Height:  |  Size: 362 B

View File

@ -4,5 +4,8 @@
width="24"
height="24">
<path d="M0 0h24v24H0z" fill="none" />
<path d="M12 1l9.5 5.5v11L12 23l-9.5-5.5v-11L12 1zm0 14a3 3 0 1 0 0-6 3 3 0 0 0 0 6z" fill="currentColor"/>
<path
d="M12 1l9.5 5.5v11L12 23l-9.5-5.5v-11L12 1zm0 14a3 3 0 1 0 0-6 3 3 0 0 0 0
6z"
fill="currentColor" />
</svg>

Before

Width:  |  Height:  |  Size: 244 B

After

Width:  |  Height:  |  Size: 263 B

View File

@ -18,4 +18,3 @@ export { default as AddIcon } from "./Add.svelte"
export { default as JavaScriptIcon } from "./JavaScript.svelte"
export { default as PreviewIcon } from "./Preview.svelte"
export { default as SettingsIcon } from "./Settings.svelte"

View File

@ -24,7 +24,6 @@
}
}
}
</script>
<div bind:this={ukModal} uk-modal {id}>

View File

@ -9,10 +9,7 @@
{#if icon}
<i class={icon} />
{/if}
<select
class:adjusted={icon}
on:change bind:value
>
<select class:adjusted={icon} on:change bind:value>
<slot />
</select>
<span class="arrow">

View File

@ -21,9 +21,7 @@
<div class="root">
<div class="button-container">
{#if !$store.currentNodeIsNew}
<ActionButton alert on:click={deleteCurrentNode}>
Delete
</ActionButton>
<ActionButton alert on:click={deleteCurrentNode}>Delete</ActionButton>
{/if}
<ActionButton color="secondary" on:click={store.saveCurrentNode}>

View File

@ -15,7 +15,7 @@
CreateEditViewModal,
CreateDatabaseModal,
DeleteRecordModal,
CreateUserModal
CreateUserModal,
} from "./ModelDataTable/modals"
let selectedRecord
@ -64,9 +64,7 @@
<div class="root">
<div class="node-view">
<div class="database-actions">
<div class="budibase__label--big">
{breadcrumbs}
</div>
<div class="budibase__label--big">{breadcrumbs}</div>
{#if $backendUiStore.selectedDatabase.id}
<ActionButton
primary
@ -80,9 +78,7 @@
</div>
{#if $backendUiStore.selectedDatabase.id}
<ModelDataTable {selectRecord} />
{:else}
Please select a database
{/if}
{:else}Please select a database{/if}
</div>
</div>

View File

@ -10,7 +10,7 @@
flatten,
map,
remove,
keys
keys,
} from "lodash/fp"
import Select from "../../common/Select.svelte"
import { getIndexSchema } from "../../common/core"
@ -23,13 +23,7 @@
const ITEMS_PER_PAGE = 10
// Internal headers we want to hide from the user
const INTERNAL_HEADERS = [
"key",
"sortKey",
"type",
"id",
"isNew"
]
const INTERNAL_HEADERS = ["key", "sortKey", "type", "id", "isNew"]
let modalOpen = false
let data = []
@ -61,11 +55,7 @@
const getSchema = getIndexSchema($store.hierarchy)
const childViewsForRecord = compose(
flatten,
map("indexes"),
get("children")
)
const childViewsForRecord = compose(flatten, map("indexes"), get("children"))
const hideInternalHeaders = compose(
remove(headerName => INTERNAL_HEADERS.includes(headerName)),

View File

@ -11,12 +11,12 @@
$: numPages = Math.ceil(data.length / ITEMS_PER_PAGE)
const next = () => {
if (currentPage + 1 === numPages) return;
if (currentPage + 1 === numPages) return
currentPage = currentPage + 1
}
const previous = () => {
if (currentPage == 0) return;
if (currentPage == 0) return
currentPage = currentPage - 1
}

View File

@ -5,7 +5,11 @@
import Modal from "../../../common/Modal.svelte"
import ActionButton from "../../../common/ActionButton.svelte"
import Select from "../../../common/Select.svelte"
import { getNewRecord, joinKey, getExactNodeForKey } from "../../../common/core"
import {
getNewRecord,
joinKey,
getExactNodeForKey,
} from "../../../common/core"
import RecordFieldControl from "./RecordFieldControl.svelte"
import * as api from "../api"
import ErrorsBox from "../../../common/ErrorsBox.svelte"
@ -15,11 +19,7 @@
let errors = []
const childModelsForModel = compose(
flatten,
map("children"),
get("children")
)
const childModelsForModel = compose(flatten, map("children"), get("children"))
$: currentAppInfo = {
appname: $store.appname,
@ -38,9 +38,7 @@
}
}
$: modelFields = selectedModel
? selectedModel.fields
: []
$: modelFields = selectedModel ? selectedModel.fields : []
function getCurrentCollectionKey(selectedRecord) {
return selectedRecord
@ -48,7 +46,13 @@
: joinKey(selectedModel.collectionName)
}
$: editingRecord = record || editingRecord || getNewRecord(selectedModel, getCurrentCollectionKey($backendUiStore.selectedRecord))
$: editingRecord =
record ||
editingRecord ||
getNewRecord(
selectedModel,
getCurrentCollectionKey($backendUiStore.selectedRecord)
)
function closed() {
editingRecord = null
@ -56,10 +60,7 @@
}
async function saveRecord() {
const recordResponse = await api.saveRecord(
editingRecord,
currentAppInfo
)
const recordResponse = await api.saveRecord(editingRecord, currentAppInfo)
backendUiStore.update(state => {
state.selectedView = state.selectedView
return state
@ -83,11 +84,8 @@
</Select>
</div>
{/if}
{#each (modelFields || []) as field}
<RecordFieldControl
record={editingRecord}
{field}
{errors} />
{#each modelFields || [] as field}
<RecordFieldControl record={editingRecord} {field} {errors} />
{/each}
</form>
<footer>

View File

@ -23,11 +23,7 @@
enabled: true,
temporaryAccessId: "",
}
const response = await api.createUser(
password,
user,
currentAppInfo
)
const response = await api.createUser(password, user, currentAppInfo)
backendUiStore.actions.users.save(user)
onClosed()
}

View File

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

View File

@ -6,22 +6,19 @@ export let field
export let errors
$: isDropdown =
field.type === "string"
&& field.typeOptions.values
&& field.typeOptions.values.length > 0
field.type === "string" &&
field.typeOptions.values &&
field.typeOptions.values.length > 0
$: isNumber = field.type === "number"
$: isText =
field.type === "string"
&& !isDropdown
$: isText = field.type === "string" && !isDropdown
$: isCheckbox = field.type === "bool"
$: isError = errors && errors.some(e => e.field && e.field === field.name)
$: isDatetime = field.type === "datetime"
</script>
<div class="uk-margin">
@ -31,7 +28,7 @@ $: isDatetime = field.type === "datetime"
<div class="uk-form-controls">
{#if isDropdown}
<Select bind:value={record[field.name]}>
<option value=""></option>
<option value="" />
{#each field.typeOptions.values as val}
<option value={val}>{val}</option>
{/each}
@ -61,7 +58,7 @@ $: isDatetime = field.type === "datetime"
class="uk-checkbox"
class:uk-form-danger={isError}
type="checkbox"
bind:checked={record[field.name]} >
bind:checked={record[field.name]} />
{field.label}
</label>
{/if}

View File

@ -1,6 +1,6 @@
export { default as DeleteRecordModal } from "./DeleteRecord.svelte";
export { default as CreateEditRecordModal } from "./CreateEditRecord.svelte";
export { default as CreateEditModelModal } from "./CreateEditModel.svelte";
export { default as CreateEditViewModal } from "./CreateEditView.svelte";
export { default as CreateDatabaseModal } from "./CreateDatabase.svelte";
export { default as CreateUserModal } from "./CreateUser.svelte";
export { default as DeleteRecordModal } from "./DeleteRecord.svelte"
export { default as CreateEditRecordModal } from "./CreateEditRecord.svelte"
export { default as CreateEditModelModal } from "./CreateEditModel.svelte"
export { default as CreateEditViewModal } from "./CreateEditView.svelte"
export { default as CreateDatabaseModal } from "./CreateDatabase.svelte"
export { default as CreateUserModal } from "./CreateUser.svelte"

View File

@ -39,10 +39,8 @@
$: models = $store.hierarchy.children
$: parent = record && record.parent()
$: isChildModel = parent && parent.name !== "root"
$: modelExistsInHierarchy = $store.currentNode && getNode(
$store.hierarchy,
$store.currentNode.nodeId
)
$: modelExistsInHierarchy =
$store.currentNode && getNode($store.hierarchy, $store.currentNode.nodeId)
store.subscribe($store => {
record = $store.currentNode

View File

@ -15,5 +15,5 @@ import "codemirror/theme/monokai.css"
/* eslint-disable */
const app = new App({
target: document.getElementById("app")
target: document.getElementById("app"),
})

View File

@ -32,8 +32,7 @@
<div class="hierarchy-title">Users</div>
<i
class="ri-add-line hoverable"
on:click={() => backendUiStore.actions.modals.show('USER')}
/>
on:click={() => backendUiStore.actions.modals.show('USER')} />
</div>
</div>

View File

@ -1,5 +1,5 @@
<script>
import { tick } from "svelte";
import { tick } from "svelte"
import { store, backendUiStore } from "../builderStore"
import getIcon from "../common/icon"
import { CheckIcon } from "../common/Icons"

View File

@ -1,6 +1,6 @@
<script>
import getIcon from "../common/icon"
import { backendUiStore } from "../builderStore";
import { backendUiStore } from "../builderStore"
export let name = ""
export let label = ""

View File

@ -30,16 +30,8 @@
<i class="ri-add-line hoverable" />
<div uk-dropdown="mode: click;">
<ul class="uk-nav uk-dropdown-nav">
<li
class="hoverable"
on:click={newModel}>
Model
</li>
<li
class="hoverable"
on:click={newView}>
View
</li>
<li class="hoverable" on:click={newModel}>Model</li>
<li class="hoverable" on:click={newView}>View</li>
</ul>
</div>
</div>

View File

@ -1,7 +1,7 @@
<script>
import { onMount } from "svelte"
import { store, backendUiStore } from "../builderStore"
import api from "../builderStore/api";
import api from "../builderStore/api"
import getIcon from "../common/icon"
import { CheckIcon } from "../common/Icons"
@ -14,12 +14,12 @@
$: currentAppInfo = {
appname: $store.appname,
instanceId: $backendUiStore.selectedDatabase.id
instanceId: $backendUiStore.selectedDatabase.id,
}
async function fetchUsers() {
const FETCH_USERS_URL = `/_builder/instance/${currentAppInfo.appname}/${currentAppInfo.instanceId}/api/users`
const response = await api.get(FETCH_USERS_URL);
const response = await api.get(FETCH_USERS_URL)
users = await response.json()
backendUiStore.update(state => {
state.users = users
@ -35,7 +35,9 @@
{#each users as user}
<li>
<i class="ri-user-4-line" />
<button class:active={user.id === $store.currentUserId}>{user.name}</button>
<button class:active={user.id === $store.currentUserId}>
{user.name}
</button>
</li>
{/each}
</ul>

View File

@ -178,8 +178,6 @@
height: 48px;
}
li button {
width: 48px;
height: 48px;

View File

@ -35,16 +35,13 @@
$: templatesByComponent = groupBy(t => t.component)($store.templates)
$: hierarchy = $store.hierarchy
$: libraryModules = $store.libraries
$: standaloneTemplates = pipe(
templatesByComponent,
[
$: standaloneTemplates = pipe(templatesByComponent, [
values,
flatten,
filter(t => !$store.components.some(c => c.name === t.component)),
map(t => ({ name: splitName(t.component).componentName, template: t })),
uniqBy(t => t.name),
]
)
])
const addRootComponent = (component, allComponents) => {
const { libName } = splitName(component.name)

View File

@ -1,6 +1,6 @@
<script>
import InputGroup from "../common/Inputs/InputGroup.svelte"
import LayoutTemplateControls from "./LayoutTemplateControls.svelte";
import LayoutTemplateControls from "./LayoutTemplateControls.svelte"
export let onStyleChanged = () => {}
export let component
@ -65,8 +65,7 @@
propertyName={name}
{meta}
{size}
type="text"
/>
type="text" />
</div>
{/each}
</div>

View File

@ -115,9 +115,7 @@
bind:value={layoutComponent}
class:uk-form-danger={saveAttempted && !layoutComponent}>
{#each layoutComponents as comp}
<option value={comp}>
{comp.componentName} - {comp.libName}
</option>
<option value={comp}>{comp.componentName} - {comp.libName}</option>
{/each}
</select>
</div>
@ -127,7 +125,6 @@
</ConfirmDialog>
<style>
.uk-margin {
display: flex;
flex-direction: column;
@ -156,6 +153,4 @@
border: 1px solid var(--slate);
border-radius: 3px;
}
</style>

View File

@ -110,7 +110,6 @@
padding: 0;
}
.root {
display: grid;
grid-template-columns: 275px 1fr 275px;

View File

@ -15,9 +15,12 @@ export const bbFactory = ({
}) => {
const relativeUrl = url => {
if (!frontendDefinition.appRootPath) return url
if (url.startsWith("http:")
|| url.startsWith("https:")
|| url.startsWith("./")) return url
if (
url.startsWith("http:") ||
url.startsWith("https:") ||
url.startsWith("./")
)
return url
return frontendDefinition.appRootPath + "/" + trimSlash(url)
}

View File

@ -21,25 +21,25 @@ export const initialiseData = async (
applicationDefinition,
accessLevels
) => {
if (!await datastore.exists(configFolder))
if (!(await datastore.exists(configFolder)))
await datastore.createFolder(configFolder)
if (!await datastore.exists(appDefinitionFile))
if (!(await datastore.exists(appDefinitionFile)))
await datastore.createJson(appDefinitionFile, applicationDefinition)
await initialiseRootCollections(datastore, applicationDefinition.hierarchy)
await initialiseRootIndexes(datastore, applicationDefinition.hierarchy)
if (!await datastore.exists(TRANSACTIONS_FOLDER))
if (!(await datastore.exists(TRANSACTIONS_FOLDER)))
await datastore.createFolder(TRANSACTIONS_FOLDER)
if (!await datastore.exists(AUTH_FOLDER))
if (!(await datastore.exists(AUTH_FOLDER)))
await datastore.createFolder(AUTH_FOLDER)
if (!await datastore.exists(USERS_LIST_FILE))
if (!(await datastore.exists(USERS_LIST_FILE)))
await datastore.createJson(USERS_LIST_FILE, [])
if (!await datastore.exists(ACCESS_LEVELS_FILE))
if (!(await datastore.exists(ACCESS_LEVELS_FILE)))
await datastore.createJson(
ACCESS_LEVELS_FILE,
accessLevels ? accessLevels : { version: 0, levels: [] }

View File

@ -1,9 +1,6 @@
import {
compileCode as cCode,
} from "@nx-js/compiler-util"
import { compileCode as cCode } from "@nx-js/compiler-util"
import { includes } from "lodash/fp"
export const compileCode = code => {
let func
let safeCode

View File

@ -140,5 +140,4 @@ const buildHeirarchalIndex = async (app, indexNode) => {
const recordNodeApplies = indexNode => recordNode =>
includes(recordNode.nodeId)(indexNode.allowedRecordNodeIds)
export default buildIndex

View File

@ -58,10 +58,9 @@ export const folderStructureArray = recordNode => {
export const getAllIdsIterator = app => async collection_Key_or_NodeKey => {
collection_Key_or_NodeKey = safeKey(collection_Key_or_NodeKey)
const recordNode = getCollectionNodeByKeyOrNodeKey(
app.hierarchy,
collection_Key_or_NodeKey
) || getNodeByKeyOrNodeKey(app.hierarchy, collection_Key_or_NodeKey)
const recordNode =
getCollectionNodeByKeyOrNodeKey(app.hierarchy, collection_Key_or_NodeKey) ||
getNodeByKeyOrNodeKey(app.hierarchy, collection_Key_or_NodeKey)
const getAllIdsIteratorForCollectionKey = async (
recordNode,

View File

@ -10,18 +10,18 @@ export const initialiseIndex = async (datastore, dir, index) => {
const indexDir = joinKey(dir, index.name)
let newDir = false
if (!await datastore.exists(indexDir)) {
if (!(await datastore.exists(indexDir))) {
await datastore.createFolder(indexDir)
newDir = true
}
if (isShardedIndex(index)) {
const shardFile = getShardMapKey(indexDir)
if (newDir || !await datastore.exists(shardFile))
if (newDir || !(await datastore.exists(shardFile)))
await datastore.createFile(shardFile, "[]")
} else {
const indexFile = getUnshardedIndexDataKey(indexDir)
if (newDir || !await datastore.exists(indexFile))
if (newDir || !(await datastore.exists(indexFile)))
await createIndexFile(datastore, indexFile, index)
}
}

View File

@ -3,7 +3,10 @@ import { promiseReadableStream } from "./promiseReadableStream"
import { createIndexFile } from "./sharding"
import { generateSchema } from "./indexSchemaCreator"
import { getIndexReader, CONTINUE_READING_RECORDS } from "./serializer"
import { getAllowedRecordNodesForIndex, getRecordNodeId } from "../templateApi/hierarchy"
import {
getAllowedRecordNodesForIndex,
getRecordNodeId,
} from "../templateApi/hierarchy"
import { $ } from "../common"
import { filter, includes, find } from "lodash/fp"

View File

@ -23,20 +23,19 @@ export const initialiseChildren = async (app, recordInfoOrKey) => {
}
export const initialiseChildrenForNode = async (app, recordNode) => {
if (isTopLevelRecord(recordNode)) {
await initialiseChildren(
app, recordNode.nodeKey())
await initialiseChildren(app, recordNode.nodeKey())
return
}
const iterate = await getAllIdsIterator(app)(recordNode.parent().collectionNodeKey())
const iterate = await getAllIdsIterator(app)(
recordNode.parent().collectionNodeKey()
)
let iterateResult = await iterate()
while (!iterateResult.done) {
const { result } = iterateResult
for (const id of result.ids) {
const initialisingRecordKey = joinKey(
result.collectionKey, id)
const initialisingRecordKey = joinKey(result.collectionKey, id)
await initialiseChildren(app, initialisingRecordKey)
}
iterateResult = await iterate()
@ -78,5 +77,3 @@ const fieldsThatReferenceThisRecord = (app, recordNode) =>
flatten,
filter(fieldReversesReferenceToNode(recordNode)),
])

View File

@ -2,16 +2,13 @@ import {
findRoot,
getFlattenedHierarchy,
fieldReversesReferenceToIndex,
isRecord
isRecord,
} from "./hierarchy"
import { $ } from "../common"
import { map, filter, reduce } from "lodash/fp"
export const canDeleteIndex = indexNode => {
const flatHierarchy = $(indexNode, [
findRoot,
getFlattenedHierarchy
])
const flatHierarchy = $(indexNode, [findRoot, getFlattenedHierarchy])
const reverseIndexes = $(flatHierarchy, [
filter(isRecord),
@ -23,30 +20,35 @@ export const canDeleteIndex = indexNode => {
}
return obj
}, []),
map(f => `field "${f.name}" on record "${f.record.name}" uses this index as a reference`)
map(
f =>
`field "${f.name}" on record "${f.record.name}" uses this index as a reference`
),
])
const lookupIndexes = $(flatHierarchy, [
filter(isRecord),
reduce((obj, r) => {
for (let field of r.fields) {
if (field.type === "reference"
&& field.typeOptions.indexNodeKey === indexNode.nodeKey()) {
if (
field.type === "reference" &&
field.typeOptions.indexNodeKey === indexNode.nodeKey()
) {
obj.push({ ...field, record: r })
}
}
return obj
}, []),
map(f => `field "${f.name}" on record "${f.record.name}" uses this index as a lookup`)
map(
f =>
`field "${f.name}" on record "${f.record.name}" uses this index as a lookup`
),
])
const errors = [
...reverseIndexes,
...lookupIndexes
]
const errors = [...reverseIndexes, ...lookupIndexes]
return {
canDelete: errors.length === 0,
errors
errors,
}
}

View File

@ -4,30 +4,30 @@ import {
fieldReversesReferenceToIndex,
isRecord,
isAncestorIndex,
isAncestor
isAncestor,
} from "./hierarchy"
import { $ } from "../common"
import { map, filter, includes } from "lodash/fp"
export const canDeleteRecord = recordNode => {
const flatHierarchy = $(recordNode, [
findRoot,
getFlattenedHierarchy
])
const flatHierarchy = $(recordNode, [findRoot, getFlattenedHierarchy])
const ancestors = $(flatHierarchy, [
filter(isAncestor(recordNode))
])
const ancestors = $(flatHierarchy, [filter(isAncestor(recordNode))])
const belongsToAncestor = i =>
ancestors.includes(i.parent())
const belongsToAncestor = i => ancestors.includes(i.parent())
const errorsForNode = node => {
const errorsThisNode = $(flatHierarchy, [
filter(i => isAncestorIndex(i)
&& belongsToAncestor(i)
&& includes(node.nodeId)(i.allowedRecordNodeIds)),
map(i => `index "${i.name}" indexes this record. Please remove the record from the index, or delete the index`)
filter(
i =>
isAncestorIndex(i) &&
belongsToAncestor(i) &&
includes(node.nodeId)(i.allowedRecordNodeIds)
),
map(
i =>
`index "${i.name}" indexes this record. Please remove the record from the index, or delete the index`
),
])
for (let child of node.children) {

View File

@ -4,7 +4,6 @@ import { isTopLevelIndex, getParentKey, getLastPartInKey } from "./hierarchy"
import { safeKey, joinKey } from "../common"
export const deleteAllIndexFilesForNode = async (app, indexNode) => {
if (isTopLevelIndex(indexNode)) {
await app.datastore.deleteFolder(indexNode.nodeKey())
return
@ -15,13 +14,11 @@ export const deleteAllIndexFilesForNode = async (app, indexNode) => {
while (!iterateResult.done) {
const { result } = iterateResult
for (const id of result.ids) {
const deletingIndexKey = joinKey(
result.collectionKey, id, indexNode.name)
const deletingIndexKey = joinKey(result.collectionKey, id, indexNode.name)
await deleteIndexFolder(app, deletingIndexKey)
}
iterateResult = await iterate()
}
}
const deleteIndexFolder = async (app, indexKey) => {
@ -29,6 +26,5 @@ const deleteIndexFolder = async (app, indexKey) => {
const indexName = getLastPartInKey(indexKey)
const parentRecordKey = getParentKey(indexKey)
const recordInfo = getRecordInfo(app.hierarchy, parentRecordKey)
await app.datastore.deleteFolder(
joinKey(recordInfo.dir, indexName))
await app.datastore.deleteFolder(joinKey(recordInfo.dir, indexName))
}

View File

@ -4,10 +4,8 @@ import { isTopLevelRecord, getCollectionKey } from "./hierarchy"
import { safeKey, joinKey } from "../common"
export const deleteAllRecordsForNode = async (app, recordNode) => {
if (isTopLevelRecord(recordNode)) {
await deleteRecordCollection(
app, recordNode.collectionName)
await deleteRecordCollection(app, recordNode.collectionName)
return
}
@ -17,16 +15,19 @@ export const deleteAllRecordsForNode = async (app, recordNode) => {
const { result } = iterateResult
for (const id of result.ids) {
const deletingCollectionKey = joinKey(
result.collectionKey, id, recordNode.collectionName)
result.collectionKey,
id,
recordNode.collectionName
)
await deleteRecordCollection(app, deletingCollectionKey)
}
iterateResult = await iterate()
}
}
const deleteRecordCollection = async (app, collectionKey) => {
collectionKey = safeKey(collectionKey)
await app.datastore.deleteFolder(
getCollectionDir(app.hierarchy, collectionKey))
getCollectionDir(app.hierarchy, collectionKey)
)
}

View File

@ -1,4 +1,9 @@
import { getFlattenedHierarchy, isRecord, isIndex, isAncestor } from "./hierarchy"
import {
getFlattenedHierarchy,
isRecord,
isIndex,
isAncestor,
} from "./hierarchy"
import { $, none } from "../common"
import { map, filter, some, find, difference } from "lodash/fp"
@ -25,7 +30,10 @@ export const diffHierarchy = (oldHierarchy, newHierarchy) => {
...deletedRecords,
...findRenamedRecords(oldHierarchyFlat, newHierarchyFlat),
...findRecordsWithFieldsChanged(oldHierarchyFlat, newHierarchyFlat),
...findRecordsWithEstimatedRecordTypeChanged(oldHierarchyFlat, newHierarchyFlat),
...findRecordsWithEstimatedRecordTypeChanged(
oldHierarchyFlat,
newHierarchyFlat
),
...findCreatedIndexes(oldHierarchyFlat, newHierarchyFlat, createdRecords),
...findDeletedIndexes(oldHierarchyFlat, newHierarchyFlat, deletedRecords),
...findUpdatedIndexes(oldHierarchyFlat, newHierarchyFlat),
@ -33,18 +41,20 @@ export const diffHierarchy = (oldHierarchy, newHierarchy) => {
}
const changeItem = (type, oldNode, newNode) => ({
type, oldNode, newNode,
type,
oldNode,
newNode,
})
const findCreatedRecords = (oldHierarchyFlat, newHierarchyFlat) => {
const allCreated = $(newHierarchyFlat, [
filter(isRecord),
filter(nodeDoesNotExistIn(oldHierarchyFlat)),
map(n => changeItem(HierarchyChangeTypes.recordCreated, null, n))
map(n => changeItem(HierarchyChangeTypes.recordCreated, null, n)),
])
return $(allCreated, [
filter(r => none(r2 => isAncestor(r.newNode)(r2.newNode))(allCreated))
filter(r => none(r2 => isAncestor(r.newNode)(r2.newNode))(allCreated)),
])
}
@ -52,11 +62,11 @@ const findDeletedRecords = (oldHierarchyFlat, newHierarchyFlat) => {
const allDeleted = $(oldHierarchyFlat, [
filter(isRecord),
filter(nodeDoesNotExistIn(newHierarchyFlat)),
map(n => changeItem(HierarchyChangeTypes.recordDeleted, n, null))
map(n => changeItem(HierarchyChangeTypes.recordDeleted, n, null)),
])
return $(allDeleted, [
filter(r => none(r2 => isAncestor(r.oldNode)(r2.oldNode))(allDeleted))
filter(r => none(r2 => isAncestor(r.oldNode)(r2.oldNode))(allDeleted)),
])
}
@ -64,12 +74,19 @@ const findRenamedRecords = (oldHierarchyFlat, newHierarchyFlat) =>
$(oldHierarchyFlat, [
filter(isRecord),
filter(nodeExistsIn(newHierarchyFlat)),
filter(nodeChanged(newHierarchyFlat, (_new,old) =>_new.collectionKey !== old.collectionKey )),
map(n => changeItem(
filter(
nodeChanged(
newHierarchyFlat,
(_new, old) => _new.collectionKey !== old.collectionKey
)
),
map(n =>
changeItem(
HierarchyChangeTypes.recordRenamed,
n,
findNodeIn(n, newHierarchyFlat))
findNodeIn(n, newHierarchyFlat)
)
),
])
const findRecordsWithFieldsChanged = (oldHierarchyFlat, newHierarchyFlat) =>
@ -77,64 +94,84 @@ const findRecordsWithFieldsChanged = (oldHierarchyFlat, newHierarchyFlat) =>
filter(isRecord),
filter(nodeExistsIn(newHierarchyFlat)),
filter(hasDifferentFields(newHierarchyFlat)),
map(n => changeItem(
map(n =>
changeItem(
HierarchyChangeTypes.recordFieldsChanged,
n,
findNodeIn(n, newHierarchyFlat))
findNodeIn(n, newHierarchyFlat)
)
),
])
const findRecordsWithEstimatedRecordTypeChanged = (oldHierarchyFlat, newHierarchyFlat) =>
const findRecordsWithEstimatedRecordTypeChanged = (
oldHierarchyFlat,
newHierarchyFlat
) =>
$(oldHierarchyFlat, [
filter(isRecord),
filter(nodeExistsIn(newHierarchyFlat)),
filter(nodeChanged(newHierarchyFlat, (_new,old) =>_new.estimatedRecordCount !== old.estimatedRecordCount)),
map(n => changeItem(
filter(
nodeChanged(
newHierarchyFlat,
(_new, old) => _new.estimatedRecordCount !== old.estimatedRecordCount
)
),
map(n =>
changeItem(
HierarchyChangeTypes.recordEstimatedRecordTypeChanged,
n,
findNodeIn(n, newHierarchyFlat))
findNodeIn(n, newHierarchyFlat)
)
),
])
const findCreatedIndexes = (oldHierarchyFlat, newHierarchyFlat, createdRecords) => {
const findCreatedIndexes = (
oldHierarchyFlat,
newHierarchyFlat,
createdRecords
) => {
const allCreated = $(newHierarchyFlat, [
filter(isIndex),
filter(nodeDoesNotExistIn(oldHierarchyFlat)),
map(n => changeItem(HierarchyChangeTypes.indexCreated, null, n))
map(n => changeItem(HierarchyChangeTypes.indexCreated, null, n)),
])
return $(allCreated, [
filter(r => none(r2 => isAncestor(r.newNode)(r2.newNode))(createdRecords))
filter(r => none(r2 => isAncestor(r.newNode)(r2.newNode))(createdRecords)),
])
}
const findDeletedIndexes = (oldHierarchyFlat, newHierarchyFlat, deletedRecords) => {
const findDeletedIndexes = (
oldHierarchyFlat,
newHierarchyFlat,
deletedRecords
) => {
const allDeleted = $(oldHierarchyFlat, [
filter(isIndex),
filter(nodeDoesNotExistIn(newHierarchyFlat)),
map(n => changeItem(HierarchyChangeTypes.indexDeleted, n, null))
map(n => changeItem(HierarchyChangeTypes.indexDeleted, n, null)),
])
return $(allDeleted, [
filter(r => none(r2 => isAncestor(r.oldNode)(r2.oldNode))(deletedRecords))
filter(r => none(r2 => isAncestor(r.oldNode)(r2.oldNode))(deletedRecords)),
])
}
const findUpdatedIndexes = (oldHierarchyFlat, newHierarchyFlat) =>
$(oldHierarchyFlat, [
filter(isIndex),
filter(nodeExistsIn(newHierarchyFlat)),
filter(nodeChanged(newHierarchyFlat, indexHasChanged)),
map(n => changeItem(
map(n =>
changeItem(
HierarchyChangeTypes.indexChanged,
n,
findNodeIn(n, newHierarchyFlat))
findNodeIn(n, newHierarchyFlat)
)
),
])
const hasDifferentFields = otherFlatHierarchy => record1 => {
const record2 = findNodeIn(record1, otherFlatHierarchy)
if (record1.fields.length !== record2.fields.length) return true
@ -147,13 +184,12 @@ const hasDifferentFields = otherFlatHierarchy => record1 => {
}
const indexHasChanged = (_new, old) =>
_new.map !== old.map
|| _new.filter !== old.filter
|| _new.getShardName !== old.getShardName
|| difference(_new.allowedRecordNodeIds)(old.allowedRecordNodeIds).length > 0
_new.map !== old.map ||
_new.filter !== old.filter ||
_new.getShardName !== old.getShardName ||
difference(_new.allowedRecordNodeIds)(old.allowedRecordNodeIds).length > 0
const isFieldSame = f1 => f2 =>
f1.name === f2.name && f1.type === f2.type
const isFieldSame = f1 => f2 => f1.name === f2.name && f1.type === f2.type
const nodeDoesNotExistIn = inThis => node =>
none(n => n.nodeId === node.nodeId)(inThis)
@ -164,5 +200,4 @@ const nodeExistsIn = inThis => node =>
const nodeChanged = (inThis, isChanged) => node =>
some(n => n.nodeId === node.nodeId && isChanged(n, node))(inThis)
const findNodeIn = (node, inThis) =>
find(n => n.nodeId === node.nodeId)(inThis)
const findNodeIn = (node, inThis) => find(n => n.nodeId === node.nodeId)(inThis)

View File

@ -201,7 +201,7 @@ export const getDependantIndexes = (hierarchy, recordNode) => {
const allowedReference = $(allIndexes, [
filter(isReferenceIndex),
filter(i => some(fieldReversesReferenceToIndex(i))(recordNode.fields))
filter(i => some(fieldReversesReferenceToIndex(i))(recordNode.fields)),
])
return [...allowedAncestors, ...allowedReference]
@ -222,7 +222,7 @@ export const isaggregateGroup = node =>
export const isShardedIndex = node =>
isIndex(node) && isNonEmptyString(node.getShardName)
export const isRoot = node => isSomething(node) && node.isRoot()
export const findRoot = node => isRoot(node) ? node : findRoot(node.parent())
export const findRoot = node => (isRoot(node) ? node : findRoot(node.parent()))
export const isDecendantOfARecord = hasMatchingAncestor(isRecord)
export const isGlobalIndex = node => isIndex(node) && isRoot(node.parent())
export const isReferenceIndex = node =>
@ -231,10 +231,8 @@ export const isAncestorIndex = node =>
isIndex(node) && node.indexType === indexTypes.ancestor
export const isTopLevelRecord = node => isRoot(node.parent()) && isRecord(node)
export const isTopLevelIndex = node => isRoot(node.parent()) && isIndex(node)
export const getCollectionKey = recordKey => $(recordKey, [
splitKey,
parts => joinKey(parts.slice(0, parts.length - 1))
])
export const getCollectionKey = recordKey =>
$(recordKey, [splitKey, parts => joinKey(parts.slice(0, parts.length - 1))])
export const fieldReversesReferenceToNode = node => field =>
field.type === "reference" &&
intersection(field.typeOptions.reverseIndexNodeKeys)(

View File

@ -58,7 +58,7 @@ const api = app => ({
validateNode,
validateAll,
validateTriggers,
upgradeData: upgradeData(app)
upgradeData: upgradeData(app),
})
export const getTemplateApi = app => api(app)

View File

@ -5,7 +5,6 @@ import { joinKey } from "../common"
import { initialiseIndex } from "../indexing/initialiseIndex"
export const initialiseNewIndex = async (app, indexNode) => {
if (isTopLevelIndex(indexNode)) {
await initialiseIndex(app.datastore, "/", indexNode)
return
@ -20,7 +19,8 @@ export const initialiseNewIndex = async (app, indexNode) => {
await initialiseIndex(
app.datastore,
getRecordInfo(app.hierarchy, recordKey).dir,
indexNode)
indexNode
)
}
iterateResult = await iterate()
}

View File

@ -7,13 +7,13 @@ import {
map,
filter,
uniqBy,
flatten
flatten,
} from "lodash/fp"
import {
findRoot,
getDependantIndexes,
isTopLevelRecord,
isAncestorIndex
isAncestorIndex,
} from "./hierarchy"
import { generateSchema } from "../indexing/indexSchemaCreator"
import { _buildIndex } from "../indexApi/buildIndex"
@ -36,19 +36,17 @@ export const upgradeData = app => async newHierarchy => {
if (changeActions.length === 0) return
const newApp = newHierarchy && cloneApp(app, {
hierarchy: newHierarchy
const newApp =
newHierarchy &&
cloneApp(app, {
hierarchy: newHierarchy,
})
await doUpgrade(app, newApp, changeActions)
await _saveApplicationHierarchy(newApp.datastore, newHierarchy)
}
const gatherChangeActions = (diff) =>
$(diff, [
map(actionForChange),
flatten,
uniqBy(a => a.compareKey)
])
const gatherChangeActions = diff =>
$(diff, [map(actionForChange), flatten, uniqBy(a => a.compareKey)])
const doUpgrade = async (oldApp, newApp, changeActions) => {
for (let action of changeActions) {
@ -58,34 +56,30 @@ const doUpgrade = async (oldApp, newApp, changeActions) => {
const actionForChange = diff =>
switchCase(
[isChangeType(HierarchyChangeTypes.recordCreated), recordCreatedAction],
[isChangeType(HierarchyChangeTypes.recordDeleted), deleteRecordsAction],
[
isChangeType(HierarchyChangeTypes.recordFieldsChanged),
rebuildAffectedIndexesAction
rebuildAffectedIndexesAction,
],
[isChangeType(HierarchyChangeTypes.recordRenamed), renameRecordAction],
[
isChangeType(HierarchyChangeTypes.recordEstimatedRecordTypeChanged),
reshardRecordsAction
reshardRecordsAction,
],
[isChangeType(HierarchyChangeTypes.indexCreated), newIndexAction],
[isChangeType(HierarchyChangeTypes.indexDeleted), deleteIndexAction],
[isChangeType(HierarchyChangeTypes.indexChanged), rebuildIndexAction],
[isChangeType(HierarchyChangeTypes.indexChanged), rebuildIndexAction]
)(diff)
const isChangeType = changeType => change =>
change.type === changeType
const isChangeType = changeType => change => change.type === changeType
const action = (diff, compareKey, run) => ({
diff,
@ -93,36 +87,48 @@ const action = (diff, compareKey, run) => ({
run,
})
const reshardRecordsAction = diff => [
action(diff, `reshardRecords-${diff.oldNode.nodeKey()}`, runReshardRecords),
]
const reshardRecordsAction = diff =>
[action(diff, `reshardRecords-${diff.oldNode.nodeKey()}`, runReshardRecords)]
const rebuildIndexAction = diff =>
[action(diff, `rebuildIndex-${diff.newNode.nodeKey()}`, runRebuildIndex)]
const rebuildIndexAction = diff => [
action(diff, `rebuildIndex-${diff.newNode.nodeKey()}`, runRebuildIndex),
]
const newIndexAction = diff => {
if (isAncestorIndex(diff.newNode)) {
return [action(diff, `rebuildIndex-${diff.newNode.nodeKey()}`, runRebuildIndex)]
return [
action(diff, `rebuildIndex-${diff.newNode.nodeKey()}`, runRebuildIndex),
]
} else {
return [action(diff, `newIndex-${diff.newNode.nodeKey()}`, runNewIndex)]
}
}
const deleteIndexAction = diff =>
[action(diff, `deleteIndex-${diff.oldNode.nodeKey()}`, runDeleteIndex)]
const deleteIndexAction = diff => [
action(diff, `deleteIndex-${diff.oldNode.nodeKey()}`, runDeleteIndex),
]
const deleteRecordsAction = diff =>
[action(diff, `deleteRecords-${diff.oldNode.nodeKey()}`, runDeleteRecords)]
const deleteRecordsAction = diff => [
action(diff, `deleteRecords-${diff.oldNode.nodeKey()}`, runDeleteRecords),
]
const renameRecordAction = diff =>
[action(diff, `renameRecords-${diff.oldNode.nodeKey()}`, runRenameRecord)]
const renameRecordAction = diff => [
action(diff, `renameRecords-${diff.oldNode.nodeKey()}`, runRenameRecord),
]
const recordCreatedAction = diff => {
if (isTopLevelRecord(diff.newNode)) {
return [action(diff, `initialiseRoot`, runInitialiseRoot)]
}
return [action(diff, `initialiseChildRecord-${diff.newNode.nodeKey()}`, runInitialiseChildRecord)]
return [
action(
diff,
`initialiseChildRecord-${diff.newNode.nodeKey()}`,
runInitialiseChildRecord
),
]
}
const rebuildAffectedIndexesAction = diff => {
@ -131,26 +137,29 @@ const rebuildAffectedIndexesAction = diff =>{
const indexes = getDependantIndexes(newHierarchy, diff.newNode)
const changedFields = (() => {
const addedFields = differenceBy(f => f.name)
(diff.oldNode.fields)
(diff.newNode.fields)
const addedFields = differenceBy(f => f.name)(diff.oldNode.fields)(
diff.newNode.fields
)
const removedFields = differenceBy(f => f.name)
(diff.newNode.fields)
(diff.oldNode.fields)
const removedFields = differenceBy(f => f.name)(diff.newNode.fields)(
diff.oldNode.fields
)
return map(f => f.name)([...addedFields, ...removedFields])
})()
const isIndexAffected = i => {
if (!isEqual(
generateSchema(oldHierarchy, i),
generateSchema(newHierarchy, i))) return true
if (
!isEqual(generateSchema(oldHierarchy, i), generateSchema(newHierarchy, i))
)
return true
if (some(f => indexes.filter.indexOf(`record.${f}`) > -1)(changedFields))
return true
if (some(f => indexes.getShardName.indexOf(`record.${f}`) > -1)(changedFields))
if (
some(f => indexes.getShardName.indexOf(`record.${f}`) > -1)(changedFields)
)
return true
return false
@ -158,7 +167,9 @@ const rebuildAffectedIndexesAction = diff =>{
return $(indexes, [
filter(isIndexAffected),
map(i => action({ newNode:i }, `rebuildIndex-${i.nodeKey()}`, runRebuildIndex))
map(i =>
action({ newNode: i }, `rebuildIndex-${i.nodeKey()}`, runRebuildIndex)
),
])
}

View File

@ -50,7 +50,6 @@ export const cleanup = async app => {
} finally {
await releaseLock(app, lock)
}
}
const getTransactionLock = async app =>

View File

@ -40,7 +40,7 @@ import {
fieldReversesReferenceToIndex,
isReferenceIndex,
getExactNodeForKey,
getParentKey
getParentKey,
} from "../templateApi/hierarchy"
import { getRecordInfo } from "../recordApi/recordInfo"
import { getIndexDir } from "../indexApi/getIndexDir"
@ -87,8 +87,9 @@ const mappedRecordsByIndexShard = (hierarchy, transactions) => {
transByShard[t.indexShardKey] = {
writes: [],
removes: [],
isRebuild: some(i => i.indexShardKey === t.indexShardKey)(indexBuild.toWrite)
|| some(i => i.indexShardKey === t.indexShardKey)(indexBuild.toRemove),
isRebuild:
some(i => i.indexShardKey === t.indexShardKey)(indexBuild.toWrite) ||
some(i => i.indexShardKey === t.indexShardKey)(indexBuild.toRemove),
indexDir: t.indexDir,
indexNodeKey: t.indexNode.nodeKey(),
indexNode: t.indexNode,
@ -274,16 +275,16 @@ const getBuildIndexTransactionsByShard = (hierarchy, transactions) => {
),
})),
])
}),
flatten,
reduce((obj, res) => {
if (res.mappedRecord.passedFilter)
obj.toWrite.push(res)
else
obj.toRemove.push(res)
reduce(
(obj, res) => {
if (res.mappedRecord.passedFilter) obj.toWrite.push(res)
else obj.toRemove.push(res)
return obj
}, { toWrite: [], toRemove: [] })
},
{ toWrite: [], toRemove: [] }
),
])
}

View File

@ -33,7 +33,8 @@ export const retrieve = async app => {
)
if (transactions.length === 0) {
await app.datastore.deleteFolder(
joinKey(TRANSACTIONS_FOLDER, buildIndexFolder))
joinKey(TRANSACTIONS_FOLDER, buildIndexFolder)
)
} else {
return transactions
}

View File

@ -14,7 +14,10 @@ export const UPDATE_RECORD_TRANSACTION = "update"
export const DELETE_RECORD_TRANSACTION = "delete"
export const BUILD_INDEX_TRANSACTION = "build"
export const isUpdate_Or_Rebuild = isOfType(UPDATE_RECORD_TRANSACTION, BUILD_INDEX_TRANSACTION)
export const isUpdate_Or_Rebuild = isOfType(
UPDATE_RECORD_TRANSACTION,
BUILD_INDEX_TRANSACTION
)
export const isUpdate = isOfType(UPDATE_RECORD_TRANSACTION)
export const isDelete = isOfType(DELETE_RECORD_TRANSACTION)
export const isCreate = isOfType(CREATE_RECORD_TRANSACTION)

View File

@ -39,7 +39,7 @@ export const testTemplatesPath = testAreaName =>
path.join(testFileArea(testAreaName), templateDefinitions)
export const getMemoryStore = () => setupDatastore(memory({}))
export const getMemoryTemplateApi = (store) => {
export const getMemoryTemplateApi = store => {
const app = {
datastore: store || getMemoryStore(),
publish: () => {},

View File

@ -2,7 +2,7 @@ import { getMemoryTemplateApi, appFromTempalteApi } from "./specHelpers"
import { getFlattenedHierarchy } from "../src/templateApi/hierarchy"
import { initialiseData } from "../src/appInitialise/initialiseData"
export const setup = async (store) => {
export const setup = async store => {
const { templateApi } = await getMemoryTemplateApi(store)
const root = templateApi.getNewRootLevel()
const contact = templateApi.getNewRecordTemplate(root, "contact", true)
@ -38,8 +38,13 @@ export const setup = async (store) => {
app.hierarchy = root
return {
root, contact, lead, app,
deal, templateApi, store: templateApi._storeHandle,
root,
contact,
lead,
app,
deal,
templateApi,
store: templateApi._storeHandle,
all_contacts: root.indexes[0],
all_leads: root.indexes[1],
deals_for_contacts: contact.indexes[0],

View File

@ -4,4 +4,3 @@ export { default as CardBody } from "./CardBody.svelte"
export { default as CardFooter } from "./CardFooter.svelte"
export { default as CardHeader } from "./CardHeader.svelte"
export { default as CardImage } from "./CardImage.svelte"

View File

@ -15,30 +15,30 @@ function createItemsStore(componentOnSelect) {
function addSingleItem(item) {
set([item])
if (componentOnSelect) {
componentOnSelect();
componentOnSelect()
}
}
function removeItem(itemId) {
update(items => {
let index = getItemIdx(items, itemId)
items.splice(index, 1);
return items;
items.splice(index, 1)
return items
})
if (componentOnSelect) {
componentOnSelect();
componentOnSelect()
}
}
function clearItems() {
set([]);
set([])
if (componentOnSelect) {
componentOnSelect();
componentOnSelect()
}
}
function getItemIdx(items, itemId) {
return items.findIndex(i => i && i._id === itemId);
return items.findIndex(i => i && i._id === itemId)
}
return {
@ -47,7 +47,7 @@ function createItemsStore(componentOnSelect) {
addSingleItem,
removeItem,
clearItems,
getItemIdx
getItemIdx,
}
}

View File

@ -61,7 +61,7 @@
const isDate = /^\d{1,2}\/\d{1,2}\/\d{4}$/
if (isDate.test(value)) {
const [year, month, day] = value.split("/").reverse()
if (month > 0 && month <= 12 && (day > 0 && day <= 31)) {
if (month > 0 && month <= 12 && day > 0 && day <= 31) {
date = new Date(year, month - 1, day)
navDate = date
openCalendar(true)

View File

@ -1,2 +1,2 @@
import "./_style.scss";
export { default as DatePicker } from "./DatePicker.svelte";
import "./_style.scss"
export { default as DatePicker } from "./DatePicker.svelte"

View File

@ -1,2 +1,2 @@
import "./_style.scss";
export { default as IconButton } from "./IconButton.svelte";
import "./_style.scss"
export { default as IconButton } from "./IconButton.svelte"

View File

@ -32,18 +32,17 @@
onMount(() => {
_bb.setContext("BBMD:list:props", { singleSelection: true })
_bb.setContext("BBMD:list:addItem", i => listItems = [...listItems, i])
_bb.setContext("BBMD:list:addItem", i => (listItems = [...listItems, i]))
selectedItemsStore = createItemsStore(() => {
const v = $selectedItemsStore && $selectedItemsStore.length > 0
const v =
$selectedItemsStore && $selectedItemsStore.length > 0
? $selectedItemsStore[0].value
: "";
: ""
value = v
_bb.setStateFromBinding(_bb.props.value, v)
_bb.call(onSelect, v)
})
_bb.setContext("BBMD:list:selectItemStore", selectedItemsStore)
@ -58,19 +57,15 @@
}
})
$: useNotchedOutline = variant === "outlined"
$: selectList && _bb.attachChildren(selectList)
$: modifiers = { variant, disabled, required, noLabel: !label }
$: props = { modifiers }
$: selectClass = cb.build({ props })
$: if (value !== undefined && instance && listItems.length > 0) {
instance.selectedIndex = listItems.findIndex(i => i.value === value)
}
</script>
<div bind:this={select} id={_helperId} class={selectClass}>

View File

@ -1,3 +1,3 @@
import "./_style.scss"
export { default as HelperText } from "./HelperText.svelte"
export { default as Select } from "./Select.svelte";
export { default as Select } from "./Select.svelte"

View File

@ -346,7 +346,7 @@ module.exports = async context => {
await bb.recordApi.save(userInMaster)
}
const deleteLatestPackageFromCache = (appname) => {
const deleteLatestPackageFromCache = appname => {
deleteCachedPackage(context, appname, LATEST_VERSIONID)
}