npm package: @fbkl/vriesea
Description: Vue Kommo Helpers
Author: Andrew
Latest version: 1.3.1

+++

Быстрый старт:

```typescript
import Vue from 'vue';
import Vuex from 'vuex';
import {VrieseaModuleConfig, VueVriesea} from './modules';
import {DomEventsService} from './services/sp/dom-events.service';
import AmoAccount from './storage/modules/amo-account';
import AppStatus from './storage/modules/app-status';
import {initializeStore, options} from './storage/store';

Vue.use(Vuex);
// Vue.use(VueMoment, {moment});
// another

Vue.use(VueVriesea, {
    config: {
        codeWidget: 'navy',
        userToken: 'token...',
        api: '/api/v1',
    },
    widget: (window as any).any,
    modules: {
        vueApi: {
            status: true,
        },
        serviceProvider: {
            status: true,
            additional: [
                // {class: ClassService},
                {class: DomEventsService, force: true},
            ],
        },
    },
    storageModules: {
        AmoAccount,
        AppStatus,
        // ...
    },
} as VrieseaModuleConfig);


const store = new Vuex.Store(options);
initializeStore(store);

```

Регистрировать модуль `VueVriesea` после основных ваших модулей
(после `Vue.use(Vuex);`) и перед `new Vuex.Store(options);`.

---

Получение Вспомогательных классов в компонентах (или в прототипе):
```typescript
// component
let httpClient: VueApi = this.$httpClient;
let vrieseaWidget: Widget = this.$vrieseaWidget;
let vrieseaProvider: ServiceProvider = this.$vrieseaProvider;
```

```typescript
// prototype
let httpClient: VueApi = Vue.prototype.$httpClient;
let vrieseaWidget: Widget = Vue.prototype.$vrieseaWidget;
let vrieseaProvider: ServiceProvider = Vue.prototype.$vrieseaProvider
```

---

Получение заранее зарегистрированых модулей (в компоненте или вне компонента):
```typescript
import {getModule} from 'vuex-module-decorators';
import {getVrieseaModule} from './storage/store';

// component
let amoAccount = getModule(AmoAccount, this.$store);
// or
let amoAccount2 = getVrieseaModule(AmoAccount);
```

```typescript
import {getModule} from 'vuex-module-decorators';
import {$store, getVrieseaModule} from './storage/store';
// outside component
let amoAccount = getModule(AmoAccount, $store);
// or
let amoAccount2 = getVrieseaModule(AmoAccount);
```

---

Использование Базового сервиса:

- Сервис необходим для инициализации первичных действий и запуск других сервисов
приложения. Является служебным.

Необходимо наследовать базовый класс `BaseAppCoreService` и реализовать
необходимые методы.

```typescript
import {BaseAppCoreService} from './services/app-core.service';

export class AppCoreService extends BaseAppCoreService {
    protected _initNext() {
        // your success logic
    }

    protected _initDenyNext() {
        // your deny logic
    }

    protected async loadAccess(): Promise<void> {
        // load your data for check success
    }

    protected _initDeepWorkflowNext() {
        // your deep workflow logic
        // (you shouls set renderDeepWorkflowTypeHook & accessDeepWorkflowTypeHooks)
    }
  
    protected _initDenyDeepWorkflowNext() {
        // your dany deep workflow logic
        // (you shouls set renderDeepWorkflowTypeHook & accessDeepWorkflowTypeHooks)
    }

    protected deepWorkflowClean() {
        // for clean in workflow logic
    }
}

// in your main app file
new AppCoreService().init();
```

Для более глубокой настройки можна наследовать только `BaseAppCoreStatusesService`.

---

## Widget

**Пример корневого загрузочного файла приложения _Widget_
(фактически одинаковы для всех приложений типа `Widget`):**
```typescript
// index.ts

import './styles/styles.scss';

import {Core} from './core';
import {factoryCallbacks} from '@fbkl/vriesea/dist/widget';
import {WidgetModel} from '@fbkl/vriesea/dist/contracts/widget.model';
import {APP} from './configs/app.config';
import {defineVrieseaConfig} from '@fbkl/vriesea/dist';


export const Index = function () {
  this.callbacks = factoryCallbacks<Core>(() => {
    let self = this as WidgetModel;

    defineVrieseaConfig({
      api: APP.pathPrefix,
      codeWidget: APP.codeWidget,
      userToken: (self.params.token_key || '').trim(),
    });

    return new Core(self);
  });
}

```

**Пример корневого рабочего файла приложения _Widget_:**
```typescript
// core.ts

import {CoreBase} from '@fbkl/vriesea/dist/widget';
import {WidgetSdkCardContract} from '@fbkl/vriesea/dist/contracts/widget.contract';

export class Core extends CoreBase implements WidgetSdkCardContract {
  constructor(context) {
    super(context);
  }

  init(): void {
    super.init();
    if (!['settings', 'advanced_settings'].includes(this._widget.area)) {
      this.doFront();
    }
  }

  async linkCard(): Promise<any[]> {
    return [];
  }

  async loadElements(): Promise<any[]> {
    return [];
  }

  async loadPreloadedData(): Promise<any[]> {
    window[this.code()].$hooks.next({type: 'loadPreloadedData'});
    return [];
  }

  async searchDataInCard(): Promise<any[]> {
    return [];
  }

  protected code(): string {
    return 'widgetPurple';
  }
}

```

