@wisemen/wise-crm-web 2.0.0-alpha.27 → 2.0.0-alpha.29

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.
package/README.md ADDED
@@ -0,0 +1,90 @@
1
+ # @wisemen/wise-crm-web
2
+
3
+ Vue 3 CRM package: business, individual and deal overviews, detail views, dialogs and widgets.
4
+
5
+ ## Extending the detail views
6
+
7
+ The business and individual detail views can be extended with content from the host app in two places.
8
+
9
+ ### Custom tabs
10
+
11
+ Tabs next to the detail sidebar are routes, registered through `useWiseCrmRoutes`. At least one tab is required for businesses and individuals. The tab component reads the entity uuid from the route params (`businessUuid` / `individualUuid` / `dealUuid`).
12
+
13
+ ```ts
14
+ useWiseCrmRoutes({
15
+ businessTabRoutes: [
16
+ {
17
+ label: computed<string>(() => t('crm.business.tabs.information')),
18
+ route: {
19
+ name: 'crm-business-information',
20
+ path: 'information',
21
+ component: (): Component => import('./CrmBusinessInformationTabView.vue'),
22
+ },
23
+ },
24
+ ],
25
+ dealTabRoutes: [...],
26
+ individualTabRoutes: [...],
27
+ })
28
+ ```
29
+
30
+ ### Custom sidebar sections
31
+
32
+ Accordion sections rendered at the end of the sidebar's Overview tab, after the built-in sections. They show in both the detail view and the quick-view dialog. Register them through the `business` / `individual` options of `useWiseCrmConfig().init()`:
33
+
34
+ ```ts
35
+ import type { WiseCrmSidebarSection } from '@wisemen/wise-crm-web'
36
+
37
+ useWiseCrmConfig().init({
38
+ // ...
39
+ options: {
40
+ business: {
41
+ sidebarSections: [
42
+ {
43
+ icon: ShoppingCart01Icon,
44
+ key: 'orders',
45
+ label: computed<string>(() => t('crm.business.sidebar.orders')),
46
+ component: defineAsyncComponent(() => import('./BusinessOrdersSidebarSection.vue')),
47
+ },
48
+ ],
49
+ },
50
+ individual: {
51
+ sidebarSections: [...],
52
+ },
53
+ // ...
54
+ },
55
+ })
56
+ ```
57
+
58
+ | Field | Description |
59
+ | -------------- | --------------------------------------------------------------------------------------------------------------------------------- |
60
+ | `key` | Unique per entity; used as the accordion item value. |
61
+ | `label` | Section header, a `ComputedRef<string>` so it follows the locale. |
62
+ | `icon` | Section header icon. |
63
+ | `component` | Section body. |
64
+ | `useIsVisible` | Optional. Receives the component's props as a `ComputedRef` and returns a `ComputedRef<boolean>`; the section is hidden while it is `false`. |
65
+
66
+ The component receives only the entity uuid. It fetches its own data and renders its own loading and empty state. Sections are open by default.
67
+
68
+ ```vue
69
+ <script setup lang="ts">
70
+ import type { WiseCrmBusinessUuid } from '@wisemen/wise-crm-web'
71
+
72
+ const props = defineProps<{
73
+ businessUuid: WiseCrmBusinessUuid
74
+ }>()
75
+ </script>
76
+ ```
77
+
78
+ Individual sections receive `individualUuid: WiseCrmIndividualUuid` instead. A component with the wrong props is a type error.
79
+
80
+ `useIsVisible` is called once in the sidebar's setup, so it can use composables such as queries. Use it to hide a section that has nothing to show for this entity, rather than rendering an empty body under its header:
81
+
82
+ ```ts
83
+ {
84
+ key: 'parent',
85
+ // ...
86
+ useIsVisible: (props) => useBusinessHasParent(computed(() => props.value.businessUuid)),
87
+ }
88
+ ```
89
+
90
+ A section that becomes visible after the sidebar has mounted still opens by default.
@@ -1,8 +1,8 @@
1
1
  import { defineComponent as n, openBlock as o, createBlock as r, unref as s, withCtx as a, createVNode as u } from "vue";
2
2
  import { useRouteParams as m } from "@vueuse/router";
