Skip to content

Commit

Permalink
Merge pull request #11 from FabricLabs/feature/sensemaker
Browse files Browse the repository at this point in the history
Sensemaker Changes
  • Loading branch information
martindale authored Jan 25, 2025
2 parents 502f06a + 9f771fc commit dc863e4
Show file tree
Hide file tree
Showing 939 changed files with 139,220 additions and 92,158 deletions.
4 changes: 0 additions & 4 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,6 @@ jobs:
node-version-file: '.nvmrc'
cache: 'npm'
cache-dependency-path: package-lock.json
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.8'
- name: Install dependencies
run: npm ci
- name: Generate coverage report
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,6 @@ dist

# Fabric Schema Store
stores/schemata

# MacOS garbage
.DS_Store
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v18.19.0
v18.19.1
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
dist: focal
language: node_js
node_js:
- 18.19.0
- 18.19.1
before_install:
- npm install -g codecov
after_success:
Expand Down
110 changes: 110 additions & 0 deletions actions/accountActions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
'use strict';

const { fetchFromAPI } = require('./apiActions');

async function fetchAccountsFromAPI(token) {
// TODO: pagination
return fetchFromAPI('/users', null, token);
}

// Action types
const FETCH_ACCOUNTS_REQUEST = 'FETCH_ACCOUNTS_REQUEST';
const FETCH_ACCOUNTS_SUCCESS = 'FETCH_ACCOUNTS_SUCCESS';
const FETCH_ACCOUNTS_FAILURE = 'FETCH_ACCOUNTS_FAILURE';

const FETCH_USER_REQUEST = 'FETCH_USER_REQUEST';
const FETCH_USER_SUCCESS = 'FETCH_USER_SUCCESS';
const FETCH_USER_FAILURE = 'FETCH_USER_FAILURE';

const PASSWORD_RESET_REQUEST = 'PASSWORD_RESET_REQUEST';
const PASSWORD_RESET_SUCCESS = 'PASSWORD_RESET_SUCCESS';
const PASSWORD_RESET_FAILURE = 'PASSWORD_RESET_FAILURE';

// Action creators
const fetchAccountsRequest = () => ({ type: FETCH_ACCOUNTS_REQUEST, loading: true });
const fetchAccountsSuccess = (users) => ({ type: FETCH_ACCOUNTS_SUCCESS, payload: users, loading: false });
const fetchAccountsFailure = (error) => ({ type: FETCH_ACCOUNTS_FAILURE, payload: error, loading: false });

const fetchAccountRequest = () => ({ type: FETCH_USER_REQUEST, loading: true });
const fetchAccountSuccess = (instance) => ({ type: FETCH_USER_SUCCESS, payload: instance, loading: false });
const fetchAccountFailure = (error) => ({ type: FETCH_USER_FAILURE, payload: error, loading: false });

const askPasswordResetRequest = (email) => ({ type: PASSWORD_RESET_REQUEST, payload: email });
const askPasswordResetSuccess = () => ({ type: PASSWORD_RESET_SUCCESS });
const askPasswordResetFailure = (error) => ({ type: PASSWORD_RESET_FAILURE, payload: error });

// Thunk action creator
const fetchAccounts = () => {
return async (dispatch, getState) => {
dispatch(fetchAccountsRequest());
const { token } = getState().auth;
try {
const users = await fetchAccountsFromAPI(token);
dispatch(fetchAccountsSuccess(users));
} catch (error) {
dispatch(fetchAccountsFailure(error));
}
};
};

const fetchAccount = (id) => {
return async (dispatch, getState) => {
dispatch(fetchAccountRequest());
const { token } = getState().auth;
try {
const instance = await fetchFromAPI(`/users/${id}`, null, token);
dispatch(fetchAccountSuccess(instance));
} catch (error) {
dispatch(fetchAccountFailure(error));
}
};
};

const askPasswordReset = (email) => {
return async (dispatch, getState) => {
dispatch(askPasswordResetRequest(email));
const { token } = getState().auth;
try {
// call for the fetch that generates the token for password reset
const fetchPromise = fetch('/passwordReset', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ email }),
});

const timeoutPromise = new Promise((_, reject) => {
setTimeout(() => {
reject(new Error("Email could not be sent. Please check your internet connection."));
}, 60000);
});

