backup yo
This commit is contained in:
parent
fd8341aaf6
commit
2580b6d362
|
@ -5,8 +5,9 @@ import {
|
|||
events, joinKey,
|
||||
} from '../common';
|
||||
import { _deleteRecord } from '../recordApi/delete';
|
||||
import { getAllIdsIterator, getAllIdsShardKey } from '../indexing/allIds';
|
||||
import { getAllIdsIterator, getAllIdsShardKey, folderStructureArray } from '../indexing/allIds';
|
||||
import { permission } from '../authApi/permissions';
|
||||
import { getRecordInfo } from "../recordApi/recordInfo";
|
||||
|
||||
export const deleteCollection = (app, disableCleanup = false) => async key => apiWrapper(
|
||||
app,
|
||||
|
@ -18,19 +19,16 @@ export const deleteCollection = (app, disableCleanup = false) => async key => ap
|
|||
|
||||
|
||||
export const _deleteCollection = async (app, key, disableCleanup) => {
|
||||
key = safeKey(key);
|
||||
const node = getNodeForCollectionPath(app.hierarchy)(key);
|
||||
|
||||
await deleteRecords(app, key);
|
||||
await deleteAllIdsFolders(app, node, key);
|
||||
await deleteCollectionFolder(app, key);
|
||||
const recordInfo = getRecordInfo(key);
|
||||
await app.datastore.deleteFolder(recordInfo)
|
||||
if (!disableCleanup) { await app.cleanupTransactions(); }
|
||||
};
|
||||
|
||||
const deleteCollectionFolder = async (app, key) => await app.datastore.deleteFolder(key);
|
||||
|
||||
|
||||
const deleteAllIdsFolders = async (app, node, key) => {
|
||||
const deleteShardFolders = async (app, node, key) => {
|
||||
|
||||
await app.datastore.deleteFolder(
|
||||
joinKey(
|
||||
key, 'allids',
|
||||
|
@ -43,37 +41,4 @@ const deleteAllIdsFolders = async (app, node, key) => {
|
|||
);
|
||||
};
|
||||
|
||||
const deleteRecords = async (app, key) => {
|
||||
const deletedAllIdsShards = [];
|
||||
const deleteAllIdsShard = async (recordId) => {
|
||||
const shardKey = getAllIdsShardKey(
|
||||
app.hierarchy, key, recordId,
|
||||
);
|
||||
|
||||
if (includes(shardKey)(deletedAllIdsShards)) {
|
||||
return;
|
||||
}
|
||||
|
||||
deletedAllIdsShards.push(shardKey);
|
||||
|
||||
await app.datastore.deleteFile(shardKey);
|
||||
};
|
||||
|
||||
const iterate = await getAllIdsIterator(app)(key);
|
||||
|
||||
let ids = await iterate();
|
||||
while (!ids.done) {
|
||||
if (ids.result.collectionKey === key) {
|
||||
for (const id of ids.result.ids) {
|
||||
await _deleteRecord(
|
||||
app,
|
||||
joinKey(key, id),
|
||||
true,
|
||||
);
|
||||
await deleteAllIdsShard(id);
|
||||
}
|
||||
}
|
||||
|
||||
ids = await iterate();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -7,19 +7,9 @@ import {
|
|||
} from '../templateApi/hierarchy';
|
||||
import { $, allTrue, joinKey } from '../common';
|
||||
|
||||
const ensureCollectionIsInitialised = async (datastore, node, parentKey) => {
|
||||
if (!await datastore.exists(parentKey)) {
|
||||
await datastore.createFolder(parentKey);
|
||||
await datastore.createFolder(
|
||||
joinKey(parentKey, 'allids'),
|
||||
);
|
||||
await datastore.createFolder(
|
||||
joinKey(
|
||||
parentKey,
|
||||
'allids',
|
||||
node.nodeId.toString(),
|
||||
),
|
||||
);
|
||||
const ensureCollectionIsInitialised = async (datastore, node, dir) => {
|
||||
if (!await datastore.exists(dir)) {
|
||||
await datastore.createFolder(dir);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -44,9 +34,8 @@ export const initialiseRootCollections = async (datastore, hierarchy) => {
|
|||
}
|
||||
};
|
||||
|
||||
export const initialiseChildCollections = async (app, recordKey) => {
|
||||
const childCollectionRecords = $(recordKey, [
|
||||
getExactNodeForPath(app.hierarchy),
|
||||
export const initialiseChildCollections = async (app, recordInfo) => {
|
||||
const childCollectionRecords = $(recordInfo.recordNode, [
|
||||
n => n.children,
|
||||
filter(isCollectionRecord),
|
||||
]);
|
||||
|
@ -55,7 +44,7 @@ export const initialiseChildCollections = async (app, recordKey) => {
|
|||
await ensureCollectionIsInitialised(
|
||||
app.datastore,
|
||||
child,
|
||||
joinKey(recordKey, child.collectionName),
|
||||
recordInfo.child(child.collectionName),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,102 +1,43 @@
|
|||
import {
|
||||
join, pull,
|
||||
map, flatten, orderBy,
|
||||
filter, find,
|
||||
join, flatten, orderBy,
|
||||
filter
|
||||
} from 'lodash/fp';
|
||||
import {
|
||||
getParentKey,
|
||||
getFlattenedHierarchy,
|
||||
getCollectionNodeByKeyOrNodeKey, getNodeForCollectionPath,
|
||||
getCollectionNodeByKeyOrNodeKey,
|
||||
isCollectionRecord, isAncestor,
|
||||
} from '../templateApi/hierarchy';
|
||||
import { joinKey, safeKey, $, getFileFromKey } from '../common';
|
||||
import { joinKey, safeKey, $ } from '../common';
|
||||
|
||||
const RECORDS_PER_FOLDER = 1000;
|
||||
export const RECORDS_PER_FOLDER = 1000;
|
||||
export const allIdChars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-';
|
||||
|
||||
const allIdChars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-';
|
||||
// this should never be changed - ever
|
||||
// - existing databases depend on the order of chars this string
|
||||
|
||||
const _new_getShardPath = (recordNode, key) => {
|
||||
const id = getFileFromKey(key);
|
||||
/**
|
||||
* folderStructureArray should return an array like
|
||||
* - [1] = all records fit into one folder
|
||||
* - [2] = all records fite into 2 folders
|
||||
* - [64, 3] = all records fit into 64 * 3 folders
|
||||
* - [64, 64, 10] = all records fit into 64 * 64 * 10 folder
|
||||
* (there are 64 possible chars in allIsChars)
|
||||
*/
|
||||
export const folderStructureArray = (recordNode, currentArray=[], currentFolderPosition=0) => {
|
||||
const maxRecords = currentFolderPosition === 0
|
||||
? RECORDS_PER_FOLDER
|
||||
: currentFolderPosition * 64 * RECORDS_PER_FOLDER;
|
||||
|
||||
|
||||
/**
|
||||
* folderStructureArray should return an array like
|
||||
* - [1] = all records fit into one folder
|
||||
* - [2] = all records fite into 2 folders
|
||||
* - [64, 3] = all records fit into 64 * 3 folders
|
||||
* - [64, 64, 10] = all records fit into 64 * 64 * 10 folder
|
||||
* (there are 64 possible chars in allIsChars)
|
||||
*/
|
||||
const folderStructureArray = (currentArray=[], currentFolderPosition=0) => {
|
||||
const maxRecords = currentFolderPosition === 0
|
||||
? RECORDS_PER_FOLDER
|
||||
: currentFolderPosition * 64 * RECORDS_PER_FOLDER;
|
||||
|
||||
if(maxRecords < recordNode.estimatedRecordCount) {
|
||||
return folderStructureArray(
|
||||
[...currentArray, 64],
|
||||
currentFolderPosition + 1);
|
||||
} else {
|
||||
const childFolderCount = Math.ceil(maxRecords / recordNode.estimatedRecordCount);
|
||||
return [...currentArray, childFolderCount]
|
||||
}
|
||||
if(maxRecords < recordNode.estimatedRecordCount) {
|
||||
return folderStructureArray(
|
||||
[...currentArray, 64],
|
||||
currentFolderPosition + 1);
|
||||
} else {
|
||||
const childFolderCount = Math.ceil(maxRecords / recordNode.estimatedRecordCount);
|
||||
return [...currentArray, childFolderCount]
|
||||
}
|
||||
|
||||
const folderStructure = folderStructureArray();
|
||||
|
||||
}
|
||||
|
||||
const allIdsStringsForFactor = (collectionNode) => {
|
||||
const factor = collectionNode.allidsShardFactor;
|
||||
const charRangePerShard = 64 / factor;
|
||||
const allIdStrings = [];
|
||||
let index = 0;
|
||||
let currentIdsShard = '';
|
||||
while (index < 64) {
|
||||
currentIdsShard += allIdChars[index];
|
||||
if ((index + 1) % charRangePerShard === 0) {
|
||||
allIdStrings.push(currentIdsShard);
|
||||
currentIdsShard = '';
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
return allIdStrings;
|
||||
};
|
||||
|
||||
export const getAllIdsShardNames = (appHierarchy, collectionKey) => {
|
||||
const collectionRecordNode = getNodeForCollectionPath(appHierarchy)(collectionKey);
|
||||
return $(collectionRecordNode, [
|
||||
c => [c.nodeId],
|
||||
map(i => map(c => _allIdsShardKey(collectionKey, i, c))(allIdsStringsForFactor(collectionRecordNode))),
|
||||
flatten,
|
||||
]);
|
||||
};
|
||||
|
||||
const _allIdsShardKey = (collectionKey, childNo, shardKey) => joinKey(
|
||||
collectionKey,
|
||||
'allids',
|
||||
childNo,
|
||||
shardKey,
|
||||
);
|
||||
|
||||
export const getAllIdsShardKey = (appHierarchy, collectionKey, recordId) => {
|
||||
const indexOfFirstDash = recordId.indexOf('-');
|
||||
|
||||
const collectionNode = getNodeForCollectionPath(appHierarchy)(collectionKey);
|
||||
|
||||
const idFirstChar = recordId[indexOfFirstDash + 1];
|
||||
const allIdsShardId = $(collectionNode, [
|
||||
allIdsStringsForFactor,
|
||||
find(i => i.includes(idFirstChar)),
|
||||
]);
|
||||
|
||||
return _allIdsShardKey(
|
||||
collectionKey,
|
||||
recordId.slice(0, indexOfFirstDash),
|
||||
allIdsShardId,
|
||||
);
|
||||
};
|
||||
|
||||
export const getAllIdsIterator = app => async (collection_Key_or_NodeKey) => {
|
||||
collection_Key_or_NodeKey = safeKey(collection_Key_or_NodeKey);
|
||||
|
@ -105,29 +46,97 @@ export const getAllIdsIterator = app => async (collection_Key_or_NodeKey) => {
|
|||
collection_Key_or_NodeKey,
|
||||
);
|
||||
|
||||
const getAllIdsIteratorForCollectionKey = async (collectionKey) => {
|
||||
const all_allIdsKeys = getAllIdsShardNames(app.hierarchy, collectionKey);
|
||||
let shardIndex = 0;
|
||||
const getAllIdsIteratorForCollectionKey = async (recordNode, collectionKey) => {
|
||||
|
||||
const folderStructure = folderStructureArray(recordNode)
|
||||
|
||||
const allIdsFromShardIterator = async () => {
|
||||
if (shardIndex === all_allIdsKeys.length) { return ({ done: true, result: { ids: [], collectionKey } }); }
|
||||
let currentFolderContents = [];
|
||||
let currentFolderIndexes = [];
|
||||
let currentSubPath = [];
|
||||
|
||||
const shardKey = all_allIdsKeys[shardIndex];
|
||||
const basePath = joinKey(
|
||||
collectionKey, recordNode.nodeId.toString());
|
||||
|
||||
|
||||
const allIds = await getAllIdsFromShard(app.datastore, shardKey);
|
||||
let folderLevel = 0;
|
||||
const levels = folderStructure.length;
|
||||
const topLevel = levels -1;
|
||||
|
||||
shardIndex++;
|
||||
const lastPathHasContent = () =>
|
||||
folderLevel === 0
|
||||
|| currentFolderContents[folderLevel - 1].length > 0;
|
||||
|
||||
return ({
|
||||
while (folderLevel < folderStructure.length && lastPathHasContent()) {
|
||||
if(folderLevel < topLevel) {
|
||||
const contentsThisLevel =
|
||||
await app.datastore.getFolderContents(
|
||||
join(basePath, ...currentSubPath));
|
||||
|
||||
currentFolderContents.push(contentsThisLevel);
|
||||
currentFolderIndexes.push(0);
|
||||
currentSubPath.push(currentFolderContents[0])
|
||||
} else {
|
||||
// placesholders only for the top level (which will be populated by nextFolder())
|
||||
currentFolderContents.push([])
|
||||
currentFolderIndexes.push(-1);
|
||||
currentSubPath.push("");
|
||||
}
|
||||
|
||||
folderLevel+=1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const nextFolder = async (lev=-1) => {
|
||||
lev = (lev === -1) ? topLevel : lev;
|
||||
if(currentFolderIndexes[lev] !== currentFolderContents[lev].length - 1){
|
||||
|
||||
const folderIndexThisLevel = currentFolderIndexes[lev] + 1;
|
||||
currentFolderIndexes[lev] = folderIndexThisLevel;
|
||||
currentSubPath[lev] = currentFolderContents[folderIndexThisLevel]
|
||||
|
||||
if(lev < topLevel) {
|
||||
let loopLev = lev + 1;
|
||||
while(loopLev <= topLevel) {
|
||||
currentFolderContents[loopLev] =
|
||||
await app.datastore.getFolderContents(join(basePath, ...currentSubPath));
|
||||
loopLev+=1;
|
||||
}
|
||||
}
|
||||
|
||||
return false; // not complete
|
||||
|
||||
} else {
|
||||
if(lev === 0) return true; // complete
|
||||
return await nextFolder(lev - 1);
|
||||
}
|
||||
}
|
||||
|
||||
const fininshedResult = ({ done: true, result: { ids: [], collectionKey } });
|
||||
|
||||
const getIdsFromCurrentfolder = async () => {
|
||||
|
||||
if(currentFolderIndexes.length < folderStructure)
|
||||
return fininshedResult;
|
||||
|
||||
const hasMore = await nextFolder();
|
||||
|
||||
if(!hasMore) return fininshedResult;
|
||||
|
||||
const result = ({
|
||||
result: {
|
||||
ids: allIds,
|
||||
collectionKey,
|
||||
ids: await app.datastore.getFolderContents(
|
||||
joinKey(basePath, currentSubPath)),
|
||||
collectionKey
|
||||
},
|
||||
done: false,
|
||||
});
|
||||
};
|
||||
done:false
|
||||
})
|
||||
|
||||
return allIdsFromShardIterator;
|
||||
return result;
|
||||
}
|
||||
|
||||
return getIdsFromCurrentfolder;
|
||||
|
||||
};
|
||||
|
||||
const ancestors = $(getFlattenedHierarchy(app.hierarchy), [
|
||||
|
@ -146,11 +155,13 @@ export const getAllIdsIterator = app => async (collection_Key_or_NodeKey) => {
|
|||
if (currentNode.nodeKey() === recordNode.nodeKey()) {
|
||||
return [
|
||||
await getAllIdsIteratorForCollectionKey(
|
||||
currentNode,
|
||||
currentCollectionKey,
|
||||
)];
|
||||
}
|
||||
const allIterators = [];
|
||||
const currentIterator = await getAllIdsIteratorForCollectionKey(
|
||||
currentNode,
|
||||
currentCollectionKey,
|
||||
);
|
||||
|
||||
|
|
|
@ -2,8 +2,8 @@ import { isShardedIndex } from '../templateApi/hierarchy';
|
|||
import { joinKey } from '../common';
|
||||
import { getShardMapKey, getUnshardedIndexDataKey, createIndexFile } from './sharding';
|
||||
|
||||
export const initialiseIndex = async (datastore, parentKey, index) => {
|
||||
const indexKey = joinKey(parentKey, index.name);
|
||||
export const initialiseIndex = async (datastore, dir, index) => {
|
||||
const indexKey = joinKey(dir, index.name);
|
||||
|
||||
await datastore.createFolder(indexKey);
|
||||
|
||||
|
|
|
@ -1,15 +1,11 @@
|
|||
import {
|
||||
safeKey, apiWrapper,
|
||||
events, joinKey,
|
||||
events,
|
||||
} from '../common';
|
||||
import { _load, getRecordFileName } from './load';
|
||||
import { _deleteCollection } from '../collectionApi/delete';
|
||||
import {
|
||||
getExactNodeForPath
|
||||
} from '../templateApi/hierarchy';
|
||||
import { _deleteIndex } from '../indexApi/delete';
|
||||
import { _loadFromInfo } from './load';
|
||||
import { transactionForDeleteRecord } from '../transactions/create';
|
||||
import { permission } from '../authApi/permissions';
|
||||
import { getRecordInfo } from "./recordInfo";
|
||||
|
||||
export const deleteRecord = (app, disableCleanup = false) => async key => {
|
||||
key = safeKey(key);
|
||||
|
@ -24,71 +20,17 @@ export const deleteRecord = (app, disableCleanup = false) => async key => {
|
|||
|
||||
// called deleteRecord because delete is a keyword
|
||||
export const _deleteRecord = async (app, key, disableCleanup) => {
|
||||
key = safeKey(key);
|
||||
const node = getExactNodeForPath(app.hierarchy)(key);
|
||||
const recordInfo = getRecordInfo(app, key);
|
||||
key = recordInfo.key;
|
||||
|
||||
const record = await _load(app, key);
|
||||
const record = await _loadFromInfo(app, recordInfo);
|
||||
await transactionForDeleteRecord(app, record);
|
||||
|
||||
for (const collectionRecord of node.children) {
|
||||
const collectionKey = joinKey(
|
||||
key, collectionRecord.collectionName,
|
||||
);
|
||||
await _deleteCollection(app, collectionKey, true);
|
||||
}
|
||||
|
||||
await app.datastore.deleteFile(
|
||||
getRecordFileName(key),
|
||||
);
|
||||
|
||||
await deleteFiles(app, key);
|
||||
await app.datastore.deleteFolder(recordInfo.dir);
|
||||
|
||||
if (!disableCleanup) { await app.cleanupTransactions(); }
|
||||
|
||||
await app.datastore.deleteFolder(key);
|
||||
await deleteIndexes(app, key);
|
||||
};
|
||||
|
||||
const deleteIndexes = async (app, key) => {
|
||||
const node = getExactNodeForPath(app.hierarchy)(key);
|
||||
/* const reverseIndexKeys = $(app.hierarchy, [
|
||||
getFlattenedHierarchy,
|
||||
map(n => n.fields),
|
||||
flatten,
|
||||
filter(isSomething),
|
||||
filter(fieldReversesReferenceToNode(node)),
|
||||
map(f => $(f.typeOptions.reverseIndexNodeKeys, [
|
||||
map(n => getNode(
|
||||
app.hierarchy,
|
||||
n))
|
||||
])
|
||||
),
|
||||
flatten,
|
||||
map(n => joinKey(key, n.name))
|
||||
]);
|
||||
|
||||
for(let i of reverseIndexKeys) {
|
||||
await _deleteIndex(app, i, true);
|
||||
} */
|
||||
|
||||
|
||||
for (const index of node.indexes) {
|
||||
const indexKey = joinKey(key, index.name);
|
||||
await _deleteIndex(app, indexKey, true);
|
||||
}
|
||||
};
|
||||
|
||||
const deleteFiles = async (app, key) => {
|
||||
const filesFolder = joinKey(key, 'files');
|
||||
const allFiles = await app.datastore.getFolderContents(
|
||||
filesFolder,
|
||||
);
|
||||
|
||||
for (const file of allFiles) {
|
||||
await app.datastore.deleteFile(file);
|
||||
}
|
||||
|
||||
await app.datastore.deleteFolder(
|
||||
joinKey(key, 'files'),
|
||||
);
|
||||
};
|
||||
|
|
|
@ -10,6 +10,7 @@ import {
|
|||
} from '../common';
|
||||
import { mapRecord } from '../indexing/evaluate';
|
||||
import { permission } from '../authApi/permissions';
|
||||
import { getRecordInfo } from "./recordInfo";
|
||||
|
||||
export const getRecordFileName = key => joinKey(key, 'record.json');
|
||||
|
||||
|
@ -24,12 +25,10 @@ export const load = app => async key => {
|
|||
);
|
||||
}
|
||||
|
||||
export const _load = async (app, key, keyStack = []) => {
|
||||
key = safeKey(key);
|
||||
const recordNode = getExactNodeForPath(app.hierarchy)(key);
|
||||
const storedData = await app.datastore.loadJson(
|
||||
getRecordFileName(key),
|
||||
);
|
||||
export const _loadFromInfo = async (app, recordInfo, keyStack = []) => {
|
||||
const key = recordInfo.key;
|
||||
const {recordNode, recordJson} = recordInfo;
|
||||
const storedData = await app.datastore.loadJson(recordJson);
|
||||
|
||||
const loadedRecord = $(recordNode.fields, [
|
||||
keyBy('name'),
|
||||
|
@ -70,4 +69,11 @@ export const _load = async (app, key, keyStack = []) => {
|
|||
return loadedRecord;
|
||||
};
|
||||
|
||||
export const _load = async (app, key, keyStack = []) =>
|
||||
_loadFromInfo(
|
||||
app,
|
||||
getRecordInfo(app, key),
|
||||
keyStack);
|
||||
|
||||
|
||||
export default load;
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
import {
|
||||
getExactNodeForPath, getActualKeyOfParent, isRoot
|
||||
} from '../templateApi/hierarchy';
|
||||
import {
|
||||
map, reduce
|
||||
} from 'lodash/fp';
|
||||
import {
|
||||
$, getDirFomKey, getFileFromKey, joinKey, safeKey
|
||||
} from '../common';
|
||||
import {
|
||||
folderStructureArray, allIdChars
|
||||
} from "../indexing/allIds";
|
||||
|
||||
export const getRecordInfo = (app, key) => {
|
||||
const recordNode = getExactNodeForPath(app.hierarchy)(key);
|
||||
const pathInfo = getRecordDirectory(recordNode, key);
|
||||
const dir = joinKey(pathInfo.base, ...pathInfo.subdirs);
|
||||
|
||||
return {
|
||||
recordJson: recordJson(dir),
|
||||
files: files(dir),
|
||||
child:(name) => joinKey(dir, name),
|
||||
key: safeKey(key),
|
||||
recordNode, pathInfo, dir
|
||||
};
|
||||
}
|
||||
|
||||
const recordJson = (dir) =>
|
||||
joinKey(dir, "record.json")
|
||||
|
||||
const files = (dir) =>
|
||||
joinKey(dir, "files")
|
||||
|
||||
const getRecordDirectory = (recordNode, key) => {
|
||||
const id = getFileFromKey(key);
|
||||
|
||||
const traverseParentKeys = (n, keys=[]) => {
|
||||
if(isRoot(n)) return keys;
|
||||
const k = getActualKeyOfParent(n, key);
|
||||
}
|
||||
|
||||
return ({
|
||||
base:getDirFomKey(key),
|
||||
subdirs: [recordNode.nodeId.toString(), ...subfolders]
|
||||
});
|
||||
}
|
||||
|
||||
const recordRelativeDirectory = (recordNode, id) => {
|
||||
const folderStructure = folderStructureArray(recordNode);
|
||||
|
||||
const subfolders = $(folderStructure, [
|
||||
reduce((result, currentCount) => {
|
||||
result.folders.push(
|
||||
folderForChar(id[result.level], currentCount)
|
||||
);
|
||||
return {level:result.level+1, folders:result.folders}
|
||||
}, {level:0, folders:[]}),
|
||||
map(f => f.folders),
|
||||
]);
|
||||
|
||||
return [recordNode.nodeId.toString(), ...subfolders]
|
||||
}
|
||||
|
||||
const folderForChar = (char, folderCount) =>
|
||||
folderCount === 1 ? ""
|
||||
: $(folderCount, [
|
||||
idFoldersForFolderCount,
|
||||
find(f => f.includes(char))
|
||||
]);
|
||||
|
||||
const idFoldersForFolderCount = (folderCount) => {
|
||||
const charRangePerShard = 64 / folderCount;
|
||||
const idFolders = [];
|
||||
let index = 0;
|
||||
let currentIdsShard = '';
|
||||
while (index < 64) {
|
||||
currentIdsShard += allIdChars[index];
|
||||
if ((index + 1) % charRangePerShard === 0) {
|
||||
idFolders.push(currentIdsShard);
|
||||
currentIdsShard = '';
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
return idFolders;
|
||||
};
|
||||
|
|
@ -1,11 +1,10 @@
|
|||
import {
|
||||
cloneDeep,
|
||||
flatten,
|
||||
map,
|
||||
filter} from 'lodash/fp';
|
||||
cloneDeep, take, takeRight,
|
||||
flatten, map, filter
|
||||
} from 'lodash/fp';
|
||||
import { initialiseChildCollections } from '../collectionApi/initialise';
|
||||
import { validate } from './validate';
|
||||
import { _load, getRecordFileName } from './load';
|
||||
import { _loadFromInfo, getRecordFileName } from './load';
|
||||
import {
|
||||
apiWrapper, events, $, joinKey,
|
||||
} from '../common';
|
||||
|
@ -20,6 +19,7 @@ import {
|
|||
import { permission } from '../authApi/permissions';
|
||||
import { initialiseIndex } from '../indexing/initialiseIndex';
|
||||
import { BadRequestError } from '../common/errors';
|
||||
import { getRecordInfo } from "./recordInfo";
|
||||
|
||||
export const save = app => async (record, context) => apiWrapper(
|
||||
app,
|
||||
|
@ -42,8 +42,14 @@ export const _save = async (app, record, context, skipValidation = false) => {
|
|||
}
|
||||
}
|
||||
|
||||
const recordInfo = getRecordInfo(app.record.key);
|
||||
const {
|
||||
recordNode, pathInfo,
|
||||
recordJson, files,
|
||||
} = recordInfo;
|
||||
|
||||
if (recordClone.isNew) {
|
||||
const recordNode = getExactNodeForPath(app.hierarchy)(record.key);
|
||||
|
||||
if(!recordNode)
|
||||
throw new Error("Cannot find node for " + record.key);
|
||||
|
||||
|
@ -51,28 +57,23 @@ export const _save = async (app, record, context, skipValidation = false) => {
|
|||
app, recordClone,
|
||||
);
|
||||
recordClone.transactionId = transaction.id;
|
||||
await app.datastore.createFolder(recordClone.key);
|
||||
await app.datastore.createFolder(
|
||||
joinKey(recordClone.key, 'files'),
|
||||
);
|
||||
await app.datastore.createJson(
|
||||
getRecordFileName(recordClone.key),
|
||||
recordClone,
|
||||
);
|
||||
await initialiseReverseReferenceIndexes(app, record);
|
||||
await initialiseAncestorIndexes(app, record);
|
||||
await initialiseChildCollections(app, recordClone.key);
|
||||
await createRecordFolderPath(app.datastore, pathInfo);
|
||||
await app.datastore.createFolder(files);
|
||||
await app.datastore.createJson(recordJson, recordClone);
|
||||
await initialiseReverseReferenceIndexes(app, recordInfo);
|
||||
await initialiseAncestorIndexes(app, recordInfo);
|
||||
await initialiseChildCollections(app, recordInfo);
|
||||
await app.publish(events.recordApi.save.onRecordCreated, {
|
||||
record: recordClone,
|
||||
});
|
||||
} else {
|
||||
const oldRecord = await _load(app, recordClone.key);
|
||||
const oldRecord = await _loadFromInfo(app, recordInfo);
|
||||
const transaction = await transactionForUpdateRecord(
|
||||
app, oldRecord, recordClone,
|
||||
);
|
||||
recordClone.transactionId = transaction.id;
|
||||
await app.datastore.updateJson(
|
||||
getRecordFileName(recordClone.key),
|
||||
recordJson,
|
||||
recordClone,
|
||||
);
|
||||
await app.publish(events.recordApi.save.onRecordUpdated, {
|
||||
|
@ -88,19 +89,16 @@ export const _save = async (app, record, context, skipValidation = false) => {
|
|||
return returnedClone;
|
||||
};
|
||||
|
||||
const initialiseAncestorIndexes = async (app, record) => {
|
||||
const recordNode = getExactNodeForPath(app.hierarchy)(record.key);
|
||||
|
||||
for (const index of recordNode.indexes) {
|
||||
const indexKey = joinKey(record.key, index.name);
|
||||
if (!await app.datastore.exists(indexKey)) { await initialiseIndex(app.datastore, record.key, index); }
|
||||
const initialiseAncestorIndexes = async (app, recordInfo) => {
|
||||
for (const index of recordInfo.recordNode.indexes) {
|
||||
const indexKey = recordInfo.child(index.name);
|
||||
if (!await app.datastore.exists(indexKey)) { await initialiseIndex(app.datastore, recordInfo.dir, index); }
|
||||
}
|
||||
};
|
||||
|
||||
const initialiseReverseReferenceIndexes = async (app, record) => {
|
||||
const recordNode = getExactNodeForPath(app.hierarchy)(record.key);
|
||||
const initialiseReverseReferenceIndexes = async (app, recordInfo) => {
|
||||
|
||||
const indexNodes = $(fieldsThatReferenceThisRecord(app, recordNode), [
|
||||
const indexNodes = $(fieldsThatReferenceThisRecord(app, recordInfo.recordNode), [
|
||||
map(f => $(f.typeOptions.reverseIndexNodeKeys, [
|
||||
map(n => getNode(
|
||||
app.hierarchy,
|
||||
|
@ -112,7 +110,7 @@ const initialiseReverseReferenceIndexes = async (app, record) => {
|
|||
|
||||
for (const indexNode of indexNodes) {
|
||||
await initialiseIndex(
|
||||
app.datastore, record.key, indexNode,
|
||||
app.datastore, recordInfo.dir, indexNode,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
@ -125,6 +123,37 @@ const fieldsThatReferenceThisRecord = (app, recordNode) => $(app.hierarchy, [
|
|||
filter(fieldReversesReferenceToNode(recordNode)),
|
||||
]);
|
||||
|
||||
const recordFolderPath = (recordNode, key) => {
|
||||
const createRecordFolderPath = async (datastore, pathInfo) => {
|
||||
|
||||
const recursiveCreateFolder = async (subdirs, dirsThatNeedCreated=[]) => {
|
||||
|
||||
// iterate backwards through directory hierachy
|
||||
// until we get to a folder that exists, then create the rest
|
||||
// e.g
|
||||
// - some/folder/here
|
||||
// - some/folder
|
||||
// - some
|
||||
const thisFolder = joinKey(pathInfo.base, ...subdirs);
|
||||
|
||||
if(await datastore.exists(thisFolder)) {
|
||||
|
||||
let creationFolder = thisFolder;
|
||||
for(let nextDir of dirsThatNeedCreated) {
|
||||
creationFolder = joinKey(creationFolder, nextDir);
|
||||
await datastore.createFolder(creationFolder);
|
||||
}
|
||||
|
||||
} else if(dirsThatNeedCreated.length > 0) {
|
||||
|
||||
await recursiveCreateFolder(
|
||||
take(subdirs.length - 1)(subdirs),
|
||||
[...takeRight(1)(subdirs), ...dirsThatNeedCreated]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
await recursiveCreateFolder(pathInfo.subdirs);
|
||||
|
||||
return joinKey(pathInfo.base, ...pathInfo.subdirs);
|
||||
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
import {setupApphierarchy, basicAppHierarchyCreator_WithFields,
|
||||
getNewFieldAndAdd} from "./specHelpers";
|
||||
import {isNonEmptyString} from "../src/common";
|
||||
import { isBoolean } from "util";
|
||||
import {permission} from "../src/authApi/permissions";
|
||||
import { _getNew } from "../src/recordApi/getNew";
|
||||
|
||||
describe("recordApi > getNew", () => {
|
||||
|
||||
it("should get object with generated id and key (full path)", async () => {
|
||||
const {recordApi} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
||||
const record = recordApi.getNew("/customers", "customer");
|
||||
|
||||
expect(record.id).toBeDefined();
|
||||
expect(isNonEmptyString(record.id)).toBeTruthy();
|
||||
|
||||
expect(record.key).toBeDefined();
|
||||
expect(isNonEmptyString(record.key)).toBeTruthy();
|
||||
expect(record.key).toBe(`/customers/${record.id}`);
|
||||
});
|
||||
|
||||
it("should create object with all declared fields, using default values", async () => {
|
||||
const {recordApi} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
||||
|
||||
const newRecord = recordApi.getNew("/customers", "customer")
|
||||
|
||||
expect(newRecord.surname).toBe(null);
|
||||
expect(newRecord.isalive).toBe(true);
|
||||
expect(newRecord.createddate).toBe(null);
|
||||
expect(newRecord.age).toBe(null);
|
||||
});
|
||||
|
||||
it("should create object with all declared fields, and use inital values", async () => {
|
||||
const {recordApi} = await setupApphierarchy(templateApi => {
|
||||
const hierarchy = basicAppHierarchyCreator_WithFields(templateApi);
|
||||
const {customerRecord} = hierarchy;
|
||||
|
||||
customerRecord.fields = [];
|
||||
|
||||
const newField = getNewFieldAndAdd(templateApi, customerRecord);
|
||||
newField("surname", "string", "hello");
|
||||
newField("isalive", "bool", "true");
|
||||
newField("age", "number", "999");
|
||||
|
||||
return hierarchy;
|
||||
});
|
||||
|
||||
const newRecord = recordApi.getNew("/customers", "customer")
|
||||
|
||||
expect(newRecord.surname).toBe("hello");
|
||||
expect(newRecord.isalive).toBe(true);
|
||||
expect(newRecord.age).toBe(999);
|
||||
});
|
||||
|
||||
it("should add a function 'isNew' which always returns true", async () => {
|
||||
const {recordApi} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
||||
const record = recordApi.getNew("/customers", "customer");
|
||||
|
||||
expect(record.isNew).toBeDefined();
|
||||
expect(isBoolean(record.isNew)).toBeTruthy();
|
||||
expect(record.isNew).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should add a function 'type' returns type", async () => {
|
||||
const {recordApi} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
||||
const record = recordApi.getNew("/customers", "customer");
|
||||
|
||||
expect(record.type).toBeDefined();
|
||||
expect(isNonEmptyString(record.type)).toBeTruthy();
|
||||
expect(record.type).toBe("customer");
|
||||
});
|
||||
|
||||
it("should throw error, user user does not have permission", async () => {
|
||||
const {recordApi, app, appHierarchy} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
||||
app.removePermission(permission.createRecord.get(appHierarchy.customerRecord.nodeKey()));
|
||||
expect(() => recordApi.getNew("/customers", "customer")).toThrow(/Unauthorized/);
|
||||
});
|
||||
|
||||
it("should not depend on having any other permissions", async () => {
|
||||
const {recordApi, app, appHierarchy} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
||||
app.withOnlyThisPermission(permission.createRecord.get(appHierarchy.customerRecord.nodeKey()));
|
||||
recordApi.getNew("/customers", "customer");
|
||||
});
|
||||
|
||||
it("for 'single record' type, should create with key ending in node name", async () => {
|
||||
const {appHierarchy} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
||||
const {settingsRecord} = appHierarchy;
|
||||
const result = _getNew(settingsRecord, "");
|
||||
expect(result.key).toBe("/settings")
|
||||
})
|
||||
});
|
||||
|
||||
|
|
@ -1,94 +1,8 @@
|
|||
import {setupApphierarchy, basicAppHierarchyCreator_WithFields,
|
||||
getNewFieldAndAdd, stubEventHandler} from "./specHelpers";
|
||||
stubEventHandler} from "./specHelpers";
|
||||
import {events, isNonEmptyString} from "../src/common";
|
||||
import { isBoolean } from "util";
|
||||
import {permission} from "../src/authApi/permissions";
|
||||
import { _getNew } from "../src/recordApi/getNew";
|
||||
|
||||
describe("recordApi > getNew", () => {
|
||||
|
||||
it("should get object with generated id and key (full path)", async () => {
|
||||
const {recordApi} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
||||
const record = recordApi.getNew("/customers", "customer");
|
||||
|
||||
expect(record.id).toBeDefined();
|
||||
expect(isNonEmptyString(record.id)).toBeTruthy();
|
||||
|
||||
expect(record.key).toBeDefined();
|
||||
expect(isNonEmptyString(record.key)).toBeTruthy();
|
||||
expect(record.key).toBe(`/customers/${record.id}`);
|
||||
});
|
||||
|
||||
it("should create object with all declared fields, using default values", async () => {
|
||||
const {recordApi} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
||||
|
||||
const newRecord = recordApi.getNew("/customers", "customer")
|
||||
|
||||
expect(newRecord.surname).toBe(null);
|
||||
expect(newRecord.isalive).toBe(true);
|
||||
expect(newRecord.createddate).toBe(null);
|
||||
expect(newRecord.age).toBe(null);
|
||||
});
|
||||
|
||||
it("should create object with all declared fields, and use inital values", async () => {
|
||||
const {recordApi} = await setupApphierarchy(templateApi => {
|
||||
const hierarchy = basicAppHierarchyCreator_WithFields(templateApi);
|
||||
const {customerRecord} = hierarchy;
|
||||
|
||||
customerRecord.fields = [];
|
||||
|
||||
const newField = getNewFieldAndAdd(templateApi, customerRecord);
|
||||
newField("surname", "string", "hello");
|
||||
newField("isalive", "bool", "true");
|
||||
newField("age", "number", "999");
|
||||
|
||||
return hierarchy;
|
||||
});
|
||||
|
||||
const newRecord = recordApi.getNew("/customers", "customer")
|
||||
|
||||
expect(newRecord.surname).toBe("hello");
|
||||
expect(newRecord.isalive).toBe(true);
|
||||
expect(newRecord.age).toBe(999);
|
||||
});
|
||||
|
||||
it("should add a function 'isNew' which always returns true", async () => {
|
||||
const {recordApi} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
||||
const record = recordApi.getNew("/customers", "customer");
|
||||
|
||||
expect(record.isNew).toBeDefined();
|
||||
expect(isBoolean(record.isNew)).toBeTruthy();
|
||||
expect(record.isNew).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should add a function 'type' returns type", async () => {
|
||||
const {recordApi} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
||||
const record = recordApi.getNew("/customers", "customer");
|
||||
|
||||
expect(record.type).toBeDefined();
|
||||
expect(isNonEmptyString(record.type)).toBeTruthy();
|
||||
expect(record.type).toBe("customer");
|
||||
});
|
||||
|
||||
it("should throw error, user user does not have permission", async () => {
|
||||
const {recordApi, app, appHierarchy} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
||||
app.removePermission(permission.createRecord.get(appHierarchy.customerRecord.nodeKey()));
|
||||
expect(() => recordApi.getNew("/customers", "customer")).toThrow(/Unauthorized/);
|
||||
});
|
||||
|
||||
it("should not depend on having any other permissions", async () => {
|
||||
const {recordApi, app, appHierarchy} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
||||
app.withOnlyThisPermission(permission.createRecord.get(appHierarchy.customerRecord.nodeKey()));
|
||||
recordApi.getNew("/customers", "customer");
|
||||
});
|
||||
|
||||
it("for 'single record' type, should create with key ending in node name", async () => {
|
||||
const {appHierarchy} = await setupApphierarchy(basicAppHierarchyCreator_WithFields);
|
||||
const {settingsRecord} = appHierarchy;
|
||||
const result = _getNew(settingsRecord, "");
|
||||
expect(result.key).toBe("/settings")
|
||||
})
|
||||
});
|
||||
|
||||
describe('recordApi > save then load', () => {
|
||||
|
||||
|
@ -292,7 +206,7 @@ describe("save", () => {
|
|||
const record = recordApi.getNew("/customers", "customer");
|
||||
record.surname = "Ledog";
|
||||
|
||||
const savedRecord = await recordApi.save(record);
|
||||
await recordApi.save(record);
|
||||
expect(await recordApi._storeHandle.exists(`${record.key}/invoice_index/index.csv`)).toBeTruthy()
|
||||
expect(await recordApi._storeHandle.exists(`${record.key}/invoice_index`)).toBeTruthy()
|
||||
expect(await recordApi._storeHandle.exists(`${record.key}/invoices`)).toBeTruthy()
|
||||
|
@ -313,7 +227,7 @@ describe("save", () => {
|
|||
const record = recordApi.getNew("/customers", "customer");
|
||||
record.surname = "Ledog";
|
||||
|
||||
const savedRecord = await recordApi.save(record);
|
||||
await recordApi.save(record);
|
||||
expect(await recordApi._storeHandle.exists(`${record.key}`)).toBeTruthy();
|
||||
expect(await recordApi._storeHandle.exists(`${record.key}/record.json`)).toBeTruthy();
|
||||
});
|
File diff suppressed because one or more lines are too long
|
@ -9,41 +9,41 @@ h4.svelte-sqtlby{margin-top:20px}
|
|||
.root.svelte-apja7r{height:100%;position:relative}.actions-header.svelte-apja7r{flex:0 1 auto}.node-view.svelte-apja7r{overflow-y:auto;flex:1 1 auto}
|
||||
.items-root.svelte-19lmivt{display:flex;flex-direction:column;max-height:100%;height:100%;background-color:var(--secondary5)}.nav-group-header.svelte-19lmivt{display:grid;grid-template-columns:[icon] auto [title] 1fr [button] auto;padding:2rem 1rem 0rem 1rem;font-size:.9rem;font-weight:bold}.nav-group-header.svelte-19lmivt>div.svelte-19lmivt:nth-child(1){padding:0rem .7rem 0rem 0rem;vertical-align:bottom;grid-column-start:icon;margin-right:5px}.nav-group-header.svelte-19lmivt>div.svelte-19lmivt:nth-child(2){margin-left:5px;vertical-align:bottom;grid-column-start:title;margin-top:auto}.nav-group-header.svelte-19lmivt>div.svelte-19lmivt:nth-child(3){vertical-align:bottom;grid-column-start:button;cursor:pointer;color:var(--primary75)}.nav-group-header.svelte-19lmivt>div.svelte-19lmivt:nth-child(3):hover{color:var(--primary75)}.hierarchy-title.svelte-19lmivt{flex:auto 1 1}.hierarchy.svelte-19lmivt{display:flex;flex-direction:column;flex:1 0 auto;height:100px}.hierarchy-items-container.svelte-19lmivt{flex:1 1 auto;overflow-y:auto}
|
||||
.root.svelte-nd1yft{height:100%;position:relative;padding:1.5rem}
|
||||
.root.svelte-wfv60d{height:100%;position:relative;padding:1.5rem}.actions-header.svelte-wfv60d{flex:0 1 auto}.node-view.svelte-wfv60d{overflow-y:auto;flex:1 1 auto}
|
||||
.uk-modal-dialog.svelte-vwwrf9{border-radius:.3rem}
|
||||
.root.svelte-1r2dipt{color:var(--secondary50);font-size:.9rem;font-weight:bold}.hierarchy-item.svelte-1r2dipt{cursor:pointer;padding:5px 0px}.hierarchy-item.svelte-1r2dipt:hover{color:var(--secondary)}.component.svelte-1r2dipt{margin-left:5px}.currentfolder.svelte-1r2dipt{color:var(--secondary100)}.selected.svelte-1r2dipt{color:var(--primary100);font-weight:bold}.title.svelte-1r2dipt{margin-left:10px}
|
||||
.root.svelte-117bbrk{padding-bottom:10px;padding-left:10px;font-size:.9rem;color:var(--secondary50);font-weight:bold}.hierarchy-item.svelte-117bbrk{cursor:pointer;padding:5px 0px}.hierarchy-item.svelte-117bbrk:hover{color:var(--secondary100)}.component.svelte-117bbrk{margin-left:5px}.selected.svelte-117bbrk{color:var(--primary100);font-weight:bold}.title.svelte-117bbrk{margin-left:10px}
|
||||
.section-container.svelte-yk1mmr{padding:15px;border-style:dotted;border-width:1px;border-color:var(--lightslate);border-radius:2px}.section-container.svelte-yk1mmr:nth-child(1){margin-bottom:15px}.row-text.svelte-yk1mmr{margin-right:15px;color:var(--primary100)}input.svelte-yk1mmr{margin-right:15px}p.svelte-yk1mmr>span.svelte-yk1mmr{margin-left:30px}.header.svelte-yk1mmr{display:grid;grid-template-columns:[title] 1fr [icon] auto}.header.svelte-yk1mmr>div.svelte-yk1mmr:nth-child(1){grid-column-start:title}.header.svelte-yk1mmr>div.svelte-yk1mmr:nth-child(2){grid-column-start:icon}
|
||||
.root.svelte-wfv60d{height:100%;position:relative;padding:1.5rem}.actions-header.svelte-wfv60d{flex:0 1 auto}.node-view.svelte-wfv60d{overflow-y:auto;flex:1 1 auto}
|
||||
.root.svelte-1r2dipt{color:var(--secondary50);font-size:.9rem;font-weight:bold}.hierarchy-item.svelte-1r2dipt{cursor:pointer;padding:5px 0px}.hierarchy-item.svelte-1r2dipt:hover{color:var(--secondary)}.component.svelte-1r2dipt{margin-left:5px}.currentfolder.svelte-1r2dipt{color:var(--secondary100)}.selected.svelte-1r2dipt{color:var(--primary100);font-weight:bold}.title.svelte-1r2dipt{margin-left:10px}
|
||||
h1.svelte-16jkjx9{font-size:1.2em}
|
||||
.component-container.svelte-teqoiq{grid-row-start:middle;grid-column-start:middle;position:relative;overflow:hidden;padding-top:56.25%;margin:auto}.component-container.svelte-teqoiq iframe.svelte-teqoiq{border:0;height:100%;left:0;position:absolute;top:0;width:100%}
|
||||
.uk-modal-dialog.svelte-vwwrf9{border-radius:.3rem}
|
||||
.section-container.svelte-yk1mmr{padding:15px;border-style:dotted;border-width:1px;border-color:var(--lightslate);border-radius:2px}.section-container.svelte-yk1mmr:nth-child(1){margin-bottom:15px}.row-text.svelte-yk1mmr{margin-right:15px;color:var(--primary100)}input.svelte-yk1mmr{margin-right:15px}p.svelte-yk1mmr>span.svelte-yk1mmr{margin-left:30px}.header.svelte-yk1mmr{display:grid;grid-template-columns:[title] 1fr [icon] auto}.header.svelte-yk1mmr>div.svelte-yk1mmr:nth-child(1){grid-column-start:title}.header.svelte-yk1mmr>div.svelte-yk1mmr:nth-child(2){grid-column-start:icon}
|
||||
.root.svelte-1ersoxu{padding:15px}.help-text.svelte-1ersoxu{color:var(--slate);font-size:10pt}
|
||||
.component-container.svelte-teqoiq{grid-row-start:middle;grid-column-start:middle;position:relative;overflow:hidden;padding-top:56.25%;margin:auto}.component-container.svelte-teqoiq iframe.svelte-teqoiq{border:0;height:100%;left:0;position:absolute;top:0;width:100%}
|
||||
.root.svelte-1abif7s{height:100%;display:flex;flex-direction:column}.padding.svelte-1abif7s{padding:1rem 1rem 0rem 1rem}.info-text.svelte-1abif7s{color:var(--secondary100);font-size:.8rem !important;font-weight:bold}.title.svelte-1abif7s{padding:2rem 1rem 1rem 1rem;display:grid;grid-template-columns:[name] 1fr [actions] auto;color:var(--secondary100);font-size:.9rem;font-weight:bold}.title.svelte-1abif7s>div.svelte-1abif7s:nth-child(1){grid-column-start:name;color:var(--secondary100)}.title.svelte-1abif7s>div.svelte-1abif7s:nth-child(2){grid-column-start:actions}.section-header.svelte-1abif7s{display:grid;grid-template-columns:[name] 1fr [actions] auto;color:var(--secondary50);font-size:.9rem;font-weight:bold;vertical-align:middle}.component-props-container.svelte-1abif7s{flex:1 1 auto;overflow-y:auto}
|
||||
.root.svelte-ehsf0i{display:block;font-size:.9rem;width:100%;cursor:pointer;font-weight:bold}.title.svelte-ehsf0i{font:var(--fontblack);padding-top:10px;padding-right:5px;padding-bottom:10px;color:var(--secondary100)}.title.svelte-ehsf0i:hover{background-color:var(--secondary10)}
|
||||
.root.svelte-18xd5y3{height:100%;padding:2rem}.settings-title.svelte-18xd5y3{font-weight:700}.title.svelte-18xd5y3{margin:3rem 0rem 0rem 0rem;font-weight:700}.recordkey.svelte-18xd5y3{font-size:14px;font-weight:600;color:var(--primary100)}.fields-table.svelte-18xd5y3{margin:1rem 1rem 0rem 0rem;border-collapse:collapse}.add-field-button.svelte-18xd5y3{cursor:pointer}.edit-button.svelte-18xd5y3{cursor:pointer;color:var(--secondary25)}.edit-button.svelte-18xd5y3:hover{cursor:pointer;color:var(--secondary75)}th.svelte-18xd5y3{text-align:left}td.svelte-18xd5y3{padding:1rem 5rem 1rem 0rem;margin:0;font-size:14px;font-weight:500}.field-label.svelte-18xd5y3{font-size:14px;font-weight:500}thead.svelte-18xd5y3>tr.svelte-18xd5y3{border-width:0px 0px 1px 0px;border-style:solid;border-color:var(--secondary75);margin-bottom:20px}tbody.svelte-18xd5y3>tr.svelte-18xd5y3{border-width:0px 0px 1px 0px;border-style:solid;border-color:var(--primary10)}tbody.svelte-18xd5y3>tr.svelte-18xd5y3:hover{background-color:var(--primary10)}tbody.svelte-18xd5y3>tr:hover .edit-button.svelte-18xd5y3{color:var(--secondary75)}.index-container.svelte-18xd5y3{border-style:solid;border-width:0 0 1px 0;border-color:var(--secondary25);padding:10px;margin-bottom:5px}.index-label.svelte-18xd5y3{color:var(--slate)}.index-name.svelte-18xd5y3{font-weight:bold;color:var(--primary100)}.index-container.svelte-18xd5y3 code.svelte-18xd5y3{margin:0;display:inline;background-color:var(--primary10);color:var(--secondary100);padding:3px}.index-field-row.svelte-18xd5y3{margin:1rem 0rem 0rem 0rem}.no-indexes.svelte-18xd5y3{margin:1rem 0rem 0rem 0rem;font-family:var(--fontnormal);font-size:14px}
|
||||
.root.svelte-pq2tmv{height:100%;padding:15px}.allowed-records.svelte-pq2tmv{margin:20px 0px}.allowed-records.svelte-pq2tmv>span.svelte-pq2tmv{margin-right:30px}
|
||||
.root.svelte-wgyofl{padding:1.5rem;width:100%;align-items:right}
|
||||
.dropdown-background.svelte-11ifkop{position:fixed;top:0;left:0;width:100vw;height:100vh}.root.svelte-11ifkop{cursor:pointer;z-index:1}.dropdown-content.svelte-11ifkop{position:absolute;background-color:var(--white);min-width:160px;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);z-index:1;font-weight:normal;border-style:solid;border-width:1px;border-color:var(--secondary10)}.dropdown-content.svelte-11ifkop:not(:focus){display:none}.action-row.svelte-11ifkop{padding:7px 10px;cursor:pointer}.action-row.svelte-11ifkop:hover{background-color:var(--primary100);color:var(--white)}
|
||||
.root.svelte-pq2tmv{height:100%;padding:15px}.allowed-records.svelte-pq2tmv{margin:20px 0px}.allowed-records.svelte-pq2tmv>span.svelte-pq2tmv{margin-right:30px}
|
||||
.root.svelte-17ju2r{display:block;font-size:.9rem;width:100%;cursor:pointer;color:var(--secondary50);font-weight:500}.title.svelte-17ju2r{padding-top:.5rem;padding-right:.5rem}.title.svelte-17ju2r:hover{background-color:var(--secondary10)}.active.svelte-17ju2r{background-color:var(--primary10)}
|
||||
.nav-item.svelte-1i5jqm7{padding:1.5rem 1rem 0rem 1rem;font-size:.9rem;font-weight:bold;cursor:pointer;flex:0 0 auto}.nav-item.svelte-1i5jqm7:hover{background-color:var(--primary10)}.active.svelte-1i5jqm7{background-color:var(--primary10)}
|
||||
.root.svelte-x3bf9z{display:flex}.root.svelte-x3bf9z:last-child{border-radius:0 var(--borderradius) var(--borderradius) 0}.root.svelte-x3bf9z:first-child{border-radius:var(--borderradius) 0 0 var(--borderradius)}.root.svelte-x3bf9z:not(:first-child):not(:last-child){border-radius:0}
|
||||
.edit-button.svelte-zm41av{cursor:pointer;color:var(--secondary25)}.title.svelte-zm41av{margin:3rem 0rem 0rem 0rem;font-weight:700}.table-content.svelte-zm41av{font-weight:500;font-size:.9rem}tr.svelte-zm41av:hover .edit-button.svelte-zm41av{color:var(--secondary75)}
|
||||
.nav-item.svelte-1i5jqm7{padding:1.5rem 1rem 0rem 1rem;font-size:.9rem;font-weight:bold;cursor:pointer;flex:0 0 auto}.nav-item.svelte-1i5jqm7:hover{background-color:var(--primary10)}.active.svelte-1i5jqm7{background-color:var(--primary10)}
|
||||
.edit-button.svelte-lhfdtn{cursor:pointer;color:var(--secondary25)}tr.svelte-lhfdtn:hover .edit-button.svelte-lhfdtn{color:var(--secondary75)}.title.svelte-lhfdtn{margin:3rem 0rem 0rem 0rem;font-weight:700}.table-content.svelte-lhfdtn{font-weight:500;font-size:.9rem}
|
||||
.info-text.svelte-1gx0gkl{font-size:0.7rem;color:var(--secondary50)}
|
||||
.root.svelte-47ohpz{font-size:10pt}.padding.svelte-47ohpz{padding:0 10px}.inherited-title.svelte-47ohpz{padding:1rem 1rem 1rem 1rem;display:grid;grid-template-columns:[name] 1fr [actions] auto;color:var(--secondary100);font-size:.9rem;font-weight:bold}.inherited-title.svelte-47ohpz>div.svelte-47ohpz:nth-child(1){grid-column-start:name;color:var(--secondary50)}.inherited-title.svelte-47ohpz>div.svelte-47ohpz:nth-child(2){grid-column-start:actions;color:var(--secondary100)}
|
||||
.library-header.svelte-chhyel{font-size:1.1em;border-color:var(--primary25);border-width:1px 0px;border-style:solid;background-color:var(--primary10);padding:5px 0}.library-container.svelte-chhyel{padding:0 0 10px 10px}.inner-header.svelte-chhyel{font-size:0.9em;font-weight:bold;margin-top:7px;margin-bottom:3px}.component.svelte-chhyel{padding:2px 0px;cursor:pointer}.component.svelte-chhyel:hover{background-color:var(--lightslate)}.component.svelte-chhyel>.name.svelte-chhyel{color:var(--secondary100);display:inline-block}.component.svelte-chhyel>.description.svelte-chhyel{font-size:0.8em;color:var(--secondary75);display:inline-block;margin-left:10px}
|
||||
.edit-button.svelte-zm41av{cursor:pointer;color:var(--secondary25)}.title.svelte-zm41av{margin:3rem 0rem 0rem 0rem;font-weight:700}.table-content.svelte-zm41av{font-weight:500;font-size:.9rem}tr.svelte-zm41av:hover .edit-button.svelte-zm41av{color:var(--secondary75)}
|
||||
.component.svelte-3sgo90{padding:5px 0}.component.svelte-3sgo90 .title.svelte-3sgo90{width:300px
|
||||
}.component.svelte-3sgo90>.description.svelte-3sgo90{font-size:0.8em;color:var(--secondary75)}.button-container.svelte-3sgo90{text-align:right;margin-top:20px}.error.svelte-3sgo90{font-size:10pt;color:red}
|
||||
.root.svelte-47ohpz{font-size:10pt}.padding.svelte-47ohpz{padding:0 10px}.inherited-title.svelte-47ohpz{padding:1rem 1rem 1rem 1rem;display:grid;grid-template-columns:[name] 1fr [actions] auto;color:var(--secondary100);font-size:.9rem;font-weight:bold}.inherited-title.svelte-47ohpz>div.svelte-47ohpz:nth-child(1){grid-column-start:name;color:var(--secondary50)}.inherited-title.svelte-47ohpz>div.svelte-47ohpz:nth-child(2){grid-column-start:actions;color:var(--secondary100)}
|
||||
.info-text.svelte-1gx0gkl{font-size:0.7rem;color:var(--secondary50)}
|
||||
.library-header.svelte-chhyel{font-size:1.1em;border-color:var(--primary25);border-width:1px 0px;border-style:solid;background-color:var(--primary10);padding:5px 0}.library-container.svelte-chhyel{padding:0 0 10px 10px}.inner-header.svelte-chhyel{font-size:0.9em;font-weight:bold;margin-top:7px;margin-bottom:3px}.component.svelte-chhyel{padding:2px 0px;cursor:pointer}.component.svelte-chhyel:hover{background-color:var(--lightslate)}.component.svelte-chhyel>.name.svelte-chhyel{color:var(--secondary100);display:inline-block}.component.svelte-chhyel>.description.svelte-chhyel{font-size:0.8em;color:var(--secondary75);display:inline-block;margin-left:10px}
|
||||
.title.svelte-dhe1ge{padding:3px;background-color:white;color:var(--secondary100);border-style:solid;border-width:1px 0 0 0;border-color:var(--lightslate)}.title.svelte-dhe1ge>span.svelte-dhe1ge{margin-left:10px}
|
||||
textarea.svelte-di7k4b{padding:3px;margin-top:5px;margin-bottom:10px;background:var(--lightslate);color:var(--white);font-family:'Courier New', Courier, monospace;width:95%;height:100px;border-radius:5px}
|
||||
.error-container.svelte-ole1mk{padding:10px;border-style:solid;border-color:var(--deletion100);border-radius:var(--borderradiusall);background:var(--deletion75)}.error-row.svelte-ole1mk{padding:5px 0px}
|
||||
input.svelte-9fre0g{margin-right:7px}
|
||||
.error-container.svelte-ole1mk{padding:10px;border-style:solid;border-color:var(--deletion100);border-radius:var(--borderradiusall);background:var(--deletion75)}.error-row.svelte-ole1mk{padding:5px 0px}
|
||||
.root.svelte-ogh8o0{display:grid;grid-template-columns:[name] 1fr [actions] auto}.root.svelte-ogh8o0>div.svelte-ogh8o0:nth-child(1){grid-column-start:name;color:var(--secondary50)}.root.svelte-ogh8o0>div.svelte-ogh8o0:nth-child(2){grid-column-start:actions}.selectedname.svelte-ogh8o0{font-weight:bold;color:var(--secondary)}
|
||||
.root.svelte-16sjty9{padding:2rem;border-radius:2rem}.uk-grid-small.svelte-16sjty9{padding:1rem}.option-container.svelte-16sjty9{border-style:dotted;border-width:1px;border-color:var(--primary75);padding:3px;margin-right:5px}
|
||||
.root.svelte-1v0yya9{padding:1rem 1rem 0rem 1rem}.prop-label.svelte-1v0yya9{font-size:0.8rem;color:var(--secondary100);font-weight:bold}
|
||||
.root.svelte-ogh8o0{display:grid;grid-template-columns:[name] 1fr [actions] auto}.root.svelte-ogh8o0>div.svelte-ogh8o0:nth-child(1){grid-column-start:name;color:var(--secondary50)}.root.svelte-ogh8o0>div.svelte-ogh8o0:nth-child(2){grid-column-start:actions}.selectedname.svelte-ogh8o0{font-weight:bold;color:var(--secondary)}
|
||||
textarea.svelte-1kv2xk7{width:300px;height:200px}
|
||||
.addelement-container.svelte-r1ft9p{cursor:pointer;padding:3px 0px;text-align:center}.addelement-container.svelte-r1ft9p:hover{background-color:var(--primary25);margin-top:5px}.control-container.svelte-r1ft9p{padding-left:3px;background:var(--secondary10)}.separator.svelte-r1ft9p{width:60%;margin:10px auto;border-style:solid;border-width:1px 0 0 0;border-color:var(--primary25)}
|
||||
.unbound-container.svelte-jubmd5{display:flex;margin:.5rem 0rem .5rem 0rem}.unbound-container.svelte-jubmd5>.svelte-jubmd5:nth-child(1){width:auto;flex:1 0 auto;font-size:0.8rem;color:var(--secondary100);border-radius:.2rem}.bound-header.svelte-jubmd5{display:flex}.bound-header.svelte-jubmd5>div.svelte-jubmd5:nth-child(1){flex:1 0 auto;width:30px;color:var(--secondary50);padding-left:5px}.binding-prop-label.svelte-jubmd5{color:var(--secondary50)}
|
||||
.addelement-container.svelte-199q8jr{cursor:pointer;padding:3px 0px;text-align:center}.addelement-container.svelte-199q8jr:hover{background-color:var(--primary25)}.item-container.svelte-199q8jr{padding-left:3px;background:var(--secondary10)}
|
||||
.unbound-container.svelte-jubmd5{display:flex;margin:.5rem 0rem .5rem 0rem}.unbound-container.svelte-jubmd5>.svelte-jubmd5:nth-child(1){width:auto;flex:1 0 auto;font-size:0.8rem;color:var(--secondary100);border-radius:.2rem}.bound-header.svelte-jubmd5{display:flex}.bound-header.svelte-jubmd5>div.svelte-jubmd5:nth-child(1){flex:1 0 auto;width:30px;color:var(--secondary50);padding-left:5px}.binding-prop-label.svelte-jubmd5{color:var(--secondary50)}
|
||||
.addelement-container.svelte-r1ft9p{cursor:pointer;padding:3px 0px;text-align:center}.addelement-container.svelte-r1ft9p:hover{background-color:var(--primary25);margin-top:5px}.control-container.svelte-r1ft9p{padding-left:3px;background:var(--secondary10)}.separator.svelte-r1ft9p{width:60%;margin:10px auto;border-style:solid;border-width:1px 0 0 0;border-color:var(--primary25)}
|
||||
.type-selector-container.svelte-1b6pj9u{display:flex}.type-selector.svelte-1b6pj9u{border-color:var(--primary50);border-radius:2px;width:50px;flex:1 0 auto}
|
||||
|
||||
/*# sourceMappingURL=bundle.css.map */
|
File diff suppressed because one or more lines are too long
|
@ -21231,7 +21231,9 @@
|
|||
]);
|
||||
|
||||
record.id = `${recordNode.nodeId}-${shortid_1()}`;
|
||||
record.key = joinKey(collectionKey, record.id);
|
||||
record.key = isSingleRecord(recordNode)
|
||||
? joinKey(collectionKey, recordNode.name)
|
||||
: joinKey(collectionKey, record.id);
|
||||
record.isNew = true;
|
||||
record.type = recordNode.name;
|
||||
return record;
|
||||
|
@ -26873,7 +26875,15 @@
|
|||
if (isIndex(obj))
|
||||
// Q: why are indexes not children ?
|
||||
// A: because they cannot have children of their own.
|
||||
{ parent.indexes.push(obj); } else if (isaggregateGroup(obj)) { parent.aggregateGroups.push(obj); } else { parent.children.push(obj); }
|
||||
{
|
||||
parent.indexes.push(obj);
|
||||
}
|
||||
else if (isaggregateGroup(obj))
|
||||
{
|
||||
parent.aggregateGroups.push(obj);
|
||||
} else {
|
||||
parent.children.push(obj);
|
||||
}
|
||||
|
||||
if (isRecord(obj)) {
|
||||
const defaultIndex = lodash_15(
|
||||
|
@ -29310,7 +29320,7 @@
|
|||
existingNode.parent().children = pipe$1(existingNode.parent().children, [
|
||||
fp_8(c => c.nodeId !== existingNode.nodeId)
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// should add node into existing hierarchy
|
||||
const cloned = fp_4(s.currentNode);
|
||||
|
@ -29329,6 +29339,13 @@
|
|||
fp_52(newIndexOfchild)
|
||||
]);
|
||||
|
||||
if(!existingNode && s.currentNode.type === "record") {
|
||||
const defaultIndex = templateApi(s.hierarchy)
|
||||
.getNewIndexTemplate(cloned.parent());
|
||||
defaultIndex.name = `all_${cloned.collectionName}`;
|
||||
defaultIndex.allowedRecordNodeIds = [cloned.nodeId];
|
||||
}
|
||||
|
||||
s.currentNodeIsNew = false;
|
||||
|
||||
savePackage(store, s);
|
||||
|
@ -49170,7 +49187,7 @@
|
|||
return child_ctx;
|
||||
}
|
||||
|
||||
// (74:8) {#each events as ev}
|
||||
// (75:8) {#each events as ev}
|
||||
function create_each_block_1$4(ctx) {
|
||||
var option, t_value = ctx.ev.name + "", t, option_value_value;
|
||||
|
||||
|
@ -49180,7 +49197,7 @@
|
|||
t = text(t_value);
|
||||
option.__value = option_value_value = ctx.ev.name;
|
||||
option.value = option.__value;
|
||||
add_location(option, file$e, 74, 8, 1965);
|
||||
add_location(option, file$e, 75, 8, 1992);
|
||||
},
|
||||
|
||||
m: function mount(target, anchor) {
|
||||
|
@ -49206,11 +49223,11 @@
|
|||
}
|
||||
}
|
||||
};
|
||||
dispatch_dev("SvelteRegisterBlock", { block, id: create_each_block_1$4.name, type: "each", source: "(74:8) {#each events as ev}", ctx });
|
||||
dispatch_dev("SvelteRegisterBlock", { block, id: create_each_block_1$4.name, type: "each", source: "(75:8) {#each events as ev}", ctx });
|
||||
return block;
|
||||
}
|
||||
|
||||
// (85:0) {#if parameters}
|
||||
// (86:0) {#if parameters}
|
||||
function create_if_block$6(ctx) {
|
||||
var each_1_anchor, current;
|
||||
|
||||
|
@ -49297,11 +49314,11 @@
|
|||
}
|
||||
}
|
||||
};
|
||||
dispatch_dev("SvelteRegisterBlock", { block, id: create_if_block$6.name, type: "if", source: "(85:0) {#if parameters}", ctx });
|
||||
dispatch_dev("SvelteRegisterBlock", { block, id: create_if_block$6.name, type: "if", source: "(86:0) {#if parameters}", ctx });
|
||||
return block;
|
||||
}
|
||||
|
||||
// (86:0) {#each parameters as p, index}
|
||||
// (87:0) {#each parameters as p, index}
|
||||
function create_each_block$6(ctx) {
|
||||
var div, t0_value = ctx.p.name + "", t0, t1, current;
|
||||
|
||||
|
@ -49319,7 +49336,7 @@
|
|||
t0 = text(t0_value);
|
||||
t1 = space();
|
||||
statebindingcontrol.$$.fragment.c();
|
||||
add_location(div, file$e, 87, 0, 2206);
|
||||
add_location(div, file$e, 88, 0, 2233);
|
||||
},
|
||||
|
||||
m: function mount(target, anchor) {
|
||||
|
@ -49361,12 +49378,12 @@
|
|||
destroy_component(statebindingcontrol, detaching);
|
||||
}
|
||||
};
|
||||
dispatch_dev("SvelteRegisterBlock", { block, id: create_each_block$6.name, type: "each", source: "(86:0) {#each parameters as p, index}", ctx });
|
||||
dispatch_dev("SvelteRegisterBlock", { block, id: create_each_block$6.name, type: "each", source: "(87:0) {#each parameters as p, index}", ctx });
|
||||
return block;
|
||||
}
|
||||
|
||||
function create_fragment$d(ctx) {
|
||||
var div, select, select_value_value, t0, t1, if_block_anchor, current, dispose;
|
||||
var div, select, option, select_value_value, t0, t1, if_block_anchor, current, dispose;
|
||||
|
||||
let each_value_1 = ctx.events;
|
||||
|
||||
|
@ -49388,6 +49405,7 @@
|
|||
c: function create() {
|
||||
div = element("div");
|
||||
select = element("select");
|
||||
option = element("option");
|
||||
|
||||
for (let i_1 = 0; i_1 < each_blocks.length; i_1 += 1) {
|
||||
each_blocks[i_1].c();
|
||||
|
@ -49398,6 +49416,9 @@
|
|||
t1 = space();
|
||||
if (if_block) if_block.c();
|
||||
if_block_anchor = empty();
|
||||
option.__value = "";
|
||||
option.value = option.__value;
|
||||
add_location(option, file$e, 73, 8, 1935);
|
||||
attr_dev(select, "class", "type-selector uk-select uk-form-small svelte-1b6pj9u");
|
||||
add_location(select, file$e, 72, 4, 1823);
|
||||
attr_dev(div, "class", "type-selector-container svelte-1b6pj9u");
|
||||
|
@ -49412,6 +49433,7 @@
|
|||
m: function mount(target, anchor) {
|
||||
insert_dev(target, div, anchor);
|
||||
append_dev(div, select);
|
||||
append_dev(select, option);
|
||||
|
||||
for (let i_1 = 0; i_1 < each_blocks.length; i_1 += 1) {
|
||||
each_blocks[i_1].m(select, null);
|
||||
|
@ -49419,10 +49441,10 @@
|
|||
|
||||
select_value_value = ctx.eventType;
|
||||
for (var i = 0; i < select.options.length; i += 1) {
|
||||
var option = select.options[i];
|
||||
var option_1 = select.options[i];
|
||||
|
||||
if (option.__value === select_value_value) {
|
||||
option.selected = true;
|
||||
if (option_1.__value === select_value_value) {
|
||||
option_1.selected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -49460,10 +49482,10 @@
|
|||
|
||||
if ((!current || changed.eventType) && select_value_value !== (select_value_value = ctx.eventType)) {
|
||||
for (var i = 0; i < select.options.length; i += 1) {
|
||||
var option = select.options[i];
|
||||
var option_1 = select.options[i];
|
||||
|
||||
if (option.__value === select_value_value) {
|
||||
option.selected = true;
|
||||
if (option_1.__value === select_value_value) {
|
||||
option_1.selected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -52435,10 +52457,10 @@
|
|||
|
||||
attr_dev(div0, "class", "uk-modal-dialog uk-modal-body svelte-vwwrf9");
|
||||
attr_dev(div0, "uk-overflow-auto", "");
|
||||
add_location(div0, file$k, 28, 4, 487);
|
||||
add_location(div0, file$k, 28, 4, 500);
|
||||
attr_dev(div1, "uk-modal", "");
|
||||
attr_dev(div1, "id", ctx.id);
|
||||
add_location(div1, file$k, 27, 0, 443);
|
||||
add_location(div1, file$k, 27, 0, 456);
|
||||
},
|
||||
|
||||
l: function claim(nodes) {
|
||||
|
@ -52535,11 +52557,12 @@
|
|||
};
|
||||
|
||||
$$self.$$.update = ($$dirty = { ukModal: 1, listenerAdded: 1, onClosed: 1, isOpen: 1 }) => {
|
||||
if ($$dirty.ukModal || $$dirty.listenerAdded || $$dirty.onClosed) { if(ukModal && !listenerAdded) {
|
||||
$$invalidate('listenerAdded', listenerAdded = true);
|
||||
ukModal.addEventListener("hide", onClosed);
|
||||
} }
|
||||
if ($$dirty.ukModal || $$dirty.isOpen) { {
|
||||
if ($$dirty.ukModal || $$dirty.listenerAdded || $$dirty.onClosed || $$dirty.isOpen) { {
|
||||
if(ukModal && !listenerAdded) {
|
||||
$$invalidate('listenerAdded', listenerAdded = true);
|
||||
ukModal.addEventListener("hide", onClosed);
|
||||
}
|
||||
|
||||
if(ukModal) {
|
||||
if(isOpen) {
|
||||
uikit.modal(ukModal).show();
|
||||
|
@ -55814,7 +55837,7 @@
|
|||
return child_ctx;
|
||||
}
|
||||
|
||||
// (60:12) {#each $store.hierarchy.children as record}
|
||||
// (83:12) {#each $store.hierarchy.children as record}
|
||||
function create_each_block_1$8(ctx) {
|
||||
var current;
|
||||
|
||||
|
@ -55855,11 +55878,11 @@
|
|||
destroy_component(hierarchyrow, detaching);
|
||||
}
|
||||
};
|
||||
dispatch_dev("SvelteRegisterBlock", { block, id: create_each_block_1$8.name, type: "each", source: "(60:12) {#each $store.hierarchy.children as record}", ctx });
|
||||
dispatch_dev("SvelteRegisterBlock", { block, id: create_each_block_1$8.name, type: "each", source: "(83:12) {#each $store.hierarchy.children as record}", ctx });
|
||||
return block;
|
||||
}
|
||||
|
||||
// (65:12) {#each $store.hierarchy.indexes as index}
|
||||
// (88:12) {#each $store.hierarchy.indexes as index}
|
||||
function create_each_block$d(ctx) {
|
||||
var current;
|
||||
|
||||
|
@ -55900,7 +55923,7 @@
|
|||
destroy_component(hierarchyrow, detaching);
|
||||
}
|
||||
};
|
||||
dispatch_dev("SvelteRegisterBlock", { block, id: create_each_block$d.name, type: "each", source: "(65:12) {#each $store.hierarchy.indexes as index}", ctx });
|
||||
dispatch_dev("SvelteRegisterBlock", { block, id: create_each_block$d.name, type: "each", source: "(88:12) {#each $store.hierarchy.indexes as index}", ctx });
|
||||
return block;
|
||||
}
|
||||
|
||||
|
@ -55982,19 +56005,19 @@
|
|||
t6 = space();
|
||||
navitem1.$$.fragment.c();
|
||||
attr_dev(div0, "class", "svelte-19lmivt");
|
||||
add_location(div0, file$u, 52, 16, 1390);
|
||||
add_location(div0, file$u, 75, 16, 1728);
|
||||
attr_dev(div1, "class", "hierarchy-title svelte-19lmivt");
|
||||
add_location(div1, file$u, 53, 16, 1450);
|
||||
add_location(div1, file$u, 76, 16, 1788);
|
||||
attr_dev(div2, "class", "nav-group-header svelte-19lmivt");
|
||||
add_location(div2, file$u, 51, 12, 1343);
|
||||
add_location(div2, file$u, 74, 12, 1681);
|
||||
attr_dev(div3, "class", "components-list-container");
|
||||
add_location(div3, file$u, 50, 8, 1291);
|
||||
add_location(div3, file$u, 73, 8, 1629);
|
||||
attr_dev(div4, "class", "hierarchy-items-container svelte-19lmivt");
|
||||
add_location(div4, file$u, 58, 8, 1614);
|
||||
add_location(div4, file$u, 81, 8, 1952);
|
||||
attr_dev(div5, "class", "hierarchy svelte-19lmivt");
|
||||
add_location(div5, file$u, 49, 4, 1259);
|
||||
add_location(div5, file$u, 72, 4, 1597);
|
||||
attr_dev(div6, "class", "items-root svelte-19lmivt");
|
||||
add_location(div6, file$u, 48, 0, 1230);
|
||||
add_location(div6, file$u, 71, 0, 1568);
|
||||
},
|
||||
|
||||
l: function claim(nodes) {
|
||||
|
@ -56154,33 +56177,56 @@
|
|||
|
||||
|
||||
|
||||
const newRootRecord = () => {
|
||||
store.newRootRecord();
|
||||
};
|
||||
|
||||
const newRootIndex = () => {
|
||||
store.newRootIndex();
|
||||
};
|
||||
|
||||
const newChildRecord = () => {
|
||||
store.newChildRecord();
|
||||
};
|
||||
|
||||
const newChildIndex = () => {
|
||||
store.newChildIndex();
|
||||
};
|
||||
|
||||
const defaultNewChildActions = [
|
||||
{
|
||||
label:"New Root Index",
|
||||
onclick: store.newRootIndex
|
||||
},
|
||||
{
|
||||
label:"New Root Record",
|
||||
onclick: store.newRootRecord
|
||||
onclick: newRootRecord
|
||||
},
|
||||
{
|
||||
label:"New Root Index",
|
||||
onclick: newRootIndex
|
||||
}
|
||||
];
|
||||
|
||||
let newChildActions = defaultNewChildActions;
|
||||
|
||||
|
||||
store.subscribe(db => {
|
||||
if(!db.currentNode || hierarchyFunctions.isIndex(db.currentNode)) {
|
||||
$$invalidate('newChildActions', newChildActions = defaultNewChildActions);
|
||||
} else {
|
||||
$$invalidate('newChildActions', newChildActions = [
|
||||
{label:"New Root Record",
|
||||
onclick: store.newRootRecord},
|
||||
{label: `New Child Record of ${db.currentNode.name}`,
|
||||
onclick: store.newChildRecord},
|
||||
{label:"New Root Index",
|
||||
onclick: store.newRootIndex},
|
||||
{label: `New Index on ${db.currentNode.name}`,
|
||||
onclick: store.newChildIndex}
|
||||
{
|
||||
label:"New Root Record",
|
||||
onclick: newRootRecord
|
||||
},
|
||||
{
|
||||
label:"New Root Index",
|
||||
onclick: newRootIndex
|
||||
},
|
||||
{
|
||||
label: `New Child Record of ${db.currentNode.name}`,
|
||||
onclick: newChildRecord
|
||||
},
|
||||
{
|
||||
label: `New Index on ${db.currentNode.name}`,
|
||||
onclick: newChildIndex
|
||||
}
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
@ -60809,7 +60855,7 @@
|
|||
return child_ctx;
|
||||
}
|
||||
|
||||
// (93:8) {#if !record.isSingle}
|
||||
// (99:8) {#if !record.isSingle}
|
||||
function create_if_block_3$3(ctx) {
|
||||
var updating_text, t, updating_text_1, current;
|
||||
|
||||
|
@ -60894,11 +60940,11 @@
|
|||
destroy_component(textbox1, detaching);
|
||||
}
|
||||
};
|
||||
dispatch_dev("SvelteRegisterBlock", { block, id: create_if_block_3$3.name, type: "if", source: "(93:8) {#if !record.isSingle}", ctx });
|
||||
dispatch_dev("SvelteRegisterBlock", { block, id: create_if_block_3$3.name, type: "if", source: "(99:8) {#if !record.isSingle}", ctx });
|
||||
return block;
|
||||
}
|
||||
|
||||
// (131:4) {:else}
|
||||
// (137:4) {:else}
|
||||
function create_else_block_1$1(ctx) {
|
||||
var t;
|
||||
|
||||
|
@ -60919,11 +60965,11 @@
|
|||
}
|
||||
}
|
||||
};
|
||||
dispatch_dev("SvelteRegisterBlock", { block, id: create_else_block_1$1.name, type: "else", source: "(131:4) {:else}", ctx });
|
||||
dispatch_dev("SvelteRegisterBlock", { block, id: create_else_block_1$1.name, type: "else", source: "(137:4) {:else}", ctx });
|
||||
return block;
|
||||
}
|
||||
|
||||
// (104:4) {#if record.fields.length > 0}
|
||||
// (110:4) {#if record.fields.length > 0}
|
||||
function create_if_block_2$5(ctx) {
|
||||
var table, thead, tr, th0, t1, th1, t3, th2, t5, th3, t6, tbody;
|
||||
|
||||
|
@ -60957,21 +61003,21 @@
|
|||
each_blocks[i].c();
|
||||
}
|
||||
attr_dev(th0, "class", "svelte-18xd5y3");
|
||||
add_location(th0, file$A, 107, 16, 2954);
|
||||
add_location(th0, file$A, 113, 16, 3154);
|
||||
attr_dev(th1, "class", "svelte-18xd5y3");
|
||||
add_location(th1, file$A, 108, 16, 2984);
|
||||
add_location(th1, file$A, 114, 16, 3184);
|
||||
attr_dev(th2, "class", "svelte-18xd5y3");
|
||||
add_location(th2, file$A, 109, 16, 3014);
|
||||
add_location(th2, file$A, 115, 16, 3214);
|
||||
attr_dev(th3, "class", "svelte-18xd5y3");
|
||||
add_location(th3, file$A, 110, 16, 3047);
|
||||
add_location(th3, file$A, 116, 16, 3247);
|
||||
attr_dev(tr, "class", "svelte-18xd5y3");
|
||||
add_location(tr, file$A, 106, 12, 2933);
|
||||
add_location(tr, file$A, 112, 12, 3133);
|
||||
attr_dev(thead, "class", "svelte-18xd5y3");
|
||||
add_location(thead, file$A, 105, 8, 2913);
|
||||
add_location(thead, file$A, 111, 8, 3113);
|
||||
attr_dev(tbody, "class", "svelte-18xd5y3");
|
||||
add_location(tbody, file$A, 113, 8, 3100);
|
||||
add_location(tbody, file$A, 119, 8, 3300);
|
||||
attr_dev(table, "class", "fields-table uk-table svelte-18xd5y3");
|
||||
add_location(table, file$A, 104, 4, 2867);
|
||||
add_location(table, file$A, 110, 4, 3067);
|
||||
},
|
||||
|
||||
m: function mount(target, anchor) {
|
||||
|
@ -61025,11 +61071,11 @@
|
|||
destroy_each(each_blocks, detaching);
|
||||
}
|
||||
};
|
||||
dispatch_dev("SvelteRegisterBlock", { block, id: create_if_block_2$5.name, type: "if", source: "(104:4) {#if record.fields.length > 0}", ctx });
|
||||
dispatch_dev("SvelteRegisterBlock", { block, id: create_if_block_2$5.name, type: "if", source: "(110:4) {#if record.fields.length > 0}", ctx });
|
||||
return block;
|
||||
}
|
||||
|
||||
// (115:12) {#each record.fields as field}
|
||||
// (121:12) {#each record.fields as field}
|
||||
function create_each_block_1$9(ctx) {
|
||||
var tr, td0, div0, t0_value = ctx.field.label + "", t0, t1, div1, t2_value = ctx.field.name + "", t2, t3, td1, t4_value = ctx.field.type + "", t4, t5, td2, raw0_value = ctx.getTypeOptions(ctx.field.typeOptions) + "", t6, td3, span0, raw1_value = getIcon("edit") + "", t7, span1, raw2_value = getIcon("trash") + "", t8, dispose;
|
||||
|
||||
|
@ -61062,24 +61108,24 @@
|
|||
span1 = element("span");
|
||||
t8 = space();
|
||||
attr_dev(div0, "class", "field-label svelte-18xd5y3");
|
||||
add_location(div0, file$A, 117, 20, 3210);
|
||||
add_location(div0, file$A, 123, 20, 3410);
|
||||
set_style(div1, "font-size", "0.8em");
|
||||
set_style(div1, "color", "var(--slate)");
|
||||
add_location(div1, file$A, 118, 20, 3275);
|
||||
add_location(div1, file$A, 124, 20, 3475);
|
||||
attr_dev(td0, "class", "svelte-18xd5y3");
|
||||
add_location(td0, file$A, 116, 16, 3184);
|
||||
add_location(td0, file$A, 122, 16, 3384);
|
||||
attr_dev(td1, "class", "svelte-18xd5y3");
|
||||
add_location(td1, file$A, 120, 16, 3383);
|
||||
add_location(td1, file$A, 126, 16, 3583);
|
||||
attr_dev(td2, "class", "svelte-18xd5y3");
|
||||
add_location(td2, file$A, 121, 16, 3422);
|
||||
add_location(td2, file$A, 127, 16, 3622);
|
||||
attr_dev(span0, "class", "edit-button svelte-18xd5y3");
|
||||
add_location(span0, file$A, 123, 20, 3515);
|
||||
add_location(span0, file$A, 129, 20, 3715);
|
||||
attr_dev(span1, "class", "edit-button svelte-18xd5y3");
|
||||
add_location(span1, file$A, 124, 20, 3626);
|
||||
add_location(span1, file$A, 130, 20, 3826);
|
||||
attr_dev(td3, "class", "svelte-18xd5y3");
|
||||
add_location(td3, file$A, 122, 16, 3490);
|
||||
add_location(td3, file$A, 128, 16, 3690);
|
||||
attr_dev(tr, "class", "svelte-18xd5y3");
|
||||
add_location(tr, file$A, 115, 12, 3163);
|
||||
add_location(tr, file$A, 121, 12, 3363);
|
||||
|
||||
dispose = [
|
||||
listen_dev(span0, "click", click_handler),
|
||||
|
@ -61138,11 +61184,11 @@
|
|||
run_all(dispose);
|
||||
}
|
||||
};
|
||||
dispatch_dev("SvelteRegisterBlock", { block, id: create_each_block_1$9.name, type: "each", source: "(115:12) {#each record.fields as field}", ctx });
|
||||
dispatch_dev("SvelteRegisterBlock", { block, id: create_each_block_1$9.name, type: "each", source: "(121:12) {#each record.fields as field}", ctx });
|
||||
return block;
|
||||
}
|
||||
|
||||
// (135:4) {#if editingField}
|
||||
// (141:4) {#if editingField}
|
||||
function create_if_block_1$8(ctx) {
|
||||
var updating_isOpen, current;
|
||||
|
||||
|
@ -61198,11 +61244,11 @@
|
|||
destroy_component(modal, detaching);
|
||||
}
|
||||
};
|
||||
dispatch_dev("SvelteRegisterBlock", { block, id: create_if_block_1$8.name, type: "if", source: "(135:4) {#if editingField}", ctx });
|
||||
dispatch_dev("SvelteRegisterBlock", { block, id: create_if_block_1$8.name, type: "if", source: "(141:4) {#if editingField}", ctx });
|
||||
return block;
|
||||
}
|
||||
|
||||
// (136:4) <Modal bind:isOpen={editingField}>
|
||||
// (142:4) <Modal bind:isOpen={editingField}>
|
||||
function create_default_slot$6(ctx) {
|
||||
var current;
|
||||
|
||||
|
@ -61251,11 +61297,11 @@
|
|||
destroy_component(fieldview, detaching);
|
||||
}
|
||||
};
|
||||
dispatch_dev("SvelteRegisterBlock", { block, id: create_default_slot$6.name, type: "slot", source: "(136:4) <Modal bind:isOpen={editingField}>", ctx });
|
||||
dispatch_dev("SvelteRegisterBlock", { block, id: create_default_slot$6.name, type: "slot", source: "(142:4) <Modal bind:isOpen={editingField}>", ctx });
|
||||
return block;
|
||||
}
|
||||
|
||||
// (171:4) {:else}
|
||||
// (177:4) {:else}
|
||||
function create_else_block$6(ctx) {
|
||||
var div;
|
||||
|
||||
|
@ -61264,7 +61310,7 @@
|
|||
div = element("div");
|
||||
div.textContent = "No indexes added.\n ";
|
||||
attr_dev(div, "class", "no-indexes svelte-18xd5y3");
|
||||
add_location(div, file$A, 171, 4, 5114);
|
||||
add_location(div, file$A, 177, 4, 5314);
|
||||
},
|
||||
|
||||
m: function mount(target, anchor) {
|
||||
|
@ -61277,11 +61323,11 @@
|
|||
}
|
||||
}
|
||||
};
|
||||
dispatch_dev("SvelteRegisterBlock", { block, id: create_else_block$6.name, type: "else", source: "(171:4) {:else}", ctx });
|
||||
dispatch_dev("SvelteRegisterBlock", { block, id: create_else_block$6.name, type: "else", source: "(177:4) {:else}", ctx });
|
||||
return block;
|
||||
}
|
||||
|
||||
// (164:8) {#if index.filter}
|
||||
// (170:8) {#if index.filter}
|
||||
function create_if_block$i(ctx) {
|
||||
var div, span, t1, code, t2_value = ctx.index.filter + "", t2;
|
||||
|
||||
|
@ -61294,11 +61340,11 @@
|
|||
code = element("code");
|
||||
t2 = text(t2_value);
|
||||
attr_dev(span, "class", "index-label svelte-18xd5y3");
|
||||
add_location(span, file$A, 165, 12, 4953);
|
||||
add_location(span, file$A, 171, 12, 5153);
|
||||
attr_dev(code, "class", "index-mapfilter svelte-18xd5y3");
|
||||
add_location(code, file$A, 166, 12, 5006);
|
||||
add_location(code, file$A, 172, 12, 5206);
|
||||
attr_dev(div, "class", "index-field-row svelte-18xd5y3");
|
||||
add_location(div, file$A, 164, 8, 4911);
|
||||
add_location(div, file$A, 170, 8, 5111);
|
||||
},
|
||||
|
||||
m: function mount(target, anchor) {
|
||||
|
@ -61321,11 +61367,11 @@
|
|||
}
|
||||
}
|
||||
};
|
||||
dispatch_dev("SvelteRegisterBlock", { block, id: create_if_block$i.name, type: "if", source: "(164:8) {#if index.filter}", ctx });
|
||||
dispatch_dev("SvelteRegisterBlock", { block, id: create_if_block$i.name, type: "if", source: "(170:8) {#if index.filter}", ctx });
|
||||
return block;
|
||||
}
|
||||
|
||||
// (148:4) {#each record.indexes as index}
|
||||
// (154:4) {#each record.indexes as index}
|
||||
function create_each_block$f(ctx) {
|
||||
var div3, div0, t0_value = ctx.index.name + "", t0, t1, span0, raw_value = getIcon("edit") + "", t2, div1, span1, t4, span2, t5_value = ctx.getIndexAllowedRecords(ctx.index) + "", t5, t6, span3, t8, span4, t9_value = ctx.index.indexType + "", t9, t10, div2, span5, t12, code, t13_value = ctx.index.map + "", t13, t14, t15, dispose;
|
||||
|
||||
|
@ -61366,26 +61412,26 @@
|
|||
if (if_block) if_block.c();
|
||||
t15 = space();
|
||||
set_style(span0, "margin-left", "7px");
|
||||
add_location(span0, file$A, 151, 12, 4306);
|
||||
add_location(span0, file$A, 157, 12, 4506);
|
||||
attr_dev(div0, "class", "index-name svelte-18xd5y3");
|
||||
add_location(div0, file$A, 149, 8, 4244);
|
||||
add_location(div0, file$A, 155, 8, 4444);
|
||||
attr_dev(span1, "class", "index-label svelte-18xd5y3");
|
||||
add_location(span1, file$A, 154, 12, 4467);
|
||||
add_location(span2, file$A, 155, 12, 4531);
|
||||
add_location(span1, file$A, 160, 12, 4667);
|
||||
add_location(span2, file$A, 161, 12, 4731);
|
||||
attr_dev(span3, "class", "index-label svelte-18xd5y3");
|
||||
set_style(span3, "margin-left", "15px");
|
||||
add_location(span3, file$A, 156, 12, 4588);
|
||||
add_location(span4, file$A, 157, 12, 4666);
|
||||
add_location(span3, file$A, 162, 12, 4788);
|
||||
add_location(span4, file$A, 163, 12, 4866);
|
||||
attr_dev(div1, "class", "index-field-row svelte-18xd5y3");
|
||||
add_location(div1, file$A, 153, 8, 4425);
|
||||
add_location(div1, file$A, 159, 8, 4625);
|
||||
attr_dev(span5, "class", "index-label svelte-18xd5y3");
|
||||
add_location(span5, file$A, 160, 12, 4762);
|
||||
add_location(span5, file$A, 166, 12, 4962);
|
||||
attr_dev(code, "class", "index-mapfilter svelte-18xd5y3");
|
||||
add_location(code, file$A, 161, 12, 4812);
|
||||
add_location(code, file$A, 167, 12, 5012);
|
||||
attr_dev(div2, "class", "index-field-row svelte-18xd5y3");
|
||||
add_location(div2, file$A, 159, 8, 4720);
|
||||
add_location(div2, file$A, 165, 8, 4920);
|
||||
attr_dev(div3, "class", "index-container svelte-18xd5y3");
|
||||
add_location(div3, file$A, 148, 4, 4206);
|
||||
add_location(div3, file$A, 154, 4, 4406);
|
||||
dispose = listen_dev(span0, "click", click_handler_2);
|
||||
},
|
||||
|
||||
|
@ -61459,7 +61505,7 @@
|
|||
dispose();
|
||||
}
|
||||
};
|
||||
dispatch_dev("SvelteRegisterBlock", { block, id: create_each_block$f.name, type: "each", source: "(148:4) {#each record.indexes as index}", ctx });
|
||||
dispatch_dev("SvelteRegisterBlock", { block, id: create_each_block$f.name, type: "each", source: "(154:4) {#each record.indexes as index}", ctx });
|
||||
return block;
|
||||
}
|
||||
|
||||
|
@ -61479,6 +61525,7 @@
|
|||
var textbox = new Textbox({ props: textbox_props, $$inline: true });
|
||||
|
||||
binding_callbacks.push(() => bind(textbox, 'text', textbox_text_binding));
|
||||
textbox.$on("change", ctx.nameChanged);
|
||||
|
||||
var if_block0 = (!ctx.record.isSingle) && create_if_block_3$3(ctx);
|
||||
|
||||
|
@ -61537,19 +61584,19 @@
|
|||
each_blocks[i].c();
|
||||
}
|
||||
attr_dev(h30, "class", "settings-title svelte-18xd5y3");
|
||||
add_location(h30, file$A, 87, 8, 2306);
|
||||
add_location(h30, file$A, 93, 8, 2479);
|
||||
attr_dev(div0, "class", "recordkey svelte-18xd5y3");
|
||||
add_location(div0, file$A, 96, 8, 2636);
|
||||
add_location(div0, file$A, 102, 8, 2836);
|
||||
attr_dev(form, "class", "uk-form-horizontal");
|
||||
add_location(form, file$A, 86, 4, 2264);
|
||||
add_location(form, file$A, 92, 4, 2437);
|
||||
attr_dev(span, "class", "add-field-button svelte-18xd5y3");
|
||||
add_location(span, file$A, 100, 15, 2735);
|
||||
add_location(span, file$A, 106, 15, 2935);
|
||||
attr_dev(h31, "class", "title svelte-18xd5y3");
|
||||
add_location(h31, file$A, 99, 4, 2701);
|
||||
add_location(h31, file$A, 105, 4, 2901);
|
||||
attr_dev(h32, "class", "title svelte-18xd5y3");
|
||||
add_location(h32, file$A, 143, 4, 4119);
|
||||
add_location(h32, file$A, 149, 4, 4319);
|
||||
attr_dev(div1, "class", "root svelte-18xd5y3");
|
||||
add_location(div1, file$A, 84, 0, 2240);
|
||||
add_location(div1, file$A, 90, 0, 2413);
|
||||
dispose = listen_dev(span, "click", ctx.newField);
|
||||
},
|
||||
|
||||
|
@ -61798,6 +61845,13 @@
|
|||
fp_41("<br>")
|
||||
]);
|
||||
|
||||
const nameChanged = ev => {
|
||||
const pluralName = n => `${n}s`;
|
||||
if(record.collectionName === "") {
|
||||
$$invalidate('record', record.collectionName = pluralName(ev.target.value), record);
|
||||
}
|
||||
};
|
||||
|
||||
function textbox_text_binding(value) {
|
||||
record.name = value;
|
||||
$$invalidate('record', record);
|
||||
|
@ -61855,6 +61909,7 @@
|
|||
onFinishedFieldEdit,
|
||||
editIndex,
|
||||
getTypeOptions,
|
||||
nameChanged,
|
||||
$store,
|
||||
textbox_text_binding,
|
||||
textbox0_text_binding,
|
||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue