Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adds percent complete and cleans up some of the state behavior #80

Merged
merged 1 commit into from
Jul 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion pages/index.html.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ module.exports = function (env) {
>by <img src="./images/bitovi-logo.png" class="inline align-baseline"/></a>
</li>
</ul>
<velocities-from-issue></velocities-from-issue>
<select-cloud></select-cloud>
<saved-urls></saved-urls>
<div id="login">
Expand All @@ -57,7 +58,7 @@ module.exports = function (env) {
</div>

<script type="module">
import main from "./dist/main.js";
import main from "./dev/main.js";
main( ${JSON.stringify(getSafeEnv())} );
</script>

Expand Down
6 changes: 1 addition & 5 deletions public/css/steerco-reporting.css
Original file line number Diff line number Diff line change
Expand Up @@ -207,11 +207,7 @@ simple-tooltip span {
border: 1px solid black;
}

.release_wrapper {
display: flex;
flex-flow: row;
gap: 16px;
}



.release_wrapper .release_box .release_box_header_bubble {
Expand Down
500 changes: 250 additions & 250 deletions public/dist/main.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion public/dist/main.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion public/dist/production.css

Large diffs are not rendered by default.

126 changes: 112 additions & 14 deletions public/gantt-grid.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// https://yumbrands.atlassian.net/issues/?filter=10897
import { StacheElement, type, ObservableObject, stache } from "./can.js";
import { showTooltip } from "./issue-tooltip.js";
import { showTooltip, showTooltipContent } from "./issue-tooltip.js";
import { percentComplete } from "./percent-complete/percent-complete.js";
/*
import { getCalendarHtml, getQuarter, getQuartersAndMonths } from "./quarter-timeline.js";
import { howMuchHasDueDateMovedForwardChangedSince, DAY_IN_MS } from "./date-helpers.js";
Expand All @@ -17,51 +18,148 @@ import SimpleTooltip from "./shared/simple-tooltip.js";
const TOOLTIP = new SimpleTooltip();
document.body.append(TOOLTIP);*/


const percentCompleteTooltip = stache(`
<button class="remove-button">❌</button>
<div class="grid gap-2" style="grid-template-columns: auto repeat(4, auto);">

<div class="font-bold">Summary</div>
<div class="font-bold">Percent Complete</div>
<div class="font-bold">Completed Working Days</div>
<div class="font-bold">Remaining Working Days</div>
<div class="font-bold">Total Working Days</div>

<div class="truncate max-w-96">{{this.issue.Summary}}</div>
<div class="text-right">{{this.getPercentComplete(this.issue)}}</div>
<div class="text-right">{{this.round( this.issue.completionRollup.completedWorkingDays) }}</div>
<div class="text-right">{{this.round(this.issue.completionRollup.remainingWorkingDays)}}</div>
<div class="text-right">{{this.round(this.issue.completionRollup.totalWorkingDays)}}</div>

{{# for(child of this.children) }}

<div class="pl-4 truncate max-w-96"><a href="{{child.url}}" class="link">{{child.summary}}</a></div>
<div class="text-right">{{this.getPercentComplete(child)}}</div>
<div class="text-right">{{this.round(child.completionRollup.completedWorkingDays)}}</div>
<div class="text-right">{{this.round(child.completionRollup.remainingWorkingDays)}}</div>
<div class="text-right">{{this.round(child.completionRollup.totalWorkingDays)}}</div>

{{/ for }}
</div>
`)

import { rollupDatesFromRollups } from "./prepare-issues/date-data.js";
import { getQuartersAndMonths } from "./quarter-timeline.js";
// loops through and creates
export class GanttGrid extends StacheElement {
static view = `
<div style="display: grid; grid-template-columns: auto repeat({{this.quartersAndMonths.months.length}}, [col] 1fr); grid-template-rows: repeat({{this.issues.length}}, auto)"
<div style="display: grid; grid-template-columns: auto auto repeat({{this.quartersAndMonths.months.length}}, [col] 1fr); grid-template-rows: repeat({{this.issues.length}}, auto)"
class='p-2 mb-10'>
<div></div>
<div></div><div></div>

{{# for(quarter of this.quartersAndMonths.quarters) }}
<div style="grid-column: span 3" class="text-center">{{quarter.name}}</div>
{{ / for }}

<div></div>
<div></div><div></div>
{{# for(month of this.quartersAndMonths.months)}}
<div class='border-b border-neutral-80 text-center'>{{month.name}}</div>
{{/ for }}

<!-- CURRENT TIME BOX -->
<div style="grid-column: 2 / span {{this.quartersAndMonths.months.length}}; grid-row: 3 / span {{this.issues.length}};">
<div style="grid-column: 3 / span {{this.quartersAndMonths.months.length}}; grid-row: 3 / span {{this.issues.length}};">
<div class='today' style="margin-left: {{this.todayMarginLeft}}%; width: 1px; background-color: orange; z-index: 1000; position: relative; height: 100%;"></div>
</div>


<!-- VERTICAL COLUMNS -->
{{# for(month of this.quartersAndMonths.months)}}
<div style="grid-column: {{ plus(scope.index, 2) }}; grid-row: 3 / span {{this.issues.length}}; z-index: 10"
<div style="grid-column: {{ plus(scope.index, 3) }}; grid-row: 3 / span {{this.issues.length}}; z-index: 10"
class='border-l border-b border-neutral-80 {{this.lastRowBorder(scope.index)}}'></div>
{{/ for }}

<!-- Each of the issues -->
{{# for(issue of this.issues) }}
{{# for(issue of this.issuesWithPercentComplete) }}
<div on:click='this.showTooltip(scope.event, issue)'
class='pointer p-1 color-text-and-bg-{{issue.dateData.rollup.status}} border-y-solid-1px-white'>
class='pointer border-y-solid-1px-white text-right {{this.classForSpecialStatus(issue.dateData.rollup.status)}} truncate max-w-96 {{this.textSize}}'>
{{issue.Summary}}
</div>
<div style="grid-column: 2" class="{{this.textSize}} text-right pointer"
on:click="this.showPercentCompleteTooltip(scope.event, issue)">{{this.getPercentComplete(issue)}}
</div>
{{ this.getReleaseTimeline(issue, scope.index) }}
{{/ for }}
</div>
`;
static props = {
breakdown: Boolean
breakdown: Boolean,
showPercentComplete: {
get default(){
return !!localStorage.getItem("showPercentComplete")
}
}
};
showTooltip(event, isssue) {
showTooltip(event.currentTarget, isssue);
get percentComplete(){
if(this.derivedIssues) {
return percentComplete(this.derivedIssues);
}
}
get issuesWithPercentComplete(){
if(this.showPercentComplete && this.percentComplete) {
const percentComplete = this.percentComplete;
const idToIssue = {};
for(const issue of percentComplete.issues) {
issue.completionRollup.totalWorkingDays
idToIssue[issue.key] = issue;
}
return this.issues.map( issue => {
return {
...issue,
completionRollup: idToIssue[issue["Issue key"]].completionRollup
}
})
} else {
return this.issues;
}
}
get lotsOfIssues(){
return this.issues.length > 20 && ! this.breakdown;
}
get textSize(){
return this.lotsOfIssues ? "text-xs pt-1 pb-0.5 px-1" : "p-1"
}
get bigBarSize(){
return this.lotsOfIssues ? "h-4" : "h-6"
}
getPercentComplete(issue) {
if(this.showPercentComplete && this.percentComplete) {
return Math.round( issue.completionRollup.completedWorkingDays * 100 / issue.completionRollup.totalWorkingDays )+"%"
} else {
return "";
}
}
showTooltip(event, issue) {
showTooltip(event.currentTarget, issue);
}
showPercentCompleteTooltip(event, issue) {
// we should get all the children ...
const keyToChildren = Object.groupBy(this.percentComplete.issues, i => i.parentKey)
const children = keyToChildren[issue["Issue key"]];

showTooltipContent(event.currentTarget, percentCompleteTooltip(
{ issue,
children,
getPercentComplete: this.getPercentComplete.bind(this),
round: Math.round
}));
}
classForSpecialStatus(status){
if( status === "complete") {
return "color-text-"+status;
} else if(status === "blocked" ) {
return "color-text-"+status;
} else {
return "";
}
}
plus(first, second) {
return first + second;
Expand All @@ -87,7 +185,7 @@ export class GanttGrid extends StacheElement {
}
getReleaseTimeline(release, index){
const base = {
gridColumn: '2 / span '+this.quartersAndMonths.months.length,
gridColumn: '3 / span '+this.quartersAndMonths.months.length,
gridRow: `${index+3}`,
};

Expand Down Expand Up @@ -213,11 +311,11 @@ export class GanttGrid extends StacheElement {
} else {

const behindTime = makeLastPeriodElement(release.dateData.rollup.status, release.dateData.rollup.lastPeriod);
behindTime.classList.add("h-6","py-1")
behindTime.classList.add(this.bigBarSize,"py-1")
lastPeriodRoot.appendChild(behindTime);

const team = document.createElement("div");
team.className = "h-6 border-y-solid-1px-white color-text-and-bg-"+release.dateData.rollup.status;
team.className = this.bigBarSize+" border-y-solid-1px-white color-text-and-bg-"+release.dateData.rollup.status;
Object.assign(team.style, getPositions(release.dateData.rollup).style);
team.style.opacity = "0.9";

Expand Down
22 changes: 12 additions & 10 deletions public/issue-tooltip.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,17 @@ export function wasStartDate(release) {
}
}


export function showTooltipContent(element, content) {

TOOLTIP.belowElementInScrollingContainer(element, content);

TOOLTIP.querySelector(".remove-button").onclick = ()=> {
showingObject = null;
TOOLTIP.leftElement()
}
}

export function showTooltip(element, issue){
console.log(issue);
if(showingObject === issue) {
Expand Down Expand Up @@ -150,16 +161,7 @@ export function showTooltip(element, issue){
</div>`
}





TOOLTIP.belowElementInScrollingContainer(element, DOM);

TOOLTIP.querySelector(".remove-button").onclick = ()=> {
showingObject = null;
TOOLTIP.leftElement()
}
showTooltipContent(element, DOM);

}

Expand Down
30 changes: 9 additions & 21 deletions public/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { TimelineReport } from "./timeline-report.js";

import "./shared/saved-urls.js";
import "./shared/select-cloud.js";
import "./shared/velocities-from-issue.js"

import JiraLogin from "./shared/jira-login.js";
import JiraOIDCHelpers from "./jira-oidc-helpers.js";
Expand All @@ -20,12 +21,19 @@ export default async function main(config) {
const selectCloud = document.querySelector("select-cloud")
selectCloud.loginComponent = loginComponent;
selectCloud.jiraHelpers = jiraHelpers;

const velocitiesConfiguration = document.querySelector("velocities-from-issue")
velocitiesConfiguration.jiraHelpers = jiraHelpers;
velocitiesConfiguration.isLoggedIn = loginComponent.isLoggedIn;
loginComponent.listenTo("isLoggedIn", ({value})=>{
velocitiesConfiguration.isLoggedIn = value;
})

const listener = ({value})=>{
if(value) {
loginComponent.off("isResolved", listener);
mainElement.style.display = "none";
const report = new TimelineReport().initialize({jiraHelpers, loginComponent, mode: "TEAMS"});
const report = new TimelineReport().initialize({jiraHelpers, loginComponent, mode: "TEAMS", velocitiesConfiguration});
report.className = "block"
document.body.append(report);
}
Expand All @@ -34,27 +42,7 @@ export default async function main(config) {
login.appendChild(loginComponent);


/*
mainElement.textContent = "Checking for Jira Access Token";

if (!jiraHelpers.hasValidAccessToken()) {
mainElement.textContent = "Getting access token";
const accessToken = await jiraHelpers.getAccessToken();
return;
}

const accessToken = await jiraHelpers.getAccessToken();

mainElement.textContent = "Got Access Token";
mainElement.style.display = "none";


// SteerCo for KFC
const report = new TimelineReport();
report.jiraHelpers = jiraHelpers;
report.mode = "TEAMS";
document.body.append(report);
report.className = "block"*/


}
Expand Down
20 changes: 6 additions & 14 deletions public/percent-complete/percent-complete.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,9 @@ import { normalizeIssue, derivedWorkIssue, rollupHierarchy } from "../shared/iss
* @param { JiraIssue[] } issues
* @param { PercentCompleteOptions } options
*/
export function percentComplete(issues, options) {
export function percentComplete(derivedWorkIssues) {

const derivedWorkIssues = issues.map( (issue)=>{
const normalized = normalizeIssue(issue);
const derived = derivedWorkIssue(normalized);
return derived;
});

console.log(completionRollup(derivedWorkIssues, {
...options
}));
return completionRollup(derivedWorkIssues);
}

function groupIssuesByHierarchyLevel(issues, options) {
Expand Down Expand Up @@ -72,7 +64,7 @@ function toCompletionRollups(issues){
* @param {*} options
* @returns {{issues: Array<RolledupCompletionIssue>, hierarchyData: Array<IssueTypeData>}}
*/
function completionRollup(allIssueData, options){
function completionRollup(allIssueData){
const completionRollups = toCompletionRollups(allIssueData);

const groupedIssueData = groupIssuesByHierarchyLevel(completionRollups);
Expand Down Expand Up @@ -130,7 +122,7 @@ function completionRollup(allIssueData, options){
// initiatives and above
if( hierarchyLevel > BASE_HIERARCHY_LEVEL ) {
// handle "parent-like" issue
handleInitiative(issueData,{issueTypeData, issueKeyToChildren}, options)
handleInitiative(issueData,{issueTypeData, issueKeyToChildren})
}
}

Expand Down Expand Up @@ -168,7 +160,7 @@ function average(arr){
* @param {*} options
* @returns
*/
function handleInitiative(issueData,{issueTypeData, issueKeyToChildren}, options) {
function handleInitiative(issueData,{issueTypeData, issueKeyToChildren}) {


// Empty
Expand Down Expand Up @@ -263,7 +255,7 @@ function altRollupWorkingDays(issues) {
// initiatives and above
if( hierarchyLevel > BASE_HIERARCHY_LEVEL ) {
// handle "parent-like" issue
handleInitiative(issueData,{issueTypeData, issueKeyToChildren}, options)
handleInitiative(issueData,{issueTypeData, issueKeyToChildren})
}
}
})
Expand Down
Loading
Loading