mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-04-18 06:13:52 +02:00
improve dashboard
This commit is contained in:
@@ -96,7 +96,6 @@
|
||||
"delete": "Delete"
|
||||
},
|
||||
"toolbar": {
|
||||
"editing": "Editing Dashboard",
|
||||
"name_placeholder": "Dashboard Name",
|
||||
"icon_placeholder": "Icon Class (Optional)"
|
||||
},
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
:dashboard-id="id"
|
||||
:is-editing="true"
|
||||
@update-panel="handleUpdatePanel"
|
||||
@remove-row="handleRemoveRow" />
|
||||
@remove-panel="handleRemovePanel" />
|
||||
|
||||
<div
|
||||
class="mt-auto flex min-h-[80px] flex-1 items-center justify-center rounded-md border-2 border-dashed border-muted-foreground/20 text-muted-foreground transition-colors hover:border-primary/40 hover:bg-primary/5"
|
||||
@@ -161,8 +161,14 @@
|
||||
showAddRowOptions.value = false;
|
||||
};
|
||||
|
||||
const handleRemoveRow = (rowIndex) => {
|
||||
editRows.value.splice(rowIndex, 1);
|
||||
const handleRemovePanel = (rowIndex, panelIndex) => {
|
||||
const row = editRows.value[rowIndex];
|
||||
if (!row) return;
|
||||
if (row.panels.length <= 1) {
|
||||
editRows.value.splice(rowIndex, 1);
|
||||
} else {
|
||||
row.panels.splice(panelIndex, 1);
|
||||
}
|
||||
};
|
||||
|
||||
const handleUpdatePanel = (rowIndex, panelIndex, panelKey) => {
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
<template>
|
||||
<div class="flex items-center gap-2 rounded-md border bg-card px-3 py-2">
|
||||
<span class="text-sm font-medium text-muted-foreground">{{ t('dashboard.toolbar.editing') }}</span>
|
||||
<Input
|
||||
:model-value="name"
|
||||
:placeholder="t('dashboard.name_placeholder')"
|
||||
:placeholder="t('dashboard.toolbar.name_placeholder')"
|
||||
class="mx-2 h-7 max-w-[200px] text-sm"
|
||||
@update:model-value="emit('update:name', $event)" />
|
||||
<div class="flex gap-2">
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
<template>
|
||||
<div class="relative flex min-h-0 flex-1 overflow-hidden rounded-md border bg-card">
|
||||
<template v-if="isEditing">
|
||||
<Button
|
||||
v-if="showRemove"
|
||||
variant="ghost"
|
||||
size="icon-sm"
|
||||
class="absolute right-1 top-1 z-20"
|
||||
@click="emit('remove')">
|
||||
<X class="size-4" />
|
||||
</Button>
|
||||
<div class="flex w-full min-h-0 flex-col gap-2 p-3">
|
||||
<div class="flex flex-1 items-center justify-center gap-2 text-xs text-muted-foreground">
|
||||
<i v-if="panelIcon" :class="panelIcon" class="text-base" />
|
||||
@@ -13,7 +21,7 @@
|
||||
</template>
|
||||
|
||||
<template v-else-if="panelKey && panelComponent">
|
||||
<div class="h-full w-full overflow-y-auto">
|
||||
<div class="dashboard-panel h-full w-full overflow-y-auto">
|
||||
<component :is="panelComponent" />
|
||||
</div>
|
||||
</template>
|
||||
@@ -32,6 +40,7 @@
|
||||
|
||||
<script setup>
|
||||
import { computed, ref } from 'vue';
|
||||
import { X } from 'lucide-vue-next';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import { Button } from '@/components/ui/button';
|
||||
@@ -48,10 +57,14 @@
|
||||
isEditing: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
showRemove: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
});
|
||||
|
||||
const emit = defineEmits(['select']);
|
||||
const emit = defineEmits(['select', 'remove']);
|
||||
const { t } = useI18n();
|
||||
const selectorOpen = ref(false);
|
||||
|
||||
@@ -87,3 +100,13 @@
|
||||
selectorOpen.value = false;
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.dashboard-panel :deep(.x-container) {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -9,16 +9,10 @@
|
||||
:key="panelIndex"
|
||||
:panel-key="panelKey"
|
||||
:is-editing="true"
|
||||
:show-remove="true"
|
||||
:class="panelEditClass"
|
||||
@select="(key) => emit('update-panel', rowIndex, panelIndex, key)" />
|
||||
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon-sm"
|
||||
class="absolute right-1 top-2 z-20 bg-background/80"
|
||||
@click="emit('remove-row', rowIndex)">
|
||||
<X class="size-4" />
|
||||
</Button>
|
||||
@select="(key) => emit('update-panel', rowIndex, panelIndex, key)"
|
||||
@remove="emit('remove-panel', rowIndex, panelIndex)" />
|
||||
</div>
|
||||
|
||||
<ResizablePanelGroup
|
||||
@@ -43,9 +37,7 @@
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue';
|
||||
import { X } from 'lucide-vue-next';
|
||||
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from '@/components/ui/resizable';
|
||||
|
||||
import DashboardPanel from './DashboardPanel.vue';
|
||||
@@ -69,7 +61,7 @@
|
||||
}
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update-panel', 'remove-row']);
|
||||
const emit = defineEmits(['update-panel', 'remove-panel']);
|
||||
|
||||
const isVertical = computed(() => props.row.direction === 'vertical');
|
||||
|
||||
|
||||
@@ -126,7 +126,7 @@
|
||||
<Spinner class="text-2xl" />
|
||||
</div>
|
||||
<template v-else-if="searchWorldResults.length > 0">
|
||||
<ItemGroup class="grid grid-cols-5 gap-3">
|
||||
<ItemGroup class="grid gap-3" style="grid-template-columns: repeat(auto-fill, minmax(180px, 1fr))">
|
||||
<Item
|
||||
v-for="world in searchWorldResults"
|
||||
:key="world.id"
|
||||
@@ -200,7 +200,7 @@
|
||||
<Spinner class="text-2xl" />
|
||||
</div>
|
||||
<template v-else-if="searchAvatarPage.length > 0">
|
||||
<ItemGroup class="grid grid-cols-5 gap-3">
|
||||
<ItemGroup class="grid gap-3" style="grid-template-columns: repeat(auto-fill, minmax(180px, 1fr))">
|
||||
<Item
|
||||
v-for="avatar in searchAvatarPage"
|
||||
:key="avatar.id"
|
||||
|
||||
Reference in New Issue
Block a user