Skip to content

Commit

Permalink
Polyglot Phrases Implementation (#96)
Browse files Browse the repository at this point in the history
* Just some examples of polyglot at work

* Test changes for internationalizaton

* Internationalization - replaced all plain string occurrences on the website with polyglot phrases

* Delete unnecessary comments and tests

* Delete localization folder

* Completed suggested changes for PR - Polyglot Phrases Implementation

* Fix HeaderTabButton onSelected

* Added requested changes by David

Co-authored-by: dotasek <[email protected]>
  • Loading branch information
Hankych and dotasek authored Oct 18, 2022
1 parent 32cbbb1 commit 2d38521
Show file tree
Hide file tree
Showing 26 changed files with 209 additions and 123 deletions.
3 changes: 0 additions & 3 deletions localization/EN-US.json

This file was deleted.

3 changes: 0 additions & 3 deletions localization/ES-MX.json

This file was deleted.

65 changes: 64 additions & 1 deletion src/commonMain/resources/polyglot/en_US.json
Original file line number Diff line number Diff line change
@@ -1 +1,64 @@
{"Validate": "Validate", "Options": "Options"}
{
"validate_heading" : "Validate",
"appscreen_validator_major" : "Validate Resources",
"appscreen_validator_minor" : "Manually enter, or upload resources for validation.",
"enter_resources_heading" : "Enter Resource",
"manual_entry_place_holder" : "Enter Resource Manually...",
"manual_entry_title" : "Code",
"manual_entry_error" : "Please enter something to validate.",
"manual_entry_cannot_parse_exception" : "Cannot parse entered text as valid JSON/XML.",
"validate_button" : "Validate",
"upload_resources_heading" : "Upload Resources",
"upload_files_title" : "Uploaded Files",
"upload_button" : "Upload",
"upload_entry_view" : "View",
"upload_entry_delete" : "Delete",
"options_heading" : "Options",
"appscreen_options_major" : "Validation Options",
"appscreen_options_minor" : "Modify setting for validating resources.",
"options_flags_title" : "Flags",
"options_flags_1_title" : "Native Validation (doNative)",
"options_flags_1_description" : "By default, the validation engine only validates using the FHIR structures and profiles. The publication processes also generate a variety of xml, json and RDF schemas. You can ask the validator to validate against these as well using this option. Note that there is nothing in these schemas that is not validated directly by the engine itself anyway, so the main use for this is to see the kind of errors that would be reported from these schemas by other software.",
"options_flags_2_title" : "Must Support (hintAboutMustSupport)",
"options_flags_2_description" : "In some cases (e.g. when creating examples for implementation guides or when checking for potential interoperability issues with a new communication partner), it can be useful to know when data elements are present in an instance when those elements are not \"mustSupport\" in the profile(s) the instance is being validated against. Identifying situations where this occurs might drive a change to the profile or cause a designer to drop an element from the instance. In other cases, the presence of the element can be fine and the information message ignored.",
"options_flags_3_title" : "Assume Valid Rest References (assumeValidRestReferences)",
"options_flags_3_description" : "If the validator can't fetch target resources, it can at least be instructed validate that the target resource is correct. For instance, if the allowed target types are (Patient or RelatedPerson), and the reference is Group/12345, then this would be usually be an error. However this is not actually explicitly stated in the FHIR specification - a reference could be to http://some.server/somewhere - it doesn't need to look like a valid FHIR RESTful reference. In fact, it's not an error even if it happens to. So by default, the validator can assume nothing about the type of resource from the content of the reference itself. However most implementers do follow those rules - a reference to either Group/12345 or http://some-server/somwhere/Group/12345 is definitely to a Group resource. (and it's definitely recommended to follow these rules). The flag assumeValidRestReferences instructs the validator to use the type found in references that look like valid RESTful URLs when validating the type of the reference.",
"options_flags_4_title" : "Extensible Binding Warnings (noExtensibleBindingWarnings)",
"options_flags_4_description" : "When the validator encounters a code that is not part of an extensible binding, it adds a warning to suggest that the code be reviewed. The validator can't determine whether the meaning of the code makes it an inappropriate extension, or not; this requires human review. Hence, the warning. But the code may be valid - that's why extensible is defined - so in some operational uses of the validator, it is appropriate to turn these warnings off",
"options_flags_5_title" : "Show Times (showTimes)",
"options_flags_5_description" : "When the validator encounters a code that is not part of an extensible binding, it adds a warning to suggest that the code be reviewed. The validator can't determine whether the meaning of the code makes it an inappropriate extension, or not; this requires human review. Hence, the warning. But the code may be valid - that's why extensible is defined - so in some operational uses of the validator, it is appropriate to turn these warnings off",
"options_flags_6_title" : "Allow Example URLs (allow-example-urls)",
"options_flags_6_description" : "Some of the examples in the FHIR specification have URLs in them that refer to example.org. By default, the validator will always mark any such references as an error, but this can be overridden with this parameter.",
"options_fhir_title" : "FHIR version",
"options_default_label" : "Version",
"options_fhir_description" : "The validator checks the resource against the base specification. By default, this is specification version 4.0.1.",
"options_ig_title" : "Implementation Guides",
"options_ig_description_1" : "You can validate against one or more published implementation guides. Select IGs using the dropdown menus below and click the ",
"options_ig_description_2" : "Add",
"options_ig_description_3" : " button to include them in your validation.",
"options_ig_dropdown" : "Select IG",
"options_ig_dropdown_hint" : "Search IGS...",
"options_ig_version_dropdown_default" : "No Compatible versions",
"options_ig_version_dropdown_hint" : "Select IG version",
"options_ig_add" : "Add",
"options_ig_selected" : "Selected IGs",
"options_ig_not_supported" : "IG not supported for FHIR version",
"options_settings_title" : "Other Settings",
"options_settings_snomed_title" : "Select SNOMED Version",
"options_settings_snomed_description" : "You can specify which edition of SNOMED CT for the terminology server to use when doing SNOMED CT Validation.",
"options_settings_tm_title" : "Set Terminology Server",
"options_settings_tm_description" : "The validation engine uses a terminology server to validate codes from large external terminologies such as SNOMED CT, LOINC, RxNorm, etc. By default, the terminology server used is tx.fhir.org, which supports most of these terminologies. If you want to use another terminology server, you can specify one here. As a warning, the server will check that the CapabilityStatement of the provided server is set correctly.",
"options_settings_tm_verify" : "Verify",
"options_settings_tm_success" : "Terminology server validated successfully!",
"options_settings_tm_error" : "Terminology server could not be validated!",
"footer_running_version" : "running validator v",
"footer_github" : "view project on github",
"footer_create_issue" : "log an issue with the team",
"footer_download_cli" : "download the latest cli",
"footer_doc" : "view the validator documentation",
"validation_results" : "Results",
"validation_fatals" : "Fatals",
"validation_errors" : "Errors",
"validation_warnings" : "Warnings",
"validation_info" : "Information"
}
27 changes: 19 additions & 8 deletions src/jsMain/kotlin/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import ui.components.footer.footer
import ui.components.header.HeaderStyle
import ui.components.main.sectionTitle
import ui.components.tabs.tabLayout
import kotlinx.browser.window

external interface AppProps : Props {
var appScreen: AppScreen
Expand All @@ -23,6 +24,14 @@ val mainScope = MainScope()

class App(props : AppProps) : RComponent<AppProps, State>() {
init {
/*
// TODO : Get actual locale of the user's browswer
console.log("LANGUAGE:")
for (item in window.navigator.languages) {
console.log(item)
}
console.log("LANGUAGE LANGUAGE LANGUAGE: " + window.navigator.language)
*/
props.fetchPolyglot("en_US")
}
override fun RBuilder.render() {
Expand All @@ -42,23 +51,25 @@ class App(props : AppProps) : RComponent<AppProps, State>() {
when (props.appScreen) {
AppScreen.VALIDATOR -> {
sectionTitle {
// TODO once localization is updated
// majorText = props.polyglot.t("heading_validate")
majorText = "Validate Resources"
minorText = "Manually enter, or upload resources for validation."
majorText = props.polyglot.t("appscreen_validator_major")
minorText = props.polyglot.t("appscreen_validator_minor")
}
tabLayout {
polyglot = props.polyglot
}
tabLayout {}
}
AppScreen.SETTINGS -> {
sectionTitle {
majorText = "Validation Options"
minorText = "Modify setting for validating resources."
majorText = props.polyglot.t("appscreen_options_major")
minorText = props.polyglot.t("appscreen_options_minor")
}
optionsPage {}
}
}
}
footer { }
footer {
polyglot = props.polyglot
}
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/jsMain/kotlin/model/AppScreen.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package model

enum class AppScreen(val display: String) {
VALIDATOR("Validate"),
SETTINGS("Options");
enum class AppScreen(val polyglotKey: String) {
VALIDATOR("validate_heading"),
SETTINGS("options_heading");

companion object {
private val map = AppScreen.values().associateBy(AppScreen::display)
private val map = AppScreen.values().associateBy(AppScreen::name)
fun fromDisplay(type: String) = map[type]
}
}
3 changes: 3 additions & 0 deletions src/jsMain/kotlin/reactredux/containers/FileUploadTab.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package reactredux.containers

import Polyglot
import model.CliContext
import model.FileInfo
import model.ValidationOutcome
Expand All @@ -18,6 +19,7 @@ private interface FileUploadTabProps : Props {
var uploadedFiles: List<ValidationOutcome>
var cliContext: CliContext
var sessionId: String
var polyglot: Polyglot
}

private interface FileUploadTabDispatchProps : Props {
Expand All @@ -34,6 +36,7 @@ val fileUploadTab: ComponentClass<Props> =
uploadedFiles = state.uploadedResourceSlice.uploadedFiles
cliContext = state.validationContextSlice.cliContext
sessionId = state.validationSessionSlice.sessionId
polyglot = state.localizationSlice.polyglotInstance
},
{ dispatch, _ ->
deleteFile = { dispatch(UploadedResourceSlice.RemoveFile(it)) }
Expand Down
3 changes: 3 additions & 0 deletions src/jsMain/kotlin/reactredux/containers/OptionsPage.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package reactredux.containers

import Polyglot
import model.CliContext
import model.PackageInfo
import react.ComponentClass
Expand All @@ -16,6 +17,7 @@ import ui.components.options.OptionsPageProps
private interface OptionsPageStateProps : Props {
var cliContext: CliContext
var selectedIgPackageInfo: Set<PackageInfo>
var polyglot: Polyglot
}

private interface OptionsPageDispatchProps : Props {
Expand All @@ -28,6 +30,7 @@ val optionsPage: ComponentClass<Props> =
{ state, _ ->
cliContext = state.validationContextSlice.cliContext
selectedIgPackageInfo = state.validationContextSlice.selectedIgPackageInfo
polyglot = state.localizationSlice.polyglotInstance
},
{ dispatch, _ ->
updateCliContext = {
Expand Down
10 changes: 5 additions & 5 deletions src/jsMain/kotlin/ui/components/footer/Footer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class Footer : RComponent<FooterProps, FooterState>() {
css {
+FooterStyle.footerTitleSmall
}
+"running validator v${state.validatorVersion}"
+ (props.polyglot.t("footer_running_version") + state.validatorVersion)
}
}
styledDiv {
Expand All @@ -64,18 +64,18 @@ class Footer : RComponent<FooterProps, FooterState>() {
footerLineItem {
href = "https://github.com/hapifhir/org.hl7.fhir.validator-wrapper"
icon = "images/github_white.png"
label = "view project on github"
label = props.polyglot.t("footer_github")
}
footerLineItem {
href = "https://github.com/hapifhir/org.hl7.fhir.validator-wrapper/issues/new/choose"
icon = "images/bug_report_white.png"
label = "log an issue with the team"
label = props.polyglot.t("footer_create_issue")
}
footerLineItem {
href =
"https://github.com/hapifhir/org.hl7.fhir.validator-wrapper/releases/latest/download/validator_cli.jar"
icon = "images/download_white.png"
label = "download the latest cli"
label = props.polyglot.t("footer_download_cli")
}
}
styledDiv {
Expand All @@ -85,7 +85,7 @@ class Footer : RComponent<FooterProps, FooterState>() {
footerLineItem {
href = "https://confluence.hl7.org/display/FHIR/Using+the+FHIR+Validator"
icon = "images/documentation_white.png"
label = "view the validator documentation"
label = props.polyglot.t("footer_doc")
}
}
}
Expand Down
15 changes: 7 additions & 8 deletions src/jsMain/kotlin/ui/components/header/Header.kt
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,6 @@ class Header (props : HeaderProps): RComponent<HeaderProps, HeaderState>(), Even
}
}




override fun RBuilder.render() {
styledDiv {
css {
Expand All @@ -86,10 +83,11 @@ class Header (props : HeaderProps): RComponent<HeaderProps, HeaderState>(), Even
}
AppScreen.values().forEach { screen ->
headerTabButton {
label = props.polyglot.t(screen.display)
name = screen.name
label = props.polyglot.t(screen.polyglotKey)
selected = props.appScreen == screen
onSelected = { buttonLabel ->
AppScreen.fromDisplay(buttonLabel)?.let { it -> props.setScreen(it) }
onSelected = { buttonName ->
AppScreen.fromDisplay(buttonName)?.let { it -> props.setScreen(it) }
}
}
}
Expand All @@ -111,7 +109,8 @@ class Header (props : HeaderProps): RComponent<HeaderProps, HeaderState>(), Even
label = "packages2.fhir.org"
status = state.packageServerState
}
/* TODO LOCALIZATION WIDGET
// TODO LOCALIZATION WIDGET
/*
textButton {
textColor = SUCCESS_GREEN
active = true
Expand All @@ -120,7 +119,7 @@ class Header (props : HeaderProps): RComponent<HeaderProps, HeaderState>(), Even
props.fetchPolyglot("jp")
}
}
*/
*/
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/jsMain/kotlin/ui/components/header/HeaderTabButton.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import styled.styledSpan

external interface HeaderTabButtonProps : Props {
var selected: Boolean
var name : String
var label: String
var onSelected: (String) -> Unit
}
Expand All @@ -33,7 +34,7 @@ class HeaderTabButton : RComponent<HeaderTabButtonProps, HeaderTabButtonState>()
}
attrs {
onClickFunction = {
props.onSelected(props.label)
props.onSelected(props.name)
}
}
styledDiv {
Expand Down
4 changes: 3 additions & 1 deletion src/jsMain/kotlin/ui/components/options/IgDisplay.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package ui.components.options

import Polyglot
import css.const.*
import css.text.TextStyle
import kotlinx.css.*
Expand All @@ -14,6 +15,7 @@ import styled.*
external interface IgDisplayProps : Props {
var fhirVersion: String
var packageInfo: PackageInfo
var polyglot: Polyglot
var onDelete: () -> Unit
}

Expand All @@ -34,7 +36,7 @@ class IgDisplay : RComponent<IgDisplayProps, State>() {
}
if (!props.packageInfo.fhirVersionMatches(props.fhirVersion)) {
attrs {
title = "IG not supported for FHIR version ${props.fhirVersion}"
title = props.polyglot.t("options_ig_not_supported") + " ${props.fhirVersion}"
}
}
styledSpan {
Expand Down
Loading

0 comments on commit 2d38521

Please sign in to comment.