Skip to content

Commit

Permalink
feat: Add loading indicator and static header to welcome message comp…
Browse files Browse the repository at this point in the history
…onent

Enhances the welcome message component by adding a static header and a loading state indicator for dynamic content.
  • Loading branch information
kgilpin committed Dec 11, 2024
1 parent 6999935 commit 4bd6fda
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 13 deletions.
9 changes: 4 additions & 5 deletions packages/cli/src/rpc/navie/metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ async function getWelcomeMessage(navieProvider: INavieProvider): Promise<string>

// Case 1: Custom welcome message may not be enabled at all
if (!isCustomWelcomeMessageEnabled(navie))
return "### Hi, I'm Navie!\n\nI can help you answer questions about your codebase, create diagrams, plan solutions, generate code and tests, and review code changes. Type `@` to see a list of commands.";
return 'I can help you answer questions about your codebase, create diagrams, plan solutions, generate code and tests, and review code changes. Type `@` to see a list of commands.';

const result: string[] = ["### Hi, I'm Navie!", ''];
const result: string[] = [];
const { projectDirectories } = configuration();

// Case 2: Remote Navie, no open project directories
Expand Down Expand Up @@ -102,13 +102,12 @@ async function getWelcomeMessage(navieProvider: INavieProvider): Promise<string>
} else {
result.push(
`It looks like you're ${welcomeSuggestion.activity}.`,
'',
'Here are some questions you might want to try:',
...welcomeSuggestion.suggestions.map((suggestion) => `- ${suggestion}`)
...welcomeSuggestion.suggestions.map((s) => `- ${s}`)
);
}

return result.join('\n');
return result.join('\n\n');
}

export function navieMetadataV1(
Expand Down
32 changes: 29 additions & 3 deletions packages/components/src/components/chat/WelcomeMessage.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
<template>
<div class="welcome-message" data-cy="welcome-message" v-html="renderedMarkdown" v-if="message" />
<div class="welcome-message" data-cy="welcome-message">
<div class="welcome-message-static">
<h3>Hi, I'm Navie!</h3>
</div>
<div class="welcome-message-dynamic" v-if="dynamicMessage" v-html="renderedMarkdown" />
<div class="welcome-message-dynamic-placeholder" v-else>Analyzing workspace...</div>
</div>
</template>

<script lang="ts">
Expand All @@ -11,15 +17,19 @@ export default Vue.extend({
name: 'v-welcome-message',
props: {
message: {
staticMessage: {
type: String,
default: `### Hi, I'm Navie`,
},
dynamicMessage: {
type: String,
default: '',
},
},
computed: {
renderedMarkdown(): string {
return DOMPurify.sanitize(marked.parse(this.message));
return DOMPurify.sanitize(marked.parse(this.dynamicMessage));
},
},
});
Expand All @@ -41,5 +51,21 @@ export default Vue.extend({
padding-top: 0.2rem;
}
}
.welcome-message-dynamic-placeholder {
$alpha: 0.075;
width: 100%;
height: 1.5rem;
border-radius: $border-radius;
background-color: rgba(black, 0.1);
background: linear-gradient(
90deg,
rgba(black, $alpha) 0%,
rgba(white, $alpha) 50%,
rgba(black, $alpha) 100%
);
background-size: 200% 100%;
animation: skeleton 3s linear infinite;
}
}
</style>
2 changes: 1 addition & 1 deletion packages/components/src/pages/ChatSearch.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
/>
<template #not-chatting>
<div class="message-box__footer">
<v-welcome-message :message="welcomeMessage" />
<v-welcome-message :dynamicMessage="welcomeMessage" />
</div>
</template>
</v-chat>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ function buildMockRpc(
} else if (method === 'v1.navie.metadata') {
callback(null, null, {
welcomeMessage:
"### Hi, I'm Navie!\n\nI can help you answer questions about your codebase, plan solutions, create diagrams, and generate code. Enter `@` to see a list of commands.",
'I can help you answer questions about your codebase, plan solutions, create diagrams, and generate code. Enter `@` to see a list of commands.',
inputPlaceholder: "Ask a question or enter '@' for commands",
commands: [
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import VWelcomeMessage from '@/components/chat/WelcomeMessage.vue';

export default {
title: 'Components/WelcomeMessage',
component: VWelcomeMessage,
};

const Template = (args) => ({
components: { VWelcomeMessage },
setup() {
return { args };
},
template: '<v-welcome-message v-bind="args" />',
});

export const Default = Template.bind({});
Default.args = {
dynamicMessage: '',
};

export const WithDynamicMessage = Template.bind({});
WithDynamicMessage.args = {
dynamicMessage: '**Welcome!** This dynamic message is loaded and sanitized.',
};
34 changes: 34 additions & 0 deletions packages/components/tests/unit/WelcomeMessage.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { mount } from '@vue/test-utils';
import VWelcomeMessage from '@/components/chat/WelcomeMessage.vue';

describe('VWelcomeMessage', () => {
let wrapper;

beforeEach(() => {
wrapper = mount(VWelcomeMessage, {
props: {
dynamicMessage: '',
},
});
});

it('renders static message by default', () => {
expect(wrapper.text()).toContain("Hi, I'm Navie");
// Check that the dynamic placeholder is shown
expect(wrapper.find('.welcome-message-dynamic-placeholder').exists()).toBe(true);
});

it('renders dynamic message when provided', async () => {
await wrapper.setProps({
dynamicMessage: '**Welcome!** This dynamic message is loaded and sanitized.',
});

// Verify that the dynamic message is rendered
expect(wrapper.find('.welcome-message-dynamic').html()).toContain(
'<strong>Welcome!</strong> This dynamic message is loaded and sanitized.'
);

// Check that the placeholder is not visible anymore
expect(wrapper.find('.welcome-message-dynamic-placeholder').exists()).toBe(false);
});
});
7 changes: 4 additions & 3 deletions packages/components/tests/unit/chat/ChatSearch.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ describe('pages/ChatSearch.vue', () => {
const noConfig = () => [[null, null, { projectDirectories: [] }]];

const navieMetadata = {
welcomeMessage: 'Welcome to Navie!',
welcomeMessage: `Welcome to Navie!`,
inputPlaceholder: 'Type something',
commands: [
{
Expand Down Expand Up @@ -608,7 +608,9 @@ describe('pages/ChatSearch.vue', () => {
});
await wrapper.vm.$nextTick();

expect(wrapper.find('[data-cy="welcome-message"]').text()).toBe(navieMetadata.welcomeMessage);
expect(wrapper.find('[data-cy="welcome-message"]').text()).toBe(
`Hi, I'm Navie! ${navieMetadata.welcomeMessage}`
);
expect(
wrapper
.find(`[data-cy="chat-input"][placeholder="${navieMetadata.inputPlaceholder}"]`)
Expand All @@ -630,7 +632,6 @@ describe('pages/ChatSearch.vue', () => {
});
await wrapper.vm.$nextTick();

expect(wrapper.find('[data-cy="welcome-message"]').exists()).toBe(false);
expect(wrapper.find('[data-cy="chat-input"]').attributes('placeholder')).toBe(
'What are you working on today?'
);
Expand Down

0 comments on commit 4bd6fda

Please sign in to comment.