@hulkapps/app-manager-vue 3.1.21 → 3.1.23

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hulkapps/app-manager-vue",
3
- "version": "3.1.21",
3
+ "version": "3.1.23",
4
4
  "description": "Vue SDK to render app manager contents",
5
5
  "main": "dist/app-manager-vue.ssr.js",
6
6
  "browser": "dist/app-manager-vue.esm.js",
@@ -68,7 +68,8 @@
68
68
  </strong>
69
69
  </ToggleButton> -->
70
70
  </div>
71
- <PlanShowcaseBanner
71
+ <!-- -------------------- Bundle Plan Banner -------------------- -->
72
+ <!-- <PlanShowcaseBanner
72
73
  v-if="bundle_plan"
73
74
  :useCardStyle="true"
74
75
  :width="this.width"
@@ -76,7 +77,7 @@
76
77
  :realPrice="parseFloat(calculateDiscountedPrice(bundle_plan)).toFixed(0)"
77
78
  :oldPrice="bundle_plan.price" @plan-clicked="handlePlanClicked(bundle_plan)"
78
79
  :isCurrentPlan="isCurrentPlanId(bundle_plan)"
79
- />
80
+ /> -->
80
81
  <PPage
81
82
  :class="[
82
83
  'app-manager-plan-page-slider',
