Skip to content

Commit 0ffdaba

Browse files
committed
init: First commit :)
0 parents  commit 0ffdaba

File tree

2 files changed

+288
-0
lines changed

2 files changed

+288
-0
lines changed

Code.js

+231
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
/*================================================================================================================*
2+
Bugrid
3+
================================================================================================================
4+
Version: 1.0.0
5+
Project Page: https://github.com/Sheetgo/bugrid
6+
Copyright: (c) 2018 by Sheetgo
7+
License: GNU General Public License, version 3 (GPL-3.0)
8+
http://www.opensource.org/licenses/gpl-3.0.html
9+
----------------------------------------------------------------------------------------------------------------
10+
Changelog:
11+
1.0.0 Initial release
12+
*================================================================================================================*/
13+
14+
15+
16+
var logsTab = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Script Actions Log");
17+
var bugsTab = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Bugs");
18+
var developersTab = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Input Developers");
19+
20+
21+
/**
22+
* This funcion will run when you open the spreadsheet. It creates a Spreadsheet menu option to run the spript
23+
*/
24+
function onOpen() {
25+
// Adds a custom menu to the spreadsheet.
26+
SpreadsheetApp.getUi()
27+
.createMenu('Bugbuster')
28+
.addItem('Bugrid', 'analyzeBugs')
29+
.addToUi();
30+
}
31+
32+
33+
function analyzeBugs() {
34+
// Gets the spreadsheet values matrix
35+
var values = bugsTab.getDataRange().getValues();
36+
for (var x = 0; x < values.length; x++) {
37+
// Ignores header of the spreadsheet
38+
if (x > 0) {
39+
40+
// Gets the current row
41+
var row = values[x];
42+
43+
// Gets the current row fields
44+
var bugId = row[alphabet_letter_index('A')];
45+
var bugDetails = row[alphabet_letter_index('E')];
46+
var supportEmail = row[alphabet_letter_index('C')];
47+
var developerName = row[alphabet_letter_index('J')];
48+
var developer = getDeveloperByName(developerName);
49+
var userEmail = row[alphabet_letter_index('D')];
50+
51+
// These two variables are used to determine whether should we notify the
52+
// support member if the bug is tag as Not a Bug.
53+
var notifiedAsNotABug = actionPerformed(bugId, "not-a-bug");
54+
var taggedAsNotABug = row[alphabet_letter_index('H')];
55+
56+
// Checks: is it tagged as a "Not a Bug" AND NOT already notifyed?
57+
if (taggedAsNotABug && !notifiedAsNotABug) {
58+
// In case it's not a bug, send e-mail to the support member
59+
MailApp.sendEmail(
60+
supportEmail, developer.email, "Bug #"+bugId+" Is not a Bug",
61+
"The Developer "+ developerName +" has marked as 'Not a Bug'\n\n"
62+
+ "User email:"+userEmail+"\n\nBug Details:\n\n"+bugDetails
63+
);
64+
65+
// Appends a log line in the Script Actions Log tab
66+
logsTab.appendRow([bugId, "not-a-bug", 1, new Date()])
67+
}
68+
69+
// These two variables are used to determine whether should we notify the
70+
// support member if the bug needs to be tested.
71+
var sentEmailForTesting = actionPerformed(bugId, "needs-testing");
72+
var shouldNotifyForTesting = row[alphabet_letter_index('L')];
73+
74+
// Checks: is it tagged as a "Needs Testing" AND NOT already notifyed?
75+
if (shouldNotifyForTesting && !sentEmailForTesting) {
76+
77+
MailApp.sendEmail(
78+
supportEmail,
79+
developer.email,
80+
"Bug Fix #"+bugId+" ready for testing",
81+
"Our development team has already fixed bug #"+bugId+". It can be"
82+
+ "tested now \n\nBug Details:\n\n"+bugDetails+"\n\nUser email: "
83+
+userEmail
84+
);
85+
86+
// Appends a log line in the Script Actions Log tab
87+
logsTab.appendRow([bugId, "needs-testing", 1, new Date()])
88+
}
89+
90+
// These two variables are used to determine whether should we notify the
91+
// user if the bug needs to be tested and if should we add the current
92+
// date on the "Release Date" column.
93+
var insertedReleaseDate = actionPerformed(bugId, "released");
94+
var taggedReleaseDate = row[alphabet_letter_index('N')];
95+
96+
// Checks: is it tagged as a "Released" AND NOT already added the release
97+
// date to the column "N"?
98+
if (taggedReleaseDate && !insertedReleaseDate) {
99+
var bugRowIndex = getBugRow(bugId, "Bugs")
100+
101+
// Sets the current Date to the column "Release Date"
102+
bugsTab.getRange(bugRowIndex+1, alphabet_letter_index('O')+1).setValue(new Date());
103+
104+
// Appends a log line in the Script Actions Log tab
105+
logsTab.appendRow([bugId, "released", 1, new Date()])
106+
107+
// Sends the e-mail
108+
MailApp.sendEmail(userEmail, userEmail, "Bug fixed!", "Our development"
109+
+ "team has already fixed bug #"+bugId+". We would appreciate if "
110+
+ "you\ could give us a feedback"
111+
);
112+
}
113+
114+
}
115+
}
116+
}
117+
118+
119+
/**
120+
* Checks the actions performed by the script at the logstab.
121+
* @param {String} bugId - The bug id from the "Bugs" sheet
122+
* @param {String} notificationType - The notification type (ex.: 'released')
123+
* @returns {boolean}
124+
*/
125+
function actionPerformed(bugId, notificationType) {
126+
var values = logsTab.getDataRange().getValues();
127+
for (var x = 0; x < values.length; x++) {
128+
if (x > 0) {
129+
var row = values[x];
130+
if (row[0] == bugId && row[1] == notificationType && row[2] == 1) {
131+
return true
132+
}
133+
}
134+
}
135+
return false
136+
}
137+
138+
139+
/**
140+
* Returns the index of the bug row.
141+
* @param {String} bugId - The bug id from the "Bugs" sheet
142+
* @returns {integer}
143+
*/
144+
function getBugRow(bugId) {
145+
var values = bugsTab.getDataRange().getValues();
146+
for (var x = 0; x < values.length; x++) {
147+
var row = values[x];
148+
if (row[0] == bugId) {
149+
return x
150+
}
151+
}
152+
}
153+
154+
155+
/**
156+
* Returns an object containing the developer's info.
157+
* @param {String} name - The developer name from column "Assign Developer"
158+
* @returns {object}
159+
*/
160+
function getDeveloperByName(name) {
161+
var values = developersTab.getDataRange().getValues();
162+
for (var x = 0; x < values.length; x++) {
163+
var row = values[x];
164+
if (x > 0) { // IGNORES HEADER
165+
var developerName = row[alphabet_letter_index('C')];
166+
var developerDescription = row[alphabet_letter_index('D')];
167+
var developerEmail = row[alphabet_letter_index('E')];
168+
if (developerDescription == name) {
169+
return {
170+
name: developerName,
171+
email: developerEmail
172+
}
173+
}
174+
}
175+
}
176+
}
177+
178+
179+
/**
180+
* Returns the numeric index, on the alphabet, from a given letter.
181+
* @param {String} stringLetters - The string letter(s) (ex.: 'AB')
182+
* @returns {integer}
183+
*/
184+
function alphabet_letter_index(stringLetters) {
185+
var letters = stringLetters.split('')
186+
var alphabet = [
187+
"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o",
188+
"p","q","r","s","t","u","v","w","x","y","z"
189+
];
190+
var alphabet_size = 26
191+
var index = 0
192+
var alphabet_layers = range(0, alphabet_size * letters.length, alphabet_size);
193+
// for loop_index, letter in enumerate(letters):
194+
letters.forEach(function(letter, loop_index){
195+
index = alphabet.indexOf(letter.toLowerCase()) + alphabet_layers[loop_index];
196+
})
197+
return index;
198+
}
199+
200+
201+
/**
202+
* https://stackoverflow.com/questions/8273047/javascript-function-similar-to-python-range
203+
* Generates an array from the given @start to the given @stop within steps
204+
* defined in @steps.
205+
* @param {integer} start - The starting point value of the range.
206+
* @param {integer} stop - The stopping point value of the range.
207+
* @param {integer} step - the steps of the range.
208+
* @returns {array}
209+
*/
210+
function range(start, stop, step) {
211+
if (typeof stop == 'undefined') {
212+
// one param defined
213+
stop = start;
214+
start = 0;
215+
}
216+
217+
if (typeof step == 'undefined') {
218+
step = 1;
219+
}
220+
221+
if ((step > 0 && start >= stop) || (step < 0 && start <= stop)) {
222+
return [];
223+
}
224+
225+
var result = [];
226+
for (var i = start; step > 0 ? i < stop : i > stop; i += step) {
227+
result.push(i);
228+
}
229+
230+
return result;
231+
};

