Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
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 @@ -101,14 +101,40 @@ onFlowComplete:
text: "Apps"
- assertVisible: "Apps"
- assertVisible: "Assignments"
- assertVisible: "People"
- tapOn: "People"
- tapOn: "TeacherA User"
- tapOn:
id: "floating_action_button" # Edit button
- tapOn: "First names*"
- runFlow:
file: "subflows/erase_text.yaml"
env:
TEXT: "First names*"
- inputText: "TeacherB"
- tapOn: "Save"
- tapOn: "Change History"
- assertVisible:
id: "app_title"
text: "Change History"
- assertVisible: "Person name changed from “TeacherA User” to “TeacherB User”"

- runFlow:
file: "subflows/admin_add_class.yaml"
file: "subflows/add_class.yaml"
env:
CLASSNAME: "New Class"
- assertVisible:
id: "app_title"
text: "New Class"

- tapOn: "Add Teacher"
- tapOn: "TeacherB User"
- tapOn: "Change History"
- assertVisible:
id: "app_title"
text: "Change History"
- assertVisible: "Teacher added: “TeacherB User”"
- back

- tapOn: "Add Student"
- tapOn: "Invite person"
- assertVisible:
Expand Down Expand Up @@ -199,6 +225,19 @@ onFlowComplete:
- assertVisible: "Pending requests.*"
- assertVisible: "Student User.*"
- tapOn: "Accept Invite"
- assertNotVisible: "Pending requests.*"
- tapOn: "Change History"
- assertVisible:
id: "app_title"
text: "Change History"
- assertVisible: "Join request approved for “Student User”"
- assertVisible: "Teacher added: “TeacherB User”"
- tapOn: "TeacherB User"
- tapOn: "Change History"
- assertVisible:
id: "app_title"
text: "Change History"
- assertVisible: "Person name changed from “TeacherA User” to “TeacherB User”"

# E) Teacher share invite link for parent device based signup
- tapOn: "Add student"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ import world.respect.shared.viewmodel.person.setusernameandpassword.CreateAccoun
import world.respect.shared.viewmodel.person.setusernameandpassword.CreateAccountSetUserNameViewModel
import world.respect.shared.viewmodel.schooldirectory.edit.SchoolDirectoryEditViewModel
import world.respect.shared.viewmodel.schooldirectory.list.SchoolDirectoryListViewModel
import world.respect.shared.viewmodel.apps.changehistory.ChangeHistoryViewModel
import world.respect.shared.domain.sharelink.LaunchSendEmailUseCase
import world.respect.shared.domain.sharelink.LaunchShareLinkUseCase
import world.respect.shared.domain.sharelink.LaunchSendSmsUseCase
Expand Down Expand Up @@ -384,6 +385,7 @@ val appKoinModule = module {
viewModelOf(::EnrollmentEditViewModel)
viewModelOf(::InviteQrViewModel)
viewModelOf(::CreateAccountSetPasswordViewModel)
viewModelOf(::ChangeHistoryViewModel)


single<GetOfflineStorageOptionsUseCase> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import world.respect.app.view.acknowledgement.AcknowledgementScreen
import world.respect.app.view.apps.changehistory.ChangeHistoryScreen
import world.respect.app.view.apps.detail.AppsDetailScreen
import world.respect.app.view.apps.enterlink.EnterLinkScreen
import world.respect.app.view.apps.launcher.AppLauncherScreen
Expand Down Expand Up @@ -73,6 +74,7 @@ import world.respect.shared.navigation.ClazzDetail
import world.respect.shared.navigation.ClazzEdit
import world.respect.shared.navigation.ClazzList
import world.respect.shared.navigation.AcceptInvite
import world.respect.shared.navigation.ChangeHistory
import world.respect.shared.navigation.CopyCode
import world.respect.shared.navigation.CreateAccount
import world.respect.shared.navigation.CreateAccountSetPassword
Expand Down Expand Up @@ -655,6 +657,15 @@ fun AppNavHost(
)
)
}

