Расширенные атрибуты
Подключение PBC Расширенные атрибуты

Подключение PBC Расширенные атрибуты

Подключение библиотечного веб-компонента qdattui-lib в UI вашего PBC

  1. В своем проекте выполнить команду npm install @diasoft/qdattui-lib

  2. В angular.json, в разделе configurations.production указать откуда брать файлы библиотеки и куда их переместить

    "projects": {
        "<project_name>": {
        ...
        "architect": {
                "build": {
                ...
                  "options": {
                  ...
                    "assets": [
                      ...
                        {
                          "glob": "**/*",
                          "input": "node_modules/@diasoft/qdattui-lib",
                          "output": "assets/qdatt"
                        }
                      ],
  1. Библиотека предоставляет 4 компонента. 3 компонента являются cправочниками, которые необходимо добавить в menu.ru/en.json своего главного меню. 4-й компонент - Схема атрибутов
  • Маски атрибутов (route: attribute-mask)

  • Типы данных атрибутов (route: attribute-data)

  • Преднастроенные атрибуты (route: preconfigured-attribute) и компонент, который в новой вкладке будет работать с конкретной бизнес сущностью

  • Схема атрибутов (route: attribute-diagram)

    3.1 Подключение справочников. Для подключения интерфейсов необходимо использовать доступные возможности компонента q-web-component, в частности передачу настроек для backend через атрибут endpoint.

    3.2 В .html указать динамическое и статическое свойства

<q-web-component
  [endpoint]="endpoint"
  bundleUrl="/api/serviceName/componentName/assets/qdatt/main.js"
></q-web-component>
  • serviceName - UI-сервис прикладного PBC, куда встраиваете

  • componentName - ваш компонент, куда встраиваете

    3.3 В .ts определить интерфейс

endpoint!: QEndpoint;
 
this.endpoint = {
      service: 'qdattui',
      component: 'qdatt',
      route: 'preconfigured-attribute' или 'attribute-data' или 'attribute-mask',
      caption: '',
      properties: {
        qdattConfig: {
          bundle: { service: serviceName, component: componentName },
          service: 'qdattattribute/qdattattribute', // указывается свой сервис. Параметр для перенаправления запросов к бэкенду
        }
      },
    };
  1. Схема атрибутов. Пример кода.
if (tab == "attribute-diagram") {
  title = "Схема атрибутов № ";
  this.rootEvents.openNewTab({
    caption: objectID ? `${title} ${objectID}` : "Схема атрибутов",
    url: `${getTabBaseUrl()}/${tab}/?objectID=${objectID}&code=${code}&localName=${localName}&description=${description}&status=${status}`,
  });
  return;
}

4.1 Описание схемы

  • getTabBaseUrl() возвращает interface/serviceUI/componentUI
  • objectID - ID БО
  • code - sysname БО
  • localName - наименование БО
  • description - описание БО
  • status - статус, 1- действует, 2- не действует

Подключение зависимости qdattattribute в бэкенд вашего PBC

⚠️

Для подключения необходимо использовать версию архетипа 3.10.08-25060602 и выше.

В /service/pom.xml вашего PBC указать зависимость qdattattribute в разделе dependencies

<dependencies>
  <dependency>
    <groupId>ru.diasoft.micro</groupId>
    <artifactId>qdattattribute</artifactId>
    <version>S-Q.UP-00002-25030307</version>
    <classifier>archlib</classifier>
  </dependency>
</dependencies>

В /database/pom.xml вашего PBC указать зависимость qdattattribute-db в разделе plugin

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-dependency-plugin</artifactId>
  <executions>
    <execution>
      <id>unpack</id>
      <phase>generate-resources</phase>
      <goals>
        <goal>unpack</goal>
      </goals>
      <configuration>
        <artifactItems>
          <artifactItem>
            <groupId>ru.diasoft.micro</groupId>
            <artifactId>qdattattribute-db</artifactId>
            <version>S-Q.UP-00002-25030307</version>
            <type>jar</type>
            <overWrite>false</overWrite>
            <outputDirectory>
              ${project.build.directory}/classes/qdattattribute
            </outputDirectory>
            <includes>**/**.xml,**/**.sql</includes>
            <excludes>META-INF/, version/</excludes>
          </artifactItem>
        </artifactItems>
      </configuration>
    </execution>
  </executions>
</plugin>
💡

После установки сервиса на ваш стенд в сваггере добавятся API из библиотечного PBC.

Подключение библиотеки q-bpm-qdatt-table в UI вашего PBC

  1. В своем проекте выполнить команду npm install @diasoft/q-bpm-qdatt-table

  2. В NgModule компонента, в котором собираетесь использовать расширенные аттрибуты в таблице, нужно импортировать два компонента и два пайпа:

import {
  QdattColumnsPipe,
  QdattFiltersPipe,
  QdattTableColumnsComponent,
  QdattTableFiltersComponent,
} from "@diasoft/q-bpm-qdatt-table";
 
@NgModule({
  imports: [
    //...ваши модули,
    QdattFiltersPipe,
    QdattColumnsPipe,
    QdattTableColumnsComponent,
    QdattTableFiltersComponent,
  ],
})
export class myModule {}
  1. Библиотека предоставляет возможность дополнить таблицу и фильтры расширенными атрибутами, для этого предлагается использовать 4 инструмента:

3.1 QdattColumnsPipe - Пайп, который получает конфигурацию расширенных атрибутов и объединяет уже существующие колонки таблицы с колонками, полученными из схемы расш. атрибутов.

При передаче значения в параметр columns таблицы нужно пропустить собственные колонки через пайп qdattColumns, и передать в этот пайп параметр code по которому будет получена конфигурация расширенных атрибутов (AttributeSchemes):

<p-table
  [scrollable]="false"
  [rows]="10"
  [columns]="(columns | qdattColumns: 'TableConfig' | async) ?? []"
  [value]="tableData"
  [lazy]="true"
  (onLazyLoad)="loadLazy($event)"
></p-table>

В данном примере:

  • columns - колонки уже существующие в таблице.
  • qdattColumns - пайп, получающий конфигурацию расширенных атрибутов и объединяющий с существующими колонками.
  • TableConfig - пример значения поля code по которому будет получена конфигурация расширенных атрибутов (AttributeSchemes).

Если в таблице предусмотрена настройка видимости колонок, то нужно пропустить собственные колонки через пайп qdattColumns в [options] компонента p-listbox, никаких дополнительных параметров в этом случае в пайп передавать не нужно:

<p-dialog header="Отображение колонок" [(visible)]="colsToggle">
  <p-listbox
    [options]="cols | qdattColumns | async"
    [(ngModel)]="dv.columns"
    [metaKeySelection]="false"
    [checkbox]="true"
    [filter]="true"
    [multiple]="true"
    optionLabel="header"
  >
  </p-listbox>
</p-dialog>

3.2 QdattTableColumnsComponent - компонент, который отобразит все дополнительные колонки, полученные из схемы расширенных атрибутов.

Его нужно использовать в таблице в шаблоне pTemplate="body", предварительно завернув все собственные колонки в проверку на !col.isQdattColumn. Эта проверка нужна для того, чтобы отличать собственные колонки от расширенных и не дублировать их отображение:

<ng-template pTemplate="body" let-row let-columns="columns">
  <tr>
    @for (col of columns; track col.id) { @if (!col.isQdattColumn) {
    <!--собственные колонки компонента, если они есть-->
    } @else {
    <td>
      <!--расширенные колонки-->
      <lib-qdatt-table-columns
        [column]="col"
        [value]="row"
      ></lib-qdatt-table-columns>
    </td>
    } }
  </tr>
</ng-template>

3.3 QdattTableFiltersComponent - компонент, который отобразит все фильтры, полученные из схемы расширенных атрибутов.

<ng-template pTemplate="caption">
  <form [formGroup]="filterFormData">
    <!--собственные фильтры компонента, если они есть-->
    <q-filter-wrapper label="Наименование:">
      <input
        pInputText
        type="text"
        class="p-inputtext-sm"
        formControlName="localNameSearch"
      />
    </q-filter-wrapper>
 
    <!--расширенные фильтры-->
    <lib-qdatt-table-filters
      [selectedFiltersNames]="selectedFilters"
      (valueChanges)="dattFiltersChanged($event)"
    ></lib-qdatt-table-filters>
  </form>
</ng-template>

В данном примере:

  • selectedFiltersNames - принимает в себя список фильтров, которые выбраны в компоненте с таблицей. Пример: ['name', 'sysName']. Если в таблице не предусмотрена настройка видимости фильтров, то не передавайте этот параметр и все дополнительные фильтры будут отображены по умолчанию.
  • valueChanges - событие изменения значения фильтров в компоненте QdattTableFiltersComponent. Возвращает объект с ключами (code) и значениями всех расш. фильтров. Пример: {name: 'Тестовое наименовение', sysName: 'Test'}.

Пример объединения расширенных фильтров с собственными:

// в компоненте таблицы добавляем функцию, которая будет обрабатывать событие изменения фильтров из `QdattTableFiltersComponent`
  public dattFiltersChanged(filters: Record<string, any>) {
    // можем записать значение в глобальную переменную, если оно нам еще где-то может понадобиться
    this.qdattFilters = filters;
    this.onLazyLoad();
  }
 
  public onLazyLoad(): void {
    const filter: any = {
      size: 20,
      page: 0,
      sort: 'appNumber,desc'
    };
    // передаем собственные фильтры компонента и фильтры, полученные из расширенных атрибутов в функцию, где будет осуществляться запрос к апи
    this.getList({...filter, ...this.qdattFilters});
  }

Если предусмотрена возможность очищения всех фильтров по одной кнопке, то в функции, где осуществляется сброс всех фильтров, вызываем метод clearAllFilters() из компонента QdattTableFiltersComponent:

@ViewChild(QdattTableFiltersComponent) qdattFiltersComponent!: QdattTableFiltersComponent;
 
public clearFilters(): void {
    // сброс собственных фильтров
    this.filtersForm.reset();
 
    // сброс расширенных фильтров
    this.qdattFiltersComponent.clearAllFilters();
    this.onLazyLoad();
  }

3.4 QdattFiltersPipe - пайп, который можно использовать для добавления расширенных фильтров в оверлее настройки видимости фильтров. Он объединит уже существующие фильтры с полученными из расш. атрибутов.

<!--Пример кнопки, которая вызывает окно с настройкой видимости фильтров-->
<button
  (click)="op.toggle($event)"
  pButton
  class="p-button-md p-button-text p-button-raised"
  icon="pi pi-filter"
  iconPos="left"
></button>
 
<p-overlayPanel #op appendTo="body">
  <ng-template pTemplate>
    <p-listbox
      [options]="(filters | qdattFilters | async) ?? []"
      [(ngModel)]="selectedFilters"
      (ngModelChange)="onSelectFilter($event)"
      [filter]="true"
      [multiple]="true"
      [checkbox]="true"
    >
    </p-listbox>
  </ng-template>
</p-overlayPanel>

В данном примере:

  • filters - список собственных фильтров компонента.
  • qdattFilters - пайп, который объединит собственные фильтры с фильтрами, полученными из расширенных атрибутов.

Подключение компонента q-dynamic-form в UI вашего PBC

  1. В своем проекте выполнить команду npm install @diasoft/qpalette-form-addons

  2. В NgModule компонента, в котором собираетесь использовать динамическую форму с расширенными атрибутами, нужно импортировать компонент:

import { QDynamicFormComponent } from "@diasoft/qpalette-form-addons";
 
@NgModule({
  imports: [
    //...ваши модули,
    QDynamicFormComponent,
  ],
})
export class myModule {}
  1. Компонент QDynamicFormComponent предоставляет возможность динамически создавать формы на основе JSON-конфигурации, полученной из схемы расширенных атрибутов.

3.1 Использование компонента в шаблоне:

<q-dynamic-form
  *ngIf="config"
  [config]="config"
  [formData]="formData"
  [showActionButtons]="showActionButtons"
  (getDynamicForm)="onGetDynamicForm($event)"
  (formSubmit)="onFormSubmit($event)"
>
</q-dynamic-form>

В данном примере:

  • config - JSON-конфигурация формы, полученная из схемы расширенных атрибутов.

  • formData - данные для заполнения формы (опционально).

  • showActionButtons - флаг отображения кнопок действий в форме - Сохранить/Отменить (опционально).

  • getDynamicForm - событие, которое возвращает экземпляр FormGroup для возможности работы с формой в компоненте.

  • formSubmit - событие отправки формы, возвращает значения всех полей формы.

    3.2 Пример реализации методов обработки событий в компоненте:

export class MyComponent {
  config: any;
  formData: any;
  showActionButtons = true;
  dynamicForm!: FormGroup;
 
  onGetDynamicForm(form: FormGroup) {
    this.dynamicForm = form;
    this.dynamicForm.valueChanges.subscribe(value => {
      console.log('Значения формы:', value);
    });
  }
 
  onFormSubmit(formValue: any) {
    console.log("Данные из dynamic-form:", formValue);
  }
}

3.3 Пример загрузки конфигурации из API:

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

import { HttpClient, HttpParams } from '@angular/common/http';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { catchError } from 'rxjs/operators';
import { of } from 'rxjs';
 
private loadAttributeConfig(): void {
  const url = this.qpdmiappApplicationFormUrlService0.url('/AttributeSchemes');
  const httpParams = new HttpParams().set('code', 'TableConfig');
 
  this.httpClient.get<any>(url, { params: httpParams })
    .pipe(
      takeUntilDestroyed(this.destroyRef),
      catchError((error) => {
        this.qMessagesService.error({
          severity: 'error',
          summary: 'Ошибка загрузки конфигурации',
          detail: `${error.message}`
        });
        return of(null);
      })
    )
    .subscribe({
      next: (response) => {
        if (!response?.content?.[0]) {
          this.qMessagesService.error({
            severity: 'error',
            summary: 'Схема атрибутов не найдена',
            detail: 'Сервер вернул пустой ответ'
          });
          return;
        }
 
        try {
          this.config = JSON.parse(response.content[0].json);
        } catch (e) {
          this.qMessagesService.error({
            severity: 'error',
            summary: 'Ошибка парсинга конфигурации',
            detail: `${e}`
          });
        }
      }
    });
}

В данном примере:

  • /AttributeSchemes - endpoint API для получения схемы атрибутов.
  • code - параметр запроса, по которому будет получена конфигурация (например, 'TableConfig').
  • response.content[0].json - JSON-строка с конфигурацией формы, которую необходимо распарсить и передать в компонент q-dynamic-form.