Table of Contents

Выбор объекта из ПОЛИНОМ:MDM

Смотрите пример Polynom/SDK/Samples.Web/polynom-select-demo.

Структуры данных

Перечисление типов объектов ПОЛИНОМ:MDM подлежащих выбору

/**
 * Типы данных объектов ПОЛИНОМ:MDM которые можно выбрать.
 */
export enum SelectPolynomObjectTypes {
  // Без типа.
  None = 0,

  // Элемент.
  Element = 4,

  // Группа.
  ElementGroup = 39,

  // Каталог.
  ElementCatalog = 40,

  // Справочник.
  Reference = 48,

  // Документ.
  Document = 71,

  // Каталог документов.
  DocumentCatalog = 69,

  // Группа документов.
  DocumentGroup = 70,

  // Каталог представлений.
  ViewpointCatalog = 91,

  // Группа представлений.
  ViewpointGroup = 92,

  // Представление.
  Viewpoint = 93
}
/**
 * Представляет сообщение интеграции с ПОЛИНОМ:MDM.
 */
export type IIntegrationResponse = {
  /** Идентификатор сообщений ПОЛИНОМ:MDM. */
  messageId: string;
};

Структура данных справочника, каталога, группы.

/*
 * Данные идентифицирующие объект.
 */
export type IIdentifierData = {
  /* Идентификатор объекта. */
  identifier?: IIdentifiableObject;

  /* Строка расположения объекта. */
  location?: string;
};

Структура данных понятия.

/*
 * Данные идентифицирующие понятие.
 */
export type IConceptIdentifierData = {
  /* Идентификатор понятия. */
  identifier?: IIdentifiableObject;

  /* Абсолютный код понятия. */
  absoluteCode?: string;
};

Структура данных фильтра.

/**
 * Контейнер фильтра.
 */
export type IFilterContainer = {
  /* Список допустимых типов объектов для выбора. */
  objectTypes: SelectPolynomObjectTypes[];

  /* Список справочников, каталогов, групп из которых допустим выбор. */
  scopes: IIdentifierData[];

  /* Список элементов для добавления в области выбора. */
  elements: IIdentifierData[];

  /* Список допустимых понятий для объектов. */
  concepts: IConceptIdentifierData[];
};

Структура данных опций диалога выбора.

/**
 * Параметры выбора.
 */
export type ISelectDialogOption = {
  /**
   * Идентификатор хранилища.
   */
  storageId: string | null;

  /**
   * Токен доступа.
   */
  accessToken: string | null;

  /**
   * Данные фильтра.
   */
  filter: Partial<IFilterContainer>;

  /**
   * Строка расположения объекта котором нужно выбрать в дереве.
   */
  location: string | null;

  /**
   * Режим только для просмотра.
   */
  readonly: boolean;

  /**
   * Признак режима множественного выбора.
   */
  multiselectMode: boolean;

  /**
   * Признак отображения сортамента.
   */
  sortamentInstanceMode: boolean;

  /**
   * Указывает на базовый тип сортамента.
   */
  sortamentInstanceBase: SortamentInstanceBase;

  /**
   * Режим открытия окна на вкладке Все размеры.
   */
  allSizesMode: boolean;

  /**
   * Значения всех доступных свойств.
   */
  allSizePropertyValues: Map<string, string>;

  /**
   * Признак открытия окна ПОЛИНОМ в режиме поиска.
   */
  searchMode: boolean;

  /**
   * Режим учета применяемости.
   */
  useApplicability: boolean;

  /**
   * Подсказка
   */
  hint?: string;

  /**
   * Изменения видимости блока фильтрации над деревом классификации
   */
  hideFilterScopeLabel?: boolean;
};

Структура данных получаемая при авторизации ПОЛИНОМ:MDM.

/**
 * Представляет данные авторизации ПОЛИНОМ:MDM.
 */
export type IAuthDataResponse = IIntegrationResponse & {
  /** Жетон доступа к ПОЛИНОМ:MDM. */
  accessToken: string;
};

Структура данных получаемая при выборе объекта в дереве классификации ПОЛИНОМ:MDM

/**
 * Представляет идентифицируемый объект.
 */
export type IIdentifiableObject = {
  /**
   * Идентификатор объекта.
   */
  objectId: number;
  /**
   * Тип объекта.
   */
  typeId: IdentifiableObjectType;
};
/**
 * Представляет объект с применяемостью.
 */
export type IHaveApplicability = {
  /**
   * Применяемость.
   */
  applicability: Applicability;
};
/**
 * Представляет данные выбранного объекта ПОЛИНОМ:MDM.
 */
export type IPolynomObjectData = IIdentifiableObject &
  IHaveApplicability & {
    /** Строка расположения объекта.  */
    location: string;
  };

Структура данных результата диалога выбора.

/**
 * Представляет результата выбора.
 */
export type ISelectDialogResult = {
  /**
   * Данные выбранного объекта.
   */
  polynomObject: IPolynomObjectData | null;

  /**
   * Данные выбранных объектов.
   */
  polynomObjects: IPolynomObjectData[];

  /**
   * Данные авторизации.
   */
  polynomAuthData: IAuthDataResponse;
};

Настройка проекта перед использованием библиотеки @ascon/polynom-select

Создать проект с помощью NX

npx create-nx-workspace polynom-select-demo --preset=angular-standalone

Требуемые зависимости

{
  "dependencies": {
    "@ascon/polynom-select": "~24.0.30110",
    "@ascon/polynom-login": "~24.0.30110"
  }
}

Расположение библиотек @ascon/polynom-select , polynom-api и их зависимостей

Polynom/SDK/Samples.Web/libs/

Варианты доставки библиотек ASCON

  1. Вы можете опубликовать библиотеки в собственный локальный репозиторий npm пакетов и выполнить команды установки.
npm install @ascon/polynom-select@24.0.30110
npm install @ascon/polynom-login@24.0.30110
  1. Вы можете копировать библиотеки в **node_modules/@ascon** своего проекта из Polynom/SDK/Samples.Web/libs/ и установить транзитивные зависимости.
npm install
Подключить активы библиотек к своему проекту

В файл project.json добавить следующее:

{
  "targets": {
    "build": {
      "options": {
        "assets": [          
          {
            "glob": "**/*",
            "input": "node_modules/@ascon/theme/assets",
            "output": "./assets"
          },
          {
            "glob": "**/*",
            "input": "libs/polynom-api/src/assets",
            "output": "/assets"
          },
          {
            "glob": "**/*",
            "input": "node_modules/@ascon/polynom-core/assets",
            "output": "./assets"
          },
          {
            "glob": "**/*",
            "input": "node_modules/@ascon/polynom-ui/assets",
            "output": "./assets"
          },
          {
            "glob": "**/*",
            "input": "node_modules/@ascon/polynom-trees/assets",
            "output": "./assets"
          },
          {
            "glob": "**/*",
            "input": "node_modules/@ascon/polynom-login/assets",
            "output": "./assets"
          },
          {
            "glob": "**/*",
            "input": "node_modules/@ascon/polynom-select/assets",
            "output": "./assets"
          },
          {
            "glob": "**/*",
            "input": "src/assets",
            "output": "./assets"
          }
        ],
        "styles": [
          {
            "input": "node_modules/@ascon/theme/theme.css",
            "inject": false,
            "bundleName": "theme"
          },
          {
            "input": "node_modules/@ascon/polynom-theme/styles/polynom-theme.css",
            "inject": true,
            "bundleName": "app-styles"
          },
          {
            "input": "node_modules/@ascon/polynom-trees/styles/polynom-trees.css",
            "inject": true,
            "bundleName": "app-styles"
          },
          {
            "input": "node_modules/@ascon/polynom-ui/styles/polynom-ui.css",
            "inject": true,
            "bundleName": "app-styles"
          },
          {
            "input": "node_modules/@ascon/polynom-login/styles/polynom-login.css",
            "inject": true,
            "bundleName": "app-styles"
          },
          {
            "input": "src/styles.scss",
            "inject": false,
            "bundleName": "app-styles"
          }
        ],
      }
    }
  }
}

В файл index.html добавить следующее:

<html lang="ru">
  <head>
    <link
      href="theme.css"
      id="theme-link"
      media="all"
      onload="this.media='all'"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="app-styles.css"    
      id="app-link" 
      media="all"
      onload="this.media='all'"
      rel="stylesheet"
      type="text/css"
    />
  </head>
</html>
Импортировать модуль библиотеки PolynomSelectModule

Добавить строку providePolynomSelect() в appConfig.

//app.config.ts

export const appConfig: ApplicationConfig = {
  providers: [
    provideAnimations(),
    provideHttpClient(withInterceptors([jwtInterceptor])),
    provideStorages(),
    provideLocalization({
      availableLangs: ['ru', 'en'],
      defaultLang: 'ru',
      prodMode: !isDevMode(),
      scopes: [
        'polynom/polynom-select-demo',
        'polynom/polynom-api',
        'polynom/polynom-select',
        'polynom/polynom-login',
        'polynom/polynom-trees',
        'polynom/polynom-ui',
        'polynom/polynom-core'
      ]
    }),
    providePolynomSelect(),
    provideRouter(appRoutes)
  ]
};
Установить настройки адреса веб сервера ПОЛИНОМ:MDM

