From 7538e2bb042c055e9d887027c60ab7836a3d3f34 Mon Sep 17 00:00:00 2001 From: Mohammad Azmi Date: Sat, 29 Nov 2025 19:39:12 +0700 Subject: [PATCH 1/5] new onboarding ui --- package.json | 1 + src/App.vue | 18 +- src/assets/styles/_base.scss | 4 + src/assets/styles/_primevue.scss | 197 ++++++++++++++++++ src/assets/styles/components/_all.scss | 1 - src/assets/styles/components/_base-input.scss | 6 +- src/assets/styles/components/_dropdown.scss | 85 -------- src/assets/styles/main.scss | 1 + src/assets/styles/pages/_api-key-form.scss | 1 - src/assets/styles/pages/_chat-interface.scss | 13 +- .../styles/pages/_onboarding-screen.scss | 4 + .../styles/pages/configuration/_main.scss | 53 +++-- src/components/ApiKeyForm.vue | 132 +++++++++--- src/components/OnboardingScreen.vue | 26 ++- src/components/common/BaseInput.vue | 4 +- src/components/common/PromptInput.vue | 58 ++++-- .../configuration/Configuration.vue | 21 +- src/main.ts | 2 + yarn.lock | 46 ++++ 19 files changed, 480 insertions(+), 193 deletions(-) create mode 100644 src/assets/styles/_primevue.scss delete mode 100644 src/assets/styles/components/_dropdown.scss diff --git a/package.json b/package.json index 821ded5..a0d8b3e 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "ollama-ai-provider": "^1.2.0", "pinia": "^3.0.2", "pluralize": "^8.0.0", + "primevue": "^4.4.1", "sql-query-identifier": "^2.8.0", "typeface-roboto": "^0.0.75", "vue": "^3.4.21", diff --git a/src/App.vue b/src/App.vue index be97314..5ca8109 100644 --- a/src/App.vue +++ b/src/App.vue @@ -7,17 +7,11 @@ -
- -
-
-
- - -
-
+ + + + @@ -33,6 +27,7 @@ import Configuration, { } from "@/components/configuration/Configuration.vue"; import OnboardingScreen from "./components/OnboardingScreen.vue"; import { getData, notify } from "@beekeeperstudio/plugin"; +import { Dialog } from "primevue"; type Page = "starting" | "chat-interface"; @@ -41,6 +36,7 @@ export default { ChatInterface, Configuration, OnboardingScreen, + Dialog, }, data() { diff --git a/src/assets/styles/_base.scss b/src/assets/styles/_base.scss index 60e8b3e..ed9d680 100644 --- a/src/assets/styles/_base.scss +++ b/src/assets/styles/_base.scss @@ -48,6 +48,10 @@ a { font-weight: 700; } +p { + line-height: 1.5; +} + /* Make the scrollbar look better */ ::-webkit-scrollbar { width: 12px; diff --git a/src/assets/styles/_primevue.scss b/src/assets/styles/_primevue.scss new file mode 100644 index 0000000..2b910d7 --- /dev/null +++ b/src/assets/styles/_primevue.scss @@ -0,0 +1,197 @@ +:root { + // Button + --p-button-primary-focus-ring-color: var(--focus-visible-outline-color); + + --p-button-text-secondary-hover-background: var(--p-togglebutton-background); + + --p-button-icon-only-width: 2rem; + --p-icon-size: 0.875rem; + + --p-button-focus-ring-style: var(--focus-visible-outline-style); + --p-button-focus-ring-width: var(--focus-visible-outline-width); + --p-button-focus-ring-offset: 2px; + // ----------------------------------- + + // Select Button + --p-selectbutton-border-radius: 8px; + // ----------------------------------- + + // Toggle Button + --p-togglebutton-color: color-mix(in srgb, var(--theme-base) 60%, var(--theme-bg)); + --p-togglebutton-background: color-mix(in srgb, var(--theme-base) 6%, var(--theme-bg)); + --p-togglebutton-padding: 0.25rem 0.25rem; + --p-togglebutton-font-weight: 700; + --p-togglebutton-border-radius: 8px; + --p-togglebutton-focus-ring-color: var(--focus-visible-outline-color); + --p-togglebutton-focus-ring-style: var(--focus-visible-outline-style); + --p-togglebutton-focus-ring-width: var(--focus-visible-outline-width); + --p-togglebutton-focus-ring-offset: var(--p-button-focus-ring-offset); + --p-togglebutton-transition-duration: var(--p-transition-duration); + + --p-togglebutton-hover-background: var(--p-togglebutton-background); + --p-togglebutton-hover-color: var(--theme-base); + --p-togglebutton-checked-color: var(--theme-base); + --p-togglebutton-checked-background: var(--p-togglebutton-background); + + --p-togglebutton-content-padding: 0.1rem 0.75rem; + --p-togglebutton-content-border-radius: 8px; + + --p-togglebutton-content-checked-background: color-mix(in srgb, + var(--theme-base) 15%, + var(--theme-bg)); + // ----------------------------------- + + // Select + --p-select-background: color-mix( + in srgb, + var(--theme-base) 6%, + var(--theme-bg)); + --p-select-color: var(--text-dark); + --p-select-border-color: var(--border-color); + --p-select-border-radius: 8px; + --p-select-padding-x: 0.75rem; + --p-select-padding-y: 0.5rem; + --p-select-dropdown-width: 1.5rem; + + --p-select-overlay-border-radius: var(--p-menu-border-radius); + --p-select-overlay-color: var(--p-menu-color); + --p-select-overlay-background: var(--p-menu-background); + --p-select-overlay-shadow: var(--p-menu-shadow); + + --p-select-option-color: var(--text-dark); + --p-select-option-padding: var(--p-menu-item-padding); + --p-select-option-border-radius: var(--p-menu-item-border-radius); + + --p-select-option-selected-color: var(--p-menu-item-focus-color); + --p-select-option-selected-background: var(--p-menu-item-focus-background); + --p-select-option-selected-focus-color: var(--p-menu-item-focus-color); + --p-select-option-selected-focus-background: var(--p-menu-item-focus-background); + --p-select-option-focus-background: var(--p-menu-item-focus-background); + --p-select-option-focus-color: var(--p-menu-item-focus-color); + + --p-select-placeholder-color: var(--text-light); + // ----------------------------------- + + + // Dialog + --p-dialog-background: var(--theme-bg); + --p-dialog-border-radius: 8px; + --p-dialog-shadow: 0 0 0.5rem var(--query-editor-bg); + --p-dialog-color: var(--text-dark); + + --p-dialog-header-padding: 1.2rem 1.2rem 0.8rem; + + --p-dialog-title-font-weight: 500; + --p-dialog-title-font-size: 1.1rem; + + --p-dialog-content-padding: 0 1.2rem 1.75rem; + --p-dialog-footer-padding: 0 1.2rem 1.2rem; + --p-dialog-footer-gap: 0.5rem; + // ----------------------------------- + + // Menu + --p-menu-border-radius: 8px; + --p-menu-color: var(--text); + --p-menu-background: color-mix(in srgb, + var(--theme-base) 6%, + var(--theme-bg)); + --p-menu-shadow: 0 0 0.5rem var(--theme-bg); + + --p-menu-submenu-label-font-weight: normal; + + --p-menu-list-padding: 0.3rem 0; + + --p-menu-item-color: var(--text-dark); + // --p-menu-item-padding: 0.482rem 0.8rem; + --p-menu-item-padding: 0.2855rem 0.8rem; + --p-menu-item-focus-background: color-mix(in srgb, + var(--theme-base) 11%, + var(--theme-bg)); + --p-menu-item-focus-color: var(--theme-base); + --p-menu-item-gap: 0.5rem; + + --p-menu-separator-border-color: color-mix(in srgb, + var(--theme-base) 10%, + var(--theme-bg)); + // ----------------------------------- + + // Context Menu -- pretty much the same as menu + --p-contextmenu-border-radius: var(--p-menu-border-radius); + --p-contextmenu-color: var(--p-menu-color); + --p-contextmenu-background: var(--p-menu-background); + --p-contextmenu-shadow: var(--p-menu-shadow); + + --p-contextmenu-submenu-label-font-weight: var(--p-menu-submenu-label-font-weight); + + --p-contextmenu-item-padding: var(--p-menu-item-padding); + --p-contextmenu-item-border-radius: var(--p-menu-item-border-radius); + --p-contextmenu-item-focus-background: var(--p-menu-item-focus-background); + --p-contextmenu-item-focus-color: var(--p-menu-item-focus-color); + // ----------------------------------- + + // Overlay + --p-mask-background: rgb(from var(--theme-bg) r g b / 0.3); + // ----------------------------------- + + // Popover + --p-popover-gutter: 0.5rem; + --p-popover-arrow-offset: 1rem; + --p-popover-background: color-mix(in srgb, + var(--theme-base) 6%, + var(--query-editor-bg)); + --p-popover-color: var(--text); + --p-popover-border-color: transparent; + --p-popover-border-radius: 8px; + --p-popover-box-shadow: 0 0 0.5rem var(--theme-bg); + // ----------------------------------- + + // Progress + --p-progressspinner-color-one: var(--theme-primary); + --p-progressspinner-color-two: var(--theme-primary); + --p-progressspinner-color-three: var(--theme-primary); + --p-progressspinner-color-four: var(--theme-primary); + // ----------------------------------- + + // Mask (overlay) + --p-mask-transition-duration: 0.2s; + // ----------------------------------- +} + +.p-menu .p-menu-item, +.p-contextmenu .p-contextmenu-item, +.p-select-list, .p-select-option { + // FIXME should be 0.9rem. But this should match the app font size for now. + font-size: 12.6px; + + .menu-icon { + font-size: 1.5em; + width: 1em; + height: 1em; + } + + a { + font-weight: normal; + } +} + +.p-select .p-select-label { + font-size: 0.9rem; + text-align: left; +} + +.p-menu { + overflow: hidden; +} + +.p-menu-list { + max-height: 90vh; + overflow-y: auto; +} + +.p-menu-item.selected { + background-color: var(--p-select-option-selected-background); +} + +.p-dialog { + max-width: 90vw; +} diff --git a/src/assets/styles/components/_all.scss b/src/assets/styles/components/_all.scss index 908f1ce..e9a6dfc 100644 --- a/src/assets/styles/components/_all.scss +++ b/src/assets/styles/components/_all.scss @@ -2,7 +2,6 @@ @use "base-input"; @use "buttons"; @use "spinner"; -@use "dropdown"; @use "run-query-result"; @use "progress-bar"; @use "switch"; diff --git a/src/assets/styles/components/_base-input.scss b/src/assets/styles/components/_base-input.scss index 4b598b1..c25f16b 100644 --- a/src/assets/styles/components/_base-input.scss +++ b/src/assets/styles/components/_base-input.scss @@ -14,6 +14,7 @@ font-size: 0.75rem; color: var(--text-dark); opacity: 0.7; + margin: 0; } .input-wrapper { @@ -25,7 +26,10 @@ input, textarea { - background-color: color-mix(in srgb, var(--theme-base) 5%, var(--query-editor-bg)); + background-color: color-mix( + in srgb, + var(--theme-base) 5%, + var(--theme-bg)); border: 1px solid var(--border-color); border-radius: 8px; padding: 0.5rem 0.75rem; diff --git a/src/assets/styles/components/_dropdown.scss b/src/assets/styles/components/_dropdown.scss deleted file mode 100644 index baa98c0..0000000 --- a/src/assets/styles/components/_dropdown.scss +++ /dev/null @@ -1,85 +0,0 @@ -.dropdown-container { - position: relative; -} - -.dropdown-trigger { - cursor: pointer; - - &:focus-visible { - outline: var(--focus-visible-outline); - } -} - -.dropdown-popover { - position: fixed; - z-index: 1000; - background-color: var(--query-editor-bg); - border: 1px solid var(--border-color); - border-radius: 8px; - padding: 0.5rem 0; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); - margin: 0; - min-width: 200px; -} - -.dropdown-option { - display: flex; - justify-content: space-between; - align-items: center; - width: 100%; - padding: 0.5rem 0.75rem; - background: none; - border: none; - text-align: left; - cursor: pointer; - color: var(--text-dark); - font-size: 0.85rem; - - .option-content { - flex: 1; - } - - .selected-indicator { - color: var(--theme-base); - font-weight: 600; - margin-left: 0.5rem; - font-size: 0.8rem; - } - - &:hover:not(.disabled), &:focus-visible { - background-color: rgb(from var(--theme-base) r g b / 5%); - } - - &.selected { - background-color: rgb(from var(--theme-base) r g b / 10%); - font-weight: 600; - } - - &.disabled { - opacity: 0.6; - cursor: not-allowed; - } -} - -.dropdown-separator { - height: 1px; - background-color: var(--border-color); - margin: 0.25rem 0; -} - -.dropdown-action { - display: block; - width: 100%; - padding: 0.5rem 0.75rem; - background: none; - border: none; - text-align: left; - cursor: pointer; - color: var(--text-dark); - font-size: 0.85rem; - font-style: italic; - - &:hover { - background-color: rgb(from var(--theme-base) r g b / 5%); - } -} diff --git a/src/assets/styles/main.scss b/src/assets/styles/main.scss index 9112149..7b6106a 100644 --- a/src/assets/styles/main.scss +++ b/src/assets/styles/main.scss @@ -3,6 +3,7 @@ @use "components/all" as components; @use "pages/all" as pages; @use "sass:color"; +@use "primevue"; #app { height: 100%; diff --git a/src/assets/styles/pages/_api-key-form.scss b/src/assets/styles/pages/_api-key-form.scss index f4eba29..971e2e6 100644 --- a/src/assets/styles/pages/_api-key-form.scss +++ b/src/assets/styles/pages/_api-key-form.scss @@ -34,7 +34,6 @@ label { margin-top: 0.6rem; - width: 10rem; } .input-wrapper { diff --git a/src/assets/styles/pages/_chat-interface.scss b/src/assets/styles/pages/_chat-interface.scss index ea79250..bbcb9bc 100644 --- a/src/assets/styles/pages/_chat-interface.scss +++ b/src/assets/styles/pages/_chat-interface.scss @@ -32,8 +32,8 @@ .settings-btn { min-width: 0; - width: 1.8rem; - height: 1.8rem; + width: 2rem; + height: 2rem; border: none; border-radius: 9999px; cursor: pointer; @@ -438,7 +438,10 @@ } .chat-input-container { - background-color: rgb(from var(--theme-base) r g b / 5%); + background-color: color-mix( + in srgb, + var(--theme-base) 5%, + var(--query-editor-bg)); border: 1px solid var(--border-color); border-radius: 8px; display: flex; @@ -453,6 +456,10 @@ border-radius: 8px; textarea { + background-color: color-mix( + in srgb, + var(--theme-base) 5%, + var(--query-editor-bg)); border-color: transparent; &:focus-visible { diff --git a/src/assets/styles/pages/_onboarding-screen.scss b/src/assets/styles/pages/_onboarding-screen.scss index 4be9023..86e4d54 100644 --- a/src/assets/styles/pages/_onboarding-screen.scss +++ b/src/assets/styles/pages/_onboarding-screen.scss @@ -54,6 +54,10 @@ max-width: 24rem; text-align: center; + h1 { + margin-top: 0; + } + .api-info { margin-top: 1.5rem; margin-bottom: 1rem; diff --git a/src/assets/styles/pages/configuration/_main.scss b/src/assets/styles/pages/configuration/_main.scss index 13ac394..4149889 100644 --- a/src/assets/styles/pages/configuration/_main.scss +++ b/src/assets/styles/pages/configuration/_main.scss @@ -15,20 +15,21 @@ } .configuration { - --config-bg-hover: color-mix(in srgb, var(--theme-base) 3.5%, var(--query-editor-bg)); - position: fixed; - top: 0; - left: 0; - overflow-y: scroll; - display: flex; - width: 100%; - height: 100%; - background-color: var(--query-editor-bg); - justify-content: center; + --config-bg-hover: color-mix(in srgb, + var(--theme-base) 3.5%, + var(--theme-bg)); + + .p-dialog-content { + padding-top: 1.75rem; + display: flex; + width: 40rem; + max-width: 100%; + height: 90vh; + max-height: 46rem; + } nav { width: 9rem; - padding: 1rem; flex-shrink: 0; position: sticky; top: 0; @@ -49,35 +50,41 @@ justify-content: flex-start; background-color: transparent; - &:not(.back-btn):hover { + &:hover { background-color: var(--config-bg-hover); } &.active { background-color: rgb(from var(--theme-base) r g b / 10%); } - } - .back-btn { - padding-left: 0; + &.close-btn { + padding: 0; + width: 2rem; + height: 2rem; + justify-content: center; + min-width: 0; + margin-top: -0.25rem; + } } + .content { - padding-bottom: 1rem; - padding-top: 1.26rem; flex-grow: 1; min-width: 0; - max-width: 39rem; + overflow-y: scroll; > :first-child { margin-top: 0; } - > :last-child { - padding-bottom: 2rem; - } - - h1, h2, h3, h4, p, li, .base-input { + h1, + h2, + h3, + h4, + p:not(.helper), + li, + .base-input { padding-inline: 1rem; } diff --git a/src/components/ApiKeyForm.vue b/src/components/ApiKeyForm.vue index 4725e35..dba0621 100644 --- a/src/components/ApiKeyForm.vue +++ b/src/components/ApiKeyForm.vue @@ -1,50 +1,69 @@ + + diff --git a/src/components/OnboardingScreen.vue b/src/components/OnboardingScreen.vue index 1045f15..81cf277 100644 --- a/src/components/OnboardingScreen.vue +++ b/src/components/OnboardingScreen.vue @@ -1,17 +1,20 @@