Advertisement
Guest User

Untitled

a guest
Mar 21st, 2019
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import React, { Component } from 'react';
  2. import { SafeAreaView, Dimensions, Image, FlatList, Alert } from 'react-native';
  3. import TabStyle from '../style/tab_style';
  4. import { Text, Container, Content, Footer, Icon, View, Card, CardItem } from 'native-base';
  5. import { createMaterialTopTabNavigator } from 'react-navigation';
  6. import moment from 'moment/min/moment-with-locales';
  7. import gql from 'graphql-tag';
  8. import { Query, Mutation } from 'react-apollo';
  9. import IconBadge from 'react-native-icon-badge';
  10.  
  11. import color from '../style/color.json';
  12. import i18n, { _setLocale } from '../languages/i18n';
  13. import TaskComponent from '../component/TaskComponent';
  14. import FullScreenLoading from '../component/FullScreenLoading';
  15. import Comment from '../component/Comment';
  16. import TextInputComponent from '../component/TextInput';
  17. import { TokenContext } from '../MyApp';
  18. import { checkValidToken } from '../util/GraphQLUtil';
  19.  
  20. let  paddingSize = 12;
  21. let deadline;
  22.  
  23. let PROCESS_STEP_QUERY = gql`
  24. query ProcessStep($processStepId: String!) {
  25.     processStep(processStepId: $processStepId) {
  26.       forms {
  27.         id
  28.         recipeStepForm {
  29.           id
  30.           name
  31.           type
  32.           required
  33.           validation
  34.         }
  35.       }
  36.     }
  37.   }
  38. `;
  39.  
  40. let PROCESS_AUDIT_QUERY = gql`
  41. query ProcessAudit($processId: String!) {
  42.     process(processId: $processId) {
  43.         steps {
  44.             forms {
  45.               recipeStepForm {
  46.                 name
  47.                 type
  48.               }
  49.               data
  50.             }
  51.             assignee {
  52.               account {
  53.                 name
  54.               }
  55.             }
  56.             complete
  57.             deadline
  58.         }
  59.     }
  60. }
  61. `;
  62.  
  63. let COMMENT_PROCESS_MUTATION = gql`
  64. mutation CommentProcess($processId: String!, $input: CommentProcessInput!) {
  65.     commentProcess(processId: $processId, input: $input) {
  66.       id
  67.     }
  68. }
  69. `;
  70.  
  71. let FETCH_COMMENT_QUERY = gql`
  72. query FetchComment($processId: String!) {
  73.     process(processId: $processId) {
  74.     comments {
  75.       processComments {
  76.         id
  77.         text
  78.         type
  79.         commenter {
  80.           account {
  81.             name
  82.             photoUrl
  83.           }
  84.         }
  85.         createdAt
  86.       }
  87.     }
  88.   }
  89. }
  90. `;
  91.  
  92. let FIND_PROCESS_STEP_QUERY = gql`
  93. query FindProcessStep($processId: String!) {
  94.     process(processId: $processId) {
  95.       steps {
  96.         id
  97.         assignee {
  98.           id
  99.         }
  100.         deadline
  101.         complete
  102.       }
  103.     }
  104. }
  105. `;
  106.  
  107. export default class TaskDetail extends Component {
  108.  
  109.     constructor(props) {
  110.         super(props);
  111.         this.state = {
  112.             totalComments: this.props.navigation.getParam('totalComments'),
  113.             processId : this.props.navigation.getParam('processId'),
  114.             processStepId : this.props.navigation.getParam('processStepId'),
  115.             title : this.props.navigation.getParam('title'),
  116.             recipe : this.props.navigation.getParam('recipe'),
  117.             img : this.props.navigation.getParam('img'),
  118.             creatorName : this.props.navigation.getParam('creatorName'),
  119.             createdAt : moment(this.props.navigation.getParam('createdAt')).format("D MMM"),
  120.             deadline:null
  121.         };
  122.     }
  123.  
  124.     componentWillMount() {
  125.         moment.locale(i18n.t('moment'));
  126.     }
  127.  
  128.     render() {
  129.         const { navigation } = this.props;
  130.         // processId = navigation.getParam('processId');
  131.         // processStepId = navigation.getParam('processStepId');
  132.         // title = navigation.getParam('title');
  133.         // recipe = navigation.getParam('recipe');
  134.         // img = navigation.getParam('img');
  135.         // creatorName = navigation.getParam('creatorName');
  136.         // createdAt = moment(navigation.getParam('createdAt')).format("D MMM");
  137.  
  138.         if (this.state.processStepId) {
  139.             deadline = moment(navigation.getParam('deadline')).format("D MMM");
  140.         }
  141.  
  142.         let TabTaskDetail = createMaterialTopTabNavigator({
  143.             'Detail': {
  144.                 navigationOptions: {
  145.                     tabBarLabel: 'Task',
  146.                 },
  147.                 screen: ()=>
  148.                 (<Detail
  149.                 processId = {this.state.processId}
  150.                 processStepId={this.state.processStepId}
  151.                 title={this.state.title}
  152.                 recipe={this.state.recipe}
  153.                 img={this.state.img}
  154.                 creatorName={this.state.creatorName}
  155.                 createdAt={this.state.createdAt}
  156.                 deadline={this.state.deadline}
  157.                 >
  158.  
  159.  
  160.                 </Detail>) ,
  161.             },
  162.             Audit: {
  163.                 screen: ()=>
  164.                 (
  165.                 <AuditTab
  166.                 processId={this.state.processId}>
  167.  
  168.                 </AuditTab>),
  169.                 navigationOptions: {
  170.                     tabBarLabel: 'Audit'
  171.                 },
  172.             },
  173.             'Attachment': {
  174.                 navigationOptions: ({ screenProps }) => ({
  175.                     tabBarLabel: ({ tintColor }) =>
  176.                         <IconBadge
  177.                             MainElement={
  178.                                 <View style={{
  179.                                     width: 100,
  180.                                     padding: 10,
  181.                                     paddingBottom: 0,
  182.                                     marginBottom: 10
  183.                                 }}>
  184.                                     <Text style={{ marginBottom: 0, fontSize: 13, fontWeight: 'bold', color: tintColor }}>COMMENT</Text>
  185.                                 </View>
  186.                             }
  187.                             BadgeElement={
  188.                                 <Text style={{ color: 'white', fontSize: 15 }}>{this.state.totalComments}</Text>
  189.                             }
  190.                             IconBadgeStyle={{
  191.                                 width: 20,
  192.                                 height: 20,
  193.                                 backgroundColor: '#026aa7'
  194.                             }}
  195.                             Hidden={!this.state.totalComments}
  196.                         />
  197.                 }),
  198.                 screen: ()=>(
  199.                 <CommentTab
  200.                 processId={this.props.processId}>
  201.  
  202.                 </CommentTab>)
  203.             }
  204.         }, TabStyle);
  205.  
  206.         return (
  207.             <SafeAreaView flex={1}>
  208.                 <View style={{ backgroundColor: '#f5f5f5', paddingBottom: 0, padding: 16 }}>
  209.                     <Text style={{ color: '#3e3f42', marginBottom: 5, fontWeight: 'bold', fontSize: 16 }}>{this.state.recipe}</Text>
  210.                     <View style={{ flexDirection: 'row' }}>
  211.                         <Image source={{ uri: this.state.img }}
  212.                             style={{ height: paddingSize * 2, width: paddingSize * 2, borderRadius: paddingSize, paddingLeft: paddingSize }} />
  213.                         <Text style={{ marginLeft: 5, color: '#3e3f42', marginTop: 5, fontSize: 14 }}>{this.state.creatorName || ''}</Text>
  214.                     </View>
  215.                     <View style={{ flexDirection: 'row', marginTop: 5, marginLeft: 2 }}>
  216.                         <Icon name="ios-calendar" size={25} color='#3e3f42' />
  217.                         <Text style={{ marginLeft: 5, color: '#3e3f42', marginTop: 3, fontSize: 14 }}>{this.state.createdAt}</Text>
  218.                     </View>
  219.                 </View>
  220.                 <TabTaskDetail />
  221.             </SafeAreaView>
  222.         );
  223.     }
  224. }
  225.  
  226. class Detail extends Component {
  227.  
  228.     constructor(props){
  229.         super(props)
  230.         this.state={
  231.             processStepId:this.props.processStepId,
  232.             processId:this.props.processId,
  233.             title :this.props.title,
  234.             img:this.props.img,
  235.             creatorName:this.props.creatorName,
  236.             createdAt:this.props.createdAt,
  237.             deadline:this.props.deadline
  238.         }
  239.     }
  240.  
  241.  
  242.     render() {
  243.         return (
  244.             <Container>
  245.                 {this.state.processStepId
  246.                     ? (this.state.processStepId == 'NO_PROCESS_STEP'
  247.                         ? <View padder>
  248.                             <View padder style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
  249.                                 <Icon name={'md-alert'} />
  250.                                 <Text style={{ textAlign: 'center' }}>{i18n.t('noTaskAvailable')}</Text>
  251.                             </View>
  252.                         </View>
  253.                         : <Query query={PROCESS_STEP_QUERY} variables={{ "processStepId":this.state.processStepId }}>
  254.                             {({ data, networkStatus, error }) => {
  255.                                 if (networkStatus === 1) {
  256.                                     return (
  257.                                         <FullScreenLoading />
  258.                                     );
  259.                                 }
  260.  
  261.                                 if (error) {
  262.                                     if (checkValidToken(error)) {
  263.                                         Alert.alert(
  264.                                             i18n.t('dataFetchFailed'),
  265.                                             i18n.t(error.networkError ? 'connectionError' : 'serverError'),
  266.                                             [
  267.                                                 { text: 'OK', style: 'cancel' },
  268.                                             ],
  269.                                             { cancelable: false }
  270.                                         );
  271.                                     }
  272.                                     return null;
  273.                                 }
  274.  
  275.                                 return (
  276.                                     <Content padder>
  277.                                         <Text style={{ marginBottom: 5, fontWeight: 'bold' }}>{this.state.title}</Text>
  278.                                         <View style={{ flexDirection: 'row' }}>
  279.                                             <Image source={{ uri: this.state.img }}
  280.                                                 style={{ height: paddingSize * 2, width: paddingSize * 2, borderRadius: paddingSize, paddingLeft: paddingSize }} />
  281.                                             <Text style={{ marginLeft: 5, marginTop: 5, fontSize: 14 }}>{this.state.creatorName}</Text>
  282.                                         </View>
  283.                                         <View style={{ flexDirection: 'row', marginTop: 5, marginLeft: 2 }}>
  284.                                             <Icon name="ios-calendar" size={25} />
  285.                                             <Text style={{ marginLeft: 5, marginTop: 8, fontSize: 14 }}>{this.state.deadline}</Text>
  286.                                         </View>
  287.                                         <Text style={{ marginTop: 5 }}>{`Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.`}</Text>
  288.                                        <TaskComponent processStepId={this.state.processStepId} step={data.processStep} />
  289.                                    </Content>
  290.                                );
  291.                            }}
  292.                        </Query>
  293.                    ) : <TokenContext.Consumer>
  294.                        {(context) => (
  295.                            <Query query={FIND_PROCESS_STEP_QUERY} variables={{ "processId": this.state.processId }}>
  296.                                {({ data, error }) => {
  297.  
  298.                                    if (error) {
  299.                                        if (checkValidToken(error)) {
  300.                                            Alert.alert(
  301.                                                i18n.t('dataFetchFailed'),
  302.                                                i18n.t(error.networkError ? 'connectionError' : 'serverError'),
  303.                                                [
  304.                                                    { text: 'OK', style: 'cancel' },
  305.                                                ],
  306.                                                { cancelable: false }
  307.                                            );
  308.                                        }
  309.                                        return null;
  310.                                    }
  311.  
  312.                                    if (data.process) {
  313.  
  314.                                        let userData = context.userLoginResponse.data;
  315.                                        let currentOrg = userData.account.organizationMembers.find((org) => org.organization.code == context.selectedOrg);
  316.                                        let myProcessStep = data.process.steps.find((element) => element.assignee.id == currentOrg.id && !element.complete);
  317.  
  318.                                        if (myProcessStep) {
  319.                                            this.state.deadline = moment(myProcessStep.deadline).format("D MMM");
  320.                                            this.state.processStepId = myProcessStep.id;
  321.                                        } else {
  322.                                            this.state.processStepId = 'NO_PROCESS_STEP';
  323.                                        }
  324.                                        this.forceUpdate();
  325.                                    }
  326.                                    return (
  327.                                        <FullScreenLoading />
  328.                                    );
  329.                                }}
  330.                            </Query>
  331.                        )}
  332.                    </TokenContext.Consumer>
  333.                }
  334.            </Container>
  335.        );
  336.    }
  337. }
  338.  
  339. class AuditTab extends Component {
  340.  
  341.    constructor(props) {
  342.        super(props);
  343.        this.state = {
  344.            expandedList: [],
  345.            processId:this.props.processId
  346.        }
  347.    }
  348.  
  349.    componentWillMount() {
  350.        moment.locale(i18n.t('moment'));
  351.    }
  352.  
  353.    render() {
  354.        return (
  355.            <Container>
  356.                <Query query={PROCESS_AUDIT_QUERY} variables={{ "processId": this.state.processId }}>
  357.                    {({ data, networkStatus, error, refetch }) => {
  358.                        if (networkStatus === 1) {
  359.                            return (
  360.                                <FullScreenLoading />
  361.                            );
  362.                        }
  363.  
  364.                        if (error) {
  365.                            if (checkValidToken(error)) {
  366.                                Alert.alert(
  367.                                    i18n.t('dataFetchFailed'),
  368.                                    i18n.t(error.networkError ? 'connectionError' : 'serverError'),
  369.                                    [
  370.                                        { text: 'OK', style: 'cancel' },
  371.                                    ],
  372.                                    { cancelable: false }
  373.                                );
  374.                            }
  375.                            data = {
  376.                                process: {
  377.                                    steps: []
  378.                                }
  379.                            };
  380.                        }
  381.  
  382.                        return (
  383.                            <FlatList data={data.process.steps.filter((item) => item.complete)}
  384.                                refreshing={networkStatus === 4}
  385.                                onRefresh={async () => {
  386.                                    await refetch();
  387.                                    this.setState({ expandedList: [] });
  388.                                }}
  389.                                keyExtractor={(item, index) => index.toString()}
  390.                                ListEmptyComponent={() => (
  391.                                    <View padder>
  392.                                        <View padder style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
  393.                                            <Icon name={'md-alert'} />
  394.                                            <Text style={{ textAlign: 'center' }}>{i18n.t('noDataAvailable')}</Text>
  395.                                        </View>
  396.                                    </View>
  397.                                )}
  398.                                renderItem={({ item, index }) => {
  399.                                    let { forms } = item;
  400.  
  401.                                    let time = new Date(item.deadline);
  402.                                    let assigner = item.assignee.account.name;
  403.  
  404.                                    return (
  405.                                        <Card>
  406.                                            <CardItem button bordered onPress={() => {
  407.                                                let newExpanded = this.state.expandedList.slice();
  408.                                                newExpanded[index] = !newExpanded[index];
  409.                                                this.setState({ expandedList: newExpanded });
  410.                                            }}>
  411.                                                <View style={{ flexDirection: 'row' }}>
  412.                                                    <View style={{ backgroundColor: color.accent, height: 32, width: 32, borderRadius: 16, alignItems: 'center', justifyContent: 'center' }}>
  413.                                                        <Text style={{ color: 'white', fontWeight: 'bold' }}>
  414.                                                            {index + 1}
  415.                                                        </Text>
  416.                                                    </View>
  417.                                                    <View style={{ paddingHorizontal: 10, flex: 1 }}>
  418.                                                        <Text style={{ fontSize: 14 }}>{'Title'}</Text>
  419.                                                        <View style={{ flexDirection: "row" }}>
  420.                                                            <Text style={{ fontSize: 14, fontWeight: 'bold', paddingRight: 2 }}>{assigner}</Text>
  421.                                                            <Text style={{ fontSize: 14 }}>{` • ${moment(time).format('ll')} ${moment(time).format('LT')}`}</Text>
  422.                                                        </View>
  423.                                                    </View>
  424.                                                    <View style={{ alignItems: 'center', justifyContent: 'center' }}>
  425.                                                        <View style={{ backgroundColor: '#b5b5b5' }}>
  426.                                                            <Text style={{ fontSize: 12, padding: 4 }}>
  427.                                                                {`${forms.length} data`}
  428.                                                            </Text>
  429.                                                        </View>
  430.                                                    </View>
  431.                                                </View>
  432.                                            </CardItem>
  433.                                            {this.state.expandedList[index] && <CardItem>
  434.                                                <View>
  435.                                                    {forms.map((formValue, valIndex) => {
  436.                                                        return (
  437.                                                            <View key={valIndex} style={{ paddingBottom: 8 }}>
  438.                                                                <Text style={{ fontWeight: 'bold' }}>{formValue.recipeStepForm.name}</Text>
  439.                                                                {(() => {
  440.                                                                    switch (formValue.recipeStepForm.type) {
  441.                                                                        case 'date':
  442.                                                                            return (
  443.                                                                                <Text>{`${moment(formValue.data.value).format('ll')}`}</Text>
  444.                                                                            );
  445.                                                                        case 'datetime':
  446.                                                                            return (
  447.                                                                                <Text>{`${moment(formValue.data.value).format('lll')}`}</Text>
  448.                                                                            );
  449.                                                                        default:
  450.                                                                            return (
  451.                                                                                <Text>{formValue.data.value}</Text>
  452.                                                                            );
  453.                                                                    }
  454.                                                                })()}
  455.                                                            </View>
  456.                                                        );
  457.                                                    })}
  458.                                                </View>
  459.                                            </CardItem>}
  460.                                        </Card>
  461.                                    );
  462.                                }}
  463.                            />
  464.                        );
  465.                    }}
  466.                </Query>
  467.            </Container>
  468.        );
  469.    }
  470. }
  471.  
  472.  
  473. class CommentTab extends Component {
  474.  
  475.    state = {
  476.        refetch: undefined,
  477.        processId:this.props.processId
  478.    };
  479.  
  480.    render() {
  481.        return (
  482.            <Container>
  483.                <Query query={FETCH_COMMENT_QUERY} variables={{ "processId": this.state.processId }}>
  484.                    {({ data, networkStatus, error, refetch }) => {
  485.                        if (networkStatus === 1) {
  486.                            return (
  487.                                <FullScreenLoading />
  488.                            );
  489.                        }
  490.  
  491.                        if (error) {
  492.                            if (checkValidToken(error)) {
  493.                                Alert.alert(
  494.                                    i18n.t('dataFetchFailed'),
  495.                                    i18n.t(error.networkError ? 'connectionError' : 'serverError'),
  496.                                    [
  497.                                        { text: 'OK', style: 'cancel' },
  498.                                    ],
  499.                                    { cancelable: false }
  500.                                );
  501.                            }
  502.                            data = {
  503.                                process: {
  504.                                    comments: {
  505.                                        processComments: []
  506.                                    }
  507.                                }
  508.                            };
  509.                        }
  510.  
  511.                        if (!this.state.refetch) {
  512.                            this.setState({ refetch });
  513.                        }
  514.  
  515.                        return (
  516.                            <FlatList data={data.process.comments.processComments}
  517.                                refreshing={networkStatus === 4}
  518.                                onRefresh={refetch}
  519.                                keyExtractor={(item) => item.id}
  520.                                renderItem={({ item }) => (
  521.                                    <Comment comment={item} />
  522.                                )} />
  523.                        );
  524.                    }}
  525.                </Query>
  526.                <Footer>
  527.                    <Mutation mutation={COMMENT_PROCESS_MUTATION}>
  528.                        {(commentProcessStep, { data, error, networkStatus }) => (
  529.                            <TextInputComponent
  530.                                postFunction={commentProcessStep}
  531.                                data={data} networkStatus={networkStatus} error={error}
  532.                                variables={{
  533.                                    "processId": this.state.processId
  534.                                }}
  535.                                refetch={this.state.refetch}
  536.                            />
  537.                        )}
  538.                    </Mutation>
  539.                </Footer>
  540.            </Container>
  541.        );
  542.    }
  543. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement