Skip to content

Commit

Permalink
Various bug fizes, added loading indicator, added search using jira's…
Browse files Browse the repository at this point in the history
… issue suggestion endpoint
  • Loading branch information
J2-Tech committed Mar 14, 2024
1 parent 12bd946 commit 89e337a
Show file tree
Hide file tree
Showing 14 changed files with 641 additions and 353 deletions.
4 changes: 4 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"tabWidth": 4,
"useTabs": false
}
8 changes: 8 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ var nunjucks = require("nunjucks");
const passport = require('passport');
const AtlassianOAuth2Strategy = require('passport-atlassian-oauth2');
const session = require('express-session');

var fs = require('fs');

if (!fs.existsSync('.env')) {
console.log("No .env file found. Please create one using the .env.example file as a template.");
process.exit(1);
}

const dotenv = require('dotenv').config();

const https = require('https');
Expand Down
17 changes: 17 additions & 0 deletions controllers/jiraAPIController.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,23 @@ exports.searchIssues = function(req, jql) {
return withRetry(searchIssuesInternal, req, jql);
}

exports.suggestIssues = function(req, query) {
return withRetry(suggestIssuesInternal, req, query);
}

function suggestIssuesInternal(req, query) {
const url = getCallURL(req);
if (process.env.JIRA_PROJECT_JQL) {
query += '&currentJQL=' + process.env.JIRA_PROJECT_JQL
}
return fetch(url + '/rest/api/3/issue/picker?query=' + query , {
method: 'GET',
headers: getDefaultHeaders(req),
agent:httpsAgent
}).then(res => res.json());

}

function getIssueInternal(req, issueId) {
const url = getCallURL(req);
return fetch(url + '/rest/api/3/issue/' + issueId, {
Expand Down
63 changes: 62 additions & 1 deletion controllers/jiraController.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ exports.getUsersWorkLogsAsEvent = function(req, start, end) {
const formattedStart = filterStartTime.toLocaleDateString('en-CA');
const formattedEnd = filterEndTime.toLocaleDateString('en-CA');

return jiraAPIController.searchIssues(req, 'worklogAuthor = currentUser() AND worklogDate >= ' + formattedStart + ' AND worklogDate <= '+ formattedEnd).then(result => {
let issuesPromise = jiraAPIController.searchIssues(req, 'worklogAuthor = currentUser() AND worklogDate >= ' + formattedStart + ' AND worklogDate <= '+ formattedEnd);

return issuesPromise.then(result => {
// create an array of issue IDs and keys from result.issues
const issues = result.issues.map(issue => { return {issueId: issue.id, issueKey: issue.key, summary: issue.fields.summary} });
const userWorkLogs = [];
Expand Down Expand Up @@ -87,6 +89,65 @@ exports.deleteWorkLog = function(req, issueId, worklogId) {
return jiraAPIController.deleteWorkLog(req, issueId, worklogId);
}

exports.suggestIssues = function(req, start, end, query) {
var startDate = new Date(start).toISOString().split('T')[0];
var endDate = new Date(end).toISOString().split('T')[0];
var searchInJira = req.query.searchInJira;
var query = req.query.query;

var promises = [];

var emptyJQL = 'worklogAuthor = currentUser() AND worklogDate >= ' + startDate + ' AND worklogDate <= '+endDate+' OR ((assignee = currentUser() OR reporter = currentUser()) AND ((statusCategory != '+ process.env.JIRA_DONE_STATUS +') OR (statusCategory = '+ process.env.JIRA_DONE_STATUS +' AND status CHANGED DURING (' + startDate + ', '+endDate+'))))';

var keyJQL = 'key = ' + query

if (searchInJira != 'true') {
promises.push(jiraAPIController.searchIssues(req, emptyJQL));
} else {
promises.push(jiraAPIController.searchIssues(req, keyJQL));
promises.push(jiraAPIController.suggestIssues(req, query));
}



return Promise.all(promises).then(results => {
// results[0] = base JQL search
// if search in jira
// results[0] = Key search
// results[1] = Suggestion search

var issues = []
if (searchInJira != 'true' && results[0].issues) {
issues = results[0].issues.map(mapIssuesFunction);
}

if (searchInJira == 'true') {
if (results[1] && results[1].sections && results[1].sections.length > 0) {
for (var i = 0; i < results[1].sections.length; i++) {
if (results[1].sections[i].id == "cs") {
//console.log(JSON.stringify(results[0].sections[i]));
// add issues from the suggestion results to the issues array
var mappedIssues = results[1].sections[i].issues.map(mapIssuesFunction);
issues = issues.concat(mappedIssues);
}
}
}
if (results[0] && results[0].issues) {
issues = issues.concat(results[0].issues.map(mapIssuesFunction));
}
}
return issues;
});
}

function mapIssuesFunction(issue) {
return {
id: issue.id,
key: issue.key,
summary: issue.fields ? issue.fields.summary : issue.summary
}
}


function formatDateToJira(toFormat) {
const dayJsDate = dayjs(toFormat);
Expand Down
2 changes: 2 additions & 0 deletions example.env
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ JIRA_OAUTH_CALLBACK_URL=http://locahost:3000/auth/callback
JIRA_DONE_STATUS="Done"
# Maximum number of issues to return at once.
JIRA_MAX_SEARCH_RESULTS=200
# JQL used to filter suggested issues. uswful for restricting to a project
JIRA_PROJECT_JQL="project = PLY"

# Express app settings
# The port to run the app on
Expand Down
Binary file added public/images/icons8-dots-loading.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 18 additions & 1 deletion public/stylesheets/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,19 @@ a {
margin-bottom: 15px;
}

.modal-content .search-options {
display: flex;
width: fit-content;
align-items: center;
}
.modal-content .search-options input {
flex-grow: 0;
}
.modal-content .search-options label {
word-break: keep-all;
white-space: nowrap;
}

.modal .destructive {
border: 2px solid darkred;
background: red;
Expand Down Expand Up @@ -139,12 +152,16 @@ input#include-weekends {
}


.about-section {
#about-section {
position: absolute;
bottom: 5px;
opacity: 35%;
}

#loading-container {
width: 50px;
overflow: clip;
}


/********** Choices.js **********/
Expand Down
12 changes: 3 additions & 9 deletions routes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,13 @@ router.get('/events', function(req, res, next) {

router.get('/issues/user', function(req, res, next) {
try {
var startDate = new Date(req.query.start).toISOString().split('T')[0];

var endDate = new Date(req.query.end).toISOString().split('T')[0];

jiraAPIController.searchIssues(req, 'worklogAuthor = currentUser() AND worklogDate >= ' + startDate + ' AND worklogDate <= '+endDate+' OR ((assignee = currentUser() OR reporter = currentUser()) AND ((statusCategory != '+ process.env.JIRA_DONE_STATUS +') OR (statusCategory = '+ process.env.JIRA_DONE_STATUS +' AND status CHANGED DURING (' + startDate + ', '+endDate+'))))').then(result => {
if (!result.issues) {
console.log(result);
}
res.json(result.issues);
jiraController.suggestIssues(req, req.query.start, req.query.end, req.query.query).then(result => {
res.json(result);
});
} catch (error) {
console.log(error);
}

});

router.get('/issues/:issueId', function(req, res, next) {
Expand Down
39 changes: 39 additions & 0 deletions views/aboutModal.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{% macro modal() %}
<div class="modal unselectable modal-about" style="display:none;">
<div class="modal-content">
<h2>About Plywood</h2>
<form class="modal-form" id="modal-form-update" method="PUT" action="{{ endpoint }}">
<div class="about-ctn">
<div class="icons-8">
<p><a target="_blank" href="https://icons8.com/icon/4ONNYCMz9R42/plywood">Plywood</a> icon by <a target="_blank" href="https://icons8.com">Icons8</a></p>
<p><a target="_blank" href="https://icons8.com/icon/KnQ23R20ge4i/dots-loading">Dots Loading</a> icon by <a target="_blank" href="https://icons8.com">Icons8</a></p>
</div>
<p>Software licensed under the <a target="_blank" href="https://opensource.org/license/MIT/">MIT License</a></p>
<p>Version: 0.2.1</p>
</div>
<div class="buttons">
<button id="close-btn-about" title="Close" type="button">✖️</button>
</div>
</form>
</div>
</div>

<script>
function showAboutModal() {
const modal = document.querySelector('.modal-about');
modal.style.display = 'block';
}
// Hide the modal
function hideAboutModal() {
const modal = document.querySelector('.modal-about');
modal.style.display = 'none';
}
// Add event listeners to the buttons
const closeBtnAbout = document.getElementById('close-btn-about');
closeBtnAbout.addEventListener('click', hideAboutModal);
</script>
{% endmacro %}
Loading

0 comments on commit 89e337a

Please sign in to comment.