add conditional role tester section
This commit is contained in:
parent
04d45859e6
commit
d77880aa4d
4 changed files with 124 additions and 3 deletions
4
locales/index.d.ts
vendored
4
locales/index.d.ts
vendored
|
|
@ -7782,6 +7782,10 @@ export interface Locale extends ILocale {
|
||||||
* This condition may be incorrect for remote users.
|
* This condition may be incorrect for remote users.
|
||||||
*/
|
*/
|
||||||
"remoteDataWarning": string;
|
"remoteDataWarning": string;
|
||||||
|
/**
|
||||||
|
* Role tester
|
||||||
|
*/
|
||||||
|
"roleTester": string;
|
||||||
};
|
};
|
||||||
"_sensitiveMediaDetection": {
|
"_sensitiveMediaDetection": {
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
34
packages/frontend/src/pages/admin/RolesTester.vue
Normal file
34
packages/frontend/src/pages/admin/RolesTester.vue
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
<!--
|
||||||
|
SPDX-FileCopyrightText: bunnybeam and other Sharkey contributors
|
||||||
|
SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
-->
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="_gaps">
|
||||||
|
<div v-if="type === 'and' || type === 'or'" class="_gaps">
|
||||||
|
<RolesTester v-for="formula in v.values" :key="formula.id" :modelValue="formula" :user="user"/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="type === 'not'" :class="$style.item">
|
||||||
|
<RolesTester v-model="v.value"/>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import type * as Misskey from 'misskey-js';
|
||||||
|
import { deepClone } from '@/utility/clone.js';
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
modelValue: any;
|
||||||
|
user: Misskey.entities.UserDetailed;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const v = ref(deepClone(props.modelValue));
|
||||||
|
|
||||||
|
const type = v.value.type;
|
||||||
|
|
||||||
|
console.log(type);
|
||||||
|
</script>
|
||||||
|
|
@ -48,15 +48,55 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</MkPagination>
|
</MkPagination>
|
||||||
</div>
|
</div>
|
||||||
</MkFolder>
|
</MkFolder>
|
||||||
<MkInfo v-else>{{ i18n.ts._role.isConditionalRole }}</MkInfo>
|
<MkFolder v-else>
|
||||||
|
<template #icon><i class="ti ti-flask"></i></template>
|
||||||
|
<template #label>{{ i18n.ts._role.roleTester }}</template>
|
||||||
|
<div class="_gaps">
|
||||||
|
<div v-if="testUser == null">
|
||||||
|
<MkButton
|
||||||
|
transparent
|
||||||
|
:class="$style.userSelectButton"
|
||||||
|
@click="selectUser"
|
||||||
|
>
|
||||||
|
<div :class="$style.userSelectButtonInner">
|
||||||
|
<span><i class="ti ti-plus"></i></span>
|
||||||
|
<span>{{ i18n.ts.selectUser }}</span>
|
||||||
|
</div>
|
||||||
|
</MkButton>
|
||||||
|
</div>
|
||||||
|
<div v-else :class="$style.userSelectedButtons">
|
||||||
|
<div style="overflow: hidden;">
|
||||||
|
<MkUserCardMini
|
||||||
|
:user="testUser"
|
||||||
|
:withChart="false"
|
||||||
|
:class="$style.userSelectedCard"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button
|
||||||
|
class="_button"
|
||||||
|
:class="$style.userSelectedRemoveButton"
|
||||||
|
@click="removeUser"
|
||||||
|
>
|
||||||
|
<i class="ti ti-x"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="testUser != null">
|
||||||
|
<RolesTester v-model="role.condFormula" :user="testUser"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</MkFolder>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</PageWithHeader>
|
</PageWithHeader>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, reactive, ref } from 'vue';
|
import { computed, reactive, ref, shallowRef } from 'vue';
|
||||||
import XEditor from './roles.editor.vue';
|
import XEditor from './roles.editor.vue';
|
||||||
|
import RolesTester from './RolesTester.vue';
|
||||||
|
import type * as Misskey from 'misskey-js';
|
||||||
import MkFolder from '@/components/MkFolder.vue';
|
import MkFolder from '@/components/MkFolder.vue';
|
||||||
import * as os from '@/os.js';
|
import * as os from '@/os.js';
|
||||||
import { misskeyApi } from '@/utility/misskey-api.js';
|
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||||
|
|
@ -64,9 +104,9 @@ import { i18n } from '@/i18n.js';
|
||||||
import { definePage } from '@/page.js';
|
import { definePage } from '@/page.js';
|
||||||
import MkButton from '@/components/MkButton.vue';
|
import MkButton from '@/components/MkButton.vue';
|
||||||
import MkUserCardMini from '@/components/MkUserCardMini.vue';
|
import MkUserCardMini from '@/components/MkUserCardMini.vue';
|
||||||
import MkInfo from '@/components/MkInfo.vue';
|
|
||||||
import MkPagination from '@/components/MkPagination.vue';
|
import MkPagination from '@/components/MkPagination.vue';
|
||||||
import { useRouter } from '@/router.js';
|
import { useRouter } from '@/router.js';
|
||||||
|
import { instance } from '@/instance.js';
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
|
@ -88,6 +128,8 @@ const role = reactive(await misskeyApi('admin/roles/show', {
|
||||||
roleId: props.id,
|
roleId: props.id,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
const testUser = shallowRef<Misskey.entities.UserDetailed | null>(null);
|
||||||
|
|
||||||
function edit() {
|
function edit() {
|
||||||
router.push('/admin/roles/' + role.id + '/edit');
|
router.push('/admin/roles/' + role.id + '/edit');
|
||||||
}
|
}
|
||||||
|
|
@ -172,6 +214,19 @@ definePage(() => ({
|
||||||
title: `${i18n.ts.role}: ${role.name}`,
|
title: `${i18n.ts.role}: ${role.name}`,
|
||||||
icon: 'ti ti-badge',
|
icon: 'ti ti-badge',
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
function selectUser() {
|
||||||
|
os.selectUser({
|
||||||
|
includeSelf: true,
|
||||||
|
localOnly: instance.noteSearchableScope === 'local',
|
||||||
|
}).then(_user => {
|
||||||
|
testUser.value = _user;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeUser() {
|
||||||
|
testUser.value = null;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" module>
|
<style lang="scss" module>
|
||||||
|
|
@ -212,4 +267,31 @@ definePage(() => ({
|
||||||
transform: rotateX(180deg);
|
transform: rotateX(180deg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.userSelectButton {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
padding: 12px;
|
||||||
|
border: 2px dashed color(from var(--MI_THEME-fg) srgb r g b / 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.userSelectButtonInner {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
min-height: 38px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.userSelectedButtons {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr auto;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.userSelectedRemoveButton {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
color: #ff2a2a;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -265,6 +265,7 @@ _role:
|
||||||
remoteFollowingLessThanOrEq: "Follows X or fewer remote accounts"
|
remoteFollowingLessThanOrEq: "Follows X or fewer remote accounts"
|
||||||
remoteFollowingMoreThanOrEq: "Follows X or more remote accounts"
|
remoteFollowingMoreThanOrEq: "Follows X or more remote accounts"
|
||||||
remoteDataWarning: "This condition may be incorrect for remote users."
|
remoteDataWarning: "This condition may be incorrect for remote users."
|
||||||
|
roleTester: "Role tester"
|
||||||
_emailUnavailable:
|
_emailUnavailable:
|
||||||
banned: "This email address is banned"
|
banned: "This email address is banned"
|
||||||
_signup:
|
_signup:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue