chore: Fix coderabbit warnings
This commit is contained in:
parent
e24ae6265b
commit
6077c63cfd
|
|
@ -9,7 +9,7 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<fieldset class="choice-checklist-fieldset">
|
<fieldset class="choice-checklist-fieldset">
|
||||||
<legend class="visually-hidden">{{ name }}</legend>
|
<legend class="visually-hidden">{{ label || name }}</legend>
|
||||||
<label
|
<label
|
||||||
v-for="(choice, index) in choices"
|
v-for="(choice, index) in choices"
|
||||||
:key="choice.value"
|
:key="choice.value"
|
||||||
|
|
@ -28,9 +28,12 @@
|
||||||
<input
|
<input
|
||||||
:id="`${id}-value`"
|
:id="`${id}-value`"
|
||||||
:name="name"
|
:name="name"
|
||||||
type="hidden"
|
type="text"
|
||||||
|
class="visually-hidden choice-checklist-value"
|
||||||
:value="modelValue"
|
:value="modelValue"
|
||||||
:required="required && modelValue === ''"
|
:required="required"
|
||||||
|
tabindex="-1"
|
||||||
|
aria-hidden="true"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -54,6 +57,10 @@ const props = defineProps({
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
choices: {
|
choices: {
|
||||||
type: Array,
|
type: Array,
|
||||||
required: true
|
required: true
|
||||||
|
|
@ -119,7 +126,7 @@ function selectNone() {
|
||||||
border: none;
|
border: none;
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 0.5em 1em;
|
gap: 0.5em 1em;
|
||||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr));
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ const choices = [
|
||||||
|
|
||||||
test('parseChecklistValue splits comma-delimited values', () => {
|
test('parseChecklistValue splits comma-delimited values', () => {
|
||||||
assert.deepEqual(parseChecklistValue('documents,photos'), ['documents', 'photos'])
|
assert.deepEqual(parseChecklistValue('documents,photos'), ['documents', 'photos'])
|
||||||
|
assert.deepEqual(parseChecklistValue('documents, photos'), ['documents', 'photos'])
|
||||||
assert.deepEqual(parseChecklistValue(''), [])
|
assert.deepEqual(parseChecklistValue(''), [])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,8 @@
|
||||||
@update:model-value="handleChoiceUpdate(arg, $event)" />
|
@update:model-value="handleChoiceUpdate(arg, $event)" />
|
||||||
|
|
||||||
<ChoiceChecklist v-else-if="arg.type === 'checklist'" :id="arg.name" :name="arg.name"
|
<ChoiceChecklist v-else-if="arg.type === 'checklist'" :id="arg.name" :name="arg.name"
|
||||||
:choices="arg.choices" :model-value="getArgumentValue(arg)" :required="arg.required"
|
:label="arg.title" :choices="arg.choices" :model-value="getArgumentValue(arg)" :required="arg.required"
|
||||||
@update:model-value="handleChecklistUpdate(arg, $event)" />
|
@update:model-value="handleChoiceUpdate(arg, $event)" />
|
||||||
|
|
||||||
<component v-else :is="getInputComponent(arg)" :id="arg.name" :name="arg.name"
|
<component v-else :is="getInputComponent(arg)" :id="arg.name" :name="arg.name"
|
||||||
:value="(arg.type === 'checkbox' || arg.type === 'confirmation') ? undefined : getArgumentValue(arg)"
|
:value="(arg.type === 'checkbox' || arg.type === 'confirmation') ? undefined : getArgumentValue(arg)"
|
||||||
|
|
@ -145,8 +145,6 @@ async function setup() {
|
||||||
} else {
|
} else {
|
||||||
argValues.value[arg.name] = false
|
argValues.value[arg.name] = false
|
||||||
}
|
}
|
||||||
} else if (arg.type === 'checklist') {
|
|
||||||
argValues.value[arg.name] = paramValue !== null ? paramValue : arg.defaultValue || ''
|
|
||||||
} else {
|
} else {
|
||||||
argValues.value[arg.name] = paramValue !== null ? paramValue : arg.defaultValue || ''
|
argValues.value[arg.name] = paramValue !== null ? paramValue : arg.defaultValue || ''
|
||||||
}
|
}
|
||||||
|
|
@ -253,12 +251,6 @@ function getValidationElement(arg) {
|
||||||
return document.getElementById(arg.name)
|
return document.getElementById(arg.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleChecklistUpdate(arg, value) {
|
|
||||||
argValues.value[arg.name] = value
|
|
||||||
updateUrlWithArg(arg.name, value)
|
|
||||||
validateArgument(arg, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleChoiceUpdate(arg, value) {
|
function handleChoiceUpdate(arg, value) {
|
||||||
argValues.value[arg.name] = value
|
argValues.value[arg.name] = value
|
||||||
updateUrlWithArg(arg.name, value)
|
updateUrlWithArg(arg.name, value)
|
||||||
|
|
@ -503,6 +495,11 @@ async function handleSubmit(event) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Object.keys(formErrors.value).length > 0) {
|
||||||
|
console.log('argument form has validation errors')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const argvs = getArgumentValues()
|
const argvs = getArgumentValues()
|
||||||
console.log('argument form has elements that passed validation')
|
console.log('argument form has elements that passed validation')
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,9 +27,9 @@ async function submitChecklistForm() {
|
||||||
await submitButton.click()
|
await submitButton.click()
|
||||||
}
|
}
|
||||||
|
|
||||||
async function waitForTerminalOutput(expectedValue) {
|
async function pollTerminal(matcher, timeoutMs = DEFAULT_UI_WAIT_MS) {
|
||||||
await webdriver.wait(
|
await webdriver.wait(
|
||||||
new Condition(`wait for checklist value ${expectedValue} in output`, async () => {
|
new Condition('wait for terminal output', async () => {
|
||||||
try {
|
try {
|
||||||
const terminalReady = await webdriver.executeScript(`
|
const terminalReady = await webdriver.executeScript(`
|
||||||
return !!(window.terminal && window.terminal.getBufferAsString);
|
return !!(window.terminal && window.terminal.getBufferAsString);
|
||||||
|
|
@ -43,42 +43,34 @@ async function waitForTerminalOutput(expectedValue) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return output.trim().includes(`Selected segments: ${expectedValue}`)
|
return matcher(output.trim())
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
timeoutMs
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function waitForTerminalOutput(expectedValue) {
|
||||||
|
await pollTerminal(
|
||||||
|
(output) => output.includes(`Selected segments: ${expectedValue}`),
|
||||||
DEFAULT_UI_WAIT_MS
|
DEFAULT_UI_WAIT_MS
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function waitForTerminalOutputPattern(pattern) {
|
async function waitForTerminalOutputPattern(pattern) {
|
||||||
await webdriver.wait(
|
await pollTerminal(
|
||||||
new Condition(`wait for terminal output matching ${pattern}`, async () => {
|
(output) => pattern.test(output),
|
||||||
try {
|
|
||||||
const terminalReady = await webdriver.executeScript(`
|
|
||||||
return !!(window.terminal && window.terminal.getBufferAsString);
|
|
||||||
`)
|
|
||||||
if (!terminalReady) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
const output = await getTerminalBuffer()
|
|
||||||
if (!output) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return pattern.test(output.trim())
|
|
||||||
} catch (e) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
10000
|
10000
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getCheckboxByValueIndex(index) {
|
async function getCheckboxByValueIndex(index) {
|
||||||
return await webdriver.findElement(By.id(`segments-${index}`))
|
const checkboxes = await webdriver.findElements(
|
||||||
|
By.css('.choice-checklist-item input[type="checkbox"]')
|
||||||
|
)
|
||||||
|
return checkboxes[index]
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('config: checklist', function () {
|
describe('config: checklist', function () {
|
||||||
|
|
@ -118,8 +110,8 @@ describe('config: checklist', function () {
|
||||||
await selectNone.click()
|
await selectNone.click()
|
||||||
await webdriver.sleep(300)
|
await webdriver.sleep(300)
|
||||||
|
|
||||||
const hidden = await webdriver.findElement(By.id('segments-value'))
|
const valueInput = await webdriver.findElement(By.css('.choice-checklist > input'))
|
||||||
expect(await hidden.getAttribute('value')).to.equal('')
|
expect(await valueInput.getAttribute('value')).to.equal('')
|
||||||
|
|
||||||
await submitChecklistForm()
|
await submitChecklistForm()
|
||||||
await waitForLogsPage()
|
await waitForLogsPage()
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,10 @@ func (cfg *Config) Sanitize() {
|
||||||
if err := cfg.validateReservedActionArgumentNames(); err != nil {
|
if err := cfg.validateReservedActionArgumentNames(); err != nil {
|
||||||
log.Fatalf("%v", err)
|
log.Fatalf("%v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := cfg.validateChecklistChoiceValues(); err != nil {
|
||||||
|
log.Fatalf("%v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *Config) validateReservedActionArgumentNames() error {
|
func (cfg *Config) validateReservedActionArgumentNames() error {
|
||||||
|
|
@ -60,6 +64,49 @@ func (action *Action) validateReservedArgumentNames() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cfg *Config) validateChecklistChoiceValues() error {
|
||||||
|
for _, action := range cfg.Actions {
|
||||||
|
if err := action.validateChecklistChoiceValues(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (action *Action) validateChecklistChoiceValues() error {
|
||||||
|
if action == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, arg := range action.Arguments {
|
||||||
|
if err := validateChecklistChoicesForArgument(action.Title, arg); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateChecklistChoicesForArgument(actionTitle string, arg ActionArgument) error {
|
||||||
|
if arg.Type != "checklist" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, choice := range arg.Choices {
|
||||||
|
if strings.Contains(choice.Value, ",") {
|
||||||
|
return fmt.Errorf(
|
||||||
|
`action %q argument %q choice value %q must not contain commas`,
|
||||||
|
actionTitle,
|
||||||
|
arg.Name,
|
||||||
|
choice.Value,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (cfg *Config) sanitizeDashboardsForInlineActions() {
|
func (cfg *Config) sanitizeDashboardsForInlineActions() {
|
||||||
for _, dashboard := range cfg.Dashboards {
|
for _, dashboard := range cfg.Dashboards {
|
||||||
cfg.sanitizeDashboardComponentForInlineActions(dashboard)
|
cfg.sanitizeDashboardComponentForInlineActions(dashboard)
|
||||||
|
|
|
||||||
|
|
@ -271,3 +271,26 @@ func TestValidateUniqueLocalUserAPIKeys(t *testing.T) {
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestValidateChecklistChoiceValuesRejectsCommas(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
c := DefaultConfig()
|
||||||
|
c.Actions = append(c.Actions, &Action{
|
||||||
|
Title: "Checklist commas",
|
||||||
|
Shell: "true",
|
||||||
|
Arguments: []ActionArgument{
|
||||||
|
{
|
||||||
|
Name: "segments",
|
||||||
|
Type: "checklist",
|
||||||
|
Choices: []ActionArgumentChoice{
|
||||||
|
{Value: "kitchen,bedroom"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
err := c.validateChecklistChoiceValues()
|
||||||
|
require.Error(t, err)
|
||||||
|
assert.Contains(t, err.Error(), `choice value "kitchen,bedroom" must not contain commas`)
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue