Untitled
unknown
plain_text
2 years ago
26 kB
6
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= ' ';
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...