Как сделать динамические вкладки с помощью Material-ui и GraphQL - PullRequest
0 голосов
/ 12 мая 2019

Я пытаюсь сделать динамические вкладки в Material-ui.Моя сфера деятельности - конференции.Конференция длится X дней, и каждый день проводится несколько сеансов.

Мне нужен какой-то способ показать эти сеансы во вкладках, используя Material-ui.Поскольку количество дней, в течение которых конференция работает, не является фиксированным, мне нужно, чтобы количество вкладок менялось.Кроме того, на каждой вкладке я хочу показать сеансы за день.

Я использую GraphQL, Apollo, React и Material-Ui.

У меня определена следующая схема GraphQL:

    export default `

   scalar Date

   enum SortDirection {
    ASCENDING
    DESCENDING
}

enum SortableSessionField {
    start_date
} 



  type Conference {
    id: ID!
    title: String!
    address: String!
    start_date: String
    end_date: String
    sessions: [Session]
  }

  type Paper{
    id: ID!
    title: String!
  }

  type Session {
     conference_session_id: ID!
     session_title: String
     session_no: String
     chair_name: String
     discussant_1_name: String
     discussant_2_name: String
     room_description:String
     start_date: String
     start_time: String
     end_time: String
     papers: [Paper]
  }


type Query {
    conferences: [Conference!]!
    sessions(conferenceId: ID!, day: String!
             sort: SortDirection = DESCENDING
             sortBy: SortableSessionField = start_date): [Session]
    conference(id: ID!): Conference 
    session(id: ID!): Session
  }  


`;

Интересная функция здесь:

sessions(conferenceId: ID!, day: String!
                 sort: SortDirection = DESCENDING
                 sortBy: SortableSessionField = start_date): [Session]

, которая с учетом идентификатора конференции и даты возвращает все сеансы для конференции в этот день.Тестируя на площадке Graphql, он возвращает правильные данные.

У меня есть следующая базовая страница React:

import React from 'react'
import FullWidthTabs from '../components/Sessions'


class SessionsPage extends React.Component {

    render() {
        return (
          <div>
              <FullWidthTabs days={['2018-06-11', '2018-06-12', '2018-06-13']}/>
          </div>

        );
    }
}
export default (SessionsPage);

в основном это просто отправка трех дат на страницу FullWidthTabs, которую я просто украл напрямуюиз Material-UI и изменены в соответствии с моими потребностями:

import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import SwipeableViews from 'react-swipeable-views';
import AppBar from '@material-ui/core/AppBar';
import Tabs from '@material-ui/core/Tabs';
import Tab from '@material-ui/core/Tab';
import Typography from '@material-ui/core/Typography';
import gql from 'graphql-tag'
import { graphql } from 'react-apollo'
import { Query } from 'react-apollo'
import SessionTab from '../components/SessionTab'


        function TabContainer( { children }) {
            return (
                    <Typography component="div" style={{padding: 8 * 3}}>
                        {children}
                    </Typography>
                    );
        }

        TabContainer.propTypes = {
            children: PropTypes.node.isRequired,
            dir: PropTypes.string.isRequired,
        };

        const styles = theme => ({
                root: {
                    backgroundColor: theme.palette.background.paper,
                    width: 500,
                },
            });

        class FullWidthTabs extends React.Component {
            state = {
                value: 0,
            };

            handleChange = (event, value) => {
                this.setState({value});
            }
            ;
                    handleChangeIndex = index => {
                        this.setState({value: index});
                    }
            ;
        render() {


                const tabs = this.props.days.map((day) => {
                    return (<Tab key={day.gridIndex} label={day} />)
                });
                const content = this.props.days.map((day) => {
                    return (<TabContainer><SessionTab conferenceId = "57" day={day}/></TabContainer>)
                });

                const {classes, theme} = this.props;

                return (
                        <div className={classes.root}>
                            <AppBar position="static" color="default">
                                <Tabs
                                    value={this.state.value}
                                    onChange={this.handleChange}
                                    indicatorColor="primary"
                                    textColor="primary"
                                    variant="fullWidth"
                                    >
                                    { tabs }
                                </Tabs>
                            </AppBar>
                            <SwipeableViews
                                axis={theme.direction === 'rtl' ? 'x-reverse' : 'x'}
                                index={this.state.value}
                                onChangeIndex={this.handleChangeIndex}
                                >
                                { content }
                            </SwipeableViews>
                        </div>
                        );
            }
        }

        FullWidthTabs.propTypes = {
            classes: PropTypes.object.isRequired,
            theme: PropTypes.object.isRequired,
        };

        export default withStyles(styles, {withTheme: true})(FullWidthTabs);

Этот компонент получает (в данном случае) три даты из HOC, должен инициализировать три вкладки и поместить некоторую информацию о сеансе на каждую вкладку.

Компонентом для отображения данных сеанса является SessionTab:

import React from 'react'
import gql from 'graphql-tag'
import { graphql } from 'react-apollo'
import { Query } from 'react-apollo'
import ConferenceCard from '../components/ConferenceCard';

const SESSIONS_QUERY = gql`
 query sessions($id: ID!, $day: String!){
    sessions(conferenceId: $id, day: $day)
      {conference_session_id
       session_title
       start_date
       start_time
       end_time
     }
  }
`

class SessionsTab extends React.Component {
    constructor(props) {
        super(props);
        console.log(props);
    }

    render() {
        let id = this.props.conferenceId;
        let day = this.props.day;
        console.log("SessionTab " + id + "  " + day);
        return (
                <Query query={SESSIONS_QUERY} variables={{id, day}}>
                    {({ loading, error, data }) => {
                        if (loading)
                                return <div>Fetching</div>
                            if (error)
                                return <div>Error</div>
                            const sessionsToRender = data.sessions
                        return (
                           <div>
                              {sessionsToRender.map(session => <div> {session.conference_session_id} </div>)}
                           </div>
                        )
                    }}
                </Query>
                )
    }
}

export default (SessionsTab);

sessionTab получает идентификатор конференции и данные и находит все сеансы за день.При тестировании в GraphQL игровая площадка работает.

Каждый SessionTab инициализируется в FullWidthTab следующим образом:

 const content = this.props.days.map((day) => {
                    return (<TabContainer><SessionTab conferenceId = "57" day={day}/></TabContainer>)
                });

, где реквизиты дней содержат даты, переданные со страницы сеанса.

Но, похоже, это не работает.

Мои вопросы:

1) это правильный способ сделать что-то?2) при запуске tab1 показывает данные, в то время как tab2 и tab3 показывают ошибку.

Я не знаю, что это неправильно, но похоже, что SessionTab неправильно инициализирован, за исключением первого.

Ким

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...