mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-26 09:19:43 +00:00
Lint: Add tailwind linter (#5984)
## Summary Adds the [tailwind lint plugin](https://github.com/francoismassart/eslint-plugin-tailwindcss/?tab=readme-ov-file#eslint-plugin-tailwindcss) and fixes the currently fixable rules ([v4 is still in beta](https://github.com/francoismassart/eslint-plugin-tailwindcss/?tab=readme-ov-file#about-tailwind-css-4-support)). ## Changes - **What**: Enforces things like consistent class order, and eventually can prohibit extra classes that could be utilities instead - **Dependencies**: The plugin and its types ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-5984-Lint-Add-tailwind-linter-2866d73d365081d89db0d998232533bb) by [Unito](https://www.unito.io) --------- Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
@@ -3,12 +3,12 @@
|
||||
class="overflow-hidden transition-all duration-300"
|
||||
:class="{
|
||||
'max-h-[500px]': isExpanded,
|
||||
'max-h-0 p-0 m-0': !isExpanded
|
||||
'm-0 max-h-0 p-0': !isExpanded
|
||||
}"
|
||||
>
|
||||
<div
|
||||
ref="sectionsContainerRef"
|
||||
class="px-6 py-4 overflow-y-auto max-h-[450px] scroll-container"
|
||||
class="scroll-container max-h-[450px] overflow-y-auto px-6 py-4"
|
||||
:style="{
|
||||
scrollbarWidth: 'thin',
|
||||
scrollbarColor: 'rgba(156, 163, 175, 0.5) transparent'
|
||||
@@ -22,11 +22,11 @@
|
||||
<Panel
|
||||
:expanded="collapsedPanels[index] === true"
|
||||
toggleable
|
||||
class="shadow-elevation-1 rounded-lg mt-2 dark-theme:bg-black dark-theme:border-black"
|
||||
class="shadow-elevation-1 mt-2 rounded-lg dark-theme:border-black dark-theme:bg-black"
|
||||
>
|
||||
<template #header>
|
||||
<div class="flex items-center justify-between w-full py-2">
|
||||
<div class="flex flex-col text-sm font-medium leading-normal">
|
||||
<div class="flex w-full items-center justify-between py-2">
|
||||
<div class="flex flex-col text-sm leading-normal font-medium">
|
||||
<span>{{ log.taskName }}</span>
|
||||
<span class="text-muted">
|
||||
{{
|
||||
@@ -56,7 +56,7 @@
|
||||
? (el) => (lastPanelRef = el as HTMLElement)
|
||||
: undefined
|
||||
"
|
||||
class="overflow-y-auto h-64 rounded-lg bg-black"
|
||||
class="h-64 overflow-y-auto rounded-lg bg-black"
|
||||
:class="{
|
||||
'h-64': index !== focusedLogs.length - 1,
|
||||
grow: index === focusedLogs.length - 1
|
||||
@@ -69,7 +69,7 @@
|
||||
:key="logIndex"
|
||||
class="text-neutral-400 dark-theme:text-muted"
|
||||
>
|
||||
<pre class="whitespace-pre-wrap break-words">{{ logLine }}</pre>
|
||||
<pre class="break-words whitespace-pre-wrap">{{ logLine }}</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div
|
||||
class="w-full px-6 py-2 shadow-lg flex items-center justify-between"
|
||||
class="flex w-full items-center justify-between px-6 py-2 shadow-lg"
|
||||
:class="{
|
||||
'rounded-t-none': progressDialogContent.isExpanded,
|
||||
'rounded-lg': !progressDialogContent.isExpanded
|
||||
@@ -32,7 +32,7 @@
|
||||
v-if="!isInProgress && !isRestartCompleted"
|
||||
rounded
|
||||
outlined
|
||||
class="mr-4 rounded-md border-2 px-3 text-neutral-600 border-neutral-900 hover:bg-neutral-100 !dark-theme:bg-transparent dark-theme:text-white dark-theme:border-white dark-theme:hover:bg-neutral-800"
|
||||
class="!dark-theme:bg-transparent mr-4 rounded-md border-2 border-neutral-900 px-3 text-neutral-600 hover:bg-neutral-100 dark-theme:border-white dark-theme:text-white dark-theme:hover:bg-neutral-800"
|
||||
@click="handleRestart"
|
||||
>
|
||||
{{ $t('manager.applyChanges') }}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div
|
||||
v-if="progressDialogContent.isExpanded"
|
||||
class="px-4 py-2 flex items-center"
|
||||
class="flex items-center px-4 py-2"
|
||||
>
|
||||
<TabMenu
|
||||
v-model:active-index="activeTabIndex"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div
|
||||
class="h-full flex flex-col mx-auto overflow-hidden"
|
||||
class="mx-auto flex h-full flex-col overflow-hidden"
|
||||
:aria-label="$t('manager.title')"
|
||||
>
|
||||
<ContentDivider :width="0.3" />
|
||||
@@ -9,11 +9,11 @@
|
||||
:icon="isSideNavOpen ? 'pi pi-chevron-left' : 'pi pi-chevron-right'"
|
||||
severity="secondary"
|
||||
filled
|
||||
class="absolute top-1/2 -translate-y-1/2 z-10"
|
||||
class="absolute top-1/2 z-10 -translate-y-1/2"
|
||||
:class="isSideNavOpen ? 'left-[12rem]' : 'left-2'"
|
||||
@click="toggleSideNav"
|
||||
/>
|
||||
<div class="flex flex-1 relative overflow-hidden">
|
||||
<div class="relative flex flex-1 overflow-hidden">
|
||||
<ManagerNavSidebar
|
||||
v-if="isSideNavOpen"
|
||||
v-model:selected-tab="selectedTab"
|
||||
@@ -25,22 +25,22 @@
|
||||
'transition-all duration-300': isSmallScreen
|
||||
}"
|
||||
>
|
||||
<div class="px-6 flex flex-col h-full">
|
||||
<div class="flex h-full flex-col px-6">
|
||||
<!-- Conflict Warning Banner -->
|
||||
<div
|
||||
v-if="shouldShowManagerBanner"
|
||||
class="bg-yellow-500/20 rounded-lg p-4 mt-3 mb-4 flex items-center gap-6 relative"
|
||||
class="relative mt-3 mb-4 flex items-center gap-6 rounded-lg bg-yellow-500/20 p-4"
|
||||
>
|
||||
<i class="pi pi-exclamation-triangle text-yellow-600 text-lg"></i>
|
||||
<div class="flex flex-col gap-2 flex-1">
|
||||
<p class="text-sm font-bold m-0">
|
||||
<i class="pi pi-exclamation-triangle text-lg text-yellow-600"></i>
|
||||
<div class="flex flex-1 flex-col gap-2">
|
||||
<p class="m-0 text-sm font-bold">
|
||||
{{ $t('manager.conflicts.warningBanner.title') }}
|
||||
</p>
|
||||
<p class="text-xs m-0">
|
||||
<p class="m-0 text-xs">
|
||||
{{ $t('manager.conflicts.warningBanner.message') }}
|
||||
</p>
|
||||
<p
|
||||
class="text-sm font-bold m-0 cursor-pointer"
|
||||
class="m-0 cursor-pointer text-sm font-bold"
|
||||
@click="onClickWarningLink"
|
||||
>
|
||||
{{ $t('manager.conflicts.warningBanner.button') }}
|
||||
@@ -52,7 +52,7 @@
|
||||
@click="dismissWarningBanner"
|
||||
>
|
||||
<i
|
||||
class="pi pi-times text-neutral-900 dark-theme:text-white text-xs"
|
||||
class="pi pi-times text-xs text-neutral-900 dark-theme:text-white"
|
||||
></i>
|
||||
</IconButton>
|
||||
</div>
|
||||
@@ -69,7 +69,7 @@
|
||||
<div class="flex-1 overflow-auto">
|
||||
<div
|
||||
v-if="isLoading"
|
||||
class="w-full h-full overflow-auto scrollbar-hide"
|
||||
class="h-full scrollbar-hide w-full overflow-auto"
|
||||
>
|
||||
<GridSkeleton :grid-style="GRID_STYLE" :skeleton-card-count />
|
||||
</div>
|
||||
@@ -110,9 +110,9 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-[clamp(250px,33%,306px)] border-l-0 flex z-20">
|
||||
<div class="z-20 flex w-[clamp(250px,33%,306px)] border-l-0">
|
||||
<ContentDivider orientation="vertical" :width="0.2" />
|
||||
<div class="w-full flex flex-col isolate">
|
||||
<div class="isolate flex w-full flex-col">
|
||||
<InfoPanel
|
||||
v-if="!hasMultipleSelections && selectedNodePack"
|
||||
:node-pack="selectedNodePack"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="w-full">
|
||||
<div class="flex items-center">
|
||||
<h2 class="text-lg font-normal text-left">
|
||||
<h2 class="text-left text-lg font-normal">
|
||||
{{ $t('manager.discoverCommunityContent') }}
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<aside
|
||||
class="flex translate-x-0 max-w-[250px] w-3/12 z-5 transition-transform duration-300 ease-in-out"
|
||||
class="z-5 flex w-3/12 max-w-[250px] translate-x-0 transition-transform duration-300 ease-in-out"
|
||||
>
|
||||
<ScrollPanel class="flex-1">
|
||||
<Listbox
|
||||
@@ -16,8 +16,8 @@
|
||||
}"
|
||||
>
|
||||
<template #option="slotProps">
|
||||
<div class="text-left flex items-center">
|
||||
<i :class="['pi', slotProps.option.icon, 'text-sm mr-2']" />
|
||||
<div class="flex items-center text-left">
|
||||
<i :class="['pi', slotProps.option.icon, 'mr-2 text-sm']" />
|
||||
<span class="text-sm">{{ slotProps.option.label }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<template>
|
||||
<div class="w-[552px] flex flex-col">
|
||||
<div class="flex w-[552px] flex-col">
|
||||
<ContentDivider :width="1" />
|
||||
<div class="px-4 py-6 w-full h-full flex flex-col gap-2">
|
||||
<div class="flex h-full w-full flex-col gap-2 px-4 py-6">
|
||||
<!-- Description -->
|
||||
<div v-if="showAfterWhatsNew">
|
||||
<p
|
||||
class="text-sm leading-4 text-neutral-800 dark-theme:text-white m-0 mb-4"
|
||||
class="m-0 mb-4 text-sm leading-4 text-neutral-800 dark-theme:text-white"
|
||||
>
|
||||
{{ $t('manager.conflicts.description') }}
|
||||
<br /><br />
|
||||
@@ -16,15 +16,16 @@
|
||||
<!-- Import Failed List Wrapper -->
|
||||
<div
|
||||
v-if="importFailedConflicts.length > 0"
|
||||
class="w-full flex flex-col bg-neutral-200 dark-theme:bg-black min-h-8 rounded-lg"
|
||||
class="flex min-h-8 w-full flex-col rounded-lg bg-neutral-200 dark-theme:bg-black"
|
||||
>
|
||||
<div
|
||||
class="w-full h-8 flex items-center justify-between gap-2 pl-4"
|
||||
data-testid="conflict-dialog-panel-toggle"
|
||||
class="flex h-8 w-full items-center justify-between gap-2 pl-4"
|
||||
@click="toggleImportFailedPanel"
|
||||
>
|
||||
<div class="flex-1 flex">
|
||||
<div class="flex flex-1">
|
||||
<span
|
||||
class="text-xs font-bold text-yellow-600 dark-theme:text-yellow-400 mr-2"
|
||||
class="mr-2 text-xs font-bold text-yellow-600 dark-theme:text-yellow-400"
|
||||
>{{ importFailedConflicts.length }}</span
|
||||
>
|
||||
<span
|
||||
@@ -40,19 +41,20 @@
|
||||
: 'pi pi-chevron-right text-xs'
|
||||
"
|
||||
text
|
||||
class="text-neutral-600 dark-theme:text-neutral-300 !bg-transparent"
|
||||
class="!bg-transparent text-neutral-600 dark-theme:text-neutral-300"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Import failed list -->
|
||||
<div
|
||||
v-if="importFailedExpanded"
|
||||
class="py-2 px-4 flex flex-col gap-2.5 max-h-[142px] overflow-y-auto scrollbar-hide"
|
||||
data-testid="conflict-dialog-panel-expanded"
|
||||
class="flex max-h-[142px] scrollbar-hide flex-col gap-2.5 overflow-y-auto px-4 py-2"
|
||||
>
|
||||
<div
|
||||
v-for="(packageName, i) in importFailedConflicts"
|
||||
:key="i"
|
||||
class="flex items-center justify-between h-6 px-4 flex-shrink-0 conflict-list-item"
|
||||
class="conflict-list-item flex h-6 flex-shrink-0 items-center justify-between px-4"
|
||||
>
|
||||
<span class="text-xs text-neutral-600 dark-theme:text-neutral-300">
|
||||
{{ packageName }}
|
||||
@@ -63,15 +65,16 @@
|
||||
</div>
|
||||
<!-- Conflict List Wrapper -->
|
||||
<div
|
||||
class="w-full flex flex-col bg-neutral-200 dark-theme:bg-black min-h-8 rounded-lg"
|
||||
class="flex min-h-8 w-full flex-col rounded-lg bg-neutral-200 dark-theme:bg-black"
|
||||
>
|
||||
<div
|
||||
class="w-full h-8 flex items-center justify-between gap-2 pl-4"
|
||||
data-testid="conflict-dialog-panel-toggle"
|
||||
class="flex h-8 w-full items-center justify-between gap-2 pl-4"
|
||||
@click="toggleConflictsPanel"
|
||||
>
|
||||
<div class="flex-1 flex">
|
||||
<div class="flex flex-1">
|
||||
<span
|
||||
class="text-xs font-bold text-yellow-600 dark-theme:text-yellow-400 mr-2"
|
||||
class="mr-2 text-xs font-bold text-yellow-600 dark-theme:text-yellow-400"
|
||||
>{{ allConflictDetails.length }}</span
|
||||
>
|
||||
<span
|
||||
@@ -87,19 +90,20 @@
|
||||
: 'pi pi-chevron-right text-xs'
|
||||
"
|
||||
text
|
||||
class="text-neutral-600 dark-theme:text-neutral-300 !bg-transparent"
|
||||
class="!bg-transparent text-neutral-600 dark-theme:text-neutral-300"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Conflicts list -->
|
||||
<div
|
||||
v-if="conflictsExpanded"
|
||||
class="py-2 px-4 flex flex-col gap-2.5 max-h-[142px] overflow-y-auto scrollbar-hide"
|
||||
data-testid="conflict-dialog-panel-expanded"
|
||||
class="flex max-h-[142px] scrollbar-hide flex-col gap-2.5 overflow-y-auto px-4 py-2"
|
||||
>
|
||||
<div
|
||||
v-for="(conflict, i) in allConflictDetails"
|
||||
:key="i"
|
||||
class="flex items-center justify-between h-6 px-4 flex-shrink-0 conflict-list-item"
|
||||
class="conflict-list-item flex h-6 flex-shrink-0 items-center justify-between px-4"
|
||||
>
|
||||
<span
|
||||
class="text-xs text-neutral-600 dark-theme:text-neutral-300"
|
||||
@@ -111,15 +115,16 @@
|
||||
</div>
|
||||
<!-- Extension List Wrapper -->
|
||||
<div
|
||||
class="w-full flex flex-col bg-neutral-200 dark-theme:bg-black min-h-8 rounded-lg"
|
||||
class="flex min-h-8 w-full flex-col rounded-lg bg-neutral-200 dark-theme:bg-black"
|
||||
>
|
||||
<div
|
||||
class="w-full h-8 flex items-center justify-between gap-2 pl-4"
|
||||
data-testid="conflict-dialog-panel-toggle"
|
||||
class="flex h-8 w-full items-center justify-between gap-2 pl-4"
|
||||
@click="toggleExtensionsPanel"
|
||||
>
|
||||
<div class="flex-1 flex">
|
||||
<div class="flex flex-1">
|
||||
<span
|
||||
class="text-xs font-bold text-yellow-600 dark-theme:text-yellow-400 mr-2"
|
||||
class="mr-2 text-xs font-bold text-yellow-600 dark-theme:text-yellow-400"
|
||||
>{{ conflictData.length }}</span
|
||||
>
|
||||
<span
|
||||
@@ -135,19 +140,20 @@
|
||||
: 'pi pi-chevron-right text-xs'
|
||||
"
|
||||
text
|
||||
class="text-neutral-600 dark-theme:text-neutral-300 !bg-transparent"
|
||||
class="!bg-transparent text-neutral-600 dark-theme:text-neutral-300"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Extension list -->
|
||||
<div
|
||||
v-if="extensionsExpanded"
|
||||
class="py-2 px-4 flex flex-col gap-2.5 max-h-[142px] overflow-y-auto scrollbar-hide"
|
||||
data-testid="conflict-dialog-panel-expanded"
|
||||
class="flex max-h-[142px] scrollbar-hide flex-col gap-2.5 overflow-y-auto px-4 py-2"
|
||||
>
|
||||
<div
|
||||
v-for="conflictResult in conflictData"
|
||||
:key="conflictResult.package_id"
|
||||
class="flex items-center justify-between h-6 px-4 flex-shrink-0 conflict-list-item"
|
||||
class="conflict-list-item flex h-6 flex-shrink-0 items-center justify-between px-4"
|
||||
>
|
||||
<span class="text-xs text-neutral-600 dark-theme:text-neutral-300">
|
||||
{{ conflictResult.package_name }}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="flex items-center justify-between w-full px-3 py-4">
|
||||
<div class="w-full flex items-center justify-between gap-2 pr-1">
|
||||
<div class="flex w-full items-center justify-between px-3 py-4">
|
||||
<div class="flex w-full items-center justify-between gap-2 pr-1">
|
||||
<Button
|
||||
:label="$t('manager.conflicts.conflictInfoTitle')"
|
||||
text
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="h-12 flex items-center justify-between w-full pl-6">
|
||||
<div class="flex h-12 w-full items-center justify-between pl-6">
|
||||
<div class="flex items-center gap-2">
|
||||
<!-- Warning Icon -->
|
||||
<i class="pi pi-exclamation-triangle text-lg"></i>
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<template>
|
||||
<Message
|
||||
:severity="statusSeverity"
|
||||
class="p-0 flex items-center rounded-xl break-words w-fit"
|
||||
class="flex w-fit items-center rounded-xl p-0 break-words"
|
||||
:pt="{
|
||||
text: { class: 'text-xs' },
|
||||
content: { class: 'px-2 py-0.5' }
|
||||
}"
|
||||
>
|
||||
<i
|
||||
class="pi pi-circle-fill mr-1.5 text-[0.6rem] p-0"
|
||||
class="pi pi-circle-fill mr-1.5 p-0 text-[0.6rem]"
|
||||
:style="{ opacity: 0.8 }"
|
||||
/>
|
||||
{{ $t(`manager.status.${statusLabel}`) }}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
v-tooltip.top="
|
||||
isDisabled ? $t('manager.enablePackToChangeVersion') : null
|
||||
"
|
||||
class="inline-flex items-center gap-1 rounded-2xl text-xs py-1"
|
||||
class="inline-flex items-center gap-1 rounded-2xl py-1 text-xs"
|
||||
:class="{
|
||||
'bg-dialog-surface px-1.5': fill,
|
||||
'cursor-pointer': !isDisabled,
|
||||
@@ -19,7 +19,7 @@
|
||||
>
|
||||
<i
|
||||
v-if="isUpdateAvailable"
|
||||
class="pi pi-arrow-circle-up text-blue-600 text-xs"
|
||||
class="pi pi-arrow-circle-up text-xs text-blue-600"
|
||||
/>
|
||||
<span>{{ installedVersion }}</span>
|
||||
<i v-if="!isDisabled" class="pi pi-chevron-right text-xxs" />
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<template>
|
||||
<div class="w-64 pt-1">
|
||||
<div class="py-2">
|
||||
<span class="pl-3 text-md font-semibold text-neutral-500">
|
||||
<span class="text-md pl-3 font-semibold text-neutral-500">
|
||||
{{ $t('manager.selectVersion') }}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="isLoadingVersions || isQueueing"
|
||||
class="text-center text-muted py-4 flex flex-col items-center"
|
||||
class="flex flex-col items-center py-4 text-center text-muted"
|
||||
>
|
||||
<ProgressSpinner class="w-8 h-8 mb-2" />
|
||||
<ProgressSpinner class="mb-2 h-8 w-8" />
|
||||
{{ $t('manager.loadingVersions') }}
|
||||
</div>
|
||||
<div v-else-if="versionOptions.length === 0" class="py-2">
|
||||
@@ -27,13 +27,13 @@
|
||||
option-value="value"
|
||||
:options="processedVersionOptions"
|
||||
:highlight-on-select="false"
|
||||
class="w-full max-h-[50vh] border-none shadow-none rounded-md"
|
||||
class="max-h-[50vh] w-full rounded-md border-none shadow-none"
|
||||
:pt="{
|
||||
listContainer: { class: 'scrollbar-hide' }
|
||||
}"
|
||||
>
|
||||
<template #option="slotProps">
|
||||
<div class="flex justify-between items-center w-full p-1">
|
||||
<div class="flex w-full items-center justify-between p-1">
|
||||
<div class="flex items-center gap-2">
|
||||
<template v-if="slotProps.option.value === 'nightly'">
|
||||
<div class="w-4"></div>
|
||||
@@ -59,7 +59,7 @@
|
||||
</template>
|
||||
</Listbox>
|
||||
<ContentDivider class="my-2" />
|
||||
<div class="flex justify-end gap-2 py-1 px-3">
|
||||
<div class="flex justify-end gap-2 px-3 py-1">
|
||||
<Button
|
||||
text
|
||||
class="text-sm"
|
||||
@@ -71,7 +71,7 @@
|
||||
<Button
|
||||
severity="secondary"
|
||||
:label="$t('g.install')"
|
||||
class="py-2.5 px-4 text-sm dark-theme:bg-unset bg-black/80 dark-theme:text-unset text-neutral-100 rounded-lg"
|
||||
class="dark-theme:bg-unset dark-theme:text-unset rounded-lg bg-black/80 px-4 py-2.5 text-sm text-neutral-100"
|
||||
:disabled="isQueueing"
|
||||
@click="handleSubmit"
|
||||
/>
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
value: $t('manager.conflicts.warningTooltip'),
|
||||
showDelay: 300
|
||||
}"
|
||||
class="flex items-center justify-center w-6 h-6 cursor-pointer"
|
||||
class="flex h-6 w-6 cursor-pointer items-center justify-center"
|
||||
@click="showConflictModal(true)"
|
||||
>
|
||||
<i class="pi pi-exclamation-triangle text-yellow-500 text-xl"></i>
|
||||
<i class="pi pi-exclamation-triangle text-xl text-yellow-500"></i>
|
||||
</div>
|
||||
<ToggleSwitch
|
||||
v-if="!canToggleDirectly"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<template v-if="nodePack">
|
||||
<div class="flex flex-col h-full z-40 overflow-hidden relative">
|
||||
<div class="top-0 z-10 px-6 pt-6 w-full">
|
||||
<div class="relative z-40 flex h-full flex-col overflow-hidden">
|
||||
<div class="top-0 z-10 w-full px-6 pt-6">
|
||||
<InfoPanelHeader
|
||||
:node-packs="[nodePack]"
|
||||
:has-conflict="hasCompatibilityIssues"
|
||||
@@ -9,7 +9,7 @@
|
||||
</div>
|
||||
<div
|
||||
ref="scrollContainer"
|
||||
class="p-6 pt-2 overflow-y-auto flex-1 text-sm scrollbar-hide"
|
||||
class="scrollbar-hide flex-1 overflow-y-auto p-6 pt-2 text-sm"
|
||||
>
|
||||
<div class="mb-6">
|
||||
<MetadataRow
|
||||
@@ -53,7 +53,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="pt-4 px-8 flex-1 overflow-hidden text-sm">
|
||||
<div class="flex-1 overflow-hidden px-8 pt-4 text-sm">
|
||||
{{ $t('manager.infoPanelEmpty') }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<PackIcon :node-pack="nodePacks[0]" width="204" height="106" />
|
||||
</slot>
|
||||
<h2
|
||||
class="text-2xl font-bold text-center mt-4 mb-2"
|
||||
class="mt-4 mb-2 text-center text-2xl font-bold"
|
||||
style="word-break: break-all"
|
||||
>
|
||||
<slot name="title">
|
||||
@@ -13,7 +13,7 @@
|
||||
</h2>
|
||||
<div
|
||||
v-if="!importFailed"
|
||||
class="mt-2 mb-4 w-full max-w-xs flex justify-center"
|
||||
class="mt-2 mb-4 flex w-full max-w-xs justify-center"
|
||||
>
|
||||
<slot name="install-button">
|
||||
<PackUninstallButton
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<template>
|
||||
<div v-if="nodePacks?.length" class="flex flex-col h-full">
|
||||
<div class="p-6 flex-1 overflow-auto">
|
||||
<div v-if="nodePacks?.length" class="flex h-full flex-col">
|
||||
<div class="flex-1 overflow-auto p-6">
|
||||
<InfoPanelHeader :node-packs>
|
||||
<template #thumbnail>
|
||||
<PackIconStacked :node-packs="nodePacks" />
|
||||
</template>
|
||||
<template #title>
|
||||
<div class="mt-5">
|
||||
<span class="inline-block mr-2 text-blue-500 text-base">{{
|
||||
<span class="mr-2 inline-block text-base text-blue-500">{{
|
||||
nodePacks.length
|
||||
}}</span>
|
||||
<span class="text-base">{{ $t('manager.packsSelected') }}</span>
|
||||
@@ -48,7 +48,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="mt-4 mx-8 flex-1 overflow-hidden text-sm">
|
||||
<div v-else class="mx-8 mt-4 flex-1 overflow-hidden text-sm">
|
||||
{{ $t('manager.infoPanelEmpty') }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
<template>
|
||||
<div class="overflow-hidden">
|
||||
<Tabs :value="activeTab">
|
||||
<TabList class="overflow-x-auto scrollbar-hide">
|
||||
<Tab v-if="hasCompatibilityIssues" value="warning" class="p-2 mr-6">
|
||||
<TabList class="scrollbar-hide overflow-x-auto">
|
||||
<Tab v-if="hasCompatibilityIssues" value="warning" class="mr-6 p-2">
|
||||
<div class="flex items-center gap-1">
|
||||
<span>⚠️</span>
|
||||
{{ importFailed ? $t('g.error') : $t('g.warning') }}
|
||||
</div>
|
||||
</Tab>
|
||||
<Tab value="description" class="p-2 mr-6">
|
||||
<Tab value="description" class="mr-6 p-2">
|
||||
{{ $t('g.description') }}
|
||||
</Tab>
|
||||
<Tab value="nodes" class="p-2">
|
||||
{{ $t('g.nodes') }}
|
||||
</Tab>
|
||||
</TabList>
|
||||
<TabPanels class="overflow-auto py-4 px-2">
|
||||
<TabPanels class="overflow-auto px-2 py-4">
|
||||
<TabPanel
|
||||
v-if="hasCompatibilityIssues"
|
||||
value="warning"
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<div class="mb-3">
|
||||
{{ section.title }}
|
||||
</div>
|
||||
<div class="text-muted break-words">
|
||||
<div class="break-words text-muted">
|
||||
<a
|
||||
v-if="section.isUrl"
|
||||
:href="section.text"
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<em v-else-if="segment.type === 'italic'">{{ segment.text }}</em>
|
||||
<code
|
||||
v-else-if="segment.type === 'code'"
|
||||
class="px-1 py-0.5 rounded text-xs"
|
||||
class="rounded px-1 py-0.5 text-xs"
|
||||
>{{ segment.text }}</code
|
||||
>
|
||||
<span v-else>{{ segment.text }}</span>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
v-if="nodePack?.description"
|
||||
:sections="descriptionSections"
|
||||
/>
|
||||
<p v-else class="text-muted italic text-sm">
|
||||
<p v-else class="text-sm text-muted italic">
|
||||
{{ $t('manager.noDescription') }}
|
||||
</p>
|
||||
<div v-if="nodePack?.latest_version?.dependencies?.length">
|
||||
@@ -14,7 +14,7 @@
|
||||
<div
|
||||
v-for="(dep, index) in nodePack.latest_version.dependencies"
|
||||
:key="index"
|
||||
class="text-muted break-words"
|
||||
class="break-words text-muted"
|
||||
>
|
||||
{{ dep }}
|
||||
</div>
|
||||
|
||||
@@ -4,16 +4,16 @@
|
||||
<div
|
||||
v-for="nodeDef in mappedNodeDefs"
|
||||
:key="createNodeDefKey(nodeDef)"
|
||||
class="border rounded-lg p-4"
|
||||
class="rounded-lg border p-4"
|
||||
>
|
||||
<NodePreview :node-def="nodeDef" class="text-[.625rem]! min-w-full!" />
|
||||
<NodePreview :node-def="nodeDef" class="min-w-full! text-[.625rem]!" />
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="isLoading">
|
||||
<ProgressSpinner />
|
||||
</template>
|
||||
<template v-else-if="nodeNames.length">
|
||||
<div v-for="node in nodeNames" :key="node" class="text-muted truncate">
|
||||
<div v-for="node in nodeNames" :key="node" class="truncate text-muted">
|
||||
{{ node }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -2,21 +2,21 @@
|
||||
<div class="flex flex-col gap-3">
|
||||
<button
|
||||
v-if="importFailedInfo"
|
||||
class="cursor-pointer outline-none border-none inline-flex items-center justify-end bg-transparent gap-1"
|
||||
class="inline-flex cursor-pointer items-center justify-end gap-1 border-none bg-transparent outline-none"
|
||||
@click="showImportFailedDialog"
|
||||
>
|
||||
<i class="pi pi-code text-base"></i>
|
||||
<span class="dark-theme:text-white text-sm">{{
|
||||
<span class="text-sm dark-theme:text-white">{{
|
||||
t('serverStart.openLogs')
|
||||
}}</span>
|
||||
</button>
|
||||
<div
|
||||
v-for="(conflict, index) in conflictResult?.conflicts || []"
|
||||
:key="index"
|
||||
class="p-3 bg-yellow-800/20 rounded-md"
|
||||
class="rounded-md bg-yellow-800/20 p-3"
|
||||
>
|
||||
<div class="flex justify-between items-center">
|
||||
<div class="text-sm break-words flex-1">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex-1 text-sm break-words">
|
||||
{{ getConflictMessage(conflict, $t) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<template>
|
||||
<div class="w-full aspect-7/3 overflow-hidden">
|
||||
<div class="aspect-7/3 w-full overflow-hidden">
|
||||
<!-- default banner show -->
|
||||
<div v-if="showDefaultBanner" class="w-full h-full">
|
||||
<div v-if="showDefaultBanner" class="h-full w-full">
|
||||
<img
|
||||
:src="DEFAULT_BANNER"
|
||||
alt="default banner"
|
||||
class="w-full h-full object-cover"
|
||||
class="h-full w-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
<!-- banner_url or icon show -->
|
||||
<div v-else class="relative w-full h-full">
|
||||
<div v-else class="relative h-full w-full">
|
||||
<!-- blur background -->
|
||||
<div
|
||||
v-if="imgSrc"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<Card
|
||||
class="w-full h-full inline-flex flex-col justify-between items-start overflow-hidden rounded-lg shadow-elevation-3 dark-theme:bg-dark-elevation-2 transition-all duration-200"
|
||||
class="shadow-elevation-3 inline-flex h-full w-full flex-col items-start justify-between overflow-hidden rounded-lg transition-all duration-200 dark-theme:bg-dark-elevation-2"
|
||||
:class="{
|
||||
'selected-card': isSelected,
|
||||
'opacity-60': isDisabled
|
||||
@@ -21,21 +21,21 @@
|
||||
<PackBanner :node-pack="nodePack" />
|
||||
</template>
|
||||
<template #content>
|
||||
<div class="pt-4 px-4 pb-3 w-full h-full">
|
||||
<div class="flex flex-col gap-y-1 w-full h-full">
|
||||
<div class="h-full w-full px-4 pt-4 pb-3">
|
||||
<div class="flex h-full w-full flex-col gap-y-1">
|
||||
<span
|
||||
class="text-sm font-bold truncate overflow-hidden text-ellipsis"
|
||||
class="truncate overflow-hidden text-sm font-bold text-ellipsis"
|
||||
>
|
||||
{{ nodePack.name }}
|
||||
</span>
|
||||
<p
|
||||
v-if="nodePack.description"
|
||||
class="flex-1 text-muted text-xs font-medium break-words overflow-hidden min-h-12 line-clamp-3 my-0 leading-4 mb-1 overflow-hidden"
|
||||
class="my-0 mb-1 line-clamp-3 min-h-12 flex-1 overflow-hidden text-xs leading-4 font-medium break-words text-muted"
|
||||
>
|
||||
{{ nodePack.description }}
|
||||
</p>
|
||||
<div class="flex flex-col gap-y-2">
|
||||
<div class="flex-1 flex items-center gap-2">
|
||||
<div class="flex flex-1 items-center gap-2">
|
||||
<div v-if="nodesCount" class="p-2 pl-0 text-xs">
|
||||
{{ nodesCount }} {{ $t('g.nodes') }}
|
||||
</div>
|
||||
@@ -47,7 +47,7 @@
|
||||
/>
|
||||
<div
|
||||
v-if="formattedLatestVersionDate"
|
||||
class="px-2 py-1 flex justify-center items-center gap-1 text-xs text-muted font-medium"
|
||||
class="flex items-center justify-center gap-1 px-2 py-1 text-xs font-medium text-muted"
|
||||
>
|
||||
{{ formattedLatestVersionDate }}
|
||||
</div>
|
||||
@@ -55,7 +55,7 @@
|
||||
<div class="flex">
|
||||
<span
|
||||
v-if="publisherName"
|
||||
class="text-xs text-muted font-medium leading-3 max-w-40 truncate"
|
||||
class="max-w-40 truncate text-xs leading-3 font-medium text-muted"
|
||||
>
|
||||
{{ publisherName }}
|
||||
</span>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div
|
||||
class="min-h-12 flex justify-between items-center px-4 py-2 text-xs text-muted font-medium leading-3"
|
||||
class="flex min-h-12 items-center justify-between px-4 py-2 text-xs leading-3 font-medium text-muted"
|
||||
>
|
||||
<div v-if="nodePack.downloads" class="flex items-center gap-1.5">
|
||||
<i class="pi pi-download text-muted"></i>
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<template>
|
||||
<div class="w-full max-w-[204] aspect-[2/1] rounded-lg overflow-hidden">
|
||||
<div class="aspect-[2/1] w-full max-w-[204] overflow-hidden rounded-lg">
|
||||
<!-- default banner show -->
|
||||
<div v-if="showDefaultBanner" class="w-full h-full">
|
||||
<div v-if="showDefaultBanner" class="h-full w-full">
|
||||
<img
|
||||
:src="DEFAULT_BANNER"
|
||||
alt="default banner"
|
||||
class="w-full h-full object-cover"
|
||||
class="h-full w-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
<!-- banner_url or icon show -->
|
||||
<div v-else class="relative w-full h-full">
|
||||
<div v-else class="relative h-full w-full">
|
||||
<!-- blur background -->
|
||||
<div
|
||||
v-if="imgSrc"
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
<template>
|
||||
<div class="relative w-[224px] h-[104px] shadow-xl">
|
||||
<div class="relative h-[104px] w-[224px] shadow-xl">
|
||||
<div
|
||||
v-for="(pack, index) in nodePacks.slice(0, maxVisible)"
|
||||
:key="pack.id"
|
||||
class="absolute w-[210px] h-[90px]"
|
||||
class="absolute h-[90px] w-[210px]"
|
||||
:style="{
|
||||
bottom: `${index * offset}px`,
|
||||
right: `${index * offset}px`,
|
||||
zIndex: maxVisible - index
|
||||
}"
|
||||
>
|
||||
<div class="border rounded-lg shadow-lg p-0.5">
|
||||
<div class="rounded-lg border p-0.5 shadow-lg">
|
||||
<PackIcon :node-pack="pack" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="relative w-full p-6">
|
||||
<div class="h-12 flex items-center gap-1 justify-between">
|
||||
<div class="flex items-center w-5/12">
|
||||
<div class="flex h-12 items-center justify-between gap-1">
|
||||
<div class="flex w-5/12 items-center">
|
||||
<AutoComplete
|
||||
v-model.lazy="searchQuery"
|
||||
:suggestions="suggestions || []"
|
||||
@@ -38,8 +38,8 @@
|
||||
:has-disabled-update-packs="hasDisabledUpdatePacks"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex mt-3 text-sm">
|
||||
<div class="flex gap-6 ml-1">
|
||||
<div class="mt-3 flex text-sm">
|
||||
<div class="ml-1 flex gap-6">
|
||||
<SearchFilterDropdown
|
||||
v-model:model-value="searchMode"
|
||||
:options="filterOptions"
|
||||
@@ -51,7 +51,7 @@
|
||||
:label="$t('g.sort')"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex items-center gap-4 ml-6">
|
||||
<div class="ml-6 flex items-center gap-4">
|
||||
<small v-if="hasResults" class="text-color-secondary">
|
||||
{{ $t('g.resultsCount', { count: searchResults?.length || 0 }) }}
|
||||
</small>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<div
|
||||
class="rounded-lg shadow-sm h-full overflow-hidden flex flex-col"
|
||||
class="flex h-full flex-col overflow-hidden rounded-lg shadow-sm"
|
||||
data-virtual-grid-item
|
||||
>
|
||||
<!-- Card header - flush with top, approximately 15% of height -->
|
||||
<div class="w-full px-4 py-3 flex justify-between items-center">
|
||||
<div class="flex w-full items-center justify-between px-4 py-3">
|
||||
<div class="flex items-center">
|
||||
<div class="w-6 h-6 flex items-center justify-center">
|
||||
<div class="flex h-6 w-6 items-center justify-center">
|
||||
<Skeleton shape="circle" width="1.5rem" height="1.5rem" />
|
||||
</div>
|
||||
<Skeleton width="5rem" height="1rem" class="ml-2" />
|
||||
@@ -15,14 +15,14 @@
|
||||
</div>
|
||||
|
||||
<!-- Card content with icon on left and text on right -->
|
||||
<div class="flex-1 p-4 flex">
|
||||
<div class="flex flex-1 p-4">
|
||||
<!-- Left icon - 64x64 -->
|
||||
<div class="shrink-0 mr-4">
|
||||
<div class="mr-4 shrink-0">
|
||||
<Skeleton width="4rem" height="4rem" border-radius="0.5rem" />
|
||||
</div>
|
||||
|
||||
<!-- Right content -->
|
||||
<div class="flex-1 flex flex-col overflow-hidden">
|
||||
<div class="flex flex-1 flex-col overflow-hidden">
|
||||
<!-- Title -->
|
||||
<Skeleton width="80%" height="1rem" class="mb-2" />
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Card footer - similar to header -->
|
||||
<div class="w-full px-5 py-4 flex justify-between items-center">
|
||||
<div class="flex w-full items-center justify-between px-5 py-4">
|
||||
<Skeleton width="4rem" height="0.8rem" />
|
||||
<Skeleton width="6rem" height="0.8rem" />
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user