Merge remote-tracking branch 'origin/master' into update-policy
This commit is contained in:
		
						commit
						60589967e1
					
				
					 5 changed files with 127 additions and 44 deletions
				
			
		|  | @ -1,13 +0,0 @@ | ||||||
| .signup |  | ||||||
| { |  | ||||||
|     height: 200px; |  | ||||||
|     width: 400px; |  | ||||||
|     position: fixed; |  | ||||||
|     left: 50%; |  | ||||||
|     margin-left: -150px; |  | ||||||
|     width:60%; |  | ||||||
| } |  | ||||||
| .border |  | ||||||
| { |  | ||||||
|     border-color:black; |  | ||||||
| } |  | ||||||
							
								
								
									
										10
									
								
								front/static/css/style.css
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								front/static/css/style.css
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,10 @@ | ||||||
|  | .fa-check-square { | ||||||
|  |     float: right; | ||||||
|  |     color: green; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fa-exclamation-triangle { | ||||||
|  |     float: right; | ||||||
|  |     color: orange; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @ -5,6 +5,7 @@ | ||||||
|     <meta name="viewport" content="width=device-width, initial-scale=1"> |     <meta name="viewport" content="width=device-width, initial-scale=1"> | ||||||
|     <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous"> |     <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous"> | ||||||
|     <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous"> |     <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous"> | ||||||
|  |     <link rel="stylesheet" href="css/style.css"> | ||||||
|     <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> |     <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> | ||||||
|     <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script> |     <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script> | ||||||
|     <script src="https://cdnjs.cloudflare.com/ajax/libs/classlist/1.2.20171210/classList.min.js"></script> |     <script src="https://cdnjs.cloudflare.com/ajax/libs/classlist/1.2.20171210/classList.min.js"></script> | ||||||
|  | @ -53,7 +54,6 @@ | ||||||
|                                 <tr> |                                 <tr> | ||||||
|                                     <th>Title</th> |                                     <th>Title</th> | ||||||
|                                     <th>Date Created</th> |                                     <th>Date Created</th> | ||||||
|                                     <th class="d-none d-lg-table-cell">State</th> |  | ||||||
|                                     <th class="d-none d-md-table-cell">Date Submitted</th> |                                     <th class="d-none d-md-table-cell">Date Submitted</th> | ||||||
|                                     <th>Action</th> |                                     <th>Action</th> | ||||||
|                                 </tr> |                                 </tr> | ||||||
|  |  | ||||||
|  | @ -9,12 +9,6 @@ function getEndpointDomain() { | ||||||
|     return "https://" + window.location.hostname + ":8444/"; |     return "https://" + window.location.hostname + ":8444/"; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function saveSectionCallback(parsedData, saveButton) { |  | ||||||
|     alert(JSON.stringify(parsedData)); |  | ||||||
|     saveButton.innerHTML = "Save"; |  | ||||||
|     saveButton.disabled = false; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| function makeAjaxRequest(method, url, callback, optional, payload) { | function makeAjaxRequest(method, url, callback, optional, payload) { | ||||||
|     const token = localStorage.getItem("token"); |     const token = localStorage.getItem("token"); | ||||||
|     const xhr = new XMLHttpRequest(); |     const xhr = new XMLHttpRequest(); | ||||||
|  | @ -57,6 +51,45 @@ function makeAjaxRequest(method, url, callback, optional, payload) { | ||||||
|     xhr.send(payload); |     xhr.send(payload); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | function updateSection(parsedData, saveButton) { | ||||||
|  |     const sectionIdStr = "#section-" + parsedData.id + "-"; | ||||||
|  |     const sectionState = document.querySelector(sectionIdStr + "state"); | ||||||
|  |     const collapseDiv = document.querySelector(sectionIdStr + "collapse"); | ||||||
|  | 
 | ||||||
|  |     // A completed section gets a header icon
 | ||||||
|  |     if (parsedData.completed) { | ||||||
|  |         const sectionAlert = collapseDiv.querySelector(".section-alert"); | ||||||
|  |         console.log(sectionAlert); | ||||||
|  |         if (sectionAlert) { | ||||||
|  |             collapseDiv.firstChild.removeChild(sectionAlert); | ||||||
|  |         } | ||||||
|  |         if (parsedData.rule_violations.length === 0) { | ||||||
|  |             // Complete with no rule violations
 | ||||||
|  |             sectionState.classList = "fas fa-check-square"; | ||||||
|  |             collapseDiv.className = "collapse"; | ||||||
|  |         } else { | ||||||
|  |             // Complete but with rule violations
 | ||||||
|  |             sectionState.classList = "fas fa-exclamation-triangle"; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     const cardFooter = createCardFooter(parsedData.rule_violations); | ||||||
|  |     if (collapseDiv.lastElementChild.classList.contains("card-footer")) { | ||||||
|  |         collapseDiv.removeChild(collapseDiv.lastElementChild); | ||||||
|  |         if (cardFooter) { | ||||||
|  |             collapseDiv.appendChild(cardFooter); | ||||||
|  |         } | ||||||
|  |     } else { | ||||||
|  |         if (cardFooter) { | ||||||
|  |             collapseDiv.appendChild(cardFooter); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     saveButton.innerHTML = "Save"; | ||||||
|  |     saveButton.disabled = false; | ||||||
|  |      | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Wraps a Bootstrap form group around a field
 | // Wraps a Bootstrap form group around a field
 | ||||||
| function createFormGroup(sectionIdStr, field) { | function createFormGroup(sectionIdStr, field) { | ||||||
|     const inputId = sectionIdStr + field.field_name; |     const inputId = sectionIdStr + field.field_name; | ||||||
|  | @ -164,15 +197,27 @@ function createFormGroup(sectionIdStr, field) { | ||||||
|     return formGroup; |     return formGroup; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function createCollapsibleCard(sectionIdStr, sectionTitle) { | function createCollapsibleCard(sectionIdStr, sectionTitle, sectionCompleted, ruleViolations) { | ||||||
|     // Create card and header
 |     // Create card and header
 | ||||||
|     const card = document.createElement("div"); |     const card = document.createElement("div"); | ||||||
|     card.classList.add("card"); |     card.classList.add("card"); | ||||||
|     const cardHeader = document.createElement("div"); |     const cardHeader = document.createElement("div"); | ||||||
|     cardHeader.classList.add("card-header"); |     cardHeader.classList.add("card-header"); | ||||||
|  |     const sectionState = document.createElement("i"); | ||||||
|  |     sectionState.id = sectionIdStr + "state"; | ||||||
| 
 | 
 | ||||||
|  |     // A completed section gets a header icon
 | ||||||
|  |     if (sectionCompleted) { | ||||||
|  |         if (ruleViolations.length === 0) { | ||||||
|  |             sectionState.classList.add("fas", "fa-check-square"); | ||||||
|  |         } else { | ||||||
|  |             sectionState.classList.add("fas", "fa-exclamation-triangle"); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |      | ||||||
|     // Create h2, button. Append button to h2, h2 to header, and header to card
 |     // Create h2, button. Append button to h2, h2 to header, and header to card
 | ||||||
|     const h2 = document.createElement("h2"); |     const h2 = document.createElement("h2"); | ||||||
|  |     h2.classList.add("mb-0"); | ||||||
|     const button = document.createElement("button"); |     const button = document.createElement("button"); | ||||||
|     button.classList.add("btn", "btn-link"); |     button.classList.add("btn", "btn-link"); | ||||||
|     button.type = "button"; |     button.type = "button"; | ||||||
|  | @ -180,43 +225,75 @@ function createCollapsibleCard(sectionIdStr, sectionTitle) { | ||||||
|     button.setAttribute("data-target", "#" + sectionIdStr + "collapse"); |     button.setAttribute("data-target", "#" + sectionIdStr + "collapse"); | ||||||
|     button.innerHTML = sectionTitle; |     button.innerHTML = sectionTitle; | ||||||
|     h2.appendChild(button); |     h2.appendChild(button); | ||||||
|  |     h2.appendChild(sectionState); | ||||||
|     cardHeader.appendChild(h2); |     cardHeader.appendChild(h2); | ||||||
|     card.appendChild(cardHeader); |     card.appendChild(cardHeader); | ||||||
| 
 | 
 | ||||||
|     return card; |     return card; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function createCollapsibleCardBody(form, type, sectionIdStr, sectionDescription, sectionCompleted) { | function createCollapsibleCardBody(form, type, sectionIdStr, sectionDescription, sectionCompleted, ruleViolations) { | ||||||
|     // Create wrapper div
 |     // Create wrapper div
 | ||||||
|     const div = document.createElement("div"); |     const collapseDiv = document.createElement("div"); | ||||||
|     div.id = sectionIdStr + "collapse"; |     collapseDiv.id = sectionIdStr + "collapse"; | ||||||
|     const sectionAlert = document.createElement("div"); |  | ||||||
|     const cardBody = document.createElement("div"); |     const cardBody = document.createElement("div"); | ||||||
|     cardBody.classList.add("card-body"); |     cardBody.classList.add("card-body"); | ||||||
|  |     const sectionAlert = document.createElement("div"); | ||||||
| 
 | 
 | ||||||
|     if (sectionCompleted) { |     if (sectionCompleted) { | ||||||
|         div.classList.add("collapse"); |         if (ruleViolations.length === 0) { | ||||||
|         sectionAlert.classList.add("alert", "alert-success"); |             collapseDiv.classList.add("collapse"); | ||||||
|         sectionAlert.innerHTML = "This section is complete"; |         } else { | ||||||
|  |             collapseDiv.classList.add("collapse", "show"); | ||||||
|  |         } | ||||||
|     } else { |     } else { | ||||||
|         div.classList.add("collapse", "show"); |         sectionAlert.classList.add("alert", "alert-danger", "section-alert"); | ||||||
|         sectionAlert.classList.add("alert", "alert-danger"); |  | ||||||
|         sectionAlert.innerHTML = "This section is not complete"; |         sectionAlert.innerHTML = "This section is not complete"; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (type === reportType.EDIT) { |     if (type === reportType.EDIT) { | ||||||
|         div.setAttribute("data-parent", "#editReportAccordion"); |         collapseDiv.setAttribute("data-parent", "#editReportAccordion"); | ||||||
|     } else { |     } else { | ||||||
|         div.setAttribute("data-parent", "#newReportAccordion"); |         collapseDiv.setAttribute("data-parent", "#newReportAccordion"); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Create card body. Append form to body, body to wrapper div
 |     // Create card body. Append form to body, body to wrapper div
 | ||||||
|     cardBody.appendChild(sectionAlert); |     cardBody.appendChild(sectionAlert); | ||||||
|     cardBody.insertAdjacentHTML("beforeend", sectionDescription); |     cardBody.insertAdjacentHTML("beforeend", sectionDescription); | ||||||
|     cardBody.appendChild(form); |     cardBody.appendChild(form); | ||||||
|     div.appendChild(cardBody); |     collapseDiv.appendChild(cardBody); | ||||||
| 
 | 
 | ||||||
|     return div; |     return collapseDiv; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function createCardFooter(ruleViolations) { | ||||||
|  |     if (ruleViolations.length === 0) { | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     const cardFooter = document.createElement("div"); | ||||||
|  |     cardFooter.classList.add("card-footer"); | ||||||
|  |     const violationMessage = document.createElement("div"); | ||||||
|  |     violationMessage.classList.add("alert", "alert-danger"); | ||||||
|  |     const heading = document.createElement("div"); | ||||||
|  |     heading.innerHTML = "Rule Violations"; | ||||||
|  |     heading.classList.add("alert-heading"); | ||||||
|  |     violationMessage.appendChild(heading); | ||||||
|  |     violationMessage.appendChild(document.createElement("hr")); | ||||||
|  | 
 | ||||||
|  |     for (let i = 0; i < ruleViolations.length; i++) { | ||||||
|  |         let violation = document.createElement("p"); | ||||||
|  |         let violationLabel = document.createElement("strong"); | ||||||
|  |         violationLabel.innerHTML = ruleViolations[i].label; | ||||||
|  |         violation.appendChild(violationLabel); | ||||||
|  |         violation.appendChild(document.createElement("br")); | ||||||
|  |         let ruleBreakText = document.createTextNode(ruleViolations[i].rule_break_text); | ||||||
|  |         violation.appendChild(ruleBreakText); | ||||||
|  |         violationMessage.appendChild(violation); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     cardFooter.appendChild(violationMessage); | ||||||
|  |     return cardFooter; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function createReportForm(parsedData, type) { | function createReportForm(parsedData, type) { | ||||||
|  | @ -252,16 +329,14 @@ function createReportForm(parsedData, type) { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Add report title and date
 |     // Add report title and date
 | ||||||
|     const reportTitle = parsedData.title; |     modalLabel.innerHTML = parsedData.title; | ||||||
|     modalLabel.innerHTML = reportTitle; |  | ||||||
| 
 | 
 | ||||||
|     // Traverse the report's sections array
 |     // Traverse the report's sections array
 | ||||||
|     const sections = parsedData.sections; |     const sections = parsedData.sections; | ||||||
|     for (let i = 0; i < sections.length; i++) { |     for (let i = 0; i < sections.length; i++) { | ||||||
|         let sectionIdStr = "section-" + sections[i].id + "-"; |  | ||||||
|         let collapsibleCard = createCollapsibleCard(sectionIdStr, sections[i].title) |  | ||||||
| 
 | 
 | ||||||
|         // Create a new form with the section key index as id
 |         // Create a new form
 | ||||||
|  |         let sectionIdStr = "section-" + sections[i].id + "-"; | ||||||
|         let form = document.createElement("form"); |         let form = document.createElement("form"); | ||||||
|         form.classList.add("form", "section-form"); |         form.classList.add("form", "section-form"); | ||||||
|         form.id = sectionIdStr + "form"; |         form.id = sectionIdStr + "form"; | ||||||
|  | @ -272,9 +347,11 @@ function createReportForm(parsedData, type) { | ||||||
|         let fields = sections[i].fields; |         let fields = sections[i].fields; | ||||||
|         for (let j = 0; j < fields.length; j++) { |         for (let j = 0; j < fields.length; j++) { | ||||||
| 
 | 
 | ||||||
|  |             /* | ||||||
|             console.log("Field label: " + fields[j].label); |             console.log("Field label: " + fields[j].label); | ||||||
|             console.log("Field type: " + fields[j].field_type); |             console.log("Field type: " + fields[j].field_type); | ||||||
|             console.log("Field value: " + fields[j].value); |             console.log("Field value: " + fields[j].value); | ||||||
|  |             */ | ||||||
| 
 | 
 | ||||||
|             // Create a form group for each field and add it to the form
 |             // Create a form group for each field and add it to the form
 | ||||||
|             form.appendChild(createFormGroup(sectionIdStr, fields[j])); |             form.appendChild(createFormGroup(sectionIdStr, fields[j])); | ||||||
|  | @ -288,7 +365,14 @@ function createReportForm(parsedData, type) { | ||||||
|         form.appendChild(saveButton); |         form.appendChild(saveButton); | ||||||
| 
 | 
 | ||||||
|         // Create collapsible card body, append form to it, append card to accordion
 |         // Create collapsible card body, append form to it, append card to accordion
 | ||||||
|         let cardBody = createCollapsibleCardBody(form, type, sectionIdStr, sections[i].html_description, sections[i].completed); |         let cardBody = createCollapsibleCardBody(form, type, sectionIdStr, | ||||||
|  |             sections[i].html_description, sections[i].completed, sections[i].rule_violations); | ||||||
|  |         let cardFooter = createCardFooter(sections[i].rule_violations); | ||||||
|  |         if (cardFooter) { | ||||||
|  |             cardBody.appendChild(cardFooter); | ||||||
|  |         } | ||||||
|  |         let collapsibleCard = createCollapsibleCard(sectionIdStr, sections[i].title, | ||||||
|  |             sections[i].completed, sections[i].rule_violations) | ||||||
|         collapsibleCard.appendChild(cardBody); |         collapsibleCard.appendChild(cardBody); | ||||||
|         accordion.appendChild(collapsibleCard); |         accordion.appendChild(collapsibleCard); | ||||||
|     } |     } | ||||||
|  | @ -323,9 +407,11 @@ function displayListOfReports(parsedData) { | ||||||
|             bodyRow.insertCell(0).innerHTML = title; |             bodyRow.insertCell(0).innerHTML = title; | ||||||
|             bodyRow.insertCell(1).innerHTML = dateCreated; |             bodyRow.insertCell(1).innerHTML = dateCreated; | ||||||
| 
 | 
 | ||||||
|  |             /* | ||||||
|             let stateCell = bodyRow.insertCell(2); |             let stateCell = bodyRow.insertCell(2); | ||||||
|             stateCell.innerHTML = state; |             stateCell.innerHTML = state; | ||||||
|             stateCell.classList.add("d-none", "d-lg-table-cell"); // Column visible only on large displays
 |             stateCell.classList.add("d-none", "d-lg-table-cell"); // Column visible only on large displays
 | ||||||
|  |             */ | ||||||
| 
 | 
 | ||||||
|             // Create edit/view button
 |             // Create edit/view button
 | ||||||
|             let actionButton = document.createElement("button"); |             let actionButton = document.createElement("button"); | ||||||
|  | @ -349,10 +435,10 @@ function displayListOfReports(parsedData) { | ||||||
|                 actionButton.setAttribute("data-target", "#viewReportModal"); |                 actionButton.setAttribute("data-target", "#viewReportModal"); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             let dateSubmittedCell = bodyRow.insertCell(3); |             let dateSubmittedCell = bodyRow.insertCell(2); | ||||||
|             dateSubmittedCell.innerHTML = dateSubmitted; |             dateSubmittedCell.innerHTML = dateSubmitted; | ||||||
|             dateSubmittedCell.classList.add("d-none", "d-md-table-cell"); // Column visible on medium and larger displays
 |             dateSubmittedCell.classList.add("d-none", "d-md-table-cell"); // Column visible on medium and larger displays
 | ||||||
|             bodyRow.insertCell(4).appendChild(actionButton); |             bodyRow.insertCell(3).appendChild(actionButton); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         table.style.visibility = "visible"; |         table.style.visibility = "visible"; | ||||||
|  | @ -468,7 +554,6 @@ if (newReportForm) { | ||||||
|         console.log("Payload:\n" + payload); |         console.log("Payload:\n" + payload); | ||||||
|         const type = reportType.NEW; |         const type = reportType.NEW; | ||||||
|         makeAjaxRequest("POST", url, createReportForm, type, payload); |         makeAjaxRequest("POST", url, createReportForm, type, payload); | ||||||
|         this.reset(); |  | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -494,7 +579,7 @@ document.addEventListener("submit", function(event) { | ||||||
|         saveButton.appendChild(document.createTextNode("  Saving...")); |         saveButton.appendChild(document.createTextNode("  Saving...")); | ||||||
|         const formData = new FormData(event.target); |         const formData = new FormData(event.target); | ||||||
|         const url = getEndpointDomain() + "api/v1/report/" + event.target.dataset.rid + "/section/" + event.target.dataset.sid; |         const url = getEndpointDomain() + "api/v1/report/" + event.target.dataset.rid + "/section/" + event.target.dataset.sid; | ||||||
|         makeAjaxRequest("PUT", url, saveSectionCallback, saveButton, formData); |         makeAjaxRequest("PUT", url, updateSection, saveButton, formData); | ||||||
|     } |     } | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -5,6 +5,7 @@ | ||||||
|     <meta name="viewport" content="width=device-width, initial-scale=1"> |     <meta name="viewport" content="width=device-width, initial-scale=1"> | ||||||
|     <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous"> |     <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous"> | ||||||
|     <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous"> |     <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous"> | ||||||
|  |     <link rel="stylesheet" href="css/style.css"> | ||||||
|     <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> |     <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> | ||||||
|     <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script> |     <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script> | ||||||
|     <script src="https://cdnjs.cloudflare.com/ajax/libs/classlist/1.2.20171210/classList.min.js"></script> |     <script src="https://cdnjs.cloudflare.com/ajax/libs/classlist/1.2.20171210/classList.min.js"></script> | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 kououken
						kououken