|
4 | 4 | *--------------------------------------------------------------------------------------------*/ |
5 | 5 |
|
6 | 6 | import { basename } from 'path'; |
| 7 | +import * as yaml from 'js-yaml'; |
7 | 8 | import * as vscode from 'vscode'; |
8 | 9 | import { CurrentIssue } from './currentIssue'; |
9 | 10 | import { IssueCompletionProvider } from './issueCompletionProvider'; |
@@ -56,6 +57,7 @@ import { |
56 | 57 | PermalinkInfo, |
57 | 58 | pushAndCreatePR, |
58 | 59 | USER_EXPRESSION, |
| 60 | + YamlIssueTemplate, |
59 | 61 | } from './util'; |
60 | 62 | import { truncate } from '../common/utils'; |
61 | 63 | import { OctokitCommon } from '../github/common'; |
@@ -1250,13 +1252,77 @@ ${options?.body ?? ''}\n |
1250 | 1252 | } |
1251 | 1253 |
|
1252 | 1254 | private getDataFromTemplate(template: string): IssueTemplate { |
| 1255 | + // Try to parse as YAML first (YAML templates have a different structure) |
| 1256 | + try { |
| 1257 | + const parsed = yaml.load(template); |
| 1258 | + if (parsed && typeof parsed === 'object' && (parsed as YamlIssueTemplate).name) { |
| 1259 | + // This is a YAML template |
| 1260 | + return this.parseYamlTemplate(parsed as YamlIssueTemplate); |
| 1261 | + } |
| 1262 | + } catch (e) { |
| 1263 | + // Not a valid YAML, continue to Markdown parsing |
| 1264 | + } |
| 1265 | + |
| 1266 | + // Parse as Markdown frontmatter template |
1253 | 1267 | const title = template.match(/title:\s*(.*)/)?.[1]?.replace(/^["']|["']$/g, ''); |
1254 | 1268 | const name = template.match(/name:\s*(.*)/)?.[1]?.replace(/^["']|["']$/g, ''); |
1255 | 1269 | const about = template.match(/about:\s*(.*)/)?.[1]?.replace(/^["']|["']$/g, ''); |
1256 | 1270 | const body = template.match(/---([\s\S]*)---([\s\S]*)/)?.[2]; |
1257 | 1271 | return { title, name, about, body }; |
1258 | 1272 | } |
1259 | 1273 |
|
| 1274 | + private parseYamlTemplate(parsed: YamlIssueTemplate): IssueTemplate { |
| 1275 | + const name = parsed.name; |
| 1276 | + const about = parsed.description || parsed.about; |
| 1277 | + const title = parsed.title; |
| 1278 | + |
| 1279 | + // Convert YAML body fields to markdown |
| 1280 | + let body = ''; |
| 1281 | + if (parsed.body && Array.isArray(parsed.body)) { |
| 1282 | + for (const field of parsed.body) { |
| 1283 | + if (field.type === 'markdown' && field.attributes?.value) { |
| 1284 | + body += field.attributes.value + '\n\n'; |
| 1285 | + } else if (field.type === 'textarea' && field.attributes?.label) { |
| 1286 | + body += `## ${field.attributes.label}\n\n`; |
| 1287 | + if (field.attributes.description) { |
| 1288 | + body += `${field.attributes.description}\n\n`; |
| 1289 | + } |
| 1290 | + if (field.attributes.placeholder) { |
| 1291 | + body += `${field.attributes.placeholder}\n\n`; |
| 1292 | + } else if (field.attributes.value) { |
| 1293 | + body += `${field.attributes.value}\n\n`; |
| 1294 | + } |
| 1295 | + } else if (field.type === 'input' && field.attributes?.label) { |
| 1296 | + body += `## ${field.attributes.label}\n\n`; |
| 1297 | + if (field.attributes.description) { |
| 1298 | + body += `${field.attributes.description}\n\n`; |
| 1299 | + } |
| 1300 | + if (field.attributes.placeholder) { |
| 1301 | + body += `${field.attributes.placeholder}\n\n`; |
| 1302 | + } |
| 1303 | + } else if (field.type === 'dropdown' && field.attributes?.label) { |
| 1304 | + body += `## ${field.attributes.label}\n\n`; |
| 1305 | + if (field.attributes.description) { |
| 1306 | + body += `${field.attributes.description}\n\n`; |
| 1307 | + } |
| 1308 | + if (field.attributes.options && Array.isArray(field.attributes.options)) { |
| 1309 | + body += field.attributes.options.map((opt: string) => `- ${opt}`).join('\n') + '\n\n'; |
| 1310 | + } |
| 1311 | + } else if (field.type === 'checkboxes' && field.attributes?.label) { |
| 1312 | + body += `## ${field.attributes.label}\n\n`; |
| 1313 | + if (field.attributes.description) { |
| 1314 | + body += `${field.attributes.description}\n\n`; |
| 1315 | + } |
| 1316 | + if (field.attributes.options && Array.isArray(field.attributes.options)) { |
| 1317 | + body += field.attributes.options.map((opt: { label?: string } | string) => `- [ ] ${typeof opt === 'string' ? opt : opt.label || ''}`).join('\n') + '\n\n'; |
| 1318 | + } |
| 1319 | + } |
| 1320 | + } |
| 1321 | + } |
| 1322 | + |
| 1323 | + return { title, name, about, body: body.trim() || undefined }; |
| 1324 | + } |
| 1325 | + |
1260 | 1326 | private async doCreateIssue( |
1261 | 1327 | document: vscode.TextDocument | undefined, |
1262 | 1328 | newIssue: NewIssue | undefined, |
|
0 commit comments