@platforma-sdk/ui-vue 1.42.24 → 1.42.34

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.
Files changed (27) hide show
  1. package/.turbo/turbo-build.log +12 -12
  2. package/.turbo/turbo-type-check.log +1 -1
  3. package/CHANGELOG.md +13 -0
  4. package/dist/plugins/Monetization/LimitCard.vue2.js +59 -46
  5. package/dist/plugins/Monetization/LimitCard.vue2.js.map +1 -1
  6. package/dist/plugins/Monetization/LimitCard.vue3.js +21 -17
  7. package/dist/plugins/Monetization/LimitCard.vue3.js.map +1 -1
  8. package/dist/plugins/Monetization/MonetizationSidebar.vue.js +39 -39
  9. package/dist/plugins/Monetization/MonetizationSidebar.vue.js.map +1 -1
  10. package/dist/plugins/Monetization/RunStatus.vue.d.ts +1 -0
  11. package/dist/plugins/Monetization/RunStatus.vue2.js +17 -20
  12. package/dist/plugins/Monetization/RunStatus.vue2.js.map +1 -1
  13. package/dist/plugins/Monetization/RunStatus.vue3.js +15 -13
  14. package/dist/plugins/Monetization/RunStatus.vue3.js.map +1 -1
  15. package/dist/plugins/Monetization/UserCabinetCard.vue.d.ts +1 -0
  16. package/dist/plugins/Monetization/UserCabinetCard.vue2.js +42 -34
  17. package/dist/plugins/Monetization/UserCabinetCard.vue2.js.map +1 -1
  18. package/dist/plugins/Monetization/UserCabinetCard.vue3.js +17 -15
  19. package/dist/plugins/Monetization/UserCabinetCard.vue3.js.map +1 -1
  20. package/dist/plugins/Monetization/useInfo.js +5 -5
  21. package/dist/plugins/Monetization/useInfo.js.map +1 -1
  22. package/package.json +7 -7
  23. package/src/plugins/Monetization/LimitCard.vue +94 -40
  24. package/src/plugins/Monetization/MonetizationSidebar.vue +3 -5
  25. package/src/plugins/Monetization/RunStatus.vue +11 -15
  26. package/src/plugins/Monetization/UserCabinetCard.vue +23 -1
  27. package/src/plugins/Monetization/useInfo.ts +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"RunStatus.vue2.js","sources":["../../../src/plugins/Monetization/RunStatus.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { PlIcon24, PlTooltip } from '@milaboratories/uikit';\n\nconst props = defineProps<{\n canRun: boolean | undefined;\n statusText: string | undefined;\n}>();\n\nconst tooltipText = computed(() => {\n if (props.canRun) {\n return 'Can run';\n }\n\n return 'Cannot run: check your monetization settings';\n});\n\nconst badgeText = computed(() => {\n if (props.canRun) {\n return 'Ready to run';\n }\n\n return 'Cannot run';\n});\n</script>\n\n<template>\n <div>\n <div :class=\"[{ [$style['can-run']]: canRun }, $style.container]\">\n <div :class=\"$style.badge\">\n <i :class=\"$style.blob\">\n <span>\n <span :class=\"$style.dot\" />\n </span>\n </i>\n <span>{{ badgeText }}</span>\n </div>\n <PlTooltip v-if=\"false\">\n <template #tooltip>\n {{ tooltipText }}\n </template>\n <PlIcon24 name=\"info\" />\n </PlTooltip>\n <slot />\n </div>\n <div v-if=\"statusText\" :class=\"$style.statusText\">{{ statusText }}</div>\n </div>\n</template>\n\n<style module>\n.container {\n display: flex;\n align-items: center;\n gap: 8px;\n --blob-color: #FF5C5C;\n --badge-background: rgba(255, 92, 92, 0.12);\n &.can-run {\n --blob-color: #49CC49;\n --badge-background: rgba(99, 224, 36, 0.12);\n }\n}\n\n.statusText {\n margin-top: 6px;\n color: var(--txt-error);\n font-size: 14px;\n font-weight: 500;\n line-height: 20px;\n}\n\n.badge {\n display: flex;\n gap: 6px;\n height: 40px;\n padding: 6px 16px 6px 8px;\n align-items: center;\n border-radius: 6px;\n border: 1px solid var(--badge-background);\n background: var(--badge-background);\n}\n\n.blob {\n width: 24px;\n height: 24px;\n display: flex;\n place-items: center;\n place-content: center;\n\n >span {\n display: flex;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n place-content: center;\n place-items: center;\n background-color: rgb(from var(--blob-color) r g b / 0.24);\n }\n\n .dot {\n border-radius: 50%;\n height: 8px;\n width: 8px;\n transform: scale(1);\n\n background: var(--blob-color);\n box-shadow: 0 0 0 0 var(--blob-color);\n animation: pulse-glob 1s infinite;\n }\n}\n</style>\n"],"names":["props","__props","computed","badgeText"],"mappings":";;;;;;;;;AAIA,UAAMA,IAAQC;AAKM,IAAAC,EAAS,MACvBF,EAAM,SACD,YAGF,8CACR;AAED,UAAMG,IAAYD,EAAS,MACrBF,EAAM,SACD,iBAGF,YACR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"RunStatus.vue2.js","sources":["../../../src/plugins/Monetization/RunStatus.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue';\n\nconst props = defineProps<{\n canRun: boolean | undefined;\n statusText: string | undefined;\n isLoading?: boolean;\n}>();\n\nconst badgeText = computed(() => {\n if (props.isLoading) {\n return 'Updating...';\n }\n\n if (props.canRun) {\n return 'Ready to run';\n }\n\n return 'Cannot run';\n});\n</script>\n\n<template>\n <div>\n <div :class=\"[{ [$style['can-run']]: canRun, [$style.loading]: isLoading }, $style.container]\">\n <div :class=\"$style.badge\">\n <i :class=\"$style.blob\">\n <span>\n <span :class=\"$style.dot\" />\n </span>\n </i>\n <span>{{ badgeText }}</span>\n </div>\n <slot />\n </div>\n <div v-if=\"statusText\" :class=\"$style.statusText\">{{ statusText }}</div>\n </div>\n</template>\n\n<style module>\n.container {\n display: flex;\n align-items: center;\n gap: 8px;\n --blob-color: #FF5C5C;\n --badge-background: rgba(255, 92, 92, 0.12);\n\n &.can-run {\n --blob-color: #49CC49;\n --badge-background: rgba(99, 224, 36, 0.12);\n }\n\n &.loading {\n --blob-color: #FFAD0A;\n --badge-background: rgba(255, 173, 10, 0.12);\n }\n}\n\n.statusText {\n margin-top: 6px;\n color: var(--txt-error);\n font-size: 14px;\n font-weight: 500;\n line-height: 20px;\n}\n\n.badge {\n display: flex;\n gap: 6px;\n height: 40px;\n padding: 6px 16px 6px 8px;\n align-items: center;\n border-radius: 6px;\n border: 1px solid var(--badge-background);\n background: var(--badge-background);\n}\n\n.blob {\n width: 24px;\n height: 24px;\n display: flex;\n place-items: center;\n place-content: center;\n\n >span {\n display: flex;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n place-content: center;\n place-items: center;\n background-color: rgb(from var(--blob-color) r g b / 0.24);\n }\n\n .dot {\n border-radius: 50%;\n height: 8px;\n width: 8px;\n transform: scale(1);\n\n background: var(--blob-color);\n box-shadow: 0 0 0 0 var(--blob-color);\n animation: pulse-glob 1s infinite;\n }\n}\n</style>\n"],"names":["props","__props","badgeText","computed"],"mappings":";;;;;;;;;AAGA,UAAMA,IAAQC,GAMRC,IAAYC,EAAS,MACrBH,EAAM,YACD,gBAGLA,EAAM,SACD,iBAGF,YACR;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,19 +1,21 @@
