This commit is contained in:
kakkokari-gtyih 2024-09-01 22:55:14 +09:00
parent d7036b0854
commit 7bfcd6d065
3 changed files with 42 additions and 23 deletions

View File

@ -37,8 +37,8 @@ SPDX-License-Identifier: AGPL-3.0-only
<div v-if="type === 'and' || type === 'or'" class="_gaps"> <div v-if="type === 'and' || type === 'or'" class="_gaps">
<div ref="dndParentEl" class="_gaps"> <div ref="dndParentEl" class="_gaps">
<div v-for="cond in values" :class="$style.item"> <div v-for="valueId in valueIds" :key="valueId" :class="$style.item">
<RolesEditorFormula :modelValue="cond" draggable @update:modelValue="updated => valuesItemUpdated(updated)" @remove="removeItem(cond)"/> <RolesEditorFormula :modelValue="valueKv[valueId]" draggable @update:modelValue="valuesItemUpdated" @remove="removeItem(valueId)"/>
</div> </div>
</div> </div>
<MkButton rounded style="margin: 0 auto;" @click="addValue"><i class="ti ti-plus"></i> {{ i18n.ts.add }}</MkButton> <MkButton rounded style="margin: 0 auto;" @click="addValue"><i class="ti ti-plus"></i> {{ i18n.ts.add }}</MkButton>
@ -75,7 +75,7 @@ import { deepClone } from '@/scripts/clone.js';
import { rolesCache } from '@/cache.js'; import { rolesCache } from '@/cache.js';
const emit = defineEmits<{ const emit = defineEmits<{
(ev: 'update:modelValue', value: any): void; (ev: 'update:modelValue', value: Misskey.entities.RoleCondFormulaValue): void;
(ev: 'remove'): void; (ev: 'remove'): void;
}>(); }>();
@ -95,24 +95,38 @@ function assertValueNot(f: Misskey.entities.RoleCondFormulaValue): f is Misskey.
const dndParentEl = shallowRef<HTMLElement>(); const dndParentEl = shallowRef<HTMLElement>();
const v = ref(deepClone(props.modelValue)); const v = ref(deepClone(props.modelValue));
const values = computed({ const valueKv = computed(() => {
if (assertLogicFormula(v.value)) {
return Object.fromEntries(v.value.values.map(v => [v.id, v] as const));
} else {
return [];
}
});
const valueIds = computed({
get: () => { get: () => {
if (assertLogicFormula(v.value)) { if (assertLogicFormula(v.value)) {
return v.value.values; return v.value.values.map(v => v.id);
} else { } else {
return []; return [];
} }
}, },
set: (newVal) => { set: (newVal) => {
if (assertLogicFormula(v.value)) { if (assertLogicFormula(v.value)) {
v.value.values = newVal; v.value.values = newVal.map(id => {
if (assertLogicFormula(v.value)) {
return v.value.values.find(v => v.id === id) ?? null;
} else {
return null;
}
}).filter(v => v !== null);
} }
} }
}); });
dragAndDrop({ dragAndDrop({
parent: dndParentEl, parent: dndParentEl,
values, values: valueIds,
group: 'roleFormula', group: 'roleFormula',
dragHandle: '.drag-handle', dragHandle: '.drag-handle',
plugins: [animations()], plugins: [animations()],
@ -154,15 +168,15 @@ function addValue() {
v.value.values.push({ id: uuid(), type: 'isRemote' }); v.value.values.push({ id: uuid(), type: 'isRemote' });
} }
function valuesItemUpdated(item) { function valuesItemUpdated(item: Misskey.entities.RoleCondFormulaValue) {
if (!assertLogicFormula(v.value)) return; if (!assertLogicFormula(v.value)) return;
const i = v.value.values.findIndex(_item => _item.id === item.id); const i = v.value.values.findIndex(_item => _item.id === item.id);
v.value.values[i] = item; v.value.values[i] = item;
} }
function removeItem(item: Misskey.entities.RoleCondFormulaValue) { function removeItem(itemId: string) {
if (!assertLogicFormula(v.value)) return; if (!assertLogicFormula(v.value)) return;
v.value.values = v.value.values.filter(_item => _item.id !== item.id); v.value.values = v.value.values.filter(_item => _item.id !== itemId);
} }
function removeSelf() { function removeSelf() {

View File

@ -11,17 +11,17 @@ SPDX-License-Identifier: AGPL-3.0-only
<div class="_gaps_m"> <div class="_gaps_m">
<div>{{ i18n.ts._serverRules.description }}</div> <div>{{ i18n.ts._serverRules.description }}</div>
<div ref="dndParentEl" class="_gaps_m"> <div ref="dndParentEl" class="_gaps_m">
<div v-for="rule, index in serverRules" :key="`${rule}_${index}`" :class="$style.item"> <div v-for="rule, index in serverRules" :key="rule.id" :class="$style.item">
<div :class="$style.itemHeader"> <div :class="$style.itemHeader">
<div :class="$style.itemNumber" v-text="String(index + 1)"/> <div :class="$style.itemNumber" v-text="String(index + 1)"/>
<span :class="$style.itemHandle" class="handle"><i class="ti ti-menu"/></span> <span :class="$style.itemHandle" class="handle"><i class="ti ti-menu"/></span>
<button class="_button" :class="$style.itemRemove" @click="remove(index)"><i class="ti ti-x"></i></button> <button class="_button" :class="$style.itemRemove" @click="remove(rule.id)"><i class="ti ti-x"></i></button>
</div> </div>
<MkInput v-model="serverRules[index]"/> <MkInput v-model="rule.value"/>
</div> </div>
</div> </div>
<div :class="$style.commands"> <div :class="$style.commands">
<MkButton rounded @click="serverRules.push('')"><i class="ti ti-plus"></i> {{ i18n.ts.add }}</MkButton> <MkButton rounded @click="add"><i class="ti ti-plus"></i> {{ i18n.ts.add }}</MkButton>
<MkButton primary rounded @click="save"><i class="ti ti-check"></i> {{ i18n.ts.save }}</MkButton> <MkButton primary rounded @click="save"><i class="ti ti-check"></i> {{ i18n.ts.save }}</MkButton>
</div> </div>
</div> </div>
@ -32,6 +32,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup> <script lang="ts" setup>
import { ref, shallowRef, computed } from 'vue'; import { ref, shallowRef, computed } from 'vue';
import { v4 as uuid } from 'uuid';
import { animations } from '@formkit/drag-and-drop'; import { animations } from '@formkit/drag-and-drop';
import { dragAndDrop } from '@formkit/drag-and-drop/vue'; import { dragAndDrop } from '@formkit/drag-and-drop/vue';
import XHeader from './_header_.vue'; import XHeader from './_header_.vue';
@ -42,7 +43,7 @@ import { definePageMetadata } from '@/scripts/page-metadata.js';
import MkButton from '@/components/MkButton.vue'; import MkButton from '@/components/MkButton.vue';
import MkInput from '@/components/MkInput.vue'; import MkInput from '@/components/MkInput.vue';
const serverRules = ref<string[]>(instance.serverRules); const serverRules = ref<{ id: string; value: string; }[]>(instance.serverRules.map((rule: string) => ({ id: uuid(), value: rule })));
const dndParentEl = shallowRef<HTMLElement>(); const dndParentEl = shallowRef<HTMLElement>();
@ -53,16 +54,20 @@ dragAndDrop({
dragHandle: '.handle', dragHandle: '.handle',
}); });
const save = async () => { async function save() {
await os.apiWithDialog('admin/update-meta', { await os.apiWithDialog('admin/update-meta', {
serverRules: serverRules.value, serverRules: serverRules.value.map(rule => rule.value),
}); });
fetchInstance(true); fetchInstance(true);
}; }
const remove = (index: number): void => { function add() {
serverRules.value.splice(index, 1); serverRules.value.push({ id: uuid(), value: '' });
}; }
function remove(id: string) {
serverRules.value = serverRules.value.filter(rule => rule.id !== id);
}
const headerTabs = computed(() => []); const headerTabs = computed(() => []);

View File

@ -43,8 +43,8 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkButton primary rounded @click="addPinnedNote()"><i class="ti ti-plus"></i></MkButton> <MkButton primary rounded @click="addPinnedNote()"><i class="ti ti-plus"></i></MkButton>
<div ref="dndParentEl"> <div ref="dndParentEl">
<div v-for="pinnedNote, index in pinnedNotes" :class="$style.pinnedNote"> <div v-for="pinnedNote, index in pinnedNotes" :key="pinnedNote.id" :class="$style.pinnedNote">
<button class="_button" :class="$style.pinnedNoteHandle" class="handle"><i class="ti ti-menu"></i></button> <button class="_button handle" :class="$style.pinnedNoteHandle"><i class="ti ti-menu"></i></button>
{{ pinnedNote.id }} {{ pinnedNote.id }}
<button class="_button" :class="$style.pinnedNoteRemove" @click="removePinnedNote(index)"><i class="ti ti-x"></i></button> <button class="_button" :class="$style.pinnedNoteRemove" @click="removePinnedNote(index)"><i class="ti ti-x"></i></button>
</div> </div>