mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-13 09:00:16 +00:00
fix: enable enforce-consistent-class-order tailwind lint rule (#9428)
## Summary Enable `better-tailwindcss/enforce-consistent-class-order` lint rule and auto-fix all 1027 violations across 263 files. Stacked on #9427. ## Changes - **What**: Sort Tailwind classes into consistent order via `eslint --fix` - Enable `enforce-consistent-class-order` as `'error'` in eslint config - Purely cosmetic reordering — no behavioral or visual changes ## Review Focus Mechanical auto-fix PR — all changes are class reordering only. This is the largest diff but lowest risk since it changes no class names, only their order. **Stack:** #9417 → #9427 → **this PR** Fixes #9300 (partial — 3 of 3 rules) ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-9428-fix-enable-enforce-consistent-class-order-tailwind-lint-rule-31a6d73d3650811c9065f5178ba3e724) by [Unito](https://www.unito.io)
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
role="status"
|
||||
tabindex="0"
|
||||
:aria-label="t('sideToolbar.activeJobStatus', { status: statusText })"
|
||||
class="flex flex-col gap-2 p-2 rounded-lg"
|
||||
class="flex flex-col gap-2 rounded-lg p-2"
|
||||
@mouseenter="hovered = true"
|
||||
@mouseleave="hovered = false"
|
||||
@focusin="hovered = true"
|
||||
@@ -47,13 +47,13 @@
|
||||
</div>
|
||||
|
||||
<!-- Footer: Progress bar or status text -->
|
||||
<div class="flex gap-1.5 items-center h-5">
|
||||
<div class="flex h-5 items-center gap-1.5">
|
||||
<!-- Running state: percentage + progress bar -->
|
||||
<template v-if="isRunning && hasProgressPercent(progressPercent)">
|
||||
<span class="shrink-0 text-sm text-muted-foreground">
|
||||
{{ Math.round(progressPercent ?? 0) }}%
|
||||
</span>
|
||||
<div class="flex-1 relative h-1 rounded-sm bg-secondary-background">
|
||||
<div class="relative h-1 flex-1 rounded-sm bg-secondary-background">
|
||||
<div
|
||||
:class="progressBarPrimaryClass"
|
||||
:style="progressPercentStyle(progressPercent)"
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<template>
|
||||
<div
|
||||
class="absolute left-2 bottom-2 flex flex-wrap justify-start gap-1 select-none"
|
||||
class="absolute bottom-2 left-2 flex flex-wrap justify-start gap-1 select-none"
|
||||
>
|
||||
<span
|
||||
v-for="badge in badges"
|
||||
:key="badge.label"
|
||||
:class="
|
||||
cn(
|
||||
'px-2 py-1 rounded-sm text-xs font-bold uppercase tracking-wider text-modal-card-tag-foreground bg-modal-card-tag-background break-all'
|
||||
'rounded-sm bg-modal-card-tag-background px-2 py-1 text-xs font-bold tracking-wider break-all text-modal-card-tag-foreground uppercase'
|
||||
)
|
||||
"
|
||||
>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
>
|
||||
<template v-if="shouldShowLeftPanel" #leftPanelHeaderTitle>
|
||||
<i class="icon-[comfy--ai-model] size-4" />
|
||||
<h2 class="flex-auto select-none text-base font-semibold text-nowrap">
|
||||
<h2 class="flex-auto text-base font-semibold text-nowrap select-none">
|
||||
{{ displayTitle }}
|
||||
</h2>
|
||||
</template>
|
||||
@@ -75,7 +75,7 @@
|
||||
<ModelInfoPanel v-if="focusedAsset" :asset="focusedAsset" :cache-key />
|
||||
<div
|
||||
v-else
|
||||
class="flex h-full items-center justify-center wrap-break-word p-6 text-center text-muted"
|
||||
class="flex h-full items-center justify-center p-6 text-center wrap-break-word text-muted"
|
||||
>
|
||||
{{ $t('assetBrowser.modelInfo.selectModelPrompt') }}
|
||||
</div>
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
:tabindex="interactive ? 0 : -1"
|
||||
:class="
|
||||
cn(
|
||||
'select-none rounded-2xl overflow-hidden transition-all duration-200 bg-modal-card-background p-2 gap-2 flex flex-col h-full',
|
||||
'flex h-full flex-col gap-2 overflow-hidden rounded-2xl bg-modal-card-background p-2 transition-all duration-200 select-none',
|
||||
interactive &&
|
||||
'group appearance-none bg-transparent m-0 outline-none text-left hover:bg-secondary-background focus:bg-secondary-background border-none focus:outline-solid outline-base-foreground outline-4',
|
||||
'group m-0 appearance-none border-none bg-transparent text-left outline-4 outline-base-foreground outline-none hover:bg-secondary-background focus:bg-secondary-background focus:outline-solid',
|
||||
focused && 'bg-secondary-background outline-solid'
|
||||
)
|
||||
"
|
||||
@@ -26,14 +26,14 @@
|
||||
v-else
|
||||
:src="asset.preview_url"
|
||||
:alt="displayName"
|
||||
class="size-full object-cover cursor-pointer"
|
||||
class="size-full cursor-pointer object-cover"
|
||||
/>
|
||||
|
||||
<AssetBadgeGroup :badges="asset.badges" />
|
||||
<IconGroup
|
||||
:class="
|
||||
cn(
|
||||
'absolute top-2 right-2 invisible group-hover:visible',
|
||||
'invisible absolute top-2 right-2 group-hover:visible',
|
||||
dropdownMenuButton?.isOpen && 'visible'
|
||||
)
|
||||
"
|
||||
@@ -66,13 +66,13 @@
|
||||
</MoreButton>
|
||||
</IconGroup>
|
||||
</div>
|
||||
<div class="max-h-32 flex flex-col gap-2 justify-between flex-auto">
|
||||
<div class="flex max-h-32 flex-auto flex-col justify-between gap-2">
|
||||
<h3
|
||||
:id="titleId"
|
||||
v-tooltip.top="{ value: displayName, showDelay: tooltipDelay }"
|
||||
:class="
|
||||
cn(
|
||||
'm-0 text-sm font-semibold line-clamp-2 wrap-anywhere',
|
||||
'm-0 line-clamp-2 text-sm font-semibold wrap-anywhere',
|
||||
'text-base-foreground'
|
||||
)
|
||||
"
|
||||
@@ -84,13 +84,13 @@
|
||||
v-tooltip.top="{ value: asset.secondaryText, showDelay: tooltipDelay }"
|
||||
:class="
|
||||
cn(
|
||||
'm-0 text-sm line-clamp-2 [-webkit-box-orient:vertical] [-webkit-line-clamp:2] [display:-webkit-box] text-muted-foreground'
|
||||
'm-0 line-clamp-2 [display:-webkit-box] text-sm text-muted-foreground [-webkit-box-orient:vertical] [-webkit-line-clamp:2]'
|
||||
)
|
||||
"
|
||||
>
|
||||
{{ asset.secondaryText }}
|
||||
</p>
|
||||
<div class="flex items-center justify-between gap-2 mt-auto">
|
||||
<div class="mt-auto flex items-center justify-between gap-2">
|
||||
<div class="flex gap-3 text-xs text-muted-foreground">
|
||||
<span v-if="asset.stats.stars" class="flex items-center gap-1">
|
||||
<i class="icon-[lucide--star] size-3" />
|
||||
@@ -115,7 +115,7 @@
|
||||
v-if="interactive"
|
||||
variant="secondary"
|
||||
size="lg"
|
||||
class="shrink-0 relative"
|
||||
class="relative shrink-0"
|
||||
@click.stop="handleSelect"
|
||||
>
|
||||
{{ $t('g.use') }}
|
||||
@@ -210,7 +210,7 @@ function confirmDeletion() {
|
||||
confirmText: t('g.delete'),
|
||||
// TODO: These need to be put into the new Button Variants once we have them.
|
||||
confirmClass: cn(
|
||||
'bg-danger-200 text-base-foreground hover:bg-danger-200/80 focus:bg-danger-200/80 focus:ring ring-base-foreground'
|
||||
'bg-danger-200 text-base-foreground ring-base-foreground hover:bg-danger-200/80 focus:bg-danger-200/80 focus:ring'
|
||||
),
|
||||
optionsDisabled,
|
||||
onCancel: () => {
|
||||
|
||||
@@ -119,7 +119,7 @@ function closeDialog() {
|
||||
v-else-if="job.status === 'completed' && job.downloadError"
|
||||
>
|
||||
<span
|
||||
class="text-xs text-destructive-background truncate max-w-32"
|
||||
class="max-w-32 truncate text-xs text-destructive-background"
|
||||
>
|
||||
{{ job.downloadError }}
|
||||
</span>
|
||||
@@ -178,7 +178,7 @@ function closeDialog() {
|
||||
|
||||
<template #footer="{ toggle }">
|
||||
<div
|
||||
class="flex flex-1 min-w-0 h-12 items-center justify-between gap-2 border-t border-border-default px-4"
|
||||
class="flex h-12 min-w-0 flex-1 items-center justify-between gap-2 border-t border-border-default px-4"
|
||||
>
|
||||
<div class="flex min-w-0 flex-1 items-center gap-2 text-sm">
|
||||
<i
|
||||
@@ -188,7 +188,7 @@ function closeDialog() {
|
||||
<span
|
||||
:class="
|
||||
cn(
|
||||
'truncate font-bold text-base-foreground transition-all duration-300 overflow-hidden',
|
||||
'truncate overflow-hidden font-bold text-base-foreground transition-all duration-300',
|
||||
isExpanded ? 'min-w-0 flex-1' : 'w-0'
|
||||
)
|
||||
"
|
||||
@@ -202,7 +202,7 @@ function closeDialog() {
|
||||
v-if="isInProgress"
|
||||
:class="
|
||||
cn(
|
||||
'text-sm text-muted-foreground transition-all duration-300 overflow-hidden',
|
||||
'overflow-hidden text-sm text-muted-foreground transition-all duration-300',
|
||||
isExpanded ? 'whitespace-nowrap' : 'w-0'
|
||||
)
|
||||
"
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<div
|
||||
class="flex gap-4 items-center justify-between px-6 pt-2 pb-6"
|
||||
class="flex items-center justify-between gap-4 px-6 pt-2 pb-6"
|
||||
data-component-id="asset-filter-bar"
|
||||
>
|
||||
<div
|
||||
class="flex gap-4 items-center"
|
||||
class="flex items-center gap-4"
|
||||
data-component-id="asset-filter-bar-left"
|
||||
>
|
||||
<MultiSelect
|
||||
|
||||
@@ -15,13 +15,13 @@
|
||||
</div>
|
||||
<div
|
||||
v-else-if="assets.length === 0"
|
||||
class="flex h-full select-none flex-col items-center justify-center py-16 text-muted-foreground"
|
||||
class="flex h-full flex-col items-center justify-center py-16 text-muted-foreground select-none"
|
||||
>
|
||||
<i class="mb-4 icon-[lucide--search] size-10" />
|
||||
<h3 class="mb-2 text-lg font-medium">
|
||||
{{ emptyTitle ?? $t('assetBrowser.noAssetsFound') }}
|
||||
</h3>
|
||||
<p class="text-sm whitespace-pre-wrap text-center">
|
||||
<p class="text-center text-sm whitespace-pre-wrap">
|
||||
{{ emptyMessage ?? $t('assetBrowser.tryAdjustingFilters') }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -13,10 +13,10 @@
|
||||
:tabindex="loading ? -1 : 0"
|
||||
:class="
|
||||
cn(
|
||||
'flex flex-col overflow-hidden cursor-pointer p-2 transition-colors duration-200 rounded-lg',
|
||||
'gap-2 select-none group',
|
||||
'flex cursor-pointer flex-col overflow-hidden rounded-lg p-2 transition-colors duration-200',
|
||||
'group gap-2 select-none',
|
||||
selected
|
||||
? 'ring-3 ring-inset ring-modal-card-border-highlighted'
|
||||
? 'ring-3 ring-modal-card-border-highlighted ring-inset'
|
||||
: 'hover:bg-modal-card-background-hovered/20'
|
||||
)
|
||||
"
|
||||
@@ -84,7 +84,7 @@
|
||||
<!-- Bottom Area: Media Info -->
|
||||
<div class="flex-1">
|
||||
<!-- Loading State -->
|
||||
<div v-if="loading" class="flex justify-between items-start">
|
||||
<div v-if="loading" class="flex items-start justify-between">
|
||||
<div class="flex flex-col gap-1">
|
||||
<div
|
||||
class="h-4 w-24 animate-pulse rounded-sm bg-modal-card-background"
|
||||
@@ -101,7 +101,7 @@
|
||||
<!-- Content -->
|
||||
<div
|
||||
v-else-if="asset && adaptedAsset"
|
||||
class="flex justify-between items-end gap-1.5"
|
||||
class="flex items-end justify-between gap-1.5"
|
||||
>
|
||||
<!-- Left side: Media name and metadata -->
|
||||
<div class="flex flex-col gap-1">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="flex gap-3 items-center">
|
||||
<div class="flex items-center gap-3">
|
||||
<SearchBox
|
||||
:model-value="searchQuery"
|
||||
:placeholder="
|
||||
@@ -7,7 +7,7 @@
|
||||
"
|
||||
@update:model-value="handleSearchChange"
|
||||
/>
|
||||
<div class="flex gap-1.5 items-center">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<MediaAssetFilterButton
|
||||
v-if="isCloud"
|
||||
v-tooltip.top="{ value: $t('assetBrowser.filterBy') }"
|
||||
|
||||
@@ -11,7 +11,7 @@ TODO: Extract checkbox pattern into reusable Checkbox component
|
||||
- Benefits: Consistent checkbox UI, better maintainability, reusable design system component
|
||||
-->
|
||||
<template>
|
||||
<div class="flex flex-col gap-0 p-0 m-0">
|
||||
<div class="m-0 flex flex-col gap-0 p-0">
|
||||
<div
|
||||
v-for="filter in filters"
|
||||
:key="filter.type"
|
||||
@@ -27,7 +27,7 @@ TODO: Extract checkbox pattern into reusable Checkbox component
|
||||
class="flex size-4 shrink-0 items-center justify-center rounded-sm p-0.5 transition-all duration-200"
|
||||
:class="
|
||||
mediaTypeFilters.includes(filter.type)
|
||||
? 'bg-primary-background border-primary-background'
|
||||
? 'border-primary-background bg-primary-background'
|
||||
: 'bg-secondary-background'
|
||||
"
|
||||
>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<span>{{ $t('sideToolbar.queueProgressOverlay.viewList') }}</span>
|
||||
</span>
|
||||
<i
|
||||
class="icon-[lucide--check] ml-auto size-4"
|
||||
class="ml-auto icon-[lucide--check] size-4"
|
||||
:class="viewMode !== 'list' && 'opacity-0'"
|
||||
/>
|
||||
</Button>
|
||||
@@ -25,13 +25,13 @@
|
||||
<span>{{ $t('sideToolbar.queueProgressOverlay.viewGrid') }}</span>
|
||||
</span>
|
||||
<i
|
||||
class="icon-[lucide--check] ml-auto size-4"
|
||||
class="ml-auto icon-[lucide--check] size-4"
|
||||
:class="viewMode !== 'grid' && 'opacity-0'"
|
||||
/>
|
||||
</Button>
|
||||
|
||||
<template v-if="showSortOptions">
|
||||
<div class="border-b w-full border-border-subtle my-1" />
|
||||
<div class="my-1 w-full border-b border-border-subtle" />
|
||||
|
||||
<Button
|
||||
variant="textonly"
|
||||
@@ -40,7 +40,7 @@
|
||||
>
|
||||
<span>{{ $t('sideToolbar.mediaAssets.sortNewestFirst') }}</span>
|
||||
<i
|
||||
class="icon-[lucide--check] ml-auto size-4"
|
||||
class="ml-auto icon-[lucide--check] size-4"
|
||||
:class="sortBy !== 'newest' && 'opacity-0'"
|
||||
/>
|
||||
</Button>
|
||||
@@ -52,7 +52,7 @@
|
||||
>
|
||||
<span>{{ $t('sideToolbar.mediaAssets.sortOldestFirst') }}</span>
|
||||
<i
|
||||
class="icon-[lucide--check] ml-auto size-4"
|
||||
class="ml-auto icon-[lucide--check] size-4"
|
||||
:class="sortBy !== 'oldest' && 'opacity-0'"
|
||||
/>
|
||||
</Button>
|
||||
@@ -65,7 +65,7 @@
|
||||
>
|
||||
<span>{{ $t('sideToolbar.mediaAssets.sortLongestFirst') }}</span>
|
||||
<i
|
||||
class="icon-[lucide--check] ml-auto size-4"
|
||||
class="ml-auto icon-[lucide--check] size-4"
|
||||
:class="sortBy !== 'longest' && 'opacity-0'"
|
||||
/>
|
||||
</Button>
|
||||
@@ -77,7 +77,7 @@
|
||||
>
|
||||
<span>{{ $t('sideToolbar.mediaAssets.sortFastestFirst') }}</span>
|
||||
<i
|
||||
class="icon-[lucide--check] ml-auto size-4"
|
||||
class="ml-auto icon-[lucide--check] size-4"
|
||||
:class="sortBy !== 'fastest' && 'opacity-0'"
|
||||
/>
|
||||
</Button>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<p
|
||||
class="m-0 line-clamp-2 text-sm/tight text-base-foreground break-all"
|
||||
class="m-0 line-clamp-2 text-sm/tight break-all text-base-foreground"
|
||||
:title="fileName"
|
||||
>
|
||||
{{ fileName }}
|
||||
|
||||
@@ -144,7 +144,7 @@ function closeDialog() {
|
||||
<div class="relative max-h-75 overflow-y-auto p-4">
|
||||
<div
|
||||
v-if="filteredJobs.length > 3"
|
||||
class="absolute right-1 top-4 h-12 w-1 rounded-full bg-muted-foreground"
|
||||
class="absolute top-4 right-1 h-12 w-1 rounded-full bg-muted-foreground"
|
||||
/>
|
||||
|
||||
<div class="flex flex-col gap-2">
|
||||
@@ -208,7 +208,7 @@ function closeDialog() {
|
||||
<div class="flex shrink-0 items-center gap-2">
|
||||
<span
|
||||
v-if="isInProgress"
|
||||
class="whitespace-nowrap text-sm text-muted-foreground"
|
||||
class="text-sm whitespace-nowrap text-muted-foreground"
|
||||
>
|
||||
{{
|
||||
t('progressToast.progressCount', {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="flex items-center gap-2 p-4 font-bold">
|
||||
<span>{{ $t('assetBrowser.uploadModelGeneric') }}</span>
|
||||
<span
|
||||
class="rounded-full bg-white px-1.5 py-0 text-xxs font-inter font-semibold uppercase text-black"
|
||||
class="rounded-full bg-white px-1.5 py-0 font-inter text-xxs font-semibold text-black uppercase"
|
||||
>
|
||||
{{ $t('g.beta') }}
|
||||
</span>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="flex justify-end gap-2 w-full">
|
||||
<div class="flex w-full justify-end gap-2">
|
||||
<div v-if="currentStep === 1" class="mr-auto flex items-center gap-2">
|
||||
<i class="icon-[lucide--circle-question-mark] text-muted-foreground" />
|
||||
<Button
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
<p class="m-0 text-sm font-bold">
|
||||
{{ $t('assetBrowser.uploadFailed') }}
|
||||
</p>
|
||||
<p v-if="error" class="text-sm text-muted mb-0">
|
||||
<p v-if="error" class="mb-0 text-sm text-muted">
|
||||
{{ error }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div
|
||||
class="flex flex-col justify-between gap-10 p-4 border-t border-border-default w-auto max-w-[min(500px,90vw)]"
|
||||
class="flex w-auto max-w-[min(500px,90vw)] flex-col justify-between gap-10 border-t border-border-default p-4"
|
||||
>
|
||||
<UploadModelUpgradeModalBody />
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<div class="flex flex-wrap justify-end gap-2 w-full">
|
||||
<div class="flex w-full flex-wrap justify-end gap-2">
|
||||
<a
|
||||
href="https://blog.comfy.org/p/comfy-cloud-new-features-and-pricing"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="text-muted-foreground mr-auto underline flex items-center gap-2"
|
||||
class="mr-auto flex items-center gap-2 text-muted-foreground underline"
|
||||
>
|
||||
<i class="icon-[lucide--external-link]" />
|
||||
<span>{{ $t('g.learnMore') }}</span>
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<template>
|
||||
<div class="flex flex-col justify-between h-full gap-6 text-sm">
|
||||
<div class="flex h-full flex-col justify-between gap-6 text-sm">
|
||||
<div class="flex flex-col gap-6">
|
||||
<div class="flex flex-col gap-2">
|
||||
<p class="m-0 text-foreground">
|
||||
<p class="text-foreground m-0">
|
||||
{{ $t('assetBrowser.uploadModelDescription1Generic') }}
|
||||
</p>
|
||||
<div class="m-0">
|
||||
<p class="m-0 text-muted-foreground">
|
||||
{{ $t('assetBrowser.uploadModelDescription2Generic') }}
|
||||
</p>
|
||||
<span class="inline-flex items-center gap-1 flex-wrap mt-2">
|
||||
<span class="mt-2 inline-flex flex-wrap items-center gap-1">
|
||||
<span class="inline-flex items-center gap-1">
|
||||
<img
|
||||
:src="civitaiIcon"
|
||||
@@ -65,7 +65,7 @@
|
||||
<Button
|
||||
variant="textonly"
|
||||
size="unset"
|
||||
class="text-muted-foreground underline p-0"
|
||||
class="p-0 text-muted-foreground underline"
|
||||
@click="openSecretsSettings"
|
||||
>
|
||||
{{ $t('assetBrowser.apiKeyHintLink') }}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="flex flex-col gap-2 px-4 py-2 text-sm text-base-foreground">
|
||||
<div class="flex items-center justify-between relative">
|
||||
<div class="relative flex items-center justify-between">
|
||||
<span class="select-none">{{ label }}</span>
|
||||
<slot name="label-action" />
|
||||
</div>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<template>
|
||||
<div
|
||||
data-component-id="ModelInfoPanel"
|
||||
class="flex h-full flex-col scrollbar-custom"
|
||||
class="flex scrollbar-custom h-full flex-col"
|
||||
>
|
||||
<PropertiesAccordionItem :class="accordionClass">
|
||||
<template #label>
|
||||
<span class="text-xs uppercase font-inter select-none">
|
||||
<span class="font-inter text-xs uppercase select-none">
|
||||
{{ t('assetBrowser.modelInfo.basicInfo') }}
|
||||
</span>
|
||||
</template>
|
||||
@@ -14,7 +14,7 @@
|
||||
<EditableText
|
||||
:model-value="displayName"
|
||||
:is-editing="isEditingDisplayName"
|
||||
:class="cn('break-all text-muted-foreground flex-auto')"
|
||||
:class="cn('flex-auto break-all text-muted-foreground')"
|
||||
@dblclick="isEditingDisplayName = !isImmutable"
|
||||
@edit="handleDisplayNameEdit"
|
||||
@cancel="isEditingDisplayName = false"
|
||||
@@ -23,11 +23,11 @@
|
||||
v-if="!isImmutable && !isEditingDisplayName"
|
||||
size="icon-sm"
|
||||
variant="muted-textonly"
|
||||
class="transition-opacity opacity-0 group-hover:opacity-100"
|
||||
class="opacity-0 transition-opacity group-hover:opacity-100"
|
||||
:aria-label="t('assetBrowser.modelInfo.editDisplayName')"
|
||||
@click="isEditingDisplayName = !isImmutable"
|
||||
>
|
||||
<i class="icon-[lucide--square-pen] self-center size-4" />
|
||||
<i class="icon-[lucide--square-pen] size-4 self-center" />
|
||||
</Button>
|
||||
</div>
|
||||
</ModelInfoField>
|
||||
@@ -42,7 +42,7 @@
|
||||
:href="sourceUrl"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="inline-flex items-center gap-1.5 text-muted-foreground no-underline transition-colors hover:text-foreground"
|
||||
class="hover:text-foreground inline-flex items-center gap-1.5 text-muted-foreground no-underline transition-colors"
|
||||
>
|
||||
<img
|
||||
v-if="sourceName === 'Civitai'"
|
||||
@@ -64,7 +64,7 @@
|
||||
|
||||
<PropertiesAccordionItem :class="accordionClass">
|
||||
<template #label>
|
||||
<span class="text-xs uppercase font-inter select-none">
|
||||
<span class="font-inter text-xs uppercase select-none">
|
||||
{{ t('assetBrowser.modelInfo.modelTagging') }}
|
||||
</span>
|
||||
</template>
|
||||
@@ -140,7 +140,7 @@
|
||||
|
||||
<PropertiesAccordionItem :class="accordionClass">
|
||||
<template #label>
|
||||
<span class="text-xs uppercase font-inter select-none">
|
||||
<span class="font-inter text-xs uppercase select-none">
|
||||
{{ t('assetBrowser.modelInfo.modelDescription') }}
|
||||
</span>
|
||||
</template>
|
||||
@@ -157,7 +157,7 @@
|
||||
class="p-0"
|
||||
@click="copyToClipboard(triggerPhrases.join(', '))"
|
||||
>
|
||||
<i class="icon-[lucide--copy] size-4 min-w-4 min-h-4 opacity-60" />
|
||||
<i class="icon-[lucide--copy] size-4 min-h-4 min-w-4 opacity-60" />
|
||||
</Button>
|
||||
</template>
|
||||
<div class="flex flex-wrap gap-1 pt-1">
|
||||
@@ -167,11 +167,11 @@
|
||||
variant="muted-textonly"
|
||||
size="unset"
|
||||
:title="t('g.copyToClipboard')"
|
||||
class="text-pretty whitespace-normal text-left text-xs"
|
||||
class="text-left text-xs text-pretty whitespace-normal"
|
||||
@click="copyToClipboard(phrase)"
|
||||
>
|
||||
{{ phrase }}
|
||||
<i class="icon-[lucide--copy] size-4 min-w-4 min-h-4 opacity-60" />
|
||||
<i class="icon-[lucide--copy] size-4 min-h-4 min-w-4 opacity-60" />
|
||||
</Button>
|
||||
</div>
|
||||
</ModelInfoField>
|
||||
@@ -194,7 +194,7 @@
|
||||
rows="3"
|
||||
:class="
|
||||
cn(
|
||||
'w-full resize-y rounded-lg border border-transparent bg-transparent px-3 py-2 text-sm text-component-node-foreground outline-none transition-colors focus:bg-component-node-widget-background',
|
||||
'w-full resize-y rounded-lg border border-transparent bg-transparent px-3 py-2 text-sm text-component-node-foreground transition-colors outline-none focus:bg-component-node-widget-background',
|
||||
isImmutable && 'cursor-not-allowed'
|
||||
)
|
||||
"
|
||||
@@ -251,7 +251,7 @@ const descriptionTextarea = useTemplateRef<HTMLTextAreaElement>(
|
||||
)
|
||||
|
||||
const accordionClass = cn(
|
||||
'bg-modal-panel-background border-t border-border-default'
|
||||
'border-t border-border-default bg-modal-panel-background'
|
||||
)
|
||||
|
||||
const { asset, cacheKey } = defineProps<{
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
<!-- Technical Details (Collapsible) -->
|
||||
<div v-if="errorMessage" class="mb-4 text-left">
|
||||
<button
|
||||
class="flex w-full items-center justify-between rounded-sm bg-secondary-background px-4 py-2 text-sm text-text-secondary transition-colors hover:bg-secondary-background-hover border-0"
|
||||
class="flex w-full items-center justify-between rounded-sm border-0 bg-secondary-background px-4 py-2 text-sm text-text-secondary transition-colors hover:bg-secondary-background-hover"
|
||||
@click="showTechnicalDetails = !showTechnicalDetails"
|
||||
>
|
||||
<span>{{ $t('cloudOnboarding.authTimeout.technicalDetails') }}</span>
|
||||
@@ -41,7 +41,7 @@
|
||||
</button>
|
||||
<div
|
||||
v-if="showTechnicalDetails"
|
||||
class="mt-2 rounded-sm border-muted-background border p-4 font-mono text-xs text-muted-foreground break-all"
|
||||
class="mt-2 rounded-sm border border-muted-background p-4 font-mono text-xs break-all text-muted-foreground"
|
||||
>
|
||||
{{ errorMessage }}
|
||||
</div>
|
||||
|
||||
@@ -97,7 +97,7 @@ onMounted(() => {
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="flex size-full items-center justify-center bg-comfy-menu-secondary-bg"
|
||||
class="bg-comfy-menu-secondary-bg flex size-full items-center justify-center"
|
||||
>
|
||||
<div class="flex flex-col items-center gap-4">
|
||||
<img
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<Button
|
||||
size="icon"
|
||||
variant="muted-textonly"
|
||||
class="rounded-full absolute top-2.5 right-2.5 z-10 size-8 p-0 text-white hover:bg-white/20"
|
||||
class="absolute top-2.5 right-2.5 z-10 size-8 rounded-full p-0 text-white hover:bg-white/20"
|
||||
:aria-label="$t('g.close')"
|
||||
@click="$emit('close', false)"
|
||||
>
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
<span>{{ option.label }}</span>
|
||||
<div
|
||||
v-if="option.value === 'yearly'"
|
||||
class="bg-primary-background text-white text-[11px] px-1 py-0.5 rounded-full flex items-center font-bold"
|
||||
class="flex items-center rounded-full bg-primary-background px-1 py-0.5 text-[11px] font-bold text-white"
|
||||
>
|
||||
-20%
|
||||
</div>
|
||||
@@ -38,19 +38,19 @@
|
||||
</template>
|
||||
</SelectButton>
|
||||
</div>
|
||||
<div class="flex flex-col xl:flex-row items-stretch gap-6">
|
||||
<div class="flex flex-col items-stretch gap-6 xl:flex-row">
|
||||
<div
|
||||
v-for="tier in tiers"
|
||||
:key="tier.id"
|
||||
:class="
|
||||
cn(
|
||||
'flex-1 flex flex-col rounded-2xl border border-border-default bg-base-background shadow-[0_0_12px_rgba(0,0,0,0.1)]',
|
||||
'flex flex-1 flex-col rounded-2xl border border-border-default bg-base-background shadow-[0_0_12px_rgba(0,0,0,0.1)]',
|
||||
tier.isPopular ? 'border-muted-foreground' : ''
|
||||
)
|
||||
"
|
||||
>
|
||||
<div class="p-8 pb-0 flex flex-col gap-8">
|
||||
<div class="flex flex-row items-center gap-2 justify-between">
|
||||
<div class="flex flex-col gap-8 p-8 pb-0">
|
||||
<div class="flex flex-row items-center justify-between gap-2">
|
||||
<span
|
||||
class="font-inter text-base/normal font-bold text-base-foreground"
|
||||
>
|
||||
@@ -58,7 +58,7 @@
|
||||
</span>
|
||||
<div
|
||||
v-if="tier.isPopular"
|
||||
class="rounded-full bg-base-foreground px-1.5 text-[11px] font-bold uppercase text-base-background h-5 tracking-tight flex items-center"
|
||||
class="flex h-5 items-center rounded-full bg-base-foreground px-1.5 text-[11px] font-bold tracking-tight text-base-background uppercase"
|
||||
>
|
||||
{{ t('subscription.mostPopular') }}
|
||||
</div>
|
||||
@@ -67,11 +67,11 @@
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="flex flex-row items-baseline gap-2">
|
||||
<span
|
||||
class="font-inter text-[32px] font-semibold leading-normal text-base-foreground"
|
||||
class="font-inter text-[32px] leading-normal font-semibold text-base-foreground"
|
||||
>
|
||||
<span
|
||||
v-show="currentBillingCycle === 'yearly'"
|
||||
class="line-through text-2xl text-muted-foreground"
|
||||
class="text-2xl text-muted-foreground line-through"
|
||||
>
|
||||
${{ tier.pricing.monthly }}
|
||||
</span>
|
||||
@@ -95,10 +95,10 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-4 pb-0 flex-1">
|
||||
<div class="flex flex-1 flex-col gap-4 pb-0">
|
||||
<div class="flex flex-row items-center justify-between">
|
||||
<span
|
||||
class="font-inter text-sm/normal font-normal text-foreground"
|
||||
class="text-foreground font-inter text-sm/normal font-normal"
|
||||
>
|
||||
{{
|
||||
currentBillingCycle === 'yearly'
|
||||
@@ -107,7 +107,7 @@
|
||||
}}
|
||||
</span>
|
||||
<div class="flex flex-row items-center gap-1">
|
||||
<i class="icon-[lucide--component] text-amber-400 text-sm" />
|
||||
<i class="icon-[lucide--component] text-sm text-amber-400" />
|
||||
<span
|
||||
class="font-inter text-sm/normal font-bold text-base-foreground"
|
||||
>
|
||||
@@ -117,7 +117,7 @@
|
||||
</div>
|
||||
|
||||
<div class="flex flex-row items-center justify-between">
|
||||
<span class="text-sm font-normal text-foreground">
|
||||
<span class="text-foreground text-sm font-normal">
|
||||
{{ t('subscription.maxDurationLabel') }}
|
||||
</span>
|
||||
<span
|
||||
@@ -128,42 +128,42 @@
|
||||
</div>
|
||||
|
||||
<div class="flex flex-row items-center justify-between">
|
||||
<span class="text-sm font-normal text-foreground">
|
||||
<span class="text-foreground text-sm font-normal">
|
||||
{{ t('subscription.gpuLabel') }}
|
||||
</span>
|
||||
<i class="pi pi-check text-xs text-success-foreground" />
|
||||
<i class="pi pi-check text-success-foreground text-xs" />
|
||||
</div>
|
||||
|
||||
<div class="flex flex-row items-center justify-between">
|
||||
<span class="text-sm font-normal text-foreground">
|
||||
<span class="text-foreground text-sm font-normal">
|
||||
{{ t('subscription.addCreditsLabel') }}
|
||||
</span>
|
||||
<i class="pi pi-check text-xs text-success-foreground" />
|
||||
<i class="pi pi-check text-success-foreground text-xs" />
|
||||
</div>
|
||||
|
||||
<div class="flex flex-row items-center justify-between">
|
||||
<span class="text-sm font-normal text-foreground">
|
||||
<span class="text-foreground text-sm font-normal">
|
||||
{{ t('subscription.customLoRAsLabel') }}
|
||||
</span>
|
||||
<i
|
||||
v-if="tier.customLoRAs"
|
||||
class="pi pi-check text-xs text-success-foreground"
|
||||
class="pi pi-check text-success-foreground text-xs"
|
||||
/>
|
||||
<i v-else class="pi pi-times text-xs text-foreground" />
|
||||
<i v-else class="pi pi-times text-foreground text-xs" />
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="flex flex-row items-start justify-between">
|
||||
<div class="flex flex-col gap-2">
|
||||
<span class="text-sm/relaxed font-normal text-foreground">
|
||||
<span class="text-foreground text-sm/relaxed font-normal">
|
||||
{{ t('subscription.videoEstimateLabel') }}
|
||||
</span>
|
||||
<div class="flex flex-row items-center gap-2 group pt-2">
|
||||
<div class="group flex flex-row items-center gap-2 pt-2">
|
||||
<i
|
||||
class="pi pi-question-circle text-xs text-muted-foreground group-hover:text-base-foreground"
|
||||
/>
|
||||
<span
|
||||
class="text-sm font-normal text-muted-foreground cursor-pointer group-hover:text-base-foreground"
|
||||
class="cursor-pointer text-sm font-normal text-muted-foreground group-hover:text-base-foreground"
|
||||
@click="togglePopover"
|
||||
>
|
||||
{{ t('subscription.videoEstimateHelp') }}
|
||||
@@ -189,8 +189,8 @@
|
||||
'h-10 w-full',
|
||||
getButtonTextClass(tier),
|
||||
tier.key === 'creator'
|
||||
? 'bg-base-foreground border-transparent hover:bg-inverted-background-hover'
|
||||
: 'bg-secondary-background border-transparent hover:bg-secondary-background-hover focus:bg-secondary-background-selected'
|
||||
? 'border-transparent bg-base-foreground hover:bg-inverted-background-hover'
|
||||
: 'border-transparent bg-secondary-background hover:bg-secondary-background-hover focus:bg-secondary-background-selected'
|
||||
)
|
||||
"
|
||||
@click="() => handleSubscribe(tier.key)"
|
||||
@@ -225,7 +225,7 @@
|
||||
href="https://cloud.comfy.org/?template=video_wan2_2_14B_i2v"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="text-sm text-azure-600 hover:text-azure-400 no-underline flex gap-1"
|
||||
class="flex gap-1 text-sm text-azure-600 no-underline hover:text-azure-400"
|
||||
>
|
||||
<span class="underline">
|
||||
{{ t('subscription.videoEstimateTryTemplate') }}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="subscription-container h-full">
|
||||
<div class="flex h-full flex-col gap-6">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="text-2xl/tight font-inter font-semibold">
|
||||
<span class="font-inter text-2xl/tight font-semibold">
|
||||
{{
|
||||
isActiveSubscription
|
||||
? $t('subscription.title')
|
||||
@@ -31,7 +31,7 @@
|
||||
class="text-xs text-text-secondary"
|
||||
@click="handleLearnMoreClick"
|
||||
>
|
||||
<i class="pi pi-question-circle text-text-secondary text-xs" />
|
||||
<i class="pi pi-question-circle text-xs text-text-secondary" />
|
||||
{{ $t('subscription.learnMore') }}
|
||||
</Button>
|
||||
<Button
|
||||
@@ -39,7 +39,7 @@
|
||||
class="text-xs text-text-secondary"
|
||||
@click="handleOpenPartnerNodesInfo"
|
||||
>
|
||||
<i class="pi pi-question-circle text-text-secondary text-xs" />
|
||||
<i class="pi pi-question-circle text-xs text-text-secondary" />
|
||||
{{ $t('subscription.partnerNodesCredits') }}
|
||||
</Button>
|
||||
<Button
|
||||
@@ -48,7 +48,7 @@
|
||||
:loading="isLoadingSupport"
|
||||
@click="handleMessageSupport"
|
||||
>
|
||||
<i class="pi pi-comment text-text-secondary text-xs" />
|
||||
<i class="pi pi-comment text-xs text-text-secondary" />
|
||||
{{ $t('subscription.messageSupport') }}
|
||||
</Button>
|
||||
</div>
|
||||
@@ -59,7 +59,7 @@
|
||||
@click="handleInvoiceHistory"
|
||||
>
|
||||
{{ $t('subscription.invoiceHistory') }}
|
||||
<i class="pi pi-external-link text-text-secondary text-xs" />
|
||||
<i class="pi pi-external-link text-xs text-text-secondary" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
<Button
|
||||
v-if="isActiveSubscription && !isFreeTier"
|
||||
variant="secondary"
|
||||
class="ml-auto rounded-lg px-4 py-2 text-sm font-normal text-text-primary bg-interface-menu-component-surface-selected"
|
||||
class="ml-auto rounded-lg bg-interface-menu-component-surface-selected px-4 py-2 text-sm font-normal text-text-primary"
|
||||
@click="
|
||||
async () => {
|
||||
await authActions.accessBillingPortal()
|
||||
@@ -64,8 +64,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col lg:flex-row gap-6 pt-9">
|
||||
<div class="flex flex-col shrink-0">
|
||||
<div class="flex flex-col gap-6 pt-9 lg:flex-row">
|
||||
<div class="flex shrink-0 flex-col">
|
||||
<div class="flex flex-col gap-3">
|
||||
<div
|
||||
:class="
|
||||
@@ -82,7 +82,7 @@
|
||||
:loading="isLoadingBalance"
|
||||
@click="handleRefresh"
|
||||
>
|
||||
<i class="pi pi-sync text-text-secondary text-sm" />
|
||||
<i class="pi pi-sync text-sm text-text-secondary" />
|
||||
</Button>
|
||||
|
||||
<div class="flex flex-col gap-2">
|
||||
@@ -99,7 +99,7 @@
|
||||
<table class="text-sm text-muted">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="pr-4 font-bold text-left align-middle">
|
||||
<td class="pr-4 text-left align-middle font-bold">
|
||||
<Skeleton
|
||||
v-if="isLoadingBalance"
|
||||
width="5rem"
|
||||
@@ -112,7 +112,7 @@
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="pr-4 font-bold text-left align-middle">
|
||||
<td class="pr-4 text-left align-middle font-bold">
|
||||
<Skeleton
|
||||
v-if="isLoadingBalance"
|
||||
width="3rem"
|
||||
@@ -135,14 +135,14 @@
|
||||
href="https://platform.comfy.org/profile/usage"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="text-sm underline text-muted"
|
||||
class="text-sm text-muted underline"
|
||||
>
|
||||
{{ $t('subscription.viewUsageHistory') }}
|
||||
</a>
|
||||
<Button
|
||||
v-if="isActiveSubscription && isFreeTier"
|
||||
variant="gradient"
|
||||
class="p-2 min-h-8 rounded-lg text-sm font-normal w-full"
|
||||
class="min-h-8 w-full rounded-lg p-2 text-sm font-normal"
|
||||
@click="handleUpgradeToAddCredits"
|
||||
>
|
||||
{{ $t('subscription.upgradeToAddCredits') }}
|
||||
@@ -150,7 +150,7 @@
|
||||
<Button
|
||||
v-else-if="isActiveSubscription"
|
||||
variant="secondary"
|
||||
class="p-2 min-h-8 rounded-lg text-sm font-normal text-text-primary bg-interface-menu-component-surface-selected"
|
||||
class="min-h-8 rounded-lg bg-interface-menu-component-surface-selected p-2 text-sm font-normal text-text-primary"
|
||||
@click="handleAddApiCredits"
|
||||
>
|
||||
{{ $t('subscription.addCredits') }}
|
||||
@@ -197,7 +197,7 @@
|
||||
href="https://www.comfy.org/cloud/pricing"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="text-sm underline hover:opacity-80 text-muted"
|
||||
class="text-sm text-muted underline hover:opacity-80"
|
||||
>
|
||||
{{ $t('subscription.viewMoreDetailsPlans') }}
|
||||
</a>
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
<template>
|
||||
<div
|
||||
v-if="showCustomPricingTable"
|
||||
class="relative flex flex-col p-4 pt-8 md:p-16 overflow-y-auto! h-full gap-8"
|
||||
class="relative flex h-full flex-col gap-8 overflow-y-auto! p-4 pt-8 md:p-16"
|
||||
>
|
||||
<Button
|
||||
size="icon"
|
||||
variant="muted-textonly"
|
||||
class="rounded-full shrink-0 text-text-secondary hover:bg-white/10 absolute right-2.5 top-2.5"
|
||||
class="absolute top-2.5 right-2.5 shrink-0 rounded-full text-text-secondary hover:bg-white/10"
|
||||
:aria-label="$t('g.close')"
|
||||
@click="handleClose"
|
||||
>
|
||||
<i class="pi pi-times text-xl" />
|
||||
</Button>
|
||||
<div class="text-center">
|
||||
<h2 class="text-xl lg:text-2xl text-muted-foreground m-0">
|
||||
<h2 class="m-0 text-xl text-muted-foreground lg:text-2xl">
|
||||
{{ $t('subscription.description') }}
|
||||
</h2>
|
||||
</div>
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
<!-- Contact and Enterprise Links -->
|
||||
<div class="flex flex-col items-center gap-2">
|
||||
<p class="text-sm text-text-secondary m-0">
|
||||
<p class="m-0 text-sm text-text-secondary">
|
||||
{{ $t('subscription.haveQuestions') }}
|
||||
</p>
|
||||
<div class="flex items-center gap-1.5">
|
||||
@@ -51,7 +51,7 @@
|
||||
<Button
|
||||
size="icon"
|
||||
variant="muted-textonly"
|
||||
class="rounded-full absolute top-2.5 right-2.5 z-10 size-8 p-0 text-white hover:bg-white/20"
|
||||
class="absolute top-2.5 right-2.5 z-10 size-8 rounded-full p-0 text-white hover:bg-white/20"
|
||||
:aria-label="$t('g.close')"
|
||||
@click="handleClose"
|
||||
>
|
||||
@@ -113,7 +113,7 @@
|
||||
|
||||
<div class="flex flex-col pt-8">
|
||||
<SubscribeButton
|
||||
class="py-2 px-4 rounded-lg"
|
||||
class="rounded-lg px-4 py-2"
|
||||
:pt="{
|
||||
root: {
|
||||
style: 'background: var(--color-accent-blue, #0B8CE9);'
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div class="flex flex-col w-full mb-4">
|
||||
<div class="mb-4 flex w-full flex-col">
|
||||
<!-- Type header row: type name + chevron -->
|
||||
<div class="flex h-8 items-center w-full">
|
||||
<p class="flex-1 min-w-0 text-sm font-medium truncate text-foreground">
|
||||
<div class="flex h-8 w-full items-center">
|
||||
<p class="text-foreground min-w-0 flex-1 truncate text-sm font-medium">
|
||||
{{ `${group.type} (${group.nodeTypes.length})` }}
|
||||
</p>
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
<TransitionCollapse>
|
||||
<div
|
||||
v-if="expanded"
|
||||
class="flex flex-col gap-0.5 pl-2 mb-2 overflow-hidden"
|
||||
class="mb-2 flex flex-col gap-0.5 overflow-hidden pl-2"
|
||||
>
|
||||
<div
|
||||
v-for="nodeType in group.nodeTypes"
|
||||
@@ -45,18 +45,18 @@
|
||||
typeof nodeType !== 'string' &&
|
||||
nodeType.nodeId != null
|
||||
"
|
||||
class="shrink-0 rounded-md bg-secondary-background-selected px-2 py-0.5 text-xs font-mono text-muted-foreground font-bold mr-1"
|
||||
class="mr-1 shrink-0 rounded-md bg-secondary-background-selected px-2 py-0.5 font-mono text-xs font-bold text-muted-foreground"
|
||||
>
|
||||
#{{ nodeType.nodeId }}
|
||||
</span>
|
||||
<p class="flex-1 min-w-0 text-xs text-muted-foreground truncate">
|
||||
<p class="min-w-0 flex-1 truncate text-xs text-muted-foreground">
|
||||
{{ getLabel(nodeType) }}
|
||||
</p>
|
||||
<Button
|
||||
v-if="typeof nodeType !== 'string' && nodeType.nodeId != null"
|
||||
variant="textonly"
|
||||
size="icon-sm"
|
||||
class="size-6 text-muted-foreground hover:text-base-foreground shrink-0 mr-1"
|
||||
class="mr-1 size-6 shrink-0 text-muted-foreground hover:text-base-foreground"
|
||||
:aria-label="t('rightSidePanel.locateNode', 'Locate Node')"
|
||||
@click="handleLocateNode(nodeType)"
|
||||
>
|
||||
@@ -67,25 +67,25 @@
|
||||
</TransitionCollapse>
|
||||
|
||||
<!-- Description rows: what it is replaced by -->
|
||||
<div class="flex flex-col text-[13px] mb-2 mt-1 px-1 gap-0.5">
|
||||
<div class="mt-1 mb-2 flex flex-col gap-0.5 px-1 text-[13px]">
|
||||
<span class="text-muted-foreground">{{
|
||||
t('nodeReplacement.willBeReplacedBy', 'This node will be replaced by:')
|
||||
}}</span>
|
||||
<span class="font-bold text-foreground">{{
|
||||
<span class="text-foreground font-bold">{{
|
||||
group.newNodeId ?? t('nodeReplacement.unknownNode', 'Unknown')
|
||||
}}</span>
|
||||
</div>
|
||||
|
||||
<!-- Replace Action Button -->
|
||||
<div class="flex items-start w-full py-1">
|
||||
<div class="flex w-full items-start py-1">
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="md"
|
||||
class="flex flex-1 w-full"
|
||||
class="flex w-full flex-1"
|
||||
@click="handleReplaceNode"
|
||||
>
|
||||
<i class="icon-[lucide--repeat] size-4 text-foreground shrink-0 mr-1" />
|
||||
<span class="text-sm text-foreground truncate min-w-0">
|
||||
<i class="text-foreground mr-1 icon-[lucide--repeat] size-4 shrink-0" />
|
||||
<span class="text-foreground min-w-0 truncate text-sm">
|
||||
{{ t('nodeReplacement.replaceNode', 'Replace Node') }}
|
||||
</span>
|
||||
</Button>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="px-4 pb-2 mt-2">
|
||||
<div class="mt-2 px-4 pb-2">
|
||||
<!-- Sub-label: guidance message shown above all swap groups -->
|
||||
<p class="m-0 pb-5 text-sm/relaxed text-muted-foreground">
|
||||
{{
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<span v-if="apiError" class="text-sm text-destructive">
|
||||
<span v-if="apiError" class="text-destructive text-sm">
|
||||
{{ apiError }}
|
||||
</span>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div
|
||||
class="flex items-center justify-between rounded-lg border border-border-default bg-base-raised-surface p-4"
|
||||
class="bg-base-raised-surface flex items-center justify-between rounded-lg border border-border-default p-4"
|
||||
>
|
||||
<div class="flex flex-col gap-1">
|
||||
<div class="flex items-center gap-2">
|
||||
@@ -13,7 +13,7 @@
|
||||
/>
|
||||
<span
|
||||
v-else-if="secret.provider"
|
||||
class="rounded-sm bg-base-surface px-2 py-0.5 text-xs text-muted"
|
||||
class="bg-base-surface rounded-sm px-2 py-0.5 text-xs text-muted"
|
||||
>
|
||||
{{ providerLabel }}
|
||||
</span>
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
|
||||
<Divider class="my-4" />
|
||||
|
||||
<div class="flex items-center justify-between my-4">
|
||||
<h3 class="text-lg font-semibold my-0">
|
||||
<div class="my-4 flex items-center justify-between">
|
||||
<h3 class="my-0 text-lg font-semibold">
|
||||
{{ $t('secrets.modelProviders') }}
|
||||
</h3>
|
||||
<Button @click="openCreateDialog">
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
<nav
|
||||
ref="navRef"
|
||||
class="scrollbar-hide flex flex-1 flex-col gap-1 overflow-y-auto px-3 py-4"
|
||||
class="flex scrollbar-hide flex-1 flex-col gap-1 overflow-y-auto px-3 py-4"
|
||||
>
|
||||
<div
|
||||
v-for="(group, index) in navGroups"
|
||||
|
||||
@@ -108,7 +108,7 @@ function handleOptOut() {
|
||||
<div
|
||||
v-if="isVisible"
|
||||
data-testid="nightly-survey-popover"
|
||||
class="fixed bottom-4 right-4 z-10000 w-80 rounded-lg border border-border-subtle bg-base-background p-4 shadow-lg"
|
||||
class="fixed right-4 bottom-4 z-10000 w-80 rounded-lg border border-border-subtle bg-base-background p-4 shadow-lg"
|
||||
>
|
||||
<div class="mb-3 flex items-start justify-between">
|
||||
<h3 class="text-sm font-medium text-text-primary">
|
||||
@@ -127,7 +127,7 @@ function handleOptOut() {
|
||||
{{ t('nightlySurvey.description') }}
|
||||
</p>
|
||||
|
||||
<div v-if="typeformError" class="mb-4 text-sm text-danger">
|
||||
<div v-if="typeformError" class="text-danger mb-4 text-sm">
|
||||
{{ t('nightlySurvey.loadError') }}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
<template>
|
||||
<div v-if="shouldShow" class="release-toast-popup">
|
||||
<div
|
||||
class="w-96 max-h-96 bg-base-background border border-border-default rounded-lg shadow-[1px_1px_8px_0_rgba(0,0,0,0.4)] flex flex-col"
|
||||
class="flex max-h-96 w-96 flex-col rounded-lg border border-border-default bg-base-background shadow-[1px_1px_8px_0_rgba(0,0,0,0.4)]"
|
||||
>
|
||||
<!-- Main content -->
|
||||
<div class="p-4 flex flex-col gap-4 flex-1 min-h-0">
|
||||
<div class="flex min-h-0 flex-1 flex-col gap-4 p-4">
|
||||
<!-- Header section with icon and text -->
|
||||
<div class="flex items-center gap-4">
|
||||
<div
|
||||
class="p-3 bg-primary-background-hover rounded-lg flex items-center justify-center shrink-0"
|
||||
class="flex shrink-0 items-center justify-center rounded-lg bg-primary-background-hover p-3"
|
||||
>
|
||||
<i class="icon-[lucide--rocket] size-4 text-white" />
|
||||
</div>
|
||||
<div class="flex flex-col gap-1">
|
||||
<div
|
||||
class="text-sm font-normal text-base-foreground leading-[1.429]"
|
||||
class="text-sm leading-[1.429] font-normal text-base-foreground"
|
||||
>
|
||||
{{ $t('releaseToast.newVersionAvailable') }}
|
||||
</div>
|
||||
<div
|
||||
class="text-sm font-normal text-muted-foreground leading-[1.21]"
|
||||
class="text-sm leading-[1.21] font-normal text-muted-foreground"
|
||||
>
|
||||
{{ latestRelease?.version }}
|
||||
</div>
|
||||
@@ -28,15 +28,15 @@
|
||||
|
||||
<!-- Description section -->
|
||||
<div
|
||||
class="pl-14 text-sm font-normal text-muted-foreground leading-[1.21] overflow-y-auto flex-1 min-h-0"
|
||||
class="min-h-0 flex-1 overflow-y-auto pl-14 text-sm leading-[1.21] font-normal text-muted-foreground"
|
||||
v-html="formattedContent"
|
||||
></div>
|
||||
</div>
|
||||
|
||||
<!-- Footer section -->
|
||||
<div class="flex justify-between items-center px-4 pb-4">
|
||||
<div class="flex items-center justify-between px-4 pb-4">
|
||||
<a
|
||||
class="flex items-center gap-2 text-sm font-normal py-1 text-muted-foreground hover:text-base-foreground"
|
||||
class="flex items-center gap-2 py-1 text-sm font-normal text-muted-foreground hover:text-base-foreground"
|
||||
:href="changelogUrl"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
@@ -47,13 +47,13 @@
|
||||
</a>
|
||||
<div class="flex items-center gap-4">
|
||||
<button
|
||||
class="h-6 px-0 bg-transparent border-none text-sm font-normal text-muted-foreground hover:text-base-foreground cursor-pointer"
|
||||
class="h-6 cursor-pointer border-none bg-transparent px-0 text-sm font-normal text-muted-foreground hover:text-base-foreground"
|
||||
@click="handleSkip"
|
||||
>
|
||||
{{ $t('releaseToast.skip') }}
|
||||
</button>
|
||||
<button
|
||||
class="h-10 px-4 bg-secondary-background hover:bg-secondary-background-hover rounded-lg border-none text-sm font-normal text-base-foreground cursor-pointer"
|
||||
class="h-10 cursor-pointer rounded-lg border-none bg-secondary-background px-4 text-sm font-normal text-base-foreground hover:bg-secondary-background-hover"
|
||||
@click="handleUpdate"
|
||||
>
|
||||
{{ $t('releaseToast.update') }}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<div class="whats-new-popup" @click.stop>
|
||||
<!-- Close Button -->
|
||||
<Button
|
||||
class="close-button absolute top-2 right-2 z-10 size-8 p-2 rounded-lg opacity-50"
|
||||
class="close-button absolute top-2 right-2 z-10 size-8 rounded-lg p-2 opacity-50"
|
||||
:aria-label="$t('g.close')"
|
||||
size="icon-sm"
|
||||
variant="muted-textonly"
|
||||
@@ -13,7 +13,7 @@
|
||||
</Button>
|
||||
|
||||
<!-- Modal Body -->
|
||||
<div class="modal-body flex flex-col gap-4 px-0 pt-0 pb-2 flex-1">
|
||||
<div class="modal-body flex flex-1 flex-col gap-4 px-0 pt-0 pb-2">
|
||||
<!-- Release Content -->
|
||||
<div
|
||||
class="content-text max-h-96 overflow-y-auto"
|
||||
@@ -23,10 +23,10 @@
|
||||
|
||||
<!-- Modal Footer -->
|
||||
<div
|
||||
class="modal-footer flex justify-between items-center gap-4 px-4 pb-4"
|
||||
class="modal-footer flex items-center justify-between gap-4 px-4 pb-4"
|
||||
>
|
||||
<a
|
||||
class="learn-more-link flex items-center gap-2 text-sm font-normal py-1"
|
||||
class="learn-more-link flex items-center gap-2 py-1 text-sm font-normal"
|
||||
:href="changelogUrl"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
:data-testid="`section-content-${section.id}`"
|
||||
class="overflow-hidden data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down"
|
||||
>
|
||||
<ul class="max-h-25 overflow-y-auto px-6 pb-1 pt-0.5">
|
||||
<ul class="max-h-25 overflow-y-auto px-6 pt-0.5 pb-1">
|
||||
<li
|
||||
v-for="item in section.items"
|
||||
:key="item.id"
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
</template>
|
||||
|
||||
<template v-else-if="error">
|
||||
<main class="flex flex-col items-center gap-4 px-8 py-8">
|
||||
<main class="flex flex-col items-center gap-4 p-8">
|
||||
<i
|
||||
class="icon-[lucide--circle-alert] size-8 text-warning-background"
|
||||
aria-hidden="true"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="rounded-lg flex flex-col gap-3">
|
||||
<div class="flex flex-col gap-3 rounded-lg">
|
||||
<CollapsibleRoot
|
||||
v-model:open="isWarningExpanded"
|
||||
class="overflow-hidden rounded-lg bg-secondary-background"
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
</p>
|
||||
<p
|
||||
v-if="isLoadingAssets"
|
||||
class="m-0 text-sm italic text-muted-foreground"
|
||||
class="m-0 text-sm text-muted-foreground italic"
|
||||
>
|
||||
{{ $t('shareWorkflow.checkingAssets') }}
|
||||
</p>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
{{ $t('comfyHubProfile.chooseProfilePicture') }}
|
||||
</label>
|
||||
<label
|
||||
class="flex size-13 cursor-pointer items-center justify-center overflow-hidden rounded-full bg-gradient-to-b from-green-600/50 to-green-900"
|
||||
class="flex size-13 cursor-pointer items-center justify-center overflow-hidden rounded-full bg-linear-to-b from-green-600/50 to-green-900"
|
||||
>
|
||||
<input
|
||||
id="profile-picture"
|
||||
@@ -68,7 +68,7 @@
|
||||
<span
|
||||
:class="
|
||||
cn(
|
||||
'pointer-events-none absolute left-4 top-1/2 -translate-y-1/2 text-sm',
|
||||
'pointer-events-none absolute top-1/2 left-4 -translate-y-1/2 text-sm',
|
||||
username ? 'text-base-foreground' : 'text-muted-foreground'
|
||||
)
|
||||
"
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Content -->
|
||||
<section class="flex flex-col items-center gap-4 px-4 pb-6 pt-4">
|
||||
<section class="flex flex-col items-center gap-4 px-4 pt-4 pb-6">
|
||||
<h2 class="m-0 text-base font-semibold text-base-foreground">
|
||||
{{ $t('comfyHubProfile.introTitle') }}
|
||||
</h2>
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
<TagsInput
|
||||
v-slot="{ isEmpty }"
|
||||
always-editing
|
||||
class="select-none bg-secondary-background"
|
||||
class="bg-secondary-background select-none"
|
||||
:model-value="tags"
|
||||
@update:model-value="$emit('update:tags', $event as string[])"
|
||||
>
|
||||
@@ -70,18 +70,18 @@
|
||||
|
||||
<TagsInput
|
||||
disabled
|
||||
class="bg-transparent hover:bg-transparent hover-within:bg-transparent p-0"
|
||||
class="hover-within:bg-transparent bg-transparent p-0 hover:bg-transparent"
|
||||
>
|
||||
<div
|
||||
v-if="displayedSuggestions.length > 0"
|
||||
class="basis-full flex flex-wrap gap-2"
|
||||
class="flex basis-full flex-wrap gap-2"
|
||||
>
|
||||
<TagsInputItem
|
||||
v-for="tag in displayedSuggestions"
|
||||
:key="tag"
|
||||
v-auto-animate
|
||||
:value="tag"
|
||||
class="cursor-pointer select-none transition-colors bg-secondary-background hover:bg-secondary-background-selected text-muted-foreground px-2"
|
||||
class="cursor-pointer bg-secondary-background px-2 text-muted-foreground transition-colors select-none hover:bg-secondary-background-selected"
|
||||
@click="addTag(tag)"
|
||||
>
|
||||
<TagsInputItemText />
|
||||
@@ -91,7 +91,7 @@
|
||||
v-if="shouldShowSuggestionToggle"
|
||||
variant="muted-textonly"
|
||||
size="unset"
|
||||
class="text-xs px-0 hover:bg-unset"
|
||||
class="hover:bg-unset px-0 text-xs"
|
||||
@click="showAllSuggestions = !showAllSuggestions"
|
||||
>
|
||||
{{
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
tabindex="0"
|
||||
role="button"
|
||||
:aria-label="$t('comfyHubPublish.uploadExampleImage')"
|
||||
class="flex h-25 aspect-square text-center cursor-pointer flex-col items-center justify-center gap-2 rounded-lg border border-dashed border-border-default transition-colors hover:border-muted-foreground focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring"
|
||||
class="focus-visible:outline-ring flex aspect-square h-25 cursor-pointer flex-col items-center justify-center gap-2 rounded-lg border border-dashed border-border-default text-center transition-colors hover:border-muted-foreground focus-visible:outline-2 focus-visible:outline-offset-2"
|
||||
@dragenter.stop
|
||||
@dragleave.stop
|
||||
@dragover.prevent.stop
|
||||
@@ -49,7 +49,7 @@
|
||||
:class="
|
||||
cn(
|
||||
'relative h-25 cursor-pointer overflow-hidden rounded-sm p-0',
|
||||
isSelected(image.id) ? 'ring-2 ring-ring' : 'ring-0'
|
||||
isSelected(image.id) ? 'ring-ring ring-2' : 'ring-0'
|
||||
)
|
||||
"
|
||||
@click="toggleSelection(image.id)"
|
||||
@@ -57,7 +57,7 @@
|
||||
<img
|
||||
:src="image.url"
|
||||
:alt="$t('comfyHubPublish.exampleImage', { index: index + 1 })"
|
||||
class="h-full w-full object-cover"
|
||||
class="size-full object-cover"
|
||||
/>
|
||||
<div
|
||||
v-if="isSelected(image.id)"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
size="md"
|
||||
>
|
||||
<template #leftPanelHeaderTitle>
|
||||
<h2 class="flex-1 select-none text-base font-semibold">
|
||||
<h2 class="flex-1 text-base font-semibold select-none">
|
||||
{{ $t('comfyHubPublish.title') }}
|
||||
</h2>
|
||||
</template>
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
severity="contrast"
|
||||
:class="
|
||||
cn(
|
||||
'size-5 shrink-0 border text-xs font-bold font-inter bg-transparent',
|
||||
'size-5 shrink-0 border bg-transparent font-inter text-xs font-bold',
|
||||
isCurrentStep(step.name)
|
||||
? 'border-base-foreground bg-base-foreground text-base-background'
|
||||
: isCompletedStep(step.name)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
:on-close="onGateClose"
|
||||
:show-close-button="false"
|
||||
/>
|
||||
<div v-else class="flex min-h-0 flex-1 flex-col px-6 pb-2 pt-4">
|
||||
<div v-else class="flex min-h-0 flex-1 flex-col px-6 pt-4 pb-2">
|
||||
<div class="flex min-h-0 flex-1 flex-col overflow-y-auto">
|
||||
<ComfyHubDescribeStep
|
||||
v-if="currentStep === 'describe'"
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
|
||||
<template v-if="thumbnailType === 'imageComparison'">
|
||||
<div
|
||||
class="flex-1 grid grid-cols-1 grid-rows-1 place-content-center-safe"
|
||||
class="grid flex-1 grid-cols-1 grid-rows-1 place-content-center-safe"
|
||||
>
|
||||
<div
|
||||
v-if="hasBothComparisonImages"
|
||||
@@ -50,12 +50,12 @@
|
||||
<img
|
||||
:src="comparisonPreviewUrls.after!"
|
||||
:alt="$t('comfyHubPublish.uploadComparisonAfterPrompt')"
|
||||
class="h-full w-full object-contain"
|
||||
class="size-full object-contain"
|
||||
/>
|
||||
<img
|
||||
:src="comparisonPreviewUrls.before!"
|
||||
:alt="$t('comfyHubPublish.uploadComparisonBeforePrompt')"
|
||||
class="absolute inset-0 h-full w-full object-contain"
|
||||
class="absolute inset-0 size-full object-contain"
|
||||
:style="{
|
||||
clipPath: `inset(0 ${100 - previewSliderPosition}% 0 0)`
|
||||
}"
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<!-- A popover that shows current user information and actions -->
|
||||
<template>
|
||||
<div
|
||||
class="current-user-popover w-80 -m-3 p-2 rounded-lg border border-border-default bg-base-background shadow-[1px_1px_8px_0_rgba(0,0,0,0.4)]"
|
||||
class="current-user-popover -m-3 w-80 rounded-lg border border-border-default bg-base-background p-2 shadow-[1px_1px_8px_0_rgba(0,0,0,0.4)]"
|
||||
>
|
||||
<!-- User Info Section -->
|
||||
<div class="flex flex-col items-center px-0 py-3 mb-4">
|
||||
<div class="mb-4 flex flex-col items-center px-0 py-3">
|
||||
<UserAvatar
|
||||
class="mb-1"
|
||||
:photo-url="userPhotoUrl"
|
||||
@@ -70,7 +70,7 @@
|
||||
}}</span>
|
||||
<i
|
||||
v-tooltip="{ value: $t('credits.unified.tooltip'), showDelay: 300 }"
|
||||
class="icon-[lucide--circle-help] mr-auto cursor-help text-base text-muted-foreground"
|
||||
class="mr-auto icon-[lucide--circle-help] cursor-help text-base text-muted-foreground"
|
||||
/>
|
||||
<!-- Upgrade to add credits (free tier) -->
|
||||
<Button
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="flex flex-col gap-8">
|
||||
<h2 class="text-xl lg:text-2xl text-muted-foreground m-0 text-center">
|
||||
<h2 class="m-0 text-center text-xl text-muted-foreground lg:text-2xl">
|
||||
{{ t('subscription.chooseBestPlanWorkspace') }}
|
||||
</h2>
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
<span>{{ option.label }}</span>
|
||||
<div
|
||||
v-if="option.value === 'yearly'"
|
||||
class="bg-primary-background text-white text-[11px] px-1 py-0.5 rounded-full flex items-center font-bold"
|
||||
class="flex items-center rounded-full bg-primary-background px-1 py-0.5 text-[11px] font-bold text-white"
|
||||
>
|
||||
-20%
|
||||
</div>
|
||||
@@ -42,19 +42,19 @@
|
||||
</template>
|
||||
</SelectButton>
|
||||
</div>
|
||||
<div class="flex flex-col xl:flex-row items-stretch gap-6">
|
||||
<div class="flex flex-col items-stretch gap-6 xl:flex-row">
|
||||
<div
|
||||
v-for="tier in tiers"
|
||||
:key="tier.id"
|
||||
:class="
|
||||
cn(
|
||||
'flex-1 flex flex-col rounded-2xl border border-border-default bg-base-background shadow-[0_0_12px_rgba(0,0,0,0.1)]',
|
||||
'flex flex-1 flex-col rounded-2xl border border-border-default bg-base-background shadow-[0_0_12px_rgba(0,0,0,0.1)]',
|
||||
tier.isPopular ? 'border-muted-foreground' : ''
|
||||
)
|
||||
"
|
||||
>
|
||||
<div class="p-8 pb-0 flex flex-col gap-8">
|
||||
<div class="flex flex-row items-center gap-2 justify-between">
|
||||
<div class="flex flex-col gap-8 p-8 pb-0">
|
||||
<div class="flex flex-row items-center justify-between gap-2">
|
||||
<span
|
||||
class="font-inter text-base/normal font-bold text-base-foreground"
|
||||
>
|
||||
@@ -62,7 +62,7 @@
|
||||
</span>
|
||||
<div
|
||||
v-if="tier.isPopular"
|
||||
class="rounded-full bg-base-foreground px-1.5 text-[11px] font-bold uppercase text-base-background h-5 tracking-tight flex items-center"
|
||||
class="flex h-5 items-center rounded-full bg-base-foreground px-1.5 text-[11px] font-bold tracking-tight text-base-background uppercase"
|
||||
>
|
||||
{{ t('subscription.mostPopular') }}
|
||||
</div>
|
||||
@@ -71,11 +71,11 @@
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="flex flex-row items-baseline gap-2">
|
||||
<span
|
||||
class="font-inter text-[32px] font-semibold leading-normal text-base-foreground"
|
||||
class="font-inter text-[32px] leading-normal font-semibold text-base-foreground"
|
||||
>
|
||||
<span
|
||||
v-show="currentBillingCycle === 'yearly'"
|
||||
class="line-through text-2xl text-muted-foreground"
|
||||
class="text-2xl text-muted-foreground line-through"
|
||||
>
|
||||
${{ getMonthlyPrice(tier) }}
|
||||
</span>
|
||||
@@ -99,13 +99,13 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-4 pb-0 flex-1">
|
||||
<div class="flex flex-1 flex-col gap-4 pb-0">
|
||||
<div class="flex flex-row items-center justify-between">
|
||||
<span class="text-sm font-normal text-foreground">
|
||||
<span class="text-foreground text-sm font-normal">
|
||||
{{ t('subscription.monthlyCreditsPerMemberLabel') }}
|
||||
</span>
|
||||
<div class="flex flex-row items-center gap-1">
|
||||
<i class="icon-[lucide--component] text-amber-400 text-sm" />
|
||||
<i class="icon-[lucide--component] text-sm text-amber-400" />
|
||||
<span
|
||||
class="font-inter text-sm/normal font-bold text-base-foreground"
|
||||
>
|
||||
@@ -115,7 +115,7 @@
|
||||
</div>
|
||||
|
||||
<div class="flex flex-row items-center justify-between">
|
||||
<span class="text-sm font-normal text-foreground">
|
||||
<span class="text-foreground text-sm font-normal">
|
||||
{{ t('subscription.maxMembersLabel') }}
|
||||
</span>
|
||||
<span
|
||||
@@ -126,7 +126,7 @@
|
||||
</div>
|
||||
|
||||
<div class="flex flex-row items-center justify-between">
|
||||
<span class="text-sm font-normal text-foreground">
|
||||
<span class="text-foreground text-sm font-normal">
|
||||
{{ t('subscription.maxDurationLabel') }}
|
||||
</span>
|
||||
<span
|
||||
@@ -137,42 +137,42 @@
|
||||
</div>
|
||||
|
||||
<div class="flex flex-row items-center justify-between">
|
||||
<span class="text-sm font-normal text-foreground">
|
||||
<span class="text-foreground text-sm font-normal">
|
||||
{{ t('subscription.gpuLabel') }}
|
||||
</span>
|
||||
<i class="pi pi-check text-xs text-success-foreground" />
|
||||
<i class="pi pi-check text-success-foreground text-xs" />
|
||||
</div>
|
||||
|
||||
<div class="flex flex-row items-center justify-between">
|
||||
<span class="text-sm font-normal text-foreground">
|
||||
<span class="text-foreground text-sm font-normal">
|
||||
{{ t('subscription.addCreditsLabel') }}
|
||||
</span>
|
||||
<i class="pi pi-check text-xs text-success-foreground" />
|
||||
<i class="pi pi-check text-success-foreground text-xs" />
|
||||
</div>
|
||||
|
||||
<div class="flex flex-row items-center justify-between">
|
||||
<span class="text-sm font-normal text-foreground">
|
||||
<span class="text-foreground text-sm font-normal">
|
||||
{{ t('subscription.customLoRAsLabel') }}
|
||||
</span>
|
||||
<i
|
||||
v-if="tier.customLoRAs"
|
||||
class="pi pi-check text-xs text-success-foreground"
|
||||
class="pi pi-check text-success-foreground text-xs"
|
||||
/>
|
||||
<i v-else class="pi pi-times text-xs text-foreground" />
|
||||
<i v-else class="pi pi-times text-foreground text-xs" />
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="flex flex-row items-start justify-between">
|
||||
<div class="flex flex-col gap-2">
|
||||
<span class="text-sm/relaxed font-normal text-foreground">
|
||||
<span class="text-foreground text-sm/relaxed font-normal">
|
||||
{{ t('subscription.videoEstimateLabel') }}
|
||||
</span>
|
||||
<div class="flex flex-row items-center gap-2 group pt-2">
|
||||
<div class="group flex flex-row items-center gap-2 pt-2">
|
||||
<i
|
||||
class="pi pi-question-circle text-xs text-muted-foreground group-hover:text-base-foreground"
|
||||
/>
|
||||
<span
|
||||
class="text-sm font-normal text-muted-foreground cursor-pointer group-hover:text-base-foreground"
|
||||
class="cursor-pointer text-sm font-normal text-muted-foreground group-hover:text-base-foreground"
|
||||
@click="togglePopover"
|
||||
>
|
||||
{{ t('subscription.videoEstimateHelp') }}
|
||||
@@ -198,8 +198,8 @@
|
||||
'h-10 w-full',
|
||||
getButtonTextClass(tier),
|
||||
tier.key === 'creator'
|
||||
? 'bg-base-foreground border-transparent hover:bg-inverted-background-hover'
|
||||
: 'bg-secondary-background border-transparent hover:bg-secondary-background-hover focus:bg-secondary-background-selected'
|
||||
? 'border-transparent bg-base-foreground hover:bg-inverted-background-hover'
|
||||
: 'border-transparent bg-secondary-background hover:bg-secondary-background-hover focus:bg-secondary-background-selected'
|
||||
)
|
||||
"
|
||||
@click="() => handleSubscribe(tier.key)"
|
||||
@@ -234,7 +234,7 @@
|
||||
href="https://cloud.comfy.org/?template=video_wan2_2_14B_i2v"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="text-sm text-azure-600 hover:text-azure-400 no-underline flex gap-1"
|
||||
class="flex gap-1 text-sm text-azure-600 no-underline hover:text-azure-400"
|
||||
>
|
||||
<span class="underline">
|
||||
{{ t('subscription.videoEstimateTryTemplate') }}
|
||||
@@ -245,7 +245,7 @@
|
||||
</Popover>
|
||||
<!-- Contact and Enterprise Links -->
|
||||
<div class="flex flex-col items-center gap-2">
|
||||
<p class="text-sm text-text-secondary m-0">
|
||||
<p class="m-0 text-sm text-text-secondary">
|
||||
{{ $t('subscription.haveQuestions') }}
|
||||
</p>
|
||||
<div class="flex items-center gap-1.5">
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<template>
|
||||
<h2 class="text-xl lg:text-2xl text-muted-foreground m-0 text-center mb-8">
|
||||
<h2 class="m-0 mb-8 text-center text-xl text-muted-foreground lg:text-2xl">
|
||||
{{ $t('subscription.preview.confirmPayment') }}
|
||||
</h2>
|
||||
<div
|
||||
class="flex flex-col justify-between items-stretch max-w-[400px] mx-auto text-sm h-full"
|
||||
class="mx-auto flex h-full max-w-[400px] flex-col items-stretch justify-between text-sm"
|
||||
>
|
||||
<div class="">
|
||||
<!-- Plan Header -->
|
||||
<div class="flex flex-col gap-2">
|
||||
<span class="text-base-foreground text-sm">
|
||||
<span class="text-sm text-base-foreground">
|
||||
{{ tierName }}
|
||||
</span>
|
||||
<div class="flex items-baseline gap-2">
|
||||
@@ -31,7 +31,7 @@
|
||||
{{ $t('subscription.preview.eachMonthCreditsRefill') }}
|
||||
</span>
|
||||
<div class="flex items-center gap-1">
|
||||
<i class="icon-[lucide--component] text-amber-400 text-sm" />
|
||||
<i class="icon-[lucide--component] text-sm text-amber-400" />
|
||||
<span class="font-bold text-base-foreground">
|
||||
{{ displayCredits }}
|
||||
</span>
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
<!-- Expandable Features -->
|
||||
<button
|
||||
class="flex items-center justify-end gap-1 text-sm text-muted-foreground hover:text-base-foreground cursor-pointer bg-transparent border-none p-0"
|
||||
class="flex cursor-pointer items-center justify-end gap-1 border-none bg-transparent p-0 text-sm text-muted-foreground hover:text-base-foreground"
|
||||
@click="isFeaturesCollapsed = !isFeaturesCollapsed"
|
||||
>
|
||||
<span>
|
||||
@@ -75,13 +75,13 @@
|
||||
<span class="text-sm text-base-foreground">
|
||||
{{ $t('subscription.gpuLabel') }}
|
||||
</span>
|
||||
<i class="pi pi-check text-xs text-success-foreground" />
|
||||
<i class="pi pi-check text-success-foreground text-xs" />
|
||||
</div>
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-sm text-base-foreground">
|
||||
{{ $t('subscription.addCreditsLabel') }}
|
||||
</span>
|
||||
<i class="pi pi-check text-xs text-success-foreground" />
|
||||
<i class="pi pi-check text-success-foreground text-xs" />
|
||||
</div>
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-sm text-base-foreground">
|
||||
@@ -89,7 +89,7 @@
|
||||
</span>
|
||||
<i
|
||||
v-if="hasCustomLoRAs"
|
||||
class="pi pi-check text-xs text-success-foreground"
|
||||
class="pi pi-check text-success-foreground text-xs"
|
||||
/>
|
||||
<i v-else class="pi pi-times text-xs text-muted-foreground" />
|
||||
</div>
|
||||
@@ -98,7 +98,7 @@
|
||||
|
||||
<!-- Total Due Section -->
|
||||
<div class="flex flex-col gap-2 border-t border-border-subtle pt-8">
|
||||
<div class="flex text-base items-center justify-between">
|
||||
<div class="flex items-center justify-between text-base">
|
||||
<span class="text-base-foreground">
|
||||
{{ $t('subscription.preview.totalDueToday') }}
|
||||
</span>
|
||||
@@ -106,7 +106,7 @@
|
||||
${{ totalDueToday }}
|
||||
</span>
|
||||
</div>
|
||||
<span class="text-muted-foreground text-sm">
|
||||
<span class="text-sm text-muted-foreground">
|
||||
{{
|
||||
$t('subscription.preview.nextPaymentDue', {
|
||||
date: nextPaymentDate
|
||||
@@ -118,7 +118,7 @@
|
||||
<!-- Footer -->
|
||||
<div class="flex flex-col gap-2 pt-8">
|
||||
<!-- Terms Agreement -->
|
||||
<p class="text-xs text-muted-foreground text-center">
|
||||
<p class="text-center text-xs text-muted-foreground">
|
||||
<i18n-t keypath="subscription.preview.termsAgreement" tag="span">
|
||||
<template #terms>
|
||||
<a
|
||||
@@ -157,7 +157,7 @@
|
||||
<!-- Back Link -->
|
||||
<Button
|
||||
variant="textonly"
|
||||
class="text-muted-foreground hover:text-base-foreground hover:bg-none text-center cursor-pointer transition-colors text-xs"
|
||||
class="cursor-pointer text-center text-xs text-muted-foreground transition-colors hover:bg-none hover:text-base-foreground"
|
||||
@click="$emit('back')"
|
||||
>
|
||||
{{ $t('subscription.preview.backToAllPlans') }}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
v-if="isSettingUp"
|
||||
class="rounded-2xl border border-interface-stroke p-6"
|
||||
>
|
||||
<div class="flex items-center gap-2 text-muted-foreground py-4">
|
||||
<div class="flex items-center gap-2 py-4 text-muted-foreground">
|
||||
<i class="pi pi-spin pi-spinner" />
|
||||
<span>{{ $t('billingOperation.subscriptionProcessing') }}</span>
|
||||
</div>
|
||||
@@ -23,10 +23,10 @@
|
||||
<i class="pi pi-info-circle" />
|
||||
</div>
|
||||
<div class="flex flex-col gap-2">
|
||||
<h2 class="text-sm font-bold text-text-primary m-0 pt-1.5">
|
||||
<h2 class="m-0 pt-1.5 text-sm font-bold text-text-primary">
|
||||
{{ $t('subscription.canceledCard.title') }}
|
||||
</h2>
|
||||
<p class="text-sm text-text-secondary m-0">
|
||||
<p class="m-0 text-sm text-text-secondary">
|
||||
{{
|
||||
$t('subscription.canceledCard.description', {
|
||||
date: formattedEndDate
|
||||
@@ -147,7 +147,7 @@
|
||||
v-if="!isFreeTierPlan"
|
||||
size="lg"
|
||||
variant="secondary"
|
||||
class="rounded-lg px-4 text-sm font-normal text-text-primary bg-interface-menu-component-surface-selected"
|
||||
class="rounded-lg bg-interface-menu-component-surface-selected px-4 text-sm font-normal text-text-primary"
|
||||
@click="manageSubscription"
|
||||
>
|
||||
{{ $t('subscription.managePayment') }}
|
||||
@@ -177,11 +177,11 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col lg:flex-row lg:items-stretch gap-6 pt-6">
|
||||
<div class="flex flex-col gap-6 pt-6 lg:flex-row lg:items-stretch">
|
||||
<div class="flex flex-col">
|
||||
<div class="flex flex-col gap-3 h-full">
|
||||
<div class="flex h-full flex-col gap-3">
|
||||
<div
|
||||
class="relative flex flex-col gap-6 rounded-2xl p-5 bg-secondary-background justify-between h-full"
|
||||
class="relative flex h-full flex-col justify-between gap-6 rounded-2xl bg-secondary-background p-5"
|
||||
>
|
||||
<Button
|
||||
variant="muted-textonly"
|
||||
@@ -190,7 +190,7 @@
|
||||
:loading="isLoadingBalance"
|
||||
@click="handleRefresh"
|
||||
>
|
||||
<i class="pi pi-sync text-text-secondary text-sm" />
|
||||
<i class="pi pi-sync text-sm text-text-secondary" />
|
||||
</Button>
|
||||
|
||||
<div class="flex flex-col gap-2">
|
||||
@@ -211,7 +211,7 @@
|
||||
<table class="text-sm text-muted">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="pr-4 font-bold text-left align-middle">
|
||||
<td class="pr-4 text-left align-middle font-bold">
|
||||
<Skeleton
|
||||
v-if="isLoadingBalance"
|
||||
width="5rem"
|
||||
@@ -226,7 +226,7 @@
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="pr-4 font-bold text-left align-middle">
|
||||
<td class="pr-4 text-left align-middle font-bold">
|
||||
<Skeleton
|
||||
v-if="isLoadingBalance"
|
||||
width="3rem"
|
||||
@@ -257,7 +257,7 @@
|
||||
<Button
|
||||
v-if="isFreeTierPlan"
|
||||
variant="gradient"
|
||||
class="p-2 min-h-8 rounded-lg text-sm font-normal w-full"
|
||||
class="min-h-8 w-full rounded-lg p-2 text-sm font-normal"
|
||||
@click="handleUpgradeToAddCredits"
|
||||
>
|
||||
{{ $t('subscription.upgradeToAddCredits') }}
|
||||
@@ -265,7 +265,7 @@
|
||||
<Button
|
||||
v-else
|
||||
variant="secondary"
|
||||
class="p-2 min-h-8 rounded-lg text-sm font-normal text-text-primary bg-interface-menu-component-surface-selected"
|
||||
class="min-h-8 rounded-lg bg-interface-menu-component-surface-selected p-2 text-sm font-normal text-text-primary"
|
||||
@click="handleAddApiCredits"
|
||||
>
|
||||
{{ $t('subscription.addCredits') }}
|
||||
@@ -316,20 +316,20 @@
|
||||
!isInPersonalWorkspace &&
|
||||
permissions.canManageSubscription
|
||||
"
|
||||
class="mt-6 flex gap-1 rounded-2xl border border-interface-stroke p-6 justify-between items-center text-sm"
|
||||
class="mt-6 flex items-center justify-between gap-1 rounded-2xl border border-interface-stroke p-6 text-sm"
|
||||
>
|
||||
<div class="flex flex-col gap-2">
|
||||
<h4 class="text-sm text-text-primary m-0">
|
||||
<h4 class="m-0 text-sm text-text-primary">
|
||||
{{ $t('subscription.nextMonthInvoice') }}
|
||||
</h4>
|
||||
<span
|
||||
class="text-muted-foreground underline cursor-pointer"
|
||||
class="cursor-pointer text-muted-foreground underline"
|
||||
@click="manageSubscription"
|
||||
>
|
||||
{{ $t('subscription.invoiceHistory') }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2 items-end">
|
||||
<div class="flex flex-col items-end gap-2">
|
||||
<h4 class="m-0 font-bold">${{ nextMonthInvoice }}</h4>
|
||||
<h5 class="m-0 text-muted-foreground">
|
||||
{{ $t('subscription.memberCount', memberCount) }}
|
||||
@@ -347,7 +347,7 @@
|
||||
href="https://www.comfy.org/cloud/pricing"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="text-sm underline hover:opacity-80 text-muted"
|
||||
class="text-sm text-muted underline hover:opacity-80"
|
||||
>
|
||||
{{ $t('subscription.viewMoreDetailsPlans') }}
|
||||
</a>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<div
|
||||
class="relative flex flex-col p-4 pt-8 md:p-16 overflow-y-auto! h-full gap-8"
|
||||
class="relative flex h-full flex-col gap-8 overflow-y-auto! p-4 pt-8 md:p-16"
|
||||
>
|
||||
<Button
|
||||
v-if="checkoutStep === 'preview'"
|
||||
size="icon"
|
||||
variant="muted-textonly"
|
||||
class="rounded-full shrink-0 text-text-secondary hover:bg-white/10 absolute left-2.5 top-2.5"
|
||||
class="absolute top-2.5 left-2.5 shrink-0 rounded-full text-text-secondary hover:bg-white/10"
|
||||
:aria-label="$t('g.back')"
|
||||
@click="handleBackToPricing"
|
||||
>
|
||||
@@ -16,7 +16,7 @@
|
||||
<Button
|
||||
size="icon"
|
||||
variant="muted-textonly"
|
||||
class="rounded-full shrink-0 text-text-secondary hover:bg-white/10 absolute right-2.5 top-2.5"
|
||||
class="absolute top-2.5 right-2.5 shrink-0 rounded-full text-text-secondary hover:bg-white/10"
|
||||
:aria-label="$t('g.close')"
|
||||
@click="handleClose"
|
||||
>
|
||||
@@ -24,7 +24,7 @@
|
||||
</Button>
|
||||
|
||||
<div v-if="reason === 'out_of_credits'" class="text-center">
|
||||
<h2 class="text-xl lg:text-2xl text-muted-foreground m-0">
|
||||
<h2 class="m-0 text-xl text-muted-foreground lg:text-2xl">
|
||||
{{ $t('credits.topUp.insufficientTitle') }}
|
||||
</h2>
|
||||
<p class="m-0 mt-2 text-sm text-text-secondary">
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
<template>
|
||||
<h2 class="text-xl lg:text-2xl text-muted-foreground m-0 text-center mb-8">
|
||||
<h2 class="m-0 mb-8 text-center text-xl text-muted-foreground lg:text-2xl">
|
||||
{{ $t('subscription.preview.confirmPlanChange') }}
|
||||
</h2>
|
||||
<div
|
||||
class="flex flex-col justify-between items-stretch mx-auto text-sm h-full"
|
||||
class="mx-auto flex h-full flex-col items-stretch justify-between text-sm"
|
||||
>
|
||||
<div>
|
||||
<!-- Plan Comparison Header -->
|
||||
<div class="flex items-center gap-4">
|
||||
<!-- Current Plan -->
|
||||
<div class="flex flex-col gap-1 w-[250px]">
|
||||
<span class="text-base-foreground text-sm">
|
||||
<div class="flex w-[250px] flex-col gap-1">
|
||||
<span class="text-sm text-base-foreground">
|
||||
{{ currentTierName }}
|
||||
</span>
|
||||
<div class="flex items-baseline gap-1">
|
||||
@@ -21,14 +21,14 @@
|
||||
{{ $t('subscription.usdPerMonthPerMember') }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-1 text-muted-foreground text-sm">
|
||||
<i class="icon-[lucide--component] text-amber-400 text-xs" />
|
||||
<div class="flex items-center gap-1 text-sm text-muted-foreground">
|
||||
<i class="icon-[lucide--component] text-xs text-amber-400" />
|
||||
<span
|
||||
>{{ currentDisplayCredits }}
|
||||
{{ $t('subscription.perMonth') }}</span
|
||||
>
|
||||
</div>
|
||||
<span class="text-muted-foreground text-sm inline">
|
||||
<span class="inline text-sm text-muted-foreground">
|
||||
{{
|
||||
$t('subscription.preview.ends', { date: currentPeriodEndDate })
|
||||
}}
|
||||
@@ -36,11 +36,11 @@
|
||||
</div>
|
||||
|
||||
<!-- Arrow -->
|
||||
<i class="pi pi-arrow-right text-muted-foreground size-8" />
|
||||
<i class="pi pi-arrow-right size-8 text-muted-foreground" />
|
||||
|
||||
<!-- New Plan -->
|
||||
<div class="flex flex-col gap-1">
|
||||
<span class="text-base-foreground text-sm font-semibold">
|
||||
<span class="text-sm font-semibold text-base-foreground">
|
||||
{{ newTierName }}
|
||||
</span>
|
||||
<div class="flex items-baseline gap-1">
|
||||
@@ -51,13 +51,13 @@
|
||||
{{ $t('subscription.usdPerMonthPerMember') }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-1 text-muted-foreground text-sm">
|
||||
<i class="icon-[lucide--component] text-amber-400 text-xs" />
|
||||
<div class="flex items-center gap-1 text-sm text-muted-foreground">
|
||||
<i class="icon-[lucide--component] text-xs text-amber-400" />
|
||||
<span
|
||||
>{{ newDisplayCredits }} {{ $t('subscription.perMonth') }}</span
|
||||
>
|
||||
</div>
|
||||
<span class="text-muted-foreground text-sm">
|
||||
<span class="text-sm text-muted-foreground">
|
||||
{{ $t('subscription.preview.starting', { date: effectiveDate }) }}
|
||||
</span>
|
||||
</div>
|
||||
@@ -70,7 +70,7 @@
|
||||
{{ $t('subscription.preview.eachMonthCreditsRefill') }}
|
||||
</span>
|
||||
<div class="flex items-center gap-1">
|
||||
<i class="icon-[lucide--component] text-amber-400 text-sm" />
|
||||
<i class="icon-[lucide--component] text-sm text-amber-400" />
|
||||
<span class="font-bold text-base-foreground">
|
||||
{{ newDisplayCredits }}
|
||||
</span>
|
||||
@@ -111,7 +111,7 @@
|
||||
|
||||
<!-- Total Due Section -->
|
||||
<div class="flex flex-col gap-2 border-t border-border-subtle pt-6">
|
||||
<div class="flex text-base items-center justify-between">
|
||||
<div class="flex items-center justify-between text-base">
|
||||
<span class="text-base-foreground">
|
||||
{{ $t('subscription.preview.totalDueToday') }}
|
||||
</span>
|
||||
@@ -119,7 +119,7 @@
|
||||
${{ totalDueToday }}
|
||||
</span>
|
||||
</div>
|
||||
<span class="text-muted-foreground text-sm">
|
||||
<span class="text-sm text-muted-foreground">
|
||||
{{
|
||||
$t('subscription.preview.nextPaymentDue', {
|
||||
date: nextPaymentDate
|
||||
@@ -143,7 +143,7 @@
|
||||
|
||||
<Button
|
||||
variant="textonly"
|
||||
class="text-muted-foreground hover:text-base-foreground hover:bg-none text-center cursor-pointer transition-colors text-xs"
|
||||
class="cursor-pointer text-center text-xs text-muted-foreground transition-colors hover:bg-none hover:text-base-foreground"
|
||||
@click="$emit('back')"
|
||||
>
|
||||
{{ $t('subscription.preview.backToAllPlans') }}
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
class="flex min-w-[460px] flex-col rounded-2xl border border-border-default bg-base-background shadow-[1px_1px_8px_0_rgba(0,0,0,0.4)]"
|
||||
>
|
||||
<!-- Header -->
|
||||
<div class="flex p-8 items-center justify-between">
|
||||
<h2 class="text-lg font-bold text-base-foreground m-0">
|
||||
<div class="flex items-center justify-between p-8">
|
||||
<h2 class="m-0 text-lg font-bold text-base-foreground">
|
||||
{{
|
||||
isInsufficientCredits
|
||||
? $t('credits.topUp.addMoreCreditsToRun')
|
||||
@@ -12,7 +12,7 @@
|
||||
}}
|
||||
</h2>
|
||||
<button
|
||||
class="cursor-pointer rounded-sm border-none bg-transparent p-0 text-muted-foreground transition-colors hover:text-base-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-secondary-foreground"
|
||||
class="focus-visible:ring-secondary-foreground cursor-pointer rounded-sm border-none bg-transparent p-0 text-muted-foreground transition-colors hover:text-base-foreground focus-visible:ring-1 focus-visible:outline-none"
|
||||
@click="() => handleClose()"
|
||||
>
|
||||
<i class="icon-[lucide--x] size-6" />
|
||||
@@ -20,7 +20,7 @@
|
||||
</div>
|
||||
<p
|
||||
v-if="isInsufficientCredits"
|
||||
class="text-sm text-muted-foreground m-0 px-8"
|
||||
class="m-0 px-8 text-sm text-muted-foreground"
|
||||
>
|
||||
{{ $t('credits.topUp.insufficientWorkflowMessage') }}
|
||||
</p>
|
||||
@@ -39,7 +39,7 @@
|
||||
size="lg"
|
||||
:class="
|
||||
cn(
|
||||
'h-10 text-base font-medium w-full focus-visible:ring-secondary-foreground',
|
||||
'focus-visible:ring-secondary-foreground h-10 w-full text-base font-medium',
|
||||
selectedPreset === amount && 'bg-secondary-background-selected'
|
||||
)
|
||||
"
|
||||
@@ -95,7 +95,7 @@
|
||||
|
||||
<p
|
||||
v-if="isBelowMin"
|
||||
class="text-sm text-red-500 m-0 px-8 pt-4 text-center flex items-center justify-center gap-1"
|
||||
class="m-0 flex items-center justify-center gap-1 px-8 pt-4 text-center text-sm text-red-500"
|
||||
>
|
||||
<i class="icon-[lucide--component] size-4" />
|
||||
{{
|
||||
@@ -106,7 +106,7 @@
|
||||
</p>
|
||||
<p
|
||||
v-if="showCeilingWarning"
|
||||
class="text-sm text-gold-500 m-0 px-8 pt-4 text-center flex items-center justify-center gap-1"
|
||||
class="m-0 flex items-center justify-center gap-1 px-8 pt-4 text-center text-sm text-gold-500"
|
||||
>
|
||||
<i class="icon-[lucide--component] size-4" />
|
||||
{{
|
||||
@@ -123,7 +123,7 @@
|
||||
>
|
||||
</p>
|
||||
|
||||
<div class="p-8 flex flex-col gap-8">
|
||||
<div class="flex flex-col gap-8 p-8">
|
||||
<Button
|
||||
:disabled="!isValidAmount || loading || isPolling"
|
||||
:loading="loading || isPolling"
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
</span>
|
||||
<span
|
||||
v-if="getTierLabel(workspace)"
|
||||
class="text-[10px] font-bold uppercase text-base-background bg-base-foreground px-1 py-0.5 rounded-full"
|
||||
class="rounded-full bg-base-foreground px-1 py-0.5 text-[10px] font-bold text-base-background uppercase"
|
||||
>
|
||||
{{ getTierLabel(workspace) }}
|
||||
</span>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
{{ $t('workspacePanel.createWorkspaceDialog.title') }}
|
||||
</h2>
|
||||
<button
|
||||
class="cursor-pointer rounded-sm border-none bg-transparent p-0 text-muted-foreground transition-colors hover:text-base-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-secondary-foreground"
|
||||
class="focus-visible:ring-secondary-foreground cursor-pointer rounded-sm border-none bg-transparent p-0 text-muted-foreground transition-colors hover:text-base-foreground focus-visible:ring-1 focus-visible:outline-none"
|
||||
:aria-label="$t('g.close')"
|
||||
@click="onCancel"
|
||||
>
|
||||
@@ -30,7 +30,7 @@
|
||||
<input
|
||||
v-model="workspaceName"
|
||||
type="text"
|
||||
class="w-full rounded-lg border border-border-default bg-transparent px-3 py-2 text-sm text-base-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-secondary-foreground"
|
||||
class="focus:ring-secondary-foreground w-full rounded-lg border border-border-default bg-transparent px-3 py-2 text-sm text-base-foreground placeholder:text-muted-foreground focus:ring-1 focus:outline-none"
|
||||
:placeholder="
|
||||
$t('workspacePanel.createWorkspaceDialog.namePlaceholder')
|
||||
"
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
{{ $t('workspacePanel.deleteDialog.title') }}
|
||||
</h2>
|
||||
<button
|
||||
class="cursor-pointer rounded-sm border-none bg-transparent p-0 text-muted-foreground transition-colors hover:text-base-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-secondary-foreground"
|
||||
class="focus-visible:ring-secondary-foreground cursor-pointer rounded-sm border-none bg-transparent p-0 text-muted-foreground transition-colors hover:text-base-foreground focus-visible:ring-1 focus-visible:outline-none"
|
||||
:aria-label="$t('g.close')"
|
||||
@click="onCancel"
|
||||
>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
{{ $t('workspacePanel.editWorkspaceDialog.title') }}
|
||||
</h2>
|
||||
<button
|
||||
class="cursor-pointer rounded-sm border-none bg-transparent p-0 text-muted-foreground transition-colors hover:text-base-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-secondary-foreground"
|
||||
class="focus-visible:ring-secondary-foreground cursor-pointer rounded-sm border-none bg-transparent p-0 text-muted-foreground transition-colors hover:text-base-foreground focus-visible:ring-1 focus-visible:outline-none"
|
||||
:aria-label="$t('g.close')"
|
||||
@click="onCancel"
|
||||
>
|
||||
@@ -27,7 +27,7 @@
|
||||
<input
|
||||
v-model="newWorkspaceName"
|
||||
type="text"
|
||||
class="w-full rounded-lg border border-border-default bg-transparent px-3 py-2 text-sm text-base-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-secondary-foreground"
|
||||
class="focus:ring-secondary-foreground w-full rounded-lg border border-border-default bg-transparent px-3 py-2 text-sm text-base-foreground placeholder:text-muted-foreground focus:ring-1 focus:outline-none"
|
||||
@keydown.enter="isValidName && onSave()"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
}}
|
||||
</h2>
|
||||
<button
|
||||
class="cursor-pointer rounded-sm border-none bg-transparent p-0 text-muted-foreground transition-colors hover:text-base-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-secondary-foreground"
|
||||
class="focus-visible:ring-secondary-foreground cursor-pointer rounded-sm border-none bg-transparent p-0 text-muted-foreground transition-colors hover:text-base-foreground focus-visible:ring-1 focus-visible:outline-none"
|
||||
:aria-label="$t('g.close')"
|
||||
@click="onCancel"
|
||||
>
|
||||
@@ -31,7 +31,7 @@
|
||||
<input
|
||||
v-model="email"
|
||||
type="email"
|
||||
class="w-full rounded-lg border border-border-default bg-transparent px-3 py-2 text-sm text-base-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-secondary-foreground"
|
||||
class="focus:ring-secondary-foreground w-full rounded-lg border border-border-default bg-transparent px-3 py-2 text-sm text-base-foreground placeholder:text-muted-foreground focus:ring-1 focus:outline-none"
|
||||
:placeholder="$t('workspacePanel.inviteMemberDialog.placeholder')"
|
||||
/>
|
||||
</div>
|
||||
@@ -70,7 +70,7 @@
|
||||
@click="onSelectLink"
|
||||
/>
|
||||
<div
|
||||
class="absolute right-3 top-2.5 cursor-pointer"
|
||||
class="absolute top-2.5 right-3 cursor-pointer"
|
||||
@click="onCopyLink"
|
||||
>
|
||||
<i
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
}}
|
||||
</h2>
|
||||
<button
|
||||
class="cursor-pointer rounded-sm border-none bg-transparent p-0 text-muted-foreground transition-colors hover:text-base-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-secondary-foreground"
|
||||
class="focus-visible:ring-secondary-foreground cursor-pointer rounded-sm border-none bg-transparent p-0 text-muted-foreground transition-colors hover:text-base-foreground focus-visible:ring-1 focus-visible:outline-none"
|
||||
:aria-label="$t('g.close')"
|
||||
@click="onDismiss"
|
||||
>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
{{ $t('workspacePanel.leaveDialog.title') }}
|
||||
</h2>
|
||||
<button
|
||||
class="cursor-pointer rounded-sm border-none bg-transparent p-0 text-muted-foreground transition-colors hover:text-base-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-secondary-foreground"
|
||||
class="focus-visible:ring-secondary-foreground cursor-pointer rounded-sm border-none bg-transparent p-0 text-muted-foreground transition-colors hover:text-base-foreground focus-visible:ring-1 focus-visible:outline-none"
|
||||
:aria-label="$t('g.close')"
|
||||
@click="onCancel"
|
||||
>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
{{ $t('workspacePanel.removeMemberDialog.title') }}
|
||||
</h2>
|
||||
<button
|
||||
class="cursor-pointer rounded-sm border-none bg-transparent p-0 text-muted-foreground transition-colors hover:text-base-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-secondary-foreground"
|
||||
class="focus-visible:ring-secondary-foreground cursor-pointer rounded-sm border-none bg-transparent p-0 text-muted-foreground transition-colors hover:text-base-foreground focus-visible:ring-1 focus-visible:outline-none"
|
||||
:aria-label="$t('g.close')"
|
||||
@click="onCancel"
|
||||
>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
{{ $t('workspacePanel.revokeInviteDialog.title') }}
|
||||
</h2>
|
||||
<button
|
||||
class="cursor-pointer rounded-sm border-none bg-transparent p-0 text-muted-foreground transition-colors hover:text-base-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-secondary-foreground"
|
||||
class="focus-visible:ring-secondary-foreground cursor-pointer rounded-sm border-none bg-transparent p-0 text-muted-foreground transition-colors hover:text-base-foreground focus-visible:ring-1 focus-visible:outline-none"
|
||||
:aria-label="$t('g.close')"
|
||||
@click="onCancel"
|
||||
>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="grow overflow-auto pt-6">
|
||||
<div
|
||||
class="flex size-full flex-col gap-2 rounded-2xl border border-interface-stroke border-inter p-6"
|
||||
class="border-inter flex size-full flex-col gap-2 rounded-2xl border border-interface-stroke p-6"
|
||||
>
|
||||
<!-- Section Header -->
|
||||
<div class="flex w-full items-center gap-9">
|
||||
@@ -153,7 +153,7 @@
|
||||
</span>
|
||||
<span
|
||||
v-if="uiConfig.showRoleBadge"
|
||||
class="text-[10px] font-bold uppercase text-base-background bg-base-foreground px-1 py-0.5 rounded-full"
|
||||
class="rounded-full bg-base-foreground px-1 py-0.5 text-[10px] font-bold text-base-background uppercase"
|
||||
>
|
||||
{{ $t('workspaceSwitcher.roleOwner') }}
|
||||
</span>
|
||||
@@ -202,7 +202,7 @@
|
||||
</span>
|
||||
<span
|
||||
v-if="uiConfig.showRoleBadge"
|
||||
class="text-[10px] font-bold uppercase text-base-background bg-base-foreground px-1 py-0.5 rounded-full"
|
||||
class="rounded-full bg-base-foreground px-1 py-0.5 text-[10px] font-bold text-base-background uppercase"
|
||||
>
|
||||
{{ getRoleBadgeLabel(member.role) }}
|
||||
</span>
|
||||
@@ -215,7 +215,7 @@
|
||||
<!-- Join date -->
|
||||
<span
|
||||
v-if="uiConfig.showDateColumn && !isSingleSeatPlan"
|
||||
class="text-sm text-muted-foreground text-right"
|
||||
class="text-right text-sm text-muted-foreground"
|
||||
>
|
||||
{{ formatDate(member.joinDate) }}
|
||||
</span>
|
||||
@@ -248,9 +248,9 @@
|
||||
<!-- Upsell Banner -->
|
||||
<div
|
||||
v-if="isSingleSeatPlan"
|
||||
class="flex items-center gap-2 rounded-xl border bg-secondary-background border-border-default px-4 py-3 mt-4 justify-center"
|
||||
class="mt-4 flex items-center justify-center gap-2 rounded-xl border border-border-default bg-secondary-background px-4 py-3"
|
||||
>
|
||||
<p class="m-0 text-sm text-foreground">
|
||||
<p class="text-foreground m-0 text-sm">
|
||||
{{
|
||||
isActiveSubscription
|
||||
? $t('workspacePanel.members.upsellBannerUpgrade')
|
||||
@@ -259,7 +259,7 @@
|
||||
</p>
|
||||
<Button
|
||||
variant="muted-textonly"
|
||||
class="cursor-pointer underline text-sm"
|
||||
class="cursor-pointer text-sm underline"
|
||||
@click="showSubscriptionDialog()"
|
||||
>
|
||||
{{ $t('workspacePanel.members.viewPlans') }}
|
||||
@@ -351,7 +351,7 @@
|
||||
{{ $t('workspacePanel.members.personalWorkspaceMessage') }}
|
||||
</p>
|
||||
<button
|
||||
class="underline bg-transparent border-none cursor-pointer"
|
||||
class="cursor-pointer border-none bg-transparent underline"
|
||||
@click="handleCreateWorkspace"
|
||||
>
|
||||
{{ $t('workspacePanel.members.createNewWorkspace') }}
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
:class="
|
||||
!isSingleSeatPlan &&
|
||||
isInviteLimitReached &&
|
||||
'opacity-50 cursor-not-allowed'
|
||||
'cursor-not-allowed opacity-50'
|
||||
"
|
||||
:aria-label="$t('workspacePanel.inviteMember')"
|
||||
@click="handleInviteMember"
|
||||
@@ -82,7 +82,7 @@
|
||||
:disabled="!!item.disabled"
|
||||
:class="
|
||||
cn(
|
||||
'flex w-full items-center gap-2 px-3 py-2 bg-transparent border-none cursor-pointer',
|
||||
'flex w-full cursor-pointer items-center gap-2 border-none bg-transparent px-3 py-2',
|
||||
item.class,
|
||||
item.disabled && 'pointer-events-auto cursor-not-allowed'
|
||||
)
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<Toast group="invite-accepted" position="top-right">
|
||||
<template #message="slotProps">
|
||||
<div class="flex items-center gap-2 justify-between w-full">
|
||||
<div class="flex w-full items-center justify-between gap-2">
|
||||
<div class="flex flex-col justify-start">
|
||||
<div class="text-base">
|
||||
{{ slotProps.message.summary }}
|
||||
</div>
|
||||
<div class="mt-1 text-sm text-foreground">
|
||||
<div class="text-foreground mt-1 text-sm">
|
||||
{{ slotProps.message.detail.text }} <br />
|
||||
{{ slotProps.message.detail.workspaceName }}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user