{"version":3,"sources":["Stores/DataStore.tsx","Stores/ApplicationState.tsx","Components/Dropzone.tsx","Page/Jobs/Upload/UploadJobTile.tsx","Page/Jobs/Upload/UploadJob.tsx","Threading/CancellationToken.ts","Page/Jobs/JobTable.tsx","Page/Jobs/JobsCard.tsx","Page/Telematics/TelematicsScanButton.tsx","Page/Telematics/TelematicsResultPopup.tsx","Page/Telematics/InvitationDialog.tsx","Page/Telematics/TelematicsCard.tsx","Page/Content.tsx","Page/App.tsx","Page/Mock.tsx","index.tsx"],"names":["DataState","JobSortMethod","DataStore","config","this","state","Loading","fetch","message","status","PermissionError","json","response","Success","DataError","errorMessage","ErrorMessage","session","Data","Complete","accountId","cancellationToken","Updating","cancelled","portalUrl","URL","protocol","href","includeCompleted","includeCancelled","UpdateTelematicsInfo","newJobList","currentFetchPage","fetchComplete","length","concat","jobs","telematicsNodeCount","ConnectedNodesCount","telematicsImportedFileCount","ImportedFilesCount","telematicsProviderNodeCount","ConnectedProvidersCount","telematicsPendingFileCount","PendingFilesCount","jobId","method","indexOfPriorJob","findIndex","j","Id","replacementJobs","slice","req","reqIdx","fileUploads","upload","request","splice","forEach","abort","filename","find","u","file","name","customerId","onChange","onComplete","onAbort","onError","Promise","resolve","reject","agent","customer","Accounts","c","XMLHttpRequest","push","addEventListener","event","lengthComputable","loaded","total","removeFileUploadRequest","formData","FormData","append","open","send","window","email","headers","body","JSON","stringify","observable","Unknown","DropZone","props","fileInputRef","React","createRef","fileListToArray","list","array","i","item","onFilesAdded","evt","disabled","files","target","openFileDialog","current","click","onDragOver","preventDefault","setState","highlighted","onDragLeave","onDrop","dataTransfer","Button","variant","className","style","cursor","onClick","FileCopyTwoTone","ref","type","multiple","title","PureComponent","UploadJobTile","uploading","uploadProgress","onFileRemoved","Paper","toFixed","LinearProgress","value","UploadJob","filesCopy","dataStore","cancelFileUpload","fileIdx","indexOf","successfullUploaded","uploadFiles","a","promises","map","sendRequest","all","handleClose","erroredFiles","Object","values","filter","v","join","userMessageTitle","userMessage","applicationState","selectedCustomer","UploadFile","percentage","copy","handleCancelUploads","cancelAllFileUploads","handleCancel","Dialog","onClose","aria-labelledby","DialogTitle","id","DialogContent","key","DialogActions","CircularProgress","color","aria-describedby","DialogContentText","autoFocus","CancellationToken","_cancel","ApplicationState","_dataStore","pollFrequency","timeoutId","syncTimerId","QueryTelematicsScanStatus","QueryScanStatus","AccountId","syncResult","isCurrentlyScanning","IsScanning","syncResultViewed","StopPollingForJobStatuses","StopTelematicsScanPolling","ClearTelematicsScanResults","ClearJobs","GetJobs","includeCompletedJobs","includeCancelledJobs","StartPollingForJobStatuses","StartTelematicsScanPolling","selectedJob","job","jobSortMethod","Any","ByCreated","sort","b","Created","localeCompare","ByUpdated","LastUpdated","ByName","File","ObjectKey","toLocaleLowerCase","ByStatus","CurrentStatus","setTimeout","PollForJobStatuses","cancel","clearTimeout","ScanRemote","sorted","applySorting","jobSortAscending","reverse","computed","StyledTableCell","withStyles","theme","createStyles","head","backgroundColor","palette","primary","main","contrastText","fontSize","TableCell","StyledTableRow","selected","secondary","light","dark","TableRow","StyledTableSortLabel","icon","TableSortLabel","ageFromDate","date","difference","dayjs","Date","toUTCString","diff","CreateSortUpdateMethod","JobTable","observer","sortByName","sortByUpdated","sortByCreated","sortByStatus","TableContainer","Table","size","aria-label","TableHead","IconComponent","KeyboardArrowDown","active","direction","TableBody","sortedJobs","selectJob","CurrentOnsiteJobId","parts","split","JL","error","filenameFromObjectKey","CurrentMessage","JobsCard","handleOpen","toggleIncludeCompleted","toggleIncludeCancelled","Typography","FormControlLabel","control","Checkbox","checked","label","UpdateJobState","console","log","ReportError","RetryJob","CancelJob","TelematicsScanButton","handleScan","isScanning","position","TelematicsResultPopup","show","newNodes","newFiles","InvitationDialog","useState","setEmail","setEmailFromUpdate","useCallback","sendInvite","handleInvite","TextField","margin","fullWidth","TelematicsCard","shouldOpenManageEquipmentInNewTab","GetTelematicsPortal","then","url","manageDialogOpen","delayWarningDialogOpen","inviteDialogOpen","handleInvitation","InitiateScan","SendInvitation","Grid","container","xs","maxWidth","alignContent","width","height","sandbox","NewFileCount","NewNodeCount","Content","display","flexDirection","src","padding","Name","FormControl","InputLabel","Select","placeholder","e","selectCustomer","MenuItem","createMuiTheme","App","ThemeProvider","MockLauncher","customers","newId","newName","regUserId","regCustomerId","currentTab","AppBar","Tabs","newValue","Tab","defaultValue","idx","encodeURIComponent","signingFetch","signingResponse","token","RegistrationPage","statusText","document","location","endsWith","ReactDOM","render","getElementById","ApplicationInsights","appInsights","instrumentationKey","enableAutoRouteTracking","loadAppInsights","trackPageView","flush","GetSession","Error","toString","jl","ajaxAppender","createAjaxAppender","consoleAppender","createConsoleAppender","setOptions","appenders","__jsnlog_configure","info","run"],"mappings":"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","file":"static/js/main.72eec681.chunk.js","sourcesContent":["import { observable } from 'mobx';\r\nimport { IAgentDTO } from '../Models/IAgentDTO';\r\nimport { IMessageResponse } from '../Models/IMessageResponse';\r\nimport { IJobDTO } from '../Models/IJobDTO';\r\nimport { CancellationToken } from '../Threading/CancellationToken';\r\nimport { IScanStatusDTO } from '../Models/IScanStatusDTO';\r\nimport { ITelematicsInfoDTO } from '../Models/ITelematicsInfoDTO';\r\nimport { IClientConfig } from '../Models/IClientConfig';\r\n\r\n/**\r\n * Data state\r\n * The general state of the data store\r\n */\r\nexport enum DataState\r\n{\r\n\t/**\r\n\t * The state has not been set to a valid value\r\n\t */\r\n\tUnknown = 0,\r\n\t/**\r\n\t * A blocking load is occuring\r\n\t */\r\n\tLoading,\r\n\t/**\r\n\t * A non-blocking load is occuring\r\n\t */\r\n\tUpdating,\r\n\t/**\r\n\t * All loading is complete and the application can run\r\n\t */\r\n\tComplete,\r\n\t/**\r\n\t * An unhandled error occured and the application must stop\r\n\t */\r\n\tDataError,\r\n\t/**\r\n\t * The user does not have permission to the requested data \r\n\t */\r\n\tPermissionError,\r\n}\r\n\r\nexport interface IFileUploadObject{\r\n\trequest: XMLHttpRequest;\r\n\tfile: File;\r\n}\r\n\r\n/**\r\n * Data store\r\n * This store holds all data that is business critical. It is expected that this data will come from,\r\n * or be stored to, the user's account on the server.\r\n */\r\nexport class DataStore\r\n{\r\n\tpublic config: IClientConfig | null = null;\r\n\r\n\t/**\r\n\t * Gets the current session and stores it\r\n\t * @returns session \r\n\t */\r\n\tpublic async GetSession(): Promise\r\n\t{\r\n\t\t// Mark that this is a blocking load\r\n\t\tthis.state = DataState.Loading;\r\n\r\n\t\t// Get the session. This uses a cookie for authentication\r\n\t\tconst message = await fetch('/api/1/session/current');\r\n\r\n\t\t// Check to see if the cookied did not validate\r\n\t\tif (message.status === 401)\r\n\t\t{\r\n\t\t\tthis.state = DataState.PermissionError;\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\t// Parse the response; a session is really an agent\r\n\t\tconst response = await message.json() as IMessageResponse;\r\n\t\tif (response.Success !== true)\r\n\t\t{\r\n\t\t\tthis.state = DataState.DataError;\r\n\t\t\tthis.errorMessage = response.ErrorMessage;\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\tthis.session = response.Data;\r\n\r\n\t\t// Indicate we are done loading\r\n\t\tthis.state = DataState.Complete;\r\n\t\treturn this.session;\r\n\t}\r\n\r\n\tpublic async GetTelematicsPortal(accountId: string, cancellationToken?:CancellationToken)\r\n\t{\r\n\t\t// Mark that this is a blocking load\r\n\t\tthis.state = DataState.Updating;\r\n\r\n\t\t// Get the session. This uses a cookie for authentication\r\n\t\tconst message = await fetch(`/api/1/account/${accountId}/telematicsPortal`);\r\n\r\n\t\t// Check to see if the cookied did not validate\r\n\t\tif (message.status === 401)\r\n\t\t{\r\n\t\t\tthis.state = DataState.PermissionError;\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\tif(cancellationToken?.cancelled)\r\n\t\t{\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\t// Parse the response\r\n\t\tconst response = await message.json() as IMessageResponse;\r\n\t\tif (response.Success !== true || response.Data === null)\r\n\t\t{\r\n\t\t\tthis.state = DataState.DataError;\r\n\t\t\tthis.errorMessage = response.ErrorMessage;\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\tif(cancellationToken?.cancelled)\r\n\t\t{\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\tlet portalUrl = new URL(response.Data);\r\n\t\t// ensure we are using https for the portal url\r\n\t\tportalUrl.protocol = 'https';\r\n\r\n\r\n\t\t// Indicate we are done loading\r\n\t\tthis.state = DataState.Complete;\r\n\t\treturn portalUrl.href;\r\n\t}\r\n\r\n\r\n\tpublic async GetJobs(accountId: string, includeCompleted: boolean, includeCancelled: boolean, cancellationToken?:CancellationToken)\r\n\t{\r\n\t\t// update the info panel immediately so there is some user feedback\r\n\t\tawait this.UpdateTelematicsInfo(accountId, cancellationToken);\r\n\t\t\r\n\t\tif(cancellationToken?.cancelled)\r\n\t\t{\r\n\t\t\treturn null;\r\n\t\t}\r\n\t\t\r\n\t\t// Mark that this is a blocking load\r\n\t\tthis.state = DataState.Updating;\r\n\r\n\t\t// This will need to loop until no additional jobs are retreived.\r\n\t\tlet newJobList : IJobDTO[] = [];\r\n\t\tlet currentFetchPage = 0;\r\n\t\tlet fetchComplete = false;\r\n\t\twhile(!fetchComplete)\r\n\t\t{\r\n\r\n\t\t\t// Get the session. This uses a cookie for authentication\r\n\t\t\tconst message = await fetch(`/api/1/account/${accountId}/job?include=[Id,RcisUserToken,FileId,Created,CurrentStatus,LastUpdated,CurrentOnsiteJobId,File,CurrentMessage]&includeCompleted=${includeCompleted}&includeCancelled=${includeCancelled}&start=${currentFetchPage}`);\r\n\r\n\t\t\t// Check to see if the cookied did not validate\r\n\t\t\tif (message.status == 401)\r\n\t\t\t{\r\n\t\t\t\tthis.state = DataState.PermissionError;\r\n\t\t\t\treturn null;\r\n\t\t\t}\r\n\r\n\t\t\tif(cancellationToken?.cancelled)\r\n\t\t\t{\r\n\t\t\t\treturn null;\r\n\t\t\t}\r\n\r\n\t\t\t// Parse the response\r\n\t\t\tconst response = await message.json() as IMessageResponse;\r\n\t\t\tif (response.Success !== true || response.Data === null)\r\n\t\t\t{\r\n\t\t\t\tthis.state = DataState.DataError;\r\n\t\t\t\tthis.errorMessage = response.ErrorMessage;\r\n\t\t\t\treturn null;\r\n\t\t\t}\r\n\r\n\t\t\tif(cancellationToken?.cancelled)\r\n\t\t\t{\r\n\t\t\t\treturn null;\r\n\t\t\t}\r\n\r\n\t\t\t// Devin 1/5/2021\r\n\t\t\t// fetching all jobs can result in some serious lag, and eventually a total freeze of the front end.\r\n\t\t\t// this needs to be done differently if we are going to loop through and grab pages of data like this.\r\n\r\n\t\t\t// if our fetch results in an empty list, we have reached the end of the list\r\n\t\t\t// otherwise just add the fetched jobs to the list.\r\n\t\t\tif(response.Data.length > 0)\r\n\t\t\t{\r\n\t\t\t\tnewJobList = newJobList.concat(response.Data);\r\n\t\t\t\t// currentFetchPage = currentFetchPage+100;\r\n\t\t\t}\r\n\t\t\t// else\r\n\t\t\t// {\r\n\t\t\t// \tfetchComplete = true;\r\n\t\t\t// }\r\n\r\n\t\t\t// to improve performance for the time being, we are just grabbing the first page of jobs\r\n\t\t\tfetchComplete = true;\r\n\t\t}\r\n\t\tthis.jobs = newJobList;\r\n\r\n\r\n\t\t// Indicate we are done loading\r\n\t\tthis.state = DataState.Complete;\r\n\t\treturn this.jobs;\r\n\t}\r\n\r\n\t\r\n\t@observable\r\n\tpublic telematicsNodeCount: number = 0;\r\n\r\n\t@observable\r\n\tpublic telematicsImportedFileCount: number = 0;\r\n\r\n\t@observable\r\n\tpublic telematicsPendingFileCount: number = 0;\r\n\r\n\t@observable\r\n\tpublic telematicsProviderNodeCount: number = 0;\r\n\r\n\tpublic async UpdateTelematicsInfo(accountId: string, cancellationToken?:CancellationToken)\r\n\t{\r\n\t\t// Mark that this is a blocking load\r\n\t\t//this.state = DataState.Updating;\r\n\r\n\t\t// Get the session. This uses a cookie for authentication\r\n\t\tconst message = await fetch(`/api/1/account/${accountId}/telematicsInfo`);\r\n\r\n\t\t// Check to see if the cookied did not validate\r\n\t\tif (message.status == 401)\r\n\t\t{\r\n\t\t\tthis.state = DataState.PermissionError;\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\tif(cancellationToken?.cancelled)\r\n\t\t{\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\t// Parse the response\r\n\t\tconst response = await message.json() as IMessageResponse;\r\n\t\tif (response.Success !== true || response.Data == null)\r\n\t\t{\r\n\t\t\tthis.state = DataState.DataError;\r\n\t\t\tthis.errorMessage = response.ErrorMessage;\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\tif(cancellationToken?.cancelled)\r\n\t\t{\r\n\t\t\treturn null;\r\n\t\t}\r\n\t\tthis.telematicsNodeCount = response.Data.ConnectedNodesCount;\r\n\t\tthis.telematicsImportedFileCount = response.Data.ImportedFilesCount;\r\n\t\tthis.telematicsProviderNodeCount = response.Data.ConnectedProvidersCount;\r\n\t\tthis.telematicsPendingFileCount = response.Data.PendingFilesCount;\r\n\r\n\r\n\t\t// Indicate we are done loading\r\n\t\t//this.state = DataState.Complete;\r\n\t}\r\n\r\n\tpublic ClearJobs()\r\n\t{\r\n\t\tthis.jobs = [];\r\n\t}\r\n\r\n\tpublic async UpdateJobState(jobId: string)\r\n\t{\r\n\t\t// Mark that this is a blocking load\r\n\t\tthis.state = DataState.Updating;\r\n\r\n\t\t// Get the session. This uses a cookie for authentication\r\n\t\tconst message = await fetch(`/api/1/job/${jobId}/status`,\r\n\t\t\t{\r\n\t\t\t\tmethod: 'POST'\r\n\t\t\t});\r\n\r\n\t\t// Check to see if the cookied did not validate\r\n\t\tif (message.status == 401)\r\n\t\t{\r\n\t\t\tthis.state = DataState.PermissionError;\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\t// Parse the response; a session is really an agent\r\n\t\tconst response = await message.json() as IMessageResponse;\r\n\t\tif (response.Success !== true || response.Data == null)\r\n\t\t{\r\n\t\t\tthis.state = DataState.DataError;\r\n\t\t\tthis.errorMessage = response.ErrorMessage;\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\t// Replace the updated data of this once job\r\n\t\tconst indexOfPriorJob = this.jobs.findIndex(j => j.Id === jobId);\r\n\t\tif(indexOfPriorJob < 0)\r\n\t\t{\r\n\t\t\treturn this.jobs;\r\n\t\t}\r\n\r\n\t\tconst replacementJobs = this.jobs.slice();\r\n\t\treplacementJobs[indexOfPriorJob] = response.Data;\r\n\t\tthis.jobs = replacementJobs;\r\n\r\n\t\t// Indicate we are done loading\r\n\t\tthis.state = DataState.Complete;\r\n\t\treturn this.jobs;\r\n\t}\r\n\r\n\t/** \r\n\t * The current session (agent)\r\n\t */\r\n\t@observable\r\n\tpublic session: IAgentDTO | null = null;\r\n\r\n\t@observable\r\n\tpublic jobs: Array = observable([]);\r\n\r\n\t/**\r\n\t * The current state of the data\r\n\t */\r\n\t@observable\r\n\tpublic state: DataState = DataState.Unknown;\r\n\r\n\t/**\r\n\t * Any custom error message (should only be set if state == DataState.DataError)\r\n\t */\r\n\t@observable\r\n\tpublic errorMessage: string | null = null;\r\n\r\n\t@observable\r\n\tpublic fileUploads: IFileUploadObject[] = [];\r\n\r\n\tpublic removeFileUploadRequest(req: XMLHttpRequest)\r\n\t{\r\n\t\tconst reqIdx = this.fileUploads.findIndex(upload => upload.request === req);\r\n\t\tif(reqIdx > -1)\r\n\t\t{\r\n\t\t\treturn this.fileUploads.splice(reqIdx,1);\r\n\t\t}\r\n\t\treturn [];\r\n\t}\r\n\r\n\tpublic cancelAllFileUploads()\r\n\t{\r\n\t\tthis.fileUploads.slice().forEach(upload => upload.request.abort());\r\n\t}\r\n\r\n\tpublic cancelFileUpload(filename: string)\r\n\t{\r\n\t\tconst upload = this.fileUploads.find(u => u.file.name === filename);\r\n\t\tif(upload)\r\n\t\t{\r\n\t\t\tupload.request.abort();\r\n\t\t}\r\n\t}\r\n\r\n\tpublic UploadFile(\r\n\t\tcustomerId: string,\r\n\t\tfile: File,\r\n\t\tonChange: (filename: string, percentage: number) => void,\r\n\t\tonComplete: (filename: string) => void,\r\n\t\tonAbort: (filename: string) => void,\r\n\t\tonError: (filename: string) => void)\r\n\t{\r\n\t\treturn new Promise((resolve, reject) =>\r\n\t\t{\r\n\t\t\tconst agent = this.session;\r\n\t\t\tif(!agent)\r\n\t\t\t{\r\n\t\t\t\treject('No agent selected');\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tconst customer = agent.Accounts.find(c => c.Id == customerId) || null;\r\n\t\t\tif (customer == null)\r\n\t\t\t{\r\n\t\t\t\treject('No customer selected');\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tconst req = new XMLHttpRequest();\r\n\r\n\t\t\t// add this request to our list of pending uploads\r\n\t\t\tthis.fileUploads.push({request: req, file: file});\r\n\r\n\t\t\treq.upload.addEventListener('progress', event =>\r\n\t\t\t{\r\n\t\t\t\tif (event.lengthComputable)\r\n\t\t\t\t{\r\n\t\t\t\t\tonChange(file.name, (event.loaded / event.total) * 100);\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t\treq.addEventListener('load', event =>\r\n\t\t\t{\r\n\t\t\t\tonComplete(file.name);\r\n\t\t\t\tresolve(req.response);\r\n\t\t\t\t// remove the inactive request from our upload list\r\n\t\t\t\tthis.removeFileUploadRequest(req);\r\n\t\t\t});\r\n\r\n\t\t\treq.addEventListener('error', event =>\r\n\t\t\t{\r\n\t\t\t\tonError(file.name);\r\n\t\t\t\treject(req.response);\r\n\t\t\t\t// remove the inactive request from our upload list\r\n\t\t\t\tthis.removeFileUploadRequest(req);\r\n\t\t\t});\r\n\r\n\t\t\treq.addEventListener('abort', event =>\r\n\t\t\t{\r\n\t\t\t\tonAbort(file.name);\r\n\t\t\t\treject(req.response);\r\n\t\t\t\t// remove the inactive request from our upload list\r\n\t\t\t\tthis.removeFileUploadRequest(req);\r\n\t\t\t});\r\n\r\n\t\t\tconst formData = new FormData();\r\n\t\t\tformData.append('file', file, file.name);\r\n\t\t\treq.open('PUT', `/api/1/agent/${agent.Id}/account/${customer.Id}/job`);\r\n\t\t\treq.send(formData);\r\n\t\t});\r\n\t}\r\n\r\n\tpublic async CancelJob(jobId: string)\r\n\t{\r\n\t\t// Mark that this is a blocking load\r\n\t\tthis.state = DataState.Loading;\r\n\r\n\t\t// Get the session. This uses a cookie for authentication\r\n\t\tconst message = await fetch(`/api/1/job/${jobId}/cancel`,\r\n\t\t\t{\r\n\t\t\t\tmethod: 'POST'\r\n\t\t\t});\r\n\r\n\t\t// Check to see if the cookied did not validate\r\n\t\tif (message.status == 401)\r\n\t\t{\r\n\t\t\tthis.state = DataState.PermissionError;\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\t// Parse the response\r\n\t\tconst response = await message.json() as IMessageResponse;\r\n\t\tif (response.Success !== true || response.Data == null)\r\n\t\t{\r\n\t\t\tthis.state = DataState.DataError;\r\n\t\t\tthis.errorMessage = response.ErrorMessage;\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\t// Replace the updated data of this once job\r\n\t\tconst indexOfPriorJob = this.jobs.findIndex(j => j.Id === jobId);\r\n\t\tconst replacementJobs = this.jobs.slice();\r\n\t\treplacementJobs[indexOfPriorJob] = response.Data;\r\n\t\tthis.jobs = replacementJobs;\r\n\r\n\t\t// Indicate we are done loading\r\n\t\tthis.state = DataState.Complete;\r\n\t\treturn this.jobs;\r\n\t}\r\n\r\n\tpublic async RetryJob(jobId: string)\r\n\t{\r\n\t\t// Mark that this is a blocking load\r\n\t\tthis.state = DataState.Loading;\r\n\r\n\t\t// Get the session. This uses a cookie for authentication\r\n\t\tconst message = await fetch(`/api/1/job/${jobId}/retry`,\r\n\t\t\t{\r\n\t\t\t\tmethod: 'POST'\r\n\t\t\t});\r\n\r\n\t\t// Check to see if the cookied did not validate\r\n\t\tif (message.status == 401)\r\n\t\t{\r\n\t\t\tthis.state = DataState.PermissionError;\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\t// Parse the response\r\n\t\tconst response = await message.json() as IMessageResponse;\r\n\t\tif (response.Success !== true || response.Data == null)\r\n\t\t{\r\n\t\t\tthis.state = DataState.DataError;\r\n\t\t\tthis.errorMessage = response.ErrorMessage;\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\t// Replace the updated data of this once job\r\n\t\tconst indexOfPriorJob = this.jobs.findIndex(j => j.Id === jobId);\r\n\t\tconst replacementJobs = this.jobs.slice();\r\n\t\treplacementJobs[indexOfPriorJob] = response.Data;\r\n\t\tthis.jobs = replacementJobs;\r\n\r\n\t\t// Indicate we are done loading\r\n\t\tthis.state = DataState.Complete;\r\n\t\treturn this.jobs;\r\n\t}\r\n\r\n\tpublic async ReportError(jobId:string)\r\n\t{\r\n\t\t// Mark that this is a blocking load\r\n\t\tthis.state = DataState.Loading;\r\n\r\n\t\t// Get the session. This uses a cookie for authentication\r\n\t\tconst message = await fetch(`/api/1/agent/${this.session?.Id}/job/${jobId}/error`,\r\n\t\t\t{\r\n\t\t\t\tmethod: 'POST'\r\n\t\t\t});\r\n\r\n\t\t// Check to see if the cookied did not validate\r\n\t\tif (message.status == 401)\r\n\t\t{\r\n\t\t\tthis.state = DataState.PermissionError;\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\tconst response = await message.json() as IMessageResponse;\r\n\t\tif (response.Success !== true || response.Data == null)\r\n\t\t{\r\n\t\t\tthis.state = DataState.DataError;\r\n\t\t\tthis.errorMessage = response.ErrorMessage;\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\twindow.open(response.Data);\r\n\r\n\t\t// Indicate we are done loading\r\n\t\tthis.state = DataState.Complete;\r\n\t\treturn;\r\n\t}\r\n\r\n\tpublic async ScanRemote(accountId:string)\r\n\t{\r\n\t\t// Mark that this is a blocking load\r\n\t\tthis.state = DataState.Loading;\r\n\r\n\t\t// This uses a cookie for authentication\r\n\t\tconst message = await fetch(`/api/1/account/${accountId}/telematics/scan`,\r\n\t\t\t{\r\n\t\t\t\tmethod: 'POST'\r\n\t\t\t});\r\n\r\n\t\t// Indicate we are done loading\r\n\t\tthis.state = DataState.Complete;\r\n\t\treturn;\r\n\t}\r\n\r\n\t\r\n\tpublic async QueryScanStatus(accountId:string) : Promise\r\n\t{\r\n\t\t// This uses a cookie for authentication\r\n\t\tconst message = await fetch(`/api/1/account/${accountId}/telematics/scan`,\r\n\t\t\t{\r\n\t\t\t\tmethod: 'GET'\r\n\t\t\t});\r\n\r\n\t\tconst response = await message.json() as IMessageResponse;\r\n\t\tif(!response.Success)\r\n\t\t{\r\n\t\t\tthis.state = DataState.DataError;\r\n\t\t\tthis.errorMessage = response.ErrorMessage;\r\n\t\t\treturn null;\r\n\t\t}\r\n\t\treturn response.Data;\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Send an invitation to the specified email that will allow the recipient to connect to the specified account\r\n\t * @param email The email address to dispatch the invitation to\r\n\t * @param accountId The account under the current agent that the invitation will connect to\r\n\t */\r\n\tpublic async SendInvitation(email:string, accountId:string)\r\n\t{\r\n\t\t// Mark that this is a blocking load\r\n\t\tthis.state = DataState.Loading;\r\n\r\n\t\t// Get the session. This uses a cookie for authentication\r\n\t\tconst message = await fetch(`/api/1/account/${accountId}/invitation`,\r\n\t\t\t{\r\n\t\t\t\tmethod: 'POST',\r\n\t\t\t\theaders: {\r\n\t\t\t\t\t'Content-Type': 'application/json',\r\n\t\t\t\t},\r\n\t\t\t\tbody: JSON.stringify(email),\r\n\t\t\t});\r\n\r\n\t\t// Check to see if the cookied did not validate\r\n\t\tif (message.status == 401)\r\n\t\t{\r\n\t\t\tthis.state = DataState.PermissionError;\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\tconst response = await message.json() as IMessageResponse;\r\n\t\tif (response.Success !== true || response.Data == null)\r\n\t\t{\r\n\t\t\tthis.state = DataState.DataError;\r\n\t\t\tthis.errorMessage = response.ErrorMessage;\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\t// Indicate we are done loading\r\n\t\tthis.state = DataState.Complete;\r\n\t\treturn;\r\n\r\n\t}\r\n}\r\n","import { observable, computed } from 'mobx';\r\nimport { IAccountDTO } from '../Models/IAccountDTO';\r\nimport { DataStore } from './DataStore';\r\nimport { IJobDTO } from '../Models/IJobDTO';\r\nimport { CancellationToken } from '../Threading/CancellationToken';\r\nimport { IScanStatusDTO } from '../Models/IScanStatusDTO';\r\n\r\nexport enum JobSortMethod\r\n{\r\n\tAny = 0,\r\n\tByName,\r\n\tByUpdated,\r\n\tByCreated,\r\n\tByStatus\r\n}\r\n\r\n/**\r\n * This store handles application view state; that is, state that we would like to be persisted, but\r\n * is not business critical and thus not stored to the server.\r\n * \r\n * This allows us to store cross-cutting concerns like 'which customer should be displayed' in \r\n * unrelated components.\r\n */\r\nexport class ApplicationState\r\n{\r\n\tprivate readonly _dataStore: DataStore\r\n\tpublic constructor(dataStore: DataStore)\r\n\t{ \r\n\t\tthis._dataStore = dataStore;\r\n\t}\r\n\r\n\t/**\r\n\t * Select customer and indicate it should be displayed\r\n\t */\r\n\tpublic selectCustomer(id: string | null): IAccountDTO | null\r\n\t{\r\n\t\tthis.StopPollingForJobStatuses();\r\n\t\tthis.StopTelematicsScanPolling();\r\n\t\tthis.ClearTelematicsScanResults();\r\n\r\n\t\tif (id == null)\r\n\t\t{\r\n\t\t\tthis.selectedCustomer = null;\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\t// Find the customer this id references\r\n\t\t\tconst customer = this._dataStore.session?.Accounts.find(c => c.Id == id) || null;\r\n\t\t\tthis.selectedCustomer = customer;\r\n\r\n\t\t\tthis._dataStore.ClearJobs();\r\n\t\t\t// Now get the jobs for this customer\r\n\t\t\tif(customer)\r\n\t\t\t{\r\n\t\t\t\tthis._dataStore.GetJobs(customer.Id, this.includeCompletedJobs, this.includeCancelledJobs);\r\n\t\t\t\tthis.StartPollingForJobStatuses();\r\n\t\t\t\tthis.StartTelematicsScanPolling();\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn this.selectedCustomer;\r\n\t}\r\n\r\n\t/**\r\n\t * The currently selected customer.\r\n\t */\r\n\t@observable\r\n\tpublic selectedCustomer: IAccountDTO | null = null;\r\n\r\n\tpublic selectJob(jobId: string | null) : IJobDTO | null\r\n\t{\r\n\t\tif(jobId == null)\r\n\t\t{\r\n\t\t\tthis.selectedJob = null;\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tconst job = this._dataStore.jobs.find(j => j.Id == jobId) || null;\r\n\t\t\tthis.selectedJob = job;\r\n\t\t}\r\n\r\n\t\treturn this.selectedJob;\r\n\t}\r\n\r\n\t@observable\r\n\tpublic selectedJob: IJobDTO | null = null;\r\n\r\n\t@observable\r\n\tpublic jobSortMethod: JobSortMethod = JobSortMethod.ByCreated;\r\n\r\n\t@observable\r\n\tpublic jobSortAscending: boolean = true;\r\n\r\n\tprivate applySorting()\r\n\t{\r\n\t\tswitch (this.jobSortMethod)\r\n\t\t{\r\n\t\tcase JobSortMethod.Any:\r\n\t\t\treturn this._dataStore.jobs.slice();\r\n\t\tcase JobSortMethod.ByCreated:\r\n\t\t\treturn this._dataStore.jobs.slice().sort((a, b) => b.Created.localeCompare(a.Created));\r\n\t\tcase JobSortMethod.ByUpdated:\r\n\t\t\treturn this._dataStore.jobs.slice().sort((a, b) => b.LastUpdated.localeCompare(a.LastUpdated));\r\n\t\tcase JobSortMethod.ByName:\r\n\t\t\treturn this._dataStore.jobs.slice().sort((a, b) => a.File.ObjectKey.toLocaleLowerCase().localeCompare(b.File.ObjectKey.toLocaleLowerCase()));\r\n\t\tcase JobSortMethod.ByStatus:\r\n\t\t\treturn this._dataStore.jobs.slice().sort((a, b) => a.CurrentStatus.toLocaleLowerCase().localeCompare(b.CurrentStatus.toLocaleLowerCase()));\r\n\t\t}\r\n\t}\r\n\r\n\t@computed\r\n\tpublic get sortedJobs()\r\n\t{\r\n\t\tif(!this._dataStore.jobs)\r\n\t\t{\r\n\t\t\treturn [];\r\n\t\t}\r\n\r\n\t\tconst sorted = this.applySorting();\r\n\t\tif(!this.jobSortAscending)\r\n\t\t{\r\n\t\t\treturn sorted.reverse();\r\n\t\t}\r\n\t\treturn sorted;\r\n\t}\r\n\r\n\t@observable\r\n\tpublic includeCompletedJobs: boolean = false;\r\n\r\n\t@observable\r\n\tpublic includeCancelledJobs: boolean = false;\r\n\r\n\tpublic StartPollingForJobStatuses()\r\n\t{\r\n\t\tthis.timeoutId = setTimeout(() => this.PollForJobStatuses(), this.pollFrequency);\r\n\t}\r\n\r\n\tpublic StopPollingForJobStatuses()\r\n\t{\r\n\t\tif(this.cancellationToken)\r\n\t\t{\r\n\t\t\tthis.cancellationToken.cancel();\r\n\t\t}\r\n\r\n\t\tclearTimeout(this.timeoutId);\r\n\t\tthis.timeoutId = null;\r\n\t}\r\n\r\n\tprivate readonly pollFrequency = 30000;\r\n\tprivate timeoutId: any = null;\r\n\tprivate cancellationToken: CancellationToken | null = null;\r\n\r\n\tprivate async PollForJobStatuses()\r\n\t{\r\n\t\tif(!this._dataStore.session)\r\n\t\t{\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tif(!this.selectedCustomer)\r\n\t\t{\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tconst cancellationToken = new CancellationToken();\r\n\t\tthis.cancellationToken = cancellationToken;\r\n\t\tawait this._dataStore.GetJobs(this.selectedCustomer.Id, this.includeCompletedJobs, this.includeCancelledJobs, cancellationToken);\r\n\r\n\t\tif(cancellationToken.cancelled)\r\n\t\t{\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tthis.timeoutId = setTimeout(() => this.PollForJobStatuses(), this.pollFrequency);\r\n\t}\r\n\r\n\r\n\t/// region: Telematics Scan state\r\n\tprivate syncTimerId: any | null = null;\r\n\t\r\n\t@observable\r\n\tpublic syncResult: IScanStatusDTO | null = null;\r\n\t\r\n\t@observable\r\n\tpublic syncResultViewed : boolean = true;\r\n\r\n\t@observable\r\n\tpublic isCurrentlyScanning: boolean = false;\r\n\r\n\tprivate QueryTelematicsScanStatus = async () =>\r\n\t{\r\n\t\tif(!this.selectedCustomer)\r\n\t\t{\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\tconst status = await this._dataStore.QueryScanStatus(this.selectedCustomer.Id);\r\n\t\t\r\n\t\tif(!this.selectedCustomer)\r\n\t\t{\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\tif(this.selectedCustomer.Id !== status?.AccountId)\r\n\t\t{\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\tthis.syncResult = status;\r\n\t\tthis.isCurrentlyScanning = status?.IsScanning || false;\r\n\t\tif(status?.IsScanning)\r\n\t\t{\r\n\t\t\tthis.syncResultViewed = false;\r\n\t\t}\r\n\t\treturn this.isCurrentlyScanning;\r\n\t}\r\n\r\n\tpublic async InitiateScan()\r\n\t{\r\n\t\tif(!this.selectedCustomer)\r\n\t\t{\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\tthis.syncResult = null;\r\n\t\tthis.syncResultViewed = false;\r\n\t\tthis.isCurrentlyScanning = true;\r\n\t\tawait this._dataStore.ScanRemote(this.selectedCustomer.Id);\r\n\t\tthis.StartTelematicsScanPolling();\r\n\t}\r\n\r\n\tpublic async StartTelematicsScanPolling()\r\n\t{\r\n\t\tconst isScanning = await this.QueryTelematicsScanStatus();\r\n\t\tif(isScanning)\r\n\t\t{\r\n\t\t\tthis.syncTimerId = setTimeout(() => \r\n\t\t\t{\r\n\t\t\t\tthis.StartTelematicsScanPolling();\r\n\t\t\t}, 3333);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tthis.StopTelematicsScanPolling();\r\n\t\t\t// after polling is complete, we should fetch jobs\r\n\t\t\tif(this.selectedCustomer)\r\n\t\t\t{\r\n\t\t\t\tawait this._dataStore.GetJobs(this.selectedCustomer.Id, this.includeCompletedJobs, this.includeCancelledJobs);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tpublic StopTelematicsScanPolling()\r\n\t{\r\n\t\tif(this.syncTimerId)\r\n\t\t{\r\n\t\t\tclearTimeout(this.syncTimerId);\r\n\t\t\tthis.syncTimerId = null;\r\n\t\t}\r\n\t}\r\n\r\n\tpublic ClearTelematicsScanResults()\r\n\t{\r\n\t\tthis.syncResult = null;\r\n\t\tthis.syncResultViewed = true;\r\n\t\tthis.isCurrentlyScanning = false;\r\n\t}\r\n}\r\n\r\n","import React, { useRef } from 'react';\r\nimport { FileCopyTwoTone } from '@material-ui/icons';\r\nimport { Paper, Button } from '@material-ui/core';\r\nimport './Dropzone.scss';\r\n\r\nexport interface IDropZoneProps\r\n{\r\n\tonFilesAdded: (files: Array) => void;\r\n\tdisabled: boolean;\r\n\ttitle: string;\r\n}\r\n\r\nexport interface IDropZoneState\r\n{\r\n\thighlighted: boolean;\r\n}\r\n\r\nexport class DropZone extends React.PureComponent\r\n{\r\n\tprivate fileInputRef = React.createRef();\r\n\tpublic constructor(props: IDropZoneProps)\r\n\t{\r\n\t\tsuper(props);\r\n\t\tthis.state = {\r\n\t\t\thighlighted: false\r\n\t\t};\r\n\t}\r\n\r\n\tprivate fileListToArray = (list: FileList) =>\r\n\t{\r\n\t\tconst array: Array = [];\r\n\t\tfor (var i = 0; i < list.length; i++)\r\n\t\t{\r\n\t\t\tconst file = list.item(i);\r\n\t\t\tif (file)\r\n\t\t\t{\r\n\t\t\t\tarray.push(file);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn array;\r\n\t}\r\n\r\n\tprivate onFilesAdded = (evt: React.ChangeEvent) =>\r\n\t{\r\n\t\tif (this.props.disabled)\r\n\t\t{\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tconst files = evt.target.files;\r\n\t\tif (this.props.onFilesAdded && files)\r\n\t\t{\r\n\t\t\tconst array = this.fileListToArray(files);\r\n\t\t\tthis.props.onFilesAdded(array);\r\n\t\t}\r\n\t}\r\n\r\n\tprivate openFileDialog = () =>\r\n\t{\r\n\t\tif (this.props.disabled\r\n\t\t\t|| !this.fileInputRef\r\n\t\t\t|| !this.fileInputRef.current)\r\n\t\t{\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tthis.fileInputRef.current.click();\r\n\t}\r\n\r\n\tprivate onDragOver = (evt:React.DragEvent) =>\r\n\t{\r\n\t\tevt.preventDefault();\r\n\r\n\t\tif (this.props.disabled)\r\n\t\t{\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tthis.setState({ highlighted: true });\r\n\t}\r\n\r\n\tprivate onDragLeave = () =>\r\n\t{\r\n\t\tthis.setState({ highlighted: false });\r\n\t}\r\n\r\n\tprivate onDrop = (event:React.DragEvent) =>\r\n\t{\r\n\t\tevent.preventDefault();\r\n\r\n\t\tif (this.props.disabled) return;\r\n\r\n\t\tconst files = event.dataTransfer.files;\r\n\t\tif (this.props.onFilesAdded)\r\n\t\t{\r\n\t\t\tconst array = this.fileListToArray(files);\r\n\t\t\tthis.props.onFilesAdded(array);\r\n\t\t}\r\n\t\tthis.setState({ highlighted: false });\r\n\t}\r\n\r\n\tpublic render()\r\n\t{\r\n\t\treturn (\r\n\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t{this.props.title}\r\n\t\t\t\r\n\t\t);\r\n\t}\r\n}","import React from 'react';\r\nimport { Paper, LinearProgress, Button } from '@material-ui/core';\r\nimport './UploadJob.scss';\r\n\r\nexport interface IUploadJobTileProps\r\n{\r\n\tfilename: string;\r\n\tuploading: boolean;\r\n\tuploadProgress: number;\r\n\tonFileRemoved: (filename: string)=>void;\r\n}\r\n\r\nexport const UploadJobTile = ({ filename, uploading, uploadProgress, onFileRemoved }:IUploadJobTileProps): JSX.Element =>\r\n{\r\n\treturn \r\n\t\t{filename} {(uploading && uploadProgress)\r\n\t\t\t? `(${uploadProgress.toFixed()}%)`\r\n\t\t\t: ''}\r\n\t\t\r\n\t\t{(uploading && uploadProgress)\r\n\t\t\t? \r\n\t\t\t: <>}\r\n\t;\r\n};\r\n","import React from 'react';\r\nimport { Dialog, DialogTitle, DialogContent, DialogContentText, DialogActions, Button, CircularProgress } from '@material-ui/core';\r\nimport { DropZone } from '../../../Components/Dropzone';\r\nimport { IStandardAppProps } from '../../../Models/IStandardAppProps';\r\nimport { UploadJobTile } from './UploadJobTile';\r\nimport './UploadJob.scss';\r\n\r\nexport interface IUploadJobProps extends IStandardAppProps\r\n{\r\n\topen: boolean;\r\n\thandleClose: () => void;\r\n}\r\n\r\nexport interface IUploadJobState\r\n{\r\n\tfiles: Array;\r\n\tuploading: boolean;\r\n\tsuccessfullUploaded: boolean;\r\n\tuploadProgress: {[key:string]:IFileProgress};\r\n\tuserMessage: string | null;\r\n\tuserMessageTitle: string | null;\r\n}\r\n\r\ninterface IFileProgress\r\n{\r\n\tname: string;\r\n\tstate: 'pending' | 'done' | 'error' | 'cancelled';\r\n\tpercentage: number;\r\n}\r\n\r\nexport class UploadJob extends React.PureComponent\r\n{\r\n\tpublic constructor(props: IUploadJobProps)\r\n\t{\r\n\t\tsuper(props);\r\n\t\tthis.state = {\r\n\t\t\tfiles: [],\r\n\t\t\tuploading: false,\r\n\t\t\tsuccessfullUploaded: false,\r\n\t\t\tuploadProgress:{},\r\n\t\t\tuserMessage: null,\r\n\t\t\tuserMessageTitle: null\r\n\t\t};\r\n\t}\r\n\r\n\tprivate onFilesAdded = (files:Array) =>\r\n\t{\r\n\t\tconst filesCopy = this.state.files.slice();\r\n\t\tfilesCopy.push(...files);\r\n\t\tthis.setState({files:filesCopy});\r\n\t}\r\n\r\n\tprivate onFileRemoved = (filename: string)=>\r\n\t{\r\n\t\tconst file = this.state.files.find(file => file.name === filename);\r\n\t\tif(file)\r\n\t\t{\r\n\t\t\t// if we are uploading this file, it needs to be cancelled\r\n\t\t\tif(this.state.uploading)\r\n\t\t\t{\r\n\t\t\t\tthis.props.dataStore.cancelFileUpload(file.name);\r\n\t\t\t}\r\n\r\n\t\t\t// in either case, we need to remove it from the list of files to be uploaded\r\n\t\t\tconst fileIdx = this.state.files.indexOf(file);\r\n\t\t\tconst filesCopy = this.state.files.slice();\r\n\t\t\tfilesCopy.splice(fileIdx,1);\r\n\t\t\tif(filesCopy.length > 0)\r\n\t\t\t{\r\n\t\t\t\tthis.setState({files: filesCopy});\r\n\t\t\t}\r\n\t\t\telse\r\n\t\t\t{\r\n\t\t\t\tthis.setState({ successfullUploaded: true, files: [], uploading: false});\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t}\r\n\r\n\tprivate uploadFiles = async () =>\r\n\t{\r\n\t\tthis.setState({ uploadProgress: {}, uploading: true });\r\n\t\tconst promises = this.state.files.map(file => this.sendRequest(file));\r\n\r\n\t\ttry\r\n\t\t{\r\n\t\t\tawait Promise.all(promises);\r\n\t\t\tthis.setState({ successfullUploaded: true, uploading: false }, () => this.props.handleClose());\r\n\t\t}\r\n\t\tcatch (e)\r\n\t\t{\r\n\t\t\tconst erroredFiles = Object.values(this.state.uploadProgress).filter(v => v.state === 'error').map(v => ' ' + v.name);\r\n\t\t\tconst cancelledFiles = Object.values(this.state.uploadProgress).filter(v => v.state === 'cancelled').map(v => ' ' + v.name);\r\n\t\t\tif(erroredFiles.length > 0)\r\n\t\t\t{\r\n\t\t\t\tconst errorMessage = 'Some files failed to upload:\\n' + erroredFiles.join('\\n');\r\n\t\t\t\tthis.setState({ successfullUploaded: true, uploading: false, userMessageTitle:'Error uploading data', userMessage:errorMessage });\r\n\t\t\t}\r\n\t\t}\r\n\t\tfinally\r\n\t\t{\r\n\t\t\tthis.setState({files: this.state.files.filter(file => this.state.uploadProgress[file.name].state !== 'done')});\r\n\t\t}\r\n\t}\r\n\r\n\tprivate sendRequest = (file: File) =>\r\n\t{\r\n\t\tif(!this.props.applicationState.selectedCustomer)\r\n\t\t{\r\n\t\t\tthrow 'No customer selected.';\r\n\t\t}\r\n\r\n\t\treturn this.props.dataStore.UploadFile(this.props.applicationState.selectedCustomer.Id,\r\n\t\t\tfile,\r\n\t\t\t(filename: string, percentage: number) =>\r\n\t\t\t{\r\n\t\t\t\tconst copy = { ...this.state.uploadProgress };\r\n\t\t\t\tcopy[filename] = {\r\n\t\t\t\t\tname: filename,\r\n\t\t\t\t\tstate: 'pending',\r\n\t\t\t\t\tpercentage: percentage\r\n\t\t\t\t};\r\n\t\t\t\tthis.setState({ uploadProgress: copy });\r\n\t\t\t},\r\n\t\t\t(filename: string) =>\r\n\t\t\t{\r\n\t\t\t\tconst copy = { ...this.state.uploadProgress };\r\n\t\t\t\tcopy[filename] = { name: filename, state: 'done', percentage: 100 };\r\n\t\t\t\tthis.setState({ uploadProgress: copy });\r\n\t\t\t},\r\n\t\t\t(filename: string) =>\r\n\t\t\t{\r\n\t\t\t\tconst copy = { ...this.state.uploadProgress };\r\n\t\t\t\tcopy[filename] = { name: filename, state: 'cancelled', percentage: 0 };\r\n\t\t\t\tthis.setState({ uploadProgress: copy });\r\n\t\t\t},\r\n\t\t\t(filename: string) =>\r\n\t\t\t{\r\n\t\t\t\tconst copy = { ...this.state.uploadProgress };\r\n\t\t\t\tcopy[filename] = { name: filename, state: 'error', percentage: 0 };\r\n\t\t\t\tthis.setState({ uploadProgress: copy });\r\n\t\t\t}\r\n\t\t);\r\n\t}\r\n\r\n\tprivate handleClose = () =>\r\n\t{\r\n\t\tif(this.state.uploading)\r\n\t\t{\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tthis.setState({successfullUploaded:false, uploading:false, uploadProgress:{}, files:[]});\r\n\t\tthis.props.handleClose();\r\n\t}\r\n\r\n\tprivate handleCancelUploads = () =>\r\n\t{\r\n\t\tthis.props.dataStore.cancelAllFileUploads();\r\n\t\tthis.setState({successfullUploaded:true, uploading:false, files:[]});\r\n\t}\r\n\r\n\tprivate handleCancel = () =>\r\n\t{\r\n\t\tthis.handleCancelUploads();\r\n\t\tthis.handleClose();\r\n\t}\r\n\r\n\tpublic render()\r\n\t{\r\n\t\treturn \r\n\t\t\tFile List\r\n\t\t\t\r\n\t\t\t\t{\r\n\t\t\t\t\tthis.state.uploading ? <> : \r\n\t\t\t\t}\r\n\t\t\t\t
\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\tthis.state.files.map(file => (\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t))\r\n\t\t\t\t\t}\r\n\t\t\t\t
\r\n\t\t\t
\r\n\t\t\t\r\n\t\t\t\t{\r\n\t\t\t\t\tthis.state.uploading ? (\r\n\t\t\t\t\t\t<>\r\n\t\t\t\t\t\t\t
\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t
\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t):(\r\n\t\t\t\t\t\t<>\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t)\r\n\t\t\t\t}\r\n\t\t\t
\r\n\t\t\t this.setState({userMessage:null})}\r\n\t\t\t\taria-labelledby=\"alert-dialog-title\"\r\n\t\t\t\taria-describedby=\"alert-dialog-description\"\r\n\t\t\t>\r\n\t\t\t\t{this.state.userMessageTitle}\r\n\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\t\t
{this.state.userMessage}
\r\n\t\t\t\t\t
\r\n\t\t\t\t
\r\n\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t
\r\n\t\t;\r\n\t}\r\n}\r\n","\r\nexport class CancellationToken\r\n{\r\n\tpublic cancel()\r\n\t{\r\n\t\tthis._cancel = true;\r\n\t}\r\n\r\n\tpublic get cancelled() : boolean\r\n\t{\r\n\t\treturn this._cancel;\r\n\t}\r\n\r\n\tprivate _cancel: boolean = false;\r\n}\r\n","import React from 'react';\r\nimport { TableContainer, Table, TableHead, TableRow, TableCell, TableBody, TableSortLabel, withStyles, Theme, createStyles } from '@material-ui/core';\r\nimport { IStandardAppProps } from '../../Models/IStandardAppProps';\r\nimport { JL } from 'jsnlog';\r\nimport dayjs from 'dayjs';\r\nimport './JobTable.scss';\r\nimport { JobSortMethod, ApplicationState } from '../../Stores/ApplicationState';\r\nimport { observer } from 'mobx-react';\r\nimport { KeyboardArrowDown } from '@material-ui/icons';\r\nimport { IJobDTO } from '../../Models/IJobDTO';\r\n\r\nconst StyledTableCell = withStyles((theme: Theme) =>\r\n\tcreateStyles({\r\n\t\thead: {\r\n\t\t\tbackgroundColor: theme.palette.primary.main,\r\n\t\t\tcolor: theme.palette.primary.contrastText,\r\n\t\t},\r\n\t\tbody: {\r\n\t\t\tfontSize: 14,\r\n\t\t},\r\n\t}),\r\n)(TableCell);\r\n\r\nconst StyledTableRow = withStyles((theme: Theme) =>\r\n\tcreateStyles({\r\n\t\tselected: {\r\n\t\t\tbackgroundColor: theme.palette.secondary.light + ' !important',\r\n\t\t\tcolor: theme.palette.primary.dark,\r\n\t\t}\r\n\t}),\r\n)(TableRow);\r\n\r\nconst StyledTableSortLabel = withStyles((theme: Theme) =>\r\n\tcreateStyles({\r\n\t\ticon: {\r\n\t\t\tcolor: theme.palette.primary.contrastText + ' !important',\r\n\t\t}\r\n\t}),\r\n)(TableSortLabel);\r\n\r\n/** \r\n * Parse an object key, which is of the form {userId}/.../{filename}\r\n */\r\nconst filenameFromObjectKey = (key: string) =>\r\n{\r\n\tconst parts = key?.split('/');\r\n\r\n\t// Validate this key is in the correct form\r\n\tif (key == null || parts.length < 2)\r\n\t{\r\n\t\tJL().error(`Unrecognized object key ${key}`);\r\n\t\treturn 'Error getting filename';\r\n\t}\r\n\r\n\t// Return the last part\r\n\treturn parts[parts.length - 1];\r\n};\r\n\r\nconst ageFromDate = (date: string) =>\r\n{\r\n\tconst difference = dayjs(new Date().toUTCString()).diff(dayjs(date), 'hour');\r\n\tif (difference > 48)\r\n\t{\r\n\t\treturn dayjs().diff(dayjs(date), 'day') + ' days';\r\n\t}\r\n\r\n\tif (difference > 24)\r\n\t{\r\n\t\treturn (difference / 24).toFixed(2) + ' days';\r\n\t}\r\n\r\n\tif (difference < 2)\r\n\t{\r\n\t\treturn dayjs().diff(dayjs(date), 'minute') + ' minutes';\r\n\t}\r\n\r\n\treturn difference + ' hours';\r\n};\r\n\r\nconst CreateSortUpdateMethod = (applicationState: ApplicationState, method: JobSortMethod) =>\r\n{\r\n\treturn () =>\r\n\t{\r\n\t\tif(applicationState.jobSortMethod === method)\r\n\t\t{\r\n\t\t\tapplicationState.jobSortAscending = !applicationState.jobSortAscending;\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tapplicationState.jobSortAscending = true;\r\n\t\tapplicationState.jobSortMethod = method;\r\n\t};\r\n};\r\n\r\nconst formatStatus = (job:IJobDTO) =>\r\n{\r\n\tif(job.CurrentStatus !== 'Error')\r\n\t{\r\n\t\treturn job.CurrentStatus;\r\n\t}\r\n\r\n\treturn `${job.CurrentStatus}:${job.CurrentMessage}`;\r\n};\r\n\r\nexport const JobTable = observer((props:IStandardAppProps) =>\r\n{\r\n\tconst sortByName = CreateSortUpdateMethod(props.applicationState, JobSortMethod.ByName);\r\n\tconst sortByUpdated = CreateSortUpdateMethod(props.applicationState, JobSortMethod.ByUpdated);\r\n\tconst sortByCreated = CreateSortUpdateMethod(props.applicationState, JobSortMethod.ByCreated);\r\n\tconst sortByStatus = CreateSortUpdateMethod(props.applicationState, JobSortMethod.ByStatus);\r\n\r\n\treturn (\r\n\t\t\r\n\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\tFilename\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\tLast Updated\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\tAge\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\tStatus\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\tprops.applicationState.sortedJobs.map(j => (\r\n\t\t\t\t\t\t\t props.applicationState.selectJob(j.Id)}\r\n\t\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t\t{filenameFromObjectKey(j.File.ObjectKey)}\r\n\t\t\t\t\t\t\t\t{ageFromDate(j.LastUpdated)} ago\r\n\t\t\t\t\t\t\t\t{ageFromDate(j.Created)}\r\n\t\t\t\t\t\t\t\t{formatStatus(j)}\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t))\r\n\t\t\t\t\t}\r\n\t\t\t\t\r\n\t\t\t
\r\n\t\t
\r\n\t);\r\n});","import React, { useState } from 'react';\r\nimport { observer, Observer } from 'mobx-react';\r\nimport { Paper, Button, Checkbox, FormControlLabel, Typography, CircularProgress } from '@material-ui/core';\r\nimport { IStandardAppProps } from '../../Models/IStandardAppProps';\r\nimport { UploadJob } from './Upload/UploadJob';\r\nimport './JobsCard.scss';\r\nimport { JobTable } from './JobTable';\r\nimport { DataState } from '../../Stores/DataStore';\r\n\r\ninterface IJobsCardState\r\n{\r\n\tincludeCompletedJobs: boolean;\r\n\tincludeCancelledJobs: boolean;\r\n\topen: boolean;\r\n\r\n}\r\n\r\n/** \r\n * This renders the section of the page dedicated to displaying and manipulating job statuses.\r\n */\r\nexport class JobsCard extends React.PureComponent\r\n{\r\n\tpublic constructor(props: IStandardAppProps)\r\n\t{\r\n\t\tsuper(props);\r\n\t\tthis.state = {\r\n\t\t\tincludeCompletedJobs: false,\r\n\t\t\tincludeCancelledJobs: false,\r\n\t\t\topen: false\r\n\t\t};\r\n\t}\r\n\r\n\tprivate handleClose = () =>\r\n\t{\r\n\t\tthis.setState({ open: false });\r\n\t\tif (this.props.applicationState.selectedCustomer)\r\n\t\t{\r\n\t\t\tthis.props.dataStore.GetJobs(\r\n\t\t\t\tthis.props.applicationState.selectedCustomer.Id,\r\n\t\t\t\tthis.props.applicationState.includeCompletedJobs,\r\n\t\t\t\tthis.props.applicationState.includeCancelledJobs);\r\n\t\t}\r\n\t};\r\n\r\n\tprivate handleOpen = () => this.setState({ open: true });\r\n\r\n\tprivate toggleIncludeCompleted = () =>\r\n\t{\r\n\t\tthis.props.applicationState.includeCompletedJobs = !this.props.applicationState.includeCompletedJobs;\r\n\t\tif (this.props.applicationState.selectedCustomer)\r\n\t\t{\r\n\t\t\tthis.props.dataStore.GetJobs(\r\n\t\t\t\tthis.props.applicationState.selectedCustomer.Id,\r\n\t\t\t\tthis.props.applicationState.includeCompletedJobs,\r\n\t\t\t\tthis.props.applicationState.includeCancelledJobs);\r\n\t\t}\r\n\t}\r\n\r\n\tprivate toggleIncludeCancelled = () =>\r\n\t{\r\n\t\tthis.props.applicationState.includeCancelledJobs = !this.props.applicationState.includeCancelledJobs;\r\n\t\tif (this.props.applicationState.selectedCustomer)\r\n\t\t{\r\n\t\t\tthis.props.dataStore.GetJobs(\r\n\t\t\t\tthis.props.applicationState.selectedCustomer.Id,\r\n\t\t\t\tthis.props.applicationState.includeCompletedJobs,\r\n\t\t\t\tthis.props.applicationState.includeCancelledJobs);\r\n\t\t}\r\n\t}\r\n\r\n\tpublic render()\r\n\t{\r\n\t\treturn
\r\n\t\t\tConversion Jobs\r\n\t\t\tThe following are Precision Ag Translation jobs for the selected account.\r\n\t\t\t{() =>\r\n\t\t\t\t\r\n\t\t\t\t\t
\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t
\r\n\t\t\t\t\t
\r\n\t\t\t\t\t\t{() => }}\r\n\t\t\t\t\t\tlabel=\"Show completed jobs\"\r\n\t\t\t\t\t\ttitle=\"Completed jobs will only displayed for an hour unless this is checked\" />\r\n\r\n\t\t\t\t\t\t{() => }}\r\n\t\t\t\t\t\tlabel=\"Show cancelled jobs\"\r\n\t\t\t\t\t\ttitle=\"Cancelled jobs will only displayed for an hour unless this is checked\" />\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\t\tif (this.props.applicationState.selectedJob)\r\n\t\t\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\t\t\tthis.props.dataStore.ReportError(this.props.applicationState.selectedJob.Id);\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t}}\r\n\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\tReport Error\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t
\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\tthis.props.dataStore.state == DataState.Updating\r\n\t\t\t\t\t\t\t? (\r\n\t\t\t\t\t\t\t\t
\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t
\r\n\t\t\t\t\t\t\t)\r\n\t\t\t\t\t\t\t: <>\r\n\t\t\t\t\t}\r\n\t\t\t\t
}\r\n\t\t\t
\r\n\t\t\t\r\n\t\t
;\r\n\t}\r\n}\r\n","import React from 'react';\r\nimport { Button, CircularProgress } from '@material-ui/core';\r\n\r\ninterface ITelematicsScanButtonProps\r\n{\r\n\thandleScan: () => void;\r\n\tisScanning: boolean;\r\n}\r\n\r\n/** This element wraps the button for scanning */\r\nexport const TelematicsScanButton = ({ handleScan, isScanning } : ITelematicsScanButtonProps) => \r\n\t
\r\n\t\t\r\n\t\t{\r\n\t\t\tisScanning ?\r\n\t\t\t\t
\r\n\t\t\t\t\t\r\n\t\t\t\t
\r\n\t\t\t\t: <>\r\n\t\t}\r\n\t
;\r\n","import React from 'react';\r\nimport { Typography, Button, Dialog, DialogTitle, DialogContent, DialogContentText, DialogActions } from '@material-ui/core';\r\n\r\ninterface ITelematicsResultPopupProps\r\n{\r\n\tshow: boolean;\r\n\tnewNodes: number;\r\n\tnewFiles: number;\r\n\tonClose: () => void;\r\n}\r\n\r\n/** This displays the results of a telematics scan */\r\nexport const TelematicsResultPopup = ({ show, newNodes, newFiles, onClose }: ITelematicsResultPopupProps) => \r\n\t\r\n\t\tScan Results\r\n\t\t\r\n\t\t\t\r\n\t\t\t\tScan completed.\r\n\t\t\t\t\r\n\t\t\t\t\t
    \r\n\t\t\t\t\t\t
  • {newNodes} new nodes found.
  • \r\n\t\t\t\t\t\t
  • {newFiles} new files found.
  • \r\n\t\t\t\t\t