@@ -396,7 +397,7 @@ export default {
396
397
  if (this.discount_code !== null) {
397
398
  params['discount_code'] = this.discount_code;
398
399
  }
399
- params['frontend_sdk_version'] = "3.1.21"
400
+ params['frontend_sdk_version'] = "3.1.23"
400
401
  let {data} = await axios.get(`${this.app_manager_config.baseUrl}/api/app-manager/plans`, {params: params}).catch(error => {
401
402
  console.error(error)
402
403
  });
@@ -1,7 +1,7 @@
1
1
  <script>
2
2
  import VariantButton from "./VariantButton";
3
3
  import Swiper, {Navigation, Pagination} from "swiper";
4
- import {calculatePlanPriceWithDiscounts, isPlanButtonDisabled, formatFeature, getPlanButtonText, isPlanNote} from "@/helpers";
4
+ import {calculatePlanPriceWithDiscounts, isPlanButtonDisabled, formatFeature, getPlanButtonText, isPlanNote, isPublicPlan} from "@/helpers";
5
5
 
6
6
  export default {
7
7
  name: "PlanCardsHighlights",
@@ -57,11 +57,17 @@ export default {
57
57
  anyAnnuallyPlanHasDiscount: false,
58
58
  anyMonthlyPlanHasNote: false,
59
59
  anyAnnuallyPlanHasNote: false,
60
+ anyMonthlyPlanHasDetail: false,
61
+ anyAnnuallyPlanHasDetail: false,
60
62
  loadingPlanId: null
61
63
  };
62
64
  },
63
65
  computed: {
64
66
  monthlyPlans() {
67
+ this.anyMonthlyPlanHasDiscount = false;
68
+ this.anyMonthlyPlanHasNote = false;
69
+ this.anyMonthlyPlanHasDetail = false;
70
+
65
71
  return this.plans
66
72
  .filter(plan => plan.interval === "EVERY_30_DAYS")
67
73
  .map(plan => {
@@ -76,10 +82,17 @@ export default {
76
82
  ) {
77
83
  this.anyMonthlyPlanHasNote = true;
78
84
  }
85
+ if (this.getSortedPlanDetails(plan).length > 0 && this.anyMonthlyPlanHasDetail === false) {
86
+ this.anyMonthlyPlanHasDetail = true;
87
+ }
79
88
  return planDetails;
80
89
  });
81
90
  },
82
91
  annualPlans() {
92
+ this.anyAnnuallyPlanHasDiscount = false;
93
+ this.anyAnnuallyPlanHasNote = false;
94
+ this.anyAnnuallyPlanHasDetail = false;
95
+
83
96
  return this.plans
84
97
  .filter(plan => plan.interval === "ANNUAL")
85
98
  .map(plan => {
@@ -94,6 +107,9 @@ export default {
94
107
  ) {
95
108
  this.anyAnnuallyPlanHasNote = true;
96
109
  }
110
+ if (this.getSortedPlanDetails(plan).length > 0 && this.anyAnnuallyPlanHasDetail === false) {
111
+ this.anyAnnuallyPlanHasDetail = true;
112
+ }
97
113
  return planDetails;
98
114
  });
99
115
  },
@@ -105,6 +121,7 @@ export default {
105
121
  }
106
122
  },
107
123
  methods: {
124
+ isPublicPlan,
108
125
  getPlanButtonText,
109
126
  isPlanNote,
110
127
  isPlanButtonDisabled,
@@ -114,7 +131,8 @@ export default {
114
131
  return Number.isNaN(normalized) ? fallback : normalized;
115
132
  },
116
133
  getSortedPlanHighlights(plan) {
117
- return Object.values(plan.highlights || {})
134
+ return Object.values(plan.details || {})
135
+ .filter((highlight) => highlight.type === "highlight")
118
136
  .sort((a, b) => this.normalizeSortOrder(a.sort_order) - this.normalizeSortOrder(b.sort_order))
119
137
  .map((highlight) => ({
120
138
  plan_id: highlight.plan_id,
@@ -127,6 +145,33 @@ export default {
127
145
  slug: `highlight_${highlight.id}`,
128
146
  }));
129
147
  },
148
+ getSortedPlanDetails(plan) {
149
+ return Object.values(plan.details || {})
150
+ .filter((detail) => detail.type === "detail")
151
+ .sort((a, b) => this.normalizeSortOrder(a.sort_order) - this.normalizeSortOrder(b.sort_order))
152
+ .map((detail) => ({
153
+ plan_id: detail.plan_id,
154
+ feature_id: `detail_${detail.id}`,
155
+ uuid: `detail_${detail.id}`,
156
+ value: "1",
157
+ value_type: "boolean",
158
+ name: detail.text,
159
+ format: null,
160
+ slug: `detail_${detail.id}`,
161
+ }));
162
+ },
163
+ getPrimaryPlanDetail(plan) {
164
+ const details = this.getSortedPlanDetails(plan);
165
+ return details.length ? details[0] : null;
166
+ },
167
+ getAdditionalPlanDetails(plan) {
168
+ const details = this.getSortedPlanDetails(plan);
169
+ if (details.length <= 1) {
170
+ return [];
171
+ }
172
+
173
+ return details.slice(1);
174
+ },
130
175
  getSortedPlanFeatures(plan) {
131
176
  const assignedFeatureUuids = new Set(Object.keys(plan.features || {}));
132
177
 
@@ -462,7 +507,7 @@ export default {
462
507
  visibility:
463
508
  plan.description
464
509
  && selectedInterval === 'monthly'
465
- && plan.is_custom === false
510
+ && isPublicPlan(plan)
466
511
  ? 'visible'
467
512
  : 'hidden',
468
513
  }"
@@ -530,6 +575,37 @@ export default {
530
575
  >
531
576
  {{ translateMe('Note: On account of your recent Shopify plan upgrade, you should consider upgrading your current app plan') }}
532
577
  </p>
578
+ <h6
579
+ class="plan-detail"
580
+ v-if="anyMonthlyPlanHasDetail"
581
+ :style="{
582
+ visibility:
583
+ selectedInterval === 'monthly' && getPrimaryPlanDetail(plan)
584
+ ? 'visible'
585
+ : 'hidden',
586
+ }"
587
+ >
588
+ <span>
589
+ {{ getPrimaryPlanDetail(plan) ? translateMe(getPrimaryPlanDetail(plan).name) : '' }}
590
+ <span
591
+ v-if="getAdditionalPlanDetails(plan).length"
592
+ class="plan-detail-tooltip-wrapper"
593
+ tabindex="0"
594
+ role="button"
595
+ aria-label="Show more plan details"
596
+ >
597
+ <span class="plan-detail-info">i</span>
598
+ <span class="plan-detail-tooltip">
599
+ <span
600
+ v-for="(detail, detailIndex) in getAdditionalPlanDetails(plan)"
601
+ :key="`monthly_detail_${plan.id}_${detailIndex}`"
602
+ >
603
+ {{ translateMe(detail.name) }}
604
+ </span>
605
+ </span>
606
+ </span>
607
+ </span>
608
+ </h6>
533
609
  </div>
534
610
  </div>
535
611
  </div>
@@ -594,7 +670,7 @@ export default {
594
670
  visibility:
595
671
  plan.description
596
672
  && selectedInterval === 'annually'
597
- && plan.is_custom === false
673
+ && isPublicPlan(plan)
598
674
  ? 'visible'
599
675
  : 'hidden',
600
676
  }"
@@ -662,6 +738,37 @@ export default {
662
738
  >
663
739
  {{ translateMe('Note: On account of your recent Shopify plan upgrade, you should consider upgrading your current app plan') }}
664
740
  </p>
741
+ <h6
742
+ class="plan-detail"
743
+ v-if="anyAnnuallyPlanHasDetail"
744
+ :style="{
745
+ visibility:
746
+ selectedInterval === 'annually' && getPrimaryPlanDetail(plan)
747
+ ? 'visible'
748
+ : 'hidden',
749
+ }"
750
+ >
751
+ <span>
752
+ {{ getPrimaryPlanDetail(plan) ? translateMe(getPrimaryPlanDetail(plan).name) : '' }}
753
+ <span
754
+ v-if="getAdditionalPlanDetails(plan).length"
755
+ class="plan-detail-tooltip-wrapper"
756
+ tabindex="0"
757
+ role="button"
758
+ aria-label="Show more plan details"
759
+ >
760
+ <span class="plan-detail-info">i</span>
761
+ <span class="plan-detail-tooltip">
762
+ <span
763
+ v-for="(detail, detailIndex) in getAdditionalPlanDetails(plan)"
764
+ :key="`annually_detail_${plan.id}_${detailIndex}`"
765
+ >
766
+ {{ translateMe(detail.name) }}
767
+ </span>
768
+ </span>
769
+ </span>
770
+ </span>
771
+ </h6>
665
772
  </div>
666
773
  </div>
667
774
  </div>
@@ -712,6 +819,8 @@ export default {
712
819
  }
713
820
 
714
821
  .card {
822
+ position: relative;
823
+ z-index: 1;
715
824
  height: 100%;
716
825
  display: flex;
717
826
  flex-direction: column;
@@ -720,6 +829,16 @@ export default {
720
829
  padding: 16px;
721
830
  }
722
831
 
832
+ .swiper-wrapper .swiper-slide {
833
+ position: relative;
834
+ z-index: 1;
835
+ }
836
+
837
+ .swiper-wrapper .swiper-slide:hover,
838
+ .swiper-wrapper .swiper-slide:focus-within {
839
+ z-index: 4;
840
+ }
841
+
723
842
  .swiper-wrapper .swiper-slide .card-border.last-card,
724
843
  .swiper-wrapper .swiper-slide:not(.swiper-slide-active) .card-border {
725
844
  border-left: 1px solid #cccccc;
@@ -759,6 +878,7 @@ export default {
759
878
 
760
879
  .card .trial_days,
761
880
  .card .description,
881
+ .card .plan-detail,
762
882
  .card .plan-note {
763
883
  font-size: 13px;
764
884
  font-weight: 400;
@@ -766,11 +886,92 @@ export default {
766
886
  }
767
887
 
768
888
  .card .trial_days,
769
- .card .description {
889
+ .card .description,
890
+ .card .plan-detail {
770
891
  text-align: center;
771
892
  text-transform: unset;
772
893
  }
773
894
 
895
+ .card .plan-detail {
896
+ display: inline-flex;
897
+ align-items: center;
898
+ gap: 6px;
899
+ min-height: 20px;
900
+ width: 100%;
901
+ justify-content: center;
902
+ border-top: 1px solid #cccccc;
903
+ margin-top: 16px;
904
+ padding-top: 12px;
905
+ }
906
+
907
+ .plan-detail-info {
908
+ display: inline-flex;
909
+ align-items: center;
910
+ justify-content: center;
911
+ width: 16px;
912
+ height: 16px;
913
+ border-radius: 50%;
914
+ border: 1px solid #757575;
915
+ color: #4A4A4A;
916
+ font-size: 12px;
917
+ line-height: 1;
918
+ cursor: help;
919
+ user-select: none;
920
+ }
921
+
922
+ .plan-detail-tooltip-wrapper {
923
+ position: relative;
924
+ display: inline-flex;
925
+ align-items: center;
926
+ justify-content: center;
927
+ outline: none;
928
+ }
929
+
930
+ .plan-detail-tooltip {
931
+ position: absolute;
932
+ right: -8px;
933
+ bottom: calc(100% + 8px);
934
+ background-color: white;
935
+ color: #333;
936
+ font-weight: 500;
937
+ max-width: 250px;
938
+ min-width: 150px;
939
+ padding: 8px 12px;
940
+ border-radius: 8px;
941
+ font-size: 13px;
942
+ box-shadow: 0 4px 8px #00000026;
943
+ opacity: 0;
944
+ visibility: hidden;
945
+ pointer-events: none;
946
+ transition: opacity 0.2s ease, transform 0.2s ease;
947
+ z-index: 20;
948
+ }
949
+
950
+ .plan-detail-tooltip span {
951
+ display: block;
952
+ text-align: left;
953
+ }
954
+
955
+ .plan-detail-tooltip::after {
956
+ content: '';
957
+ position: absolute;
958
+ top: 100%;
959
+ right: 12px;
960
+ width: 0;
961
+ height: 0;
962
+ border-left: 8px solid transparent;
963
+ border-right: 8px solid transparent;
964
+ border-top: 8px solid white;
965
+ filter: drop-shadow(0 2px 2px rgba(0, 0, 0, 0.1));
966
+ }
967
+
968
+ .plan-detail-tooltip-wrapper:hover .plan-detail-tooltip,
969
+ .plan-detail-tooltip-wrapper:focus .plan-detail-tooltip,
970
+ .plan-detail-tooltip-wrapper:focus-within .plan-detail-tooltip {
971
+ opacity: 1;
972
+ visibility: visible;
973
+ }
974
+
774
975
  .card .plan-note {
775
976
  margin-top: 8px;
776
977
  text-align: center;