@hulkapps/app-manager-vue 2.1.0 → 2.1.3

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": "2.1.0",
3
+ "version": "2.1.3",
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",
@@ -1,10 +1,56 @@
1
1
  <template>
2
+ <PSkeletonPage title="Plans"
3
+ :fullWidth="false"
4
+ primaryAction
5
+ :secondaryActions="2"
6
+ :breadcrumbs="false"
7
+ v-if="planLoading">
8
+ <PLayout>
9
+ <PLayoutSection oneThird="">
10
+ <PCard sectioned="">
11
+ <PTextContainer>
12
+ <PSkeletonDisplayText size="small" />
13
+ <PSkeletonBodyText />
14
+ </PTextContainer>
15
+ </PCard>
16
+ </PLayoutSection>
17
+ <PLayoutSection oneThird="">
18
+ <PCard sectioned="">
19
+ <PTextContainer>
20
+ <PSkeletonDisplayText size="small" />
21
+ <PSkeletonBodyText />
22
+ </PTextContainer>
23
+ </PCard>
24
+ </PLayoutSection>
25
+ <PLayoutSection oneThird="">
26
+ <PCard sectioned="">
27
+ <PTextContainer>
28
+ <PSkeletonDisplayText size="small" />
29
+ <PSkeletonBodyText />
30
+ </PTextContainer>
31
+ </PCard>
32
+ </PLayoutSection>
33
+ </PLayout>
34
+ <PLayout style="margin-top: 20px">
35
+ <PLayoutSection>
36
+ <PCard sectioned=""><PSkeletonBodyText /></PCard>
37
+ <PCard sectioned=""><PSkeletonBodyText /></PCard>
38
+ <PCard sectioned=""><PSkeletonBodyText /></PCard>
39
+ <PCard sectioned=""><PSkeletonBodyText /></PCard>
40
+ </PLayoutSection>
41
+ </PLayout>
42
+ </PSkeletonPage>
43
+ <PEmptyState
44
+ heading="No Plans"
45
+ image="https://cdn.shopify.com/s/files/1/0262/4071/2726/files/emptystate-files.png"
46
+ v-else-if="!this.planLoading && this.plans.length === 0"
47
+ />
2
48
  <PPage
3
49
  class="app-manager-plan-page custom-title"
4
50
  title="Choose plan"
5
51
  :subtitle = "subtitleContent"
52
+ v-else
6
53
  >
7
-
8
54
  <PStack slot="primaryAction">
9
55
  <PStackItem style="margin-top: 20px">
10
56
  <PButtonGroup class="btn-group" segmented>
@@ -138,8 +184,8 @@
138
184
  <PButton plain @click="activePlan">{{ ('I will choose the plan later') }}</PButton>
139
185
  </PStackItem>
140
186
  </PStack>
187
+ <PlanBanners />
141
188
  </PLayoutSection>
142
- <PlanBanners />
143
189
  </PLayout>
144
190
  <!--====================================================================-->
145
191
  </PPage>
@@ -163,11 +209,17 @@
163
209
  import {PDataTableCol} from "../polaris-vue/src/components/PDataTable/components/PDataTableCol";
164
210
  import {PDataTableRow} from "../polaris-vue/src/components/PDataTable/components/PDataTableRow";
165
211
  import {PIcon} from "../polaris-vue/src/components/PIcon";
212
+ import {PCard} from "../polaris-vue/src/components/PCard"
213
+ import {PCardSection} from "../polaris-vue/src/components/PCard/components/PCardSection"
214
+ import {PSkeletonPage} from "../polaris-vue/src/components/PSkeletonPage"
215
+ import {PSkeletonDisplayText} from "../polaris-vue/src/components/PSkeletonDisplayText"
216
+ import {PSkeletonBodyText} from "../polaris-vue/src/components/PSkeletonBodyText"
166
217
  import {PTextStyle} from "../polaris-vue/src/components/PTextStyle";
218
+ import {PEmptyState} from "../polaris-vue/src/components/PEmptyState";
167
219
 
