Some checks failed
Build and Release / Create Release (push) Has been skipped
Build and Release / Unit Tests (push) Successful in 3m22s
Build and Release / Build Binaries (amd64, darwin, macos) (push) Has been cancelled
Build and Release / Build Binaries (amd64, linux, linux-latest) (push) Has been cancelled
Build and Release / Build Binaries (amd64, windows, windows-latest) (push) Has been cancelled
Build and Release / Build Binaries (arm64, darwin, macos) (push) Has been cancelled
Build and Release / Build Binary (linux/arm64) (push) Has been cancelled
Build and Release / Lint (push) Has been cancelled
Build and Release / Integration Tests (PostgreSQL) (push) Has been cancelled
Include loaded plugin details (name, version, description) in /api/v2/version response when plugins are enabled. Also add page class to AI learning admin templates for consistent styling.
188 lines
7.5 KiB
Handlebars
188 lines
7.5 KiB
Handlebars
{{template "admin/layout_head" (dict "ctxData" . "pageClass" "admin ai-learning")}}
|
|
<div class="admin ai-learning">
|
|
<h4 class="ui top attached header">
|
|
{{ctx.Locale.Tr "admin.ai_learning"}}
|
|
</h4>
|
|
|
|
<!-- Stats Tiles -->
|
|
<div class="ui attached segment">
|
|
<div style="display: flex; justify-content: space-around; text-align: center;">
|
|
<div style="padding: 15px 25px; background: var(--color-box-body); border: 1px solid var(--color-secondary); border-radius: 8px; min-width: 150px;">
|
|
<div style="font-size: 2em; font-weight: bold; color: #2185d0;">{{.Stats.TotalPatterns}}</div>
|
|
<div style="color: var(--color-text-light); margin-top: 5px;">{{ctx.Locale.Tr "admin.ai_learning.total_patterns"}}</div>
|
|
</div>
|
|
<div style="padding: 15px 25px; background: var(--color-box-body); border: 1px solid var(--color-secondary); border-radius: 8px; min-width: 150px;">
|
|
<div style="font-size: 2em; font-weight: bold; color: #6435c9;">{{.Stats.TotalOccurrences}}</div>
|
|
<div style="color: var(--color-text-light); margin-top: 5px;">{{ctx.Locale.Tr "admin.ai_learning.total_occurrences"}}</div>
|
|
</div>
|
|
<div style="padding: 15px 25px; background: var(--color-box-body); border: 1px solid var(--color-secondary); border-radius: 8px; min-width: 150px;">
|
|
<div style="font-size: 2em; font-weight: bold; color: #21ba45;">{{.Stats.TotalSuccesses}}</div>
|
|
<div style="color: var(--color-text-light); margin-top: 5px;">{{ctx.Locale.Tr "admin.ai_learning.total_successes"}}</div>
|
|
</div>
|
|
<div style="padding: 15px 25px; background: var(--color-box-body); border: 1px solid var(--color-secondary); border-radius: 8px; min-width: 150px;">
|
|
<div style="font-size: 2em; font-weight: bold; color: #f2711c;">{{printf "%.1f" .Stats.SuccessRate}}%</div>
|
|
<div style="color: var(--color-text-light); margin-top: 5px;">{{ctx.Locale.Tr "admin.ai_learning.success_rate"}}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Filters -->
|
|
<div class="ui attached segment">
|
|
<form class="ui form" method="get">
|
|
<div class="fields" style="align-items: flex-end; margin-bottom: 0;">
|
|
<div class="four wide field">
|
|
<label>{{ctx.Locale.Tr "admin.ai_learning.filter_pattern"}}</label>
|
|
<input type="text" name="pattern" value="{{.PatternFilter}}" placeholder="e.g., NETSDK1147">
|
|
</div>
|
|
<div class="three wide field">
|
|
<label>{{ctx.Locale.Tr "admin.ai_learning.filter_runner_type"}}</label>
|
|
<select class="ui dropdown" name="runner_type">
|
|
<option value="">{{ctx.Locale.Tr "admin.ai_learning.all"}}</option>
|
|
<option value="_any" {{if eq "_any" $.RunnerTypeFilter}}selected{{end}}>Any (universal)</option>
|
|
{{range .Stats.TopRunnerTypes}}
|
|
<option value="{{.}}" {{if eq . $.RunnerTypeFilter}}selected{{end}}>{{.}}</option>
|
|
{{end}}
|
|
</select>
|
|
</div>
|
|
<div class="four wide field">
|
|
<label>{{ctx.Locale.Tr "admin.ai_learning.filter_project_type"}}</label>
|
|
<select class="ui dropdown" name="project_type">
|
|
<option value="">{{ctx.Locale.Tr "admin.ai_learning.all"}}</option>
|
|
<option value="_any" {{if eq "_any" $.RunnerTypeFilter}}selected{{end}}>Any (universal)</option>
|
|
{{range .Stats.TopProjectTypes}}
|
|
<option value="{{.}}" {{if eq . $.ProjectTypeFilter}}selected{{end}}>{{.}}</option>
|
|
{{end}}
|
|
</select>
|
|
</div>
|
|
<div class="field">
|
|
<button class="ui primary button" type="submit">{{ctx.Locale.Tr "admin.ai_learning.filter"}}</button>
|
|
</div>
|
|
<div class="field">
|
|
<a class="ui button" href="{{AppSubUrl}}/-/admin/ai-learning">{{ctx.Locale.Tr "admin.ai_learning.clear_filters"}}</a>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<!-- Pattern List -->
|
|
<div class="ui attached segment">
|
|
<form method="post" action="{{AppSubUrl}}/-/admin/ai-learning/delete">
|
|
{{.CsrfTokenHtml}}
|
|
<table class="ui celled striped table">
|
|
<thead>
|
|
<tr>
|
|
<th class="collapsing">
|
|
<div class="ui checkbox">
|
|
<input type="checkbox" class="select-all">
|
|
<label></label>
|
|
</div>
|
|
</th>
|
|
<th>{{ctx.Locale.Tr "admin.ai_learning.pattern"}}</th>
|
|
<th>{{ctx.Locale.Tr "admin.ai_learning.runner_type"}}</th>
|
|
<th>{{ctx.Locale.Tr "admin.ai_learning.project_type"}}</th>
|
|
<th class="collapsing">{{ctx.Locale.Tr "admin.ai_learning.occurrences"}}</th>
|
|
<th class="collapsing">{{ctx.Locale.Tr "admin.ai_learning.successes"}}</th>
|
|
<th class="collapsing">{{ctx.Locale.Tr "admin.ai_learning.actions"}}</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{{range .Patterns}}
|
|
<tr>
|
|
<td>
|
|
<div class="ui checkbox">
|
|
<input type="checkbox" name="ids[]" value="{{.ID}}">
|
|
<label></label>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<strong>{{.Pattern}}</strong>
|
|
{{if .Diagnosis}}
|
|
<br><small class="text truncate" style="color: var(--color-text-light); max-width: 300px; display: inline-block;">{{.Diagnosis}}</small>
|
|
{{end}}
|
|
</td>
|
|
<td>
|
|
{{if .RunnerType}}
|
|
<span class="ui small label" style="background-color: {{if eq .RunnerType "linux"}}#21ba45{{else if eq .RunnerType "windows"}}#2185d0{{else if eq .RunnerType "macos"}}#a333c8{{else}}#767676{{end}}; color: white;">
|
|
{{.RunnerType}}
|
|
</span>
|
|
{{else}}
|
|
<span class="ui small grey label">any</span>
|
|
{{end}}
|
|
</td>
|
|
<td>
|
|
{{if .ProjectType}}
|
|
<span class="ui small teal label">{{.ProjectType}}</span>
|
|
{{if .Framework}}
|
|
<span class="ui small label">{{.Framework}}</span>
|
|
{{end}}
|
|
{{else}}
|
|
<span class="ui small grey label">any</span>
|
|
{{end}}
|
|
</td>
|
|
<td class="center aligned">
|
|
<span class="ui small label" style="background-color: #6435c9; color: white;">{{.OccurrenceCount}}</span>
|
|
</td>
|
|
<td class="center aligned">
|
|
<span class="ui small label" style="background-color: #21ba45; color: white;">{{.SuccessCount}}</span>
|
|
</td>
|
|
<td class="collapsing">
|
|
<a class="ui mini primary button" href="{{AppSubUrl}}/-/admin/ai-learning/{{.ID}}">
|
|
{{svg "octicon-pencil" 14}} {{ctx.Locale.Tr "edit"}}
|
|
</a>
|
|
<button class="ui mini red button link-action" type="button"
|
|
data-url="{{AppSubUrl}}/-/admin/ai-learning/{{.ID}}/delete"
|
|
data-modal-confirm="{{ctx.Locale.Tr "admin.ai_learning.delete_confirm"}}">
|
|
{{svg "octicon-trash" 14}}
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
{{else}}
|
|
<tr>
|
|
<td colspan="7" class="center aligned">
|
|
<i>{{ctx.Locale.Tr "admin.ai_learning.no_patterns"}}</i>
|
|
</td>
|
|
</tr>
|
|
{{end}}
|
|
</tbody>
|
|
</table>
|
|
|
|
{{if .Patterns}}
|
|
<div class="ui divider"></div>
|
|
<button class="ui red button delete-selected" type="submit" disabled>
|
|
{{svg "octicon-trash" 14}} {{ctx.Locale.Tr "admin.ai_learning.delete_selected"}}
|
|
</button>
|
|
{{end}}
|
|
</form>
|
|
</div>
|
|
|
|
{{template "base/paginate" .}}
|
|
</div>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const selectAll = document.querySelector('.select-all');
|
|
const checkboxes = document.querySelectorAll('input[name="ids[]"]');
|
|
const deleteBtn = document.querySelector('.delete-selected');
|
|
|
|
if (selectAll) {
|
|
selectAll.addEventListener('change', function() {
|
|
checkboxes.forEach(cb => cb.checked = this.checked);
|
|
updateDeleteBtn();
|
|
});
|
|
}
|
|
|
|
checkboxes.forEach(cb => {
|
|
cb.addEventListener('change', updateDeleteBtn);
|
|
});
|
|
|
|
function updateDeleteBtn() {
|
|
if (deleteBtn) {
|
|
const checked = document.querySelectorAll('input[name="ids[]"]:checked');
|
|
deleteBtn.disabled = checked.length === 0;
|
|
}
|
|
}
|
|
});
|
|
</script>
|
|
|
|
{{template "admin/layout_footer" .}}
|