@mobilon-dev/chotto 0.3.78 → 0.3.79

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,100 +1,98 @@
1
- import { computed as p, unref as A, ref as h, watch as g } from "vue";
2
- import { CHANNEL_TYPES as t } from "./useCommunicationChannels.js";
3
- const C = ["confirmed", "unconfirmed"];
4
- function S(n) {
5
- return C.includes(n);
1
+ import { computed as A, unref as a, ref as y, watch as g } from "vue";
2
+ const T = ["confirmed", "unconfirmed"];
3
+ function w(n) {
4
+ return T.includes(n);
6
5
  }
7
- function k(n) {
6
+ function B(n) {
8
7
  const e = n == null ? void 0 : n.status;
9
- return S(e) ? `status-${e}` : null;
8
+ return w(e) ? `status-${e}` : null;
10
9
  }
11
- function d(n) {
10
+ function C(n) {
12
11
  return (n == null ? void 0 : n.status) === "confirmed";
13
12
  }
14
- function T(n) {
13
+ function E(n) {
15
14
  return (n == null ? void 0 : n.status) === "unconfirmed";
16
15
  }
17
- function z(n) {
18
- return T(n);
16
+ function O(n) {
17
+ return E(n);
19
18
  }
20
- function s(n, e) {
21
- return e || d(n);
19
+ function d(n, e) {
20
+ return e || C(n);
22
21
  }
23
- function v(n, e) {
24
- return s(n, e) ? e ? "selected-indicator" : "confirmed-indicator" : null;
22
+ function U(n, e) {
23
+ return d(n, e) ? e ? "selected-indicator" : "confirmed-indicator" : null;
25
24
  }
26
- function c(n, e) {
25
+ function l(n, e) {
27
26
  return !e || !(n != null && n.id) ? !1 : n.id === e;
28
27
  }
29
- function m(n, e) {
28
+ function S(n, e) {
30
29
  return !(n != null && n.id) || !(e != null && e.length) ? !1 : e.includes(n.id);
31
30
  }
32
- function y(n, e) {
33
- return c(n, e.confirmingAttributeId) || s(n, e.isSelected);
31
+ function v(n, e) {
32
+ return l(n, e.confirmingAttributeId) || d(n, e.isSelected);
34
33
  }
35
- function B(n, e) {
36
- return m(n, e.blockedAttributeIds) ? !c(n, e.confirmingAttributeId) && !s(n, e.isSelected) : !1;
34
+ function F(n, e) {
35
+ return S(n, e.blockedAttributeIds) ? !l(n, e.confirmingAttributeId) && !d(n, e.isSelected) : !1;
37
36
  }
38
- function E(n, e) {
39
- return c(n, e.confirmingAttributeId) ? "confirming" : m(n, e.blockedAttributeIds) ? "blocked" : y(n, e) ? e.isSelected ? "selected" : d(n) ? "confirmed" : null : null;
37
+ function z(n, e) {
38
+ return l(n, e.confirmingAttributeId) ? "confirming" : S(n, e.blockedAttributeIds) ? "blocked" : v(n, e) ? e.isSelected ? "selected" : C(n) ? "confirmed" : null : null;
40
39
  }
41
- function N(n, e, u) {
42
- const o = E(n, u);
43
- return !o || !e ? "" : e[o] ?? "";
40
+ function L(n, e, c) {
41
+ const s = z(n, c);
42
+ return !s || !e ? "" : e[s] ?? "";
44
43
  }
45
- function O({
44
+ function _({
46
45
  contactAttributes: n,
47
- frozenAttribute: e
46
+ panelChannelTypes: e,
47
+ frozenAttribute: c
48
48
  }) {
49
- const u = p(() => A(n) ?? []), o = h(
50
- Object.fromEntries(t.map((i) => [i, []]))
51
- ), f = () => {
52
- const i = Object.fromEntries(
53
- t.map((r) => [r, []])
54
- );
55
- u.value.forEach((r) => {
49
+ const s = A(() => a(n) ?? []), f = A(() => a(e) ?? []), m = (o) => Object.fromEntries(o.map((i) => [i, []])), p = y(
50
+ m(f.value)
51
+ ), t = () => {
52
+ const o = f.value, i = m(o), u = new Set(o);
53
+ s.value.forEach((r) => {
56
54
  if (!(!r || !r.type)) {
57
55
  if (r.type === "telegram") {
58
- i.telegram.push(r);
56
+ u.has("telegram") && i.telegram.push(r);
59
57
  return;
60
58
  }
61
59
  if (r.type === "max") {
62
- i.max.push(r);
60
+ u.has("max") && i.max.push(r);
63
61
  return;
64
62
  }
65
63
  if (r.type === "phone") {
66
- ["whatsapp", "sms", "phone"].forEach((l) => {
67
- i[l].push(r);
64
+ ["whatsapp", "sms", "phone"].forEach((h) => {
65
+ u.has(h) && i[h].push(r);
68
66
  });
69
67
  return;
70
68
  }
71
- i[r.type] && i[r.type].push(r);
69
+ u.has(r.type) && i[r.type] && i[r.type].push(r);
72
70
  }
73
- }), o.value = i;
71
+ }), p.value = i;
74
72
  };
75
- return g(u, f, { deep: !0, immediate: !0 }), {
76
- organizedContactAttributes: o,
77
- organizeContactAttributes: f,
78
- isAttributeFrozen: (i) => {
79
- const r = e.value;
80
- return !i || !(r != null && r.id) ? !1 : i.id === r.id;
73
+ return g(s, t, { deep: !0, immediate: !0 }), g(f, t), {
74
+ organizedContactAttributes: p,
75
+ organizeContactAttributes: t,
76
+ isAttributeFrozen: (o) => {
77
+ const i = c.value;
78
+ return !o || !(i != null && i.id) ? !1 : o.id === i.id;
81
79
  }
82
80
  };
83
81
  }
84
82
  export {
85
- C as CONTACT_ATTRIBUTE_STATUSES,
86
- v as getAttributeCheckIndicatorClass,
87
- E as getAttributeIndicatorTooltipKey,
88
- N as getAttributeIndicatorTooltipText,
89
- k as getAttributeStatusClass,
90
- m as isAttributeBlocked,
91
- d as isAttributeConfirmed,
92
- c as isAttributeConfirming,
93
- T as isAttributeUnconfirmed,
94
- S as isContactAttributeStatus,
95
- z as needsAttributeConfirmation,
96
- s as shouldShowAttributeCheckmark,
97
- y as shouldShowAttributeIndicator,
98
- B as shouldShowBlockedIndicatorSlot,
99
- O as useCommunicationAttributes
83
+ T as CONTACT_ATTRIBUTE_STATUSES,
84
+ U as getAttributeCheckIndicatorClass,
85
+ z as getAttributeIndicatorTooltipKey,
86
+ L as getAttributeIndicatorTooltipText,
87
+ B as getAttributeStatusClass,
88
+ S as isAttributeBlocked,
89
+ C as isAttributeConfirmed,
90
+ l as isAttributeConfirming,
91
+ E as isAttributeUnconfirmed,
92
+ w as isContactAttributeStatus,
93
+ O as needsAttributeConfirmation,
94
+ d as shouldShowAttributeCheckmark,
95
+ v as shouldShowAttributeIndicator,
96
+ F as shouldShowBlockedIndicatorSlot,
97
+ _ as useCommunicationAttributes
100
98
  };
@@ -1,71 +1,95 @@
1
- import { computed as m, unref as c } from "vue";
1
+ import { computed as c, unref as i } from "vue";
2
2
  /* empty css */
3
- import P from "../icons/CommunicationPanelPhoneIcon.vue.js";
4
- import S from "../icons/CommunicationPanelWhatsAppIcon.vue.js";
5
- import M from "../icons/CommunicationPanelTelegramIcon.vue.js";
6
- import T from "../icons/CommunicationPanelMaxIcon.vue.js";
7
- import b from "../icons/CommunicationPanelSMSIcon.vue.js";
8
- import d from "../icons/CommunicationPanelSubmenuPhoneIcon.vue.js";
9
- import v from "../icons/CommunicationPanelSubmenuWhatsAppIcon.vue.js";
10
- import x from "../icons/CommunicationPanelSubmenuTelegramIcon.vue.js";
11
- import w from "../icons/CommunicationPanelSubmenuMaxIcon.vue.js";
12
- import A from "../icons/CommunicationPanelSubmenuSMSIcon.vue.js";
13
- const F = ["whatsapp", "telegram", "max", "sms", "phone"], y = {
14
- phone: P,
15
- whatsapp: S,
16
- telegram: M,
17
- max: T,
18
- sms: b
19
- }, E = {
20
- phone: d,
21
- whatsapp: v,
22
- telegram: x,
23
- max: w,
3
+ import M from "../icons/CommunicationPanelPhoneIcon.vue.js";
4
+ import b from "../icons/CommunicationPanelWhatsAppIcon.vue.js";
5
+ import w from "../icons/CommunicationPanelTelegramIcon.vue.js";
6
+ import x from "../icons/CommunicationPanelMaxIcon.vue.js";
7
+ import A from "../icons/CommunicationPanelSMSIcon.vue.js";
8
+ import y from "../icons/CommunicationPanelSubmenuPhoneIcon.vue.js";
9
+ import E from "../icons/CommunicationPanelSubmenuWhatsAppIcon.vue.js";
10
+ import F from "../icons/CommunicationPanelSubmenuTelegramIcon.vue.js";
11
+ import L from "../icons/CommunicationPanelSubmenuMaxIcon.vue.js";
12
+ import N from "../icons/CommunicationPanelSubmenuSMSIcon.vue.js";
13
+ const I = ["whatsapp", "telegram", "max", "sms", "phone"], _ = ["max", "telegram", "whatsapp", "sms", "phone"];
14
+ function g(a) {
15
+ return I.includes(a);
16
+ }
17
+ function D(a, r) {
18
+ const u = (a ?? _).filter(g), m = r === void 0 ? [...I] : r.filter(g), p = new Set(m), t = /* @__PURE__ */ new Set(), l = [];
19
+ for (const o of u)
20
+ p.has(o) && !t.has(o) && (t.add(o), l.push(o));
21
+ for (const o of m)
22
+ t.has(o) || (t.add(o), l.push(o));
23
+ return l;
24
+ }
25
+ const H = {
26
+ phone: M,
27
+ whatsapp: b,
28
+ telegram: w,
29
+ max: x,
24
30
  sms: A
25
- }, L = {
31
+ }, R = {
32
+ phone: y,
33
+ whatsapp: E,
34
+ telegram: F,
35
+ max: L,
36
+ sms: N
37
+ }, W = {
26
38
  phone: "Позвонить",
27
39
  whatsapp: "Выберите контакт и канал для отправки сообщения",
28
40
  telegram: "Выберите контакт и канал для отправки сообщения",
29
41
  max: "Выберите контакт и канал для отправки сообщения",
30
42
  sms: "Выберите контакт и канал для отправки сообщения"
31
43
  };
32
- function O({ channels: i, channelTooltips: u, selectedChannelType: s }) {
33
- const t = m(() => c(i) ?? []), p = m(() => c(u) ?? {}), h = m(
34
- () => F.map((n) => ({
44
+ function Z({
45
+ channels: a,
46
+ channelTooltips: r,
47
+ channelOrder: u,
48
+ visibleChannelTypes: m,
49
+ selectedChannelType: p
50
+ }) {
51
+ const t = c(() => i(a) ?? []), l = c(() => i(r) ?? {}), o = c(
52
+ () => D(i(u), i(m))
53
+ ), d = c(
54
+ () => o.value.map((n) => ({
35
55
  type: n,
36
- component: y[n]
56
+ component: H[n]
37
57
  }))
38
- ), C = (n) => {
39
- const e = p.value[n];
40
- return e || (L[n] ?? "");
41
- }, o = (n) => {
58
+ ), S = (n) => {
59
+ const e = l.value[n];
60
+ return e || (W[n] ?? "");
61
+ }, s = (n) => {
42
62
  if (!n) return null;
43
63
  const [e] = n.split(".");
44
64
  return e.includes("waba") ? "whatsapp" : e.includes("telegrambot") ? "telegram" : e;
45
- }, g = (n) => t.value.filter((e) => o(e.channelId) === n).length > 1, f = (n) => s.value === n, l = (n) => {
46
- const e = t.value.filter((I) => o(I.channelId) === n);
65
+ }, P = (n) => t.value.filter((e) => s(e.channelId) === n).length > 1, T = (n) => p.value === n, C = (n) => {
66
+ const e = t.value.filter((v) => s(v.channelId) === n);
47
67
  return e.length === 1 ? e[0] : null;
48
- }, a = (n) => E[n] ?? null, r = (n) => {
49
- const e = o(n);
50
- return e ? a(e) : null;
68
+ }, h = (n) => R[n] ?? null, f = (n) => {
69
+ const e = s(n);
70
+ return e ? h(e) : null;
51
71
  };
52
72
  return {
53
- channelsTypes: h,
54
- getTooltipText: C,
55
- getChannelTypeFromId: o,
56
- hasMultipleChannels: g,
57
- isChannelActive: f,
58
- getSingleChannelForType: l,
59
- getMenuChannelIconComponent: a,
60
- getMenuChannelIconComponentForChannelId: r,
73
+ panelChannelTypes: o,
74
+ channelsTypes: d,
75
+ getTooltipText: S,
76
+ getChannelTypeFromId: s,
77
+ hasMultipleChannels: P,
78
+ isChannelActive: T,
79
+ getSingleChannelForType: C,
80
+ getMenuChannelIconComponent: h,
81
+ getMenuChannelIconComponentForChannelId: f,
61
82
  getSingleMenuChannelIconComponent: (n) => {
62
- const e = l(n);
63
- return e ? r(e.channelId) : a(n);
83
+ const e = C(n);
84
+ return e ? f(e.channelId) : h(n);
64
85
  },
65
- getAvailableChannels: (n) => t.value.filter((e) => o(e.channelId) === n)
86
+ getAvailableChannels: (n) => t.value.filter((e) => s(e.channelId) === n)
66
87
  };
67
88
  }
68
89
  export {
69
- F as CHANNEL_TYPES,
70
- O as useCommunicationChannels
90
+ I as CHANNEL_TYPES,
91
+ _ as DEFAULT_CHANNEL_ORDER,
92
+ g as isChannelType,
93
+ D as resolvePanelChannelTypes,
94
+ Z as useCommunicationChannels
71
95
  };
@@ -13,6 +13,8 @@ declare const _default: import("vue").DefineComponent<{}, {
13
13
  attributeTooltips: Record<string, any>;
14
14
  attributeIndicatorTooltips: Record<string, any>;
15
15
  showChannelIcons: boolean;
16
+ channelOrder?: unknown[] | undefined;
17
+ visibleChannelTypes?: unknown[] | undefined;
16
18
  $props: {
17
19
  readonly channels?: unknown[] | undefined;
18
20
  readonly messages?: unknown[] | undefined;
@@ -27,6 +29,8 @@ declare const _default: import("vue").DefineComponent<{}, {
27
29
  readonly attributeTooltips?: Record<string, any> | undefined;
28
30
  readonly attributeIndicatorTooltips?: Record<string, any> | undefined;
29
31
  readonly showChannelIcons?: boolean | undefined;
32
+ readonly channelOrder?: unknown[] | undefined;
33
+ readonly visibleChannelTypes?: unknown[] | undefined;
30
34
  };
31
35
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
32
36
  export default _default;
@@ -1,4 +1,5 @@
1
1
  import { type Ref, type ComputedRef } from 'vue';
2
+ import { type ChannelType } from './useCommunicationChannels';
2
3
  /** Допустимые статусы контактного атрибута */
3
4
  export declare const CONTACT_ATTRIBUTE_STATUSES: readonly ["confirmed", "unconfirmed"];
4
5
  export type ContactAttributeStatus = (typeof CONTACT_ATTRIBUTE_STATUSES)[number];
@@ -54,11 +55,12 @@ type MaybeRef<T> = T | Ref<T> | ComputedRef<T>;
54
55
  /**
55
56
  * Параметры composable для работы с контактными атрибутами.
56
57
  */
58
+ type PanelChannelTypesRef = MaybeRef<readonly ChannelType[]>;
57
59
  interface UseCommunicationAttributesOptions {
58
60
  /** Реактивный список контактных атрибутов */
59
61
  contactAttributes: MaybeRef<ContactAttribute[]>;
60
- /** Текущий активный тип канала */
61
- activeChannelType: Ref<string | null>;
62
+ /** Типы каналов, отображаемые в панели */
63
+ panelChannelTypes: PanelChannelTypesRef;
62
64
  /** Текущий замороженный атрибут (подсвеченный) */
63
65
  frozenAttribute: Ref<{
64
66
  id?: string;
@@ -67,7 +69,7 @@ interface UseCommunicationAttributesOptions {
67
69
  /**
68
70
  * Формирует структуру организованных атрибутов.
69
71
  */
70
- export declare function useCommunicationAttributes({ contactAttributes, frozenAttribute, }: UseCommunicationAttributesOptions): {
72
+ export declare function useCommunicationAttributes({ contactAttributes, panelChannelTypes, frozenAttribute, }: UseCommunicationAttributesOptions): {
71
73
  organizedContactAttributes: Ref<Record<string, ContactAttribute[]>, Record<string, ContactAttribute[]>>;
72
74
  organizeContactAttributes: () => void;
73
75
  isAttributeFrozen: (attribute: ContactAttribute | null | undefined) => boolean;
@@ -1,9 +1,17 @@
1
1
  import { type Component, type ComputedRef, type Ref } from 'vue';
2
2
  /**
3
- * Список поддерживаемых типов каналов в панели коммуникаций.
3
+ * Все поддерживаемые типы каналов в панели коммуникаций.
4
4
  */
5
5
  export declare const CHANNEL_TYPES: readonly ["whatsapp", "telegram", "max", "sms", "phone"];
6
6
  export type ChannelType = (typeof CHANNEL_TYPES)[number];
7
+ /** Порядок кнопок каналов по умолчанию. */
8
+ export declare const DEFAULT_CHANNEL_ORDER: readonly ChannelType[];
9
+ export declare function isChannelType(value: string): value is ChannelType;
10
+ /**
11
+ * Собирает итоговый список типов для панели: порядок из channelOrder, видимость из visibleChannelTypes.
12
+ * Типы из visibleChannelTypes, отсутствующие в channelOrder, добавляются в конце.
13
+ */
14
+ export declare function resolvePanelChannelTypes(channelOrder: readonly string[] | undefined, visibleChannelTypes: readonly string[] | undefined): ChannelType[];
7
15
  /**
8
16
  * Базовое описание канала.
9
17
  */
@@ -16,15 +24,21 @@ type MaybeRef<T> = T | Ref<T> | ComputedRef<T>;
16
24
  type ChannelTooltips = Record<string, string>;
17
25
  type ChannelsRef = MaybeRef<Channel[]>;
18
26
  type ChannelTooltipsRef = MaybeRef<ChannelTooltips | undefined>;
27
+ type ChannelTypesRef = MaybeRef<readonly string[] | undefined>;
19
28
  interface UseCommunicationChannelsOptions {
20
29
  /** Реактивный список каналов */
21
30
  channels: ChannelsRef;
22
31
  /** Реактивная карта пользовательских подсказок */
23
32
  channelTooltips?: ChannelTooltipsRef;
33
+ /** Порядок кнопок каналов в панели */
34
+ channelOrder?: ChannelTypesRef;
35
+ /** Типы каналов, которые нужно отображать (с бэка — доступные пользователю) */
36
+ visibleChannelTypes?: ChannelTypesRef;
24
37
  /** Текущий выбранный тип канала */
25
38
  selectedChannelType: Ref<string | null>;
26
39
  }
27
- export declare function useCommunicationChannels({ channels, channelTooltips, selectedChannelType }: UseCommunicationChannelsOptions): {
40
+ export declare function useCommunicationChannels({ channels, channelTooltips, channelOrder, visibleChannelTypes, selectedChannelType, }: UseCommunicationChannelsOptions): {
41
+ panelChannelTypes: ComputedRef<("phone" | "whatsapp" | "telegram" | "sms" | "max")[]>;
28
42
  channelsTypes: ComputedRef<{
29
43
  type: "phone" | "whatsapp" | "telegram" | "sms" | "max";
30
44
  component: Component;
@@ -16,6 +16,8 @@ declare const meta: {
16
16
  attributeTooltips: Record<string, any>;
17
17
  attributeIndicatorTooltips: Record<string, any>;
18
18
  showChannelIcons: boolean;
19
+ channelOrder?: unknown[] | undefined;
20
+ visibleChannelTypes?: unknown[] | undefined;
19
21
  $props: {
20
22
  readonly channels?: unknown[] | undefined;
21
23
  readonly messages?: unknown[] | undefined;
@@ -30,6 +32,8 @@ declare const meta: {
30
32
  readonly attributeTooltips?: Record<string, any> | undefined;
31
33
  readonly attributeIndicatorTooltips?: Record<string, any> | undefined;
32
34
  readonly showChannelIcons?: boolean | undefined;
35
+ readonly channelOrder?: unknown[] | undefined;
36
+ readonly visibleChannelTypes?: unknown[] | undefined;
33
37
  };
34
38
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
35
39
  args: {};
@@ -37,4 +41,8 @@ declare const meta: {
37
41
  export default meta;
38
42
  type Story = StoryObj<typeof meta>;
39
43
  export declare const Default: Story;
44
+ /** Только телефон — без мессенджеров (нет доступных каналов связи). */
45
+ export declare const PhoneOnly: Story;
46
+ /** Доступны только WhatsApp и Telegram, свой порядок. */
47
+ export declare const LimitedMessengers: Story;
40
48
  export declare const InteractiveWithFeed: Story;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mobilon-dev/chotto",
3
- "version": "0.3.78",
3
+ "version": "0.3.79",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",