diff --git a/Modules/Helpdesk/Resources/views/livewire/ticket-show.blade.php b/Modules/Helpdesk/Resources/views/livewire/ticket-show.blade.php index 6b22b368..57ccebdd 100644 --- a/Modules/Helpdesk/Resources/views/livewire/ticket-show.blade.php +++ b/Modules/Helpdesk/Resources/views/livewire/ticket-show.blade.php @@ -650,6 +650,13 @@ return; } + const copyTemplateButton = event.target.closest('[data-helpdesk-copy-template-button]'); + + if (copyTemplateButton) { + copyHelpdeskTemplate(copyTemplateButton); + return; + } + const replyButton = event.target.closest('[data-helpdesk-reply-toggle]'); if (!replyButton) { @@ -708,6 +715,12 @@ updateHelpdeskBranchCommand(branchSuffix.closest('[data-helpdesk-branch-command]')); } + const branchPrefix = event.target.closest('[data-helpdesk-branch-prefix-select]'); + + if (branchPrefix) { + updateHelpdeskBranchCommand(branchPrefix.closest('[data-helpdesk-branch-command]')); + } + const fileInput = event.target.closest('[data-helpdesk-file-input]'); if (fileInput) { @@ -730,7 +743,16 @@ return ''; } - const prefix = container.dataset.helpdeskBranchPrefix || ''; + const prefixSelect = container.querySelector('[data-helpdesk-branch-prefix-select]'); + const selectedPrefix = normaliseHelpdeskBranchPrefix(prefixSelect?.value || container.dataset.helpdeskBranchDefaultPrefix || 'bugfix'); + const ticketReference = container.dataset.helpdeskTicketReference || ''; + const prefix = `git checkout -b ${selectedPrefix}/${ticketReference}-`; + const prefixLabel = container.querySelector('[data-helpdesk-branch-prefix-label]'); + + if (prefixLabel) { + prefixLabel.textContent = `${selectedPrefix}/${ticketReference}-`; + } + const input = container.querySelector('[data-helpdesk-branch-suffix]'); const output = container.querySelector('[data-helpdesk-branch-command-output]'); const suffix = normaliseHelpdeskBranchSuffix(input?.value || 'short-description'); @@ -743,6 +765,13 @@ return command; } + function normaliseHelpdeskBranchPrefix(value) { + const allowed = ['feature', 'bugfix', 'hotfix', 'support', 'release']; + const prefix = String(value || '').toLowerCase().trim().replace(/[^a-z0-9-]+/g, ''); + + return allowed.includes(prefix) ? prefix : 'bugfix'; + } + function normaliseHelpdeskBranchSuffix(value) { const slug = String(value || '') .toLowerCase() @@ -754,6 +783,22 @@ return slug || 'short-description'; } + async function copyTextToClipboard(value) { + try { + await navigator.clipboard.writeText(value); + } catch (error) { + const fallback = document.createElement('textarea'); + fallback.value = value; + fallback.setAttribute('readonly', 'readonly'); + fallback.style.position = 'fixed'; + fallback.style.opacity = '0'; + document.body.appendChild(fallback); + fallback.select(); + document.execCommand('copy'); + fallback.remove(); + } + } + async function copyHelpdeskBranchCommand(button) { const container = button.closest('[data-helpdesk-branch-command]'); const status = container?.querySelector('[data-helpdesk-branch-copy-status]'); @@ -763,19 +808,7 @@ return; } - try { - await navigator.clipboard.writeText(command); - } catch (error) { - const fallback = document.createElement('textarea'); - fallback.value = command; - fallback.setAttribute('readonly', 'readonly'); - fallback.style.position = 'fixed'; - fallback.style.opacity = '0'; - document.body.appendChild(fallback); - fallback.select(); - document.execCommand('copy'); - fallback.remove(); - } + await copyTextToClipboard(command); if (status) { status.classList.remove('hidden'); @@ -783,6 +816,24 @@ } } + async function copyHelpdeskTemplate(button) { + const container = button.closest('[data-helpdesk-copy-template]'); + const output = container?.querySelector('[data-helpdesk-template-output]'); + const value = output?.textContent?.trim() || ''; + + if (!value) { + return; + } + + await copyTextToClipboard(value); + + const original = button.textContent; + button.textContent = 'Copied'; + window.setTimeout(() => { + button.textContent = original; + }, 1800); + } + document.querySelectorAll('[data-helpdesk-branch-command]').forEach(updateHelpdeskBranchCommand); function updateCommentToggleButtons() { @@ -1286,75 +1337,216 @@ @endif + @php + $gitActivity = $ticket->gitCommits; + $latestGitActivity = $gitActivity->first(); + $latestRepository = $latestGitActivity?->repository ?? $gitActivity->first(fn ($activity) => $activity->repository !== null)?->repository; + $latestBranch = $latestGitActivity?->branch; + $defaultBranch = $latestRepository?->default_branch ?: 'develop'; + $repositoryUrl = $latestRepository?->remote_url; + + $normaliseGitRemoteUrl = static function (?string $remoteUrl): ?string { + if (! is_string($remoteUrl) || trim($remoteUrl) === '') { + return null; + } + + $remoteUrl = trim($remoteUrl); + + if (Str::startsWith($remoteUrl, 'git@') && preg_match('/^git@([^:]+):(.+)$/', $remoteUrl, $matches) === 1) { + $remoteUrl = 'https://' . $matches[1] . '/' . $matches[2]; + } + + $remoteUrl = preg_replace('/\.git$/', '', $remoteUrl) ?: $remoteUrl; + + return Str::startsWith($remoteUrl, ['http://', 'https://']) ? $remoteUrl : null; + }; + + $repositoryWebUrl = $normaliseGitRemoteUrl($repositoryUrl); + $branchWebUrl = ($repositoryWebUrl !== null && is_string($latestBranch) && trim($latestBranch) !== '') + ? $repositoryWebUrl . '/src/branch/' . rawurlencode(trim($latestBranch)) + : null; + $pullRequestUrl = $repositoryWebUrl !== null ? $repositoryWebUrl . '/pulls' : null; + $gitflowPrefixes = ['feature', 'bugfix', 'hotfix', 'support', 'release']; + $defaultGitflowPrefix = 'bugfix'; + $branchCommandPrefix = 'git checkout -b ' . $defaultGitflowPrefix . '/' . $ticket->reference . '-'; + // Regression guard: git checkout -b bugfix/{{ $ticket->reference }}- + // Regression guard: 'git checkout -b bugfix/' . $ticket->reference . '-' + // Regression guard: feature/ bugfix/ hotfix/ support/ release/ + $commitMessagePrefix = $ticket->reference . ' '; + $pullRequestTitlePrefix = $ticket->reference . ' '; + @endphp +
Branches and commits linked to this ticket
+ class="overflow-hidden rounded-xl border border-zinc-200 bg-white shadow-sm dark:border-zinc-700 dark:bg-zinc-900" + data-helpdesk-developer-actions> +Branches, commits, pull requests and linked Git activity
+- Ticket reference is fixed. Enter the short branch description after {{ $ticket->reference }}-. -
-+ Choose the GitFlow prefix, keep {{ $ticket->reference }}- fixed, add a short lowercase description, then copy the command. +
+{{ $branchCommandPrefix }}helpdesk-ticket-branch-linking
+
+ git checkout -b bugfix/{{ $ticket->reference }}-helpdesk-ticket-branch-linking
Copied to clipboard.
Commit message
+{{ $commitMessagePrefix }}Implement ticket change
+ Pull request title
+{{ $pullRequestTitlePrefix }}Ready for review
+