Skip to content

Commit

Permalink
feat: enable login app type (#845)
Browse files Browse the repository at this point in the history
  • Loading branch information
tomzemp committed Apr 25, 2024
1 parent 9c9aa17 commit 2586e38
Show file tree
Hide file tree
Showing 18 changed files with 229 additions and 44 deletions.
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,27 @@

* **deps:** Updated major version of UI

# [10.6.0-alpha.3](https://github.com/dhis2/app-platform/compare/v10.6.0-alpha.2...v10.6.0-alpha.3) (2024-03-21)


### Features

* enable publishing login_app apps ([93093ca](https://github.com/dhis2/app-platform/commit/93093ca9ce286801e0c0a9bb421ae847be0fd8e6))

# [10.6.0-alpha.2](https://github.com/dhis2/app-platform/compare/v10.6.0-alpha.1...v10.6.0-alpha.2) (2024-03-20)


### Features

* add redirect to safe login mode for login apps ([#835](https://github.com/dhis2/app-platform/issues/835)) ([ba26ada](https://github.com/dhis2/app-platform/commit/ba26adaab450eaeda19c3b29410275ac563d370b))

# [10.6.0-alpha.1](https://github.com/dhis2/app-platform/compare/v10.5.0...v10.6.0-alpha.1) (2024-03-05)


### Features

* updates for login_app type [LIBS-405] ([#831](https://github.com/dhis2/app-platform/issues/831)) ([0cc2fbd](https://github.com/dhis2/app-platform/commit/0cc2fbd5b633b9b8953ba29d8450f93b0037d458))

# [10.5.0](https://github.com/dhis2/app-platform/compare/v10.4.1...v10.5.0) (2024-02-19)


Expand Down
7 changes: 5 additions & 2 deletions adapter/i18n/en.pot
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ msgstr ""
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
"POT-Creation-Date: 2023-02-08T14:36:41.461Z\n"
"PO-Revision-Date: 2023-02-08T14:36:41.461Z\n"
"POT-Creation-Date: 2024-03-14T15:31:40.141Z\n"
"PO-Revision-Date: 2024-03-14T15:31:40.141Z\n"

msgid "Save your data"
msgstr "Save your data"
Expand Down Expand Up @@ -45,6 +45,9 @@ msgstr "Try again"
msgid "Something went wrong"
msgstr "Something went wrong"

msgid "Redirect to safe login mode"
msgstr "Redirect to safe login mode"

msgid "Hide technical details"
msgstr "Hide technical details"

Expand Down
21 changes: 20 additions & 1 deletion adapter/src/components/ErrorBoundary.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,16 @@ export class ErrorBoundary extends Component {
})
}

handleSafeLoginRedirect = () => {
window.location.href =
this.props.baseURL +
(this.props.baseURL.endsWith('/') ? '' : '/') +
'dhis-web-commons/security/login.action'
}

render() {
const { children, fullscreen, onRetry } = this.props
const { children, fullscreen, onRetry, loginApp, baseURL } = this.props

if (this.state.error) {
if (this.props.plugin) {
return (
Expand All @@ -88,6 +96,15 @@ export class ErrorBoundary extends Component {
<h1 className="message">
{i18n.t('Something went wrong')}
</h1>
{loginApp && baseURL && (
<div className="retry">
<UIButton
onClick={this.handleSafeLoginRedirect}
>
{i18n.t('Redirect to safe login mode')}
</UIButton>
</div>
)}
{onRetry && (
<div className="retry">
<UIButton onClick={onRetry}>
Expand Down Expand Up @@ -141,7 +158,9 @@ export class ErrorBoundary extends Component {

ErrorBoundary.propTypes = {
children: PropTypes.node.isRequired,
baseURL: PropTypes.string,
fullscreen: PropTypes.bool,
loginApp: PropTypes.bool,
plugin: PropTypes.bool,
onPluginError: PropTypes.func,
onRetry: PropTypes.func,
Expand Down
37 changes: 37 additions & 0 deletions adapter/src/components/LoginAppWrapper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import PropTypes from 'prop-types'
import React from 'react'
import { useSystemDefaultLocale } from '../utils/useLocale.js'
import { Alerts } from './Alerts.js'
import { ErrorBoundary } from './ErrorBoundary.js'
import { LoadingMask } from './LoadingMask.js'
import { styles } from './styles/AppWrapper.style.js'

export const LoginAppWrapper = ({ url, children }) => {
const { loading: localeLoading } = useSystemDefaultLocale()
// cannot check current user for a loginApp (no api/me)

if (localeLoading) {
return <LoadingMask />
}

return (
<div className="app-shell-adapter">
<style jsx>{styles}</style>
<div className="app-shell-app">
<ErrorBoundary
onRetry={() => window.location.reload()}
loginApp={true}
baseURL={url}
>
{children}
</ErrorBoundary>
</div>
<Alerts />
</div>
)
}

LoginAppWrapper.propTypes = {
children: PropTypes.node,
url: PropTypes.string,
}
33 changes: 30 additions & 3 deletions adapter/src/components/ServerVersionProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export const ServerVersionProvider = ({
plugin,
parentAlertsAdd,
showAlertsInPlugin,
loginApp,
children,
}) => {
const offlineInterface = useOfflineInterface()
Expand Down Expand Up @@ -103,6 +104,27 @@ export const ServerVersionProvider = ({
? state
: { loading: true, error: undefined, systemInfo: undefined }
)

// version is available from api/loginConfig
if (loginApp) {
const requestLogin = get(`${baseUrl}/api/loginConfig`)
requestLogin
.then((loginConfig) => {
setSystemInfoState({
loading: false,
error: undefined,
systemInfo: { version: loginConfig.apiVersion },
})
})
.catch((e) => {
setSystemInfoState({
loading: false,
error: e,
systemInfo: undefined,
})
})
return
}
const request = get(`${baseUrl}/api/system/info`)
request
.then((systemInfo) => {
Expand All @@ -125,7 +147,7 @@ export const ServerVersionProvider = ({
return () => {
request.abort()
}
}, [appName, baseUrl])
}, [appName, baseUrl, loginApp])

useEffect(() => {
if (pwaEnabled) {
Expand All @@ -137,7 +159,11 @@ export const ServerVersionProvider = ({

// This needs to come before 'loading' case to show modal at correct times
if (systemInfoState.error || baseUrlState.error) {
return <LoginModal appName={appName} baseUrl={baseUrl} />
return !loginApp ? (
<LoginModal appName={appName} baseUrl={baseUrl} />
) : (
<p>Specify DHIS2_BASE_URL environment variable</p>
)
}

if (
Expand All @@ -162,7 +188,7 @@ export const ServerVersionProvider = ({
systemInfo,
pwaEnabled,
}}
offlineInterface={offlineInterface}
offlineInterface={loginApp ? null : offlineInterface}
plugin={plugin}
parentAlertsAdd={parentAlertsAdd}
showAlertsInPlugin={showAlertsInPlugin}
Expand All @@ -177,6 +203,7 @@ ServerVersionProvider.propTypes = {
appVersion: PropTypes.string.isRequired,
apiVersion: PropTypes.number,
children: PropTypes.element,
loginApp: PropTypes.bool,
parentAlertsAdd: PropTypes.func,
plugin: PropTypes.bool,
pwaEnabled: PropTypes.bool,
Expand Down
74 changes: 52 additions & 22 deletions adapter/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import PropTypes from 'prop-types'
import React from 'react'
import { AppWrapper } from './components/AppWrapper.js'
import { ErrorBoundary } from './components/ErrorBoundary.js'
import { LoginAppWrapper } from './components/LoginAppWrapper.js'
import { OfflineInterfaceProvider } from './components/OfflineInterfaceContext.js'
import { PWALoadingBoundary } from './components/PWALoadingBoundary.js'
import { ServerVersionProvider } from './components/ServerVersionProvider.js'
Expand All @@ -19,38 +20,66 @@ const AppAdapter = ({
showAlertsInPlugin,
onPluginError,
clearPluginError,
loginApp,
children,
}) => (
<ErrorBoundary
plugin={plugin}
fullscreen
onRetry={checkForSWUpdateAndReload}
>
<OfflineInterfaceProvider>
<PWALoadingBoundary>
}) => {
if (loginApp) {
return (
<ErrorBoundary
fullscreen
onRetry={() => {
window.location.reload()
}}
plugin={false}
loginApp={true}
baseURL={url}
>
<ServerVersionProvider
appName={appName}
appVersion={appVersion}
url={url}
apiVersion={apiVersion}
pwaEnabled={pwaEnabled}
plugin={plugin}
parentAlertsAdd={parentAlertsAdd}
showAlertsInPlugin={showAlertsInPlugin}
loginApp={loginApp}
plugin={false}
>
<AppWrapper
<LoginAppWrapper url={url}>{children}</LoginAppWrapper>
</ServerVersionProvider>
</ErrorBoundary>
)
}
return (
<ErrorBoundary
plugin={plugin}
fullscreen
onRetry={checkForSWUpdateAndReload}
>
<OfflineInterfaceProvider>
<PWALoadingBoundary>
<ServerVersionProvider
appName={appName}
appVersion={appVersion}
url={url}
apiVersion={apiVersion}
pwaEnabled={pwaEnabled}
plugin={plugin}
onPluginError={onPluginError}
clearPluginError={clearPluginError}
direction={direction}
parentAlertsAdd={parentAlertsAdd}
showAlertsInPlugin={showAlertsInPlugin}
>
{children}
</AppWrapper>
</ServerVersionProvider>
</PWALoadingBoundary>
</OfflineInterfaceProvider>
</ErrorBoundary>
)
<AppWrapper
plugin={plugin}
onPluginError={onPluginError}
clearPluginError={clearPluginError}
direction={direction}
>
{children}
</AppWrapper>
</ServerVersionProvider>
</PWALoadingBoundary>
</OfflineInterfaceProvider>
</ErrorBoundary>
)
}

AppAdapter.propTypes = {
appName: PropTypes.string.isRequired,
Expand All @@ -59,6 +88,7 @@ AppAdapter.propTypes = {
children: PropTypes.element,
clearPluginError: PropTypes.func,
direction: PropTypes.oneOf(['ltr', 'rtl', 'auto']),
loginApp: PropTypes.bool,
parentAlertsAdd: PropTypes.func,
plugin: PropTypes.bool,
pwaEnabled: PropTypes.bool,
Expand Down
30 changes: 29 additions & 1 deletion adapter/src/utils/useLocale.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useDataQuery } from '@dhis2/app-runtime'
import i18n from '@dhis2/d2-i18n'
import { useState, useEffect } from 'react'
import { useState, useEffect, useMemo } from 'react'
import {
setI18nLocale,
parseLocale,
Expand Down Expand Up @@ -56,3 +56,31 @@ export const useCurrentUserLocale = (configDirection) => {

return { loading: loading || !locale, locale, direction }
}

const loginConfigQuery = {
loginConfig: {
resource: 'loginConfig',
},
}

export const useSystemDefaultLocale = () => {
// system language from loginConfiqQuery
const { loading, data, error } = useDataQuery(loginConfigQuery)
// set userSettings to use system locale by default
const localeInformation = useMemo(
() => ({
userSettings: {
keyUiLocale:
data &&
(data?.loginConfig?.uiLocale || window.navigator.language),
},
configDirection: 'auto',
}),
[data]
)
const locale = useLocale(localeInformation)
if (error) {
console.error(error)
}
return { loading: loading || !locale, locale }
}
9 changes: 5 additions & 4 deletions cli/src/commands/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const generateManifests = require('../lib/generateManifests')
const i18n = require('../lib/i18n')
const loadEnvFiles = require('../lib/loadEnvFiles')
const parseConfig = require('../lib/parseConfig')
const { isApp } = require('../lib/parseConfig')
const makePaths = require('../lib/paths')
const makePlugin = require('../lib/plugin')
const { injectPrecacheManifest } = require('../lib/pwa')
Expand Down Expand Up @@ -71,7 +72,7 @@ const handler = async ({
const shell = makeShell({ config, paths })
const plugin = makePlugin({ config, paths })

if (config.type === 'app') {
if (isApp(config.type)) {
setAppParameters(standalone, config)
}

Expand Down Expand Up @@ -106,7 +107,7 @@ const handler = async ({
paths,
})

if (config.type === 'app') {
if (isApp(config.type)) {
reporter.info('Bootstrapping local appShell...')
await shell.bootstrap({ shell: shellSource, force })
}
Expand All @@ -115,7 +116,7 @@ const handler = async ({
`Building ${config.type} ${chalk.bold(config.name)}...`
)

if (config.type === 'app') {
if (isApp(config.type)) {
await compile({
config,
paths,
Expand Down Expand Up @@ -168,7 +169,7 @@ const handler = async ({
}
)

if (config.type === 'app') {
if (isApp(config.type)) {
if (!fs.pathExistsSync(paths.shellBuildOutput)) {
reporter.error('No build output found')
process.exit(1)
Expand Down
Loading

0 comments on commit 2586e38

Please sign in to comment.