@gitlab/ui 66.25.1 → 66.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,45 @@
1
+ import { MOCK_RESPONSE_MESSAGE, MOCK_USER_PROMPT_MESSAGE } from '../../mock_data';
2
+ import GlDuoChatMessage from './duo_chat_message.vue';
3
+ import readme from './duo_chat_message.md';
4
+
5
+ const renderMarkdown = (content) => content;
6
+ const renderGFM = () => {};
7
+
8
+ const generateProps = ({ message = MOCK_RESPONSE_MESSAGE } = {}) => ({
9
+ message,
10
+ });
11
+
12
+ const Template = (args, { argTypes }) => ({
13
+ components: { GlDuoChatMessage },
14
+ props: Object.keys(argTypes),
15
+ provide: {
16
+ renderMarkdown,
17
+ renderGFM,
18
+ },
19
+ template: `
20
+ <gl-duo-chat-message :message="message" />
21
+ `,
22
+ });
23
+
24
+ export const User = Template.bind({});
25
+ User.args = generateProps({
26
+ message: MOCK_USER_PROMPT_MESSAGE,
27
+ });
28
+
29
+ export const Response = Template.bind({});
30
+ Response.args = generateProps({
31
+ message: MOCK_RESPONSE_MESSAGE,
32
+ });
33
+
34
+ export default {
35
+ title: 'experimental/duo/chat/duo-chat-message',
36
+ component: GlDuoChatMessage,
37
+ parameters: {
38
+ docs: {
39
+ description: {
40
+ component: readme,
41
+ },
42
+ },
43
+ },
44
+ argTypes: {},
45
+ };
@@ -0,0 +1,107 @@
1
+ <script>
2
+ import { GlDuoUserFeedback } from '../../../../../../index';
3
+ import { SafeHtmlDirective as SafeHtml } from '../../../../../../directives/safe_html/safe_html';
4
+ import { MESSAGE_MODEL_ROLES } from '../../constants';
5
+ import DocumentationSources from '../duo_chat_message_sources/duo_chat_message_sources.vue';
6
+
7
+ const concatIndicesUntilEmpty = (arr) => {
8
+ const start = arr.findIndex((el) => el);
9
+ if (start === -1 || start !== 1) return ''; // If there are no non-empty elements
10
+
11
+ const end = arr.slice(start).findIndex((el) => !el);
12
+ return end > 0 ? arr.slice(start, end).join('') : arr.slice(start).join('');
13
+ };
14
+
15
+ export default {
16
+ name: 'GlDuoChatMessage',
17
+ components: {
18
+ DocumentationSources,
19
+ GlDuoUserFeedback,
20
+ },
21
+ directives: {
22
+ SafeHtml,
23
+ },
24
+ inject: ['renderGFM', 'renderMarkdown'],
25
+ props: {
26
+ /**
27
+ * A message object
28
+ */
29
+ message: {
30
+ type: Object,
31
+ required: true,
32
+ },
33
+ },
34
+ data() {
35
+ return {
36
+ messageContent: '',
37
+ };
38
+ },
39
+ computed: {
40
+ isAssistantMessage() {
41
+ return this.message.role.toLowerCase() === MESSAGE_MODEL_ROLES.assistant;
42
+ },
43
+ isUserMessage() {
44
+ return this.message.role.toLowerCase() === MESSAGE_MODEL_ROLES.user;
45
+ },
46
+ sources() {
47
+ return this.message.extras?.sources;
48
+ },
49
+ content() {
50
+ return (
51
+ this.message.contentHtml ||
52
+ this.renderMarkdown(this.message.content || this.message.errors.join('; '))
53
+ );
54
+ },
55
+ },
56
+ watch: {
57
+ message: {
58
+ handler() {
59
+ const { chunkId, content } = this.message;
60
+ if (!chunkId) {
61
+ this.messageChunks = [];
62
+ this.messageContent = this.content;
63
+ this.renderGFM(this.$refs.content);
64
+ } else {
65
+ this.messageChunks[chunkId] = content;
66
+ this.messageContent = this.renderMarkdown(concatIndicesUntilEmpty(this.messageChunks));
67
+ }
68
+ },
69
+ deep: true,
70
+ },
71
+ },
72
+ beforeCreate() {
73
+ /**
74
+ * Keeps cache of previous chunks used for rerendering the AI response when streaming.
75
+ * Is intentionally non-reactive
76
+ */
77
+ this.messageChunks = [];
78
+ },
79
+ mounted() {
80
+ this.messageContent = this.content;
81
+ if (this.message.chunkId) {
82
+ this.messageChunks[this.message.chunkId] = this.message.content;
83
+ }
84
+ this.renderGFM(this.$refs.content);
85
+ },
86
+ };
87
+ </script>
88
+ <template>
89
+ <div
90
+ class="gl-p-4 gl-mb-4 gl-rounded-lg gl-line-height-20 gl-word-break-word duo-chat-message"
91
+ :class="{
92
+ 'gl-ml-auto gl-bg-blue-100 gl-text-blue-900 gl-rounded-bottom-right-none': isUserMessage,
93
+ 'gl-rounded-bottom-left-none gl-text-gray-900 gl-bg-white gl-border-1 gl-border-solid gl-border-gray-50':
94
+ isAssistantMessage,
95
+ }"
96
+ >
97
+ <div ref="content" v-safe-html="messageContent"></div>
98
+
99
+ <template v-if="isAssistantMessage">
100
+ <documentation-sources v-if="sources" :sources="sources" />
101
+
102
+ <div class="gl-display-flex gl-align-items-flex-end gl-mt-4">
103
+ <gl-duo-user-feedback @feedback="$emit('track-feedback', $event)" />
104
+ </div>
105
+ </template>
106
+ </div>
107
+ </template>
@@ -22,8 +22,10 @@ const MOCK_SOURCES = [
22
22
 
23
23
  export const MOCK_RESPONSE_MESSAGE = {
24
24
  id: '123',
25
- content: '_Duo Chat message_ comming from AI',
26
- contentHtml: '<p><em>Duo Chat message</em> comming from AI</p>',
25
+ content:
26
+ 'To create a new template:\n\n1. Create a new Markdown (`.md`) file inside the `.gitlab/issue_templates/` or `.gitlab/merge_request_templates/` directory in your repository.\n2. Commit the template file to your default branch.\n\nTo check if this has worked correctly, create a new issue or merge request and see if you can find your template in the **Choose a template** dropdown list.',
27
+ contentHtml:
28
+ '\u003cp data-sourcepos="1:1-1:25" dir="auto"\u003eTo create a new template:\u003c/p\u003e\n\u003col data-sourcepos="3:1-5:0" dir="auto"\u003e\n\u003cli data-sourcepos="3:1-3:143"\u003eCreate a new Markdown (\u003ccode\u003e.md\u003c/code\u003e) file inside the \u003ccode\u003e.gitlab/issue_templates/\u003c/code\u003e or \u003ccode\u003e.gitlab/merge_request_templates/\u003c/code\u003e directory in your repository.\u003c/li\u003e\n\u003cli data-sourcepos="4:1-5:0"\u003eCommit the template file to your default branch.\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp data-sourcepos="6:1-6:156" dir="auto"\u003eTo check if this has worked correctly, create a new issue or merge request and see if you can find your template in the \u003cstrong\u003eChoose a template\u003c/strong\u003e dropdown list.\u003c/p\u003e',
27
29
  role: MESSAGE_MODEL_ROLES.assistant,
28
30
  extras: {
29
31
  sources: MOCK_SOURCES,
@@ -32,3 +34,44 @@ export const MOCK_RESPONSE_MESSAGE = {
32
34
  errors: [],
33
35
  timestamp: '2021-04-21T12:00:00.000Z',
34
36
  };
37
+
38
+ export const MOCK_CHUNK_RESPONSE_MESSAGE = {
39
+ chunkId: 1,
40
+ content: 'chunk',
41
+ role: MESSAGE_MODEL_ROLES.assistant,
42
+ requestId: '987',
43
+ errors: [],
44
+ timestamp: '2021-04-21T12:00:00.000Z',
45
+ };
46
+
47
+ export const MOCK_RESPONSE_MESSAGE_FOR_STREAMING = {
48
+ id: '123',
49
+ content: `To change your password in GitLab:
50
+
51
+ Log in to your GitLab account.
52
+ Select your avatar in the top right corner and choose Edit profile.
53
+ On the left sidebar, select Password.
54
+ Enter your current password in the Current password field.
55
+ Enter your new password in the New password and Password confirmation fields.
56
+ Select Save password.
57
+ If you don't know your current password, select the I forgot my password link to reset it.
58
+
59
+ GitLab enforces password requirements when you choose a new password.`,
60
+ contentHtml: '',
61
+ role: 'assistant',
62
+ extras: {},
63
+ requestId: '987',
64
+ errors: [],
65
+ timestamp: '2021-04-21T12:00:00.000Z',
66
+ };
67
+
68
+ export const MOCK_USER_PROMPT_MESSAGE = {
69
+ id: '456',
70
+ content: 'How to create a new template?',
71
+ contentHtml: '',
72
+ role: MESSAGE_MODEL_ROLES.user,
73
+ requestId: '987',
74
+ errors: [],
75
+ timestamp: '2021-04-21T12:00:00.000Z',
76
+ extras: null,
77
+ };
@@ -3,6 +3,7 @@
3
3
  // @import '../components/base/dropdown/dropdown'
4
4
  //
5
5
  // ADD COMPONENT IMPORTS - needed for yarn generate:component. Do not remove
6
+ @import '../components/experimental/duo/chat/components/duo_chat_message/duo_chat_message';
6
7
  @import '../components/experimental/duo/chat/components/duo_chat_loader/duo_chat_loader';
7
8
  @import '../components/base/new_dropdowns/disclosure/disclosure_dropdown';
8
9
  @import '../components/base/keyset_pagination/keyset_pagination';