1
- (function(){"use strict";try{if(typeof document<"u"){var e=document.createElement("style");e.appendChild(document.createTextNode("._container_s8cm3_2{display:flex;align-items:center;gap:8px;--blob-color: #FF5C5C;--badge-background: rgba(255, 92, 92, .12)}._container_s8cm3_2._can-run_s8cm3_8{--blob-color: #49CC49;--badge-background: rgba(99, 224, 36, .12)}._statusText_s8cm3_14{margin-top:6px;color:var(--txt-error);font-size:14px;font-weight:500;line-height:20px}._badge_s8cm3_22{display:flex;gap:6px;height:40px;padding:6px 16px 6px 8px;align-items:center;border-radius:6px;border:1px solid var(--badge-background);background:var(--badge-background)}._blob_s8cm3_33{width:24px;height:24px;display:flex;place-items:center;place-content:center}._blob_s8cm3_33>span{display:flex;width:16px;height:16px;border-radius:50%;place-content:center;place-items:center;background-color:rgb(from var(--blob-color) r g b / .24)}._blob_s8cm3_33 ._dot_s8cm3_50{border-radius:50%;height:8px;width:8px;transform:scale(1);background:var(--blob-color);box-shadow:0 0 0 0 var(--blob-color);animation:_pulse-glob_s8cm3_1 1s infinite}")),document.head.appendChild(e)}}catch(o){console.error("vite-plugin-css-injected-by-js",o)}})();
2
- const t = "_container_s8cm3_2", s = "_statusText_s8cm3_14", _ = "_badge_s8cm3_22", c = "_blob_s8cm3_33", o = "_dot_s8cm3_50", n = {
1
+ (function(){"use strict";try{if(typeof document<"u"){var e=document.createElement("style");e.appendChild(document.createTextNode("._container_1l90y_2{display:flex;align-items:center;gap:8px;--blob-color: #FF5C5C;--badge-background: rgba(255, 92, 92, .12)}._container_1l90y_2._can-run_1l90y_9{--blob-color: #49CC49;--badge-background: rgba(99, 224, 36, .12)}._container_1l90y_2._loading_1l90y_14{--blob-color: #FFAD0A;--badge-background: rgba(255, 173, 10, .12)}._statusText_1l90y_20{margin-top:6px;color:var(--txt-error);font-size:14px;font-weight:500;line-height:20px}._badge_1l90y_28{display:flex;gap:6px;height:40px;padding:6px 16px 6px 8px;align-items:center;border-radius:6px;border:1px solid var(--badge-background);background:var(--badge-background)}._blob_1l90y_39{width:24px;height:24px;display:flex;place-items:center;place-content:center}._blob_1l90y_39>span{display:flex;width:16px;height:16px;border-radius:50%;place-content:center;place-items:center;background-color:rgb(from var(--blob-color) r g b / .24)}._blob_1l90y_39 ._dot_1l90y_56{border-radius:50%;height:8px;width:8px;transform:scale(1);background:var(--blob-color);box-shadow:0 0 0 0 var(--blob-color);animation:_pulse-glob_1l90y_1 1s infinite}")),document.head.appendChild(e)}}catch(o){console.error("vite-plugin-css-injected-by-js",o)}})();
2
+ const t = "_container_1l90y_2", _ = "_loading_1l90y_14", o = "_statusText_1l90y_20", l = "_badge_1l90y_28", n = "_blob_1l90y_39", s = "_dot_1l90y_56", a = {
3
3
  container: t,
4
- "can-run": "_can-run_s8cm3_8",
5
- statusText: s,
6
- badge: _,
7
- blob: c,
8
- "pulse-glob": "_pulse-glob_s8cm3_1",
9
- dot: o
4
+ "can-run": "_can-run_1l90y_9",
5
+ loading: _,
6
+ statusText: o,
7
+ badge: l,
8
+ blob: n,
9
+ "pulse-glob": "_pulse-glob_1l90y_1",
10
+ dot: s
10
11
  };
11
12
  export {
12
- _ as badge,
13
- c as blob,
13
+ l as badge,
14
+ n as blob,
14
15
  t as container,
15
- n as default,
16
- o as dot,
17
- s as statusText
16
+ a as default,
17
+ s as dot,
18
+ _ as loading,
19
+ o as statusText
18
20
  };
19
21
  //# sourceMappingURL=RunStatus.vue3.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"RunStatus.vue3.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;"}
1
+ {"version":3,"file":"RunStatus.vue3.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;"}
@@ -1,5 +1,6 @@
1
1
  type __VLS_Props = {
2
2
  userCabinetUrl: string;
3
+ email?: string;
3
4
  };
4
5
  declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
5
6
  export default _default;
@@ -1,63 +1,71 @@
1
- import { defineComponent as y, ref as C, computed as v, createElementBlock as s, openBlock as i, createCommentVNode as b, createElementVNode as l, normalizeClass as o, createVNode as r, toDisplayString as n, unref as c, withCtx as p, createTextVNode as f } from "vue";
2
- import { PlTooltip as U, PlMaskIcon24 as h } from "@milaboratories/uikit";
3
- const k = ["title"], V = /* @__PURE__ */ y({
1
+ import { defineComponent as v, ref as b, computed as f, createElementBlock as a, openBlock as s, createCommentVNode as p, createElementVNode as o, normalizeClass as t, createVNode as u, toDisplayString as i, unref as c, withCtx as d, createTextVNode as U } from "vue";
2
+ import { PlTooltip as k, PlMaskIcon24 as $ } from "@milaboratories/uikit";
3
+ const T = ["title"], w = /* @__PURE__ */ v({
4
4
  __name: "UserCabinetCard",
5
5
  props: {
6
- userCabinetUrl: {}
6
+ userCabinetUrl: {},
7
+ email: {}
7
8
  },
8
- setup(u) {
9
- const a = u, t = C(""), d = v(() => t.value ? "clipboard-copied" : "clipboard"), m = () => {
10
- a.userCabinetUrl && navigator.clipboard.writeText(a.userCabinetUrl).then(() => {
11
- t.value = "URL copied!", setTimeout(() => {
12
- t.value = "";
9
+ setup(m) {
10
+ const n = m, l = b(""), y = f(() => l.value ? "clipboard-copied" : "clipboard"), C = () => {
11
+ n.userCabinetUrl && navigator.clipboard.writeText(n.userCabinetUrl).then(() => {
12
+ l.value = "URL copied!", setTimeout(() => {
13
+ l.value = "";
13
14
  }, 2e3);
14
15
  }).catch((e) => {
15
- console.error("Failed to copy text: ", e), t.value = "Copy failed", setTimeout(() => {
16
- t.value = "";
16
+ console.error("Failed to copy text: ", e), l.value = "Copy failed", setTimeout(() => {
17
+ l.value = "";
17
18
  }, 2e3);
18
19
  });
19
20
  };
20
- return (e, T) => (i(), s("div", null, [
21
- e.userCabinetUrl ? (i(), s("div", {
21
+ return (e, r) => (s(), a("div", null, [
22
+ e.userCabinetUrl ? (s(), a("div", {
22
23
  key: 0,
23
- class: o(e.$style.urlSection)
24
+ class: t(e.$style.urlSection)
24
25
  }, [
25
- l("div", {
26
- class: o(e.$style.urlLabel)
26
+ o("div", {
27
+ class: t(e.$style.urlLabel)
27
28
  }, "Scientist cabinet URL:", 2),
28
- l("div", {
29
- class: o(e.$style.urlActions)
29
+ o("div", {
30
+ class: t(e.$style.urlActions)
30
31
  }, [
31
- l("div", {
32
- class: o(e.$style.urlDisplay),
32
+ o("div", {
33
+ class: t(e.$style.urlDisplay),
33
34
  title: e.userCabinetUrl
34
- }, n(e.userCabinetUrl), 11, k),
35
- r(c(U), {
35
+ }, i(e.userCabinetUrl), 11, T),
36
+ u(c(k), {
36
37
  "close-delay": 800,
37
38
  position: "top"
38
39
  }, {
39
- tooltip: p(() => [
40
- f(n(t.value ? t.value : "Copy"), 1)
40
+ tooltip: d(() => [
41
+ U(i(l.value ? l.value : "Copy"), 1)
41
42
  ]),
42
- default: p(() => [
43
- r(c(h), {
44
- class: o(e.$style.copyIcon),
43
+ default: d(() => [
44
+ u(c($), {
45
+ class: t(e.$style.copyIcon),
45
46
  title: "Copy content",
46
- name: d.value,
47
- onClick: m
47
+ name: y.value,
48
+ onClick: C
48
49
  }, null, 8, ["class", "name"])
49
50
  ]),
50
51
  _: 1
51
52
  })
52
- ], 2)
53
- ], 2)) : b("", !0),
54
- l("div", {
55
- class: o(e.$style.hint)
53
+ ], 2),
54
+ e.email ? (s(), a("div", {
55
+ key: 0,
56
+ class: t(e.$style.email)
57
+ }, [
58
+ r[0] || (r[0] = o("span", null, "License owner:", -1)),
59
+ o("span", null, i(e.email), 1)
60
+ ], 2)) : p("", !0)
61
+ ], 2)) : p("", !0),
62
+ o("div", {
63
+ class: t(e.$style.hint)
56
64
  }, " * Copy and paste the link into your browser ", 2)
57
65
  ]));
58
66
  }
59
67
  });
60
68
  export {
61
- V as default
69
+ w as default
62
70
  };
63
71
  //# sourceMappingURL=UserCabinetCard.vue2.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"UserCabinetCard.vue2.js","sources":["../../../src/plugins/Monetization/UserCabinetCard.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, computed } from 'vue';\nimport { PlTooltip, PlMaskIcon24 } from '@milaboratories/uikit';\n\nconst props = defineProps<{\n userCabinetUrl: string;\n}>();\n\nconst copiedMessage = ref('');\n\nconst iconName = computed(() => (copiedMessage.value ? 'clipboard-copied' : 'clipboard'));\n\nconst copyToClipboard = () => {\n if (props.userCabinetUrl) {\n navigator.clipboard.writeText(props.userCabinetUrl)\n .then(() => {\n copiedMessage.value = 'URL copied!';\n setTimeout(() => {\n copiedMessage.value = '';\n }, 2000);\n })\n .catch((err) => {\n console.error('Failed to copy text: ', err);\n copiedMessage.value = 'Copy failed';\n setTimeout(() => {\n copiedMessage.value = '';\n }, 2000);\n });\n }\n};\n</script>\n\n<template>\n <div>\n <div v-if=\"userCabinetUrl\" :class=\"$style.urlSection\">\n <div :class=\"$style.urlLabel\">Scientist cabinet URL:</div>\n <div :class=\"$style.urlActions\">\n <div :class=\"$style.urlDisplay\" :title=\"userCabinetUrl\">{{ userCabinetUrl }}</div>\n <PlTooltip :close-delay=\"800\" position=\"top\">\n <PlMaskIcon24 :class=\"$style.copyIcon\" title=\"Copy content\" :name=\"iconName\" @click=\"copyToClipboard\" />\n <template #tooltip>{{ copiedMessage ? copiedMessage : 'Copy' }}</template>\n </PlTooltip>\n </div>\n </div>\n <div :class=\"$style.hint\">\n * Copy and paste the link into your browser\n </div>\n </div>\n</template>\n\n<style module>\n.hint {\n margin-top: 6px;\n color: var(--txt-03);\n font-size: 12px;\n font-weight: 500;\n line-height: 16px;\n}\n\n.copyIcon {\n cursor: pointer;\n}\n\n.urlSection {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 12px;\n background-color: #f0f0f0;\n border-radius: 6px;\n}\n\n.urlLabel {\n font-weight: 500;\n color: #555;\n}\n\n.urlActions {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: nowrap;\n}\n\n.urlDisplay {\n font-family: monospace;\n font-size: 14px;\n color: #0066cc;\n padding: 6px 10px 6px 0;\n border-radius: 4px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 300px;\n}\n</style>\n"],"names":["props","__props","copiedMessage","ref","iconName","computed","copyToClipboard","err"],"mappings":";;;;;;;;AAIA,UAAMA,IAAQC,GAIRC,IAAgBC,EAAI,EAAE,GAEtBC,IAAWC,EAAS,MAAOH,EAAc,QAAQ,qBAAqB,WAAY,GAElFI,IAAkB,MAAM;AAC5B,MAAIN,EAAM,kBACR,UAAU,UAAU,UAAUA,EAAM,cAAc,EAC/C,KAAK,MAAM;AACV,QAAAE,EAAc,QAAQ,eACtB,WAAW,MAAM;AACf,UAAAA,EAAc,QAAQ;AAAA,QACxB,GAAG,GAAI;AAAA,MACT,CAAC,EACA,MAAM,CAACK,MAAQ;AACd,gBAAQ,MAAM,yBAAyBA,CAAG,GAC1CL,EAAc,QAAQ,eACtB,WAAW,MAAM;AACf,UAAAA,EAAc,QAAQ;AAAA,QACxB,GAAG,GAAI;AAAA,MACT,CAAC;AAAA,IAEP;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"UserCabinetCard.vue2.js","sources":["../../../src/plugins/Monetization/UserCabinetCard.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, computed } from 'vue';\nimport { PlTooltip, PlMaskIcon24 } from '@milaboratories/uikit';\n\nconst props = defineProps<{\n userCabinetUrl: string;\n email?: string;\n}>();\n\nconst copiedMessage = ref('');\n\nconst iconName = computed(() => (copiedMessage.value ? 'clipboard-copied' : 'clipboard'));\n\nconst copyToClipboard = () => {\n if (props.userCabinetUrl) {\n navigator.clipboard.writeText(props.userCabinetUrl)\n .then(() => {\n copiedMessage.value = 'URL copied!';\n setTimeout(() => {\n copiedMessage.value = '';\n }, 2000);\n })\n .catch((err) => {\n console.error('Failed to copy text: ', err);\n copiedMessage.value = 'Copy failed';\n setTimeout(() => {\n copiedMessage.value = '';\n }, 2000);\n });\n }\n};\n</script>\n\n<template>\n <div>\n <div v-if=\"userCabinetUrl\" :class=\"$style.urlSection\">\n <div :class=\"$style.urlLabel\">Scientist cabinet URL:</div>\n <div :class=\"$style.urlActions\">\n <div :class=\"$style.urlDisplay\" :title=\"userCabinetUrl\">{{ userCabinetUrl }}</div>\n <PlTooltip :close-delay=\"800\" position=\"top\">\n <PlMaskIcon24 :class=\"$style.copyIcon\" title=\"Copy content\" :name=\"iconName\" @click=\"copyToClipboard\" />\n <template #tooltip>{{ copiedMessage ? copiedMessage : 'Copy' }}</template>\n </PlTooltip>\n </div>\n <div v-if=\"email\" :class=\"$style.email\">\n <span>License owner:</span>\n <span>{{ email }}</span>\n </div>\n </div>\n <div :class=\"$style.hint\">\n * Copy and paste the link into your browser\n </div>\n </div>\n</template>\n\n<style module>\n.hint {\n margin-top: 6px;\n color: var(--txt-03);\n font-size: 12px;\n font-weight: 500;\n line-height: 16px;\n}\n\n.email {\n display: flex;\n align-items: center;\n justify-content: space-between;\n font-size: 12px;\n color: var(--txt-03);\n\n > span:last-child {\n max-width: 200px;\n text-overflow: ellipsis;\n display: block;\n white-space: nowrap;\n overflow: hidden;\n }\n}\n\n.copyIcon {\n cursor: pointer;\n}\n\n.urlSection {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 12px;\n background-color: #F7F8FA;\n border-radius: 6px;\n border: 1px solid #E1E3EB;\n}\n\n.urlLabel {\n font-weight: 500;\n color: #555;\n}\n\n.urlActions {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: nowrap;\n}\n\n.urlDisplay {\n font-family: monospace;\n font-size: 14px;\n color: #0066cc;\n padding: 6px 10px 6px 0;\n border-radius: 4px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 300px;\n}\n</style>\n"],"names":["props","__props","copiedMessage","ref","iconName","computed","copyToClipboard","err"],"mappings":";;;;;;;;;AAIA,UAAMA,IAAQC,GAKRC,IAAgBC,EAAI,EAAE,GAEtBC,IAAWC,EAAS,MAAOH,EAAc,QAAQ,qBAAqB,WAAY,GAElFI,IAAkB,MAAM;AAC5B,MAAIN,EAAM,kBACR,UAAU,UAAU,UAAUA,EAAM,cAAc,EAC/C,KAAK,MAAM;AACV,QAAAE,EAAc,QAAQ,eACtB,WAAW,MAAM;AACf,UAAAA,EAAc,QAAQ;AAAA,QACxB,GAAG,GAAI;AAAA,MACT,CAAC,EACA,MAAM,CAACK,MAAQ;AACd,gBAAQ,MAAM,yBAAyBA,CAAG,GAC1CL,EAAc,QAAQ,eACtB,WAAW,MAAM;AACf,UAAAA,EAAc,QAAQ;AAAA,QACxB,GAAG,GAAI;AAAA,MACT,CAAC;AAAA,IAEP;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,19 +1,21 @@
1
- (function(){"use strict";try{if(typeof document<"u"){var e=document.createElement("style");e.appendChild(document.createTextNode("._hint_1bvg8_2{margin-top:6px;color:var(--txt-03);font-size:12px;font-weight:500;line-height:16px}._copyIcon_1bvg8_10{cursor:pointer}._urlSection_1bvg8_14{display:flex;flex-direction:column;gap:8px;padding:12px;background-color:#f0f0f0;border-radius:6px}._urlLabel_1bvg8_23{font-weight:500;color:#555}._urlActions_1bvg8_28{display:flex;align-items:center;gap:10px;flex-wrap:nowrap}._urlDisplay_1bvg8_35{font-family:monospace;font-size:14px;color:#06c;padding:6px 10px 6px 0;border-radius:4px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:300px}")),document.head.appendChild(e)}}catch(o){console.error("vite-plugin-css-injected-by-js",o)}})();
2
- const l = "_hint_1bvg8_2", o = "_copyIcon_1bvg8_10", c = "_urlSection_1bvg8_14", n = "_urlLabel_1bvg8_23", t = "_urlActions_1bvg8_28", _ = "_urlDisplay_1bvg8_35", s = {
3
- hint: l,
4
- copyIcon: o,
5
- urlSection: c,
6
- urlLabel: n,
7
- urlActions: t,
8
- urlDisplay: _
1
+ (function(){"use strict";try{if(typeof document<"u"){var e=document.createElement("style");e.appendChild(document.createTextNode("._hint_hc54t_2{margin-top:6px;color:var(--txt-03);font-size:12px;font-weight:500;line-height:16px}._email_hc54t_10{display:flex;align-items:center;justify-content:space-between;font-size:12px;color:var(--txt-03)}._email_hc54t_10>span:last-child{max-width:200px;text-overflow:ellipsis;display:block;white-space:nowrap;overflow:hidden}._copyIcon_hc54t_26{cursor:pointer}._urlSection_hc54t_30{display:flex;flex-direction:column;gap:8px;padding:12px;background-color:#f7f8fa;border-radius:6px;border:1px solid #E1E3EB}._urlLabel_hc54t_40{font-weight:500;color:#555}._urlActions_hc54t_45{display:flex;align-items:center;gap:10px;flex-wrap:nowrap}._urlDisplay_hc54t_52{font-family:monospace;font-size:14px;color:#06c;padding:6px 10px 6px 0;border-radius:4px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:300px}")),document.head.appendChild(e)}}catch(t){console.error("vite-plugin-css-injected-by-js",t)}})();
2
+ const c = "_hint_hc54t_2", t = "_email_hc54t_10", l = "_copyIcon_hc54t_26", o = "_urlSection_hc54t_30", _ = "_urlLabel_hc54t_40", n = "_urlActions_hc54t_45", s = "_urlDisplay_hc54t_52", i = {
3
+ hint: c,
4
+ email: t,
5
+ copyIcon: l,
6
+ urlSection: o,
7
+ urlLabel: _,
8
+ urlActions: n,
9
+ urlDisplay: s
9
10
  };
10
11
  export {
11
- o as copyIcon,
12
- s as default,
13
- l as hint,
14
- t as urlActions,
15
- _ as urlDisplay,
16
- n as urlLabel,
17
- c as urlSection
12
+ l as copyIcon,
13
+ i as default,
14
+ t as email,
15
+ c as hint,
16
+ n as urlActions,
17
+ s as urlDisplay,
18
+ _ as urlLabel,
19
+ o as urlSection
18
20
  };
19
21
  //# sourceMappingURL=UserCabinetCard.vue3.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"UserCabinetCard.vue3.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
1
+ {"version":3,"file":"UserCabinetCard.vue3.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;"}
@@ -1,14 +1,14 @@
1
1
  import { computed as n, ref as i, watch as g } from "vue";
2
2
  import { useSdkPlugin as h } from "../../defineApp.js";
3
- import { Response as w } from "./validation.js";
4
- import { useIntervalFn as D } from "@vueuse/core";
3
+ import { Response as D } from "./validation.js";
4
+ import { useIntervalFn as O } from "@vueuse/core";
5
5
  function E() {
6
6
  const m = h(), s = n(() => m.loaded ? m.useApp() : void 0), a = n(() => {
7
7
  var e, o;
8
8
  return "__mnzDate" in ((o = (e = s.value) == null ? void 0 : e.model) == null ? void 0 : o.args);
9
9
  }), v = n(() => {
10
10
  var e;
11
- return w.safeParse((e = s.value) == null ? void 0 : e.model.outputs.__mnzInfo);
11
+ return D.safeParse((e = s.value) == null ? void 0 : e.model.outputs.__mnzInfo);
12
12
  }), c = n(() => {
13
13
  var e;
14
14
  return (e = v.value) == null ? void 0 : e.data;
@@ -33,7 +33,7 @@ function E() {
33
33
  return !!((e = t.value) != null && e.canRun);
34
34
  }), z = n(() => {
35
35
  var e;
36
- return c.value ? (e = t.value) == null ? void 0 : e.status : "awaiting";
36
+ return c.value ? (e = t.value) == null ? void 0 : e.status : "";
37
37
  }), I = n(() => {
38
38
  var e;
39
39
  return (e = t.value) == null ? void 0 : e.customerEmail;
@@ -50,7 +50,7 @@ function E() {
50
50
  return g(f, (e) => {
51
51
  var o;
52
52
  a.value && (((o = s.value) == null ? void 0 : o.model.args).__mnzCanRun = e);
53
- }), a.value && D(d, 6e4), {
53
+ }), a.value && O(d, 6e4), {
54
54
  hasMonetization: a,
55
55
  result: t,
56
56
  error: _,
@@ -1 +1 @@
1
- {"version":3,"file":"useInfo.js","sources":["../../../src/plugins/Monetization/useInfo.ts"],"sourcesContent":["import { computed, watch, ref } from 'vue';\nimport { useSdkPlugin } from '../../defineApp';\nimport { Response } from './validation';\nimport { useIntervalFn } from '@vueuse/core';\n\nexport function useInfo() {\n const sdk = useSdkPlugin();\n\n const app = computed(() => (sdk.loaded ? sdk.useApp() : undefined));\n\n const hasMonetization = computed(() => '__mnzDate' in (app.value?.model?.args as Record<string, unknown>));\n\n const parsed = computed(() => Response.safeParse(app.value?.model.outputs['__mnzInfo']));\n\n const currentInfo = computed<Response | undefined>(() => parsed.value?.data);\n\n const error = computed(() => parsed.value?.error ?? info.value?.response?.error);\n\n const info = ref<Response | undefined>(undefined);\n\n const isLoading = ref(false);\n\n const version = ref(0);\n\n watch([currentInfo], ([i]) => {\n if (i) {\n info.value = i;\n const v = ++version.value;\n setTimeout(() => {\n if (version.value === v) {\n isLoading.value = false;\n }\n }, 1000);\n }\n }, { immediate: true });\n\n const result = computed(() => info.value?.response?.result);\n\n const canRun = computed(() => !!result.value?.canRun);\n\n const status = computed(() => currentInfo.value ? result.value?.status : 'awaiting');\n\n const customerEmail = computed(() => result.value?.customerEmail);\n\n const endOfBillingPeriod = computed(() => result.value?.mnz.endOfBillingPeriod);\n\n const limits = computed(() => result.value?.mnz.limits);\n\n const refresh = () => {\n isLoading.value = true;\n (app.value?.model.args as Record<string, unknown>)['__mnzDate'] = new Date().toISOString();\n };\n\n watch(canRun, (v) => {\n if (hasMonetization.value) {\n (app.value?.model.args as Record<string, unknown>)['__mnzCanRun'] = v;\n }\n });\n\n if (hasMonetization.value) {\n useIntervalFn(refresh, 60_000); // 1 minute\n }\n\n return {\n hasMonetization,\n result,\n error,\n canRun,\n status,\n customerEmail,\n endOfBillingPeriod,\n limits,\n refresh,\n version,\n isLoading,\n };\n}\n"],"names":["useInfo","sdk","useSdkPlugin","app","computed","hasMonetization","_b","_a","parsed","Response","currentInfo","error","_c","info","ref","isLoading","version","watch","i","v","result","canRun","status","customerEmail","endOfBillingPeriod","limits","refresh","useIntervalFn"],"mappings":";;;;AAKO,SAASA,IAAU;AACxB,QAAMC,IAAMC,EAAA,GAENC,IAAMC,EAAS,MAAOH,EAAI,SAASA,EAAI,OAAA,IAAW,MAAU,GAE5DI,IAAkBD,EAAS,MAAA;;AAAM,4BAAgBE,KAAAC,IAAAJ,EAAI,UAAJ,gBAAAI,EAAW,UAAX,gBAAAD,EAAkB;AAAA,GAAgC,GAEnGE,IAASJ,EAAS,MAAA;;AAAM,WAAAK,EAAS,WAAUF,IAAAJ,EAAI,UAAJ,gBAAAI,EAAW,MAAM,QAAQ,SAAY;AAAA,GAAC,GAEjFG,IAAcN,EAA+B,MAAA;;AAAM,YAAAG,IAAAC,EAAO,UAAP,gBAAAD,EAAc;AAAA,GAAI,GAErEI,IAAQP,EAAS,MAAA;;AAAM,aAAAG,IAAAC,EAAO,UAAP,gBAAAD,EAAc,YAASK,KAAAN,IAAAO,EAAK,UAAL,gBAAAP,EAAY,aAAZ,gBAAAM,EAAsB;AAAA,GAAK,GAEzEC,IAAOC,EAA0B,MAAS,GAE1CC,IAAYD,EAAI,EAAK,GAErBE,IAAUF,EAAI,CAAC;AAErB,EAAAG,EAAM,CAACP,CAAW,GAAG,CAAC,CAACQ,CAAC,MAAM;AAC5B,QAAIA,GAAG;AACL,MAAAL,EAAK,QAAQK;AACb,YAAMC,IAAI,EAAEH,EAAQ;AACpB,iBAAW,MAAM;AACf,QAAIA,EAAQ,UAAUG,MACpBJ,EAAU,QAAQ;AAAA,MAEtB,GAAG,GAAI;AAAA,IACT;AAAA,EACF,GAAG,EAAE,WAAW,IAAM;AAEtB,QAAMK,IAAShB,EAAS,MAAA;;AAAM,YAAAE,KAAAC,IAAAM,EAAK,UAAL,gBAAAN,EAAY,aAAZ,gBAAAD,EAAsB;AAAA,GAAM,GAEpDe,IAASjB,EAAS,MAAA;;AAAM,YAAC,GAACG,IAAAa,EAAO,UAAP,QAAAb,EAAc;AAAA,GAAM,GAE9Ce,IAASlB,EAAS;;AAAM,WAAAM,EAAY,SAAQH,IAAAa,EAAO,UAAP,gBAAAb,EAAc,SAAS;AAAA,GAAU,GAE7EgB,IAAgBnB,EAAS,MAAA;;AAAM,YAAAG,IAAAa,EAAO,UAAP,gBAAAb,EAAc;AAAA,GAAa,GAE1DiB,IAAqBpB,EAAS,MAAA;;AAAM,YAAAG,IAAAa,EAAO,UAAP,gBAAAb,EAAc,IAAI;AAAA,GAAkB,GAExEkB,IAASrB,EAAS,MAAA;;AAAM,YAAAG,IAAAa,EAAO,UAAP,gBAAAb,EAAc,IAAI;AAAA,GAAM,GAEhDmB,IAAU,MAAM;;AACpB,IAAAX,EAAU,QAAQ,MACjBR,IAAAJ,EAAI,UAAJ,gBAAAI,EAAW,MAAM,MAAiC,aAAe,oBAAI,KAAA,GAAO,YAAA;AAAA,EAC/E;AAEA,SAAAU,EAAMI,GAAQ,CAACF,MAAM;;AACnB,IAAId,EAAgB,YACjBE,IAAAJ,EAAI,UAAJ,gBAAAI,EAAW,MAAM,MAAiC,cAAiBY;AAAA,EAExE,CAAC,GAEGd,EAAgB,SAClBsB,EAAcD,GAAS,GAAM,GAGxB;AAAA,IACL,iBAAArB;AAAA,IACA,QAAAe;AAAA,IACA,OAAAT;AAAA,IACA,QAAAU;AAAA,IACA,QAAAC;AAAA,IACA,eAAAC;AAAA,IACA,oBAAAC;AAAA,IACA,QAAAC;AAAA,IACA,SAAAC;AAAA,IACA,SAAAV;AAAA,IACA,WAAAD;AAAA,EAAA;AAEJ;"}
1
+ {"version":3,"file":"useInfo.js","sources":["../../../src/plugins/Monetization/useInfo.ts"],"sourcesContent":["import { computed, watch, ref } from 'vue';\nimport { useSdkPlugin } from '../../defineApp';\nimport { Response } from './validation';\nimport { useIntervalFn } from '@vueuse/core';\n\nexport function useInfo() {\n const sdk = useSdkPlugin();\n\n const app = computed(() => (sdk.loaded ? sdk.useApp() : undefined));\n\n const hasMonetization = computed(() => '__mnzDate' in (app.value?.model?.args as Record<string, unknown>));\n\n const parsed = computed(() => Response.safeParse(app.value?.model.outputs['__mnzInfo']));\n\n const currentInfo = computed<Response | undefined>(() => parsed.value?.data);\n\n const error = computed(() => parsed.value?.error ?? info.value?.response?.error);\n\n const info = ref<Response | undefined>(undefined);\n\n const isLoading = ref(false);\n\n const version = ref(0);\n\n watch([currentInfo], ([i]) => {\n if (i) {\n info.value = i;\n const v = ++version.value;\n setTimeout(() => {\n if (version.value === v) {\n isLoading.value = false;\n }\n }, 1000);\n }\n }, { immediate: true });\n\n const result = computed(() => info.value?.response?.result);\n\n const canRun = computed(() => !!result.value?.canRun);\n\n const status = computed(() => currentInfo.value ? result.value?.status : '');\n\n const customerEmail = computed(() => result.value?.customerEmail);\n\n const endOfBillingPeriod = computed(() => result.value?.mnz.endOfBillingPeriod);\n\n const limits = computed(() => result.value?.mnz.limits);\n\n const refresh = () => {\n isLoading.value = true;\n (app.value?.model.args as Record<string, unknown>)['__mnzDate'] = new Date().toISOString();\n };\n\n watch(canRun, (v) => {\n if (hasMonetization.value) {\n (app.value?.model.args as Record<string, unknown>)['__mnzCanRun'] = v;\n }\n });\n\n if (hasMonetization.value) {\n useIntervalFn(refresh, 60_000); // 1 minute\n }\n\n return {\n hasMonetization,\n result,\n error,\n canRun,\n status,\n customerEmail,\n endOfBillingPeriod,\n limits,\n refresh,\n version,\n isLoading,\n };\n}\n"],"names":["useInfo","sdk","useSdkPlugin","app","computed","hasMonetization","_b","_a","parsed","Response","currentInfo","error","_c","info","ref","isLoading","version","watch","i","v","result","canRun","status","customerEmail","endOfBillingPeriod","limits","refresh","useIntervalFn"],"mappings":";;;;AAKO,SAASA,IAAU;AACxB,QAAMC,IAAMC,EAAA,GAENC,IAAMC,EAAS,MAAOH,EAAI,SAASA,EAAI,OAAA,IAAW,MAAU,GAE5DI,IAAkBD,EAAS,MAAA;;AAAM,4BAAgBE,KAAAC,IAAAJ,EAAI,UAAJ,gBAAAI,EAAW,UAAX,gBAAAD,EAAkB;AAAA,GAAgC,GAEnGE,IAASJ,EAAS,MAAA;;AAAM,WAAAK,EAAS,WAAUF,IAAAJ,EAAI,UAAJ,gBAAAI,EAAW,MAAM,QAAQ,SAAY;AAAA,GAAC,GAEjFG,IAAcN,EAA+B,MAAA;;AAAM,YAAAG,IAAAC,EAAO,UAAP,gBAAAD,EAAc;AAAA,GAAI,GAErEI,IAAQP,EAAS,MAAA;;AAAM,aAAAG,IAAAC,EAAO,UAAP,gBAAAD,EAAc,YAASK,KAAAN,IAAAO,EAAK,UAAL,gBAAAP,EAAY,aAAZ,gBAAAM,EAAsB;AAAA,GAAK,GAEzEC,IAAOC,EAA0B,MAAS,GAE1CC,IAAYD,EAAI,EAAK,GAErBE,IAAUF,EAAI,CAAC;AAErB,EAAAG,EAAM,CAACP,CAAW,GAAG,CAAC,CAACQ,CAAC,MAAM;AAC5B,QAAIA,GAAG;AACL,MAAAL,EAAK,QAAQK;AACb,YAAMC,IAAI,EAAEH,EAAQ;AACpB,iBAAW,MAAM;AACf,QAAIA,EAAQ,UAAUG,MACpBJ,EAAU,QAAQ;AAAA,MAEtB,GAAG,GAAI;AAAA,IACT;AAAA,EACF,GAAG,EAAE,WAAW,IAAM;AAEtB,QAAMK,IAAShB,EAAS,MAAA;;AAAM,YAAAE,KAAAC,IAAAM,EAAK,UAAL,gBAAAN,EAAY,aAAZ,gBAAAD,EAAsB;AAAA,GAAM,GAEpDe,IAASjB,EAAS,MAAA;;AAAM,YAAC,GAACG,IAAAa,EAAO,UAAP,QAAAb,EAAc;AAAA,GAAM,GAE9Ce,IAASlB,EAAS;;AAAM,WAAAM,EAAY,SAAQH,IAAAa,EAAO,UAAP,gBAAAb,EAAc,SAAS;AAAA,GAAE,GAErEgB,IAAgBnB,EAAS,MAAA;;AAAM,YAAAG,IAAAa,EAAO,UAAP,gBAAAb,EAAc;AAAA,GAAa,GAE1DiB,IAAqBpB,EAAS,MAAA;;AAAM,YAAAG,IAAAa,EAAO,UAAP,gBAAAb,EAAc,IAAI;AAAA,GAAkB,GAExEkB,IAASrB,EAAS,MAAA;;AAAM,YAAAG,IAAAa,EAAO,UAAP,gBAAAb,EAAc,IAAI;AAAA,GAAM,GAEhDmB,IAAU,MAAM;;AACpB,IAAAX,EAAU,QAAQ,MACjBR,IAAAJ,EAAI,UAAJ,gBAAAI,EAAW,MAAM,MAAiC,aAAe,oBAAI,KAAA,GAAO,YAAA;AAAA,EAC/E;AAEA,SAAAU,EAAMI,GAAQ,CAACF,MAAM;;AACnB,IAAId,EAAgB,YACjBE,IAAAJ,EAAI,UAAJ,gBAAAI,EAAW,MAAM,MAAiC,cAAiBY;AAAA,EAExE,CAAC,GAEGd,EAAgB,SAClBsB,EAAcD,GAAS,GAAM,GAGxB;AAAA,IACL,iBAAArB;AAAA,IACA,QAAAe;AAAA,IACA,OAAAT;AAAA,IACA,QAAAU;AAAA,IACA,QAAAC;AAAA,IACA,eAAAC;AAAA,IACA,oBAAAC;AAAA,IACA,QAAAC;AAAA,IACA,SAAAC;AAAA,IACA,SAAAV;AAAA,IACA,WAAAD;AAAA,EAAA;AAEJ;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platforma-sdk/ui-vue",
3
- "version": "1.42.24",
3
+ "version": "1.42.34",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "styles": "dist/index.js",
@@ -25,9 +25,9 @@
25
25
  "@vueuse/integrations": "^13.3.0",
26
26
  "d3-format": "^3.1.0",
27
27
  "zod": "~3.23.8",
28
- "@milaboratories/biowasm-tools": "^1.1.2",
29
- "@milaboratories/uikit": "2.4.5",
30
- "@platforma-sdk/model": "~1.42.23"
28
+ "@milaboratories/biowasm-tools": "1.1.2",
29
+ "@milaboratories/uikit": "2.4.6",
30
+ "@platforma-sdk/model": "1.42.25"
31
31
  },
32
32
  "devDependencies": {
33
33
  "happy-dom": "^15.11.7",
@@ -42,10 +42,10 @@
42
42
  "yarpm": "^1.2.0",
43
43
  "fast-json-patch": "^3.1.1",
44
44
  "@faker-js/faker": "^9.2.0",
45
- "@milaboratories/eslint-config": "^1.0.4",
46
45
  "@milaboratories/ts-configs": "1.0.6",
47
- "@milaboratories/helpers": "^1.6.21",
48
- "@milaboratories/ts-builder": "1.0.4",
46
+ "@milaboratories/helpers": "1.6.22",
47
+ "@milaboratories/ts-builder": "1.0.5",
48
+ "@milaboratories/eslint-config": "1.0.4",
49
49
  "@milaboratories/build-configs": "1.0.8"
50
50
  },
51
51
  "scripts": {
@@ -10,19 +10,42 @@ const props = defineProps<{
10
10
  unit?: string;
11
11
  }>();
12
12
 
13
+ const total = computed(() => {
14
+ if (props.available === null) return null;
15
+ return props.available + props.toSpend + props.used;
16
+ });
17
+
18
+ const exceeded = computed(() => {
19
+ if (props.available === null) return false;
20
+ return props.available < 0;
21
+ });
22
+
23
+ const availableNow = computed(() => {
24
+ if (props.available === null) return null;
25
+ return props.available + props.toSpend;
26
+ });
27
+
28
+ const clampPercentage = (n: number) => Math.max(0, Math.min(100, n));
29
+
13
30
  const toSpendPercentage = computed(() => {
14
- if (props.available === null) return 0;
15
- return (props.toSpend / props.available) * 100;
31
+ if (total.value === null) return 0;
32
+ if (total.value === 0) return 0;
33
+ if (exceeded.value) return 0;
34
+ return clampPercentage((props.toSpend / total.value) * 100);
16
35
  });
17
36
 
18
37
  const usedPercentage = computed(() => {
19
- if (props.available === null) return 0;
20
- return (props.used / props.available) * 100;
38
+ if (total.value === null) return 0;
39
+ if (total.value === 0) return 0;
40
+ return clampPercentage((props.used / total.value) * 100);
21
41
  });
22
42
 
23
43
  const availablePercentage = computed(() => {
24
44
  if (props.available === null) return 100;
25
- return 100 - usedPercentage.value - toSpendPercentage.value;
45
+ if (total.value === null) return 100;
46
+ if (total.value === 0) return 100;
47
+ if (exceeded.value) return 0;
48
+ return clampPercentage(props.available / total.value * 100);
26
49
  });
27
50
 
28
51
  const computedLabel = computed(() => {
@@ -39,6 +62,10 @@ const formatUnit = (v: number) => {
39
62
  if (props.type === 'volume_limit') return toGB(v);
40
63
  return v;
41
64
  };
65
+
66
+ const showBar = (n: number) => {
67
+ return Number(n.toFixed(2)) > 0;
68
+ };
42
69
  </script>
43
70
 
44
71
  <template>
@@ -46,25 +73,33 @@ const formatUnit = (v: number) => {
46
73
  <span :class="$style.label">{{ computedLabel }}</span>
47
74
  <div :class="$style.content">
48
75
  <div :class="$style.contentAvailable">
49
- Available:
50
- <div style="flex: 1" />
51
- <span v-if="available !== null"><strong>{{ formatUnit(available) }}</strong> / {{ formatUnit(available + toSpend + used) }}</span>
52
- <span v-else>Unlimited</span>
53
- </div>
54
- <div :class="$style.progressBar">
55
- <span :class="$style.progressBarAvailable" :style="{ width: `${availablePercentage}%` }" />
56
- <span :class="$style.progressBarToSpend" :style="{ width: `${toSpendPercentage}%` }" />
57
- <span :class="$style.progressBarUsed" :style="{ width: `${usedPercentage}%` }" />
76
+ <div>
77
+ Available:
78
+ <div style="flex: 1" />
79
+ <span v-if="availableNow !== null"><strong>{{ formatUnit(availableNow) }}</strong> / {{ formatUnit(available! + toSpend + used) }}</span>
80
+ <span v-else>Unlimited</span>
81
+ </div>
82
+ <div :class="[$style.afterRun, { [$style.exceeded]: exceeded }]">
83
+ <span v-if="exceeded">Too many files selected</span>
84
+ <span style="flex: 1" />
85
+ <span>After run:</span>
86
+ <span v-if="available !== null">{{ formatUnit(available) }} / {{ formatUnit(available + toSpend + used) }}</span>
87
+ </div>
88
+ <div :class="[$style.progressBar, { [$style.exceeded]: exceeded }]">
89
+ <span v-if="showBar(availablePercentage)" :class="$style.progressBarAvailable" :style="{ width: `${availablePercentage.toFixed(2)}%` }" />
90
+ <span v-if="showBar(toSpendPercentage)" :class="$style.progressBarToSpend" :style="{ width: `${toSpendPercentage.toFixed(2)}%` }" />
91
+ <span v-if="showBar(usedPercentage)" :class="$style.progressBarUsed" :style="{ width: `${usedPercentage.toFixed(2)}%` }" />
92
+ </div>
58
93
  </div>
59
94
  <div :class="$style.legends">
60
- <div :class="$style.usedLegend">
61
- <span/>
62
- Used: {{ formatUnit(used) }}
63
- </div>
64
95
  <div :class="$style.toSpendLegend">
65
96
  <span/>
66
97
  To spend: {{ formatUnit(toSpend) }}
67
98
  </div>
99
+ <div :class="$style.usedLegend">
100
+ <span/>
101
+ Used: {{ formatUnit(used) }}
102
+ </div>
68
103
  </div>
69
104
  </div>
70
105
  </div>
@@ -74,7 +109,6 @@ const formatUnit = (v: number) => {
74
109
  .container {
75
110
  display: flex;
76
111
  flex-direction: column;
77
- gap: 8px;
78
112
  background-color: var(--bg-base-light);
79
113
  border-radius: 6px;
80
114
  padding: 10px 12px 16px 12px;
@@ -87,7 +121,8 @@ const formatUnit = (v: number) => {
87
121
 
88
122
  .label {
89
123
  display: block;
90
- margin-bottom: 30px;
124
+ min-height: 36px;
125
+ margin-bottom: 8px;
91
126
  color: var(--txt-01);
92
127
  font-size: 14px;
93
128
  font-weight: 600;
@@ -97,64 +132,83 @@ const formatUnit = (v: number) => {
97
132
  .content {
98
133
  display: flex;
99
134
  flex-direction: column;
100
- gap: 20px;
135
+ gap: 16px;
101
136
  }
102
137
 
103
138
  .contentAvailable {
104
139
  display: flex;
105
- align-items: flex-start;
106
- gap: 8px;
107
- strong {
108
- font-size: 28px;
109
- font-weight: 500;
110
- line-height: 36px; /* 128.571% */
111
- letter-spacing: -0.56px;
140
+ flex-direction: column;
141
+ gap: 6px;
142
+ > div {
143
+ display: flex;
144
+ align-items: flex-start;
145
+ }
146
+ >div:first-child {
147
+ gap: 8px;
148
+ strong {
149
+ font-size: 28px;
150
+ font-weight: 500;
151
+ line-height: 36px; /* 128.571% */
152
+ letter-spacing: -0.56px;
153
+ }
154
+ }
155
+ }
156
+
157
+ .afterRun {
158
+ display: flex;
159
+ align-items: center;
160
+ justify-content: flex-end;
161
+ gap: 4px;
162
+ font-size: 12px;
163
+ font-style: normal;
164
+ font-weight: 500;
165
+ line-height: 16px;
166
+ color: var(--txt-03);
167
+ &.exceeded {
168
+ color: var(--txt-error);
112
169
  }
113
170
  }
114
171
 
115
172
  .progressBar {
116
173
  width: 100%;
117
- height: 8px;
174
+ height: 12px;
118
175
  background-color: #E0E0E0;
119
- border-radius: 4px;
120
176
  display: flex;
121
177
  align-items: center;
122
178
  border: 1px solid var(--border-color-default);
123
179
  > span {
124
180
  display: block;
125
181
  height: 100%;
182
+ outline: 1px solid var(--border-color-default);
183
+ }
184
+ &.exceeded {
185
+ opacity: 0.2;
126
186
  }
127
187
  }
128
188
 
129
189
  .progressBarAvailable {
130
- background-color: #49CC49;
131
- border-radius: 4px;
190
+ background: linear-gradient(270deg, #A1E59C 0%, #D0F5B0 98.81%);
132
191
  }
133
192
 
134
193
  .progressBarUsed {
135
194
  background-color: #FFCECC;
136
- border-radius: 4px;
137
195
  }
138
196
 
139
197
  .progressBarToSpend {
140
198
  background-color: #FAF5AA;
141
- border-radius: 4px;
142
199
  }
143
200
 
144
201
  .legends {
145
202
  display: flex;
203
+ justify-content: space-between;
146
204
  gap: 8px;
147
205
 
148
- > div {
149
- flex: 1;
150
- }
151
-
152
206
  span {
153
207
  display: block;
154
208
  border-radius: 1px;
155
209
  border: 1px solid var(--border-color-default);
156
- width: 16px;
157
- height: 16px;
210
+ width: 12px;
211
+ height: 12px;
158
212
  }
159
213
  }
160
214
 
@@ -62,10 +62,8 @@ const statusText = computed(() => {
62
62
  return 'Select a subscription plan in the Scientist Cabinet.';
63
63
  case 'inactive':
64
64
  return 'Not found billing period.';
65
- case 'awaiting':
66
- return 'Waiting for monetization information';
67
65
  default:
68
- return 'Unknown status: ' + status.value;
66
+ return '';
69
67
  }
70
68
  });
71
69
 
@@ -83,7 +81,7 @@ const btnIcon = computed(() => {
83
81
  </div>
84
82
  </template>
85
83
  <PlDropdown label="Product" readonly :model-value="productName" :options="options" />
86
- <RunStatus :can-run="canRun" :status-text="statusText">
84
+ <RunStatus :can-run="canRun" :is-loading="isLoading" :status-text="statusText">
87
85
  <PlBtnSecondary
88
86
  title="Refresh status"
89
87
  round
@@ -97,7 +95,7 @@ const btnIcon = computed(() => {
97
95
  <PlAlert v-if="error" type="error">
98
96
  {{ error }}
99
97
  </PlAlert>
100
- <UserCabinetCard v-if="userCabinetUrl" :user-cabinet-url="userCabinetUrl" />
98
+ <UserCabinetCard v-if="userCabinetUrl" :email="customerEmail" :user-cabinet-url="userCabinetUrl" />
101
99
  <EndOfPeriod v-if="endOfBillingPeriod" :end-of-period="endOfBillingPeriod" />
102
100
  <template v-if="limits">
103
101
  <LimitCard