Миграция кода Apollo из стиля 1.x в 2.1 - PullRequest
0 голосов
/ 01 октября 2018

Я следую коду, который работает правильно, и делаю все, что мне нужно, он содержит запрос, мутации и подписку.Код ниже является частью для панели администратора, я могу добавлять, редактировать и удалять элементы, в то же время все работает в режиме реального времени через подписку Apollo.Все остальные части приложения ориентированы на совместную работу, поэтому этот код является базовым для всего приложения.

TeamManagement.js

import React from 'react';
import gql from 'graphql-tag';
import { graphql, compose } from 'react-apollo';
import { Table } from 'semantic-ui-react';
import TeamRowRender from './TeamRowRender';
import AddNewTeam from './AddNewTeam';

const GET_ALL_TEAMS = gql`
  query {
    getAllTeams {
      id
      name
      description
      created
    }
  }
`;

const ADD_TEAM = gql`
  mutation($name: String!, $description: String!) {
    addTeam(name: $name, description: $description) {
      id
      name
      description
      created
    }
  }
`;

const UPDATE_TEAM = gql`
  mutation($id: String!, $name: String!, $description: String!) {
    updateTeam(id: $id, name: $name, description: $description) {
      id
      name
      description
      created
    }
  }
`;

const REMOVE_TEAM = gql`
  mutation($id: String!) {
    removeTeam(id: $id) {
      id
      name
      description
      created
    }
  }
`;

const TEAM_UPDATED = gql`
  subscription {
    teamUpdated {
      mutation
      team {
        id
        name
        description
        created
      }
    }
  }
`;

class TeamManagementView extends React.Component {
  constructor(props) {
    super(props);
    this.handleAdd = this.handleAdd.bind(this);
    this.handleUpdate = this.handleUpdate.bind(this);
    this.handleRemove = this.handleRemove.bind(this);
  }

  componentDidMount() {
    console.log('Component TeamManagementView:', 'componentDidMount', this.props);
    this.props.subscribeToUpdates();
  }

  componentWillUnmount() {
    // Unsibscribe subscription
    // this.querySubscription.unsubscribe();
  }

  handleAdd(name, description) {
    console.log(
      'Component TeamManagement:',
      'handleAdd:',
      'name:',
      name,
      'description:',
      description
    );
    this.props.submit_add_team(name, description);
  }

  handleUpdate(id, name, description) {
    console.log('Component TeamManagement:', 'handleUpdate:', id, name, description);
    this.props.submit_update_team(id, name, description);
  }

  handleRemove(id) {
    console.log('Component TeamManagement:', 'handleRemove:', 'id:', id);
    this.props.submit_remove_team(id);
  }

  render() {
    console.log('Component TeamManagement:', 'this.props:', this.props);
    if (this.props.teams.loading) {
      return <div>Loading</div>;
    }
    if (this.props.teams.error) {
      console.log(this.props.teams.error);
      return <div>Error</div>;
    }
    const teamsToRender = this.props.teams.getAllTeams;
    const rowsTeams = teamsToRender.map((team) => (
      <TeamRowRender
        team={team}
        key={team.id}
        handleUpdate={this.handleUpdate}
        handleRemove={this.handleRemove}
      />
    ));

    return (
      <div>
        <Table celled>
          <Table.Header>
            <Table.Row>
              <Table.HeaderCell>ID</Table.HeaderCell>
              <Table.HeaderCell>Name</Table.HeaderCell>
              <Table.HeaderCell>Description</Table.HeaderCell>
              <Table.HeaderCell>Created</Table.HeaderCell>
              <Table.HeaderCell textAlign="center">Action</Table.HeaderCell>
            </Table.Row>
          </Table.Header>
          <Table.Body>{rowsTeams}</Table.Body>
        </Table>
        <AddNewTeam handleAdd={this.handleAdd} />
      </div>
    );
  }
}