composable<ChangeHistory> {
ChangeHistoryScreen(
viewModel = respectViewModel(
onSetAppUiState = onSetAppUiState,
navController = respectNavController,
)
)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package world.respect.app.view.apps.changehistory

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import kotlinx.datetime.TimeZone
import org.jetbrains.compose.resources.stringResource
import world.respect.datalayer.db.school.ext.fullName
import world.respect.shared.generated.resources.Res
import world.respect.shared.generated.resources.change_format
import world.respect.shared.util.rememberFormattedDateTime
import world.respect.shared.viewmodel.apps.changehistory.ChangeHistoryUiState
import world.respect.shared.viewmodel.apps.changehistory.ChangeHistoryViewModel

@Composable
fun ChangeHistoryScreen(
viewModel: ChangeHistoryViewModel,
) {
val uiState by viewModel.uiState.collectAsState()

ChangeHistoryScreen(
uiState = uiState
)

}

@Composable
fun ChangeHistoryScreen(
uiState: ChangeHistoryUiState,
) {
val changeHistoryEntryWithWhoDid = uiState.changeHistoryEntryWithWhoDid ?: return

Column(
modifier = Modifier
.fillMaxSize()
.verticalScroll(rememberScrollState())
.padding(16.dp)
) {

changeHistoryEntryWithWhoDid.forEach { group ->

group.changeHistoryEntry.forEach { entry ->

entry.changes.forEach { change ->

Text(
text = group.person.fullName(),
)
val createdAtStr = rememberFormattedDateTime(
timeInMillis = entry.timestamp,
timeZoneId = TimeZone.currentSystemDefault().id,
)

Text(text = createdAtStr)
Text(
text = stringResource(
Res.string.change_format,
change.field.displayName,
change.oldVal?:"",
change.newVal
)
)
Spacer(modifier = Modifier.height(16.dp))

}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Key
import androidx.compose.material.icons.filled.Replay
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.ListItem
import androidx.compose.material3.MaterialTheme
Expand All @@ -30,6 +31,7 @@ import world.respect.shared.generated.resources.email
import world.respect.shared.generated.resources.family_members
import world.respect.shared.generated.resources.gender
import world.respect.shared.generated.resources.manage_account
import world.respect.shared.generated.resources.change_history
import world.respect.shared.generated.resources.phone_number
import world.respect.shared.generated.resources.role
import world.respect.shared.generated.resources.username_label
Expand All @@ -47,6 +49,7 @@ fun PersonDetailScreen(
onClickManageAccount = viewModel::navigateToManageAccount,
onClickCreateAccount = viewModel::onClickCreateAccount,
onClickPhoneNumber = viewModel::onClickPhoneNumber,
onClickChangeHistoryButton = viewModel::onClickChangeHistoryButton,
onClickFamilyMember = viewModel::onClickFamilyMember
)
}
Expand All @@ -56,6 +59,7 @@ fun PersonDetailScreen(
uiState: PersonDetailUiState,
onClickManageAccount:() -> Unit,
onClickCreateAccount: () -> Unit,
onClickChangeHistoryButton: () -> Unit,
onClickPhoneNumber: () -> Unit,
onClickFamilyMember: (String) -> Unit,
) {
Expand All @@ -80,6 +84,13 @@ fun PersonDetailScreen(
onClick = onClickCreateAccount,
)
}
if(uiState.changeHistoryButtonVisible){
RespectQuickActionButton(
labelText = stringResource(Res.string.change_history),
imageVector = Icons.Default.Replay,
onClick = onClickChangeHistoryButton,
)
}
}

HorizontalDivider()
Expand Down
2 changes: 2 additions & 0 deletions respect-datalayer-db/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ kotlin {
api(libs.androidx.paging.common)
api(libs.androidx.room.paging)
implementation(libs.napier)
implementation(libs.koin.core)
implementation(project.dependencies.platform(libs.koin.bom))

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import world.respect.datalayer.db.school.daos.ReportEntityDao
import world.respect.datalayer.db.realm.entities.IndicatorEntity
import world.respect.datalayer.db.school.daos.AssignmentEntityDao
import world.respect.datalayer.db.school.daos.AssignmentLearningResourceRefEntityDao
import world.respect.datalayer.db.school.daos.ChangeHistoryDao
import world.respect.datalayer.db.school.daos.ClassEntityDao
import world.respect.datalayer.db.school.daos.ClassPermissionEntityDao
import world.respect.datalayer.db.school.daos.EnrollmentEntityDao
Expand All @@ -57,6 +58,8 @@ import world.respect.datalayer.db.school.entities.ReportEntity
import world.respect.datalayer.db.school.entities.SchoolAppEntity
import world.respect.datalayer.db.school.entities.WriteQueueItemEntity
import world.respect.datalayer.db.school.daos.SchoolPermissionGrantDao
import world.respect.datalayer.db.school.entities.ChangeHistoryChangeEntity
import world.respect.datalayer.db.school.entities.ChangeHistoryEntity
import world.respect.datalayer.db.school.entities.ClassPermissionEntity
import world.respect.datalayer.db.school.entities.PullSyncStatusEntity
import world.respect.datalayer.db.school.entities.SchoolPermissionGrantEntity
Expand Down Expand Up @@ -105,6 +108,8 @@ import world.respect.datalayer.school.model.Report
OpdsGroupEntity::class,
OpdsFeedEntity::class,
OpdsFeedMetadataEntity::class,
ChangeHistoryEntity::class,
ChangeHistoryChangeEntity::class,
],
version = 12,
)
Expand Down Expand Up @@ -162,6 +167,8 @@ abstract class RespectSchoolDatabase: RoomDatabase() {

abstract fun getOpdsGroupEntityDao(): OpdsGroupEntityDao

abstract fun getChangeHistoryDao(): ChangeHistoryDao


companion object {

Expand All @@ -182,6 +189,7 @@ abstract class RespectSchoolDatabase: RoomDatabase() {
)

}

}

// The Room compiler generates the `actual` implementations.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,39 @@ val MIGRATION_11_12 = object: Migration(11, 12) {
}
}

