-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathindex.html
1 lines (1 loc) · 21.1 KB
/
index.html
1
<html><head><title>RepoSense Report</title><link rel="shortcut icon" type="image/x-icon" href="favicon.ico"/><link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Titillium+Web"/><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/normalize.min.css"/><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/mui.min.css"/><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/styles/color-brewer.min.css"/><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue-loading-spinner.css"/><link rel="stylesheet" href="static/css/style.css"/><script src="https://use.fontawesome.com/releases/v5.0.13/js/all.js"></script><script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script><script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jszip.min.js"></script><script src="https://cdn.jsdelivr.net/gh/highlightjs/[email protected]/build/highlight.min.js"></script><script src="https://cdn.jsdelivr.net/gh/highlightjs/[email protected]/build/languages/asciidoc.min.js"></script><script src="https://cdn.jsdelivr.net/gh/highlightjs/[email protected]/build/languages/gradle.min.js"></script><script src="https://cdn.jsdelivr.net/gh/highlightjs/[email protected]/build/languages/plaintext.min.js"></script><script src="https://cdn.jsdelivr.net/gh/highlightjs/[email protected]/build/languages/scss.min.js"></script><script src="https://cdn.jsdelivr.net/gh/highlightjs/[email protected]/build/languages/yaml.min.js"></script><script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue-loading-spinner.js"></script></head><body><div id="app"><div id="app-wrapper" v-if="userUpdated" onmousemove="mouseMove(event)" onmouseup="deregisterMouseMove()" onmouseleave="deregisterMouseMove()"><div id="tab-resize-guide"></div><div id="summary-wrapper"><div class="summary-status" v-if="loadedRepo<repoLength">Loading repos ... {{ loadedRepo }} / {{ repoLength }}</div><v_summary class="tab-padding" ref="summary" v-bind:repos="users" v-bind:error-messages="errorMessages" v-on:view-zoom="updateTabZoom" v-on:view-authorship="updateTabAuthorship" v-on:get-dates="receiveDates"></v_summary><div class="timestamp-footer"><span>Generated by </span><a v-bind:href="getRepoSenseHomeLink()" target="_blank"><strong>RepoSense</strong></a><span> (</span><a v-bind:href="getRepoSenseVersionLink()" target="_blank"><strong>{{ repoSenseVersion }}</strong></a><span>) on {{ creationDate }}</span></div></div><div id="tabs-wrapper" v-if="isTabActive"><div id="tab-resize" onmousedown="registerMouseMove()"></div><div class="tab-close" v-on:click="deactivateTab"><i class="fas fa-caret-right"></i></div><div class="tab-content tab-padding"><div class="tab-panes"><v_authorship class="tab-pane" id="tab-authorship" v-if="tabType === 'authorship'" v-bind:key="generateKey(tabInfo.tabAuthorship)" v-bind:info="tabInfo.tabAuthorship"></v_authorship><v_zoom class="tab-pane" id="tab-zoom" v-else-if="tabType === 'zoom'" v-bind:key="generateKey(tabInfo.tabZoom)" v-bind:info="tabInfo.tabZoom" v-on:view-summary="updateSummaryDates"></v_zoom><div class="tab-pane" id="tab-empty" v-else="v-else"><div class="title"><span>To view the code attributed to a specific author, click the </span><i class="fas fa-code"></i><span> icon next to that author's name.</span><br/><span>To hide the code view, click the </span><i class="fas fa-caret-right"></i><span> icon on the left.</span></div></div></div></div></div></div><template v-else="v-else"><div class="empty">Please upload a .zip file generated by RepoSense.</div><form id="file-upload" onsubmit="return false;"><input type="file" accept=".zip" v-on:change="updateReportZip"/><div class="loader" v-if="isLoading"><circle-spinner></circle-spinner><div class="loading">Loading resources...</div></div></form></template></div><vuetemplate id="v_summary"><div class="wrapper" id="summary"><form class="summary-picker mui-form--inline" onsubmit="return false;"><div class="summary-picker__section"><div class="mui-textfield"><input class="summary-picker__search" type="text" v-on:change="updateFilterSearch" v-model="filterSearch"/><label>search</label></div><div class="mui-select grouping"><select v-model="filterGroupSelection"><option value="groupByNone">None</option><option value="groupByRepos">Repo/Branch</option><option value="groupByAuthors">Author</option></select><label>group by</label></div><div class="mui-select sort-group"><select v-model="sortGroupSelection"><option value="groupTitle">↑ group title</option><option value="groupTitle dsc">↓ group title</option><option value="totalCommits">↑ contribution</option><option value="totalCommits dsc">↓ contribution</option><option value="variance">↑ variance</option><option value="variance dsc">↓ variance</option></select><label>sort groups by</label></div><div class="mui-select sort-within-group"><select v-model="sortWithinGroupSelection" v-bind:disabled="filterGroupSelection === 'groupByNone' || isMergeGroup"><option value="title">↑ title</option><option value="title dsc">↓ title</option><option value="totalCommits">↑ contribution</option><option value="totalCommits dsc">↓ contribution</option><option value="variance">↑ variance</option><option value="variance dsc">↓ variance</option></select><label>sort within groups by</label></div><div class="mui-select"><select v-model="filterTimeFrame"><option value="commit">Commit</option><option value="day">Day</option><option value="week">Week</option></select><label>granularity</label></div><div class="mui-textfield summary-picker__date"><input v-if="isSafariBrowser" type="text" placeholder="yyyy-mm-dd" v-bind:value="filterSinceDate" v-on:keyup.enter="updateTmpFilterSinceDate" onkeydown="formatInputDateOnKeyDown(event)" oninput="appendDashInputDate(event)" maxlength="10"/><input v-else="v-else" type="date" v-bind:value="filterSinceDate" v-on:input="updateTmpFilterSinceDate" onkeydown="return false" v-bind:min="minDate" v-bind:max="filterUntilDate"/><label>since</label></div><div class="mui-textfield summary-picker__date"><input v-if="isSafariBrowser" type="text" placeholder="yyyy-mm-dd" v-bind:value="filterUntilDate" v-on:keyup.enter="updateTmpFilterUntilDate" onkeydown="formatInputDateOnKeyDown(event)" oninput="appendDashInputDate(event)" maxlength="10"/><input v-else="v-else" type="date" v-bind:value="filterUntilDate" v-on:input="updateTmpFilterUntilDate" onkeydown="return false" v-bind:min="filterSinceDate" v-bind:max="maxDate"/><label>until</label></div><div class="mui-textfield summary-picker__date"><a v-on:click="resetDateRange">Reset date range</a></div><div class="summary-picker__checkboxes summary-picker__section"><label><input class="mui-checkbox summary-picker__checkbox" type="checkbox" v-model="filterBreakdown" v-on:change="setSummaryHash()"/><span>breakdown by file type</span></label><label class="merge-group" v-bind:style="filterGroupSelection === 'groupByNone' ? { opacity:0.5 } : { opacity:1.0 }"><input class="mui-checkbox summary-picker__checkbox" type="checkbox" v-model="isMergeGroup" v-bind:disabled="filterGroupSelection === 'groupByNone'"/><span>merge group</span></label></div></div></form><div class="error-message-box" v-if="Object.entries(errorMessages).length"><div class="error-message-box__close-button" onclick="dismissTab(this)">×</div><div class="error-message-box__message">The following issues occurred when analyzing the following repositories:</div><div class="error-message-box__failed-repo" v-for="errorBlock in errorMessages"><i class="fas fa-exclamation mini-font"></i><span class="error-message-box__failed-repo--name">{{ errorBlock.repoName }}</span><div class="error-message-box__failed-repo--reason" v-if="errorBlock.errorMessage.startsWith('Unexpected error stack trace')"><span>Oops, an unexpected error occurred. If you think this is due to a problem in RepoSense, please report in </span><a v-bind:href="getReportIssueGitHubLink(errorBlock.errorMessage)" target="_blank"><strong>our issue tracker </strong></a><span>or email us at </span><a v-bind:href="getReportIssueEmailLink(errorBlock.errorMessage)"><span>{{ getReportIssueEmailAddress() }}</span></a></div><div class="error-message-box__failed-repo--reason" v-else="v-else">{{ errorBlock.errorMessage }}</div></div></div><div id="summary-charts"><div class="summary-charts" v-for="(repo, i) in filteredRepos"><div class="summary-charts__title" v-if="filterGroupSelection === 'groupByRepos'"><div class="summary-charts__title--index">{{ i+1 }}</div><div class="summary-charts__title--repo">{{ repo[0].repoName }}</div><div class="summary-charts__title--contribution mini-font" title="Total contribution of group">[{{ getGroupTotalContribution(repo) }} lines]</div></div><div class="summary-charts__title" v-if="filterGroupSelection === 'groupByAuthors'" v-bind:class="{ warn: repo[0].name === '-' }"><div class="summary-charts__title--index">{{ i+1 }}</div><div class="summary-charts__title--repo">{{ repo[0].displayName }} ({{ repo[0].name }})</div><div class="summary-charts__title--contribution mini-font" title="Total contribution of group">[{{ getGroupTotalContribution(repo) }} lines]</div></div><div class="summary-charts__fileType--breakdown" v-if="filterBreakdown"><template v-if="filterGroupSelection === 'groupByRepos'"><div class="summary-charts__fileType--breakdown__legend" v-for="fileType in getFileTypes(repo)"><i class="fas fa-circle" v-bind:style="{ 'color' : contributionBarFileTypeColors[fileType] }"></i><span> {{ fileType }} </span></div></template><template v-else="v-else"><div class="summary-charts__fileType--breakdown__legend" v-for="fileType in Object.keys(contributionBarFileTypeColors)"><i class="fas fa-circle" v-bind:style="{ 'color' : contributionBarFileTypeColors[fileType] }"></i><span> {{ fileType }} </span></div></template></div><div class="summary-chart" v-for="(user, i) in repo"><div class="summary-chart__title" v-if="!isMergeGroup"><div class="summary-chart__title--index">{{ i+1 }}</div><div class="summary-chart__title--repo" v-if="filterGroupSelection === 'groupByNone'">{{ user.repoName }}</div><div class="summary-chart__title--author-repo" v-if="filterGroupSelection === 'groupByAuthors'">{{ user.repoName }}</div><div class="summary-chart__title--name" v-if="filterGroupSelection !== 'groupByAuthors'" v-bind:class="{ warn: user.name === '-' }">{{ user.displayName }} ({{ user.name }})</div><div class="summary-chart__title--contribution mini-font">[{{ user.totalCommits }} lines]</div><a title="click to view author's code" onclick="deactivateAllOverlays()" v-on:click="openTabAuthorship(user, repo, i)"><i class="summary-chart__title--button fas fa-code"></i></a><a v-bind:href="getRepoLink(repo[i])" target="_blank" title="click to view author's repo"><i class="summary-chart__title--button fab fa-github"></i></a><a title="click to view breakdown of commits" onclick="deactivateAllOverlays()" v-on:click="openTabZoom(user, filterSinceDate, filterUntilDate)"><i class="summary-chart__title--button fas fa-list-ul"></i></a></div><div class="summary-chart__ramp" onclick="viewClick(event)" v-on:click="openTabZoomSubrange(user)"><v_ramp v-bind:groupby="filterGroupSelection" v-bind:user="user" v-bind:tframe="filterTimeFrame" v-bind:sdate="filterSinceDate" v-bind:udate="filterUntilDate" v-bind:avgsize="avgCommitSize" v-bind:mergegroup="isMergeGroup"></v_ramp><div class="overlay"></div></div><div class="summary-chart__contribution"><template v-if="filterBreakdown"><div class="summary-chart__contrib" v-for="(widths, fileType) in getFileTypeContributionBars(user.fileTypeContribution)"><div class="summary-chart__contrib--bar--fileType" v-for="width in widths" v-bind:style="{ width: width + '%', 'background-color': contributionBarFileTypeColors[fileType] }" v-bind:title="fileType + ': ' + user.fileTypeContribution[fileType] + ' lines, ' + 'total: ' + user.totalCommits + ' lines ' + '(contribution from ' + minDate + ' to ' + maxDate + ')'"></div></div></template><template v-else="v-else"><div class="summary-chart__contrib" v-bind:title="'Total contribution from ' + minDate + ' to ' + maxDate + ': ' + user.totalCommits + ' lines'"><div class="summary-chart__contrib--bar" v-for="width in getContributionBars(user.totalCommits)" v-bind:style="{ width: width+'%' }"></div></div></template></div></div></div></div></div></vuetemplate><vuetemplate id="v_ramp"><div class="ramp"><template v-if="tframe === 'commit'"><template v-for="(slice, j) in user.commits"><a class="ramp__slice" draggable="false" onclick="rampClick(event);" v-for="(commit, k) in slice.commitResults" v-if="commit.insertions>0" v-bind:href="getLink(user, commit)" target="_blank" v-bind:title="`[${slice.date}] ${commit.messageTitle}: ${commit.insertions} lines`" v-bind:class="'ramp__slice--color' + getSliceColor(slice.date)" v-bind:style="{ zIndex: user.commits.length - j, borderLeftWidth: getWidth(commit) + 'em', right: ((getSlicePos(slice.date) + (getCommitPos(k, slice.commitResults.length))) * 100) + '%' }"></a></template></template><template v-else="v-else"><a class="ramp__slice" draggable="false" onclick="rampClick(event);" v-for="(slice, j) in user.commits" v-if="slice.insertions > 0" v-bind:title="`${tframe === 'day' ? '[' + slice.date + '] Daily' : '[' + slice.date + ' till ' + slice.endDate + '] Weekly'} contribution: ${slice.insertions} lines`" v-bind:href="getLink(user, slice)" target="_blank" v-bind:class="'ramp__slice--color' + getSliceColor(slice.date)" v-bind:style="[ { zIndex: user.commits.length - j, borderLeftWidth: getWidth(slice) + 'em', right: (getSlicePos(tframe === 'day' ? slice.date : slice.endDate) * 100) + '%' }, /* disallow clickable ramp slices when merging groups that are grouped by authors as unable to form a url that navigates to different repositories of the same author */ mergegroup && groupby === 'groupByAuthors' ? { cursor: 'auto', pointerEvents: 'none' } : { cursor: 'pointer', pointerEvents: 'auto' } ]"></a></template></div></vuetemplate><vuetemplate id="v_zoom"><div id="zoom"><div class="zoom__title"><div class="zoom_title--group large-font"><span v-if="info.filterGroupSelection === 'groupByAuthors'">{{ info.user.displayName }} ({{ info.user.name }})</span><span v-else="v-else">{{ info.user.repoName }}</span></div><div class="zoom__title--chart medium-font" v-if="!info.isMergeGroup"><span>↳ </span><span v-if="info.filterGroupSelection === 'groupByAuthors'">{{ info.user.repoName }}</span><span v-else="v-else">{{ info.user.displayName }} ({{ info.user.name }})</span></div><div class="zoom__title--period medium-font"><span>↳ </span><span>{{ info.sinceDate }} to {{ info.untilDate }} </span><a v-on:click="openSummary">[Show ramp chart for this period]</a></div><div class="zoom__title--granularity mini-font">granularity: one ramp per {{ filterTimeFrame }}</div></div><v_ramp v-bind:groupby="info.filterGroupSelection" v-bind:user="info.user" v-bind:tframe="filterTimeFrame" v-bind:sdate="info.sinceDate" v-bind:udate="info.untilDate" v-bind:avgsize="info.avgCommitSize" v-bind:mergegroup="info.isMergeGroup"></v_ramp><div class="zoom__toggle-commit-message-body" v-if="info.user.commits.length"><button v-if="expandedCommitMessagesCount === 0" v-on:click="toggleAllCommitMessagesBody(true)">show all commit messages body</button><button v-else="v-else" v-on:click="toggleAllCommitMessagesBody(false)">hide all commit messages body</button></div><div class="zoom__day" v-for="day in info.user.commits"><template v-if="day.insertions > 0"><h3 v-if="filterTimeFrame === 'week'">Week of {{ day.date }}</h3><h3 v-else="v-else">{{ day.date }}</h3><ul><li class="commit-message active" v-for="slice in day.commitResults"><a v-bind:href="getSliceLink(slice)" target="_blank">{{ slice.messageTitle }}</a><span> ({{ slice.insertions }} lines)</span><a v-if="slice.messageBody !== ''" v-on:click="updateExpandedCommitMessagesCount" onclick="toggleNext(this)" title="Click to show/hide the commit message body"><i class="commit-message--button fas fa-ellipsis-h"></i></a><div class="body" v-if="slice.messageBody !== ''"><pre>{{ slice.messageBody }}</pre></div></li></ul></template></div></div></vuetemplate><vuetemplate id="v_segment"><div class="segment" v-bind:class="{ untouched: !segment.authored, active: segment.lines.length < 5 }"><div class="closer" v-if="!segment.authored && segment.lines.length > 4" v-on:click="loadCode()"><i class="fas fa-plus-circle icon open" v-bind:title="'Click to open code'"></i><i class="fas fa-chevron-circle-down icon hide" v-bind:title="'Click to hide code'"></i></div><div v-if="loaded" v-hljs="path"><div class="code" v-for="(line, index) in segment.lines"><div class="line-number">{{ segment.lineNumbers[index] + "\n" }}</div><div class="line-content">{{ line + "\n" }}</div></div></div><div class="closer bottom" v-if="!segment.authored && segment.lines.length > 4" v-on:click="loadCode()"><i class="fas fa-chevron-circle-up icon hide" v-bind:title="'Click to hide code'"></i></div></div></vuetemplate><vuetemplate id="v_authorship"><div id="authorship"><div class="toolbar" v-if="hasCommits(info)"><a v-if="activeFilesCount === 0" v-on:click="expandAll(true)">Expand all</a><a v-else="v-else" v-on:click="expandAll(false)">Collapse all</a></div><div class="title"><a class="repoName large-font" v-bind:href="info.location" target="_blank" v-bind:title="'Click to open the repo'">{{ info.repo }}</a><div class="author medium-font"><span>↳ </span><span>{{ info.name }} ({{ info.author }})</span></div><div class="period medium-font"><span>↳ </span><span>{{ info.minDate }} to {{ info.maxDate }}</span></div><div class="contribution" v-if="isLoaded && files.length!=0"><div class="sorting mui-form--inline"><div class="mui-select"><select class="medium-font" v-model="filesSortType"><option value="lineOfCode">LoC</option><option value="path">Path</option><option value="fileName">File Name</option><option value="fileType">File Type</option></select><label class="medium-font">sort by</label></div><label><input class="mui-checkbox" type="checkbox" v-model="toReverseSortFiles"/><span class="medium-font reverse">reverse</span></label></div><div class="searchbox"><input class="radio-button--search" type="radio" name="filter" value="search" v-bind:checked="isSearchBar" v-on:click="indicateSearchBar"/><form class="file-picker mui-form--inline" onsubmit="return false"><input class="medium-font" id="search" type="search" placeholder="Filter by glob" v-on:change="updateFilterSearch" v-on:click="indicateSearchBar"/><button class="medium-font" id="submit-button" type="submit" v-on:click="indicateSearchBar">Filter</button></form></div><div class="fileType"><input class="radio-button--checkbox" type="radio" name="filter" value="checkboxes" v-bind:checked="isCheckBoxes" v-on:click="indicateCheckBoxes"/><div class="checkboxes mui-form--inline" v-if="files.length > 0"><label><input class="mui-checkbox--fileType" type="checkbox" v-on:click="selectAll" v-model="isSelectAllChecked"/><span v-bind:title="getTotalFileBlankLineInfo()"><span class="select medium-font">All: </span><span class="loc medium-font">{{ totalLineCount }} </span><span class="bloc medium-font">({{ totalBlankLineCount }})</span></span></label><template v-for="fileType in Object.keys(getFileTypeExistingLinesObj)"><label v-bind:key="fileType"><input class="mui-checkbox--fileType" type="checkbox" v-bind:checked="selectedFileTypes.includes(fileType)" v-on:change="selectFileType(fileType)"/><span v-bind:title="getFileTypeBlankLineInfo(fileType)"><span>{{ fileType }}: {{ getFileTypeExistingLinesObj[fileType] }} </span><span class="bloc">({{ fileTypeBlankLinesObj[fileType] }})</span></span></label></template></div></div></div></div><div class="files" v-if="isLoaded"><div class="empty" v-if="files.length === 0">nothing to see here :(</div><template v-for="file in selectedFiles"><div class="file active" v-bind:key="file.path"><div class="title"><span class="path" onclick="toggleNext(this.parentNode)" v-on:click="updateCount">{{ file.path }} </span><span class="loc">({{ file.lineCount }} lines)</span><a v-bind:href="getFileLink(file, 'commits')" target="_blank" title="click to view the history view of file"><i class="button fas fa-history"></i></a><a v-bind:href="getFileLink(file, 'blame')" target="_blank" title="click to view the blame view of file"><i class="button fas fa-user-edit"></i></a></div><pre class="hljs"><div v-for="segment in file.segments"><v_segment v-bind:segment="segment" v-bind:path="file.path"></v_segment></div></pre></div></template></div><div class="empty" v-else="v-else">loading...</div></div></vuetemplate><script src="static/js/api.js"></script><script src="static/js/safari_date.js"></script><script src="static/js/v_ramp.js"></script><script src="static/js/v_zoom.js"></script><script src="static/js/v_segment.js"></script><script src="static/js/v_summary.js"></script><script src="static/js/v_authorship.js"></script><script src="static/js/main.js"></script></body></html>