Hauteur de cellule relative au viewport (h-[68dvh] min-h-80 lg:h-[calc((100dvh-9rem)/2)]) au lieu de h-80 fixe : terminaux grands sur PC, exploitables sur mobile. xterm se re-fit via son ResizeObserver.
36 lines
1.3 KiB
Vue
36 lines
1.3 KiB
Vue
<template>
|
|
<div class="flex flex-col gap-2">
|
|
<p v-if="sessions.length === 0" class="text-sm text-zinc-500">{{ t('groups.gridEmpty') }}</p>
|
|
<template v-else>
|
|
<p v-if="sessions.length > MAX_CELLS" class="text-xs text-amber-400">
|
|
{{ t('groups.gridCapped', { shown: MAX_CELLS, total: sessions.length }) }}
|
|
</p>
|
|
<!-- une seule socket WS multiplexe tous les terminaux ; cap dur pour préserver GPU/canaux.
|
|
Sur mobile la grille retombe à une colonne (empilement). Hauteur relative au viewport
|
|
(dvh) : terminaux grands sur PC, exploitables sur mobile ; xterm re-fit via ResizeObserver.
|
|
Plancher min-h-80 pour les fenêtres courtes. -->
|
|
<div class="grid grid-cols-1 gap-3 lg:grid-cols-2 2xl:grid-cols-3">
|
|
<TerminalCell
|
|
v-for="s in shown"
|
|
:key="s.id"
|
|
:session="s"
|
|
class="h-[68dvh] min-h-80 lg:h-[calc((100dvh-9rem)/2)]"
|
|
/>
|
|
</div>
|
|
</template>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { computed } from 'vue';
|
|
import { useI18n } from 'vue-i18n';
|
|
import type { SessionSummary } from '@arboretum/shared';
|
|
import TerminalCell from './TerminalCell.vue';
|
|
|
|
const props = defineProps<{ sessions: SessionSummary[] }>();
|
|
const { t } = useI18n();
|
|
|
|
const MAX_CELLS = 6;
|
|
const shown = computed(() => props.sessions.slice(0, MAX_CELLS));
|
|
</script>
|