Skip to content

Commit

Permalink
Merge pull request #288 from dhis2/release/0.3.0
Browse files Browse the repository at this point in the history
Release/0.3.0
  • Loading branch information
andresmr authored Aug 26, 2024
2 parents 5f0172d + a1fca6d commit 240431b
Show file tree
Hide file tree
Showing 194 changed files with 9,464 additions and 4,692 deletions.
37 changes: 34 additions & 3 deletions .github/workflows/generate-paparazzi-golden-images.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,38 @@ on:

jobs:
ci_job:
runs-on: macos-latest
runs-on: ubuntu-latest
steps:
- name: Run Hello World
run: echo "Hello, World!"
- uses: actions/checkout@v3
with:
lfs: 'true'
fetch-depth: 0
persist-credentials: false

- name: Set Up JDK
uses: actions/setup-java@v3
with:
distribution: 'zulu' # See 'Supported distributions' for available options
java-version: '17'
cache: 'gradle'

- name: Change wrapper permissions
run: chmod +x ./gradlew

- name: Generate Golden Images
run: ./gradlew designsystem:recordPaparazziDebug

- uses: actions/upload-artifact@v4
with:
name: GoldenImages
path: ./designsystem/src/test/snapshots/
if-no-files-found: 'error'

- name: Commit Changes
run: .github/workflows/scripts/commit-changes.sh

- name: Push changes
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
branch: ${{ github.ref }}
2 changes: 2 additions & 0 deletions .github/workflows/github-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
lfs: 'true'

- name: Set Up JDK
uses: actions/setup-java@v3
Expand Down
18 changes: 18 additions & 0 deletions .github/workflows/scripts/commit-changes.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
readonly GIT_HAS_CHANGES=1 # 0 = clean, 1 = dirty

git config user.name "GitHub Actions Bot"
git config user.email "<[email protected]>"

# Following git command checks the git diff of staged files
# and assigns the exit code to GIT_DIFF_STATUS variable.
git diff --quiet; GIT_DIFF_STATUS=$?

# If the GIT_DIFF_STATUS is 1 (GIT_HAS_CHANGES) then we know
# there are changes and we can commit the changes and push
# them to new branch
if [[ ${GIT_DIFF_STATUS} -eq ${GIT_HAS_CHANGES} ]]; then
git add -A
git commit -m "Paparazzi Golden Images"

exit 0
fi
10 changes: 10 additions & 0 deletions .tx/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[main]
host = https://www.transifex.com
lang_map = fa_AF: prs, uz@Cyrl: uz, uz@Latn: b+uz+Latn, zh_CN: zh-rCN, pt_BR: pt-rBR, es_419: b+es+419

[o:hisp-uio:p:mobile-ui:r:strings-xml]
file_filter = designsystem/src/commonMain/resources/values-<lang>/strings.xml
source_file = designsystem/src/commonMain/resources/values/strings.xml
source_lang = en
type = ANDROID
minimum_perc = 0
27 changes: 26 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ In the module **build.gradle.kts**:

```kotlin
dependencies {
implementation("org.hisp.dhis.mobile:designsystem:0.2.1")
implementation("org.hisp.dhis.mobile:designsystem:0.3.0")
}
```

