diff --git a/src/browser/modules/Frame/FrameSuccess.jsx b/src/browser/modules/Frame/FrameSuccess.jsx
index b3112cc643a..60e73beaee1 100644
--- a/src/browser/modules/Frame/FrameSuccess.jsx
+++ b/src/browser/modules/Frame/FrameSuccess.jsx
@@ -20,7 +20,11 @@
import React from 'react'
const FrameSuccess = props => {
if (!props || !props.message) return null
- return {props.message}
+ return (
+
+ {props.message}
+
+ )
}
export default FrameSuccess
diff --git a/src/browser/modules/Stream/Auth/ConnectForm.tsx b/src/browser/modules/Stream/Auth/ConnectForm.tsx
index 9de13413c42..b51f2950d53 100644
--- a/src/browser/modules/Stream/Auth/ConnectForm.tsx
+++ b/src/browser/modules/Stream/Auth/ConnectForm.tsx
@@ -187,7 +187,6 @@ export default function ConnectForm(props: ConnectFormProps): JSX.Element {
data-testid="username"
onChange={props.onUsernameChange}
defaultValue={props.username}
- required
/>
@@ -202,7 +201,6 @@ export default function ConnectForm(props: ConnectFormProps): JSX.Element {
onChange={props.onPasswordChange}
defaultValue={props.password}
type="password"
- required
/>
diff --git a/src/browser/modules/User/UserAdd.jsx b/src/browser/modules/User/UserAdd.jsx
index bfa67f98c88..75f85196f13 100644
--- a/src/browser/modules/User/UserAdd.jsx
+++ b/src/browser/modules/User/UserAdd.jsx
@@ -32,7 +32,7 @@ import {
createDatabaseUser,
addRoleToUser
} from 'shared/modules/cypher/boltUserHelper'
-import { CYPHER_REQUEST } from 'shared/modules/cypher/cypherDuck'
+import { ROUTED_CYPHER_WRITE_REQUEST } from 'shared/modules/cypher/cypherDuck'
import RolesSelector from './RolesSelector'
import FrameTemplate from 'browser/modules/Frame/FrameTemplate'
@@ -111,7 +111,7 @@ export class UserAdd extends Component {
this.state.roles.forEach(role => {
this.props.bus &&
this.props.bus.self(
- CYPHER_REQUEST,
+ ROUTED_CYPHER_WRITE_REQUEST,
{
query: addRoleToUser(
this.state.username,
@@ -149,7 +149,7 @@ export class UserAdd extends Component {
getRoles() {
this.props.bus &&
this.props.bus.self(
- CYPHER_REQUEST,
+ ROUTED_CYPHER_WRITE_REQUEST,
{
query: listRolesQuery(Boolean(this.props.useSystemDb)),
queryType: NEO4J_BROWSER_USER_ACTION_QUERY,
@@ -174,7 +174,9 @@ export class UserAdd extends Component {
)
}
- submit() {
+ submit = event => {
+ event.preventDefault()
+
this.setState({ isLoading: true, success: null, errors: null })
const errors = []
if (!this.state.username) errors.push('Missing username')
@@ -193,7 +195,7 @@ export class UserAdd extends Component {
createUser() {
this.props.bus &&
this.props.bus.self(
- CYPHER_REQUEST,
+ ROUTED_CYPHER_WRITE_REQUEST,
{
query: createDatabaseUser(
this.state,
@@ -297,7 +299,7 @@ export class UserAdd extends Component {
/>
)
frameContents = (
-
+
Username
-
+
@@ -402,9 +400,4 @@ const mapStateToProps = state => {
}
}
-export default withBus(
- connect(
- mapStateToProps,
- null
- )(UserAdd)
-)
+export default withBus(connect(mapStateToProps, null)(UserAdd))
diff --git a/src/browser/modules/User/UserAdd.test.js b/src/browser/modules/User/UserAdd.test.js
index 11fbc5d099f..a1cc4d0be23 100644
--- a/src/browser/modules/User/UserAdd.test.js
+++ b/src/browser/modules/User/UserAdd.test.js
@@ -23,7 +23,7 @@ import React from 'react'
import { createBus } from 'suber'
import { UserAdd } from './UserAdd'
-import { CYPHER_REQUEST } from 'shared/modules/cypher/cypherDuck'
+import { ROUTED_CYPHER_WRITE_REQUEST } from 'shared/modules/cypher/cypherDuck'
import { listRolesQuery } from 'shared/modules/cypher/boltUserHelper'
// Stubbing out title bar as it depends on store
@@ -41,7 +41,7 @@ describe('', () => {
}
const busCallback = jest.fn()
- bus.one(CYPHER_REQUEST, busCallback)
+ bus.one(ROUTED_CYPHER_WRITE_REQUEST, busCallback)
render()
diff --git a/src/browser/modules/User/UserList.jsx b/src/browser/modules/User/UserList.jsx
index b721eae6d99..bf7629d290e 100644
--- a/src/browser/modules/User/UserList.jsx
+++ b/src/browser/modules/User/UserList.jsx
@@ -29,7 +29,7 @@ import {
} from 'shared/modules/cypher/boltUserHelper'
import UserInformation from './UserInformation'
import bolt from 'services/bolt/bolt'
-import { CYPHER_REQUEST } from 'shared/modules/cypher/cypherDuck'
+import { ROUTED_CYPHER_WRITE_REQUEST } from 'shared/modules/cypher/cypherDuck'
import { StyledLink } from 'browser-components/buttons'
import { StyledTable, StyledTh } from 'browser-components/DataTables'
import { StyledButtonContainer } from './styled'
@@ -100,7 +100,7 @@ export class UserList extends Component {
getUserList() {
this.props.bus.self(
- CYPHER_REQUEST,
+ ROUTED_CYPHER_WRITE_REQUEST,
{
query: listUsersQuery(Boolean(this.props.useSystemDb)),
queryType: NEO4J_BROWSER_USER_ACTION_QUERY,
@@ -119,7 +119,7 @@ export class UserList extends Component {
getRoles() {
this.props.bus.self(
- CYPHER_REQUEST,
+ ROUTED_CYPHER_WRITE_REQUEST,
{
query: listRolesQuery(Boolean(this.props.useSystemDb)),
queryType: NEO4J_BROWSER_USER_ACTION_QUERY,
diff --git a/src/browser/modules/User/UserList.test.js b/src/browser/modules/User/UserList.test.js
index 9902ed41802..d77d9b319e8 100644
--- a/src/browser/modules/User/UserList.test.js
+++ b/src/browser/modules/User/UserList.test.js
@@ -23,7 +23,7 @@ import React from 'react'
import { createBus } from 'suber'
import { UserList } from './UserList'
-import { CYPHER_REQUEST } from 'shared/modules/cypher/cypherDuck'
+import { ROUTED_CYPHER_WRITE_REQUEST } from 'shared/modules/cypher/cypherDuck'
import {
listRolesQuery,
listUsersQuery
@@ -44,7 +44,7 @@ describe('', () => {
}
const busCallback = jest.fn()
- bus.take(CYPHER_REQUEST, busCallback)
+ bus.take(ROUTED_CYPHER_WRITE_REQUEST, busCallback)
render()
@@ -68,7 +68,7 @@ describe('', () => {
}
const busCallback = jest.fn()
- bus.take(CYPHER_REQUEST, busCallback)
+ bus.take(ROUTED_CYPHER_WRITE_REQUEST, busCallback)
render()
diff --git a/src/shared/modules/cypher/cypherDuck.js b/src/shared/modules/cypher/cypherDuck.js
index 9d5dcf3d692..f8e831adece 100644
--- a/src/shared/modules/cypher/cypherDuck.js
+++ b/src/shared/modules/cypher/cypherDuck.js
@@ -42,6 +42,7 @@ import {
const NAME = 'cypher'
export const CYPHER_REQUEST = `${NAME}/REQUEST`
+export const ROUTED_CYPHER_WRITE_REQUEST = `${NAME}/ROUTED_WRITE_REQUEST`
export const AD_HOC_CYPHER_REQUEST = `${NAME}/AD_HOC_REQUEST`
export const CLUSTER_CYPHER_REQUEST = `${NAME}/CLUSTER_REQUEST`
export const FORCE_CHANGE_PASSWORD = `${NAME}/FORCE_CHANGE_PASSWORD`
@@ -117,6 +118,35 @@ export const cypherRequestEpic = (some$, store) =>
}))
})
+export const routedCypherRequestEpic = (some$, store) =>
+ some$.ofType(ROUTED_CYPHER_WRITE_REQUEST).mergeMap(action => {
+ if (!action.$$responseChannel) return Rx.Observable.of(null)
+
+ const [id, promise] = bolt.routedWriteTransaction(
+ action.query,
+ action.params,
+ {
+ useCypherThread: shouldUseCypherThread(store.getState()),
+ ...getUserTxMetadata(action.queryType || null)({
+ hasServerSupport: canSendTxMetadata(store.getState())
+ }),
+ cancelable: true,
+ useDb: action.useDb
+ }
+ )
+ return promise
+ .then(result => ({
+ type: action.$$responseChannel,
+ success: true,
+ result
+ }))
+ .catch(error => ({
+ type: action.$$responseChannel,
+ success: false,
+ error
+ }))
+ })
+
export const adHocCypherRequestEpic = (some$, store) =>
some$.ofType(AD_HOC_CYPHER_REQUEST).mergeMap(action => {
const connection = getActiveConnectionData(store.getState())
diff --git a/src/shared/rootEpic.js b/src/shared/rootEpic.js
index f3a737aa595..02c5af45bfe 100644
--- a/src/shared/rootEpic.js
+++ b/src/shared/rootEpic.js
@@ -58,6 +58,7 @@ import { clearLocalstorageEpic } from './modules/localstorage/localstorageDuck'
import { populateEditorFromUrlEpic } from './modules/editor/editorDuck'
import {
adHocCypherRequestEpic,
+ routedCypherRequestEpic,
cypherRequestEpic,
clusterCypherRequestEpic,
handleForcePasswordChangeEpic
@@ -121,6 +122,7 @@ export default combineEpics(
injectDiscoveryEpic,
populateEditorFromUrlEpic,
adHocCypherRequestEpic,
+ routedCypherRequestEpic,
cypherRequestEpic,
clusterCypherRequestEpic,
clearLocalstorageEpic,