Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(xo-lite/network): add side panel informations and some trad #8150

Open
wants to merge 30 commits into
base: lite/network-tab
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
6af7318
feat(xo-lite/network): implementation of network tab and add network …
J0ris-K Nov 20, 2024
658d615
feat(xo-lite/network): add pif store
J0ris-K Nov 20, 2024
76c80fe
feat(xo-lite/network): add pif store
J0ris-K Nov 20, 2024
382826f
remove translation due to duplicate key
J0ris-K Nov 20, 2024
ff997a9
Reactivate network tab
J0ris-K Nov 20, 2024
cca5d62
add functional checkbox and spinner
J0ris-K Nov 20, 2024
258d4b1
improvement
J0ris-K Nov 20, 2024
6b6f5cc
feedback
J0ris-K Nov 28, 2024
9bf1954
feat(xo-lite): creating child components for more readability and add…
J0ris-K Dec 2, 2024
6509b6a
feat(xo-lite): fix ui
J0ris-K Dec 2, 2024
f4faa2e
feat(xo-lite): adding pif status component, some improvement and css
J0ris-K Dec 3, 2024
505131d
review feedback
J0ris-K Dec 4, 2024
1164f4e
review feedback
J0ris-K Dec 12, 2024
5ebade3
review feedback
J0ris-K Dec 12, 2024
46db63d
review feedback
J0ris-K Dec 16, 2024
5659e0a
remove duplicate
J0ris-K Dec 30, 2024
3b6abcc
use new component for status and move code in pif store
J0ris-K Dec 31, 2024
777fc5b
extract type status
J0ris-K Dec 31, 2024
aa9241e
feat(xo-lite): adding pif status component, some improvement and css
J0ris-K Dec 3, 2024
172fca7
feat(xo-lite/network): implementation of network tab and add network …
J0ris-K Nov 20, 2024
618afca
feedback
J0ris-K Nov 28, 2024
c3f05cf
feat(xo-lite): creating child components for more readability and add…
J0ris-K Dec 2, 2024
9698cb3
feat(xo-lite/network): add side panel information and some trad
J0ris-K Nov 20, 2024
67cf17e
feat(xo-lite): add selected pifs in side panel and copy to clipboard
J0ris-K Nov 21, 2024
3e320f3
feat(xo-lite): improvements
J0ris-K Nov 26, 2024
db2c82d
remove duplicate translation
J0ris-K Dec 4, 2024
9836097
remove duplicate translation and add no selection hero in panel
J0ris-K Dec 4, 2024
b23f935
improvement
J0ris-K Dec 5, 2024
3430d8e
remove pif status component since he's in web-core
J0ris-K Dec 31, 2024
a05a2dd
improve
J0ris-K Jan 2, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion @xen-orchestra/lite/src/components/pool/PoolTabBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<RouterTab :to="{ name: 'pool.system', params: { uuid: pool?.uuid } }" disabled>
{{ $t('system') }}
</RouterTab>
<RouterTab :to="{ name: 'pool.network', params: { uuid: pool?.uuid } }" disabled>
<RouterTab :to="{ name: 'pool.network', params: { uuid: pool?.uuid } }">
{{ $t('network') }}
</RouterTab>
<RouterTab :to="{ name: 'pool.storage', params: { uuid: pool?.uuid } }" disabled>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
<template>
<div class="container">
<UiTitle>
{{ $t('host-internal-networks') }}
<template #actions>
<UiButton
v-tooltip="$t('coming-soon')"
disabled
:left-icon="faPlus"
variant="secondary"
accent="info"
size="medium"
>
{{ $t('new') }}
</UiButton>
</template>
</UiTitle>
<div class="content">
<UiQuerySearchBar class="table-query" @search="value => (searchQuery = value)" />
<UiTableActions title="Table actions">
<UiButton
v-tooltip="$t('coming-soon')"
disabled
:left-icon="faEdit"
variant="tertiary"
accent="info"
size="medium"
>
{{ $t('edit') }}
</UiButton>
<UiButton
v-tooltip="$t('coming-soon')"
disabled
:left-icon="faTrash"
variant="tertiary"
accent="danger"
size="medium"
>
{{ $t('delete') }}
</UiButton>
</UiTableActions>
<UiTopBottomTable
:selected-items="selected.length"
:total-items="networkUuids.length"
@toggle-select-all="toggleSelect"
/>
<div v-if="filteredNetworks.length > 0" class="table">
<VtsTable vertical-border>
<thead>
<tr>
<template v-for="column of visibleColumns" :key="column.id">
<th v-if="column.id === 'checkbox'" class="checkbox">
<UiCheckbox :v-model="areAllSelected" accent="info" @update:model-value="toggleSelect" />
</th>
<th v-else-if="column.id === 'more'" class="more">
<UiButtonIcon size="small" accent="info" :icon="getHeaderIcon(column.id)" />
{{ column.label }}
</th>
<ColumnTitle v-else :icon="getHeaderIcon(column.id)">
<span class="text-ellipsis">{{ column.label }}</span>
</ColumnTitle>
</template>
</tr>
</thead>
<tbody>
<tr
v-for="row of rows"
:key="row.id"
:class="{ 'row-selected': selectedRowId === (row.value as XenApiNetwork).uuid }"
@click="selectRow(row.value, 'host-internal-network')"
>
<td v-for="column of row.visibleColumns" :key="column.id" class="typo p2-regular">
<UiCheckbox v-if="column.id === 'checkbox'" v-model="selected" accent="info" :value="row.id" />
<VtsIcon v-else-if="column.id === 'more'" accent="info" :icon="faEllipsis" />
<div v-else v-tooltip="{ placement: 'bottom-end' }" class="text-ellipsis">
{{ column.value }}
</div>
</td>
</tr>
</tbody>
</VtsTable>
</div>

