Moved all services in same tab and planning in its own

This commit is contained in:
Arnaud Vergnet 2020-04-21 19:30:13 +02:00
parent 0b17a35856
commit 03c4a43e58
8 changed files with 153 additions and 189 deletions

View file

@ -2,13 +2,22 @@
import * as React from 'react'; import * as React from 'react';
import {Animated, View} from "react-native"; import {Animated, View} from "react-native";
import type {cardItem, cards} from "../../../screens/Insa/InsaHomeScreen";
import CardListItem from "./CardListItem"; import CardListItem from "./CardListItem";
type Props = { type Props = {
dataset: Array<cards> dataset: Array<cards>
} }
export type cardItem = {
title: string,
subtitle: string,
image: string | number,
onPress: () => void,
};
export type cards = Array<cardItem>;
export default class CardList extends React.Component<Props> { export default class CardList extends React.Component<Props> {
renderItem = ({item}: { item: cards }) => { renderItem = ({item}: { item: cards }) => {

View file

@ -2,7 +2,7 @@
import * as React from 'react'; import * as React from 'react';
import {Caption, Card, Paragraph} from 'react-native-paper'; import {Caption, Card, Paragraph} from 'react-native-paper';
import type {cardItem} from "../../../screens/Insa/InsaHomeScreen"; import type {cardItem} from "./CardList";
type Props = { type Props = {
width: string | number, width: string | number,

View file

@ -19,8 +19,8 @@ type State = {
const TAB_ICONS = { const TAB_ICONS = {
proxiwash: 'tshirt-crew', proxiwash: 'tshirt-crew',
students: 'account-circle', services: 'account-circle',
insa: 'book', planning: 'calendar-range',
planex: 'clock', planex: 'clock',
}; };

View file

@ -8,6 +8,7 @@ import DebugScreen from '../screens/About/DebugScreen';
import {createStackNavigator, TransitionPresets} from "@react-navigation/stack"; import {createStackNavigator, TransitionPresets} from "@react-navigation/stack";
import i18n from "i18n-js"; import i18n from "i18n-js";
import TabNavigator from "./MainTabNavigator"; import TabNavigator from "./MainTabNavigator";
import TetrisScreen from "../screens/Tetris/TetrisScreen";
const defaultScreenOptions = { const defaultScreenOptions = {
gestureEnabled: true, gestureEnabled: true,
@ -59,6 +60,13 @@ function MainStackComponent(props: { createTabNavigator: () => React.Node }) {
title: i18n.t('aboutScreen.debug') title: i18n.t('aboutScreen.debug')
}} }}
/> />
<MainStack.Screen
name="tetris"
component={TetrisScreen}
options={{
title: i18n.t("game.title"),
}}
/>
</MainStack.Navigator> </MainStack.Navigator>
); );
} }

View file

@ -28,7 +28,6 @@ import {AmicaleWebsiteScreen} from "../screens/Websites/AmicaleWebsiteScreen";
import {ElusEtudiantsWebsiteScreen} from "../screens/Websites/ElusEtudiantsWebsiteScreen"; import {ElusEtudiantsWebsiteScreen} from "../screens/Websites/ElusEtudiantsWebsiteScreen";
import {WiketudWebsiteScreen} from "../screens/Websites/WiketudWebsiteScreen"; import {WiketudWebsiteScreen} from "../screens/Websites/WiketudWebsiteScreen";
import {TutorInsaWebsiteScreen} from "../screens/Websites/TutorInsaWebsiteScreen"; import {TutorInsaWebsiteScreen} from "../screens/Websites/TutorInsaWebsiteScreen";
import TetrisScreen from "../screens/Tetris/TetrisScreen";
import LoginScreen from "../screens/Amicale/LoginScreen"; import LoginScreen from "../screens/Amicale/LoginScreen";
import ProfileScreen from "../screens/Amicale/ProfileScreen"; import ProfileScreen from "../screens/Amicale/ProfileScreen";
import ClubListScreen from "../screens/Amicale/Clubs/ClubListScreen"; import ClubListScreen from "../screens/Amicale/Clubs/ClubListScreen";
@ -37,7 +36,6 @@ import VoteScreen from "../screens/Amicale/VoteScreen";
import AmicaleContactScreen from "../screens/Amicale/AmicaleContactScreen"; import AmicaleContactScreen from "../screens/Amicale/AmicaleContactScreen";
import AmicaleHomeScreen from "../screens/Amicale/AmicaleHomeScreen"; import AmicaleHomeScreen from "../screens/Amicale/AmicaleHomeScreen";
import WebsitesHomeScreen from "../screens/Websites/WebsitesHomeScreen"; import WebsitesHomeScreen from "../screens/Websites/WebsitesHomeScreen";
import InsaHomeScreen from "../screens/Insa/InsaHomeScreen";
const defaultScreenOptions = { const defaultScreenOptions = {
gestureEnabled: true, gestureEnabled: true,
@ -77,41 +75,32 @@ function createScreenCollapsibleStack(
) )
} }
function getWebsiteStack(name: string, Stack: any, component: any, title: string) { function getWebsiteStack(name: string, Stack: any, component: any, title: string) {
return createScreenCollapsibleStack(name, Stack, component, title, false); return createScreenCollapsibleStack(name, Stack, component, title, false);
} }
const StudentsStack = createStackNavigator(); const ServicesStack = createStackNavigator();
function StudentsStackComponent() { function ServicesStackComponent() {
return ( return (
<StudentsStack.Navigator <ServicesStack.Navigator
initialRouteName="index" initialRouteName="index"
headerMode={"screen"} headerMode={"screen"}
screenOptions={defaultScreenOptions} screenOptions={defaultScreenOptions}
> >
<StudentsStack.Screen {createScreenCollapsibleStack("index", ServicesStack, WebsitesHomeScreen, "SERVICES")}
name="index"
component={WebsitesHomeScreen} {createScreenCollapsibleStack("proximo", ServicesStack, ProximoMainScreen, "Proximo")}
options={{
title: "WEBSITES HOME",
}}
/>
{getWebsiteStack("amicale-website", StudentsStack, AmicaleWebsiteScreen, "Amicale")}
{getWebsiteStack("elus-etudiants", StudentsStack, ElusEtudiantsWebsiteScreen, "Élus Étudiants")}
{getWebsiteStack("wiketud", StudentsStack, WiketudWebsiteScreen, "Wiketud")}
{getWebsiteStack("tutorinsa", StudentsStack, TutorInsaWebsiteScreen, "Tutor'INSA")}
{createScreenCollapsibleStack("proximo", StudentsStack, ProximoMainScreen, "Proximo")}
{createScreenCollapsibleStack( {createScreenCollapsibleStack(
"proximo-list", "proximo-list",
StudentsStack, ServicesStack,
ProximoListScreen, ProximoListScreen,
i18n.t('screens.proximoArticles'), i18n.t('screens.proximoArticles'),
true, true,
{...screenTransition}, {...screenTransition},
)} )}
<StudentsStack.Screen <ServicesStack.Screen
name="proximo-about" name="proximo-about"
component={ProximoAboutScreen} component={ProximoAboutScreen}
options={{ options={{
@ -119,22 +108,18 @@ function StudentsStackComponent() {
...modalTransition, ...modalTransition,
}} }}
/> />
<StudentsStack.Screen
name="planning"
component={PlanningScreen} {/*{createScreenCollapsibleStack("index", PlanningStack, InsaHomeScreen, "INSA HOME")}*/}
options={{ {getWebsiteStack("available-rooms", PlanningStack, AvailableRoomScreen, i18n.t('screens.availableRooms'))}
title: i18n.t('screens.planning'), {getWebsiteStack("bib", PlanningStack, BibScreen, i18n.t('screens.bib'))}
}} {createScreenCollapsibleStack("self-menu", PlanningStack, SelfMenuScreen, i18n.t('screens.menuSelf'))}
/>
<StudentsStack.Screen {getWebsiteStack("amicale-website", ServicesStack, AmicaleWebsiteScreen, "Amicale")}
name="planning-information" {getWebsiteStack("elus-etudiants", ServicesStack, ElusEtudiantsWebsiteScreen, "Élus Étudiants")}
component={PlanningDisplayScreen} {getWebsiteStack("wiketud", ServicesStack, WiketudWebsiteScreen, "Wiketud")}
options={{ {getWebsiteStack("tutorinsa", ServicesStack, TutorInsaWebsiteScreen, "Tutor'INSA")}
title: i18n.t('screens.planningDisplayScreen'), </ServicesStack.Navigator>
...modalTransition,
}}
/>
</StudentsStack.Navigator>
); );
} }
@ -160,20 +145,31 @@ function ProxiwashStackComponent() {
); );
} }
const InsaStack = createStackNavigator(); const PlanningStack = createStackNavigator();
function InsaStackComponent() { function PlanningStackComponent() {
return ( return (
<InsaStack.Navigator <PlanningStack.Navigator
initialRouteName="index" initialRouteName="index"
headerMode={"screen"} headerMode={"screen"}
screenOptions={defaultScreenOptions} screenOptions={defaultScreenOptions}
> >
{createScreenCollapsibleStack("index", InsaStack, InsaHomeScreen, "INSA HOME")} <ServicesStack.Screen
{getWebsiteStack("available-rooms", InsaStack, AvailableRoomScreen, i18n.t('screens.availableRooms'))} name="planning"
{getWebsiteStack("bib", InsaStack, BibScreen, i18n.t('screens.bib'))} component={PlanningScreen}
{createScreenCollapsibleStack("self-menu", InsaStack, SelfMenuScreen, i18n.t('screens.menuSelf'))} options={{
</InsaStack.Navigator> title: i18n.t('screens.planning'),
}}
/>
<ServicesStack.Screen
name="planning-information"
component={PlanningDisplayScreen}
options={{
title: i18n.t('screens.planningDisplayScreen'),
...modalTransition,
}}
/>
</PlanningStack.Navigator>
); );
} }
@ -207,14 +203,6 @@ function HomeStackComponent(initialRoute: string | null, defaultData: { [key: st
useNativeDriver: true, useNativeDriver: true,
} }
)} )}
<HomeStack.Screen
name="feed-information"
component={FeedItemScreen}
options={{
title: i18n.t('screens.feedDisplayScreen'),
...modalTransition,
}}
/>
<HomeStack.Screen <HomeStack.Screen
name="scanner" name="scanner"
component={ScannerScreen} component={ScannerScreen}
@ -224,20 +212,30 @@ function HomeStackComponent(initialRoute: string | null, defaultData: { [key: st
}} }}
/> />
<HomeStack.Screen <HomeStack.Screen
name="home-planning-information" name="club-information"
component={ClubDisplayScreen}
options={{
title: i18n.t('screens.clubDisplayScreen'),
...modalTransition,
}}
/>
<HomeStack.Screen
name="feed-information"
component={FeedItemScreen}
options={{
title: i18n.t('screens.feedDisplayScreen'),
...modalTransition,
}}
/>
<HomeStack.Screen
name="planning-information"
component={PlanningDisplayScreen} component={PlanningDisplayScreen}
options={{ options={{
title: i18n.t('screens.planningDisplayScreen'), title: i18n.t('screens.planningDisplayScreen'),
...modalTransition, ...modalTransition,
}} }}
/> />
<HomeStack.Screen
name="tetris"
component={TetrisScreen}
options={{
title: i18n.t("game.title"),
}}
/>
<HomeStack.Screen <HomeStack.Screen
name="login" name="login"
component={LoginScreen} component={LoginScreen}
@ -253,14 +251,6 @@ function HomeStackComponent(initialRoute: string | null, defaultData: { [key: st
}} }}
/> />
{createScreenCollapsibleStack("club-list", HomeStack, ClubListScreen, i18n.t('clubs.clubList'))} {createScreenCollapsibleStack("club-list", HomeStack, ClubListScreen, i18n.t('clubs.clubList'))}
<HomeStack.Screen
name="club-information"
component={ClubDisplayScreen}
options={{
title: i18n.t('screens.clubDisplayScreen'),
...modalTransition,
}}
/>
<HomeStack.Screen <HomeStack.Screen
name="club-about" name="club-about"
component={ClubAboutScreen} component={ClubAboutScreen}
@ -348,10 +338,10 @@ export default class TabNavigator extends React.Component<Props> {
options={{title: i18n.t('screens.proxiwash')}} options={{title: i18n.t('screens.proxiwash')}}
/> />
<Tab.Screen <Tab.Screen
name="students" name="services"
option option
component={StudentsStackComponent} component={ServicesStackComponent}
options={{title: "ETUDIANTS"}} options={{title: "SERVICES"}}
/> />
<Tab.Screen <Tab.Screen
@ -360,9 +350,9 @@ export default class TabNavigator extends React.Component<Props> {
options={{title: i18n.t('screens.home')}} options={{title: i18n.t('screens.home')}}
/> />
<Tab.Screen <Tab.Screen
name="insa" name="planning"
component={InsaStackComponent} component={PlanningStackComponent}
options={{title: "INSA"}} options={{title: "EVENTS"}}
/> />
<Tab.Screen <Tab.Screen

View file

@ -161,12 +161,16 @@ class HomeScreen extends React.Component<Props> {
}; };
onProximoClick = () => { onProximoClick = () => {
this.props.navigation.navigate("proximo"); this.props.navigation.navigate('services', {screen: "index"});
}; };
onTutorInsaClick = () => this.props.navigation.navigate('tutorinsa'); onTutorInsaClick = () => {
this.props.navigation.navigate('services', {screen: "index"});
};
onMenuClick = () => this.props.navigation.navigate('self-menu'); onMenuClick = () => {
this.props.navigation.navigate('services', {screen: "index"});
};
/** /**
* Creates the dataset to be used in the FlatList * Creates the dataset to be used in the FlatList
@ -407,8 +411,11 @@ class HomeScreen extends React.Component<Props> {
getDashboardEvent(content: Array<event>) { getDashboardEvent(content: Array<event>) {
let futureEvents = this.getFutureEvents(content); let futureEvents = this.getFutureEvents(content);
let displayEvent = this.getDisplayEvent(futureEvents); let displayEvent = this.getDisplayEvent(futureEvents);
const clickPreviewAction = () => // const clickPreviewAction = () =>
this.props.navigation.navigate('home-planning-information', {data: displayEvent}); // this.props.navigation.navigate('students', {
// screen: 'planning-information',
// params: {data: displayEvent}
// });
return ( return (
<DashboardItem <DashboardItem
eventNumber={futureEvents.length} eventNumber={futureEvents.length}
@ -416,7 +423,7 @@ class HomeScreen extends React.Component<Props> {
> >
<PreviewEventDashboardItem <PreviewEventDashboardItem
event={displayEvent != null ? displayEvent : undefined} event={displayEvent != null ? displayEvent : undefined}
clickAction={clickPreviewAction} clickAction={this.onEventContainerClick}
/> />
</DashboardItem> </DashboardItem>
); );

View file

@ -1,98 +0,0 @@
// @flow
import * as React from 'react';
import CardList from "../../components/Lists/CardList/CardList";
import CustomTabBar from "../../components/Tabbar/CustomTabBar";
import {Collapsible} from "react-navigation-collapsible";
import {withCollapsible} from "../../utils/withCollapsible";
type Props = {
navigation: Object,
route: Object,
collapsibleStack: Collapsible,
}
type State = {}
const BIB_IMAGE = "https://scontent-cdg2-1.xx.fbcdn.net/v/t1.0-9/50695561_2124263197597162_2325349608210825216_n.jpg?_nc_cat=109&_nc_sid=8bfeb9&_nc_ohc=tmcV6FWO7_kAX9vfWHU&_nc_ht=scontent-cdg2-1.xx&oh=3b81c76e46b49f7c3a033ea3b07ec212&oe=5EC59B4D";
const RU_IMAGE = "https://scontent-cdg2-1.xx.fbcdn.net/v/t1.0-9/47123773_2041883702501779_5289372776166064128_o.jpg?_nc_cat=100&_nc_sid=cdbe9c&_nc_ohc=dpuBGlIIy_EAX8CyC0l&_nc_ht=scontent-cdg2-1.xx&oh=5c5bb4f0c7f12b554246f7c9b620a5f3&oe=5EC4DB31";
const ROOM_IMAGE = "https://scontent-cdt1-1.xx.fbcdn.net/v/t1.0-9/47041013_2043521689004647_316124496522117120_n.jpg?_nc_cat=103&_nc_sid=8bfeb9&_nc_ohc=bIp8OVJvvSEAX8mKnDZ&_nc_ht=scontent-cdt1-1.xx&oh=b4fef72a645804a849ad30e9e20fca12&oe=5EC29309";
const EMAIL_IMAGE = "https://etud-mel.insa-toulouse.fr/webmail/images/logo-bluemind.png";
const ENT_IMAGE = "https://ent.insa-toulouse.fr/media/org/jasig/portal/layout/tab-column/xhtml-theme/insa/institutional/LogoInsa.png";
export type cardItem = {
title: string,
subtitle: string,
image: string | number,
onPress: () => void,
};
export type cards = Array<cardItem>;
class InsaHomeScreen extends React.Component<Props, State> {
state = {};
dataset: Array<cards>;
constructor(props: Props) {
super(props);
const nav = props.navigation;
this.dataset = [
[
{
title: "RU",
subtitle: "the ru",
image: RU_IMAGE,
onPress: () => nav.navigate("self-menu"),
},
],
[
{
title: "AVAILABLE ROOMS",
subtitle: "ROOMS",
image: ROOM_IMAGE,
onPress: () => nav.navigate("available-rooms"),
},
{
title: "BIB",
subtitle: "BIB",
image: BIB_IMAGE,
onPress: () => nav.navigate("bib"),
},
],
[
{
title: "EMAIL",
subtitle: "EMAIL",
image: EMAIL_IMAGE,
onPress: () => nav.navigate("available-rooms"),
},
{
title: "ENT",
subtitle: "ENT",
image: ENT_IMAGE,
onPress: () => nav.navigate("bib"),
},
],
];
}
render() {
const {containerPaddingTop, scrollIndicatorInsetTop, onScroll} = this.props.collapsibleStack;
return (
<CardList
dataset={this.dataset}
onScroll={onScroll}
contentContainerStyle={{
paddingTop: containerPaddingTop,
paddingBottom: CustomTabBar.TAB_BAR_HEIGHT + 20
}}
scrollIndicatorInsets={{top: scrollIndicatorInsetTop}}
/>
);
}
}
export default withCollapsible(InsaHomeScreen);

View file

@ -1,24 +1,29 @@
// @flow // @flow
import * as React from 'react'; import * as React from 'react';
import type {cards} from "../../components/Lists/CardList/CardList";
import CardList from "../../components/Lists/CardList/CardList"; import CardList from "../../components/Lists/CardList/CardList";
import CustomTabBar from "../../components/Tabbar/CustomTabBar"; import CustomTabBar from "../../components/Tabbar/CustomTabBar";
import {withCollapsible} from "../../utils/withCollapsible"; import {withCollapsible} from "../../utils/withCollapsible";
import type {cards} from "../Insa/InsaHomeScreen";
import {Collapsible} from "react-navigation-collapsible"; import {Collapsible} from "react-navigation-collapsible";
import {CommonActions} from "@react-navigation/native";
type Props = { type Props = {
navigation: Object, navigation: Object,
route: Object, route: Object,
collapsibleStack: Collapsible, collapsibleStack: Collapsible,
} }
const BIB_IMAGE = "https://scontent-cdg2-1.xx.fbcdn.net/v/t1.0-9/50695561_2124263197597162_2325349608210825216_n.jpg?_nc_cat=109&_nc_sid=8bfeb9&_nc_ohc=tmcV6FWO7_kAX9vfWHU&_nc_ht=scontent-cdg2-1.xx&oh=3b81c76e46b49f7c3a033ea3b07ec212&oe=5EC59B4D";
const RU_IMAGE = "https://scontent-cdg2-1.xx.fbcdn.net/v/t1.0-9/47123773_2041883702501779_5289372776166064128_o.jpg?_nc_cat=100&_nc_sid=cdbe9c&_nc_ohc=dpuBGlIIy_EAX8CyC0l&_nc_ht=scontent-cdg2-1.xx&oh=5c5bb4f0c7f12b554246f7c9b620a5f3&oe=5EC4DB31";
const ROOM_IMAGE = "https://scontent-cdt1-1.xx.fbcdn.net/v/t1.0-9/47041013_2043521689004647_316124496522117120_n.jpg?_nc_cat=103&_nc_sid=8bfeb9&_nc_ohc=bIp8OVJvvSEAX8mKnDZ&_nc_ht=scontent-cdt1-1.xx&oh=b4fef72a645804a849ad30e9e20fca12&oe=5EC29309";
const EMAIL_IMAGE = "https://etud-mel.insa-toulouse.fr/webmail/images/logo-bluemind.png";
const ENT_IMAGE = "https://ent.insa-toulouse.fr/media/org/jasig/portal/layout/tab-column/xhtml-theme/insa/institutional/LogoInsa.png";
const PROXIMO_IMAGE = require("../../../assets/proximo-logo.png"); const PROXIMO_IMAGE = require("../../../assets/proximo-logo.png");
const WIKETUD_LINK = "https://wiki.etud.insa-toulouse.fr/resources/assets/wiketud.png?ff051"; const WIKETUD_LINK = "https://wiki.etud.insa-toulouse.fr/resources/assets/wiketud.png?ff051";
const AMICALE_IMAGE = require("../../../assets/amicale.png"); const AMICALE_IMAGE = require("../../../assets/amicale.png");
const EE_IMAGE = "https://etud.insa-toulouse.fr/~eeinsat/wp-content/uploads/2019/09/logo-blanc.png"; const EE_IMAGE = "https://etud.insa-toulouse.fr/~eeinsat/wp-content/uploads/2019/09/logo-blanc.png";
const TUTORINSA_IMAGE = "https://www.etud.insa-toulouse.fr/~tutorinsa/public/images/logo-gray.png"; const TUTORINSA_IMAGE = "https://www.etud.insa-toulouse.fr/~tutorinsa/public/images/logo-gray.png";
const PLANNING_IMAGE = "https://scontent-cdg2-1.xx.fbcdn.net/v/t1.0-9/89719124_1737599216391004_5007805161305800704_o.jpg?_nc_cat=102&_nc_sid=825194&_nc_ohc=04zvPRn2SzIAX8v3F4q&_nc_ht=scontent-cdg2-1.xx&oh=ecc4af602818481c4192c92b8a45c69b&oe=5EC355E2";
class WebsitesHomeScreen extends React.Component<Props> { class WebsitesHomeScreen extends React.Component<Props> {
@ -29,17 +34,45 @@ class WebsitesHomeScreen extends React.Component<Props> {
const nav = props.navigation; const nav = props.navigation;
this.dataset = [ this.dataset = [
[ [
{
title: "RU",
subtitle: "the ru",
image: RU_IMAGE,
onPress: () => nav.navigate("self-menu"),
},
{ {
title: "proximo", title: "proximo",
subtitle: "proximo", subtitle: "proximo",
image: PROXIMO_IMAGE, image: PROXIMO_IMAGE,
onPress: () => nav.navigate("proximo"), onPress: () => nav.navigate("proximo"),
}, },
],
[
{ {
title: "planning", title: "AVAILABLE ROOMS",
subtitle: "planning", subtitle: "ROOMS",
image: PLANNING_IMAGE, image: ROOM_IMAGE,
onPress: () => nav.navigate("planning"), onPress: () => nav.navigate("available-rooms"),
},
{
title: "BIB",
subtitle: "BIB",
image: BIB_IMAGE,
onPress: () => nav.navigate("bib"),
},
],
[
{
title: "EMAIL",
subtitle: "EMAIL",
image: EMAIL_IMAGE,
onPress: () => nav.navigate("available-rooms"),
},
{
title: "ENT",
subtitle: "ENT",
image: ENT_IMAGE,
onPress: () => nav.navigate("bib"),
}, },
], ],
[ [
@ -67,12 +100,27 @@ class WebsitesHomeScreen extends React.Component<Props> {
title: "TUTOR INSA", title: "TUTOR INSA",
subtitle: "TUTOR INSA", subtitle: "TUTOR INSA",
image: TUTORINSA_IMAGE, image: TUTORINSA_IMAGE,
onPress: () => nav.navigate("tutor-insa"), onPress: () => nav.navigate("tutorinsa"),
}, },
], ],
]; ];
} }
componentDidMount() {
this.props.navigation.addListener('focus', this.handleNavigationParams);
}
handleNavigationParams = () => {
if (this.props.route.params != null) {
if (this.props.route.params.nextScreen != null) {
this.props.navigation.navigate(this.props.route.params.nextScreen);
// reset params to prevent infinite loop
this.props.navigation.dispatch(CommonActions.setParams({nextScreen: null}));
}
}
};
render() { render() {
const {containerPaddingTop, scrollIndicatorInsetTop, onScroll} = this.props.collapsibleStack; const {containerPaddingTop, scrollIndicatorInsetTop, onScroll} = this.props.collapsibleStack;
return ( return (