feat(workspace): Enhanced sidebar, account switcher, and dashboard templates
- Reorganized sidebar layout with logo dropdown menu at top - Added account dropdown with Netflix-style workspace/role switcher - Team workspaces with roles: Workflow Builder, Visual Artist, Motion Designer, Project Manager - Added Shared Projects and Starred sections for team view - Dashboard templates section with "View Templates" CTA button - Added WorkspaceCard and WorkspaceFilterSelect components - Added TemplatesView page with category filtering - PrimeVue Popover styling overrides for dark theme - Updated account display to show user name and workspace type - Various workspace view improvements and thumbnail assets 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
|
After Width: | Height: | Size: 640 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 750 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 216 KiB |
BIN
ComfyUI_vibe/public/assets/card_images/comfyui_workflow.jpg
Normal file
|
After Width: | Height: | Size: 587 KiB |
|
After Width: | Height: | Size: 206 KiB |
BIN
ComfyUI_vibe/public/assets/card_images/workflow_01.webp
Normal file
|
After Width: | Height: | Size: 58 KiB |
146
ComfyUI_vibe/public/comfy-logo-blue.svg
Normal file
@@ -0,0 +1,146 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 450 125.2">
|
||||
<!-- Generator: Adobe Illustrator 29.5.1, SVG Export Plug-In . SVG Version: 2.1.0 Build 141) -->
|
||||
<defs>
|
||||
<style>
|
||||
.st0 {
|
||||
fill: #1b2dce;
|
||||
}
|
||||
|
||||
.st1 {
|
||||
fill: #fff;
|
||||
}
|
||||
|
||||
.st2 {
|
||||
opacity: .6;
|
||||
}
|
||||
|
||||
.st3 {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<g id="watermark" class="st3">
|
||||
<g>
|
||||
<g id="watermark1" data-name="watermark" class="st2">
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<polygon class="st1" points="188.8 273.8 183.2 286.6 180.3 286.6 174.7 273.8 177.9 273.8 181.8 283 185.8 273.8 188.8 273.8"/>
|
||||
<path class="st1" d="M198.5,282.3h-7.5c.3,1.2,1.3,2,2.8,2s1.8-.3,2.5-1l1.5,1.7c-.9,1-2.3,1.6-4.1,1.6-3.4,0-5.6-2.1-5.6-5.1s2.3-5.1,5.3-5.1,5.1,1.9,5.1,5.1c0,.2,0,.5,0,.8M191,280.7h4.9c-.2-1.2-1.1-2.1-2.4-2.1-1.3,0-2.2.8-2.4,2.1"/>
|
||||
<path class="st1" d="M199.7,281.5c0-3,2.3-5.1,5.5-5.1s3.7.9,4.4,2.5l-2.2,1.2c-.5-.9-1.3-1.4-2.2-1.4-1.4,0-2.6,1-2.6,2.7s1.1,2.7,2.6,2.7,1.7-.4,2.2-1.4l2.2,1.2c-.7,1.6-2.3,2.5-4.4,2.5-3.2,0-5.5-2.1-5.5-5.1"/>
|
||||
<path class="st1" d="M217.8,286c-.6.4-1.4.6-2.3.6-2.3,0-3.7-1.2-3.7-3.5v-4.1h-1.5v-2.2h1.5v-2.4h2.9v2.4h2.5v2.2h-2.5v4c0,.8.5,1.3,1.2,1.3s.8-.1,1.2-.4l.8,2Z"/>
|
||||
</g>
|
||||
<path class="st1" d="M237.5,276.6v2.6c-.2,0-.4,0-.6,0-1.6,0-2.6.9-2.6,2.8v4.7h-2.9v-9.9h2.7v1.3c.7-1,1.9-1.5,3.4-1.5"/>
|
||||
<path class="st1" d="M238.3,285.1l1-2.2c1.1.8,2.7,1.3,4.2,1.3s2.5-.6,2.5-1.4c0-2.4-7.5-.8-7.5-5.5s1.8-4,5.4-4,3.3.4,4.5,1.1l-.9,2.3c-1.2-.7-2.4-1-3.6-1-1.8,0-2.4.7-2.4,1.5,0,2.4,7.5.7,7.5,5.5s-1.8,4-5.5,4c-2,0-4.1-.6-5.2-1.5"/>
|
||||
<path class="st1" d="M260.4,282.3h-7.5c.3,1.2,1.3,2,2.8,2s1.8-.3,2.5-1l1.5,1.7c-.9,1-2.3,1.6-4.1,1.6-3.4,0-5.6-2.1-5.6-5.1s2.3-5.1,5.3-5.1,5.1,1.9,5.1,5.1c0,.2,0,.5,0,.8M252.9,280.7h4.9c-.2-1.2-1.1-2.1-2.4-2.1-1.3,0-2.2.8-2.4,2.1"/>
|
||||
<path class="st1" d="M272,282.3h-7.5c.3,1.2,1.3,2,2.8,2s1.8-.3,2.5-1l1.5,1.7c-.9,1-2.3,1.6-4.1,1.6-3.4,0-5.6-2.1-5.6-5.1s2.3-5.1,5.3-5.1,5.1,1.9,5.1,5.1c0,.2,0,.5,0,.8M264.5,280.7h4.9c-.2-1.2-1.1-2.1-2.4-2.1-1.3,0-2.2.8-2.4,2.1"/>
|
||||
<polygon class="st1" points="278.2 282.8 276.8 284.1 276.8 286.6 274 286.6 274 273 276.8 273 276.8 280.7 281 276.8 284.4 276.8 280.3 280.9 284.8 286.6 281.3 286.6 278.2 282.8"/>
|
||||
<path class="st1" d="M231.6,288h0l-2.9-2.9c-.4.5-1,.9-1.5,1.3,0,0-.2.1-.3.2l3,3c.5.5,1.2.5,1.7,0,.5-.5.5-1.2,0-1.7"/>
|
||||
<path class="st1" d="M225,275.9c.2-.2.5-.3.8-.3s0,0,.1,0c-.2-.2-.5-.2-.8-.2s-.7.2-1,.5c0,0-.1,0-.2,0,0,0,0-.2,0-.3,0-.2-.1-.4-.3-.5,0,.1.1.3.1.4s0,.2,0,.3c-2.8.2-5,2.5-5,5.4s2.4,5.4,5.4,5.4,5.4-2.4,5.4-5.4c0-2.7-2-5-4.6-5.4M223,277.3c.4,0,.8.1,1.2.3.4-.2.8-.4,1.3-.4.7,0,1.3.3,1.8.8-.4-.4-1-.6-1.6-.6s-.9.1-1.2.3c0,0-.2,0-.2.1,0,0-.1,0-.2-.1-.4-.2-.8-.3-1.3-.3s-.6,0-.9.2c.3-.2.7-.3,1.1-.3M226.8,281.7c.1.3.2.6.2,1,0,1.5-1.2,2.8-2.8,2.8s-2.8-1.2-2.8-2.8,0-.7.2-1c-.6-.4-1-1.1-1-1.8,0-1.2,1-2.2,2.2-2.2s1.1.2,1.5.6c.4-.4.9-.6,1.5-.6,1.2,0,2.2,1,2.2,2.2s-.4,1.5-1,1.8"/>
|
||||
<path class="st1" d="M226.7,279.7c0,.5-.4.9-.9.9s-.9-.4-.9-.9.4-.9.9-.9.2,0,.3,0c0,0,0,.1,0,.2,0,.3.2.5.5.5s0,0,.1,0c0,0,0,.1,0,.2"/>
|
||||
<path class="st1" d="M223.3,279.7c0,.4-.3.7-.7.7s-.7-.3-.7-.7.3-.7.7-.7.1,0,.2,0c0,0,0,.1,0,.2,0,.2.2.4.4.4s0,0,.1,0c0,0,0,0,0,.1"/>
|
||||
<g>
|
||||
<g>
|
||||
<rect class="st1" x="217.9" y="280.4" width=".6" height=".6"/>
|
||||
<rect class="st1" x="229.8" y="280.4" width=".6" height=".6"/>
|
||||
<path class="st1" d="M230.2,280.7h-.1c0-3.2-2.6-5.9-5.9-5.9s-5.9,2.6-5.9,5.9h-.1c0-1.6.6-3.1,1.8-4.3s2.7-1.8,4.3-1.8,3.1.6,4.3,1.8c1.1,1.1,1.8,2.7,1.8,4.3"/>
|
||||
</g>
|
||||
<rect class="st1" x="223.9" y="274.4" width=".6" height=".6"/>
|
||||
<rect class="st1" x="219.9" y="274.7" width="8.4" height=".1"/>
|
||||
<path class="st1" d="M220.2,274.8c0,.1,0,.2-.2.2s-.2,0-.2-.2,0-.2.2-.2c.1,0,.2,0,.2.2"/>
|
||||
<path class="st1" d="M228.6,274.8c0,.1,0,.2-.2.2s-.2,0-.2-.2,0-.2.2-.2c.1,0,.2,0,.2.2"/>
|
||||
</g>
|
||||
</g>
|
||||
<path class="st1" d="M289.4,286c0,1.6-2.4,1.6-2.4,0,0-1.6,2.4-1.6,2.4,0Z"/>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st1" d="M136.7,279.2l1.8,6.1,1.9-6.1h2.2l-2.8,8.1h-2.3l-.8-2.4-.7-2.7-.7,2.7-.8,2.4h-2.3l-2.8-8.1h2.2l1.9,6.1,1.8-6.1h1.8Z"/>
|
||||
<path class="st1" d="M151.7,279.2l1.8,6.1,1.9-6.1h2.2l-2.8,8.1h-2.3l-.8-2.4-.7-2.7-.7,2.7-.8,2.4h-2.3l-2.8-8.1h2.2l1.9,6.1,1.8-6.1h1.8Z"/>
|
||||
<path class="st1" d="M166.7,279.2l1.8,6.1,1.9-6.1h2.2l-2.8,8.1h-2.3l-.8-2.4-.7-2.7-.7,2.7-.8,2.4h-2.3l-2.8-8.1h2.2l1.9,6.1,1.8-6.1h1.8Z"/>
|
||||
</g>
|
||||
<path class="st1" d="M175.9,286.1c0,1.6-2.4,1.6-2.4,0,0-1.6,2.4-1.6,2.4,0Z"/>
|
||||
<path class="st1" d="M297.7,286c-.9.9-1.9,1.3-3.1,1.3-2.3,0-4.3-1.4-4.3-4.3s2-4.3,4.3-4.3,2,.3,2.9,1.2l-1.3,1.3c-.5-.4-1.1-.6-1.6-.6-1.3,0-2.3,1-2.3,2.4s1,2.4,2.3,2.4,1.3-.2,1.8-.7l1.3,1.3Z"/>
|
||||
<path class="st1" d="M306.8,283.1c0,2.3-1.6,4.2-4.2,4.2s-4.2-1.9-4.2-4.2,1.6-4.2,4.2-4.2c2.6,0,4.2,1.9,4.2,4.2ZM300.4,283.1c0,1.2.7,2.4,2.2,2.4s2.2-1.1,2.2-2.4-.9-2.4-2.2-2.4c-1.4,0-2.2,1.2-2.2,2.4Z"/>
|
||||
<path class="st1" d="M313.6,287.3v-4.3c0-1.1-.6-2-1.7-2s-1.7,1-1.7,2v4.3h-2v-8.1h1.9v1c.6-.8,1.5-1.1,2.3-1.1s1.9.4,2.4,1.5c.7-1.1,1.7-1.5,2.7-1.5,2.3,0,3.4,1.4,3.4,3.8v4.4h-2v-4.4c0-1.1-.4-2-1.5-2s-1.8.9-1.8,2v4.3h-2Z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g class="st2">
|
||||
<g>
|
||||
<path class="st1" d="M321,243.9c0-1.2-1-2.1-2.2-2.1-.9,0-.8.1-.8-.9,0-1.1,0-2.2,0-3.3,0-.4-.1-.7-.4-1-2.3-2.7-4.7-5.3-7-8-.1-.1-.3-.2-.4-.4h-18.6c-.8.3-1.1.9-1.1,1.7,0,3.7,0,7.5,0,11.2s0,.6-.5.6c-1.5-.1-2.5,1-2.5,2.5,0,3.5,0,7,0,10.4,0,1.6.9,2.4,2.5,2.4q.6,0,.6.6c0,2.2,0,4.4,0,6.7,0,1.2.6,1.8,1.8,1.8,8,0,16,0,24,0,1.2,0,1.8-.6,1.8-1.7,0-2.3,0-4.5,0-6.8,0-.5,0-.5.5-.5.3,0,.5,0,.8,0,1-.2,1.7-1,1.7-2.1,0-3.7,0-7.4,0-11.1ZM292.5,229.8h16c.5,0,.6,0,.6.6,0,2.2,0,4.5,0,6.7,0,.8.2,1.1,1.1,1.1,1.9,0,3.8,0,5.7,0,.5,0,.5,0,.5.5,0,.9,0,1.8,0,2.7,0,.5,0,.5-.5.5-3.9,0-7.8,0-11.7,0h-11.6c-.5,0-.6,0-.6-.6,0-3.6,0-7.2,0-10.9,0-.6,0-.6.6-.6ZM315.8,264.2c-3.9,0-7.8,0-11.6,0h-11.6c-.6,0-.6,0-.6-.6,0-2,0-4,0-6,0-.5,0-.5.5-.5,7.8,0,15.6,0,23.4,0,.5,0,.5,0,.5.5,0,2,0,4,0,6,0,.6,0,.6-.6.6Z"/>
|
||||
<g>
|
||||
<rect class="st1" x="302.4" y="229.7" width="1.8" height="1.1"/>
|
||||
<rect class="st1" x="300.7" y="230.7" width="1.8" height="1.1"/>
|
||||
<rect class="st1" x="302.4" y="231.8" width="1.8" height="1.1"/>
|
||||
<rect class="st1" x="300.7" y="232.8" width="1.8" height="1.1"/>
|
||||
<rect class="st1" x="302.4" y="233.9" width="1.8" height="1.1"/>
|
||||
<rect class="st1" x="300.7" y="234.9" width="1.8" height="1.1"/>
|
||||
<rect class="st1" x="302.4" y="236" width="1.8" height="1.1"/>
|
||||
<rect class="st1" x="300.7" y="237" width="1.8" height="1.1"/>
|
||||
<rect class="st1" x="302.4" y="238.1" width="1.8" height="1.1"/>
|
||||
<rect class="st1" x="300.7" y="239.1" width="1.8" height="1.1"/>
|
||||
<rect class="st1" x="302.4" y="240.2" width="1.8" height="1.1"/>
|
||||
<rect class="st1" x="300.7" y="241.3" width="1.8" height="1.1"/>
|
||||
</g>
|
||||
</g>
|
||||
<path class="st1" d="M162.6,243.9c0-1.2-1-2.1-2.2-2.1-.9,0-.8.1-.8-.9,0-1.1,0-2.2,0-3.3,0-.4-.1-.7-.4-1-2.3-2.7-4.7-5.3-7-8-.1-.1-.3-.2-.4-.4h-18.6c-.8.3-1.1.9-1.1,1.7,0,3.7,0,7.5,0,11.2s0,.6-.6.6c-1.5-.1-2.5,1-2.5,2.5,0,3.5,0,7,0,10.4,0,1.6.9,2.4,2.4,2.4q.6,0,.6.6c0,2.2,0,4.4,0,6.7,0,1.2.6,1.8,1.8,1.8,8,0,16,0,24,0,1.2,0,1.8-.6,1.8-1.7,0-2.3,0-4.5,0-6.8,0-.5,0-.5.5-.5.3,0,.5,0,.8,0,1-.2,1.7-1,1.7-2.1,0-3.7,0-7.4,0-11.1ZM134.2,229.8h16c.5,0,.6,0,.6.6,0,2.2,0,4.5,0,6.7,0,.8.2,1.1,1.1,1.1,1.9,0,3.8,0,5.7,0,.5,0,.5,0,.5.5,0,.9,0,1.8,0,2.7,0,.5,0,.5-.5.5-3.9,0-7.8,0-11.7,0h-11.6c-.6,0-.6,0-.6-.6,0-3.6,0-7.2,0-10.9,0-.6,0-.6.6-.6ZM157.5,264.2c-3.9,0-7.8,0-11.6,0h-11.6c-.6,0-.6,0-.6-.6,0-2,0-4,0-6,0-.5,0-.5.5-.5,7.8,0,15.6,0,23.4,0,.5,0,.5,0,.5.5,0,2,0,4,0,6,0,.6,0,.6-.6.6Z"/>
|
||||
<g>
|
||||
<path class="st1" d="M134.8,253.3v-7.9h2.8c.4,0,.7,0,1.1.2s.6.3.9.5c.2.2.4.5.6.8.1.3.2.6.2,1s0,.7-.2,1-.3.6-.6.8c-.2.2-.5.4-.9.5s-.7.2-1.1.2h-1.3v2.9h-1.5ZM137.6,249c.4,0,.7-.1.9-.3.2-.2.3-.5.3-.8s0-.3,0-.4-.1-.2-.2-.3c0,0-.2-.2-.4-.2-.1,0-.3,0-.5,0h-1.3v2.2h1.3Z"/>
|
||||
<path class="st1" d="M141.3,245.4h1.7l3.2,5.3h0v-1.5c0,0,0-3.8,0-3.8h1.5v7.9h-1.6l-3.4-5.6h0v1.5c0,0,0,4.1,0,4.1h-1.5v-7.9h0Z"/>
|
||||
<path class="st1" d="M152.9,248.9h3.9c0,0,0,.2,0,.3,0,.1,0,.2,0,.4,0,.5,0,1-.2,1.4s-.4.8-.7,1.2c-.4.4-.8.7-1.3.9-.5.2-1.1.3-1.7.3s-1.1-.1-1.6-.3c-.5-.2-.9-.5-1.3-.9-.4-.4-.7-.8-.9-1.3s-.3-1.1-.3-1.6.1-1.1.3-1.6.5-.9.9-1.3c.4-.4.8-.7,1.3-.9s1-.3,1.6-.3,1.2.1,1.7.3.9.5,1.3.9l-1,1c-.3-.3-.5-.5-.9-.6-.3-.1-.7-.2-1.1-.2s-.7,0-1,.2c-.3.1-.6.3-.9.5-.2.2-.4.5-.6.9-.1.3-.2.7-.2,1.1s0,.8.2,1.1c.1.3.3.6.6.9.2.2.5.4.9.5.3.1.7.2,1,.2s.8,0,1.1-.2c.3-.1.5-.3.7-.5.1-.1.3-.3.4-.5.1-.2.2-.4.2-.7h-2.5v-1.3h0Z"/>
|
||||
</g>
|
||||
<path class="st1" d="M199,243.9c0-1.2-1-2.1-2.2-2.1-.9,0-.8.1-.8-.9,0-1.1,0-2.2,0-3.3,0-.4-.1-.7-.4-1-2.3-2.7-4.7-5.3-7-8-.1-.1-.3-.2-.4-.4h-18.6c-.8.3-1.1.9-1.1,1.7,0,3.7,0,7.5,0,11.2s0,.6-.6.6c-1.5-.1-2.5,1-2.5,2.5,0,3.5,0,7,0,10.4,0,1.6.9,2.4,2.4,2.4q.6,0,.6.6c0,2.2,0,4.4,0,6.7,0,1.2.6,1.8,1.8,1.8,8,0,16,0,24,0,1.2,0,1.8-.6,1.8-1.7,0-2.3,0-4.5,0-6.8,0-.5,0-.5.5-.5.3,0,.5,0,.8,0,1-.2,1.7-1,1.7-2.1,0-3.7,0-7.4,0-11.1ZM170.6,229.8h16c.5,0,.6,0,.6.6,0,2.2,0,4.5,0,6.7,0,.8.2,1.1,1.1,1.1,1.9,0,3.8,0,5.7,0,.5,0,.5,0,.5.5,0,.9,0,1.8,0,2.7,0,.5,0,.5-.5.5-3.9,0-7.8,0-11.7,0h-11.6c-.6,0-.6,0-.6-.6,0-3.6,0-7.2,0-10.9,0-.6,0-.6.6-.6ZM193.9,264.2c-3.9,0-7.8,0-11.6,0h-11.6c-.6,0-.6,0-.6-.6,0-2,0-4,0-6,0-.5,0-.5.5-.5,7.8,0,15.6,0,23.4,0,.5,0,.5,0,.5.5,0,2,0,4,0,6,0,.6,0,.6-.6.6Z"/>
|
||||
<g>
|
||||
<path class="st1" d="M180.1,245.4h1.7l3,7.9h-1.6l-.7-1.9h-3l-.7,1.9h-1.6l3-7.9ZM182,250l-.7-2-.3-1h0l-.3,1-.7,2h2.1Z"/>
|
||||
<path class="st1" d="M186.3,247.1c-.1,0-.2,0-.4,0s-.2-.1-.3-.2c0,0-.2-.2-.2-.3,0-.1,0-.2,0-.4s0-.3,0-.4c0-.1.1-.2.2-.3,0,0,.2-.2.3-.2.1,0,.2,0,.4,0,.3,0,.5,0,.7.3.2.2.3.4.3.7s0,.5-.3.7c-.2.2-.4.3-.7.3ZM185.6,253.3v-5.4h1.4v5.4h-1.4Z"/>
|
||||
</g>
|
||||
<path class="st1" d="M236,243.9c0-1.2-1-2.1-2.2-2.1-.9,0-.8.1-.8-.9,0-1.1,0-2.2,0-3.3,0-.4-.1-.7-.4-1-2.3-2.7-4.7-5.3-7-8-.1-.1-.3-.2-.4-.4h-18.6c-.8.3-1.1.9-1.1,1.7,0,3.7,0,7.5,0,11.2s0,.6-.6.6c-1.5-.1-2.5,1-2.5,2.5,0,3.5,0,7,0,10.4,0,1.6.9,2.4,2.4,2.4q.6,0,.6.6c0,2.2,0,4.4,0,6.7,0,1.2.6,1.8,1.8,1.8,8,0,16,0,24,0,1.2,0,1.8-.6,1.8-1.7,0-2.3,0-4.5,0-6.8,0-.5,0-.5.5-.5.3,0,.5,0,.8,0,1-.2,1.7-1,1.7-2.1,0-3.7,0-7.4,0-11.1ZM207.6,229.8h16c.5,0,.6,0,.6.6,0,2.2,0,4.5,0,6.7,0,.8.2,1.1,1.1,1.1,1.9,0,3.8,0,5.7,0,.5,0,.5,0,.5.5,0,.9,0,1.8,0,2.7,0,.5,0,.5-.5.5-3.9,0-7.8,0-11.7,0h-11.6c-.6,0-.6,0-.6-.6,0-3.6,0-7.2,0-10.9,0-.6,0-.6.6-.6ZM230.9,264.2c-3.9,0-7.8,0-11.6,0h-11.6c-.6,0-.6,0-.6-.6,0-2,0-4,0-6,0-.5,0-.5.5-.5,7.8,0,15.6,0,23.4,0,.5,0,.5,0,.5.5,0,2,0,4,0,6,0,.6,0,.6-.6.6Z"/>
|
||||
<g>
|
||||
<path class="st1" d="M211.4,253.5c-.3,0-.7,0-1-.1-.3,0-.6-.2-.8-.4-.3-.2-.5-.4-.7-.7-.2-.3-.3-.6-.5-1l1.4-.6c.1.4.3.7.5,1,.3.3.6.4,1,.4s.3,0,.4,0c.1,0,.3,0,.4-.2s.2-.2.3-.3c0-.1,0-.3,0-.4s0-.3,0-.4c0-.1-.1-.2-.3-.3-.1-.1-.3-.2-.5-.3-.2,0-.4-.2-.7-.3l-.5-.2c-.2,0-.4-.2-.6-.3-.2-.1-.4-.3-.6-.5s-.3-.4-.4-.6c-.1-.2-.2-.5-.2-.8s0-.6.2-.9c.1-.3.3-.5.5-.7.2-.2.5-.4.8-.5s.7-.2,1-.2.7,0,1,.2.5.2.7.4c.2.2.4.3.5.5.1.2.2.4.3.6l-1.3.6c0-.2-.2-.4-.4-.6-.2-.2-.5-.3-.8-.3s-.6,0-.8.2-.3.3-.3.6.1.4.3.6c.2.2.5.3,1,.5l.5.2c.3.1.6.2.9.4.3.1.5.3.7.5.2.2.3.4.4.7.1.3.1.5.1.9s0,.8-.2,1.1c-.2.3-.4.5-.6.7-.3.2-.5.3-.9.4-.3,0-.6.1-1,.1Z"/>
|
||||
<path class="st1" d="M214.5,245.4h1.6l1.6,4.8.3,1h0l.3-1,1.7-4.8h1.6l-2.9,7.9h-1.6l-2.8-7.9Z"/>
|
||||
<path class="st1" d="M226.1,248.9h3.9c0,0,0,.2,0,.3s0,.2,0,.4c0,.5,0,1-.2,1.4-.2.4-.4.8-.7,1.2-.4.4-.8.7-1.3.9-.5.2-1.1.3-1.7.3s-1.1-.1-1.6-.3-.9-.5-1.3-.9c-.4-.4-.7-.8-.9-1.3-.2-.5-.3-1.1-.3-1.6s.1-1.1.3-1.6.5-.9.9-1.3c.4-.4.8-.7,1.3-.9.5-.2,1-.3,1.6-.3s1.2.1,1.7.3.9.5,1.3.9l-1,1c-.3-.3-.5-.5-.9-.6-.3-.1-.7-.2-1.1-.2s-.7,0-1,.2c-.3.1-.6.3-.8.5-.2.2-.4.5-.6.9-.1.3-.2.7-.2,1.1s0,.8.2,1.1c.1.3.3.6.6.9.2.2.5.4.9.5.3.1.7.2,1,.2s.8,0,1.1-.2.5-.3.7-.5c.1-.1.3-.3.4-.5.1-.2.2-.4.2-.7h-2.5v-1.3h0Z"/>
|
||||
</g>
|
||||
<path class="st1" d="M272.3,243.9c0-1.2-1-2.1-2.2-2.1-.9,0-.8.1-.8-.9,0-1.1,0-2.2,0-3.3,0-.4-.1-.7-.4-1-2.3-2.7-4.7-5.3-7-8-.1-.1-.3-.2-.4-.4h-18.6c-.8.3-1.1.9-1.1,1.7,0,3.7,0,7.5,0,11.2s0,.6-.5.6c-1.5-.1-2.5,1-2.5,2.5,0,3.5,0,7,0,10.4,0,1.6.9,2.4,2.5,2.4q.6,0,.6.6c0,2.2,0,4.4,0,6.7,0,1.2.6,1.8,1.8,1.8,8,0,16,0,24,0,1.2,0,1.8-.6,1.8-1.7,0-2.3,0-4.5,0-6.8,0-.5,0-.5.5-.5.3,0,.5,0,.8,0,1-.2,1.7-1,1.7-2.1,0-3.7,0-7.4,0-11.1ZM243.8,229.8h16c.5,0,.6,0,.6.6,0,2.2,0,4.5,0,6.7,0,.8.2,1.1,1.1,1.1,1.9,0,3.8,0,5.7,0,.5,0,.5,0,.5.5,0,.9,0,1.8,0,2.7,0,.5,0,.5-.5.5-3.9,0-7.8,0-11.7,0h-11.6c-.5,0-.6,0-.6-.6,0-3.6,0-7.2,0-10.9,0-.6,0-.6.6-.6ZM267.1,264.2c-3.9,0-7.8,0-11.6,0h-11.6c-.6,0-.6,0-.6-.6,0-2,0-4,0-6,0-.5,0-.5.5-.5,7.8,0,15.6,0,23.4,0,.5,0,.5,0,.5.5,0,2,0,4,0,6,0,.6,0,.6-.6.6Z"/>
|
||||
<g>
|
||||
<path class="st1" d="M248,246.8v1.8h3.2v1.4h-3.2v1.8h3.5v1.4h-5v-7.9h5v1.4h-3.5Z"/>
|
||||
<path class="st1" d="M252.9,253.3v-7.9h2.8c.4,0,.7,0,1.1.2s.6.3.9.5.4.5.6.8c.1.3.2.6.2,1s0,.7-.2,1c-.1.3-.3.6-.6.8s-.5.4-.9.5-.7.2-1.1.2h-1.3v2.9h-1.5ZM255.7,249c.4,0,.7-.1.9-.3.2-.2.3-.5.3-.8s0-.3,0-.4-.1-.2-.2-.3c0,0-.2-.2-.4-.2-.1,0-.3,0-.5,0h-1.3v2.2h1.3Z"/>
|
||||
<path class="st1" d="M261.8,253.5c-.3,0-.7,0-1-.1-.3,0-.6-.2-.8-.4-.3-.2-.5-.4-.7-.7-.2-.3-.3-.6-.5-1l1.4-.6c.1.4.3.7.5,1,.3.3.6.4,1,.4s.3,0,.4,0c.1,0,.3,0,.4-.2.1,0,.2-.2.3-.3,0-.1.1-.3.1-.4s0-.3,0-.4c0-.1-.1-.2-.3-.3-.1-.1-.3-.2-.5-.3-.2,0-.4-.2-.7-.3l-.5-.2c-.2,0-.4-.2-.6-.3-.2-.1-.4-.3-.6-.5s-.3-.4-.4-.6c-.1-.2-.2-.5-.2-.8s0-.6.2-.9c.1-.3.3-.5.5-.7.2-.2.5-.4.8-.5.3-.1.7-.2,1-.2s.7,0,1,.2.5.2.7.4c.2.2.4.3.5.5.1.2.2.4.3.6l-1.3.6c0-.2-.2-.4-.4-.6-.2-.2-.5-.3-.8-.3s-.6,0-.8.2c-.2.2-.3.3-.3.6s.1.4.3.6.5.3,1,.5l.5.2c.3.1.6.2.9.4.3.1.5.3.7.5.2.2.3.4.4.7,0,.3.1.5.1.9s0,.8-.2,1.1c-.2.3-.4.5-.6.7-.3.2-.5.3-.9.4-.3,0-.6.1-1,.1Z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M296.4,251.8l4-5h-3.8v-1.4h5.6v1.5l-4,5h4v1.4h-5.8v-1.5h0Z"/>
|
||||
<path class="st1" d="M303.4,245.4h1.5v7.9h-1.5v-7.9Z"/>
|
||||
<path class="st1" d="M306.5,253.3v-7.9h2.8c.4,0,.7,0,1.1.2s.6.3.9.5.4.5.6.8c.1.3.2.6.2,1s0,.7-.2,1c-.1.3-.3.6-.6.8s-.5.4-.9.5-.7.2-1.1.2h-1.3v2.9h-1.5ZM309.3,249c.4,0,.7-.1.9-.3.2-.2.3-.5.3-.8s0-.3,0-.4-.1-.2-.2-.3c0,0-.2-.2-.4-.2-.1,0-.3,0-.5,0h-1.3v2.2h1.3Z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g class="st2">
|
||||
<path class="st1" d="M275.1,245.9h9.1v2.2h-9.1v-2.2ZM275.1,249.7h9.1v2.2h-9.1v-2.2Z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g class="st2">
|
||||
<path class="st1" d="M131.8,291.5h1.6c1.3,0,2.1.8,2.1,2s-.9,2-2.1,2h-1.6v-3.9ZM133.3,295.1c1,0,1.7-.7,1.7-1.6s-.7-1.6-1.7-1.6h-1.2v3.2h1.2Z"/>
|
||||
<path class="st1" d="M140.1,293.5c0-1.1.9-2,2.1-2s2.1.9,2.1,2-.9,2-2.1,2-2.1-.9-2.1-2ZM143.9,293.5c0-.9-.7-1.6-1.7-1.6s-1.7.7-1.7,1.6.7,1.6,1.7,1.6c.9,0,1.7-.7,1.7-1.6Z"/>
|
||||
<path class="st1" d="M154.6,291.5l-1.3,3.9h-.4l-1.2-3.4-1.2,3.4h-.4l-1.3-3.9h.4l1.1,3.4,1.2-3.4h.4l1.2,3.4,1.2-3.4h.4Z"/>
|
||||
<path class="st1" d="M162.7,291.5v3.9h-.3l-2.5-3.2v3.2h-.4v-3.9h.3l2.5,3.2v-3.2h.4Z"/>
|
||||
<path class="st1" d="M168.1,291.5h.4v3.6h2.2v.4h-2.6v-3.9h0Z"/>
|
||||
<path class="st1" d="M175.1,293.5c0-1.1.9-2,2.1-2s2.1.9,2.1,2-.9,2-2.1,2-2.1-.9-2.1-2ZM178.8,293.5c0-.9-.7-1.6-1.7-1.6s-1.7.7-1.7,1.6.7,1.6,1.7,1.6c.9,0,1.7-.7,1.7-1.6Z"/>
|
||||
<path class="st1" d="M186.6,294.4h-2.2l-.5,1.1h-.4l1.8-3.9h.4l1.8,3.9h-.4l-.5-1.1ZM186.5,294l-.9-2.1-.9,2.1h1.9Z"/>
|
||||
<path class="st1" d="M192.3,291.5h1.6c1.3,0,2.1.8,2.1,2s-.9,2-2.1,2h-1.6v-3.9ZM193.9,295.1c1,0,1.7-.7,1.7-1.6s-.7-1.6-1.7-1.6h-1.2v3.2h1.2Z"/>
|
||||
<path class="st1" d="M209,294.4h-2.2l-.5,1.1h-.4l1.8-3.9h.4l1.8,3.9h-.4l-.5-1.1ZM208.9,294l-.9-2.1-.9,2.1h1.9Z"/>
|
||||
<path class="st1" d="M214.7,291.5h.4v3.6h2.2v.4h-2.6v-3.9h0Z"/>
|
||||
<path class="st1" d="M222.1,291.5h.4v3.6h2.2v.4h-2.6v-3.9h0Z"/>
|
||||
<path class="st1" d="M235.4,291.8v1.6h2v.4h-2v1.7h-.4v-3.9h2.7v.4h-2.3Z"/>
|
||||
<path class="st1" d="M242.7,291.5h.4v3.9h-.4v-3.9Z"/>
|
||||
<path class="st1" d="M248.5,291.5h.4v3.6h2.2v.4h-2.6v-3.9h0Z"/>
|
||||
<path class="st1" d="M258.6,295.1v.4h-2.8v-3.9h2.7v.4h-2.3v1.4h2v.4h-2v1.5h2.4Z"/>
|
||||
<path class="st1" d="M269.7,291.8v1.6h2v.4h-2v1.7h-.4v-3.9h2.7v.4h-2.3Z"/>
|
||||
<path class="st1" d="M276.5,293.5c0-1.1.9-2,2.1-2s2.1.9,2.1,2-.9,2-2.1,2-2.1-.9-2.1-2ZM280.2,293.5c0-.9-.7-1.6-1.7-1.6s-1.7.7-1.7,1.6.7,1.6,1.7,1.6c.9,0,1.7-.7,1.7-1.6Z"/>
|
||||
<path class="st1" d="M288.3,295.4l-.9-1.3c-.1,0-.2,0-.3,0h-1.1v1.3h-.4v-3.9h1.5c1,0,1.6.5,1.6,1.4s-.3,1.1-.9,1.2l1,1.4h-.5ZM288.3,292.8c0-.6-.4-1-1.2-1h-1v2h1c.8,0,1.2-.4,1.2-1Z"/>
|
||||
<path class="st1" d="M297.9,291.5v3.9h-.4v-3.2l-1.6,2.7h-.2l-1.6-2.6v3.1h-.4v-3.9h.3l1.7,2.9,1.7-2.9h.3Z"/>
|
||||
<path class="st1" d="M305.7,294.4h-2.2l-.5,1.1h-.4l1.8-3.9h.4l1.8,3.9h-.4l-.5-1.1ZM305.6,294l-.9-2.1-.9,2.1h1.9Z"/>
|
||||
<path class="st1" d="M312,291.8h-1.4v-.4h3.2v.4h-1.4v3.6h-.4v-3.6h0Z"/>
|
||||
<path class="st1" d="M318.1,295l.2-.3c.3.3.8.5,1.3.5.7,0,1.1-.3,1.1-.7,0-1.1-2.4-.4-2.4-1.9s.5-1.1,1.5-1.1.9.1,1.2.4v.3c-.5-.2-.9-.3-1.2-.3-.7,0-1,.3-1,.7,0,1.1,2.4.4,2.4,1.9s-.5,1.1-1.5,1.1c-.6,0-1.2-.2-1.5-.5Z"/>
|
||||
</g>
|
||||
</g>
|
||||
<path class="st0" d="M376.7,125.2c-2.4,0-4.4-.9-5.7-2.6-1.3-1.8-1.7-4.2-.9-6.7l4.5-15.5c1.5-5.1,6.9-9.3,12-9.3h10c1.2,0,2.2-.8,2.6-1.9l1.7-6c.2-.8,0-1.7-.4-2.3-.5-.7-1.3-1.1-2.1-1.1h-21.9c-.1,0-.2,0-.4,0h-7.4c-2.4,0-4.4-.9-5.7-2.6-1.3-1.8-1.7-4.2-.9-6.7l.9-3c.2-.8,0-1.7-.4-2.3-.5-.7-1.3-1.1-2.1-1.1h-2.8c-1.2,0-2.2.8-2.6,1.9l-1.3,4.5c-1.5,5.1-6.9,9.3-12,9.3h-10c-1.2,0-2.2.8-2.6,1.9l-2.8,9.8s0,.1,0,.2l-4,14s0,.1,0,.2l-2.9,10.1c-1.5,5.1-6.9,9.3-12,9.3h-15.5c-2.4,0-4.4-.9-5.7-2.6-1.3-1.8-1.7-4.2-.9-6.7l13-45.2s0-.1,0-.2l.9-3.2c.2-.8,0-1.7-.4-2.3-.5-.7-1.3-1.1-2.1-1.1h-2.8c-1.2,0-2.2.8-2.6,1.9l-5.7,19.6s0,.1,0,.2l-2.1,7.4c-1.5,5.1-6.9,9.3-12,9.3h-15.5c-2.4,0-4.4-.9-5.7-2.6-1.3-1.8-1.7-4.2-.9-6.7l9.4-32.8c.2-.8,0-1.7-.4-2.3-.5-.7-1.3-1.1-2.1-1.1h-2.8c-1.2,0-2.2.8-2.6,1.9l-4,14s0,.1,0,.2l-5.8,20.1c-1.5,5.1-6.9,9.3-12,9.3h-15.5c-2.4,0-4.4-.9-5.7-2.6-1.3-1.8-1.7-4.2-.9-6.7l4.5-15.5s0-.1,0-.2l4.9-17.1c.2-.8,0-1.7-.4-2.3-.5-.7-1.3-1.1-2.1-1.1h-2.8c-1.2,0-2.2.8-2.6,1.9l-.4,1.4s0,.1,0,.2l-9.1,31.4s0,.1,0,.2l-.3,1.1c-1.5,5.1-6.9,9.3-12,9.3h-15.5c-2.4,0-4.4-.9-5.7-2.6-1.3-1.8-1.7-4.2-.9-6.7l.9-3c.2-.8,0-1.7-.4-2.3-.5-.7-1.3-1.1-2.1-1.1h-2.8c-1.2,0-2.2.8-2.6,1.9l-1.3,4.5c-1.5,5.1-6.9,9.3-12,9.3h-10.1c-1.2,0-2.2.8-2.6,1.9l-3.3,11.5c-1.5,5.1-6.9,9.3-12,9.3h-15.5c-2.4,0-4.4-.9-5.7-2.6-1.3-1.8-1.7-4.2-.9-6.7l2.9-10c.2-.8,0-1.7-.4-2.3-.5-.7-1.3-1.1-2.1-1.1h-8.3c-2.4,0-4.4-.9-5.7-2.6-1.3-1.8-1.7-4.2-.9-6.7l.9-3c.2-.8,0-1.7-.4-2.3-.5-.7-1.3-1.1-2.1-1.1h-2.8c-1.2,0-2.2.8-2.6,1.9l-1.3,4.5c-1.5,5.1-6.9,9.3-12,9.3h-21.3s-15.6,0-15.6,0c-2.4,0-4.4-.9-5.7-2.6-1.3-1.8-1.7-4.2-.9-6.7l2.9-10.1c.2-.8,0-1.7-.4-2.3-.5-.7-1.3-1.1-2.1-1.1H7c-2.4,0-4.4-.9-5.7-2.6-1.3-1.8-1.7-4.2-.9-6.7l7.7-26.9s0-.1,0-.2l2.5-8.7c0,0,0-.1,0-.2l.7-2.3c1.5-5.1,6.9-9.3,12-9.3h10c1.2,0,2.2-.8,2.6-1.9l3.3-11.5C40.7,4.2,46,0,51.2,0h21.3S88,0,88,0c2.4,0,4.4.9,5.7,2.6,1.3,1.8,1.7,4.2.9,6.7l-4.5,15.5c-1.5,5.1-6.9,9.3-12,9.3h-21.3s-9.9,0-9.9,0c-1.2,0-2.2.8-2.6,1.9l-4.4,15.3s0,.1,0,.2l-3.8,13.3c-.2.8,0,1.7.4,2.3.5.7,1.3,1.1,2.1,1.1s14.1,0,14.1,0h15.5c2.4,0,4.4.9,5.7,2.6,1.3,1.8,1.7,4.2.9,6.7l-.9,3.1c-.2.8,0,1.7.4,2.3.5.7,1.3,1.1,2.1,1.1h2.8c1.2,0,2.2-.8,2.6-1.9l1.7-5.8s6.2-21.5,6.2-21.5c1.5-5.1,6.9-9.3,12-9.3h9.9c1.2,0,2.2-.8,2.6-1.9l3.3-11.5c1.5-5.1,6.9-9.3,12-9.3h15.5c2.4,0,4.4.9,5.7,2.6,1.3,1.8,1.7,4.2.9,6.7l-2.9,10c-.2.8,0,1.7.4,2.3.5.7,1.3,1.1,2.1,1.1h8.4c2.4,0,4.4.9,5.7,2.6,1.3,1.8,1.7,4.2.9,6.7l-7.4,25.9c-.2.8,0,1.7.4,2.3s1.3,1.1,2.1,1.1h2.8c1.2,0,2.2-.8,2.6-1.9l3.5-12.2s0-.1,0-.2l9.1-31.4s0-.1,0-.2l1.8-6.1c1.5-5.1,6.9-9.3,12-9.3h36.8c2.4,0,4.4.9,5.7,2.6,1.3,1.8,1.7,4.2.9,6.7l-2.9,10.1c-.2.8,0,1.7.4,2.3.5.7,1.3,1.1,2.1,1.1h2.9c1.2,0,2.2-.8,2.6-1.9l3.3-11.5c1.5-5.1,6.9-9.3,12-9.3h15.5c2.4,0,4.4.9,5.7,2.6,1.3,1.8,1.7,4.2.9,6.7l-2.9,10c-.2.8,0,1.7.4,2.3.5.7,1.3,1.1,2.1,1.1h8.3c2.4,0,4.4.9,5.7,2.6,1.3,1.8,1.7,4.2.9,6.7l-.9,3.1c-.2.8,0,1.7.4,2.3.5.7,1.3,1.1,2.1,1.1h2.8c1.2,0,2.2-.8,2.6-1.9l7.9-27.3c1.5-5.1,6.9-9.3,12-9.3h10c1.2,0,2.2-.8,2.6-1.9l3.3-11.5c1.5-5.1,6.9-9.3,12-9.3h15.5c2.4,0,4.4.9,5.7,2.6,1.3,1.8,1.7,4.2.9,6.7l-4.5,15.5c-1.5,5.1-6.9,9.3-12,9.3h-10c-1.2,0-2.2.8-2.6,1.9l-1.7,6c-.2.8,0,1.7.4,2.3.5.7,1.3,1.1,2.1,1.1h8.4c2.4,0,4.4.9,5.7,2.6,1.3,1.8,1.7,4.2.9,6.7l-.9,3.1c-.2.8,0,1.7.4,2.3.5.7,1.3,1.1,2.1,1.1h2.8c1.2,0,2.2-.8,2.6-1.9l7.9-27.3c1.5-5.1,6.9-9.3,12-9.3h15.5c2.4,0,4.4.9,5.7,2.6,1.3,1.8,1.7,4.2.9,6.7l-7,24.4s0,.1,0,.2l-.8,2.6c-.2.8,0,1.7.4,2.3.5.7,1.3,1.1,2.1,1.1h2.8c1.2,0,2.2-.8,2.6-1.9l8.3-28.6c1.5-5.1,6.9-9.3,12-9.3h15.5c2.4,0,4.4.9,5.7,2.6,1.3,1.8,1.7,4.2.9,6.7l-17.6,61.1c-1.5,5.1-6.9,9.3-12,9.3h-10c-1.2,0-2.2.8-2.6,1.9l-3.3,11.5c-1.5,5.1-6.9,9.3-12,9.3h-15.5ZM125.5,57c-1.2,0-2.2.8-2.6,1.9l-8.3,28.8c-.2.8,0,1.7.4,2.3.5.7,1.3,1.1,2.1,1.1h2.8c1.2,0,2.2-.8,2.6-1.9l8.3-28.8c.2-.8,0-1.7-.4-2.3-.5-.7-1.3-1.1-2.1-1.1h-2.8Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 21 KiB |
146
ComfyUI_vibe/public/comfy-logo-yellow.svg
Normal file
@@ -0,0 +1,146 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 450 125.2">
|
||||
<!-- Generator: Adobe Illustrator 29.5.1, SVG Export Plug-In . SVG Version: 2.1.0 Build 141) -->
|
||||
<defs>
|
||||
<style>
|
||||
.st0 {
|
||||
fill: #f3ff56;
|
||||
}
|
||||
|
||||
.st1 {
|
||||
fill: #fff;
|
||||
}
|
||||
|
||||
.st2 {
|
||||
opacity: .6;
|
||||
}
|
||||
|
||||
.st3 {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<g id="watermark" class="st3">
|
||||
<g>
|
||||
<g id="watermark1" data-name="watermark" class="st2">
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<polygon class="st1" points="188.8 273.8 183.2 286.6 180.3 286.6 174.7 273.8 177.9 273.8 181.8 283 185.8 273.8 188.8 273.8"/>
|
||||
<path class="st1" d="M198.5,282.3h-7.5c.3,1.2,1.3,2,2.8,2s1.8-.3,2.5-1l1.5,1.7c-.9,1-2.3,1.6-4.1,1.6-3.4,0-5.6-2.1-5.6-5.1s2.3-5.1,5.3-5.1,5.1,1.9,5.1,5.1c0,.2,0,.5,0,.8M191,280.7h4.9c-.2-1.2-1.1-2.1-2.4-2.1-1.3,0-2.2.8-2.4,2.1"/>
|
||||
<path class="st1" d="M199.7,281.5c0-3,2.3-5.1,5.5-5.1s3.7.9,4.4,2.5l-2.2,1.2c-.5-.9-1.3-1.4-2.2-1.4-1.4,0-2.6,1-2.6,2.7s1.1,2.7,2.6,2.7,1.7-.4,2.2-1.4l2.2,1.2c-.7,1.6-2.3,2.5-4.4,2.5-3.2,0-5.5-2.1-5.5-5.1"/>
|
||||
<path class="st1" d="M217.8,286c-.6.4-1.4.6-2.3.6-2.3,0-3.7-1.2-3.7-3.5v-4.1h-1.5v-2.2h1.5v-2.4h2.9v2.4h2.5v2.2h-2.5v4c0,.8.5,1.3,1.2,1.3s.8-.1,1.2-.4l.8,2Z"/>
|
||||
</g>
|
||||
<path class="st1" d="M237.5,276.6v2.6c-.2,0-.4,0-.6,0-1.6,0-2.6.9-2.6,2.8v4.7h-2.9v-9.9h2.7v1.3c.7-1,1.9-1.5,3.4-1.5"/>
|
||||
<path class="st1" d="M238.3,285.1l1-2.2c1.1.8,2.7,1.3,4.2,1.3s2.5-.6,2.5-1.4c0-2.4-7.5-.8-7.5-5.5s1.8-4,5.4-4,3.3.4,4.5,1.1l-.9,2.3c-1.2-.7-2.4-1-3.6-1-1.8,0-2.4.7-2.4,1.5,0,2.4,7.5.7,7.5,5.5s-1.8,4-5.5,4c-2,0-4.1-.6-5.2-1.5"/>
|
||||
<path class="st1" d="M260.4,282.3h-7.5c.3,1.2,1.3,2,2.8,2s1.8-.3,2.5-1l1.5,1.7c-.9,1-2.3,1.6-4.1,1.6-3.4,0-5.6-2.1-5.6-5.1s2.3-5.1,5.3-5.1,5.1,1.9,5.1,5.1c0,.2,0,.5,0,.8M252.9,280.7h4.9c-.2-1.2-1.1-2.1-2.4-2.1-1.3,0-2.2.8-2.4,2.1"/>
|
||||
<path class="st1" d="M272,282.3h-7.5c.3,1.2,1.3,2,2.8,2s1.8-.3,2.5-1l1.5,1.7c-.9,1-2.3,1.6-4.1,1.6-3.4,0-5.6-2.1-5.6-5.1s2.3-5.1,5.3-5.1,5.1,1.9,5.1,5.1c0,.2,0,.5,0,.8M264.5,280.7h4.9c-.2-1.2-1.1-2.1-2.4-2.1-1.3,0-2.2.8-2.4,2.1"/>
|
||||
<polygon class="st1" points="278.2 282.8 276.8 284.1 276.8 286.6 274 286.6 274 273 276.8 273 276.8 280.7 281 276.8 284.4 276.8 280.3 280.9 284.8 286.6 281.3 286.6 278.2 282.8"/>
|
||||
<path class="st1" d="M231.6,288h0l-2.9-2.9c-.4.5-1,.9-1.5,1.3,0,0-.2.1-.3.2l3,3c.5.5,1.2.5,1.7,0,.5-.5.5-1.2,0-1.7"/>
|
||||
<path class="st1" d="M225,275.9c.2-.2.5-.3.8-.3s0,0,.1,0c-.2-.2-.5-.2-.8-.2s-.7.2-1,.5c0,0-.1,0-.2,0,0,0,0-.2,0-.3,0-.2-.1-.4-.3-.5,0,.1.1.3.1.4s0,.2,0,.3c-2.8.2-5,2.5-5,5.4s2.4,5.4,5.4,5.4,5.4-2.4,5.4-5.4c0-2.7-2-5-4.6-5.4M223,277.3c.4,0,.8.1,1.2.3.4-.2.8-.4,1.3-.4.7,0,1.3.3,1.8.8-.4-.4-1-.6-1.6-.6s-.9.1-1.2.3c0,0-.2,0-.2.1,0,0-.1,0-.2-.1-.4-.2-.8-.3-1.3-.3s-.6,0-.9.2c.3-.2.7-.3,1.1-.3M226.8,281.7c.1.3.2.6.2,1,0,1.5-1.2,2.8-2.8,2.8s-2.8-1.2-2.8-2.8,0-.7.2-1c-.6-.4-1-1.1-1-1.8,0-1.2,1-2.2,2.2-2.2s1.1.2,1.5.6c.4-.4.9-.6,1.5-.6,1.2,0,2.2,1,2.2,2.2s-.4,1.5-1,1.8"/>
|
||||
<path class="st1" d="M226.7,279.7c0,.5-.4.9-.9.9s-.9-.4-.9-.9.4-.9.9-.9.2,0,.3,0c0,0,0,.1,0,.2,0,.3.2.5.5.5s0,0,.1,0c0,0,0,.1,0,.2"/>
|
||||
<path class="st1" d="M223.3,279.7c0,.4-.3.7-.7.7s-.7-.3-.7-.7.3-.7.7-.7.1,0,.2,0c0,0,0,.1,0,.2,0,.2.2.4.4.4s0,0,.1,0c0,0,0,0,0,.1"/>
|
||||
<g>
|
||||
<g>
|
||||
<rect class="st1" x="217.9" y="280.4" width=".6" height=".6"/>
|
||||
<rect class="st1" x="229.8" y="280.4" width=".6" height=".6"/>
|
||||
<path class="st1" d="M230.2,280.7h-.1c0-3.2-2.6-5.9-5.9-5.9s-5.9,2.6-5.9,5.9h-.1c0-1.6.6-3.1,1.8-4.3s2.7-1.8,4.3-1.8,3.1.6,4.3,1.8c1.1,1.1,1.8,2.7,1.8,4.3"/>
|
||||
</g>
|
||||
<rect class="st1" x="223.9" y="274.4" width=".6" height=".6"/>
|
||||
<rect class="st1" x="219.9" y="274.7" width="8.4" height=".1"/>
|
||||
<path class="st1" d="M220.2,274.8c0,.1,0,.2-.2.2s-.2,0-.2-.2,0-.2.2-.2c.1,0,.2,0,.2.2"/>
|
||||
<path class="st1" d="M228.6,274.8c0,.1,0,.2-.2.2s-.2,0-.2-.2,0-.2.2-.2c.1,0,.2,0,.2.2"/>
|
||||
</g>
|
||||
</g>
|
||||
<path class="st1" d="M289.4,286c0,1.6-2.4,1.6-2.4,0,0-1.6,2.4-1.6,2.4,0Z"/>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st1" d="M136.7,279.2l1.8,6.1,1.9-6.1h2.2l-2.8,8.1h-2.3l-.8-2.4-.7-2.7-.7,2.7-.8,2.4h-2.3l-2.8-8.1h2.2l1.9,6.1,1.8-6.1h1.8Z"/>
|
||||
<path class="st1" d="M151.7,279.2l1.8,6.1,1.9-6.1h2.2l-2.8,8.1h-2.3l-.8-2.4-.7-2.7-.7,2.7-.8,2.4h-2.3l-2.8-8.1h2.2l1.9,6.1,1.8-6.1h1.8Z"/>
|
||||
<path class="st1" d="M166.7,279.2l1.8,6.1,1.9-6.1h2.2l-2.8,8.1h-2.3l-.8-2.4-.7-2.7-.7,2.7-.8,2.4h-2.3l-2.8-8.1h2.2l1.9,6.1,1.8-6.1h1.8Z"/>
|
||||
</g>
|
||||
<path class="st1" d="M175.9,286.1c0,1.6-2.4,1.6-2.4,0,0-1.6,2.4-1.6,2.4,0Z"/>
|
||||
<path class="st1" d="M297.7,286c-.9.9-1.9,1.3-3.1,1.3-2.3,0-4.3-1.4-4.3-4.3s2-4.3,4.3-4.3,2,.3,2.9,1.2l-1.3,1.3c-.5-.4-1.1-.6-1.6-.6-1.3,0-2.3,1-2.3,2.4s1,2.4,2.3,2.4,1.3-.2,1.8-.7l1.3,1.3Z"/>
|
||||
<path class="st1" d="M306.8,283.1c0,2.3-1.6,4.2-4.2,4.2s-4.2-1.9-4.2-4.2,1.6-4.2,4.2-4.2c2.6,0,4.2,1.9,4.2,4.2ZM300.4,283.1c0,1.2.7,2.4,2.2,2.4s2.2-1.1,2.2-2.4-.9-2.4-2.2-2.4c-1.4,0-2.2,1.2-2.2,2.4Z"/>
|
||||
<path class="st1" d="M313.6,287.3v-4.3c0-1.1-.6-2-1.7-2s-1.7,1-1.7,2v4.3h-2v-8.1h1.9v1c.6-.8,1.5-1.1,2.3-1.1s1.9.4,2.4,1.5c.7-1.1,1.7-1.5,2.7-1.5,2.3,0,3.4,1.4,3.4,3.8v4.4h-2v-4.4c0-1.1-.4-2-1.5-2s-1.8.9-1.8,2v4.3h-2Z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g class="st2">
|
||||
<g>
|
||||
<path class="st1" d="M321,243.9c0-1.2-1-2.1-2.2-2.1-.9,0-.8.1-.8-.9,0-1.1,0-2.2,0-3.3,0-.4-.1-.7-.4-1-2.3-2.7-4.7-5.3-7-8-.1-.1-.3-.2-.4-.4h-18.6c-.8.3-1.1.9-1.1,1.7,0,3.7,0,7.5,0,11.2s0,.6-.5.6c-1.5-.1-2.5,1-2.5,2.5,0,3.5,0,7,0,10.4,0,1.6.9,2.4,2.5,2.4q.6,0,.6.6c0,2.2,0,4.4,0,6.7,0,1.2.6,1.8,1.8,1.8,8,0,16,0,24,0,1.2,0,1.8-.6,1.8-1.7,0-2.3,0-4.5,0-6.8,0-.5,0-.5.5-.5.3,0,.5,0,.8,0,1-.2,1.7-1,1.7-2.1,0-3.7,0-7.4,0-11.1ZM292.5,229.8h16c.5,0,.6,0,.6.6,0,2.2,0,4.5,0,6.7,0,.8.2,1.1,1.1,1.1,1.9,0,3.8,0,5.7,0,.5,0,.5,0,.5.5,0,.9,0,1.8,0,2.7,0,.5,0,.5-.5.5-3.9,0-7.8,0-11.7,0h-11.6c-.5,0-.6,0-.6-.6,0-3.6,0-7.2,0-10.9,0-.6,0-.6.6-.6ZM315.8,264.2c-3.9,0-7.8,0-11.6,0h-11.6c-.6,0-.6,0-.6-.6,0-2,0-4,0-6,0-.5,0-.5.5-.5,7.8,0,15.6,0,23.4,0,.5,0,.5,0,.5.5,0,2,0,4,0,6,0,.6,0,.6-.6.6Z"/>
|
||||
<g>
|
||||
<rect class="st1" x="302.4" y="229.7" width="1.8" height="1.1"/>
|
||||
<rect class="st1" x="300.7" y="230.7" width="1.8" height="1.1"/>
|
||||
<rect class="st1" x="302.4" y="231.8" width="1.8" height="1.1"/>
|
||||
<rect class="st1" x="300.7" y="232.8" width="1.8" height="1.1"/>
|
||||
<rect class="st1" x="302.4" y="233.9" width="1.8" height="1.1"/>
|
||||
<rect class="st1" x="300.7" y="234.9" width="1.8" height="1.1"/>
|
||||
<rect class="st1" x="302.4" y="236" width="1.8" height="1.1"/>
|
||||
<rect class="st1" x="300.7" y="237" width="1.8" height="1.1"/>
|
||||
<rect class="st1" x="302.4" y="238.1" width="1.8" height="1.1"/>
|
||||
<rect class="st1" x="300.7" y="239.1" width="1.8" height="1.1"/>
|
||||
<rect class="st1" x="302.4" y="240.2" width="1.8" height="1.1"/>
|
||||
<rect class="st1" x="300.7" y="241.3" width="1.8" height="1.1"/>
|
||||
</g>
|
||||
</g>
|
||||
<path class="st1" d="M162.6,243.9c0-1.2-1-2.1-2.2-2.1-.9,0-.8.1-.8-.9,0-1.1,0-2.2,0-3.3,0-.4-.1-.7-.4-1-2.3-2.7-4.7-5.3-7-8-.1-.1-.3-.2-.4-.4h-18.6c-.8.3-1.1.9-1.1,1.7,0,3.7,0,7.5,0,11.2s0,.6-.6.6c-1.5-.1-2.5,1-2.5,2.5,0,3.5,0,7,0,10.4,0,1.6.9,2.4,2.4,2.4q.6,0,.6.6c0,2.2,0,4.4,0,6.7,0,1.2.6,1.8,1.8,1.8,8,0,16,0,24,0,1.2,0,1.8-.6,1.8-1.7,0-2.3,0-4.5,0-6.8,0-.5,0-.5.5-.5.3,0,.5,0,.8,0,1-.2,1.7-1,1.7-2.1,0-3.7,0-7.4,0-11.1ZM134.2,229.8h16c.5,0,.6,0,.6.6,0,2.2,0,4.5,0,6.7,0,.8.2,1.1,1.1,1.1,1.9,0,3.8,0,5.7,0,.5,0,.5,0,.5.5,0,.9,0,1.8,0,2.7,0,.5,0,.5-.5.5-3.9,0-7.8,0-11.7,0h-11.6c-.6,0-.6,0-.6-.6,0-3.6,0-7.2,0-10.9,0-.6,0-.6.6-.6ZM157.5,264.2c-3.9,0-7.8,0-11.6,0h-11.6c-.6,0-.6,0-.6-.6,0-2,0-4,0-6,0-.5,0-.5.5-.5,7.8,0,15.6,0,23.4,0,.5,0,.5,0,.5.5,0,2,0,4,0,6,0,.6,0,.6-.6.6Z"/>
|
||||
<g>
|
||||
<path class="st1" d="M134.8,253.3v-7.9h2.8c.4,0,.7,0,1.1.2s.6.3.9.5c.2.2.4.5.6.8.1.3.2.6.2,1s0,.7-.2,1-.3.6-.6.8c-.2.2-.5.4-.9.5s-.7.2-1.1.2h-1.3v2.9h-1.5ZM137.6,249c.4,0,.7-.1.9-.3.2-.2.3-.5.3-.8s0-.3,0-.4-.1-.2-.2-.3c0,0-.2-.2-.4-.2-.1,0-.3,0-.5,0h-1.3v2.2h1.3Z"/>
|
||||
<path class="st1" d="M141.3,245.4h1.7l3.2,5.3h0v-1.5c0,0,0-3.8,0-3.8h1.5v7.9h-1.6l-3.4-5.6h0v1.5c0,0,0,4.1,0,4.1h-1.5v-7.9h0Z"/>
|
||||
<path class="st1" d="M152.9,248.9h3.9c0,0,0,.2,0,.3,0,.1,0,.2,0,.4,0,.5,0,1-.2,1.4s-.4.8-.7,1.2c-.4.4-.8.7-1.3.9-.5.2-1.1.3-1.7.3s-1.1-.1-1.6-.3c-.5-.2-.9-.5-1.3-.9-.4-.4-.7-.8-.9-1.3s-.3-1.1-.3-1.6.1-1.1.3-1.6.5-.9.9-1.3c.4-.4.8-.7,1.3-.9s1-.3,1.6-.3,1.2.1,1.7.3.9.5,1.3.9l-1,1c-.3-.3-.5-.5-.9-.6-.3-.1-.7-.2-1.1-.2s-.7,0-1,.2c-.3.1-.6.3-.9.5-.2.2-.4.5-.6.9-.1.3-.2.7-.2,1.1s0,.8.2,1.1c.1.3.3.6.6.9.2.2.5.4.9.5.3.1.7.2,1,.2s.8,0,1.1-.2c.3-.1.5-.3.7-.5.1-.1.3-.3.4-.5.1-.2.2-.4.2-.7h-2.5v-1.3h0Z"/>
|
||||
</g>
|
||||
<path class="st1" d="M199,243.9c0-1.2-1-2.1-2.2-2.1-.9,0-.8.1-.8-.9,0-1.1,0-2.2,0-3.3,0-.4-.1-.7-.4-1-2.3-2.7-4.7-5.3-7-8-.1-.1-.3-.2-.4-.4h-18.6c-.8.3-1.1.9-1.1,1.7,0,3.7,0,7.5,0,11.2s0,.6-.6.6c-1.5-.1-2.5,1-2.5,2.5,0,3.5,0,7,0,10.4,0,1.6.9,2.4,2.4,2.4q.6,0,.6.6c0,2.2,0,4.4,0,6.7,0,1.2.6,1.8,1.8,1.8,8,0,16,0,24,0,1.2,0,1.8-.6,1.8-1.7,0-2.3,0-4.5,0-6.8,0-.5,0-.5.5-.5.3,0,.5,0,.8,0,1-.2,1.7-1,1.7-2.1,0-3.7,0-7.4,0-11.1ZM170.6,229.8h16c.5,0,.6,0,.6.6,0,2.2,0,4.5,0,6.7,0,.8.2,1.1,1.1,1.1,1.9,0,3.8,0,5.7,0,.5,0,.5,0,.5.5,0,.9,0,1.8,0,2.7,0,.5,0,.5-.5.5-3.9,0-7.8,0-11.7,0h-11.6c-.6,0-.6,0-.6-.6,0-3.6,0-7.2,0-10.9,0-.6,0-.6.6-.6ZM193.9,264.2c-3.9,0-7.8,0-11.6,0h-11.6c-.6,0-.6,0-.6-.6,0-2,0-4,0-6,0-.5,0-.5.5-.5,7.8,0,15.6,0,23.4,0,.5,0,.5,0,.5.5,0,2,0,4,0,6,0,.6,0,.6-.6.6Z"/>
|
||||
<g>
|
||||
<path class="st1" d="M180.1,245.4h1.7l3,7.9h-1.6l-.7-1.9h-3l-.7,1.9h-1.6l3-7.9ZM182,250l-.7-2-.3-1h0l-.3,1-.7,2h2.1Z"/>
|
||||
<path class="st1" d="M186.3,247.1c-.1,0-.2,0-.4,0s-.2-.1-.3-.2c0,0-.2-.2-.2-.3,0-.1,0-.2,0-.4s0-.3,0-.4c0-.1.1-.2.2-.3,0,0,.2-.2.3-.2.1,0,.2,0,.4,0,.3,0,.5,0,.7.3.2.2.3.4.3.7s0,.5-.3.7c-.2.2-.4.3-.7.3ZM185.6,253.3v-5.4h1.4v5.4h-1.4Z"/>
|
||||
</g>
|
||||
<path class="st1" d="M236,243.9c0-1.2-1-2.1-2.2-2.1-.9,0-.8.1-.8-.9,0-1.1,0-2.2,0-3.3,0-.4-.1-.7-.4-1-2.3-2.7-4.7-5.3-7-8-.1-.1-.3-.2-.4-.4h-18.6c-.8.3-1.1.9-1.1,1.7,0,3.7,0,7.5,0,11.2s0,.6-.6.6c-1.5-.1-2.5,1-2.5,2.5,0,3.5,0,7,0,10.4,0,1.6.9,2.4,2.4,2.4q.6,0,.6.6c0,2.2,0,4.4,0,6.7,0,1.2.6,1.8,1.8,1.8,8,0,16,0,24,0,1.2,0,1.8-.6,1.8-1.7,0-2.3,0-4.5,0-6.8,0-.5,0-.5.5-.5.3,0,.5,0,.8,0,1-.2,1.7-1,1.7-2.1,0-3.7,0-7.4,0-11.1ZM207.6,229.8h16c.5,0,.6,0,.6.6,0,2.2,0,4.5,0,6.7,0,.8.2,1.1,1.1,1.1,1.9,0,3.8,0,5.7,0,.5,0,.5,0,.5.5,0,.9,0,1.8,0,2.7,0,.5,0,.5-.5.5-3.9,0-7.8,0-11.7,0h-11.6c-.6,0-.6,0-.6-.6,0-3.6,0-7.2,0-10.9,0-.6,0-.6.6-.6ZM230.9,264.2c-3.9,0-7.8,0-11.6,0h-11.6c-.6,0-.6,0-.6-.6,0-2,0-4,0-6,0-.5,0-.5.5-.5,7.8,0,15.6,0,23.4,0,.5,0,.5,0,.5.5,0,2,0,4,0,6,0,.6,0,.6-.6.6Z"/>
|
||||
<g>
|
||||
<path class="st1" d="M211.4,253.5c-.3,0-.7,0-1-.1-.3,0-.6-.2-.8-.4-.3-.2-.5-.4-.7-.7-.2-.3-.3-.6-.5-1l1.4-.6c.1.4.3.7.5,1,.3.3.6.4,1,.4s.3,0,.4,0c.1,0,.3,0,.4-.2s.2-.2.3-.3c0-.1,0-.3,0-.4s0-.3,0-.4c0-.1-.1-.2-.3-.3-.1-.1-.3-.2-.5-.3-.2,0-.4-.2-.7-.3l-.5-.2c-.2,0-.4-.2-.6-.3-.2-.1-.4-.3-.6-.5s-.3-.4-.4-.6c-.1-.2-.2-.5-.2-.8s0-.6.2-.9c.1-.3.3-.5.5-.7.2-.2.5-.4.8-.5s.7-.2,1-.2.7,0,1,.2.5.2.7.4c.2.2.4.3.5.5.1.2.2.4.3.6l-1.3.6c0-.2-.2-.4-.4-.6-.2-.2-.5-.3-.8-.3s-.6,0-.8.2-.3.3-.3.6.1.4.3.6c.2.2.5.3,1,.5l.5.2c.3.1.6.2.9.4.3.1.5.3.7.5.2.2.3.4.4.7.1.3.1.5.1.9s0,.8-.2,1.1c-.2.3-.4.5-.6.7-.3.2-.5.3-.9.4-.3,0-.6.1-1,.1Z"/>
|
||||
<path class="st1" d="M214.5,245.4h1.6l1.6,4.8.3,1h0l.3-1,1.7-4.8h1.6l-2.9,7.9h-1.6l-2.8-7.9Z"/>
|
||||
<path class="st1" d="M226.1,248.9h3.9c0,0,0,.2,0,.3s0,.2,0,.4c0,.5,0,1-.2,1.4-.2.4-.4.8-.7,1.2-.4.4-.8.7-1.3.9-.5.2-1.1.3-1.7.3s-1.1-.1-1.6-.3-.9-.5-1.3-.9c-.4-.4-.7-.8-.9-1.3-.2-.5-.3-1.1-.3-1.6s.1-1.1.3-1.6.5-.9.9-1.3c.4-.4.8-.7,1.3-.9.5-.2,1-.3,1.6-.3s1.2.1,1.7.3.9.5,1.3.9l-1,1c-.3-.3-.5-.5-.9-.6-.3-.1-.7-.2-1.1-.2s-.7,0-1,.2c-.3.1-.6.3-.8.5-.2.2-.4.5-.6.9-.1.3-.2.7-.2,1.1s0,.8.2,1.1c.1.3.3.6.6.9.2.2.5.4.9.5.3.1.7.2,1,.2s.8,0,1.1-.2.5-.3.7-.5c.1-.1.3-.3.4-.5.1-.2.2-.4.2-.7h-2.5v-1.3h0Z"/>
|
||||
</g>
|
||||
<path class="st1" d="M272.3,243.9c0-1.2-1-2.1-2.2-2.1-.9,0-.8.1-.8-.9,0-1.1,0-2.2,0-3.3,0-.4-.1-.7-.4-1-2.3-2.7-4.7-5.3-7-8-.1-.1-.3-.2-.4-.4h-18.6c-.8.3-1.1.9-1.1,1.7,0,3.7,0,7.5,0,11.2s0,.6-.5.6c-1.5-.1-2.5,1-2.5,2.5,0,3.5,0,7,0,10.4,0,1.6.9,2.4,2.5,2.4q.6,0,.6.6c0,2.2,0,4.4,0,6.7,0,1.2.6,1.8,1.8,1.8,8,0,16,0,24,0,1.2,0,1.8-.6,1.8-1.7,0-2.3,0-4.5,0-6.8,0-.5,0-.5.5-.5.3,0,.5,0,.8,0,1-.2,1.7-1,1.7-2.1,0-3.7,0-7.4,0-11.1ZM243.8,229.8h16c.5,0,.6,0,.6.6,0,2.2,0,4.5,0,6.7,0,.8.2,1.1,1.1,1.1,1.9,0,3.8,0,5.7,0,.5,0,.5,0,.5.5,0,.9,0,1.8,0,2.7,0,.5,0,.5-.5.5-3.9,0-7.8,0-11.7,0h-11.6c-.5,0-.6,0-.6-.6,0-3.6,0-7.2,0-10.9,0-.6,0-.6.6-.6ZM267.1,264.2c-3.9,0-7.8,0-11.6,0h-11.6c-.6,0-.6,0-.6-.6,0-2,0-4,0-6,0-.5,0-.5.5-.5,7.8,0,15.6,0,23.4,0,.5,0,.5,0,.5.5,0,2,0,4,0,6,0,.6,0,.6-.6.6Z"/>
|
||||
<g>
|
||||
<path class="st1" d="M248,246.8v1.8h3.2v1.4h-3.2v1.8h3.5v1.4h-5v-7.9h5v1.4h-3.5Z"/>
|
||||
<path class="st1" d="M252.9,253.3v-7.9h2.8c.4,0,.7,0,1.1.2s.6.3.9.5.4.5.6.8c.1.3.2.6.2,1s0,.7-.2,1c-.1.3-.3.6-.6.8s-.5.4-.9.5-.7.2-1.1.2h-1.3v2.9h-1.5ZM255.7,249c.4,0,.7-.1.9-.3.2-.2.3-.5.3-.8s0-.3,0-.4-.1-.2-.2-.3c0,0-.2-.2-.4-.2-.1,0-.3,0-.5,0h-1.3v2.2h1.3Z"/>
|
||||
<path class="st1" d="M261.8,253.5c-.3,0-.7,0-1-.1-.3,0-.6-.2-.8-.4-.3-.2-.5-.4-.7-.7-.2-.3-.3-.6-.5-1l1.4-.6c.1.4.3.7.5,1,.3.3.6.4,1,.4s.3,0,.4,0c.1,0,.3,0,.4-.2.1,0,.2-.2.3-.3,0-.1.1-.3.1-.4s0-.3,0-.4c0-.1-.1-.2-.3-.3-.1-.1-.3-.2-.5-.3-.2,0-.4-.2-.7-.3l-.5-.2c-.2,0-.4-.2-.6-.3-.2-.1-.4-.3-.6-.5s-.3-.4-.4-.6c-.1-.2-.2-.5-.2-.8s0-.6.2-.9c.1-.3.3-.5.5-.7.2-.2.5-.4.8-.5.3-.1.7-.2,1-.2s.7,0,1,.2.5.2.7.4c.2.2.4.3.5.5.1.2.2.4.3.6l-1.3.6c0-.2-.2-.4-.4-.6-.2-.2-.5-.3-.8-.3s-.6,0-.8.2c-.2.2-.3.3-.3.6s.1.4.3.6.5.3,1,.5l.5.2c.3.1.6.2.9.4.3.1.5.3.7.5.2.2.3.4.4.7,0,.3.1.5.1.9s0,.8-.2,1.1c-.2.3-.4.5-.6.7-.3.2-.5.3-.9.4-.3,0-.6.1-1,.1Z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M296.4,251.8l4-5h-3.8v-1.4h5.6v1.5l-4,5h4v1.4h-5.8v-1.5h0Z"/>
|
||||
<path class="st1" d="M303.4,245.4h1.5v7.9h-1.5v-7.9Z"/>
|
||||
<path class="st1" d="M306.5,253.3v-7.9h2.8c.4,0,.7,0,1.1.2s.6.3.9.5.4.5.6.8c.1.3.2.6.2,1s0,.7-.2,1c-.1.3-.3.6-.6.8s-.5.4-.9.5-.7.2-1.1.2h-1.3v2.9h-1.5ZM309.3,249c.4,0,.7-.1.9-.3.2-.2.3-.5.3-.8s0-.3,0-.4-.1-.2-.2-.3c0,0-.2-.2-.4-.2-.1,0-.3,0-.5,0h-1.3v2.2h1.3Z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g class="st2">
|
||||
<path class="st1" d="M275.1,245.9h9.1v2.2h-9.1v-2.2ZM275.1,249.7h9.1v2.2h-9.1v-2.2Z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g class="st2">
|
||||
<path class="st1" d="M131.8,291.5h1.6c1.3,0,2.1.8,2.1,2s-.9,2-2.1,2h-1.6v-3.9ZM133.3,295.1c1,0,1.7-.7,1.7-1.6s-.7-1.6-1.7-1.6h-1.2v3.2h1.2Z"/>
|
||||
<path class="st1" d="M140.1,293.5c0-1.1.9-2,2.1-2s2.1.9,2.1,2-.9,2-2.1,2-2.1-.9-2.1-2ZM143.9,293.5c0-.9-.7-1.6-1.7-1.6s-1.7.7-1.7,1.6.7,1.6,1.7,1.6c.9,0,1.7-.7,1.7-1.6Z"/>
|
||||
<path class="st1" d="M154.6,291.5l-1.3,3.9h-.4l-1.2-3.4-1.2,3.4h-.4l-1.3-3.9h.4l1.1,3.4,1.2-3.4h.4l1.2,3.4,1.2-3.4h.4Z"/>
|
||||
<path class="st1" d="M162.7,291.5v3.9h-.3l-2.5-3.2v3.2h-.4v-3.9h.3l2.5,3.2v-3.2h.4Z"/>
|
||||
<path class="st1" d="M168.1,291.5h.4v3.6h2.2v.4h-2.6v-3.9h0Z"/>
|
||||
<path class="st1" d="M175.1,293.5c0-1.1.9-2,2.1-2s2.1.9,2.1,2-.9,2-2.1,2-2.1-.9-2.1-2ZM178.8,293.5c0-.9-.7-1.6-1.7-1.6s-1.7.7-1.7,1.6.7,1.6,1.7,1.6c.9,0,1.7-.7,1.7-1.6Z"/>
|
||||
<path class="st1" d="M186.6,294.4h-2.2l-.5,1.1h-.4l1.8-3.9h.4l1.8,3.9h-.4l-.5-1.1ZM186.5,294l-.9-2.1-.9,2.1h1.9Z"/>
|
||||
<path class="st1" d="M192.3,291.5h1.6c1.3,0,2.1.8,2.1,2s-.9,2-2.1,2h-1.6v-3.9ZM193.9,295.1c1,0,1.7-.7,1.7-1.6s-.7-1.6-1.7-1.6h-1.2v3.2h1.2Z"/>
|
||||
<path class="st1" d="M209,294.4h-2.2l-.5,1.1h-.4l1.8-3.9h.4l1.8,3.9h-.4l-.5-1.1ZM208.9,294l-.9-2.1-.9,2.1h1.9Z"/>
|
||||
<path class="st1" d="M214.7,291.5h.4v3.6h2.2v.4h-2.6v-3.9h0Z"/>
|
||||
<path class="st1" d="M222.1,291.5h.4v3.6h2.2v.4h-2.6v-3.9h0Z"/>
|
||||
<path class="st1" d="M235.4,291.8v1.6h2v.4h-2v1.7h-.4v-3.9h2.7v.4h-2.3Z"/>
|
||||
<path class="st1" d="M242.7,291.5h.4v3.9h-.4v-3.9Z"/>
|
||||
<path class="st1" d="M248.5,291.5h.4v3.6h2.2v.4h-2.6v-3.9h0Z"/>
|
||||
<path class="st1" d="M258.6,295.1v.4h-2.8v-3.9h2.7v.4h-2.3v1.4h2v.4h-2v1.5h2.4Z"/>
|
||||
<path class="st1" d="M269.7,291.8v1.6h2v.4h-2v1.7h-.4v-3.9h2.7v.4h-2.3Z"/>
|
||||
<path class="st1" d="M276.5,293.5c0-1.1.9-2,2.1-2s2.1.9,2.1,2-.9,2-2.1,2-2.1-.9-2.1-2ZM280.2,293.5c0-.9-.7-1.6-1.7-1.6s-1.7.7-1.7,1.6.7,1.6,1.7,1.6c.9,0,1.7-.7,1.7-1.6Z"/>
|
||||
<path class="st1" d="M288.3,295.4l-.9-1.3c-.1,0-.2,0-.3,0h-1.1v1.3h-.4v-3.9h1.5c1,0,1.6.5,1.6,1.4s-.3,1.1-.9,1.2l1,1.4h-.5ZM288.3,292.8c0-.6-.4-1-1.2-1h-1v2h1c.8,0,1.2-.4,1.2-1Z"/>
|
||||
<path class="st1" d="M297.9,291.5v3.9h-.4v-3.2l-1.6,2.7h-.2l-1.6-2.6v3.1h-.4v-3.9h.3l1.7,2.9,1.7-2.9h.3Z"/>
|
||||
<path class="st1" d="M305.7,294.4h-2.2l-.5,1.1h-.4l1.8-3.9h.4l1.8,3.9h-.4l-.5-1.1ZM305.6,294l-.9-2.1-.9,2.1h1.9Z"/>
|
||||
<path class="st1" d="M312,291.8h-1.4v-.4h3.2v.4h-1.4v3.6h-.4v-3.6h0Z"/>
|
||||
<path class="st1" d="M318.1,295l.2-.3c.3.3.8.5,1.3.5.7,0,1.1-.3,1.1-.7,0-1.1-2.4-.4-2.4-1.9s.5-1.1,1.5-1.1.9.1,1.2.4v.3c-.5-.2-.9-.3-1.2-.3-.7,0-1,.3-1,.7,0,1.1,2.4.4,2.4,1.9s-.5,1.1-1.5,1.1c-.6,0-1.2-.2-1.5-.5Z"/>
|
||||
</g>
|
||||
</g>
|
||||
<path class="st0" d="M376.7,125.2c-2.4,0-4.4-.9-5.7-2.6-1.3-1.8-1.7-4.2-.9-6.7l4.5-15.5c1.5-5.1,6.9-9.3,12-9.3h10c1.2,0,2.2-.8,2.6-1.9l1.7-6c.2-.8,0-1.7-.4-2.3-.5-.7-1.3-1.1-2.1-1.1h-21.9c-.1,0-.2,0-.4,0h-7.4c-2.4,0-4.4-.9-5.7-2.6-1.3-1.8-1.7-4.2-.9-6.7l.9-3c.2-.8,0-1.7-.4-2.3-.5-.7-1.3-1.1-2.1-1.1h-2.8c-1.2,0-2.2.8-2.6,1.9l-1.3,4.5c-1.5,5.1-6.9,9.3-12,9.3h-10c-1.2,0-2.2.8-2.6,1.9l-2.8,9.8s0,.1,0,.2l-4,14s0,.1,0,.2l-2.9,10.1c-1.5,5.1-6.9,9.3-12,9.3h-15.5c-2.4,0-4.4-.9-5.7-2.6-1.3-1.8-1.7-4.2-.9-6.7l13-45.2s0-.1,0-.2l.9-3.2c.2-.8,0-1.7-.4-2.3-.5-.7-1.3-1.1-2.1-1.1h-2.8c-1.2,0-2.2.8-2.6,1.9l-5.7,19.6s0,.1,0,.2l-2.1,7.4c-1.5,5.1-6.9,9.3-12,9.3h-15.5c-2.4,0-4.4-.9-5.7-2.6-1.3-1.8-1.7-4.2-.9-6.7l9.4-32.8c.2-.8,0-1.7-.4-2.3-.5-.7-1.3-1.1-2.1-1.1h-2.8c-1.2,0-2.2.8-2.6,1.9l-4,14s0,.1,0,.2l-5.8,20.1c-1.5,5.1-6.9,9.3-12,9.3h-15.5c-2.4,0-4.4-.9-5.7-2.6-1.3-1.8-1.7-4.2-.9-6.7l4.5-15.5s0-.1,0-.2l4.9-17.1c.2-.8,0-1.7-.4-2.3-.5-.7-1.3-1.1-2.1-1.1h-2.8c-1.2,0-2.2.8-2.6,1.9l-.4,1.4s0,.1,0,.2l-9.1,31.4s0,.1,0,.2l-.3,1.1c-1.5,5.1-6.9,9.3-12,9.3h-15.5c-2.4,0-4.4-.9-5.7-2.6-1.3-1.8-1.7-4.2-.9-6.7l.9-3c.2-.8,0-1.7-.4-2.3-.5-.7-1.3-1.1-2.1-1.1h-2.8c-1.2,0-2.2.8-2.6,1.9l-1.3,4.5c-1.5,5.1-6.9,9.3-12,9.3h-10.1c-1.2,0-2.2.8-2.6,1.9l-3.3,11.5c-1.5,5.1-6.9,9.3-12,9.3h-15.5c-2.4,0-4.4-.9-5.7-2.6-1.3-1.8-1.7-4.2-.9-6.7l2.9-10c.2-.8,0-1.7-.4-2.3-.5-.7-1.3-1.1-2.1-1.1h-8.3c-2.4,0-4.4-.9-5.7-2.6-1.3-1.8-1.7-4.2-.9-6.7l.9-3c.2-.8,0-1.7-.4-2.3-.5-.7-1.3-1.1-2.1-1.1h-2.8c-1.2,0-2.2.8-2.6,1.9l-1.3,4.5c-1.5,5.1-6.9,9.3-12,9.3h-21.3s-15.6,0-15.6,0c-2.4,0-4.4-.9-5.7-2.6-1.3-1.8-1.7-4.2-.9-6.7l2.9-10.1c.2-.8,0-1.7-.4-2.3-.5-.7-1.3-1.1-2.1-1.1H7c-2.4,0-4.4-.9-5.7-2.6-1.3-1.8-1.7-4.2-.9-6.7l7.7-26.9s0-.1,0-.2l2.5-8.7c0,0,0-.1,0-.2l.7-2.3c1.5-5.1,6.9-9.3,12-9.3h10c1.2,0,2.2-.8,2.6-1.9l3.3-11.5C40.7,4.2,46,0,51.2,0h21.3S88,0,88,0c2.4,0,4.4.9,5.7,2.6,1.3,1.8,1.7,4.2.9,6.7l-4.5,15.5c-1.5,5.1-6.9,9.3-12,9.3h-21.3s-9.9,0-9.9,0c-1.2,0-2.2.8-2.6,1.9l-4.4,15.3s0,.1,0,.2l-3.8,13.3c-.2.8,0,1.7.4,2.3.5.7,1.3,1.1,2.1,1.1s14.1,0,14.1,0h15.5c2.4,0,4.4.9,5.7,2.6,1.3,1.8,1.7,4.2.9,6.7l-.9,3.1c-.2.8,0,1.7.4,2.3.5.7,1.3,1.1,2.1,1.1h2.8c1.2,0,2.2-.8,2.6-1.9l1.7-5.8s6.2-21.5,6.2-21.5c1.5-5.1,6.9-9.3,12-9.3h9.9c1.2,0,2.2-.8,2.6-1.9l3.3-11.5c1.5-5.1,6.9-9.3,12-9.3h15.5c2.4,0,4.4.9,5.7,2.6,1.3,1.8,1.7,4.2.9,6.7l-2.9,10c-.2.8,0,1.7.4,2.3.5.7,1.3,1.1,2.1,1.1h8.4c2.4,0,4.4.9,5.7,2.6,1.3,1.8,1.7,4.2.9,6.7l-7.4,25.9c-.2.8,0,1.7.4,2.3s1.3,1.1,2.1,1.1h2.8c1.2,0,2.2-.8,2.6-1.9l3.5-12.2s0-.1,0-.2l9.1-31.4s0-.1,0-.2l1.8-6.1c1.5-5.1,6.9-9.3,12-9.3h36.8c2.4,0,4.4.9,5.7,2.6,1.3,1.8,1.7,4.2.9,6.7l-2.9,10.1c-.2.8,0,1.7.4,2.3.5.7,1.3,1.1,2.1,1.1h2.9c1.2,0,2.2-.8,2.6-1.9l3.3-11.5c1.5-5.1,6.9-9.3,12-9.3h15.5c2.4,0,4.4.9,5.7,2.6,1.3,1.8,1.7,4.2.9,6.7l-2.9,10c-.2.8,0,1.7.4,2.3.5.7,1.3,1.1,2.1,1.1h8.3c2.4,0,4.4.9,5.7,2.6,1.3,1.8,1.7,4.2.9,6.7l-.9,3.1c-.2.8,0,1.7.4,2.3.5.7,1.3,1.1,2.1,1.1h2.8c1.2,0,2.2-.8,2.6-1.9l7.9-27.3c1.5-5.1,6.9-9.3,12-9.3h10c1.2,0,2.2-.8,2.6-1.9l3.3-11.5c1.5-5.1,6.9-9.3,12-9.3h15.5c2.4,0,4.4.9,5.7,2.6,1.3,1.8,1.7,4.2.9,6.7l-4.5,15.5c-1.5,5.1-6.9,9.3-12,9.3h-10c-1.2,0-2.2.8-2.6,1.9l-1.7,6c-.2.8,0,1.7.4,2.3.5.7,1.3,1.1,2.1,1.1h8.4c2.4,0,4.4.9,5.7,2.6,1.3,1.8,1.7,4.2.9,6.7l-.9,3.1c-.2.8,0,1.7.4,2.3.5.7,1.3,1.1,2.1,1.1h2.8c1.2,0,2.2-.8,2.6-1.9l7.9-27.3c1.5-5.1,6.9-9.3,12-9.3h15.5c2.4,0,4.4.9,5.7,2.6,1.3,1.8,1.7,4.2.9,6.7l-7,24.4s0,.1,0,.2l-.8,2.6c-.2.8,0,1.7.4,2.3.5.7,1.3,1.1,2.1,1.1h2.8c1.2,0,2.2-.8,2.6-1.9l8.3-28.6c1.5-5.1,6.9-9.3,12-9.3h15.5c2.4,0,4.4.9,5.7,2.6,1.3,1.8,1.7,4.2.9,6.7l-17.6,61.1c-1.5,5.1-6.9,9.3-12,9.3h-10c-1.2,0-2.2.8-2.6,1.9l-3.3,11.5c-1.5,5.1-6.9,9.3-12,9.3h-15.5ZM125.5,57c-1.2,0-2.2.8-2.6,1.9l-8.3,28.8c-.2.8,0,1.7.4,2.3.5.7,1.3,1.1,2.1,1.1h2.8c1.2,0,2.2-.8,2.6-1.9l8.3-28.8c.2-.8,0-1.7-.4-2.3-.5-.7-1.3-1.1-2.1-1.1h-2.8Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 21 KiB |
BIN
ComfyUI_vibe/public/thumbnails/asset-1.jpg
Normal file
|
After Width: | Height: | Size: 8.6 KiB |
BIN
ComfyUI_vibe/public/thumbnails/asset-2.jpg
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
ComfyUI_vibe/public/thumbnails/canvas-1.jpg
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
ComfyUI_vibe/public/thumbnails/canvas-2.jpg
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
ComfyUI_vibe/public/thumbnails/project-1.jpg
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
ComfyUI_vibe/public/thumbnails/project-2.jpg
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
ComfyUI_vibe/public/thumbnails/workflow-1.jpg
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
ComfyUI_vibe/public/thumbnails/workflow-2.jpg
Normal file
|
After Width: | Height: | Size: 30 KiB |
@@ -337,3 +337,15 @@ body {
|
||||
--p-tooltip-background: #18181b;
|
||||
--p-tooltip-color: #fafafa;
|
||||
}
|
||||
|
||||
/* ===================== PrimeVue Popover Overrides ===================== */
|
||||
@layer primevue {
|
||||
.p-popover {
|
||||
--p-popover-background: #18181b;
|
||||
--p-popover-border-color: #3f3f46;
|
||||
--p-popover-border-radius: 0.5rem;
|
||||
--p-popover-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1);
|
||||
--p-popover-padding: 0;
|
||||
--p-popover-content-padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
2
ComfyUI_vibe/src/components.d.ts
vendored
@@ -63,7 +63,9 @@ declare module 'vue' {
|
||||
WidgetText: typeof import('./components/v2/nodes/widgets/WidgetText.vue')['default']
|
||||
WidgetToggle: typeof import('./components/v2/nodes/widgets/WidgetToggle.vue')['default']
|
||||
WorkflowsTab: typeof import('./components/v2/workspace/WorkflowsTab.vue')['default']
|
||||
WorkspaceCard: typeof import('./components/v2/workspace/WorkspaceCard.vue')['default']
|
||||
WorkspaceEmptyState: typeof import('./components/v2/workspace/WorkspaceEmptyState.vue')['default']
|
||||
WorkspaceFilterSelect: typeof import('./components/v2/workspace/WorkspaceFilterSelect.vue')['default']
|
||||
WorkspaceLayout: typeof import('./components/v2/layout/WorkspaceLayout.vue')['default']
|
||||
WorkspaceSearchInput: typeof import('./components/v2/workspace/WorkspaceSearchInput.vue')['default']
|
||||
WorkspaceSidebar: typeof import('./components/v2/layout/WorkspaceSidebar.vue')['default']
|
||||
|
||||
@@ -1,9 +1,23 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { computed, ref } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import Tooltip from 'primevue/tooltip'
|
||||
import Popover from 'primevue/popover'
|
||||
import { useUiStore } from '@/stores/uiStore'
|
||||
|
||||
const vTooltip = Tooltip
|
||||
const uiStore = useUiStore()
|
||||
|
||||
const accountMenu = ref<InstanceType<typeof Popover> | null>(null)
|
||||
const logoMenu = ref<InstanceType<typeof Popover> | null>(null)
|
||||
|
||||
function toggleAccountMenu(event: Event): void {
|
||||
accountMenu.value?.toggle(event)
|
||||
}
|
||||
|
||||
function toggleLogoMenu(event: Event): void {
|
||||
logoMenu.value?.toggle(event)
|
||||
}
|
||||
|
||||
interface MenuItem {
|
||||
label: string
|
||||
@@ -31,18 +45,33 @@ const userMenuGroups = computed<MenuGroup[]>(() => [
|
||||
label: 'Overview',
|
||||
items: [
|
||||
{ label: 'Dashboard', icon: 'pi pi-home', route: `/${props.workspaceId}` },
|
||||
{ label: 'Recents', icon: 'pi pi-clock', route: `/${props.workspaceId}/recents` },
|
||||
{ label: 'Projects', icon: 'pi pi-folder', route: `/${props.workspaceId}/projects` },
|
||||
{ label: 'Canvases', icon: 'pi pi-objects-column', route: `/${props.workspaceId}/canvases` }
|
||||
{ label: 'Recents', icon: 'pi pi-clock', route: `/${props.workspaceId}/recents` }
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Library',
|
||||
label: 'My Library',
|
||||
items: [
|
||||
{ label: 'Projects', icon: 'pi pi-folder', route: `/${props.workspaceId}/projects` },
|
||||
{ label: 'Canvases', icon: 'pi pi-objects-column', route: `/${props.workspaceId}/canvases` },
|
||||
{ label: 'Templates', icon: 'pi pi-th-large', route: `/${props.workspaceId}/templates` },
|
||||
{ label: 'Workflows', icon: 'pi pi-sitemap', route: `/${props.workspaceId}/workflows` },
|
||||
{ label: 'Assets', icon: 'pi pi-images', route: `/${props.workspaceId}/assets` },
|
||||
{ label: 'Models', icon: 'pi pi-box', route: `/${props.workspaceId}/models` },
|
||||
{ label: 'Trash', icon: 'pi pi-trash', route: `/${props.workspaceId}/trash` }
|
||||
{ label: 'Models', icon: 'pi pi-box', route: `/${props.workspaceId}/models` }
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Shared Projects',
|
||||
items: [
|
||||
{ label: 'Image Generation', icon: 'pi pi-folder', route: `/${props.workspaceId}/img-gen` },
|
||||
{ label: 'Video Processing', icon: 'pi pi-folder', route: `/${props.workspaceId}/video-proc` },
|
||||
{ label: 'Audio Enhancement', icon: 'pi pi-folder', route: `/${props.workspaceId}/audio-enh` }
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Starred',
|
||||
items: [
|
||||
{ label: 'Main Workflow', icon: 'pi pi-star-fill', route: `/${props.workspaceId}/img-gen/main-workflow` },
|
||||
{ label: 'Upscale 4x', icon: 'pi pi-star-fill', route: `/${props.workspaceId}/upscale/upscale-4x` }
|
||||
]
|
||||
}
|
||||
])
|
||||
@@ -52,29 +81,43 @@ const teamMenuGroups = computed<MenuGroup[]>(() => [
|
||||
label: 'Overview',
|
||||
items: [
|
||||
{ label: 'Dashboard', icon: 'pi pi-home', route: `/${props.workspaceId}` },
|
||||
{ label: 'Recents', icon: 'pi pi-clock', route: `/${props.workspaceId}/recents` },
|
||||
{ label: 'Projects', icon: 'pi pi-folder', route: `/${props.workspaceId}/projects` },
|
||||
{ label: 'Canvases', icon: 'pi pi-objects-column', route: `/${props.workspaceId}/canvases` }
|
||||
{ label: 'Recents', icon: 'pi pi-clock', route: `/${props.workspaceId}/recents` }
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Library',
|
||||
label: 'My Library',
|
||||
items: [
|
||||
{ label: 'Projects', icon: 'pi pi-folder', route: `/${props.workspaceId}/projects` },
|
||||
{ label: 'Canvases', icon: 'pi pi-objects-column', route: `/${props.workspaceId}/canvases` },
|
||||
{ label: 'Templates', icon: 'pi pi-th-large', route: `/${props.workspaceId}/templates` },
|
||||
{ label: 'Workflows', icon: 'pi pi-sitemap', route: `/${props.workspaceId}/workflows` },
|
||||
{ label: 'Assets', icon: 'pi pi-images', route: `/${props.workspaceId}/assets` },
|
||||
{ label: 'Models', icon: 'pi pi-box', route: `/${props.workspaceId}/models` },
|
||||
{ label: 'Trash', icon: 'pi pi-trash', route: `/${props.workspaceId}/trash` }
|
||||
{ label: 'Models', icon: 'pi pi-box', route: `/${props.workspaceId}/models` }
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Team',
|
||||
label: 'Shared Projects',
|
||||
items: [
|
||||
{ label: 'Members', icon: 'pi pi-users', route: `/${props.workspaceId}/members`, badge: 8 },
|
||||
{ label: 'Activity', icon: 'pi pi-history', route: `/${props.workspaceId}/activity` }
|
||||
{ label: 'Image Generation', icon: 'pi pi-folder', route: `/${props.workspaceId}/img-gen` },
|
||||
{ label: 'Video Processing', icon: 'pi pi-folder', route: `/${props.workspaceId}/video-proc` },
|
||||
{ label: 'Audio Enhancement', icon: 'pi pi-folder', route: `/${props.workspaceId}/audio-enh` }
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Starred',
|
||||
items: [
|
||||
{ label: 'Main Workflow', icon: 'pi pi-star-fill', route: `/${props.workspaceId}/img-gen/main-workflow` },
|
||||
{ label: 'Upscale 4x', icon: 'pi pi-star-fill', route: `/${props.workspaceId}/upscale/upscale-4x` }
|
||||
]
|
||||
}
|
||||
])
|
||||
|
||||
const trashItem = computed<MenuItem>(() => ({
|
||||
label: 'Trash',
|
||||
icon: 'pi pi-trash',
|
||||
route: `/${props.workspaceId}/trash`
|
||||
}))
|
||||
|
||||
const menuGroups = computed(() => (isTeam.value ? teamMenuGroups.value : userMenuGroups.value))
|
||||
|
||||
function isActive(itemRoute?: string): boolean {
|
||||
@@ -92,26 +135,124 @@ function signOut(): void {
|
||||
|
||||
<template>
|
||||
<aside
|
||||
class="flex h-full w-60 flex-col border-r border-zinc-200 bg-zinc-50/50 dark:border-zinc-800 dark:bg-zinc-950"
|
||||
class="flex h-full w-[300px] flex-col border-r border-zinc-200 bg-zinc-50/50 dark:border-zinc-800 dark:bg-zinc-950"
|
||||
>
|
||||
<!-- Header -->
|
||||
<div class="flex h-14 items-center gap-3 border-b border-zinc-200 px-4 dark:border-zinc-800">
|
||||
<div
|
||||
<!-- Logo -->
|
||||
<div class="flex h-14 items-center justify-between px-3">
|
||||
<button
|
||||
class="flex items-center gap-1.5 rounded-md px-2 py-1.5 transition-colors hover:bg-zinc-100 dark:hover:bg-zinc-800"
|
||||
@click="toggleLogoMenu"
|
||||
>
|
||||
<img src="/comfy-logo-yellow.svg" alt="ComfyUI" class="h-6" />
|
||||
<i class="pi pi-chevron-down text-[10px] text-zinc-400" />
|
||||
</button>
|
||||
|
||||
<!-- Settings -->
|
||||
<RouterLink
|
||||
v-tooltip.bottom="'Settings'"
|
||||
:to="`/${workspaceId}/settings`"
|
||||
:class="[
|
||||
'flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-md text-sm font-semibold',
|
||||
isTeam ? 'bg-blue-600 text-white' : 'bg-zinc-900 text-white dark:bg-zinc-100 dark:text-zinc-900'
|
||||
'flex h-8 w-8 items-center justify-center rounded-md transition-colors',
|
||||
isActive(`/${workspaceId}/settings`)
|
||||
? 'bg-zinc-900 text-white dark:bg-zinc-100 dark:text-zinc-900'
|
||||
: 'text-zinc-500 hover:bg-zinc-100 hover:text-zinc-700 dark:text-zinc-400 dark:hover:bg-zinc-800 dark:hover:text-zinc-200'
|
||||
]"
|
||||
>
|
||||
{{ workspaceId.charAt(0).toUpperCase() }}
|
||||
</div>
|
||||
<div class="flex-1 overflow-hidden">
|
||||
<p class="truncate text-sm font-medium text-zinc-900 dark:text-zinc-100">
|
||||
{{ workspaceId }}
|
||||
</p>
|
||||
<p class="text-xs text-zinc-500 dark:text-zinc-400">
|
||||
{{ isTeam ? 'Team' : 'Personal' }}
|
||||
</p>
|
||||
</div>
|
||||
<i class="pi pi-cog text-base" />
|
||||
</RouterLink>
|
||||
|
||||
<!-- Logo Menu Popover -->
|
||||
<Popover ref="logoMenu" append-to="self">
|
||||
<div class="flex w-60 flex-col p-1">
|
||||
<!-- File Section -->
|
||||
<div class="px-3 pb-1 pt-1.5 text-[11px] font-medium uppercase tracking-wide text-zinc-500 dark:text-zinc-400">
|
||||
File
|
||||
</div>
|
||||
<button class="flex w-full items-center gap-2.5 rounded-md px-3 py-2 text-left text-[13px] text-zinc-700 transition-colors hover:bg-zinc-100 dark:text-zinc-200 dark:hover:bg-zinc-800">
|
||||
<i class="pi pi-file w-4 text-sm text-zinc-400" />
|
||||
<span class="flex-1">New Workflow</span>
|
||||
<span class="text-[11px] text-zinc-400">Ctrl+N</span>
|
||||
</button>
|
||||
<button class="flex w-full items-center gap-2.5 rounded-md px-3 py-2 text-left text-[13px] text-zinc-700 transition-colors hover:bg-zinc-100 dark:text-zinc-200 dark:hover:bg-zinc-800">
|
||||
<i class="pi pi-folder-open w-4 text-sm text-zinc-400" />
|
||||
<span class="flex-1">Open...</span>
|
||||
<span class="text-[11px] text-zinc-400">Ctrl+O</span>
|
||||
</button>
|
||||
<button class="flex w-full items-center gap-2.5 rounded-md px-3 py-2 text-left text-[13px] text-zinc-700 transition-colors hover:bg-zinc-100 dark:text-zinc-200 dark:hover:bg-zinc-800">
|
||||
<i class="pi pi-save w-4 text-sm text-zinc-400" />
|
||||
<span class="flex-1">Save</span>
|
||||
<span class="text-[11px] text-zinc-400">Ctrl+S</span>
|
||||
</button>
|
||||
<button class="flex w-full items-center gap-2.5 rounded-md px-3 py-2 text-left text-[13px] text-zinc-700 transition-colors hover:bg-zinc-100 dark:text-zinc-200 dark:hover:bg-zinc-800">
|
||||
<i class="pi pi-download w-4 text-sm text-zinc-400" />
|
||||
<span>Export...</span>
|
||||
</button>
|
||||
|
||||
<div class="mx-2 my-1 h-px bg-zinc-200 dark:bg-zinc-700" />
|
||||
|
||||
<!-- Workspace Section -->
|
||||
<div class="px-3 pb-1 pt-1.5 text-[11px] font-medium uppercase tracking-wide text-zinc-500 dark:text-zinc-400">
|
||||
Workspace
|
||||
</div>
|
||||
<RouterLink
|
||||
:to="`/${workspaceId}`"
|
||||
class="flex w-full items-center gap-2.5 rounded-md px-3 py-2 text-left text-[13px] text-zinc-700 transition-colors hover:bg-zinc-100 dark:text-zinc-200 dark:hover:bg-zinc-800"
|
||||
@click="logoMenu?.hide()"
|
||||
>
|
||||
<i class="pi pi-home w-4 text-sm text-zinc-400" />
|
||||
<span>Dashboard</span>
|
||||
</RouterLink>
|
||||
<RouterLink
|
||||
:to="`/${workspaceId}/projects`"
|
||||
class="flex w-full items-center gap-2.5 rounded-md px-3 py-2 text-left text-[13px] text-zinc-700 transition-colors hover:bg-zinc-100 dark:text-zinc-200 dark:hover:bg-zinc-800"
|
||||
@click="logoMenu?.hide()"
|
||||
>
|
||||
<i class="pi pi-folder w-4 text-sm text-zinc-400" />
|
||||
<span>Projects</span>
|
||||
</RouterLink>
|
||||
|
||||
<div class="mx-2 my-1 h-px bg-zinc-200 dark:bg-zinc-700" />
|
||||
|
||||
<!-- Account Section -->
|
||||
<div class="px-3 pb-1 pt-1.5 text-[11px] font-medium uppercase tracking-wide text-zinc-500 dark:text-zinc-400">
|
||||
Account
|
||||
</div>
|
||||
<RouterLink
|
||||
:to="`/${workspaceId}/settings`"
|
||||
class="flex w-full items-center gap-2.5 rounded-md px-3 py-2 text-left text-[13px] text-zinc-700 transition-colors hover:bg-zinc-100 dark:text-zinc-200 dark:hover:bg-zinc-800"
|
||||
@click="logoMenu?.hide()"
|
||||
>
|
||||
<i class="pi pi-cog w-4 text-sm text-zinc-400" />
|
||||
<span>Settings</span>
|
||||
</RouterLink>
|
||||
<button
|
||||
class="flex w-full items-center gap-2.5 rounded-md px-3 py-2 text-left text-[13px] text-zinc-700 transition-colors hover:bg-zinc-100 dark:text-zinc-200 dark:hover:bg-zinc-800"
|
||||
@click="uiStore.toggleInterfaceVersion()"
|
||||
>
|
||||
<i class="pi pi-sparkles w-4 text-sm text-zinc-400" />
|
||||
<span class="flex-1">Experimental UI</span>
|
||||
<div
|
||||
class="h-5 w-9 rounded-full p-0.5 transition-colors"
|
||||
:class="uiStore.interfaceVersion === 'v2' ? 'bg-blue-500' : 'bg-zinc-300 dark:bg-zinc-600'"
|
||||
>
|
||||
<div
|
||||
class="h-4 w-4 rounded-full bg-white transition-transform"
|
||||
:class="uiStore.interfaceVersion === 'v2' ? 'translate-x-4' : 'translate-x-0'"
|
||||
/>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<div class="mx-2 my-1 h-px bg-zinc-200 dark:bg-zinc-700" />
|
||||
|
||||
<button
|
||||
class="flex w-full items-center gap-2.5 rounded-md px-3 py-2 text-left text-[13px] text-red-500 transition-colors hover:bg-red-50 dark:text-red-400 dark:hover:bg-red-500/10"
|
||||
@click="signOut(); logoMenu?.hide()"
|
||||
>
|
||||
<i class="pi pi-sign-out w-4 text-sm" />
|
||||
<span>Sign out</span>
|
||||
</button>
|
||||
</div>
|
||||
</Popover>
|
||||
</div>
|
||||
|
||||
<!-- Menu Groups -->
|
||||
@@ -153,27 +294,139 @@ function signOut(): void {
|
||||
</template>
|
||||
</nav>
|
||||
|
||||
<!-- Footer -->
|
||||
<div class="flex items-center justify-end gap-1 border-t border-zinc-200 px-3 py-2 dark:border-zinc-800">
|
||||
<!-- Trash -->
|
||||
<div class="px-3 pb-2">
|
||||
<RouterLink
|
||||
v-tooltip.top="'Settings'"
|
||||
:to="`/${workspaceId}/settings`"
|
||||
:to="trashItem.route ?? '#'"
|
||||
:class="[
|
||||
'flex h-8 w-8 items-center justify-center rounded-md transition-colors',
|
||||
isActive(`/${workspaceId}/settings`)
|
||||
? 'bg-zinc-900 text-white dark:bg-zinc-100 dark:text-zinc-900'
|
||||
: 'text-zinc-500 hover:bg-zinc-100 hover:text-zinc-700 dark:text-zinc-400 dark:hover:bg-zinc-800 dark:hover:text-zinc-200'
|
||||
'flex items-center gap-3 rounded-md px-2 py-1.5 text-sm transition-colors',
|
||||
isActive(trashItem.route)
|
||||
? 'bg-zinc-900 font-medium text-white dark:bg-zinc-100 dark:text-zinc-900'
|
||||
: 'text-zinc-600 hover:bg-zinc-100 hover:text-zinc-900 dark:text-zinc-400 dark:hover:bg-zinc-800 dark:hover:text-zinc-100'
|
||||
]"
|
||||
>
|
||||
<i class="pi pi-cog text-base" />
|
||||
<i :class="[trashItem.icon, 'text-base']" />
|
||||
<span>{{ trashItem.label }}</span>
|
||||
</RouterLink>
|
||||
</div>
|
||||
|
||||
<!-- Footer -->
|
||||
<div class="border-t border-zinc-200 px-3 py-3 dark:border-zinc-800">
|
||||
<!-- Account Dropdown -->
|
||||
<button
|
||||
v-tooltip.top="'Sign out'"
|
||||
class="flex h-8 w-8 items-center justify-center rounded-md text-zinc-500 transition-colors hover:bg-zinc-100 hover:text-zinc-700 dark:text-zinc-400 dark:hover:bg-zinc-800 dark:hover:text-zinc-200"
|
||||
@click="signOut"
|
||||
class="flex w-full items-center gap-2 rounded-md px-2 py-1.5 transition-colors hover:bg-zinc-100 dark:hover:bg-zinc-800"
|
||||
@click="toggleAccountMenu"
|
||||
>
|
||||
<i class="pi pi-sign-out text-base" />
|
||||
<div
|
||||
:class="[
|
||||
'flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full text-xs font-semibold',
|
||||
isTeam ? 'bg-blue-600 text-white' : 'bg-zinc-900 text-white dark:bg-zinc-100 dark:text-zinc-900'
|
||||
]"
|
||||
>
|
||||
J
|
||||
</div>
|
||||
<div class="flex-1 overflow-hidden text-left">
|
||||
<p class="truncate text-sm font-medium text-zinc-900 dark:text-zinc-100">
|
||||
John Doe
|
||||
</p>
|
||||
<p class="text-xs text-zinc-500 dark:text-zinc-400">
|
||||
{{ isTeam ? 'Netflix' : 'Personal Workspace' }}
|
||||
</p>
|
||||
</div>
|
||||
<i class="pi pi-chevron-down text-xs text-zinc-400" />
|
||||
</button>
|
||||
|
||||
<!-- Account Popover -->
|
||||
<Popover ref="accountMenu" append-to="self">
|
||||
<div class="flex w-64 flex-col p-2">
|
||||
<!-- Personal -->
|
||||
<p class="px-2 py-1 text-[11px] font-medium uppercase tracking-wide text-zinc-400 dark:text-zinc-500">
|
||||
Personal
|
||||
</p>
|
||||
<RouterLink
|
||||
to="/user"
|
||||
class="flex items-center gap-2.5 rounded-md px-2 py-2 text-sm text-zinc-700 transition-colors hover:bg-zinc-100 dark:text-zinc-300 dark:hover:bg-zinc-800"
|
||||
@click="accountMenu?.hide()"
|
||||
>
|
||||
<div class="flex h-7 w-7 items-center justify-center rounded-full bg-zinc-900 text-xs font-semibold text-white dark:bg-zinc-100 dark:text-zinc-900">
|
||||
U
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<p class="font-medium">My Workspace</p>
|
||||
<p class="text-xs text-zinc-500 dark:text-zinc-400">Owner</p>
|
||||
</div>
|
||||
</RouterLink>
|
||||
|
||||
<div class="my-2 h-px bg-zinc-200 dark:bg-zinc-700" />
|
||||
|
||||
<!-- Team Workspaces -->
|
||||
<p class="px-2 py-1 text-[11px] font-medium uppercase tracking-wide text-zinc-400 dark:text-zinc-500">
|
||||
Acme Studio
|
||||
</p>
|
||||
<RouterLink
|
||||
to="/team"
|
||||
class="flex items-center gap-2.5 rounded-md px-2 py-2 text-sm text-zinc-700 transition-colors hover:bg-zinc-100 dark:text-zinc-300 dark:hover:bg-zinc-800"
|
||||
@click="accountMenu?.hide()"
|
||||
>
|
||||
<div class="flex h-7 w-7 items-center justify-center rounded-full bg-violet-600 text-xs font-semibold text-white">
|
||||
<i class="pi pi-sitemap text-xs" />
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<p class="font-medium">Workflow Builder</p>
|
||||
<p class="text-xs text-zinc-500 dark:text-zinc-400">Full access</p>
|
||||
</div>
|
||||
</RouterLink>
|
||||
<RouterLink
|
||||
to="/team-artist"
|
||||
class="flex items-center gap-2.5 rounded-md px-2 py-2 text-sm text-zinc-700 transition-colors hover:bg-zinc-100 dark:text-zinc-300 dark:hover:bg-zinc-800"
|
||||
@click="accountMenu?.hide()"
|
||||
>
|
||||
<div class="flex h-7 w-7 items-center justify-center rounded-full bg-pink-600 text-xs font-semibold text-white">
|
||||
<i class="pi pi-palette text-xs" />
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<p class="font-medium">Visual Artist</p>
|
||||
<p class="text-xs text-zinc-500 dark:text-zinc-400">Edit assets & canvases</p>
|
||||
</div>
|
||||
</RouterLink>
|
||||
<RouterLink
|
||||
to="/team-motion"
|
||||
class="flex items-center gap-2.5 rounded-md px-2 py-2 text-sm text-zinc-700 transition-colors hover:bg-zinc-100 dark:text-zinc-300 dark:hover:bg-zinc-800"
|
||||
@click="accountMenu?.hide()"
|
||||
>
|
||||
<div class="flex h-7 w-7 items-center justify-center rounded-full bg-orange-600 text-xs font-semibold text-white">
|
||||
<i class="pi pi-video text-xs" />
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<p class="font-medium">Motion Designer</p>
|
||||
<p class="text-xs text-zinc-500 dark:text-zinc-400">Edit video workflows</p>
|
||||
</div>
|
||||
</RouterLink>
|
||||
<RouterLink
|
||||
to="/team-pm"
|
||||
class="flex items-center gap-2.5 rounded-md px-2 py-2 text-sm text-zinc-700 transition-colors hover:bg-zinc-100 dark:text-zinc-300 dark:hover:bg-zinc-800"
|
||||
@click="accountMenu?.hide()"
|
||||
>
|
||||
<div class="flex h-7 w-7 items-center justify-center rounded-full bg-emerald-600 text-xs font-semibold text-white">
|
||||
<i class="pi pi-chart-bar text-xs" />
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<p class="font-medium">Project Manager</p>
|
||||
<p class="text-xs text-zinc-500 dark:text-zinc-400">View only</p>
|
||||
</div>
|
||||
</RouterLink>
|
||||
|
||||
<div class="my-2 h-px bg-zinc-200 dark:bg-zinc-700" />
|
||||
|
||||
<button
|
||||
class="flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-sm text-red-500 transition-colors hover:bg-red-50 dark:text-red-400 dark:hover:bg-red-500/10"
|
||||
@click="signOut(); accountMenu?.hide()"
|
||||
>
|
||||
<i class="pi pi-sign-out text-sm" />
|
||||
<span>Sign out</span>
|
||||
</button>
|
||||
</div>
|
||||
</Popover>
|
||||
</div>
|
||||
</aside>
|
||||
</template>
|
||||
|
||||
99
ComfyUI_vibe/src/components/v2/workspace/WorkspaceCard.vue
Normal file
@@ -0,0 +1,99 @@
|
||||
<script setup lang="ts">
|
||||
interface Props {
|
||||
thumbnail: string
|
||||
title: string
|
||||
description?: string
|
||||
icon?: string
|
||||
badge?: string
|
||||
badgeClass?: string
|
||||
stats?: Array<{ icon: string; value: string | number }>
|
||||
updatedAt?: string
|
||||
actionLabel?: string
|
||||
actionIcon?: string
|
||||
}
|
||||
|
||||
withDefaults(defineProps<Props>(), {
|
||||
description: undefined,
|
||||
icon: undefined,
|
||||
badge: undefined,
|
||||
badgeClass: 'bg-zinc-500/20 text-zinc-400',
|
||||
stats: () => [],
|
||||
updatedAt: undefined,
|
||||
actionLabel: undefined,
|
||||
actionIcon: undefined
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
click: []
|
||||
menu: [event: MouseEvent]
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="group cursor-pointer overflow-hidden rounded-lg border border-zinc-200 bg-white text-left transition-all hover:border-zinc-300 hover:shadow-sm dark:border-zinc-800 dark:bg-zinc-900 dark:hover:border-zinc-700"
|
||||
@click="emit('click')"
|
||||
>
|
||||
<div class="relative aspect-square overflow-hidden">
|
||||
<img
|
||||
:src="thumbnail"
|
||||
:alt="title"
|
||||
class="h-full w-full object-cover transition-transform duration-300 group-hover:scale-105"
|
||||
/>
|
||||
<div class="absolute inset-0 bg-gradient-to-t from-black/60 via-transparent to-transparent" />
|
||||
|
||||
<!-- Type icon badge (bottom-left) -->
|
||||
<div
|
||||
v-if="icon"
|
||||
class="absolute bottom-2 left-2 flex h-8 w-8 items-center justify-center rounded-md bg-black/30 backdrop-blur-sm"
|
||||
>
|
||||
<i :class="[icon, 'text-sm text-white/90']" />
|
||||
</div>
|
||||
|
||||
<!-- Menu button (top-right) -->
|
||||
<button
|
||||
class="absolute right-2 top-2 rounded p-1 text-white/70 opacity-0 transition-opacity hover:bg-black/20 hover:text-white group-hover:opacity-100"
|
||||
@click.stop="emit('menu', $event)"
|
||||
>
|
||||
<i class="pi pi-ellipsis-h text-sm" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="p-3">
|
||||
<div class="flex items-start justify-between gap-2">
|
||||
<div class="min-w-0 flex-1">
|
||||
<h3 class="truncate font-medium text-zinc-900 dark:text-zinc-100">{{ title }}</h3>
|
||||
<p v-if="description" class="mt-0.5 line-clamp-1 text-sm text-zinc-500 dark:text-zinc-400">
|
||||
{{ description }}
|
||||
</p>
|
||||
</div>
|
||||
<!-- Action button -->
|
||||
<span
|
||||
v-if="actionLabel"
|
||||
class="inline-flex flex-shrink-0 items-center gap-1 rounded-md bg-blue-50 px-2 py-1 text-xs font-medium text-blue-600 transition-colors group-hover:bg-blue-600 group-hover:text-white dark:bg-blue-950 dark:text-blue-400 dark:group-hover:bg-blue-600 dark:group-hover:text-white"
|
||||
>
|
||||
<i v-if="actionIcon" :class="[actionIcon, 'text-[10px]']" />
|
||||
{{ actionLabel }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div v-if="badge || stats.length > 0 || updatedAt" class="mt-2 flex items-center gap-2 text-xs text-zinc-400 dark:text-zinc-500">
|
||||
<!-- Badge -->
|
||||
<span v-if="badge" :class="['rounded px-1.5 py-0.5 text-[10px] font-medium', badgeClass]">
|
||||
{{ badge }}
|
||||
</span>
|
||||
|
||||
<!-- Stats -->
|
||||
<template v-if="stats.length > 0">
|
||||
<span v-for="(stat, idx) in stats" :key="idx" class="flex items-center gap-1">
|
||||
<i v-if="stat.icon" :class="[stat.icon, 'text-[10px]']" />
|
||||
{{ stat.value }}
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<!-- Updated time -->
|
||||
<span v-if="updatedAt" class="ml-auto">{{ updatedAt }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,30 @@
|
||||
<script setup lang="ts">
|
||||
interface FilterOption {
|
||||
value: string
|
||||
label: string
|
||||
}
|
||||
|
||||
defineProps<{
|
||||
modelValue: string
|
||||
options: FilterOption[]
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
'update:modelValue': [value: string]
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="relative">
|
||||
<select
|
||||
:value="modelValue"
|
||||
class="appearance-none rounded-md border border-zinc-200 bg-white py-2 pl-3 pr-8 text-sm text-zinc-700 outline-none transition-colors focus:border-zinc-400 focus:ring-1 focus:ring-zinc-400 dark:border-zinc-700 dark:bg-zinc-800 dark:text-zinc-300 dark:focus:border-zinc-500 dark:focus:ring-zinc-500"
|
||||
@change="emit('update:modelValue', ($event.target as HTMLSelectElement).value)"
|
||||
>
|
||||
<option v-for="option in options" :key="option.value" :value="option.value">
|
||||
{{ option.label }}
|
||||
</option>
|
||||
</select>
|
||||
<i class="pi pi-filter pointer-events-none absolute right-2.5 top-1/2 -translate-y-1/2 text-xs text-zinc-400" />
|
||||
</div>
|
||||
</template>
|
||||
@@ -3,4 +3,6 @@ export { default as WorkspaceEmptyState } from './WorkspaceEmptyState.vue'
|
||||
export { default as WorkspaceViewToggle } from './WorkspaceViewToggle.vue'
|
||||
export { default as WorkspaceSearchInput } from './WorkspaceSearchInput.vue'
|
||||
export { default as WorkspaceSortSelect } from './WorkspaceSortSelect.vue'
|
||||
export { default as WorkspaceFilterSelect } from './WorkspaceFilterSelect.vue'
|
||||
export { default as WorkspaceCard } from './WorkspaceCard.vue'
|
||||
export { default as CreateProjectDialog } from './CreateProjectDialog.vue'
|
||||
|
||||
@@ -47,6 +47,11 @@ const ComfyPreset = definePreset(Aura, {
|
||||
},
|
||||
select: {
|
||||
borderRadius: '8px'
|
||||
},
|
||||
popover: {
|
||||
borderRadius: '8px',
|
||||
shadow: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1)',
|
||||
padding: '0'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -54,6 +54,11 @@ const v2Routes: RouteRecordRaw[] = [
|
||||
name: 'workspace-recents',
|
||||
component: () => import('./views/v2/workspace/RecentsView.vue')
|
||||
},
|
||||
{
|
||||
path: 'templates',
|
||||
name: 'workspace-templates',
|
||||
component: () => import('./views/v2/workspace/TemplatesView.vue')
|
||||
},
|
||||
{
|
||||
path: 'trash',
|
||||
name: 'workspace-trash',
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { WorkspaceCard } from '@/components/v2/workspace'
|
||||
|
||||
const route = useRoute()
|
||||
const workspaceId = computed(() => route.params.workspaceId as string)
|
||||
|
||||
// View mode
|
||||
type ViewMode = 'grid' | 'list'
|
||||
const viewMode = ref<ViewMode>('list')
|
||||
const viewMode = ref<ViewMode>('grid')
|
||||
|
||||
// Filter type
|
||||
type AssetType = 'all' | 'image' | 'video' | 'audio'
|
||||
@@ -26,11 +27,11 @@ const sortOptions: { value: SortOption; label: string }[] = [
|
||||
|
||||
// Mock assets data
|
||||
const assets = ref([
|
||||
{ id: 'asset-1', name: 'input-image.png', type: 'image', size: '2.4 MB', sizeBytes: 2516582, dimensions: '1024x1024', updatedAt: '2 hours ago', updatedTimestamp: Date.now() - 2 * 60 * 60 * 1000 },
|
||||
{ id: 'asset-2', name: 'reference.jpg', type: 'image', size: '1.8 MB', sizeBytes: 1887437, dimensions: '768x768', updatedAt: '1 day ago', updatedTimestamp: Date.now() - 24 * 60 * 60 * 1000 },
|
||||
{ id: 'asset-3', name: 'mask.png', type: 'image', size: '0.5 MB', sizeBytes: 524288, dimensions: '512x512', updatedAt: '2 days ago', updatedTimestamp: Date.now() - 2 * 24 * 60 * 60 * 1000 },
|
||||
{ id: 'asset-4', name: 'output-video.mp4', type: 'video', size: '24.5 MB', sizeBytes: 25690112, dimensions: '1920x1080', updatedAt: '3 days ago', updatedTimestamp: Date.now() - 3 * 24 * 60 * 60 * 1000 },
|
||||
{ id: 'asset-5', name: 'background.wav', type: 'audio', size: '8.2 MB', sizeBytes: 8598323, dimensions: '3:24', updatedAt: '1 week ago', updatedTimestamp: Date.now() - 7 * 24 * 60 * 60 * 1000 }
|
||||
{ id: 'asset-1', name: 'input-image.png', type: 'image', size: '2.4 MB', sizeBytes: 2516582, dimensions: '1024x1024', updatedAt: '2 hours ago', updatedTimestamp: Date.now() - 2 * 60 * 60 * 1000, thumbnail: '/thumbnails/asset-1.jpg' },
|
||||
{ id: 'asset-2', name: 'reference.jpg', type: 'image', size: '1.8 MB', sizeBytes: 1887437, dimensions: '768x768', updatedAt: '1 day ago', updatedTimestamp: Date.now() - 24 * 60 * 60 * 1000, thumbnail: '/thumbnails/asset-2.jpg' },
|
||||
{ id: 'asset-3', name: 'mask.png', type: 'image', size: '0.5 MB', sizeBytes: 524288, dimensions: '512x512', updatedAt: '2 days ago', updatedTimestamp: Date.now() - 2 * 24 * 60 * 60 * 1000, thumbnail: '/assets/card_images/workflow_01.webp' },
|
||||
{ id: 'asset-4', name: 'output-video.mp4', type: 'video', size: '24.5 MB', sizeBytes: 25690112, dimensions: '1920x1080', updatedAt: '3 days ago', updatedTimestamp: Date.now() - 3 * 24 * 60 * 60 * 1000, thumbnail: '/assets/card_images/2690a78c-c210-4a52-8c37-3cb5bc4d9e71.webp' },
|
||||
{ id: 'asset-5', name: 'background.wav', type: 'audio', size: '8.2 MB', sizeBytes: 8598323, dimensions: '3:24', updatedAt: '1 week ago', updatedTimestamp: Date.now() - 7 * 24 * 60 * 60 * 1000, thumbnail: '/assets/card_images/bacb46ea-7e63-4f19-a253-daf41461e98f.webp' }
|
||||
])
|
||||
|
||||
// Search, filter and sort
|
||||
@@ -201,30 +202,17 @@ function getAssetIcon(type: string): string {
|
||||
v-else-if="viewMode === 'grid'"
|
||||
class="grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5"
|
||||
>
|
||||
<div
|
||||
<WorkspaceCard
|
||||
v-for="asset in filteredAssets"
|
||||
:key="asset.id"
|
||||
class="group aspect-square cursor-pointer rounded-lg border border-zinc-200 bg-white p-4 text-left transition-all hover:border-zinc-300 hover:shadow-sm dark:border-zinc-800 dark:bg-zinc-900 dark:hover:border-zinc-700"
|
||||
>
|
||||
<div class="flex h-full flex-col">
|
||||
<div class="flex items-start justify-between">
|
||||
<div class="flex h-10 w-10 items-center justify-center rounded-md bg-zinc-100 dark:bg-zinc-800">
|
||||
<i :class="[getAssetIcon(asset.type), 'text-zinc-500 dark:text-zinc-400']" />
|
||||
</div>
|
||||
<button
|
||||
class="rounded p-1 text-zinc-400 opacity-0 transition-opacity hover:bg-zinc-100 hover:text-zinc-600 group-hover:opacity-100 dark:hover:bg-zinc-800 dark:hover:text-zinc-300"
|
||||
@click.stop
|
||||
>
|
||||
<i class="pi pi-ellipsis-h text-sm" />
|
||||
</button>
|
||||
</div>
|
||||
<div class="mt-auto">
|
||||
<h3 class="truncate font-medium text-zinc-900 dark:text-zinc-100">{{ asset.name }}</h3>
|
||||
<p class="mt-1 text-sm text-zinc-500 dark:text-zinc-400">{{ asset.dimensions }}</p>
|
||||
<p class="mt-1 text-xs text-zinc-400 dark:text-zinc-500">{{ asset.size }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
:thumbnail="asset.thumbnail"
|
||||
:title="asset.name"
|
||||
:icon="getAssetIcon(asset.type)"
|
||||
:stats="[
|
||||
{ icon: '', value: asset.dimensions },
|
||||
{ icon: '', value: asset.size }
|
||||
]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- List View -->
|
||||
|
||||
@@ -105,6 +105,7 @@ const emptyStateDescription = computed(() =>
|
||||
<div class="p-6">
|
||||
<WorkspaceViewHeader
|
||||
title="Canvases"
|
||||
:subtitle="`${canvases.length} canvases`"
|
||||
action-label="New Canvas"
|
||||
@action="createCanvas"
|
||||
/>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { WorkspaceCard } from '@/components/v2/workspace'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
@@ -22,12 +23,12 @@ const recentActivity = [
|
||||
]
|
||||
|
||||
const starterTemplates = [
|
||||
{ id: 'txt2img', name: 'Text to Image', description: 'Generate images from text prompts', icon: 'pi pi-image', gradient: 'from-violet-500 to-purple-600' },
|
||||
{ id: 'img2img', name: 'Image to Image', description: 'Transform existing images', icon: 'pi pi-images', gradient: 'from-blue-500 to-cyan-500' },
|
||||
{ id: 'upscale', name: 'Upscale', description: '4x image upscaling workflow', icon: 'pi pi-expand', gradient: 'from-emerald-500 to-teal-600' },
|
||||
{ id: 'inpaint', name: 'Inpainting', description: 'Edit parts of an image', icon: 'pi pi-pencil', gradient: 'from-orange-500 to-amber-500' },
|
||||
{ id: 'controlnet', name: 'ControlNet', description: 'Guided image generation', icon: 'pi pi-sliders-h', gradient: 'from-pink-500 to-rose-600' },
|
||||
{ id: 'video', name: 'Video Generation', description: 'Create videos from prompts', icon: 'pi pi-video', gradient: 'from-indigo-500 to-blue-600' }
|
||||
{ id: 'txt2img', name: 'Text to Image', description: 'Generate images from text prompts', icon: 'pi pi-image', thumbnail: '/assets/card_images/workflow_01.webp' },
|
||||
{ id: 'img2img', name: 'Image to Image', description: 'Transform existing images', icon: 'pi pi-images', thumbnail: '/assets/card_images/2690a78c-c210-4a52-8c37-3cb5bc4d9e71.webp' },
|
||||
{ id: 'upscale', name: 'Upscale', description: '4x image upscaling workflow', icon: 'pi pi-expand', thumbnail: '/assets/card_images/bacb46ea-7e63-4f19-a253-daf41461e98f.webp' },
|
||||
{ id: 'inpaint', name: 'Inpainting', description: 'Edit parts of an image', icon: 'pi pi-pencil', thumbnail: '/assets/card_images/228616f4-12ad-426d-84fb-f20e488ba7ee.webp' },
|
||||
{ id: 'controlnet', name: 'ControlNet', description: 'Guided image generation', icon: 'pi pi-sliders-h', thumbnail: '/assets/card_images/683255d3-1d10-43d9-a6ff-ef142061e88a.webp' },
|
||||
{ id: 'video', name: 'Video Generation', description: 'Create videos from prompts', icon: 'pi pi-video', thumbnail: '/assets/card_images/91f1f589-ddb4-4c4f-b3a7-ba30fc271987.webp' }
|
||||
]
|
||||
</script>
|
||||
|
||||
@@ -89,33 +90,31 @@ const starterTemplates = [
|
||||
<div class="mb-8">
|
||||
<h2 class="mb-3 text-sm font-medium text-zinc-900 dark:text-zinc-100">Start from a template</h2>
|
||||
<div class="grid grid-cols-2 gap-3 sm:grid-cols-3 lg:grid-cols-6">
|
||||
<button
|
||||
<WorkspaceCard
|
||||
v-for="template in starterTemplates"
|
||||
:key="template.id"
|
||||
class="group overflow-hidden rounded-lg border border-zinc-200 bg-white text-left transition-all hover:border-zinc-300 hover:shadow-md dark:border-zinc-800 dark:bg-zinc-900 dark:hover:border-zinc-700"
|
||||
:thumbnail="template.thumbnail"
|
||||
:title="template.name"
|
||||
:description="template.description"
|
||||
:icon="template.icon"
|
||||
action-label="Run"
|
||||
action-icon="pi pi-play"
|
||||
@click="router.push(`/${workspaceId}/default/${template.id}`)"
|
||||
/>
|
||||
</div>
|
||||
<!-- View All Templates CTA -->
|
||||
<div class="mt-6 flex items-center gap-4 pt-2">
|
||||
<button
|
||||
class="inline-flex items-center gap-2 rounded-md border border-zinc-200 bg-white px-3 py-2 text-sm font-medium text-zinc-700 transition-colors hover:bg-zinc-50 dark:border-zinc-700 dark:bg-zinc-800 dark:text-zinc-300 dark:hover:bg-zinc-700"
|
||||
@click="router.push(`/${workspaceId}/templates`)"
|
||||
>
|
||||
<div
|
||||
:class="[
|
||||
'flex aspect-square items-center justify-center bg-gradient-to-br',
|
||||
template.gradient
|
||||
]"
|
||||
>
|
||||
<i :class="[template.icon, 'text-3xl text-white/90']" />
|
||||
</div>
|
||||
<div class="flex items-end justify-between gap-2 p-3">
|
||||
<div class="min-w-0 flex-1">
|
||||
<p class="text-sm font-medium text-zinc-900 dark:text-zinc-100">{{ template.name }}</p>
|
||||
<p class="mt-0.5 line-clamp-1 text-xs text-zinc-500 dark:text-zinc-400">{{ template.description }}</p>
|
||||
</div>
|
||||
<span
|
||||
class="inline-flex flex-shrink-0 items-center gap-1 rounded-md bg-blue-50 px-2 py-1 text-xs font-medium text-blue-600 transition-colors group-hover:bg-blue-600 group-hover:text-white dark:bg-blue-950 dark:text-blue-400 dark:group-hover:bg-blue-600 dark:group-hover:text-white"
|
||||
>
|
||||
<i class="pi pi-play text-[10px]" />
|
||||
Run
|
||||
</span>
|
||||
</div>
|
||||
View Templates
|
||||
<i class="pi pi-arrow-right text-xs" />
|
||||
</button>
|
||||
<span class="text-sm text-zinc-400 dark:text-zinc-500">
|
||||
<span class="font-semibold text-zinc-600 dark:text-zinc-300">803+</span> workflows, models, nodes by Comfy & community
|
||||
</span>
|
||||
<div class="h-px flex-1 bg-zinc-200 dark:bg-zinc-800" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
WorkspaceSearchInput,
|
||||
WorkspaceSortSelect,
|
||||
CreateProjectDialog,
|
||||
WorkspaceCard,
|
||||
} from '@/components/v2/workspace'
|
||||
|
||||
const route = useRoute()
|
||||
@@ -31,10 +32,10 @@ const sortOptions = [
|
||||
|
||||
// Projects data
|
||||
const projects = ref([
|
||||
{ id: 'img-gen', name: 'Image Generation', description: 'AI image generation workflows', canvasCount: 5, modelCount: 12, updatedAt: '2 hours ago', updatedTimestamp: Date.now() - 2 * 60 * 60 * 1000 },
|
||||
{ id: 'video-proc', name: 'Video Processing', description: 'Video enhancement and editing', canvasCount: 3, modelCount: 8, updatedAt: '1 day ago', updatedTimestamp: Date.now() - 24 * 60 * 60 * 1000 },
|
||||
{ id: 'audio-enh', name: 'Audio Enhancement', description: 'Audio processing pipelines', canvasCount: 2, modelCount: 4, updatedAt: '3 days ago', updatedTimestamp: Date.now() - 3 * 24 * 60 * 60 * 1000 },
|
||||
{ id: 'upscale', name: 'Upscaling', description: 'Image and video upscaling', canvasCount: 4, modelCount: 6, updatedAt: '1 week ago', updatedTimestamp: Date.now() - 7 * 24 * 60 * 60 * 1000 }
|
||||
{ id: 'img-gen', name: 'Image Generation', description: 'AI image generation workflows', canvasCount: 5, modelCount: 12, updatedAt: '2 hours ago', updatedTimestamp: Date.now() - 2 * 60 * 60 * 1000, thumbnail: '/thumbnails/project-1.jpg' },
|
||||
{ id: 'video-proc', name: 'Video Processing', description: 'Video enhancement and editing', canvasCount: 3, modelCount: 8, updatedAt: '1 day ago', updatedTimestamp: Date.now() - 24 * 60 * 60 * 1000, thumbnail: '/thumbnails/project-2.jpg' },
|
||||
{ id: 'audio-enh', name: 'Audio Enhancement', description: 'Audio processing pipelines', canvasCount: 2, modelCount: 4, updatedAt: '3 days ago', updatedTimestamp: Date.now() - 3 * 24 * 60 * 60 * 1000, thumbnail: '/assets/card_images/28e9f7ea-ef00-48e8-849d-8752a34939c7.webp' },
|
||||
{ id: 'upscale', name: 'Upscaling', description: 'Image and video upscaling', canvasCount: 4, modelCount: 6, updatedAt: '1 week ago', updatedTimestamp: Date.now() - 7 * 24 * 60 * 60 * 1000, thumbnail: '/assets/card_images/comfyui_workflow.jpg' }
|
||||
])
|
||||
|
||||
// Create dialog
|
||||
@@ -125,42 +126,19 @@ const emptyStateDescription = computed(() =>
|
||||
v-else-if="viewMode === 'grid'"
|
||||
class="grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5"
|
||||
>
|
||||
<div
|
||||
<WorkspaceCard
|
||||
v-for="project in filteredProjects"
|
||||
:key="project.id"
|
||||
class="group aspect-square cursor-pointer rounded-lg border border-zinc-200 bg-white p-4 text-left transition-all hover:border-zinc-300 hover:shadow-sm dark:border-zinc-800 dark:bg-zinc-900 dark:hover:border-zinc-700"
|
||||
:thumbnail="project.thumbnail"
|
||||
:title="project.name"
|
||||
:description="project.description"
|
||||
icon="pi pi-folder"
|
||||
:stats="[
|
||||
{ icon: 'pi pi-objects-column', value: project.canvasCount },
|
||||
{ icon: 'pi pi-box', value: project.modelCount }
|
||||
]"
|
||||
@click="openProject(project.id)"
|
||||
>
|
||||
<div class="flex h-full flex-col">
|
||||
<div class="flex items-start justify-between">
|
||||
<div class="flex h-10 w-10 items-center justify-center rounded-md bg-zinc-100 dark:bg-zinc-800">
|
||||
<i class="pi pi-folder text-zinc-500 dark:text-zinc-400" />
|
||||
</div>
|
||||
<button
|
||||
class="rounded p-1 text-zinc-400 opacity-0 transition-opacity hover:bg-zinc-100 hover:text-zinc-600 group-hover:opacity-100 dark:hover:bg-zinc-800 dark:hover:text-zinc-300"
|
||||
@click.stop
|
||||
>
|
||||
<i class="pi pi-ellipsis-h text-sm" />
|
||||
</button>
|
||||
</div>
|
||||
<div class="mt-auto">
|
||||
<h3 class="font-medium text-zinc-900 dark:text-zinc-100">{{ project.name }}</h3>
|
||||
<p class="mt-1 line-clamp-2 text-sm text-zinc-500 dark:text-zinc-400">
|
||||
{{ project.description }}
|
||||
</p>
|
||||
<div class="mt-2 flex items-center gap-3 text-xs text-zinc-400 dark:text-zinc-500">
|
||||
<span class="flex items-center gap-1">
|
||||
<i class="pi pi-objects-column" />
|
||||
{{ project.canvasCount }}
|
||||
</span>
|
||||
<span class="flex items-center gap-1">
|
||||
<i class="pi pi-box" />
|
||||
{{ project.modelCount }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- List View -->
|
||||
|
||||
@@ -1,6 +1,15 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import WorkspaceViewHeader from '@/components/v2/workspace/WorkspaceViewHeader.vue'
|
||||
import { ref, computed } from 'vue'
|
||||
import {
|
||||
WorkspaceViewHeader,
|
||||
WorkspaceSearchInput,
|
||||
WorkspaceViewToggle,
|
||||
WorkspaceSortSelect,
|
||||
WorkspaceFilterSelect,
|
||||
WorkspaceCard,
|
||||
} from '@/components/v2/workspace'
|
||||
|
||||
type ViewMode = 'grid' | 'list'
|
||||
|
||||
interface RecentItem {
|
||||
id: string
|
||||
@@ -8,20 +17,63 @@ interface RecentItem {
|
||||
type: 'canvas' | 'workflow' | 'asset' | 'project'
|
||||
icon: string
|
||||
updatedAt: string
|
||||
thumbnail?: string
|
||||
thumbnail: string
|
||||
}
|
||||
|
||||
const searchQuery = ref('')
|
||||
const viewMode = ref<ViewMode>('grid')
|
||||
const sortBy = ref('recent')
|
||||
const filterBy = ref('all')
|
||||
|
||||
const sortOptions = [
|
||||
{ value: 'recent', label: 'Most Recent' },
|
||||
{ value: 'name', label: 'Name' },
|
||||
{ value: 'type', label: 'Type' },
|
||||
]
|
||||
|
||||
const filterOptions = [
|
||||
{ value: 'all', label: 'All Types' },
|
||||
{ value: 'canvas', label: 'Canvas' },
|
||||
{ value: 'workflow', label: 'Workflow' },
|
||||
{ value: 'project', label: 'Project' },
|
||||
{ value: 'asset', label: 'Asset' },
|
||||
]
|
||||
|
||||
const recentItems = ref<RecentItem[]>([
|
||||
{ id: '1', name: 'Portrait Generation', type: 'canvas', icon: 'pi-objects-column', updatedAt: '2 minutes ago' },
|
||||
{ id: '2', name: 'SDXL Workflow', type: 'workflow', icon: 'pi-sitemap', updatedAt: '15 minutes ago' },
|
||||
{ id: '3', name: 'Product Shots', type: 'project', icon: 'pi-folder', updatedAt: '1 hour ago' },
|
||||
{ id: '4', name: 'reference_image.png', type: 'asset', icon: 'pi-image', updatedAt: '2 hours ago' },
|
||||
{ id: '5', name: 'Inpainting Canvas', type: 'canvas', icon: 'pi-objects-column', updatedAt: '3 hours ago' },
|
||||
{ id: '6', name: 'ControlNet Pipeline', type: 'workflow', icon: 'pi-sitemap', updatedAt: '5 hours ago' },
|
||||
{ id: '7', name: 'Marketing Assets', type: 'project', icon: 'pi-folder', updatedAt: 'Yesterday' },
|
||||
{ id: '8', name: 'logo_v2.png', type: 'asset', icon: 'pi-image', updatedAt: 'Yesterday' },
|
||||
{ id: '1', name: 'Portrait Generation', type: 'canvas', icon: 'pi pi-objects-column', updatedAt: '2 minutes ago', thumbnail: '/thumbnails/canvas-1.jpg' },
|
||||
{ id: '2', name: 'SDXL Workflow', type: 'workflow', icon: 'pi pi-sitemap', updatedAt: '15 minutes ago', thumbnail: '/thumbnails/workflow-1.jpg' },
|
||||
{ id: '3', name: 'Product Shots', type: 'project', icon: 'pi pi-folder', updatedAt: '1 hour ago', thumbnail: '/thumbnails/project-1.jpg' },
|
||||
{ id: '4', name: 'reference_image.png', type: 'asset', icon: 'pi pi-image', updatedAt: '2 hours ago', thumbnail: '/thumbnails/asset-1.jpg' },
|
||||
{ id: '5', name: 'Inpainting Canvas', type: 'canvas', icon: 'pi pi-objects-column', updatedAt: '3 hours ago', thumbnail: '/thumbnails/canvas-2.jpg' },
|
||||
{ id: '6', name: 'ControlNet Pipeline', type: 'workflow', icon: 'pi pi-sitemap', updatedAt: '5 hours ago', thumbnail: '/thumbnails/workflow-2.jpg' },
|
||||
{ id: '7', name: 'Marketing Assets', type: 'project', icon: 'pi pi-folder', updatedAt: 'Yesterday', thumbnail: '/thumbnails/project-2.jpg' },
|
||||
{ id: '8', name: 'logo_v2.png', type: 'asset', icon: 'pi pi-image', updatedAt: 'Yesterday', thumbnail: '/thumbnails/asset-2.jpg' },
|
||||
])
|
||||
|
||||
const filteredItems = computed(() => {
|
||||
let items = [...recentItems.value]
|
||||
|
||||
// Filter by type
|
||||
if (filterBy.value !== 'all') {
|
||||
items = items.filter(item => item.type === filterBy.value)
|
||||
}
|
||||
|
||||
// Filter by search query
|
||||
if (searchQuery.value) {
|
||||
const query = searchQuery.value.toLowerCase()
|
||||
items = items.filter(item => item.name.toLowerCase().includes(query))
|
||||
}
|
||||
|
||||
// Sort items
|
||||
if (sortBy.value === 'name') {
|
||||
items.sort((a, b) => a.name.localeCompare(b.name))
|
||||
} else if (sortBy.value === 'type') {
|
||||
items.sort((a, b) => a.type.localeCompare(b.type))
|
||||
}
|
||||
|
||||
return items
|
||||
})
|
||||
|
||||
function getTypeLabel(type: string): string {
|
||||
const labels: Record<string, string> = {
|
||||
canvas: 'Canvas',
|
||||
@@ -41,6 +93,7 @@ function getTypeColor(type: string): string {
|
||||
}
|
||||
return colors[type] || 'bg-zinc-500/20 text-zinc-400'
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -51,28 +104,68 @@ function getTypeColor(type: string): string {
|
||||
:show-create-buttons="true"
|
||||
/>
|
||||
|
||||
<div class="space-y-2">
|
||||
<div
|
||||
v-for="item in recentItems"
|
||||
<!-- Search & Actions Toolbar -->
|
||||
<div class="mb-4 flex items-center gap-3">
|
||||
<WorkspaceSearchInput
|
||||
v-model="searchQuery"
|
||||
placeholder="Search recents..."
|
||||
/>
|
||||
<WorkspaceViewToggle v-model="viewMode" />
|
||||
<WorkspaceSortSelect v-model="sortBy" :options="sortOptions" />
|
||||
<WorkspaceFilterSelect v-model="filterBy" :options="filterOptions" />
|
||||
</div>
|
||||
|
||||
<!-- Grid View -->
|
||||
<div
|
||||
v-if="viewMode === 'grid'"
|
||||
class="grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5"
|
||||
>
|
||||
<WorkspaceCard
|
||||
v-for="item in filteredItems"
|
||||
:key="item.id"
|
||||
class="flex items-center gap-4 rounded-lg border border-zinc-200 bg-white p-4 transition-colors hover:border-zinc-300 hover:bg-zinc-50 dark:border-zinc-800 dark:bg-zinc-900 dark:hover:border-zinc-700 dark:hover:bg-zinc-800/50"
|
||||
>
|
||||
<div class="flex h-10 w-10 items-center justify-center rounded-lg bg-zinc-100 dark:bg-zinc-800">
|
||||
<i :class="['pi', item.icon, 'text-lg text-zinc-500 dark:text-zinc-400']" />
|
||||
</div>
|
||||
<div class="flex-1 min-w-0">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-medium text-zinc-900 dark:text-zinc-100">{{ item.name }}</span>
|
||||
<span :class="['rounded px-1.5 py-0.5 text-[10px] font-medium', getTypeColor(item.type)]">
|
||||
{{ getTypeLabel(item.type) }}
|
||||
</span>
|
||||
:thumbnail="item.thumbnail"
|
||||
:title="item.name"
|
||||
:icon="item.icon"
|
||||
:badge="getTypeLabel(item.type)"
|
||||
:badge-class="getTypeColor(item.type)"
|
||||
:updated-at="item.updatedAt"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- List View -->
|
||||
<div v-else class="rounded-lg border border-zinc-200 bg-white dark:border-zinc-800 dark:bg-zinc-900">
|
||||
<div class="divide-y divide-zinc-100 dark:divide-zinc-800">
|
||||
<div
|
||||
v-for="item in filteredItems"
|
||||
:key="item.id"
|
||||
class="flex w-full cursor-pointer items-center gap-4 px-5 py-4 text-left transition-colors hover:bg-zinc-50 dark:hover:bg-zinc-800/50"
|
||||
>
|
||||
<div class="flex h-10 w-10 items-center justify-center rounded-md bg-zinc-100 dark:bg-zinc-800">
|
||||
<i :class="['pi', item.icon, 'text-zinc-500 dark:text-zinc-400']" />
|
||||
</div>
|
||||
<p class="text-sm text-zinc-500 dark:text-zinc-400">{{ item.updatedAt }}</p>
|
||||
<div class="flex-1 min-w-0">
|
||||
<p class="font-medium text-zinc-900 dark:text-zinc-100">{{ item.name }}</p>
|
||||
<p class="text-sm text-zinc-500 dark:text-zinc-400">
|
||||
<span :class="['rounded px-1.5 py-0.5 text-[10px] font-medium', getTypeColor(item.type)]">
|
||||
{{ getTypeLabel(item.type) }}
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<span class="text-sm text-zinc-400 dark:text-zinc-500">{{ item.updatedAt }}</span>
|
||||
<button
|
||||
class="rounded p-1 text-zinc-400 hover:bg-zinc-100 hover:text-zinc-600 dark:hover:bg-zinc-700 dark:hover:text-zinc-300"
|
||||
@click.stop
|
||||
>
|
||||
<i class="pi pi-ellipsis-h text-sm" />
|
||||
</button>
|
||||
</div>
|
||||
<button class="flex h-8 w-8 items-center justify-center rounded-md text-zinc-400 transition-colors hover:bg-zinc-100 hover:text-zinc-600 dark:hover:bg-zinc-800 dark:hover:text-zinc-300">
|
||||
<i class="pi pi-ellipsis-v text-sm" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Empty State -->
|
||||
<div v-if="filteredItems.length === 0" class="py-12 text-center">
|
||||
<i class="pi pi-search mb-4 text-4xl text-zinc-300 dark:text-zinc-600" />
|
||||
<p class="text-zinc-500 dark:text-zinc-400">No items found</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -46,29 +46,28 @@ const sections = computed(() => {
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-8">
|
||||
<!-- Sidebar Navigation -->
|
||||
<nav class="w-48 flex-shrink-0">
|
||||
<ul class="flex flex-col gap-1">
|
||||
<li v-for="section in sections" :key="section.id">
|
||||
<button
|
||||
:class="[
|
||||
'flex w-full items-center gap-3 rounded-md px-3 py-2 text-sm transition-colors',
|
||||
activeSection === section.id
|
||||
? 'bg-zinc-100 font-medium text-zinc-900 dark:bg-zinc-800 dark:text-zinc-100'
|
||||
: 'text-zinc-600 hover:bg-zinc-50 hover:text-zinc-900 dark:text-zinc-400 dark:hover:bg-zinc-800/50 dark:hover:text-zinc-100'
|
||||
]"
|
||||
@click="activeSection = section.id"
|
||||
>
|
||||
<i :class="[section.icon, 'text-sm']" />
|
||||
{{ section.label }}
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- Tab Navigation -->
|
||||
<div class="mb-6 border-b border-zinc-200 dark:border-zinc-800">
|
||||
<nav class="flex gap-1">
|
||||
<button
|
||||
v-for="section in sections"
|
||||
:key="section.id"
|
||||
:class="[
|
||||
'flex items-center gap-2 border-b-2 px-4 py-2.5 text-sm font-medium transition-colors',
|
||||
activeSection === section.id
|
||||
? 'border-zinc-900 text-zinc-900 dark:border-zinc-100 dark:text-zinc-100'
|
||||
: 'border-transparent text-zinc-500 hover:border-zinc-300 hover:text-zinc-700 dark:text-zinc-400 dark:hover:border-zinc-600 dark:hover:text-zinc-300'
|
||||
]"
|
||||
@click="activeSection = section.id"
|
||||
>
|
||||
<i :class="[section.icon, 'text-sm']" />
|
||||
{{ section.label }}
|
||||
</button>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<!-- Content -->
|
||||
<div class="flex-1">
|
||||
<!-- Content -->
|
||||
<div class="max-w-2xl">
|
||||
<!-- General Settings -->
|
||||
<div v-if="activeSection === 'general'" class="space-y-6">
|
||||
<div class="rounded-lg border border-zinc-200 bg-white p-6 dark:border-zinc-800 dark:bg-zinc-900">
|
||||
@@ -266,7 +265,6 @@ const sections = computed(() => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
180
ComfyUI_vibe/src/views/v2/workspace/TemplatesView.vue
Normal file
@@ -0,0 +1,180 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import {
|
||||
WorkspaceViewHeader,
|
||||
WorkspaceSearchInput,
|
||||
WorkspaceViewToggle,
|
||||
WorkspaceSortSelect,
|
||||
WorkspaceFilterSelect,
|
||||
WorkspaceCard,
|
||||
} from '@/components/v2/workspace'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const workspaceId = computed(() => route.params.workspaceId as string)
|
||||
|
||||
type ViewMode = 'grid' | 'list'
|
||||
|
||||
const searchQuery = ref('')
|
||||
const viewMode = ref<ViewMode>('grid')
|
||||
const sortBy = ref('popular')
|
||||
const filterBy = ref('all')
|
||||
|
||||
const sortOptions = [
|
||||
{ value: 'popular', label: 'Most Popular' },
|
||||
{ value: 'recent', label: 'Recently Added' },
|
||||
{ value: 'name', label: 'Name' },
|
||||
]
|
||||
|
||||
const filterOptions = [
|
||||
{ value: 'all', label: 'All Categories' },
|
||||
{ value: 'official', label: 'Official' },
|
||||
{ value: 'sdxl', label: 'SDXL' },
|
||||
{ value: 'controlnet', label: 'ControlNet' },
|
||||
{ value: 'video', label: 'Video' },
|
||||
{ value: 'community', label: 'Community' },
|
||||
]
|
||||
|
||||
const templates = ref([
|
||||
{ id: 'txt2img', name: 'Text to Image', description: 'Generate images from text prompts', category: 'official', icon: 'pi pi-image', thumbnail: '/assets/card_images/workflow_01.webp', uses: 12500 },
|
||||
{ id: 'img2img', name: 'Image to Image', description: 'Transform existing images', category: 'official', icon: 'pi pi-images', thumbnail: '/assets/card_images/2690a78c-c210-4a52-8c37-3cb5bc4d9e71.webp', uses: 8900 },
|
||||
{ id: 'upscale', name: 'Upscale 4x', description: '4x image upscaling workflow', category: 'official', icon: 'pi pi-expand', thumbnail: '/assets/card_images/bacb46ea-7e63-4f19-a253-daf41461e98f.webp', uses: 7200 },
|
||||
{ id: 'inpaint', name: 'Inpainting', description: 'Edit parts of an image', category: 'official', icon: 'pi pi-pencil', thumbnail: '/assets/card_images/228616f4-12ad-426d-84fb-f20e488ba7ee.webp', uses: 6100 },
|
||||
{ id: 'controlnet', name: 'ControlNet Pose', description: 'Pose-guided generation', category: 'controlnet', icon: 'pi pi-sliders-h', thumbnail: '/assets/card_images/683255d3-1d10-43d9-a6ff-ef142061e88a.webp', uses: 5400 },
|
||||
{ id: 'video', name: 'Video Generation', description: 'Create videos from prompts', category: 'video', icon: 'pi pi-video', thumbnail: '/assets/card_images/91f1f589-ddb4-4c4f-b3a7-ba30fc271987.webp', uses: 4800 },
|
||||
{ id: 'sdxl-turbo', name: 'SDXL Turbo', description: 'Fast SDXL generation', category: 'sdxl', icon: 'pi pi-bolt', thumbnail: '/assets/card_images/28e9f7ea-ef00-48e8-849d-8752a34939c7.webp', uses: 4200 },
|
||||
{ id: 'canny', name: 'ControlNet Canny', description: 'Edge-guided generation', category: 'controlnet', icon: 'pi pi-stop', thumbnail: '/assets/card_images/comfyui_workflow.jpg', uses: 3800 },
|
||||
{ id: 'depth', name: 'ControlNet Depth', description: 'Depth-guided generation', category: 'controlnet', icon: 'pi pi-box', thumbnail: '/assets/card_images/can-you-rate-my-comfyui-workflow-v0-o9clchhji39c1.webp', uses: 3500 },
|
||||
{ id: 'sdxl-refiner', name: 'SDXL + Refiner', description: 'Two-stage SDXL workflow', category: 'sdxl', icon: 'pi pi-sparkles', thumbnail: '/assets/card_images/dda28581-37c8-44da-8822-57d1ccc2118c_2130x1658.png', uses: 3200 },
|
||||
{ id: 'animatediff', name: 'AnimateDiff', description: 'Animate images to video', category: 'video', icon: 'pi pi-play', thumbnail: '/thumbnails/workflow-1.jpg', uses: 2900 },
|
||||
{ id: 'face-swap', name: 'Face Swap', description: 'Swap faces in images', category: 'community', icon: 'pi pi-user', thumbnail: '/thumbnails/workflow-2.jpg', uses: 2600 },
|
||||
])
|
||||
|
||||
const filteredTemplates = computed(() => {
|
||||
let result = [...templates.value]
|
||||
|
||||
if (filterBy.value !== 'all') {
|
||||
result = result.filter(t => t.category === filterBy.value)
|
||||
}
|
||||
|
||||
if (searchQuery.value) {
|
||||
const query = searchQuery.value.toLowerCase()
|
||||
result = result.filter(t =>
|
||||
t.name.toLowerCase().includes(query) ||
|
||||
t.description.toLowerCase().includes(query)
|
||||
)
|
||||
}
|
||||
|
||||
if (sortBy.value === 'name') {
|
||||
result.sort((a, b) => a.name.localeCompare(b.name))
|
||||
} else if (sortBy.value === 'popular') {
|
||||
result.sort((a, b) => b.uses - a.uses)
|
||||
}
|
||||
|
||||
return result
|
||||
})
|
||||
|
||||
function getCategoryColor(category: string): string {
|
||||
const colors: Record<string, string> = {
|
||||
official: 'bg-blue-500/20 text-blue-400',
|
||||
sdxl: 'bg-purple-500/20 text-purple-400',
|
||||
controlnet: 'bg-green-500/20 text-green-400',
|
||||
video: 'bg-amber-500/20 text-amber-400',
|
||||
community: 'bg-pink-500/20 text-pink-400',
|
||||
}
|
||||
return colors[category] || 'bg-zinc-500/20 text-zinc-400'
|
||||
}
|
||||
|
||||
function formatUses(uses: number): string {
|
||||
if (uses >= 1000) {
|
||||
return `${(uses / 1000).toFixed(1)}k`
|
||||
}
|
||||
return uses.toString()
|
||||
}
|
||||
|
||||
function openTemplate(templateId: string): void {
|
||||
router.push(`/${workspaceId.value}/default/${templateId}`)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="p-6">
|
||||
<WorkspaceViewHeader
|
||||
title="Templates"
|
||||
:subtitle="`${templates.length} templates available`"
|
||||
:show-create-buttons="true"
|
||||
/>
|
||||
|
||||
<!-- Search & Filters -->
|
||||
<div class="mb-4 flex items-center gap-3">
|
||||
<WorkspaceSearchInput
|
||||
v-model="searchQuery"
|
||||
placeholder="Search templates..."
|
||||
/>
|
||||
<WorkspaceViewToggle v-model="viewMode" />
|
||||
<WorkspaceSortSelect v-model="sortBy" :options="sortOptions" />
|
||||
<WorkspaceFilterSelect v-model="filterBy" :options="filterOptions" />
|
||||
</div>
|
||||
|
||||
<!-- Grid View -->
|
||||
<div
|
||||
v-if="viewMode === 'grid'"
|
||||
class="grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5"
|
||||
>
|
||||
<WorkspaceCard
|
||||
v-for="template in filteredTemplates"
|
||||
:key="template.id"
|
||||
:thumbnail="template.thumbnail"
|
||||
:title="template.name"
|
||||
:description="template.description"
|
||||
:icon="template.icon"
|
||||
:badge="template.category"
|
||||
:badge-class="getCategoryColor(template.category)"
|
||||
action-label="Run"
|
||||
action-icon="pi pi-play"
|
||||
:stats="[{ icon: 'pi pi-users', value: formatUses(template.uses) }]"
|
||||
@click="openTemplate(template.id)"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- List View -->
|
||||
<div v-else class="rounded-lg border border-zinc-200 bg-white dark:border-zinc-800 dark:bg-zinc-900">
|
||||
<div class="divide-y divide-zinc-100 dark:divide-zinc-800">
|
||||
<div
|
||||
v-for="template in filteredTemplates"
|
||||
:key="template.id"
|
||||
class="flex w-full cursor-pointer items-center gap-4 px-5 py-4 text-left transition-colors hover:bg-zinc-50 dark:hover:bg-zinc-800/50"
|
||||
@click="openTemplate(template.id)"
|
||||
>
|
||||
<div class="h-12 w-12 overflow-hidden rounded-md">
|
||||
<img :src="template.thumbnail" :alt="template.name" class="h-full w-full object-cover" />
|
||||
</div>
|
||||
<div class="flex-1 min-w-0">
|
||||
<p class="font-medium text-zinc-900 dark:text-zinc-100">{{ template.name }}</p>
|
||||
<p class="text-sm text-zinc-500 dark:text-zinc-400">{{ template.description }}</p>
|
||||
</div>
|
||||
<span :class="['rounded px-2 py-1 text-xs font-medium capitalize', getCategoryColor(template.category)]">
|
||||
{{ template.category }}
|
||||
</span>
|
||||
<span class="flex items-center gap-1 text-sm text-zinc-400 dark:text-zinc-500">
|
||||
<i class="pi pi-users text-xs" />
|
||||
{{ formatUses(template.uses) }}
|
||||
</span>
|
||||
<button
|
||||
class="inline-flex items-center gap-1 rounded-md bg-blue-600 px-3 py-1.5 text-sm font-medium text-white transition-colors hover:bg-blue-700"
|
||||
>
|
||||
<i class="pi pi-play text-xs" />
|
||||
Run
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Empty State -->
|
||||
<div v-if="filteredTemplates.length === 0" class="py-12 text-center">
|
||||
<i class="pi pi-search mb-4 text-4xl text-zinc-300 dark:text-zinc-600" />
|
||||
<p class="text-zinc-500 dark:text-zinc-400">No templates found</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,6 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { WorkspaceCard } from '@/components/v2/workspace'
|
||||
|
||||
const route = useRoute()
|
||||
const workspaceId = computed(() => route.params.workspaceId as string)
|
||||
@@ -21,10 +22,10 @@ const sortOptions: { value: SortOption; label: string }[] = [
|
||||
|
||||
// Mock workflows data
|
||||
const workflows = ref([
|
||||
{ id: 'txt2img-basic', name: 'Text to Image Basic', description: 'Simple text to image generation', nodeCount: 8, updatedAt: '1 day ago', updatedTimestamp: Date.now() - 24 * 60 * 60 * 1000 },
|
||||
{ id: 'img2img-refine', name: 'Image Refinement', description: 'Refine and enhance images', nodeCount: 12, updatedAt: '2 days ago', updatedTimestamp: Date.now() - 2 * 24 * 60 * 60 * 1000 },
|
||||
{ id: 'upscale-4x', name: '4x Upscale', description: 'High quality image upscaling', nodeCount: 5, updatedAt: '3 days ago', updatedTimestamp: Date.now() - 3 * 24 * 60 * 60 * 1000 },
|
||||
{ id: 'controlnet-pose', name: 'ControlNet Pose', description: 'Pose-guided generation', nodeCount: 15, updatedAt: '1 week ago', updatedTimestamp: Date.now() - 7 * 24 * 60 * 60 * 1000 }
|
||||
{ id: 'txt2img-basic', name: 'Text to Image Basic', description: 'Simple text to image generation', nodeCount: 8, updatedAt: '1 day ago', updatedTimestamp: Date.now() - 24 * 60 * 60 * 1000, thumbnail: '/thumbnails/workflow-1.jpg' },
|
||||
{ id: 'img2img-refine', name: 'Image Refinement', description: 'Refine and enhance images', nodeCount: 12, updatedAt: '2 days ago', updatedTimestamp: Date.now() - 2 * 24 * 60 * 60 * 1000, thumbnail: '/thumbnails/workflow-2.jpg' },
|
||||
{ id: 'upscale-4x', name: '4x Upscale', description: 'High quality image upscaling', nodeCount: 5, updatedAt: '3 days ago', updatedTimestamp: Date.now() - 3 * 24 * 60 * 60 * 1000, thumbnail: '/assets/card_images/can-you-rate-my-comfyui-workflow-v0-o9clchhji39c1.webp' },
|
||||
{ id: 'controlnet-pose', name: 'ControlNet Pose', description: 'Pose-guided generation', nodeCount: 15, updatedAt: '1 week ago', updatedTimestamp: Date.now() - 7 * 24 * 60 * 60 * 1000, thumbnail: '/assets/card_images/dda28581-37c8-44da-8822-57d1ccc2118c_2130x1658.png' }
|
||||
])
|
||||
|
||||
// Search and sort
|
||||
@@ -166,38 +167,16 @@ const filteredWorkflows = computed(() => {
|
||||
v-else-if="viewMode === 'grid'"
|
||||
class="grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5"
|
||||
>
|
||||
<div
|
||||
<WorkspaceCard
|
||||
v-for="workflow in filteredWorkflows"
|
||||
:key="workflow.id"
|
||||
class="group aspect-square cursor-pointer rounded-lg border border-zinc-200 bg-white p-4 text-left transition-all hover:border-zinc-300 hover:shadow-sm dark:border-zinc-800 dark:bg-zinc-900 dark:hover:border-zinc-700"
|
||||
>
|
||||
<div class="flex h-full flex-col">
|
||||
<div class="flex items-start justify-between">
|
||||
<div class="flex h-10 w-10 items-center justify-center rounded-md bg-zinc-100 dark:bg-zinc-800">
|
||||
<i class="pi pi-sitemap text-zinc-500 dark:text-zinc-400" />
|
||||
</div>
|
||||
<button
|
||||
class="rounded p-1 text-zinc-400 opacity-0 transition-opacity hover:bg-zinc-100 hover:text-zinc-600 group-hover:opacity-100 dark:hover:bg-zinc-800 dark:hover:text-zinc-300"
|
||||
@click.stop
|
||||
>
|
||||
<i class="pi pi-ellipsis-h text-sm" />
|
||||
</button>
|
||||
</div>
|
||||
<div class="mt-auto">
|
||||
<h3 class="font-medium text-zinc-900 dark:text-zinc-100">{{ workflow.name }}</h3>
|
||||
<p class="mt-1 line-clamp-2 text-sm text-zinc-500 dark:text-zinc-400">
|
||||
{{ workflow.description }}
|
||||
</p>
|
||||
<div class="mt-2 flex items-center gap-3 text-xs text-zinc-400 dark:text-zinc-500">
|
||||
<span class="flex items-center gap-1">
|
||||
<i class="pi pi-stop" />
|
||||
{{ workflow.nodeCount }}
|
||||
</span>
|
||||
<span>{{ workflow.updatedAt }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
:thumbnail="workflow.thumbnail"
|
||||
:title="workflow.name"
|
||||
:description="workflow.description"
|
||||
icon="pi pi-sitemap"
|
||||
:stats="[{ icon: 'pi pi-stop', value: workflow.nodeCount }]"
|
||||
:updated-at="workflow.updatedAt"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- List View -->
|
||||
|
||||