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 ref="dndParentEl" class="_gaps">
<div v-for="cond in values" :class="$style.item">
<RolesEditorFormula :modelValue="cond" draggable @update:modelValue="updated => valuesItemUpdated(updated)" @remove="removeItem(cond)"/>
<div v-for="valueId in valueIds" :key="valueId" :class="$style.item">
<RolesEditorFormula :modelValue="valueKv[valueId]" draggable @update:modelValue="valuesItemUpdated" @remove="removeItem(valueId)"/>
</div>
</div>
<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';
const emit = defineEmits<{
(ev: 'update:modelValue', value: any): void;
(ev: 'update:modelValue', value: Misskey.entities.RoleCondFormulaValue): void;
(ev: 'remove'): void;
}>();
@ -95,24 +95,38 @@ function assertValueNot(f: Misskey.entities.RoleCondFormulaValue): f is Misskey.
const dndParentEl = shallowRef<HTMLElement>();
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: () => {
if (assertLogicFormula(v.value)) {
return v.value.values;
return v.value.values.map(v => v.id);
} else {
return [];
}
},
set: (newVal) => {
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({
parent: dndParentEl,
values,
values: valueIds,
group: 'roleFormula',
dragHandle: '.drag-handle',
plugins: [animations()],
@ -154,15 +168,15 @@ function addValue() {
v.value.values.push({ id: uuid(), type: 'isRemote' });
}
function valuesItemUpdated(item) {
function valuesItemUpdated(item: Misskey.entities.RoleCondFormulaValue) {
if (!assertLogicFormula(v.value)) return;
const i = v.value.values.findIndex(_item => _item.id === item.id);
v.value.values[i] = item;
}
function removeItem(item: Misskey.entities.RoleCondFormulaValue) {
function removeItem(itemId: string) {
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() {

View File

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