Перед запуском диалогового окна нужно установить настройки адреса веб сервера ПОЛИНОМ:MDM (например веб сервер ПОЛИНОМ:MDM работает на 127.0.0.1:5100)

// Параметры WEB API ПОЛИНОМ:MDM
const polynomApiConfig: PolynomApiConfig = inject(PolynomApiConfig);

polynomApiConfig.setHost("http://localhost:5100");

Или в компоненте из которого будет вызываться окно ПОЛИНОМ:MDM.

@Component({
  selector: "mdm-select-object",
  standalone: true,
  imports: [CommonModule],
  templateUrl: "./select-object.component.html",
  styleUrl: "./select-object.component.scss",
})
export class SelectObjectComponent implements OnInit, OnDestroy {
  // Сервис авторизации ПОЛИНОМ:MDM.
  private readonly _loginService: LoginService = inject(LoginService);

  public ngOnInit(): void {
    this._polynomApiConfig.setHost("http://127.0.0.1:5100");
  }
}

Примеры вызова ПОЛИНОМ:MDM

Подготовка компонента

Импорт классов, интерфейсов, сервисов.

import {
  IPolynomAuthData,
  IPolynomObjectData,
  SelectDialogs,
  SelectPolynomObjectTypes,
} from "@ascon/polynom-select";

import { LoginService, PolynomApiConfig } from "@ascon/polynom-api";

Получить экземпляры глобальных сервисов

// Сервис диалогов PrimeNg.
private readonly _dialogService: DialogService = inject(DialogService);

// Сервис конфигурации Polynom Web Api
private readonly _polynomApiConfig: PolynomApiConfig = inject(PolynomApiConfig);

// Сервис авторизации ПОЛИНОМ:MDM.
private readonly _loginService: LoginService = inject(LoginService);

Поля данных получаемых из диалога выбора объекта ПОЛИНОМ:MDM.

// Данные выбранного объекта ПОЛИНОМ:MDM.
private _polynomObject: IPolynomObjectData | null = null;

// Данные авторизации ПОЛИНОМ:MDM.
private _polynomAuthData: IPolynomAuthData | null = null;

Вызов окна выбора объекта ПОЛИНОМ:MDM без предварительной авторизации

Авторизация ПОЛИНОМ:MDM произойдет в окне выбора

selectPolynom($event: MouseEvent): void {
    // Строка расположения объекта которы долже быть открыт в окне ПОЛИНОМ:MDM
    const location = "<строка расположения объекта>";

    // Указываем типы объектов справочника которые хотим выбрать
    const filterObjectIds = [
      SelectPolynomObjectTypes.Element,
      SelectPolynomObjectTypes.Document,
      SelectPolynomObjectTypes.Viewpoint
    ];

    SelectDialog.show(this._dialogService, {
    filter: {objectTypes: filterObjectIds},
    location: this.location
  })
  .pipe(take(1))
    .subscribe({
      next: value => {
        if (!value?.polynomObject) {
          return;
        }

        this.location = value.polynomObject.location;
      }
    });
}

Вызов окна выбора объекта ПОЛИНОМ:MDM c предварительной авторизацией

accessToken может быть получен из общего сервиса авторизации или из web api ПОЛИНОМ:MDM.

storageId необходим для указания хранилища.

// Сервис авторизации ПОЛИНОМ:MDM.
private readonly _loginService: LoginService = inject(LoginService);

// Список описаний хранилищ ПОЛИНОМ:MDM.
private _storageDefinitions: IStorageDefinition[] = [];

// Запрашивает список описаний хранилищ ПОЛИНОМ:MDM.
requestStorageDefinition(): void {
    this._loginService
        .getStorageDefinition()
        .pipe(take(1))
        .subscribe({
            next: storageDefinitions => {
                this.storageDefinitions = storageDefinitions;
            },
            error: err => {console.error(err);}
        });
}

// Авторизует пользователя в ПОЛИНОМ:MDM
signInByPassword(storageId: string, login: string, password: string): void {
    if (!storageId || !login || !password) {
        return;
    }

    const request = SignInRequest.create({
        storageId: storageId,
        login: login,
        password: password,
        clientType: this._polynomWebApiConfig.clientType,
        moduleName: "Клиент ПОЛИНОМ:MDM" // Опционально
    });

    this._loginService
        .signIn(request)
        .pipe(take(1))
        .subscribe({
            next: () => {
                // Действия после успешной авторизации
            },
            error: err => {console.error(err);}
        });
}