const TeamManagement = compose(
  graphql(GET_ALL_TEAMS, {
    name: 'teams',
    props: (props) =>
      Object.assign({}, props, {
        subscribeToUpdates: (params) => {
          return props.teams.subscribeToMore({
            document: TEAM_UPDATED,
            variables: {
              name: 'Teams'
            },
            updateQuery: (prev, { subscriptionData }) => {
              if (!subscriptionData.data) {
                return prev;
              }
              console.log('subscriptionData.data:', subscriptionData.data);
              switch (subscriptionData.data.teamUpdated.mutation) {
                case 'teamAdded':
                  console.log('Subscription mutation: teamAdded detected');
                  console.log(prev);
                  const newTeam = subscriptionData.data.teamUpdated.team;
                  return Object.assign({}, prev, {
                    getAllTeams: [newTeam, ...prev.getAllTeams]
                  });
                case 'removeTeam':
                  console.log('Subscription mutation: removeTeam detected');
                  return Object.assign({}, prev, {
                    getAllTeams: prev.getAllTeams.filter(
                      (team) => team.id !== subscriptionData.data.teamUpdated.team.id
                    )
                  });
                case 'updateTeam':
                  console.log('Subscription mutation: updateTeam detected');
                  const updindex = prev.getAllTeams.findIndex(
                    (team) => team.id === subscriptionData.data.teamUpdated.team.id
                  );
                  const updteams = Object.assign([], prev.getAllTeams);
                  const updteam = subscriptionData.data.teamUpdated.team;
                  updteams.splice(updindex, 1, updteam);
                  return Object.assign({}, prev, {
                    getAllTeams: updteams
                  });
                default:
                  console.log('Subscription mutation: can not recognize mutation');
              }
            },
            onError: (err) => console.error(err)
          });
        }
      })
  }),
  graphql(ADD_TEAM, {
    props: ({ mutate }) => ({
      submit_add_team: (name, description) => mutate({ variables: { name, description } })
    })
  }),
  graphql(UPDATE_TEAM, {
    props: ({ mutate }) => ({
      submit_update_team: (id, name, description) =>
        mutate({ variables: { id, name, description } })
    })
  }),
  graphql(REMOVE_TEAM, {
    props: ({ mutate }) => ({
      submit_remove_team: (id) => mutate({ variables: { id } })
    })
  })
)(TeamManagementView);

export default TeamManagement;

TeamRowRender.js

import React from 'react';

import { Table, Button, Input } from 'semantic-ui-react';

class TeamRowRender extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isEditStatus: false,
      name: '',
      description: ''
    };
    this.handleEdit = this.handleEdit.bind(this);
    this.handleCancel = this.handleCancel.bind(this);
    this.handleNameChange = this.handleNameChange.bind(this);
    this.handleDescriptionChange = this.handleDescriptionChange.bind(this);
    this.handleSubmitSave = this.handleSubmitSave.bind(this);
    this.handleSubmitRemove = this.handleSubmitRemove.bind(this);
  }

  handleEdit() {
    // console.log('Component RowRender:', 'handleEdit:');
    this.setState({
      isEditStatus: true,
      name: this.props.team.name,
      description: this.props.team.description
    });
  }

  handleCancel() {
    // console.log('Component RowRender:', 'handleCancel:');
    this.setState({
      isEditStatus: false,
      name: '',
      description: ''
    });
  }

  handleNameChange(event) {
    this.setState({ name: event.target.value });
  }

  handleDescriptionChange(event) {
    this.setState({ description: event.target.value });
  }

  handleSubmitSave(id) {
    console.log('Component RowRender:', 'handleSubmitSave:', 'id:', id);
    this.props.handleUpdate(id, this.state.name, this.state.description);
    this.setState({
      isEditStatus: false,
      name: '',
      description: ''
    });
  }

  handleSubmitRemove(id) {
    console.log('Component RowRender:', 'handleSubmitRemove:', 'id:', id);
    this.props.handleRemove(id);
  }

  render() {
    // console.log('Component RowRender:', 'this.props:', this.props);
    // console.log('Component RowRender:', 'this.state:', this.state);
    const dateTime = new Date(this.props.team.created / 1000);
    const creationDate = dateTime.toGMTString();

    if (this.state.isEditStatus === true) {
      return (
        <Table.Row>
          <Table.Cell>{this.props.team.id}</Table.Cell>
          <Table.Cell>
            <Input
              size="small"
              type="text"
              value={this.state.name}
              onChange={this.handleNameChange}
            />
          </Table.Cell>
          <Table.Cell>
            <Input
              size="small"
              type="text"
              value={this.state.description}
              onChange={this.handleDescriptionChange}
            />
          </Table.Cell>
          <Table.Cell>{creationDate}</Table.Cell>
          <Table.Cell textAlign="right">
            <Button size="small" basic color="green" onClick={this.handleCancel}>
              Cancel
            </Button>
            <Button
              size="small"
              basic
              color="blue"
              onClick={() => this.handleSubmitSave(this.props.team.id)}
            >
              Save
            </Button>
          </Table.Cell>
        </Table.Row>
      );
    }
    return (
      <Table.Row>
        <Table.Cell>{this.props.team.id}</Table.Cell>
        <Table.Cell>{this.props.team.name}</Table.Cell>
        <Table.Cell>{this.props.team.description}</Table.Cell>
        <Table.Cell>{creationDate}</Table.Cell>
        <Table.Cell textAlign="right">
          <Button size="small" basic color="green" onClick={this.handleEdit}>
            Edit
          </Button>
          <Button
            size="small"
            basic
            color="red"
            onClick={() => this.handleSubmitRemove(this.props.team.id)}
          >
            Remove
          </Button>
        </Table.Cell>
      </Table.Row>
    );
  }
}

