replace el-dialog

This commit is contained in:
pa
2026-01-15 15:33:20 +09:00
committed by Natsumi
parent fc13dca0a4
commit 3b47d3a0eb
67 changed files with 7034 additions and 6769 deletions

View File

@@ -1,56 +1,58 @@
<template>
<el-dialog
class="x-dialog"
v-model="bioDialog.visible"
:title="t('dialog.bio.header')"
width="600px"
append-to-body>
<div v-loading="bioDialog.loading">
<InputGroupTextareaField
v-model="bioDialog.bio"
:maxlength="512"
:rows="5"
:placeholder="t('dialog.bio.bio_placeholder')"
class="mb-2.5"
show-count />
<Dialog v-model:open="bioDialog.visible">
<DialogContent class="x-dialog sm:max-w-150">
<DialogHeader>
<DialogTitle>{{ t('dialog.bio.header') }}</DialogTitle>
</DialogHeader>
<InputGroupAction
v-for="(link, index) in bioDialog.bioLinks"
:key="index"
v-model="bioDialog.bioLinks[index]"
:maxlength="64"
show-count
size="sm"
style="margin-top: 5px">
<template #leading>
<img :src="getFaviconUrl(link)" style="width: 16px; height: 16px; vertical-align: middle" />
</template>
<template #actions>
<Button variant="ghost" size="icon-sm" @click="bioDialog.bioLinks.splice(index, 1)"
><Trash2 class="size-4"
/></Button>
</template>
</InputGroupAction>
<div v-loading="bioDialog.loading">
<InputGroupTextareaField
v-model="bioDialog.bio"
:maxlength="512"
:rows="5"
:placeholder="t('dialog.bio.bio_placeholder')"
class="mb-2.5"
show-count />
<Button
variant="outline"
:disabled="bioDialog.bioLinks.length >= 3"
size="sm"
class="mt-2"
@click="bioDialog.bioLinks.push('')">
{{ t('dialog.bio.add_link') }}
</Button>
</div>
<InputGroupAction
v-for="(link, index) in bioDialog.bioLinks"
:key="index"
v-model="bioDialog.bioLinks[index]"
:maxlength="64"
show-count
size="sm"
style="margin-top: 5px">
<template #leading>
<img :src="getFaviconUrl(link)" style="width: 16px; height: 16px; vertical-align: middle" />
</template>
<template #actions>
<Button variant="ghost" size="icon-sm" @click="bioDialog.bioLinks.splice(index, 1)"
><Trash2 class="size-4"
/></Button>
</template>
</InputGroupAction>
<template #footer>
<Button :disabled="bioDialog.loading" @click="saveBio">
{{ t('dialog.bio.update') }}
</Button>
</template>
</el-dialog>
<Button
variant="outline"
:disabled="bioDialog.bioLinks.length >= 3"
size="sm"
class="mt-2"
@click="bioDialog.bioLinks.push('')">
{{ t('dialog.bio.add_link') }}
</Button>
</div>
<DialogFooter>
<Button :disabled="bioDialog.loading" @click="saveBio">
{{ t('dialog.bio.update') }}
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
</template>
<script setup>
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { InputGroupAction, InputGroupTextareaField } from '@/components/ui/input-group';
import { Button } from '@/components/ui/button';
import { Trash2 } from 'lucide-vue-next';

View File

