-
Notifications
You must be signed in to change notification settings - Fork 102
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: [ANDROAPP-6689] Create DataSetInstanceScreen
- Loading branch information
Showing
29 changed files
with
795 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
22 changes: 22 additions & 0 deletions
22
...egates/src/androidMain/kotlin/org/dhis2/mobile/aggregates/ui/DataSetTableScreenPreview.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package org.dhis2.mobile.aggregates.ui | ||
|
||
import androidx.compose.runtime.Composable | ||
import androidx.compose.ui.tooling.preview.Preview | ||
import org.dhis2.mobile.aggregates.model.previewDataSetScreenState | ||
import org.hisp.dhis.mobile.ui.designsystem.theme.DHIS2Theme | ||
|
||
@Preview(device = "id:pixel_8a") | ||
@Composable | ||
fun DataSetTableScreenPreview() { | ||
DHIS2Theme { | ||
DataSetInstanceScreen(previewDataSetScreenState(false, 3)) {} | ||
} | ||
} | ||
|
||
@Preview(device = "id:pixel_c") | ||
@Composable | ||
fun DataSetTableTabletScreenPreview() { | ||
DHIS2Theme { | ||
DataSetInstanceScreen(previewDataSetScreenState(true, 10)) {} | ||
} | ||
} |
9 changes: 9 additions & 0 deletions
9
aggregates/src/androidMain/kotlin/org/dhis2/mobile/aggregates/ui/ScreenWidth.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package org.dhis2.mobile.aggregates.ui | ||
|
||
import androidx.compose.runtime.Composable | ||
import androidx.compose.ui.platform.LocalConfiguration | ||
import androidx.compose.ui.unit.Dp | ||
import androidx.compose.ui.unit.dp | ||
|
||
@Composable | ||
actual fun getScreenWidth(): Dp = LocalConfiguration.current.screenWidthDp.dp |
8 changes: 8 additions & 0 deletions
8
aggregates/src/commonMain/kotlin/org/dhis2/mobile/aggregates/model/DataSetDetails.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package org.dhis2.mobile.aggregates.model | ||
|
||
data class DataSetDetails( | ||
val titleLabel: String, | ||
val dateLabel: String, | ||
val orgUnitLabel: String, | ||
val catOptionComboLabel: String, | ||
) |
27 changes: 27 additions & 0 deletions
27
aggregates/src/commonMain/kotlin/org/dhis2/mobile/aggregates/model/DataSetScreenState.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package org.dhis2.mobile.aggregates.model | ||
|
||
data class DataSetScreenState( | ||
val dataSetDetails: DataSetDetails, | ||
val dataSetSections: List<DataSetSection>, | ||
val useTwoPane: Boolean, | ||
) | ||
|
||
inline fun previewDataSetScreenState( | ||
useTwoPane: Boolean, | ||
numberOfTabs: Int, | ||
) = DataSetScreenState( | ||
dataSetDetails = DataSetDetails( | ||
titleLabel = "Data set title", | ||
dateLabel = "Jan. 2024", | ||
orgUnitLabel = "Org. Unit", | ||
catOptionComboLabel = "Cat. Option Combo", | ||
), | ||
dataSetSections = buildList { | ||
repeat(numberOfTabs) { | ||
add( | ||
DataSetSection("uid$it", "Section $it"), | ||
) | ||
} | ||
}, | ||
useTwoPane = useTwoPane, | ||
) |
6 changes: 6 additions & 0 deletions
6
aggregates/src/commonMain/kotlin/org/dhis2/mobile/aggregates/model/DataSetSection.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package org.dhis2.mobile.aggregates.model | ||
|
||
data class DataSetSection( | ||
val uid: String, | ||
val title: String, | ||
) |
130 changes: 130 additions & 0 deletions
130
aggregates/src/commonMain/kotlin/org/dhis2/mobile/aggregates/ui/AdaptativeTabRow.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
package org.dhis2.mobile.aggregates.ui | ||
|
||
import androidx.compose.foundation.layout.fillMaxWidth | ||
import androidx.compose.foundation.layout.height | ||
import androidx.compose.material3.MaterialTheme | ||
import androidx.compose.material3.ScrollableTabRow | ||
import androidx.compose.material3.Tab | ||
import androidx.compose.material3.TabRow | ||
import androidx.compose.material3.TabRowDefaults | ||
import androidx.compose.material3.TabRowDefaults.tabIndicatorOffset | ||
import androidx.compose.material3.Text | ||
import androidx.compose.runtime.Composable | ||
import androidx.compose.runtime.LaunchedEffect | ||
import androidx.compose.runtime.getValue | ||
import androidx.compose.runtime.mutableStateListOf | ||
import androidx.compose.runtime.mutableStateOf | ||
import androidx.compose.runtime.remember | ||
import androidx.compose.runtime.setValue | ||
import androidx.compose.ui.Modifier | ||
import androidx.compose.ui.layout.onGloballyPositioned | ||
import androidx.compose.ui.platform.LocalDensity | ||
import androidx.compose.ui.unit.dp | ||
import org.hisp.dhis.mobile.ui.designsystem.theme.Spacing | ||
|
||
/** | ||
* Adaptive Tab Row | ||
* Displays a scrollable tab row if the total width of the tabs exceeds the screen width. | ||
* @param modifier Modifier for styling | ||
* @param tabLabels List of tab labels to display | ||
* @param onTabClicked Callback function to be invoked when a tab is clicked | ||
* **/ | ||
@Composable | ||
fun AdaptiveTabRow( | ||
modifier: Modifier = Modifier, | ||
tabLabels: List<String>, | ||
onTabClicked: (index: Int) -> Unit, | ||
) { | ||
var selectedTab by remember { mutableStateOf(0) } | ||
val tabWidths = remember { mutableStateListOf<Int>() } | ||
var scrollable by remember { mutableStateOf(false) } | ||
|
||
// Calculate total width of tabs | ||
val totalTabWidth = tabWidths.sum() | ||
val screenWidth = with(LocalDensity.current) { | ||
getScreenWidth().roundToPx() | ||
} | ||
|
||
LaunchedEffect(key1 = totalTabWidth, key2 = screenWidth) { | ||
// Determine if tabs should be scrollable | ||
scrollable = totalTabWidth > screenWidth | ||
} | ||
|
||
// TabRow with conditional behavior | ||
if (false) { | ||
ScrollableTabRow( | ||
modifier = modifier | ||
.height(48.dp) | ||
.fillMaxWidth(), | ||
selectedTabIndex = selectedTab, | ||
containerColor = MaterialTheme.colorScheme.primary, | ||
edgePadding = Spacing.Spacing16, | ||
indicator = { tabPositions -> | ||
TabRowDefaults.PrimaryIndicator( | ||
width = 56.dp, | ||
modifier = Modifier.tabIndicatorOffset(tabPositions[selectedTab]), | ||
color = MaterialTheme.colorScheme.onPrimary, | ||
) | ||
}, | ||
divider = {}, | ||
) { | ||
tabLabels.forEachIndexed { index, tabLabel -> | ||
Tab( | ||
modifier = Modifier | ||
.height(48.dp) | ||
.onGloballyPositioned { coordinates -> | ||
tabWidths.add(index, coordinates.size.width) | ||
}, | ||
selected = selectedTab == index, | ||
onClick = { | ||
selectedTab = index | ||
onTabClicked(index) | ||
}, | ||
) { | ||
Text( | ||
text = tabLabel, | ||
color = MaterialTheme.colorScheme.onPrimary, | ||
style = MaterialTheme.typography.titleSmall, | ||
) | ||
} | ||
} | ||
} | ||
} else { | ||
TabRow( | ||
modifier = modifier | ||
.height(48.dp) | ||
.fillMaxWidth(), | ||
selectedTabIndex = selectedTab, | ||
containerColor = MaterialTheme.colorScheme.primary, | ||
indicator = { tabPositions -> | ||
TabRowDefaults.PrimaryIndicator( | ||
width = 56.dp, | ||
modifier = Modifier.tabIndicatorOffset(tabPositions[selectedTab]), | ||
color = MaterialTheme.colorScheme.onPrimary, | ||
) | ||
}, | ||
divider = {}, | ||
) { | ||
tabLabels.forEachIndexed { index, tabLabel -> | ||
Tab( | ||
modifier = Modifier | ||
.height(48.dp) | ||
.onGloballyPositioned { coordinates -> | ||
tabWidths.add(index, coordinates.size.width) | ||
}, | ||
selected = selectedTab == index, | ||
onClick = { | ||
selectedTab = index | ||
onTabClicked(index) | ||
}, | ||
) { | ||
Text( | ||
text = tabLabel, | ||
color = MaterialTheme.colorScheme.onPrimary, | ||
style = MaterialTheme.typography.titleSmall, | ||
) | ||
} | ||
} | ||
} | ||
} | ||
} |
96 changes: 96 additions & 0 deletions
96
aggregates/src/commonMain/kotlin/org/dhis2/mobile/aggregates/ui/DataSetDetailRow.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
package org.dhis2.mobile.aggregates.ui | ||
|
||
import androidx.compose.foundation.layout.Arrangement.Absolute.spacedBy | ||
import androidx.compose.foundation.lazy.LazyRow | ||
import androidx.compose.material.icons.Icons | ||
import androidx.compose.material.icons.filled.AccountTree | ||
import androidx.compose.material.icons.filled.CalendarMonth | ||
import androidx.compose.material.icons.filled.Category | ||
import androidx.compose.material3.Icon | ||
import androidx.compose.runtime.Composable | ||
import androidx.compose.ui.Alignment | ||
import androidx.compose.ui.Modifier | ||
import org.dhis2.mobile.aggregates.model.DataSetDetails | ||
import org.hisp.dhis.mobile.ui.designsystem.component.AssistChip | ||
import org.hisp.dhis.mobile.ui.designsystem.component.Tag | ||
import org.hisp.dhis.mobile.ui.designsystem.component.TagType | ||
import org.hisp.dhis.mobile.ui.designsystem.theme.Spacing | ||
|
||
@Composable | ||
internal fun DataSetDetails( | ||
modifier: Modifier = Modifier, | ||
editable: Boolean = false, | ||
dataSetDetails: DataSetDetails, | ||
) { | ||
LazyRow( | ||
modifier = modifier, | ||
verticalAlignment = Alignment.CenterVertically, | ||
horizontalArrangement = spacedBy(Spacing.Spacing8), | ||
) { | ||
item { | ||
if (editable) { | ||
AssistChip( | ||
label = dataSetDetails.dateLabel, | ||
icon = { | ||
Icon( | ||
imageVector = Icons.Filled.CalendarMonth, | ||
contentDescription = "", | ||
) | ||
}, | ||
onClick = { | ||
/*not yet supported*/ | ||
}, | ||
) | ||
} else { | ||
Tag( | ||
label = dataSetDetails.dateLabel, | ||
type = TagType.DEFAULT, | ||
) | ||
} | ||
} | ||
|
||
item { | ||
if (editable) { | ||
AssistChip( | ||
label = dataSetDetails.orgUnitLabel, | ||
icon = { | ||
Icon( | ||
imageVector = Icons.Filled.AccountTree, | ||
contentDescription = "", | ||
) | ||
}, | ||
onClick = { | ||
/*not yet supported*/ | ||
}, | ||
) | ||
} else { | ||
Tag( | ||
label = dataSetDetails.orgUnitLabel, | ||
type = TagType.DEFAULT, | ||
) | ||
} | ||
} | ||
|
||
item { | ||
if (editable) { | ||
AssistChip( | ||
label = dataSetDetails.catOptionComboLabel, | ||
icon = { | ||
Icon( | ||
imageVector = Icons.Filled.Category, | ||
contentDescription = "", | ||
) | ||
}, | ||
onClick = { | ||
/*not yet supported*/ | ||
}, | ||
) | ||
} else { | ||
Tag( | ||
label = dataSetDetails.catOptionComboLabel, | ||
type = TagType.DEFAULT, | ||
) | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.