const response = await Promise.race([timeoutPromise, fetchPromise]);
if (!response.ok) {
const error = await response.json();
throw new Error(error.message);
}
//email with reset token sent
dispatch(askPasswordResetSuccess());
} catch (error) {
dispatch(askPasswordResetFailure(error));
}
};
}


module.exports = {
fetchAccount,
fetchAccounts,
askPasswordReset,
FETCH_USER_REQUEST,
FETCH_USER_SUCCESS,
FETCH_USER_FAILURE,
FETCH_ACCOUNTS_REQUEST,
FETCH_ACCOUNTS_SUCCESS,
FETCH_ACCOUNTS_FAILURE,
PASSWORD_RESET_REQUEST,
PASSWORD_RESET_SUCCESS,
PASSWORD_RESET_FAILURE,
};
219 changes: 219 additions & 0 deletions actions/adminActions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
'use strict';

const { fetchFromAPI } = require('./apiActions');

const createTimeoutPromise = require('../functions/createTimeoutPromise');


// API Functions
async function fetchStatsFromAPI (token) {
const response = await fetch('/statistics/admin', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
});

return await response.json();
}

async function fetchSyncStatsFromAPI (token) {
const response = await fetch('/statistics/sync', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
});

return await response.json();
}

async function createInvitationThroughAPI (invitation, token) {
const response = await fetch('/invitations', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify(invitation)
});

return await response.json();
}

// Action types
const FETCH_ADMIN_STATS_REQUEST = 'FETCH_ADMIN_STATS_REQUEST';
const FETCH_ADMIN_STATS_SUCCESS = 'FETCH_ADMIN_STATS_SUCCESS';
const FETCH_ADMIN_STATS_FAILURE = 'FETCH_ADMIN_STATS_FAILURE';

const FETCH_SYNC_STATS_REQUEST = 'FETCH_SYNC_STATS_REQUEST';
const FETCH_SYNC_STATS_SUCCESS = 'FETCH_SYNC_STATS_SUCCESS';
const FETCH_SYNC_STATS_FAILURE = 'FETCH_SYNC_STATS_FAILURE';

const FETCH_ALL_CONVERSATIONS_SUCCESS = 'FETCH_ALL_CONVERSATIONS_SUCCESS';
const FETCH_ALL_CONVERSATIONS_FAILURE = 'FETCH_ALL_CONVERSATIONS_FAILURE';

const CREATE_INVITATION_REQUEST = 'CREATE_INVITATION_REQUEST';
const CREATE_INVITATION_SUCCESS = 'CREATE_INVITATION_SUCCESS';
const CREATE_INVITATION_FAILURE = 'CREATE_INVITATION_FAILURE';

const EDIT_USERNAME_REQUEST = 'EDIT_USERNAME_REQUEST';
const EDIT_USERNAME_SUCCESS = 'EDIT_USERNAME_SUCCESS';
const EDIT_USERNAME_FAILURE = 'EDIT_USERNAME_FAILURE';

const EDIT_EMAIL_REQUEST = 'EDIT_EMAIL_REQUEST';
const EDIT_EMAIL_SUCCESS = 'EDIT_EMAIL_SUCCESS';
const EDIT_EMAIL_FAILURE = 'EDIT_EMAIL_FAILURE';

// Action creators
const fetchAdminStatsRequest = () => ({ type: FETCH_ADMIN_STATS_REQUEST });
const fetchAdminStatsSuccess = (stats) => ({ type: FETCH_ADMIN_STATS_SUCCESS, payload: stats });
const fetchAdminStatsFailure = (error) => ({ type: FETCH_SYNC_STATS_FAILURE, payload: error });

const fetchSyncStatsFailure = (error) => ({ type: FETCH_ADMIN_STATS_FAILURE, payload: error });
const fetchSyncStatsRequest = () => ({ type: FETCH_SYNC_STATS_REQUEST });
const fetchSyncStatsSuccess = (stats) => ({ type: FETCH_SYNC_STATS_SUCCESS, payload: stats });

const fetchAllConversationsSuccess = (conversations) => ({ type: FETCH_ALL_CONVERSATIONS_SUCCESS, payload: conversations });
const fetchAllConversationsFailure = (error) => ({ type: FETCH_ALL_CONVERSATIONS_FAILURE, payload: error });

