Untitled

 avatar
unknown
plain_text
2 years ago
26 kB
5
Indexable
// ==UserScript==
// @name         sivnan
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        https://issues.amazon.com/*
// @match       https://sim.amazon.com/sprints/*
// @require  http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js
// @icon         data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @grant           GM.xmlHttpRequest
// @connect    maxis-service-prod-pdx.amazon.com
// ==/UserScript==

(function() {
    'use strict';

    window.onload = function () {
    setTimeout(function () {
var style = document.createElement('style');
  let simBaseUrl = 'https://maxis-service-prod-pdx.amazon.com';
style.innerHTML = '.newDivClass { width:90px;}';
const cssRules = `
.plannedStartDate{
  width:90px;
}

.plannedEndDate{
  width:90px;
}

.actualStartDate{
  width:90px;
}

.actualEndDate{
  width:90px;
}

.status{
  width:90px;
}

.comments{
  contentEditable = true;
  width = '90px';
  overflow = 'hidden';
  border = '1px solid #ccc';
}
.modal-container {
  position: fixed;
  top: 50px;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: flex-start;
  z-index: 1000;
}

.notification-box{
    background-color: #fff;
    color: #fff;
    padding: 20px;
    border-radius: 10px;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
    text-align: center;
    width:400px;
}
`;
style.textContent = cssRules;
document.head.appendChild(style);

//hash map
       const myHashMap = {};
        var editButton = document.getElementsByClassName('btn document-edit-toggle');
editButton[0].click();
        var cancelButton = document.getElementsByClassName('btn btn-large document-edit-toggle');
        cancelButton[0].click();
let bb = document.getElementsByClassName("table table-striped table-condensed");
let cc = bb[0].childNodes[1].childNodes;
var elementarray = Array.from(cc);
elementarray.forEach(function(elem){
    myHashMap[elem.childNodes[0].querySelector('.input-xlarge').value] = elem.cells[1].querySelector('.input-mini').value;
})
for (const element in myHashMap) {
    console.log(element);
   console.log(myHashMap[element]);
}

//Adding all psd ped asd aed status comments in sprint-list task  row.
var c = document.getElementsByClassName("sprint-tasks-header sprint-list-task-row");
const psd = document.createElement('div');
psd.classList.add('plannedStartDate');
psd.textContent = 'psd';
const ped = document.createElement('div');
ped.classList.add('plannedEndDate');
ped.textContent = 'ped';
const asd = document.createElement('div');
asd.classList.add('actualStartDate');
asd.textContent = 'asd';
const aed = document.createElement('div');
aed.classList.add('actualEndDate');
aed.textContent = 'aed';
const status = document.createElement('div');
status.classList.add('status');
status.textContent = 'status';
const comments = document.createElement('div');
comments.classList.add('comments');
comments.textContent = 'comments';


c[0].childNodes[3].insertAdjacentElement('afterend', psd);
c[0].childNodes[4].insertAdjacentElement('afterend', ped);
c[0].childNodes[5].insertAdjacentElement('afterend', asd);
c[0].childNodes[6].insertAdjacentElement('afterend', aed);
c[0].childNodes[7].insertAdjacentElement('afterend', status);
c[0].childNodes[8].insertAdjacentElement('afterend', comments);

        // Find the button element by its class name
const button = document.querySelector('.btn.btn-primary.select2-clickable');

// Add a click event listener to the button
button.addEventListener('click', () => {
  // Delay the reload by one second (1000 milliseconds)
  setTimeout(() => {
    location.reload();
  }, 3000);
});


var columnWidths = ['198px', '50px', '90px', '156px', '90px', '90px', '90px', '90px', '90px', '90px','90px','90px','90px'];
for (var i = 0; i <= 12; i++) {
  if(i === 10)continue;
  c[0].childNodes[i].style.setProperty('width', columnWidths[i], 'important');
  c[0].childNodes[i].style.setProperty('margin-right', '57px', 'important');
}

//Adding scroll bar
var doc = document.getElementsByClassName("document-content");
doc[0].style.overflowX = 'auto'; // or 'auto' for automatic scrollbar when needed
doc[0].style.whiteSpace = 'nowrap';

//Changing container width to 2500px
var elements = document.getElementsByClassName("sprint-tasks-header sprint-list-task-row");
elements[0].style.width='2500px'

//Adding tool tip and width to task titles
var a = document.getElementsByClassName("sprint-task ");
var elementArray = Array.from(a);
elementArray.forEach(function(elem){
   elem.childNodes[3].childNodes[0].style.width = '198px';
    elem.childNodes[3].childNodes[0].overflowX = 'auto';
    elem.childNodes[3].childNodes[0].whiteSpace = 'nowrap';
})
//Adding textbox div's for all tasks
var elementsArray = Array.from(a);

elementsArray.forEach(function(elem) {
 //psd
  const textField = document.createElement('input');
  textField.type = 'text';
  textField.style.width = '60px';
 const psd = document.createElement('div');
  psd.classList.add('plannedStartDate');
  psd.appendChild(textField);
  elem.childNodes[3].childNodes[3].insertAdjacentElement('afterend', psd);

//ped
 const textField2 = document.createElement('input');
  textField2.type = 'text';
 textField2.style.width = '60px';
 const ped = document.createElement('div');
  ped.classList.add('plannedEndDate');
  ped.appendChild(textField2);
    elem.childNodes[3].childNodes[4].insertAdjacentElement('afterend', ped);

  //asd
 const textField3 = document.createElement('input');
  textField3.type = 'text';
 textField3.style.width = '60px';
 const asd = document.createElement('div');
    asd.classList.add('actualStartDate');
  asd.appendChild(textField3);

elem.childNodes[3].childNodes[5].insertAdjacentElement('afterend', asd);

//aed
 const textField4 = document.createElement('input');
  textField4.type = 'text';
 textField4.style.width = '60px';
 const aed = document.createElement('div');
  aed.classList.add('actualEndDate');
  aed.appendChild(textField4);

   elem.childNodes[3].childNodes[6].insertAdjacentElement('afterend', aed);

 //status
 /* const label = document.createElement('label');
 label.style.width = '60px';*/
 const status = document.createElement('div');
  status.classList.add('status');
  //status.appendChild(label);

 elem.childNodes[3].childNodes[7].insertAdjacentElement('afterend', status);
//comments
 const comments = document.createElement('div');
  comments.contentEditable = true;
  comments.style.width = '90px';
  comments.style.overflow = 'hidden';
  comments.style.border = '1px solid #ccc';

  // Set the tooltip to show the content when it overflows
  comments.addEventListener('mouseover', function() {
    if (comments.scrollWidth > comments.clientWidth) {
      comments.title = comments.textContent;
    } else {
      comments.removeAttribute('title');
    }
  });
    comments.addEventListener('keydown', function(event) {
  if (event.key === 'Enter') {
    event.preventDefault(); // Prevent the default Enter behavior
  }
});

 comments.addEventListener('paste', function(event) {
  event.preventDefault(); // Prevent the default paste behavior
  const clipboardData = event.clipboardData || window.clipboardData;
  const pastedText = clipboardData.getData('text/plain');
  document.execCommand('insertText', false, pastedText.replace(/\n/g, ' '));
});

  elem.childNodes[3].childNodes[8].insertAdjacentElement('afterend', comments);

});

//after adding all elements setting up widths
elementArray.forEach(function(elem){
 for (var i = 1; i <= 12; i++) {
  if(i === 10)continue;
   elem.childNodes[3].childNodes[i].style.setProperty('width', columnWidths[i], 'important');
  elem.childNodes[3].childNodes[i].style.setProperty('margin-right', '57px', 'important');
}
    elem.childNodes[3].childNodes[0].style.setProperty('margin-right','57px','important');
})


             //picking dates in custom field
async function getCustomFields(issueId) {
    return new Promise((resolve, reject) => {
        let customFieldId = "planned_start_date_of_input_queue";
        let customFieldUrl = `${simBaseUrl}/issues/${issueId}?q=${customFieldId}`;
        GM.xmlHttpRequest({
            url: customFieldUrl,
            method: "GET",
            headers: {
                "credentials": "include",
                "redirect": "follow",
            },
            onload: resp => {
                if (resp.status === 200) {
                    // Parse the response text to extract the custom field value
                    let responseData = JSON.parse(resp.responseText);
                    console.log("response"+issueId);
                    if(responseData.customFields)
                    {
                    let customFieldValue = responseData.customFields.date.find(field => field.id === customFieldId);
                    let value = customFieldValue.value;
                    console.log(value);
                    let date = new Date(value);
                    let year = date.getUTCFullYear();
                    let month = date.getUTCMonth() + 1; // Adding 1 to the month
                    let day = date.getUTCDate()+1;
                    let formattedDate = `${month.toString().padStart(2, '0')}/${day.toString().padStart(2, '0')}/${year}`;
                    console.log(issueId+""+formattedDate);
                    // Resolve the promise with the formatted date
                    resolve(formattedDate);
                    }
                    else
                    {
                      resolve("");
                    }
                } else {
                    // Reject the promise with an error message
                    reject(new Error("Failed to fetch custom field value."));
                }
            },
            onerror: error => {
                // Reject the promise with the error object
                reject(error);
            }
        });
    });
}

        //saving dates
function saveDates(issueId,istStartDate,istEndDate){
    let dateUrl = `${simBaseUrl}/issues/${issueId}`;
    //console.log("in save dates and: "+ stringId+" "+istDate);
    //const istDate = new Date('09/11/2023');
    const utcDate = new Date(istStartDate.getTime() - istStartDate.getTimezoneOffset() * 60000);
    const utcStartDate = utcDate.toISOString();
    const utcEndDate = new Date(istEndDate.getTime() - istEndDate.getTimezoneOffset() * 60000).toISOString();
   // console.log(utcDateString);
   var postData = {
    "pathEdits": [
        {
            "path": "/schedule",
            "editAction": "PUT",
           "data": {
          "estimatedStartDate": utcStartDate,
          "estimatedCompletionDate": utcEndDate
        }
        }
    ]
};

 GM.xmlHttpRequest({
    url: `${dateUrl}/edits`,
    method: "POST",
     data: JSON.stringify(postData),
    headers: {
          "Content-Type": "application/json",
        "credentials": "include",
        "redirect": "follow",
    },
    onload: resp => {
        if (resp.status === 200 || resp.status === 201) {
            let responseData = JSON.parse(resp.responseText);
            console.log(responseData);
        } else {
            console.error("Failed to put dates.");
        }
    },
    onerror: error => {
        console.error("Error occurred while posting value.", error);
    }

});
}

 
elementArray.forEach(function(elem){
        var urlLink = elem.childNodes[3].childNodes[0].childNodes[7].href;
       var parts = urlLink.split('/');
      var uniqueID = parts[parts.length - 1];
  //   if(elem.childNodes[3].childNodes[4].querySelector('input').value != '')
      getCustomFields(uniqueID)
    .then(formattedDate => {
          if(formattedDate == ""){
              console.log("no custom fields and formatted date empty");
                generateNotification(uniqueID,elem);
              console.log("after generating notification");

             /*  getCustomFields(uniqueID).then(formattedDate =>{
                    console.log("formatted date for newly created story :"+ formattedDate +"end.");
                    elem.childNodes[3].childNodes[4].querySelector('input').value = formattedDate;
                    elem.childNodes[3].childNodes[4].querySelector('input').readOnly = true;
                        })*/
          }
          else{
              elem.childNodes[3].childNodes[4].querySelector('input').value = formattedDate;
               elem.childNodes[3].childNodes[4].querySelector('input').readOnly = true;
          }

      })

});

//notification

function generateNotification(uniqueID,elem){
 var x = document.getElementsByClassName('unstyled sprint-tasks');
        const styleElement = document.createElement('style');
document.head.appendChild(styleElement);

// Create a modal container
const modalContainer = document.createElement('div');


styleElement.textContent = cssRules;
modalContainer.classList.add('modal-container');
// Create the notification box
const notificationBox = document.createElement('div');
//notificationBox.style.backgroundColor = '#3498db'; // Background color
notificationBox.classList.add('notification-box');
// Create the close button (X)
const closeButton = document.createElement('span');
closeButton.textContent = 'X';
closeButton.style.position = 'absolute';
closeButton.style.top = '10px';
closeButton.style.right = '10px';
closeButton.style.cursor = 'pointer';
closeButton.addEventListener('click', () => {
  // Check if all date fields are filled before closing
  const dateInputs = [projectStartDateInput, projectEndDateInput, stageStartDateInput, stageEndDateInput];
  const allDatesEntered = dateInputs.every(input => input.value);

  if (allDatesEntered) {
    modalContainer.style.display = 'none'; // Close the pop-up

  } else {
    alert('Please enter all dates before closing the notification.');
  }
});

// Create the notification message
const notificationMessage = document.createElement('p');
notificationMessage.textContent = 'Please enter the following dates!';
notificationMessage.style.color = '#333';
// Create date inputs with datepicker
const projectStartDateInput = createDateInput('Planned Start Date for Project: ');
const projectEndDateInput = createDateInput('Planned End Date for Project: ');
const stageStartDateInput = createDateInput('Planned Start Date for 1st Stage: ');
const stageEndDateInput = createDateInput('Planned End Date for 1st Stage: ');
const enterDatesLink = document.createElement('a');
enterDatesLink.textContent = 'Enter dates for all stages';
enterDatesLink.style.cursor = 'pointer';
enterDatesLink.addEventListener('click', () => {
  generateNewNotification(); // Call the function to generate a new notification
});


function createDateInput(labelText) {
  const container = document.createElement('div');
  container.className = 'input-append';
  const label = document.createElement('span');
  label.innerHTML = labelText;
  label.style.fontSize = '12px';
  label.style.color = '#333';
  const input = document.createElement('input');
  input.className = 'input-small datepicker';
  input.setAttribute('data-date-field', 'estimatedStartDate');
  input.setAttribute('data-link', 'issueDates^estimatedStartDate');
  input.setAttribute('placeholder', 'MM/DD/YYYY');
  input.setAttribute('type', 'text');
  const addOn = document.createElement('span');
  addOn.className = 'add-on';
  const calendarIcon = document.createElement('i');
  calendarIcon.className = 'icon-calendar';
  addOn.appendChild(calendarIcon);
  container.appendChild(label);
  container.appendChild(input);
  container.appendChild(addOn);
  return container;
}

// Create a submit button
const submitButton = document.createElement('button');
submitButton.textContent = 'Submit';
submitButton.style.backgroundColor = '#fff'; // Button background color
submitButton.style.color = '#333'; // Button text color
submitButton.addEventListener('click', () => {
  // Check if all date fields are filled before closing
  const dateInputs = [projectStartDateInput, projectEndDateInput, stageStartDateInput, stageEndDateInput];
  const allDatesEntered = dateInputs.every(input => input.querySelector('input').value);


   const projectStartDateValue = projectStartDateInput.querySelector('input').value;
  const projectEndDateValue = projectEndDateInput.querySelector('input').value;
  const stageStartDateValue = stageStartDateInput.querySelector('input').value;
  const stageEndDateValue = stageEndDateInput.querySelector('input').value;



  if (allDatesEntered) {
    modalContainer.style.display = 'none'; // Close the pop-up

    console.log('Project Start Date:', projectStartDateValue);
    console.log('Project End Date:', projectEndDateValue);
    console.log('1st Stage Start Date:', stageStartDateValue);
    console.log('1st Stage End Date:', stageEndDateValue);
 
        const currentDate = new Date();

        // Create a status label element
        const statusLabel = document.createElement('span');
       // statusLabel.classList.add('label');
        const stageEndDatex = new Date(stageEndDateValue);
        // Set the background color based on your conditions
        if (currentDate > stageEndDatex) {
            statusLabel.style.backgroundColor = '#ff0000'; // Red background color
            statusLabel.title = 'Overdue'; // Tooltip text for the status
            statusLabel.style.width = '15px';
          statusLabel.style.display = 'inline-block';
           statusLabel.innerHTML= '&nbsp';
            statusLabel.style.marginRight = '5px'
                        statusLabel.marginTop = '8px';
           a[0].childNodes[3].childNodes[8].appendChild(statusLabel);
            const statusDropdown = document.createElement('select');
  statusDropdown.style.width = '60px';

            const placeholderOption = document.createElement('option');
placeholderOption.value = ''; // Set an empty value
placeholderOption.textContent = ''; // Set empty text

  // Create option elements for the dropdown
  const redOption = document.createElement('option');
  redOption.value = 'red';
  redOption.textContent = 'Red';

  const greenOption = document.createElement('option');
  greenOption.value = 'green';
  greenOption.textContent = 'Green';

  const yellowOption = document.createElement('option');
  yellowOption.value = 'yellow';
  yellowOption.textContent = 'Yellow';

            statusDropdown.appendChild(placeholderOption);

  // Append option elements to the dropdown
  statusDropdown.appendChild(redOption);
  statusDropdown.appendChild(greenOption);
  statusDropdown.appendChild(yellowOption);
            statusDropdown.style.marginTop = '8px';
            statusDropdown.style.height = '20px';
            a[0].childNodes[3].childNodes[8].appendChild(statusDropdown);
        }
      const istDate = new Date(stageStartDateValue);

// Convert to UTC
const utcDate = new Date(istDate.getTime() - istDate.getTimezoneOffset() * 60000);

// Format the UTC date as an ISO string
const utcDateString = utcDate.toISOString();

// Now, you can use utcDateString in your postData
var postData = {
    "pathEdits": [
        {
            "path": "/customFields/date/planned_start_date_of_input_queue",
            "editAction": "PUT",
            "data": { "id": "planned_start_date_of_input_queue", "value": utcDateString }
        }
    ]
};
 GM.xmlHttpRequest({
    url: simBaseUrl + `/issues/${uniqueID}/edits`,
    method: "POST",
    data: JSON.stringify(postData),
    headers: {
        "Content-Type": "application/json",
        "credentials": "include",
        "redirect": "follow",
    },
    onload: resp => {
        if (resp.status === 200) {
            // Parse the response text to extract the custom field value
             console.log(resp);
        } else {
            console.error("Failed to post custom field value.");
        }
    },
    onerror: error => {
        console.error("Error occurred while fetching custom field value.", error);
    }
});
elem.childNodes[3].childNodes[4].querySelector('input').value = stageStartDateValue;
elem.childNodes[3].childNodes[4].querySelector('input').readOnly = true;


   const date1 = new Date(projectStartDateValue);
const date2 = new Date(projectEndDateValue);

 saveDates(uniqueID, date1, date2);
 

  } else {
    alert('Please enter all dates before closing the notification.');
  }
});




function generateNewNotification() {
  const newModalContainer = document.createElement('div');
  newModalContainer.classList.add('modal-container');

  // Create the new notification box
  const newNotificationBox = document.createElement('div');
  newNotificationBox.classList.add('notification-box');
  newNotificationBox.style.width = '1000px';

  // Create the close button (X) for the new notification
  const newCloseButton = document.createElement('span');
  newCloseButton.textContent = 'X';
  newCloseButton.style.position = 'absolute';
  newCloseButton.style.top = '10px';
  newCloseButton.style.right = '10px';
  newCloseButton.style.cursor = 'pointer';
  newCloseButton.addEventListener('click', () => {
    // Close the new notification when the close button is clicked
    newModalContainer.style.display = 'none';
  });

  // Create a container to hold all the stage dates
  const stageDatesContainer = document.createElement('div');
  stageDatesContainer.style.display = 'flex';
  stageDatesContainer.style.flexWrap = 'wrap';

  // Create fields for each stage's "Planned Start Date" and "Planned End Date"
  const stages = ['IQ', 'I', 'CR', 'DC', 'D'];

  // Create fields for each stage's "Planned Start Date" and "Planned End Date"
  stages.forEach((stage) => {
    // Create a container for each stage's dates
    const stageContainer = document.createElement('div');
    stageContainer.style.display = 'flex';
    stageContainer.style.flexDirection = 'row';
    stageContainer.style.marginBottom = '10px';

    // Label for "Planned Start Date"
    const plannedStartDateLabel = document.createElement('label');
    plannedStartDateLabel.textContent = `Planned Start Date of ${stage}:`;
    plannedStartDateLabel.style.marginRight = '10px';

    // Input for "Planned Start Date"
    const plannedStartDateInput = document.createElement('input');
    plannedStartDateInput.type = 'text';
    plannedStartDateInput.placeholder = 'MM/DD/YYYY'; // You can set the desired placeholder text

    // Create "Add-On" for the planned start date input
    const plannedStartDateAddOn = document.createElement('span');
    plannedStartDateAddOn.className = 'add-on';
    const plannedStartDateCalendarIcon = document.createElement('i');
    plannedStartDateCalendarIcon.className = 'icon-calendar';
    plannedStartDateAddOn.appendChild(plannedStartDateCalendarIcon);

    // Label for "Planned End Date"
    const plannedEndDateLabel = document.createElement('label');
    plannedEndDateLabel.textContent = `Planned End Date of ${stage}:`;
    plannedEndDateLabel.style.marginLeft = '20px';
    plannedEndDateLabel.style.marginRight = '10px';

    // Input for "Planned End Date"
    const plannedEndDateInput = document.createElement('input');
    plannedEndDateInput.type = 'text';
    plannedEndDateInput.placeholder = 'MM/DD/YYYY'; // You can set the desired placeholder text

    // Create "Add-On" for the planned end date input
    const plannedEndDateAddOn = document.createElement('span');
    plannedEndDateAddOn.className = 'add-on';
    const plannedEndDateCalendarIcon = document.createElement('i');
    plannedEndDateCalendarIcon.className = 'icon-calendar';
    plannedEndDateAddOn.appendChild(plannedEndDateCalendarIcon);

    // Append elements to the stage container
    stageContainer.appendChild(plannedStartDateLabel);
    stageContainer.appendChild(plannedStartDateInput);
    stageContainer.appendChild(plannedStartDateAddOn);

    stageContainer.appendChild(plannedEndDateLabel);
    stageContainer.appendChild(plannedEndDateInput);
    stageContainer.appendChild(plannedEndDateAddOn);

    // Append the stage container to the stage dates container
    stageDatesContainer.appendChild(stageContainer);
  });

  // Create a submit button for the new notification
  const newSubmitButton = document.createElement('button');
  newSubmitButton.textContent = 'Submit';
  newSubmitButton.addEventListener('click', () => {
    // Handle the submission of the new notification here
    // You can retrieve the values of the date inputs as needed
  });

  // Append elements to the new notification box
  newNotificationBox.appendChild(newCloseButton);
  newNotificationBox.appendChild(stageDatesContainer);
  newNotificationBox.appendChild(newSubmitButton);

  // Append the new notification box to the new modal container
  newModalContainer.appendChild(newNotificationBox);

  // Append the new modal container to the document body
  document.body.appendChild(newModalContainer);
}


// Append elements to the notification box
notificationBox.appendChild(closeButton);
notificationBox.appendChild(notificationMessage);
notificationBox.appendChild(projectStartDateInput);
notificationBox.appendChild(projectEndDateInput);
notificationBox.appendChild(stageStartDateInput);
notificationBox.appendChild(stageEndDateInput);
notificationBox.appendChild(enterDatesLink);
notificationBox.appendChild(document.createElement('br'));
notificationBox.appendChild(document.createElement('br'));
notificationBox.appendChild(submitButton);
// Append the link container to the notification box


// Append the notification box to the modal container
modalContainer.appendChild(notificationBox);

// Append the modal container to the document body
document.body.appendChild(modalContainer);
}
    }, 4000); // Adjust the delay time as needed (in milliseconds)
};



})();
Editor is loading...