Skip to content

Commit

Permalink
Bug-Reporter API(#111)
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
Ethck authored Jul 8, 2021
1 parent db02bb2 commit a990544
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 12 deletions.
4 changes: 4 additions & 0 deletions Module/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
"label": "Description",
"placeholder": "What happened, how to reproduce, etc."
},
"apiDetails": {
"label": "Stack Traces / Errors",
"placeholder": "This field can be used for stack traces, error messages, etc."
},
"errors": {
"incomplete": "Please finish filling out required values."
},
Expand Down
66 changes: 61 additions & 5 deletions Module/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,25 @@ const generateModuleSettings = (mod) => {
return schema;
}

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


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

this.formFields = {
bugTitle: '',
bugTitle: title || '',
issuer: '',
issueLabel: '',
bugDescription: '',
apiDetails: description || '',
}

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

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

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

// let the app know we're ready to send stuff
Expand All @@ -358,7 +373,8 @@ class BugReportForm extends FormApplication {
body: fullDescription,
repo: bugsUrl,
moduleList,
moduleSettings: moduleSettings
moduleSettings: moduleSettings,
additionalDetails
}),
})
// wait for the response
Expand Down Expand Up @@ -556,6 +572,44 @@ function getModuleSelection() {
});
}

/**
* API class that allows other modules to interact with Bug Reporter
*/
class BugReporterAPI {
/**
* This function allows you to check if a given module (modid) is supported
* by the Bug Reporter Module.
*
* NOTE: This evaluation currently does NOT check if the given `bugs` url from
* the module's manifest is legitimate, so in theory there can be a false positive.
*
* @param {'String'} modid ID of the module in question
* @returns True if Bug Reporter is functional with the provided module ID
*/
allowBugReporter(modid) {
const module = game.modules.get(modid) || game.system;
return (module.data.flags?.allowBugReporter || module.data.allowBugReporter);
}

/**
* Begin the workflow for a given module/system (modid) and potentially provide some
* pre-filled details to the form like the Title of the bug report and some details. Note
* that the details must be a String and will undergo some slight modifications (as well as
* some content moderation from the FoundryVttBugReporterApi hosted on Azure)
*
* @param {String} modid ID of the module to start the workflow for
* @param {String} title What you want to be pre-populated into the `title` field.
* @param {String} details What you want to be included in the "body" of the bug report.
*/
bugWorkflow(modid, title = "", details = "") {
if (this.allowBugReporter(modid)) {
new BugReportForm(undefined, { selectedModule: modid, title, description: details} ).render(true);
} else {
console.error("The module " + modid + " does not support bug-reporter.")
}
}
}

// Once Foundry has initialized, add our Hook to listen for sidebar render
Hooks.once("init", () => {
Hooks.on("renderSidebarTab", async (app, html) => {
Expand All @@ -571,6 +625,8 @@ Hooks.once("init", () => {
// game version
button.insertAfter(html.find("#game-details"));
}
// game.modules isn't populated until init, so we insert our API here.
game.modules.get("bug-reporter").api = new BugReporterAPI;
});

game.settings.register("bug-reporter", "contactInfo", {
Expand Down
9 changes: 8 additions & 1 deletion Module/templates/bug-report.html
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,15 @@ <h4 class="flexrow">
<div class="form-group-stacked">
<label class="wide">{{localize 'BUG.form.bugDescription.label'}}*</label>
<textarea placeholder="{{localize 'BUG.form.bugDescription.placeholder'}}" class="bug-description" maxlength="875"
name="formFields.bugDescription" value="{{formFields.bugDescription}}" rows=10 data-type="String"></textarea>
name="formFields.bugDescription" rows=10 data-type="String">{{formFields.bugDescription}}</textarea>
</div>
{{#if formFields.apiDetails}}
<div class="form-group-stacked">
<label class="wide">{{localize 'BUG.form.apiDetails.label'}}*</label>
<textarea placeholder="{{localize 'BUG.form.apiDetails.placeholder'}}" class="bug-description" maxlength="875"
name="formFields.apiDetails" rows=10 data-type="String">{{formFields.apiDetails}}</textarea>
</div>
{{/if}}

<button type="submit" {{#if isSending}}disabled{{/if}} class="bug-submit">{{localize "BUG.submit"}}</button>
{{else}}
Expand Down
41 changes: 35 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,16 @@ This module allows users to search for and sometimes create github/gitlab issues

#### Examples:

0.8.3+
```md
"bugs": "https://github.com/Ethck/legendary-training-wheels/issues",
"flags": {
"allowBugReporter": true
}
```

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.

Github
```md
"bugs": "https://github.com/Ethck/legendary-training-wheels/issues",
Expand All @@ -33,12 +43,31 @@ Gitlab
"allowBugReporter": true
```

0.8.3+
```md
"bugs": "https://github.com/Ethck/legendary-training-wheels/issues",
"flags": {
"allowBugReporter": true
}
### Bug Reporter API

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.

The API can be accessed as follows:

```js
game.modules.get("bug-reporter").api;
```

In the API you will find the following methods available for your use:

- allowBugReporter(modid)
- bugWorkflow(modid, title = "", details = "")

#### allowBugReporter()

allowBugReporter takes a string of the module name and returns whether or not the module in question supports Bug Reporter.

#### bugWorkflow()
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.

Example:
```js
game.modules.get("bug-reporter").api.bugWorkflow("bug-reporter", "Testing the API", "Here are my auto-generated details, perhaps even an error message");
```

#### Rationale:
Expand Down

0 comments on commit a990544

Please sign in to comment.