Skip to content

Commit a990544

Browse files
authored
Bug-Reporter API(#111)
* Added in Bug Reporter API closes #103 * Added additional newline to additional details to preserve formatting. * Added information about the Bug Reporter API to the documentation. * Adjusted information for making bug-reporter work in manifests. * Added safeguard on bugWorkflow to ensure the module supports bug-reporter.
1 parent db02bb2 commit a990544

File tree

4 files changed

+108
-12
lines changed

4 files changed

+108
-12
lines changed

Module/lang/en.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@
2121
"label": "Description",
2222
"placeholder": "What happened, how to reproduce, etc."
2323
},
24+
"apiDetails": {
25+
"label": "Stack Traces / Errors",
26+
"placeholder": "This field can be used for stack traces, error messages, etc."
27+
},
2428
"errors": {
2529
"incomplete": "Please finish filling out required values."
2630
},

Module/main.js

Lines changed: 61 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,25 @@ const generateModuleSettings = (mod) => {
5959
return schema;
6060
}
6161

62+
/**
63+
* Format given API Details (usually pre-filled via the BugReporterAPI) in a way that is similar to what
64+
* is already used in our bug report structure.
65+
*
66+
* @param {String} apiDetails Details such as errors and/or stack traces to append to the bug report.
67+
* @returns
68+
*/
69+
const generateAdditionalDetails = (apiDetails) => {
70+
let schema = `<details>\n<summary>Additional Details</summary>\n\n{REPL_DETAILS}\n</details>`
71+
return schema.replace(/{REPL_DETAILS}/gi, apiDetails);
72+
}
73+
6274

