Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 9 additions & 1 deletion dashboard/src/assets/mdi-subset/materialdesignicons-subset.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Auto-generated MDI subset – 268 icons */
/* Auto-generated MDI subset – 270 icons */
/* Do not edit manually. Run: pnpm run subset-icons */

@font-face {
Expand Down Expand Up @@ -1060,6 +1060,14 @@
content: "\F056E";
}

.mdi-view-grid-compact::before {
content: "\F1C61";
}

.mdi-view-grid-outline::before {
content: "\F11D9";
}

.mdi-volume-high::before {
content: "\F057E";
}
Expand Down
Binary file not shown.
Binary file not shown.
117 changes: 62 additions & 55 deletions dashboard/src/components/shared/ExtensionCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ref, computed, watch, useAttrs } from "vue";
import { useCustomizerStore } from "@/stores/customizer";
import { useModuleI18n } from "@/i18n/composables";
import UninstallConfirmDialog from "./UninstallConfirmDialog.vue";
import PluginActivationSwitch from "./PluginActivationSwitch.vue";
import PluginPlatformChip from "./PluginPlatformChip.vue";
import StyledMenu from "./StyledMenu.vue";
import defaultPluginIcon from "/favicon.svg";
Expand All @@ -25,6 +26,10 @@ const props = defineProps({
type: Boolean,
default: false,
},
compact: {
type: Boolean,
default: false,
},
});

