This commit is contained in:
pa
2026-03-10 23:09:04 +09:00
parent 607e09d271
commit 1c9e4621f5
10 changed files with 216 additions and 49 deletions

View File

@@ -80,12 +80,11 @@ vi.mock('../../../../services/request', () => ({
}));
vi.mock('vue-i18n', () => ({
useI18n: () => ({
t: (key) => key
,
locale: require('vue').ref('en')
}),
t: (key) => key,
locale: require('vue').ref('en')
}),
createI18n: () => ({
global: { t: (key) => key , locale: require('vue').ref('en') },
global: { t: (key) => key, locale: require('vue').ref('en') },
install: vi.fn()
})
}));
@@ -96,7 +95,7 @@ vi.mock('worker-timers', () => ({
import { useGroupMembers } from '../useGroupMembers';
import { groupRequest, queryRequest } from '../../../../api';
import { groupDialogFilterOptions } from '../../../../shared/constants';
import { FILTER_EVERYONE } from '../../../../shared/constants';
/**
*
@@ -409,9 +408,7 @@ describe('useGroupMembers', () => {
test('marks done on error', async () => {
const groupDialog = createGroupDialog();
queryRequest.fetch.mockRejectedValue(
new Error('fail')
);
queryRequest.fetch.mockRejectedValue(new Error('fail'));
const {
loadMoreGroupMembers,
@@ -450,7 +447,7 @@ describe('useGroupMembers', () => {
describe('setGroupMemberFilter', () => {
test('does not reload when filter unchanged', async () => {
const { markRaw } = require('vue');
const filter = markRaw(groupDialogFilterOptions.everyone);
const filter = markRaw(FILTER_EVERYONE);
const groupDialog = createGroupDialog();
// Use markRaw to prevent Vue from wrapping the filter in a Proxy
groupDialog.value.memberFilter = filter;

View File

@@ -2,7 +2,9 @@ import { computed, ref } from 'vue';
import {
groupDialogFilterOptions,
groupDialogSortingOptions
groupDialogSortingOptions,
FILTER_EVERYONE,
FILTER_NO_ROLE
} from '../../../shared/constants';
import { groupRequest, queryRequest } from '../../../api';
import { debounce } from '../../../shared/utils';
@@ -39,7 +41,7 @@ export function useGroupMembers(
return groupDialog.value?.memberSortOrder?.value ?? '';
},
set(value) {
const option = Object.values(groupDialogSortingOptions).find(
const option = groupDialogSortingOptions.find(
(item) => item.value === value
);
if (option) {
@@ -61,11 +63,11 @@ export function useGroupMembers(
if (!key) return;
if (key === 'everyone') {
setGroupMemberFilter(groupDialogFilterOptions.everyone);
setGroupMemberFilter(FILTER_EVERYONE);
return;
}
if (key === 'usersWithNoRole') {
setGroupMemberFilter(groupDialogFilterOptions.usersWithNoRole);
setGroupMemberFilter(FILTER_NO_ROLE);
return;
}
@@ -82,18 +84,16 @@ export function useGroupMembers(
});
const groupDialogMemberFilterGroups = computed(() => {
const filterItems = Object.values(groupDialogFilterOptions).map(
(item) => ({
value:
item.id === null
? 'everyone'
: item.id === ''
? 'usersWithNoRole'
: `role:${item.id}`,
label: t(item.name),
search: t(item.name)
})
);
const filterItems = groupDialogFilterOptions.map((item) => ({
value:
item.id === null
? 'everyone'
: item.id === ''
? 'usersWithNoRole'
: `role:${item.id}`,
label: t(item.name),
search: t(item.name)
}));
const roleItems = (groupDialog.value?.ref?.roles ?? [])
.filter((role) => !role.defaultRole)

View File

@@ -1,5 +1,12 @@
<script setup>
import { DialogClose, DialogContent, DialogPortal, useForwardPropsEmits } from 'reka-ui';
import {
DialogClose,
DialogContent,
DialogDescription,
DialogPortal,
useForwardPropsEmits,
VisuallyHidden
} from 'reka-ui';
import { inject, onBeforeUnmount, ref, watch } from 'vue';
import { X } from 'lucide-vue-next';
import { acquireModalPortalLayer } from '@/lib/modalPortalLayers';
@@ -71,6 +78,10 @@
">
<slot />
<VisuallyHidden as-child>
<DialogDescription />
</VisuallyHidden>
<DialogClose
v-if="showCloseButton"
data-slot="dialog-close"

View File

@@ -1,5 +1,13 @@
<script setup>
import { DialogClose, DialogContent, DialogOverlay, DialogPortal, useForwardPropsEmits } from 'reka-ui';
import {
DialogClose,
DialogContent,
DialogDescription,
DialogOverlay,
DialogPortal,
useForwardPropsEmits,
VisuallyHidden
} from 'reka-ui';
import { inject, onBeforeUnmount, ref, watch } from 'vue';
import { X } from 'lucide-vue-next';
import { acquireModalPortalLayer } from '@/lib/modalPortalLayers';
@@ -76,6 +84,10 @@
">
<slot />
<VisuallyHidden as-child>
<DialogDescription />
</VisuallyHidden>
<DialogClose class="absolute top-4 right-4 p-0.5 transition-colors rounded-md hover:bg-secondary">
<X class="w-4 h-4" />
<span class="sr-only">Close</span>