Skip to content

Commit c0137f2

Browse files
authored
Reorganize onboarding and add Kuma AI (baserow#4606)
1 parent 0d4c43d commit c0137f2

40 files changed

Lines changed: 1159 additions & 746 deletions

backend/src/baserow/api/user/serializers.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,3 +471,7 @@ class ShareOnboardingDetailsWithBaserowSerializer(serializers.Serializer):
471471
help_text="The country that the user has chosen during the onboarding.",
472472
required=True,
473473
)
474+
how = serializers.CharField(
475+
help_text="How the user found Baserow.",
476+
required=True,
477+
)

backend/src/baserow/api/user/views.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -863,7 +863,12 @@ class ShareOnboardingDetailsWithBaserowView(APIView):
863863
@validate_body(ShareOnboardingDetailsWithBaserowSerializer)
864864
def post(self, request, data):
865865
UserHandler().start_share_onboarding_details_with_baserow(
866-
request.user, data["team"], data["role"], data["size"], data["country"]
866+
request.user,
867+
data["team"],
868+
data["role"],
869+
data["size"],
870+
data["country"],
871+
data["how"],
867872
)
868873

869874
return Response(status=204)

backend/src/baserow/core/user/handler.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -945,7 +945,13 @@ def send_email():
945945
)(send_email)()
946946