export default TeamRowRender;

Ниже моего попытки переписать код, который используется в компонентах Apollo 2.1 {Query}, мне нужна та же функциональность с объединением мутаций, запросов и подписок.

Ранее я мог запускать код из props: this.props.submit_add_team (name, description);Как мне нужно сделать то же самое со стилем apollo 2.1 ..

StudiosWithData.js

import React from 'react';
import gql from 'graphql-tag';
import { graphql, compose } from 'react-apollo';
import { Query } from 'react-apollo';
import { Table } from 'semantic-ui-react';
import StudioRowRender from './StudioRowRender';

const GET_ALL_STUDIOS = gql`
  query {
    getAllStudios {
      id
      name
      description
      team {
        id
        name
        description
      }
    }
  }
`;

const UPDATE_STUDIO = gql`
  mutation($id: String!, $name: String!, $description: String!) {
    updateStudio(id: $id, name: $name, description: $description) {
      id
      name
      description
      team {
        id
        name
        description
      }
    }
  }
`;

const REMOVE_STUDIO = gql`
  mutation($id: String!) {
    removeStudio(id: $id) {
      id
    }
  }
`;

const STUDIOS_SUBSCRIPTION = gql`
  subscription {
    studioUpdated {
      mutation
      studio {
        id
        name
        description
        team {
          id
          name
          description
        }
      }
    }
  }
`;

class Studios extends React.Component {
  componentDidMount() {
    this.props.subscribeToMore();
  }
  render() {
    console.log('Component Studios:', 'this.props:', this.props);

    const studiosToRender = this.props.data.getAllStudios;
    const rowsStudios = studiosToRender.map((studio) => (
      <StudioRowRender studio={studio} key={studio.id} />
    ));

    return (
      <div>
        <h5>Studios</h5>
        <Table celled>
          <Table.Header>
            <Table.Row>
              <Table.HeaderCell>ID</Table.HeaderCell>
              <Table.HeaderCell>Name</Table.HeaderCell>
              <Table.HeaderCell>Description</Table.HeaderCell>
            </Table.Row>
          </Table.Header>
          <Table.Body>{rowsStudios}</Table.Body>
        </Table>
      </div>
    );
  }
}

const withRemove = graphql(REMOVE_STUDIO, {
  props: ({ data }) => ({
    loadingRemove: data.loading,
    remove: data.remove
  })
});

const withUpdate = graphql(UPDATE_STUDIO, {
  props: ({ data }) => ({
    loadingUpdate: data.loading,
    update: data.update
  })
});

const StudiosWithData = () => (
  <Query query={GET_ALL_STUDIOS}>
    {({ loading, error, data, subscribeToMore }) => {
      if (loading) return <p>Loading...</p>;
      if (error) return <p>Error: {error.message}</p>;
      const subscribeToUpdates = () =>
        subscribeToMore({
          document: STUDIOS_SUBSCRIPTION,
          updateQuery: (prev, { subscriptionData }) => {
            console.log('subscriptionData.data:', subscriptionData.data);
            if (!subscriptionData.data) return prev;
          }
        });
      return <Studios data={data} subscribeToMore={subscribeToUpdates} />;
    }}
  </Query>
);

export default StudiosWithData;

StudioRowRender.js

import React from 'react';

import { Table, Button, Input } from 'semantic-ui-react';

class StudioRowRender extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <Table.Row>
        <Table.Cell>{this.props.studio.id}</Table.Cell>
        <Table.Cell>{this.props.studio.name}</Table.Cell>
        <Table.Cell>{this.props.studio.description}</Table.Cell>
      </Table.Row>
    );
  }
}

export default StudioRowRender;
...