val MIGRATE_12_13 = object : Migration(12, 13) {

override fun migrate(connection: SQLiteConnection) {

connection.execSQL("""
CREATE TABLE IF NOT EXISTS `ChangeHistoryEntity` (
`hGuid` TEXT NOT NULL,
`hGuidHash` INTEGER NOT NULL,
`hTable` TEXT NOT NULL,
`hTimestamp` INTEGER NOT NULL,
`hWhoGuid` TEXT NOT NULL,
`hWhoGuidHash` INTEGER NOT NULL,
`hTableGuid` TEXT NOT NULL,
PRIMARY KEY(`hGuidHash`)
)
""".trimIndent())

connection.execSQL("""
CREATE TABLE IF NOT EXISTS `ChangeHistoryChangeEntity` (
`hcId` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
`hcHistoryGuidHash` INTEGER NOT NULL,
`hcField` TEXT NOT NULL,
`hcOldVal` TEXT,
`hcNewVal` TEXT NOT NULL
)
""".trimIndent())
}
}


fun RoomDatabase.Builder<RespectSchoolDatabase>.addCommonMigrations(

): RoomDatabase.Builder<RespectSchoolDatabase> {
return this.addMigrations(MIGRATION_11_12)
return this.addMigrations(MIGRATION_11_12,MIGRATE_12_13)
}

Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import world.respect.datalayer.UidNumberMapper
import world.respect.datalayer.db.school.opds.OpdsPublicationDataSourceDb
import world.respect.datalayer.db.school.opds.OpdsFeedDataSourceDb
import world.respect.datalayer.db.school.AssignmentDatasourceDb
import world.respect.datalayer.db.school.ChangeHistoryDataSourceDb
import world.respect.datalayer.db.school.ClassDatasourceDb
import world.respect.datalayer.db.school.EnrollmentDataSourceDb
import world.respect.datalayer.db.school.GetAuthenticatedPersonUseCase
Expand All @@ -20,6 +21,7 @@ import world.respect.datalayer.db.school.ReportDataSourceDb
import world.respect.datalayer.db.school.SchoolAppDataSourceDb
import world.respect.datalayer.db.school.SchoolPermissionGrantDataSourceDb
import world.respect.datalayer.school.AssignmentDataSourceLocal
import world.respect.datalayer.school.ChangeHistoryLocal
import world.respect.datalayer.school.ClassDataSourceLocal
import world.respect.datalayer.school.DummySchoolConfigSettingsDataSource
import world.respect.datalayer.school.EnrollmentDataSourceLocal
Expand Down Expand Up @@ -77,7 +79,7 @@ class SchoolDataSourceDb(
}

override val personDataSource: PersonDataSourceLocal by lazy {
PersonDataSourceDb(schoolDb, uidNumberMapper, authenticatedUser, checkPersonPermissionUseCase)
PersonDataSourceDb(schoolDb, uidNumberMapper, authenticatedUser, checkPersonPermissionUseCase,changeHistoryDataSource)
}

override val personPasskeyDataSource: PersonPasskeyDataSourceLocal by lazy {
Expand Down Expand Up @@ -117,6 +119,11 @@ class SchoolDataSourceDb(
AssignmentDatasourceDb(schoolDb, uidNumberMapper, authenticatedUser)
}

override val changeHistoryDataSource: ChangeHistoryLocal by lazy {
ChangeHistoryDataSourceDb(schoolDb,uidNumberMapper)
}


override val opdsPublicationDataSource: OpdsPublicationDataSourceLocal by lazy {
OpdsPublicationDataSourceDb(
respectSchoolDatabase = schoolDb,
Expand Down
Loading