Skip to content

Commit 44759be

Browse files
committed
Make live API requests
1 parent 135daf6 commit 44759be

3 files changed

Lines changed: 72 additions & 98 deletions

File tree

index.html

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,15 @@ <h2 class="section-title">Your repo, your rules</h2>
116116
</div>
117117

118118
<div id="errorAlert" class="error-alert hidden">
119-
<svg class="error-icon" viewBox="0 0 24 24">
120-
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" fill="#F44336"/>
121-
</svg>
122-
<span id="errorMessage">Something went wrong. Please try again.</span>
119+
<div class="error-header">
120+
<svg class="error-icon" viewBox="0 0 24 24">
121+
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z" fill="#F44336"/>
122+
</svg>
123+
<span class="error-title">Rule not supported</span>
124+
</div>
125+
<div class="error-content">
126+
<p id="errorMessage">Something went wrong. Please try again.</p>
127+
</div>
123128
</div>
124129
</div>
125130
</div>

script.js

Lines changed: 41 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ let isLoading = false;
1616
let currentRule = '';
1717

1818
// API Configuration
19-
const API_ENDPOINT = 'https://api.example.com/generate-rule';
19+
const API_ENDPOINT = 'https://api.watchflow.dev/api/v1/rules/evaluate';
2020

2121
// Initialize the application
2222
document.addEventListener('DOMContentLoaded', function() {
@@ -89,102 +89,53 @@ async function handleAnalyzeClick() {
8989

9090
// Generate rule via API
9191
async function generateRule(description) {
92-
try {
93-
const response = await fetch(API_ENDPOINT, {
94-
method: 'POST',
95-
headers: {
96-
'Content-Type': 'application/json',
97-
},
98-
body: JSON.stringify({ description }),
99-
});
100-
101-
if (!response.ok) {
102-
throw new Error(`HTTP error! status: ${response.status}`);
103-
}
104-
105-
const data = await response.json();
106-
107-
if (!data.rule) {
108-
throw new Error('Invalid response format');
109-
}
110-
111-
return data.rule;
112-
113-
} catch (error) {
114-
// For demo purposes, return a mock rule if API fails
115-
if (error.message.includes('fetch')) {
116-
return generateMockRule(description);
92+
const response = await fetch(API_ENDPOINT, {
93+
method: 'POST',
94+
headers: {
95+
'Content-Type': 'application/json',
96+
'Accept': 'application/json',
97+
},
98+
body: JSON.stringify({
99+
rule_text: description,
100+
event_data: null
101+
}),
102+
});
103+
104+
if (!response.ok) {
105+
// Handle validation errors or other API errors
106+
if (response.status === 422) {
107+
const errorData = await response.json();
108+
throw new Error(`Validation error: ${errorData.detail || 'Invalid rule description format'}`);
117109
}
118-
throw error;
110+
throw new Error(`API error: ${response.status} ${response.statusText}`);
119111
}
120-
}
121-
122-
// Generate mock rule for demonstration
123-
function generateMockRule(description) {
124-
const mockRules = {
125-
'pr title': `name: PR Title Format
126-
description: ${description}
127-
on:
128-
pull_request:
129-
types: [opened, edited, synchronize]
130-
rules:
131-
- name: Check PR title format
132-
condition: |
133-
pull_request.title matches /^[A-Z]+-\\d+: .+$/
134-
message: "PR title must follow the pattern PROJ-123: Description"
135-
severity: error`,
136-
137-
'commit': `name: Commit Message Format
138-
description: ${description}
139-
on:
140-
push:
141-
branches: [main, develop]
142-
rules:
143-
- name: Check commit message format
144-
condition: |
145-
commit.message matches /^(feat|fix|docs|style|refactor|test|chore): .+$/
146-
message: "Commit messages must follow conventional commits format"
147-
severity: error`,
148-
149-
'approval': `name: Approval Requirements
150-
description: ${description}
151-
on:
152-
pull_request:
153-
types: [opened, review_requested]
154-
rules:
155-
- name: Check approval requirements
156-
condition: |
157-
pull_request.author not in pull_request.reviewers
158-
message: "Pull requests cannot be approved by the author"
159-
severity: error`,
160-
161-
'default': `name: Custom Rule
162-
description: ${description}
163-
on:
164-
pull_request:
165-
types: [opened, edited, synchronize]
166-
rules:
167-
- name: Custom validation
168-
condition: |
169-
# Add your custom validation logic here
170-
true
171-
message: "Custom validation message"
172-
severity: warning`
173-
};
174112

175-
const lowerDescription = description.toLowerCase();
113+
const data = await response.json();
114+
115+
if (!data) {
116+
throw new Error('Empty response from API');
117+
}
118+
119+
// Check if the rule is supported
120+
if (!data.supported) {
121+
const reason = data.feedback || 'This type of rule is not supported by Watchflow';
122+
throw new Error(reason);
123+
}
176124

177-
if (lowerDescription.includes('title') || lowerDescription.includes('pr')) {
178-
return mockRules['pr title'];
179-
} else if (lowerDescription.includes('commit')) {
180-
return mockRules['commit'];
181-
} else if (lowerDescription.includes('approval') || lowerDescription.includes('review')) {
182-
return mockRules['approval'];
183-
} else {
184-
return mockRules['default'];
125+
// Extract the YAML snippet from the response
126+
if (data.snippet) {
127+
// Remove the markdown code block wrapper if present
128+
let yaml = data.snippet;
129+
if (yaml.startsWith('```yaml\n')) {
130+
yaml = yaml.replace(/^```yaml\n/, '').replace(/\n```$/, '');
131+
}
132+
return yaml;
185133
}
134+
135+
throw new Error('No rule snippet found in API response');
186136
}
187137

138+
188139
// Handle download button click
189140
function handleDownloadClick() {
190141
if (!currentRule) return;

style.css

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -450,13 +450,10 @@ body::after {
450450
}
451451

452452
.error-alert {
453-
display: flex;
454-
align-items: center;
455-
gap: 0.75rem;
456453
background: #FFEBEE;
457454
border: 3px solid var(--error-color);
458455
border-radius: 12px;
459-
padding: 1rem;
456+
padding: 1.5rem;
460457
margin-top: 1rem;
461458
box-shadow: 4px 4px 0 var(--shadow-color);
462459
opacity: 0;
@@ -468,6 +465,27 @@ body::after {
468465
display: none;
469466
}
470467

468+
.error-header {
469+
display: flex;
470+
align-items: center;
471+
gap: 0.75rem;
472+
margin-bottom: 1rem;
473+
}
474+
475+
.error-title {
476+
font-weight: 700;
477+
font-size: 1.1rem;
478+
color: var(--error-color);
479+
}
480+
481+
.error-content {
482+
color: var(--text-secondary);
483+
line-height: 1.5;
484+
}
485+
486+
.error-content p {
487+
margin: 0;
488+
}
471489

472490
.error-icon {
473491
width: 24px;

0 commit comments

Comments
 (0)