Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
a62ba5e
Time spent widget core
domonkosadam Oct 6, 2025
605890c
Fix time spent widget
domonkosadam Oct 7, 2025
95203dc
Refactor domain service apis
domonkosadam Oct 7, 2025
8b874db
Refactor api
domonkosadam Oct 7, 2025
fbbbb3e
Widget header component
domonkosadam Oct 7, 2025
c923241
UI improvements
domonkosadam Oct 8, 2025
841e172
UI improvements
domonkosadam Oct 8, 2025
02fe151
Add preview
domonkosadam Oct 8, 2025
e5c5f33
Fix course handling
domonkosadam Oct 8, 2025
f4951f2
Merge branch 'master' into CLX-2879-Skill-Highlights-widget
domonkosadam Oct 8, 2025
c7130d6
Implement skill highlights widget
domonkosadam Oct 8, 2025
f7701ea
Fix button style
domonkosadam Oct 8, 2025
e18386b
Implement widget tests
domonkosadam Oct 8, 2025
70f5f8c
Merge branch 'CLX-2848-Time-spent-widget' into CLX-2879-Skill-Highlig…
domonkosadam Oct 8, 2025
380a234
Merge branch 'master' into CLX-2848-Time-spent-widget
domonkosadam Oct 8, 2025
294d7f9
Fix tests
domonkosadam Oct 8, 2025
4f12892
Merge branch 'CLX-2848-Time-spent-widget' into CLX-2879-Skill-Highlig…
domonkosadam Oct 8, 2025
76fa122
Implement tests
domonkosadam Oct 8, 2025
dc16994
Fix tests
domonkosadam Oct 8, 2025
3c55980
Fix skill query parameter
domonkosadam Oct 8, 2025
5c82f8f
Clickable skills
domonkosadam Oct 9, 2025
95b6ba6
Fix data handling
domonkosadam Oct 15, 2025
b3499ee
Refactor time spent widget unit tests for new API structure
domonkosadam Oct 15, 2025
51f7048
Add horizontal scrollable row for dashboard time spent widget
domonkosadam Oct 15, 2025
749a5d0
Implement empty state
domonkosadam Oct 15, 2025
b5c5ab4
Refactor loading
domonkosadam Oct 15, 2025
aa66c93
Set max width
domonkosadam Oct 15, 2025
2940655
Merge branch 'CLX-2848-Time-spent-widget' into CLX-2879-Skill-Highlig…
domonkosadam Oct 15, 2025
4b70cce
Fix loading ui
domonkosadam Oct 15, 2025
7a19f44
Add preview
domonkosadam Oct 15, 2025
0b48a34
Fix findings
domonkosadam Oct 20, 2025
c74d0fe
Merge branch 'master' into CLX-2879-Skill-Highlights-widget
domonkosadam Oct 21, 2025
59678b2
Fix merge issues
domonkosadam Oct 21, 2025
b4c0ec8
Fix merge issue
domonkosadam Oct 21, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ package com.instructure.canvas.espresso.mockcanvas.fakes

import com.instructure.canvas.espresso.mockcanvas.MockCanvas
import com.instructure.canvasapi2.managers.graphql.horizon.journey.GetProgramsManager
import com.instructure.canvasapi2.managers.graphql.horizon.journey.GetSkillsManager
import com.instructure.canvasapi2.managers.graphql.horizon.journey.GetWidgetsManager
import com.instructure.canvasapi2.managers.graphql.horizon.journey.Program
import com.instructure.canvasapi2.managers.graphql.horizon.journey.ProgramRequirement
import com.instructure.canvasapi2.managers.graphql.horizon.journey.Skill
import com.instructure.canvasapi2.utils.DataResult
import com.instructure.journey.GetWidgetDataQuery
import com.instructure.journey.type.ProgramProgressCourseEnrollmentStatus
Expand Down Expand Up @@ -103,4 +105,29 @@ class FakeGetWidgetsManager : GetWidgetsManager {
)
)
}
}

