Component: The Rest of the PrimeVue buttons (#7649)
## Summary Automated initial change, cleaned up manually. Please check the screenshot changes. Includes a11y updates to icon buttons. Doesn't hit the buttons in Desktop. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-7649-WIP-Component-The-Rest-of-the-PrimeVue-buttons-2ce6d73d365081d68e06f200f1321267) by [Unito](https://www.unito.io) --------- Co-authored-by: GitHub Action <action@github.com> Co-authored-by: github-actions <github-actions@github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@@ -110,16 +110,18 @@ type KeysOfType<T, Match> = {
|
|||||||
}[keyof T]
|
}[keyof T]
|
||||||
|
|
||||||
class ConfirmDialog {
|
class ConfirmDialog {
|
||||||
|
private readonly root: Locator
|
||||||
public readonly delete: Locator
|
public readonly delete: Locator
|
||||||
public readonly overwrite: Locator
|
public readonly overwrite: Locator
|
||||||
public readonly reject: Locator
|
public readonly reject: Locator
|
||||||
public readonly confirm: Locator
|
public readonly confirm: Locator
|
||||||
|
|
||||||
constructor(public readonly page: Page) {
|
constructor(public readonly page: Page) {
|
||||||
this.delete = page.locator('button.p-button[aria-label="Delete"]')
|
this.root = page.getByRole('dialog')
|
||||||
this.overwrite = page.locator('button.p-button[aria-label="Overwrite"]')
|
this.delete = this.root.getByRole('button', { name: 'Delete' })
|
||||||
this.reject = page.locator('button.p-button[aria-label="Cancel"]')
|
this.overwrite = this.root.getByRole('button', { name: 'Overwrite' })
|
||||||
this.confirm = page.locator('button.p-button[aria-label="Confirm"]')
|
this.reject = this.root.getByRole('button', { name: 'Cancel' })
|
||||||
|
this.confirm = this.root.getByRole('button', { name: 'Confirm' })
|
||||||
}
|
}
|
||||||
|
|
||||||
async click(locator: KeysOfType<ConfirmDialog, Locator>) {
|
async click(locator: KeysOfType<ConfirmDialog, Locator>) {
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ export class ComfyNodeSearchFilterSelectionPanel {
|
|||||||
async addFilter(filterValue: string, filterType: string) {
|
async addFilter(filterValue: string, filterType: string) {
|
||||||
await this.selectFilterType(filterType)
|
await this.selectFilterType(filterType)
|
||||||
await this.selectFilterValue(filterValue)
|
await this.selectFilterValue(filterValue)
|
||||||
await this.page.locator('.p-button-label:has-text("Add")').click()
|
await this.page.locator('button:has-text("Add")').click()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -85,11 +85,11 @@ test.describe('Missing models warning', () => {
|
|||||||
const missingModelsWarning = comfyPage.page.locator('.comfy-missing-models')
|
const missingModelsWarning = comfyPage.page.locator('.comfy-missing-models')
|
||||||
await expect(missingModelsWarning).toBeVisible()
|
await expect(missingModelsWarning).toBeVisible()
|
||||||
|
|
||||||
const downloadButton = missingModelsWarning.getByLabel('Download')
|
const downloadButton = missingModelsWarning.getByText('Download')
|
||||||
await expect(downloadButton).toBeVisible()
|
await expect(downloadButton).toBeVisible()
|
||||||
|
|
||||||
// Check that the copy URL button is also visible for Desktop environment
|
// Check that the copy URL button is also visible for Desktop environment
|
||||||
const copyUrlButton = missingModelsWarning.getByLabel('Copy URL')
|
const copyUrlButton = missingModelsWarning.getByText('Copy URL')
|
||||||
await expect(copyUrlButton).toBeVisible()
|
await expect(copyUrlButton).toBeVisible()
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -102,11 +102,11 @@ test.describe('Missing models warning', () => {
|
|||||||
const missingModelsWarning = comfyPage.page.locator('.comfy-missing-models')
|
const missingModelsWarning = comfyPage.page.locator('.comfy-missing-models')
|
||||||
await expect(missingModelsWarning).toBeVisible()
|
await expect(missingModelsWarning).toBeVisible()
|
||||||
|
|
||||||
const downloadButton = missingModelsWarning.getByLabel('Download')
|
const downloadButton = missingModelsWarning.getByText('Download')
|
||||||
await expect(downloadButton).toBeVisible()
|
await expect(downloadButton).toBeVisible()
|
||||||
|
|
||||||
// Check that the copy URL button is also visible for Desktop environment
|
// Check that the copy URL button is also visible for Desktop environment
|
||||||
const copyUrlButton = missingModelsWarning.getByLabel('Copy URL')
|
const copyUrlButton = missingModelsWarning.getByText('Copy URL')
|
||||||
await expect(copyUrlButton).toBeVisible()
|
await expect(copyUrlButton).toBeVisible()
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -176,7 +176,7 @@ test.describe('Missing models warning', () => {
|
|||||||
const missingModelsWarning = comfyPage.page.locator('.comfy-missing-models')
|
const missingModelsWarning = comfyPage.page.locator('.comfy-missing-models')
|
||||||
await expect(missingModelsWarning).toBeVisible()
|
await expect(missingModelsWarning).toBeVisible()
|
||||||
|
|
||||||
const downloadButton = comfyPage.page.getByLabel('Download')
|
const downloadButton = comfyPage.page.getByText('Download')
|
||||||
await expect(downloadButton).toBeVisible()
|
await expect(downloadButton).toBeVisible()
|
||||||
const downloadPromise = comfyPage.page.waitForEvent('download')
|
const downloadPromise = comfyPage.page.waitForEvent('download')
|
||||||
await downloadButton.click()
|
await downloadButton.click()
|
||||||
@@ -290,7 +290,7 @@ test.describe('Settings', () => {
|
|||||||
// Save keybinding
|
// Save keybinding
|
||||||
const saveButton = comfyPage.page
|
const saveButton = comfyPage.page
|
||||||
.getByLabel('New Blank Workflow')
|
.getByLabel('New Blank Workflow')
|
||||||
.getByLabel('Save')
|
.getByText('Save')
|
||||||
await saveButton.click()
|
await saveButton.click()
|
||||||
|
|
||||||
const request = await requestPromise
|
const request = await requestPromise
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 86 KiB After Width: | Height: | Size: 80 KiB |
|
Before Width: | Height: | Size: 100 KiB After Width: | Height: | Size: 95 KiB |
|
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 8.7 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 20 KiB |
@@ -123,8 +123,7 @@ test.describe('Node Help', () => {
|
|||||||
await expect(helpPage).toContainText('KSampler')
|
await expect(helpPage).toContainText('KSampler')
|
||||||
|
|
||||||
// Click the back button - use a more specific selector
|
// Click the back button - use a more specific selector
|
||||||
const backButton = comfyPage.page.locator('button:has(.pi-arrow-left)')
|
const backButton = helpPage.getByRole('button', { name: /back/i })
|
||||||
await expect(backButton).toBeVisible()
|
|
||||||
await backButton.click()
|
await backButton.click()
|
||||||
|
|
||||||
// Verify that we're back to the node library view
|
// Verify that we're back to the node library view
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 95 KiB |
|
Before Width: | Height: | Size: 97 KiB After Width: | Height: | Size: 97 KiB |
|
Before Width: | Height: | Size: 100 KiB After Width: | Height: | Size: 93 KiB |
@@ -100,7 +100,7 @@ test.describe('Node library sidebar', () => {
|
|||||||
const tab = comfyPage.menu.nodeLibraryTab
|
const tab = comfyPage.menu.nodeLibraryTab
|
||||||
|
|
||||||
await tab.getFolder('foo').click({ button: 'right' })
|
await tab.getFolder('foo').click({ button: 'right' })
|
||||||
await comfyPage.page.getByLabel('New Folder').click()
|
await comfyPage.page.getByRole('menuitem', { name: 'New Folder' }).click()
|
||||||
const textInput = comfyPage.page.locator('.editable-text input')
|
const textInput = comfyPage.page.locator('.editable-text input')
|
||||||
await textInput.waitFor({ state: 'visible' })
|
await textInput.waitFor({ state: 'visible' })
|
||||||
await textInput.fill('bar')
|
await textInput.fill('bar')
|
||||||
@@ -203,7 +203,7 @@ test.describe('Node library sidebar', () => {
|
|||||||
await comfyPage.page
|
await comfyPage.page
|
||||||
.locator('.color-field .p-selectbutton > *:nth-child(2)')
|
.locator('.color-field .p-selectbutton > *:nth-child(2)')
|
||||||
.click()
|
.click()
|
||||||
await comfyPage.page.getByLabel('Confirm').click()
|
await comfyPage.page.getByRole('button', { name: 'Confirm' }).click()
|
||||||
await comfyPage.nextFrame()
|
await comfyPage.nextFrame()
|
||||||
expect(
|
expect(
|
||||||
await comfyPage.getSetting('Comfy.NodeLibrary.BookmarksCustomization')
|
await comfyPage.getSetting('Comfy.NodeLibrary.BookmarksCustomization')
|
||||||
@@ -223,7 +223,7 @@ test.describe('Node library sidebar', () => {
|
|||||||
await comfyPage.page
|
await comfyPage.page
|
||||||
.locator('.icon-field .p-selectbutton > *:nth-child(2)')
|
.locator('.icon-field .p-selectbutton > *:nth-child(2)')
|
||||||
.click()
|
.click()
|
||||||
await comfyPage.page.getByLabel('Confirm').click()
|
await comfyPage.page.getByRole('button', { name: 'Confirm' }).click()
|
||||||
await comfyPage.nextFrame()
|
await comfyPage.nextFrame()
|
||||||
expect(
|
expect(
|
||||||
await comfyPage.getSetting('Comfy.NodeLibrary.BookmarksCustomization')
|
await comfyPage.getSetting('Comfy.NodeLibrary.BookmarksCustomization')
|
||||||
@@ -261,7 +261,7 @@ test.describe('Node library sidebar', () => {
|
|||||||
await comfyPage.page
|
await comfyPage.page
|
||||||
.locator('.icon-field .p-selectbutton > *:nth-child(2)')
|
.locator('.icon-field .p-selectbutton > *:nth-child(2)')
|
||||||
.click()
|
.click()
|
||||||
await comfyPage.page.getByLabel('Confirm').click()
|
await comfyPage.page.getByRole('button', { name: 'Confirm' }).click()
|
||||||
await comfyPage.nextFrame()
|
await comfyPage.nextFrame()
|
||||||
|
|
||||||
// Verify the color selection is saved
|
// Verify the color selection is saved
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 75 KiB |
|
Before Width: | Height: | Size: 115 KiB After Width: | Height: | Size: 114 KiB |
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 59 KiB |
|
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 98 KiB After Width: | Height: | Size: 98 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 109 KiB After Width: | Height: | Size: 109 KiB |
|
Before Width: | Height: | Size: 109 KiB After Width: | Height: | Size: 108 KiB |
|
Before Width: | Height: | Size: 139 KiB After Width: | Height: | Size: 139 KiB |
|
Before Width: | Height: | Size: 140 KiB After Width: | Height: | Size: 140 KiB |
|
Before Width: | Height: | Size: 109 KiB After Width: | Height: | Size: 108 KiB |
|
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 84 KiB |
@@ -5,23 +5,23 @@
|
|||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
v-tooltip="{ value: $t('menu.showMenu'), showDelay: 300 }"
|
v-tooltip="{ value: $t('menu.showMenu'), showDelay: 300 }"
|
||||||
icon="pi pi-bars"
|
variant="muted-textonly"
|
||||||
severity="secondary"
|
size="lg"
|
||||||
text
|
|
||||||
size="large"
|
|
||||||
:aria-label="$t('menu.showMenu')"
|
:aria-label="$t('menu.showMenu')"
|
||||||
aria-live="assertive"
|
aria-live="assertive"
|
||||||
@click="exitFocusMode"
|
@click="exitFocusMode"
|
||||||
@contextmenu="showNativeSystemMenu"
|
@contextmenu="showNativeSystemMenu"
|
||||||
/>
|
>
|
||||||
|
<i class="pi pi-bars" />
|
||||||
|
</Button>
|
||||||
<div class="window-actions-spacer" />
|
<div class="window-actions-spacer" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
|
||||||
import { watchEffect } from 'vue'
|
import { watchEffect } from 'vue'
|
||||||
|
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import { useSettingStore } from '@/platform/settings/settingStore'
|
import { useSettingStore } from '@/platform/settings/settingStore'
|
||||||
import { app } from '@/scripts/app'
|
import { app } from '@/scripts/app'
|
||||||
import { useWorkspaceStore } from '@/stores/workspaceStore'
|
import { useWorkspaceStore } from '@/stores/workspaceStore'
|
||||||
|
|||||||
@@ -22,12 +22,13 @@
|
|||||||
value: item.tooltip,
|
value: item.tooltip,
|
||||||
showDelay: 600
|
showDelay: 600
|
||||||
}"
|
}"
|
||||||
:label="String(item.label ?? '')"
|
:variant="item.key === queueMode ? 'primary' : 'secondary'"
|
||||||
:icon="item.icon"
|
size="sm"
|
||||||
:severity="item.key === queueMode ? 'primary' : 'secondary'"
|
class="w-full justify-start"
|
||||||
size="small"
|
>
|
||||||
text
|
<i v-if="item.icon" :class="item.icon" />
|
||||||
/>
|
{{ String(item.label ?? '') }}
|
||||||
|
</Button>
|
||||||
</template>
|
</template>
|
||||||
</SplitButton>
|
</SplitButton>
|
||||||
<BatchCountEdit />
|
<BatchCountEdit />
|
||||||
@@ -36,12 +37,12 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
import Button from 'primevue/button'
|
|
||||||
import type { MenuItem } from 'primevue/menuitem'
|
import type { MenuItem } from 'primevue/menuitem'
|
||||||
import SplitButton from 'primevue/splitbutton'
|
import SplitButton from 'primevue/splitbutton'
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import { isCloud } from '@/platform/distribution/types'
|
import { isCloud } from '@/platform/distribution/types'
|
||||||
import { useTelemetry } from '@/platform/telemetry'
|
import { useTelemetry } from '@/platform/telemetry'
|
||||||
import { app } from '@/scripts/app'
|
import { app } from '@/scripts/app'
|
||||||
|
|||||||
@@ -46,21 +46,22 @@
|
|||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<Button
|
<Button
|
||||||
v-if="isShortcutsTabActive"
|
v-if="isShortcutsTabActive"
|
||||||
:label="$t('shortcuts.manageShortcuts')"
|
variant="muted-textonly"
|
||||||
icon="pi pi-cog"
|
size="sm"
|
||||||
severity="secondary"
|
|
||||||
size="small"
|
|
||||||
text
|
|
||||||
@click="openKeybindingSettings"
|
@click="openKeybindingSettings"
|
||||||
/>
|
>
|
||||||
|
<i class="pi pi-cog" />
|
||||||
|
{{ $t('shortcuts.manageShortcuts') }}
|
||||||
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
class="justify-self-end"
|
class="justify-self-end"
|
||||||
icon="pi pi-times"
|
variant="muted-textonly"
|
||||||
severity="secondary"
|
size="sm"
|
||||||
size="small"
|
:aria-label="t('g.close')"
|
||||||
text
|
|
||||||
@click="closeBottomPanel"
|
@click="closeBottomPanel"
|
||||||
/>
|
>
|
||||||
|
<i class="pi pi-times" />
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</TabList>
|
</TabList>
|
||||||
@@ -79,7 +80,6 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
|
||||||
import Tab from 'primevue/tab'
|
import Tab from 'primevue/tab'
|
||||||
import type { TabPassThroughMethodOptions } from 'primevue/tab'
|
import type { TabPassThroughMethodOptions } from 'primevue/tab'
|
||||||
import TabList from 'primevue/tablist'
|
import TabList from 'primevue/tablist'
|
||||||
@@ -88,6 +88,7 @@ import { computed } from 'vue'
|
|||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
import ExtensionSlot from '@/components/common/ExtensionSlot.vue'
|
import ExtensionSlot from '@/components/common/ExtensionSlot.vue'
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import { useDialogService } from '@/services/dialogService'
|
import { useDialogService } from '@/services/dialogService'
|
||||||
import { useBottomPanelStore } from '@/stores/workspace/bottomPanelStore'
|
import { useBottomPanelStore } from '@/stores/workspace/bottomPanelStore'
|
||||||
import type { BottomPanelExtension } from '@/types/extensionTypes'
|
import type { BottomPanelExtension } from '@/types/extensionTypes'
|
||||||
|
|||||||
@@ -11,9 +11,8 @@
|
|||||||
value: tooltipText,
|
value: tooltipText,
|
||||||
showDelay: 300
|
showDelay: 300
|
||||||
}"
|
}"
|
||||||
icon="pi pi-copy"
|
variant="secondary"
|
||||||
severity="secondary"
|
size="sm"
|
||||||
size="small"
|
|
||||||
:class="
|
:class="
|
||||||
cn('absolute top-2 right-8 transition-opacity', {
|
cn('absolute top-2 right-8 transition-opacity', {
|
||||||
'opacity-0 pointer-events-none select-none': !isHovered
|
'opacity-0 pointer-events-none select-none': !isHovered
|
||||||
@@ -21,18 +20,20 @@
|
|||||||
"
|
"
|
||||||
:aria-label="tooltipText"
|
:aria-label="tooltipText"
|
||||||
@click="handleCopy"
|
@click="handleCopy"
|
||||||
/>
|
>
|
||||||
|
<i class="pi pi-copy" />
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useElementHover, useEventListener } from '@vueuse/core'
|
import { useElementHover, useEventListener } from '@vueuse/core'
|
||||||
import type { IDisposable } from '@xterm/xterm'
|
import type { IDisposable } from '@xterm/xterm'
|
||||||
import Button from 'primevue/button'
|
|
||||||
import type { Ref } from 'vue'
|
import type { Ref } from 'vue'
|
||||||
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import { useTerminal } from '@/composables/bottomPanelTabs/useTerminal'
|
import { useTerminal } from '@/composables/bottomPanelTabs/useTerminal'
|
||||||
import { electronAPI, isElectron } from '@/utils/envUtil'
|
import { electronAPI, isElectron } from '@/utils/envUtil'
|
||||||
import { cn } from '@/utils/tailwindUtil'
|
import { cn } from '@/utils/tailwindUtil'
|
||||||
|
|||||||
@@ -7,20 +7,24 @@
|
|||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
v-tooltip="$t('g.upload')"
|
v-tooltip="$t('g.upload')"
|
||||||
:icon="isUploading ? 'pi pi-spin pi-spinner' : 'pi pi-upload'"
|
variant="secondary"
|
||||||
size="small"
|
size="sm"
|
||||||
|
:aria-label="$t('g.upload')"
|
||||||
:disabled="isUploading"
|
:disabled="isUploading"
|
||||||
@click="triggerFileInput"
|
@click="triggerFileInput"
|
||||||
/>
|
>
|
||||||
|
<i :class="isUploading ? 'pi pi-spin pi-spinner' : 'pi pi-upload'" />
|
||||||
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
v-tooltip="$t('g.clear')"
|
v-tooltip="$t('g.clear')"
|
||||||
outlined
|
variant="destructive"
|
||||||
icon="pi pi-trash"
|
size="sm"
|
||||||
severity="danger"
|
:aria-label="$t('g.clear')"
|
||||||
size="small"
|
|
||||||
:disabled="!modelValue"
|
:disabled="!modelValue"
|
||||||
@click="clearImage"
|
@click="clearImage"
|
||||||
/>
|
>
|
||||||
|
<i class="pi pi-trash" />
|
||||||
|
</Button>
|
||||||
<input
|
<input
|
||||||
ref="fileInput"
|
ref="fileInput"
|
||||||
type="file"
|
type="file"
|
||||||
@@ -32,10 +36,10 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
|
||||||
import InputText from 'primevue/inputtext'
|
import InputText from 'primevue/inputtext'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import { useToastStore } from '@/platform/updates/common/toastStore'
|
import { useToastStore } from '@/platform/updates/common/toastStore'
|
||||||
import { api } from '@/scripts/api'
|
import { api } from '@/scripts/api'
|
||||||
|
|
||||||
|
|||||||
@@ -27,24 +27,19 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<Button
|
<Button variant="textonly" @click="resetCustomization">
|
||||||
:label="$t('g.reset')"
|
<i class="pi pi-refresh" />
|
||||||
icon="pi pi-refresh"
|
{{ $t('g.reset') }}
|
||||||
class="p-button-text"
|
</Button>
|
||||||
@click="resetCustomization"
|
<Button autofocus @click="confirmCustomization">
|
||||||
/>
|
<i class="pi pi-check" />
|
||||||
<Button
|
{{ $t('g.confirm') }}
|
||||||
:label="$t('g.confirm')"
|
</Button>
|
||||||
icon="pi pi-check"
|
|
||||||
autofocus
|
|
||||||
@click="confirmCustomization"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
|
||||||
import Dialog from 'primevue/dialog'
|
import Dialog from 'primevue/dialog'
|
||||||
import Divider from 'primevue/divider'
|
import Divider from 'primevue/divider'
|
||||||
import SelectButton from 'primevue/selectbutton'
|
import SelectButton from 'primevue/selectbutton'
|
||||||
@@ -52,6 +47,7 @@ import { computed, ref, watch } from 'vue'
|
|||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
import ColorCustomizationSelector from '@/components/common/ColorCustomizationSelector.vue'
|
import ColorCustomizationSelector from '@/components/common/ColorCustomizationSelector.vue'
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import { useNodeBookmarkStore } from '@/stores/nodeBookmarkStore'
|
import { useNodeBookmarkStore } from '@/stores/nodeBookmarkStore'
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
|||||||
@@ -16,20 +16,22 @@
|
|||||||
<Button
|
<Button
|
||||||
v-if="status === null || status === 'error'"
|
v-if="status === null || status === 'error'"
|
||||||
class="file-action-button"
|
class="file-action-button"
|
||||||
:label="$t('g.download') + ' (' + fileSize + ')'"
|
variant="secondary"
|
||||||
size="small"
|
size="sm"
|
||||||
outlined
|
|
||||||
:disabled="!!props.error"
|
:disabled="!!props.error"
|
||||||
icon="pi pi-download"
|
|
||||||
@click="triggerDownload"
|
@click="triggerDownload"
|
||||||
/>
|
>
|
||||||
|
<i class="pi pi-download" />
|
||||||
|
{{ $t('g.download') + ' (' + fileSize + ')' }}
|
||||||
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
v-if="(status === null || status === 'error') && !!props.url"
|
v-if="(status === null || status === 'error') && !!props.url"
|
||||||
:label="$t('g.copyURL')"
|
variant="secondary"
|
||||||
size="small"
|
size="sm"
|
||||||
outlined
|
|
||||||
@click="copyURL"
|
@click="copyURL"
|
||||||
/>
|
>
|
||||||
|
{{ $t('g.copyURL') }}
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@@ -49,44 +51,48 @@
|
|||||||
v-if="status === 'in_progress'"
|
v-if="status === 'in_progress'"
|
||||||
v-tooltip.top="t('electronFileDownload.pause')"
|
v-tooltip.top="t('electronFileDownload.pause')"
|
||||||
class="file-action-button"
|
class="file-action-button"
|
||||||
size="small"
|
variant="secondary"
|
||||||
outlined
|
size="sm"
|
||||||
:disabled="!!props.error"
|
:disabled="!!props.error"
|
||||||
icon="pi pi-pause-circle"
|
|
||||||
@click="triggerPauseDownload"
|
@click="triggerPauseDownload"
|
||||||
/>
|
>
|
||||||
|
<i class="pi pi-pause-circle" />
|
||||||
|
</Button>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
v-if="status === 'paused'"
|
v-if="status === 'paused'"
|
||||||
v-tooltip.top="t('electronFileDownload.resume')"
|
v-tooltip.top="t('electronFileDownload.resume')"
|
||||||
class="file-action-button"
|
class="file-action-button"
|
||||||
size="small"
|
variant="secondary"
|
||||||
outlined
|
size="sm"
|
||||||
|
:aria-label="t('electronFileDownload.resume')"
|
||||||
:disabled="!!props.error"
|
:disabled="!!props.error"
|
||||||
icon="pi pi-play-circle"
|
|
||||||
@click="triggerResumeDownload"
|
@click="triggerResumeDownload"
|
||||||
/>
|
>
|
||||||
|
<i class="pi pi-play-circle" />
|
||||||
|
</Button>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
v-tooltip.top="t('electronFileDownload.cancel')"
|
v-tooltip.top="t('electronFileDownload.cancel')"
|
||||||
class="file-action-button"
|
class="file-action-button"
|
||||||
size="small"
|
variant="destructive"
|
||||||
outlined
|
size="sm"
|
||||||
|
:aria-label="t('electronFileDownload.cancel')"
|
||||||
:disabled="!!props.error"
|
:disabled="!!props.error"
|
||||||
icon="pi pi-times-circle"
|
|
||||||
severity="danger"
|
|
||||||
@click="triggerCancelDownload"
|
@click="triggerCancelDownload"
|
||||||
/>
|
>
|
||||||
|
<i class="pi pi-times-circle" />
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
|
||||||
import ProgressBar from 'primevue/progressbar'
|
import ProgressBar from 'primevue/progressbar'
|
||||||
import { computed, ref } from 'vue'
|
import { computed, ref } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import { useCopyToClipboard } from '@/composables/useCopyToClipboard'
|
import { useCopyToClipboard } from '@/composables/useCopyToClipboard'
|
||||||
import { useDownload } from '@/composables/useDownload'
|
import { useDownload } from '@/composables/useDownload'
|
||||||
import { useElectronDownloadStore } from '@/stores/electronDownloadStore'
|
import { useElectronDownloadStore } from '@/stores/electronDownloadStore'
|
||||||
|
|||||||
@@ -22,31 +22,27 @@
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Button
|
<Button
|
||||||
:label="$t('g.download') + ' (' + fileSize + ')'"
|
variant="secondary"
|
||||||
size="small"
|
|
||||||
outlined
|
|
||||||
:disabled="!!props.error"
|
:disabled="!!props.error"
|
||||||
:title="props.url"
|
:title="props.url"
|
||||||
@click="download.triggerBrowserDownload"
|
@click="download.triggerBrowserDownload"
|
||||||
/>
|
>
|
||||||
|
{{ $t('g.download') + ' (' + fileSize + ')' }}
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Button
|
<Button variant="secondary" :disabled="!!props.error" @click="copyURL">
|
||||||
:label="$t('g.copyURL')"
|
{{ $t('g.copyURL') }}
|
||||||
size="small"
|
</Button>
|
||||||
outlined
|
|
||||||
:disabled="!!props.error"
|
|
||||||
@click="copyURL"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
|
||||||
import Message from 'primevue/message'
|
import Message from 'primevue/message'
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
|
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import { useCopyToClipboard } from '@/composables/useCopyToClipboard'
|
import { useCopyToClipboard } from '@/composables/useCopyToClipboard'
|
||||||
import { useDownload } from '@/composables/useDownload'
|
import { useDownload } from '@/composables/useDownload'
|
||||||
import { formatSize } from '@/utils/formatUtil'
|
import { formatSize } from '@/utils/formatUtil'
|
||||||
|
|||||||
@@ -14,21 +14,20 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
<Button
|
<Button size="sm" @click="triggerFileInput">
|
||||||
icon="pi pi-upload"
|
<i class="pi pi-upload" />
|
||||||
:label="$t('g.upload')"
|
{{ $t('g.upload') }}
|
||||||
size="small"
|
</Button>
|
||||||
@click="triggerFileInput"
|
|
||||||
/>
|
|
||||||
<Button
|
<Button
|
||||||
v-if="modelValue"
|
v-if="modelValue"
|
||||||
class="w-full"
|
class="w-full"
|
||||||
outlined
|
variant="destructive"
|
||||||
icon="pi pi-trash"
|
size="sm"
|
||||||
severity="danger"
|
:aria-label="$t('g.delete')"
|
||||||
size="small"
|
|
||||||
@click="clearImage"
|
@click="clearImage"
|
||||||
/>
|
>
|
||||||
|
<i class="pi pi-trash" />
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<input
|
<input
|
||||||
@@ -42,9 +41,10 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
modelValue: string
|
modelValue: string
|
||||||
}>()
|
}>()
|
||||||
|
|||||||
@@ -10,10 +10,11 @@
|
|||||||
</p>
|
</p>
|
||||||
<Button
|
<Button
|
||||||
v-if="buttonLabel"
|
v-if="buttonLabel"
|
||||||
:label="buttonLabel"
|
variant="textonly"
|
||||||
class="p-button-text"
|
|
||||||
@click="$emit('action')"
|
@click="$emit('action')"
|
||||||
/>
|
>
|
||||||
|
{{ buttonLabel }}
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</Card>
|
</Card>
|
||||||
@@ -21,9 +22,10 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
|
||||||
import Card from 'primevue/card'
|
import Card from 'primevue/card'
|
||||||
|
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
class?: string
|
class?: string
|
||||||
icon?: string
|
icon?: string
|
||||||
|
|||||||
@@ -11,24 +11,25 @@
|
|||||||
<ApiNodesList :node-names="apiNodeNames" />
|
<ApiNodesList :node-names="apiNodeNames" />
|
||||||
|
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<Button :label="t('g.learnMore')" link @click="handleLearnMoreClick" />
|
<Button variant="textonly" @click="handleLearnMoreClick">
|
||||||
|
{{ t('g.learnMore') }}
|
||||||
|
</Button>
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
<Button
|
<Button variant="secondary" @click="onCancel?.()">
|
||||||
:label="t('g.cancel')"
|
{{ t('g.cancel') }}
|
||||||
outlined
|
</Button>
|
||||||
severity="secondary"
|
<Button @click="onLogin?.()">
|
||||||
@click="onCancel?.()"
|
{{ t('g.login') }}
|
||||||
/>
|
</Button>
|
||||||
<Button :label="t('g.login')" @click="onLogin?.()" />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import { useExternalLink } from '@/composables/useExternalLink'
|
import { useExternalLink } from '@/composables/useExternalLink'
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
|||||||
@@ -31,69 +31,64 @@
|
|||||||
}}</label>
|
}}</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Button
|
<Button variant="secondary" autofocus @click="onCancel">
|
||||||
:label="$t('g.cancel')"
|
<i class="pi pi-undo" />
|
||||||
icon="pi pi-undo"
|
{{ $t('g.cancel') }}
|
||||||
severity="secondary"
|
</Button>
|
||||||
autofocus
|
<Button v-if="type === 'default'" variant="primary" @click="onConfirm">
|
||||||
@click="onCancel"
|
<i class="pi pi-check" />
|
||||||
/>
|
{{ $t('g.confirm') }}
|
||||||
<Button
|
</Button>
|
||||||
v-if="type === 'default'"
|
|
||||||
:label="$t('g.confirm')"
|
|
||||||
severity="primary"
|
|
||||||
icon="pi pi-check"
|
|
||||||
@click="onConfirm"
|
|
||||||
/>
|
|
||||||
<Button
|
<Button
|
||||||
v-else-if="type === 'delete'"
|
v-else-if="type === 'delete'"
|
||||||
:label="$t('g.delete')"
|
variant="destructive"
|
||||||
severity="danger"
|
|
||||||
icon="pi pi-trash"
|
|
||||||
@click="onConfirm"
|
@click="onConfirm"
|
||||||
/>
|
>
|
||||||
|
<i class="pi pi-trash" />
|
||||||
|
{{ $t('g.delete') }}
|
||||||
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
v-else-if="type === 'overwrite' || type === 'overwriteBlueprint'"
|
v-else-if="type === 'overwrite' || type === 'overwriteBlueprint'"
|
||||||
:label="$t('g.overwrite')"
|
variant="destructive"
|
||||||
severity="warn"
|
|
||||||
icon="pi pi-save"
|
|
||||||
@click="onConfirm"
|
@click="onConfirm"
|
||||||
/>
|
>
|
||||||
|
<i class="pi pi-save" />
|
||||||
|
{{ $t('g.overwrite') }}
|
||||||
|
</Button>
|
||||||
<template v-else-if="type === 'dirtyClose'">
|
<template v-else-if="type === 'dirtyClose'">
|
||||||
<Button
|
<Button variant="secondary" @click="onDeny">
|
||||||
:label="$t('g.no')"
|
<i class="pi pi-times" />
|
||||||
severity="secondary"
|
{{ $t('g.no') }}
|
||||||
icon="pi pi-times"
|
</Button>
|
||||||
@click="onDeny"
|
<Button @click="onConfirm">
|
||||||
/>
|
<i class="pi pi-save" />
|
||||||
<Button :label="$t('g.save')" icon="pi pi-save" @click="onConfirm" />
|
{{ $t('g.save') }}
|
||||||
|
</Button>
|
||||||
</template>
|
</template>
|
||||||
<Button
|
<Button
|
||||||
v-else-if="type === 'reinstall'"
|
v-else-if="type === 'reinstall'"
|
||||||
:label="$t('desktopMenu.reinstall')"
|
variant="destructive"
|
||||||
severity="warn"
|
|
||||||
icon="pi pi-eraser"
|
|
||||||
@click="onConfirm"
|
@click="onConfirm"
|
||||||
/>
|
>
|
||||||
|
<i class="pi pi-eraser" />
|
||||||
|
{{ $t('desktopMenu.reinstall') }}
|
||||||
|
</Button>
|
||||||
<!-- Invalid - just show a close button. -->
|
<!-- Invalid - just show a close button. -->
|
||||||
<Button
|
<Button v-else variant="primary" @click="onCancel">
|
||||||
v-else
|
<i class="pi pi-times" />
|
||||||
:label="$t('g.close')"
|
{{ $t('g.close') }}
|
||||||
severity="primary"
|
</Button>
|
||||||
icon="pi pi-times"
|
|
||||||
@click="onCancel"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
|
||||||
import Checkbox from 'primevue/checkbox'
|
import Checkbox from 'primevue/checkbox'
|
||||||
import Message from 'primevue/message'
|
import Message from 'primevue/message'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import { useSettingStore } from '@/platform/settings/settingStore'
|
import { useSettingStore } from '@/platform/settings/settingStore'
|
||||||
import type { ConfirmationDialogType } from '@/services/dialogService'
|
import type { ConfirmationDialogType } from '@/services/dialogService'
|
||||||
import { useDialogStore } from '@/stores/dialogStore'
|
import { useDialogStore } from '@/stores/dialogStore'
|
||||||
|
|||||||
@@ -14,18 +14,16 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div class="flex justify-center gap-2">
|
<div class="flex justify-center gap-2">
|
||||||
|
<Button v-show="!reportOpen" variant="textonly" @click="showReport">
|
||||||
|
{{ $t('g.showReport') }}
|
||||||
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
v-show="!reportOpen"
|
v-show="!reportOpen"
|
||||||
text
|
variant="textonly"
|
||||||
:label="$t('g.showReport')"
|
|
||||||
@click="showReport"
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
v-show="!reportOpen"
|
|
||||||
text
|
|
||||||
:label="$t('issueReport.helpFix')"
|
|
||||||
@click="showContactSupport"
|
@click="showContactSupport"
|
||||||
/>
|
>
|
||||||
|
{{ $t('issueReport.helpFix') }}
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<template v-if="reportOpen">
|
<template v-if="reportOpen">
|
||||||
<Divider />
|
<Divider />
|
||||||
@@ -40,18 +38,15 @@
|
|||||||
:repo-owner="repoOwner"
|
:repo-owner="repoOwner"
|
||||||
:repo-name="repoName"
|
:repo-name="repoName"
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button v-if="reportOpen" @click="copyReportToClipboard">
|
||||||
v-if="reportOpen"
|
<i class="pi pi-copy" />
|
||||||
:label="$t('g.copyToClipboard')"
|
{{ $t('g.copyToClipboard') }}
|
||||||
icon="pi pi-copy"
|
</Button>
|
||||||
@click="copyReportToClipboard"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
|
||||||
import Divider from 'primevue/divider'
|
import Divider from 'primevue/divider'
|
||||||
import ScrollPanel from 'primevue/scrollpanel'
|
import ScrollPanel from 'primevue/scrollpanel'
|
||||||
import { useToast } from 'primevue/usetoast'
|
import { useToast } from 'primevue/usetoast'
|
||||||
@@ -60,6 +55,7 @@ import { useI18n } from 'vue-i18n'
|
|||||||
|
|
||||||
import NoResultsPlaceholder from '@/components/common/NoResultsPlaceholder.vue'
|
import NoResultsPlaceholder from '@/components/common/NoResultsPlaceholder.vue'
|
||||||
import FindIssueButton from '@/components/dialog/content/error/FindIssueButton.vue'
|
import FindIssueButton from '@/components/dialog/content/error/FindIssueButton.vue'
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import { useCopyToClipboard } from '@/composables/useCopyToClipboard'
|
import { useCopyToClipboard } from '@/composables/useCopyToClipboard'
|
||||||
import { useTelemetry } from '@/platform/telemetry'
|
import { useTelemetry } from '@/platform/telemetry'
|
||||||
import { api } from '@/scripts/api'
|
import { api } from '@/scripts/api'
|
||||||
|
|||||||
@@ -18,11 +18,11 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
|
||||||
import FloatLabel from 'primevue/floatlabel'
|
import FloatLabel from 'primevue/floatlabel'
|
||||||
import InputText from 'primevue/inputtext'
|
import InputText from 'primevue/inputtext'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import { useDialogStore } from '@/stores/dialogStore'
|
import { useDialogStore } from '@/stores/dialogStore'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
|
|||||||
@@ -51,8 +51,7 @@
|
|||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
class="h-10"
|
class="h-10"
|
||||||
severity="secondary"
|
variant="secondary"
|
||||||
outlined
|
|
||||||
@click="signInWithGoogle"
|
@click="signInWithGoogle"
|
||||||
>
|
>
|
||||||
<i class="pi pi-google mr-2"></i>
|
<i class="pi pi-google mr-2"></i>
|
||||||
@@ -66,8 +65,7 @@
|
|||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
class="h-10"
|
class="h-10"
|
||||||
severity="secondary"
|
variant="secondary"
|
||||||
outlined
|
|
||||||
@click="signInWithGithub"
|
@click="signInWithGithub"
|
||||||
>
|
>
|
||||||
<i class="pi pi-github mr-2"></i>
|
<i class="pi pi-github mr-2"></i>
|
||||||
@@ -82,8 +80,7 @@
|
|||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
class="h-10"
|
class="h-10"
|
||||||
severity="secondary"
|
variant="secondary"
|
||||||
outlined
|
|
||||||
@click="showApiKeyForm = true"
|
@click="showApiKeyForm = true"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
@@ -142,12 +139,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
|
||||||
import Divider from 'primevue/divider'
|
import Divider from 'primevue/divider'
|
||||||
import Message from 'primevue/message'
|
import Message from 'primevue/message'
|
||||||
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
||||||
import { getComfyPlatformBaseUrl } from '@/config/comfyApi'
|
import { getComfyPlatformBaseUrl } from '@/config/comfyApi'
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -58,26 +58,27 @@
|
|||||||
<Button
|
<Button
|
||||||
:disabled="!selectedCredits || loading"
|
:disabled="!selectedCredits || loading"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
severity="primary"
|
variant="primary"
|
||||||
:label="$t('credits.topUp.buy')"
|
:class="cn('w-full', (!selectedCredits || loading) && 'opacity-30')"
|
||||||
:class="['w-full', { 'opacity-30': !selectedCredits || loading }]"
|
|
||||||
:pt="{ label: { class: 'text-primary-foreground' } }"
|
|
||||||
@click="handleBuy"
|
@click="handleBuy"
|
||||||
/>
|
>
|
||||||
|
{{ $t('credits.topUp.buy') }}
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
|
||||||
import { useToast } from 'primevue/usetoast'
|
import { useToast } from 'primevue/usetoast'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
import { creditsToUsd } from '@/base/credits/comfyCredits'
|
import { creditsToUsd } from '@/base/credits/comfyCredits'
|
||||||
import UserCredit from '@/components/common/UserCredit.vue'
|
import UserCredit from '@/components/common/UserCredit.vue'
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
||||||
import { useSubscription } from '@/platform/cloud/subscription/composables/useSubscription'
|
import { useSubscription } from '@/platform/cloud/subscription/composables/useSubscription'
|
||||||
import { useTelemetry } from '@/platform/telemetry'
|
import { useTelemetry } from '@/platform/telemetry'
|
||||||
|
import { cn } from '@/utils/tailwindUtil'
|
||||||
|
|
||||||
import CreditTopUpOption from './credit/CreditTopUpOption.vue'
|
import CreditTopUpOption from './credit/CreditTopUpOption.vue'
|
||||||
|
|
||||||
|
|||||||
@@ -7,12 +7,9 @@
|
|||||||
<PasswordFields />
|
<PasswordFields />
|
||||||
|
|
||||||
<!-- Submit Button -->
|
<!-- Submit Button -->
|
||||||
<Button
|
<Button type="submit" class="mt-4 h-10 font-medium" :loading="loading">
|
||||||
type="submit"
|
{{ $t('userSettings.updatePassword') }}
|
||||||
:label="$t('userSettings.updatePassword')"
|
</Button>
|
||||||
class="mt-4 h-10 font-medium"
|
|
||||||
:loading="loading"
|
|
||||||
/>
|
|
||||||
</Form>
|
</Form>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -20,10 +17,10 @@
|
|||||||
import type { FormSubmitEvent } from '@primevue/forms'
|
import type { FormSubmitEvent } from '@primevue/forms'
|
||||||
import { Form } from '@primevue/forms'
|
import { Form } from '@primevue/forms'
|
||||||
import { zodResolver } from '@primevue/forms/resolvers/zod'
|
import { zodResolver } from '@primevue/forms/resolvers/zod'
|
||||||
import Button from 'primevue/button'
|
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
|
|
||||||
import PasswordFields from '@/components/dialog/content/signin/PasswordFields.vue'
|
import PasswordFields from '@/components/dialog/content/signin/PasswordFields.vue'
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
||||||
import { updatePasswordSchema } from '@/schemas/signInSchema'
|
import { updatePasswordSchema } from '@/schemas/signInSchema'
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<Button
|
<Button variant="secondary" @click="openGitHubIssues">
|
||||||
:label="$t('g.findIssues')"
|
<i class="pi pi-github" />
|
||||||
severity="secondary"
|
{{ $t('g.findIssues') }}
|
||||||
icon="pi pi-github"
|
</Button>
|
||||||
@click="openGitHubIssues"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
|
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import { useTelemetry } from '@/platform/telemetry'
|
import { useTelemetry } from '@/platform/telemetry'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
|
|||||||
@@ -10,15 +10,23 @@
|
|||||||
<div>
|
<div>
|
||||||
{{ $t('g.currentUser') }}: {{ userStore.currentUser?.username }}
|
{{ $t('g.currentUser') }}: {{ userStore.currentUser?.username }}
|
||||||
</div>
|
</div>
|
||||||
<Button icon="pi pi-sign-out" text @click="logout" />
|
<Button
|
||||||
|
class="text-inherit"
|
||||||
|
variant="textonly"
|
||||||
|
size="icon"
|
||||||
|
:aria-label="$t('menuLabels.Sign Out')"
|
||||||
|
@click="logout"
|
||||||
|
>
|
||||||
|
<i class="pi pi-sign-out" />
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</Message>
|
</Message>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
|
||||||
import Message from 'primevue/message'
|
import Message from 'primevue/message'
|
||||||
|
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import { useUserStore } from '@/stores/userStore'
|
import { useUserStore } from '@/stores/userStore'
|
||||||
|
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
|
|||||||
@@ -23,24 +23,33 @@
|
|||||||
<template #body="slotProps">
|
<template #body="slotProps">
|
||||||
<div class="actions invisible flex flex-row">
|
<div class="actions invisible flex flex-row">
|
||||||
<Button
|
<Button
|
||||||
icon="pi pi-pencil"
|
variant="textonly"
|
||||||
class="p-button-text"
|
size="icon"
|
||||||
|
:aria-label="$t('g.edit')"
|
||||||
@click="editKeybinding(slotProps.data)"
|
@click="editKeybinding(slotProps.data)"
|
||||||
/>
|
>
|
||||||
|
<i class="pi pi-pencil" />
|
||||||
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
icon="pi pi-replay"
|
variant="textonly"
|
||||||
class="p-button-text p-button-warn"
|
size="icon"
|
||||||
|
:aria-label="$t('g.reset')"
|
||||||
:disabled="
|
:disabled="
|
||||||
!keybindingStore.isCommandKeybindingModified(slotProps.data.id)
|
!keybindingStore.isCommandKeybindingModified(slotProps.data.id)
|
||||||
"
|
"
|
||||||
@click="resetKeybinding(slotProps.data)"
|
@click="resetKeybinding(slotProps.data)"
|
||||||
/>
|
>
|
||||||
|
<i class="pi pi-replay" />
|
||||||
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
icon="pi pi-trash"
|
variant="textonly"
|
||||||
class="p-button-text p-button-danger"
|
size="icon"
|
||||||
|
:aria-label="$t('g.delete')"
|
||||||
:disabled="!slotProps.data.keybinding"
|
:disabled="!slotProps.data.keybinding"
|
||||||
@click="removeKeybinding(slotProps.data)"
|
@click="removeKeybinding(slotProps.data)"
|
||||||
/>
|
>
|
||||||
|
<i class="pi pi-trash" />
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
@@ -104,30 +113,31 @@
|
|||||||
</div>
|
</div>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<Button
|
<Button
|
||||||
:label="existingKeybindingOnCombo ? 'Overwrite' : 'Save'"
|
:variant="existingKeybindingOnCombo ? 'destructive' : 'primary'"
|
||||||
:icon="existingKeybindingOnCombo ? 'pi pi-pencil' : 'pi pi-check'"
|
|
||||||
:severity="existingKeybindingOnCombo ? 'warn' : undefined"
|
|
||||||
autofocus
|
autofocus
|
||||||
@click="saveKeybinding"
|
@click="saveKeybinding"
|
||||||
/>
|
>
|
||||||
|
<i
|
||||||
|
:class="existingKeybindingOnCombo ? 'pi pi-pencil' : 'pi pi-check'"
|
||||||
|
/>
|
||||||
|
{{ existingKeybindingOnCombo ? $t('g.overwrite') : $t('g.save') }}
|
||||||
|
</Button>
|
||||||
</template>
|
</template>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
<Button
|
<Button
|
||||||
v-tooltip="$t('g.resetAllKeybindingsTooltip')"
|
v-tooltip="$t('g.resetAllKeybindingsTooltip')"
|
||||||
class="mt-4"
|
class="mt-4 w-full"
|
||||||
:label="$t('g.resetAll')"
|
variant="destructive-textonly"
|
||||||
icon="pi pi-replay"
|
|
||||||
severity="danger"
|
|
||||||
fluid
|
|
||||||
text
|
|
||||||
@click="resetAllKeybindings"
|
@click="resetAllKeybindings"
|
||||||
/>
|
>
|
||||||
|
<i class="pi pi-replay" />
|
||||||
|
{{ $t('g.resetAll') }}
|
||||||
|
</Button>
|
||||||
</PanelTemplate>
|
</PanelTemplate>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { FilterMatchMode } from '@primevue/core/api'
|
import { FilterMatchMode } from '@primevue/core/api'
|
||||||
import Button from 'primevue/button'
|
|
||||||
import Column from 'primevue/column'
|
import Column from 'primevue/column'
|
||||||
import DataTable from 'primevue/datatable'
|
import DataTable from 'primevue/datatable'
|
||||||
import Dialog from 'primevue/dialog'
|
import Dialog from 'primevue/dialog'
|
||||||
@@ -139,6 +149,7 @@ import { computed, ref, watchEffect } from 'vue'
|
|||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
import SearchBox from '@/components/common/SearchBox.vue'
|
import SearchBox from '@/components/common/SearchBox.vue'
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import { useKeybindingService } from '@/services/keybindingService'
|
import { useKeybindingService } from '@/services/keybindingService'
|
||||||
import { useCommandStore } from '@/stores/commandStore'
|
import { useCommandStore } from '@/stores/commandStore'
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -17,10 +17,11 @@
|
|||||||
<Skeleton v-if="loading" width="2rem" height="2rem" />
|
<Skeleton v-if="loading" width="2rem" height="2rem" />
|
||||||
<Button
|
<Button
|
||||||
v-else-if="isActiveSubscription"
|
v-else-if="isActiveSubscription"
|
||||||
:label="$t('credits.purchaseCredits')"
|
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
@click="handlePurchaseCreditsClick"
|
@click="handlePurchaseCreditsClick"
|
||||||
/>
|
>
|
||||||
|
{{ $t('credits.purchaseCredits') }}
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-row items-center">
|
<div class="flex flex-row items-center">
|
||||||
<Skeleton
|
<Skeleton
|
||||||
@@ -33,25 +34,26 @@
|
|||||||
{{ $t('credits.lastUpdated') }}: {{ formattedLastUpdateTime }}
|
{{ $t('credits.lastUpdated') }}: {{ formattedLastUpdateTime }}
|
||||||
</div>
|
</div>
|
||||||
<Button
|
<Button
|
||||||
icon="pi pi-refresh"
|
variant="muted-textonly"
|
||||||
text
|
size="icon-sm"
|
||||||
size="small"
|
:aria-label="$t('g.refresh')"
|
||||||
severity="secondary"
|
|
||||||
@click="() => authActions.fetchBalance()"
|
@click="() => authActions.fetchBalance()"
|
||||||
/>
|
>
|
||||||
|
<i class="pi pi-refresh" />
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<h3>{{ $t('credits.activity') }}</h3>
|
<h3>{{ $t('credits.activity') }}</h3>
|
||||||
<Button
|
<Button
|
||||||
:label="$t('credits.invoiceHistory')"
|
variant="muted-textonly"
|
||||||
text
|
|
||||||
severity="secondary"
|
|
||||||
icon="pi pi-arrow-up-right"
|
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
@click="handleCreditsHistoryClick"
|
@click="handleCreditsHistoryClick"
|
||||||
/>
|
>
|
||||||
|
<i class="pi pi-arrow-up-right" />
|
||||||
|
{{ $t('credits.invoiceHistory') }}
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template v-if="creditHistory.length > 0">
|
<template v-if="creditHistory.length > 0">
|
||||||
@@ -86,34 +88,24 @@
|
|||||||
<UsageLogsTable ref="usageLogsTableRef" />
|
<UsageLogsTable ref="usageLogsTableRef" />
|
||||||
|
|
||||||
<div class="flex flex-row gap-2">
|
<div class="flex flex-row gap-2">
|
||||||
<Button
|
<Button variant="muted-textonly" @click="handleFaqClick">
|
||||||
:label="$t('credits.faqs')"
|
<i class="pi pi-question-circle" />
|
||||||
text
|
{{ $t('credits.faqs') }}
|
||||||
severity="secondary"
|
</Button>
|
||||||
icon="pi pi-question-circle"
|
<Button variant="muted-textonly" @click="handleOpenPartnerNodesInfo">
|
||||||
@click="handleFaqClick"
|
<i class="pi pi-question-circle" />
|
||||||
/>
|
{{ $t('subscription.partnerNodesCredits') }}
|
||||||
<Button
|
</Button>
|
||||||
:label="$t('subscription.partnerNodesCredits')"
|
<Button variant="muted-textonly" @click="handleMessageSupport">
|
||||||
text
|
<i class="pi pi-comments" />
|
||||||
severity="secondary"
|
{{ $t('credits.messageSupport') }}
|
||||||
icon="pi pi-question-circle"
|
</Button>
|
||||||
@click="handleOpenPartnerNodesInfo"
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
:label="$t('credits.messageSupport')"
|
|
||||||
text
|
|
||||||
severity="secondary"
|
|
||||||
icon="pi pi-comments"
|
|
||||||
@click="handleMessageSupport"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
|
||||||
import Column from 'primevue/column'
|
import Column from 'primevue/column'
|
||||||
import DataTable from 'primevue/datatable'
|
import DataTable from 'primevue/datatable'
|
||||||
import Divider from 'primevue/divider'
|
import Divider from 'primevue/divider'
|
||||||
@@ -123,6 +115,7 @@ import { computed, ref, watch } from 'vue'
|
|||||||
|
|
||||||
import UserCredit from '@/components/common/UserCredit.vue'
|
import UserCredit from '@/components/common/UserCredit.vue'
|
||||||
import UsageLogsTable from '@/components/dialog/content/setting/UsageLogsTable.vue'
|
import UsageLogsTable from '@/components/dialog/content/setting/UsageLogsTable.vue'
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
||||||
import { useExternalLink } from '@/composables/useExternalLink'
|
import { useExternalLink } from '@/composables/useExternalLink'
|
||||||
import { useSubscription } from '@/platform/cloud/subscription/composables/useSubscription'
|
import { useSubscription } from '@/platform/cloud/subscription/composables/useSubscription'
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { createTestingPinia } from '@pinia/testing'
|
import { createTestingPinia } from '@pinia/testing'
|
||||||
import { mount } from '@vue/test-utils'
|
import { mount } from '@vue/test-utils'
|
||||||
import Badge from 'primevue/badge'
|
import Badge from 'primevue/badge'
|
||||||
import Button from 'primevue/button'
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import Column from 'primevue/column'
|
import Column from 'primevue/column'
|
||||||
import PrimeVue from 'primevue/config'
|
import PrimeVue from 'primevue/config'
|
||||||
import DataTable from 'primevue/datatable'
|
import DataTable from 'primevue/datatable'
|
||||||
|
|||||||
@@ -78,9 +78,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}"
|
}"
|
||||||
icon="pi pi-info-circle"
|
variant="textonly"
|
||||||
class="p-button-text p-button-sm"
|
size="icon-sm"
|
||||||
/>
|
:aria-label="$t('credits.additionalInfo')"
|
||||||
|
>
|
||||||
|
<i class="pi pi-info-circle" />
|
||||||
|
</Button>
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
</DataTable>
|
</DataTable>
|
||||||
@@ -89,13 +92,13 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Badge from 'primevue/badge'
|
import Badge from 'primevue/badge'
|
||||||
import Button from 'primevue/button'
|
|
||||||
import Column from 'primevue/column'
|
import Column from 'primevue/column'
|
||||||
import DataTable from 'primevue/datatable'
|
import DataTable from 'primevue/datatable'
|
||||||
import Message from 'primevue/message'
|
import Message from 'primevue/message'
|
||||||
import ProgressSpinner from 'primevue/progressspinner'
|
import ProgressSpinner from 'primevue/progressspinner'
|
||||||
import { computed, ref } from 'vue'
|
import { computed, ref } from 'vue'
|
||||||
|
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import { useTelemetry } from '@/platform/telemetry'
|
import { useTelemetry } from '@/platform/telemetry'
|
||||||
import type { AuditLog } from '@/services/customerEventsService'
|
import type { AuditLog } from '@/services/customerEventsService'
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -44,11 +44,12 @@
|
|||||||
value: $t('userSettings.updatePassword'),
|
value: $t('userSettings.updatePassword'),
|
||||||
showDelay: 300
|
showDelay: 300
|
||||||
}"
|
}"
|
||||||
icon="pi pi-pen-to-square"
|
variant="muted-textonly"
|
||||||
severity="secondary"
|
size="icon-sm"
|
||||||
text
|
|
||||||
@click="dialogService.showUpdatePasswordDialog()"
|
@click="dialogService.showUpdatePasswordDialog()"
|
||||||
/>
|
>
|
||||||
|
<i class="pi pi-pen-to-square" />
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -58,21 +59,18 @@
|
|||||||
style="--pc-spinner-color: #000"
|
style="--pc-spinner-color: #000"
|
||||||
/>
|
/>
|
||||||
<div v-else class="mt-4 flex flex-col gap-2">
|
<div v-else class="mt-4 flex flex-col gap-2">
|
||||||
<Button
|
<Button class="w-32" variant="secondary" @click="handleSignOut">
|
||||||
class="w-32"
|
<i class="pi pi-sign-out" />
|
||||||
severity="secondary"
|
{{ $t('auth.signOut.signOut') }}
|
||||||
:label="$t('auth.signOut.signOut')"
|
</Button>
|
||||||
icon="pi pi-sign-out"
|
|
||||||
@click="handleSignOut"
|
|
||||||
/>
|
|
||||||
<Button
|
<Button
|
||||||
v-if="!isApiKeyLogin"
|
v-if="!isApiKeyLogin"
|
||||||
class="w-fit"
|
class="w-fit"
|
||||||
variant="text"
|
variant="destructive-textonly"
|
||||||
severity="danger"
|
|
||||||
:label="$t('auth.deleteAccount.deleteAccount')"
|
|
||||||
@click="handleDeleteAccount"
|
@click="handleDeleteAccount"
|
||||||
/>
|
>
|
||||||
|
{{ $t('auth.deleteAccount.deleteAccount') }}
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -84,24 +82,25 @@
|
|||||||
|
|
||||||
<Button
|
<Button
|
||||||
class="w-52"
|
class="w-52"
|
||||||
severity="primary"
|
variant="primary"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
:label="$t('auth.login.signInOrSignUp')"
|
|
||||||
icon="pi pi-user"
|
|
||||||
@click="handleSignIn"
|
@click="handleSignIn"
|
||||||
/>
|
>
|
||||||
|
<i class="pi pi-user" />
|
||||||
|
{{ $t('auth.login.signInOrSignUp') }}
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
|
||||||
import Divider from 'primevue/divider'
|
import Divider from 'primevue/divider'
|
||||||
import ProgressSpinner from 'primevue/progressspinner'
|
import ProgressSpinner from 'primevue/progressspinner'
|
||||||
import TabPanel from 'primevue/tabpanel'
|
import TabPanel from 'primevue/tabpanel'
|
||||||
|
|
||||||
import UserAvatar from '@/components/common/UserAvatar.vue'
|
import UserAvatar from '@/components/common/UserAvatar.vue'
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import { useCurrentUser } from '@/composables/auth/useCurrentUser'
|
import { useCurrentUser } from '@/composables/auth/useCurrentUser'
|
||||||
import { useDialogService } from '@/services/dialogService'
|
import { useDialogService } from '@/services/dialogService'
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Form } from '@primevue/forms'
|
import { Form } from '@primevue/forms'
|
||||||
import { mount } from '@vue/test-utils'
|
import { mount } from '@vue/test-utils'
|
||||||
import { createPinia } from 'pinia'
|
import { createPinia } from 'pinia'
|
||||||
import Button from 'primevue/button'
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import PrimeVue from 'primevue/config'
|
import PrimeVue from 'primevue/config'
|
||||||
import InputText from 'primevue/inputtext'
|
import InputText from 'primevue/inputtext'
|
||||||
import Message from 'primevue/message'
|
import Message from 'primevue/message'
|
||||||
@@ -99,9 +99,10 @@ describe('ApiKeyForm', () => {
|
|||||||
)
|
)
|
||||||
await wrapper.find('form').trigger('submit')
|
await wrapper.find('form').trigger('submit')
|
||||||
|
|
||||||
const submitButton = wrapper
|
const buttons = wrapper.findAllComponents(Button)
|
||||||
.findAllComponents(Button)
|
const submitButton = buttons.find(
|
||||||
.find((btn) => btn.text() === 'Save')
|
(btn) => btn.attributes('type') === 'submit'
|
||||||
|
)
|
||||||
expect(submitButton?.props('loading')).toBe(true)
|
expect(submitButton?.props('loading')).toBe(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -67,10 +67,15 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-4 flex items-center justify-between">
|
<div class="mt-4 flex items-center justify-between">
|
||||||
<Button type="button" link @click="$emit('back')">
|
<Button type="button" variant="textonly" @click="$emit('back')">
|
||||||
{{ t('g.back') }}
|
{{ t('g.back') }}
|
||||||
</Button>
|
</Button>
|
||||||
<Button type="submit" :loading="loading" :disabled="loading">
|
<Button
|
||||||
|
type="submit"
|
||||||
|
variant="primary"
|
||||||
|
:loading="loading"
|
||||||
|
:disabled="loading"
|
||||||
|
>
|
||||||
{{ t('g.save') }}
|
{{ t('g.save') }}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
@@ -82,12 +87,12 @@
|
|||||||
import type { FormSubmitEvent } from '@primevue/forms'
|
import type { FormSubmitEvent } from '@primevue/forms'
|
||||||
import { Form } from '@primevue/forms'
|
import { Form } from '@primevue/forms'
|
||||||
import { zodResolver } from '@primevue/forms/resolvers/zod'
|
import { zodResolver } from '@primevue/forms/resolvers/zod'
|
||||||
import Button from 'primevue/button'
|
|
||||||
import InputText from 'primevue/inputtext'
|
import InputText from 'primevue/inputtext'
|
||||||
import Message from 'primevue/message'
|
import Message from 'primevue/message'
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import { getComfyPlatformBaseUrl } from '@/config/comfyApi'
|
import { getComfyPlatformBaseUrl } from '@/config/comfyApi'
|
||||||
import {
|
import {
|
||||||
configValueOrDefault,
|
configValueOrDefault,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Form } from '@primevue/forms'
|
import { Form } from '@primevue/forms'
|
||||||
import type { VueWrapper } from '@vue/test-utils'
|
import type { VueWrapper } from '@vue/test-utils'
|
||||||
import { mount } from '@vue/test-utils'
|
import { mount } from '@vue/test-utils'
|
||||||
import Button from 'primevue/button'
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import PrimeVue from 'primevue/config'
|
import PrimeVue from 'primevue/config'
|
||||||
import InputText from 'primevue/inputtext'
|
import InputText from 'primevue/inputtext'
|
||||||
import Password from 'primevue/password'
|
import Password from 'primevue/password'
|
||||||
|
|||||||
@@ -64,10 +64,11 @@
|
|||||||
<Button
|
<Button
|
||||||
v-else
|
v-else
|
||||||
type="submit"
|
type="submit"
|
||||||
:label="t('auth.login.loginButton')"
|
|
||||||
class="mt-4 h-10 font-medium"
|
class="mt-4 h-10 font-medium"
|
||||||
:disabled="!$form.valid"
|
:disabled="!$form.valid"
|
||||||
/>
|
>
|
||||||
|
{{ t('auth.login.loginButton') }}
|
||||||
|
</Button>
|
||||||
</Form>
|
</Form>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -76,7 +77,6 @@ import type { FormSubmitEvent } from '@primevue/forms'
|
|||||||
import { Form } from '@primevue/forms'
|
import { Form } from '@primevue/forms'
|
||||||
import { zodResolver } from '@primevue/forms/resolvers/zod'
|
import { zodResolver } from '@primevue/forms/resolvers/zod'
|
||||||
import { useThrottleFn } from '@vueuse/core'
|
import { useThrottleFn } from '@vueuse/core'
|
||||||
import Button from 'primevue/button'
|
|
||||||
import InputText from 'primevue/inputtext'
|
import InputText from 'primevue/inputtext'
|
||||||
import Password from 'primevue/password'
|
import Password from 'primevue/password'
|
||||||
import ProgressSpinner from 'primevue/progressspinner'
|
import ProgressSpinner from 'primevue/progressspinner'
|
||||||
@@ -84,6 +84,7 @@ import { useToast } from 'primevue/usetoast'
|
|||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
||||||
import { signInSchema } from '@/schemas/signInSchema'
|
import { signInSchema } from '@/schemas/signInSchema'
|
||||||
import type { SignInData } from '@/schemas/signInSchema'
|
import type { SignInData } from '@/schemas/signInSchema'
|
||||||
|
|||||||
@@ -33,10 +33,11 @@
|
|||||||
<Button
|
<Button
|
||||||
v-else
|
v-else
|
||||||
type="submit"
|
type="submit"
|
||||||
:label="t('auth.signup.signUpButton')"
|
|
||||||
class="mt-4 h-10 font-medium"
|
class="mt-4 h-10 font-medium"
|
||||||
:disabled="!$form.valid"
|
:disabled="!$form.valid"
|
||||||
/>
|
>
|
||||||
|
{{ t('auth.signup.signUpButton') }}
|
||||||
|
</Button>
|
||||||
</Form>
|
</Form>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -45,12 +46,12 @@ import type { FormSubmitEvent } from '@primevue/forms'
|
|||||||
import { Form, FormField } from '@primevue/forms'
|
import { Form, FormField } from '@primevue/forms'
|
||||||
import { zodResolver } from '@primevue/forms/resolvers/zod'
|
import { zodResolver } from '@primevue/forms/resolvers/zod'
|
||||||
import { useThrottleFn } from '@vueuse/core'
|
import { useThrottleFn } from '@vueuse/core'
|
||||||
import Button from 'primevue/button'
|
|
||||||
import InputText from 'primevue/inputtext'
|
import InputText from 'primevue/inputtext'
|
||||||
import ProgressSpinner from 'primevue/progressspinner'
|
import ProgressSpinner from 'primevue/progressspinner'
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import { signUpSchema } from '@/schemas/signInSchema'
|
import { signUpSchema } from '@/schemas/signInSchema'
|
||||||
import type { SignUpData } from '@/schemas/signInSchema'
|
import type { SignUpData } from '@/schemas/signInSchema'
|
||||||
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
|
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
|
||||||
|
|||||||
@@ -1,21 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<Button
|
<Button
|
||||||
ref="buttonRef"
|
ref="buttonRef"
|
||||||
severity="secondary"
|
variant="secondary"
|
||||||
class="group h-8 rounded-none! bg-comfy-menu-bg p-0 transition-none! hover:rounded-lg! hover:bg-interface-button-hover-surface!"
|
class="group h-8 rounded-none! bg-comfy-menu-bg p-0 transition-none! hover:rounded-lg! hover:bg-interface-button-hover-surface!"
|
||||||
:style="buttonStyles"
|
:style="buttonStyles"
|
||||||
@click="toggle"
|
@click="toggle"
|
||||||
>
|
>
|
||||||
<template #default>
|
<div class="flex items-center gap-1 pr-0.5">
|
||||||
<div class="flex items-center gap-1 pr-0.5">
|
<div
|
||||||
<div
|
class="rounded-lg bg-interface-panel-selected-surface p-2 group-hover:bg-interface-button-hover-surface"
|
||||||
class="rounded-lg bg-interface-panel-selected-surface p-2 group-hover:bg-interface-button-hover-surface"
|
>
|
||||||
>
|
<i :class="currentModeIcon" class="block h-4 w-4" />
|
||||||
<i :class="currentModeIcon" class="block h-4 w-4" />
|
|
||||||
</div>
|
|
||||||
<i class="icon-[lucide--chevron-down] block h-4 w-4 pr-1.5" />
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
<i class="icon-[lucide--chevron-down] block h-4 w-4 pr-1.5" />
|
||||||
|
</div>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Popover
|
<Popover
|
||||||
@@ -56,10 +54,10 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
|
||||||
import Popover from 'primevue/popover'
|
import Popover from 'primevue/popover'
|
||||||
import { computed, ref } from 'vue'
|
import { computed, ref } from 'vue'
|
||||||
|
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
|
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
|
||||||
import { useCommandStore } from '@/stores/commandStore'
|
import { useCommandStore } from '@/stores/commandStore'
|
||||||
|
|
||||||
|
|||||||
@@ -24,22 +24,18 @@
|
|||||||
|
|
||||||
<Button
|
<Button
|
||||||
v-tooltip.top="fitViewTooltip"
|
v-tooltip.top="fitViewTooltip"
|
||||||
severity="secondary"
|
variant="secondary"
|
||||||
icon="pi pi-expand"
|
|
||||||
:aria-label="fitViewTooltip"
|
:aria-label="fitViewTooltip"
|
||||||
:style="stringifiedMinimapStyles.buttonStyles"
|
:style="stringifiedMinimapStyles.buttonStyles"
|
||||||
class="h-8 w-8 bg-comfy-menu-bg p-0 hover:bg-interface-button-hover-surface!"
|
class="h-8 w-8 bg-comfy-menu-bg p-0 hover:bg-interface-button-hover-surface!"
|
||||||
@click="() => commandStore.execute('Comfy.Canvas.FitView')"
|
@click="() => commandStore.execute('Comfy.Canvas.FitView')"
|
||||||
>
|
>
|
||||||
<template #icon>
|
<i class="icon-[lucide--focus] h-4 w-4" />
|
||||||
<i class="icon-[lucide--focus] h-4 w-4" />
|
|
||||||
</template>
|
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
v-tooltip.top="t('zoomControls.label')"
|
v-tooltip.top="t('zoomControls.label')"
|
||||||
severity="secondary"
|
variant="secondary"
|
||||||
:label="t('zoomControls.label')"
|
|
||||||
:class="zoomButtonClass"
|
:class="zoomButtonClass"
|
||||||
:aria-label="t('zoomControls.label')"
|
:aria-label="t('zoomControls.label')"
|
||||||
data-testid="zoom-controls-button"
|
data-testid="zoom-controls-button"
|
||||||
@@ -56,16 +52,14 @@
|
|||||||
|
|
||||||
<Button
|
<Button
|
||||||
v-tooltip.top="minimapTooltip"
|
v-tooltip.top="minimapTooltip"
|
||||||
severity="secondary"
|
variant="secondary"
|
||||||
:aria-label="minimapTooltip"
|
:aria-label="minimapTooltip"
|
||||||
data-testid="toggle-minimap-button"
|
data-testid="toggle-minimap-button"
|
||||||
:style="stringifiedMinimapStyles.buttonStyles"
|
:style="stringifiedMinimapStyles.buttonStyles"
|
||||||
:class="minimapButtonClass"
|
:class="minimapButtonClass"
|
||||||
@click="onMinimapToggleClick"
|
@click="onMinimapToggleClick"
|
||||||
>
|
>
|
||||||
<template #icon>
|
<i class="icon-[lucide--map] h-4 w-4" />
|
||||||
<i class="icon-[lucide--map] h-4 w-4" />
|
|
||||||
</template>
|
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
@@ -77,27 +71,25 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}"
|
}"
|
||||||
severity="secondary"
|
variant="secondary"
|
||||||
:class="linkVisibleClass"
|
:class="linkVisibleClass"
|
||||||
:aria-label="linkVisibilityAriaLabel"
|
:aria-label="linkVisibilityAriaLabel"
|
||||||
data-testid="toggle-link-visibility-button"
|
data-testid="toggle-link-visibility-button"
|
||||||
:style="stringifiedMinimapStyles.buttonStyles"
|
:style="stringifiedMinimapStyles.buttonStyles"
|
||||||
@click="onLinkVisibilityToggleClick"
|
@click="onLinkVisibilityToggleClick"
|
||||||
>
|
>
|
||||||
<template #icon>
|
<i class="icon-[lucide--route-off] h-4 w-4" />
|
||||||
<i class="icon-[lucide--route-off] h-4 w-4" />
|
|
||||||
</template>
|
|
||||||
</Button>
|
</Button>
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
|
||||||
import ButtonGroup from 'primevue/buttongroup'
|
import ButtonGroup from 'primevue/buttongroup'
|
||||||
import { computed, onBeforeUnmount, onMounted } from 'vue'
|
import { computed, onBeforeUnmount, onMounted } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import { useZoomControls } from '@/composables/useZoomControls'
|
import { useZoomControls } from '@/composables/useZoomControls'
|
||||||
import { LiteGraph } from '@/lib/litegraph/src/litegraph'
|
import { LiteGraph } from '@/lib/litegraph/src/litegraph'
|
||||||
import { useSettingStore } from '@/platform/settings/settingStore'
|
import { useSettingStore } from '@/platform/settings/settingStore'
|
||||||
|
|||||||
@@ -4,21 +4,18 @@
|
|||||||
value: $t('commands.Comfy_Canvas_ToggleSelectedNodes_Bypass.label'),
|
value: $t('commands.Comfy_Canvas_ToggleSelectedNodes_Bypass.label'),
|
||||||
showDelay: 1000
|
showDelay: 1000
|
||||||
}"
|
}"
|
||||||
severity="secondary"
|
variant="muted-textonly"
|
||||||
text
|
:aria-label="$t('commands.Comfy_Canvas_ToggleSelectedNodes_Bypass.label')"
|
||||||
data-testid="bypass-button"
|
data-testid="bypass-button"
|
||||||
class="hover:bg-secondary-background"
|
class="hover:bg-secondary-background"
|
||||||
@click="toggleBypass"
|
@click="toggleBypass"
|
||||||
>
|
>
|
||||||
<template #icon>
|
<i class="icon-[lucide--redo-dot] size-4" />
|
||||||
<i class="icon-[lucide--redo-dot] h-4 w-4" />
|
|
||||||
</template>
|
|
||||||
</Button>
|
</Button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
|
|
||||||
import { useCommandStore } from '@/stores/commandStore'
|
import { useCommandStore } from '@/stores/commandStore'
|
||||||
|
|
||||||
const commandStore = useCommandStore()
|
const commandStore = useCommandStore()
|
||||||
|
|||||||
@@ -6,19 +6,13 @@
|
|||||||
showDelay: 1000
|
showDelay: 1000
|
||||||
}"
|
}"
|
||||||
data-testid="color-picker-button"
|
data-testid="color-picker-button"
|
||||||
severity="secondary"
|
variant="muted-textonly"
|
||||||
text
|
:aria-label="t('g.color')"
|
||||||
@click="() => (showColorPicker = !showColorPicker)"
|
@click="() => (showColorPicker = !showColorPicker)"
|
||||||
>
|
>
|
||||||
<div class="flex items-center gap-1 px-0">
|
<div class="flex items-center gap-1 px-0">
|
||||||
<i
|
<i class="pi pi-circle-fill" :style="{ color: currentColor ?? '' }" />
|
||||||
class="pi pi-circle-fill h-4 w-4"
|
<i class="icon-[lucide--chevron-down]" />
|
||||||
:style="{ color: currentColor ?? '' }"
|
|
||||||
/>
|
|
||||||
<i
|
|
||||||
class="pi pi-chevron-down h-4 w-4 py-1"
|
|
||||||
:style="{ fontSize: '0.5rem' }"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</Button>
|
</Button>
|
||||||
<div
|
<div
|
||||||
@@ -48,12 +42,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
|
||||||
import SelectButton from 'primevue/selectbutton'
|
import SelectButton from 'primevue/selectbutton'
|
||||||
import type { Raw } from 'vue'
|
import type { Raw } from 'vue'
|
||||||
import { computed, ref, watch } from 'vue'
|
import { computed, ref, watch } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import type {
|
import type {
|
||||||
ColorOption as CanvasColorOption,
|
ColorOption as CanvasColorOption,
|
||||||
Positionable
|
Positionable
|
||||||
|
|||||||
@@ -4,15 +4,15 @@
|
|||||||
value: $t('commands.Comfy_Graph_EditSubgraphWidgets.label'),
|
value: $t('commands.Comfy_Graph_EditSubgraphWidgets.label'),
|
||||||
showDelay: 1000
|
showDelay: 1000
|
||||||
}"
|
}"
|
||||||
severity="secondary"
|
variant="muted-textonly"
|
||||||
text
|
:aria-label="$t('commands.Comfy_Graph_EditSubgraphWidgets.label')"
|
||||||
icon="icon-[lucide--settings-2]"
|
|
||||||
@click="handleClick"
|
@click="handleClick"
|
||||||
/>
|
>
|
||||||
|
<i class="icon-[lucide--settings-2]" />
|
||||||
|
</Button>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
|
|
||||||
import { useRightSidePanelStore } from '@/stores/workspace/rightSidePanelStore'
|
import { useRightSidePanelStore } from '@/stores/workspace/rightSidePanelStore'
|
||||||
|
|
||||||
const rightSidePanelStore = useRightSidePanelStore()
|
const rightSidePanelStore = useRightSidePanelStore()
|
||||||
|
|||||||
@@ -5,14 +5,12 @@
|
|||||||
value: $t('commands.Comfy_Graph_UnpackSubgraph.label'),
|
value: $t('commands.Comfy_Graph_UnpackSubgraph.label'),
|
||||||
showDelay: 1000
|
showDelay: 1000
|
||||||
}"
|
}"
|
||||||
severity="secondary"
|
variant="muted-textonly"
|
||||||
|
:aria-label="$t('commands.Comfy_Graph_UnpackSubgraph.label')"
|
||||||
data-testid="convert-to-subgraph-button"
|
data-testid="convert-to-subgraph-button"
|
||||||
text
|
|
||||||
@click="() => commandStore.execute('Comfy.Graph.UnpackSubgraph')"
|
@click="() => commandStore.execute('Comfy.Graph.UnpackSubgraph')"
|
||||||
>
|
>
|
||||||
<template #icon>
|
<i class="icon-[lucide--expand] size-4" />
|
||||||
<i class="icon-[lucide--expand] h-4 w-4" />
|
|
||||||
</template>
|
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
v-else-if="isConvertVisible"
|
v-else-if="isConvertVisible"
|
||||||
@@ -20,21 +18,20 @@
|
|||||||
value: $t('commands.Comfy_Graph_ConvertToSubgraph.label'),
|
value: $t('commands.Comfy_Graph_ConvertToSubgraph.label'),
|
||||||
showDelay: 1000
|
showDelay: 1000
|
||||||
}"
|
}"
|
||||||
severity="secondary"
|
variant="muted-textonly"
|
||||||
|
size="icon"
|
||||||
|
:aria-label="$t('commands.Comfy_Graph_ConvertToSubgraph.label')"
|
||||||
data-testid="convert-to-subgraph-button"
|
data-testid="convert-to-subgraph-button"
|
||||||
text
|
|
||||||
@click="() => commandStore.execute('Comfy.Graph.ConvertToSubgraph')"
|
@click="() => commandStore.execute('Comfy.Graph.ConvertToSubgraph')"
|
||||||
>
|
>
|
||||||
<template #icon>
|
<i class="icon-[lucide--shrink] size-4" />
|
||||||
<i class="icon-[lucide--shrink]" />
|
|
||||||
</template>
|
|
||||||
</Button>
|
</Button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
|
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import { useSelectionState } from '@/composables/graph/useSelectionState'
|
import { useSelectionState } from '@/composables/graph/useSelectionState'
|
||||||
import { useCommandStore } from '@/stores/commandStore'
|
import { useCommandStore } from '@/stores/commandStore'
|
||||||
|
|
||||||
|
|||||||
@@ -5,19 +5,19 @@
|
|||||||
value: $t('commands.Comfy_Canvas_DeleteSelectedItems.label'),
|
value: $t('commands.Comfy_Canvas_DeleteSelectedItems.label'),
|
||||||
showDelay: 1000
|
showDelay: 1000
|
||||||
}"
|
}"
|
||||||
severity="secondary"
|
variant="muted-textonly"
|
||||||
text
|
:aria-label="$t('commands.Comfy_Canvas_DeleteSelectedItems.label')"
|
||||||
icon-class="w-4 h-4"
|
|
||||||
icon="pi pi-trash"
|
|
||||||
data-testid="delete-button"
|
data-testid="delete-button"
|
||||||
@click="() => commandStore.execute('Comfy.Canvas.DeleteSelectedItems')"
|
@click="() => commandStore.execute('Comfy.Canvas.DeleteSelectedItems')"
|
||||||
/>
|
>
|
||||||
|
<i class="icon-[lucide--trash-2]" />
|
||||||
|
</Button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
|
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import { useSelectionState } from '@/composables/graph/useSelectionState'
|
import { useSelectionState } from '@/composables/graph/useSelectionState'
|
||||||
import type { Positionable } from '@/lib/litegraph/src/interfaces'
|
import type { Positionable } from '@/lib/litegraph/src/interfaces'
|
||||||
import { useCommandStore } from '@/stores/commandStore'
|
import { useCommandStore } from '@/stores/commandStore'
|
||||||
|
|||||||
@@ -4,21 +4,21 @@
|
|||||||
value: t('selectionToolbox.executeButton.tooltip'),
|
value: t('selectionToolbox.executeButton.tooltip'),
|
||||||
showDelay: 1000
|
showDelay: 1000
|
||||||
}"
|
}"
|
||||||
class="size-8 bg-primary-background text-white p-0"
|
variant="primary"
|
||||||
text
|
:aria-label="t('selectionToolbox.executeButton.tooltip')"
|
||||||
@mouseenter="() => handleMouseEnter()"
|
@mouseenter="() => handleMouseEnter()"
|
||||||
@mouseleave="() => handleMouseLeave()"
|
@mouseleave="() => handleMouseLeave()"
|
||||||
@click="handleClick"
|
@click="handleClick"
|
||||||
>
|
>
|
||||||
<i class="icon-[lucide--play] size-4" />
|
<i class="icon-[lucide--play]" />
|
||||||
</Button>
|
</Button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
|
||||||
import { computed, ref } from 'vue'
|
import { computed, ref } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import { useSelectionState } from '@/composables/graph/useSelectionState'
|
import { useSelectionState } from '@/composables/graph/useSelectionState'
|
||||||
import type { LGraphNode } from '@/lib/litegraph/src/litegraph'
|
import type { LGraphNode } from '@/lib/litegraph/src/litegraph'
|
||||||
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
|
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
|
||||||
|
|||||||
@@ -5,17 +5,20 @@
|
|||||||
st(`commands.${normalizeI18nKey(command.id)}.label`, '') || undefined,
|
st(`commands.${normalizeI18nKey(command.id)}.label`, '') || undefined,
|
||||||
showDelay: 1000
|
showDelay: 1000
|
||||||
}"
|
}"
|
||||||
severity="secondary"
|
variant="muted-textonly"
|
||||||
text
|
:aria-label="st(`commands.${normalizeI18nKey(command.id)}.label`, '')"
|
||||||
icon-class="w-4 h-4"
|
|
||||||
:icon="typeof command.icon === 'function' ? command.icon() : command.icon"
|
|
||||||
@click="() => commandStore.execute(command.id)"
|
@click="() => commandStore.execute(command.id)"
|
||||||
/>
|
>
|
||||||
|
<i
|
||||||
|
:class="[
|
||||||
|
typeof command.icon === 'function' ? command.icon() : command.icon
|
||||||
|
]"
|
||||||
|
/>
|
||||||
|
</Button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
|
|
||||||
import { st } from '@/i18n'
|
import { st } from '@/i18n'
|
||||||
import type { ComfyCommand } from '@/stores/commandStore'
|
import type { ComfyCommand } from '@/stores/commandStore'
|
||||||
import { useCommandStore } from '@/stores/commandStore'
|
import { useCommandStore } from '@/stores/commandStore'
|
||||||
|
|||||||
@@ -4,18 +4,16 @@
|
|||||||
value: $t('g.frameNodes'),
|
value: $t('g.frameNodes'),
|
||||||
showDelay: 1000
|
showDelay: 1000
|
||||||
}"
|
}"
|
||||||
class="frame-nodes-button"
|
variant="muted-textonly"
|
||||||
text
|
:aria-label="$t('g.frameNodes')"
|
||||||
severity="secondary"
|
|
||||||
@click="frameNodes"
|
@click="frameNodes"
|
||||||
>
|
>
|
||||||
<i class="icon-[lucide--frame] h-4 w-4" />
|
<i class="icon-[lucide--frame]" />
|
||||||
</Button>
|
</Button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
|
|
||||||
import { useFrameNodes } from '@/composables/graph/useFrameNodes'
|
import { useFrameNodes } from '@/composables/graph/useFrameNodes'
|
||||||
|
|
||||||
const { frameNodes } = useFrameNodes()
|
const { frameNodes } = useFrameNodes()
|
||||||
|
|||||||
@@ -5,17 +5,16 @@
|
|||||||
showDelay: 1000
|
showDelay: 1000
|
||||||
}"
|
}"
|
||||||
data-testid="info-button"
|
data-testid="info-button"
|
||||||
text
|
variant="muted-textonly"
|
||||||
severity="secondary"
|
:aria-label="$t('g.info')"
|
||||||
@click="onInfoClick"
|
@click="onInfoClick"
|
||||||
>
|
>
|
||||||
<i class="icon-[lucide--info] size-4" />
|
<i class="icon-[lucide--info]" />
|
||||||
</Button>
|
</Button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
|
|
||||||
import { useTelemetry } from '@/platform/telemetry'
|
import { useTelemetry } from '@/platform/telemetry'
|
||||||
import { useRightSidePanelStore } from '@/stores/workspace/rightSidePanelStore'
|
import { useRightSidePanelStore } from '@/stores/workspace/rightSidePanelStore'
|
||||||
|
|
||||||
|
|||||||
@@ -4,17 +4,16 @@
|
|||||||
value: $t('commands.Comfy_3DViewer_Open3DViewer.label'),
|
value: $t('commands.Comfy_3DViewer_Open3DViewer.label'),
|
||||||
showDelay: 1000
|
showDelay: 1000
|
||||||
}"
|
}"
|
||||||
severity="secondary"
|
variant="muted-textonly"
|
||||||
text
|
:aria-label="$t('commands.Comfy_3DViewer_Open3DViewer.label')"
|
||||||
icon="pi pi-pencil"
|
|
||||||
icon-class="w-4 h-4"
|
|
||||||
@click="open3DViewer"
|
@click="open3DViewer"
|
||||||
/>
|
>
|
||||||
|
<i class="icon-[lucide--pencil]" />
|
||||||
|
</Button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
|
|
||||||
import { useCommandStore } from '@/stores/commandStore'
|
import { useCommandStore } from '@/stores/commandStore'
|
||||||
|
|
||||||
const commandStore = useCommandStore()
|
const commandStore = useCommandStore()
|
||||||
|
|||||||
@@ -5,17 +5,16 @@
|
|||||||
value: $t('commands.Comfy_MaskEditor_OpenMaskEditor.label'),
|
value: $t('commands.Comfy_MaskEditor_OpenMaskEditor.label'),
|
||||||
showDelay: 1000
|
showDelay: 1000
|
||||||
}"
|
}"
|
||||||
severity="secondary"
|
variant="muted-textonly"
|
||||||
text
|
:aria-label="$t('commands.Comfy_MaskEditor_OpenMaskEditor.label')"
|
||||||
@click="openMaskEditor"
|
@click="openMaskEditor"
|
||||||
>
|
>
|
||||||
<i-comfy:mask class="!h-4 !w-4" />
|
<i class="icon-[comfy--mask]" />
|
||||||
</Button>
|
</Button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
|
|
||||||
import { useSelectionState } from '@/composables/graph/useSelectionState'
|
import { useSelectionState } from '@/composables/graph/useSelectionState'
|
||||||
import { useCommandStore } from '@/stores/commandStore'
|
import { useCommandStore } from '@/stores/commandStore'
|
||||||
|
|
||||||
|
|||||||
@@ -5,18 +5,16 @@
|
|||||||
showDelay: 1000
|
showDelay: 1000
|
||||||
}"
|
}"
|
||||||
data-testid="more-options-button"
|
data-testid="more-options-button"
|
||||||
text
|
variant="muted-textonly"
|
||||||
class="h-8 w-8 px-0"
|
:aria-label="$t('g.moreOptions')"
|
||||||
severity="secondary"
|
|
||||||
@click="handleClick"
|
@click="handleClick"
|
||||||
>
|
>
|
||||||
<i class="icon-[lucide--more-vertical] h-4 w-4" />
|
<i class="icon-[lucide--more-vertical]" />
|
||||||
</Button>
|
</Button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
|
|
||||||
import { toggleNodeOptions } from '@/composables/graph/useMoreOptionsMenu'
|
import { toggleNodeOptions } from '@/composables/graph/useMoreOptionsMenu'
|
||||||
|
|
||||||
const handleClick = (event: Event) => {
|
const handleClick = (event: Event) => {
|
||||||
|
|||||||
@@ -2,19 +2,19 @@
|
|||||||
<Button
|
<Button
|
||||||
v-show="isRefreshable"
|
v-show="isRefreshable"
|
||||||
v-tooltip.top="t('g.refreshNode')"
|
v-tooltip.top="t('g.refreshNode')"
|
||||||
severity="secondary"
|
variant="muted-textonly"
|
||||||
text
|
:aria-label="t('g.refreshNode')"
|
||||||
data-testid="refresh-button"
|
data-testid="refresh-button"
|
||||||
@click="refreshSelected"
|
@click="refreshSelected"
|
||||||
>
|
>
|
||||||
<i class="icon-[lucide--refresh-cw] h-4 w-4" />
|
<i class="icon-[lucide--refresh-cw]" />
|
||||||
</Button>
|
</Button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import { useRefreshableSelection } from '@/composables/useRefreshableSelection'
|
import { useRefreshableSelection } from '@/composables/useRefreshableSelection'
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
|||||||
@@ -5,20 +5,18 @@
|
|||||||
value: $t('commands.Comfy_PublishSubgraph.label'),
|
value: $t('commands.Comfy_PublishSubgraph.label'),
|
||||||
showDelay: 1000
|
showDelay: 1000
|
||||||
}"
|
}"
|
||||||
severity="secondary"
|
variant="muted-textonly"
|
||||||
text
|
:aria-label="$t('commands.Comfy_PublishSubgraph.label')"
|
||||||
@click="() => commandStore.execute('Comfy.PublishSubgraph')"
|
@click="() => commandStore.execute('Comfy.PublishSubgraph')"
|
||||||
>
|
>
|
||||||
<template #icon>
|
<i class="icon-[lucide--book-open]" />
|
||||||
<i class="icon-[lucide--book-open]" />
|
|
||||||
</template>
|
|
||||||
</Button>
|
</Button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
|
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import { SubgraphNode } from '@/lib/litegraph/src/litegraph'
|
import { SubgraphNode } from '@/lib/litegraph/src/litegraph'
|
||||||
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
|
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
|
||||||
import { useCommandStore } from '@/stores/commandStore'
|
import { useCommandStore } from '@/stores/commandStore'
|
||||||
|
|||||||
@@ -7,7 +7,13 @@
|
|||||||
@wheel.stop
|
@wheel.stop
|
||||||
>
|
>
|
||||||
<div class="show-menu relative">
|
<div class="show-menu relative">
|
||||||
<Button class="p-button-rounded p-button-text" @click="toggleMenu">
|
<Button
|
||||||
|
variant="textonly"
|
||||||
|
size="icon"
|
||||||
|
:aria-label="$t('menu.showMenu')"
|
||||||
|
class="rounded-full"
|
||||||
|
@click="toggleMenu"
|
||||||
|
>
|
||||||
<i class="pi pi-bars text-lg text-white" />
|
<i class="pi pi-bars text-lg text-white" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
@@ -19,8 +25,13 @@
|
|||||||
<Button
|
<Button
|
||||||
v-for="category in availableCategories"
|
v-for="category in availableCategories"
|
||||||
:key="category"
|
:key="category"
|
||||||
class="p-button-text flex w-full items-center justify-start"
|
variant="textonly"
|
||||||
:class="{ 'bg-smoke-600': activeCategory === category }"
|
:class="
|
||||||
|
cn(
|
||||||
|
'flex w-full items-center justify-start',
|
||||||
|
activeCategory === category && 'bg-smoke-600'
|
||||||
|
)
|
||||||
|
"
|
||||||
@click="selectCategory(category)"
|
@click="selectCategory(category)"
|
||||||
>
|
>
|
||||||
<i :class="getCategoryIcon(category)" />
|
<i :class="getCategoryIcon(category)" />
|
||||||
@@ -72,7 +83,6 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
|
||||||
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||||
|
|
||||||
import CameraControls from '@/components/load3d/controls/CameraControls.vue'
|
import CameraControls from '@/components/load3d/controls/CameraControls.vue'
|
||||||
@@ -80,12 +90,14 @@ import ExportControls from '@/components/load3d/controls/ExportControls.vue'
|
|||||||
import LightControls from '@/components/load3d/controls/LightControls.vue'
|
import LightControls from '@/components/load3d/controls/LightControls.vue'
|
||||||
import ModelControls from '@/components/load3d/controls/ModelControls.vue'
|
import ModelControls from '@/components/load3d/controls/ModelControls.vue'
|
||||||
import SceneControls from '@/components/load3d/controls/SceneControls.vue'
|
import SceneControls from '@/components/load3d/controls/SceneControls.vue'
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import type {
|
import type {
|
||||||
CameraConfig,
|
CameraConfig,
|
||||||
LightConfig,
|
LightConfig,
|
||||||
ModelConfig,
|
ModelConfig,
|
||||||
SceneConfig
|
SceneConfig
|
||||||
} from '@/extensions/core/load3d/interfaces'
|
} from '@/extensions/core/load3d/interfaces'
|
||||||
|
import { cn } from '@/utils/tailwindUtil'
|
||||||
|
|
||||||
const { isSplatModel = false, isPlyModel = false } = defineProps<{
|
const { isSplatModel = false, isPlyModel = false } = defineProps<{
|
||||||
isSplatModel?: boolean
|
isSplatModel?: boolean
|
||||||
|
|||||||
@@ -72,12 +72,10 @@
|
|||||||
|
|
||||||
<div class="p-4">
|
<div class="p-4">
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
<Button
|
<Button variant="secondary" @click="handleCancel">
|
||||||
icon="pi pi-times"
|
<i class="pi pi-times" />
|
||||||
severity="secondary"
|
{{ t('g.cancel') }}
|
||||||
:label="t('g.cancel')"
|
</Button>
|
||||||
@click="handleCancel"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -85,7 +83,6 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
|
||||||
import { onBeforeUnmount, onMounted, ref, toRaw } from 'vue'
|
import { onBeforeUnmount, onMounted, ref, toRaw } from 'vue'
|
||||||
|
|
||||||
import CameraControls from '@/components/load3d/controls/viewer/ViewerCameraControls.vue'
|
import CameraControls from '@/components/load3d/controls/viewer/ViewerCameraControls.vue'
|
||||||
@@ -93,6 +90,7 @@ import ExportControls from '@/components/load3d/controls/viewer/ViewerExportCont
|
|||||||
import LightControls from '@/components/load3d/controls/viewer/ViewerLightControls.vue'
|
import LightControls from '@/components/load3d/controls/viewer/ViewerLightControls.vue'
|
||||||
import ModelControls from '@/components/load3d/controls/viewer/ViewerModelControls.vue'
|
import ModelControls from '@/components/load3d/controls/viewer/ViewerModelControls.vue'
|
||||||
import SceneControls from '@/components/load3d/controls/viewer/ViewerSceneControls.vue'
|
import SceneControls from '@/components/load3d/controls/viewer/ViewerSceneControls.vue'
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import { useLoad3dDrag } from '@/composables/useLoad3dDrag'
|
import { useLoad3dDrag } from '@/composables/useLoad3dDrag'
|
||||||
import { useLoad3dViewer } from '@/composables/useLoad3dViewer'
|
import { useLoad3dViewer } from '@/composables/useLoad3dViewer'
|
||||||
import { t } from '@/i18n'
|
import { t } from '@/i18n'
|
||||||
|
|||||||
@@ -3,7 +3,13 @@
|
|||||||
v-if="animations && animations.length > 0"
|
v-if="animations && animations.length > 0"
|
||||||
class="pointer-events-auto absolute top-0 left-0 z-10 flex w-full items-center justify-center gap-2 pt-2"
|
class="pointer-events-auto absolute top-0 left-0 z-10 flex w-full items-center justify-center gap-2 pt-2"
|
||||||
>
|
>
|
||||||
<Button class="p-button-rounded p-button-text" @click="togglePlay">
|
<Button
|
||||||
|
size="icon"
|
||||||
|
variant="textonly"
|
||||||
|
class="rounded-full"
|
||||||
|
:aria-label="$t('g.playPause')"
|
||||||
|
@click="togglePlay"
|
||||||
|
>
|
||||||
<i
|
<i
|
||||||
:class="['pi', playing ? 'pi-pause' : 'pi-play', 'text-lg text-white']"
|
:class="['pi', playing ? 'pi-pause' : 'pi-play', 'text-lg text-white']"
|
||||||
/>
|
/>
|
||||||
@@ -28,9 +34,10 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
|
||||||
import Select from 'primevue/select'
|
import Select from 'primevue/select'
|
||||||
|
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
|
|
||||||
type Animation = { name: string; index: number }
|
type Animation = { name: string; index: number }
|
||||||
|
|
||||||
const animations = defineModel<Animation[]>('animations')
|
const animations = defineModel<Animation[]>('animations')
|
||||||
|
|||||||
@@ -1,13 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<Button class="p-button-rounded p-button-text" @click="switchCamera">
|
<Button
|
||||||
<i
|
v-tooltip.right="{
|
||||||
v-tooltip.right="{
|
value: $t('load3d.switchCamera'),
|
||||||
value: $t('load3d.switchCamera'),
|
showDelay: 300
|
||||||
showDelay: 300
|
}"
|
||||||
}"
|
size="icon"
|
||||||
:class="['pi', 'pi-camera', 'text-lg text-white']"
|
variant="textonly"
|
||||||
/>
|
class="rounded-full"
|
||||||
|
:aria-label="$t('load3d.switchCamera')"
|
||||||
|
@click="switchCamera"
|
||||||
|
>
|
||||||
|
<i :class="['pi', 'pi-camera', 'text-lg text-white']" />
|
||||||
</Button>
|
</Button>
|
||||||
<PopupSlider
|
<PopupSlider
|
||||||
v-if="showFOVButton"
|
v-if="showFOVButton"
|
||||||
@@ -18,10 +22,10 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
|
|
||||||
import PopupSlider from '@/components/load3d/controls/PopupSlider.vue'
|
import PopupSlider from '@/components/load3d/controls/PopupSlider.vue'
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import type { CameraType } from '@/extensions/core/load3d/interfaces'
|
import type { CameraType } from '@/extensions/core/load3d/interfaces'
|
||||||
|
|
||||||
const cameraType = defineModel<CameraType>('cameraType')
|
const cameraType = defineModel<CameraType>('cameraType')
|
||||||
|
|||||||
@@ -2,16 +2,17 @@
|
|||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<div class="show-export-formats relative">
|
<div class="show-export-formats relative">
|
||||||
<Button
|
<Button
|
||||||
class="p-button-rounded p-button-text"
|
v-tooltip.right="{
|
||||||
|
value: $t('load3d.exportModel'),
|
||||||
|
showDelay: 300
|
||||||
|
}"
|
||||||
|
size="icon"
|
||||||
|
variant="textonly"
|
||||||
|
class="rounded-full"
|
||||||
|
:aria-label="$t('load3d.exportModel')"
|
||||||
@click="toggleExportFormats"
|
@click="toggleExportFormats"
|
||||||
>
|
>
|
||||||
<i
|
<i class="pi pi-download text-lg text-white" />
|
||||||
v-tooltip.right="{
|
|
||||||
value: $t('load3d.exportModel'),
|
|
||||||
showDelay: 300
|
|
||||||
}"
|
|
||||||
class="pi pi-download text-lg text-white"
|
|
||||||
/>
|
|
||||||
</Button>
|
</Button>
|
||||||
<div
|
<div
|
||||||
v-show="showExportFormats"
|
v-show="showExportFormats"
|
||||||
@@ -21,7 +22,8 @@
|
|||||||
<Button
|
<Button
|
||||||
v-for="format in exportFormats"
|
v-for="format in exportFormats"
|
||||||
:key="format.value"
|
:key="format.value"
|
||||||
class="p-button-text text-white"
|
variant="textonly"
|
||||||
|
class="text-white"
|
||||||
@click="exportModel(format.value)"
|
@click="exportModel(format.value)"
|
||||||
>
|
>
|
||||||
{{ format.label }}
|
{{ format.label }}
|
||||||
@@ -33,9 +35,10 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
|
||||||
import { onMounted, onUnmounted, ref } from 'vue'
|
import { onMounted, onUnmounted, ref } from 'vue'
|
||||||
|
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'exportModel', format: string): void
|
(e: 'exportModel', format: string): void
|
||||||
}>()
|
}>()
|
||||||
@@ -48,17 +51,17 @@ const exportFormats = [
|
|||||||
{ label: 'STL', value: 'stl' }
|
{ label: 'STL', value: 'stl' }
|
||||||
]
|
]
|
||||||
|
|
||||||
const toggleExportFormats = () => {
|
function toggleExportFormats() {
|
||||||
showExportFormats.value = !showExportFormats.value
|
showExportFormats.value = !showExportFormats.value
|
||||||
}
|
}
|
||||||
|
|
||||||
const exportModel = (format: string) => {
|
function exportModel(format: string) {
|
||||||
emit('exportModel', format)
|
emit('exportModel', format)
|
||||||
|
|
||||||
showExportFormats.value = false
|
showExportFormats.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
const closeExportFormatsList = (e: MouseEvent) => {
|
function closeExportFormatsList(e: MouseEvent) {
|
||||||
const target = e.target as HTMLElement
|
const target = e.target as HTMLElement
|
||||||
|
|
||||||
if (!target.closest('.show-export-formats')) {
|
if (!target.closest('.show-export-formats')) {
|
||||||
|
|||||||
@@ -2,16 +2,17 @@
|
|||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<div v-if="showLightIntensityButton" class="show-light-intensity relative">
|
<div v-if="showLightIntensityButton" class="show-light-intensity relative">
|
||||||
<Button
|
<Button
|
||||||
class="p-button-rounded p-button-text"
|
v-tooltip.right="{
|
||||||
|
value: $t('load3d.lightIntensity'),
|
||||||
|
showDelay: 300
|
||||||
|
}"
|
||||||
|
size="icon"
|
||||||
|
variant="textonly"
|
||||||
|
class="rounded-full"
|
||||||
|
:aria-label="$t('load3d.lightIntensity')"
|
||||||
@click="toggleLightIntensity"
|
@click="toggleLightIntensity"
|
||||||
>
|
>
|
||||||
<i
|
<i class="pi pi-sun text-lg text-white" />
|
||||||
v-tooltip.right="{
|
|
||||||
value: $t('load3d.lightIntensity'),
|
|
||||||
showDelay: 300
|
|
||||||
}"
|
|
||||||
class="pi pi-sun text-lg text-white"
|
|
||||||
/>
|
|
||||||
</Button>
|
</Button>
|
||||||
<div
|
<div
|
||||||
v-show="showLightIntensity"
|
v-show="showLightIntensity"
|
||||||
@@ -31,10 +32,10 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
|
||||||
import Slider from 'primevue/slider'
|
import Slider from 'primevue/slider'
|
||||||
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||||
|
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import type { MaterialMode } from '@/extensions/core/load3d/interfaces'
|
import type { MaterialMode } from '@/extensions/core/load3d/interfaces'
|
||||||
import { useSettingStore } from '@/platform/settings/settingStore'
|
import { useSettingStore } from '@/platform/settings/settingStore'
|
||||||
|
|
||||||
@@ -56,11 +57,11 @@ const lightAdjustmentIncrement = useSettingStore().get(
|
|||||||
'Comfy.Load3D.LightAdjustmentIncrement'
|
'Comfy.Load3D.LightAdjustmentIncrement'
|
||||||
)
|
)
|
||||||
|
|
||||||
const toggleLightIntensity = () => {
|
function toggleLightIntensity() {
|
||||||
showLightIntensity.value = !showLightIntensity.value
|
showLightIntensity.value = !showLightIntensity.value
|
||||||
}
|
}
|
||||||
|
|
||||||
const closeLightSlider = (e: MouseEvent) => {
|
function closeLightSlider(e: MouseEvent) {
|
||||||
const target = e.target as HTMLElement
|
const target = e.target as HTMLElement
|
||||||
|
|
||||||
if (!target.closest('.show-light-intensity')) {
|
if (!target.closest('.show-light-intensity')) {
|
||||||
|
|||||||
@@ -1,14 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<div class="show-up-direction relative">
|
<div class="show-up-direction relative">
|
||||||
<Button class="p-button-rounded p-button-text" @click="toggleUpDirection">
|
<Button
|
||||||
<i
|
v-tooltip.right="{
|
||||||
v-tooltip.right="{
|
value: t('load3d.upDirection'),
|
||||||
value: t('load3d.upDirection'),
|
showDelay: 300
|
||||||
showDelay: 300
|
}"
|
||||||
}"
|
size="icon"
|
||||||
class="pi pi-arrow-up text-lg text-white"
|
variant="textonly"
|
||||||
/>
|
class="rounded-full"
|
||||||
|
:aria-label="t('load3d.upDirection')"
|
||||||
|
@click="toggleUpDirection"
|
||||||
|
>
|
||||||
|
<i class="pi pi-arrow-up text-lg text-white" />
|
||||||
</Button>
|
</Button>
|
||||||
<div
|
<div
|
||||||
v-show="showUpDirection"
|
v-show="showUpDirection"
|
||||||
@@ -18,8 +22,10 @@
|
|||||||
<Button
|
<Button
|
||||||
v-for="direction in upDirections"
|
v-for="direction in upDirections"
|
||||||
:key="direction"
|
:key="direction"
|
||||||
class="p-button-text text-white"
|
variant="textonly"
|
||||||
:class="{ 'bg-blue-500': upDirection === direction }"
|
:class="
|
||||||
|
cn('text-white', upDirection === direction && 'bg-blue-500')
|
||||||
|
"
|
||||||
@click="selectUpDirection(direction)"
|
@click="selectUpDirection(direction)"
|
||||||
>
|
>
|
||||||
{{ direction.toUpperCase() }}
|
{{ direction.toUpperCase() }}
|
||||||
@@ -30,16 +36,17 @@
|
|||||||
|
|
||||||
<div v-if="!hideMaterialMode" class="show-material-mode relative">
|
<div v-if="!hideMaterialMode" class="show-material-mode relative">
|
||||||
<Button
|
<Button
|
||||||
class="p-button-rounded p-button-text"
|
v-tooltip.right="{
|
||||||
|
value: t('load3d.materialMode'),
|
||||||
|
showDelay: 300
|
||||||
|
}"
|
||||||
|
size="icon"
|
||||||
|
variant="textonly"
|
||||||
|
class="rounded-full"
|
||||||
|
:aria-label="t('load3d.materialMode')"
|
||||||
@click="toggleMaterialMode"
|
@click="toggleMaterialMode"
|
||||||
>
|
>
|
||||||
<i
|
<i class="pi pi-box text-lg text-white" />
|
||||||
v-tooltip.right="{
|
|
||||||
value: t('load3d.materialMode'),
|
|
||||||
showDelay: 300
|
|
||||||
}"
|
|
||||||
class="pi pi-box text-lg text-white"
|
|
||||||
/>
|
|
||||||
</Button>
|
</Button>
|
||||||
<div
|
<div
|
||||||
v-show="showMaterialMode"
|
v-show="showMaterialMode"
|
||||||
@@ -49,8 +56,13 @@
|
|||||||
<Button
|
<Button
|
||||||
v-for="mode in materialModes"
|
v-for="mode in materialModes"
|
||||||
:key="mode"
|
:key="mode"
|
||||||
class="p-button-text whitespace-nowrap text-white"
|
variant="textonly"
|
||||||
:class="{ 'bg-blue-500': materialMode === mode }"
|
:class="
|
||||||
|
cn(
|
||||||
|
'whitespace-nowrap text-white',
|
||||||
|
materialMode === mode && 'bg-blue-500'
|
||||||
|
)
|
||||||
|
"
|
||||||
@click="selectMaterialMode(mode)"
|
@click="selectMaterialMode(mode)"
|
||||||
>
|
>
|
||||||
{{ formatMaterialMode(mode) }}
|
{{ formatMaterialMode(mode) }}
|
||||||
@@ -62,14 +74,15 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
|
||||||
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||||
|
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import type {
|
import type {
|
||||||
MaterialMode,
|
MaterialMode,
|
||||||
UpDirection
|
UpDirection
|
||||||
} from '@/extensions/core/load3d/interfaces'
|
} from '@/extensions/core/load3d/interfaces'
|
||||||
import { t } from '@/i18n'
|
import { t } from '@/i18n'
|
||||||
|
import { cn } from '@/utils/tailwindUtil'
|
||||||
|
|
||||||
const { hideMaterialMode = false, isPlyModel = false } = defineProps<{
|
const { hideMaterialMode = false, isPlyModel = false } = defineProps<{
|
||||||
hideMaterialMode?: boolean
|
hideMaterialMode?: boolean
|
||||||
@@ -108,31 +121,31 @@ const materialModes = computed(() => {
|
|||||||
return modes
|
return modes
|
||||||
})
|
})
|
||||||
|
|
||||||
const toggleUpDirection = () => {
|
function toggleUpDirection() {
|
||||||
showUpDirection.value = !showUpDirection.value
|
showUpDirection.value = !showUpDirection.value
|
||||||
showMaterialMode.value = false
|
showMaterialMode.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
const selectUpDirection = (direction: UpDirection) => {
|
function selectUpDirection(direction: UpDirection) {
|
||||||
upDirection.value = direction
|
upDirection.value = direction
|
||||||
showUpDirection.value = false
|
showUpDirection.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
const toggleMaterialMode = () => {
|
function toggleMaterialMode() {
|
||||||
showMaterialMode.value = !showMaterialMode.value
|
showMaterialMode.value = !showMaterialMode.value
|
||||||
showUpDirection.value = false
|
showUpDirection.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
const selectMaterialMode = (mode: MaterialMode) => {
|
function selectMaterialMode(mode: MaterialMode) {
|
||||||
materialMode.value = mode
|
materialMode.value = mode
|
||||||
showMaterialMode.value = false
|
showMaterialMode.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
const formatMaterialMode = (mode: MaterialMode) => {
|
function formatMaterialMode(mode: MaterialMode) {
|
||||||
return t(`load3d.materialModes.${mode}`)
|
return t(`load3d.materialModes.${mode}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const closeSceneSlider = (e: MouseEvent) => {
|
function closeSceneSlider(e: MouseEvent) {
|
||||||
const target = e.target as HTMLElement
|
const target = e.target as HTMLElement
|
||||||
|
|
||||||
if (!target.closest('.show-up-direction')) {
|
if (!target.closest('.show-up-direction')) {
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="relative show-slider">
|
<div class="relative show-slider">
|
||||||
<Button class="p-button-rounded p-button-text" @click="toggleSlider">
|
<Button
|
||||||
<i
|
v-tooltip.right="{ value: tooltipText, showDelay: 300 }"
|
||||||
v-tooltip.right="{ value: tooltipText, showDelay: 300 }"
|
size="icon"
|
||||||
:class="['pi', icon, 'text-lg text-white']"
|
variant="textonly"
|
||||||
/>
|
class="rounded-full"
|
||||||
|
:aria-label="tooltipText"
|
||||||
|
@click="toggleSlider"
|
||||||
|
>
|
||||||
|
<i :class="['pi', icon, 'text-lg text-white']" />
|
||||||
</Button>
|
</Button>
|
||||||
<div
|
<div
|
||||||
v-show="showSlider"
|
v-show="showSlider"
|
||||||
@@ -22,10 +26,11 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
|
||||||
import Slider from 'primevue/slider'
|
import Slider from 'primevue/slider'
|
||||||
import { onMounted, onUnmounted, ref } from 'vue'
|
import { onMounted, onUnmounted, ref } from 'vue'
|
||||||
|
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
|
|
||||||
const {
|
const {
|
||||||
icon = 'pi-expand',
|
icon = 'pi-expand',
|
||||||
min = 10,
|
min = 10,
|
||||||
|
|||||||
@@ -2,20 +2,26 @@
|
|||||||
<div class="relative rounded-lg bg-smoke-700/30">
|
<div class="relative rounded-lg bg-smoke-700/30">
|
||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
<Button
|
<Button
|
||||||
class="p-button-rounded p-button-text"
|
v-tooltip.right="{
|
||||||
:class="{
|
value: isRecording
|
||||||
'p-button-danger': isRecording,
|
? $t('load3d.stopRecording')
|
||||||
'recording-button-blink': isRecording
|
: $t('load3d.startRecording'),
|
||||||
|
showDelay: 300
|
||||||
}"
|
}"
|
||||||
|
size="icon"
|
||||||
|
variant="textonly"
|
||||||
|
:class="
|
||||||
|
cn(
|
||||||
|
'rounded-full',
|
||||||
|
isRecording && 'text-red-500 recording-button-blink'
|
||||||
|
)
|
||||||
|
"
|
||||||
|
:aria-label="
|
||||||
|
isRecording ? $t('load3d.stopRecording') : $t('load3d.startRecording')
|
||||||
|
"
|
||||||
@click="toggleRecording"
|
@click="toggleRecording"
|
||||||
>
|
>
|
||||||
<i
|
<i
|
||||||
v-tooltip.right="{
|
|
||||||
value: isRecording
|
|
||||||
? $t('load3d.stopRecording')
|
|
||||||
: $t('load3d.startRecording'),
|
|
||||||
showDelay: 300
|
|
||||||
}"
|
|
||||||
:class="[
|
:class="[
|
||||||
'pi',
|
'pi',
|
||||||
isRecording ? 'pi-circle-fill' : 'pi-video',
|
isRecording ? 'pi-circle-fill' : 'pi-video',
|
||||||
@@ -26,30 +32,32 @@
|
|||||||
|
|
||||||
<Button
|
<Button
|
||||||
v-if="hasRecording && !isRecording"
|
v-if="hasRecording && !isRecording"
|
||||||
class="p-button-rounded p-button-text"
|
v-tooltip.right="{
|
||||||
|
value: $t('load3d.exportRecording'),
|
||||||
|
showDelay: 300
|
||||||
|
}"
|
||||||
|
size="icon"
|
||||||
|
variant="textonly"
|
||||||
|
class="rounded-full"
|
||||||
|
:aria-label="$t('load3d.exportRecording')"
|
||||||
@click="handleExportRecording"
|
@click="handleExportRecording"
|
||||||
>
|
>
|
||||||
<i
|
<i class="pi pi-download text-lg text-white" />
|
||||||
v-tooltip.right="{
|
|
||||||
value: $t('load3d.exportRecording'),
|
|
||||||
showDelay: 300
|
|
||||||
}"
|
|
||||||
class="pi pi-download text-lg text-white"
|
|
||||||
/>
|
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
v-if="hasRecording && !isRecording"
|
v-if="hasRecording && !isRecording"
|
||||||
class="p-button-rounded p-button-text"
|
v-tooltip.right="{
|
||||||
|
value: $t('load3d.clearRecording'),
|
||||||
|
showDelay: 300
|
||||||
|
}"
|
||||||
|
size="icon"
|
||||||
|
variant="textonly"
|
||||||
|
class="rounded-full"
|
||||||
|
:aria-label="$t('load3d.clearRecording')"
|
||||||
@click="handleClearRecording"
|
@click="handleClearRecording"
|
||||||
>
|
>
|
||||||
<i
|
<i class="pi pi-trash text-lg text-white" />
|
||||||
v-tooltip.right="{
|
|
||||||
value: $t('load3d.clearRecording'),
|
|
||||||
showDelay: 300
|
|
||||||
}"
|
|
||||||
class="pi pi-trash text-lg text-white"
|
|
||||||
/>
|
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
@@ -63,7 +71,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
|
import { cn } from '@/utils/tailwindUtil'
|
||||||
|
|
||||||
const hasRecording = defineModel<boolean>('hasRecording')
|
const hasRecording = defineModel<boolean>('hasRecording')
|
||||||
const isRecording = defineModel<boolean>('isRecording')
|
const isRecording = defineModel<boolean>('isRecording')
|
||||||
@@ -76,7 +85,7 @@ const emit = defineEmits<{
|
|||||||
(e: 'clearRecording'): void
|
(e: 'clearRecording'): void
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const toggleRecording = () => {
|
function toggleRecording() {
|
||||||
if (isRecording.value) {
|
if (isRecording.value) {
|
||||||
emit('stopRecording')
|
emit('stopRecording')
|
||||||
} else {
|
} else {
|
||||||
@@ -84,15 +93,15 @@ const toggleRecording = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleExportRecording = () => {
|
function handleExportRecording() {
|
||||||
emit('exportRecording')
|
emit('exportRecording')
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleClearRecording = () => {
|
function handleClearRecording() {
|
||||||
emit('clearRecording')
|
emit('clearRecording')
|
||||||
}
|
}
|
||||||
|
|
||||||
const formatDuration = (seconds: number): string => {
|
function formatDuration(seconds: number): string {
|
||||||
const minutes = Math.floor(seconds / 60)
|
const minutes = Math.floor(seconds / 60)
|
||||||
const remainingSeconds = Math.floor(seconds % 60)
|
const remainingSeconds = Math.floor(seconds % 60)
|
||||||
return `${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`
|
return `${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`
|
||||||
|
|||||||
@@ -1,25 +1,29 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<Button
|
<Button
|
||||||
class="p-button-rounded p-button-text"
|
v-tooltip.right="{ value: $t('load3d.showGrid'), showDelay: 300 }"
|
||||||
:class="{ 'p-button-outlined': showGrid }"
|
variant="textonly"
|
||||||
|
size="icon"
|
||||||
|
:class="cn('rounded-full', showGrid && 'ring-2 ring-white/50')"
|
||||||
|
:aria-label="$t('load3d.showGrid')"
|
||||||
@click="toggleGrid"
|
@click="toggleGrid"
|
||||||
>
|
>
|
||||||
<i
|
<i class="pi pi-table text-lg text-white" />
|
||||||
v-tooltip.right="{ value: $t('load3d.showGrid'), showDelay: 300 }"
|
|
||||||
class="pi pi-table text-lg text-white"
|
|
||||||
/>
|
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<div v-if="!hasBackgroundImage">
|
<div v-if="!hasBackgroundImage">
|
||||||
<Button class="p-button-rounded p-button-text" @click="openColorPicker">
|
<Button
|
||||||
<i
|
v-tooltip.right="{
|
||||||
v-tooltip.right="{
|
value: $t('load3d.backgroundColor'),
|
||||||
value: $t('load3d.backgroundColor'),
|
showDelay: 300
|
||||||
showDelay: 300
|
}"
|
||||||
}"
|
variant="textonly"
|
||||||
class="pi pi-palette text-lg text-white"
|
size="icon"
|
||||||
/>
|
class="rounded-full"
|
||||||
|
:aria-label="$t('load3d.backgroundColor')"
|
||||||
|
@click="openColorPicker"
|
||||||
|
>
|
||||||
|
<i class="pi pi-palette text-lg text-white" />
|
||||||
<input
|
<input
|
||||||
ref="colorPickerRef"
|
ref="colorPickerRef"
|
||||||
type="color"
|
type="color"
|
||||||
@@ -33,14 +37,18 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="!hasBackgroundImage">
|
<div v-if="!hasBackgroundImage">
|
||||||
<Button class="p-button-rounded p-button-text" @click="openImagePicker">
|
<Button
|
||||||
<i
|
v-tooltip.right="{
|
||||||
v-tooltip.right="{
|
value: $t('load3d.uploadBackgroundImage'),
|
||||||
value: $t('load3d.uploadBackgroundImage'),
|
showDelay: 300
|
||||||
showDelay: 300
|
}"
|
||||||
}"
|
variant="textonly"
|
||||||
class="pi pi-image text-lg text-white"
|
size="icon"
|
||||||
/>
|
class="rounded-full"
|
||||||
|
:aria-label="$t('load3d.uploadBackgroundImage')"
|
||||||
|
@click="openImagePicker"
|
||||||
|
>
|
||||||
|
<i class="pi pi-image text-lg text-white" />
|
||||||
<input
|
<input
|
||||||
ref="imagePickerRef"
|
ref="imagePickerRef"
|
||||||
type="file"
|
type="file"
|
||||||
@@ -53,17 +61,22 @@
|
|||||||
|
|
||||||
<div v-if="hasBackgroundImage">
|
<div v-if="hasBackgroundImage">
|
||||||
<Button
|
<Button
|
||||||
class="p-button-rounded p-button-text"
|
v-tooltip.right="{
|
||||||
:class="{ 'p-button-outlined': backgroundRenderMode === 'panorama' }"
|
value: $t('load3d.panoramaMode'),
|
||||||
|
showDelay: 300
|
||||||
|
}"
|
||||||
|
variant="textonly"
|
||||||
|
size="icon"
|
||||||
|
:class="
|
||||||
|
cn(
|
||||||
|
'rounded-full',
|
||||||
|
backgroundRenderMode === 'panorama' && 'ring-2 ring-white/50'
|
||||||
|
)
|
||||||
|
"
|
||||||
|
:aria-label="$t('load3d.panoramaMode')"
|
||||||
@click="toggleBackgroundRenderMode"
|
@click="toggleBackgroundRenderMode"
|
||||||
>
|
>
|
||||||
<i
|
<i class="pi pi-globe text-lg text-white" />
|
||||||
v-tooltip.right="{
|
|
||||||
value: $t('load3d.panoramaMode'),
|
|
||||||
showDelay: 300
|
|
||||||
}"
|
|
||||||
class="pi pi-globe text-lg text-white"
|
|
||||||
/>
|
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -75,27 +88,29 @@
|
|||||||
|
|
||||||
<div v-if="hasBackgroundImage">
|
<div v-if="hasBackgroundImage">
|
||||||
<Button
|
<Button
|
||||||
class="p-button-rounded p-button-text"
|
v-tooltip.right="{
|
||||||
|
value: $t('load3d.removeBackgroundImage'),
|
||||||
|
showDelay: 300
|
||||||
|
}"
|
||||||
|
variant="textonly"
|
||||||
|
size="icon"
|
||||||
|
class="rounded-full"
|
||||||
|
:aria-label="$t('load3d.removeBackgroundImage')"
|
||||||
@click="removeBackgroundImage"
|
@click="removeBackgroundImage"
|
||||||
>
|
>
|
||||||
<i
|
<i class="pi pi-times text-lg text-white" />
|
||||||
v-tooltip.right="{
|
|
||||||
value: $t('load3d.removeBackgroundImage'),
|
|
||||||
showDelay: 300
|
|
||||||
}"
|
|
||||||
class="pi pi-times text-lg text-white"
|
|
||||||
/>
|
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
|
||||||
import { computed, ref } from 'vue'
|
import { computed, ref } from 'vue'
|
||||||
|
|
||||||
import PopupSlider from '@/components/load3d/controls/PopupSlider.vue'
|
import PopupSlider from '@/components/load3d/controls/PopupSlider.vue'
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import type { BackgroundRenderModeType } from '@/extensions/core/load3d/interfaces'
|
import type { BackgroundRenderModeType } from '@/extensions/core/load3d/interfaces'
|
||||||
|
import { cn } from '@/utils/tailwindUtil'
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'updateBackgroundImage', file: File | null): void
|
(e: 'updateBackgroundImage', file: File | null): void
|
||||||
|
|||||||
@@ -1,23 +1,26 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="relative rounded-lg bg-smoke-700/30">
|
<div class="relative rounded-lg bg-smoke-700/30">
|
||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
<Button class="p-button-rounded p-button-text" @click="openIn3DViewer">
|
<Button
|
||||||
<i
|
v-tooltip.right="{
|
||||||
v-tooltip.right="{
|
value: t('load3d.openIn3DViewer'),
|
||||||
value: t('load3d.openIn3DViewer'),
|
showDelay: 300
|
||||||
showDelay: 300
|
}"
|
||||||
}"
|
size="icon"
|
||||||
class="pi pi-expand text-lg text-white"
|
variant="textonly"
|
||||||
/>
|
class="rounded-full"
|
||||||
|
:aria-label="t('load3d.openIn3DViewer')"
|
||||||
|
@click="openIn3DViewer"
|
||||||
|
>
|
||||||
|
<i class="pi pi-expand text-lg text-white" />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
|
||||||
|
|
||||||
import Load3DViewerContent from '@/components/load3d/Load3dViewerContent.vue'
|
import Load3DViewerContent from '@/components/load3d/Load3dViewerContent.vue'
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import { t } from '@/i18n'
|
import { t } from '@/i18n'
|
||||||
import type { LGraphNode } from '@/lib/litegraph/src/LGraphNode'
|
import type { LGraphNode } from '@/lib/litegraph/src/LGraphNode'
|
||||||
import { useLoad3dService } from '@/services/load3dService'
|
import { useLoad3dService } from '@/services/load3dService'
|
||||||
|
|||||||
@@ -9,9 +9,8 @@
|
|||||||
</Select>
|
</Select>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
severity="secondary"
|
variant="muted-textonly"
|
||||||
text
|
class="rounded-full"
|
||||||
rounded
|
|
||||||
@click="exportModel(exportFormat)"
|
@click="exportModel(exportFormat)"
|
||||||
>
|
>
|
||||||
{{ $t('load3d.export') }}
|
{{ $t('load3d.export') }}
|
||||||
@@ -20,10 +19,11 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
|
||||||
import Select from 'primevue/select'
|
import Select from 'primevue/select'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'exportModel', format: string): void
|
(e: 'exportModel', format: string): void
|
||||||
}>()
|
}>()
|
||||||
|
|||||||
@@ -15,13 +15,10 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="!hasBackgroundImage && !disableBackgroundUpload">
|
<div v-if="!hasBackgroundImage && !disableBackgroundUpload">
|
||||||
<Button
|
<Button variant="secondary" class="w-full" @click="openImagePicker">
|
||||||
severity="secondary"
|
<i class="pi pi-image" />
|
||||||
:label="$t('load3d.uploadBackgroundImage')"
|
{{ $t('load3d.uploadBackgroundImage') }}
|
||||||
icon="pi pi-image"
|
</Button>
|
||||||
class="w-full"
|
|
||||||
@click="openImagePicker"
|
|
||||||
/>
|
|
||||||
<input
|
<input
|
||||||
ref="imagePickerRef"
|
ref="imagePickerRef"
|
||||||
type="file"
|
type="file"
|
||||||
@@ -34,38 +31,38 @@
|
|||||||
<div v-if="hasBackgroundImage" class="space-y-2">
|
<div v-if="hasBackgroundImage" class="space-y-2">
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
<Button
|
<Button
|
||||||
:severity="backgroundRenderMode === 'tiled' ? 'primary' : 'secondary'"
|
:variant="backgroundRenderMode === 'tiled' ? 'primary' : 'secondary'"
|
||||||
:label="$t('load3d.tiledMode')"
|
|
||||||
icon="pi pi-th-large"
|
|
||||||
class="flex-1"
|
class="flex-1"
|
||||||
@click="setBackgroundRenderMode('tiled')"
|
@click="setBackgroundRenderMode('tiled')"
|
||||||
/>
|
>
|
||||||
|
<i class="pi pi-th-large" />
|
||||||
|
{{ $t('load3d.tiledMode') }}
|
||||||
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
:severity="
|
:variant="
|
||||||
backgroundRenderMode === 'panorama' ? 'primary' : 'secondary'
|
backgroundRenderMode === 'panorama' ? 'primary' : 'secondary'
|
||||||
"
|
"
|
||||||
:label="$t('load3d.panoramaMode')"
|
|
||||||
icon="pi pi-globe"
|
|
||||||
class="flex-1"
|
class="flex-1"
|
||||||
@click="setBackgroundRenderMode('panorama')"
|
@click="setBackgroundRenderMode('panorama')"
|
||||||
/>
|
>
|
||||||
|
<i class="pi pi-globe" />
|
||||||
|
{{ $t('load3d.panoramaMode') }}
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<Button
|
<Button variant="secondary" class="w-full" @click="removeBackgroundImage">
|
||||||
severity="secondary"
|
<i class="pi pi-times" />
|
||||||
:label="$t('load3d.removeBackgroundImage')"
|
{{ $t('load3d.removeBackgroundImage') }}
|
||||||
icon="pi pi-times"
|
</Button>
|
||||||
class="w-full"
|
|
||||||
@click="removeBackgroundImage"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
|
||||||
import Checkbox from 'primevue/checkbox'
|
import Checkbox from 'primevue/checkbox'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
|
|
||||||
const backgroundColor = defineModel<string>('backgroundColor')
|
const backgroundColor = defineModel<string>('backgroundColor')
|
||||||
const showGrid = defineModel<boolean>('showGrid')
|
const showGrid = defineModel<boolean>('showGrid')
|
||||||
const backgroundRenderMode = defineModel<'tiled' | 'panorama'>(
|
const backgroundRenderMode = defineModel<'tiled' | 'panorama'>(
|
||||||
|
|||||||
@@ -46,28 +46,22 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex gap-3">
|
<div class="flex gap-3">
|
||||||
<Button
|
<Button variant="primary" :disabled="!saveEnabled" @click="handleSave">
|
||||||
:label="saveButtonText"
|
<i class="pi pi-check" />
|
||||||
icon="pi pi-check"
|
{{ saveButtonText }}
|
||||||
size="small"
|
</Button>
|
||||||
:disabled="!saveEnabled"
|
<Button variant="secondary" @click="handleCancel">
|
||||||
@click="handleSave"
|
<i class="pi pi-times" />
|
||||||
/>
|
{{ t('g.cancel') }}
|
||||||
<Button
|
</Button>
|
||||||
:label="t('g.cancel')"
|
|
||||||
icon="pi pi-times"
|
|
||||||
size="small"
|
|
||||||
severity="secondary"
|
|
||||||
@click="handleCancel"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import { useCanvasTools } from '@/composables/maskeditor/useCanvasTools'
|
import { useCanvasTools } from '@/composables/maskeditor/useCanvasTools'
|
||||||
import { useMaskEditorSaver } from '@/composables/maskeditor/useMaskEditorSaver'
|
import { useMaskEditorSaver } from '@/composables/maskeditor/useMaskEditorSaver'
|
||||||
import { t } from '@/i18n'
|
import { t } from '@/i18n'
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { watchDebounced } from '@vueuse/core'
|
import { watchDebounced } from '@vueuse/core'
|
||||||
import Button from 'primevue/button'
|
|
||||||
import {
|
import {
|
||||||
computed,
|
computed,
|
||||||
customRef,
|
customRef,
|
||||||
@@ -10,6 +9,7 @@ import {
|
|||||||
triggerRef
|
triggerRef
|
||||||
} from 'vue'
|
} from 'vue'
|
||||||
|
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import {
|
import {
|
||||||
demoteWidget,
|
demoteWidget,
|
||||||
isRecommendedWidget,
|
isRecommendedWidget,
|
||||||
@@ -315,7 +315,7 @@ onBeforeUnmount(() => {
|
|||||||
class="flex justify-center border-t border-interface-stroke py-4"
|
class="flex justify-center border-t border-interface-stroke py-4"
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
size="small"
|
size="sm"
|
||||||
class="rounded border-none px-3 py-0.5"
|
class="rounded border-none px-3 py-0.5"
|
||||||
@click.stop="showRecommended"
|
@click.stop="showRecommended"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Button from 'primevue/button'
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
|
|
||||||
import { cn } from '@/utils/tailwindUtil'
|
import { cn } from '@/utils/tailwindUtil'
|
||||||
import type { ClassValue } from '@/utils/tailwindUtil'
|
import type { ClassValue } from '@/utils/tailwindUtil'
|
||||||
|
|
||||||
@@ -43,13 +42,13 @@ function getIcon() {
|
|||||||
<div class="text-sm line-clamp-1 leading-8">{{ widgetName }}</div>
|
<div class="text-sm line-clamp-1 leading-8">{{ widgetName }}</div>
|
||||||
</div>
|
</div>
|
||||||
<Button
|
<Button
|
||||||
size="small"
|
variant="muted-textonly"
|
||||||
text
|
size="sm"
|
||||||
:icon="getIcon()"
|
|
||||||
:disabled="isPhysical"
|
:disabled="isPhysical"
|
||||||
severity="secondary"
|
|
||||||
@click.stop="$emit('toggleVisibility')"
|
@click.stop="$emit('toggleVisibility')"
|
||||||
/>
|
>
|
||||||
|
<i :class="getIcon()" />
|
||||||
|
</Button>
|
||||||
<div
|
<div
|
||||||
v-if="isDraggable"
|
v-if="isDraggable"
|
||||||
class="size-4 pointer-events-none icon-[lucide--grip-vertical]"
|
class="size-4 pointer-events-none icon-[lucide--grip-vertical]"
|
||||||
|
|||||||
@@ -14,11 +14,13 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
icon="pi pi-filter"
|
variant="secondary"
|
||||||
severity="secondary"
|
:aria-label="$t('g.addNodeFilterCondition')"
|
||||||
class="filter-button z-10"
|
class="filter-button z-10"
|
||||||
@click="nodeSearchFilterVisible = true"
|
@click="nodeSearchFilterVisible = true"
|
||||||
/>
|
>
|
||||||
|
<i class="pi pi-filter" />
|
||||||
|
</Button>
|
||||||
<Dialog
|
<Dialog
|
||||||
v-model:visible="nodeSearchFilterVisible"
|
v-model:visible="nodeSearchFilterVisible"
|
||||||
class="min-w-96"
|
class="min-w-96"
|
||||||
@@ -79,7 +81,6 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { debounce } from 'es-toolkit/compat'
|
import { debounce } from 'es-toolkit/compat'
|
||||||
import Button from 'primevue/button'
|
|
||||||
import Dialog from 'primevue/dialog'
|
import Dialog from 'primevue/dialog'
|
||||||
import { computed, nextTick, onMounted, ref } from 'vue'
|
import { computed, nextTick, onMounted, ref } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
@@ -88,6 +89,7 @@ import NodePreview from '@/components/node/NodePreview.vue'
|
|||||||
import AutoCompletePlus from '@/components/primevueOverride/AutoCompletePlus.vue'
|
import AutoCompletePlus from '@/components/primevueOverride/AutoCompletePlus.vue'
|
||||||
import NodeSearchFilter from '@/components/searchbox/NodeSearchFilter.vue'
|
import NodeSearchFilter from '@/components/searchbox/NodeSearchFilter.vue'
|
||||||
import NodeSearchItem from '@/components/searchbox/NodeSearchItem.vue'
|
import NodeSearchItem from '@/components/searchbox/NodeSearchItem.vue'
|
||||||
|
import Button from '@/components/ui/button/Button.vue'
|
||||||
import { useSettingStore } from '@/platform/settings/settingStore'
|
import { useSettingStore } from '@/platform/settings/settingStore'
|
||||||
import { useTelemetry } from '@/platform/telemetry'
|
import { useTelemetry } from '@/platform/telemetry'
|
||||||
import type { ComfyNodeDefImpl } from '@/stores/nodeDefStore'
|
import type { ComfyNodeDefImpl } from '@/stores/nodeDefStore'
|
||||||
|
|||||||