@@ -1,45 +1,49 @@
<template>
<el-dialog
class="x-dialog"
:model-value="props.visible"
title="Edit Note And Memo"
:show-close="false"
top="30vh"
width="500px"
append-to-body
@close="cancel">
<template v-if="!hideUserNotes || (hideUserNotes && hideUserMemos)">
<span class="name my-2">{{ t('dialog.user.info.note') }}</span>
<br />
<InputGroupTextareaField
v-model="note"
:autosize="{ minRows: 6, maxRows: 20 }"
:maxlength="256"
:rows="6"
:placeholder="t('dialog.user.info.note_placeholder')"
input-class="extra resize-none"
class="my-2"
show-count />
</template>
<template v-if="!hideUserMemos || (hideUserNotes && hideUserMemos)">
<span class="name">{{ t('dialog.user.info.memo') }}</span>
<InputGroupTextareaField
v-model="memo"
class="extra mt-2"
:rows="6"
:placeholder="t('dialog.user.info.memo_placeholder')"
input-class="resize-none min-h-0" />
</template>
<template #footer>
<div class="dialog-footer">
<Dialog
:open="props.visible"
@update:open="
(open) => {
if (!open) cancel();
}
">
<DialogContent class="x-dialog sm:max-w-125 translate-y-0" style="top: 30vh" :show-close-button="false">
<DialogHeader>
<DialogTitle>Edit Note And Memo</DialogTitle>
</DialogHeader>
<template v-if="!hideUserNotes || (hideUserNotes && hideUserMemos)">
<span class="name my-2">{{ t('dialog.user.info.note') }}</span>
<br />
<InputGroupTextareaField
v-model="note"
:autosize="{ minRows: 6, maxRows: 20 }"
:maxlength="256"
:rows="6"
:placeholder="t('dialog.user.info.note_placeholder')"
input-class="extra resize-none"
class="my-2"
show-count />
</template>
<template v-if="!hideUserMemos || (hideUserNotes && hideUserMemos)">
<span class="name">{{ t('dialog.user.info.memo') }}</span>
<InputGroupTextareaField
v-model="memo"
class="extra mt-2"
:rows="6"
:placeholder="t('dialog.user.info.memo_placeholder')"
input-class="resize-none min-h-0" />
</template>
<DialogFooter>
<Button variant="secondary" @click="cancel" class="mr-2">Cancel</Button>
<Button @click="saveChanges">Confirm</Button>
</div>
</template>
</el-dialog>
</DialogFooter>
</DialogContent>
</Dialog>
</template>
<script setup>
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { ref, watch } from 'vue';
import { Button } from '@/components/ui/button';
import { InputGroupTextareaField } from '@/components/ui/input-group';

View File

@@ -1,63 +1,67 @@
<template>
<el-dialog
class="x-dialog"
v-model="languageDialog.visible"
:title="t('dialog.language.header')"
width="400px"
append-to-body>
<div v-loading="languageDialog.loading">
<div v-for="item in currentUser.$languages" :key="item.key" style="margin: 6px 0">
<Badge variant="outline" style="margin-right: 5px">
<span
class="flags"
:class="languageClass(item.key)"
style="display: inline-block; margin-right: 5px"></span>
{{ item.value }} ({{ item.key.toUpperCase() }})
<button
type="button"
style="
margin-left: 6px;
border: none;
background: transparent;
padding: 0;
display: inline-flex;
align-items: center;
color: inherit;
cursor: pointer;
"
@click="removeUserLanguage(item.key)">
<X class="h-3 w-3" />
</button>
</Badge>
<Dialog v-model:open="languageDialog.visible">
<DialogContent class="x-dialog sm:max-w-100">
<DialogHeader>
<DialogTitle>{{ t('dialog.language.header') }}</DialogTitle>
</DialogHeader>
<div v-loading="languageDialog.loading">
<div v-for="item in currentUser.$languages" :key="item.key" style="margin: 6px 0">
<Badge variant="outline" style="margin-right: 5px">
<span
class="flags"
:class="languageClass(item.key)"
style="display: inline-block; margin-right: 5px"></span>
{{ item.value }} ({{ item.key.toUpperCase() }})
<button
type="button"
style="
margin-left: 6px;
border: none;
background: transparent;
padding: 0;
display: inline-flex;
align-items: center;
color: inherit;
cursor: pointer;
"
@click="removeUserLanguage(item.key)">
<X class="h-3 w-3" />
</button>
</Badge>
</div>
<Select
:model-value="selectedLanguageToAdd"
:disabled="
languageDialog.loading || (currentUser.$languages && currentUser.$languages.length === 3)
"
@update:modelValue="handleAddUserLanguage">
<SelectTrigger size="sm" style="margin-top: 14px">
<SelectValue :placeholder="t('dialog.language.select_language')" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectItem
v-for="item in languageDialog.languages"
:key="item.key"
:value="item.key"
:text-value="item.value">
<span
class="flags"
:class="languageClass(item.key)"
style="display: inline-block; margin-right: 5px"></span>
{{ item.value }} ({{ item.key.toUpperCase() }})
</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
</div>
<Select
:model-value="selectedLanguageToAdd"
:disabled="languageDialog.loading || (currentUser.$languages && currentUser.$languages.length === 3)"
@update:modelValue="handleAddUserLanguage">
<SelectTrigger size="sm" style="margin-top: 14px">
<SelectValue :placeholder="t('dialog.language.select_language')" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectItem
v-for="item in languageDialog.languages"
:key="item.key"
:value="item.key"
:text-value="item.value">
<span
class="flags"
:class="languageClass(item.key)"
style="display: inline-block; margin-right: 5px"></span>
{{ item.value }} ({{ item.key.toUpperCase() }})
</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
</div>
</el-dialog>
</DialogContent>
</Dialog>
</template>
<script setup>
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { X } from 'lucide-vue-next';
import { ref } from 'vue';
import { storeToRefs } from 'pinia';