Expand Down Expand Up @@ -109,3 +109,28 @@ Saves snapshots as golden values to a predefined source-controlled location (def

Runs tests and verifies against previously-recorded golden values. Failures generate diffs at
`/build/paparazzi/failures`.

# Documentation

The Mobile UI documentation is integrated in the [developer portal](https://developers.dhis2.org/). It
uses [Docusaurus](https://docusaurus.io), a modern tool to build documentation pages.

The documentation is written in Markdown. The sidebar is automatically generated based on the metadata
of the different files. It follows the rules explained in the [autogenerated sidebar docs](https://docusaurus.io/docs/next/sidebar/autogenerated#autogenerated-sidebar-metadata).
In short, every file must have a `sidebar_position` label at the beginning of the document, which
defines the position of the document relative to its folder. Then, each folder has a `_category_.yml`
file, which has a `position` property defining the position of that folder relative to its parent folder.

It is possible to nest as many folders as desired following that pattern.

## Testing

It is possible to build the Developers portal documentation to test your changes.

Steps to test:
1. Do the changes in the Mobile UI docs and push them to a branch in github.
2. Download the [Deverlopers portal repository](https://github.com/dhis2/developer-portal).
3. Change the branch in the Mobile UI block in the file `docs-migrate.js` to point to your branch.
4. Follow the instructions in [CONTRIBUTING](https://github.com/dhis2/developer-portal/blob/main/CONTRIBUTING.md)
to build the docs.

1 change: 1 addition & 0 deletions android/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ plugins {
id("org.jetbrains.compose")
id("com.android.application")
kotlin("multiplatform")
alias(libs.plugins.compose.compiler)
}

kotlin {
Expand Down
20 changes: 20 additions & 0 deletions android/src/main/java/org/hisp/dhis/android/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,22 @@ package org.hisp.dhis.android
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.runtime.Composable
import androidx.compose.runtime.SideEffect
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.platform.LocalContext
import androidx.core.view.WindowCompat
import org.hisp.dhis.common.App

class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
val res = LocalContext.current.resources
SetStatusBarColor()
App(
imageBitmapLoader = {
BitmapFactory.decodeResource(
Expand All @@ -27,3 +32,18 @@ class MainActivity : AppCompatActivity() {
}
}
}

@Composable
fun SetStatusBarColor() {
val context = LocalContext.current
val window = (context as? ComponentActivity)?.window

SideEffect {
window?.let {
WindowCompat.getInsetsController(it, it.decorView).apply {
isAppearanceLightStatusBars = true
}
it.statusBarColor = 0xFFE2F2FF.toInt()
}
}
}
6 changes: 5 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
version = "0.2.1-SNAPSHOT"
version = "0.3.0-SNAPSHOT"
group = "org.hisp.dhis.mobile"

plugins {
Expand All @@ -11,6 +11,7 @@ plugins {
id("org.jlleitschuh.gradle.ktlint") version "11.5.1"
id("org.jetbrains.dokka") version "1.9.20"
id("io.github.gradle-nexus.publish-plugin") version "1.3.0"
alias(libs.plugins.compose.compiler)
}

/**
Expand All @@ -27,6 +28,9 @@ allprojects {
version.set("0.50.0")
verbose.set(true)
outputToConsole.set(true)
filter {
exclude("**/generated/**")
}
}

tasks.withType<KotlinCompile>().all {
Expand Down
1 change: 1 addition & 0 deletions common/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ plugins {
kotlin("multiplatform")
id("org.jetbrains.compose")
id("com.android.library")
alias(libs.plugins.compose.compiler)
}

kotlin {
Expand Down
98 changes: 65 additions & 33 deletions common/src/commonMain/kotlin/org/hisp/dhis/common/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ImageBitmap
import org.hisp.dhis.common.screens.Components
import org.hisp.dhis.common.screens.Groups
import org.hisp.dhis.common.screens.NoComponentSelectedScreen
import org.hisp.dhis.common.screens.actionInputs.ActionInputsScreen
import org.hisp.dhis.common.screens.basicTextInputs.BasicTextInputsScreen
Expand All @@ -22,6 +24,7 @@ import org.hisp.dhis.common.screens.others.ChipsScreen
import org.hisp.dhis.common.screens.others.IndicatorScreen
import org.hisp.dhis.common.screens.others.LegendScreen
import org.hisp.dhis.common.screens.others.MetadataAvatarScreen
import org.hisp.dhis.common.screens.others.NavigationBarScreen
import org.hisp.dhis.common.screens.others.ProgressScreen
import org.hisp.dhis.common.screens.others.SearchBarScreen
import org.hisp.dhis.common.screens.others.SectionScreen
Expand All @@ -31,8 +34,12 @@ import org.hisp.dhis.common.screens.toggleableInputs.ToggleableInputsScreen
import org.hisp.dhis.mobile.ui.designsystem.component.DropdownItem
import org.hisp.dhis.mobile.ui.designsystem.component.InputDropDown
import org.hisp.dhis.mobile.ui.designsystem.component.InputShellState
import org.hisp.dhis.mobile.ui.designsystem.component.InputStyle
import org.hisp.dhis.mobile.ui.designsystem.component.MetadataAvatarSize
import org.hisp.dhis.mobile.ui.designsystem.theme.DHIS2Theme
import org.hisp.dhis.mobile.ui.designsystem.theme.Shape
import org.hisp.dhis.mobile.ui.designsystem.theme.Spacing
import org.hisp.dhis.mobile.ui.designsystem.theme.SurfaceColor

@Composable
fun App(imageBitmapLoader: (() -> ImageBitmap)? = null) {
Expand All @@ -45,50 +52,75 @@ fun App(imageBitmapLoader: (() -> ImageBitmap)? = null) {
fun Main(
imageBitmapLoader: (() -> ImageBitmap)?,
) {
val currentScreen = remember { mutableStateOf(Components.ACTION_INPUTS) }
val currentScreen = remember { mutableStateOf(Groups.NO_GROUP_SELECTED) }
var isComponentSelected by remember { mutableStateOf(false) }

Column(
verticalArrangement = Arrangement.spacedBy(Spacing.Spacing16),
modifier = Modifier
.background(Color.White)
.padding(Spacing.Spacing16),
.background(SurfaceColor.Container),
) {
val screenDropdownItemList = mutableListOf<DropdownItem>()
Components.entries.forEach {
Groups.entries.forEach {
screenDropdownItemList.add(DropdownItem(it.label))
}

InputDropDown(
"Components",
dropdownItems = screenDropdownItemList.toList(),
onItemSelected = { currentScreen.value = getCurrentScreen(it.label) },
onResetButtonClicked = { currentScreen.value = Components.NO_COMPONENT_SELECTED },
state = InputShellState.UNFOCUSED,
selectedItem = DropdownItem(currentScreen.value.label),
)
if (isComponentSelected) {
InputDropDown(
modifier = Modifier.padding(
start = Spacing.Spacing16,
end = Spacing.Spacing16,
top = Spacing.Spacing16,
),
title = "Group",
dropdownItems = screenDropdownItemList.toList(),
onItemSelected = { currentScreen.value = getCurrentScreen(it.label) },
onResetButtonClicked = { currentScreen.value = Groups.NO_GROUP_SELECTED },
state = InputShellState.UNFOCUSED,
expanded = true,
selectedItem = DropdownItem(currentScreen.value.label),
inputStyle = InputStyle.DataInputStyle().apply { backGroundColor = SurfaceColor.SurfaceBright },
)

when (currentScreen.value) {
Components.ACTION_INPUTS -> ActionInputsScreen()
Components.BADGES -> BadgesScreen()
Components.BASIC_TEXT_INPUTS -> BasicTextInputsScreen()
Components.BOTTOM_SHEETS -> BottomSheetsScreen()
Components.BUTTONS -> ButtonsScreen()
Components.CARDS -> CardsScreen()
Components.CHIPS -> ChipsScreen()
Components.INDICATOR -> IndicatorScreen()
Components.LEGEND -> LegendScreen()
Components.METADATA_AVATAR -> MetadataAvatarScreen()
Components.PROGRESS_INDICATOR -> ProgressScreen()
Components.PARAMETER_SELECTOR -> ParameterSelectorScreen()
Components.SECTIONS -> SectionScreen()
Components.TOGGLEABLE_INPUTS -> ToggleableInputsScreen(imageBitmapLoader)
Components.TAGS -> TagsScreen()
Components.SEARCH_BAR -> SearchBarScreen()
Components.NO_COMPONENT_SELECTED -> NoComponentSelectedScreen()
when (currentScreen.value) {
Groups.ACTION_INPUTS -> ActionInputsScreen()
Groups.BADGES -> BadgesScreen()
Groups.BASIC_TEXT_INPUTS -> BasicTextInputsScreen()
Groups.BOTTOM_SHEETS -> BottomSheetsScreen()
Groups.BUTTONS -> ButtonsScreen()
Groups.CARDS -> CardsScreen()
Groups.CHIPS -> ChipsScreen()
Groups.INDICATOR -> IndicatorScreen()
Groups.LEGEND -> LegendScreen()
Groups.METADATA_AVATAR -> MetadataAvatarScreen()
Groups.PROGRESS_INDICATOR -> ProgressScreen()
Groups.PARAMETER_SELECTOR -> ParameterSelectorScreen()
Groups.SECTIONS -> SectionScreen()
Groups.TOGGLEABLE_INPUTS -> ToggleableInputsScreen(imageBitmapLoader)
Groups.TAGS -> TagsScreen()
Groups.SEARCH_BAR -> SearchBarScreen()
Groups.NAVIGATION_BAR -> NavigationBarScreen()
Groups.NO_GROUP_SELECTED -> NoComponentSelectedScreen()
}
} else {
NoComponentSelectedScreen(
modifier = Modifier
.background(Color.White, Shape.NoRounding),
) {
isComponentSelected = !isComponentSelected
}
}
}
}

fun getCurrentScreen(label: String): Components {
return Components.entries.firstOrNull { it.label == label } ?: Components.ACTION_INPUTS
fun getCurrentScreen(label: String): Groups {
return Groups.entries.firstOrNull { it.label == label } ?: Groups.ACTION_INPUTS
}

fun getAvailableMetadataAvatarSizes() = listOf(
MetadataAvatarSize.XS(),
MetadataAvatarSize.S(),
MetadataAvatarSize.M(),
MetadataAvatarSize.L(),
MetadataAvatarSize.XL(),
)
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.hisp.dhis.common.screens

enum class Components(val label: String) {
enum class Groups(val label: String) {
ACTION_INPUTS("Action inputs"),
BASIC_TEXT_INPUTS("Basic text Inputs"),
BOTTOM_SHEETS("Bottom sheet components"),
Expand All @@ -17,5 +17,6 @@ enum class Components(val label: String) {
METADATA_AVATAR("Metadata Avatar"),
INDICATOR("Indicators"),
PARAMETER_SELECTOR("Parameter selector"),
NO_COMPONENT_SELECTED("No component selected"),
NAVIGATION_BAR("Navigation Bar"),
NO_GROUP_SELECTED("No group selected"),
}
Loading

0 comments on commit 240431b

Please sign in to comment.