Skip to content

Commit 7838c54

Browse files
Merge pull request #41 from DSACMS/sachin/autoGeneration
Auto Generation Complete
2 parents 85d73b3 + 7482303 commit 7838c54

File tree

4 files changed

+295
-0
lines changed

4 files changed

+295
-0
lines changed

css/styles.css

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,59 @@ body {
44

55
textarea {
66
margin-bottom: 10px;
7+
}
8+
9+
#auto-generation {
10+
border-radius: 15px;
11+
padding: 20px;
12+
padding-bottom: 25px;
13+
margin-top: 20px;
14+
margin-bottom: 20px;
15+
background: lightgray;
16+
width: 100%;
17+
max-width: 800px;
18+
box-sizing: border-box;
19+
}
20+
21+
#github-url-form {
22+
margin-top: 25px;
23+
width: 100%;
24+
}
25+
26+
#repo-url {
27+
width: 100%;
28+
max-width: 750px;
29+
box-sizing: border-box;
30+
}
31+
32+
#repo-url-button {
33+
margin-top: 10px;
34+
border-radius: 5px;
35+
}
36+
37+
#notification {
38+
padding: 10px;
39+
margin-bottom: 15px;
40+
border-radius: 5px;
41+
position: relative;
42+
width: 100%;
43+
max-width: 800px;
44+
box-sizing: border-box;
45+
animation: slideDown 0.3s ease;
46+
}
47+
48+
#notification-message {
49+
margin: 0;
50+
padding-right: 20px;
51+
}
52+
53+
@keyframes slideDown {
54+
from {
55+
opacity: 0;
56+
transform: translateY(-10px);
57+
}
58+
to {
59+
opacity: 1;
60+
transform: translateY(0);
61+
}
762
}

