Files
api/web/components/LayoutViews/Card/CardGrid.vue
T
Michael Datelle 5d4a16fe8f feat: build docker card layout (#1572)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Introduced a comprehensive Docker management interface with detail and
card views, including new components for container overview, logs,
console, editing, and web preview.
* Added a new layout and navigation system for detailed item views with
tabbed content and groupable card layouts.
* Enabled dynamic loading and registration of Unraid UI web components,
including a new `<unraid-detail-test />` web component.
  * Added new page and layout components for enhanced UI flexibility.

* **Enhancements**
* Updated environment variable handling and documentation, including
production license key support.
* Switched to "@nuxt/ui-pro" for advanced UI features and updated
related configuration.
  * Improved theme initialization and UI configuration injection.

* **Chores**
* Added development dependencies and updated ignore rules for
environment files.
  * Adjusted ESLint configuration for component definition checks.

* **Style**
  * Minor improvements to import statements and style tag formatting.

* **Documentation**
  * Updated example environment variable files and comments for clarity.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: mdatelle <mike@datelle.net>
2025-09-03 15:48:50 -04:00

121 lines
3.2 KiB
Vue

<script setup lang="ts">
import { computed } from 'vue';
import type { Item } from './Card.vue';
import CardGroupHeader from './CardGroupHeader.vue';
import CardItem from './CardItem.vue';
interface Props {
items: Item[];
selectedItems: string[];
selectedItemId?: string;
expandedGroups: Record<string, boolean>;
autostartStates: Record<string, boolean>;
runningStates: Record<string, boolean>;
}
const props = defineProps<Props>();
const emit = defineEmits<{
'update:selectedItems': [items: string[]];
'item-select': [itemId: string];
'update:expandedGroups': [groups: Record<string, boolean>];
'update:autostart': [itemId: string, value: boolean];
'toggle-running': [itemId: string];
}>();
const flattenedItems = computed(() => {
const result: Array<Item & { isGroupChild?: boolean; parentGroup?: string }> = [];
for (const item of props.items) {
if (item.isGroup && item.children) {
// Add group header
result.push(item);
// Add children only if group is expanded
if (props.expandedGroups[item.id]) {
for (const child of item.children) {
result.push({
...child,
isGroupChild: true,
parentGroup: item.id,
});
}
}
} else {
result.push(item);
}
}
return result;
});
const toggleItemSelection = (itemId: string) => {
const newItems = [...props.selectedItems];
const index = newItems.indexOf(itemId);
if (index > -1) {
newItems.splice(index, 1);
} else {
newItems.push(itemId);
}
emit('update:selectedItems', newItems);
};
const isItemSelected = (itemId: string) => {
return props.selectedItems.includes(itemId);
};
const handleItemClick = (itemId: string) => {
emit('item-select', itemId);
};
const toggleGroupExpansion = (groupId: string) => {
const newGroups = { ...props.expandedGroups };
newGroups[groupId] = !newGroups[groupId];
emit('update:expandedGroups', newGroups);
};
const handleAutostartUpdate = (itemId: string, value: boolean) => {
emit('update:autostart', itemId, value);
};
const handleToggleRunning = (itemId: string) => {
emit('toggle-running', itemId);
};
</script>
<template>
<div class="p-6 w-full">
<div class="space-y-4 w-full max-w-full">
<template v-for="item in flattenedItems" :key="item.id">
<!-- Group Header -->
<CardGroupHeader
v-if="item.isGroup"
:label="item.label"
:icon="item.icon"
:badge="item.badge"
:is-expanded="expandedGroups[item.id]"
@toggle="toggleGroupExpansion(item.id)"
/>
<!-- Regular Card Item -->
<CardItem
v-else
:item="item"
:is-selected="isItemSelected(item.id)"
:is-active="selectedItemId === item.id"
:is-group-child="item.isGroupChild"
:autostart-value="autostartStates[item.id] || false"
:is-running="runningStates[item.id] || false"
@toggle-selection="toggleItemSelection"
@click="handleItemClick"
@update:autostart="handleAutostartUpdate(item.id, $event)"
@toggle-running="handleToggleRunning"
/>
</template>
</div>
</div>
</template>