// 定义要发送到父组件的事件
Expand Down Expand Up @@ -188,6 +193,7 @@ const openWebui = () => {
<v-card
v-bind="attrs"
class="extension-card mx-auto d-flex flex-column h-100"
:class="{ 'extension-card--compact': compact }"
elevation="0"
height="100%"
:ripple="false"
Expand All @@ -210,7 +216,7 @@ const openWebui = () => {
>
<v-card-text class="extension-card-text">
<div class="extension-content-row">
<div class="extension-image-container">
<div v-if="!compact" class="extension-image-container">
<img
:src="logoSrc"
:alt="extension.name"
Expand All @@ -222,8 +228,8 @@ const openWebui = () => {
<div class="extension-meta-group">
<div class="extension-title-row">
<p
class="text-h3 font-weight-black extension-title"
:class="{ 'text-h4': $vuetify.display.xs }"
class="font-weight-black extension-title"
:class="compact || $vuetify.display.xs ? 'text-h4' : 'text-h3'"
>
<v-tooltip
location="top"
Expand All @@ -241,19 +247,22 @@ const openWebui = () => {
>
</template>
</v-tooltip>
<span v-if="extension.version" class="extension-version">
<span
v-if="extension.version && !compact"
class="extension-version"
>
{{ extension.version }}
</span>
<v-chip
v-if="extension.reserved"
v-if="extension.reserved && !compact"
color="primary"
size="x-small"
class="extension-system-chip"
>
{{ tm("status.system") }}
</v-chip>
<v-chip
v-if="!marketMode"
v-if="!marketMode && !compact"
:color="extension.activated ? 'success' : 'default'"
:prepend-icon="
extension.activated
Expand Down Expand Up @@ -292,40 +301,15 @@ const openWebui = () => {
</v-tooltip>
</p>

<template v-if="!marketMode">
<v-tooltip location="left">
<template v-slot:activator="{ props: tooltipProps }">
<div class="extension-switch-wrap" @click.stop>
<div
v-bind="tooltipProps"
style="display: inline-flex; align-items: center"
>
<v-switch
:model-value="extension.activated"
:aria-label="
extension.activated
? tm('buttons.stop')
: tm('buttons.load')
"
color="success"
density="compact"
hide-details
inset
@update:model-value="toggleActivation"
></v-switch>
</div>
</div>
</template>
<span>{{
extension.activated
? tm("buttons.stop")
: tm("buttons.load")
}}</span>
</v-tooltip>
</template>
<PluginActivationSwitch
v-if="!marketMode && !compact"
:activated="extension.activated"
tooltip-location="left"
@toggle="toggleActivation"
/>
</div>

<div class="extension-chip-group d-flex flex-wrap">
<div v-if="!compact" class="extension-chip-group d-flex flex-wrap">
<v-chip
v-if="extension?.has_update"
color="warning"
Expand Down Expand Up @@ -359,6 +343,7 @@ const openWebui = () => {
</div>

<div
v-if="!compact"
class="extension-desc"
:class="{ 'text-caption': $vuetify.display.xs }"
>
Expand All @@ -370,15 +355,15 @@ const openWebui = () => {

<v-card-actions class="extension-actions">
<template v-if="!marketMode">
<v-spacer></v-spacer>
<v-spacer v-if="!compact"></v-spacer>
<v-tooltip location="top">
<template v-slot:activator="{ props: pinTooltipProps }">
<v-btn
v-bind="pinTooltipProps"
:aria-label="isPinned ? tm('buttons.unpin') : tm('buttons.pin')"
:color="isPinned ? 'primary' : 'secondary'"
:icon="isPinned ? 'mdi-pin' : 'mdi-pin-outline'"
size="small"
:size="compact ? 'x-small' : 'small'"
variant="tonal"
class="extension-pin-btn"
@click.stop="togglePin"
Expand All @@ -392,7 +377,7 @@ const openWebui = () => {
<v-btn
v-bind="actionProps"
icon="mdi-book-open-page-variant"
size="small"
:size="compact ? 'x-small' : 'small'"
variant="tonal"
color="info"
@click.stop="viewReadme"
Expand All @@ -409,7 +394,7 @@ const openWebui = () => {
<v-btn
v-bind="actionProps"
icon="mdi-monitor-dashboard"
size="small"
:size="compact ? 'x-small' : 'small'"
variant="tonal"
color="primary"
:disabled="!extension.activated"
Expand All @@ -423,7 +408,7 @@ const openWebui = () => {
<v-btn
v-bind="actionProps"
icon="mdi-cog"
size="small"
:size="compact ? 'x-small' : 'small'"
variant="tonal"
color="primary"
@click.stop="configure"
Expand All @@ -436,7 +421,7 @@ const openWebui = () => {
<v-btn
v-bind="actionProps"
icon="mdi-refresh"
size="small"
:size="compact ? 'x-small' : 'small'"
variant="tonal"
color="primary"
@click.stop="reloadExtension"
Expand All @@ -449,7 +434,7 @@ const openWebui = () => {
<v-btn
v-bind="menuProps"
icon="mdi-dots-horizontal"
size="small"
:size="compact ? 'x-small' : 'small'"
variant="tonal"
color="secondary"
@click.stop
Expand Down Expand Up @@ -520,6 +505,12 @@ const openWebui = () => {
}}</v-list-item-title>
</v-list-item>
</StyledMenu>

<PluginActivationSwitch
v-if="compact"
:activated="extension.activated"
@toggle="toggleActivation"
/>
</template>
<template v-else>
<v-btn color="primary" size="small" @click.stop="viewReadme">
Expand Down Expand Up @@ -620,20 +611,10 @@ const openWebui = () => {
margin-left: 8px;
}

.extension-switch-wrap {
display: flex;
align-items: center;
flex-shrink: 0;
}

.extension-pin-btn {
flex-shrink: 0;
}

.extension-switch-wrap :deep(.v-switch) {
margin: 0;
}

@media (max-width: 600px) {
.extension-content-row {
gap: 10px;
Expand All @@ -652,4 +633,30 @@ const openWebui = () => {
min-height: 42px;
padding: 0 12px 10px;
}

.extension-card--compact {
align-items: center;
flex-direction: row !important;
min-height: 44px;
}

.extension-card--compact .extension-card-text {
flex: 1 1 auto;
min-width: 0;
padding: 6px 0 6px 12px;
}

.extension-card--compact .extension-content-row,
.extension-card--compact .extension-title-row {
align-items: center;
gap: 4px;
}

.extension-card--compact .extension-actions {
flex: 0 0 auto;
flex-wrap: nowrap;
gap: 2px;
min-height: 0;
padding: 6px 8px 6px 4px;
}
</style>
54 changes: 54 additions & 0 deletions dashboard/src/components/shared/PluginActivationSwitch.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<script setup lang="ts">
import { useModuleI18n } from "@/i18n/composables";

withDefaults(
defineProps<{
activated: boolean;
tooltipLocation?: "top" | "left";
}>(),
{
tooltipLocation: "top",
},
);

const emit = defineEmits(["toggle"]);
const { tm } = useModuleI18n("features/extension");
</script>

<template>
<v-tooltip :location="tooltipLocation">
<template #activator="{ props: tooltipProps }">
<div class="plugin-activation-switch" @click.stop>
<div v-bind="tooltipProps" class="plugin-activation-switch__control">
<v-switch
:model-value="activated"
:aria-label="activated ? tm('buttons.stop') : tm('buttons.load')"
color="success"
density="compact"
hide-details
inset
@update:model-value="emit('toggle')"
/>
</div>
</div>
</template>
<span>{{ activated ? tm("buttons.stop") : tm("buttons.load") }}</span>
</v-tooltip>
</template>

<style scoped>
.plugin-activation-switch {
display: flex;
align-items: center;
flex-shrink: 0;
}

.plugin-activation-switch__control {
display: inline-flex;
align-items: center;
}

.plugin-activation-switch :deep(.v-switch) {
margin: 0;
}
</style>
5 changes: 3 additions & 2 deletions dashboard/src/i18n/locales/en-US/features/extension.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@
"all": "All"
},
"views": {
"card": "Card View",
"list": "List View"
"displayDensity": "Plugin display density",
"detailed": "Detailed mode",
"compact": "Compact mode"
},
"buttons": {
"showSystemPlugins": "Show System Extensions",
Expand Down
5 changes: 3 additions & 2 deletions dashboard/src/i18n/locales/ru-RU/features/extension.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@
"all": "Все"
},
"views": {
"card": "Плитка",
"list": "Список"
"displayDensity": "Плотность отображения плагинов",
"detailed": "Подробный режим",
"compact": "Компактный режим"
},
"buttons": {
"showSystemPlugins": "Показать системные",
Expand Down
5 changes: 3 additions & 2 deletions dashboard/src/i18n/locales/zh-CN/features/extension.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@
"all": "全部"
},
"views": {
"card": "卡片视图",
"list": "列表视图"
"displayDensity": "插件显示密度",
"detailed": "详细模式",
"compact": "紧凑模式"
},
"buttons": {
"showSystemPlugins": "显示系统插件",
Expand Down
2 changes: 0 additions & 2 deletions dashboard/src/views/ExtensionPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,6 @@ const {
updateConfirmDialog,
updateAllConfirmDialog,
changelogDialog,
getInitialListViewMode,
isListView,
pluginSearch,
loading_,
currentPage,
Expand Down
Loading
Loading