Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import React from "react";
- import {MuiThemeProvider, withStyles} from "@material-ui/core/styles";
- import {theme} from "../saasintegrations/theme.js";
- import InfoTab from "./saas/InfoTab.jsx";
- import MediaTab from "./tabs/media_tab/MediaTab.jsx";
- import UsersTab from "./tabs/saas_users/UsersTab";
- import ContractsTab from "./tabs/contracts_tab/ContractsTab.jsx";
- import HistoryTab from "./tabs/history_tab/HistoryTabWrapper.jsx";
- import Snackbar from "./componentsUtils/Snackbar.jsx";
- import DialogTitle from "@material-ui/core/DialogTitle";
- import Dialog from "@material-ui/core/Dialog";
- import Tabs from "@material-ui/core/Tabs";
- import Tab from "@material-ui/core/Tab";
- import Close from "@material-ui/icons/Close";
- import AssociateCatalogPopup from "./saas/CatalogAssociationPopup/CatalogAssociationPopup.jsx";
- import {OomnitzaDb} from "../api/api.coffee";
- import {OomnitzaUtility} from "../util/util.coffee";
- import LinkedIcon from "@material-ui/icons/Link";
- import UnlinkedIcon from "../saas/LinkCatalog";
- import _ from "lodash";
- import moment from "moment";
- import env from "../util/Environment.js";
- import {
- tabs,
- defaultSaasFieldsConfig,
- hiddenFields,
- getMeta,
- getContractsMeta,
- getDetails,
- getMedia,
- getMediaById,
- sendMedia,
- deleteMedia,
- updateSaas,
- wfTriggerCheck,
- getContracts,
- getFieldList,
- getLinkedStatus,
- isAutocomplete,
- getFieldsConfiguredOnSB,
- getSaasFromHistory,
- getInitialVisibleFields
- } from "./SaasDetailsUtils";
- import {ARCHIVE, NEW, EDIT, VERSION} from "./constants";
- const db = new OomnitzaDb();
- const maxWidth = 1360;
- const maxHeight = 944;
- const styles = {
- associationPanel: {
- marginRight: 15,
- display: "flex",
- alignItems: "center",
- fontSize: 14,
- color: "#8a8a8a"
- },
- dialogTitle: {
- height: 25,
- display: "flex",
- justifyContent: "space-between",
- alignItems: "center",
- backgroundColor: "#f5f5f5"
- },
- dialogSaasName: {
- maxWidth: 600,
- whiteSpace: "nowrap",
- overflow: "hidden",
- textOverflow: "ellipsis",
- fontSize: 20,
- fontWeight: "bold",
- color: "#222"
- },
- closeIcon: {
- color: "#8a8a8a",
- cursor: "pointer"
- },
- linkIconLinked: {
- marginLeft: 12,
- cursor: "pointer",
- color: "#99cc34"
- },
- linkIconUnlinked: {
- marginLeft: 12,
- cursor: "pointer",
- color: "#8a8a8a",
- "&:hover": {
- color: "#1f1f1f"
- }
- },
- linkedCatalogName: {
- maxWidth: 200,
- whiteSpace: "nowrap",
- overflow: "hidden",
- textOverflow: "ellipsis",
- color: "#000000",
- },
- paper: {
- position: "relative",
- maxWidth: maxWidth,
- maxHeight: maxHeight,
- overflow: "hidden",
- height: "calc(100% - 40px)",
- width: "100%",
- "& *": {
- fontFamily: "Roboto"
- }
- },
- tabsContainer: {
- margin: "0 12px"
- },
- tabsRoot: {
- backgroundColor: "#f5f5f5"
- },
- selectedTab: {
- color: "#1f1f1f"
- },
- disabledTab: {
- color: "#e0e0e0"
- },
- rootTab: {
- minWidth: 0,
- fontSize: "14px",
- fontWeight: 500,
- },
- snackBarError: {
- marginBottom: 20
- }
- };
- class SaasDetailsPopup extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- openStats: false,
- mode: props.mode,
- error: false,
- errorMessage: "",
- open: props.open,
- showActions: false,
- currentTab: this.props.initPage,
- meta: {},
- origFields: [],
- origData: {},
- fields: [],
- errorModel: {},
- data: [],
- tabsDisabled: false,
- media: [],
- history: [],
- contracts: [],
- contractsMeta: {},
- workflowList: [],
- showAssociatePopup: false,
- dateFormat: "MM/DD/YY",
- visibleFields: getInitialVisibleFields()
- };
- this.loadData();
- }
- componentWillReceiveProps(nextProps) {
- this.setState({ //TODO navigation to users tab goes here
- open: nextProps.open,
- media: [],
- history: [],
- contracts: [],
- showActions: false
- });
- }
- render() {
- const {classes, saas_id} = this.props;
- const {currentTab, open, data, showAssociatePopup, error, errorMessage} = this.state;
- return (<MuiThemeProvider theme={theme}>
- <Dialog
- aria-labelledby="simple-dialog-title"
- open={open}
- classes={{
- paper: classes.paper
- }}
- >
- {showAssociatePopup
- &&
- <AssociateCatalogPopup
- saas_id={saas_id}
- handleChangeCatalogLink={this.handleChangeCatalogLink}
- handleCancelClick={this.toggleAssociatePopup}/>
- }
- <DialogTitle
- id="simple-dialog-title"
- disableTypography
- classes={{
- root: classes.dialogTitle
- }}
- >
- <h2 className={classes.dialogSaasName}>
- {data.saas_name}
- </h2>
- <div style={{display: "flex", alignItems: "center"}}>
- {this.getAssociationCatalogControl()}
- <Close onClick={this.handleClose} className={classes.closeIcon}/>
- </div>
- </DialogTitle>
- <Tabs
- value={currentTab}
- indicatorColor="primary"
- style={{color: "#09c"}}
- onChange={this.changeTab}
- classes={{
- flexContainer: classes.tabsContainer,
- root: classes.tabsRoot
- }}
- >
- {this.getTabs()}
- </Tabs>
- {this.getTabsContent(currentTab)}
- <Snackbar
- style={{marginBottom: 20}}
- open={error}
- message={errorMessage}
- handleClose={this.onCloseErrorMsg}
- />
- </Dialog>
- </MuiThemeProvider>);
- }
- toggleAssociatePopup = () => {
- const showAssociatePopup = !this.state.showAssociatePopup;
- this.setState({showAssociatePopup});
- };
- handleChangeCatalogLink = () => {
- this.toggleAssociatePopup();
- this.loadData();
- };
- getAssociationCatalogControl = () => {
- const {classes} = this.props;
- const {data, mode} = this.state;
- const linked = getLinkedStatus(data);
- return (
- <div className={classes.associationPanel}>
- {linked
- ?
- <p>Linked with: <span className={classes.linkedCatalogName}> {data.saas_name}</span></p>
- :
- <span>This software is not associated with catalog</span>}
- {mode === EDIT
- &&
- linked
- ?
- <LinkedIcon className={classes.linkIconLinked} onClick={this.toggleAssociatePopup}/>
- :
- <UnlinkedIcon className={classes.linkIconUnlinked} onClick={this.toggleAssociatePopup}/>
- }
- </div>);
- };
- loadData = () => {
- const {mode, saas_id} = this.props;
- $.when(
- getMeta(),
- getDetails(saas_id),
- getContractsMeta(),
- this.getDateFormat(),
- ).then(([meta], [data], [contractsMeta], dateFormat) => {
- const errorModel = getErrorsModel(meta);
- this.setState({
- meta,
- contractsMeta,
- data,
- origData: _.cloneDeep(data),
- errorModel,
- dateFormat,
- });
- getFieldsConfiguredOnSB("SAAS", getInitialVisibleFields())
- .then(visibleFields => {
- //const fields = getFieldList(meta, data, mode, visibleFields);
- this.setState({visibleFields});
- });
- });
- };
- changeTab = (event, value) => {
- this.setState({currentTab: value});
- };
- getTabs = () => {
- const {classes: {rootTab: root, selectedTab: selected, disabledTab: disabled}} = this.props;
- const {tabsDisabled, currentTab} = this.state;
- return tabs.map(({label, id}) => {
- return <Tab
- key={id}
- value={id}
- disabled={currentTab !== id && tabsDisabled}
- label={label}
- classes={{root, selected, disabled}}
- />;
- });
- };
- getTabsContent = (currentTab) => {
- const {
- showActions, fields, media, history, workflowList, errorModel, data, contracts, contractsMeta,
- dateFormat, openStats, error
- } = this.state;
- const {initData, saas_id} = this.props;
- let filteredFields = this.filterByRelationalAndCleanUpErrors(fields);
- if (currentTab === "info") {
- return <InfoTab
- fields={filteredFields}
- {...data}
- errorModel={errorModel}
- image={`/api/v3/saas/${saas_id}/thumbnail?size=215`}
- width={"240px"}
- workflowList={workflowList}
- onBlur={this.validateField}
- showActions={showActions}
- handleChange={this.handleChange}
- handleCancel={this.handleCancel}
- handleSave={this.handleSave}
- onAutocomplete={this.onAutocomplete}
- onAddValue={this.onAddValue}
- />;
- } else if (currentTab === "media") {
- return <MediaTab
- getMedia={this.getMedia}
- sendMedia={this.sendMedia}
- deleteMedia={this.deleteMedia}
- toggleDisplayPhoto={this.toggleDisplayPhoto}
- mediaList={media}
- />;
- } else if (currentTab === "history") {
- return <HistoryTab
- previewVersion={this.previewVersionFromHistory}
- getHistoryList={this.getHistoryList}
- historyList={history}
- />;
- } else if (currentTab === "users") {
- return <UsersTab
- error={error}
- openStats={openStats}
- onCloseStats={this.onCloseStats}
- onOpenStats={this.onOpenStats}
- refreshSaas={this.refreshSaas}
- usageStatistic={data.usage_statistic}
- saasId={data.saas_id}
- dateFormat={dateFormat}
- initData={initData}
- failCallback={this.onOpenErrorMsg}
- />;
- } else if (currentTab === "contracts") {
- return <ContractsTab
- saasId={data.saas_id}
- clearContractsList={this.clearContractsList}
- getContracts={this.getContracts.bind(this)}
- contracts={contracts}
- contractMeta={contractsMeta}
- />;
- }
- };
- onAddValue = (id, value) => {
- this.handleChange({id, value: {value, label: value}});
- };
- onAutocomplete = (fieldId, value, data_type) => {
- let {searchUsers, searchLocations, searchField} = this.props;
- if (data_type === "USERS") {
- return searchUsers(value);
- } else if (data_type === "LOCATION") {
- return searchLocations(value);
- }
- return searchField(fieldId, value);
- };
- handleChange = ({id, value}) => {
- let currentFields = _.map(this.state.fields, ((field) => {
- if (field.id === id) {
- return _.extend({}, field, {value: _.isNull(value) ? "" : value});
- }
- return field;
- }));
- const isDataSame = this.compareFieldSets(this.filterByRelationalAndCleanUpErrors(currentFields), this.state.origFields);
- this.setState({fields: currentFields, showActions: !isDataSame, tabsDisabled: !isDataSame}, () => {
- this.validateField(id, "change");
- this.wfTriggerCheck(id, value);
- });
- };
- compareFieldSets = (current, original) => {
- const origMap = original.reduce(((obj, {value, id}) => {
- obj[id] = value;
- return obj;
- }), {});
- return _.every(current, (field) => {
- return _.isEqual(field.value, origMap[field.id]);
- });
- };
- validateField = (id, event) => {
- let {errorModel} = this.state;
- _.map(this.filterByRelationalAndCleanUpErrors(this.state.fields), ((field) => {
- if (field.id === id) {
- errorModel[field.id] = this.getErrorMessage(id, field, event);
- }
- }));
- this.setState({errorModel: errorModel});
- };
- getErrorMessage = (id, field, event) => {
- if (this.shouldValidate(field, event) && this.isMandatory(field)) {
- return "This is a mandatory field";
- }
- return "";
- };
- shouldValidate = (field, event) => {
- let {errorModel} = this.state;
- return event === "blur" || (event === "change" && !!errorModel[field.id]);
- };
- isMandatory = (field) => {
- return !_.trim(field.value) && field.mandatory;
- };
- validateOnSave = () => {
- let {errorModel} = this.state;
- _.map(this.filterByRelationalAndCleanUpErrors(this.state.fields), ((field) => {
- if (this.isMandatory(field)) {
- errorModel[field.id] = "This is a mandatory field";
- } else {
- errorModel[field.id] = "";
- }
- }));
- this.setState({errorModel: errorModel});
- };
- handleCancel = () => {
- this.setState({
- fields: _.cloneDeep(this.state.origFields),
- errorModel: {},
- showActions: false,
- tabsDisabled: false,
- workflowList: []
- });
- };
- handleClose = () => {
- this.setState({open: false});
- };
- handleSave = () => {
- const {saas_id} = this.props;
- this.validateOnSave();
- if (this.noErrors()) {
- let data = this.filterFieldOnSave();
- updateSaas(saas_id, data).then(() => {
- this.setState({showActions: false, tabsDisabled: false}, this.loadData);
- }).fail(oom.util.failCallback);
- }
- };
- noErrors = () => {
- return _.every(this.state.errorModel, (field) => {
- return !field;
- });
- };
- wfTriggerCheck = (id, value) => {
- const {saas_id} = this.props;
- return wfTriggerCheck(saas_id, id, value).then((response) => {
- this.setState({workflowList: response});
- });
- };
- filterByRelationalAndCleanUpErrors = (fields) => {
- const {errorModel} = this.state;
- return _.filter(fields, (field) => {
- let shouldShow = this.shouldShowByRelational(field, fields);
- if (!shouldShow) {
- errorModel[field.id] = "";
- }
- return shouldShow;
- });
- };
- shouldShowByRelational = ({dependencies}, currentFields) => {
- const fieldValueMap = createMap(currentFields);
- if (!_.isEmpty(dependencies)) {
- return _.every(dependencies, (values, id) => {
- let {value, data_type} = fieldValueMap[id];
- if (data_type === "LOCATION") {
- return _.includes(values, _.get(value, "value", value));
- }
- return _.includes(values, value);
- });
- }
- return true;
- };
- filterFieldOnSave = () => {
- const {fields, origFields} = this.state;
- let origFieldsMap = origFields.reduce(((obj, {value, id}) => {
- obj[id] = value;
- return obj;
- }), {});
- let transformedValues = _.map(this.filterByRelationalAndCleanUpErrors(fields), ({value, id, data_type, searchhelp_type}) => {
- let newValue = value;
- if (isAutocomplete(data_type)) {
- newValue = _.has(value, "value") ? {id: value.value, label: value.label} : value;
- } else if (isCustomAutocomplete(searchhelp_type)) {
- newValue = _.get(value, "value", value);
- } else if (data_type === "DATE") {
- newValue = moment(value).unix();
- }
- return {id, value: newValue};
- });
- let changedFields = _.filter(transformedValues, ({value, id}) => {
- return !_.isEqual(value, origFieldsMap[id]);
- });
- return changedFields.reduce(((obj, {value, id}) => {
- obj[id] = value;
- return obj;
- }), {});
- };
- getMedia = () => {
- const {saas_id} = this.props;
- return getMedia(saas_id).then((media) => this.setState({media}));
- };
- sendMedia = (data) => {
- const {saas_id} = this.props;
- return sendMedia(saas_id, data);
- };
- deleteMedia = (id) => {
- const {saas_id} = this.props;
- return deleteMedia(saas_id, id);
- };
- toggleDisplayPhoto = (id) => {
- const {saas_id} = this.props;
- const {media} = this.state;
- return db.v3.query.patch(["saas", saas_id, "media", id, "default_display"], {})
- .then(() => {
- return getMediaById(saas_id, id)
- })
- .then(mediaItem => {
- this.setState({media: media.map((item) => id === item.uid ? mediaItem : item)})
- });
- };
- getHistoryList = (skipCount, params) => {
- const {saas_id} = this.props;
- const queryParams = ["limit=100", `skip=${skipCount}`, ...params];
- return db.v3.query.get(["saas", saas_id, "changes-history"], queryParams)
- .then(({data: history, facets}) => {
- if (skipCount) {
- this.setState({history: this.state.history.concat(history)}); //TODO uniq - если накладыватся элементы списка
- } else {
- this.setState({history});
- }
- return [facets, skipCount];
- });
- };
- previewVersionFromHistory = (version) => {
- const {saas_id} = this.props;
- const {meta} = this.state;
- return getSaasFromHistory(saas_id, version).then((data) => {
- this.setState({
- mode: VERSION,
- tabsDisabled: true,
- currentTab: "info"
- });
- getFieldsConfiguredOnSB("SAAS", defaultSaasFieldsConfig).then(visibleFields => {
- const fields = getFieldList(meta, data, mode, visibleFields);
- this.setState({
- fields,
- origFields: _.cloneDeep(fields)
- });
- }).fail(oom.util.failCallback);
- })
- };
- refreshSaas = () => {
- return getDetails().then(data => {
- this.setState({data})
- });
- };
- onOpenStats = () => {
- this.setState({openStats: true});
- };
- onCloseStats = () => {
- this.setState({openStats: false});
- };
- getContracts = (skipCount = 0) => {
- const {saas_id} = this.props;
- return getContracts(saas_id, skipCount)
- .then(contracts => {
- if (skipCount) { //TODO uniq - если накладыватся элементы списка
- this.setState({contracts: this.state.contracts.concat(contracts)});
- } else {
- this.setState({contracts});
- }
- });
- };
- clearContractsList = () => {
- this.setState({contracts: []});
- };
- onOpenErrorMsg = (errorMessage) => {
- this.setState({error: true, errorMessage})
- };
- onCloseErrorMsg = () => {
- this.setState({error: false, errorMessage: ""})
- };
- getDateFormat = () => {
- return env.getDateFormat({moment: true});
- };
- }
- function isCustomAutocomplete(searchhelp_type) {
- return searchhelp_type === "dynamic";
- }
- function getErrorsModel(meta) {
- let errorModel = {};
- _.map(_.keys(_.omit(meta, hiddenFields)), (key) => {
- errorModel[key] = "";
- });
- return errorModel;
- }
- function createMap(fieldList) {
- return fieldList.reduce(((obj, {value, data_type, id}) => {
- if (data_type === "CHECKBOX") {
- obj[id] = {value: value == "1" ? "Checked" : "Unchecked", data_type};
- } else {
- obj[id] = {value, data_type};
- }
- return obj;
- }), {});
- }
- export default withStyles(styles)(SaasDetailsPopup);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement