Skip to content

Commit

Permalink
adds option to toggle menu in all contexts
Browse files Browse the repository at this point in the history
  • Loading branch information
Elorfin committed Mar 23, 2021
1 parent 9ead6a5 commit 6ceeef4
Show file tree
Hide file tree
Showing 21 changed files with 268 additions and 178 deletions.
34 changes: 23 additions & 11 deletions src/main/app/Resources/modules/data/types/choice/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,24 +38,36 @@ const dataType = {
required: true
}
],
parse: (display, options) => Object.keys(options.choices).find(enumValue => display === enumValue || display === options.choices[enumValue]),
parse: (display, options) => {
if (null !== display) {
return Object.keys(options.choices).find(enumValue => display === enumValue || display === options.choices[enumValue])
}

return null
},
render: (raw, options) => {
if (Array.isArray(raw)) {
return raw.map(value => options.choices[value]).join(', ')
} else {
return options.choices[raw]
if (null !== raw) {
if (Array.isArray(raw)) {
return raw.map(value => options.choices[value]).join(', ')
} else {
return options.choices[raw]
}
}

return null
},
validate: (value, options) => {
const choices = options.choices || {}
if (value) {
const choices = options.choices || {}

if (options.multiple) {
const unknown = differenceBy(value, Object.keys(choices), (selected) => selected+'')
if (0 !== unknown.length) {
if (options.multiple) {
const unknown = differenceBy(value, Object.keys(choices), (selected) => selected+'')
if (0 !== unknown.length) {
return tval('This value is invalid.')
}
} else if (-1 === Object.keys(choices).indexOf(value)) {
return tval('This value is invalid.')
}
} else if (!choices.hasOwnProperty(value)) {
return tval('This value is invalid.')
}
},
components: {
Expand Down
4 changes: 2 additions & 2 deletions src/main/app/Resources/modules/input/components/radios.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,10 @@ const Radios = props => {
key="empty-value"
id={`${props.id}-empty`}
label={props.placeholder || trans('none')}
value={null}
value=""
inline={props.inline}
checked={null === props.value}
onChange={props.onChange}
onChange={() => props.onChange(null)}
/>
}

Expand Down
18 changes: 18 additions & 0 deletions src/main/app/Resources/modules/layout/menu/store/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,21 @@ actions.open = makeActionCreator(MENU_OPEN)
actions.close = makeActionCreator(MENU_CLOSE)
actions.toggle = makeActionCreator(MENU_TOGGLE)
actions.changeSection = makeActionCreator(MENU_CHANGE_SECTION, 'section')


actions.setState = (state = null) => (dispatch) => {
switch (state) {
case 'open':
// force open the menu
dispatch(actions.open())
break

case 'close':
// force close the menu
dispatch(actions.close())
break

default:
// let the menu in its previous state
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import {makeActionCreator} from '#/main/app/store/actions'

import {API_REQUEST} from '#/main/app/api'

import {selectors as configSelectors} from '#/main/app/config/store/selectors'
import {actions as menuActions} from '#/main/app/layout/menu/store/actions'

// actions
export const ADMINISTRATION_LOAD = 'ADMINISTRATION_LOAD'

Expand All @@ -13,10 +15,16 @@ actions.load = makeActionCreator(ADMINISTRATION_LOAD, 'tools')
/**
* Fetch the required data to open administration.
*/
actions.open = () => ({
actions.open = () => (dispatch, getState) => dispatch({
[API_REQUEST]: {
silent: true,
url: ['claro_admin_open'],
success: (response, dispatch) => dispatch(actions.load(response.tools))
success: (response) => {
dispatch(actions.load(response.tools))

// set menu state based on a admin configuration
// TODO : get the value from the open response later
dispatch(menuActions.setState(configSelectors.param(getState(), 'admin.menu', null)))
}
}
})
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import {makeActionCreator} from '#/main/app/store/actions'
import {API_REQUEST} from '#/main/app/api'

import {selectors as configSelectors} from '#/main/app/config/store/selectors'
import {actions as menuActions} from '#/main/app/layout/menu/store/actions'

// actions
export const DESKTOP_LOAD = 'DESKTOP_LOAD'

Expand All @@ -12,16 +15,21 @@ actions.load = makeActionCreator(DESKTOP_LOAD, 'data')
/**
* Fetch the required data to open the current user desktop.
*/
actions.open = () => ({
actions.open = () => (dispatch, getState) => dispatch({
[API_REQUEST]: {
silent: true,
url: ['claro_desktop_open'],
success: (response, dispatch) => dispatch(actions.load(response)),
error: (error, errorStatus, dispatch) => {
success: (response) => {
dispatch(actions.load(response))

// set menu state based on desktop configuration
// TODO : get the value from the open response later
dispatch(menuActions.setState(configSelectors.param(getState(), 'desktop.menu', null)))
},
error: (error, errorStatus) => {
if (403 === errorStatus) {
dispatch(actions.load({}))
}
}
}
})

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import React, {Component} from 'react'
import {PropTypes as T} from 'prop-types'

import {Routes} from '#/main/app/router/components/routes'
Expand All @@ -13,83 +13,80 @@ import {HomeExternalAccount} from '#/main/app/layout/sections/home/components/ex

// TODO : move all security sections in main/authentication

const HomeMain = (props) =>
<Routes
redirect={[
{from: '/', exact: true, to: '/unavailable', disabled: !props.unavailable},
{from: '/home', to: '/unavailable', disabled: !props.unavailable},
{from: '/unavailable', to: '/', disabled: props.unavailable},
class HomeMain extends Component {
componentDidMount() {
this.props.open()
}

{from: '/', exact: true, to: '/login', disabled: props.hasHome || props.authenticated},
{from: '/', exact: true, to: '/home', disabled: props.unavailable || !props.hasHome},
{from: '/', exact: true, to: '/desktop', disabled: props.unavailable || props.hasHome || !props.authenticated},
render() {
return (
<Routes
redirect={[
{from: '/', exact: true, to: '/unavailable', disabled: !this.props.unavailable},
{from: '/home', to: '/unavailable', disabled: !this.props.unavailable},
{from: '/unavailable', to: '/', disabled: this.props.unavailable},

{from: '/login', to: '/', disabled: !props.authenticated}
]}
routes={[
{
path: '/unavailable',
disabled: !props.unavailable,
render: () => {
const Disabled = (
<HomeDisabled
disabled={props.disabled}
maintenance={props.maintenance}
maintenanceMessage={props.maintenanceMessage}
authenticated={props.authenticated}
restrictions={props.restrictions}
reactivate={props.reactivate}
/>
)
{from: '/', exact: true, to: '/login', disabled: this.props.hasHome || this.props.authenticated},
{from: '/', exact: true, to: '/home', disabled: this.props.unavailable || !this.props.hasHome},
{from: '/', exact: true, to: '/desktop', disabled: this.props.unavailable || this.props.hasHome || !this.props.authenticated},

return Disabled
}
}, {
path: '/reset_password',
disabled: props.authenticated || !props.changePassword,
component: SendPassword
}, {
path: '/newpassword/:hash',
component: NewPassword
}, {
path: '/login',
disabled: props.authenticated,
component: HomeLogin
}, {
path: '/registration',
disabled: props.unavailable || !props.selfRegistration || props.authenticated,
component: HomeRegistration
}, { // TODO : disable if no sso
path: '/external/:app',
render: (routeProps) => {
const LinkAccount = (
<HomeExternalAccount
isAuthenticated={props.authenticated}
selfRegistration={props.selfRegistration}
serviceName={routeProps.match.params.app}
linkExternalAccount={props.linkExternalAccount}
/>
)

return LinkAccount
}
}, {
path: '/home',
disabled: props.unavailable || !props.hasHome,
onEnter: () => props.openHome(props.homeType, props.homeData),
render: () => {
const Home = (
<HomeContent
type={props.homeType}
content={props.homeData}
/>
)

return Home
}
}
]}
/>
{from: '/login', to: '/', disabled: !this.props.authenticated}
]}
routes={[
{
path: '/unavailable',
disabled: !this.props.unavailable,
render: () => (
<HomeDisabled
disabled={this.props.disabled}
maintenance={this.props.maintenance}
maintenanceMessage={this.props.maintenanceMessage}
authenticated={this.props.authenticated}
restrictions={this.props.restrictions}
reactivate={this.props.reactivate}
/>
)
}, {
path: '/reset_password',
disabled: this.props.authenticated || !this.props.changePassword,
component: SendPassword
}, {
path: '/newpassword/:hash',
component: NewPassword
}, {
path: '/login',
disabled: this.props.authenticated,
component: HomeLogin
}, {
path: '/registration',
disabled: this.props.unavailable || !this.props.selfRegistration || this.props.authenticated,
component: HomeRegistration
}, { // TODO : disable if no sso
path: '/external/:app',
render: (routeProps) => (
<HomeExternalAccount
isAuthenticated={this.props.authenticated}
selfRegistration={this.props.selfRegistration}
serviceName={routeProps.match.params.app}
linkExternalAccount={this.props.linkExternalAccount}
/>
)
}, {
path: '/home',
disabled: this.props.unavailable || !this.props.hasHome,
onEnter: () => this.props.openHome(this.props.homeType, this.props.homeData),
render: () => (
<HomeContent
type={this.props.homeType}
content={this.props.homeData}
/>
)
}
]}
/>
)
}
}

HomeMain.propTypes = {
unavailable: T.bool.isRequired,
Expand All @@ -102,6 +99,7 @@ HomeMain.propTypes = {
hasHome: T.bool.isRequired,
homeType: T.string.isRequired,
homeData: T.string,
open: T.func.isRequired,
openHome: T.func.isRequired,
linkExternalAccount: T.func.isRequired,
restrictions: T.shape({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {actions as layoutActions, selectors as layoutSelectors} from '#/main/app
import {actions as toolActions} from '#/main/core/tool/store'

import {HomeMain as HomeMainComponent} from '#/main/app/layout/sections/home/components/main'
import {selectors} from '#/main/app/layout/sections/home/store'
import {actions, selectors} from '#/main/app/layout/sections/home/store'
import {constants} from '#/main/app/layout/sections/home/constants'

const HomeMain = connect(
Expand All @@ -25,6 +25,9 @@ const HomeMain = connect(
changePassword: configSelectors.param(state, 'authentication.changePassword')
}),
(dispatch) => ({
open() {
dispatch(actions.open())
},
openHome(type, data) {
if (constants.HOME_TYPE_URL === type) {
window.location.replace(data)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

import {selectors as configSelectors} from '#/main/app/config/store/selectors'
import {actions as menuActions} from '#/main/app/layout/menu/store/actions'

export const actions = {}

actions.open = () => (dispatch, getState) => {
// set menu state based on home configuration
dispatch(menuActions.setState(configSelectors.param(getState(), 'home.menu', null)))
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@

import {actions} from '#/main/app/layout/sections/home/store/actions'
import {selectors} from '#/main/app/layout/sections/home/store/selectors'

export {
actions,
selectors
}
}
2 changes: 2 additions & 0 deletions src/main/core/API/Serializer/Platform/ClientSerializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,11 @@ public function serialize()
'desktop' => [ // TODO : find a better way to store and expose this
'defaultTool' => $this->config->getParameter('desktop.default_tool'),
'showProgression' => $this->config->getParameter('desktop.show_progression'),
'menu' => $this->config->getParameter('desktop.menu'),
],
'admin' => [ // TODO : find a better way to store and expose this
'defaultTool' => $this->config->getParameter('admin.default_tool'),
'menu' => $this->config->getParameter('admin.menu'),
],
'privacy' => $this->config->getParameter('privacy'),
'pricing' => $this->config->getParameter('pricing'),
Expand Down

0 comments on commit 6ceeef4

Please sign in to comment.