Могу ли я отобразить настройки фильтра на панели приложения ReactAdmin? - PullRequest
0 голосов
/ 30 марта 2020

Можно ли отобразить элементы моего текущего фильтра на панели приложения ReactAdmin?

Например, у меня есть фильтр команды для отображения результатов продаж для данной команды в компании. Этот бит все работает. Фильтр попадает в маршрут как идентификатор команды, а не имя. Я не уверен, возможно ли это изменить, и я, вероятно, не хочу в любом случае; но все равно я хотел бы отобразить выбранную команду name из фильтра на панели приложения.

Я уже настроил пользовательскую панель приложения, но информация, которая мне нужна, не кажется, что он недоступен в качестве подпорки для панели приложения.

В Redux Tools я вижу, что команды по идентификатору были предварительно загружены в admin\resources; но я не уверен, что макет этих предварительно загруженных элементов официально поддерживается? И нет ли каких-либо официальных сроков относительно того, когда они загружены? (Они должны быть там, потому что они были загружены для фильтра, поэтому логически я предполагаю (??), что тот, который мне нужен, должен быть там, когда выбрано значение фильтра ....)

Тогда, как Насколько я вижу, чтобы получить текущие настройки фильтра, мне нужно было бы извлечь что-то из части состояния router.

Я мог бы попытаться подключить свою пользовательскую панель приложений к Redux и извлечь вышеуказанные предметы. Я думаю, я мог бы заставить это работать - но это имеет сильный запах кода. Запах «сломается с любыми обновлениями ReactAdmin», возможно, смешанный с запахом «доступа к состоянию из неправильного места, в неподходящее время»!

Есть ли более чистый, более официальный способ go об этом?

1 Ответ

0 голосов
/ 01 апреля 2020

Я реализовал «официально не поддерживаемый» подход, который я предложил в своем собственном вопросе. Он работает нормально, но - честное предупреждение - насколько я знаю, он может перестать работать после обновления ReactAdmin.

Если я отработаю более официально поддерживаемый подход или мне удастся что-то зафиксировать из этого обратно в Проект ReactAdmin Я обновлю этот ответ.

Итак, вот пользовательский макет:

// CustomLayout.js
import React from 'react';
import { connect } from 'react-redux';
import { Layout, AppBar } from 'react-admin';
import Typography from '@material-ui/core/Typography';
import { makeStyles } from '@material-ui/core/styles';
import getFilterValue from './getFilterValue';

const useStyles = makeStyles(
  theme => ({
    title: {
      flex: 1,
      textOverflow: 'ellipsis',
      whiteSpace: 'nowrap',
      overflow: 'hidden',
    },
  }),
  { name: 'RaAppBar' }
);

const CustomAppBarUnconnected = (props) => {
  const classes = useStyles(props);
  const { title } = props;
  return (
    <AppBar
      {...props}
    >
      <Typography
        variant="h6"
        color="inherit"
        className={classes.title}
      >
        { title }
      </Typography>
    </AppBar>
  );
}

const mapStateToProps = (state, props) => {
  let team = getFilterValue(state, 'teamId', 'teams'); //, 'name');
  let previousMonth = getFilterValue(state, 'previousMonth');
  let title = `${team ? team.name : 'Company'} Sales. ${previousMonth ? `Previous month = ${previousMonth}` : 'Nothing to see here'}.`;
  return {
    ...props,
    title
  };
};

const CustomAppBar = connect(
  mapStateToProps,
)(CustomAppBarUnconnected);

export const CustomLayout = (props) =>
  <Layout
    {...props}
    appBar={ CustomAppBar }
  />;

Примените это в своем приложении ReactAdmin, используя <Admin layout={CustomLayout}>. Вот пример выходных данных:

enter image description here

Большая часть пользовательского макета представляет собой просто шаблон, необходимый для получения пользовательской панели приложения, которая выглядит как панель по умолчанию: она проходит дочерние элементы к стандартной панели приложений, применяя форматирование, необходимое для того, чтобы заголовок выглядел точно так же, как стандартный заголовок.

Если вы хотите, чтобы заголовок по умолчанию отображался вместе с вашим настраиваемым заголовком, добавьте <span id="react-admin-title" /> там, где вы хотите, чтобы он появился (предположительно, где-то рядом с { title }).

Если вы также хотите более тщательно перестроить панель приложения, то (следуя документации ReactAdmin ), вы бы необходимо создать новый пользовательский класс AppBar с нуля, начиная с исходного класса ReactAdmin AppBar . Затем просто свяжите его с Redux, как я делал выше.

Ключевое изменение в этой пользовательской компоновке заключается в том, что AppBar теперь подключен к Redux, что означает, что в mapStateToProps мы можем вызвать новый function getFilterValue:

// getFilterValue.js
const getFilterValue = (state, source, resource, field) => {
  let value = undefined;

  if (!state || !source) return value;

  const filterJSON =
    state.router &&
    state.router.location &&
    state.router.location.query &&
    state.router.location.query.filter;

  if (filterJSON) {
    let filter = JSON.parse(decodeURIComponent(filterJSON));

    let id = filter && filter[source];

    if (id !== undefined) {
      if (!resource) {
        value = id;
      } else {
        const data =
          state.admin &&
          state.admin.resources &&
          state.admin.resources[resource] &&
          state.admin.resources[resource].data;

        if (data) {
          value = data[id];
          if (field) {
            value = value[field];
          }
        }
      }
    }
  }

  return value;
};

export default getFilterValue;

В зависимости от того, какие аргументы вы передаете getFilterValue, вы можете:

  • Получить необработанный элемент из фильтра: (state, source)
  • Сопоставить необработанный идентификатор элемента из фильтра с объектом, уже выбранным из API: (state, source, resource)
  • Сопоставить идентификатор из фильтра с элементом и затем извлечь именованное поле из элемента: (state, source, resource, field)

undefined всегда возвращается, если требуемое значение не существует; например, если вы не находитесь на странице с запрошенным фильтром, или если фильтр еще не был применен пользователем, или вы сделали опечатку в любом из аргументов.

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