Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -193,28 +193,28 @@ <h2 class="visually-hidden" id="workflow-recipe-title">Agentic workflow wizard</
<div class="recipe-item">
<button class="recipe-clause progress-step" type="button" data-step="6" aria-expanded="false" aria-controls="step-6" disabled>
<span class="step-indicator" aria-hidden="true">6</span>
<span class="recipe-key recipe-key-preview">Finish</span>
<span class="recipe-value">copy your prompt and run it</span>
<span class="recipe-key recipe-key-preview" id="finish-step-label">Finish</span>
<span class="recipe-value" id="finish-step-description">copy your prompt and run it</span>
</button>
<section class="wizard-step" id="step-6">

<div class="preview-container prompt-panel">
<div class="finish-cta">
<div class="finish-icon" aria-hidden="true"><svg class="octicon" aria-hidden="true"><use href="#octicon-check"></use></svg></div>
<div class="finish-cta-copy">
<h2>Your workflow generator prompt is ready</h2>
<p>Copy it, then paste it into your agent from the repository you want to automate.</p>
<h2 id="finish-title">Your workflow generator prompt is ready</h2>
<p id="finish-message">Copy it, then paste it into your agent from the repository you want to automate.</p>
</div>
<button class="btn btn-primary btn-copy-prompt" id="btn-copy" type="button">Copy prompt</button>
<span class="visually-hidden" id="copy-status" role="status" aria-live="polite"></span>
</div>

<div class="prompt-card">
<div class="prompt-card-header">
<span>Prompt preview</span>
<span class="prompt-card-hint">Review before copying</span>
<span id="finish-preview-label">Prompt preview</span>
<span class="prompt-card-hint" id="finish-preview-hint">Review before copying</span>
</div>
<div class="prompt-preview" aria-label="Generated prompt preview">
<div class="prompt-preview" id="finish-preview" aria-label="Generated prompt preview">
<div class="preview-code" id="preview-code"></div>
</div>
</div>
Expand Down Expand Up @@ -258,7 +258,7 @@ <h2>Your workflow generator prompt is ready</h2>

<dialog class="copy-modal" id="copy-modal" aria-labelledby="copy-modal-title" aria-describedby="copy-modal-description">
<div class="copy-modal-card">
<button class="copy-modal-close" type="button" data-copy-modal-close aria-label="Close">
<button class="copy-modal-close" id="copy-modal-close" type="button" data-copy-modal-close aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<div class="copy-modal-celebration" aria-hidden="true">
Expand All @@ -269,17 +269,17 @@ <h2>Your workflow generator prompt is ready</h2>
<svg class="octicon" aria-hidden="true"><use href="#octicon-check"></use></svg>
</div>
</div>
<p class="copy-modal-eyebrow">Prompt copied</p>
<p class="copy-modal-eyebrow" id="copy-modal-eyebrow">Prompt copied</p>
<h2 id="copy-modal-title">Your workflow is one prompt away</h2>
<p id="copy-modal-description">Open your coding agent from the repository you want to automate, then paste the prompt to generate your agentic workflow.</p>
<div class="copy-modal-next-step">
<svg class="octicon" aria-hidden="true"><use href="#octicon-terminal"></use></svg>
<div>
<strong>Run it in your repository</strong>
<span>Your agent will take it from there.</span>
<strong id="copy-modal-next-step-title">Run it in your repository</strong>
<span id="copy-modal-next-step-description">Your agent will take it from there.</span>
</div>
</div>
<button class="btn copy-modal-action" type="button" data-copy-modal-close>Got it</button>
<button class="btn copy-modal-action" id="copy-modal-action" type="button" data-copy-modal-close>Got it</button>
</div>
</dialog>
<script type="module" src="./js/main.js"></script>
Expand Down
4 changes: 2 additions & 2 deletions src/js/ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -792,9 +792,9 @@ function showCopyFailure() {
const status = document.getElementById('copy-status');
clearTimeout(copyFeedbackTimer);
button.dataset.defaultLabel ||= button.textContent;
button.textContent = 'Copy failed — try again';
button.textContent = button.dataset.failureLabel || 'Copy failed — try again';
button.classList.add('copy-error');
status.textContent = 'Prompt could not be copied. Please try again.';
status.textContent = status.dataset.failureMessage || 'Prompt could not be copied. Please try again.';
copyFeedbackTimer = setTimeout(resetCopyFeedback, 3000);
}

Expand Down
46 changes: 46 additions & 0 deletions src/js/wizard-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,25 @@ const LANDING_ELEMENTS = {
outputs_label: 'landing-outputs-label'
};

const FINISH_ELEMENTS = {
step_label: 'finish-step-label',
step_description: 'finish-step-description',
title: 'finish-title',
message: 'finish-message',
copy_button: 'btn-copy',
preview_label: 'finish-preview-label',
preview_hint: 'finish-preview-hint'
};

const COPY_SUCCESS_ELEMENTS = {
eyebrow: 'copy-modal-eyebrow',
title: 'copy-modal-title',
description: 'copy-modal-description',
next_step_title: 'copy-modal-next-step-title',
next_step_description: 'copy-modal-next-step-description',
action: 'copy-modal-action'
};