const createInvitationRequest = () => ({ type: CREATE_INVITATION_REQUEST });
const createInvitationSuccess = (instance) => ({ type: CREATE_INVITATION_SUCCESS, payload: instance });
const createInvitationFailure = (error) => ({ type: CREATE_INVITATION_FAILURE, payload: error });

const editUsernameRequest = () => ({ type: EDIT_USERNAME_REQUEST, loading: true });
const editUsernameSuccess = () => ({ type: EDIT_USERNAME_SUCCESS, loading: false });
const editUsernameFailure = (error) => ({ type: EDIT_USERNAME_FAILURE, payload: error, loading: false });

const editEmailRequest = () => ({ type: EDIT_EMAIL_REQUEST, loading: true });
const editEmailSuccess = () => ({ type: EDIT_EMAIL_SUCCESS, loading: false });
const editEmailFailure = (error) => ({ type: EDIT_EMAIL_FAILURE, payload: error, loading: false });

// Thunk action creator
const fetchAdminStats = () => {
return async (dispatch, getState) => {
dispatch(fetchAdminStatsRequest());
const { token } = getState().auth;
try {
const stats = await fetchStatsFromAPI(token);
dispatch(fetchAdminStatsSuccess(stats));
} catch (error) {
dispatch(fetchAdminStatsFailure(error));
}
};
};

const fetchSyncStats = () => {
return async (dispatch, getState) => {
dispatch(fetchSyncStatsRequest());
const { token } = getState().auth;
try {
const stats = await fetchSyncStatsFromAPI(token);
dispatch(fetchSyncStatsSuccess(stats));
} catch (error) {
dispatch(fetchSyncStatsFailure(error));
}
};
};

const fetchAllConversationsFromAPI = () => {
return async (dispatch, getState) => {
dispatch(fetchAdminStatsRequest());
const { token } = getState().auth;

try {
const conversations = await fetchFromAPI('/conversations', {
query: {
include: '*'
}
}, token);

dispatch(fetchAllConversationsSuccess(conversations));
} catch (error) {
dispatch(fetchAllConversationsFailure(error));
}
};
}

const createInvitation = (invitation) => {
return async (dispatch, getState) => {
dispatch(createInvitationRequest());
const { token } = getState().auth;

try {
const instance = await createInvitationThroughAPI(invitation, token);
dispatch(createInvitationSuccess(instance));
} catch (error) {
dispatch(createInvitationFailure(error));
}
};
}

const editUsername = (id, newUsername) => {
return async (dispatch, getState) => {
const { token } = getState().auth;
dispatch(editUsernameRequest());
try {
const fetchPromise = fetch('/users/username', {
method: 'PATCH',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ id, newUsername }),
});

const timeoutPromise = createTimeoutPromise(15000, 'Fetch timed out');

const response = await Promise.race([timeoutPromise, fetchPromise]);
dispatch(editUsernameSuccess());
} catch (error) {
dispatch(editUsernameFailure(error));
}
}
}

const editEmail = (id, newEmail) => {
return async (dispatch, getState) => {
const { token } = getState().auth;
dispatch(editEmailRequest());
try {
const fetchPromise = fetch('/users/email', {
method: 'PATCH',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ id, newEmail }),
});

const timeoutPromise = createTimeoutPromise(15000, 'Fetch timed out');

const response = await Promise.race([timeoutPromise, fetchPromise]);
dispatch(editEmailSuccess());
} catch (error) {
dispatch(editEmailFailure(error));
}
}
}


module.exports = {
fetchAdminStats,
fetchAllConversationsFromAPI,
fetchSyncStats,
createInvitation,
editUsername,
editEmail,
FETCH_ADMIN_STATS_REQUEST,
FETCH_ADMIN_STATS_SUCCESS,
FETCH_ADMIN_STATS_FAILURE,
EDIT_USERNAME_REQUEST,
EDIT_USERNAME_SUCCESS,
EDIT_USERNAME_FAILURE,
EDIT_EMAIL_REQUEST,
EDIT_EMAIL_SUCCESS,
EDIT_EMAIL_FAILURE,
};
Loading

0 comments on commit dc863e4

Please sign in to comment.