// Открывает диалог выбора объекта ПОЛИНОМ:MDM с установлеными значениями **storageId** **accessToken**.
// Окно заблокирует выбор хранилища указанным в **storageId** и попытается авторизоватся с помощью уже существующего **accessToken**.
selectPolynom($event: MouseEvent): void {
    // Строка расположения объекта которы долже быть открыт в окне ПОЛИНОМ:MDM
    const location = "<строка расположения объекта>";

    // Указываем типы объектов справочника которые хотим выбрать
    const filterObjectIds = [
      SelectPolynomObjectTypes.Element,
      SelectPolynomObjectTypes.Document,
      SelectPolynomObjectTypes.Viewpoint
    ];

    SelectDialog.show(this._dialogService, {
    storageId: this._loginService.storageId,
    accessToken: this._loginService.accessToken,
    filter: {objectTypes: filterObjectIds},
    location: this.location
  })
  .pipe(take(1))
    .subscribe({
      next: value => {
        if (!value?.polynomObject) {
          return;
        }

        this.location = value.polynomObject.location;
      }
    });
}

Выбор области связи

  selectLinkScope(): void {
    const config: ISelectConfig = {
      currentElement: ClassifiableObject.defaultObject(),
      cannotSelected: []
    };

    SelectLinkScopeDialog.show(this._dialogService, config, translate('Select link scope'))
      .pipe(take(1))
      .subscribe({
        next: value => {
          if (!value || value.buttonEvent === CloseResult.Cancel) {
            return;
          }

          if (value.buttonEvent === CloseResult.Select) {
            this.linkScopeResult = value.values;
            return;
          }
        }
      });
  }

Выбор тип связи

  selectLinkType(): void {
    const config: ISelectConfig = {
      currentElement: ClassifiableObject.defaultObject(),
      cannotSelected: []
    };

    SelectTypeLinkDialog.show(this._dialogService, config, translate('Select link type'))
      .pipe(take(1))
      .subscribe({
        next: value => {
          if (!value || value.buttonEvent === CloseResult.Cancel) {
            return;
          }

          if (value.buttonEvent === CloseResult.Select) {
            this.linkTypeSelectionResult = value.values;
            return;
          }
        }
      });
  }

Выбор свойства

  selectObjectProperty(): void {
    const config: ISelectConfig = {
      currentElement: ClassifiableObject.defaultObject(),
      cannotSelected: []
    };

    SelectObjectPropertyDialog.show(this._dialogService, config, translate('Select properties'))
      .pipe(take(1))
      .subscribe({
        next: value => {
          if (!value || value.buttonEvent === CloseResult.Cancel) {
            return;
          }

          if (value.buttonEvent === CloseResult.Select) {
            this.objectPropertyResult = value.values;
            return;
          }
        }
      });
  }

Выбор объекта классификации

  selectClassificationObject(): void {
    const config: ISelectConfig = {
      currentElement: ClassifiableObject.defaultObject(),
      cannotSelected: []
    };

    SelectClassificationObjectDialog.show(this._dialogService, config, translate('Select object'))
      .pipe(take(1))
      .subscribe({
        next: value => {
          if (!value || value.buttonEvent === CloseResult.Cancel) {
            return;
          }

          if (value.buttonEvent === CloseResult.Select) {
            this.objectSelectionResult = value.values;
            return;
          }
        }
      });
  }

Выбор понятия

  selectConcept(): void {
    const config: ISelectConfig = {
      currentElement: ClassifiableObject.defaultObject(),
      cannotSelected: []
    };

    SelectConceptDialog.show(this._dialogService, config, translate('Select concepts'))
      .pipe(take(1))
      .subscribe({
        next: value => {
          if (!value || value.buttonEvent === CloseResult.Cancel) {
            return;
          }

          if (value.buttonEvent === CloseResult.Select) {
            this.conceptClassificationSelectionResult = value.values;
            return;
          }
        }
      });
  }

Выбор группы классификации

  selectClassificationGroup(): void {
    const config: ISelectConfig = {
      currentElement: ClassifiableObject.defaultObject(),
      cannotSelected: []
    };

    SelectClassificationGroupDialog.show(this._dialogService, config, translate('Select classification scope'))
      .pipe(take(1))
      .subscribe({
        next: value => {
          if (!value || value.buttonEvent === CloseResult.Cancel) {
            return;
          }

          if (value.buttonEvent === CloseResult.Select) {
            this.classificationGroupSelectionResult = value.values;
            return;
          }
        }
      });
  }