parent
b8dd3ec359
commit
e0eb79656e
16 changed files with 499 additions and 8 deletions
|
|
@ -66,3 +66,12 @@ export function goToFlaggedPosts() {
|
|||
}, getState);
|
||||
};
|
||||
}
|
||||
|
||||
export function goToChannelInfo() {
|
||||
return async (dispatch, getState) => {
|
||||
dispatch({
|
||||
type: NavigationTypes.NAVIGATION_PUSH,
|
||||
route: Routes.ChannelInfo
|
||||
}, getState);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
36
app/components/formatted_date.js
Normal file
36
app/components/formatted_date.js
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright (c) 2017 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import React, {Component, PropTypes} from 'react';
|
||||
import {injectIntl, intlShape} from 'react-intl';
|
||||
import {Text} from 'react-native';
|
||||
|
||||
class FormattedDate extends Component {
|
||||
static propTypes = {
|
||||
intl: intlShape.isRequired,
|
||||
value: PropTypes.any.isRequired,
|
||||
format: PropTypes.string,
|
||||
children: PropTypes.func
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
intl,
|
||||
value,
|
||||
children,
|
||||
...props
|
||||
} = this.props;
|
||||
|
||||
Reflect.deleteProperty(props, 'format');
|
||||
|
||||
const formattedDate = intl.formatDate(value, this.props);
|
||||
|
||||
if (typeof children === 'function') {
|
||||
return children(formattedDate);
|
||||
}
|
||||
|
||||
return <Text>{formattedDate}</Text>;
|
||||
}
|
||||
}
|
||||
|
||||
export default injectIntl(FormattedDate);
|
||||
|
|
@ -22,5 +22,9 @@ export default {
|
|||
},
|
||||
Search: {
|
||||
key: 'Search'
|
||||
},
|
||||
ChannelInfo: {
|
||||
key: 'ChannelInfo',
|
||||
title: {id: 'mobile.routes.channelInfo', defaultMessage: 'Info'}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -23,7 +23,8 @@ export default class Channel extends React.PureComponent {
|
|||
loadProfilesAndTeamMembersForDMSidebar: React.PropTypes.func.isRequired,
|
||||
selectInitialChannel: React.PropTypes.func.isRequired,
|
||||
openChannelDrawer: React.PropTypes.func.isRequired,
|
||||
handlePostDraftChanged: React.PropTypes.func.isRequired
|
||||
handlePostDraftChanged: React.PropTypes.func.isRequired,
|
||||
goToChannelInfo: React.PropTypes.func.isRequired
|
||||
}).isRequired,
|
||||
currentTeam: React.PropTypes.object,
|
||||
currentChannel: React.PropTypes.object,
|
||||
|
|
@ -110,6 +111,7 @@ export default class Channel extends React.PureComponent {
|
|||
currentChannel={currentChannel}
|
||||
openLeftDrawer={this.openChannelDrawer}
|
||||
openRightDrawer={this.openRightSidebar}
|
||||
goToChannelInfo={this.props.actions.goToChannelInfo}
|
||||
/>
|
||||
<ChannelPostList channel={currentChannel}/>
|
||||
<PostTextbox
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import {openChannelDrawer} from 'app/actions/views/drawer';
|
|||
import {getCurrentChannel} from 'service/selectors/entities/channels';
|
||||
import {getTheme} from 'service/selectors/entities/preferences';
|
||||
import {getCurrentTeam} from 'service/selectors/entities/teams';
|
||||
import {goToChannelInfo} from 'app/actions/navigation';
|
||||
|
||||
import Channel from './channel';
|
||||
|
||||
|
|
@ -35,7 +36,8 @@ function mapDispatchToProps(dispatch) {
|
|||
loadProfilesAndTeamMembersForDMSidebar,
|
||||
selectInitialChannel,
|
||||
openChannelDrawer,
|
||||
handlePostDraftChanged
|
||||
handlePostDraftChanged,
|
||||
goToChannelInfo
|
||||
}, dispatch)
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@ export default class ChannelHeader extends React.PureComponent {
|
|||
displayName: React.PropTypes.string.isRequired,
|
||||
theme: React.PropTypes.object.isRequired,
|
||||
openLeftDrawer: React.PropTypes.func.isRequired,
|
||||
openRightDrawer: React.PropTypes.func.isRequired
|
||||
openRightDrawer: React.PropTypes.func.isRequired,
|
||||
goToChannelInfo: React.PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
render() {
|
||||
|
|
@ -38,9 +39,13 @@ export default class ChannelHeader extends React.PureComponent {
|
|||
</TouchableHighlight>
|
||||
</View>
|
||||
<View style={{flex: 1, flexDirection: 'row', justifyContent: 'flex-start', alignItems: 'center', backgroundColor: theme.sidebarHeaderBg}}>
|
||||
<Text style={{color: theme.sidebarHeaderTextColor, fontSize: 15, fontWeight: 'bold'}}>
|
||||
{displayName}
|
||||
</Text>
|
||||
<TouchableHighlight onPress={this.props.goToChannelInfo}>
|
||||
<View>
|
||||
<Text style={{color: theme.sidebarHeaderTextColor, fontSize: 15, fontWeight: 'bold'}}>
|
||||
{displayName}
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
</View>
|
||||
<TouchableHighlight
|
||||
onPress={this.props.openRightDrawer}
|
||||
|
|
|
|||
132
app/scenes/channel_info/channel_info.js
Normal file
132
app/scenes/channel_info/channel_info.js
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
// Copyright (c) 2017 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import React, {PropTypes, PureComponent} from 'react';
|
||||
import {
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
View
|
||||
} from 'react-native';
|
||||
|
||||
import ChannelInfoHeader from './channel_info_header';
|
||||
import ChannelInfoRow from './channel_info_row';
|
||||
|
||||
const style = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1
|
||||
},
|
||||
footer: {
|
||||
marginTop: 40
|
||||
},
|
||||
separator: {
|
||||
flex: 1,
|
||||
marginHorizontal: 15
|
||||
},
|
||||
separatorContainer: {
|
||||
flex: 1,
|
||||
backgroundColor: '#fff',
|
||||
height: 1
|
||||
},
|
||||
scrollView: {
|
||||
flex: 1
|
||||
}
|
||||
});
|
||||
|
||||
export default class ChannelInfo extends PureComponent {
|
||||
static propTypes = {
|
||||
currentChannel: PropTypes.object.isRequired,
|
||||
currentChannelCreatorName: PropTypes.string,
|
||||
currentChannelMemberCount: PropTypes.number,
|
||||
isFavorite: PropTypes.bool.isRequired,
|
||||
theme: PropTypes.object.isRequired,
|
||||
actions: PropTypes.shape({
|
||||
getChannelStats: PropTypes.func.isRequired
|
||||
})
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.actions.getChannelStats(this.props.currentChannel.team_id, this.props.currentChannel.id);
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
currentChannel,
|
||||
currentChannelCreatorName,
|
||||
currentChannelMemberCount,
|
||||
isFavorite,
|
||||
theme
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<View style={style.container}>
|
||||
<ScrollView
|
||||
style={style.scrollView}
|
||||
contentContainerStyle={{backgroundColor: theme.centerChannelBg}}
|
||||
>
|
||||
<ChannelInfoHeader
|
||||
createAt={currentChannel.create_at}
|
||||
creator={currentChannelCreatorName}
|
||||
displayName={currentChannel.display_name}
|
||||
header={currentChannel.header}
|
||||
purpose={currentChannel.purpose}
|
||||
/>
|
||||
<ChannelInfoRow
|
||||
action={() => true}
|
||||
defaultMessage='Favorite'
|
||||
detail={isFavorite}
|
||||
icon='star-o'
|
||||
textId='mobile.routes.channelInfo.favorite'
|
||||
togglable={true}
|
||||
/>
|
||||
<View style={style.separatorContainer}>
|
||||
<View style={[style.separator, {backgroundColor: this.props.theme.centerChannelBg}]}/>
|
||||
</View>
|
||||
<ChannelInfoRow
|
||||
action={() => true}
|
||||
defaultMessage='Notification Preferences'
|
||||
icon='bell-o'
|
||||
textId='channel_header.notificationPreferences'
|
||||
/>
|
||||
<View style={style.separatorContainer}>
|
||||
<View style={[style.separator, {backgroundColor: this.props.theme.centerChannelBg}]}/>
|
||||
</View>
|
||||
<ChannelInfoRow
|
||||
action={() => true}
|
||||
defaultMessage='Manage Members'
|
||||
detail={currentChannelMemberCount}
|
||||
icon='users'
|
||||
textId='channel_header.manageMembers'
|
||||
/>
|
||||
<View style={style.separatorContainer}>
|
||||
<View style={[style.separator, {backgroundColor: this.props.theme.centerChannelBg}]}/>
|
||||
</View>
|
||||
<ChannelInfoRow
|
||||
action={() => true}
|
||||
defaultMessage='Add Members'
|
||||
icon='user-plus'
|
||||
textId='channel_header.addMembers'
|
||||
/>
|
||||
<View style={style.separatorContainer}>
|
||||
<View style={[style.separator, {backgroundColor: this.props.theme.centerChannelBg}]}/>
|
||||
</View>
|
||||
<ChannelInfoRow
|
||||
action={() => true}
|
||||
defaultMessage='Leave Channel'
|
||||
icon='sign-out'
|
||||
textId='navbar.leave'
|
||||
/>
|
||||
<View style={style.footer}>
|
||||
<ChannelInfoRow
|
||||
action={() => true}
|
||||
defaultMessage='Delete Channel'
|
||||
icon='trash'
|
||||
iconColor='#DA4A4A'
|
||||
textId='mobile.routes.channelInfo.delete_channel'
|
||||
textColor='#DA4A4A'
|
||||
/>
|
||||
</View>
|
||||
</ScrollView>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
40
app/scenes/channel_info/channel_info_container.js
Normal file
40
app/scenes/channel_info/channel_info_container.js
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
// Copyright (c) 2017 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import {bindActionCreators} from 'redux';
|
||||
import {connect} from 'react-redux';
|
||||
|
||||
import {getChannelStats} from 'service/actions/channels';
|
||||
import {getCurrentChannel, getCurrentChannelStats, getChannelsByCategory} from 'service/selectors/entities/channels';
|
||||
import {getTheme} from 'service/selectors/entities/preferences';
|
||||
import {getUser} from 'service/selectors/entities/users';
|
||||
|
||||
import ChannelInfo from './channel_info';
|
||||
|
||||
function mapStateToProps(state, ownProps) {
|
||||
const currentChannel = getCurrentChannel(state);
|
||||
const currentChannelCreator = getUser(state, currentChannel.creator_id);
|
||||
const currentChannelCreatorName = currentChannelCreator && currentChannelCreator.username;
|
||||
const currentChannelMemberCount = getCurrentChannelStats(state) && getCurrentChannelStats(state).member_count;
|
||||
const favoriteChannels = getChannelsByCategory(state).favoriteChannels.map((f) => f.id);
|
||||
const isFavorite = favoriteChannels.indexOf(currentChannel.id) > -1;
|
||||
|
||||
return {
|
||||
...ownProps,
|
||||
currentChannel,
|
||||
currentChannelCreatorName,
|
||||
currentChannelMemberCount,
|
||||
isFavorite,
|
||||
theme: getTheme(state)
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return {
|
||||
actions: bindActionCreators({
|
||||
getChannelStats
|
||||
}, dispatch)
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(ChannelInfo);
|
||||
116
app/scenes/channel_info/channel_info_header.js
Normal file
116
app/scenes/channel_info/channel_info_header.js
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
// Copyright (c) 2017 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import React, {PropTypes} from 'react';
|
||||
import {
|
||||
StyleSheet,
|
||||
Text,
|
||||
View
|
||||
} from 'react-native';
|
||||
import Icon from 'react-native-vector-icons/FontAwesome';
|
||||
|
||||
import FormattedDate from 'app/components/formatted_date';
|
||||
import FormattedText from 'app/components/formatted_text';
|
||||
|
||||
const style = StyleSheet.create({
|
||||
container: {
|
||||
backgroundColor: '#fff',
|
||||
marginBottom: 40,
|
||||
padding: 15
|
||||
},
|
||||
channelName: {
|
||||
marginLeft: 5,
|
||||
fontSize: 15,
|
||||
fontWeight: '600'
|
||||
},
|
||||
channelNameContainer: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
paddingBottom: 10
|
||||
},
|
||||
createdBy: {
|
||||
flexDirection: 'row',
|
||||
fontSize: 11,
|
||||
opacity: 0.5,
|
||||
marginTop: 5
|
||||
},
|
||||
detail: {
|
||||
fontSize: 13
|
||||
},
|
||||
header: {
|
||||
fontSize: 12,
|
||||
opacity: 0.5,
|
||||
marginBottom: 10
|
||||
},
|
||||
section: {
|
||||
marginTop: 15
|
||||
},
|
||||
url: {
|
||||
fontSize: 11,
|
||||
opacity: 0.5,
|
||||
marginBottom: 10
|
||||
}
|
||||
});
|
||||
|
||||
function channelInfoHeader(props) {
|
||||
const {createAt, creator, displayName, header, purpose} = props;
|
||||
return (
|
||||
<View style={style.container}>
|
||||
<View style={style.channelNameContainer}>
|
||||
<Icon
|
||||
name='globe'
|
||||
size={15}
|
||||
color='rgba(0, 0, 0, 0.7)'
|
||||
/>
|
||||
<Text style={style.channelName}>{displayName}</Text>
|
||||
</View>
|
||||
{purpose.length > 0 &&
|
||||
<View style={style.section}>
|
||||
<FormattedText
|
||||
style={style.header}
|
||||
id='channel_info.purpose'
|
||||
defaultMessage='Purpose'
|
||||
/>
|
||||
<Text style={style.detail}>{purpose}</Text>
|
||||
</View>
|
||||
}
|
||||
{header.length > 0 &&
|
||||
<View style={style.section}>
|
||||
<FormattedText
|
||||
style={style.header}
|
||||
id='channel_info.header'
|
||||
defaultMessage='Header'
|
||||
/>
|
||||
<Text style={style.detail}>{header}</Text>
|
||||
</View>
|
||||
}
|
||||
{creator &&
|
||||
<Text style={style.createdBy}>
|
||||
<FormattedText
|
||||
id='mobile.routes.channelInfo.createdBy'
|
||||
defaultMessage='Created by {creator} on '
|
||||
values={{
|
||||
creator
|
||||
}}
|
||||
/>
|
||||
<FormattedDate
|
||||
value={new Date(createAt)}
|
||||
year='numeric'
|
||||
month='long'
|
||||
day='2-digit'
|
||||
/>
|
||||
</Text>
|
||||
}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
channelInfoHeader.propTypes = {
|
||||
createAt: PropTypes.number.isRequired,
|
||||
creator: PropTypes.string,
|
||||
displayName: PropTypes.string.isRequired,
|
||||
header: PropTypes.string,
|
||||
purpose: PropTypes.string
|
||||
};
|
||||
|
||||
export default channelInfoHeader;
|
||||
106
app/scenes/channel_info/channel_info_row.js
Normal file
106
app/scenes/channel_info/channel_info_row.js
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
// Copyright (c) 2017 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import React, {PropTypes} from 'react';
|
||||
import {
|
||||
StyleSheet,
|
||||
Switch,
|
||||
Text,
|
||||
TouchableHighlight,
|
||||
View
|
||||
} from 'react-native';
|
||||
import Icon from 'react-native-vector-icons/FontAwesome';
|
||||
|
||||
import FormattedText from 'app/components/formatted_text';
|
||||
|
||||
const style = StyleSheet.create({
|
||||
container: {
|
||||
backgroundColor: '#fff',
|
||||
paddingHorizontal: 15,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center'
|
||||
},
|
||||
detail: {
|
||||
marginHorizontal: 15,
|
||||
color: 'rgba(0, 0, 0, 0.5)',
|
||||
fontSize: 15
|
||||
},
|
||||
label: {
|
||||
flex: 1,
|
||||
marginLeft: 15,
|
||||
fontSize: 15,
|
||||
paddingVertical: 15
|
||||
},
|
||||
leftIcon: {
|
||||
width: 17
|
||||
}
|
||||
});
|
||||
|
||||
function createTouchableComponent(children, action) {
|
||||
return (
|
||||
<TouchableHighlight onPress={action}>
|
||||
{children}
|
||||
</TouchableHighlight>
|
||||
);
|
||||
}
|
||||
|
||||
function channelInfoRow(props) {
|
||||
const {action, defaultMessage, detail, icon, iconColor, textColor, textId, togglable} = props;
|
||||
|
||||
const RowComponent = (
|
||||
<View style={style.container}>
|
||||
<Icon
|
||||
name={icon}
|
||||
size={15}
|
||||
color={iconColor}
|
||||
style={style.leftIcon}
|
||||
/>
|
||||
<FormattedText
|
||||
style={[style.label, {color: textColor}]}
|
||||
id={textId}
|
||||
defaultMessage={defaultMessage}
|
||||
/>
|
||||
<Text style={style.detail}>{detail}</Text>
|
||||
{togglable ?
|
||||
<Switch
|
||||
action={action}
|
||||
value={detail}
|
||||
/> :
|
||||
<Icon
|
||||
name='chevron-right'
|
||||
size={15}
|
||||
color='rgba(0, 0, 0, 0.7)'
|
||||
/>
|
||||
}
|
||||
</View>
|
||||
);
|
||||
|
||||
if (togglable) {
|
||||
return RowComponent;
|
||||
}
|
||||
|
||||
return createTouchableComponent(RowComponent, action);
|
||||
}
|
||||
|
||||
channelInfoRow.propTypes = {
|
||||
action: PropTypes.func.isRequired,
|
||||
defaultMessage: PropTypes.string.isRequired,
|
||||
detail: PropTypes.oneOfType([
|
||||
PropTypes.string,
|
||||
PropTypes.number,
|
||||
PropTypes.bool
|
||||
]),
|
||||
icon: PropTypes.string.isRequired,
|
||||
iconColor: PropTypes.string,
|
||||
textId: PropTypes.string.isRequired,
|
||||
togglable: PropTypes.bool,
|
||||
textColor: PropTypes.string
|
||||
};
|
||||
|
||||
channelInfoRow.defaultProps = {
|
||||
iconColor: 'rgba(0, 0, 0, 0.7)',
|
||||
textColor: '#000',
|
||||
togglable: false
|
||||
};
|
||||
|
||||
export default channelInfoRow;
|
||||
6
app/scenes/channel_info/index.js
Normal file
6
app/scenes/channel_info/index.js
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
// Copyright (c) 2017 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import ChannelInfoContainer from './channel_info_container';
|
||||
|
||||
export default ChannelInfoContainer;
|
||||
|
|
@ -7,6 +7,7 @@ import Root from './root/root_container.js';
|
|||
import Search from './search/search_container.js';
|
||||
import SelectServer from './select_server/select_server_container.js';
|
||||
import SelectTeam from './select_team/select_team_container.js';
|
||||
import ChannelInfo from './channel_info';
|
||||
|
||||
const scenes = {
|
||||
Root,
|
||||
|
|
@ -14,7 +15,8 @@ const scenes = {
|
|||
Login,
|
||||
SelectTeam,
|
||||
ChannelView: Channel, // Special case the name for this one to avoid ambiguity
|
||||
Search
|
||||
Search,
|
||||
ChannelInfo
|
||||
};
|
||||
|
||||
export function getComponentForScene(key) {
|
||||
|
|
|
|||
|
|
@ -958,7 +958,7 @@
|
|||
"backstage_sidebar.integrations.outgoing_webhooks": "Outgoing Webhooks",
|
||||
"calling_screen": "Calling",
|
||||
"center_panel.recent": "Click here to jump to recent messages. ",
|
||||
"chanel_header.addMembers": "Add Members",
|
||||
"channel_header.addMembers": "Add Members",
|
||||
"change_url.close": "Close",
|
||||
"change_url.endWithLetter": "Must end with a letter or number",
|
||||
"change_url.invalidUrl": "Invalid URL",
|
||||
|
|
@ -1489,6 +1489,10 @@
|
|||
"mobile.routes.login": "Login",
|
||||
"mobile.routes.postsList": "Posts List",
|
||||
"mobile.routes.selectTeam": "Select Team",
|
||||
"mobile.routes.channelInfo": "Info",
|
||||
"mobile.routes.channelInfo.createdBy": "Created by {creator} on ",
|
||||
"mobile.routes.channelInfo.delete_channel": "Delete Channel",
|
||||
"mobile.routes.channelInfo.favorite": "Favorite",
|
||||
"more_channels.close": "Close",
|
||||
"more_channels.create": "Create New Channel",
|
||||
"more_channels.createClick": "Click 'Create New Channel' to make a new one",
|
||||
|
|
|
|||
|
|
@ -9,6 +9,10 @@ function getAllChannels(state) {
|
|||
return state.entities.channels.channels;
|
||||
}
|
||||
|
||||
function getAllChannelStats(state) {
|
||||
return state.entities.channels.stats;
|
||||
}
|
||||
|
||||
export function getCurrentChannelId(state) {
|
||||
return state.entities.channels.currentId;
|
||||
}
|
||||
|
|
@ -21,6 +25,14 @@ export const getCurrentChannel = createSelector(
|
|||
}
|
||||
);
|
||||
|
||||
export const getCurrentChannelStats = createSelector(
|
||||
getAllChannelStats,
|
||||
getCurrentChannelId,
|
||||
(allChannelStats, currentChannelId) => {
|
||||
return allChannelStats[currentChannelId];
|
||||
}
|
||||
);
|
||||
|
||||
export const getChannelsOnCurrentTeam = createSelector(
|
||||
getAllChannels,
|
||||
getCurrentTeamId,
|
||||
|
|
|
|||
6
service/selectors/entities/general.js
Normal file
6
service/selectors/entities/general.js
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
// Copyright (c) 2017 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
export function getCurrentUrl(state) {
|
||||
return state.entities.general.credentials.url;
|
||||
}
|
||||
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
import {createSelector} from 'reselect';
|
||||
|
||||
import {getCurrentUrl} from './general';
|
||||
|
||||
export function getCurrentTeamId(state) {
|
||||
return state.entities.teams.currentId;
|
||||
}
|
||||
|
|
@ -19,3 +21,10 @@ export const getCurrentTeam = createSelector(
|
|||
}
|
||||
);
|
||||
|
||||
export const getCurrentTeamUrl = createSelector(
|
||||
getCurrentUrl,
|
||||
getCurrentTeam,
|
||||
(currentUrl, currentTeam) => {
|
||||
return `${currentUrl}/${currentTeam.name}`;
|
||||
}
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in a new issue