PromucFlow_constructor/app/client/src/selectors/entitiesSelector.ts
Hetu Nandu 655b160922
Web worker evaluation (#706)
- Adds Web workers and does evaluations in off the main thread
- Removes any need to store functions in the data tree and only keeps them around while evaluating
- Maintains a stored data tree in the redux state
- Evaluates based on editor events instead of state changes
2020-10-21 09:55:32 +05:30

274 lines
7.6 KiB
TypeScript

import { AppState } from "reducers";
import {
ActionData,
ActionDataState,
} from "reducers/entityReducers/actionsReducer";
import { ActionResponse } from "api/ActionAPI";
import { QUERY_CONSTANT } from "constants/QueryEditorConstants";
import { createSelector } from "reselect";
import { Datasource } from "api/DatasourcesApi";
import { Action } from "entities/Action";
import { find } from "lodash";
import ImageAlt from "assets/images/placeholder-image.svg";
import { CanvasWidgetsReduxState } from "../reducers/entityReducers/canvasWidgetsReducer";
export const getEntities = (state: AppState): AppState["entities"] =>
state.entities;
export const getPluginIdsOfNames = (
state: AppState,
names: Array<string>,
): Array<string> | undefined => {
const plugins = state.entities.plugins.list.filter(plugin =>
names.includes(plugin.name),
);
const pluginIds = plugins.map(plugin => plugin.id);
if (!pluginIds.length) return undefined;
return pluginIds;
};
export const getPluginIdsOfPackageNames = (
state: AppState,
names: Array<string>,
): Array<string> | undefined => {
const plugins = state.entities.plugins.list.filter(plugin =>
names.includes(plugin.packageName),
);
const pluginIds = plugins.map(plugin => plugin.id);
if (!pluginIds.length) return undefined;
return pluginIds;
};
export const getPluginNameFromDatasourceId = (
state: AppState,
datasourceId: string,
): string | undefined => {
const datasource = state.entities.datasources.list.find(
datasource => datasource.id === datasourceId,
);
const plugin = state.entities.plugins.list.find(
plugin => plugin.id === datasource?.pluginId,
);
if (!plugin) return undefined;
return plugin.name;
};
export const getPluginPackageFromId = (state: AppState, pluginId: string) => {
const plugin = state.entities.plugins.list.find(
plugin => plugin.id === pluginId,
);
if (!plugin) return "";
return plugin.packageName;
};
export const getPluginPackageFromDatasourceId = (
state: AppState,
datasourceId: string,
): string | undefined => {
const datasource = state.entities.datasources.list.find(
datasource => datasource.id === datasourceId,
);
const plugin = state.entities.plugins.list.find(
plugin => plugin.id === datasource?.pluginId,
);
if (!plugin) return undefined;
return plugin.packageName;
};
export const getPluginNameFromId = (state: AppState, pluginId: string) => {
const plugin = state.entities.plugins.list.find(
plugin => plugin.id === pluginId,
);
if (!plugin) return "";
return plugin.name;
};
export const getPluginForm = (state: AppState, pluginId: string): any[] => {
return state.entities.plugins.formConfigs[pluginId];
};
export const getActions = (state: AppState): ActionDataState =>
state.entities.actions;
export const getDatasource = (
state: AppState,
datasourceId: string,
): Datasource | undefined =>
state.entities.datasources.list.find(
datasource => datasource.id === datasourceId,
);
export const getDatasourceDraft = (state: AppState, id: string) => {
const drafts = state.ui.datasourcePane.drafts;
if (id in drafts) return drafts[id];
return {};
};
export const getPlugins = (state: AppState) => state.entities.plugins.list;
export const getPluginEditorConfigs = (state: AppState) =>
state.entities.plugins.editorConfigs;
export const getDBPlugins = createSelector(getPlugins, plugins =>
plugins.filter(plugin => plugin.type === QUERY_CONSTANT),
);
export const getDBDatasources = createSelector(
getDBPlugins,
getEntities,
(dbPlugins, entities) => {
const datasources = entities.datasources.list;
const dbPluginIds = dbPlugins.map(plugin => plugin.id);
return datasources.filter(datasource =>
dbPluginIds.includes(datasource.pluginId),
);
},
);
export const getQueryName = (state: AppState, actionId: string): string => {
const action = state.entities.actions.find((action: ActionData) => {
return action.config.id === actionId;
});
return action?.config.name ?? "";
};
const getCurrentPageId = (state: AppState) =>
state.entities.pageList.currentPageId;
export const getDatasourcePlugins = createSelector(getPlugins, plugins => {
return plugins.filter(plugin => plugin?.allowUserDatasources ?? true);
});
export const getPluginImages = createSelector(getPlugins, plugins => {
const pluginImages: Record<string, string> = {};
plugins.forEach(plugin => {
pluginImages[plugin.id] = plugin?.iconLocation ?? ImageAlt;
});
return pluginImages;
});
export const getPluginTemplates = createSelector(getPlugins, plugins => {
const pluginTemplates: Record<string, any> = {};
plugins.forEach(plugin => {
pluginTemplates[plugin.id] = plugin.templates;
});
return pluginTemplates;
});
export const getPluginResponseTypes = createSelector(getPlugins, plugins => {
const pluginResponseTypes: Record<string, any> = {};
plugins.forEach(plugin => {
pluginResponseTypes[plugin.id] = plugin.responseType;
});
return pluginResponseTypes;
});
export const getPluginDocumentationLinks = createSelector(
getPlugins,
plugins => {
const pluginDocumentationLinks: Record<string, string | undefined> = {};
plugins.forEach(plugin => {
pluginDocumentationLinks[plugin.id] = plugin.documentationLink;
});
return pluginDocumentationLinks;
},
);
export const getActionsForCurrentPage = createSelector(
getCurrentPageId,
getActions,
(pageId, actions) => {
if (!pageId) return [];
return actions.filter(a => a.config.pageId === pageId);
},
);
export const getQueryActionsForCurrentPage = createSelector(
getActionsForCurrentPage,
actions => {
return actions.filter((action: ActionData) => {
return action.config.pluginType === QUERY_CONSTANT;
});
},
);
export const getPlugin = (state: AppState, pluginId: string) => {
return state.entities.plugins.list.find(plugin => plugin.id === pluginId);
};
export const getActionResponses = createSelector(getActions, actions => {
const responses: Record<string, ActionResponse | undefined> = {};
actions.forEach(a => {
responses[a.config.id] = a.data;
});
return responses;
});
export const getAction = (
state: AppState,
actionId: string,
): Action | undefined => {
const action = find(state.entities.actions, a => a.config.id === actionId);
return action ? action.config : undefined;
};
export function getCurrentPageNameByActionId(
state: AppState,
actionId: string,
): string {
const action = state.entities.actions.find(action => {
return action.config.id === actionId;
});
const pageId = action ? action.config.pageId : "";
return getPageNameByPageId(state, pageId);
}
export function getPageNameByPageId(state: AppState, pageId: string): string {
const page = state.entities.pageList.pages.find(
page => page.pageId === pageId,
);
return page ? page.pageName : "";
}
const getQueryPaneSavingMap = (state: AppState) => state.ui.queryPane.isSaving;
const getApiPaneSavingMap = (state: AppState) => state.ui.apiPane.isSaving;
const getActionDirtyState = (state: AppState) => state.ui.apiPane.isDirty;
export const isActionSaving = (id: string) =>
createSelector(
[getQueryPaneSavingMap, getApiPaneSavingMap],
(querySavingMap, apiSavingsMap) => {
return (
(id in querySavingMap && querySavingMap[id]) ||
(id in apiSavingsMap && apiSavingsMap[id])
);
},
);
export const isActionDirty = (id: string) =>
createSelector([getActionDirtyState], actionDirtyMap => {
return id in actionDirtyMap && actionDirtyMap[id];
});
export const getAppData = (state: AppState) => state.entities.app;
export const getCanvasWidgets = (state: AppState): CanvasWidgetsReduxState =>
state.entities.canvasWidgets;