**Методы:**
- `render`, `init`, `bindActions`, `destroy`,
  `settings`, `onSave`, `advancedSettings`, и др.
  (в зависимости от реализованых интерфесов `contracts/widget.contract.ts`) -
  корневые хуки приложения
  (вызываются автоматически в зависимоти от области или действия приложения)
- `doFront` - инициализация front скриптов и запуск front приложения
- `doDp` - инициализация front скриптов и запуск `digital pipeline` front приложения
- `initWidget` - инициализация front представления виджета в правой части амо
(часто связан с вызовом метода `doFront`)
```typescript
if (['lcard'].includes(this._widget.area)) {
    this.doFront();
    this.initWidget();
}
```
- `loadingDp` - инициализация в области dp (следует вызов `doDp`)
```typescript
import {CoreBase} from '@fbkl/vriesea/dist/widget/core-base';
import {WidgetDpContract} from '@fbkl/vriesea/dist/contracts/widget.contract';

export class Core extends CoreBase implements WidgetDpContract {
  // ...
  dpSettings(): void {
    this.loadingDp();
    this.doDp();
  }
}
```
- `miniSettings` - инициализация настройек виджета в
разделе Интеграции/Установка. Работа пакета `@fbkl/pine`
- `code` - возвращает строковое представление ключа
глобальной области хранения инстенса приложения
(необходим для внедрения метаданых приложения в другие части
других связных приложений)

---

## webpack

Все виджеты имеют общие настройки. Предоставляются `webpack` конфиги
(и postcss) для повторного использования в разных проектах.

- webpack/production/{widget,app,front}

```js
// In your webpack.config.js

const webpackConfig = require('@fbkl/vriesea/dist/webpack/production/widget/webpack.config')

module.exports = {
    ...webpackConfig,
}

```

```js
// In your vue.config.js

const vueConfig = require('@fbkl/vriesea/dist/webpack/production/front/vue.config');

module.exports = {
    ...vueConfig,
}

```

```js
// In your postcss.config.js

const postcssConfig = require('@fbkl/vriesea/dist/webpack/production/front/postcss.config')

module.exports = {
    ...postcssConfig,
}

```

---

#### webpack loaders

- `element-ui-loader.ts` - оптимизиция скриптов element-ui

---

#### webpack plugins

- postcss:
  - `postcss-parent-prefix.ts` - изоляция стилей element-ui

---

## Widget (Vue.prototype.$vrieseaWidget)

Рабосий клас Widget содержащий инстанс приложения
(для получения метаданых и других данных приложения).

---

## Service Provider

Провайдер разных сервисов приложения.

Включает:
- CatalogTabCardService - работа с амо каталогами (костыли упрощающие жизнь)
- DomEventsService - регистрация и обработка глобальных событий (events)
- PusherService - Pusher/Socket сервис
- +++ `in future`

---

## Константы и хелперы

**Часто использованные функции и переменные для работы:**

- `amo-cf.helper.ts`:
  - `CF_TYPES` - константы номерных типов амо кастомноых полей
  - `CF_TYPE_NAMES` - константы строковых типов амо кастомноых полей
  - `getFrontCfEnumForField` - функция получения `enum` из фронт определенного к.поля
  - `getFrontCfEnumsForField` - функция получения `enums` из фронт определенного к.поля
- `amo-instance.helper.ts`:
  - `ENTITY_CODES` - константы кодов типов сущностей
  - `LIVE_KEYS` - константы кодов наблюдаемых данных в
  глобальной переменной `APP` | ~~`AMOCRM`~~ (примеры есть в tomato, pang)
  - `entityConvert` - ф-ия конвертации области (area) в код сужности
  - `entitySingleConvert` - ф-ия конвертации код сужности в одиночный
  код (leads -> lead)
  - `getEntityName` - ф-ия получения названия сущности по коду сущности
  - `getAmoEntityLink` - ф-ия получения ссылки на конкретную сущность
  - `getLiveKey` и `getLiveValue` - ф-ии помошники для наблюдения изменений в обектах сущностей
- `amo-interface.helper.ts`:
  - `hideInMenu` - ф-ия скрытия фиджета в списках (в списке мульти акшн)
  - `dpSettingsBox` - ф-ия подготовки dp
- `error.helper.ts` - Клас обработки ошибок и их представления пользователю
- `str.helper.ts` - Клас обработки строк

---

TODO: (WARN)
- loadLinked in amoinstance maybe return 204 (empty body if linked not found)