#graphql #aws-amplify #react-admin
#graphql #aws-amplify #react-admin
Вопрос:
Я использую react-admin с Amplify. Один из моих типов graphql имеет поле AWSJSON, содержащее массив статусов для пакетного задания. Я бы хотел, чтобы этот массив отображался в datagrid, который пользователь может развернуть, чтобы увидеть результат каждого элемента в пакете.
Данные возвращаются из API в виде stringified JSON. Как я могу JSON.проанализировать данные, а затем передать их в arrayField для отображения с помощью Datagrid в моем списке / показать компоненты?
Содержимое поля выглядит следующим образом:
[{"reference":"11134","status":"OK"},{"reference":"10278","status":"OK"}]
ОБНОВЛЕНИЕ: приведенный ниже ответ был дан после того, как я немного обновил модель данных, чтобы:
[{"id": "somerandomuid", "clientReference":"11134","status":"OK"}]
Мой код выглядит так:
Схема:
type JobTask
@model
@auth(
rules: [
{ allow: owner }
{ allow: groups, groups: ["admins"] }
]
) {
id: ID!
results: AWSJSON
status: String
expiryDate: AWSTimestamp! @ttl
}
Показать компонент:
export const TaskShow = (props) => {
return (
<Show title={props.header} {...props}>
<SimpleShowLayout>
<Datagrid expand={<ResultsPanel />}>
<TextField
key={cuid()}
fullWidth={true}
source="id"
label="Batch Id"
/>
<TextField
key={cuid()}
fullWidth={true}
source="status"
label="Status"
/>
</Datagrid>
</SimpleShowLayout>
</Show>
);
Компонент ResultsPanel:
const ResultsPanel = (props) => {
console.log(props)
let resultsArray = JSON.parse(JSON.parse(props.record.results));
console.log(resultsArray);
return (
<>
{resultsArray.map((result) => {
return (
<ArrayField>
<Datagrid>
<TextField source="reference" />
<TextField source="status" />
</Datagrid>
</ArrayField>
);
})}
</>
);
};
Но все, что я получаю, это:
Комментарии:
1. Почему вы разбираете здесь дважды
JSON.parse(JSON.parse(props.record.results))
?2. Это очень хороший вопрос. По какой-то причине строка имеет двойную строку. Если я разбираю его только один раз, тип по-прежнему является строкой, и map завершается ошибкой.
3. Это интересно. Является ли строковое значение
'[{"reference":"11134","status":"OK"},{"reference":"10278","status":"OK"}]'
? Если разобрать это, я получу массив объектов на своей стороне. Кроме того, не могли бы вы поделиться этимTextField
компонентом? Не уверен, является ли это частью библиотеки или нет, но я боюсь, что вы действительно отображаете только имя поля, а не значение.4. это консольный журнал значений. Но на самом деле проблема не в этом. Проблема в том, как мне получить это проанализированное значение «в» компонент react admin datagrid?
5. Да, я разобрался с этим прошлой ночью. Проблема с исходным кодом в том, что вы правы, это строка. Я предполагаю, что он используется в качестве параметра функции внутри компонента. После долгой возни с list contextprovider я пришел к выводу, что это тоже не сработает. Подозреваю, что это связано с тем, что он должен находиться в компоненте списка, а не в компоненте показа.
Ответ №1:
Думал, что я опубликую свои выводы для всех, кто может столкнуться с этим.
Datagrid требует контекста, который для него предоставит компонент list, но поскольку это находится в компоненте show, я пытался вместо этого использовать Array для предоставления контекста.
Для компонента arrayField требуется исходный код, который должен быть строкой, которая точно соответствует полю / свойству в ответе API; это не может быть произвольный объект / массив. Однако свойство, которому соответствует строка, должно быть массивом, и нет способа сообщить компоненту обработать содержимое этого поля / свойства перед его использованием. Итак, Arrayfield отсутствует в качестве поставщика контекста.
Поскольку Array не работает с моей структурой данных, я подумал, что могу использовать RA listcontextprovider , который не очень хорошо документирован, но, похоже, позволяет вам создавать контекст, который может использоваться datagrid, насколько я могу судить. Но это всегда выдавало мне ошибку, когда я использовал его с правильными реквизитами (во всяком случае, насколько я мог судить — как я уже сказал, документация немного скудная).
В конце концов, я отказался от собственных компонентов RA как плохо подходящих для моего варианта использования и написал компонент пользовательского поля, который вместо этого делает то, что мне нужно (т. Е. Анализирует поле из записи и передает массив в datagrid для визуализации). Я использовал встроенную сетку данных MUI, которая работает как шарм:
const ResultsPanel = (props) => {
let resultsArray = JSON.parse(JSON.parse(props.record.results));
let columns = [
{ field: "id", headerName: "Item Id", flex: 1 },
{ field: "clientReference", headerName: "Your Reference", flex: 1 },
{ field: "status", headerName: "Import Status", flex: 1 },
];
return (
<div style={{ height: 400, width: "100%" }}>
<DataGrid columns={columns} rows={resultsArray} />
</div>
);
};