@hulkapps/app-manager-vue 3.1.22 → 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.22",
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",
@@ -397,7 +397,7 @@ export default {
397
397
  if (this.discount_code !== null) {
398
398
  params['discount_code'] = this.discount_code;
399
399
  }
400
- params['frontend_sdk_version'] = "3.1.22"
400
+ params['frontend_sdk_version'] = "3.1.23"
401
401
  let {data} = await axios.get(`${this.app_manager_config.baseUrl}/api/app-manager/plans`, {params: params}).catch(error => {
402
402
  console.error(error)
403
403
  });
@@ -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
  },
@@ -115,7 +131,8 @@ export default {
115
131
  return Number.isNaN(normalized) ? fallback : normalized;
116
132
  },
117
133
  getSortedPlanHighlights(plan) {
118
- return Object.values(plan.highlights || {})
134
+ return Object.values(plan.details || {})
135
+ .filter((highlight) => highlight.type === "highlight")
119
136
  .sort((a, b) => this.normalizeSortOrder(a.sort_order) - this.normalizeSortOrder(b.sort_order))
120
137
  .map((highlight) => ({
121
138
  plan_id: highlight.plan_id,
@@ -128,6 +145,33 @@ export default {
128
145
  slug: `highlight_${highlight.id}`,
129
146
  }));
130
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
+ },
131
175
  getSortedPlanFeatures(plan) {
132
176
  const assignedFeatureUuids = new Set(Object.keys(plan.features || {}));
133
177
 
@@ -531,6 +575,37 @@ export default {
531
575
  >
532
576
  {{ translateMe('Note: On account of your recent Shopify plan upgrade, you should consider upgrading your current app plan') }}
533
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>
534
609
  </div>
535
610
  </div>
536
611
  </div>
@@ -663,6 +738,37 @@ export default {
663
738
  >
664
739
  {{ translateMe('Note: On account of your recent Shopify plan upgrade, you should consider upgrading your current app plan') }}
665
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>
666
772
  </div>
667
773
  </div>
668
774
  </div>
@@ -713,6 +819,8 @@ export default {
713
819
  }
714
820
 
715
821
  .card {
822
+ position: relative;
823
+ z-index: 1;
716
824
  height: 100%;
717
825
  display: flex;
718
826
  flex-direction: column;
@@ -721,6 +829,16 @@ export default {
721
829
  padding: 16px;
722
830
  }
723
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
+
724
842
  .swiper-wrapper .swiper-slide .card-border.last-card,
725
843
  .swiper-wrapper .swiper-slide:not(.swiper-slide-active) .card-border {
726
844
  border-left: 1px solid #cccccc;
@@ -760,6 +878,7 @@ export default {
760
878
 
761
879
  .card .trial_days,
762
880
  .card .description,
881
+ .card .plan-detail,
763
882
  .card .plan-note {
764
883
  font-size: 13px;
765
884
  font-weight: 400;
@@ -767,11 +886,92 @@ export default {
767
886
  }
768
887
 
769
888
  .card .trial_days,
770
- .card .description {
889
+ .card .description,
890
+ .card .plan-detail {
771
891
  text-align: center;
772
892
  text-transform: unset;
773
893
  }
774
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
+
775
975
  .card .plan-note {
776
976
  margin-top: 8px;
777
977
  text-align: center;