Skip to content
代码片段 群组 项目
未验证 提交 33ab3cee 编辑于 作者: Jannik Lehmann's avatar Jannik Lehmann 提交者: GitLab
浏览文件

Merge branch 'jnnkl-migrate-duo-chat-resize' into 'master'

No related branches found
No related tags found
无相关合并请求
......@@ -15,7 +15,8 @@ import duoUserFeedbackMutation from 'ee/ai/graphql/duo_user_feedback.mutation.gr
import Tracking from '~/tracking';
import { i18n, GENIE_CHAT_RESET_MESSAGE, GENIE_CHAT_CLEAR_MESSAGE } from 'ee/ai/constants';
import getAiSlashCommands from 'ee/ai/graphql/get_ai_slash_commands.query.graphql';
import { TANUKI_BOT_TRACKING_EVENT_NAME, MESSAGE_TYPES } from '../constants';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { TANUKI_BOT_TRACKING_EVENT_NAME, MESSAGE_TYPES, WIDTH_OFFSET } from '../constants';
import TanukiBotSubscriptions from './tanuki_bot_subscriptions.vue';
export default {
......@@ -42,7 +43,7 @@ export default {
DuoChatCallout,
TanukiBotSubscriptions,
},
mixins: [Tracking.mixin()],
mixins: [Tracking.mixin(), glFeatureFlagsMixin()],
provide() {
return {
renderGFM,
......@@ -104,6 +105,10 @@ export default {
cancelledRequestIds: [],
completedRequestId: null,
aiSlashCommands: [],
width: 400,
height: window.innerHeight,
minWidth: 400,
minHeight: 400,
};
},
computed: {
......@@ -115,6 +120,21 @@ export default {
return this.resourceId || this.userId;
},
shouldRenderResizable() {
return this.glFeatures.duoChatDynamicDimension;
},
dimensions() {
return {
width: this.width,
height: this.height,
top: this.top,
maxHeight: this.maxHeight,
maxWidth: this.maxWidth,
minWidth: this.minWidth,
minHeight: this.minHeight,
left: this.left,
};
},
hasCommands() {
return this.duoChatGlobalState.commands.length > 0;
},
......@@ -129,8 +149,34 @@ export default {
},
},
},
mounted() {
this.setDimensions();
window.addEventListener('resize', this.onWindowResize);
},
beforeDestroy() {
// Remove the event listener when the component is destroyed
window.removeEventListener('resize', this.onWindowResize);
},
methods: {
...mapActions(['addDuoChatMessage', 'setMessages', 'setLoading']),
setDimensions() {
this.updateDimensions();
},
updateDimensions(width, height) {
this.maxWidth = window.innerWidth - WIDTH_OFFSET;
this.maxHeight = window.innerHeight;
this.width = Math.min(width || this.width, this.maxWidth);
this.height = Math.min(height || this.height, this.maxHeight);
this.top = window.innerHeight - this.height;
this.left = window.innerWidth - this.width;
},
onChatResize(e) {
this.updateDimensions(e.width, e.height);
},
onWindowResize() {
this.updateDimensions();
},
isClearOrResetMessage(question) {
return [GENIE_CHAT_CLEAR_MESSAGE, GENIE_CHAT_RESET_MESSAGE].includes(question);
},
......@@ -277,9 +323,11 @@ export default {
id="duo-chat"
:slash-commands="aiSlashCommands"
:title="$options.i18n.gitlabChat"
:dimensions="dimensions"
:messages="messages"
:error="error"
:is-loading="loading"
:should-render-resizable="shouldRenderResizable"
:predefined-prompts="$options.i18n.predefinedPrompts"
:badge-type="null"
:tool-name="toolName"
......@@ -289,6 +337,7 @@ export default {
@send-chat-prompt="onSendChatPrompt"
@chat-hidden="onChatClose"
@track-feedback="onTrackFeedback"
@chat-resize="onChatResize"
/>
</div>
<duo-chat-callout @callout-dismissed="onCalloutDismissed" />
......
......@@ -27,3 +27,5 @@ export const ERROR_MESSAGE = s__(
export const TANUKI_BOT_TRACKING_EVENT_NAME = 'ask_gitlab_chat';
export const TANUKI_BOT_FEEDBACK_ISSUE_URL = 'https://gitlab.com/gitlab-org/gitlab/-/issues/408527';
export const WIDTH_OFFSET = 10;
.duo-chat-resizable {
// important because we're overwritting styles on data-attr set by https://github.com/nikitasnv/vue-resizable
// to make sure we're having the correct scroll behaviour
position: fixed !important;
}
.duo-chat-container .duo-chat-drawer {
z-index: $zindex-duo-chat;
......
---
name: duo_chat_dynamic_dimension
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/508981
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/175019
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/508981
milestone: '17.7'
group: group::duo chat
type: beta
default_enabled: false
......@@ -28,6 +28,7 @@ def add_gon_variables
gon.billing_accounts_url = ::Gitlab::Routing.url_helpers.subscription_portal_billing_accounts_url
gon.payment_form_url = ::Gitlab::Routing.url_helpers.subscription_portal_payment_form_url
gon.payment_validation_form_id = ::Gitlab::SubscriptionPortal::PAYMENT_VALIDATION_FORM_ID
push_frontend_feature_flag(:duo_chat_dynamic_dimension)
push_frontend_feature_flag(:advanced_context_resolver, current_user)
end
......
......@@ -9,7 +9,7 @@ import TanukiBotChatApp from 'ee/ai/tanuki_bot/components/app.vue';
import DuoChatCallout from 'ee/ai/components/global_callout/duo_chat_callout.vue';
import TanukiBotSubscriptions from 'ee/ai/tanuki_bot/components/tanuki_bot_subscriptions.vue';
import { GENIE_CHAT_RESET_MESSAGE, GENIE_CHAT_CLEAR_MESSAGE } from 'ee/ai/constants';
import { TANUKI_BOT_TRACKING_EVENT_NAME } from 'ee/ai/tanuki_bot/constants';
import { TANUKI_BOT_TRACKING_EVENT_NAME, WIDTH_OFFSET } from 'ee/ai/tanuki_bot/constants';
import chatMutation from 'ee/ai/graphql/chat.mutation.graphql';
import duoUserFeedbackMutation from 'ee/ai/graphql/duo_user_feedback.mutation.graphql';
import getAiMessages from 'ee/ai/graphql/get_ai_messages.query.graphql';
......@@ -82,6 +82,7 @@ describeSkipVue3(skipReason, () => {
const createComponent = ({
initialState = {},
propsData = { userId: MOCK_USER_ID, resourceId: MOCK_RESOURCE_ID },
glFeatures = { duoChatDynamicDimension: false },
} = {}) => {
const store = new Vuex.Store({
actions: actionSpies,
......@@ -101,6 +102,9 @@ describeSkipVue3(skipReason, () => {
store,
apolloProvider,
propsData,
provide: {
glFeatures,
},
});
};
......@@ -611,4 +615,68 @@ describeSkipVue3(skipReason, () => {
});
});
});
describe('Resizable Dimensions', () => {
beforeEach(() => {
duoChatGlobalState.isShown = true;
createComponent();
});
it('initializes dimensions correctly on mount', () => {
createComponent();
expect(wrapper.vm.width).toBe(400);
expect(wrapper.vm.height).toBe(window.innerHeight);
expect(wrapper.vm.maxWidth).toBe(window.innerWidth - WIDTH_OFFSET);
expect(wrapper.vm.maxHeight).toBe(window.innerHeight);
});
it('updates dimensions correctly when `chat-resize` event is emitted', async () => {
const newWidth = 600;
const newHeight = 500;
const chat = findDuoChat();
chat.vm.$emit('chat-resize', { width: newWidth, height: newHeight });
await nextTick();
expect(wrapper.vm.width).toBe(newWidth);
expect(wrapper.vm.height).toBe(newHeight);
});
it('ensures dimensions do not exceed maxWidth or maxHeight', async () => {
const newWidth = window.innerWidth + 100;
const newHeight = window.innerHeight + 100;
const chat = findDuoChat();
chat.vm.$emit('chat-resize', { width: newWidth, height: newHeight });
await nextTick();
expect(wrapper.vm.width).toBe(window.innerWidth - WIDTH_OFFSET);
expect(wrapper.vm.height).toBe(window.innerHeight);
});
it('updates dimensions when the window is resized', async () => {
createComponent();
window.innerWidth = 1200;
window.innerHeight = 800;
window.dispatchEvent(new Event('resize'));
await nextTick();
expect(wrapper.vm.maxWidth).toBe(1200 - WIDTH_OFFSET);
expect(wrapper.vm.maxHeight).toBe(800);
});
it('renders DuoChat with shouldRenderResizable=false when duoChatDynamicDimension flag is false', () => {
createComponent({ glFeatures: { duoChatDynamicDimension: false } });
const duoChat = findDuoChat();
expect(duoChat.exists()).toBe(true);
expect(duoChat.props('shouldRenderResizable')).toBe(false);
});
it('renders DuoChat with shouldRenderResizable=true when duoChatDynamicDimension flag is true', () => {
createComponent({ glFeatures: { duoChatDynamicDimension: true } });
const duoChat = findDuoChat();
expect(duoChat.exists()).toBe(true);
expect(duoChat.props('shouldRenderResizable')).toBe(true);
});
});
});
0% 加载中 .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册