Создание интерактивных информационных панелей с помощью Airtable и React
Опубликовано: 2022-03-11Независимо от того, является ли компания крупным предприятием или начинающим стартапом, сбор данных от пользователей и клиентов, а также отчетность или визуализация этих данных имеют решающее значение для бизнеса.
Недавно я работал с телемедицинским стартапом в Бразилии. Его миссия состоит в том, чтобы обеспечить удаленный уход и мониторинг, соединяя пациентов с медицинскими работниками и тренерами по здоровью. Основная потребность состояла в том, чтобы создать интерфейс для тренеров и медицинских работников, чтобы они могли легко просматривать информацию о пациенте и наиболее важные показатели, связанные с их конкретной ситуацией: панель инструментов.
Введите Typeform и Airtable.
Форма шрифта
Typeform — это один из самых популярных инструментов для сбора данных, который обеспечивает адаптивный веб-интерфейс для пользователей, заполняющих опрос. Он также имеет несколько функций, которые делают опросы более интеллектуальными, особенно в сочетании:
- Логические прыжки
- Скрытые поля
Опросами можно делиться через URL-адреса, которые могут быть предварительно заполнены значениями для скрытых полей, которые затем можно использовать для реализации логических переходов и изменения поведения опроса для пользователя со ссылкой.
Использование Airtable
Airtable — это гибрид электронной таблицы и базы данных и облачная платформа для совместной работы. Его ориентация на функциональность «укажи и щелкни» означает, что пользователи, не являющиеся техническими специалистами, могут настроить его без кодирования. Airtable имеет множество вариантов использования в любом бизнесе или проекте.
Вы можете использовать Airtable Base для:
- CRM (управление взаимоотношениями с клиентами)
- HRIS (Информационная система управления персоналом)
- Управление проектом
- Контент-планирование
- Планировка события
- Отзывы пользователей
Есть еще много потенциальных вариантов использования. Вы можете ознакомиться с кейсами Airtable здесь.
Если вы не знакомы с Airtable, концептуальная модель данных выглядит следующим образом:
- Рабочее пространство — состоит из оснований
- База - состоит из таблиц
- Таблица — состоит из полей (столбцов) и строк
- Представление — перспектива данных таблицы с дополнительными фильтрами и уменьшенными полями.
- Поле — столбец таблицы с типом поля; см. здесь для получения дополнительной информации о типах полей
Помимо размещения базы данных в облаке со знакомыми функциями электронных таблиц, вот несколько причин, по которым платформа настолько мощна:
Для нетехнических пользователей Airtable предоставляет:
- Простой в использовании внешний интерфейс
- Автоматизация, которую можно создать с помощью конфигурации «укажи и щелкни» для отправки электронных писем, обработки строк данных, планирования встреч в календарях и т. д.
- Несколько типов представлений, которые позволяют командам совместно работать над одной и той же базой и таблицами.
- Приложения Airtable, которые можно установить из магазина, чтобы увеличить базу
Для разработчиков Airtable предоставляет:
- Хорошо документированный внутренний API
- Среда сценариев, которая позволяет разработчикам автоматизировать действия в базе.
- Автоматизация, которая также может запускать специально разработанные сценарии, которые запускаются в среде Airtable, расширяя возможности автоматизации.
Вы можете узнать больше об Airtable здесь.
Начало работы: Typeform для Airtable
Опросы Typeform уже были настроены клиентом, и следующим шагом было планирование того, как эти данные попадут в Airtable, а затем превратятся в панель мониторинга. При создании информационных панелей поверх любой базы данных возникает множество вопросов: Как мы должны структурировать данные? Какие данные нужно будет обработать перед визуализацией? Должны ли мы синхронизировать базу с Google Sheets и использовать Google Data Studio? Должны ли мы экспортировать и найти другой сторонний инструмент?
К счастью для разработчиков, Airtable не только обеспечивает автоматизацию и сценарии для выполнения этапов обработки данных, но также позволяет создавать собственные приложения и интерфейсы поверх базы Airtable с приложениями Airtable.
Пользовательские приложения в Airtable
Пользовательские приложения в Airtable существуют с тех пор, как в начале 2018 года был выпущен SDK Airtable Blocks, и недавно они были переименованы в Приложения. Выпуск Blocks был огромным, поскольку это означало, что у создателей теперь была возможность разработать, как выразился Airtable, «бесконечно рекомбинируемый набор Lego».
Совсем недавно, с изменением приложений, Airtable Marketplace также позволил публично делиться приложениями.
Приложения Airtable предоставляют предприятиям набор Lego, который можно бесконечно комбинировать, чтобы они могли адаптировать его к своим потребностям.
Чтобы создать пользовательское приложение в Airtable, разработчик JavaScript должен знать, как использовать React, одну из самых популярных библиотек JavaScript для создания пользовательских интерфейсов. Airtable предоставляет библиотеку функциональных компонентов и хуков React, которые очень помогают быстро создать согласованный пользовательский интерфейс и определить, как вы будете управлять состоянием в приложении и его компонентах.
Прочтите статью Airtable «Начало работы» для получения дополнительной информации и Airtable на GitHub для получения примеров приложений.
Требования к панели управления Airtable
После просмотра макетов панели мониторинга с командой клиента стало ясно, какие типы данных следует использовать. Нам потребуется ряд компонентов панели мониторинга, которые будут отображаться в виде текста на панели инструментов и диаграмм различных показателей, которые можно будет отслеживать с течением времени.
Тренеры и медицинские работники должны были иметь возможность создавать индивидуальные информационные панели для каждого пациента, поэтому нам нужен был гибкий способ добавления и удаления диаграмм. Другие статические данные, относящиеся к каждому пациенту, будут отображаться независимо от выбранного пациента.
В этом случае разделы приборной панели сводились к:
- Общая информация - имя пациента, адрес электронной почты, номер телефона, контактные данные, дата рождения, возраст
- Цели — цели, поставленные пациентом на основе результатов опроса.
- Некоторые статистические данные - ИМТ, рост и вес
- Использование лекарств — перечисление всех отпускаемых по рецепту лекарств, уже используемых пациентом.
- Семейный анамнез состояний — помогает в диагностике определенных состояний.
- Диаграммы — раздел, в котором пользователь панели инструментов Airtable может добавить диаграмму и настроить, какие показатели будут отображаться с течением времени.
Один из способов приблизиться ко всем разделам, кроме диаграмм, — это жестко закодировать все столбцы для целей, использования лекарств и семейной истории на панели инструментов. Однако это не позволит команде клиента добавлять новые вопросы в опрос Typeform или добавлять новый столбец в таблицу Airtable для представления этих данных на панели инструментов без обновления пользовательского приложения разработчиком.
Более элегантным и расширяемым решением этой проблемы было найти способ пометить столбцы как относящиеся к определенному разделу информационной панели и получить эти столбцы с помощью метаданных, которые Airtable предоставляет при использовании моделей Table и Field.
Это было достигнуто с помощью описания полей в качестве места для пометки столбца из таблицы как относящегося к разделу информационной панели, который будет отображаться для пользователя. Затем мы могли гарантировать, что только те, у кого есть роль создателя (администраторы) для базы, имели возможность изменять эти описания полей, чтобы изменить то, что отображается на панели инструментов. Чтобы проиллюстрировать это решение, мы сосредоточимся в основном на элементах общей информации и на том, как представлять диаграммы.
Создание системы #TAG#
Учитывая разделы панели инструментов, имело смысл сделать многоразовые теги для некоторых разделов и специальные теги для определенных столбцов. Для таких элементов, как имя пациента, адрес электронной почты и номер телефона, в описание каждого поля были добавлены #NAME# , #EMAIL# и #PHONE# соответственно. Это позволит получить эту информацию через метаданные таблицы следующим образом:
const name = table ? table.fields.filter(field => field.description?.includes("#NAME#"))Для областей информационной панели, которые должны быть извлечены из множества столбцов с тегами, у нас будут следующие теги для каждого раздела информационной панели:
- ОБЖ — Цели
- FAM - Семейная история
- MED — Использование в медицине
- CAN - Семейный анамнез, специфичный для рака
- CHART — любой столбец, который должен быть источником для добавления диаграмм; должно быть количество
Кроме того, было важно отделить имя столбца в таблице от метки, которую он получит на панели инструментов, поэтому все, что получило #TAG# , также могло получить два #LABEL# в своем описании поля. . Описание поля будет выглядеть так:
Если теги #LABEL# отсутствуют, мы будем отображать имя столбца из Таблицы.
Мы можем проанализировать набор меток в описании с помощью простой функции, подобной этой, после извлечения поля с помощью предыдущего примера кода:
// utils.js export const setLabel = (field, labelTag = "#LABEL#") => { const labelTags = (field.description?.match(new RegExp(labelTag, "g")) || []).length; let label; if (labelTags === 2) label = field.description?.split(`${labelTag}`)[1]; if (!label || label?.trim() === '') label = field.name; return {...field, label, name: field.name, description: field.description}; } С помощью этой системы #TAG# мы достигаем трех основных целей:
- Названия столбцов (полей) в Таблице можно изменить по желанию.
- Метки данных на панели мониторинга могут отличаться от имен столбцов.
- Разделы информационной панели «Цели», «Применение лекарств», «Семейный анамнез» и «Диаграммы» могут обновляться командой клиента, не затрагивая ни строчки кода.
Сохраняющееся состояние в Airtable
В React мы используем состояние и передаем его компонентам в качестве свойств, чтобы повторно отобразить этот компонент, если его состояние изменится. Обычно это связано с вызовом API, который подпитывает компонент информационной панели, но в Airtable у нас уже есть все данные, и нам просто нужно отфильтровать то, что мы отображаем, в зависимости от того, какого пациента мы просматриваем. Кроме того, если мы используем состояние, оно не будет сохранять данные после обновления на самой приборной панели.
Итак, как мы можем сохранить значение после обновления, чтобы панель мониторинга оставалась отфильтрованной? К счастью, Airtable предоставляет для этого хук под названием useGlobalConfig, в котором он поддерживает хранилище ключей и значений для установки приложения на панели инструментов. Нам просто нужно реализовать логику извлечения значений из этого хранилища ключей и значений, когда приложение загружается, чтобы подпитывать наши компоненты панели.
Что еще более полезно в использовании хука useGlobalConfig , так это то, что когда его значения установлены, компонент панели мониторинга и его дочерние компоненты повторно визуализируются, поэтому вы можете использовать Global Config, как если бы вы использовали переменную состояния в типичной реализации React.
Знакомство с диаграммами
Airtable предоставляет примеры диаграмм в своем приложении Simple Chart, которое использует React Charts, оболочку React для Chart.js (chart-ception).

В приложении Simple Chart у нас есть одна диаграмма для всего приложения, но в нашем приложении Dashboard нам нужна возможность, чтобы пользователь мог добавлять и удалять свои собственные диаграммы со своей панели инструментов. Более того, в ходе обсуждения с клиентской командой выяснилось, что некоторые показатели лучше отображать на одном графике (например, показатели диастолического и систолического артериального давления).
При этом нам предстоит решить следующие задачи:
- Сохраняющееся состояние для каждого пользовательского графика (или, что еще лучше, с помощью Global Config)
- Разрешение нескольких метрик на диаграмму
Именно здесь пригодится мощь Global Config, поскольку мы можем использовать хранилище ключей и значений для сохранения выбранных метрик и всего остального в нашем списке диаграмм. Когда мы настраиваем диаграмму в пользовательском интерфейсе, сам компонент диаграммы будет повторно отображаться из-за обновлений глобальной конфигурации. Для раздела диаграмм панели инструментов, вот суть с компонентами для справки, с акцентом на диаграммы панели инструментов charts.js и одиночный файл chart.js.
Таблица , передаваемая каждой диаграмме, используется для ее метаданных для поиска полей, в то время как переданные записи уже были отфильтрованы пациентом, выбранным в компоненте панели мониторинга верхнего уровня, который импортирует dashboard_charts/index.js .
Обратите внимание, что поля, указанные как параметры в раскрывающемся списке для диаграммы, извлекаются с использованием тега #CHART# , о котором мы упоминали ранее, с этой строкой в useEffect :
// single_chart/index.js … useEffect(() => { (async () => { ... if (table) { const tempFieldOptions = table.fields.filter(field => field.description?.includes('#CHART#')).map(field => { return { ...setLabel(field), value: field.id } }); setFieldSelectOptions([...tempFieldOptions]); } })(); }, [table, records, fields]); ... В приведенном выше коде показано, как упомянутая ранее функция setLabel используется с тегом #TAG# для добавления всего, что содержится в тегах #LABEL# , и отображения этого параметра в раскрывающемся списке полей.
Наш компонент диаграммы использует преимущества многоосевых возможностей, предоставляемых Chart.js, что показано с помощью React Charts. Мы только что расширили его через пользовательский интерфейс, добавив пользователю возможность добавлять набор данных и тип диаграммы (линейная или гистограмма).
Ключом к использованию Global Config в этом случае является знание того, что каждый ключ может содержать только строку | логический | номер | ноль | Глобальный массив конфигурации | GlobalConfigObject (см. справочник по значениям глобальной конфигурации).
У нас есть следующие элементы, которые необходимо поддерживать для каждого графика:
- chartTitle , который генерируется автоматически и может быть переименован пользователем.
- массив fields , в котором каждый элемент имеет:
- поле как fieldId из Airtable
- chartOption одной строкой | бар, как указано в документах Chart.js
- цвет как цвет Airtable из colorUtils
- hex как шестнадцатеричный код, относящийся к цвету Airtable.
Чтобы справиться с этим, я счел наиболее удобным преобразовать эти данные в строку как объект вместо того, чтобы устанавливать ключи и значения Global Config до конца. См. пример ниже (globalConfig.json в сути), который включает значения Global Config для фильтрации записей по пациенту и некоторые связанные переменные, используемые для поддержки компонента фильтрации typeahead (спасибо react-bootstrap-typeahead):
{ "xCharts": { "chart-1605425876029": "{\"fields\":[{\"field\":\"fldxLfpjdmYeDOhXT\",\"chartOption\":\"line\",\"color\":\"blueBright\",\"hex\":\"#2d7ff9\"},{\"field\":\"fldqwG8iFazZD5CLH\",\"chartOption\":\"line\",\"color\":\"blueLight1\",\"hex\":\"#9cc7ff\"}],\"chartTitle\":\"Grafico criado em 11/15/2020, 2:37:56 AM\"}", "chart-1605425876288": "{\"fields\":[{\"field\":\"fldGJZIdRlq3V3cKu\",\"chartOption\":\"line\",\"color\":\"blue\",\"hex\":\"#1283da\"}],\"chartTitle\":\"Grafico criado em 11/15/2020, 2:37:56 AM\"}", "chart-1605425876615": "{\"fields\":[{\"field\":\"fld1AnNcfvXm8DiNs\",\"chartOption\":\"line\",\"color\":\"blueLight1\",\"hex\":\"#9cc7ff\"},{\"field\":\"fldryX5N6vUYWbdzy\",\"chartOption\":\"line\",\"color\":\"blueDark1\",\"hex\":\"#2750ae\"}],\"chartTitle\":\"Grafico criado em 11/15/2020, 2:37:56 AM\"}", "chart-1605425994036": "{\"fields\":[{\"field\":\"fld9ak8Ja6DPweMdJ\",\"chartOption\":\"line\",\"color\":\"blueLight2\",\"hex\":\"#cfdfff\"},{\"field\":\"fldxVgXdZSECMVEj6\",\"chartOption\":\"line\",\"color\":\"blue\",\"hex\":\"#1283da\"}],\"chartTitle\":\"Grafico criado em 11/15/2020, 2:39:54 AM\"}", "chart-1605430015978": "{\"fields\":[{\"field\":\"fldwdMJkmEGFFSqMy\",\"chartOption\":\"line\",\"color\":\"blue\",\"hex\":\"#1283da\"},{\"field\":\"fldqwG8iFazZD5CLH\",\"chartOption\":\"line\",\"color\":\"blueLight1\",\"hex\":\"#9cc7ff\"}],\"chartTitle\":\"New Chart\"}", "chart-1605430916029": "{\"fields\":[{\"field\":\"fldCuf3I2V027YAWL\",\"chartOption\":\"line\",\"color\":\"blueLight1\",\"hex\":\"#9cc7ff\"},{\"field\":\"fldBJjtRkWUTuUf60\",\"chartOption\":\"line\",\"color\":\"blueDark1\",\"hex\":\"#2750ae\"}],\"chartTitle\":\"Grafico criado em 11/15/2020, 4:01:56 AM\"}", "chart-1605431704374": "{\"fields\":[{\"field\":\"fld7oBtl3iiHNHqoJ\",\"chartOption\":\"line\",\"color\":\"blue\",\"hex\":\"#1283da\"}],\"chartTitle\":\"Grafico criado em 11/15/2020, 4:15:04 AM\"}" }, "xPatientEmail": "[email protected]", "xTypeaheadValue": "Elle Gold ([email protected])", "xSelectedValue": "[{\"label\":\"Elle Gold ([email protected])\",\"id\":\"[email protected]\",\"name\":\"Elle Gold\",\"email\":\"[email protected]\"}]" }Примечание. Все данные, содержащиеся выше, и данные, включенные в анимацию ниже, не являются реальными данными пациента.
Вот посмотрите на окончательный результат:
Что насчет шрифта?
Для фильтрации по пациенту нам нужен был способ выбрать пациента, а затем отфильтровать записи на основе этого пациента. В этом разделе мы рассмотрим, как это было достигнуто.
Для typeahead, react-bootstrap-typeahead был простым выбором, так как оставалось только подготовить параметры для typeahead, смешать его с вводом Airtable для стилизации и загрузки bootstrap, а также некоторые другие стили для нашего меню. Перетаскивание компонентов из ваших любимых библиотек компонентов в приложение Airtable не так просто, как в типичной веб-разработке React; однако есть всего несколько дополнительных шагов, чтобы все выглядело так, как вы ожидаете.
Вот окончательный результат:
Чтобы отобразить ввод Airtable и сохранить согласованность всех наших стилей, react-bootstrap-typeahead поставляется с реквизитом renderInput. Подробнее о том, как изменить визуализацию компонента, см. здесь.
Для стилей начальной загрузки и для переопределения наших пунктов меню были использованы следующие две утилиты из Airtable:
- loadCSSFromString
- loadCSSFromURLAsync
См. суть frontend.js для выдержки из реализации typeahead.
Эта строка использовалась для глобальной загрузки бутстрапа:
// frontend/index.js loadCSSFromURLAsync('https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css'); Вы заметите некоторую добавленную логику для таких вещей, как обработка изменений стиля при наведении или рестайлинг ссылок ( <a></a> ), чтобы получить знакомый внешний вид начальной загрузки. Это также включает в себя настройку значений Global Config для опережающего ввода и фильтрацию записей, чтобы, если пользователь покидает свою панель мониторинга, обновлял свою страницу или хотел поделиться этой панелью с другими, приложение сохраняло выбранного пациента на панели инструментов. Приложение. Это также позволяет пользователям устанавливать несколько копий одного и того же приложения рядом на одной и той же панели управления Airtable с разными выбранными пациентами или с разными диаграммами.
Имейте в виду, что информационная панель в Airtable также доступна для всех пользователей Base, поэтому эти пользовательские установки приложений на информационной панели будут отфильтрованы для одних и тех же пациентов и диаграмм независимо от того, какие пользователи просматривают информационную панель в одно и то же время.
Давайте подытожим то, что мы рассмотрели до сих пор:
- Airtable позволяет как нетехническим пользователям, так и техническим пользователям сотрудничать в Airtable.
- Typeform поставляется с интеграцией Airtable, которая позволяет нетехническим пользователям сопоставлять результаты Typeform с Airtable.
- Приложения Airtable — это мощный способ расширить свою базу Airtable, независимо от того, выбираете ли вы на рынке или создаете собственное приложение.
- С помощью этих приложений разработчики могут быстро расширять Airtable практически любым возможным способом. Наш приведенный выше пример занял всего три недели, чтобы спроектировать и реализовать (конечно, с огромной помощью существующих библиотек).
- Систему
#TAG#можно использовать для изменения панели инструментов, не требуя изменения кода разработчиками. Для этого есть лучшие и худшие варианты использования. Обязательно ограничьте разрешения ролью Creator, если используете эту стратегию. - Использование Global Config позволяет разработчикам сохранять данные в установке приложения. Смешайте это со своей стратегией управления состоянием, чтобы заполнить данные для ваших компонентов.
- Не рассчитывайте перетаскивать компоненты из других библиотек и проектов прямо в ваше приложение Airtable. Стили можно загружать с помощью
loadCSSFromStringиloadCSSFromURLAsync, предоставляемых Airtable.
Перспектива
Используйте более сложное промежуточное ПО
С Typeform и Airtable легко и экономично настроить сопоставление вопросов со столбцами.
Однако есть один большой недостаток: если у вас есть опрос из более чем 100 вопросов, сопоставленных с Airtable, и вам нужно изменить сопоставление, вы должны удалить все сопоставление и начать заново. Это явно не идеально, но для бесплатной интеграции с этим можно справиться.
Другими вариантами могут быть интеграция Zapier (или аналогичной) для управления данными между Typeform и Airtable. Затем вы можете изменить сопоставление любого вопроса с любым столбцом, не начиная с нуля. Это также будет иметь свои собственные соображения по стоимости.
Надеемся, что некоторые из извлеченных и изложенных здесь уроков помогут тем, кто хочет создавать решения с помощью Airtable.
Наконец, вы можете ознакомиться с сутью файлов, обсуждаемых в этой статье.