947947
def start_share_onboarding_details_with_baserow(
948-
self, user, team: str, role: str, size: str, country: str
948+
self,
949+
user,
950+
team: str,
951+
role: str,
952+
size: str,
953+
country: str,
954+
how: str,
949955
):
950956
"""
951957
Starts a celery task that shares some user information with baserow.io. Note
@@ -962,10 +968,17 @@ def start_share_onboarding_details_with_baserow(
962968
email = user.email
963969

964970
share_onboarding_details_with_baserow.delay(
965-
email=email, team=team, role=role, size=size, country=country
971+
email=email,
972+
team=team,
973+
role=role,
974+
size=size,
975+
country=country,
976+
how=how,
966977
)
967978

968-
def share_onboarding_details_with_baserow(self, email, team, role, size, country):
979+
def share_onboarding_details_with_baserow(
980+
self, email, team, role, size, country, how
981+
):
969982
"""
970983
Makes an API request to baserow.io that shares the additional information. Note
971984
that this is only triggered if the user given permission during the onboarding
@@ -975,6 +988,7 @@ def share_onboarding_details_with_baserow(self, email, team, role, size, country
975988
:param role: The role that the user shared.
976989
:param size: The company size that the user shared.
977990
:param country: The country name that the user shared.
991+
:param how: How the user found Baserow.
978992
"""
979993

980994
settings_object = CoreHandler().get_settings()
@@ -990,6 +1004,7 @@ def share_onboarding_details_with_baserow(self, email, team, role, size, country
9901004
"size": size,
9911005
"country": country,
9921006
"email": email,
1007+
"how": how,
9931008
"instance_id": settings_object.instance_id,
9941009
},
9951010
timeout=settings.ADDITIONAL_INFORMATION_TIMEOUT_SECONDS,

backend/tests/baserow/api/users/test_user_views.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,6 +1247,7 @@ def test_share_onboarding_details_with_baserow(mock_task, client, data_fixture):
12471247
"role": "CEO",
12481248
"size": "11 - 50",
12491249
"country": "The Netherlands",
1250+
"how": "Google",
12501251
},
12511252
format="json",
12521253
HTTP_AUTHORIZATION=f"JWT {token}",
@@ -1260,6 +1261,7 @@ def test_share_onboarding_details_with_baserow(mock_task, client, data_fixture):
12601261
role="CEO",
12611262
size="11 - 50",
12621263
country="The Netherlands",
1264+
how="Google",
12631265
)
12641266

12651267

backend/tests/baserow/core/user/test_user_handler.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -792,7 +792,7 @@ def test_start_share_onboarding_details_with_baserow(mock_task, data_fixture):
792792
user = data_fixture.create_user()
793793

794794
UserHandler().start_share_onboarding_details_with_baserow(
795-
user, "Marketing", "CEO", "11 - 50", "The Netherlands"
795+
user, "Marketing", "CEO", "11 - 50", "The Netherlands", "Google"
796796
)
797797

798798
mock_task.delay.assert_called_with(
@@ -801,6 +801,7 @@ def test_start_share_onboarding_details_with_baserow(mock_task, data_fixture):
801801
role="CEO",
802802
size="11 - 50",
803803
country="The Netherlands",
804+
how="Google",
804805
)
805806

806807

@@ -822,6 +823,7 @@ def test_share_onboarding_details_with_baserow_valid_response(data_fixture):
822823
"role": "CEO",
823824
"size": "11 - 50",
824825
"country": "The Netherlands",
826+
"how": "Google",
825827
"instance_id": "1",
826828
}
827829
)
@@ -834,6 +836,7 @@ def test_share_onboarding_details_with_baserow_valid_response(data_fixture):
834836
role="CEO",
835837
size="11 - 50",
836838
country="The Netherlands",
839+
how="Google",
837840
)
838841

839842
assert response1.call_count == 1
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"type": "feature",
3+
"message": "Add Kuma to onboarding and reorganize the steps.",
4+
"issue_origin": "github",
5+
"issue_number": null,
6+
"domain": "core",
7+
"bullet_points": [],
8+
"created_at": "2026-01-30"
9+
}

enterprise/web-frontend/modules/baserow_enterprise/assets/scss/components/all.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,5 @@
2222
@import 'file_input_element_form';
2323
@import 'custom_code';
2424
@import 'assistant';
25+
@import 'assistant_onboarding';
2526
@import 'date_dependency';
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
.assistant-onboarding {
2+
margin-top: 20px;
3+
width: 360px;
4+
height: 210px;
5+
display: flex;
6+
flex-direction: column;
7+
align-items: center;
8+
}
9+
10+
.assistant-onboarding__logo {
11+
margin-bottom: 10px;
12+
}
13+
14+
.assistant-onboarding__title {
15+
font-size: 20px;
16+
font-weight: 500;
17+
color: $palette-neutral-1200;
18+
margin-bottom: 32px;
19+
display: flex;
20+
align-items: center;
21+
}
22+
23+
.assistant-onboarding__title-icon {
24+
color: $palette-cyan-700;
25+
margin-right: 6px;
26+
}
27+
28+
.assistant-onboarding__message {
29+
display: flex;
30+
background-color: $palette-cyan-50;
31+
border: 1px solid $palette-cyan-200;
32+
border-radius: 12px;
33+
padding: 12px 16px;
34+
overflow-wrap: break-word;
35+
width: 100%;
36+
}
37+
38+
.assistant-onboarding__loading-wrapper {
39+
flex: 0 0 28px;
40+
width: 28px;
41+
}
42+
43+
.assistant-onboarding__loading {
44+
@include loading(1.4rem, $palette-cyan-500);
45+
}
46+
47+
.assistant-onboarding__text {
48+
display: -webkit-box;
49+
max-width: 100%;
50+
-webkit-line-clamp: 4;
51+
-webkit-box-orient: vertical;
52+
overflow: hidden;
53+
line-height: 20px;
54+
color: $palette-cyan-700;
55+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<template>
2+
<div class="assistant-onboarding">
3+
<div class="assistant-onboarding__logo">
4+
<img :src="image" alt="kuma" width="56" height="56" />
5+
</div>
6+
<div class="assistant-onboarding__title">
7+
<i class="iconoir-magic-wand assistant-onboarding__title-icon"></i>
8+
Kuma is building your database
9+
</div>
10+
<div class="assistant-onboarding__message">
11+
<div class="assistant-onboarding__loading-wrapper">
12+
<div class="assistant-onboarding__loading"></div>
13+
</div>
14+
<div class="assistant-onboarding__text">
15+
{{ message }}
16+
</div>
17+
</div>
18+
</div>
19+
</template>
20+
21+
<script>
22+
import { mapGetters } from 'vuex'
23+
import image from '@baserow_enterprise/assets/images/kuma.svg?url'
24+
25+
export default {
26+
name: 'AssistantOnboardingMessage',
27+
computed: {
28+
...mapGetters({
29+
messages: 'assistant/messages',
30+
}),
31+
message() {
32+
const defaultMessage = this.$t('assistantOnboardingMessage.instructing')
33+
const messages = Array.isArray(this.messages) ? this.messages : []
34+
const lastReasoning = [...messages]
35+
.reverse()
36+
.find(
37+
(m) =>
38+
m?.role === 'ai' &&
39+
m?.reasoning === true &&
40+
typeof m?.content === 'string' &&
41+
m.content.trim()
42+
)
43+
return lastReasoning?.content ?? defaultMessage
44+
},
45+
image() {
46+
return image
47+
},
48+
},
49+
}
50+
</script>

enterprise/web-frontend/modules/baserow_enterprise/components/assistant/AssistantSidebarItem.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export default {
4141
)
4242
},
4343
isConfigured() {
44-
return this.$config.public.baserowEnterpriseAssistantLLMModel !== null
44+
return !!this.$config.public.baserowEnterpriseAssistantLLMModel
4545
},
4646
},
4747
mounted() {

0 commit comments

Comments
 (0)