package component import ( "bytes" "context" "forge.cadoles.com/wpetit/clearcase/internal/core/model" "forge.cadoles.com/wpetit/clearcase/internal/http/form" common "forge.cadoles.com/wpetit/clearcase/internal/http/handler/webui/common/component" "github.com/pkg/errors" "github.com/yuin/goldmark" "log/slog" "strings" ) type PullRequestPageVModel struct { PullRequestURL string SummaryForm *form.Form PullRequestForm *form.Form PullRequestTips string Projects []*model.Project PullRequests []*model.PullRequest SelectedProjectID string SelectedPullRequestID string } const summaryPlaceholder = ` Décrivez rapidement les modifications apportées par la PR, ClearCase utilisera le modèle de PR présent dans le dépôt (ou un modèle par défaut) afin de générer une version mise en forme et complétée. Afin de fournir plus d'information de contexte au LLM, vous pouvez faire référence à d'autres tickets du dépôt via un ou plusieurs '#' et/ou des chemins vers des fichiers présents dans celui ci. ` const bodyPlaceholder = ` Une fois votre PR générée, vous pourrez l'éditer puis la créer directement en cliquant sur le bouton 'Mettre à jour' ci-dessous. ` const prTemplatePlaceholder = ` Vous pouvez surcharger le modèle de PR fourni par le projet en remplissant ce champ. ` func NewPullRequestSummaryForm() *form.Form { return form.New( form.NewField( "project", form.Attrs{}, form.NonEmpty("Ce champ ne doit pas être vide."), ), form.NewField( "pullrequest", form.Attrs{}, form.NonEmpty("Ce champ ne doit pas être vide."), ), form.NewField( "summary", form.Attrs{ "type": "textarea", "rows": "20", "placeholder": strings.TrimSpace(summaryPlaceholder), }, form.NonEmpty("Ce champ ne doit pas être vide."), ), form.NewField( "template", form.Attrs{ "type": "textarea", "rows": "20", "placeholder": strings.TrimSpace(prTemplatePlaceholder), }, ), ) } func NewPullRequestForm() *form.Form { return form.New( form.NewField( "title", form.Attrs{ "type": "text", "placeholder": "Écrivez le résumé de votre demande et cliquez sur 'Générer' pour remplir automatiquement ces champs.", }, form.NonEmpty("Ce champ ne doit pas être vide."), ), form.NewField( "body", form.Attrs{ "type": "textarea", "rows": "20", "placeholder": strings.TrimSpace(bodyPlaceholder), }, form.NonEmpty("Ce champ ne doit pas être vide."), ), ) } templ PullRequestPage(vmodel PullRequestPageVModel) { @common.AppPage(common.WithPageOptions( common.WithTitle("Éditer une PR"), )) { if vmodel.PullRequestURL != "" {

Pull Request modifiée !

Votre PR a été mise à jour et est disponible à l'adresse suivante: { vmodel.PullRequestURL }.
@templ.JSFuncCall("clearSummary", vmodel.SelectedProjectID) @templ.JSFuncCall("openPR", vmodel.PullRequestURL) }

Résumé de la PR

@common.FormSelect( vmodel.SummaryForm, "pr-project", "project", "Projet", common.WithOptions(projectsToOptions(vmodel.Projects)...), common.WithAttrs( "hx-get", string(common.CurrentURL(ctx, common.WithoutValues("project", "*"))), "hx-target", "body", "hx-push-url", "true", ), ) @common.FormSelect( vmodel.SummaryForm, "pr-pullrequest", "pullrequest", "PR", common.WithOptions(pullRequestsToOptions(vmodel.PullRequests)...), common.WithAttrs( "hx-get", string(common.CurrentURL(ctx, common.WithoutValues("pullrequest", "*"))), "hx-target", "body", "hx-push-url", "true", ), ) @common.FormTextarea( vmodel.SummaryForm, "pr-summary", "summary", "Résumé", common.WithTextareaAttrs( "hx-on:change", "onSummaryChange(event)", ), )
Paramètres avancés @common.FormTextarea( vmodel.SummaryForm, "pr-template", "template", "Surcharger le modèle de demande", common.WithTextareaAttrs( "hx-on:change", "onPullRequestTemplateChange(event)", ), )

Votre PR

@common.FormField(vmodel.PullRequestForm, "pr-title", "title", "Titre") @common.FormTextarea(vmodel.PullRequestForm, "pr-body", "body", "Corps")
if vmodel.PullRequestTips != "" { {{ html := markdownToHTML(ctx, vmodel.PullRequestTips) }} if html != "" {

Questionnements

Utilisez ces quelques questions pour réfléchir aux éléments d'informations nécessaire à la bonne rédaction de votre PR:

@templ.Raw(html)
} } } } func projectsToOptions(projects []*model.Project) []string { options := make([]string, 0, len(projects)) options = append(options, "", "") for _, p := range projects { options = append(options, p.Name, p.ID) } return options } func pullRequestsToOptions(pullRequests []*model.PullRequest) []string { options := make([]string, 0, len(pullRequests)) options = append(options, "", "") for _, pr := range pullRequests { options = append(options, pr.Title, pr.ID) } return options } func markdownToHTML(ctx context.Context, text string) string { var buff bytes.Buffer if err := goldmark.Convert([]byte(text), &buff); err != nil { slog.ErrorContext(ctx, "could not convert markdown to html", slog.Any("error", errors.WithStack(err))) return "" } return buff.String() }