class FakeGetSkillsManager: GetSkillsManager {
override suspend fun getSkills(
completedOnly: Boolean?,
forceNetwork: Boolean
): List<Skill> {
return listOf(
Skill(
id = "1",
name = "Skill 1",
proficiencyLevel = "beginner",
createdAt = null,
updatedAt = null
),
Skill(
id = "2",
name = "Skill 2",
proficiencyLevel = "expert",
createdAt = null,
updatedAt = null
)
)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
query GetSkills($completedOnly: Boolean) {
skills(completedOnly: $completedOnly) {
id
name
proficiencyLevel
createdAt
updatedAt
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import com.apollographql.apollo.ApolloClient
import com.instructure.canvasapi2.di.JourneyApolloClient
import com.instructure.canvasapi2.managers.graphql.horizon.journey.GetProgramManagerImpl
import com.instructure.canvasapi2.managers.graphql.horizon.journey.GetProgramsManager
import com.instructure.canvasapi2.managers.graphql.horizon.journey.GetSkillsManager
import com.instructure.canvasapi2.managers.graphql.horizon.journey.GetSkillsManagerImpl
import com.instructure.canvasapi2.managers.graphql.horizon.journey.GetWidgetsManager
import com.instructure.canvasapi2.managers.graphql.horizon.journey.GetWidgetsManagerImpl
import dagger.Module
Expand All @@ -44,4 +46,11 @@ class JourneyModule {
return GetProgramManagerImpl(journeyClient)
}

@Provides
fun provideSkillsManager(
@JourneyApolloClient journeyClient: ApolloClient
): GetSkillsManager {
return GetSkillsManagerImpl(journeyClient)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright (C) 2025 - present Instructure, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.instructure.canvasapi2.managers.graphql.horizon.journey

import com.apollographql.apollo.ApolloClient
import com.apollographql.apollo.api.Optional
import com.instructure.canvasapi2.enqueueQuery
import com.instructure.journey.GetSkillsQuery
import java.util.Date
import javax.inject.Inject

data class Skill(
val id: String,
val name: String,
val proficiencyLevel: String?,
val createdAt: Date?,
val updatedAt: Date?
)

interface GetSkillsManager {
suspend fun getSkills(completedOnly: Boolean?, forceNetwork: Boolean): List<Skill>
}

class GetSkillsManagerImpl @Inject constructor(
private val journeyClient: ApolloClient
) : GetSkillsManager {
override suspend fun getSkills(
completedOnly: Boolean?,
forceNetwork: Boolean
): List<Skill> {
val query = GetSkillsQuery(
completedOnly = Optional.presentIfNotNull(completedOnly)
)

val result = journeyClient.enqueueQuery(query, forceNetwork)
val skills = result.dataAssertNoErrors.skills

return skills.map { skill ->
Skill(
id = skill.id,
name = skill.name,
proficiencyLevel = skill.proficiencyLevel,
createdAt = skill.createdAt,
updatedAt = skill.updatedAt
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ import com.instructure.canvas.espresso.mockcanvas.addItemToModule
import com.instructure.canvas.espresso.mockcanvas.addModuleToCourse
import com.instructure.canvas.espresso.mockcanvas.fakes.FakeGetHorizonCourseManager
import com.instructure.canvas.espresso.mockcanvas.fakes.FakeGetProgramsManager
import com.instructure.canvas.espresso.mockcanvas.fakes.FakeGetSkillsManager
import com.instructure.canvas.espresso.mockcanvas.fakes.FakeGetWidgetsManager
import com.instructure.canvas.espresso.mockcanvas.init
import com.instructure.canvasapi2.di.graphql.GetCoursesModule
import com.instructure.canvasapi2.di.graphql.JourneyModule
import com.instructure.canvasapi2.managers.graphql.horizon.HorizonGetCoursesManager
import com.instructure.canvasapi2.managers.graphql.horizon.journey.GetProgramsManager
import com.instructure.canvasapi2.managers.graphql.horizon.journey.GetSkillsManager
import com.instructure.canvasapi2.managers.graphql.horizon.journey.GetWidgetsManager
import com.instructure.canvasapi2.models.Page
import com.instructure.horizon.espresso.HorizonTest
Expand All @@ -42,6 +44,7 @@ class HorizonDashboardInteractionTest: HorizonTest() {
private val fakeGetHorizonCourseManager = FakeGetHorizonCourseManager()
private val fakeGetProgramsManager = FakeGetProgramsManager()
private val fakeGetWidgetsManager = FakeGetWidgetsManager()
private val fakeGetSkillsManager = FakeGetSkillsManager()

@BindValue
@JvmField
Expand All @@ -51,6 +54,10 @@ class HorizonDashboardInteractionTest: HorizonTest() {
@JvmField
val getWidgetsManager: GetWidgetsManager = fakeGetWidgetsManager

@BindValue
@JvmField
val getSkillsManager: GetSkillsManager = fakeGetSkillsManager

@BindValue
@JvmField
val getCoursesManager: HorizonGetCoursesManager = fakeGetHorizonCourseManager
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@ package com.instructure.horizon.interaction.features.home
import com.instructure.canvas.espresso.mockcanvas.MockCanvas
import com.instructure.canvas.espresso.mockcanvas.fakes.FakeGetHorizonCourseManager
import com.instructure.canvas.espresso.mockcanvas.fakes.FakeGetProgramsManager
import com.instructure.canvas.espresso.mockcanvas.fakes.FakeGetSkillsManager
import com.instructure.canvas.espresso.mockcanvas.fakes.FakeGetWidgetsManager
import com.instructure.canvas.espresso.mockcanvas.init
import com.instructure.canvasapi2.di.graphql.GetCoursesModule
import com.instructure.canvasapi2.di.graphql.JourneyModule
import com.instructure.canvasapi2.managers.graphql.horizon.HorizonGetCoursesManager
import com.instructure.canvasapi2.managers.graphql.horizon.journey.GetProgramsManager
import com.instructure.canvasapi2.managers.graphql.horizon.journey.GetSkillsManager
import com.instructure.canvasapi2.managers.graphql.horizon.journey.GetWidgetsManager
import com.instructure.horizon.espresso.HorizonTest
import com.instructure.horizon.pages.HorizonHomePage
Expand All @@ -39,6 +41,7 @@ class HorizonHomeInteractionTest : HorizonTest() {
private val fakeGetHorizonCourseManager = FakeGetHorizonCourseManager()
private val fakeGetProgramsManager = FakeGetProgramsManager()
private val fakeGetWidgetsManager = FakeGetWidgetsManager()
private val fakeGetSkillsManager = FakeGetSkillsManager()

@BindValue
@JvmField
Expand All @@ -48,6 +51,10 @@ class HorizonHomeInteractionTest : HorizonTest() {
@JvmField
val getWidgetsManager: GetWidgetsManager = fakeGetWidgetsManager

@BindValue
@JvmField
val getSkillsManager: GetSkillsManager = fakeGetSkillsManager

@BindValue
@JvmField
val getCoursesManager: HorizonGetCoursesManager = fakeGetHorizonCourseManager
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@ import com.instructure.canvas.espresso.mockcanvas.MockCanvas
import com.instructure.canvas.espresso.mockcanvas.addAccountNotification
import com.instructure.canvas.espresso.mockcanvas.fakes.FakeGetHorizonCourseManager
import com.instructure.canvas.espresso.mockcanvas.fakes.FakeGetProgramsManager
import com.instructure.canvas.espresso.mockcanvas.fakes.FakeGetSkillsManager
import com.instructure.canvas.espresso.mockcanvas.fakes.FakeGetWidgetsManager
import com.instructure.canvas.espresso.mockcanvas.init
import com.instructure.canvasapi2.di.graphql.GetCoursesModule
import com.instructure.canvasapi2.di.graphql.JourneyModule
import com.instructure.canvasapi2.managers.graphql.horizon.HorizonGetCoursesManager
import com.instructure.canvasapi2.managers.graphql.horizon.journey.GetProgramsManager
import com.instructure.canvasapi2.managers.graphql.horizon.journey.GetSkillsManager
import com.instructure.canvasapi2.managers.graphql.horizon.journey.GetWidgetsManager
import com.instructure.horizon.espresso.HorizonTest
import dagger.hilt.android.testing.BindValue
Expand All @@ -39,6 +41,7 @@ class HorizonNotificationInteractionTest: HorizonTest() {
private val fakeGetHorizonCourseManager = FakeGetHorizonCourseManager()
private val fakeGetProgramsManager = FakeGetProgramsManager()
private val fakeGetWidgetsManager = FakeGetWidgetsManager()
private val fakeGetSkillsManager = FakeGetSkillsManager()

@BindValue
@JvmField
Expand All @@ -48,6 +51,10 @@ class HorizonNotificationInteractionTest: HorizonTest() {
@JvmField
val getWidgetsManager: GetWidgetsManager = fakeGetWidgetsManager

@BindValue
@JvmField
val getSkillsManager: GetSkillsManager = fakeGetSkillsManager

@BindValue
@JvmField
val getCoursesManager: HorizonGetCoursesManager = fakeGetHorizonCourseManager
Expand Down
Loading
Loading