168
220
  export default {
169
221
  name: "AppManagerGroupPlan",
170
- components: { YearlyPlanPromotion, PlanBanners, PPage, PStack, PStackItem, PButton, PButtonGroup, PHeading, PLayout, PLayoutSection, PTextContainer, PDataTable, PDataTableCol, PDataTableRow, PIcon, PTextStyle },
222
+ components: { YearlyPlanPromotion, PlanBanners, PPage, PStack, PStackItem, PButton, PButtonGroup, PHeading, PLayout, PLayoutSection, PTextContainer, PDataTable, PDataTableCol, PDataTableRow, PIcon, PTextStyle, PCard, PCardSection, PSkeletonPage, PSkeletonBodyText, PSkeletonDisplayText, PEmptyState },
171
223
  props: ['shop_domain'],
172
224
  data() {
173
225
  return {
@@ -178,6 +230,7 @@
178
230
  shopify_plan: '',
179
231
  default_plan_id: null,
180
232
  onboard: true,
233
+ planLoading: false,
181
234
  subtitleContent: '',
182
235
  checkList: [
183
236
  "60 days free trial",
@@ -262,7 +315,7 @@
262
315
  return [plan.shopify_plans.includes(this.shop.shopify_plan) || !plan.store_base_plan ? {backgroundColor: '#f0f8f5', color: '#257f60'} : {}];
263
316
  },
264
317
  isCurrentPlan(plan) {
265
- return this.shop.plan && (plan.id === this.shop.plan.id || (!plan.is_custom && plan.base_plan === this.shop.plan.id));
318
+ return !this.plan.choose_later && this.shop.plan && (plan.id === this.shop.plan.id || (!plan.is_custom && plan.base_plan === this.shop.plan.id));
266
319
  },
267
320
  isSamePlanInOtherInterval(plan) {
268
321
  return this.shop.plan && (plan.shopify_plans === this.shop.plan.shopify_plans)
@@ -290,6 +343,24 @@
290
343
  return plan.price - plan.discount
291
344
  }
292
345
  },
346
+ headerClasses(firstColumn) {
347
+ return {
348
+ 'Polaris-DataTable__Cell': true,
349
+ 'Polaris-DataTable__Cell--header': true,
350
+ 'Polaris-DataTable__Cell--verticalAlignMiddle': true,
351
+ 'Polaris-DataTable__Cell--firstColumn': Boolean(firstColumn),
352
+ };
353
+ },
354
+ groupBy(objectArray, property) {
355
+ return objectArray.reduce((acc, obj) => {
356
+ const key = obj[property];
357
+ if (!acc[key]) {
358
+ acc[key] = [];
359
+ }
360
+ acc[key].push(obj);
361
+ return acc;
362
+ }, {});
363
+ },
293
364
  async getPlanUrl(plan) {
294
365
  let shopName = this.shop.name;
295
366
  const response = await axios.get(`${this.app_manager_config.baseUrl}/api/app-manager/plan/process/${plan.id}?shop=${shopName}`).catch(error => {
@@ -319,50 +390,46 @@
319
390
  async selectPlan(value){
320
391
  this.selectedPlan= value;
321
392
  },
322
- headerClasses(firstColumn) {
323
- return {
324
- 'Polaris-DataTable__Cell': true,
325
- 'Polaris-DataTable__Cell--header': true,
326
- 'Polaris-DataTable__Cell--verticalAlignMiddle': true,
327
- 'Polaris-DataTable__Cell--firstColumn': Boolean(firstColumn),
328
- };
393
+ async fetchFeatures() {
394
+ let {data} = await axios.get(`${this.app_manager_config.baseUrl}/api/app-manager/plan-features`).catch(error => {
395
+ console.error(error)
396
+ });
397
+ if (data.features.length) {
398
+ this.features = data.features;
399
+ this.features = this.features?.filter((item) => item.hidden_feature !== true)
400
+ this.features = this.features?.sort((featureA, featureB) => parseInt(featureA.display_order) - parseInt(featureB.display_order))
401
+ this.features = this.features?.sort((featureA, featureB) => parseInt(featureA.group_order) - parseInt(featureB.group_order))
402
+ this.featuresByGroup = this.groupBy(this.features, 'group')
403
+ }
329
404
  },
330
- groupBy(objectArray, property) {
331
- return objectArray.reduce((acc, obj) => {
332
- const key = obj[property];
333
- if (!acc[key]) {
334
- acc[key] = [];
405
+ async fetchPlans() {
406
+ let {data} = await axios.get(`${this.app_manager_config.baseUrl}/api/app-manager/plans`, { params: { 'shop_domain': this.shop_domain } }).catch(error => {
407
+ console.error(error)
408
+ });
409
+ if (data.plans.length) {
410
+ this.plans = data.plans;
411
+ this.plans = this.plans?.sort((planA, planB) => parseFloat(planA.price) - parseFloat(planB.price));
412
+
413
+ if (this.plans[0].store_base_plan) {
414
+ this.subtitleContent = 'App plans are based on your existing shopify plan';
335
415
  }
336
- // Add object to list for given key's value
337
- acc[key].push(obj);
338
- return acc;
339
- }, {});
340
- }
416
+
417
+ this.plan = data.plan;
418
+ if (this.plan?.interval === 'ANNUAL') {
419
+ this.selectedPlan = 'annually'
420
+
421
+ }
422
+ this.shopify_plan = data.shopify_plan;
423
+ this.default_plan_id = data.default_plan_id;
424
+ this.onboard = !this.plan
425
+ }
426
+ },
341
427
  },
342
428
  async mounted() {
343
-
344
- const featuresData = await axios.get(`${this.app_manager_config.baseUrl}/api/app-manager/plan-features`).catch(error => {
345
- console.error(error)
346
- });
347
- this.features = featuresData.data.features;
348
- this.features = this.features.sort((featureA, featureB) => parseInt(featureA.display_order) - parseInt(featureB.display_order))
349
- this.features = this.features.sort((featureA, featureB) => parseInt(featureA.group_order) - parseInt(featureB.group_order))
350
- this.featuresByGroup = this.groupBy(this.features, 'group')
351
- const plansData = await axios.get(`${this.app_manager_config.baseUrl}/api/app-manager/plans`, { params: { 'shop_domain': this.shop_domain } }).catch(error => {
352
- console.error(error)
353
- });
354
- this.plans = plansData.data.plans;
355
- this.plans = this.plans.sort((planA, planB) => parseFloat(planA.price) - parseFloat(planB.price));
356
- if (this.plans && this.plans[0].store_base_plan) {
357
- this.subtitleContent = 'App plans are based on your existing shopify plan';
358
- }
359
- this.shopify_plan = plansData.data.shopify_plan;
360
- this.plan = plansData.data.plan;
361
- if (this.plan?.interval === 'ANNUAL') {
362
- this.selectedPlan = 'annually'
363
- }
364
- this.default_plan_id = plansData.data.default_plan_id;
365
- this.onboard = !this.plan
429
+ this.planLoading = true;
430
+ await this.fetchFeatures();
431
+ await this.fetchPlans();
432
+ this.planLoading = false;
366
433
  }
367
434
  }
368
435
  </script>
@@ -554,4 +621,17 @@
554
621
  word-spacing: 999px;
555
622
  white-space: pre-line !important;
556
623
  }
624
+
625
+ .app-manager .app-manager-plan-page .Polaris-DataTable__Table {
626
+ table-layout: fixed !important;
627
+ }
628
+
629
+ .app-manager .app-manager-plan-page td {
630
+ vertical-align: middle !important;
631
+ }
632
+
633
+ .app-manager .app-manager-plan-page td.feature__class {
634
+ word-wrap:break-word !important;
635
+ white-space: normal !important;
636
+ }
557
637
  </style>
@@ -1,8 +1,56 @@
1
1
  <template>
2
+ <PSkeletonPage title="Plans"
3
+ :fullWidth="false"
4
+ primaryAction
5
+ :secondaryActions="2"
6
+ :breadcrumbs="false"
7
+ v-if="planLoading">
8
+ <PLayout>
9
+ <PLayoutSection oneThird="">
10
+ <PCard sectioned="">
11
+ <PTextContainer>
12
+ <PSkeletonDisplayText size="small" />
13
+ <PSkeletonBodyText />
14
+ </PTextContainer>
15
+ </PCard>
16
+ </PLayoutSection>
17
+ <PLayoutSection oneThird="">
18
+ <PCard sectioned="">
19
+ <PTextContainer>
20
+ <PSkeletonDisplayText size="small" />
21
+ <PSkeletonBodyText />
22
+ </PTextContainer>
23
+ </PCard>
24
+ </PLayoutSection>
25
+ <PLayoutSection oneThird="">
26
+ <PCard sectioned="">
27
+ <PTextContainer>
28
+ <PSkeletonDisplayText size="small" />
29
+ <PSkeletonBodyText />
30
+ </PTextContainer>
31
+ </PCard>
32
+ </PLayoutSection>
33
+ </PLayout>
34
+ <PLayout style="margin-top: 20px">
35
+ <PLayoutSection>
36
+ <PCard sectioned=""><PSkeletonBodyText /></PCard>
37
+ <PCard sectioned=""><PSkeletonBodyText /></PCard>
38
+ <PCard sectioned=""><PSkeletonBodyText /></PCard>
39
+ <PCard sectioned=""><PSkeletonBodyText /></PCard>
40
+ </PLayoutSection>
41
+ </PLayout>
42
+ </PSkeletonPage>
43
+ <PEmptyState
44
+ heading="No Plans"
45
+ image="https://cdn.shopify.com/s/files/1/0262/4071/2726/files/emptystate-files.png"
46
+ v-else-if="!this.planLoading && this.plans.length === 0"
47
+ >
48
+ </PEmptyState>
2
49
  <PPage
3
50
  class="app-manager-plan-page-slider custom-title"
4
51
  title="Choose plan"
5
52
  :subtitle = "subtitleContent"
53
+ v-else
6
54
  >
7
55
 
8
56
  <PStack slot="primaryAction">
@@ -28,7 +76,7 @@
28
76
  <div class="Polaris-ResourceList__ResourceListWrapper features" style="width: 30%">
29
77
  <div class="plan__price"></div>
30
78
  <ul class="Polaris-ResourceList">
31
- <li class="Polaris-ResourceList__ItemWrapper pro_title" :class="`feature__type__${feature.value_type} feature__class`" v-for="(feature, key) in features" :key="key">
79
+ <li class="Polaris-ResourceList__ItemWrapper pro_title" :class="`${feature.value_type}__type__${feature.slug} feature__type__${feature.value_type} feature__class`" v-for="(feature, key) in features" :key="key">
32
80
  <div class="Polaris-ResourceList-Item__Container">
33
81
  <div class="Polaris-ResourceList-Item__Content">
34
82
  <h1 class="for-price-per-month"><span>{{ feature.name }}</span></h1>
@@ -42,8 +90,14 @@
42
90
  <template>
43
91
  <slide :id="key" :class="`slide-${key}`" v-for="(plan, key) in selectedPlan === 'monthly' ? monthlyPlan : yearlyPlan" :key="`slide-${key}`" >
44
92
  <div class="plan__price" :style="activePlanStyle(plan)">
45
- <b style="font-size: 16px">{{(plan.name)}}</b>
46
- <div v-if="plan.discount && plan.discount > 0" >
93
+ <div v-if="plan.price === 0">
94
+ <b v-if="plan.name !== 'Free'" style="font-size: 16px">{{(plan.name)}}</b>
95
+ <p style="display: flex;margin-top: 10px">
96
+ <PHeading style="font-size: 25px;font-weight: 700;">Free</PHeading>
97
+ </p>
98
+ </div>
99
+ <div v-else-if="plan.discount && plan.discount > 0" >
100
+ <b style="font-size: 16px">{{(plan.name)}}</b>
47
101
  <p style="display: flex;margin-top: 10px">
48
102
  <PHeading style="font-size: 25px;font-weight: 700;">${{parseFloat(calculateDiscountedPrice(plan)).toFixed(2)}}</PHeading>
49
103
  <b style="margin-top: 5px;font-size: 17px">/{{selectedPlan === 'monthly' ? ("mo") : ("year")}}</b>
@@ -54,15 +108,16 @@
54
108
  </p>
55
109
  </div>
56
110
  <div v-else>
111
+ <b style="font-size: 16px">{{(plan.name)}}</b>
57
112
  <p style="display: flex;margin-top: 10px">
58
113
  <PHeading style="font-size: 25px;font-weight: 700;">${{parseFloat(plan.price).toFixed(2)}}</PHeading>
59
- <b style="margin-top: 5px;font-size: 17px">/{{selectedPlan === 'monthly' ? ("mo") : ("year")}}</b>
114
+ <b style="margin-top: 5px;font-size: 17px">/{{selectedPlan === 'monthly' ? ("mo") : ("year")}}</b>
60
115
  </p>
61
116
  </div>
62
117
  </div>
63
118
  <div>
64
119
  <ul>
65
- <li v-for="(feature, key) in features" :class="`feature__type__${feature.value_type}`" :key="key" :style="activePlanStyle(plan)">
120
+ <li v-for="(feature, key) in features" :class="`${feature.value_type}__type__${feature.slug} feature__list feature__type__${feature.value_type}`" :key="key" :style="activePlanStyle(plan)">
66
121
  <div>
67
122
  <template v-if="plan.features && plan.features[feature.uuid]" style="display: flex">
68
123
  <template v-if="plan.features[feature.uuid].value_type === 'boolean'">
@@ -104,7 +159,6 @@
104
159
  </carousel>
105
160
  </template>
106
161
  </PLayoutSection>
107
- <PlanBanners />
108
162
  </PLayout>
109
163
  <!--====================================================================-->
110
164
  <PStack v-if="onboard && !shop.has_plan" class="choose-plan-btn" alignment="center" distribution="center" vertical>
@@ -112,6 +166,7 @@
112
166
  <PButton plain @click="activePlan">{{ ('I will choose the plan later') }}</PButton>
113
167
  </PStackItem>
114
168
  </PStack>
169
+ <PlanBanners />
115
170
  </PPage>
116
171
  </template>
117
172
 
@@ -134,16 +189,24 @@
134
189
  import {PDataTableRow} from "../polaris-vue/src/components/PDataTable/components/PDataTableRow";
135
190
  import {PIcon} from "../polaris-vue/src/components/PIcon";
136
191
  import {PTextStyle} from "../polaris-vue/src/components/PTextStyle";
192
+ import {PCard} from "../polaris-vue/src/components/PCard"
193
+ import {PCardSection} from "../polaris-vue/src/components/PCard/components/PCardSection"
194
+ import {PSkeletonPage} from "../polaris-vue/src/components/PSkeletonPage"
195
+ import {PSkeletonDisplayText} from "../polaris-vue/src/components/PSkeletonDisplayText"
196
+ import {PSkeletonBodyText} from "../polaris-vue/src/components/PSkeletonBodyText"
197
+ import {PEmptyState} from "../polaris-vue/src/components/PEmptyState"
137
198
  import {Carousel, Slide} from 'vue-carousel';
138
199
 
139
200
  export default {
140
201
  name: "AppManagerSliderPlan",
141
- components: { Carousel, Slide, YearlyPlanPromotion, PlanBanners, PPage, PStack, PStackItem, PButton, PButtonGroup, PHeading, PLayout, PLayoutSection, PTextContainer, PDataTable, PDataTableCol, PDataTableRow, PIcon, PTextStyle },
202
+ components: { Carousel, Slide, YearlyPlanPromotion, PlanBanners, PPage, PStack, PStackItem, PButton, PButtonGroup, PHeading, PLayout, PLayoutSection, PTextContainer, PDataTable, PDataTableCol, PDataTableRow, PIcon, PTextStyle, PCardSection, PCard, PSkeletonDisplayText, PSkeletonBodyText, PSkeletonPage, PEmptyState },
142
203
  props: ['shop_domain'],
143
204
  data() {
144
205
  return {
145
- perPage: 4,
206
+ slideLength : 0,
207
+ perPage: 0,
146
208
  currentSlide: 0,
209
+ planLoading: false,
147
210
  plan: {},
148
211
  plans: [],
149
212
  features: [],
@@ -253,7 +316,9 @@
253
316
  element = document.querySelector(lastSlideClassName);
254
317
  element.classList.add('last-slide')
255
318
 
256
- document.querySelector('.VueCarousel-navigation-button.VueCarousel-navigation-prev').style.left = -document.querySelector('.Polaris-ResourceList__ResourceListWrapper.features').offsetWidth + 'px';
319
+ if (document.querySelector('.VueCarousel-navigation-button.VueCarousel-navigation-prev')) {
320
+ document.querySelector('.VueCarousel-navigation-button.VueCarousel-navigation-prev').style.left = -document.querySelector('.Polaris-ResourceList__ResourceListWrapper.features').offsetWidth + 'px';
321
+ }
257
322
  },
258
323
  activePlanStyle(plan) {
259
324
  return [plan.shopify_plans.includes(this.shop.shopify_plan) || !plan.store_base_plan ? {backgroundColor: '#f0f8f5', color: '#257f60'} : {}];
@@ -262,7 +327,7 @@
262
327
  return plan.shopify_plans.includes(this.shop.shopify_plan) || !plan.store_base_plan ? 'active-plan' : '';
263
328
  },
264
329
  isCurrentPlan(plan) {
265
- return this.shop.plan && (plan.id === this.shop.plan.id || (!plan.is_custom && plan.base_plan === this.shop.plan.id));
330
+ return !this.plan.choose_later && this.shop.plan && (plan.id === this.shop.plan.id || (!plan.is_custom && plan.base_plan === this.shop.plan.id));
266
331
  },
267
332
  isSamePlanInOtherInterval(plan) {
268
333
  return this.shop.plan && (plan.shopify_plans === this.shop.plan.shopify_plans)
@@ -320,11 +385,9 @@
320
385
  this.selectedPlan = value;
321
386
  this.$nextTick(() => {
322
387
 
323
- let maxHeight = 0
324
- let elements = document.querySelectorAll('.feature__type__array');
388
+ let elements = document.querySelectorAll('.plan__price');
389
+ let maxHeight = 0;
325
390
  elements.forEach((item) => {
326
- item.style.minHeight = 'unset';
327
- console.log(item.offsetHeight)
328
391
  if (maxHeight < item.offsetHeight) {
329
392
  maxHeight = item.offsetHeight
330
393
  }
@@ -333,16 +396,88 @@
333
396
  item.style.minHeight = maxHeight + 'px';
334
397
  });
335
398
 
336
- let element = document.querySelector('.slide-0');
337
- if (element) {
338
- element.classList.add('first-slide')
339
- element = document.querySelector('.slide-3');
340
- element.classList.add('last-slide')
341
- document.querySelector('.VueCarousel-navigation-button.VueCarousel-navigation-prev').style.left = -document.querySelector('.Polaris-ResourceList__ResourceListWrapper.features').offsetWidth + 'px';
399
+ this.slideLength = this.selectedPlan === 'monthly' ? this.monthlyPlan.length : this.yearlyPlan.length;
400
+ this.perPage = this.slideLength >= 4 ? 4 : this.slideLength;
401
+
402
+ // calculate and reset height of rows
403
+ this.features.forEach((feature) => {
404
+ let className = feature.value_type + '__type__' + feature.slug;
405
+ let elements = document.querySelectorAll('.' + className);
406
+ let maxHeight = 0;
407
+ elements.forEach((item) => {
408
+ item.style.minHeight = 'unset';
409
+ if (maxHeight < item.offsetHeight) {
410
+ maxHeight = item.offsetHeight
411
+ }
412
+ });
413
+ elements.forEach((item) => {
414
+ item.style.minHeight = maxHeight + 'px';
415
+ });
416
+ })
417
+
418
+ // remove first-slide and last-slide classes
419
+ let allSlides = document.getElementsByClassName('VueCarousel-slide');
420
+ for (let i=0, max=allSlides.length; i < max; i++) {
421
+ let slide = document.getElementById(allSlides[i].id);
422
+ slide.classList.remove('first-slide')
423
+ slide.classList.remove('last-slide')
342
424
  }
343
425
 
426
+ // add first-slide and last-slide classes
427
+ let pagesCount = this.slideLength;
428
+ setTimeout(() => {
429
+ let element = document.querySelector('.slide-0');
430
+ if (element) {
431
+ element.classList.add('first-slide')
432
+ if (pagesCount < 4) {
433
+ let lastSlideClass = '.slide-' + (pagesCount-1)
434
+ element = document.querySelector(lastSlideClass);
435
+ element.classList.add('last-slide')
436
+ }
437
+ else {
438
+ element = document.querySelector('.slide-3');
439
+ element.classList.add('last-slide')
440
+ }
441
+ if (document.querySelector('.VueCarousel-navigation-button.VueCarousel-navigation-prev')) {
442
+ document.querySelector('.VueCarousel-navigation-button.VueCarousel-navigation-prev').style.left = -document.querySelector('.Polaris-ResourceList__ResourceListWrapper.features').offsetWidth + 'px';
443
+ }
444
+ }
445
+ }, 100)
446
+
344
447
  });
345
448
  },
449
+ async fetchFeatures() {
450
+ let {data} = await axios.get(`${this.app_manager_config.baseUrl}/api/app-manager/plan-features`).catch(error => {
451
+ console.error(error)
452
+ });
453
+ if (data.features.length) {
454
+ this.features = data.features;
455
+ this.features = this.features?.filter((item) => item.hidden_feature !== true)
456
+ this.features = this.features?.sort((featureA, featureB) => parseInt(featureA.display_order) - parseInt(featureB.display_order))
457
+ }
458
+ },
459
+ async fetchPlans() {
460
+ let {data} = await axios.get(`${this.app_manager_config.baseUrl}/api/app-manager/plans`, { params: { 'shop_domain': this.shop_domain } }).catch(error => {
461
+ console.error(error)
462
+ });
463
+ if (data.plans.length) {
464
+ this.plans = data.plans;
465
+ this.plans = this.plans?.sort((planA, planB) => parseFloat(planA.price) - parseFloat(planB.price));
466
+
467
+ if (this.plans[0].store_base_plan) {
468
+ this.subtitleContent = 'App plans are based on your existing shopify plan';
469
+ }
470
+
471
+ this.plan = data.plan;
472
+ if (this.plan?.interval === 'ANNUAL') {
473
+ this.selectedPlan = 'annually'
474
+
475
+ }
476
+ this.shopify_plan = data.shopify_plan;
477
+ this.default_plan_id = data.default_plan_id;
478
+ this.onboard = !this.plan
479
+ }
480
+ },
346
481
  headerClasses(firstColumn) {
347
482
  return {
348
483
  'Polaris-DataTable__Cell': true,
@@ -354,49 +489,75 @@
354
489
  },
355
490
  async mounted() {
356
491
 
357
- const featuresData = await axios.get(`${this.app_manager_config.baseUrl}/api/app-manager/plan-features`).catch(error => {
358
- console.error(error)
359
- });
360
- this.features = featuresData.data.features;
361
- this.features = this.features.sort((featureA, featureB) => parseInt(featureA.display_order) - parseInt(featureB.display_order))
362
-
363
- const plansData = await axios.get(`${this.app_manager_config.baseUrl}/api/app-manager/plans`, { params: { 'shop_domain': this.shop_domain } }).catch(error => {
364
- console.error(error)
365
- });
366
- this.plans = plansData.data.plans;
367
- this.plans = this.plans.sort((planA, planB) => parseFloat(planA.price) - parseFloat(planB.price));
368
- if (this.plans && this.plans[0].store_base_plan) {
369
- this.subtitleContent = 'App plans are based on your existing shopify plan';
370
- }
371
- this.shopify_plan = plansData.data.shopify_plan;
372
- this.plan = plansData.data.plan;
373
- if (this.plan?.interval === 'ANNUAL') {
374
- this.selectedPlan = 'annually'
375
- }
376
- this.default_plan_id = plansData.data.default_plan_id;
377
- this.onboard = !this.plan
492
+ this.planLoading = true;
493
+ await this.fetchFeatures();
494
+ await this.fetchPlans();
495
+ this.planLoading = false;
378
496
 
379
497
  this.$nextTick(() => {
380
498
 
381
- let maxHeight = 0
382
- let elements = document.querySelectorAll('.feature__type__array');
383
- elements.forEach((item) => {
384
- if (maxHeight < item.offsetHeight) {
385
- maxHeight = item.offsetHeight
386
- }
387
- });
388
- elements.forEach((item) => {
389
- item.style.minHeight = maxHeight + 'px';
390
- });
499
+ // calculate height of cell
500
+ setTimeout(() => {
391
501
 
392
- let element = document.querySelector('.slide-0');
393
- if (element) {
394
- element.classList.add('first-slide')
395
- element = document.querySelector('.slide-3');
396
- element.classList.add('last-slide')
397
- document.querySelector('.VueCarousel-navigation-button.VueCarousel-navigation-prev').style.left = -document.querySelector('.Polaris-ResourceList__ResourceListWrapper.features').offsetWidth + 'px';
502
+ let elements = document.querySelectorAll('.plan__price');
503
+ let maxHeight = 0;
504
+ elements.forEach((item) => {
505
+ item.style.minHeight = 'unset';
506
+ if (maxHeight < item.offsetHeight) {
507
+ maxHeight = item.offsetHeight
508
+ }
509
+ });
510
+ elements.forEach((item) => {
511
+ item.style.minHeight = maxHeight + 'px';
512
+ });
513
+
514
+ this.features.forEach((feature) => {
515
+ let className = feature.value_type + '__type__' + feature.slug;
516
+ elements = document.querySelectorAll('.' + className);
517
+ maxHeight = 0;
518
+ elements.forEach((item) => {
519
+ if (maxHeight < item.offsetHeight) {
520
+ maxHeight = item.offsetHeight
521
+ }
522
+ });
523
+ elements.forEach((item) => {
524
+ item.style.minHeight = maxHeight + 'px';
525
+ });
526
+ })
527
+ }, 100);
528
+
529
+ // remove fist-slide and last-slide classes from all slides
530
+ let allSlides = document.getElementsByClassName('VueCarousel-slide');
531
+ for (let i=0, max=allSlides.length; i < max; i++) {
532
+ let slide = document.getElementById(allSlides[i].id);
533
+ slide.classList.remove('first-slide')
534
+ slide.classList.remove('last-slide')
398
535
  }
399
536
 
537
+ // add first-slide and last-slide
538
+ this.slideLength = this.selectedPlan === 'monthly' ? this.monthlyPlan.length : this.yearlyPlan.length;
539
+ this.perPage = this.slideLength >= 4 ? 4 : this.slideLength;
540
+
541
+ let pagesCount = this.slideLength;
542
+ setTimeout(() => {
543
+ let element = document.querySelector('.slide-0');
544
+ if (element) {
545
+ element.classList.add('first-slide')
546
+ if (pagesCount < 4) {
547
+ let lastSlideClass = '.slide-' + (pagesCount-1)
548
+ element = document.querySelector(lastSlideClass);
549
+ element.classList.add('last-slide')
550
+ }
551
+ else {
552
+ element = document.querySelector('.slide-3');
553
+ element.classList.add('last-slide')
554
+ }
555
+ if (document.querySelector('.VueCarousel-navigation-button.VueCarousel-navigation-prev')) {
556
+ document.querySelector('.VueCarousel-navigation-button.VueCarousel-navigation-prev').style.left = -document.querySelector('.Polaris-ResourceList__ResourceListWrapper.features').offsetWidth + 'px';
557
+ }
558
+ }
559
+ }, 100)
560
+
400
561
  });
401
562
  },
402
563
  }
@@ -430,9 +591,9 @@
430
591
  border-right: none;
431
592
  border-left: 1px solid #dddddd;
432
593
  }
433
- .app-manager .app-manager-plan-page-slider .plan__price{
594
+ /*.app-manager .app-manager-plan-page-slider .plan__price{
434
595
  min-height:121px;
435
- }
596
+ }*/
436
597
  .app-manager .app-manager-plan-page-slider .Polaris-ResourceList__ResourceListWrapper.features li:last-child,
437
598
  .app-manager .app-manager-plan-page-slider .Polaris-Layout__Section .VueCarousel-slide li:nth-last-child(2)
438
599
  {
@@ -489,6 +650,7 @@
489
650
  margin-left: 0px !important;
490
651
  z-index: unset !important;
491
652
  }
653
+ .app-manager .app-manager-plan-page-slider .feature__list,
492
654
  .app-manager .app-manager-plan-page-slider .feature__type__array
493
655
  {
494
656
  display: flex;