Skip to content

Configurable issue types model (#14)#17

Open
stilliard wants to merge 4 commits into
masterfrom
feature/14-configurable-issue-types
Open

Configurable issue types model (#14)#17
stilliard wants to merge 4 commits into
masterfrom
feature/14-configurable-issue-types

Conversation

@stilliard

Copy link
Copy Markdown
Owner

Closes #14.

Abstracts the hardcoded issue "type" into a real data model. Each type maps to a GitHub native issue type, a set of default labels, and a body template.

What changed

  • New Types module (popup/modules/types.js) with seeded defaults (Bug / Enhancement / Other), backed by chrome.storage.local. Shape: { id, name, githubType, labels[], bodyTemplate }. Exposes getAll (seeds on first use), saveAll, find.
  • Radios rendered from the model instead of hardcoded HTML (app.html → a #type_options render target).
  • Submit handler builds the URL from the selected type: emits &type= (native issue type, gracefully ignored where unsupported), &labels= (supports multiple), and the body template — replacing the inline if (type=='bug') chain. Pure-redirect UX preserved.
  • Updated feature template order: Story → Requirements → Tasks → Acceptance criteria.
  • Readiness barrier so IssueForm.init never restores/binds the async-rendered radios before they exist.

Status

  • Builds clean (npm run build); types.js passes node --check.
  • Implementation (Tasks) complete; Acceptance criteria pending a browser run — they assert runtime behaviour a compile can't prove. Manual check:
    1. npm run build, reload the unpacked extension at chrome://extensions
    2. Popup → three radios render (Bug/Enhancement/Other), Bug pre-checked
    3. Pick Enhancement, submit → new-issue URL has &type=Feature&labels=enhancement + body template
    4. Reopen popup → last type selection still selected (validates the readiness-barrier fix)

Follow-ups (separate issues)

🤖 Generated with Claude Code

Abstract the hardcoded issue "type" into a real data model where each type
maps to a GitHub native issue type, a set of default labels, and a body
template.

- Add Types module (popup/modules/types.js) with seeded defaults
  (Bug/Enhancement/Other), backed by chrome.storage.local. Each type is
  { id, name, githubType, labels[], bodyTemplate }. Exposes getAll (seeds
  on first use), saveAll, and find.
- Render the type radios from the model instead of hardcoded HTML.
- Build the new-issue URL from the selected type: emit &type= (native issue
  type, ignored where unsupported), &labels= (supports multiple), and the
  body template — replacing the inline if (type=='bug') chain.
- Adopt the updated feature template order: Story -> Requirements -> Tasks
  -> Acceptance criteria.
- Gate IssueForm.init behind a readiness barrier so it never restores/binds
  the async-rendered radios before they exist.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 12, 2026 22:47

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements a configurable “Issue Types” data model (GitHub native issue type + default labels + body template) and refactors the popup UI/submit flow to use it instead of hardcoded radios and template logic.

Changes:

  • Added popup/modules/types.js to seed, persist, and query issue types from chrome.storage.local.
  • Updated the report-issue screen to render type radios dynamically into #type_options instead of hardcoded HTML.
  • Refactored the submit handler to build &type=, multi-label &labels=, and &body= from the selected type model.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
popup/modules/types.js Introduces the Types model with defaults, storage helpers, and lookup.
popup/app.js Renders type selector from storage and builds the GitHub new-issue URL from the selected type.
popup/app.html Replaces hardcoded type radios with a render target and loads the new Types module.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread popup/app.js Outdated
Comment on lines +32 to +40
var radios = types.map(function (type, i) {
// TODO(#15): escape type.name/type.id once users can define their own types
var inputId = 'type_' + type.id;
return '<input type="radio" name="type" class="hidden-checkbox" '
+ 'value="' + type.id + '" id="' + inputId + '"' + (i === 0 ? ' checked' : '') + '>'
+ '<label tabindex="0" role="button" class="hidden-checkbox-label" for="' + inputId + '">'
+ type.name + '</label>';
});
$screen.find('#type_options').html(radios.join(''));
Comment thread popup/app.js
Comment on lines 160 to 167
added_url = $screen.find('#added_url').prop('checked'),
added_screenshot = $screen.find('#added_screenshot').prop('checked'),
added_debug = $screen.find('#added_debug').prop('checked'),
type_field = $screen.find('#type_field input[name="type"]:checked').val(),
type_id = $screen.find('#type_field input[name="type"]:checked').val(),
selectedType = Types.find(issueTypes, type_id),
body = '',
url = 'https://github.com/' + repo + '/issues/new?title=' + encodeURIComponent(title);

Comment thread popup/modules/types.js
Comment on lines +91 to +102
function getAll(callback) {
chrome.storage.local.get(['types'], function (result) {
if (result.types) {
callback(JSON.parse(result.types));
return;
}
// first use: seed storage with the defaults
saveAll(DEFAULTS, function () {
callback(DEFAULTS);
});
});
}
stilliard and others added 3 commits June 13, 2026 14:18
…pacing

Review follow-ups on #14:

- Rename the popup "Issue type:" label to "Type:"
- Restore the inter-button gap on the type radios (lost when moving from
  static markup to generated radios)
- Render radios via DOM APIs + .text() and normalise the element id, so a
  hand-edited chrome.storage value can't inject markup or break the DOM
- Fall back to the first (default) type when none is checked, avoiding an
  untyped issue on an early submit (regression vs the old static radios)
- Parse stored types defensively, reseeding defaults on corrupt/invalid data

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The defaults are the single source of truth in code, so every user on the
defaults gets template/type improvements with no migration. Removes the
seed-on-read write, the defensive parse, the unused saveAll helper, and —
getAll now being synchronous — the readiness barrier in app.js (the type
radios render before IssueForm.init, so no race to guard).

Persistence for user-customised types is deferred to #15.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Configurable Issue Types model (GitHub issue type + labels + body template)

2 participants