insomnia/packages/insomnia-app/app/ui/redux/modules/global.js
2018-12-12 12:36:11 -05:00

303 lines
8.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import electron from 'electron';
import * as React from 'react';
import { combineReducers } from 'redux';
import fs from 'fs';
import path from 'path';
import AskModal from '../../../ui/components/modals/ask-modal';
import * as moment from 'moment';
import * as importUtils from '../../../common/import';
import AlertModal from '../../components/modals/alert-modal';
import PaymentNotificationModal from '../../components/modals/payment-notification-modal';
import LoginModal from '../../components/modals/login-modal';
import * as models from '../../../models';
import SelectModal from '../../components/modals/select-modal';
import { showError, showModal } from '../../components/modals/index';
const LOCALSTORAGE_PREFIX = `insomnia::meta`;
const LOAD_START = 'global/load-start';
const LOAD_STOP = 'global/load-stop';
const LOAD_REQUEST_START = 'global/load-request-start';
const LOAD_REQUEST_STOP = 'global/load-request-stop';
const REQUEST_GROUP_TOGGLE_COLLAPSE = 'global/request-group-toggle';
const SET_ACTIVE_WORKSPACE = 'global/activate-workspace';
const COMMAND_ALERT = 'app/alert';
const COMMAND_LOGIN = 'app/auth/login';
const COMMAND_TRIAL_END = 'app/billing/trial-end';
const COMMAND_IMPORT_URI = 'app/import';
// ~~~~~~~~ //
// REDUCERS //
// ~~~~~~~~ //
function activeWorkspaceReducer(state = null, action) {
switch (action.type) {
case SET_ACTIVE_WORKSPACE:
return action.workspaceId;
default:
return state;
}
}
function loadingReducer(state = false, action) {
switch (action.type) {
case LOAD_START:
return true;
case LOAD_STOP:
return false;
default:
return state;
}
}
function loadingRequestsReducer(state = {}, action) {
switch (action.type) {
case LOAD_REQUEST_START:
return Object.assign({}, state, { [action.requestId]: action.time });
case LOAD_REQUEST_STOP:
return Object.assign({}, state, { [action.requestId]: -1 });
default:
return state;
}
}
export const reducer = combineReducers({
isLoading: loadingReducer,
loadingRequestIds: loadingRequestsReducer,
activeWorkspaceId: activeWorkspaceReducer,
});
// ~~~~~~~ //
// ACTIONS //
// ~~~~~~~ //
export function newCommand(command, args) {
return async dispatch => {
switch (command) {
case COMMAND_ALERT:
showModal(AlertModal, { title: args.title, message: args.message });
break;
case COMMAND_LOGIN:
showModal(LoginModal, { title: args.title, message: args.message });
break;
case COMMAND_TRIAL_END:
showModal(PaymentNotificationModal);
break;
case COMMAND_IMPORT_URI:
await showModal(AlertModal, {
title: 'Confirm Data Import',
message: (
<span>
Do you really want to import <code>{args.uri}</code>?
</span>
),
addCancel: true,
});
dispatch(importUri(args.workspaceId, args.uri));
break;
}
};
}
export function loadStart() {
return { type: LOAD_START };
}
export function loadStop() {
return { type: LOAD_STOP };
}
export function loadRequestStart(requestId) {
return { type: LOAD_REQUEST_START, requestId, time: Date.now() };
}
export function loadRequestStop(requestId) {
return { type: LOAD_REQUEST_STOP, requestId };
}
export function setActiveWorkspace(workspaceId) {
window.localStorage.setItem(
`${LOCALSTORAGE_PREFIX}::activeWorkspaceId`,
JSON.stringify(workspaceId),
);
return { type: SET_ACTIVE_WORKSPACE, workspaceId };
}
export function toggleRequestGroup(requestGroup) {
return {
type: REQUEST_GROUP_TOGGLE_COLLAPSE,
requestGroupId: requestGroup._id,
};
}
export function importFile(workspaceId) {
return async dispatch => {
dispatch(loadStart());
const options = {
title: 'Import Insomnia Data',
buttonLabel: 'Import',
properties: ['openFile'],
filters: [
{
name: 'Insomnia Import',
extensions: ['', 'sh', 'txt', 'json', 'har', 'curl', 'bash', 'shell', 'yaml', 'yml'],
},
],
};
electron.remote.dialog.showOpenDialog(options, async paths => {
if (!paths) {
// It was cancelled, so let's bail out
dispatch(loadStop());
return;
}
// Let's import all the paths!
for (const p of paths) {
try {
const uri = `file://${p}`;
await importUtils.importUri(workspaceId, uri);
} catch (err) {
showModal(AlertModal, { title: 'Import Failed', message: err + '' });
} finally {
dispatch(loadStop());
}
}
});
};
}
export function importUri(workspaceId, uri) {
return async dispatch => {
dispatch(loadStart());
try {
await importUtils.importUri(workspaceId, uri);
} catch (err) {
showModal(AlertModal, { title: 'Import Failed', message: err + '' });
} finally {
dispatch(loadStop());
}
};
}
export function exportFile(workspaceId = null) {
return dispatch => {
dispatch(loadStart());
const VALUE_JSON = 'json';
const VALUE_HAR = 'har';
showModal(SelectModal, {
title: 'Select Export Type',
options: [
{
name: 'Insomnia Sharable with other Insomnia users',
value: VALUE_JSON,
},
{ name: 'HAR HTTP Archive Format', value: VALUE_HAR },
],
message: 'Which format would you like to export as?',
onCancel: () => {
dispatch(loadStop());
},
onDone: async selectedFormat => {
const workspace = await models.workspace.getById(workspaceId);
// Check if we want to export private environments
let environments;
if (workspace) {
const parentEnv = await models.environment.getOrCreateForWorkspace(workspace);
environments = [parentEnv, ...(await models.environment.findByParentId(parentEnv._id))];
} else {
environments = await models.environment.all();
}
let exportPrivateEnvironments = false;
const privateEnvironments = environments.filter(e => e.isPrivate);
if (privateEnvironments.length) {
const names = privateEnvironments.map(e => e.name).join(', ');
exportPrivateEnvironments = await showModal(AskModal, {
title: 'Export Private Environments?',
message: `Do you want to include private environments (${names}) in your export?`,
});
}
const date = moment().format('YYYY-MM-DD');
const name = (workspace ? workspace.name : 'Insomnia All').replace(/ /g, '-');
const lastDir = window.localStorage.getItem('insomnia.lastExportPath');
const dir = lastDir || electron.remote.app.getPath('desktop');
const options = {
title: 'Export Insomnia Data',
buttonLabel: 'Export',
defaultPath: path.join(dir, `${name}_${date}`),
filters: [],
};
if (selectedFormat === VALUE_HAR) {
options.filters = [
{
name: 'HTTP Archive 1.2',
extensions: ['har', 'har.json', 'json'],
},
];
} else {
options.filters = [{ name: 'Insomnia Export', extensions: ['json'] }];
}
electron.remote.dialog.showSaveDialog(options, async filename => {
if (!filename) {
// It was cancelled, so let's bail out
dispatch(loadStop());
return;
}
let json;
try {
if (selectedFormat === VALUE_HAR) {
json = await importUtils.exportHAR(workspace, exportPrivateEnvironments);
} else {
json = await importUtils.exportJSON(workspace, exportPrivateEnvironments);
}
} catch (err) {
showError({
title: 'Export Failed',
error: err,
message: 'Export failed due to an unexpected error',
});
dispatch(loadStop());
return;
}
// Remember last exported path
window.localStorage.setItem('insomnia.lastExportPath', path.dirname(filename));
fs.writeFile(filename, json, {}, err => {
if (err) {
console.warn('Export failed', err);
return;
}
dispatch(loadStop());
});
});
},
});
};
}
export function init() {
let workspaceId = null;
try {
const key = `${LOCALSTORAGE_PREFIX}::activeWorkspaceId`;
const item = window.localStorage.getItem(key);
workspaceId = JSON.parse(item);
} catch (e) {
// Nothing here...
}
return setActiveWorkspace(workspaceId);
}