go-gitea / gitea

Git with a cup of tea! Painless self-hosted all-in-one software development service, including Git hosting, code review, team collaboration, package registry and CI/CD
https://gitea.com
MIT License
43.82k stars 5.38k forks source link

Pre-fill new issue Labels from URL parameter #27341

Open h0lg opened 11 months ago

h0lg commented 11 months ago

Feature Description

If it was possible to pre-fill the Labels of a new issue from a URL parameter, I could link users from different components of a host app to the new issue form and help everyone involved to categorize the new issue correctly.

Correct categorization would allow further integration of issue tracking into a host app, like listing all open issues or FAQ for a component.

Imagine /issues/new?labels=kind/bug,area/dashboard which would pre-fill the Labels with kind/bug and area/dashboard.

Or /issues/new/choose?labels=area/dashboard which could patch the area/dashboard through and apply it on top of whatever labels are configured in the issue template the user chooses.

This would be an enhancement of the current behaviour which pre-fills the new issue form's title, body, milestone and project from URL parameters:

https://github.com/go-gitea/gitea/blob/3fcad582c9b9bfe66f4a346652f82b1aaf18430d/routers/web/repo/issue.go#L914-L950

I didn't find this behaviour described in the API docs, but something similar for creating new files.

eeyrjmr commented 11 months ago

Would issue templates be better instead as you can preset desired labels for different templates on a per-repo basis

h0lg commented 11 months ago

Would issue templates be better instead as you can preset desired labels for different templates on a per-repo basis

I don't thinks so. Let's say I have 50 distinct components or pages in my app. I'd rather create 50 labels to "map" them to my gitea repo than maintain 50 issue templates.

JakobDev commented 11 months ago

There are also repo owner who don't want that users can set labels themself. Your use case sounds very specific.

h0lg commented 10 months ago

There are also repo owner who don't want that users can set labels themself.

Good point - I can understand that setting them from the URL only works if you allow setting them at all. That's a different question though and can be answered on a per-repo or per-issue-type basis. Do you trust your users to be competent enough collaborators? The way I use gitea, I'd love their support in categorizing an issue properly by labelling/tagging. But note that pre-setting the labels from the URL would actually take that work off their hands most of the time. For sure, you may have to fix the labels sometimes when users apply the wrong ones. But you already have to do that if you do it manually.

Also note that the same argument could be applied to milestone and project - I imagine some repo owners don't want their users to set those, yet the API to do so from the URL exists.

Your use case sounds very specific.

Does it? Too specific for gitea? I feel this is not a far-fetched request considering the existence of similar APIs for similar process-related issue properties.

Also, the potential benefits of automating the labelling of issues to are huge:

h0lg commented 7 months ago

I successfully implemented this by adding a custom footer.tmpl with the following contents to my $GITEA_CUSTOM/templates/custom folder:

<script>
$(() => {
    // pre-selects new issue labels from query string parameter in the form of labels=kind/bug,area/dashboard
    if (location.pathname.endsWith('/issues/new')) { // only run on new issue page
        const urlParams = new URLSearchParams(location.search),
            joinedLabels = urlParams.get('labels');

        if (joinedLabels !== null) {
            const addedLabels = joinedLabels.split(','),

                // case-insensitive string comparison; see https://stackoverflow.com/a/2140723
                labelEquals = (a, b) => a.localeCompare(b, undefined, { sensitivity: 'accent' }) === 0,

                // find matching labels in dropdown menu by text
                $items = $('.menu .item .ui.label', '.select-label.dropdown')
                    .filter((_i, label) => addedLabels.some(added => labelEquals(added, label.innerText)))
                    .map((_i, label) => label.closest('.item')); // and select their closest items

            $items.trigger('click'); // selects matching items
        }
    }
});
</script>
h0lg commented 2 months ago

This updated script works for v1.22:

<script>
$(() => {
    // pre-selects new issue labels from query string parameter in the form of labels=kind/bug,area/dashboard
    if (location.pathname.endsWith('/issues/new')) { // only run on new issue page
        const urlParams = new URLSearchParams(location.search),
            joinedLabels = urlParams.get('labels');

        if (joinedLabels !== null) {
            const addedLabels = joinedLabels.split(','),

                // gets the innerText of the first descandant with class descendantClass
                getFirstText = (element, descendantClass) => element.getElementsByClassName(descendantClass)[0].innerText,

                // case-insensitive string comparison; see https://stackoverflow.com/a/2140723
                labelEquals = (a, b) => a.localeCompare(b, undefined, { sensitivity: 'accent' }) === 0,

                // find matching labels in dropdown menu by text
                $items = $('.menu .item .scope-parent', '.select-label.dropdown')
                    .filter((_i, label) => {
                        const synthdText = getFirstText(label, 'scope-left') + '/' + getFirstText(label, 'scope-right');
                        return addedLabels.some(added => labelEquals(added, synthdText));
                    })
                    .map((_i, label) => label.closest('.item')); // and select their closest items

            $items.trigger('click'); // selects matching items
        }
    }
});
</script>