From baa4a479ebdf7412c8cb5b3bb3f74d8429fb4688 Mon Sep 17 00:00:00 2001 From: Luke Shingles Date: Sat, 7 Dec 2024 14:39:45 +0000 Subject: [PATCH] Use react 19 --- .../forcephot/templates/tasklist-react.html | 31 +- static/js/lightcurveplotly.min.js | 72 ++++- static/js/newrequest.min.js | 6 + static/js/queuepage/build.sh | 6 + static/js/queuepage/package.json | 6 +- .../{ => queuepage/src}/lightcurveplotly.js | 0 static/js/queuepage/src/newrequest.jsx | 5 +- static/js/queuepage/src/task.jsx | 284 ----------------- static/js/queuepage/src/tasklist.jsx | 292 +++++++++++++++++- .../js/{queuepage.min.js => tasklist.min.js} | 12 +- 10 files changed, 398 insertions(+), 316 deletions(-) create mode 100644 static/js/newrequest.min.js create mode 100755 static/js/queuepage/build.sh rename static/js/{ => queuepage/src}/lightcurveplotly.js (100%) delete mode 100644 static/js/queuepage/src/task.jsx rename static/js/{queuepage.min.js => tasklist.min.js} (54%) diff --git a/atlasserver/forcephot/templates/tasklist-react.html b/atlasserver/forcephot/templates/tasklist-react.html index 75b64bb..7dca77d 100644 --- a/atlasserver/forcephot/templates/tasklist-react.html +++ b/atlasserver/forcephot/templates/tasklist-react.html @@ -125,20 +125,25 @@ $(document).ready(inactivityTimer); + + + - - - - - - + "react": "https://esm.sh/react@19/?dev", + "reactdom": "https://esm.sh/react-dom@19/client?dev", {% else %} - - - - - + "react": "https://esm.sh/react@19/", + "reactdom": "https://esm.sh/react-dom@19/client/", {% endif %} + "newrequest": "{% static 'js/newrequest.min.js' %}" + } + } + + {% endblock %} diff --git a/static/js/lightcurveplotly.min.js b/static/js/lightcurveplotly.min.js index a734a1e..3623f0e 100644 --- a/static/js/lightcurveplotly.min.js +++ b/static/js/lightcurveplotly.min.js @@ -1 +1,71 @@ -"use strict";!function(){for(var l=lcdivname,a=(jslimitsglobal[l].today-jslimitsglobal[l].xmin)/20,e=jslimitsglobal[l].xmin-a,o=jslimitsglobal[l].xmax+a,s=jslimitsglobal[l].xmin-jslimitsglobal[l].discoveryDate-a,t=jslimitsglobal[l].today-jslimitsglobal[l].discoveryDate+a,i=jslimitsglobal[l].ymin,r=jslimitsglobal[l].ymax,c=["#6A5ACD","#008000","#DAA520","#A0522D","#FF69B4","#DC143C","#708090","#FFD700","#0000FF","#4B0082","#800080","#008B8B","#FF8C00","#A52A2A","#DB7093","#800000","#B22222","#9ACD32","#FA8072","#000000"],b=[],g=0;g0&&(3==jslcdataglobal[l][g][y].length?(m.push(jslcdataglobal[l][g][y][0]),d.push(jslcdataglobal[l][g][y][1]),n.push(jslcdataglobal[l][g][y][2])):(j.push(jslcdataglobal[l][g][y][0]),h.push(jslcdataglobal[l][g][y][1])));var f={x:m,y:d,error_y:{type:"data",array:n,visible:!0,width:errorbarsize,color:c[jslabelsglobal[l][g].color],opacity:.4},type:"scatter",mode:"markers",name:jslabelsglobal[l][g].label,marker:{color:c[jslabelsglobal[l][g].color],opacity:.4,line:{width:0,color:"black"},size:markersize}};"-"==jslabelsglobal[l][g].label.charAt(0)?f.marker.symbol="diamond":f.marker.symbol="circle",b.push(f);var p={x:j,y:h,type:"scatter",mode:"markers",name:jslabelsglobal[l][g].label,marker:{color:c[jslabelsglobal[l][g].color],opacity:.4,symbol:"limit-arrow",line:{width:0,color:c[jslabelsglobal[l][g].color]},size:arrowsize}};b.push(p)}}if("undefined"!=typeof lcplotwidth)lcplotwidth;else $(l).innerWidth();if(l.includes("flux"))var v=!1,x="Flux / µJy";else v="reversed",x="AB Mag";var u={showlegend:!0,yaxis:{range:[i,r],autorange:v,tickformat:".1f",hoverformat:".2f",title:x},xaxis:{tickformat:".f",hoverformat:".5f",range:[e,o],title:"mjd"},margin:{l:70,r:0,b:30,t:30},height:lcplotheight};l.includes("forced")||(u.xaxis2={tickformat:".f",overlaying:"x",zeroline:!1,side:"top",hoverformat:".5f",range:[s,t],title:"days since earliest detection"}),Plotly.react(l.replace("#",""),b,u,{displayModeBar:!1,responsive:!0})}(); +// 2018-06-25 KWS Javascript Lightcurve Plotting code using Plotly. +// The code was originally written for flot, so a +// conversion needs to be done at the beginning. +// Javascript code to plot the lightcurves. NOTE that it gets its data +// a data variable in the calling page. The trick is setting that data +// correctly. +// +// This code is free of HTML tags, with the exception of
. +// +// The code requires the following data to be set in the calling HTML: +// +// * jslcdata - an array of filter arrays - e.g. for each filter do this... +// jslcdata.push([[55973.492, 20.4057, 0.024156], [55973.4929, 20.3998, 0.022031]]); +// +// * jslabels - an array of labels - the same length as the array of filters - e.g. +// jslabels.push("g"); +// +// * jslclimits - a dictionary of limit values, currently xmin, xmax, ymin, ymax, +// discoveryDate and today. +// First of all, setup some global variable based on data min and max to +// setup the padding on the graph and the x2 axis. This is done here, rather +// than in the calling page, because the padding, etc is presentation specific. +// GLOBAL VARIABLES BEGIN +// 2013-02-06 KWS Wrap the entire code in an anonymous function block. This forces +// everything within here into a different scope. It means that the +// plot code can be called multiple times on the same page without +// worrying about variable name clashes. Needed for window resize. +"use strict";(function(){// Need to set the div ID from the global data +var locallcdivname=lcdivname;//var lightcurve = $(locallcdivname); +// Always refer to the external data via the global variable and lcdivname. +var pad=20;// i.e. 5 percent +var xpadding=(jslimitsglobal[locallcdivname]["today"]-jslimitsglobal[locallcdivname]["xmin"])/pad;var xmin=jslimitsglobal[locallcdivname]["xmin"]-xpadding;var xmax=jslimitsglobal[locallcdivname]["xmax"]+xpadding;var x2min=jslimitsglobal[locallcdivname]["xmin"]-jslimitsglobal[locallcdivname]["discoveryDate"]-xpadding;var x2max=jslimitsglobal[locallcdivname]["today"]-jslimitsglobal[locallcdivname]["discoveryDate"]+xpadding;var ymin=jslimitsglobal[locallcdivname]["ymin"];var ymax=jslimitsglobal[locallcdivname]["ymax"];// color palette for each data series (up to 20 at the moment) +var colors=["#6A5ACD",//SlateBlue +"#008000",//Green +"#DAA520",//GoldenRod +"#A0522D",//Sienna +"#FF69B4",//HotPink +"#DC143C",//Crimson +"#708090",//SlateGray +"#FFD700",//Gold +"#0000FF",//Blue +"#4B0082",//Indigo +"#800080",//Purple +"#008B8B",//DarkCyan +"#FF8C00",//Darkorange +"#A52A2A",//Brown +"#DB7093",//PaleVioletRed +"#800000",//Maroon +"#B22222",//FireBrick +"#9ACD32",//YellowGreen +"#FA8072",//Salmon +"#000000"];//Black +// Should feed the colors form the calling page - better still, the CSS +var plotColors={"backgroundColor":"#FFFFFF","axisColor":"#000000","tickColor":"#BFBFBF","shadingColor":"#DDDDDD","tooltipBackground":"#EEEEFF","tooltipBorder":"#FFDDDD","todaylineColor":"FF0000"};// GLOBAL VARIABLES END +// So... Flot wanted [[x, y, error], [x, y, error], ...] +// Plotly wants [x, x, ...], [y, y, ...], [error, error, ...]. Should be easy to convert, +// but it's a bit of a pain! +// All the lightcurve data +var data=[];for(var filter=0;filter0){if(jslcdataglobal[locallcdivname][filter][lc].length==3){// It's a det +detx.push(jslcdataglobal[locallcdivname][filter][lc][0]);dety.push(jslcdataglobal[locallcdivname][filter][lc][1]);dete.push(jslcdataglobal[locallcdivname][filter][lc][2])}else{// It's a non-det +nondetx.push(jslcdataglobal[locallcdivname][filter][lc][0]);nondety.push(jslcdataglobal[locallcdivname][filter][lc][1])}}}}// Add the plot properties +var tracedets={x:detx,y:dety,error_y:{type:"data",array:dete,visible:true,width:errorbarsize,color:colors[jslabelsglobal[locallcdivname][filter]["color"]],opacity:0.4},type:"scatter",mode:"markers",name:jslabelsglobal[locallcdivname][filter]["label"],marker:{color:colors[jslabelsglobal[locallcdivname][filter]["color"]],opacity:0.4,line:{width:0,color:"black"},size:markersize}};if(jslabelsglobal[locallcdivname][filter]["label"].charAt(0)=="-"){tracedets["marker"]["symbol"]="diamond"}else{tracedets["marker"]["symbol"]="circle"}data.push(tracedets);var tracenondets={x:nondetx,y:nondety,type:"scatter",mode:"markers",name:jslabelsglobal[locallcdivname][filter]["label"],marker:{color:colors[jslabelsglobal[locallcdivname][filter]["color"]],opacity:0.4,symbol:"limit-arrow",line:{width:0,color:colors[jslabelsglobal[locallcdivname][filter]["color"]]},size:arrowsize}};data.push(tracenondets)}}if(typeof lcplotwidth!=="undefined"){var w=lcplotwidth}else{var w=$(locallcdivname).innerWidth()}if(locallcdivname.includes("flux")){var yautorange=false;var ylabel="Flux / \xB5Jy"}else{var yautorange="reversed";var ylabel="AB Mag"}var layout={showlegend:true,yaxis:{range:[ymin,ymax],autorange:yautorange,tickformat:".1f",hoverformat:".2f",title:ylabel},xaxis:{tickformat:".f",hoverformat:".5f",range:[xmin,xmax],title:"mjd"},margin:{l:70,r:0,b:30,t:30},// width: w, //window.innerWidth, +// width: '100%', +height:lcplotheight//window.innerHeight +};//paper_bgcolor: 'rgba(0,0,0,0)'} +//plot_bgcolor: 'rgba(0,0,0,0)'} +// 2018-10-11 KWS Add another x axis if not forced photometry +if(!locallcdivname.includes("forced")){layout["xaxis2"]={tickformat:".f",overlaying:"x",zeroline:false,side:"top",hoverformat:".5f",range:[x2min,x2max],title:"days since earliest detection"}}Plotly.react(locallcdivname.replace("#",""),data,layout,{displayModeBar:false,responsive:true})})(); + diff --git a/static/js/newrequest.min.js b/static/js/newrequest.min.js new file mode 100644 index 0000000..7433447 --- /dev/null +++ b/static/js/newrequest.min.js @@ -0,0 +1,6 @@ +"use strict";import React from"react";let submission_in_progress=false;function getDefaultMjdMin(){return(mjdFromDate(new Date)-30).toFixed(5)}export class NewRequest extends React.Component{get_defaultstate(){// localStorage.getItem('') will be null if the key doesn't exist and null != false, +// so != false will default to true, and != true will default to false. +return{showradechelp:false,radeclist:localStorage.getItem("radeclist")!=null?localStorage.getItem("radeclist"):"",mjd_min:localStorage.getItem("mjd_min")!=null?localStorage.getItem("mjd_min"):getDefaultMjdMin(),mjd_max:localStorage.getItem("mjd_max")!=null?localStorage.getItem("mjd_max"):"",comment:localStorage.getItem("comment")!=null?localStorage.getItem("comment"):"",use_reduced:localStorage.getItem("use_reduced")=="true",send_email:localStorage.getItem("send_email")!="false",enable_stack_rock:localStorage.getItem("enable_stack_rock")=="true",enable_propermotion:localStorage.getItem("enable_propermotion")=="true",radec_epoch_year:localStorage.getItem("radec_epoch_year")!=null?localStorage.getItem("radec_epoch_year"):"",propermotion_ra:localStorage.getItem("propermotion_ra")!=null?localStorage.getItem("propermotion_ra"):0,propermotion_dec:localStorage.getItem("propermotion_dec")!=null?localStorage.getItem("propermotion_dec"):0,errors:[],httperror:"",submission_in_progress:false// duplicated to trigger a render +}}constructor(props){super(props);this.state=this.get_defaultstate();this.handlechange_mjd_min=this.handlechange_mjd_min.bind(this);this.update_mjd_min=this.update_mjd_min.bind(this);this.handlechange_mjd_max=this.handlechange_mjd_max.bind(this);this.update_mjd_max=this.update_mjd_max.bind(this);this.submit=this.submit.bind(this)}componentDidMount(){this.update_mjd_min(this.state.mjd_min);this.update_mjd_max(this.state.mjd_max)}update_mjd_min(strmjdmin){let isostrmin="";if(strmjdmin==""){isostrmin="(leave blank to fetch earliest)"}else{try{const mjdmin=parseFloat(strmjdmin);const isostr_withmilliseconds=dateFromMJD(mjdmin).toISOString();isostrmin=isostr_withmilliseconds.includes(".")?isostr_withmilliseconds.split(".")[0]+"Z":isostr_withmilliseconds}catch(err){isostrmin="error";console.log("error",err,err.message)}}this.setState({"mjd_min":strmjdmin,"mjd_min_isoformat":isostrmin})}handlechange_mjd_min(event){this.update_mjd_min(event.target.value);localStorage.setItem("mjd_min",event.target.value)}update_mjd_max(strmjdmax){let isostrmax="";if(strmjdmax==""){isostrmax="(leave blank to fetch latest)"}else{try{const mjdmax=parseFloat(strmjdmax);console.log("invalid?",strmjdmax,mjdmax);const isostr_withmilliseconds=dateFromMJD(mjdmax).toISOString();isostrmax=isostr_withmilliseconds.includes(".")?isostr_withmilliseconds.split(".")[0]+"Z":isostr_withmilliseconds}catch(err){isostrmax="error";console.log("error",err,err.message)}}this.setState({"mjd_max":strmjdmax,"mjd_max_isoformat":isostrmax});localStorage.setItem("mjd_max",strmjdmax)}handlechange_mjd_max(event){this.update_mjd_max(event.target.value)}async submit(){const datadict={radeclist:this.state.radeclist,mjd_min:this.state.mjd_min==""?null:this.state.mjd_min,mjd_max:this.state.mjd_max==""?null:this.state.mjd_max,use_reduced:this.state.use_reduced,send_email:this.state.send_email,comment:this.state.comment,request_type:this.props.allow_stack_rock&&this.state.enable_stack_rock?"SSOSTACK":"FP"};if(this.state.enable_propermotion){datadict["radec_epoch_year"]=this.state.radec_epoch_year;datadict["propermotion_ra"]=this.state.propermotion_ra;datadict["propermotion_dec"]=this.state.propermotion_dec}console.log(datadict);fetch(api_url_base,{credentials:"same-origin",method:"POST",body:JSON.stringify(datadict),headers:{"X-CSRFToken":getCookie("csrftoken"),"Accept":"application/json","Content-Type":"application/json"}}).catch(error=>{submission_in_progress=false;console.log("New task HTTP request failed",error);this.setState({"httperror":"HTTP request failed.","submission_in_progress":false})}).then(response=>{submission_in_progress=false;this.setState({"httperror":"","submission_in_progress":false});console.log("New task: HTTP response ",response.status);if(response.status==201){console.log("New task: successful creation",response.status);localStorage.removeItem("radeclist");localStorage.removeItem("enable_propermotion");localStorage.removeItem("enable_stack_rock");localStorage.removeItem("radec_epoch_year");localStorage.removeItem("propermotion_ra");localStorage.removeItem("propermotion_dec");localStorage.removeItem("mjd_min");localStorage.removeItem("mjd_max");localStorage.removeItem("comment");this.setState(this.get_defaultstate());response.json().then(data=>{// console.log('Creation data', data); +data.forEach((task,i)=>{console.log("Created new task",task.id);newtaskids.push(task.id)})});window.history.pushState({},document.title,api_url_base);this.props.fetchData(true)}else if(response.status==400){response.json().then(data=>{console.log("New task: errors returned",data);this.setState({"errors":data})})}else{console.log("New task: Error on submission: ",response.status)};}).catch(error=>{submission_in_progress=false;console.log("New task HTTP request failed",error);this.setState({"httperror":"HTTP request failed. Check internet connection and server are online.","submission_in_progress":false})})}onSubmit(){event.preventDefault();if(submission_in_progress){console.log("New task: Submission already in progress");return}console.log("New task: Submitting",api_url_base);submission_in_progress=true;this.setState({"submission_in_progress":false});this.submit()}render(){const formcontent=[];formcontent.push(/*#__PURE__*/React.createElement("ul",{key:"ulradec"},/*#__PURE__*/React.createElement("li",null,/*#__PURE__*/React.createElement("label",{htmlFor:"id_radeclist"},"RA Dec / MPC names:"),/*#__PURE__*/React.createElement("textarea",{name:"radeclist",cols:"",rows:"3",required:true,id:"id_radeclist",value:this.state.radeclist,onChange:e=>{this.setState({"radeclist":e.target.value});localStorage.setItem("radeclist",e.target.value)}}),"\xA0",/*#__PURE__*/React.createElement("a",{onClick:()=>{this.setState({"showradechelp":!this.state.showradechelp})}},"Help"),this.state.showradechelp?/*#__PURE__*/React.createElement("div",{id:"radec_help",style:{display:"block",clear:"right",fontSize:"small"},className:"collapse"},"Each line should consist of a right ascension and a declination coordinate (J2000) in decimal or sexagesimal notation (RA/DEC separated by a space or a comma) or 'mpc ' and a Minor Planet Center object name (e.g. 'mpc Makemake'). Limit of 100 objects per submission. If requested, email notification will be sent only after all targets in the list have been processed."):null),"radeclist"in this.state.errors?/*#__PURE__*/React.createElement("ul",{className:"errorlist"},/*#__PURE__*/React.createElement("li",null,this.state.errors["radeclist"])):""));formcontent.push(/*#__PURE__*/React.createElement("div",{key:"propermotion_checkbox",id:"propermotion_checkboxdiv",style:{width:"100%"}},/*#__PURE__*/React.createElement("label",{style:{width:"100%"}},/*#__PURE__*/React.createElement("input",{type:"checkbox",checked:this.state.enable_propermotion,onChange:e=>{this.setState({"enable_propermotion":e.target.checked});localStorage.setItem("enable_propermotion",e.target.checked)},style:{position:"static",display:"inline",width:"5em"}})," Proper motion")));if(this.state.enable_propermotion){formcontent.push(/*#__PURE__*/React.createElement("div",{key:"propermotion_panel",id:"propermotion_panel",style:{background:"rgb(235,235,235)"}},/*#__PURE__*/React.createElement("p",{key:"propermotiondesc",style:{fontSize:"small"}},"If the star is moving, the J2000 coordinates above are correct for a specified epoch along with proper motions in RA (angle) and Dec in milliarcseconds. The epoch of ATLAS observations varies from 2015.5 to the present. Note: these are angular velocities, not rates of coordinate change."),/*#__PURE__*/React.createElement("ul",{key:"propermotion_inputs"},/*#__PURE__*/React.createElement("li",{key:"radec_epoch_year"},/*#__PURE__*/React.createElement("label",{htmlFor:"id_radec_epoch_year"},"Epoch year:"),/*#__PURE__*/React.createElement("input",{type:"number",name:"radec_epoch_year",step:"0.1",id:"id_radec_epoch_year",value:this.state.radec_epoch_year,onChange:e=>{this.setState({"radec_epoch_year":e.target.value});localStorage.setItem("radec_epoch_year",e.target.value)}})),/*#__PURE__*/React.createElement("li",{key:"propermotion_ra"},/*#__PURE__*/React.createElement("label",{htmlFor:"id_propermotion_ra"},"PM RA [mas/yr]"),/*#__PURE__*/React.createElement("input",{type:"number",name:"propermotion_ra",step:"any",id:"id_propermotion_ra",value:this.state.propermotion_ra,onChange:e=>{this.setState({"propermotion_ra":e.target.value});localStorage.setItem("propermotion_ra",e.target.value)}})),/*#__PURE__*/React.createElement("li",{key:"propermotion_dec"},/*#__PURE__*/React.createElement("label",{htmlFor:"id_propermotion_dec"},"PM Dec [mas/yr]"),/*#__PURE__*/React.createElement("input",{type:"number",name:"propermotion_dec",step:"any",id:"id_propermotion_dec",value:this.state.propermotion_dec,onChange:e=>{this.setState({"propermotion_dec":e.target.value});localStorage.setItem("propermotion_dec",e.target.value)}})))))}if(this.props.allow_stack_rock){formcontent.push(/*#__PURE__*/React.createElement("div",{key:"stack_rock",id:"stack_rock",style:{width:"100%"}},/*#__PURE__*/React.createElement("label",{style:{width:"100%"}},/*#__PURE__*/React.createElement("input",{type:"checkbox",checked:this.state.enable_stack_rock,onChange:e=>{this.setState({"enable_stack_rock":e.target.checked});localStorage.setItem("enable_stack_rock",e.target.checked)},style:{position:"static",display:"inline",width:"5em"}})," Get stack of SS object images")));if(this.state.enable_stack_rock){formcontent.push(/*#__PURE__*/React.createElement("div",{key:"stackrock_panel",id:"stackrock_panel",style:{background:"rgb(235,235,235)"}},/*#__PURE__*/React.createElement("p",{key:"stackrockdesc",style:{fontSize:"small"}},"Perform a shift & stack operation for the MPC object entered above.")))}}formcontent.push(/*#__PURE__*/React.createElement("ul",{key:"ulmjdoptions"},/*#__PURE__*/React.createElement("li",{key:"mjd_min"},/*#__PURE__*/React.createElement("label",{htmlFor:"id_mjd_min"},"MJD min:"),/*#__PURE__*/React.createElement("input",{type:"number",name:"mjd_min",step:"any",id:"id_mjd_min",value:this.state.mjd_min,onChange:this.handlechange_mjd_min}),/*#__PURE__*/React.createElement("a",{className:"btn",onClick:()=>{this.setState({"mjd_min":getDefaultMjdMin()});this.update_mjd_min(getDefaultMjdMin());localStorage.removeItem("mjd_min")}},"\u21A9\uFE0F"),/*#__PURE__*/React.createElement("p",{className:"inputisodate",id:"id_mjd_min_isoformat"},this.state.mjd_min_isoformat)),/*#__PURE__*/React.createElement("li",{key:"mjd_max"},/*#__PURE__*/React.createElement("label",{htmlFor:"id_mjd_max"},"MJD max:"),/*#__PURE__*/React.createElement("input",{type:"number",name:"mjd_max",step:"any",id:"id_mjd_max",value:this.state.mjd_max,onChange:this.handlechange_mjd_max}),/*#__PURE__*/React.createElement("p",{className:"inputisodate",id:"id_mjd_max_isoformat"},this.state.mjd_max_isoformat),"mjd_max"in this.state.errors?/*#__PURE__*/React.createElement("ul",{className:"errorlist"},/*#__PURE__*/React.createElement("li",null,this.state.errors["mjd_max"])):""),/*#__PURE__*/React.createElement("li",{key:"comment"},/*#__PURE__*/React.createElement("label",{htmlFor:"id_comment"},"Comment:"),/*#__PURE__*/React.createElement("input",{type:"text",name:"comment",maxLength:"300",id:"id_comment",value:this.state.comment,onChange:e=>{this.setState({"comment":e.target.value});localStorage.setItem("comment",e.target.value)}})),/*#__PURE__*/React.createElement("li",{key:"use_reduced"},/*#__PURE__*/React.createElement("input",{type:"checkbox",name:"use_reduced",id:"id_use_reduced",checked:this.state.use_reduced,onChange:e=>{this.setState({"use_reduced":e.target.checked});localStorage.setItem("use_reduced",e.target.checked)}}),/*#__PURE__*/React.createElement("label",{htmlFor:"id_use_reduced"},"Use reduced (input) instead of difference images (",/*#__PURE__*/React.createElement("a",{href:"../faq/"},"FAQ"),")")),/*#__PURE__*/React.createElement("li",{key:"send_email"},/*#__PURE__*/React.createElement("input",{type:"checkbox",name:"send_email",id:"id_send_email",checked:this.state.send_email,onChange:e=>{this.setState({"send_email":e.target.checked});localStorage.setItem("send_email",e.target.checked)}}),/*#__PURE__*/React.createElement("label",{htmlFor:"id_send_email"},"Email me when completed"))));if("non_field_errors"in this.state.errors){formcontent.push(/*#__PURE__*/React.createElement("ul",{className:"errorlist"},/*#__PURE__*/React.createElement("li",null,this.state.errors["non_field_errors"])))}const submitclassname=submission_in_progress?"btn btn-info submitting":"btn btn-info";const submitvalue=submission_in_progress?"Requesting...":"Request";formcontent.push(/*#__PURE__*/React.createElement("input",{key:"submitbutton",className:submitclassname,id:"submitrequest",type:"submit",value:submitvalue}));if(this.state.httperror!=""){formcontent.push(/*#__PURE__*/React.createElement("p",{key:"httperror",style:{"color":"red"}},this.state.httperror))}return/*#__PURE__*/React.createElement("div",{key:"newrequestcontainer",id:"newrequestcontainer"},/*#__PURE__*/React.createElement("div",{key:"newrequestsource",className:"newrequest",id:"newrequestsource"},/*#__PURE__*/React.createElement("div",{key:"newtask",className:"task"},/*#__PURE__*/React.createElement("h2",{key:"newtaskheader"},"New request"),/*#__PURE__*/React.createElement("form",{key:"newtaskform",id:"newrequest",onSubmit:this.onSubmit.bind(this)},formcontent))))}} + diff --git a/static/js/queuepage/build.sh b/static/js/queuepage/build.sh new file mode 100755 index 0000000..306b2d3 --- /dev/null +++ b/static/js/queuepage/build.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +babel --minified --presets @babel/preset-react src/newrequest.jsx > ../newrequest.min.js +babel --minified --presets @babel/preset-react src/tasklist.jsx > ../tasklist.min.js + +babel --minified --presets @babel/preset-react src/lightcurveplotly.js > ../lightcurveplotly.min.js diff --git a/static/js/queuepage/package.json b/static/js/queuepage/package.json index b7399c4..9db686f 100644 --- a/static/js/queuepage/package.json +++ b/static/js/queuepage/package.json @@ -1,9 +1,11 @@ { "dependencies": { "@babel/cli": "^7.22.9", - "@babel/preset-react": "^7.22.5" + "@babel/preset-react": "^7.22.5", + "@react": "^19.0.0", + "@react-dom": "^19.0.0" }, "scripts": { - "build": "babel --minified --presets @babel/preset-react src/newrequest.jsx src/task.jsx src/tasklist.jsx > ../queuepage.min.js" + "build": "./build.sh" } } diff --git a/static/js/lightcurveplotly.js b/static/js/queuepage/src/lightcurveplotly.js similarity index 100% rename from static/js/lightcurveplotly.js rename to static/js/queuepage/src/lightcurveplotly.js diff --git a/static/js/queuepage/src/newrequest.jsx b/static/js/queuepage/src/newrequest.jsx index 88a524c..029540a 100644 --- a/static/js/queuepage/src/newrequest.jsx +++ b/static/js/queuepage/src/newrequest.jsx @@ -1,12 +1,14 @@ 'use strict'; +import React from "react" + let submission_in_progress = false; function getDefaultMjdMin() { return (mjdFromDate(new Date()) - 30.).toFixed(5); } -class NewRequest extends React.Component { +export class NewRequest extends React.Component { get_defaultstate() { // localStorage.getItem('') will be null if the key doesn't exist and null != false, // so != false will default to true, and != true will default to false. @@ -288,4 +290,3 @@ class NewRequest extends React.Component {
); } } - diff --git a/static/js/queuepage/src/task.jsx b/static/js/queuepage/src/task.jsx deleted file mode 100644 index e2a703f..0000000 --- a/static/js/queuepage/src/task.jsx +++ /dev/null @@ -1,284 +0,0 @@ -'use strict'; - -class TaskPlot extends React.PureComponent { - constructor(props) { - super(props); - } - - componentDidMount() { - console.log('activating plot', this.props.taskid) - const plot_url = new URL(this.props.taskurl); - plot_url.pathname += 'resultplotdata.js'; - plot_url.search = ''; - $.ajax({ url: plot_url, cache: true, dataType: 'script' }); - } - - componentWillUnmount() { - console.log('Unmounting plot for task ', this.props.taskid); - delete jslimitsglobal['#plotforcedflux-task-' + this.props.taskid] - delete jslcdataglobal['#plotforcedflux-task-' + this.props.taskid] - delete jslabelsglobal['#plotforcedflux-task-' + this.props.taskid] - } - - render() { - return ( -
- ); - } -} - -class Task extends React.Component { - constructor(props) { - super(props); - this.state = {} - this.state.updateTimeElapsed = this.updateTimeElapsed.bind(this); - this.state.interval = null; - this.state.timeelapsed = -1; - this.state.httperror = ''; - } - - deleteTask() { - const li_id = '#task-' + this.props.taskdata.id - // $(li_id).hide(300); - $(li_id).slideUp(200); - setTimeout(() => { - // console.log('Starting delete of task ', this.props.taskdata.id); - $.ajax({ - headers: { - "X-CSRFToken": getCookie("csrftoken") - }, - url: this.props.taskdata.url, method: 'delete', - success: (result) => { console.log('Deleted task ', this.props.taskdata.id); this.props.fetchData() }, - error: (err) => { console.log('Failed to delete task ', this.props.taskdata.id, err); $('#task-' + this.props.taskdata.id).slideDown(100); this.props.fetchData(); } - }); - }, 200); - } - - requestImages() { - const request_image_url = new URL(this.props.taskdata.url); - request_image_url.pathname += 'requestimages'; - request_image_url.search = ''; - - fetch(request_image_url, - { - credentials: "same-origin", - method: "GET", - headers: { - "X-CSRFToken": getCookie("csrftoken"), - 'Accept': 'application/json', - 'Content-Type': 'application/json', - }, - }) - .catch(error => { - console.log('requestImages HTTP request failed', error); - this.setState({ 'httperror': 'HTTP request failed.' }); - }) - .then((response) => { - if (response.status == 200 && response.redirected) { - // console.log(response) - this.setState({ 'httperror': '' }); - const newimgtask_id = parseInt(new URL(response.url).searchParams.get('newids')); - newtaskids.push(newimgtask_id); - console.log('requestimages created task', newimgtask_id); - const new_page_url = new URL(response.url); - new_page_url.searchParams.delete('newids'); - window.history.pushState({}, document.title, new_page_url); - this.props.fetchData(true); - } else { - response.json().then(data => { - console.log('requestImages: errors returned', data); - this.setState({ 'httperror': 'ERROR: ' + data["error"] }); - }); - } - }); - } - - static getDerivedStateFromProps(props, state) { - if (props.taskdata.starttimestamp != null && props.taskdata.finishtimestamp == null) { - if (state.interval == null) { - const starttime = new Date(props.taskdata.starttimestamp).getTime(); - const timeelapsed = (new Date().getTime() - starttime) / 1000.; - return { 'interval': setInterval(state.updateTimeElapsed, 1000), 'timeelapsed': timeelapsed.toFixed(0) }; - } - } else if (state.interval != null) { - return { 'interval': null }; - } - - return null; - } - - componentDidMount() { - // componentDidUpdate() { - this.updateTimeElapsed(); - if (newtaskids.includes(this.props.taskdata.id)) { - const li_id = '#task-' + this.props.taskdata.id - console.log('showing new task', this.props.taskdata.id); - $(li_id).hide(); - // $(li_id).show(600); - $(li_id).slideDown(200); - newtaskids = newtaskids.filter(item => { return item !== this.props.taskdata.id }) - } - - // this.interval = setInterval(() => {this.updateTimeElapsed()}, 1000); - } - - componentWillUnmount() { - clearInterval(this.state.interval); - // this.state.interval = null; - } - - updateTimeElapsed() { - if (this.props.taskdata.starttimestamp != null && this.props.taskdata.finishtimestamp == null) { - const starttime = new Date(this.props.taskdata.starttimestamp).getTime(); - const timeelapsed = (new Date().getTime() - starttime) / 1000.; - this.setState({ 'timeelapsed': timeelapsed.toFixed(0) }); - } else if (this.state.interval != null) { - clearInterval(this.state.interval); - this.setState({ 'interval': null }); - } - } - - shouldComponentUpdate(nextProps, nextState) { - if (nextState.httperror != this.state.httperror) { - return true; - } - if (nextProps.taskdata.starttimestamp != null && nextProps.taskdata.finishtimestamp == null) { - return true; - } - if (JSON.stringify(nextProps) != JSON.stringify(this.props)) { - return true; - } - - return false; - } - - render() { - const task = this.props.taskdata; - let statusclass = 'none'; - let buttontext = 'none'; - if (task.finishtimestamp != null) { - statusclass = "finished"; - buttontext = 'Delete'; - } else if (task.starttimestamp != null) { - statusclass = "queued started"; - buttontext = 'Cancel'; - } else { - statusclass = "queued notstarted"; - buttontext = 'Cancel'; - } - console.log('Task ' + task.id + ' rendered'); - let delbutton = null; - if (task.user_id == user_id) { - delbutton = ; - } - let taskbox = [ -
- {delbutton} - -
- ]; - - taskbox.push(
{ this.props.setSingleTaskView(e, task.id, task.url) }}>Task {task.id}
); - - if (task.parent_task_url) { - taskbox.push(

Image request for { this.props.setSingleTaskView(e, task.parent_task_id, task.parent_task_url) }}>Task {task.parent_task_id}

); - } else if (task.parent_task_id) { - taskbox.push(

Image request for Task {task.parent_task_id} (deleted)

); - } else if (task.request_type == 'IMGZIP') { - taskbox.push(

Image request

); - } - - if (task.request_type == 'IMGZIP') { - const imagetype = task.use_reduced ? 'reduced' : 'difference'; - taskbox.push(

Up to the first 1000 {imagetype} images will be retrieved. The image request and download link may expire after one week.

); - } - - if (task.user_id != user_id) { - taskbox.push(
User: {task.username}
); - } - - if (task.comment != null && task.comment != '') { - taskbox.push(
Comment: {task.comment}
); - } - - if (task.mpc_name != null && task.mpc_name != '') { - taskbox.push(
MPC Object: {task.mpc_name}
); - } else { - let radecepoch = ''; - if (task.radec_epoch_year != null) { - radecepoch = (epoch {task.radec_epoch_year}) ; - } - taskbox.push(
RA Dec: {radecepoch}{task.ra} {task.dec}
); - if (task.propermotion_ra > 0 || task.propermotion_dec > 0) { - taskbox.push(
Proper motion [mas/yr]: {task.propermotion_ra} {task.propermotion_dec}
); - } - } - - if (task.request_type == "SSOSTACK") { - taskbox.push(
Image: Stacked
); - } else { - taskbox.push(
Images: {task.use_reduced ? 'Reduced' : 'Difference'}
); - } - - if (task.mjd_min != null || task.mjd_max != null) { - const mjdmin = task.mjd_min != null ? task.mjd_min : "0"; - const mjdmax = task.mjd_max != null ? task.mjd_max : "∞"; - taskbox.push(
MJD request: [{mjdmin}, {mjdmax}]
); - } - - taskbox.push(
Queued at {new Date(task.timestamp).toLocaleString()}
); - if (task.finishtimestamp != null) { - taskbox.push(
Finished at {new Date(task.finishtimestamp).toLocaleString()}
); - if (task.error_msg != null) { - taskbox.push(

Error: {task.error_msg}

); - } else { - if (task.request_type == 'FP') { - taskbox.push(Data); - taskbox.push(PDF); - } else if (task.request_type == 'SSOSTACK') { - taskbox.push(Data); - if (task.result_imagestack_url != null) { - taskbox.push(Stacked image (FITS)); - } else { - taskbox.push(

The download link has expired. Delete this task and request again if necessary.

); - } - } - - if (task.request_type == 'IMGZIP') { - if (task.result_imagezip_url != null) { - taskbox.push(Download images (ZIP)); - } else { - taskbox.push(

The download link has expired. Delete this task and request again if necessary.

); - } - } else if (task.imagerequest_task_id != null) { - if (task.imagerequest_finished) { - taskbox.push( { this.props.setSingleTaskView(e, task.imagerequest_task_id, task.imagerequest_url) }}>Images retrieved); - } else { - taskbox.push( { this.props.setSingleTaskView(e, task.imagerequest_task_id, task.imagerequest_url) }}>Images requested); - } - } else if (task.request_type == 'FP' && user_id == task.user_id) { - taskbox.push(); - } - } - } else if (task.starttimestamp != null) { - taskbox.push(
Running (started {this.state.timeelapsed} seconds ago)
); - } else { - taskbox.push(
Waiting ({task.queuepos} tasks ahead of this one)
); - } - - if (this.state.httperror != '') { - taskbox.push(

{this.state.httperror}

); - } - - - if (task.finishtimestamp != null && task.error_msg == null && task.request_type == 'FP' && !this.props.hidePlot) { - taskbox.push(); - } - - return ( -
  • - {taskbox} -
  • - ); - } -} diff --git a/static/js/queuepage/src/tasklist.jsx b/static/js/queuepage/src/tasklist.jsx index 1eacf4c..31a2639 100644 --- a/static/js/queuepage/src/tasklist.jsx +++ b/static/js/queuepage/src/tasklist.jsx @@ -1,14 +1,296 @@ 'use strict'; -const jslcdataglobal = new Object(); -const jslabelsglobal = new Object(); -const jslimitsglobal = new Object(); +import React from "react" +import ReactDOM from 'reactdom'; +import { NewRequest } from "newrequest"; + +class TaskPlot extends React.PureComponent { + constructor(props) { + super(props); + } + + componentDidMount() { + console.log('activating plot', this.props.taskid) + const plot_url = new URL(this.props.taskurl); + plot_url.pathname += 'resultplotdata.js'; + plot_url.search = ''; + $.ajax({ url: plot_url, cache: true, dataType: 'script' }); + } + + componentWillUnmount() { + console.log('Unmounting plot for task ', this.props.taskid); + delete jslimitsglobal['#plotforcedflux-task-' + this.props.taskid] + delete jslcdataglobal['#plotforcedflux-task-' + this.props.taskid] + delete jslabelsglobal['#plotforcedflux-task-' + this.props.taskid] + } + + render() { + return ( +
    + ); + } +} + +export class Task extends React.Component { + constructor(props) { + super(props); + this.state = {} + this.state.updateTimeElapsed = this.updateTimeElapsed.bind(this); + this.state.interval = null; + this.state.timeelapsed = -1; + this.state.httperror = ''; + } + + deleteTask() { + const li_id = '#task-' + this.props.taskdata.id + // $(li_id).hide(300); + $(li_id).slideUp(200); + setTimeout(() => { + // console.log('Starting delete of task ', this.props.taskdata.id); + $.ajax({ + headers: { + "X-CSRFToken": getCookie("csrftoken") + }, + url: this.props.taskdata.url, method: 'delete', + success: (result) => { console.log('Deleted task ', this.props.taskdata.id); this.props.fetchData() }, + error: (err) => { console.log('Failed to delete task ', this.props.taskdata.id, err); $('#task-' + this.props.taskdata.id).slideDown(100); this.props.fetchData(); } + }); + }, 200); + } + + requestImages() { + const request_image_url = new URL(this.props.taskdata.url); + request_image_url.pathname += 'requestimages'; + request_image_url.search = ''; + + fetch(request_image_url, + { + credentials: "same-origin", + method: "GET", + headers: { + "X-CSRFToken": getCookie("csrftoken"), + 'Accept': 'application/json', + 'Content-Type': 'application/json', + }, + }) + .catch(error => { + console.log('requestImages HTTP request failed', error); + this.setState({ 'httperror': 'HTTP request failed.' }); + }) + .then((response) => { + if (response.status == 200 && response.redirected) { + // console.log(response) + this.setState({ 'httperror': '' }); + const newimgtask_id = parseInt(new URL(response.url).searchParams.get('newids')); + newtaskids.push(newimgtask_id); + console.log('requestimages created task', newimgtask_id); + const new_page_url = new URL(response.url); + new_page_url.searchParams.delete('newids'); + window.history.pushState({}, document.title, new_page_url); + this.props.fetchData(true); + } else { + response.json().then(data => { + console.log('requestImages: errors returned', data); + this.setState({ 'httperror': 'ERROR: ' + data["error"] }); + }); + } + }); + } + + static getDerivedStateFromProps(props, state) { + if (props.taskdata.starttimestamp != null && props.taskdata.finishtimestamp == null) { + if (state.interval == null) { + const starttime = new Date(props.taskdata.starttimestamp).getTime(); + const timeelapsed = (new Date().getTime() - starttime) / 1000.; + return { 'interval': setInterval(state.updateTimeElapsed, 1000), 'timeelapsed': timeelapsed.toFixed(0) }; + } + } else if (state.interval != null) { + return { 'interval': null }; + } + + return null; + } + + componentDidMount() { + // componentDidUpdate() { + this.updateTimeElapsed(); + if (newtaskids.includes(this.props.taskdata.id)) { + const li_id = '#task-' + this.props.taskdata.id + console.log('showing new task', this.props.taskdata.id); + $(li_id).hide(); + // $(li_id).show(600); + $(li_id).slideDown(200); + newtaskids = newtaskids.filter(item => { return item !== this.props.taskdata.id }) + } + + // this.interval = setInterval(() => {this.updateTimeElapsed()}, 1000); + } + + componentWillUnmount() { + clearInterval(this.state.interval); + // this.state.interval = null; + } + + updateTimeElapsed() { + if (this.props.taskdata.starttimestamp != null && this.props.taskdata.finishtimestamp == null) { + const starttime = new Date(this.props.taskdata.starttimestamp).getTime(); + const timeelapsed = (new Date().getTime() - starttime) / 1000.; + this.setState({ 'timeelapsed': timeelapsed.toFixed(0) }); + } else if (this.state.interval != null) { + clearInterval(this.state.interval); + this.setState({ 'interval': null }); + } + } + + shouldComponentUpdate(nextProps, nextState) { + if (nextState.httperror != this.state.httperror) { + return true; + } + if (nextProps.taskdata.starttimestamp != null && nextProps.taskdata.finishtimestamp == null) { + return true; + } + if (JSON.stringify(nextProps) != JSON.stringify(this.props)) { + return true; + } + + return false; + } + + render() { + const task = this.props.taskdata; + let statusclass = 'none'; + let buttontext = 'none'; + if (task.finishtimestamp != null) { + statusclass = "finished"; + buttontext = 'Delete'; + } else if (task.starttimestamp != null) { + statusclass = "queued started"; + buttontext = 'Cancel'; + } else { + statusclass = "queued notstarted"; + buttontext = 'Cancel'; + } + console.log('Task ' + task.id + ' rendered'); + let delbutton = null; + if (task.user_id == user_id) { + delbutton = ; + } + let taskbox = [ +
    + {delbutton} + +
    + ]; + + taskbox.push(
    { this.props.setSingleTaskView(e, task.id, task.url) }}>Task {task.id}
    ); + + if (task.parent_task_url) { + taskbox.push(

    Image request for { this.props.setSingleTaskView(e, task.parent_task_id, task.parent_task_url) }}>Task {task.parent_task_id}

    ); + } else if (task.parent_task_id) { + taskbox.push(

    Image request for Task {task.parent_task_id} (deleted)

    ); + } else if (task.request_type == 'IMGZIP') { + taskbox.push(

    Image request

    ); + } + + if (task.request_type == 'IMGZIP') { + const imagetype = task.use_reduced ? 'reduced' : 'difference'; + taskbox.push(

    Up to the first 1000 {imagetype} images will be retrieved. The image request and download link may expire after one week.

    ); + } + + if (task.user_id != user_id) { + taskbox.push(
    User: {task.username}
    ); + } + + if (task.comment != null && task.comment != '') { + taskbox.push(
    Comment: {task.comment}
    ); + } + + if (task.mpc_name != null && task.mpc_name != '') { + taskbox.push(
    MPC Object: {task.mpc_name}
    ); + } else { + let radecepoch = ''; + if (task.radec_epoch_year != null) { + radecepoch = (epoch {task.radec_epoch_year}) ; + } + taskbox.push(
    RA Dec: {radecepoch}{task.ra} {task.dec}
    ); + if (task.propermotion_ra > 0 || task.propermotion_dec > 0) { + taskbox.push(
    Proper motion [mas/yr]: {task.propermotion_ra} {task.propermotion_dec}
    ); + } + } + + if (task.request_type == "SSOSTACK") { + taskbox.push(
    Image: Stacked
    ); + } else { + taskbox.push(
    Images: {task.use_reduced ? 'Reduced' : 'Difference'}
    ); + } + + if (task.mjd_min != null || task.mjd_max != null) { + const mjdmin = task.mjd_min != null ? task.mjd_min : "0"; + const mjdmax = task.mjd_max != null ? task.mjd_max : "∞"; + taskbox.push(
    MJD request: [{mjdmin}, {mjdmax}]
    ); + } + + taskbox.push(
    Queued at {new Date(task.timestamp).toLocaleString()}
    ); + if (task.finishtimestamp != null) { + taskbox.push(
    Finished at {new Date(task.finishtimestamp).toLocaleString()}
    ); + if (task.error_msg != null) { + taskbox.push(

    Error: {task.error_msg}

    ); + } else { + if (task.request_type == 'FP') { + taskbox.push(Data); + taskbox.push(PDF); + } else if (task.request_type == 'SSOSTACK') { + taskbox.push(Data); + if (task.result_imagestack_url != null) { + taskbox.push(Stacked image (FITS)); + } else { + taskbox.push(

    The download link has expired. Delete this task and request again if necessary.

    ); + } + } + + if (task.request_type == 'IMGZIP') { + if (task.result_imagezip_url != null) { + taskbox.push(Download images (ZIP)); + } else { + taskbox.push(

    The download link has expired. Delete this task and request again if necessary.

    ); + } + } else if (task.imagerequest_task_id != null) { + if (task.imagerequest_finished) { + taskbox.push( { this.props.setSingleTaskView(e, task.imagerequest_task_id, task.imagerequest_url) }}>Images retrieved); + } else { + taskbox.push( { this.props.setSingleTaskView(e, task.imagerequest_task_id, task.imagerequest_url) }}>Images requested); + } + } else if (task.request_type == 'FP' && user_id == task.user_id) { + taskbox.push(); + } + } + } else if (task.starttimestamp != null) { + taskbox.push(
    Running (started {this.state.timeelapsed} seconds ago)
    ); + } else { + taskbox.push(
    Waiting ({task.queuepos} tasks ahead of this one)
    ); + } + + if (this.state.httperror != '') { + taskbox.push(

    {this.state.httperror}

    ); + } + + + if (task.finishtimestamp != null && task.error_msg == null && task.request_type == 'FP' && !this.props.hidePlot) { + taskbox.push(); + } + + return ( +
  • + {taskbox} +
  • + ); + } +} let tasklist_api_request_active = false; const tasklist_fetchcache = []; let tasklist_api_error = ''; - class Pager extends React.PureComponent { constructor(props) { super(props); @@ -60,7 +342,7 @@ class Pager extends React.PureComponent { } } -class TaskPage extends React.Component { +export class TaskPage extends React.Component { constructor(props) { super(props); diff --git a/static/js/queuepage.min.js b/static/js/tasklist.min.js similarity index 54% rename from static/js/queuepage.min.js rename to static/js/tasklist.min.js index 6f7afb8..36f5424 100644 --- a/static/js/queuepage.min.js +++ b/static/js/tasklist.min.js @@ -1,24 +1,18 @@ -"use strict";let submission_in_progress=false;function getDefaultMjdMin(){return(mjdFromDate(new Date)-30).toFixed(5)}class NewRequest extends React.Component{get_defaultstate(){// localStorage.getItem('') will be null if the key doesn't exist and null != false, -// so != false will default to true, and != true will default to false. -return{showradechelp:false,radeclist:localStorage.getItem("radeclist")!=null?localStorage.getItem("radeclist"):"",mjd_min:localStorage.getItem("mjd_min")!=null?localStorage.getItem("mjd_min"):getDefaultMjdMin(),mjd_max:localStorage.getItem("mjd_max")!=null?localStorage.getItem("mjd_max"):"",comment:localStorage.getItem("comment")!=null?localStorage.getItem("comment"):"",use_reduced:localStorage.getItem("use_reduced")=="true",send_email:localStorage.getItem("send_email")!="false",enable_stack_rock:localStorage.getItem("enable_stack_rock")=="true",enable_propermotion:localStorage.getItem("enable_propermotion")=="true",radec_epoch_year:localStorage.getItem("radec_epoch_year")!=null?localStorage.getItem("radec_epoch_year"):"",propermotion_ra:localStorage.getItem("propermotion_ra")!=null?localStorage.getItem("propermotion_ra"):0,propermotion_dec:localStorage.getItem("propermotion_dec")!=null?localStorage.getItem("propermotion_dec"):0,errors:[],httperror:"",submission_in_progress:false// duplicated to trigger a render -}}constructor(props){super(props);this.state=this.get_defaultstate();this.handlechange_mjd_min=this.handlechange_mjd_min.bind(this);this.update_mjd_min=this.update_mjd_min.bind(this);this.handlechange_mjd_max=this.handlechange_mjd_max.bind(this);this.update_mjd_max=this.update_mjd_max.bind(this);this.submit=this.submit.bind(this)}componentDidMount(){this.update_mjd_min(this.state.mjd_min);this.update_mjd_max(this.state.mjd_max)}update_mjd_min(strmjdmin){let isostrmin="";if(strmjdmin==""){isostrmin="(leave blank to fetch earliest)"}else{try{const mjdmin=parseFloat(strmjdmin);const isostr_withmilliseconds=dateFromMJD(mjdmin).toISOString();isostrmin=isostr_withmilliseconds.includes(".")?isostr_withmilliseconds.split(".")[0]+"Z":isostr_withmilliseconds}catch(err){isostrmin="error";console.log("error",err,err.message)}}this.setState({"mjd_min":strmjdmin,"mjd_min_isoformat":isostrmin})}handlechange_mjd_min(event){this.update_mjd_min(event.target.value);localStorage.setItem("mjd_min",event.target.value)}update_mjd_max(strmjdmax){let isostrmax="";if(strmjdmax==""){isostrmax="(leave blank to fetch latest)"}else{try{const mjdmax=parseFloat(strmjdmax);console.log("invalid?",strmjdmax,mjdmax);const isostr_withmilliseconds=dateFromMJD(mjdmax).toISOString();isostrmax=isostr_withmilliseconds.includes(".")?isostr_withmilliseconds.split(".")[0]+"Z":isostr_withmilliseconds}catch(err){isostrmax="error";console.log("error",err,err.message)}}this.setState({"mjd_max":strmjdmax,"mjd_max_isoformat":isostrmax});localStorage.setItem("mjd_max",strmjdmax)}handlechange_mjd_max(event){this.update_mjd_max(event.target.value)}async submit(){const datadict={radeclist:this.state.radeclist,mjd_min:this.state.mjd_min==""?null:this.state.mjd_min,mjd_max:this.state.mjd_max==""?null:this.state.mjd_max,use_reduced:this.state.use_reduced,send_email:this.state.send_email,comment:this.state.comment,request_type:this.props.allow_stack_rock&&this.state.enable_stack_rock?"SSOSTACK":"FP"};if(this.state.enable_propermotion){datadict["radec_epoch_year"]=this.state.radec_epoch_year;datadict["propermotion_ra"]=this.state.propermotion_ra;datadict["propermotion_dec"]=this.state.propermotion_dec}console.log(datadict);fetch(api_url_base,{credentials:"same-origin",method:"POST",body:JSON.stringify(datadict),headers:{"X-CSRFToken":getCookie("csrftoken"),"Accept":"application/json","Content-Type":"application/json"}}).catch(error=>{submission_in_progress=false;console.log("New task HTTP request failed",error);this.setState({"httperror":"HTTP request failed.","submission_in_progress":false})}).then(response=>{submission_in_progress=false;this.setState({"httperror":"","submission_in_progress":false});console.log("New task: HTTP response ",response.status);if(response.status==201){console.log("New task: successful creation",response.status);localStorage.removeItem("radeclist");localStorage.removeItem("enable_propermotion");localStorage.removeItem("enable_stack_rock");localStorage.removeItem("radec_epoch_year");localStorage.removeItem("propermotion_ra");localStorage.removeItem("propermotion_dec");localStorage.removeItem("mjd_min");localStorage.removeItem("mjd_max");localStorage.removeItem("comment");this.setState(this.get_defaultstate());response.json().then(data=>{// console.log('Creation data', data); -data.forEach((task,i)=>{console.log("Created new task",task.id);newtaskids.push(task.id)})});window.history.pushState({},document.title,api_url_base);this.props.fetchData(true)}else if(response.status==400){response.json().then(data=>{console.log("New task: errors returned",data);this.setState({"errors":data})})}else{console.log("New task: Error on submission: ",response.status)};}).catch(error=>{submission_in_progress=false;console.log("New task HTTP request failed",error);this.setState({"httperror":"HTTP request failed. Check internet connection and server are online.","submission_in_progress":false})})}onSubmit(){event.preventDefault();if(submission_in_progress){console.log("New task: Submission already in progress");return}console.log("New task: Submitting",api_url_base);submission_in_progress=true;this.setState({"submission_in_progress":false});this.submit()}render(){const formcontent=[];formcontent.push(/*#__PURE__*/React.createElement("ul",{key:"ulradec"},/*#__PURE__*/React.createElement("li",null,/*#__PURE__*/React.createElement("label",{htmlFor:"id_radeclist"},"RA Dec / MPC names:"),/*#__PURE__*/React.createElement("textarea",{name:"radeclist",cols:"",rows:"3",required:true,id:"id_radeclist",value:this.state.radeclist,onChange:e=>{this.setState({"radeclist":e.target.value});localStorage.setItem("radeclist",e.target.value)}}),"\xA0",/*#__PURE__*/React.createElement("a",{onClick:()=>{this.setState({"showradechelp":!this.state.showradechelp})}},"Help"),this.state.showradechelp?/*#__PURE__*/React.createElement("div",{id:"radec_help",style:{display:"block",clear:"right",fontSize:"small"},className:"collapse"},"Each line should consist of a right ascension and a declination coordinate (J2000) in decimal or sexagesimal notation (RA/DEC separated by a space or a comma) or 'mpc ' and a Minor Planet Center object name (e.g. 'mpc Makemake'). Limit of 100 objects per submission. If requested, email notification will be sent only after all targets in the list have been processed."):null),"radeclist"in this.state.errors?/*#__PURE__*/React.createElement("ul",{className:"errorlist"},/*#__PURE__*/React.createElement("li",null,this.state.errors["radeclist"])):""));formcontent.push(/*#__PURE__*/React.createElement("div",{key:"propermotion_checkbox",id:"propermotion_checkboxdiv",style:{width:"100%"}},/*#__PURE__*/React.createElement("label",{style:{width:"100%"}},/*#__PURE__*/React.createElement("input",{type:"checkbox",checked:this.state.enable_propermotion,onChange:e=>{this.setState({"enable_propermotion":e.target.checked});localStorage.setItem("enable_propermotion",e.target.checked)},style:{position:"static",display:"inline",width:"5em"}})," Proper motion")));if(this.state.enable_propermotion){formcontent.push(/*#__PURE__*/React.createElement("div",{key:"propermotion_panel",id:"propermotion_panel",style:{background:"rgb(235,235,235)"}},/*#__PURE__*/React.createElement("p",{key:"propermotiondesc",style:{fontSize:"small"}},"If the star is moving, the J2000 coordinates above are correct for a specified epoch along with proper motions in RA (angle) and Dec in milliarcseconds. The epoch of ATLAS observations varies from 2015.5 to the present. Note: these are angular velocities, not rates of coordinate change."),/*#__PURE__*/React.createElement("ul",{key:"propermotion_inputs"},/*#__PURE__*/React.createElement("li",{key:"radec_epoch_year"},/*#__PURE__*/React.createElement("label",{htmlFor:"id_radec_epoch_year"},"Epoch year:"),/*#__PURE__*/React.createElement("input",{type:"number",name:"radec_epoch_year",step:"0.1",id:"id_radec_epoch_year",value:this.state.radec_epoch_year,onChange:e=>{this.setState({"radec_epoch_year":e.target.value});localStorage.setItem("radec_epoch_year",e.target.value)}})),/*#__PURE__*/React.createElement("li",{key:"propermotion_ra"},/*#__PURE__*/React.createElement("label",{htmlFor:"id_propermotion_ra"},"PM RA [mas/yr]"),/*#__PURE__*/React.createElement("input",{type:"number",name:"propermotion_ra",step:"any",id:"id_propermotion_ra",value:this.state.propermotion_ra,onChange:e=>{this.setState({"propermotion_ra":e.target.value});localStorage.setItem("propermotion_ra",e.target.value)}})),/*#__PURE__*/React.createElement("li",{key:"propermotion_dec"},/*#__PURE__*/React.createElement("label",{htmlFor:"id_propermotion_dec"},"PM Dec [mas/yr]"),/*#__PURE__*/React.createElement("input",{type:"number",name:"propermotion_dec",step:"any",id:"id_propermotion_dec",value:this.state.propermotion_dec,onChange:e=>{this.setState({"propermotion_dec":e.target.value});localStorage.setItem("propermotion_dec",e.target.value)}})))))}if(this.props.allow_stack_rock){formcontent.push(/*#__PURE__*/React.createElement("div",{key:"stack_rock",id:"stack_rock",style:{width:"100%"}},/*#__PURE__*/React.createElement("label",{style:{width:"100%"}},/*#__PURE__*/React.createElement("input",{type:"checkbox",checked:this.state.enable_stack_rock,onChange:e=>{this.setState({"enable_stack_rock":e.target.checked});localStorage.setItem("enable_stack_rock",e.target.checked)},style:{position:"static",display:"inline",width:"5em"}})," Get stack of SS object images")));if(this.state.enable_stack_rock){formcontent.push(/*#__PURE__*/React.createElement("div",{key:"stackrock_panel",id:"stackrock_panel",style:{background:"rgb(235,235,235)"}},/*#__PURE__*/React.createElement("p",{key:"stackrockdesc",style:{fontSize:"small"}},"Perform a shift & stack operation for the MPC object entered above.")))}}formcontent.push(/*#__PURE__*/React.createElement("ul",{key:"ulmjdoptions"},/*#__PURE__*/React.createElement("li",{key:"mjd_min"},/*#__PURE__*/React.createElement("label",{htmlFor:"id_mjd_min"},"MJD min:"),/*#__PURE__*/React.createElement("input",{type:"number",name:"mjd_min",step:"any",id:"id_mjd_min",value:this.state.mjd_min,onChange:this.handlechange_mjd_min}),/*#__PURE__*/React.createElement("a",{className:"btn",onClick:()=>{this.setState({"mjd_min":getDefaultMjdMin()});this.update_mjd_min(getDefaultMjdMin());localStorage.removeItem("mjd_min")}},"\u21A9\uFE0F"),/*#__PURE__*/React.createElement("p",{className:"inputisodate",id:"id_mjd_min_isoformat"},this.state.mjd_min_isoformat)),/*#__PURE__*/React.createElement("li",{key:"mjd_max"},/*#__PURE__*/React.createElement("label",{htmlFor:"id_mjd_max"},"MJD max:"),/*#__PURE__*/React.createElement("input",{type:"number",name:"mjd_max",step:"any",id:"id_mjd_max",value:this.state.mjd_max,onChange:this.handlechange_mjd_max}),/*#__PURE__*/React.createElement("p",{className:"inputisodate",id:"id_mjd_max_isoformat"},this.state.mjd_max_isoformat),"mjd_max"in this.state.errors?/*#__PURE__*/React.createElement("ul",{className:"errorlist"},/*#__PURE__*/React.createElement("li",null,this.state.errors["mjd_max"])):""),/*#__PURE__*/React.createElement("li",{key:"comment"},/*#__PURE__*/React.createElement("label",{htmlFor:"id_comment"},"Comment:"),/*#__PURE__*/React.createElement("input",{type:"text",name:"comment",maxLength:"300",id:"id_comment",value:this.state.comment,onChange:e=>{this.setState({"comment":e.target.value});localStorage.setItem("comment",e.target.value)}})),/*#__PURE__*/React.createElement("li",{key:"use_reduced"},/*#__PURE__*/React.createElement("input",{type:"checkbox",name:"use_reduced",id:"id_use_reduced",checked:this.state.use_reduced,onChange:e=>{this.setState({"use_reduced":e.target.checked});localStorage.setItem("use_reduced",e.target.checked)}}),/*#__PURE__*/React.createElement("label",{htmlFor:"id_use_reduced"},"Use reduced (input) instead of difference images (",/*#__PURE__*/React.createElement("a",{href:"../faq/"},"FAQ"),")")),/*#__PURE__*/React.createElement("li",{key:"send_email"},/*#__PURE__*/React.createElement("input",{type:"checkbox",name:"send_email",id:"id_send_email",checked:this.state.send_email,onChange:e=>{this.setState({"send_email":e.target.checked});localStorage.setItem("send_email",e.target.checked)}}),/*#__PURE__*/React.createElement("label",{htmlFor:"id_send_email"},"Email me when completed"))));if("non_field_errors"in this.state.errors){formcontent.push(/*#__PURE__*/React.createElement("ul",{className:"errorlist"},/*#__PURE__*/React.createElement("li",null,this.state.errors["non_field_errors"])))}const submitclassname=submission_in_progress?"btn btn-info submitting":"btn btn-info";const submitvalue=submission_in_progress?"Requesting...":"Request";formcontent.push(/*#__PURE__*/React.createElement("input",{key:"submitbutton",className:submitclassname,id:"submitrequest",type:"submit",value:submitvalue}));if(this.state.httperror!=""){formcontent.push(/*#__PURE__*/React.createElement("p",{key:"httperror",style:{"color":"red"}},this.state.httperror))}return/*#__PURE__*/React.createElement("div",{key:"newrequestcontainer",id:"newrequestcontainer"},/*#__PURE__*/React.createElement("div",{key:"newrequestsource",className:"newrequest",id:"newrequestsource"},/*#__PURE__*/React.createElement("div",{key:"newtask",className:"task"},/*#__PURE__*/React.createElement("h2",{key:"newtaskheader"},"New request"),/*#__PURE__*/React.createElement("form",{key:"newtaskform",id:"newrequest",onSubmit:this.onSubmit.bind(this)},formcontent))))}} -"use strict";class TaskPlot extends React.PureComponent{constructor(props){super(props)}componentDidMount(){console.log("activating plot",this.props.taskid);const plot_url=new URL(this.props.taskurl);plot_url.pathname+="resultplotdata.js";plot_url.search="";$.ajax({url:plot_url,cache:true,dataType:"script"})}componentWillUnmount(){console.log("Unmounting plot for task ",this.props.taskid);delete jslimitsglobal["#plotforcedflux-task-"+this.props.taskid];delete jslcdataglobal["#plotforcedflux-task-"+this.props.taskid];delete jslabelsglobal["#plotforcedflux-task-"+this.props.taskid]}render(){return/*#__PURE__*/React.createElement("div",{key:"plot",id:"plotforcedflux-task-"+this.props.taskid,className:"plot",style:{width:"100%",height:"300px"}})}}class Task extends React.Component{constructor(props){super(props);this.state={};this.state.updateTimeElapsed=this.updateTimeElapsed.bind(this);this.state.interval=null;this.state.timeelapsed=-1;this.state.httperror=""}deleteTask(){const li_id="#task-"+this.props.taskdata.id;// $(li_id).hide(300); +"use strict";import React from"react";import ReactDOM from"reactdom";import{NewRequest}from"newrequest";class TaskPlot extends React.PureComponent{constructor(props){super(props)}componentDidMount(){console.log("activating plot",this.props.taskid);const plot_url=new URL(this.props.taskurl);plot_url.pathname+="resultplotdata.js";plot_url.search="";$.ajax({url:plot_url,cache:true,dataType:"script"})}componentWillUnmount(){console.log("Unmounting plot for task ",this.props.taskid);delete jslimitsglobal["#plotforcedflux-task-"+this.props.taskid];delete jslcdataglobal["#plotforcedflux-task-"+this.props.taskid];delete jslabelsglobal["#plotforcedflux-task-"+this.props.taskid]}render(){return/*#__PURE__*/React.createElement("div",{key:"plot",id:"plotforcedflux-task-"+this.props.taskid,className:"plot",style:{width:"100%",height:"300px"}})}}export class Task extends React.Component{constructor(props){super(props);this.state={};this.state.updateTimeElapsed=this.updateTimeElapsed.bind(this);this.state.interval=null;this.state.timeelapsed=-1;this.state.httperror=""}deleteTask(){const li_id="#task-"+this.props.taskdata.id;// $(li_id).hide(300); $(li_id).slideUp(200);setTimeout(()=>{// console.log('Starting delete of task ', this.props.taskdata.id); $.ajax({headers:{"X-CSRFToken":getCookie("csrftoken")},url:this.props.taskdata.url,method:"delete",success:result=>{console.log("Deleted task ",this.props.taskdata.id);this.props.fetchData()},error:err=>{console.log("Failed to delete task ",this.props.taskdata.id,err);$("#task-"+this.props.taskdata.id).slideDown(100);this.props.fetchData()}})},200)}requestImages(){const request_image_url=new URL(this.props.taskdata.url);request_image_url.pathname+="requestimages";request_image_url.search="";fetch(request_image_url,{credentials:"same-origin",method:"GET",headers:{"X-CSRFToken":getCookie("csrftoken"),"Accept":"application/json","Content-Type":"application/json"}}).catch(error=>{console.log("requestImages HTTP request failed",error);this.setState({"httperror":"HTTP request failed."})}).then(response=>{if(response.status==200&&response.redirected){// console.log(response) this.setState({"httperror":""});const newimgtask_id=parseInt(new URL(response.url).searchParams.get("newids"));newtaskids.push(newimgtask_id);console.log("requestimages created task",newimgtask_id);const new_page_url=new URL(response.url);new_page_url.searchParams.delete("newids");window.history.pushState({},document.title,new_page_url);this.props.fetchData(true)}else{response.json().then(data=>{console.log("requestImages: errors returned",data);this.setState({"httperror":"ERROR: "+data["error"]})})}})}static getDerivedStateFromProps(props,state){if(props.taskdata.starttimestamp!=null&&props.taskdata.finishtimestamp==null){if(state.interval==null){const starttime=new Date(props.taskdata.starttimestamp).getTime();const timeelapsed=(new Date().getTime()-starttime)/1000;return{"interval":setInterval(state.updateTimeElapsed,1000),"timeelapsed":timeelapsed.toFixed(0)}}}else if(state.interval!=null){return{"interval":null}}return null}componentDidMount(){// componentDidUpdate() { this.updateTimeElapsed();if(newtaskids.includes(this.props.taskdata.id)){const li_id="#task-"+this.props.taskdata.id;console.log("showing new task",this.props.taskdata.id);$(li_id).hide();// $(li_id).show(600); $(li_id).slideDown(200);newtaskids=newtaskids.filter(item=>{return item!==this.props.taskdata.id})}// this.interval = setInterval(() => {this.updateTimeElapsed()}, 1000); }componentWillUnmount(){clearInterval(this.state.interval);// this.state.interval = null; -}updateTimeElapsed(){if(this.props.taskdata.starttimestamp!=null&&this.props.taskdata.finishtimestamp==null){const starttime=new Date(this.props.taskdata.starttimestamp).getTime();const timeelapsed=(new Date().getTime()-starttime)/1000;this.setState({"timeelapsed":timeelapsed.toFixed(0)})}else if(this.state.interval!=null){clearInterval(this.state.interval);this.setState({"interval":null})}}shouldComponentUpdate(nextProps,nextState){if(nextState.httperror!=this.state.httperror){return true}if(nextProps.taskdata.starttimestamp!=null&&nextProps.taskdata.finishtimestamp==null){return true}if(JSON.stringify(nextProps)!=JSON.stringify(this.props)){return true}return false}render(){const task=this.props.taskdata;let statusclass="none";let buttontext="none";if(task.finishtimestamp!=null){statusclass="finished";buttontext="Delete"}else if(task.starttimestamp!=null){statusclass="queued started";buttontext="Cancel"}else{statusclass="queued notstarted";buttontext="Cancel"}console.log("Task "+task.id+" rendered");let delbutton=null;if(task.user_id==user_id){delbutton=/*#__PURE__*/React.createElement("button",{className:"btn btn-sm btn-danger",onClick:()=>this.deleteTask()},buttontext)}let taskbox=[/*#__PURE__*/React.createElement("div",{key:"rightside",className:"rightside"},delbutton,/*#__PURE__*/React.createElement("img",{src:task.previewimage_url,style:{display:"block",marginTop:"1em",marginLeft:"1em"}}))];taskbox.push(/*#__PURE__*/React.createElement("div",{key:"tasknum"},/*#__PURE__*/React.createElement("a",{key:"tasklink",href:task.url,onClick:e=>{this.props.setSingleTaskView(e,task.id,task.url)}},"Task ",task.id)));if(task.parent_task_url){taskbox.push(/*#__PURE__*/React.createElement("p",{key:"imgrequest"},"Image request for ",/*#__PURE__*/React.createElement("a",{key:"parent_task_link",href:task.parent_task_url,onClick:e=>{this.props.setSingleTaskView(e,task.parent_task_id,task.parent_task_url)}},"Task ",task.parent_task_id)))}else if(task.parent_task_id){taskbox.push(/*#__PURE__*/React.createElement("p",{key:"imgrequest"},"Image request for Task ",task.parent_task_id," (deleted)"))}else if(task.request_type=="IMGZIP"){taskbox.push(/*#__PURE__*/React.createElement("p",{key:"imgrequest"},"Image request"))}if(task.request_type=="IMGZIP"){const imagetype=task.use_reduced?"reduced":"difference";taskbox.push(/*#__PURE__*/React.createElement("p",{key:"imgrequestnote"},"Up to the first 1000 ",imagetype," images will be retrieved. The image request and download link may expire after one week."))}if(task.user_id!=user_id){taskbox.push(/*#__PURE__*/React.createElement("div",{key:"user"},"User: ",task.username))}if(task.comment!=null&&task.comment!=""){taskbox.push(/*#__PURE__*/React.createElement("div",{key:"comment"},"Comment: ",/*#__PURE__*/React.createElement("b",null,task.comment)))}if(task.mpc_name!=null&&task.mpc_name!=""){taskbox.push(/*#__PURE__*/React.createElement("div",{key:"target"},"MPC Object: ",task.mpc_name))}else{let radecepoch="";if(task.radec_epoch_year!=null){radecepoch=/*#__PURE__*/React.createElement("span",null,"(epoch ",task.radec_epoch_year,") ")}taskbox.push(/*#__PURE__*/React.createElement("div",{key:"target"},"RA Dec: ",radecepoch,task.ra," ",task.dec));if(task.propermotion_ra>0||task.propermotion_dec>0){taskbox.push(/*#__PURE__*/React.createElement("div",{key:"propermotion"},"Proper motion [mas/yr]: ",task.propermotion_ra," ",task.propermotion_dec))}}if(task.request_type=="SSOSTACK"){taskbox.push(/*#__PURE__*/React.createElement("div",{key:"imgtype"},"Image: Stacked"))}else{taskbox.push(/*#__PURE__*/React.createElement("div",{key:"imgtype"},"Images: ",task.use_reduced?"Reduced":"Difference"))}if(task.mjd_min!=null||task.mjd_max!=null){const mjdmin=task.mjd_min!=null?task.mjd_min:"0";const mjdmax=task.mjd_max!=null?task.mjd_max:"\u221E";taskbox.push(/*#__PURE__*/React.createElement("div",{key:"mjdrange"},"MJD request: [",mjdmin,", ",mjdmax,"]"))}taskbox.push(/*#__PURE__*/React.createElement("div",{key:"queuetime"},"Queued at ",new Date(task.timestamp).toLocaleString()));if(task.finishtimestamp!=null){taskbox.push(/*#__PURE__*/React.createElement("div",{key:"status"},"Finished at ",new Date(task.finishtimestamp).toLocaleString()));if(task.error_msg!=null){taskbox.push(/*#__PURE__*/React.createElement("p",{key:"error_msg",style:{color:"black",fontWeight:"bold",marginTop:"1em"}},"Error: ",task.error_msg))}else{if(task.request_type=="FP"){taskbox.push(/*#__PURE__*/React.createElement("a",{key:"datalink",className:"results btn btn-info getdata",href:task.result_url,target:"_blank"},"Data"));taskbox.push(/*#__PURE__*/React.createElement("a",{key:"pdflink",className:"results btn btn-info getpdf",href:task.pdfplot_url,target:"_blank"},"PDF"))}else if(task.request_type=="SSOSTACK"){taskbox.push(/*#__PURE__*/React.createElement("a",{key:"datalink",className:"results btn btn-info getdata",href:task.result_url,target:"_blank"},"Data"));if(task.result_imagestack_url!=null){taskbox.push(/*#__PURE__*/React.createElement("a",{key:"imgdownload",className:"results btn btn-info",href:task.result_imagestack_url,target:"_blank"},"Stacked image (FITS)"))}else{taskbox.push(/*#__PURE__*/React.createElement("p",null,"The download link has expired. Delete this task and request again if necessary."))}}if(task.request_type=="IMGZIP"){if(task.result_imagezip_url!=null){taskbox.push(/*#__PURE__*/React.createElement("a",{key:"imgdownload",className:"results btn btn-info",href:task.result_imagezip_url},"Download images (ZIP)"))}else{taskbox.push(/*#__PURE__*/React.createElement("p",null,"The download link has expired. Delete this task and request again if necessary."))}}else if(task.imagerequest_task_id!=null){if(task.imagerequest_finished){taskbox.push(/*#__PURE__*/React.createElement("a",{key:"imgrequest",className:"btn btn-primary",href:task.imagerequest_url,onClick:e=>{this.props.setSingleTaskView(e,task.imagerequest_task_id,task.imagerequest_url)}},"Images retrieved"))}else{taskbox.push(/*#__PURE__*/React.createElement("a",{key:"imgrequest",className:"btn btn-warning",href:task.imagerequest_url,onClick:e=>{this.props.setSingleTaskView(e,task.imagerequest_task_id,task.imagerequest_url)}},"Images requested"))}}else if(task.request_type=="FP"&&user_id==task.user_id){taskbox.push(/*#__PURE__*/React.createElement("button",{key:"imgrequest",className:"btn btn-info",onClick:()=>this.requestImages(),title:"Download FITS and JPEG images for up to the first 1000 observations."},"Request ",task.use_reduced?"reduced":"diff"," images"))}}}else if(task.starttimestamp!=null){taskbox.push(/*#__PURE__*/React.createElement("div",{key:"status",style:{color:"red",fontStyle:"italic",marginTop:"1em"}},"Running (started ",this.state.timeelapsed," seconds ago)"))}else{taskbox.push(/*#__PURE__*/React.createElement("div",{key:"status",style:{fontStyle:"italic",marginTop:"1em"}},"Waiting (",task.queuepos," tasks ahead of this one)"))}if(this.state.httperror!=""){taskbox.push(/*#__PURE__*/React.createElement("p",{key:"httperror",style:{"color":"red"}},this.state.httperror))}if(task.finishtimestamp!=null&&task.error_msg==null&&task.request_type=="FP"&&!this.props.hidePlot){taskbox.push(/*#__PURE__*/React.createElement(TaskPlot,{key:"plot",taskid:task.id,taskurl:task.url}))}return/*#__PURE__*/React.createElement("li",{key:"task-"+task.id,className:"task "+statusclass,id:"task-"+task.id},taskbox)}} -"use strict";const jslcdataglobal=new Object;const jslabelsglobal=new Object;const jslimitsglobal=new Object;let tasklist_api_request_active=false;const tasklist_fetchcache=[];let tasklist_api_error="";class Pager extends React.PureComponent{constructor(props){super(props);this.state={};if(this.props.previous!=null){this.state.previous_cursor=new URL(this.props.previous).searchParams.get("cursor")}if(this.props.next!=null){this.state.next_cursor=new URL(this.props.next).searchParams.get("cursor")}}// componentWillReceiveProps(nextProps) { +}updateTimeElapsed(){if(this.props.taskdata.starttimestamp!=null&&this.props.taskdata.finishtimestamp==null){const starttime=new Date(this.props.taskdata.starttimestamp).getTime();const timeelapsed=(new Date().getTime()-starttime)/1000;this.setState({"timeelapsed":timeelapsed.toFixed(0)})}else if(this.state.interval!=null){clearInterval(this.state.interval);this.setState({"interval":null})}}shouldComponentUpdate(nextProps,nextState){if(nextState.httperror!=this.state.httperror){return true}if(nextProps.taskdata.starttimestamp!=null&&nextProps.taskdata.finishtimestamp==null){return true}if(JSON.stringify(nextProps)!=JSON.stringify(this.props)){return true}return false}render(){const task=this.props.taskdata;let statusclass="none";let buttontext="none";if(task.finishtimestamp!=null){statusclass="finished";buttontext="Delete"}else if(task.starttimestamp!=null){statusclass="queued started";buttontext="Cancel"}else{statusclass="queued notstarted";buttontext="Cancel"}console.log("Task "+task.id+" rendered");let delbutton=null;if(task.user_id==user_id){delbutton=/*#__PURE__*/React.createElement("button",{className:"btn btn-sm btn-danger",onClick:()=>this.deleteTask()},buttontext)}let taskbox=[/*#__PURE__*/React.createElement("div",{key:"rightside",className:"rightside"},delbutton,/*#__PURE__*/React.createElement("img",{src:task.previewimage_url,style:{display:"block",marginTop:"1em",marginLeft:"1em"}}))];taskbox.push(/*#__PURE__*/React.createElement("div",{key:"tasknum"},/*#__PURE__*/React.createElement("a",{key:"tasklink",href:task.url,onClick:e=>{this.props.setSingleTaskView(e,task.id,task.url)}},"Task ",task.id)));if(task.parent_task_url){taskbox.push(/*#__PURE__*/React.createElement("p",{key:"imgrequest"},"Image request for ",/*#__PURE__*/React.createElement("a",{key:"parent_task_link",href:task.parent_task_url,onClick:e=>{this.props.setSingleTaskView(e,task.parent_task_id,task.parent_task_url)}},"Task ",task.parent_task_id)))}else if(task.parent_task_id){taskbox.push(/*#__PURE__*/React.createElement("p",{key:"imgrequest"},"Image request for Task ",task.parent_task_id," (deleted)"))}else if(task.request_type=="IMGZIP"){taskbox.push(/*#__PURE__*/React.createElement("p",{key:"imgrequest"},"Image request"))}if(task.request_type=="IMGZIP"){const imagetype=task.use_reduced?"reduced":"difference";taskbox.push(/*#__PURE__*/React.createElement("p",{key:"imgrequestnote"},"Up to the first 1000 ",imagetype," images will be retrieved. The image request and download link may expire after one week."))}if(task.user_id!=user_id){taskbox.push(/*#__PURE__*/React.createElement("div",{key:"user"},"User: ",task.username))}if(task.comment!=null&&task.comment!=""){taskbox.push(/*#__PURE__*/React.createElement("div",{key:"comment"},"Comment: ",/*#__PURE__*/React.createElement("b",null,task.comment)))}if(task.mpc_name!=null&&task.mpc_name!=""){taskbox.push(/*#__PURE__*/React.createElement("div",{key:"target"},"MPC Object: ",task.mpc_name))}else{let radecepoch="";if(task.radec_epoch_year!=null){radecepoch=/*#__PURE__*/React.createElement("span",null,"(epoch ",task.radec_epoch_year,") ")}taskbox.push(/*#__PURE__*/React.createElement("div",{key:"target"},"RA Dec: ",radecepoch,task.ra," ",task.dec));if(task.propermotion_ra>0||task.propermotion_dec>0){taskbox.push(/*#__PURE__*/React.createElement("div",{key:"propermotion"},"Proper motion [mas/yr]: ",task.propermotion_ra," ",task.propermotion_dec))}}if(task.request_type=="SSOSTACK"){taskbox.push(/*#__PURE__*/React.createElement("div",{key:"imgtype"},"Image: Stacked"))}else{taskbox.push(/*#__PURE__*/React.createElement("div",{key:"imgtype"},"Images: ",task.use_reduced?"Reduced":"Difference"))}if(task.mjd_min!=null||task.mjd_max!=null){const mjdmin=task.mjd_min!=null?task.mjd_min:"0";const mjdmax=task.mjd_max!=null?task.mjd_max:"\u221E";taskbox.push(/*#__PURE__*/React.createElement("div",{key:"mjdrange"},"MJD request: [",mjdmin,", ",mjdmax,"]"))}taskbox.push(/*#__PURE__*/React.createElement("div",{key:"queuetime"},"Queued at ",new Date(task.timestamp).toLocaleString()));if(task.finishtimestamp!=null){taskbox.push(/*#__PURE__*/React.createElement("div",{key:"status"},"Finished at ",new Date(task.finishtimestamp).toLocaleString()));if(task.error_msg!=null){taskbox.push(/*#__PURE__*/React.createElement("p",{key:"error_msg",style:{color:"black",fontWeight:"bold",marginTop:"1em"}},"Error: ",task.error_msg))}else{if(task.request_type=="FP"){taskbox.push(/*#__PURE__*/React.createElement("a",{key:"datalink",className:"results btn btn-info getdata",href:task.result_url,target:"_blank"},"Data"));taskbox.push(/*#__PURE__*/React.createElement("a",{key:"pdflink",className:"results btn btn-info getpdf",href:task.pdfplot_url,target:"_blank"},"PDF"))}else if(task.request_type=="SSOSTACK"){taskbox.push(/*#__PURE__*/React.createElement("a",{key:"datalink",className:"results btn btn-info getdata",href:task.result_url,target:"_blank"},"Data"));if(task.result_imagestack_url!=null){taskbox.push(/*#__PURE__*/React.createElement("a",{key:"imgdownload",className:"results btn btn-info",href:task.result_imagestack_url,target:"_blank"},"Stacked image (FITS)"))}else{taskbox.push(/*#__PURE__*/React.createElement("p",null,"The download link has expired. Delete this task and request again if necessary."))}}if(task.request_type=="IMGZIP"){if(task.result_imagezip_url!=null){taskbox.push(/*#__PURE__*/React.createElement("a",{key:"imgdownload",className:"results btn btn-info",href:task.result_imagezip_url},"Download images (ZIP)"))}else{taskbox.push(/*#__PURE__*/React.createElement("p",null,"The download link has expired. Delete this task and request again if necessary."))}}else if(task.imagerequest_task_id!=null){if(task.imagerequest_finished){taskbox.push(/*#__PURE__*/React.createElement("a",{key:"imgrequest",className:"btn btn-primary",href:task.imagerequest_url,onClick:e=>{this.props.setSingleTaskView(e,task.imagerequest_task_id,task.imagerequest_url)}},"Images retrieved"))}else{taskbox.push(/*#__PURE__*/React.createElement("a",{key:"imgrequest",className:"btn btn-warning",href:task.imagerequest_url,onClick:e=>{this.props.setSingleTaskView(e,task.imagerequest_task_id,task.imagerequest_url)}},"Images requested"))}}else if(task.request_type=="FP"&&user_id==task.user_id){taskbox.push(/*#__PURE__*/React.createElement("button",{key:"imgrequest",className:"btn btn-info",onClick:()=>this.requestImages(),title:"Download FITS and JPEG images for up to the first 1000 observations."},"Request ",task.use_reduced?"reduced":"diff"," images"))}}}else if(task.starttimestamp!=null){taskbox.push(/*#__PURE__*/React.createElement("div",{key:"status",style:{color:"red",fontStyle:"italic",marginTop:"1em"}},"Running (started ",this.state.timeelapsed," seconds ago)"))}else{taskbox.push(/*#__PURE__*/React.createElement("div",{key:"status",style:{fontStyle:"italic",marginTop:"1em"}},"Waiting (",task.queuepos," tasks ahead of this one)"))}if(this.state.httperror!=""){taskbox.push(/*#__PURE__*/React.createElement("p",{key:"httperror",style:{"color":"red"}},this.state.httperror))}if(task.finishtimestamp!=null&&task.error_msg==null&&task.request_type=="FP"&&!this.props.hidePlot){taskbox.push(/*#__PURE__*/React.createElement(TaskPlot,{key:"plot",taskid:task.id,taskurl:task.url}))}return/*#__PURE__*/React.createElement("li",{key:"task-"+task.id,className:"task "+statusclass,id:"task-"+task.id},taskbox)}}let tasklist_api_request_active=false;const tasklist_fetchcache=[];let tasklist_api_error="";class Pager extends React.PureComponent{constructor(props){super(props);this.state={};if(this.props.previous!=null){this.state.previous_cursor=new URL(this.props.previous).searchParams.get("cursor")}if(this.props.next!=null){this.state.next_cursor=new URL(this.props.next).searchParams.get("cursor")}}// componentWillReceiveProps(nextProps) { // if (JSON.stringify(nextProps) != JSON.stringify(this.state)) // { // this.setState(nextProps); // console.log('Pager changed'); // } // } -static getDerivedStateFromProps(props,state){const statechanges={};if(props.previous!=null){statechanges.previous_cursor=new URL(props.previous).searchParams.get("cursor")}if(props.next!=null){statechanges.next_cursor=new URL(props.next).searchParams.get("cursor")}return statechanges}render(){console.log("Pager rendered");if(this.props.taskcount==null){return null}else{return/*#__PURE__*/React.createElement("div",{id:"paginator",key:"paginator"},/*#__PURE__*/React.createElement("p",{key:"pagedescription"},"Showing tasks ",this.props.pagefirsttaskposition+1,"-",this.props.pagefirsttaskposition+this.props.pagetaskcount," of ",this.props.taskcount),/*#__PURE__*/React.createElement("ul",{key:"prevnext",className:"pager"},this.props.previous!=null?/*#__PURE__*/React.createElement("li",{key:"previous",className:"previous"},/*#__PURE__*/React.createElement("a",{onClick:()=>{this.props.updateCursor(this.state.previous_cursor)},style:{cursor:"pointer"}},"\xAB Newer")):null,this.props.next!=null?/*#__PURE__*/React.createElement("li",{key:"next",className:"next"},/*#__PURE__*/React.createElement("a",{onClick:()=>{this.props.updateCursor(this.state.next_cursor)},style:{cursor:"pointer"}},"Older \xBB")):null))}}}class TaskPage extends React.Component{constructor(props){super(props);this.state={taskcount:null,results:null,scrollToTopAfterUpdate:false,dataurl:window.location.href,fetchtimeelapsed:null};this.newRequest=React.createRef();this.setSingleTaskView=this.setSingleTaskView.bind(this);this.updateCursor=this.updateCursor.bind(this);this.fetchData=this.fetchData.bind(this)}filterclass(filtername,strurl){// var page_url = new URL(window.location.href); +static getDerivedStateFromProps(props,state){const statechanges={};if(props.previous!=null){statechanges.previous_cursor=new URL(props.previous).searchParams.get("cursor")}if(props.next!=null){statechanges.next_cursor=new URL(props.next).searchParams.get("cursor")}return statechanges}render(){console.log("Pager rendered");if(this.props.taskcount==null){return null}else{return/*#__PURE__*/React.createElement("div",{id:"paginator",key:"paginator"},/*#__PURE__*/React.createElement("p",{key:"pagedescription"},"Showing tasks ",this.props.pagefirsttaskposition+1,"-",this.props.pagefirsttaskposition+this.props.pagetaskcount," of ",this.props.taskcount),/*#__PURE__*/React.createElement("ul",{key:"prevnext",className:"pager"},this.props.previous!=null?/*#__PURE__*/React.createElement("li",{key:"previous",className:"previous"},/*#__PURE__*/React.createElement("a",{onClick:()=>{this.props.updateCursor(this.state.previous_cursor)},style:{cursor:"pointer"}},"\xAB Newer")):null,this.props.next!=null?/*#__PURE__*/React.createElement("li",{key:"next",className:"next"},/*#__PURE__*/React.createElement("a",{onClick:()=>{this.props.updateCursor(this.state.next_cursor)},style:{cursor:"pointer"}},"Older \xBB")):null))}}}export class TaskPage extends React.Component{constructor(props){super(props);this.state={taskcount:null,results:null,scrollToTopAfterUpdate:false,dataurl:window.location.href,fetchtimeelapsed:null};this.newRequest=/*#__PURE__*/React.createRef();this.setSingleTaskView=this.setSingleTaskView.bind(this);this.updateCursor=this.updateCursor.bind(this);this.fetchData=this.fetchData.bind(this)}filterclass(filtername,strurl){// var page_url = new URL(window.location.href); const page_url=new URL(strurl);const started=page_url.searchParams.get("started");if(filtername==null){if(started==null&&this.singleTaskViewTaskId(this.state.dataurl)==null){return"btn-primary"}else{return"btn-link"}}else if(filtername=="started"){if(started=="true"){return"btn-primary"}else{return"btn-link"}}}setFilter(filtername){console.log("changed filter to",filtername);const new_page_url=new URL(api_url_base);new_page_url.search="";if(filtername!=null){new_page_url.searchParams.set(filtername,true)}if(new_page_url!=window.location.href){window.history.pushState({},document.title,new_page_url);const statechanges={"scrollToTopAfterUpdate":true,dataurl:new_page_url};if(filtername=="started"&&this.state.results!=null){statechanges["results"]=this.state.results.filter(task=>{return task.starttimestamp!=null});if(statechanges["results"].length==0){// prevent flash of "there are no results" for empty ([] non-null) results list statechanges["results"]=null}}this.setState(statechanges,()=>{this.fetchData(true)})}}singleTaskViewTaskId(strurl){const pathext=strurl.toString().replace(api_url_base.toString(),"").split("/").filter(el=>{return el.length!=0});if(pathext.length==1&&!isNaN(pathext[0])){return parseInt(pathext[0])}else{return null}}setSingleTaskView(event,task_id,task_url){if(event.ctrlKey||event.metaKey||event.shiftKey){return;// let the browser deal with the click natively }event.preventDefault();const new_page_url=api_url_base+task_id+"/";window.history.pushState({},document.title,new_page_url);console.log("Task list changed to single task view for ",new_page_url.toString());let newresults=this.state.results.filter(task=>{return task.id==task_id});if(newresults.length==0){newresults=null;// prevent flash of "there are no results" for empty (non-null) results list