3
- import { _ as p } from "./index-BdE_BLXy.js";
4
- import { bq as c } from "./uuid.util-8nyk7pzI.js";
5
- import { _ } from "./CrmDetailView.vue_vue_type_script_setup_true_lang-UxTnX2I8.js";
3
+ import { _ as p } from "./index-BUpwoOnq.js";
4
+ import { bq as c } from "./uuid.util-DeP0Xkdy.js";
5
+ import { _ } from "./CrmDetailView.vue_vue_type_script_setup_true_lang-64gLoRcz.js";
6
6
  const x = /* @__PURE__ */ n({
7
7
  __name: "BusinessDetailView",
8
8
  props: {
@@ -1,7 +1,7 @@
1
1
  import { defineComponent as v, ref as h, unref as e, openBlock as d, createElementBlock as u, createElementVNode as t, renderSlot as x, createVNode as r, withCtx as f, Fragment as y, renderList as g, createBlock as w, toValue as m, createCommentVNode as b } from "vue";
2
2
  import { onKeyStroke as C } from "@vueuse/core";
3
3
  import { UITabsRouterLink as k, UITabsRouterLinkItem as R, UIIconButton as B } from "@wisemen/vue-core-design-system";
4
- import { d as E, f as T, T as I, a6 as V } from "./index-BdE_BLXy.js";
4
+ import { d as E, f as T, T as I, a6 as V } from "./index-BUpwoOnq.js";
5
5
  import { useRoute as A, RouterView as H } from "vue-router";
6
6
  class U {
7
7
  /**
@@ -1,7 +1,7 @@
1
1
  import { defineComponent as C, openBlock as t, createElementBlock as f, createElementVNode as s, createVNode as a, withCtx as n, toDisplayString as m, unref as e, createBlock as o, createCommentVNode as _, Fragment as g, renderList as v, normalizeClass as b, resolveDynamicComponent as k, computed as M } from "vue";
2
2
  import { useRouteParams as I } from "@vueuse/router";
3
3
  import { useOffsetInfiniteQuery as L } from "@wisemen/vue-core-api-utils";
4
- import { M as T, D as p, g as w, a as A, m as S, b as V, u as j, A as Q } from "./index-BdE_BLXy.js";
4
+ import { M as T, D as p, g as w, a as A, m as S, b as V, u as j, A as Q } from "./index-BUpwoOnq.js";
5
5
  import { UIEmptyState as U } from "@wisemen/vue-core-design-system";
6
6
  import { AnimatePresence as $, Motion as q } from "motion-v";
7
7
  import { AccordionRoot as z, AccordionItem as B, AccordionHeader as E, AccordionTrigger as F, AccordionContent as H } from "reka-ui";
@@ -1,9 +1,9 @@
1
1
  import { defineComponent as x, openBlock as d, createBlock as g, unref as e, ref as V, useTemplateRef as Se, createElementBlock as q, withCtx as r, createVNode as o, mergeProps as O, createElementVNode as S, toDisplayString as z, nextTick as ke, computed as w, createCommentVNode as F, Fragment as te, createTextVNode as ie, renderList as Fe, useModel as $e, mergeModels as Te } from "vue";
2
2
  import { useRouteParams as Me } from "@vueuse/router";
3
3
  import { useI18n as I } from "vue-i18n";
4
- import { bq as fe, bv as Ve, bx as qe, bA as Ee } from "./uuid.util-8nyk7pzI.js";
5
- import { _ as Le } from "./CrmDetailView.vue_vue_type_script_setup_true_lang-UxTnX2I8.js";
6
- import { c as k, d as pe, e as Oe, f as $, h as L, i as Qe, E as _e, C as ge, j as Ae, k as Be, l as Ke, n as je, o as R, g as Re, J as ze, p as Ge, q as re, r as Ye, I as Ze, s as ye, t as A, v as He, w as be, x as Je, y as Xe, U as We, z as ea, u as aa, B as ta, Q as na, F as la, G as oa, H as ia, K as se, L as he, N as ra, O as ue, P as sa, R as ua, S as ca, T as da, V as ve, W as ma, X as fa, Y as pa, Z as _a, $ as ga, a0 as ya, a1 as ba, a2 as ha, a3 as va, a4 as Ua, A as Ca } from "./index-BdE_BLXy.js";
4
+ import { bq as fe, bv as Ve, bx as qe, bA as Ee } from "./uuid.util-DeP0Xkdy.js";
5
+ import { _ as Le } from "./CrmDetailView.vue_vue_type_script_setup_true_lang-64gLoRcz.js";
6
+ import { c as k, d as pe, e as Oe, f as $, h as L, i as Qe, E as _e, C as ge, j as Ae, k as Be, l as Ke, n as je, o as R, g as Re, J as ze, p as Ge, q as re, r as Ye, I as Ze, s as ye, t as A, v as He, w as be, x as Je, y as Xe, U as We, z as ea, u as aa, B as ta, Q as na, F as la, G as oa, H as ia, K as se, L as he, N as ra, O as ue, P as sa, R as ua, S as ca, T as da, V as ve, W as ma, X as fa, Y as pa, Z as _a, $ as ga, a0 as ya, a1 as ba, a2 as ha, a3 as va, a4 as Ua, A as Ca } from "./index-BUpwoOnq.js";
7
7
  import { useToast as Ue, useOverlay as H, UIConfirmDialog as wa, UIIconButton as ne, UITextField as G, toFormField as Q, UIDropdownMenu as Pa, UIDropdownMenuGroup as Da, UIDropdownMenuItem as ce, UIPhoneNumberField as de, UIFormLayout as le, UIFormFieldGroup as B, UIFormFieldGrid as K, UIFormDialog as Ce, UIDialogHeader as we, UIForm as me, UIDialogBody as J, UIDialogFooter as X, UIDialogFooterSubmit as W, createAutocompleteOptions as xa, createSelectOptions as ee, UIAutocomplete as Ia, UISelect as ae, UIButton as Na, UIBadge as Pe } from "@wisemen/vue-core-design-system";
8
8
  import { useMutation as T, useQuery as De, useOffsetInfiniteQuery as Sa, useKeysetInfiniteQuery as ka } from "@wisemen/vue-core-api-utils";
9
9
  import { useForm as Y } from "formango";
@@ -1,8 +1,8 @@
1
1
  import { defineComponent as n, openBlock as o, createBlock as r, unref as i, withCtx as s, createVNode as u } from "vue";
2
2
  import { useRouteParams as d } from "@vueuse/router";
3
- import { bq as m } from "./uuid.util-8nyk7pzI.js";
4
- import { _ as p } from "./CrmDetailView.vue_vue_type_script_setup_true_lang-UxTnX2I8.js";
5
- import { a5 as c } from "./index-BdE_BLXy.js";
3
+ import { bq as m } from "./uuid.util-DeP0Xkdy.js";
4
+ import { _ as p } from "./CrmDetailView.vue_vue_type_script_setup_true_lang-64gLoRcz.js";
5
+ import { a5 as c } from "./index-BUpwoOnq.js";
6
6
  const k = /* @__PURE__ */ n({
7
7
  __name: "IndividualDetailView",
8
8
  props: {