parent
4349911076
commit
2b5f7dc8de
@ -36,6 +36,8 @@ const messages = {
|
|||||||
filterSyntaxLinkTooltip: 'Explore the search syntax in the documentation',
|
filterSyntaxLinkTooltip: 'Explore the search syntax in the documentation',
|
||||||
filterVifsOnlyConnected: 'Connected VIFs',
|
filterVifsOnlyConnected: 'Connected VIFs',
|
||||||
filterVifsOnlyDisconnected: 'Disconnected VIFs',
|
filterVifsOnlyDisconnected: 'Disconnected VIFs',
|
||||||
|
filterRemotesOnlyConnected: 'Connected remotes',
|
||||||
|
filterRemotesOnlyDisconnected: 'Disconnected remotes',
|
||||||
|
|
||||||
// ----- Copiable component -----
|
// ----- Copiable component -----
|
||||||
copyToClipboard: 'Copy to clipboard',
|
copyToClipboard: 'Copy to clipboard',
|
||||||
@ -359,16 +361,17 @@ const messages = {
|
|||||||
remoteConnected: 'Connected',
|
remoteConnected: 'Connected',
|
||||||
remoteDisconnected: 'Disconnected',
|
remoteDisconnected: 'Disconnected',
|
||||||
remoteDeleteTip: 'Delete',
|
remoteDeleteTip: 'Delete',
|
||||||
|
remoteDeleteSelected: 'Delete selected remotes',
|
||||||
remoteNamePlaceHolder: 'remote name *',
|
remoteNamePlaceHolder: 'remote name *',
|
||||||
remoteMyNamePlaceHolder: 'Name *',
|
remoteMyNamePlaceHolder: 'Name *',
|
||||||
remoteLocalPlaceHolderPath: '/path/to/backup',
|
remoteLocalPlaceHolderPath: '/path/to/backup',
|
||||||
remoteNfsPlaceHolderHost: 'host *',
|
remoteNfsPlaceHolderHost: 'host *',
|
||||||
remoteNfsPlaceHolderPath: 'path/to/backup',
|
remoteNfsPlaceHolderPath: 'path/to/backup',
|
||||||
remoteSmbPlaceHolderRemotePath: 'subfolder [path\\to\\backup]',
|
remoteSmbPlaceHolderRemotePath: 'subfolder [path\\\\to\\\\backup]',
|
||||||
remoteSmbPlaceHolderUsername: 'Username',
|
remoteSmbPlaceHolderUsername: 'Username',
|
||||||
remoteSmbPlaceHolderPassword: 'Password',
|
remoteSmbPlaceHolderPassword: 'Password',
|
||||||
remoteSmbPlaceHolderDomain: 'Domain',
|
remoteSmbPlaceHolderDomain: 'Domain',
|
||||||
remoteSmbPlaceHolderAddressShare: '<address>\\<share> *',
|
remoteSmbPlaceHolderAddressShare: '<address>\\\\<share> *',
|
||||||
remotePlaceHolderPassword: 'password(fill to edit)',
|
remotePlaceHolderPassword: 'password(fill to edit)',
|
||||||
|
|
||||||
// ------ New Storage -----
|
// ------ New Storage -----
|
||||||
@ -1238,6 +1241,9 @@ const messages = {
|
|||||||
'Delete schedule{nSchedules, plural, one {} other {s}}',
|
'Delete schedule{nSchedules, plural, one {} other {s}}',
|
||||||
deleteSchedulesModalMessage:
|
deleteSchedulesModalMessage:
|
||||||
'Are you sure you want to delete {nSchedules, number} schedule{nSchedules, plural, one {} other {s}}?',
|
'Are you sure you want to delete {nSchedules, number} schedule{nSchedules, plural, one {} other {s}}?',
|
||||||
|
deleteRemotesModalTitle: 'Delete remote{nRemotes, plural, one {} other {s}}',
|
||||||
|
deleteRemotesModalMessage:
|
||||||
|
'Are you sure you want to delete {nRemotes, number} remote{nRemotes, plural, one {} other {s}}?',
|
||||||
revertVmModalTitle: 'Revert your VM',
|
revertVmModalTitle: 'Revert your VM',
|
||||||
deleteVifsModalTitle: 'Delete VIF{nVifs, plural, one {} other {s}}',
|
deleteVifsModalTitle: 'Delete VIF{nVifs, plural, one {} other {s}}',
|
||||||
deleteVifsModalMessage:
|
deleteVifsModalMessage:
|
||||||
|
@ -1659,6 +1659,20 @@ export const deleteRemote = remote =>
|
|||||||
subscribeRemotes.forceRefresh
|
subscribeRemotes.forceRefresh
|
||||||
)
|
)
|
||||||
|
|
||||||
|
export const deleteRemotes = remotes =>
|
||||||
|
confirm({
|
||||||
|
title: _('deleteRemotesModalTitle', { nRemotes: remotes.length }),
|
||||||
|
body: _('deleteRemotesModalMessage', { nRemotes: remotes.length }),
|
||||||
|
}).then(
|
||||||
|
() =>
|
||||||
|
Promise.all(
|
||||||
|
map(remotes, remote =>
|
||||||
|
_call('remote.delete', { id: resolveId(remote) })
|
||||||
|
)
|
||||||
|
)::tap(subscribeRemotes.forceRefresh),
|
||||||
|
noop
|
||||||
|
)
|
||||||
|
|
||||||
export const enableRemote = remote =>
|
export const enableRemote = remote =>
|
||||||
_call('remote.set', { id: resolveId(remote), enabled: true })::tap(
|
_call('remote.set', { id: resolveId(remote), enabled: true })::tap(
|
||||||
subscribeRemotes.forceRefresh
|
subscribeRemotes.forceRefresh
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import _, { messages } from 'intl'
|
import _, { messages } from 'intl'
|
||||||
import ActionButton from 'action-button'
|
import ActionButton from 'action-button'
|
||||||
import ActionRowButton from 'action-row-button'
|
|
||||||
import filter from 'lodash/filter'
|
import filter from 'lodash/filter'
|
||||||
import Icon from 'icon'
|
import Icon from 'icon'
|
||||||
import isEmpty from 'lodash/isEmpty'
|
import isEmpty from 'lodash/isEmpty'
|
||||||
import map from 'lodash/map'
|
import map from 'lodash/map'
|
||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
import some from 'lodash/some'
|
import some from 'lodash/some'
|
||||||
|
import SortedTable from 'sorted-table'
|
||||||
import StateButton from 'state-button'
|
import StateButton from 'state-button'
|
||||||
import Tooltip from 'tooltip'
|
import Tooltip from 'tooltip'
|
||||||
import { addSubscriptions } from 'utils'
|
import { addSubscriptions } from 'utils'
|
||||||
@ -19,6 +19,7 @@ import { injectIntl } from 'react-intl'
|
|||||||
import {
|
import {
|
||||||
createRemote,
|
createRemote,
|
||||||
deleteRemote,
|
deleteRemote,
|
||||||
|
deleteRemotes,
|
||||||
disableRemote,
|
disableRemote,
|
||||||
editRemote,
|
editRemote,
|
||||||
enableRemote,
|
enableRemote,
|
||||||
@ -31,255 +32,225 @@ const remoteTypes = {
|
|||||||
nfs: 'remoteTypeNfs',
|
nfs: 'remoteTypeNfs',
|
||||||
smb: 'remoteTypeSmb',
|
smb: 'remoteTypeSmb',
|
||||||
}
|
}
|
||||||
|
const _changeUrlElement = (remote, value, element) =>
|
||||||
class AbstractRemote extends Component {
|
editRemote(remote, { url: format({ ...remote, [element]: value }) })
|
||||||
_changeUrlElement = (value, element) => {
|
const _showError = remote => alert(_('remoteConnectionFailed'), remote.error)
|
||||||
const remote = { ...this.props.remote }
|
const COLUMN_NAME = {
|
||||||
remote[element] = value
|
component: @injectIntl
|
||||||
const url = format(remote)
|
class RemoteName extends Component {
|
||||||
return editRemote(remote, { url })
|
render () {
|
||||||
}
|
const { item: remote, intl } = this.props
|
||||||
|
return (
|
||||||
_showError = () => alert(_('remoteConnectionFailed'), this.props.remote.error)
|
<Text
|
||||||
|
onChange={name => editRemote(remote, { name })}
|
||||||
_changeName = name => {
|
placeholder={intl.formatMessage(messages.remoteMyNamePlaceHolder)}
|
||||||
const { remote } = this.props
|
value={remote.name}
|
||||||
return editRemote(remote, { name })
|
/>
|
||||||
}
|
|
||||||
|
|
||||||
_test = () => {
|
|
||||||
const { remote } = this.props
|
|
||||||
testRemote(remote).then(answer => {
|
|
||||||
const title = (
|
|
||||||
<span>
|
|
||||||
<Icon icon={answer.success ? 'success' : 'error'} />{' '}
|
|
||||||
{_(answer.success ? 'remoteTestSuccess' : 'remoteTestFailure', {
|
|
||||||
name: remote.name,
|
|
||||||
})}
|
|
||||||
</span>
|
|
||||||
)
|
)
|
||||||
let body
|
}
|
||||||
if (answer.success) {
|
},
|
||||||
body = _('remoteTestSuccessMessage')
|
name: _('remoteName'),
|
||||||
} else {
|
sortCriteria: 'name',
|
||||||
body = (
|
}
|
||||||
<p>
|
const COLUMN_STATE = {
|
||||||
<dl className='dl-horizontal'>
|
itemRenderer: remote => (
|
||||||
<dt>{_('remoteTestError')}</dt>
|
<div>
|
||||||
<dd>{answer.error}</dd>
|
<StateButton
|
||||||
<dt>{_('remoteTestStep')}</dt>
|
disabledLabel={_('remoteDisconnected')}
|
||||||
<dd>{answer.step}</dd>
|
disabledHandler={enableRemote}
|
||||||
</dl>
|
disabledTooltip={_('remoteConnectTip')}
|
||||||
</p>
|
enabledLabel={_('remoteConnected')}
|
||||||
|
enabledHandler={disableRemote}
|
||||||
|
enabledTooltip={_('remoteDisconnectTip')}
|
||||||
|
handlerParam={remote}
|
||||||
|
state={remote.enabled}
|
||||||
|
/>{' '}
|
||||||
|
{remote.error && (
|
||||||
|
<Tooltip content={_('remoteConnectionFailed')}>
|
||||||
|
<a
|
||||||
|
className='text-danger btn btn-link'
|
||||||
|
onClick={() => _showError(remote)}
|
||||||
|
style={{ padding: '0px' }}
|
||||||
|
>
|
||||||
|
<Icon icon='alarm' size='lg' />
|
||||||
|
</a>
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
name: _('remoteState'),
|
||||||
|
}
|
||||||
|
|
||||||
|
const COLUMNS_LOCAL_REMOTE = [
|
||||||
|
COLUMN_NAME,
|
||||||
|
{
|
||||||
|
component: @injectIntl
|
||||||
|
class LocalRemotePath extends Component {
|
||||||
|
render () {
|
||||||
|
const { item: remote, intl } = this.props
|
||||||
|
return (
|
||||||
|
<Text
|
||||||
|
onChange={v => _changeUrlElement(remote, v, 'path')}
|
||||||
|
placeholder={intl.formatMessage(
|
||||||
|
messages.remoteLocalPlaceHolderPath
|
||||||
|
)}
|
||||||
|
value={remote.path}
|
||||||
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
alert(title, body)
|
},
|
||||||
})
|
name: _('remotePath'),
|
||||||
}
|
},
|
||||||
|
COLUMN_STATE,
|
||||||
render () {
|
]
|
||||||
const { remote } = this.props
|
const COLUMNS_NFS_REMOTE = [
|
||||||
|
COLUMN_NAME,
|
||||||
return (
|
{
|
||||||
<tr>
|
component: @injectIntl
|
||||||
<td />
|
class NfsRemoteInfo extends Component {
|
||||||
<td>
|
render () {
|
||||||
<Text
|
const { item: remote, intl } = this.props
|
||||||
value={remote.name}
|
return (
|
||||||
onChange={this._changeName}
|
<span>
|
||||||
placeholder={this.props.intl.formatMessage(
|
<strong className='text-info'>\\</strong>
|
||||||
messages.remoteNamePlaceHolder
|
<Text
|
||||||
)}
|
onChange={v => _changeUrlElement(remote, v, 'host')}
|
||||||
/>
|
placeholder={intl.formatMessage(
|
||||||
</td>
|
messages.remoteNfsPlaceHolderHost
|
||||||
<td>{this._renderRemoteInfo(remote)}</td>
|
)}
|
||||||
<td>{this._renderAuthInfo(remote)}</td>
|
value={remote.host}
|
||||||
<td>
|
|
||||||
<StateButton
|
|
||||||
disabledLabel={_('remoteDisconnected')}
|
|
||||||
disabledHandler={enableRemote}
|
|
||||||
disabledTooltip={_('remoteConnectTip')}
|
|
||||||
enabledLabel={_('remoteConnected')}
|
|
||||||
enabledHandler={disableRemote}
|
|
||||||
enabledTooltip={_('remoteDisconnectTip')}
|
|
||||||
handlerParam={remote}
|
|
||||||
state={remote.enabled}
|
|
||||||
/>{' '}
|
|
||||||
{remote.error && (
|
|
||||||
<Tooltip content={_('remoteConnectionFailed')}>
|
|
||||||
<a
|
|
||||||
className='text-danger btn btn-link'
|
|
||||||
style={{ padding: '0px' }}
|
|
||||||
onClick={this._showError}
|
|
||||||
>
|
|
||||||
<Icon icon='alarm' size='lg' />
|
|
||||||
</a>
|
|
||||||
</Tooltip>
|
|
||||||
)}
|
|
||||||
</td>
|
|
||||||
<td className='text-xs-right'>
|
|
||||||
{remote.enabled && (
|
|
||||||
<Tooltip content={_('remoteTestTip')}>
|
|
||||||
<ActionRowButton
|
|
||||||
btnStyle='primary'
|
|
||||||
handler={this._test}
|
|
||||||
icon='diagnosis'
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
|
||||||
)}{' '}
|
|
||||||
<Tooltip content={_('remoteDeleteTip')}>
|
|
||||||
<ActionRowButton
|
|
||||||
btnStyle='danger'
|
|
||||||
handler={deleteRemote}
|
|
||||||
handlerParam={remote}
|
|
||||||
icon='delete'
|
|
||||||
/>
|
/>
|
||||||
</Tooltip>
|
:
|
||||||
</td>
|
<Text
|
||||||
</tr>
|
onChange={v => _changeUrlElement(remote, v, 'path')}
|
||||||
)
|
placeholder={intl.formatMessage(
|
||||||
}
|
messages.remoteNfsPlaceHolderPath
|
||||||
|
)}
|
||||||
|
value={remote.path}
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
name: _('remoteDevice'),
|
||||||
|
},
|
||||||
|
COLUMN_STATE,
|
||||||
|
]
|
||||||
|
const COLUMNS_SMB_REMOTE = [
|
||||||
|
COLUMN_NAME,
|
||||||
|
{
|
||||||
|
component: @injectIntl
|
||||||
|
class SmbRemoteInfo extends Component {
|
||||||
|
render () {
|
||||||
|
const { item: remote, intl } = this.props
|
||||||
|
return (
|
||||||
|
<span>
|
||||||
|
<strong className='text-info'>\\</strong>
|
||||||
|
<Text
|
||||||
|
value={remote.host}
|
||||||
|
onChange={v => _changeUrlElement(remote, v, 'host')}
|
||||||
|
/>
|
||||||
|
<strong className='text-info'>\</strong>
|
||||||
|
<span>
|
||||||
|
<Text
|
||||||
|
onChange={v => _changeUrlElement(remote, v, 'path')}
|
||||||
|
placeholder={intl.formatMessage(
|
||||||
|
messages.remoteSmbPlaceHolderRemotePath
|
||||||
|
)}
|
||||||
|
value={remote.path}
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
name: _('remoteShare'),
|
||||||
|
},
|
||||||
|
COLUMN_STATE,
|
||||||
|
{
|
||||||
|
component: @injectIntl
|
||||||
|
class SmbRemoteAuthInfo extends Component {
|
||||||
|
render () {
|
||||||
|
const { item: remote, intl } = this.props
|
||||||
|
return (
|
||||||
|
<span>
|
||||||
|
<Text
|
||||||
|
value={remote.username}
|
||||||
|
onChange={v => _changeUrlElement(remote, v, 'username')}
|
||||||
|
/>
|
||||||
|
:
|
||||||
|
<Password
|
||||||
|
value=''
|
||||||
|
onChange={v => _changeUrlElement(remote, v, 'password')}
|
||||||
|
placeholder={intl.formatMessage(
|
||||||
|
messages.remotePlaceHolderPassword
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
@
|
||||||
|
<Text
|
||||||
|
value={remote.domain}
|
||||||
|
onChange={v => _changeUrlElement(remote, v, 'domain')}
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
name: _('remoteAuth'),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
_renderRemoteInfo () {
|
const GROUPED_ACTIONS = [
|
||||||
throw new Error('NOT IMPLEMENTED')
|
{
|
||||||
}
|
handler: deleteRemotes,
|
||||||
|
icon: 'delete',
|
||||||
|
label: _('remoteDeleteSelected'),
|
||||||
|
level: 'danger',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
_renderAuthInfo () {
|
const INDIVIDUAL_ACTIONS = [
|
||||||
throw new Error('NOT IMPLEMENTED')
|
{
|
||||||
}
|
disabled: remote => !remote.enabled,
|
||||||
|
handler: remote =>
|
||||||
get accessible () {
|
testRemote(remote).then(
|
||||||
throw new Error('NOT IMPLEMENTED')
|
answer =>
|
||||||
}
|
answer.success
|
||||||
|
? alert(
|
||||||
get unaccessible () {
|
<span>
|
||||||
throw new Error('NOT IMPLEMENTED')
|
<Icon icon='success' />{' '}
|
||||||
}
|
{_('remoteTestSuccess', { name: remote.name })}
|
||||||
}
|
</span>,
|
||||||
|
_('remoteTestSuccessMessage')
|
||||||
@injectIntl
|
)
|
||||||
class LocalRemote extends AbstractRemote {
|
: alert(
|
||||||
_renderRemoteInfo () {
|
<span>
|
||||||
const { remote } = this.props
|
<Icon icon='error' />{' '}
|
||||||
return (
|
{_('remoteTestFailure', { name: remote.name })}
|
||||||
<Text
|
</span>,
|
||||||
value={remote.path}
|
<p>
|
||||||
onChange={v => this._changeUrlElement(v, 'path')}
|
<dl className='dl-horizontal'>
|
||||||
placeholder={this.props.intl.formatMessage(
|
<dt>{_('remoteTestError')}</dt>
|
||||||
messages.remoteLocalPlaceHolderPath
|
<dd>{answer.error}</dd>
|
||||||
)}
|
<dt>{_('remoteTestStep')}</dt>
|
||||||
/>
|
<dd>{answer.step}</dd>
|
||||||
)
|
</dl>
|
||||||
}
|
</p>
|
||||||
|
)
|
||||||
_renderAuthInfo () {
|
),
|
||||||
return ''
|
icon: 'diagnosis',
|
||||||
}
|
label: _('remoteTestTip'),
|
||||||
|
level: 'primary',
|
||||||
get accessible () {
|
},
|
||||||
return 'Accessible'
|
{
|
||||||
}
|
handler: deleteRemote,
|
||||||
|
icon: 'delete',
|
||||||
get unaccessible () {
|
label: _('remoteDeleteTip'),
|
||||||
return 'Unaccessible'
|
level: 'danger',
|
||||||
}
|
},
|
||||||
}
|
]
|
||||||
|
const FILTERS = {
|
||||||
@injectIntl
|
filterRemotesOnlyConnected: 'enabled?',
|
||||||
class NfsRemote extends AbstractRemote {
|
filterRemotesOnlyDisconnected: '!enabled?',
|
||||||
_renderRemoteInfo () {
|
|
||||||
const { remote } = this.props
|
|
||||||
return (
|
|
||||||
<span>
|
|
||||||
<Text
|
|
||||||
value={remote.host}
|
|
||||||
onChange={v => this._changeUrlElement(v, 'host')}
|
|
||||||
placeholder={this.props.intl.formatMessage(
|
|
||||||
messages.remoteNfsPlaceHolderHost
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
:
|
|
||||||
<Text
|
|
||||||
value={remote.path}
|
|
||||||
onChange={v => this._changeUrlElement(v, 'path')}
|
|
||||||
placeholder={this.props.intl.formatMessage(
|
|
||||||
messages.remoteNfsPlaceHolderPath
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
_renderAuthInfo () {
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
|
|
||||||
get accessible () {
|
|
||||||
return _('remoteMounted')
|
|
||||||
}
|
|
||||||
|
|
||||||
get unaccessible () {
|
|
||||||
return _('remoteUnmounted')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@injectIntl
|
|
||||||
class SmbRemote extends AbstractRemote {
|
|
||||||
_renderRemoteInfo () {
|
|
||||||
const { remote } = this.props
|
|
||||||
return (
|
|
||||||
<span>
|
|
||||||
<strong className='text-info'>\\</strong>
|
|
||||||
<Text
|
|
||||||
value={remote.host}
|
|
||||||
onChange={v => this._changeUrlElement(v, 'host')}
|
|
||||||
/>
|
|
||||||
<strong className='text-info'>\</strong>
|
|
||||||
<span>
|
|
||||||
<Text
|
|
||||||
value={remote.path}
|
|
||||||
onChange={v => this._changeUrlElement(v, 'path')}
|
|
||||||
placeholder={this.props.intl.formatMessage(
|
|
||||||
messages.remoteSmbPlaceHolderRemotePath
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
_renderAuthInfo () {
|
|
||||||
const { remote } = this.props
|
|
||||||
return (
|
|
||||||
<span>
|
|
||||||
<Text
|
|
||||||
value={remote.username}
|
|
||||||
onChange={v => this._changeUrlElement(v, 'username')}
|
|
||||||
/>
|
|
||||||
:
|
|
||||||
<Password
|
|
||||||
value=''
|
|
||||||
onChange={v => this._changeUrlElement(v, 'password')}
|
|
||||||
placeholder={this.props.intl.formatMessage(
|
|
||||||
messages.remotePlaceHolderPassword
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
@
|
|
||||||
<Text
|
|
||||||
value={remote.domain}
|
|
||||||
onChange={v => this._changeUrlElement(v, 'domain')}
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
get accessible () {
|
|
||||||
return 'Accessible'
|
|
||||||
}
|
|
||||||
|
|
||||||
get unaccessible () {
|
|
||||||
return 'Unaccessible'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@addSubscriptions({
|
@addSubscriptions({
|
||||||
@ -351,53 +322,48 @@ export default class Remotes extends Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<table className='table table-hover'>
|
{!isEmpty(remotes.file) && (
|
||||||
{!isEmpty(remotes.file) && (
|
<div>
|
||||||
<tbody>
|
<h2>{_('remoteTypeLocal')}</h2>
|
||||||
<tr>
|
<SortedTable
|
||||||
<th className='text-info'>{_('remoteTypeLocal')}</th>
|
collection={remotes.file}
|
||||||
<th>{_('remoteName')}</th>
|
columns={COLUMNS_LOCAL_REMOTE}
|
||||||
<th>{_('remotePath')}</th>
|
filters={FILTERS}
|
||||||
<th />
|
groupedActions={GROUPED_ACTIONS}
|
||||||
<th>{_('remoteState')}</th>
|
individualActions={INDIVIDUAL_ACTIONS}
|
||||||
<th className='text-xs-right'>{_('remoteAction')}</th>
|
stateUrlParam='l'
|
||||||
</tr>
|
/>
|
||||||
{map(remotes.file, (remote, key) => (
|
</div>
|
||||||
<LocalRemote remote={remote} key={key} />
|
)}
|
||||||
))}
|
|
||||||
</tbody>
|
{!isEmpty(remotes.nfs) && (
|
||||||
)}
|
<div>
|
||||||
{!isEmpty(remotes.nfs) && (
|
<h2>{_('remoteTypeNfs')}</h2>
|
||||||
<tbody>
|
<SortedTable
|
||||||
<tr>
|
collection={remotes.nfs}
|
||||||
<th className='text-info'>{_('remoteTypeNfs')}</th>
|
columns={COLUMNS_NFS_REMOTE}
|
||||||
<th>{_('remoteName')}</th>
|
filters={FILTERS}
|
||||||
<th>{_('remoteDevice')}</th>
|
groupedActions={GROUPED_ACTIONS}
|
||||||
<th />
|
individualActions={INDIVIDUAL_ACTIONS}
|
||||||
<th>{_('remoteState')}</th>
|
stateUrlParam='nfs'
|
||||||
<th className='text-xs-right'>{_('remoteAction')}</th>
|
/>
|
||||||
</tr>
|
</div>
|
||||||
{map(remotes.nfs, (remote, key) => (
|
)}
|
||||||
<NfsRemote remote={remote} key={key} />
|
|
||||||
))}
|
{!isEmpty(remotes.smb) && (
|
||||||
</tbody>
|
<div>
|
||||||
)}
|
<h2>{_('remoteTypeSmb')}</h2>
|
||||||
{!isEmpty(remotes.smb) && (
|
<SortedTable
|
||||||
<tbody>
|
collection={remotes.smb}
|
||||||
<tr>
|
columns={COLUMNS_SMB_REMOTE}
|
||||||
<th className='text-info'>{_('remoteTypeSmb')}</th>
|
filters={FILTERS}
|
||||||
<th>{_('remoteName')}</th>
|
groupedActions={GROUPED_ACTIONS}
|
||||||
<th>{_('remoteShare')}</th>
|
individualActions={INDIVIDUAL_ACTIONS}
|
||||||
<th>{_('remoteAuth')}</th>
|
stateUrlParam='smb'
|
||||||
<th>{_('remoteState')}</th>
|
/>
|
||||||
<th className='text-xs-right'>{_('remoteAction')}</th>
|
</div>
|
||||||
</tr>
|
)}
|
||||||
{map(remotes.smb, (remote, key) => (
|
|
||||||
<SmbRemote remote={remote} key={key} />
|
|
||||||
))}
|
|
||||||
</tbody>
|
|
||||||
)}
|
|
||||||
</table>
|
|
||||||
<h2>{_('newRemote')}</h2>
|
<h2>{_('newRemote')}</h2>
|
||||||
<form id='newRemoteForm'>
|
<form id='newRemoteForm'>
|
||||||
<div className='form-group'>
|
<div className='form-group'>
|
||||||
@ -449,7 +415,7 @@ export default class Remotes extends Component {
|
|||||||
</fieldset>
|
</fieldset>
|
||||||
)}
|
)}
|
||||||
{type === 'nfs' && (
|
{type === 'nfs' && (
|
||||||
<fieldset className='form-group'>
|
<fieldset>
|
||||||
<div className='form-group'>
|
<div className='form-group'>
|
||||||
<input
|
<input
|
||||||
type='text'
|
type='text'
|
||||||
@ -461,7 +427,7 @@ export default class Remotes extends Component {
|
|||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className='input-group'>
|
<div className='input-group form-group'>
|
||||||
<span className='input-group-addon'>/</span>
|
<span className='input-group-addon'>/</span>
|
||||||
<input
|
<input
|
||||||
type='text'
|
type='text'
|
||||||
@ -476,7 +442,7 @@ export default class Remotes extends Component {
|
|||||||
</fieldset>
|
</fieldset>
|
||||||
)}
|
)}
|
||||||
{type === 'smb' && (
|
{type === 'smb' && (
|
||||||
<fieldset className='form-group'>
|
<fieldset>
|
||||||
<div className='input-group form-group'>
|
<div className='input-group form-group'>
|
||||||
<span className='input-group-addon'>\\</span>
|
<span className='input-group-addon'>\\</span>
|
||||||
<input
|
<input
|
||||||
|
Loading…
Reference in New Issue
Block a user