Skip to content

Commit cbc2321

Browse files
committed
Merge branch 'refs/heads/main' into deprecations
2 parents f7bc9e1 + 9d2118b commit cbc2321

File tree

567 files changed

+13213
-19901
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

567 files changed

+13213
-19901
lines changed

.github/labeler.yml

+1-7
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ admin-ui:
9696
- changed-files:
9797
- any-glob-to-any-file:
9898
- solr/webapp/**
99+
- solr/ui/**
99100

100101
# Add 'prometheus-exporter' label
101102
prometheus-exporter:
@@ -124,11 +125,6 @@ module:gcs-repository:
124125
- any-glob-to-any-file:
125126
- solr/modules/gcs-repository/**
126127

127-
module:hdfs:
128-
- changed-files:
129-
- any-glob-to-any-file:
130-
- solr/modules/hdfs/**
131-
132128
module:jwt-auth:
133129
- changed-files:
134130
- any-glob-to-any-file:
@@ -196,9 +192,7 @@ cat:index:
196192
- changed-files:
197193
- any-glob-to-any-file:
198194
- '**/org/apache/solr/index/**'
199-
- '**/org/apache/solr/hdfs/index/**'
200195
- '**/org/apache/solr/update/**'
201-
- '**/org/apache/solr/hdfs/update/**'
202196
- '**/org/apache/solr/scripting/update/**'
203197
- '**/org/apache/solr/handler/loader/**'
204198

.github/renovate.json

+5-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@
66
"enabledManagers": ["gradle", "github-actions"],
77
"includePaths": ["gradle/libs.versions.toml", "versions.*", "build.gradle", ".github/workflows/*"],
88
"postUpgradeTasks": {
9-
"commands": ["./gradlew resolveAndLockAll --write-locks", "./gradlew updateLicenses"],
9+
"commands": [
10+
"./gradlew resolveAndLockAll --write-locks",
11+
"./gradlew kotlinUpgradeYarnLock",
12+
"./gradlew updateLicenses"
13+
],
1014
"fileFilters": ["solr/licenses/*.sha1"],
1115
"executionMode": "branch"
1216
},

.github/workflows/gradle-precommit.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,6 @@ jobs:
4242
${{ runner.os }}-gradle-
4343
4444
- name: Run gradle check (without tests)
45-
run: ./gradlew check -x test -Ptask.times=true
45+
run: ./gradlew check -x test -Ptask.times=true --continue
4646

4747
- uses: gradle/wrapper-validation-action@v3

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ __pycache__
3636
gradle/wrapper/gradle-wrapper.jar
3737
.gradletasknamecache
3838

39+
# Kotlin
40+
.kotlin/
41+
3942
# WANT TO ADD MORE? You can tell Git without adding to this file:
4043
# See https://git-scm.com/docs/gitignore
4144
# In particular, if you have tools you use, add to $GIT_DIR/info/exclude or use core.excludesFile

build.gradle

+4
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ plugins {
2525
alias(libs.plugins.owasp.dependencycheck)
2626
alias(libs.plugins.cutterslade.analyze)
2727
alias(libs.plugins.benmanes.versions)
28+
alias(libs.plugins.kotlin.multiplatform) apply false
2829
alias(libs.plugins.littlerobots.versioncatalogupdate) apply false
2930
alias(libs.plugins.thetaphi.forbiddenapis) apply false
3031
alias(libs.plugins.undercouch.download) apply false
@@ -38,6 +39,9 @@ plugins {
3839
rootProject.ext.minJavaVersionDefault = JavaVersion.toVersion(libs.versions.java.min.get())
3940
rootProject.ext.minJavaVersionSolrJ = JavaVersion.toVersion(libs.versions.java.solrj.get())
4041

42+
// Check development mode for entire project (defaults to true if 'production' not provided and set to true)
43+
rootProject.ext.development = !project.hasProperty('production') || project.findProperty('production') != 'true'
44+
4145
apply from: file('gradle/globals.gradle')
4246

4347
// General metadata.

dev-docs/dependency-upgrades.adoc

+9-7
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,18 @@ Read the https://github.com/apache/solr/blob/main/help/dependencies.txt[help/dep
2626
explanation of how dependencies are managed.
2727

2828
== Manual dependency upgrades
29-
In order to upgrade a dependency, you need to run through a number of steps:
29+
To upgrade a dependency, you need to run through a number of steps:
3030

3131
1. Identify the available versions from e.g. https://search.maven.org[Maven Central]
3232
2. Update the version in `gradle/libs.versions.toml` file
33-
3. Run `./gradlew resolveAndLockAll` to re-generate lockfiles. Note that this may cause a cascading effect where
34-
the locked version of other dependencies also change.
35-
4. In case of a conflict, resolve the conflict according to `help/dependencies.txt`
36-
5. Update the license and notice files of the changed dependencies. See `help/dependencies.txt` for details.
37-
6. Run `./gradlew updateLicenses` to re-generate SHA1 checksums of the new jar files.
38-
7. Once in a while, a new version of a dependency will transitively bring in brand-new dependencies.
33+
3. Run `./gradlew resolveAndLockAll --write-locks` to re-generate lockfiles. Note that this may cause a cascading effect
34+
where the locked version of other dependencies also changes.
35+
4. Run `./gradlew kotlinUpgradeYarnLock` to update the kotlin-js-store lockfile used for the new UI.
36+
Most of the cases it will not have any changes.
37+
5. In case of a conflict, resolve the conflict according to `help/dependencies.txt`
38+
6. Update the license and notice files of the changed dependencies. See `help/dependencies.txt` for details.
39+
7. Run `./gradlew updateLicenses` to re-generate SHA1 checksums of the new jar files.
40+
8. Once in a while, a new version of a dependency will transitively bring in brand-new dependencies.
3941
You'll need to decide whether to keep or exclude them. See `help/dependencies.txt` for details.
4042

4143
=== Constraints and Version Alignment
+117
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
= Component Development
2+
:toc: left
3+
4+
== Overview
5+
6+
The following list contains a possible approach for implementing a new UI component:
7+
8+
1. Create a new design or start with an existing design, see for example Figma
9+
2. Validate the use case and analyze the components that may be used for the implementation
10+
3. Create Composables that represent the UI component(s) and use placeholders for data population
11+
4. Create a component interface and implementation with the UI state and UI component interactions
12+
5. Create previews with preview component implementations to check the UI implementation
13+
6. Create a store and store provider for fetching resources and interacting with Solr backend
14+
7. Implement the client used by the store provider
15+
8. Write tests and test the new component
16+
9. If not already done, integrate the component in the existing application
17+
10. If not already done, extract resources like texts to allow internationalization and localization
18+
19+
It is recommended to take a look at existing components, so that you get a better understanding
20+
of how things are implemented, what they have in common, and how each technology is utilized.
21+
22+
== Component's Logic
23+
24+
=== Components (Decompose)
25+
26+
The component integration interacts with the UI composables and the state store.
27+
28+
The implementation of the component interface "catches" user inputs like clicks and passes them
29+
to the store as ``Intent``s. The intents are then handled by the store implementation and
30+
may send a request to the backend and / or update the store state. The component is consuming
31+
and mapping the store state to the UI state. So once the store state is updated, it will
32+
reflect the changes in the UI.
33+
34+
=== State Stores and Store Providers
35+
36+
The state stores manage the state of the application, but independent of the state that is
37+
represented in the UI. Instances are created by store providers that hold the logic of the
38+
store.
39+
40+
Store providers consist of three elements:
41+
42+
- an executor implementation that consumes actions and intents and creates messages and labels
43+
- a reducer that updates the store state with the messages produced by the executor
44+
- a function for retrieving an instance of the store
45+
46+
The store provider does also define the interface for the client that has to be provided in
47+
order for the executor to make API calls and interact with the Solr backend.
48+
49+
== Component's Visuals
50+
51+
=== Composables
52+
53+
Composables are the UI elements that are defined and styled. They can be seen as boxes, rows and
54+
columns that are nested and change their style and structure based on conditions, state and input.
55+
56+
There are many ways to get started, but the easiest way probably is to get familiar with the basics
57+
and try things out. The Figma designs make use of almost the same elements for designing,
58+
so the structure and configurations there may be mapped almost one-by-one in Compose code.
59+
60+
=== Styling
61+
62+
The styling in Compose is done via ``Modifier``s. Each composable should normally accept a modifier
63+
as a parameter, so that the user can customize specific visual parameters of the composable like
64+
width, height and alignment in the parent's composable.
65+
66+
Since we are using Material 3, you do not have to care much about colors, typography and shapes.
67+
These are configured for the entire app, and you only have to make use of the right properties
68+
that are provided by the theme.
69+
70+
=== Accessibility
71+
72+
Compose comes with many accessibility features that can be used to improve the user experience.
73+
74+
The simplest form of accessibility in a UI is probably the responsiveness of the UI. This is
75+
realized with `WindowSizeClass`. Some composables may use a wrapper (usually suffixed with
76+
`Content`) that checks the window size and loads different UI based on the dimensions of the
77+
current window.
78+
79+
Another accessibility feature is the resource loading based on the system's locale or the user's
80+
preference. This allows the UI to be displayed in the user's native language. For that, you have
81+
to simply provide translations in the Compose resources.
82+
83+
Another accessibility feature often underestimated is coloring. Some people with color vision
84+
deficiency may need a different theme, so that elements with problematic contrasts may be
85+
better visible again.
86+
87+
Additional accessibility features like font scaling, semantics for screen readers may also
88+
be considered. Jetpack Compose provides a https://developer.android.com/develop/ui/compose/accessibility[simplified overview]
89+
and https://developer.android.com/codelabs/jetpack-compose-accessibility#0[Codelabs] for getting started.
90+
91+
=== Navigation and Child Components
92+
93+
Some components may have navigation elements and will load other components inside a frame layout.
94+
Since components hold a hierarchical context that needs to be managed somehow, child components
95+
(also used in navigation) are instantiated in a slightly different manner.
96+
97+
Decompose provides https://arkivanov.github.io/Decompose/navigation/overview/[a few examples]
98+
and details of the process behind the navigation and child components.
99+
100+
== Additional Notes
101+
102+
=== Dependency Locking
103+
104+
When adding or changing dependencies, you typically run `./gradlew resolveAndLockAll --write-locks`.
105+
Since we are building a web application from kotlin sources, we also have to update the JS lockfile
106+
with `./gradlew kotlinUpgradeYarnLock`. This will update the lockfile found at `kotlin-js-store/yarn.lock`.
107+
108+
Some multiplatform libraries have platform-specific dependency resolution that will result in different
109+
lockfiles being generated, based on the environment the lock task is executed. It is important to exclude
110+
these platform-specific libraries from the lockfile to ensure a consistent lockfile generation across
111+
different operating systems.
112+
113+
Platform-specific libraries come with a module name suffix that includes the platform name, like
114+
in `org.jetbrains.compose.desktop:desktop-jvm-windows-x64`. To identify those, look into the
115+
changes after updating the lockfile and add the necessary ignore-clause if such libraries
116+
exist. These ignore-clauses should be added in `gradle/validation/dependencies.gradle` inside the
117+
`allprojects.dependencyLocking` block.

dev-docs/ui/introduction.adoc

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
= New UI
2+
3+
== Introduction
4+
5+
The new UI that is introduced is a standalone frontend client that makes use of Solr's API.
6+
It is written in Kotlin and uses Compose Multiplatform as the UI framework.
7+
8+
== Overview
9+
10+
Since UI development mostly relies on different technologies and frameworks than backends use,
11+
the documentation is covering the following topics for new and experienced developers:
12+
13+
- Technology Overview
14+
- Module Structure and Elements
15+
- Component Development
16+
- Testing and Deployment
17+
18+
== Notes
19+
20+
All the references to files and directories in the UI documentation are from within
21+
the `solr/ui` module, if not otherwise stated.

dev-docs/ui/module-structure.adoc

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
= Module Structure and Elements
2+
3+
== Module Structure
4+
5+
The `ui` module follows a quite simple structure. It is split in
6+
7+
- *components*, which covers the logic part of the frontend and therefore contains
8+
the interfaces and implementations of them,
9+
- the *UI* part, which covers the visual elements, styling and everything related to UI, and
10+
- the *utils*, which contains various utilities used in both UI and logic.
11+
12+
In general, both UI and logic of the frontend are separated in "components" that follow similar,
13+
if not the same, structure and files.
14+
15+
== Components (Logic)
16+
17+
The logical part of a simple component (`org/apache/solr/ui/components`) usually consists of:
18+
19+
- **The component interface** (`[ComponentName]Component.kt`), that defines the UI state and the
20+
interaction options,
21+
22+
- **The store interface** (`store/[ComponentName]Store.kt`), that defines the (Solr) API state,
23+
intents for interacting with the state and optional labels (fire-and-forget events),
24+
25+
- **The store provider** (`store/[ComponentName]StoreProvider.kt`), that defines an API client
26+
interface that is used for making requests against the Solr API by consuming intents,
27+
updates the state and publishes labels,
28+
29+
- **The implementations** (`integration/*`), including component-specific mappings
30+
(`integration/Mappers.kt`) and interface implementations (like
31+
`integration/[Variant][ComponentName]Component.kt`),
32+
33+
- **Component-specific data classes** (`domain/*`), that are used only by the UI module
34+
35+
- **Component-specific API classes** (`data/*`), that are used for representing API requests /
36+
responses.
37+
38+
Some components may use multiple stores to consume different API endpoints or no store at all
39+
if no API interaction is necessary. Multiple components may also be used to simplify the complexity
40+
or separate the responsibilities into smaller UI elements.
41+
42+
Component data classes for API and internal use may also be merged and used interchangeably to
43+
reduce overall complexity. However, this affects the separation of concerns and may require
44+
in a later state the separation and mapping again.
45+
46+
This structure is strongly inspired by Decompose's https://arkivanov.github.io/Decompose/samples/[samples].
47+
48+
== User Interface (UI)
49+
50+
Similar to the logical part, the UI classes are also separated in components under
51+
`org.apache.solr.ui.views`.
52+
53+
Components may consist of one or multiple composables that make up a screen, section or
54+
element. The composables may also be reused, which is why they may be moved at some point
55+
during development to `.ui.components`.
56+
57+
Some vector assets like logos may be migrated to `ImageVector` and placed in `.ui.icons`
58+
to later be used in the UI.
59+
60+
Theme-related classes, functions and variables are all placed inside `.ui.theme`. The UI
61+
is making strong use of and customizes Material 3. You can find more information about
62+
Compose and Material 3 at https://m3.material.io/develop/android/jetpack-compose[Material Design - Jetpack Compose].
63+
64+
Composables may accept a component interface and be stateful, or simply hoist the entire
65+
state via parameters and be stateless. For more information about state hoisting,
66+
you can have a look at https://developer.android.com/develop/ui/compose/state[Managing state].
67+
68+
=== Compose Resources
69+
70+
Compose Resources are similar to assets in a web app and can be found at
71+
`commonMain/composeResources`. They contain files like fonts, translations, images,
72+
raw files and more.
73+
74+
The resource directories can use "qualifiers" that allow files to have variants.
75+
The most common use case is having translations for any text loaded. The directory
76+
`values/strings.xml` is the default / fallback strings resource file, that holds all values
77+
in english. If we would like to add translations for german now, we could use
78+
`values-de/strings.xml` and translate individual strings to german. Any string that is used
79+
and has no translation will automatically fall back to the value stored in `values/strings.xml`.
80+
81+
At the moment of writing, the language, theme and density qualifier are supported.
82+
83+
For more information about Compose Resources, see
84+
https://www.jetbrains.com/help/kotlin-multiplatform-dev/compose-images-resources.html[Multiplatform Resources].

0 commit comments

Comments
 (0)