const FOOTER_ELEMENTS = {
source: ['footer-source', 'footer-source-label'],
report_issue: ['footer-report-issue', 'footer-report-issue'],
Expand Down Expand Up @@ -68,6 +87,33 @@ export function applyPageContent(config, configUrl) {
const landing = config && config.landing ? config.landing : {};
Object.entries(LANDING_ELEMENTS).forEach(([key, id]) => setText(id, landing[key]));

const finish = config && config.finish ? config.finish : {};
Object.entries(FINISH_ELEMENTS).forEach(([key, id]) => setText(id, finish[key]));
const copyButton = document.getElementById('btn-copy');
if (copyButton) {
if (typeof finish.copy_button === 'string') {
copyButton.dataset.defaultLabel = finish.copy_button;
}
if (typeof finish.copy_failure_button === 'string') {
copyButton.dataset.failureLabel = finish.copy_failure_button;
}
}
const copyStatus = document.getElementById('copy-status');
if (copyStatus && typeof finish.copy_failure_status === 'string') {
copyStatus.dataset.failureMessage = finish.copy_failure_status;
}
const preview = document.getElementById('finish-preview');
if (preview && typeof finish.preview_aria_label === 'string') {
preview.setAttribute('aria-label', finish.preview_aria_label);
}

const copySuccess = config && config.copy_success ? config.copy_success : {};
Object.entries(COPY_SUCCESS_ELEMENTS).forEach(([key, id]) => setText(id, copySuccess[key]));
const closeButton = document.getElementById('copy-modal-close');
if (closeButton && typeof copySuccess.close_label === 'string') {
closeButton.setAttribute('aria-label', copySuccess.close_label);
}

const footer = config && config.footer ? config.footer : {};
Object.entries(FOOTER_ELEMENTS).forEach(([key, ids]) => {
const item = footer[key] || {};
Expand Down
21 changes: 21 additions & 0 deletions src/wizard.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,27 @@
"agent_label": "Agent",
"outputs_label": "Safe outputs"
},
"finish": {
"step_label": "Finish",
"step_description": "copy your prompt and run it",
"title": "Your workflow generator prompt is ready",
"message": "Copy it, then paste it into your agent from the repository you want to automate.",
"copy_button": "Copy prompt",
"copy_failure_button": "Copy failed — try again",
"copy_failure_status": "Prompt could not be copied. Please try again.",
"preview_label": "Prompt preview",
"preview_hint": "Review before copying",
"preview_aria_label": "Generated prompt preview"
},
"copy_success": {
"close_label": "Close",
"eyebrow": "Prompt copied",
"title": "Your workflow is one prompt away",
"description": "Open your coding agent from the repository you want to automate, then paste the prompt to generate your agentic workflow.",
"next_step_title": "Run it in your repository",
"next_step_description": "Your agent will take it from there.",
"action": "Got it"
},
"footer": {
"source": {
"url": "https://github.com/githubnext/gh-aw-wizard",
Expand Down
8 changes: 6 additions & 2 deletions test/a11y.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,12 @@ describe('Copy prompt success modal', () => {
});

it('tells users to run the copied prompt in their repository', () => {
expect(html).toContain('Open your coding agent from the repository you want to automate');
expect(html).toContain('<strong>Run it in your repository</strong>');
expect(wizard.copy_success.description).toContain(
'Open your coding agent from the repository you want to automate'
);
expect(wizard.copy_success.next_step_title).toBe('Run it in your repository');
expect(html).toContain('id="copy-modal-description"');
expect(html).toContain('id="copy-modal-next-step-title"');
});

it('announces clipboard failures without opening the success modal', () => {
Expand Down
32 changes: 32 additions & 0 deletions test/wizard-config.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ describe('wizard configuration', () => {
const elements = {
'landing-title': { textContent: '' },
'landing-button-label': { textContent: '' },
'finish-title': { textContent: '' },
'btn-copy': { textContent: '', dataset: {} },
'copy-status': { textContent: '', dataset: {} },
'finish-preview': { setAttribute: vi.fn() },
'copy-modal-title': { textContent: '' },
'copy-modal-close': { setAttribute: vi.fn() },
'footer-source': { href: '' },
'footer-source-label': { textContent: '' },
'footer-security': { href: '', textContent: '' }
Expand All @@ -70,6 +76,17 @@ describe('wizard configuration', () => {
title: 'Build an automation',
button: 'Start building'
},
finish: {
title: 'Your custom prompt is ready',
copy_button: 'Copy custom prompt',
copy_failure_button: 'Try copying again',
copy_failure_status: 'The custom prompt was not copied.',
preview_aria_label: 'Custom prompt preview'
},
copy_success: {
close_label: 'Dismiss',
title: 'Custom prompt copied'
},
footer: {
source: {
url: './source',
Expand All @@ -84,6 +101,21 @@ describe('wizard configuration', () => {

expect(elements['landing-title'].textContent).toBe('Build an automation');
expect(elements['landing-button-label'].textContent).toBe('Start building');
expect(elements['finish-title'].textContent).toBe('Your custom prompt is ready');
expect(elements['btn-copy']).toMatchObject({
textContent: 'Copy custom prompt',
dataset: {
defaultLabel: 'Copy custom prompt',
failureLabel: 'Try copying again'
}
});
expect(elements['copy-status'].dataset.failureMessage).toBe('The custom prompt was not copied.');
expect(elements['finish-preview'].setAttribute).toHaveBeenCalledWith(
'aria-label',
'Custom prompt preview'
);
expect(elements['copy-modal-title'].textContent).toBe('Custom prompt copied');
expect(elements['copy-modal-close'].setAttribute).toHaveBeenCalledWith('aria-label', 'Dismiss');
expect(elements['footer-source']).toMatchObject({
href: 'https://custom.example/config/source'
});
Expand Down
Loading