discourse/app/assets/javascripts/admin/addon/components/simple-list.gjs
benj 343292688c
FIX: Removes debugging line (#35157)
Found while working on a customization. Caused a floating integer in the
admin settings.

Before:
<img width="426" height="199" alt="Screenshot 2025-10-02 at 1 08 13 PM"
src="https://github.com/user-attachments/assets/98e4148f-6e80-42fd-aa00-272cc05e238e"
/>

After:
<img width="388" height="211" alt="Screenshot 2025-10-02 at 1 37 48 PM"
src="https://github.com/user-attachments/assets/680d4c33-4d2b-44ee-ad4c-6b4ac0eb0bd2"
/>
2025-10-02 14:54:12 -05:00

153 lines
4.3 KiB
Text
Vendored

import Component from "@glimmer/component";
import { cached, tracked } from "@glimmer/tracking";
import { fn, hash } from "@ember/helper";
import { on } from "@ember/modifier";
import { action } from "@ember/object";
import { TrackedArray } from "@ember-compat/tracked-built-ins";
import { gt, not } from "truth-helpers";
import DButton from "discourse/components/d-button";
import withEventValue from "discourse/helpers/with-event-value";
import { i18n } from "discourse-i18n";
import ComboBox from "select-kit/components/combo-box";
// args: onChange, inputDelimiter, values, allowAny, choices
export default class SimpleList extends Component {
@tracked newValue = "";
@cached
get collection() {
return new TrackedArray(
this.args.values
?.split(this.args.inputDelimiter || "\n")
.filter(Boolean) || []
);
}
get isPredefinedList() {
return !this.args.allowAny && this.args.choices?.length > 0;
}
get validValues() {
return this.args.choices?.filter((name) => !this.collection.includes(name));
}
@action
keyDown(event) {
if (event.key === "Enter") {
this.addValue(this.newValue);
}
}
@action
changeValue(index, event) {
this.collection[index] = event.target.value;
this.args.onChange?.(this.collection);
}
@action
addValue(value) {
if (!value) {
return;
}
this.newValue = null;
this.collection.push(value);
this.args.onChange?.(this.collection);
}
@action
removeAt(index) {
this.collection.splice(index, 1);
this.args.onChange?.(this.collection);
}
@action
shift(index, offset) {
let futureIndex = index + offset;
if (futureIndex > this.collection.length - 1) {
futureIndex = 0;
} else if (futureIndex < 0) {
futureIndex = this.collection.length - 1;
}
const shiftedValue = this.collection[index];
this.collection.splice(index, 1);
this.collection.splice(futureIndex, 0, shiftedValue);
this.args.onChange?.(this.collection);
}
<template>
<div class="simple-list value-list" ...attributes>
{{#if this.collection}}
<div class="values">
{{#each this.collection as |value index|}}
<div data-index={{index}} class="value">
<DButton
@action={{fn this.removeAt index}}
@icon="xmark"
class="btn-default remove-value-btn btn-small"
/>
<input
{{on "focusout" (fn this.changeValue index)}}
value={{value}}
title={{value}}
type="text"
class="value-input"
/>
{{#if (gt this.collection.length 1)}}
<DButton
@action={{fn this.shift index -1}}
@icon="arrow-up"
class="btn-default shift-up-value-btn btn-small"
/>
<DButton
@action={{fn this.shift index 1}}
@icon="arrow-down"
class="btn-default shift-down-value-btn btn-small"
/>
{{/if}}
</div>
{{/each}}
</div>
{{/if}}
<div class="simple-list-input">
{{#if this.isPredefinedList}}
{{#if this.validValues}}
<ComboBox
@content={{this.validValues}}
@value={{this.newValue}}
@onChange={{this.addValue}}
@valueProperty={{@setting.computedValueProperty}}
@nameProperty={{@setting.computedNameProperty}}
@options={{hash castInteger=true allowAny=false}}
class="add-value-input"
/>
{{/if}}
{{else}}
<input
{{on "input" (withEventValue (fn (mut this.newValue)))}}
{{on "keydown" this.keyDown}}
value={{this.newValue}}
type="text"
placeholder={{i18n "admin.site_settings.simple_list.add_item"}}
autocomplete="off"
autocorrect="off"
autocapitalize="off"
class="add-value-input"
/>
<DButton
@action={{fn this.addValue this.newValue}}
@disabled={{not this.newValue}}
@icon="plus"
class="add-value-btn btn-small"
/>
{{/if}}
</div>
</div>
</template>
}