META

Список и редактирование сущности

Смарт-формы

Обратите внимание, что скорее всего вам будет достаточно функционала Смарт-форм.

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

Общее

Для начала ознакомьтесь со статьей Жизненный цикл запроса

Типичная задача META - вывод списка объектов и их редактирование

Регистрация Entity

Чтобы начать работать с новой сущностью добавьте ее в репозиторий META AppContent. В списке полей обычно достаточно указать primary key и поле, которе будет считаться именем объекта сущности. Для примера попробуем зарегистрировать таблицу example_entity из БД с meta id “meta_samples”.

В репозитории AppContent в директории /entity/meta_samples создайте файл example_entity___public.example_entity.yaml.

Такое название файла надо читать так: {ENTITY_ID}___{DB_SCHEMA}.{DB_TABLE}.yaml Это именование позволяет быстро и легко искать файлы через IDE поиском по имени файла и пока что не влияет на парсер конфига, но будет влиять.

Контент файла:

id: 'example_entity'
name: Пример
db_alias: meta_samples
schema: public
table: example_entity
fields:
- alias: id # для metaql
  db_type: uuid
  is_primary: true # говорит, что поле - первичный ключ
  name: id # название поля в БД
- alias: name
  db_type: text
  is_title: true # говорит, что поле - является именем объекта сущности, например как users.full_name будет использовано для автоматического получения для названия объекта в хлебных крошках
  name: name

Добавьте новую страницу: Список сущностей в таблице

<script type="meta/sql" db-alias="meta_samples" id="res" entity-id="example_entity"
  elem-attrs='{"addObjectButton":{"title":"Entity", "mode":"modal", "modalSize":"lg", "env":{"sp":{"obj":{"name":"test"}}} }}' order="1000">
SELECT
  ee.id,
  ee.name,
  ee.creation_time,
  
  json_build_object(
      'pager', json_build_object('total', count(*) over()),
      'headers', json_build_array(
        json_build_object('name', 'id', 'isVisible', false),
        json_build_object('name', 'name', 'displayName', 'Имя'),
        json_build_object('name', 'creation_time', 'displayName', 'Добавлено')
      )
    ) as table_props_field
FROM example_entity ee
ORDER BY ${sort}
${pager}
</script>

Добавьте новую страницу: Редактирование объекта в карточке

Зайдите на страницу на своем домене: /card?e=example_entity&o=1&a=ВАШ_APP_ID

  • o=1 - нужно чтобы мета показала левое меню сущности, чтобы мы могли добавить первую страницу
  • a=XXX - id вашего приложения

Итак, добавьте новую страницу и зайдите в ее параметры:

  • Роль: “Основная страница создания/редактирования/просмотра объекта”
  • Снимите галку с “Сохранять состояние в URL”. Для редактирование карточек это скорее плохо, а для страниц с отчетами это позволяет не думать о сохранении параметров фильтор в url
  • Когда страница готова к публикации снимите галку с “Показывать в меню только разработчикам”, если вы хотите чтобы все пользователи видели ее в меню

Далее работаем с контентом страницы:

  • Вставьте контент
  • Замените db-alias на свой
  • Замените название таблицы и список полей на свои
<script id="name_validator" type="meta/sql" db-alias="meta_samples" depends="name">
SELECT 'name_validator_unique' as id, 'Имя уже используется' as name FROM public.example_entity WHERE name = :env.sp.name LIMIT 1
</script>

<script type="meta/sql" db-alias="meta_samples" id="info" internal>
-- выбирайте только те поля, которые вам нужны

SELECT id, name, creation_time, last_user_id
FROM public.example_entity
WHERE id=NULLIF(:env.objectId, '0')::uuid
LIMIT 1
</script>

<elem states="default" order="190">
  <tpl>
    <form name="editGroupForm" ng-submit="changeState('save', {obj:env.sp.obj})">
      <me-lego elems="editCard.elems" output="env.sp.obj"></me-lego>
      <div ng-if="$root.isDebugMode">
        <pre>{{env.sp.obj|json}}</pre>
      </div>
    </form>
  </tpl>
</elem>

<script type="meta/js" id="editCard" elem="hidden" states="default">
  function main(vm, pvm, env) {
    // Получаем инфу из бд, если редактирвание или указываем здачение по умолчанию
    var info = pvm.data.info.notEmpty ? pvm.data.info.rows[0] : {};
    // Не добавляейте в env секретные поля - эти данные уйдут в интерфейс
    pvm.initEnvSp(env, {obj: info});

    vm.elems = [
      {
        id: "name",
        label: "Название",
        span: 12,
        name: "me-input",
        refPvmValidator: {id: "name_validator"},
        attrs: {
          required: true,
          min: 2,
          max: 30
        }
      },
      {name: "newrow"},
      {
        id: "submit",
        name: "me-submit",
        attrs: {
          value: '${i18n("common.saveButton")}'
        }
      }
    ];
  }
</script>

<script type="meta/sql" db-alias="meta_samples" elem="hidden" states="save" id="upsert">
INSERT INTO example_entity (id, name, last_user_id)
VALUES ( COALESCE(NULLIF(:env.objectId, '0')::uuid, uuid_generate_v4()), :env.sp.obj.name, :env.userId )
ON CONFLICT (id) DO UPDATE SET
  name = EXCLUDED.name
RETURNING id;
</script>


<script type="meta/js" elem="hidden" states="save">
function main(pvm, vm, env, ObjectLogService) {
  var isNew = !env.hasObjectId;
  var objectId = isNew ? pvm.data.upsert.rows[0].id : env.objectId;

  if (isNew) {
    pvm.redirect = {
      url: "/card?e=" + env.entityId + "&o=" + objectId + "&a=" + env.applicationId
    };
  } else {
    pvm.toInitialState();
    pvm.closeModal();
  }
  pvm.popup = {level: "success", message: "${i18n('common.saveSuccess')}"};
  ObjectLogService.logValue(env.entityId, objectId, isNew ? 'ADD' : 'SET', env.sp.obj);
}
</script>