Download a list of items that failed due to import errors.
); \n textRows.push();\n textRows.push(
Review the Summary tab of the spreadsheet for failure reasons.
);\n textRows.push();\n textRows.push(
Please fix the import errors and try importing again.
);\n break;\n case \"Completed\":\n imageSource = \"https://files.connectwise.com/UI/Icons/v1.0/Status_Success.svg\";\n textHeader = \"Success! Your import is complete\";\n textRows.push(
Navigate to System and select Data Import to import more configurations.
);\n break;\n case \"Pending\":\n case \"Processing\":\n default:\n imageSource = \"https://files.connectwise.com/UI/Icons/v1.0/Application_Time.svg\";\n textHeader = \"Almost there! Your import is in progress\";\n textRows.push(
You can now close this screen or keep it open to see when your import is complete.
);\n textRows.push();\n textRows.push(
Navigate to System and select Data Import, then Jobs for import details.
);\n }\n\n let resultMessageDiv =
\n
\n \n
\n
\n {textHeader}\n
\n
\n {textRows}\n
\n
;\n\n //If button is pressed, activate redirect to new page\n if (this.state.redirect === true) {\n return
\n \n
;\n } \n \n \n return
\n
\n
\n \n
\n {this.state.displaySpinner ?\n
\n
\n \n
\n
:\n resultMessageDiv\n }\n
\n
\n {\n this.state.displaySpinner === false ?\n
\n
Import Another File
\n
:\n null\n } \n \n {\n showDownloadLink ? \n
\n
Download Error Details
\n
:\n null\n }\n
\n\n
;\n }\n}\n\nconst mapStateToProps = state => {\n let id = state.setup.configTypeId;\n return {\n uniqueCompanies: state.mapping.uniqueCompanies,\n configTypeQuestions: state.setup.configTypeQuestionDictionary[id],\n file: state.setup.file,\n mapping: state.mapping.mappings,\n mappingHeaders: state.mapping.mappingHeaders,\n vendor: state.setup.vendor,\n startLine: state.mapping.startLine,\n renewable: state.setup.renewable,\n selectConfigType: state.setup.configType,\n appSettings: state.configs.appSettings,\n templateName: state.mapping.templateName,\n configTypeId: state.setup.configTypeId,\n duplicateConfigurations: state.duplicates.duplicateConfigurations,\n importWithDuplicates: state.duplicates.importWithDuplicates\n };\n};\n\nconst mapDispatchToProps = {\n resetSetupScreen,\n resetMappingScreen\n};\n\nexport default connect(\n mapStateToProps,\n mapDispatchToProps\n)(Summary);\n\n","import { Component } from 'react';\nimport { connect } from \"react-redux\";\nimport { setConfigs } from \"../redux/actions\";\n\nexport class ConfigContainer extends Component {\n constructor(props) {\n super(props);\n\n this.componentDidMount = this.componentDidMount.bind(this);\n this.fetchBackendConfigs = this.fetchBackendConfigs.bind(this);\n }\n\n componentDidMount() {\n //Call fetch and perform any additional necessary data manipulation here\n this.fetchBackendConfigs()\n .then(newConfigs => {\n this.props.setInstrumentationKey(newConfigs.instrumentationKey);\n this.props.setConfigs(newConfigs);\n })\n .then(result => {\n this.props.appSettingsLoaded();\n })\n }\n\n fetchBackendConfigs() {\n var displayError = this.props.displayError;\n return fetch('api/Configurations', {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json'\n }\n })\n .then(res => res.json())\n .then(response => this.props.handleFetchErrors(response))\n .catch(function (error) {\n console.log(error);\n displayError(error.message, true);\n });\n }\n\n render() {\n return null;\n }\n}\n\nconst mapDispatchToProps = {\n setConfigs\n};\n\nexport default connect(\n null,\n mapDispatchToProps\n)(ConfigContainer);","import React, { Component } from 'react';\nimport { CwButton } from 'cw-widgets';\nimport './PageWrapper.css';\n\nexport class PageWrapper extends Component {\n\n constructor(props) {\n super(props);\n this.state = {\n currentPage: 1\n };\n\n this.setCurrentPage = this.setCurrentPage.bind(this);\n }\n\n calculatePageCount(dataSize, pageSize) {\n return Math.ceil(dataSize / pageSize);\n }\n\n setCurrentPage(newPageNumber) {\n this.setState({\n currentPage: newPageNumber\n })\n }\n\n //Choose whether to show or hide a page. return value is True if page number is displayed and False if page number is hidden\n showOrHidePageNumber(page, currentPage, pageCount) {\n let distanceFromPageToCurrentPage = Math.abs(currentPage - page);\n let distanceFromPageToFirstPage = Math.abs(page - 1);\n let distanceFromPageToLastPage = Math.abs(pageCount - page);\n\n let showPage = distanceFromPageToCurrentPage <= 1 || distanceFromPageToFirstPage <= 1 || distanceFromPageToLastPage <= 1;\n return showPage;\n }\n\n render() {\n let pageCount = this.calculatePageCount(this.props.dataSize, this.props.pageSize);\n\n let pageButtons = [];\n\n let currentPage = this.state.currentPage\n let backButton = \n\n pageButtons.push(backButton);\n\n //First\n let ellipsesCheck = true;\n\n for (let i = 1; i <= pageCount; i++) {\n //If page should be shown, create element\n if (this.showOrHidePageNumber(i, this.state.currentPage, pageCount)) {\n let buttonClassName = \"pageButton\";\n if (this.state.currentPage === i) {\n buttonClassName = \"pageButton pageButtonSelected\";\n }\n\n let button = ;\n pageButtons.push(button);\n ellipsesCheck = true;\n }\n //If not, check if ellipses should be shown\n else {\n if (ellipsesCheck) {\n let gap = \n ellipsesCheck = false;\n pageButtons.push(gap);\n }\n }\n }\n\n let forwardButton = \n\n pageButtons.push(forwardButton);\n\n return
\n }\n}","import React, { Component } from 'react';\nimport { SplitFrameScrollPadding } from '../Shared/SplitFrameScrollPadding';\nimport { CwLabel, CwCheckBox, CwButton, CwDialog } from 'cw-widgets';\nimport { Redirect } from 'react-router';\nimport './Mapping.css';\nimport { PageWrapper } from '../Shared/PageWrapper';\n\nexport class DuplicateConfigsDialog extends Component {\n\n constructor(props) {\n super(props);\n this.state = {\n redirect: false\n };\n this.buildSpreadsheetPreview = this.buildSpreadsheetPreview.bind(this);\n this.getStartIndex = this.getStartIndex.bind(this);\n this.getPage = this.getPage.bind(this);\n this.continue = this.continue.bind(this);\n }\n\n getStartIndex(pageSize, pageNumber) {\n return (pageSize * (pageNumber - 1));\n }\n\n buildSpreadsheetPreview(headers, dataArray) {\n let numOfColumns = headers ? headers.length : 0;\n let numOfRows = dataArray ? dataArray.length : 0;\n //create header columns\n let headerColumns = [];\n for (let col = 0; col <= numOfColumns; col++) {\n if (col === 0) {\n headerColumns.push(
);\n }\n else {\n headerColumns.push(
{headers[col - 1].displayName}
);\n }\n }\n\n //create rows\n let rows = [];\n //iterate over row quantity\n for (let row = 0; row < numOfRows; row++) {\n let rowData = [];\n //...and then iterate over column quantity\n for (let col = 0; col <= numOfColumns; col++) {\n if (col === 0) {\n rowData.push(
);\n }\n else {\n let cellData =
{dataArray[row][headers[col - 1].name]}
|| null;\n rowData.push(
{cellData}
);\n }\n }\n rows.push(
{rowData}
);\n }\n\n //return final table object\n return
\n \n
\n {headerColumns}\n
\n \n \n {rows}\n \n
;\n }\n\n continue() {\n this.setState({redirect: true})\n }\n\n getPage(pageDetails, pageSize) {\n let startIndex = this.getStartIndex(pageSize, pageDetails.currentPage);\n let endIndex = startIndex + pageSize;\n let pageNames = this.props.tableData.slice(startIndex, endIndex);\n\n let cancelFrame =
\n let dataTable = this.buildSpreadsheetPreview(this.props.tableHeaders, pageNames);\n let spreadsheetPreviewFrame =
\n {dataTable}\n
\n\n let table =
\n \n
;\n\n return table;\n }\n\n render() { \n let pageSize = 4;\n let dataSize = this.props.tableData ? this.props.tableData.length : 0;\n\n if (this.state.redirect === true) {\n return
\n \n
;\n }\n\n return (\n
\n
\n
\n \n
\n
The potential duplicate configurations this import will create are shown below. Please indicate if you want to Import With Duplicates to create new configurations for each line listed, or Import Without Duplicates to skip the lines shown and avoid creating duplicates when importing.
\n }\n}\n\nconst mapStateToProps = state => {\n return {\n uniqueCompanies: state.mapping.uniqueCompanies,\n appSettings: state.configs.appSettings,\n configTypeId: state.setup.configTypeId,\n file: state.setup.file,\n mapping: state.mapping.mappings,\n startLine: state.mapping.startLine,\n duplicateConfigurations: state.duplicates.duplicateConfigurations,\n importWithDuplicates: state.duplicates.importWithDuplicates\n };\n};\n\nconst mapDispatchToProps = {\n setCompanyAndSiteLink,\n setSiteLink,\n setDupes,\n setImportWithDuplicates,\n resetCompanyLinkingScreen\n};\n\nexport default connect(\n mapStateToProps,\n mapDispatchToProps\n)(CompanyLinking);","import React, { Component } from 'react';\nimport { CwDialog, CwButton } from 'cw-widgets';\nimport './Page.css';\n\nexport class ConfirmPrompt extends Component {\n\n render() {\n let confirmButton = \n let cancelButton = \n let buttonList = [cancelButton, confirmButton];\n let dialogContent = this.props.dialogContent;\n\n if (!this.props.showPrompt) {\n return null;\n }\n\n return
\n
\n \n {dialogContent}\n \n
\n
;\n }\n}","import React, { Component } from 'react';\nimport { CwLabel, CwImage } from 'cw-widgets';\nimport './Page.css';\n\nexport class Recommended extends Component {\n\n constructor(props) {\n super(props);\n this.state = {\n };\n }\n\n render() {\n let index = 1;\n let rows = [];\n let dragstart_handler = this.props.dragStartHandler;\n let row = \"\";\n let values = this.props.values;\n for (let item in values) {\n row =
dragstart_handler(ev, item)} >\n
\n
{values[item]}
\n
;\n \n rows.push(row);\n index++;\n };\n\n return
\n
\n {this.props.title}\n
\n
\n
\n {rows}\n
\n
\n
\n }\n}","import React from 'react';\nimport './Page.css';\nimport {CwComboBox} from 'cw-widgets';\n\nexport class NumberInput extends React.Component {\n constructor(props) {\n super(props);\n this.onChange = this.onChange.bind(this);\n }\n onChange(e) {\n this.props.setStartLine(e.id);\n }\n render() {\n return
\n
\n \n
\n
\n \n \n
\n
\n \n
\n
\n \n
\n
;\n }\n}","import React, { Component } from 'react';\nimport { SplitFrameScrollPadding } from '../Shared/SplitFrameScrollPadding';\nimport { CwLabel, CwImage } from 'cw-widgets';\nimport { Recommended } from '../Shared/Recommended';\nimport { NumberInput } from '../Shared/NumberInput';\nimport './Mapping.css';\n\nexport class Mapping extends Component {\n\n constructor(props) {\n super(props);\n this.state = {\n skipHeaders: false,\n firstLineIndex: 0,\n draggedItemId: null,\n mappingHeaders: {}\n };\n this.startLineValues = [];\n this.buildSpreadsheetPreview = this.buildSpreadsheetPreview.bind(this);\n\n this.onDragStartHandler = this.onDragStartHandler.bind(this);\n this.onDropHandler = this.onDropHandler.bind(this);\n\n this.removeMapping = this.removeMapping.bind(this);\n }\n\n buildMappingHeadersFromMappings(mappingDictionary, recommendedRows, additionalRows) {\n let mappingHeaderDictionary = {};\n for (let mapping in mappingDictionary) {\n\n let mappingLabel = recommendedRows[mapping] || additionalRows[mapping];\n if (!mappingLabel) {\n continue;\n }\n mappingLabel = this.truncateHeaderLabel(mappingLabel);\n let mappingValue = mappingDictionary[mapping];\n let dictionaryProperty = mappingHeaderDictionary[mappingValue];\n if (dictionaryProperty === undefined || dictionaryProperty === null) {\n dictionaryProperty = [];\n }\n dictionaryProperty.push({ id: mapping, label: mappingLabel });\n mappingHeaderDictionary[mappingValue] = dictionaryProperty;\n }\n return mappingHeaderDictionary;\n }\n\n checkMappedHeaders(mappings, rows) {\n let returnRows = [];\n for (let row in rows) {\n if (!mappings[row]) {\n returnRows[row] = rows[row];\n }\n }\n return returnRows;\n }\n\n onDragStartHandler(ev, id) {\n ev.preventDefault();\n this.setState({ draggedItemId: id });\n document.getElementById(\"mappingframe\").style.cursor = \"move\"; \n }\n\n truncateHeaderLabel(label) {\n if (label.length > 17) {\n label = label.substring(0, 17);\n label = label + \"...\";\n return label;\n }\n else {\n return label;\n }\n }\n\n onDropHandler(ev, colid) {\n ev.preventDefault();\n document.getElementById(\"mappingframe\").style.cursor = \"auto\"; \n\n // Get the id of the target and add the moved element to the target's DOM\n let rowid = this.state[\"draggedItemId\"];\n this.setState({ draggedItemId: null });\n if (colid === undefined || rowid === undefined || rowid === null || rowid === \"\") {\n return;\n }\n \n let dict = this.props.mapping;\n dict[rowid] = colid;\n let mappingDetail = { colid: rowid, mappings: dict[rowid] }\n this.props.setMapping(mappingDetail);\n }\n removeMapping(colid, propid) {\n this.props.removeMapping(propid);\n }\n\n buildSpreadsheetPreview(mappingHeaders) {\n\n function countforeach(value) {\n let length = value.length;\n if (length > maxLength) {\n maxLength = length;\n }\n }\n let dataArray = this.props.dataPreview;\n let maxLength = 0;\n dataArray.forEach(countforeach);\n this.startLineValues = [];\n //create header columns\n let headerColumns = [];\n let removeMapping = this.removeMapping;\n let dropHandler = this.onDropHandler;\n for (let i = 0; i < maxLength; i++) {\n let id = \"col\" + i;\n let headerRows = [];\n if (mappingHeaders && mappingHeaders[id]) {\n mappingHeaders[id].forEach(item => {\n let propId = \"\";\n propId = item.id;\n let label = item.label;\n headerRows.push(
{label}
removeMapping(id, propId)} />
);\n });\n }\n if (i === 0) {\n headerColumns.push(
dropHandler(ev, id)}>
\n {headerRows}\n
);\n }\n else {\n headerColumns.push(
dropHandler(ev, id)}>
\n {headerRows}\n
);\n }\n }\n\n //Make sure start line can't be set to greater than number of import rows\n\n //create rows\n let rows = [];\n //iterate over row quantity\n for (let row = 0; row < dataArray.length; row++) {\n let idName = (row + 1).toString();\n this.startLineValues.push({ id: row, name: idName })\n let rowColumns = [];\n //...and then iterate over column quantity\n for (let col = 0; col < maxLength; col++) {\n\n\n let cellData =
{dataArray[row][col]}
|| null;\n let lineNumber =
{row+1}
\n if (col === 0) {\n rowColumns.push(
{lineNumber}{cellData}
);\n }\n else {\n rowColumns.push(
{cellData}
);\n }\n\n }\n let rowState = \"normalDataRow\";\n if (row < this.props.startLine) {\n rowState = \"skippedDataRow\";\n }\n rows.push(
{rowColumns}
);\n }\n\n //return final table object\n return
\n \n
\n {headerColumns}\n
\n \n \n {rows}\n \n
;\n }\n render() {\n let mappingHeaders = this.buildMappingHeadersFromMappings(this.props.mapping, this.props.recommended, this.props.additionalFields);\n\n let recommendedRows = this.checkMappedHeaders(this.props.mapping, this.props.recommended);\n let additionalRows = this.checkMappedHeaders(this.props.mapping, this.props.additionalFields);\n\n let leftFrame =
\n
\n \n
\n \n \n
;\n\n let cancelFrame =
\n\n let dataTable = this.buildSpreadsheetPreview(mappingHeaders);\n\n let spreadsheetPreviewFrame =
\n {dataTable}\n
\n\n //Display data preview table and columns for mappings here\n let rightFrame =
\n \n
;\n\n return (\n
\n
\n \n
\n
\n \n
\n
\n\n )\n };\n}\n","import React, { Component } from 'react';\nimport { NavButtons } from '../Shared/NavButtons';\nimport { PageLogoHeader } from '../Shared/PageLogoHeader'\nimport initiateAppInsights from \"../Shared/AppInsights\";\nimport { Dropdown } from '../Shared/Dropdown';\nimport { SplitFrame } from '../Shared/SplitFrame';\nimport { ConfirmPrompt } from '../Shared/ConfirmPrompt';\nimport { connect } from \"react-redux\";\nimport { Mapping } from './Mapping';\nimport { CwLabel } from 'cw-widgets';\nimport {\n setMapping,\n removeMapping,\n loadMappings,\n setStartLine,\n addUniqueCompanies,\n resetMappingScreen,\n selectMappingTemplate\n} from \"../../redux/actions\";\nimport './Mapping.css';\nimport '../Shared/Page.css';\nimport '../Shared/SplitFrame.css';\n\nimport { CwTextField, CwButton, CwImage } from 'cw-widgets';\n\n\nexport class MappingsPage extends Component {\n\n constructor(props) {\n super(props);\n this.state = {\n skipHeaders: false,\n firstLineIndex: 0,\n templateTextEntry: this.props.templateName ? this.props.templateName : \"\",\n templateSelection: this.props.templateName ? { id: this.props.templateName, name: this.props.templateName } : null,\n templates: [],\n loadingTemplates: true,\n templateLoadError: false,\n showPrompt: false\n }; \n this.getRecommendedValues = this.getRecommendedValues.bind(this);\n this.getAdditionalValues = this.getAdditionalValues.bind(this);\n this.postFileForProcessing = this.postFileForProcessing.bind(this);\n this.checkForwardLinkActive = this.checkForwardLinkActive.bind(this);\n\n this.onDropWindowHandler = this.onDropWindowHandler.bind(this);\n\n this.sendAppInsights();\n this.getSaveElement = this.getSaveElement.bind(this);\n this.selectTemplate = this.selectTemplate.bind(this);\n this.createNameLine = this.createNameLine.bind(this);\n this.createSaveButton = this.createSaveButton.bind(this);\n this.nameChange = this.nameChange.bind(this);\n this.validateChars = this.validateChars.bind(this);\n this.saveOnClick = this.saveOnClick.bind(this);\n this.getTemplates(props.manageInfo, props.displayError, props.handleFetchErrors);\n this.processTemplates = this.processTemplates.bind(this);\n this.addNewTemplateToState = this.addNewTemplateToState.bind(this);\n this.postNewTemplate = this.postNewTemplate.bind(this);\n this.newSelectedTemplate = this.newSelectedTemplate.bind(this);\n this.activateConfirmPrompt = this.activateConfirmPrompt.bind(this);\n this.duplicateMappingCancelAction = this.duplicateMappingCancelAction.bind(this);\n this.duplicateMappingConfirmAction = this.duplicateMappingConfirmAction.bind(this);\n this.loadMappingFromDatabase = this.loadMappingFromDatabase.bind(this);\n this.fetchMappingTemplate = this.fetchMappingTemplate.bind(this);\n }\n\n sendAppInsights() {\n if (this.props.appSettings) {\n if (this.props.appSettings.instrumentationKey) {\n var instrumentationKey = this.props.appSettings.instrumentationKey;\n var appInsights = initiateAppInsights(instrumentationKey);\n appInsights.trackPageView({\n name: \"Mapping page\"\n });\n }\n }\n }\n\n getTemplates(manageInfo, displayError, handleFetchErrors) {\n if (this.props.getManageInfoHeader) {\n let headers = this.props.getManageInfoHeader(manageInfo);\n fetch('api/database/GetSavedMappings/' + this.props.configTypeId, {\n method: 'GET',\n headers: headers\n }).then(res => res.json())\n .then(response => handleFetchErrors(response))\n .then(data => {\n var templateList = data;\n templateList.unshift('');\n this.processTemplates(templateList);\n }).catch (function (error) {\n console.log(error);\n displayError(error.message, true);\n this.setState({templateLoadError: true})\n });\n }\n }\n\n processTemplates(templates) {\n var result = [];\n for (var index in templates) {\n result.push({ name: templates[index], id: templates[index] });\n }\n this.setState({\n templates: result,\n loadingTemplates: false\n });\n }\n\n onDropWindowHandler(ev) {\n ev.preventDefault();\n document.getElementById(\"mappingframe\").style.cursor = \"auto\";\n }\n\n\n postFileForProcessing() {\n const formData = new FormData();\n let file = this.props.file;\n let siteColumn = this.props.mapping[\"siteName\"] !== null ? this.props.mapping[\"siteName\"] : \"\";\n formData.append(file.name, file);\n return fetch('api/file/GetUniqueValuesFromColumn/', {\n method: 'POST',\n headers: {\n 'companyColumn': this.props.mapping[\"companyName\"],\n 'siteColumn': siteColumn,\n 'firstLineIndex': this.props.startLine\n },\n body: formData\n }).then(res => res.json()).then(response => this.props.handleFetchErrors(response))\n .then(companyData => {\n let uniqueCompanies = this.parseCompanies(companyData);\n this.checkCompaniesForValidLinks(Object.keys(uniqueCompanies))\n .then(linkData => {\n let uniqueCompaniesWithLinkedData = this.mergeCompanyAndLinkData(linkData, uniqueCompanies);\n this.props.addUniqueCompanies(uniqueCompaniesWithLinkedData);\n })\n return false;\n }).catch(function (error) {\n console.log(error);\n this.props.displayError(error.message, true);\n });\n }\n\n mergeCompanyAndLinkData(linkData, uniqueCompanies) {\n for (let index in linkData) {\n let link = linkData[index];\n if (uniqueCompanies[link.companySite]) {\n uniqueCompanies[link.companySite].linkedCompany = link.linkedCompany;\n uniqueCompanies[link.companySite].linkedSite = link.linkedSite;\n uniqueCompanies[link.companySite].linkedCompanyId = link.id\n }\n }\n return uniqueCompanies;\n }\n\n parseCompanies(companies) {\n var companiesOutput = {};\n for (var i = 0; i < companies.length; i++) {\n let hasSite = (companies[i].site === undefined || companies[i].site == null || companies[i].site.length <= 0) ? false : true;\n let combinedName = hasSite ? companies[i].company + ' - ' + companies[i].site : companies[i].company;\n companiesOutput[combinedName] = {\n site: companies[i].site,\n company: companies[i].company,\n };\n }\n return companiesOutput;\n }\n\n checkCompaniesForValidLinks(companiesAndSites) {\n let manageInfo = this.props.manageInfo;\n let manageInfoHeaders = this.props.getManageInfoHeader(manageInfo);\n let handleFetchErrors = this.props.handleFetchErrors;\n let displayError = this.props.displayError;\n\n let getCompanyLinksRequest = {\n importMappingName: this.props.templateName,\n configurationTypeId: this.props.configTypeId,\n companiesAndSites: companiesAndSites\n }\n\n return fetch('api/database/GetCompanyLinkDetails/', {\n method: 'POST',\n headers: manageInfoHeaders,\n body: JSON.stringify(getCompanyLinksRequest)\n })\n .then(res => res.json())\n .then(response => handleFetchErrors(response))\n .catch(function (error) {\n console.log(error);\n displayError(error.message, true);\n });\n }\n\n getRecommendedValues() {\n let recommendedValues = {\n \"companyName\": \"Company*\",\n \"name\": \"Configuration Name*\",\n \"siteName\": \"Site\",\n \"manufacturerPartNumber\": \"Manufacturer Part Number\",\n \"manufacturerName\": \"Manufacturer\",\n \"warrantyExpirationDate\": \"Expiration Date\",\n \"serialNumber\": \"Serial Number\"\n };\n\n return recommendedValues;\n }\n\n getAdditionalValues() {\n let tempadditionalvalues = {\n \"installationDate\": \"Install Date\",\n \"installedBy\": \"Installed by\",\n \"purchaseDate\": \"Purchase Date\",\n //\"locationId\": \"Location\", // cutomer won't be able to map this\n \"modelNumber\": \"Model Number\",\n \"tagNumber\": \"Tag number\",\n \"notes\": \"Notes\",\n \"vendorNotes\": \"Vendor Notes\"\n };\n\n if (this.props.configTypeQuestions) {\n this.props.configTypeQuestions.forEach(item => {\n tempadditionalvalues[\"question_\" + item.id] = item.question\n });\n };\n\n return tempadditionalvalues;\n }\n \n checkForwardLinkActive() {\n if (this.props.mapping[\"companyName\"] && this.props.mapping[\"name\"] && this.props.startLine < this.props.dataPreview.length) {\n return true;\n }\n else {\n return false;\n }\n }\n \n selectTemplate() {\n var selectId = \"selectTemplate\";\n var selectText = \"Loading Mapping Templates...\";\n var noTemplatesText = \"No Saved Mappings\";\n var selectTemplateWatermark = \"Select a Mapping Template\";\n\n let noTemplates = !this.state.loadingTemplates && !(this.state.templates.length > 1);\n let dropdownWatermark = noTemplates ? noTemplatesText : selectTemplateWatermark;\n let returnTemplate = \n return returnTemplate;\n }\n\n newSelectedTemplate(selectedTemplate, loadFromDatabase = true) {\n let name = selectedTemplate.name === null || selectedTemplate.name.length === 0 ? \"\" : selectedTemplate.name;\n this.nameChange(name);\n this.props.selectMappingTemplate(name);\n\n this.setState({\n templateSelection: selectedTemplate,\n templateTextEntry: selectedTemplate.name\n });\n\n if (name !== \"\" && loadFromDatabase) {\n this.loadMappingFromDatabase(name, this.props.dataPreview);\n }\n }\n\n loadMappingFromDatabase(selectedTemplateName, dataPreview) {\n let setStartLine = this.props.setStartLine;\n let loadMappings = this.props.loadMappings;\n let constructValidTemplate = this.constructValidTemplate;\n\n this.fetchMappingTemplate(selectedTemplateName)\n .then(function (template) {\n setStartLine(template.startLineNumber);\n let validTemplate = constructValidTemplate(template.propertyMap, dataPreview);\n loadMappings(validTemplate);\n });\n }\n\n constructValidTemplate(propertyMap, dataPreview) {\n //calculate widest row of spreadsheet\n function countforeach(value) {\n let length = value.length;\n if (length > maxLength) {\n maxLength = length;\n }\n }\n let maxLength = 0;\n dataPreview.forEach(countforeach);\n\n let validTemplate = {}\n for (let mapping in propertyMap) {\n let colNumber = propertyMap[mapping];\n\n let intColNumber = colNumber.slice(3)\n if (intColNumber < maxLength) {\n validTemplate[mapping] = propertyMap[mapping];\n }\n }\n\n return validTemplate;\n }\n\n fetchMappingTemplate(selectedTemplateName) {\n let manageInfo = this.props.manageInfo;\n let configTypeId = this.props.configTypeId;\n let apiUrl = configTypeId + \"/\" + selectedTemplateName;\n let displayError = this.props.displayError;\n if (this.props.getManageInfoHeader) {\n let headers = this.props.getManageInfoHeader(manageInfo);\n return fetch('api/database/GetSavedMappingDetails/' + apiUrl, {\n method: 'GET',\n headers: headers\n }).then(res => res.json())\n .then(response => this.props.handleFetchErrors(response))\n .catch(function (error) {\n console.log(error);\n displayError(error.message, true);\n });\n }\n }\n\n createNameLine() {\n var nameId = \"nameTemplate\";\n var nameTemplateWatermark = \"Enter Template Name\";\n let nameTemplate = this.validateChars(e)}\n />\n return nameTemplate;\n }\n\n nameChange(newName) {\n this.setState({\n templateTextEntry: newName\n })\n }\n\n validateChars(e) {\n const regex = /^[0-9a-zA-Z _]+$/;\n if (!regex.test(e.key)) {\n e.preventDefault();\n }\n }\n\n createSaveButton() {\n let saveProperties = {};\n let saveDisabled = !this.enableSaveButton();\n saveProperties.onClick = this.saveOnClick;\n saveProperties.disable = saveDisabled;\n saveProperties.className = saveDisabled ? \"saveButtonDisabled\" : \"saveButtonEnabled\";\n saveProperties.value = ;\n let saveButton =\n
\n \n
Save
\n
; \n return saveButton;\n }\n \n enableSaveButton() {\n if (this.state.templateTextEntry && this.props.mapping[\"companyName\"] && this.props.mapping[\"name\"] && !!this.state.templateTextEntry.trim()) {\n return true;\n }\n else {\n return false;\n }\n }\n\n saveOnClick() {\n //if the template name matches an existing template name show a pop-up asking stuff\n var existingTemplates = this.state.templates;\n var newTemplateName = this.state.templateTextEntry;\n let sanitizedTemplateName = newTemplateName.trim().replace(/[^0-9a-zA-Z_ ]/g, '').substring(0, 100);;\n //find duplicates\n let duplicate = false;\n if (sanitizedTemplateName.length > 0) {\n if (existingTemplates) {\n duplicate = this.checkTemplatesForDuplicate(sanitizedTemplateName, existingTemplates);\n }\n\n if (duplicate) {\n this.activateConfirmPrompt(sanitizedTemplateName);\n }\n else {\n this.postNewTemplate(sanitizedTemplateName);\n this.addNewTemplateToState(sanitizedTemplateName);\n }\n }\n }\n\n checkTemplatesForDuplicate(targetTemplateName, templates) {\n for (var template in templates) {\n if (templates[template].name === targetTemplateName) {\n return true;\n }\n }\n\n return false;\n }\n\n addNewTemplateToState(name) {\n let sortedTemplates = this.state.templates;\n\n sortedTemplates.push({ name: name, id: name });\n\n sortedTemplates.sort(function (a, b) {\n var nameA = a.name.toUpperCase();\n var nameB = b.name.toUpperCase();\n return nameA.localeCompare(nameB);\n })\n\n this.setState({\n templates: sortedTemplates\n });\n\n this.newSelectedTemplate({ name: name, id: name }, false)\n }\n\n postNewTemplate(name) {\n let manageInfo = this.props.manageInfo\n let headers = this.props.getManageInfoHeader(manageInfo);\n let mapdata = {\n \"importMappingName\": name,\n \"companyIdentifier\": manageInfo.companyId,\n \"configurationTypeId\": this.props.configTypeId,\n \"propertyMap\": this.props.mapping,\n \"startLineNumber\": this.props.startLine\n }\n fetch('api/database/SaveConfigurationMapping/', {\n method: 'POST',\n headers: headers,\n body: JSON.stringify(mapdata)\n }).then(res => res.json())\n .then(response => this.props.handleFetchErrors(response))\n .catch(function (error) {\n console.log(error);\n this.props.displayError(error.message, true);\n });\n\n }\n\n getSaveElement() {\n\n var selectedTemplate = this.selectTemplate();\n var nameTemplate = this.createNameLine();\n var saveButton = this.createSaveButton(); \n\n let selectionTable = ;\n\n return (\n
\n \n
\n );\n }\n\n activateConfirmPrompt(name) {\n this.setState({\n showPrompt: true,\n temporaryMappingName: name\n })\n }\n\n duplicateMappingConfirmAction() {\n let mappingName = this.state.templateTextEntry;\n this.postNewTemplate(mappingName);\n this.setState({ showPrompt: false });\n }\n\n duplicateMappingCancelAction() {\n this.setState({ showPrompt: false });\n }\n\n render() {\n var recommended = this.getRecommendedValues();\n var additionalFields = this.getAdditionalValues();\n var saveElement = this.getSaveElement();\n\n let duplicateMappingDialogText = \"A mapping with this name already exists. Click Save to overwrite the existing mapping, or Cancel to close this dialog and enter a different name\";\n\n return (\n
\n \n
\n
\n \n
\n
\n
\n
\n PREVIEW AND MAPPING\n
\n
Drag and drop fields from the panel to assign Manage fields to columns in your import file. You can assign multiple fields to a single column, if needed. You must map required fields to continue.
\n
\n \n {saveElement}\n \n
\n
\n \n
\n );\n }\n}\n\nconst mapStateToProps = state => {\n let id = state.setup.configTypeId;\n return {\n configTypeQuestions: state.setup.configTypeQuestionDictionary[id],\n dataPreview: state.setup.dataPreview,\n file: state.setup.file,\n mapping: state.mapping.mappings,\n startLine: state.mapping.startLine,\n appSettings: state.configs.appSettings,\n configTypeId: state.setup.configTypeId,\n templateName: state.mapping.templateName\n };\n};\n\nconst mapDispatchToProps = {\n setMapping,\n removeMapping,\n loadMappings,\n setStartLine,\n addUniqueCompanies,\n resetMappingScreen,\n selectMappingTemplate\n};\n\nexport default connect(\n mapStateToProps,\n mapDispatchToProps\n)(MappingsPage);\n\n","import {\n SELECT_CONFIGURATION_TYPE,\n SELECT_VENDOR,\n SELECT_FILE,\n ADD_DATA_PREVIEW,\n ADD_CONFIGURATION_TYPE_QUESTIONS,\n ADD_CONFIGURATION_TYPES,\n ADD_VENDORS,\n TOGGLE_RENEWABLE,\n SET_MAPPING,\n REMOVE_MAPPING,\n LOAD_MAPPINGS,\n ADD_UNIQUE_COMPANIES,\n SET_COMPANY_AND_SITE_LINK,\n SET_SITE_LINK,\n RESET_MAPPING_SCREEN,\n RESET_COMPANY_LINKING_SCREEN,\n SET_START_LINE,\n SET_CONFIGS,\n RESET_SETUP_SCREEN,\n SELECT_MAPPING_TEMPLATE,\n SET_DUPES,\n SET_IMPORT_WITH_DUPLICATES\n} from './actionTypes';\n\nexport const selectConfigType = configType => ({\n type: SELECT_CONFIGURATION_TYPE,\n payload: { configType }\n});\n\nexport const setStartLine = startLine => ({\n type: SET_START_LINE,\n payload: { startLine }\n});\n\nexport const selectVendor = vendor => ({\n type: SELECT_VENDOR,\n payload: { vendor }\n});\n\nexport const selectFile = file => ({\n type: SELECT_FILE,\n payload: { file }\n})\n\nexport const addDataPreview = dataPreview => ({\n type: ADD_DATA_PREVIEW,\n payload: { dataPreview }\n})\n\nexport const addConfigTypeQuestions = configTypeQuestions => ({\n type: ADD_CONFIGURATION_TYPE_QUESTIONS,\n payload: { configTypeQuestions }\n})\n\nexport const addConfigTypes = configTypes => ({\n type: ADD_CONFIGURATION_TYPES,\n payload: { configTypes }\n});\n\nexport const addVendors = vendors => ({\n type: ADD_VENDORS,\n payload: { vendors }\n});\n\nexport const toggleRenewable = renewable => ({\n type: TOGGLE_RENEWABLE,\n payload: { renewable }\n})\n\n\nexport const setMapping = mapping => ({\n type: SET_MAPPING,\n payload: { mapping }\n})\n\nexport const removeMapping = mappingId => ({\n type: REMOVE_MAPPING,\n payload: { mappingId }\n})\n\nexport const loadMappings = mappings => ({\n type: LOAD_MAPPINGS,\n payload: { mappings }\n})\n\nexport const addUniqueCompanies = companies => ({\n type: ADD_UNIQUE_COMPANIES,\n payload: { companies }\n})\n\nexport const setCompanyAndSiteLink = company => ({\n type: SET_COMPANY_AND_SITE_LINK,\n payload: { company }\n})\n\nexport const setSiteLink = company => ({\n type: SET_SITE_LINK,\n payload: { company }\n})\n\nexport const resetMappingScreen = reset => ({\n type: RESET_MAPPING_SCREEN,\n payload: { reset }\n})\n\nexport const resetCompanyLinkingScreen = reset => ({\n type: RESET_COMPANY_LINKING_SCREEN,\n payload: { reset }\n})\n\nexport const setConfigs = configs => ({\n type: SET_CONFIGS,\n payload: { configs }\n})\n\nexport const resetSetupScreen = reset => ({\n type: RESET_SETUP_SCREEN,\n payload: { reset }\n})\n\nexport const selectMappingTemplate = template => ({\n type: SELECT_MAPPING_TEMPLATE,\n payload: { template }\n})\n\nexport const setDupes = dupeList => ({\n type: SET_DUPES,\n payload: { dupeList }\n})\n\nexport const setImportWithDuplicates = importWithDuplicates => ({\n type: SET_IMPORT_WITH_DUPLICATES,\n payload: { importWithDuplicates }\n})","import {\n SELECT_CONFIGURATION_TYPE,\n SELECT_VENDOR,\n SELECT_FILE,\n ADD_DATA_PREVIEW,\n ADD_CONFIGURATION_TYPE_QUESTIONS,\n ADD_CONFIGURATION_TYPES,\n ADD_VENDORS,\n TOGGLE_RENEWABLE,\n RESET_SETUP_SCREEN\n} from \"../actionTypes\";\n\nconst initialState = {\n configType: null,\n configTypeId: null,\n configTypeQuestionDictionary: {},\n vendor: null,\n file: null,\n dataPreview: [],\n configTypes: [],\n vendors: [],\n configTypesLoading: true,\n vendorsLoading: true,\n renewable: true\n};\n\n\nexport default function (state = initialState, action) {\n switch (action.type) {\n case SELECT_CONFIGURATION_TYPE: {\n return Object.assign({}, state, {\n configType: action.payload.configType,\n configTypeId: action.payload.configType.id\n })\n }\n case SELECT_VENDOR: {\n return Object.assign({}, state, {\n vendor: action.payload.vendor\n })\n }\n case SELECT_FILE: {\n return Object.assign({}, state, {\n file: action.payload.file,\n })\n }\n case ADD_DATA_PREVIEW: {\n return Object.assign({}, state, {\n dataPreview: action.payload.dataPreview\n })\n }\n case ADD_CONFIGURATION_TYPE_QUESTIONS: {\n let id = action.payload.configTypeQuestions.id;\n let questions = action.payload.configTypeQuestions.questions;\n return {\n ...state,\n configTypeQuestionDictionary: {\n ...state.configTypeQuestionDictionary,\n [id]: questions\n }\n }\n }\n case ADD_CONFIGURATION_TYPES: {\n return Object.assign({}, state, {\n configTypes: action.payload.configTypes,\n configTypesLoading: false\n })\n }\n case ADD_VENDORS: {\n return Object.assign({}, state, {\n vendors: action.payload.vendors,\n vendorsLoading: false\n })\n }\n case TOGGLE_RENEWABLE: {\n return Object.assign({}, state, {\n renewable: action.payload.renewable\n })\n }\n case RESET_SETUP_SCREEN: {\n return Object.assign({}, state, {\n mappings: {},\n mappingHeaders: {},\n uniqueCompanies: {},\n startLine: 0,\n configType: null,\n configTypeId: null,\n configTypes: [],\n configTypeQuestionDictionary: {},\n file: null,\n dataPreview: [],\n vendor: null,\n vendors: [],\n configTypesLoading: true,\n vendorsLoading: true,\n renewable: true\n })\n }\n default: {\n return state;\n }\n }\n}","import {\n SET_MAPPING,\n REMOVE_MAPPING,\n LOAD_MAPPINGS,\n ADD_UNIQUE_COMPANIES,\n SET_COMPANY_AND_SITE_LINK,\n SET_SITE_LINK,\n RESET_MAPPING_SCREEN,\n RESET_COMPANY_LINKING_SCREEN,\n SET_START_LINE,\n SELECT_MAPPING_TEMPLATE\n} from \"../actionTypes\";\n\nconst initialState = {\n mappings: {},\n startLine: 0,\n uniqueCompanies: {},\n templateName: \"\"\n}\n\nexport default function(state = initialState, action) {\n switch (action.type) {\n case SET_MAPPING: {\n let id = action.payload.mapping.colid;\n let mapping = action.payload.mapping.mappings;\n let newState = {\n ...state,\n mappings: {\n ...state.mappings,\n [id]: mapping\n }\n }\n return newState;\n }\n case REMOVE_MAPPING: {\n let currentState = state;\n let mappingProperty = \"mappings\";\n let id = action.payload.mappingId;\n\n let { [mappingProperty]: mappingValue, ...noMapping } = currentState;\n let { [id]: idValue, ...noId } = mappingValue;\n let newState = { ...noMapping, [mappingProperty]: noId }\n\n return newState;\n }\n case LOAD_MAPPINGS: {\n return Object.assign({}, state, {\n mappings: action.payload.mappings\n })\n }\n case SET_START_LINE: {\n return Object.assign({}, state, {\n startLine: action.payload.startLine\n })\n }\n case ADD_UNIQUE_COMPANIES: {\n return Object.assign({}, state, {\n uniqueCompanies: action.payload.companies\n })\n }\n case SET_COMPANY_AND_SITE_LINK: {\n let companyName = action.payload.company.id;\n let companyDetails = action.payload.company.details;\n return {\n ...state,\n uniqueCompanies: {\n ...state.uniqueCompanies,\n [companyName]: {\n ...state.uniqueCompanies[companyName],\n linkedSite: companyDetails.linkedSite,\n linkedCompany: companyDetails.linkedCompany\n }\n }\n }\n }\n\n case SET_SITE_LINK: {\n let companyName = action.payload.company.id;\n let companyDetails = action.payload.company.details;\n return {\n ...state,\n uniqueCompanies: {\n ...state.uniqueCompanies,\n [companyName]: {\n ...state.uniqueCompanies[companyName],\n linkedSite: companyDetails.linkedSite\n }\n }\n }\n }\n case RESET_MAPPING_SCREEN: {\n return Object.assign({}, state, {\n mappings: {},\n uniqueCompanies: {},\n startLine: 0,\n selectedTemplate: null,\n templateName: \"\"\n })\n } \n case RESET_COMPANY_LINKING_SCREEN: {\n return {\n ...state,\n uniqueCompanies: {}\n }\n }\n case SELECT_MAPPING_TEMPLATE: {\n return Object.assign({}, state, {\n templateName: action.payload.template\n })\n }\n default: {\n return state;\n }\n }\n}; ","import {\n SET_CONFIGS\n} from \"../actionTypes\";\n\nconst initialState = {\n appSettings: null,\n configsLoaded: false\n}\n\nexport default function (state = initialState, action) {\n switch (action.type) {\n case SET_CONFIGS: {\n return Object.assign({}, state, {\n appSettings: action.payload.configs,\n configsLoaded: true\n })\n }\n default: {\n return state;\n }\n }\n}; ","import {\n SET_DUPES, SET_IMPORT_WITH_DUPLICATES\n} from \"../actionTypes\";\n\nconst initialState = {\n duplicateConfigurations: [],\n importWithDuplicates: false \n}\n\nexport default function (state = initialState, action) {\n switch (action.type) {\n case SET_DUPES: {\n return Object.assign({}, state, {\n duplicateConfigurations: action.payload.dupeList\n })\n }\n case SET_IMPORT_WITH_DUPLICATES: {\n return Object.assign({}, state, {\n importWithDuplicates: action.payload.importWithDuplicates\n })\n }\n default: {\n return state;\n }\n }\n}; ","import { combineReducers } from \"redux\";\nimport setup from \"./setup\";\nimport mapping from \"./mapping\";\nimport configs from \"./configs\";\nimport duplicates from \"./duplicates\";\n\nexport default combineReducers({ setup, mapping, configs, duplicates });","import { createStore } from \"redux\";\nimport rootReducer from \"./reducers\";\n\nexport default createStore(rootReducer);","// In production, we register a service worker to serve assets from local cache.\n\n// This lets the app load faster on subsequent visits in production, and gives\n// it offline capabilities. However, it also means that developers (and users)\n// will only see deployed updates on the \"N+1\" visit to a page, since previously\n// cached resources are updated in the background.\n\n// To learn more about the benefits of this model, read https://goo.gl/KwvDNy.\n// This link also includes instructions on opting out of this behavior.\n\nconst isLocalhost = Boolean(\n window.location.hostname === 'localhost' ||\n // [::1] is the IPv6 localhost address.\n window.location.hostname === '[::1]' ||\n // 127.0.0.1/8 is considered localhost for IPv4.\n window.location.hostname.match(\n /^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/\n )\n);\n\nexport default function register() {\n if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {\n // The URL constructor is available in all browsers that support SW.\n const publicUrl = new URL(process.env.PUBLIC_URL, window.location);\n if (publicUrl.origin !== window.location.origin) {\n // Our service worker won't work if PUBLIC_URL is on a different origin\n // from what our page is served on. This might happen if a CDN is used to\n // serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374\n return;\n }\n\n window.addEventListener('load', () => {\n const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;\n\n if (isLocalhost) {\n // This is running on localhost. Lets check if a service worker still exists or not.\n checkValidServiceWorker(swUrl);\n } else {\n // Is not local host. Just register service worker\n registerValidSW(swUrl);\n }\n });\n }\n}\n\nfunction registerValidSW(swUrl) {\n navigator.serviceWorker\n .register(swUrl)\n .then(registration => {\n registration.onupdatefound = () => {\n const installingWorker = registration.installing;\n installingWorker.onstatechange = () => {\n if (installingWorker.state === 'installed') {\n if (navigator.serviceWorker.controller) {\n // At this point, the old content will have been purged and\n // the fresh content will have been added to the cache.\n // It's the perfect time to display a \"New content is\n // available; please refresh.\" message in your web app.\n console.log('New content is available; please refresh.');\n } else {\n // At this point, everything has been precached.\n // It's the perfect time to display a\n // \"Content is cached for offline use.\" message.\n console.log('Content is cached for offline use.');\n }\n }\n };\n };\n })\n .catch(error => {\n console.error('Error during service worker registration:', error);\n });\n}\n\nfunction checkValidServiceWorker(swUrl) {\n // Check if the service worker can be found. If it can't reload the page.\n fetch(swUrl)\n .then(response => {\n // Ensure service worker exists, and that we really are getting a JS file.\n if (\n response.status === 404 ||\n response.headers.get('content-type').indexOf('javascript') === -1\n ) {\n // No service worker found. Probably a different app. Reload the page.\n navigator.serviceWorker.ready.then(registration => {\n registration.unregister().then(() => {\n window.location.reload();\n });\n });\n } else {\n // Service worker found. Proceed as normal.\n registerValidSW(swUrl);\n }\n })\n .catch(() => {\n console.log(\n 'No internet connection found. App is running in offline mode.'\n );\n });\n}\n\nexport function unregister() {\n if ('serviceWorker' in navigator) {\n navigator.serviceWorker.ready.then(registration => {\n registration.unregister();\n });\n }\n}\n","import './index.css';\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport { BrowserRouter } from 'react-router-dom';\nimport { Provider } from 'react-redux';\nimport store from './redux/store';\nimport App from './App';\nimport registerServiceWorker from './registerServiceWorker';\nimport { DndProvider } from 'react-dnd'\nimport HTML5Backend from 'react-dnd-html5-backend'\n\nconst baseUrl = document.getElementsByTagName('base')[0].getAttribute('href');\nconst rootElement = document.getElementById('root');\n\nlet connectWiseClientApi;\nlet timer;\n\ndocument.addEventListener(\"DOMContentLoaded\", function (event) {\n onReady();\n});\n\nfunction onReady() {\n timer = setTimeout(DisplayError, 60000, \"Authentication request to Manage timed out.\"); // \"Authentication request to Manage Hosted API timed out.\"\n let targetWindow = window.parent;\n if (targetWindow) {\n let message = JSON.stringify({ 'message': 'wizardloaded' });\n window.addEventListener(\"message\", receiveMessage, false);\n targetWindow.postMessage(message, \"*\");\n }\n else {\n // Old code to work with HostedAPI authentication\n connectWiseClientApi = new window.ConnectWiseHostedAPI('*',\n {\n \"eventHandlers\": [\n { \"event\": \"onLoad\", \"callback\": onLoadCallback }\n ]\n }\n , true); \n }\n};\n\nfunction receiveMessage(event) {\n // Do we trust the sender of this message?\n if (event.origin.indexOf(\"localhost\") === -1 && event.origin.indexOf(\"connectwisedev.com\") === -1 &&\n event.origin.indexOf(\"myconnectwise.net\") === -1 && event.origin.indexOf(\"cw.connectwise.net\") === -1) {\n return;\n }\n\n if (event.data) {\n let data = JSON.parse(event.data);\n if (data.memberHash) {\n window.removeEventListener(\"message\", receiveMessage);\n handleAuthData(data);\n }\n }\n }\n\nfunction handleAuthData(authData) {\n clearTimeout(timer);\n const manageInfo = {\n 'memberHash': authData.memberHash,\n 'memberId': authData.memberid ? authData.memberid : authData.memberId,\n 'companyId': authData.companyid ? authData.companyid : authData.companyId,\n 'site': authData.site,\n 'version': authData.codeBase,\n 'memberEmail': authData.memberEmail,\n 'memberContext': authData.memberContext\n }\n ReactDOM.render(\n \n \n \n \n \n \n ,\n rootElement);\n}\n\nasync function onLoadCallback() {\n connectWiseClientApi.post({ \"request\": \"getMemberAuthentication\" },\n async function (authData) {\n clearTimeout(timer);\n if (authData && authData.memberHash) {\n handleAuthData(authData);\n }\n else {\n let errorText = \"Member hash was not present for attempted access\";\n DisplayError(errorText);\n } \n })\n};\n\nfunction DisplayError(errorText)\n{\n let error = {};\n error[\"errorText\"] = errorText;\n fetch('api/cwRestApi/logFrontEndError/', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(error)\n });\n ReactDOM.render(\n
Sorry we are unable to load this page. The error has been logged. Please try again later.
,\n rootElement);\n}\n\n//display some message like \"loading, please wait?\nReactDOM.render(\n
Loading Your Page
,\n rootElement);\n\n///////////////////////////////\nregisterServiceWorker();\n\n\n","import { ApplicationInsights } from '@microsoft/applicationinsights-web';\nimport { ReactPlugin } from '@microsoft/applicationinsights-react-js';\nimport { createBrowserHistory } from \"history\";\n\nexport default function initiateAppInsights(instrumentationKey) {\n var browserHistory = createBrowserHistory({ basename: '' });\n var reactPlugin = new ReactPlugin();\n var appInsights = new ApplicationInsights({\n config: {\n instrumentationKey: instrumentationKey,\n extensions: [reactPlugin],\n extensionConfig: {\n [reactPlugin.identifier]: { history: browserHistory }\n }\n }\n });\n appInsights.loadAppInsights();\n return appInsights;\n};\n\nexport function initiateAppInsightsWithReactPlugin(reactPlugin, instrumentationKey) {\n var browserHistory = createBrowserHistory({ basename: '' });\n var appInsights = new ApplicationInsights({\n config: {\n instrumentationKey: instrumentationKey,\n extensions: [reactPlugin],\n extensionConfig: {\n [reactPlugin.identifier]: { history: browserHistory }\n }\n }\n });\n appInsights.loadAppInsights();\n return appInsights;\n};\n\n\n","import React, { Component } from 'react';\nimport { CwImage } from 'cw-widgets';\nimport './Page.css';\n\nexport class PageLogoHeader extends Component {\n\n constructor(props) {\n super(props);\n this.state = {\n };\n }\n render() {\n return
\n
\n
\n \n
\n
\n
{this.props.pageNumber} of 3 Steps
\n
\n
\n
;\n }\n}","import React, { Component } from 'react';\nimport './NavButtons.css';\nimport { Redirect, Prompt } from 'react-router';\nimport { CwButton, CwImage } from 'cw-widgets';\n\nexport class NavButtons extends Component {\n\n constructor(props) {\n super(props);\n this.state = {\n redirect: false,\n prompt: false,\n redirectRoute: \"\"\n };\n this.handleBackButtonClick = this.handleBackButtonClick.bind(this);\n this.handleForwardButtonClick = this.handleForwardButtonClick.bind(this);\n this.reroute = this.reroute.bind(this);\n }\n\n handleBackButtonClick() {\n if (this.props.backCustom) {\n this.props.backCustom();\n }\n let route = this.props.backRoute ? this.props.backRoute : '/';\n this.reroute(route);\n }\n\n handleForwardButtonClick() {\n let route = this.props.forwardRoute ? this.props.forwardRoute : '/home';\n if (this.props.forwardCustom) {\n this.props.forwardCustom()\n .then(blockRoute => {\n if (!blockRoute) {\n this.reroute(route);\n }\n });\n }\n else {\n this.reroute(route);\n }\n }\n\n reroute(route) {\n this.setState({ redirect: true, prompt: false, redirectRoute: route })\n }\n\n render() {\n let backProps = {};\n let forwardDisabled = !this.props.forwardLinkActive();\n\n //If back button is expected to be visible\n if (!this.props.backButtonDisabled) {\n backProps.onClick = this.handleBackButtonClick;\n backProps.className = \"backButton\"\n backProps.value = ;\n }\n\n let forwardProps = {};\n forwardProps.disabled = forwardDisabled;\n forwardProps.onClick = this.handleForwardButtonClick;\n forwardProps.className = forwardDisabled ? \"forwardButtonDisabled\" : \"forwardButton\";\n\n forwardProps.value = ;\n\n let backButton = ;\n let forwardButton = ; \n\n if (this.props.finalButton) {\n let finalProps = {};\n let imageState = forwardDisabled ? \"finalNavButtonImageDisabled\" : \"finalNavButtonImage\";\n finalProps.disabled = forwardDisabled;\n finalProps.onClick = this.handleForwardButtonClick;\n finalProps.className = forwardDisabled ? \"finalButtonDisabled\" : \"finalButton\";\n\n finalProps.value = ;\n\n let finalText = this.props.forwardTooltipText;\n let finalTooltip = {finalText};\n forwardButton = { finalText ? finalTooltip : null }\n }\n\n //If button is pressed, activate redirect to new page\n if (this.state.redirect === true) {\n return
\n \n \n
;\n }\n\n if (this.props.disableBackButton) {\n return
\n {forwardButton}\n
\n }\n return
\n {backButton}{forwardButton}\n
;\n }\n}","import React, { Component } from 'react';\nimport { CwComboBox, CwLabel } from 'cw-widgets';\nimport './Page.css';\n\nexport class Dropdown extends Component {\n\n render() {\n let id = this.props.id;\n let optionList = [];\n let selectedOption = this.props.selection\n if (this.props.options) {\n this.props.options.map((option) => optionList.push({ id: option.id, name: option.name }));\n }\n return
\n {this.props.header ?\n
\n {this.props.header}\n
\n :null}\n
\n \n
\n
;\n }\n}","import React from 'react';\nimport './SplitFrame.css';\n\nexport class SplitFrame extends React.Component {\n\n render() {\n let leftWidth = this.props.leftFrameWidth || \"50%\";\n let rightWidth = this.props.rightFrameWidth || \"50%\";\n let frameHeight = this.props.frameHeight || \"auto\";\n\n return
\n \n
\n
\n {this.props.leftChildren}\n
\n
\n {this.props.rightChildren}\n
\n
\n \n
\n }\n}","import React from 'react';\nimport './SplitFrame.css';\n\nexport class SplitFrameScrollPadding extends React.Component {\n\n render() {\n let leftWidth = this.props.leftFrameWidth || \"50%\";\n let rightWidth = this.props.rightFrameWidth || \"50%\";\n let frameHeight = this.props.frameHeight || \"auto\";\n\n return
\n );\n }\n}\nexport default FileDialog;","import React, { Component } from 'react';\nimport '../Shared/Page.css';\nimport { Dropdown } from '../Shared/Dropdown';\nimport { FileDialog } from '../Shared/FileDialog';\nimport { SplitFrame } from '../Shared/SplitFrame';\nimport { PageLogoHeader } from '../Shared/PageLogoHeader'\nimport { NavButtons } from '../Shared/NavButtons';\nimport Popup from '../Popup';\nimport { CwLabel, CwCheckBox } from 'cw-widgets';\nimport { connect } from \"react-redux\";\nimport {\n selectConfigType,\n selectVendor,\n selectFile,\n addDataPreview,\n addConfigTypeQuestions,\n addConfigTypes,\n addVendors,\n toggleRenewable\n} from \"../../redux/actions\";\nimport XLSX from \"xlsx\";\nimport initiateAppInsights from \"../Shared/AppInsights\";\n\nexport class Setup extends Component {\n displayName = Setup.name\n\n constructor(props) {\n super(props);\n this.state = {\n showPopup: false\n };\n\n this.handleConfigurationTypeChange = this.handleConfigurationTypeChange.bind(this);\n this.checkForwardLinkActive = this.checkForwardLinkActive.bind(this);\n this.togglePopup = this.togglePopup.bind(this);\n this.popupMessage = this.popupMessage.bind(this);\n this.loadConfigurationTypeQuestions = this.loadConfigurationTypeQuestions.bind(this);\n this.handleFileChange = this.handleFileChange.bind(this);\n this.loadVendors(props.manageInfo);\n this.loadConfigurationTypes(props.manageInfo);\n\n this.sendAppInsights();\n }\n\n sendAppInsights() {\n if (this.props.appSettings) {\n if (this.props.appSettings.instrumentationKey) {\n var instrumentationKey = this.props.appSettings.instrumentationKey;\n var appInsights = initiateAppInsights(instrumentationKey);\n appInsights.trackPageView({\n name: \"Setup page\"\n });\n }\n }\n }\n\n togglePopup() {\n this.setState({\n showPopup: !this.state.showPopup,\n });\n }\n\n popupMessage(title, message) {\n this.setState({\n messageTitle: title,\n messageText: message,\n showPopup: true\n });\n }\n\n loadConfigurationTypes(manageInfo) {\n var displayError = this.props.displayError;\n fetch('api/cwRestApi/getCompanyConfigurationTypes/', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(manageInfo)\n }).then(res => res.json()).then(response => this.props.handleFetchErrors(response))\n .then(data => {\n this.props.addConfigTypes(data);\n }).catch(function (error) {\n console.log(error);\n displayError(error.message, true);\n });\n }\n\n loadVendors(manageInfo) {\n var displayError = this.props.displayError;\n fetch('api/cwRestApi/getVendors/', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(manageInfo)\n }).then(res => res.json()).then(response => this.props.handleFetchErrors(response))\n .then(data => {\n this.props.addVendors(data);\n }).catch(function (error) {\n console.log(error);\n displayError(error.message, true);\n });\n }\n\n loadConfigurationTypeQuestions(manageInfo, id) {\n var displayError = this.props.displayError;\n var toSend = this.props.manageInfo;\n toSend[\"searchParameter\"] = id;\n fetch('api/cwRestApi/GetConfigurationTypeQuestions/', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(toSend)\n }).then(res => res.json()).then(response => this.props.handleFetchErrors(response))\n .then(data => {\n let configTypeQuestions = { id: id, questions: data }\n this.props.addConfigTypeQuestions(configTypeQuestions);\n }).catch(function (error) {\n console.log(error);\n displayError(error.message, true);\n });\n }\n checkForwardLinkActive() {\n if (this.props.configType && this.props.file && this.props.vendor) {\n return true;\n }\n else {\n return false;\n }\n }\n\n handleConfigurationTypeChange(option) {\n if (option) {\n this.loadConfigurationTypeQuestions(this.props.manageInfo, option.id);\n this.props.selectConfigType(option);\n }\n }\n\n handleFileChange(fileList) {\n let file = fileList[0];\n\n /* Boilerplate to set up FileReader */\n const reader = new FileReader();\n const rABS = !!reader.readAsBinaryString;\n reader.onload = (e) => {\n /* Parse data */\n const bstr = e.target.result;\n const wb = XLSX.read(bstr, { type: rABS ? 'binary' : 'array', sheetRows: 10 });\n /* Get first worksheet */\n const wsname = wb.SheetNames[0];\n const ws = wb.Sheets[wsname];\n /* Convert array of arrays */\n const data = XLSX.utils.sheet_to_json(ws, { header: 1, raw: false });\n\n this.props.addDataPreview(data);\n };\n if (rABS) reader.readAsBinaryString(file); else reader.readAsArrayBuffer(file);\n this.props.selectFile(file);\n }\n\n render() {\n let configurationTypeId = \"ConfigurationType\";\n let configurationTypeHeader = \"Configuration Type *\";\n let configurationTypeText = \"Loading configuration types...\";\n let configurationTypeWatermark = \"Select Manage Configuration Type\";\n\n let vendorId = \"Vendor\";\n let vendorHeader = \"Vendor *\";\n let vendorText = \"Loading vendors...\";\n let vendorWatermark = \"Select Vendor Name\";\n\n let leftFrame = \n\n let rightFrame = \n return (\n
\n \n
\n
\n \n
\n
\n
\n CONFIGURATION TYPE\n
\n
The Configuration Type screen lets you import a list of configurations from a single vendor and assign one configuration type to each list. \n Select the Vendor and Manage Configuration Type you want to assign to imported configurations.\n
\n
\n
\n \n
\n
\n Select to indicate that imported items expire and renew. \n