6375
/**
6476
* Based off of Moo Man's Excellent WFRP4e Bug Reporter
6577
* https://github.com/moo-man/WFRP4e-FoundryVTT/blob/master/modules/apps/bug-report.js
6678
*/
6779
class BugReportForm extends FormApplication {
68-
constructor(app, { selectedModule }) {
80+
constructor(app, { selectedModule, title = "", description = "" }) {
6981
super(app);
7082
this.endpoint = "https://foundryvttbugreporter.azurewebsites.net/api/ReportBugFunction?code=VCvrWib1lha2nf9Pza7fOaThNTksbmHdEjVhIudCHwXg3zyg4vPprg==";
7183
this.module = game.modules.get(selectedModule) || game.system;
@@ -79,10 +91,11 @@ class BugReportForm extends FormApplication {
7991
}
8092

8193
this.formFields = {
82-
bugTitle: '',
94+
bugTitle: title || '',
8395
issuer: '',
8496
issueLabel: '',
8597
bugDescription: '',
98+
apiDetails: description || '',
8699
}
87100

88101
this.foundIssues = [];
@@ -292,7 +305,7 @@ class BugReportForm extends FormApplication {
292305
async _updateObject(ev, formData) {
293306
// obtain original data
294307
const mod = this.module;
295-
const {formFields: { bugTitle, bugDescription, issuer, label, sendActiveModules, sendModSettings }} = expandObject(formData);
308+
const {formFields: { apiDetails, bugTitle, bugDescription, issuer, label, sendActiveModules, sendModSettings }} = expandObject(formData);
296309

297310
// if any of our warnings are not checked, throw
298311
if (!bugTitle || !bugDescription) {
@@ -337,10 +350,12 @@ class BugReportForm extends FormApplication {
337350
const moduleList = sendActiveModules ? generateActiveModuleList() : "";
338351
// generate module settings
339352
const moduleSettings = sendModSettings ? generateModuleSettings(mod) : "";
353+
// format errors / stack traces provided by API
354+
const additionalDetails = (apiDetails != false) ? generateAdditionalDetails(apiDetails): "";
340355

341356
// construct gitlab link (if applicable)
342357
if (this.gitlab) {
343-
bugsUrl = bugsUrl + `?title=${encodeURIComponent(bugTitle)}&description=${encodeURIComponent(fullDescription + "\n" + moduleList + moduleSettings)}`;
358+
bugsUrl = bugsUrl + `?title=${encodeURIComponent(bugTitle)}&description=${encodeURIComponent(fullDescription + "\n" + moduleList + moduleSettings + additionalDetails)}`;
344359
}
345360

346361
// let the app know we're ready to send stuff
@@ -358,7 +373,8 @@ class BugReportForm extends FormApplication {
358373
body: fullDescription,
359374
repo: bugsUrl,
360375
moduleList,
361-
moduleSettings: moduleSettings
376+
moduleSettings: moduleSettings,
377+
additionalDetails
362378
}),
363379
})
364380
// wait for the response
@@ -556,6 +572,44 @@ function getModuleSelection() {
556572
});
557573
}
558574

575+
/**
576+
* API class that allows other modules to interact with Bug Reporter
577+
*/
578+
class BugReporterAPI {
579+
/**
580+
* This function allows you to check if a given module (modid) is supported
581+
* by the Bug Reporter Module.
582+
*
583+
* NOTE: This evaluation currently does NOT check if the given `bugs` url from
584+
* the module's manifest is legitimate, so in theory there can be a false positive.
585+
*
586+
* @param {'String'} modid ID of the module in question
587+
* @returns True if Bug Reporter is functional with the provided module ID
588+
*/
589+
allowBugReporter(modid) {
590+
const module = game.modules.get(modid) || game.system;
591+
return (module.data.flags?.allowBugReporter || module.data.allowBugReporter);
592+
}
593+
594+
/**
595+
* Begin the workflow for a given module/system (modid) and potentially provide some
596+
* pre-filled details to the form like the Title of the bug report and some details. Note
597+
* that the details must be a String and will undergo some slight modifications (as well as
598+
* some content moderation from the FoundryVttBugReporterApi hosted on Azure)
599+
*
600+
* @param {String} modid ID of the module to start the workflow for
601+
* @param {String} title What you want to be pre-populated into the `title` field.
602+
* @param {String} details What you want to be included in the "body" of the bug report.
603+
*/
604+
bugWorkflow(modid, title = "", details = "") {
605+
if (this.allowBugReporter(modid)) {
606+
new BugReportForm(undefined, { selectedModule: modid, title, description: details} ).render(true);
607+
} else {
608+
console.error("The module " + modid + " does not support bug-reporter.")
609+
}
610+
}
611+
}
612+
559613
// Once Foundry has initialized, add our Hook to listen for sidebar render
560614
Hooks.once("init", () => {
561615
Hooks.on("renderSidebarTab", async (app, html) => {
@@ -571,6 +625,8 @@ Hooks.once("init", () => {
571625
// game version
572626
button.insertAfter(html.find("#game-details"));
573627
}
628+
// game.modules isn't populated until init, so we insert our API here.
629+
game.modules.get("bug-reporter").api = new BugReporterAPI;
574630
});
575631

576632
game.settings.register("bug-reporter", "contactInfo", {

Module/templates/bug-report.html

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,15 @@ <h4 class="flexrow">
122122
<div class="form-group-stacked">
123123
<label class="wide">{{localize 'BUG.form.bugDescription.label'}}*</label>
124124
<textarea placeholder="{{localize 'BUG.form.bugDescription.placeholder'}}" class="bug-description" maxlength="875"
125-
name="formFields.bugDescription" value="{{formFields.bugDescription}}" rows=10 data-type="String"></textarea>
125+
name="formFields.bugDescription" rows=10 data-type="String">{{formFields.bugDescription}}</textarea>
126126
</div>
127+
{{#if formFields.apiDetails}}
128+
<div class="form-group-stacked">
129+
<label class="wide">{{localize 'BUG.form.apiDetails.label'}}*</label>
130+
<textarea placeholder="{{localize 'BUG.form.apiDetails.placeholder'}}" class="bug-description" maxlength="875"
131+
name="formFields.apiDetails" rows=10 data-type="String">{{formFields.apiDetails}}</textarea>
132+
</div>
133+
{{/if}}
127134

128135
<button type="submit" {{#if isSending}}disabled{{/if}} class="bug-submit">{{localize "BUG.submit"}}</button>
129136
{{else}}

README.md

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,16 @@ This module allows users to search for and sometimes create github/gitlab issues
2121

2222
#### Examples:
2323

24+
0.8.3+
25+
```md
26+
"bugs": "https://github.com/Ethck/legendary-training-wheels/issues",
27+
"flags": {
28+
"allowBugReporter": true
29+
}
30+
```
31+
32+
The following examples are remnants from the 0.7.X releases for how to make bug-reporter work, but they are kept to show the proper Github/lab links.
33+
2434
Github
2535
```md
2636
"bugs": "https://github.com/Ethck/legendary-training-wheels/issues",
@@ -33,12 +43,31 @@ Gitlab
3343
"allowBugReporter": true
3444
```
3545

36-
0.8.3+
37-
```md
38-
"bugs": "https://github.com/Ethck/legendary-training-wheels/issues",
39-
"flags": {
40-
"allowBugReporter": true
41-
}
46+
### Bug Reporter API
47+
48+
As of Bug Reporter version 1.3.1 there is now an API that a developer can launch and pre-fill with data for bug reports.
49+
50+
The API can be accessed as follows:
51+
52+
```js
53+
game.modules.get("bug-reporter").api;
54+
```
55+
56+
In the API you will find the following methods available for your use:
57+
58+
- allowBugReporter(modid)
59+
- bugWorkflow(modid, title = "", details = "")
60+
61+
#### allowBugReporter()
62+
63+
allowBugReporter takes a string of the module name and returns whether or not the module in question supports Bug Reporter.
64+
65+
#### bugWorkflow()
66+
bugWorkflow takes the modid and option title & details to generate a bug report that will be prefilled with the details of the bug that you provide. These details can be formatted however you desire, but it will be wrapped inside of <summary> tags on transmission to Github/lab.
67+
68+
Example:
69+
```js
70+
game.modules.get("bug-reporter").api.bugWorkflow("bug-reporter", "Testing the API", "Here are my auto-generated details, perhaps even an error message");
4271
```
4372

4473
#### Rationale:

0 commit comments

Comments
 (0)