\r\n\t\t\t\t
\r\n\t\t\t
\r\n\t\t
\r\n\t\t\r\n\t\t\t\r\n\t\t\r\n\t
;\r\n","import React, { useState, useCallback } from 'react';\r\nimport { Button, Dialog, DialogTitle, DialogContent, DialogContentText, TextField, DialogActions } from '@material-ui/core';\r\nexport const InvitationDialog = (props: {\r\n\topen: boolean;\r\n\thandleClose: () => void;\r\n\thandleInvite: (email: string) => void;\r\n}) =>\r\n{\r\n\tconst [email, setEmail] = useState('');\r\n\tconst setEmailFromUpdate = useCallback((evt) => setEmail(evt.target.value), []);\r\n\tconst sendInvite = useCallback(() => props.handleInvite(email), [email, props.handleInvite]);\r\n\treturn \r\n\t\tInvite to connect\r\n\t\t\r\n\t\t\t\r\n\t\t\t\tTo invite someone to share their precision ag data with you,\r\n\t\t\t\tplease enter their email address here.
\r\n\t\t\t\t
\r\n\t\t\t\tThe recipient will be able to enter their credentials for any AGI supported telematics system \r\n\t\t\t\tthey use for data import, identical to the Manage Equipment button.\r\n\t\t\t
\r\n\t\t\t\r\n\t\t
\r\n\t\t\r\n\t\t\t\r\n\t\t\t\r\n\t\t\r\n\t
;\r\n};\r\n","import { IStandardAppProps } from '../../Models/IStandardAppProps';\r\nimport React from 'react';\r\nimport { Typography, Button, Grid, Dialog, DialogActions, DialogContentText, DialogContent } from '@material-ui/core';\r\nimport Iframe from 'react-iframe';\r\nimport './TelematicsCard.scss';\r\nimport { Observer } from 'mobx-react';\r\nimport { TelematicsScanButton } from './TelematicsScanButton';\r\nimport { TelematicsResultPopup } from './TelematicsResultPopup';\r\nimport { InvitationDialog } from './InvitationDialog';\r\n\r\ninterface IState\r\n{\r\n\tmanageDialogOpen: boolean;\r\n\tinviteDialogOpen: boolean;\r\n\tportalUrl: string;\r\n\tdelayWarningDialogOpen: boolean;\r\n}\r\n\r\n/** \r\n * This renders the section of the page dedicated to displaying and manipulating job statuses.\r\n */\r\nexport class TelematicsCard extends React.PureComponent\r\n{\r\n\t/* We will re-enable iframe once the page works in an iframe */\r\n\tprivate readonly shouldOpenManageEquipmentInNewTab = true;\r\n\r\n\tpublic constructor(props: IStandardAppProps)\r\n\t{\r\n\t\tsuper(props);\r\n\t\tthis.state = {\r\n\t\t\tmanageDialogOpen: false,\r\n\t\t\tinviteDialogOpen: false,\r\n\t\t\tdelayWarningDialogOpen: false,\r\n\t\t\tportalUrl: ''\r\n\t\t};\r\n\t}\r\n\r\n\tpublic componentWillUnmount()\r\n\t{\r\n\t\tthis.props.applicationState.StopTelematicsScanPolling();\r\n\t}\r\n\r\n\tprivate handleOpen = () =>\r\n\t{\r\n\t\tif (this.props.applicationState.selectedCustomer)\r\n\t\t{\r\n\t\t\tthis.props.dataStore.GetTelematicsPortal(this.props.applicationState.selectedCustomer.Id).then(url =>\r\n\t\t\t{\r\n\t\t\t\tif (url)\r\n\t\t\t\t{\r\n\t\t\t\t\tthis.setState({ portalUrl: url, manageDialogOpen: true, delayWarningDialogOpen: true });\r\n\t\t\t\t\t// If we aren't using iframes, open this in a new tab\r\n\t\t\t\t\tif(this.shouldOpenManageEquipmentInNewTab)\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\twindow.open(this.state.portalUrl, '_blank');\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\t};\r\n\r\n\tprivate handleClose = () => \r\n\t{\r\n\t\tthis.setState({ manageDialogOpen: false, inviteDialogOpen: false, delayWarningDialogOpen: false });\r\n\t\tthis.handleScan();\r\n\t}\r\n\r\n\tprivate handleInvitation = () =>\r\n\t{\r\n\t\t// Display a popup requesting an email address for the grower\r\n\t\tthis.setState({inviteDialogOpen:true});\r\n\t}\r\n\r\n\tprivate handleScan = () =>\r\n\t{\r\n\t\tthis.props.applicationState.InitiateScan();\r\n\t}\r\n\tprivate sendInvite = (email:string) =>\r\n\t{\r\n\t\t// dispatch this invite for the currently selected grower to the provided email address\r\n\t\tthis.props.dataStore.SendInvitation(email, this.props.applicationState.selectedCustomer!.Id);\r\n\t}\r\n\r\n\tpublic render()\r\n\t{\r\n\r\n\t\treturn {() =>\r\n\t\t{\r\n\t\t\tconst isScanning = this.props.applicationState.isCurrentlyScanning;\r\n\r\n\t\t\treturn (\r\n\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\t\tTelematics\r\n\t\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t{this.props.dataStore.telematicsProviderNodeCount} providers connected\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t{this.props.dataStore.telematicsNodeCount} total connected nodes\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t{this.props.dataStore.telematicsImportedFileCount} files retrieved\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t{this.props.dataStore.telematicsPendingFileCount} files pending\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\tAfter adding a new provider, files can take up to two hours to be available.\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t
\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\t\t