index.html

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<html>
22
<head>
3+
<meta charset="utf-8">
34
<!-- USWDS not working -->
45
<!-- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"> -->
56
<!-- <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"> -->
@@ -24,6 +25,7 @@
2425
<!-- Render the form -->
2526
<script src="js/generateFormComponents.js"></script>
2627
<script src="js/formDataToJson.js"></script>
28+
<script src="js/autoGenerateFields.js"></script>
2729
<script type="text/javascript">
2830
createFormComponents()
2931
.then((components) => {
@@ -38,6 +40,7 @@
3840
},
3941
components: components,
4042
}).then(function (form) {
43+
window.formIOInstance = form;
4144
form.on("submit", function (submission) {
4245
console.log("form submission here:", submission);
4346
createCodeJson(submission.data);
@@ -51,12 +54,28 @@
5154
</head>
5255
<body>
5356
<div id="form-header"></div>
57+
58+
<div id="notification" style="display: none;">
59+
<p id="notification-message"></p>
60+
</div>
61+
62+
<div id="auto-generation">
63+
<p id="auto-generation-header"></p>
64+
<form id="github-url-form">
65+
<label for="repo-url">GitHub Repository URL</label><br>
66+
<input type="text" id="repo-url" name="repo-url"><br>
67+
<input type="submit" id="repo-url-button" value="Submit">
68+
</form>
69+
</div>
70+
5471
<div id="formio"></div>
72+
5573
<div id="output">
5674
<label for="json-result">Your JSON Metadata </label>
5775
<textarea class="form-control" rows="10" id="json-result" readonly></textarea>
5876
<button type="button" class="btn btn-outline" href="#" onclick="copyToClipboard(event)">Copy</button>
5977
<button type="button" class="btn btn-outline" href="#" onclick="downloadFile(event)">Download</button>
6078
</div>
79+
6180
</body>
6281
</html>

js/autoGenerateFields.js

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
// We wait for DOM to be fully loaded before initializing
2+
document.addEventListener("DOMContentLoaded", function() {
3+
setupFormHandler();
4+
setupNotificationSystem();
5+
});
6+
7+
// This works by creating an object with methods for different notification types of either error or success
8+
// Calling either of these methods calls the main functionality, show(), which manipulates the notification element in HTML
9+
// The show() method changes the element based on type and displays the message to the user
10+
// The hide() function makes sure that the notification fades away after 5 seconds
11+
const notificationSystem = {
12+
show: function(message, type = 'error') {
13+
const notification = document.getElementById('notification');
14+
const messageElement = document.getElementById('notification-message');
15+
16+
messageElement.textContent = message;
17+
18+
if (type === 'error') {
19+
notification.style.backgroundColor = '#f8d7da';
20+
notification.style.color = '#721c24';
21+
notification.style.border = '1px solid #f5c6cb';
22+
} else {
23+
notification.style.backgroundColor = '#d4edda';
24+
notification.style.color = '#155724';
25+
notification.style.border = '1px solid #c3e6cb';
26+
}
27+
28+
notification.style.display = 'block';
29+
setTimeout(() => {
30+
notification.style.opacity = '1';
31+
}, 10);
32+
33+
clearTimeout(this.timeout);
34+
this.timeout = setTimeout(() => this.hide(), 5000);
35+
},
36+
37+
hide: function() {
38+
const notification = document.getElementById('notification');
39+
notification.style.opacity = '0';
40+
setTimeout(() => {
41+
notification.style.display = 'none';
42+
}, 500);
43+
},
44+
45+
error: function(message) {
46+
this.show(message, 'error');
47+
},
48+
49+
success: function(message) {
50+
this.show(message, 'success');
51+
},
52+
};
53+
54+
function setupNotificationSystem() {
55+
const notification = document.getElementById('notification');
56+
if (notification) {
57+
notification.style.opacity = '0';
58+
notification.style.transition = 'opacity 0.5s ease';
59+
}
60+
}
61+
62+
function setupFormHandler() {
63+
const form = document.getElementById("github-url-form");
64+
65+
form.addEventListener("submit", async function(event) {
66+
event.preventDefault();
67+
68+
const submitButton = document.getElementById("repo-url-button");
69+
70+
submitButton.value = "Loading...";
71+
submitButton.disabled = true;
72+
73+
try {
74+
const repoURL = document.getElementById("repo-url").value;
75+
76+
if (repoURL.length == 0) {
77+
throw new Error("Please enter a GitHub repository URL");
78+
}
79+
80+
const repoInfo = extractGitHubInfo(repoURL);
81+
82+
if (!repoInfo) {
83+
throw new Error("Invalid GitHub URL format. Please enter a valid GitHub repository URL ->(https://github.com/username/repository)");
84+
}
85+
86+
const repositoryInfo = await getRepoInformation(repoInfo);
87+
const languages = await getRepoLanguages(repoInfo)
88+
89+
if (repositoryInfo) {
90+
preFillFields(repositoryInfo, languages);
91+
notificationSystem.success("Repository data loaded successfully!");
92+
} else {
93+
throw new Error("Could not fetch repository information. Please check the URL and try again.");
94+
}
95+
96+
} catch (error) {
97+
console.error(error.message);
98+
notificationSystem.error(error.message);
99+
} finally {
100+
submitButton.value = "Submit";
101+
submitButton.disabled = false;
102+
}
103+
});
104+
}
105+
106+
function extractGitHubInfo(url) {
107+
// Regex pattern to match GitHub URLs and extract org and repo
108+
const regex = /(?:https?:\/\/)?(?:www\.)?github\.com\/([^\/]+)\/([^\/\s]+)/;
109+
const match = url.match(regex);
110+
111+
if (match && match.length === 3) {
112+
return {
113+
organization: match[1],
114+
repository: match[2]
115+
};
116+
}
117+
118+
return null;
119+
}
120+
121+
async function getRepoInformation(repoInfo) {
122+
const baseURL = "https://api.github.com/repos/";
123+
const endpoint = `${baseURL}${repoInfo.organization}/${repoInfo.repository}`;
124+
125+
try {
126+
const response = await fetch(endpoint);
127+
128+
if (!response.ok) {
129+
throw new Error(`GitHub API error (${response.status}): ${response.statusText}`);
130+
}
131+
132+
return await response.json();
133+
} catch (error) {
134+
console.error("Fetch error:", error.message);
135+
}
136+
}
137+
138+
async function getRepoLanguages(repoInfo) {
139+
const endpoint = `https://api.github.com/repos/${repoInfo.organization}/${repoInfo.repository}/languages`
140+
141+
try {
142+
const response = await fetch(endpoint);
143+
144+
if (!response.ok) {
145+
throw new Error(`GitHub API error (${response.status}): ${response.statusText}`);
146+
}
147+
148+
return await response.json();
149+
} catch (error) {
150+
console.error("Fetch error:", error.message);
151+
}
152+
}
153+
154+
function preFillFields(repoData, languages) {
155+
if (!window.formIOInstance) {
156+
notificationSystem.error("Form interface not initialized. Please refresh and try again.");
157+
return;
158+
}
159+
160+
try {
161+
let licenses = [];
162+
if (repoData.license && repoData.license.spdx_id) {
163+
licenses.push({
164+
name: repoData.license.spdx_id,
165+
URL: repoData.html_url + "/blob/main/LICENSE"
166+
});
167+
}
168+
169+
const submission = {
170+
data: {
171+
name: repoData.name || '',
172+
description: repoData.description || '',
173+
174+
repositoryURL: repoData.html_url || '',
175+
repositoryVisibility: repoData.private ? "private" : "public",
176+
vcs: 'git',
177+
178+
permissions: {
179+
licenses: licenses
180+
},
181+
182+
reuseFrequency: {
183+
forks: repoData.forks_count || 0
184+
},
185+
186+
languages: Object.keys(languages) || [],
187+
188+
date: {
189+
created: repoData.created_at || '',
190+
lastModified: repoData.updated_at || '',
191+
metaDataLastUpdated: new Date().toISOString()
192+
},
193+
194+
tags: repoData.topics || [],
195+
196+
feedbackMechanisms: [repoData.html_url + "/issues"]
197+
}
198+
};
199+
200+
window.formIOInstance.setSubmission(submission);
201+
202+
} catch (error) {
203+
notificationSystem.error("Error filling form fields with repository data. Please refresh and try again");
204+
console.error("Form fill error:", error);
205+
}
206+
}
207+
208+
// This is global so we could use this throughout the website!
209+
window.showErrorNotification = function(message) {
210+
notificationSystem.error(message);
211+
};
212+
213+
window.showSuccessNotification = function(message) {
214+
notificationSystem.success(message);
215+
};

js/generateFormComponents.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,11 @@ function createFormHeading(title, description) {
250250
container.innerHTML = `<h1>${title}</h1>\n<h2>${description}</h2>`;
251251
}
252252

253+
function createAutoGenerationBox() {
254+
const container = document.getElementById("auto-generation-header")
255+
container.innerHTML = `<h3>Auto Generate Fields</h3> \n <h4> Please enter your repositories GitHub URL in order to automatically pre-fill some of the fields in this form! </h4> \n <h6> <i>This currently only works on <b>public</b> repositories</i> </h6>`
256+
}
257+
253258
// Iterates through each json field and creates component array for Form.io
254259
function createAllComponents(schema, prefix = ""){
255260
let components = [];
@@ -293,6 +298,7 @@ async function createFormComponents() {
293298
console.log("JSON Data:", jsonData);
294299

295300
createFormHeading(jsonData["title"], jsonData["description"]);
301+
createAutoGenerationBox()
296302

297303
components = createAllComponents(jsonData);
298304

0 commit comments

Comments
 (0)