View File

@@ -1,35 +1,37 @@
<template>
<el-dialog
:z-index="previousInstancesUserDialogIndex"
v-model="isVisible"
:title="t('dialog.previous_instances.header')"
width="1000px"
append-to-body>
<DataTableLayout
class="min-w-0 w-full"
:table="table"
:loading="loading"
:table-style="tableStyle"
:page-sizes="pageSizes"
:total-items="totalItems"
:on-page-size-change="handlePageSizeChange">
<template #toolbar>
<div style="display: flex; align-items: center; justify-content: space-between">
<span style="font-size: 14px" v-text="previousInstancesUserDialog.userRef.displayName"></span>
<InputGroupField
v-model="search"
:placeholder="t('dialog.previous_instances.search_placeholder')"
clearable
class="w-1/3"
style="display: block" />
</div>
</template>
</DataTableLayout>
</el-dialog>
<Dialog v-model:open="isVisible">
<DialogContent class="sm:max-w-250">
<DialogHeader>
<DialogTitle>{{ t('dialog.previous_instances.header') }}</DialogTitle>
</DialogHeader>
<DataTableLayout
class="min-w-0 w-full"
:table="table"
:loading="loading"
:table-style="tableStyle"
:page-sizes="pageSizes"
:total-items="totalItems"
:on-page-size-change="handlePageSizeChange">
<template #toolbar>
<div style="display: flex; align-items: center; justify-content: space-between">
<span style="font-size: 14px" v-text="previousInstancesUserDialog.userRef.displayName"></span>
<InputGroupField
v-model="search"
:placeholder="t('dialog.previous_instances.search_placeholder')"
clearable
class="w-1/3"
style="display: block" />
</div>
</template>
</DataTableLayout>
</DialogContent>
</Dialog>
</template>
<script setup>
import { computed, nextTick, ref, watch } from 'vue';
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { computed, ref, watch } from 'vue';
import { InputGroupField } from '@/components/ui/input-group';
import { storeToRefs } from 'pinia';
import { useI18n } from 'vue-i18n';
@@ -52,7 +54,6 @@
import { DataTableLayout } from '../../ui/data-table';
import { createColumns } from './previousInstancesUserColumns.jsx';
import { database } from '../../../service/database';
import { getNextDialogIndex } from '../../../shared/utils/base/ui';
import { useVrcxVueTable } from '../../../lib/table/useVrcxVueTable';
const props = defineProps({
@@ -90,8 +91,6 @@
const vrcxStore = useVrcxStore();
const { t } = useI18n();
const previousInstancesUserDialogIndex = ref(2000);
const isVisible = computed({
get: () => props.previousInstancesUserDialog.visible,
set: (value) => {
@@ -178,9 +177,6 @@
() => props.previousInstancesUserDialog.openFlg,
() => {
if (props.previousInstancesUserDialog.visible) {
nextTick(() => {
previousInstancesUserDialogIndex.value = getNextDialogIndex();
});
refreshPreviousInstancesUserTable();
}
}

View File

@@ -1,27 +1,30 @@
<template>
<el-dialog
class="x-dialog"
v-model="pronounsDialog.visible"
:title="t('dialog.pronouns.header')"
width="600px"
append-to-body>
<div v-loading="pronounsDialog.loading">
<InputGroupTextareaField
v-model="pronounsDialog.pronouns"
:maxlength="32"
:rows="2"
:placeholder="t('dialog.pronouns.pronouns_placeholder')"
show-count />
</div>
<template #footer>
<Button :disabled="pronounsDialog.loading" @click="savePronouns">
{{ t('dialog.pronouns.update') }}
</Button>
</template>
</el-dialog>
<Dialog v-model:open="pronounsDialog.visible">
<DialogContent class="x-dialog sm:max-w-150">
<DialogHeader>
<DialogTitle>{{ t('dialog.pronouns.header') }}</DialogTitle>
</DialogHeader>
<div v-loading="pronounsDialog.loading">
<InputGroupTextareaField
v-model="pronounsDialog.pronouns"
:maxlength="32"
:rows="2"
:placeholder="t('dialog.pronouns.pronouns_placeholder')"
show-count />
</div>
<DialogFooter>
<Button :disabled="pronounsDialog.loading" @click="savePronouns">
{{ t('dialog.pronouns.update') }}
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
</template>
<script setup>
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { InputGroupTextareaField } from '@/components/ui/input-group';
import { toast } from 'vue-sonner';

View File

@@ -1,30 +1,37 @@
<template>
<el-dialog
class="x-dialog"
:model-value="sendInviteRequestDialogVisible"
:title="t('dialog.invite_request_message.header')"
width="800px"
append-to-body
@close="cancelSendInviteRequest">
<template v-if="isLocalUserVrcPlusSupporter">
<input class="inviteImageUploadButton" type="file" accept="image/*" @change="inviteImageUpload" />
</template>
<Dialog
:open="sendInviteRequestDialogVisible"
@update:open="
(open) => {
if (!open) cancelSendInviteRequest();
}
">
<DialogContent class="x-dialog sm:max-w-200">
<DialogHeader>
<DialogTitle>{{ t('dialog.invite_request_message.header') }}</DialogTitle>
</DialogHeader>
<DataTableLayout
style="margin-top: 10px"
:table="inviteRequestMessageTanstackTable"
:loading="false"
:show-pagination="false"
:on-row-click="handleInviteRequestMessageRowClick" />
<template v-if="isLocalUserVrcPlusSupporter">
<input class="inviteImageUploadButton" type="file" accept="image/*" @change="inviteImageUpload" />
</template>
<DataTableLayout
style="margin-top: 10px"
:table="inviteRequestMessageTanstackTable"
:loading="false"
:show-pagination="false"
:on-row-click="handleInviteRequestMessageRowClick" />
<DialogFooter>
<Button variant="secondary" class="mr-2" @click="cancelSendInviteRequest">{{
t('dialog.invite_request_message.cancel')
}}</Button>
<Button @click="refreshInviteMessageTableData('request')">{{
t('dialog.invite_request_message.refresh')
}}</Button>
</DialogFooter>
</DialogContent>
<template #footer>
<Button variant="secondary" class="mr-2" @click="cancelSendInviteRequest">{{
t('dialog.invite_request_message.cancel')
}}</Button>
<Button @click="refreshInviteMessageTableData('request')">{{
t('dialog.invite_request_message.refresh')
}}</Button>
</template>
<SendInviteConfirmDialog
v-model:isSendInviteConfirmDialogVisible="isSendInviteConfirmDialogVisible"
:sendInviteDialog="sendInviteDialog"
@@ -37,10 +44,11 @@
@update:sendInviteDialog="emit('update:sendInviteDialog', $event)"
:invite-dialog="inviteDialog"
@closeInviteDialog="closeInviteDialog" />
</el-dialog>
</Dialog>
</template>
<script setup>
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { computed, ref } from 'vue';
import { Button } from '@/components/ui/button';
import { DataTableLayout } from '@/components/ui/data-table';

View File

@@ -1,96 +1,98 @@
<template>
<el-dialog
class="x-dialog"
v-model="socialStatusDialog.visible"
:title="t('dialog.social_status.header')"
append-to-body
width="400px">
<div v-loading="socialStatusDialog.loading">
<Select :model-value="socialStatusDialog.status" @update:modelValue="handleSocialStatusChange">
<SelectTrigger size="sm" style="margin-top: 10px; width: 100%">
<span class="flex items-center gap-2">
<i v-if="socialStatusDialog.status === 'join me'" class="x-user-status joinme"></i>
<i v-else-if="socialStatusDialog.status === 'active'" class="x-user-status online"></i>
<i v-else-if="socialStatusDialog.status === 'ask me'" class="x-user-status askme"></i>
<i v-else-if="socialStatusDialog.status === 'busy'" class="x-user-status busy"></i>
<i v-else-if="socialStatusDialog.status === 'offline'" class="x-user-status offline"></i>
<SelectValue :placeholder="t('dialog.social_status.status_placeholder')" />
</span>
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectItem value="join me" :text-value="t('dialog.user.status.join_me')">
<i class="x-user-status joinme"></i> {{ t('dialog.user.status.join_me') }}
</SelectItem>
<SelectItem value="active" :text-value="t('dialog.user.status.online')">
<i class="x-user-status online"></i> {{ t('dialog.user.status.online') }}
</SelectItem>
<SelectItem value="ask me" :text-value="t('dialog.user.status.ask_me')">
<i class="x-user-status askme"></i> {{ t('dialog.user.status.ask_me') }}
</SelectItem>
<SelectItem value="busy" :text-value="t('dialog.user.status.busy')">
<i class="x-user-status busy"></i> {{ t('dialog.user.status.busy') }}
</SelectItem>
<SelectItem
v-if="currentUser.$isModerator"
value="offline"
:text-value="t('dialog.user.status.offline')">
<i class="x-user-status offline"></i> {{ t('dialog.user.status.offline') }}
</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
<Dialog v-model:open="socialStatusDialog.visible">
<DialogContent class="x-dialog sm:max-w-100">
<DialogHeader>
<DialogTitle>{{ t('dialog.social_status.header') }}</DialogTitle>
</DialogHeader>
<InputGroupField
v-model="socialStatusDialog.statusDescription"
:placeholder="t('dialog.social_status.status_placeholder')"
:maxlength="32"
clearable
show-count
class="mt-2.5" />
<Collapsible v-model:open="isOpen" class="mt-3 flex w-full flex-col gap-2">
<div class="flex items-center justify-between gap-4 px-4">
<h4 class="text-sm font-semibold">{{ t('dialog.social_status.history') }}</h4>
<CollapsibleTrigger as-child>
<Button variant="ghost" size="icon" class="size-8">
<ChevronsUpDown />
<span class="sr-only">Toggle</span>
</Button>
</CollapsibleTrigger>
</div>
<div
v-if="!isOpen && latestHistoryItem"
class="cursor-pointer rounded-md border w-full px-4 py-2 font-mono text-sm"
@click="setSocialStatusFromHistory(latestHistoryItem)">
{{ latestHistoryItem.status }}
</div>
<CollapsibleContent class="flex flex-col gap-2">
<div
v-for="item in historyItems"
:key="item.no ?? item.status"
class="cursor-pointer rounded-md border w-full px-4 py-2 font-mono text-sm"
@click="setSocialStatusFromHistory(item)">
{{ item.status }}
<div v-loading="socialStatusDialog.loading">
<Select :model-value="socialStatusDialog.status" @update:modelValue="handleSocialStatusChange">
<SelectTrigger size="sm" style="margin-top: 10px; width: 100%">
<span class="flex items-center gap-2">
<i v-if="socialStatusDialog.status === 'join me'" class="x-user-status joinme"></i>
<i v-else-if="socialStatusDialog.status === 'active'" class="x-user-status online"></i>
<i v-else-if="socialStatusDialog.status === 'ask me'" class="x-user-status askme"></i>
<i v-else-if="socialStatusDialog.status === 'busy'" class="x-user-status busy"></i>
<i v-else-if="socialStatusDialog.status === 'offline'" class="x-user-status offline"></i>
<SelectValue :placeholder="t('dialog.social_status.status_placeholder')" />
</span>
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectItem value="join me" :text-value="t('dialog.user.status.join_me')">
<i class="x-user-status joinme"></i> {{ t('dialog.user.status.join_me') }}
</SelectItem>
<SelectItem value="active" :text-value="t('dialog.user.status.online')">
<i class="x-user-status online"></i> {{ t('dialog.user.status.online') }}
</SelectItem>
<SelectItem value="ask me" :text-value="t('dialog.user.status.ask_me')">
<i class="x-user-status askme"></i> {{ t('dialog.user.status.ask_me') }}
</SelectItem>
<SelectItem value="busy" :text-value="t('dialog.user.status.busy')">
<i class="x-user-status busy"></i> {{ t('dialog.user.status.busy') }}
</SelectItem>
<SelectItem
v-if="currentUser.$isModerator"
value="offline"
:text-value="t('dialog.user.status.offline')">
<i class="x-user-status offline"></i> {{ t('dialog.user.status.offline') }}
</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
<InputGroupField
v-model="socialStatusDialog.statusDescription"
:placeholder="t('dialog.social_status.status_placeholder')"
:maxlength="32"
clearable
show-count
class="mt-2.5" />
<Collapsible v-model:open="isOpen" class="mt-3 flex w-full flex-col gap-2">
<div class="flex items-center justify-between gap-4 px-4">
<h4 class="text-sm font-semibold">{{ t('dialog.social_status.history') }}</h4>
<CollapsibleTrigger as-child>
<Button variant="ghost" size="icon" class="size-8">
<ChevronsUpDown />
<span class="sr-only">Toggle</span>
</Button>
</CollapsibleTrigger>
</div>
</CollapsibleContent>
</Collapsible>
</div>
<div
v-if="!isOpen && latestHistoryItem"
class="cursor-pointer rounded-md border w-full px-4 py-2 font-mono text-sm"
@click="setSocialStatusFromHistory(latestHistoryItem)">
{{ latestHistoryItem.status }}
</div>
<CollapsibleContent class="flex flex-col gap-2">
<div
v-for="item in historyItems"
:key="item.no ?? item.status"
class="cursor-pointer rounded-md border w-full px-4 py-2 font-mono text-sm"
@click="setSocialStatusFromHistory(item)">
{{ item.status }}
</div>
</CollapsibleContent></Collapsible
>
</div>
<template #footer>
<Button :disabled="socialStatusDialog.loading" @click="saveSocialStatus">
{{ t('dialog.social_status.update') }}
</Button>
</template>
</el-dialog>
<DialogFooter>
<Button :disabled="socialStatusDialog.loading" @click="saveSocialStatus">
{{ t('dialog.social_status.update') }}
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
</template>
<script setup lang="ts">
import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible';
import { computed, ref } from 'vue';
import { Button } from '@/components/ui/button';
import { InputGroupField } from '@/components/ui/input-group';
import { ChevronsUpDown } from 'lucide-vue-next';
import { InputGroupField } from '@/components/ui/input-group';
import { storeToRefs } from 'pinia';
import { toast } from 'vue-sonner';
import { useI18n } from 'vue-i18n';

File diff suppressed because it is too large Load Diff