<VtsStateHero v-if="searchQuery && filteredNetworks.length === 0" type="table" image="no-result">
<div>{{ $t('no-result') }}</div>
</VtsStateHero>

<UiCardSpinner v-if="!isReady" />
<UiTopBottomTable
:selected-items="selected.length"
:total-items="networkUuids.length"
@toggle-select-all="toggleSelect"
/>
</div>
</div>
</template>

<script setup lang="ts">
import UiCardSpinner from '@/components/ui/UiCardSpinner.vue'
import useMultiSelect from '@/composables/multi-select.composable'
import type { XenApiNetwork } from '@/libs/xen-api/xen-api.types'
import VtsIcon from '@core/components/icon/VtsIcon.vue'
import VtsStateHero from '@core/components/state-hero/VtsStateHero.vue'
import ColumnTitle from '@core/components/table/ColumnTitle.vue'
import VtsTable from '@core/components/table/VtsTable.vue'
import UiButton from '@core/components/ui/button/UiButton.vue'
import UiButtonIcon from '@core/components/ui/button-icon/UiButtonIcon.vue'
import UiCheckbox from '@core/components/ui/checkbox/UiCheckbox.vue'
import UiQuerySearchBar from '@core/components/ui/query-search-bar/UiQuerySearchBar.vue'
import UiTableActions from '@core/components/ui/table-actions/UiTableActions.vue'
import UiTitle from '@core/components/ui/title/UiTitle.vue'
import UiTopBottomTable from '@core/components/ui/top-bottom-table/UiTopBottomTable.vue'
import { useTable } from '@core/composables/table.composable'
import { vTooltip } from '@core/directives/tooltip.directive'
import type { IconDefinition } from '@fortawesome/fontawesome-common-types'
import {
faAlignLeft,
faCaretDown,
faEdit,
faEllipsis,
faHashtag,
faPlus,
faTrash,
} from '@fortawesome/free-solid-svg-icons'
import { computed, ref } from 'vue'

const { networks, isReady } = defineProps<{
networks: XenApiNetwork[]
isReady: boolean
selectedRowId: string | null
}>()

const emit = defineEmits<{
rowSelectNetwork: [value: any]
}>()

const searchQuery = ref('')

const selectRow = (item: any, table: string) => {
emit('rowSelectNetwork', { item, table })
}

const filteredNetworks = computed(() => {
const searchTerm = searchQuery.value.trim().toLocaleLowerCase()
if (!searchTerm) {
return networks
}
return networks.filter(network =>
Object.values(network).some(value => String(value).toLocaleLowerCase().includes(searchTerm))
)
})

const networkUuids = computed(() => networks.map(network => network.uuid))

const { selected, areAllSelected } = useMultiSelect(networkUuids)

const toggleSelect = () => {
selected.value = selected.value.length === 0 ? networkUuids.value : []
}

const { visibleColumns, rows } = useTable('networks', filteredNetworks, {
rowId: record => record.uuid,
columns: define => [
define('checkbox', () => '', { label: '', isHideable: false }),
define('name_label', { label: 'Name', isHideable: true }),
define('name_description', { label: 'Description', isHideable: true }),
define('MTU', { label: 'MTU', isHideable: true }),
define('default_locking_mode', { label: 'Default Locking mode', isHideable: true }),
define('more', () => '', { label: '', isHideable: false }),
],
})

type NetworkHeader = 'name_label' | 'name_description' | 'MTU' | 'default_locking_mode' | 'more'

const headerIcon: Record<NetworkHeader, IconDefinition> = {
name_label: faAlignLeft,
name_description: faAlignLeft,
MTU: faHashtag,
default_locking_mode: faCaretDown,
more: faEllipsis,
}

const getHeaderIcon = (status: NetworkHeader) => headerIcon[status]
</script>

<style scoped lang="postcss">
.container,
.content {
display: flex;
flex-direction: column;
}

.container {
gap: 2.4rem;

.content {
gap: 0.8rem;

.table {
overflow-x: auto;

tbody tr:hover {
cursor: pointer;
background-color: var(--color-info-background-hover);
}

tr:last-child {
border-bottom: 1px solid var(--color-neutral-border);
}
}

.row-selected {
background-color: var(--color-info-background-selected);
}

.checkbox,
.more {
width: 4.8rem;
}
}
}
</style>
Loading
Loading