Merge branch 'feat-add-language-support' of github.com:OliveTin/OliveTin into feat-add-language-support

This commit is contained in:
jamesread 2025-11-10 22:50:58 +00:00
commit 3df22f2ccb
5 changed files with 62 additions and 60 deletions

View File

@ -14,12 +14,9 @@
</div> </div>
<template v-else-if="component.type == 'fieldset'"> <template v-else-if="component.type == 'fieldset'">
<fieldset>
<legend>{{ component.title }}</legend>
<template v-for="subcomponent in component.contents" :key="subcomponent.title"> <template v-for="subcomponent in component.contents" :key="subcomponent.title">
<DashboardComponent :component="subcomponent" /> <DashboardComponent :component="subcomponent" />
</template> </template>
</fieldset>
</template> </template>
<div v-else> <div v-else>

View File

@ -7,7 +7,7 @@
<form @submit="handleSubmit"> <form @submit="handleSubmit">
<template v-if="actionArguments.length > 0"> <template v-if="actionArguments.length > 0">
<template v-for="arg in actionArguments" :key="arg.name" class="argument-group"> <template v-for="arg in actionArguments" :key="arg.name">
<label :for="arg.name"> <label :for="arg.name">
{{ formatLabel(arg.title) }} {{ formatLabel(arg.title) }}
</label> </label>
@ -96,18 +96,27 @@ async function setup() {
// Initialize values from query params or defaults // Initialize values from query params or defaults
actionArguments.value.forEach(arg => { actionArguments.value.forEach(arg => {
const paramValue = getQueryParamValue(arg.name)
argValues.value[arg.name] = paramValue !== null ? paramValue : arg.defaultValue || ''
if (arg.type === 'confirmation') { if (arg.type === 'confirmation') {
hasConfirmation.value = true hasConfirmation.value = true
const paramValue = getQueryParamValue(arg.name)
let checkedValue = false
if (paramValue !== null) {
checkedValue = paramValue === '1' || paramValue === 'true' || paramValue === true
} else if (arg.defaultValue !== undefined && arg.defaultValue !== '') {
checkedValue = arg.defaultValue === '1' || arg.defaultValue === 'true' || arg.defaultValue === true
}
argValues.value[arg.name] = checkedValue
confirmationChecked.value = checkedValue
} else {
const paramValue = getQueryParamValue(arg.name)
argValues.value[arg.name] = paramValue !== null ? paramValue : arg.defaultValue || ''
} }
}) })
// Run initial validation on all fields after DOM is updated // Run initial validation on all fields after DOM is updated
await nextTick() await nextTick()
for (const arg of actionArguments.value) { for (const arg of actionArguments.value) {
if (arg.type && !arg.type.startsWith('regex:') && arg.type !== 'select' && arg.type !== '') { if (arg.type && !arg.type.startsWith('regex:') && arg.type !== 'select' && arg.type !== '' && arg.type !== 'confirmation') {
await validateArgument(arg, argValues.value[arg.name]) await validateArgument(arg, argValues.value[arg.name])
} }
} }
@ -143,7 +152,11 @@ function getInputType(arg) {
return undefined return undefined
} }
if (arg.type === 'ascii_identifier') { if (arg.type === 'confirmation') {
return 'checkbox'
}
if (arg.type === 'ascii_identifier' || arg.type === 'ascii') {
return 'text' return 'text'
} }
@ -158,8 +171,8 @@ function getPattern(arg) {
} }
function getArgumentValue(arg) { function getArgumentValue(arg) {
if (arg.type === 'checkbox') { if (arg.type === 'checkbox' || arg.type === 'confirmation') {
return argValues.value[arg.name] === '1' || argValues.value[arg.name] === true return argValues.value[arg.name] === '1' || argValues.value[arg.name] === true || argValues.value[arg.name] === 'true'
} }
return argValues.value[arg.name] || '' return argValues.value[arg.name] || ''
} }
@ -240,7 +253,7 @@ function getArgumentValues() {
for (const arg of actionArguments.value) { for (const arg of actionArguments.value) {
let value = argValues.value[arg.name] || '' let value = argValues.value[arg.name] || ''
if (arg.type === 'checkbox') { if (arg.type === 'checkbox' || arg.type === 'confirmation') {
value = value ? '1' : '0' value = value ? '1' : '0'
} }
@ -348,22 +361,6 @@ form {
grid-template-columns: max-content auto auto; grid-template-columns: max-content auto auto;
} }
.argument-group {
display: flex;
flex-direction: column;
gap: 0.25rem;
}
.argument-group label {
font-weight: 500;
color: #333;
}
.argument-group input:invalid,
.argument-group select:invalid,
.argument-group textarea:invalid {
border-color: #dc3545;
}
.argument-description { .argument-description {
font-size: 0.875rem; font-size: 0.875rem;

View File

@ -104,7 +104,7 @@ let terminal = null
function initializeTerminal() { function initializeTerminal() {
terminal = new OutputTerminal(executionTrackingId.value) terminal = new OutputTerminal(executionTrackingId.value)
terminal.open(xtermOutput.value) terminal.open(xtermOutput.value)
terminal.resize(80, 24) terminal.resize(80, 40)
window.terminal = terminal window.terminal = terminal
} }
@ -327,6 +327,17 @@ function goBack() {
} }
onMounted(() => { onMounted(() => {
document.addEventListener('fullscreenchange', (e) => {
setTimeout(() => { // Wait for the DOM to settle
if (document.fullscreenElement) {
window.terminal.fit()
} else {
window.terminal.resize(80, 40)
window.terminal.fit()
}
}, 100)
})
initializeTerminal() initializeTerminal()
fetchExecutionResult(props.executionTrackingId) fetchExecutionResult(props.executionTrackingId)

View File

@ -43,7 +43,7 @@ describe('config: dashboards with basic fieldsets', function () {
// Check that we have the expected number of fieldsets // Check that we have the expected number of fieldsets
const allFieldsets = await webdriver.findElements(By.css('fieldset')) const allFieldsets = await webdriver.findElements(By.css('fieldset'))
expect(allFieldsets).to.have.length(5, 'Expected 5 fieldsets total') expect(allFieldsets).to.have.length(3, 'Expected 3 fieldsets total')
// Check that we have fieldsets with the expected titles // Check that we have fieldsets with the expected titles
const fieldsetTitles = [] const fieldsetTitles = []

View File

@ -89,13 +89,10 @@ func buildDefaultDashboard(rr *DashboardRenderRequest) *apiv1.Dashboard {
} }
func sortActions(components []*apiv1.DashboardComponent) []*apiv1.DashboardComponent { func sortActions(components []*apiv1.DashboardComponent) []*apiv1.DashboardComponent {
log.Infof("sortActions: %+v", components)
sort.Slice(components, func(i, j int) bool { sort.Slice(components, func(i, j int) bool {
if components[i].Action == nil { if components[i].Action == nil || components[j].Action == nil {
return false return components[i].Title < components[j].Title
}
if components[j].Action == nil {
return true
} }
if components[i].Action.Order == components[j].Action.Order { if components[i].Action.Order == components[j].Action.Order {