README.md

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# BugRid
2+
3+
## Introduction
4+
5+
Here at Sheetgo, we started using a Spreadsheet to keep track of our bugs in order to efficiently fix them. After some time, we noticed that the Bug Spreadsheet started to grow in complexity thus presenting us as the challenge: How can we create a solution that has well defined rules and an efficient flow of notification across all this process?
6+
7+
In order to achieve this, we combined the power of sheetgo background with spreadsheets with what we priviously had in bug tracking controll, to create a new template.
8+
9+
## How to Configure Your Bugbuster solution
10+
11+
[Create a copy](https://docs.google.com/spreadsheets/d/1EUt_ackq0m47wE2t4g-SNdxfDIJd5Rk9KisbXL2qj4o/copy) of the Google Sheet by clicking on the link and clicking “Make a Copy” that will be used as the central database for bug submissions. It includes the following tabs:
12+
13+
1. Dashboard: Statistics around your bug tracking process
14+
2. Bugs: Central database of all reported bugs
15+
3. Input Developers: Where you assign names and emails to your developers.
16+
17+
Ignore all hidden tabs (only for advanced users who want to modify their solution). If you want to manipulate those, please contact [[email protected]](mailto://[email protected]).
18+
19+
## Step 2: Input Developers
20+
21+
On the tab Input Developers, add your developer team. You can have up to 10 developers in your team. Provide an email and name for each of them. Consequently, every developer has his/her own custom filter view to work on only his/her bugs on the Bugs tab. They can even bookmark their filter view URL to directly access only their bugs.
22+
23+
![Input Developers](https://blog.sheetgo.com/wp-content/uploads/2018/09/Screenshot_2018-09-28_17-38-21.png)
24+
25+
## Step 3: Bugs tab
26+
27+
On the bugs tab, only edit the white columns G:J. Grey columns are not meant to be edited. For every new bug on this tab, fill in columns G:J to assign it to a developer. Developers in turn only need to work on the columns K:N.
28+
29+
**Remember**: As the one assigning bugs, don’t be in any custom filter view!
30+
31+
![Bugs Tab](https://blog.sheetgo.com/wp-content/uploads/2018/09/Screenshot_2018-09-28_17-41-18.png)
32+
33+
## Step 4: Google Form
34+
35+
At step 1, you created a copy of the Google Sheet which also created a copy of the Google Form that is used by the user support team to submit new bugs. Now, go to the menu Form > Edit form and open the Google Form that had been created automatically. If you are prompted to restore the folder that is used to hold uploaded screenshots or videos, press Restore. Every new bug submitted using this Google Form will be added as a new row to your Google Sheet on the tab Bugs.
36+
37+
To submit your first bug, click on the Preview icon to open the form in preview mode. You can send this link to your support team, for them to submit new bugs.
38+
39+
![Google Form](https://blog.sheetgo.com/wp-content/uploads/2018/09/Screenshot_2018-09-28_17-41-53.png)
40+
41+
## Step 5: Installing the Google Emailing Script
42+
43+
Let us now focus on the last integral part of this bug tracking system: the email component. The idea is that as soon as the developer has fixed a bug and requires testing feedback from the support member, he/she can check column L on the Bugs tab. Once this column has been checked for a bug, a script sends an automatic email to the support member (column C) to test and give feedback by replying to the email.
44+
45+
This is an iterative process. As soon as the bug has been fixed, sufficiently tested, and finally released, the developer can check column N to send a final confirmation email to the user who had experienced the bug.
46+
47+
To set up this emailing script, on the Google Sheet, select Tools from the menu and then Script Editor. Click on the icon for current project triggers.
48+
49+
![Google Apps Script](https://blog.sheetgo.com/wp-content/uploads/2018/09/Screenshot_2018-09-28_17-42-35.png)
50+
51+
Set up your project trigger as shown in the below screenshot:
52+
53+
![Set up Trigger](https://blog.sheetgo.com/wp-content/uploads/2018/09/Screenshot_2018-09-28_17-43-01.png)
54+
55+
Congratulations!
56+
57+
You have just set up your own bug tracking ticketing system. Now, have one of your user support people submit a new bug using the Google Form and let your developers play with killing the bugs. 🙂

0 commit comments

Comments
 (0)