diff --git a/public/app/db.js b/public/app/db.js
index 0df99706..b8ba720c 100644
--- a/public/app/db.js
+++ b/public/app/db.js
@@ -11,6 +11,7 @@ const fsPromises = fs.promises;
const SPACES_COLLECTION = 'spaces';
const ACTIONS_COLLECTION = 'actions';
const USERS_COLLECTION = 'users';
+const APP_INSTANCE_RESOURCES_COLLECTION = 'resources';
// bootstrap database
const ensureDatabaseExists = async (dbPath = DATABASE_PATH) => {
@@ -37,6 +38,7 @@ const bootstrapDatabase = (dbPath = DATABASE_PATH) => {
[USERS_COLLECTION]: [],
user: { lang: DEFAULT_LANG },
[ACTIONS_COLLECTION]: [],
+ [APP_INSTANCE_RESOURCES_COLLECTION]: [],
}).write();
return db;
};
@@ -44,6 +46,7 @@ const bootstrapDatabase = (dbPath = DATABASE_PATH) => {
module.exports = {
SPACES_COLLECTION,
USERS_COLLECTION,
+ APP_INSTANCE_RESOURCES_COLLECTION,
ensureDatabaseExists,
bootstrapDatabase,
};
diff --git a/public/app/listeners/clearUserInput.js b/public/app/listeners/clearUserInput.js
index 48f7930d..83d6a5fd 100644
--- a/public/app/listeners/clearUserInput.js
+++ b/public/app/listeners/clearUserInput.js
@@ -1,50 +1,26 @@
-const _ = require('lodash');
const { CLEARED_USER_INPUT_CHANNEL } = require('../config/channels');
const { ERROR_GENERAL } = require('../config/errors');
-const { SPACES_COLLECTION } = require('../db');
+const {
+ SPACES_COLLECTION,
+ APP_INSTANCE_RESOURCES_COLLECTION,
+} = require('../db');
const logger = require('../logger');
-const clearUserInput = (mainWindow, db) => async (event, { id }) => {
+const clearUserInput = (mainWindow, db) => async (
+ event,
+ { spaceId, userId }
+) => {
try {
- logger.debug(`clearing user input for space ${id}`);
+ logger.debug(`clearing user input for space ${spaceId} of user ${userId}`);
- // get handle to the space
- const spaceHandle = db.get(SPACES_COLLECTION).find({ id });
-
- // get handle to regular items
- const regularItems = spaceHandle
- .get('phases')
- // we only care about phases with items
- .filter(phase => phase.items)
- // ensure all items are in the same level of the array
- .flatMap(phase => phase.items);
-
- // get handle to tools
- const tools = spaceHandle.get('items');
-
- // remove user input in items within phases then
- // remove user input in tools
- [regularItems, tools].forEach(handle => {
- // we only care about items with app instances
- handle
- .filter(item => item.appInstance)
- // ensure all app instances are in the same level
- .flatMap(item => item.appInstance)
- // user input is saved inside resources
- .filter(appInstance => appInstance.resources)
- // iterate through app instances to be able to delete
- // reference to the original resource array and thus
- // mutate the db object
- .forEach(appInstance => {
- const resources = _.get(appInstance, 'resources');
- // we should not remove resources marked as public
- _.remove(resources, resource => resource.visibility !== 'public');
- })
- .write();
- });
+ db.get(APP_INSTANCE_RESOURCES_COLLECTION)
+ .remove({ visibility: 'private', spaceId, user: userId })
+ .write();
// we need to return the value of the mutated
// space object to the frontend
+ // get handle to the space
+ const spaceHandle = db.get(SPACES_COLLECTION).find({ id: spaceId });
const space = spaceHandle.value();
mainWindow.webContents.send(CLEARED_USER_INPUT_CHANNEL, space);
diff --git a/public/app/listeners/getAppInstance.js b/public/app/listeners/getAppInstance.js
new file mode 100644
index 00000000..1f4a7907
--- /dev/null
+++ b/public/app/listeners/getAppInstance.js
@@ -0,0 +1,42 @@
+const { GET_APP_INSTANCE_CHANNEL } = require('../config/channels');
+
+const getAppInstance = (mainWindow, db) => (event, payload = {}) => {
+ try {
+ const { spaceId, subSpaceId, id } = payload;
+
+ let appInstance;
+
+ // tools live on the parent
+ const tool = spaceId === subSpaceId;
+
+ // if not a tool, we need to go one step further into the phase
+ if (!tool) {
+ appInstance = db
+ .get('spaces')
+ .find({ id: spaceId })
+ .get('phases')
+ .find({ id: subSpaceId })
+ .get('items')
+ .filter(item => item.appInstance)
+ .map(item => item.appInstance)
+ .find({ id })
+ .value();
+ } else {
+ appInstance = db
+ .get('spaces')
+ .find({ id: spaceId })
+ .get('items')
+ .filter(item => item.appInstance)
+ .map(item => item.appInstance)
+ .find({ id })
+ .value();
+ }
+
+ mainWindow.webContents.send(GET_APP_INSTANCE_CHANNEL, appInstance);
+ } catch (e) {
+ console.error(e);
+ mainWindow.webContents.send(GET_APP_INSTANCE_CHANNEL, null);
+ }
+};
+
+module.exports = getAppInstance;
diff --git a/public/app/listeners/getAppInstanceResources.js b/public/app/listeners/getAppInstanceResources.js
index 6dc638bd..bd7988ba 100644
--- a/public/app/listeners/getAppInstanceResources.js
+++ b/public/app/listeners/getAppInstanceResources.js
@@ -1,39 +1,13 @@
const { GET_APP_INSTANCE_RESOURCES_CHANNEL } = require('../config/channels');
+const { APP_INSTANCE_RESOURCES_COLLECTION } = require('../db');
-const getAppInstanceResources = (mainWindow, db) => async (
- event,
- data = {}
-) => {
+const getAppInstanceResources = (mainWindow, db) => (event, data = {}) => {
const defaultResponse = [];
- const { userId, appInstanceId, spaceId, subSpaceId, type } = data;
+ const { userId, appInstanceId, type } = data;
try {
- // tools live on the parent
- const tool = spaceId === subSpaceId;
-
- let appInstanceResourcesHandle;
-
- // if not a tool, we need to go one step further into the phase
- if (!tool) {
- appInstanceResourcesHandle = db
- .get('spaces')
- .find({ id: spaceId })
- .get('phases')
- .find({ id: subSpaceId })
- .get('items')
- .filter(item => item.appInstance)
- .map(item => item.appInstance)
- .find({ id: appInstanceId })
- .get('resources');
- } else {
- appInstanceResourcesHandle = db
- .get('spaces')
- .find({ id: spaceId })
- .get('items')
- .filter(item => item.appInstance)
- .map(item => item.appInstance)
- .find({ id: appInstanceId })
- .get('resources');
- }
+ const appInstanceResourcesHandle = db
+ .get(APP_INSTANCE_RESOURCES_COLLECTION)
+ .filter({ appInstance: appInstanceId });
// only filter by type if provided
if (type) {
diff --git a/public/app/listeners/index.js b/public/app/listeners/index.js
index fa372159..cd6d8799 100644
--- a/public/app/listeners/index.js
+++ b/public/app/listeners/index.js
@@ -25,6 +25,7 @@ const isAuthenticated = require('./isAuthenticated');
const getAppInstanceResources = require('./getAppInstanceResources');
const postAppInstanceResource = require('./postAppInstanceResource');
const patchAppInstanceResource = require('./patchAppInstanceResource');
+const getAppInstance = require('./getAppInstance');
module.exports = {
loadSpace,
@@ -54,4 +55,5 @@ module.exports = {
getAppInstanceResources,
postAppInstanceResource,
patchAppInstanceResource,
+ getAppInstance,
};
diff --git a/public/app/listeners/patchAppInstanceResource.js b/public/app/listeners/patchAppInstanceResource.js
index 1e48034f..b0253cb0 100644
--- a/public/app/listeners/patchAppInstanceResource.js
+++ b/public/app/listeners/patchAppInstanceResource.js
@@ -1,50 +1,20 @@
const { PATCH_APP_INSTANCE_RESOURCE_CHANNEL } = require('../config/channels');
+const { APP_INSTANCE_RESOURCES_COLLECTION } = require('../db');
-const patchAppInstanceResource = (mainWindow, db) => async (
- event,
- payload = {}
-) => {
+const patchAppInstanceResource = (mainWindow, db) => (event, payload = {}) => {
try {
- const { appInstanceId, spaceId, subSpaceId, data, id } = payload;
+ const { appInstanceId: appInstance, data, id } = payload;
const now = new Date();
const fieldsToUpdate = {
updatedAt: now,
data,
};
- let resource;
-
- // tools live on the parent
- const tool = spaceId === subSpaceId;
-
- // if not a tool, we need to go one step further into the phase
- if (!tool) {
- resource = db
- .get('spaces')
- .find({ id: spaceId })
- .get('phases')
- .find({ id: subSpaceId })
- .get('items')
- .filter(item => item.appInstance)
- .map(item => item.appInstance)
- .find({ id: appInstanceId })
- .get('resources')
- .find({ id })
- .assign(fieldsToUpdate)
- .value();
- } else {
- resource = db
- .get('spaces')
- .find({ id: spaceId })
- .get('items')
- .filter(item => item.appInstance)
- .map(item => item.appInstance)
- .find({ id: appInstanceId })
- .get('resources')
- .find({ id })
- .assign(fieldsToUpdate)
- .value();
- }
+ const resource = db
+ .get(APP_INSTANCE_RESOURCES_COLLECTION)
+ .find({ appInstance, id })
+ .assign(fieldsToUpdate)
+ .value();
db.write();
mainWindow.webContents.send(PATCH_APP_INSTANCE_RESOURCE_CHANNEL, resource);
diff --git a/public/app/listeners/postAppInstanceResource.js b/public/app/listeners/postAppInstanceResource.js
index a948bd41..4b498daf 100644
--- a/public/app/listeners/postAppInstanceResource.js
+++ b/public/app/listeners/postAppInstanceResource.js
@@ -1,16 +1,13 @@
const ObjectId = require('bson-objectid');
const { POST_APP_INSTANCE_RESOURCE_CHANNEL } = require('../config/channels');
+const { APP_INSTANCE_RESOURCES_COLLECTION } = require('../db');
-const postAppInstanceResource = (mainWindow, db) => async (
- event,
- payload = {}
-) => {
+const postAppInstanceResource = (mainWindow, db) => (event, payload = {}) => {
try {
const {
userId,
appInstanceId,
spaceId,
- subSpaceId,
format,
type,
data,
@@ -23,6 +20,7 @@ const postAppInstanceResource = (mainWindow, db) => async (
// prepare the resource that we will create
const resourceToWrite = {
appInstance: appInstanceId,
+ spaceId,
createdAt: now,
updatedAt: now,
data,
@@ -33,34 +31,10 @@ const postAppInstanceResource = (mainWindow, db) => async (
id: ObjectId().str,
};
- // tools live on the parent
- const tool = spaceId === subSpaceId;
-
// write the resource to the database
- // if not a tool, we need to go one step further into the phase
- if (!tool) {
- db.get('spaces')
- .find({ id: spaceId })
- .get('phases')
- .find({ id: subSpaceId })
- .get('items')
- .filter(item => item.appInstance)
- .map(item => item.appInstance)
- .find({ id: appInstanceId })
- .get('resources')
- .push(resourceToWrite)
- .write();
- } else {
- db.get('spaces')
- .find({ id: spaceId })
- .get('items')
- .filter(item => item.appInstance)
- .map(item => item.appInstance)
- .find({ id: appInstanceId })
- .get('resources')
- .push(resourceToWrite)
- .write();
- }
+ db.get(APP_INSTANCE_RESOURCES_COLLECTION)
+ .push(resourceToWrite)
+ .write();
// send back the resource
mainWindow.webContents.send(
diff --git a/public/electron.js b/public/electron.js
index ae829a88..d0c1722c 100644
--- a/public/electron.js
+++ b/public/electron.js
@@ -83,6 +83,7 @@ const {
getAppInstanceResources,
postAppInstanceResource,
patchAppInstanceResource,
+ getAppInstance,
} = require('./app/listeners');
const isMac = require('./app/utils/isMac');
@@ -433,44 +434,7 @@ app.on('ready', async () => {
);
// called when getting an AppInstance
- ipcMain.on(GET_APP_INSTANCE_CHANNEL, (event, payload = {}) => {
- try {
- const { spaceId, subSpaceId, id } = payload;
-
- let appInstance;
-
- // tools live on the parent
- const tool = spaceId === subSpaceId;
-
- // if not a tool, we need to go one step further into the phase
- if (!tool) {
- appInstance = db
- .get('spaces')
- .find({ id: spaceId })
- .get('phases')
- .find({ id: subSpaceId })
- .get('items')
- .filter(item => item.appInstance)
- .map(item => item.appInstance)
- .find({ id })
- .value();
- } else {
- appInstance = db
- .get('spaces')
- .find({ id: spaceId })
- .get('items')
- .filter(item => item.appInstance)
- .map(item => item.appInstance)
- .find({ id })
- .value();
- }
-
- mainWindow.webContents.send(GET_APP_INSTANCE_CHANNEL, appInstance);
- } catch (e) {
- console.error(e);
- mainWindow.webContents.send(GET_APP_INSTANCE_CHANNEL, null);
- }
- });
+ ipcMain.on(GET_APP_INSTANCE_CHANNEL, getAppInstance(mainWindow, db));
// called when getting the database
ipcMain.on(GET_DATABASE_CHANNEL, async () => {
diff --git a/src/actions/space.js b/src/actions/space.js
index 059f1b92..b2ba805d 100644
--- a/src/actions/space.js
+++ b/src/actions/space.js
@@ -293,7 +293,7 @@ const deleteSpace = ({ id }) => dispatch => {
});
};
-const clearUserInput = async ({ id }) => async dispatch => {
+const clearUserInput = async ({ spaceId, userId }) => async dispatch => {
try {
// show confirmation prompt
window.ipcRenderer.send(SHOW_CLEAR_USER_INPUT_PROMPT_CHANNEL);
@@ -304,13 +304,17 @@ const clearUserInput = async ({ id }) => async dispatch => {
(event, response) => {
if (response === 1) {
dispatch(flagClearingUserInput(true));
- window.ipcRenderer.send(CLEAR_USER_INPUT_CHANNEL, { id });
+ window.ipcRenderer.send(CLEAR_USER_INPUT_CHANNEL, {
+ spaceId,
+ userId,
+ });
}
}
);
// listen for response from backend
window.ipcRenderer.once(CLEARED_USER_INPUT_CHANNEL, (event, response) => {
+ console.log('response', response);
if (response === ERROR_GENERAL) {
toastr.error(ERROR_MESSAGE_HEADER, ERROR_CLEARING_USER_INPUT_MESSAGE);
} else {
diff --git a/src/components/space/ClearButton.js b/src/components/space/ClearButton.js
index 89d6c4e1..f1e04077 100644
--- a/src/components/space/ClearButton.js
+++ b/src/components/space/ClearButton.js
@@ -17,13 +17,14 @@ class ClearButton extends Component {
button: PropTypes.string,
}).isRequired,
t: PropTypes.func.isRequired,
- id: PropTypes.string.isRequired,
+ spaceId: PropTypes.string.isRequired,
+ userId: PropTypes.string.isRequired,
dispatchClearUserInput: PropTypes.func.isRequired,
};
handleClearUserInput = () => {
- const { id, dispatchClearUserInput } = this.props;
- dispatchClearUserInput({ id });
+ const { spaceId, userId, dispatchClearUserInput } = this.props;
+ dispatchClearUserInput({ spaceId, userId });
};
render() {
@@ -42,6 +43,10 @@ class ClearButton extends Component {
}
}
+const mapStateToProps = ({ authentication }) => ({
+ userId: authentication.getIn(['user', 'userId']),
+});
+
const mapDispatchToProps = {
dispatchClearUserInput: clearUserInput,
};
@@ -51,7 +56,7 @@ const StyledComponent = withStyles(Styles)(ClearButton);
const TranslatedComponent = withTranslation()(StyledComponent);
const ConnectedComponent = connect(
- null,
+ mapStateToProps,
mapDispatchToProps
)(TranslatedComponent);
diff --git a/src/components/space/SpaceHeader.js b/src/components/space/SpaceHeader.js
index 5661284d..134aeb3b 100644
--- a/src/components/space/SpaceHeader.js
+++ b/src/components/space/SpaceHeader.js
@@ -132,7 +132,7 @@ class SpaceHeader extends Component {
const { space } = this.props;
const { saved, id } = space;
if (saved) {
- return ;
+ return ;
}
return null;
}
diff --git a/src/data/sample.json b/src/data/sample.json
index 1cc7aeb2..1615c587 100644
--- a/src/data/sample.json
+++ b/src/data/sample.json
@@ -62,19 +62,7 @@
"settings": {
"headerVisible": false
},
- "resources": [
- {
- "appInstance": "5ce2c2e23a209c1877b3dc80",
- "createdAt": "2019-05-21T17:06:29.683Z",
- "updatedAt": "2019-05-24T13:24:05.073Z",
- "data": "Sample text.",
- "format": "v1",
- "type": "input",
- "visibility": "private",
- "user": "5ce422795fe28eeca1001e0a",
- "id": "5ce430152f6f6672b16fca57"
- }
- ],
+ "resources": [],
"createdAt": "2019-05-21T17:06:29.683Z",
"updatedAt": "2019-05-24T13:24:05.073Z"
}
@@ -180,18 +168,21 @@
"geolocationEnabled": false
}
},
- "actions": [ {
- "appInstance": "5ce2c2323a209c1877b3dc80",
- "createdAt": "2019-05-21T17:06:29.683Z",
- "updatedAt": "2019-05-24T13:24:05.073Z",
- "data": "Sample text.",
- "format": "v1",
- "type": "input",
- "visibility": "private",
- "user": "5ce422795fe28eeca1001e0a",
- "id": "5ce430152f6f6672b16fca57",
- "verb": "saved",
- "spaceId": "6ccb068bbb18b80359966631"}],
+ "actions": [
+ {
+ "appInstance": "5ce2c2323a209c1877b3dc80",
+ "createdAt": "2019-05-21T17:06:29.683Z",
+ "updatedAt": "2019-05-24T13:24:05.073Z",
+ "data": "Sample text.",
+ "format": "v1",
+ "type": "input",
+ "visibility": "private",
+ "user": "5ce422795fe28eeca1001e0a",
+ "id": "5ce430152f6f6672b16fca57",
+ "verb": "saved",
+ "spaceId": "6ccb068bbb18b80359966631"
+ }
+ ],
"users": [
{
"userId": 1,
@@ -202,5 +193,6 @@
"geolocationEnabled": false
}
}
- ]
+ ],
+ "resources": []
}